Minix 文件系统的超级快操作表如下:
static const struct super_operations minix_sops = { .alloc_inode = minix_alloc_inode,//分配inode .destroy_inode = minix_destroy_inode,//销毁inode .write_inode = minix_write_inode, .delete_inode = minix_delete_inode, .put_super = minix_put_super, .statfs = minix_statfs, .remount_fs = minix_remount, };
下面详细介绍每一个函数:
static struct inode *minix_alloc_inode(struct super_block *sb) { struct minix_inode_info *ei; //采用slab的方法分配一个minix_inode_info结构 ei = (struct minix_inode_info *)kmem_cache_alloc(minix_inode_cachep, GFP_KERNEL); if (!ei) return NULL; //返回其中的inode域 return &ei->vfs_inode; }
static void minix_put_super(struct super_block *sb) { int i; struct minix_sb_info *sbi = minix_sb(sb);//sb->s_fs_info,这是minix超级块的私有数据 if (!(sb->s_flags & MS_RDONLY)) { if (sbi->s_version != MINIX_V3) /* s_state is now out from V3 sb */ sbi->s_ms->s_state = sbi->s_mount_state; //标记超级块脏,用于刷新到磁盘 mark_buffer_dirty(sbi->s_sbh); } //释放inode位图 for (i = 0; i < sbi->s_imap_blocks; i++) brelse(sbi->s_imap[i]); //释放数据位图 for (i = 0; i < sbi->s_zmap_blocks; i++) brelse(sbi->s_zmap[i]); //释放超级块缓冲区 brelse (sbi->s_sbh); kfree(sbi->s_imap); sb->s_fs_info = NULL; //释放sbi自身 kfree(sbi); }
static void minix_destroy_inode(struct inode *inode) { //采用slab的方法释放minix_inode_info的结构(放到了缓存中) kmem_cache_free(minix_inode_cachep, minix_i(inode)); }
static void minix_delete_inode(struct inode *inode) { truncate_inode_pages(&inode->i_data, 0); inode->i_size = 0; minix_truncate(inode); minix_free_inode(inode); }
static int minix_write_inode(struct inode *inode, struct writeback_control *wbc) { int err = 0; struct buffer_head *bh; if (INODE_VERSION(inode) == MINIX_V1) bh = V1_minix_update_inode(inode); else bh = V2_minix_update_inode(inode); if (!bh) return -EIO; if (wbc->sync_mode == WB_SYNC_ALL && buffer_dirty(bh)) { sync_dirty_buffer(bh); if (buffer_req(bh) && !buffer_uptodate(bh)) { printk("IO error syncing minix inode [%s:%08lx]\n", inode->i_sb->s_id, inode->i_ino); err = -EIO; } } brelse (bh); return err; }
static int minix_statfs(struct dentry *dentry, struct kstatfs *buf) { struct super_block *sb = dentry->d_sb; struct minix_sb_info *sbi = minix_sb(sb); u64 id = huge_encode_dev(sb->s_bdev->bd_dev); buf->f_type = sb->s_magic; buf->f_bsize = sb->s_blocksize; buf->f_blocks = (sbi->s_nzones - sbi->s_firstdatazone) << sbi->s_log_zone_size; buf->f_bfree = minix_count_free_blocks(sbi); buf->f_bavail = buf->f_bfree; buf->f_files = sbi->s_ninodes; buf->f_ffree = minix_count_free_inodes(sbi); buf->f_namelen = sbi->s_namelen; buf->f_fsid.val[0] = (u32)id; buf->f_fsid.val[1] = (u32)(id >> 32); return 0; }
static int minix_remount (struct super_block * sb, int * flags, char * data) { struct minix_sb_info * sbi = minix_sb(sb); //sb->s_fs_info struct minix_super_block * ms; ms = sbi->s_ms; if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) return 0; if (*flags & MS_RDONLY) { if (ms->s_state & MINIX_VALID_FS || !(sbi->s_mount_state & MINIX_VALID_FS)) return 0; /* Mounting a rw partition read-only. */ if (sbi->s_version != MINIX_V3) ms->s_state = sbi->s_mount_state; mark_buffer_dirty(sbi->s_sbh); } else { /* Mount a partition which is read-only, read-write. */ if (sbi->s_version != MINIX_V3) { sbi->s_mount_state = ms->s_state; ms->s_state &= ~MINIX_VALID_FS; } else { sbi->s_mount_state = MINIX_VALID_FS; } mark_buffer_dirty(sbi->s_sbh); if (!(sbi->s_mount_state & MINIX_VALID_FS)) printk("MINIX-fs warning: remounting unchecked fs, " "running fsck is recommended\n"); else if ((sbi->s_mount_state & MINIX_ERROR_FS)) printk("MINIX-fs warning: remounting fs with errors, " "running fsck is recommended\n"); } return 0; }