From 42839e6cd9368fa3ead61c1cb241b6a25740a745 Mon Sep 17 00:00:00 2001 From: g2px1 Date: Fri, 20 Jun 2025 17:44:27 +0000 Subject: [PATCH] 1 --- libfs.c | 81 +++++++++++++++++++++++++++++++++++----------------- restart.bash | 23 +++++---------- 2 files changed, 62 insertions(+), 42 deletions(-) diff --git a/libfs.c b/libfs.c index 166253b..d68f04f 100644 --- a/libfs.c +++ b/libfs.c @@ -1,7 +1,3 @@ -/* - * Custom Filesystem Module - Implements the described behavior for "books" and "authors" directories. - */ - #include #include #include @@ -13,6 +9,7 @@ #include #include #include +#include #define FS_MAGIC 0x20240615 #define BOOKS_MODE 01777 @@ -32,7 +29,7 @@ struct link_entry { struct inode *target; }; -DEFINE_HASHTABLE(link_table, 6); // 64 buckets +DEFINE_HASHTABLE(link_table, 6); static void remove_links_to_inode(struct inode *inode) { struct link_entry *entry; @@ -40,6 +37,7 @@ static void remove_links_to_inode(struct inode *inode) { int bkt; hash_for_each_safe(link_table, bkt, tmp, entry, node) { if (entry->target == inode) { + printk(KERN_INFO "customfs: removing hardlink to inode %lu\n", inode->i_ino); d_delete(entry->link); hash_del(&entry->node); kfree(entry); @@ -57,6 +55,16 @@ static void fs_evict_inode(struct inode *inode) { clear_inode(inode); } +static int fs_statfs(struct dentry *dentry, struct kstatfs *buf) { + buf->f_type = FS_MAGIC; + return 0; +} + +static const struct super_operations fs_ops = { + .evict_inode = fs_evict_inode, + .statfs = fs_statfs, +}; + static ssize_t books_file_read(struct file *file, char __user *buf, size_t len, loff_t *ppos) { return simple_read_from_buffer(buf, len, ppos, file->private_data, PAGE_SIZE); } @@ -78,20 +86,18 @@ static const struct inode_operations books_file_iops = { static const struct inode_operations author_subdir_iops; -static struct dentry *author_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) { - return simple_lookup(dir, dentry, flags); -} - static int author_mkdir(struct user_namespace *ns, struct inode *dir, struct dentry *dentry, umode_t mode) { - struct inode *inode; - inode = new_inode(dir->i_sb); + struct inode *inode = new_inode(dir->i_sb); if (!inode) return -ENOMEM; inode->i_ino = get_next_ino(); - inode_init_owner(ns, inode, dir, S_IFDIR | AUTHOR_SUBDIR_MODE); + inode_init_owner(&init_user_ns, inode, dir, S_IFDIR | AUTHOR_SUBDIR_MODE); inode->i_op = &author_subdir_iops; inode->i_fop = &simple_dir_operations; + inc_nlink(inode); + inc_nlink(dir); d_add(dentry, inode); + printk(KERN_INFO "customfs: created author subdir '%s'\n", dentry->d_name.name); return 0; } @@ -106,22 +112,20 @@ static int author_link(struct dentry *old_dentry, struct inode *dir, struct dent entry->link = dget(new_dentry); entry->target = inode; hash_add(link_table, &entry->node, inode->i_ino); + printk(KERN_INFO "customfs: created hardlink '%s' to inode %lu\n", + new_dentry->d_name.name, inode->i_ino); } } return err; } static const struct inode_operations author_subdir_iops = { - .lookup = author_lookup, + .lookup = simple_lookup, .mkdir = author_mkdir, .rmdir = simple_rmdir, .link = author_link, }; -static const struct super_operations fs_ops = { - .evict_inode = fs_evict_inode, -}; - static struct inode *fs_make_inode(struct super_block *sb, umode_t mode) { struct inode *inode = new_inode(sb); if (!inode) @@ -131,9 +135,10 @@ static struct inode *fs_make_inode(struct super_block *sb, umode_t mode) { inode->i_sb = sb; inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode); - if (S_ISDIR(mode) && !inode->i_op) { + if (S_ISDIR(mode)) { inode->i_op = &simple_dir_inode_operations; inode->i_fop = &simple_dir_operations; + inc_nlink(inode); } else if (S_ISREG(mode)) { inode->i_fop = &books_file_fops; inode->i_op = &books_file_iops; @@ -159,33 +164,55 @@ static int fs_fill_super(struct super_block *sb, void *data, int silent) { if (!root_dentry) return -ENOMEM; - sb->s_root = root_dentry; - books_inode = fs_make_inode(sb, S_IFDIR | BOOKS_MODE); if (!books_inode) - return -ENOMEM; + goto out_root; books_inode->i_op = &simple_dir_inode_operations; books_inode->i_fop = &simple_dir_operations; - books_inode->i_mode |= S_IWUSR | S_IWGRP | S_IWOTH; + inc_nlink(books_inode); books_dentry = d_alloc_name(root_dentry, "books"); if (!books_dentry) - return -ENOMEM; + goto out_books; d_add(books_dentry, books_inode); + d_rehash(books_dentry); + printk(KERN_INFO "customfs: 'books' directory created\n"); authors_inode = fs_make_inode(sb, S_IFDIR | AUTHORS_MODE); if (!authors_inode) - return -ENOMEM; + goto out_books_dentry; + authors_inode->i_op = &author_subdir_iops; + inc_nlink(authors_inode); authors_dentry = d_alloc_name(root_dentry, "authors"); if (!authors_dentry) - return -ENOMEM; - authors_inode->i_op = &author_subdir_iops; + goto out_authors; d_add(authors_dentry, authors_inode); + d_rehash(authors_dentry); + printk(KERN_INFO "customfs: 'authors' directory created\n"); + + sb->s_root = root_dentry; + + printk(KERN_INFO "customfs: fill_super completed\n"); + printk(KERN_INFO "customfs: root inode=%lu\n", root_inode->i_ino); + printk(KERN_INFO "customfs: books inode=%lu\n", books_inode->i_ino); + printk(KERN_INFO "customfs: authors inode=%lu\n", authors_inode->i_ino); return 0; + +out_authors: + iput(authors_inode); +out_books_dentry: + dput(books_dentry); +out_books: + iput(books_inode); +out_root: + dput(root_dentry); + iput(root_inode); + return -ENOMEM; } static struct dentry *fs_mount(struct file_system_type *type, int flags, const char *dev, void *data) { + printk(KERN_INFO "customfs: mounting\n"); return mount_nodev(type, flags, data, fs_fill_super); } @@ -198,11 +225,13 @@ static struct file_system_type fs_type = { static int __init fs_init(void) { hash_init(link_table); + printk(KERN_INFO "customfs: module loaded\n"); return register_filesystem(&fs_type); } static void __exit fs_exit(void) { unregister_filesystem(&fs_type); + printk(KERN_INFO "customfs: module unloaded\n"); } module_init(fs_init); diff --git a/restart.bash b/restart.bash index c66d7c5..980d87f 100755 --- a/restart.bash +++ b/restart.bash @@ -1,21 +1,12 @@ #!/bin/bash + set -e -# Убить все процессы, использующие /mnt/test -sudo fuser -km /mnt/test || true +sudo umount /mnt/customfs 2>/dev/null || true +sudo rmmod libfs 2>/dev/null || true -# Подождать, пока умрут -sleep 0.5 +make -# Умонтировать -sudo umount /mnt/test || true - -# Выгрузить модуль -sudo rmmod statsfs || true - -# Подождать, пока освободится -sleep 0.5 - -# Вставить модуль и смонтировать -sudo insmod statsfs.ko -sudo mount -t libfs none /mnt/test +sudo insmod libfs.ko +sudo mount -t customfs none /mnt/customfs +ls -l /mnt/customfs