From dd5a0e207c9ec9111b04ed0654d6b10d966a9487 Mon Sep 17 00:00:00 2001 From: g2px1 Date: Tue, 17 Jun 2025 18:58:40 +0000 Subject: [PATCH] now no need to reboot --- statsfs.c | 103 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 57 insertions(+), 46 deletions(-) diff --git a/statsfs.c b/statsfs.c index 7bb1f87..0fb926b 100644 --- a/statsfs.c +++ b/statsfs.c @@ -10,6 +10,7 @@ #include #include #include +#include /* для iov_iter_count() */ #define LIBFS_MAGIC 0xA0B0C0D0 #define LIBFS_BOOKS_MODE 01777 @@ -39,9 +40,26 @@ static int libfs_rename(struct mnt_idmap *idmap, struct inode *old_dir, static int libfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry); +/* Обёртки с логированием */ +static ssize_t libfs_read_iter(struct kiocb *iocb, struct iov_iter *iter) +{ + struct inode *inode = file_inode(iocb->ki_filp); + pr_info("statsfs: READ ino#%lu pos=%lld len=%zu\n", + inode->i_ino, iocb->ki_pos, iov_iter_count(iter)); + return generic_file_read_iter(iocb, iter); +} + +static ssize_t libfs_write_iter(struct kiocb *iocb, struct iov_iter *iter) +{ + struct inode *inode = file_inode(iocb->ki_filp); + pr_info("statsfs: WRITE ino#%lu pos=%lld len=%zu\n", + inode->i_ino, iocb->ki_pos, iov_iter_count(iter)); + return generic_file_write_iter(iocb, iter); +} + static const struct file_operations libfs_file_ops = { - .read_iter = generic_file_read_iter, - .write_iter = generic_file_write_iter, + .read_iter = libfs_read_iter, + .write_iter = libfs_write_iter, .llseek = generic_file_llseek, }; @@ -58,8 +76,8 @@ static const struct inode_operations libfs_dir_iops = { .rmdir = libfs_rmdir, .rename = libfs_rename, .link = libfs_link, - .mknod = NULL, /* запрещаем */ - .symlink = NULL, /* запрещаем */ + .mknod = NULL, + .symlink = NULL, }; static const struct super_operations statsfs_sops = { @@ -71,26 +89,24 @@ static const struct super_operations statsfs_sops = { static struct inode *libfs_get_inode(struct super_block *sb, umode_t mode) { struct inode *inode; - pr_info("statsfs: libfs_get_inode(sb=%p, mode=%o)\n", sb, mode); + inode = new_inode(sb); if (!inode) { pr_err("statsfs: new_inode failed for mode %o\n", mode); return NULL; } - - inode->i_ino = get_next_ino(); - inode->i_sb = sb; - inode->i_mode = mode; + inode->i_ino = get_next_ino(); + inode->i_sb = sb; + inode->i_mode = mode; if (S_ISDIR(mode)) { inode->i_op = &libfs_dir_iops; inode->i_fop = &simple_dir_operations; pr_info("statsfs: created dir inode #%lu\n", inode->i_ino); } else { - inode->i_op = &libfs_file_iops; - inode->i_fop = &libfs_file_ops; - + inode->i_op = &libfs_file_iops; + inode->i_fop = &libfs_file_ops; inode->i_private = kzalloc(sizeof(struct hlist_head), GFP_KERNEL); if (!inode->i_private) { pr_err("statsfs: kzalloc for inode #%lu failed\n", inode->i_ino); @@ -98,9 +114,9 @@ static struct inode *libfs_get_inode(struct super_block *sb, umode_t mode) return NULL; } INIT_HLIST_HEAD((struct hlist_head *)inode->i_private); - pr_info("statsfs: created file inode #%lu with private list\n", inode->i_ino); + pr_info("statsfs: created file inode #%lu with private list\n", + inode->i_ino); } - return inode; } @@ -118,30 +134,29 @@ static void cleanup_links(struct inode *victim) hlist_for_each_entry_safe(le, tmp, list, node) { struct dentry *link = le->link; - struct dentry *pd; - struct inode *parent; - if (!link || d_unlinked(link)) { - pr_info("statsfs: link already gone, freeing entry\n"); + pr_info("statsfs: link gone, freeing entry\n"); hlist_del(&le->node); dput(link); kfree(le); continue; } - pd = dget_parent(link); - if (pd) { - parent = d_inode(pd); - if (WARN_ON(!parent)) - goto skip_unlink; - inode_lock(parent); - vfs_unlink(NULL, parent, link, NULL); - inode_unlock(parent); - pr_info("statsfs: unlinked %pd from parent inode #%lu\n", - link, parent->i_ino); - dput(pd); + { + struct dentry *pd = dget_parent(link); + struct inode *parent; + if (pd) { + parent = d_inode(pd); + if (WARN_ON(!parent)) + goto skip_unlink; + inode_lock(parent); + vfs_unlink(NULL, parent, link, NULL); + inode_unlock(parent); + pr_info("statsfs: unlinked %pd from parent inode #%lu\n", + link, parent->i_ino); + dput(pd); + } } - skip_unlink: hlist_del(&le->node); dput(link); @@ -162,7 +177,6 @@ static int libfs_create(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, umode_t mode, bool excl) { struct inode *inode; - pr_info("statsfs: CREATE %pd in dir inode #%lu mode=%o\n", dentry, dir->i_ino, mode); if (dir != books_inode) @@ -175,7 +189,8 @@ static int libfs_create(struct mnt_idmap *idmap, struct inode *dir, inode->i_uid = current_fsuid(); inode->i_gid = current_fsgid(); d_add(dentry, inode); - pr_info("statsfs: added file %pd as inode #%lu\n", dentry, inode->i_ino); + pr_info("statsfs: added file %pd as inode #%lu\n", + dentry, inode->i_ino); return 0; } @@ -183,16 +198,14 @@ static int libfs_unlink(struct inode *dir, struct dentry *dentry) { struct inode *victim = d_inode(dentry); int err; - pr_info("statsfs: UNLINK %pd from dir inode #%lu\n", dentry, dir->i_ino); if (dir == libfs_sb->s_root->d_inode && is_protected(dentry)) return -EPERM; err = simple_unlink(dir, dentry); - if (!err && dir == books_inode) { + if (!err && dir == books_inode) cleanup_links(victim); - } return err; } @@ -200,7 +213,6 @@ static int libfs_mkdir(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, umode_t mode) { struct inode *inode; - pr_info("statsfs: MKDIR %pd in dir inode #%lu\n", dentry, dir->i_ino); if (dir == libfs_sb->s_root->d_inode || dir == books_inode) @@ -215,7 +227,8 @@ static int libfs_mkdir(struct mnt_idmap *idmap, struct inode *dir, inode->i_uid = current_fsuid(); d_add(dentry, inode); inc_nlink(dir); - pr_info("statsfs: created subdir %pd as inode #%lu\n", dentry, inode->i_ino); + pr_info("statsfs: created subdir %pd as inode #%lu\n", + dentry, inode->i_ino); return 0; } @@ -234,7 +247,7 @@ static int libfs_rename(struct mnt_idmap *idmap, struct inode *odir, struct dentry *odent, struct inode *ndir, struct dentry *ndent, unsigned int flags) { - pr_info("statsfs: RENAME %pd (ino#%lu) -> %pd (ino#%lu)\n", + pr_info("statsfs: RENAME %pd(ino#%lu) -> %pd(ino#%lu)\n", odent, odir->i_ino, ndent, ndir->i_ino); if ((odir == libfs_sb->s_root->d_inode || ndir == libfs_sb->s_root->d_inode) && (is_protected(odent) || is_protected(ndent))) @@ -250,7 +263,6 @@ static int libfs_link(struct dentry *old_dentry, struct inode *dir, struct inode *t = d_inode(old_dentry); struct link_entry *le; int err; - pr_info("statsfs: LINK %pd -> %pd in dir inode #%lu\n", old_dentry, new_dentry, dir->i_ino); if (!S_ISREG(t->i_mode)) @@ -276,11 +288,10 @@ static int libfs_link(struct dentry *old_dentry, struct inode *dir, static int libfs_fill_super(struct super_block *sb, void *data, int silent) { struct inode *root; - pr_info("statsfs: fill_super\n"); - libfs_sb = sb; - sb->s_magic = LIBFS_MAGIC; - sb->s_op = &statsfs_sops; + libfs_sb = sb; + sb->s_magic = LIBFS_MAGIC; + sb->s_op = &statsfs_sops; root = libfs_get_inode(sb, S_IFDIR | 0755); if (!root) @@ -312,7 +323,7 @@ static struct dentry *libfs_mount(struct file_system_type *fs, static void libfs_evict_inode(struct inode *inode) { - pr_info("statsfs: evict_inode inode #%lu\n", inode->i_ino); + pr_info("statsfs: evict_inode ino#%lu\n", inode->i_ino); truncate_inode_pages_final(&inode->i_data); cleanup_links(inode); clear_inode(inode); @@ -320,7 +331,7 @@ static void libfs_evict_inode(struct inode *inode) static struct file_system_type libfs_type = { .owner = THIS_MODULE, - .name = "libfs", + .name = "statsfs", .mount = libfs_mount, .kill_sb = kill_litter_super, }; @@ -346,4 +357,4 @@ module_exit(libfs_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("you"); -MODULE_DESCRIPTION("Custom library FS with books and authors (with debug logs)"); +MODULE_DESCRIPTION("Custom library FS with books and authors (with debug logs)"); \ No newline at end of file