static int myfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) { struct inode *inode = myfs_get_inode(dir->i_sb, dir, mode, dev); int error = -ENOSPC; if(inode) { /* Fill in inode information for a dentry */ d_instantiate(dentry, inode); dget(dentry); error = 0; dir->i_mtime = dir->i_ctime = CURRENT_TIME; } return error; }
static int myfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) { struct inode *inode; int error = -EPERM; if (dentry->d_inode) return -EEXIST; inode = myfs_get_inode(dir->i_sb, mode, dev); if (inode) { d_instantiate(dentry, inode); dget(dentry); error = 0; } return error; }
static int myfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) { struct inode *inode; int error = -ENOSPC; inode = myfs_get_inode(dir->i_sb, dir, S_IFLNK | S_IRWXUGO, 0); if(inode) { int l = strlen(symname)+1; error = page_symlink(inode, symname, l); if(!error) { d_instantiate(dentry, inode); dget(dentry); dir->i_mtime = dir->i_ctime = CURRENT_TIME; } else iput(inode); } return error; }
// 填充超级块入口 static int myfs_fill_sb(struct super_block *sb, void *data, int silent) { struct inode *root = NULL; struct myfs_fs_info *fsi; int err; int logval; sb->s_magic = MYFS_MAGIC_NUMBER; // 文件系统标识符 sb->s_op = &myfs_super_ops; // 超级块上的操作 sb->s_fs_info = fsi = kzalloc(sizeof(struct myfs_fs_info), GFP_KERNEL); if (!fsi) { printk("myfs: fsinfo allocation failed\n"); return -ENOMEM; } err = myfs_parse_options(data, fsi); printk("myfs: options - blksz=%lu, filemsz=%lu, mode=%o, fssize=%lu!\n", fsi->block_size, fsi->file_max_size, fsi->root_mode, fsi->fs_max_size); if (err) return err; sb->s_maxbytes = fsi->file_max_size; sb->s_blocksize = fsi->block_size; for (logval = 0; fsi->block_size > 1; logval++, fsi->block_size >>= 1); fsi->block_size = sb->s_blocksize; sb->s_blocksize_bits = logval; sb->s_time_gran = 1; root = myfs_get_inode(sb, NULL, S_IFDIR | fsi->root_mode, 0); sb->s_root = d_make_root(root); if (!sb->s_root) { printk("myfs: root creation failed\n"); return -ENOMEM; } return 0; }
static int myfs_fill_super(struct super_block *sb, void *data, int silent) { struct inode *root_inode; struct dentry *root_dentry; /* TODO 2: fill super_block * - blocksize, blocksize_bits * - magic * - super operations * - maxbytes */ sb->s_maxbytes = MAX_LFS_FILESIZE; sb->s_blocksize = MYFS_BLOCKSIZE; sb->s_blocksize_bits = MYFS_BLOCKSIZE_BITS; sb->s_magic = MYFS_MAGIC; sb->s_op = &myfs_ops; /* mode = directory & access rights (755) */ root_inode = myfs_get_inode(sb, S_IFDIR | S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); root_inode->i_ino = 1; printk(LOG_LEVEL "root inode has %d link(s)\n", root_inode->i_nlink); if (!root_inode) return -ENOMEM; root_dentry = d_make_root(root_inode); if (!root_dentry) goto out_no_root; sb->s_root = root_dentry; return 0; out_no_root: iput(root_inode); return -ENOMEM; }