diff --git a/libfs.c b/libfs.c index 04d7efa..2c8c7c4 100644 --- a/libfs.c +++ b/libfs.c @@ -59,8 +59,10 @@ static ssize_t dummy_write(struct file *file, const char __user *buf, size_t len struct inode *inode = file_inode(file); loff_t new_end = *ppos + len; - if (inode->i_size < new_end) inode->i_size = new_end; - *ppos += len; + if (inode->i_size < new_end) + inode->i_size = new_end; + + *ppos = new_end; mark_inode_dirty(inode); return len; } @@ -128,20 +130,43 @@ static int books_create(struct user_namespace *ns, struct inode *dir, return -ENOMEM; inode->i_uid = current_fsuid(); -// inode->i_op = &simple_file_inode_operations; inode->i_op = &custom_file_inode_operations; inode->i_fop = &custom_file_ops; -// d_instantiate(dentry, inode); - d_add(dentry, inode); + logf("books_create: dentry addr=%px, inode=%px", dentry, inode); + d_instantiate(dentry, inode); + inc_nlink(inode); + logf("books_create: d_instantiate done, dentry->d_inode=%px", dentry->d_inode); logf("dentry flags: %u, dentry name: %s", dentry->d_flags, dentry->d_name.name); mark_inode_dirty(inode); - logf("books_create: created file %s (ino=%lu)", dentry->d_name.name, inode->i_ino); return 0; } +#if 0 +static struct dentry *books_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) { + logf("books_lookup: looking for %s in ino=%lu", dentry->d_name.name, dir->i_ino); + return simple_lookup(dir, dentry, flags); +} +#endif +static struct dentry *books_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) { + struct dentry *child; + + logf("books_lookup: looking for %s in ino=%lu", dentry->d_name.name, dir->i_ino); + + child = d_lookup(dentry->d_parent, &dentry->d_name); + if (child) { + d_add(dentry, d_inode(child)); // связываем найденное inode + dput(child); + } else { + d_add(dentry, NULL); // файл не найден + } + + return NULL; // всегда возвращается NULL в lookup +} + + static const struct inode_operations books_dir_iops = { - .lookup = simple_lookup, + .lookup = books_lookup, .create = books_create, }; @@ -236,6 +261,7 @@ static int custom_mkdir(struct user_namespace *ns, struct inode *dir, struct den inode->i_fop = &simple_dir_operations; d_instantiate(dentry, inode); + inc_nlink(inode); inc_nlink(dir); logf("mkdir success: created %s in ino=%lu by uid=%u", @@ -291,6 +317,23 @@ static int custom_link(struct dentry *old_dentry, struct inode *dir, struct dent return r; } +static struct dentry *fs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) { + struct dentry *found; + + logf("fs_lookup: looking for %s in ino=%lu", dentry->d_name.name, dir->i_ino); + + found = d_lookup(dentry->d_parent, &dentry->d_name); + if (found) { + d_add(dentry, d_inode(found)); + dput(found); + } else { + d_add(dentry, NULL); + } + + return NULL; +} + +#if 0 static const struct inode_operations fs_dir_iops = { .lookup = simple_lookup, .mkdir = custom_mkdir, @@ -299,6 +342,15 @@ static const struct inode_operations fs_dir_iops = { .rename = custom_rename, .link = custom_link, }; +#endif +static const struct inode_operations fs_dir_iops = { + .lookup = fs_lookup, + .mkdir = custom_mkdir, + .unlink = custom_unlink, + .rmdir = custom_rmdir, + .rename = custom_rename, + .link = custom_link, +}; static void evict_inode(struct inode *inode) { clear_inode(inode);