📄 ops_fstype.c
字号:
/* Read in the master statfs inode */ sdp->sd_statfs_inode = gfs2_lookup_simple(sdp->sd_master_dir, "statfs"); if (IS_ERR(sdp->sd_statfs_inode)) { error = PTR_ERR(sdp->sd_statfs_inode); fs_err(sdp, "can't read in statfs inode: %d\n", error); goto fail_inum; } /* Read in the resource index inode */ sdp->sd_rindex = gfs2_lookup_simple(sdp->sd_master_dir, "rindex"); if (IS_ERR(sdp->sd_rindex)) { error = PTR_ERR(sdp->sd_rindex); fs_err(sdp, "can't get resource index inode: %d\n", error); goto fail_statfs; } ip = GFS2_I(sdp->sd_rindex); set_bit(GLF_STICKY, &ip->i_gl->gl_flags); sdp->sd_rindex_vn = ip->i_gl->gl_vn - 1; /* Read in the quota inode */ sdp->sd_quota_inode = gfs2_lookup_simple(sdp->sd_master_dir, "quota"); if (IS_ERR(sdp->sd_quota_inode)) { error = PTR_ERR(sdp->sd_quota_inode); fs_err(sdp, "can't get quota file inode: %d\n", error); goto fail_rindex; } return 0;fail_qinode: iput(sdp->sd_quota_inode);fail_rindex: gfs2_clear_rgrpd(sdp); iput(sdp->sd_rindex);fail_statfs: iput(sdp->sd_statfs_inode);fail_inum: iput(sdp->sd_inum_inode);fail_journal: init_journal(sdp, UNDO);fail_master: iput(sdp->sd_master_dir);fail: return error;}static int init_per_node(struct gfs2_sbd *sdp, int undo){ struct inode *pn = NULL; char buf[30]; int error = 0; struct gfs2_inode *ip; if (sdp->sd_args.ar_spectator) return 0; if (undo) goto fail_qc_gh; pn = gfs2_lookup_simple(sdp->sd_master_dir, "per_node"); if (IS_ERR(pn)) { error = PTR_ERR(pn); fs_err(sdp, "can't find per_node directory: %d\n", error); return error; } sprintf(buf, "inum_range%u", sdp->sd_jdesc->jd_jid); sdp->sd_ir_inode = gfs2_lookup_simple(pn, buf); if (IS_ERR(sdp->sd_ir_inode)) { error = PTR_ERR(sdp->sd_ir_inode); fs_err(sdp, "can't find local \"ir\" file: %d\n", error); goto fail; } sprintf(buf, "statfs_change%u", sdp->sd_jdesc->jd_jid); sdp->sd_sc_inode = gfs2_lookup_simple(pn, buf); if (IS_ERR(sdp->sd_sc_inode)) { error = PTR_ERR(sdp->sd_sc_inode); fs_err(sdp, "can't find local \"sc\" file: %d\n", error); goto fail_ir_i; } sprintf(buf, "quota_change%u", sdp->sd_jdesc->jd_jid); sdp->sd_qc_inode = gfs2_lookup_simple(pn, buf); if (IS_ERR(sdp->sd_qc_inode)) { error = PTR_ERR(sdp->sd_qc_inode); fs_err(sdp, "can't find local \"qc\" file: %d\n", error); goto fail_ut_i; } iput(pn); pn = NULL; ip = GFS2_I(sdp->sd_ir_inode); error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &sdp->sd_ir_gh); if (error) { fs_err(sdp, "can't lock local \"ir\" file: %d\n", error); goto fail_qc_i; } ip = GFS2_I(sdp->sd_sc_inode); error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &sdp->sd_sc_gh); if (error) { fs_err(sdp, "can't lock local \"sc\" file: %d\n", error); goto fail_ir_gh; } ip = GFS2_I(sdp->sd_qc_inode); error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &sdp->sd_qc_gh); if (error) { fs_err(sdp, "can't lock local \"qc\" file: %d\n", error); goto fail_ut_gh; } return 0;fail_qc_gh: gfs2_glock_dq_uninit(&sdp->sd_qc_gh);fail_ut_gh: gfs2_glock_dq_uninit(&sdp->sd_sc_gh);fail_ir_gh: gfs2_glock_dq_uninit(&sdp->sd_ir_gh);fail_qc_i: iput(sdp->sd_qc_inode);fail_ut_i: iput(sdp->sd_sc_inode);fail_ir_i: iput(sdp->sd_ir_inode);fail: if (pn) iput(pn); return error;}static int init_threads(struct gfs2_sbd *sdp, int undo){ struct task_struct *p; int error = 0; if (undo) goto fail_quotad; sdp->sd_log_flush_time = jiffies; sdp->sd_jindex_refresh_time = jiffies; p = kthread_run(gfs2_logd, sdp, "gfs2_logd"); error = IS_ERR(p); if (error) { fs_err(sdp, "can't start logd thread: %d\n", error); return error; } sdp->sd_logd_process = p; sdp->sd_statfs_sync_time = jiffies; sdp->sd_quota_sync_time = jiffies; p = kthread_run(gfs2_quotad, sdp, "gfs2_quotad"); error = IS_ERR(p); if (error) { fs_err(sdp, "can't start quotad thread: %d\n", error); goto fail; } sdp->sd_quotad_process = p; return 0;fail_quotad: kthread_stop(sdp->sd_quotad_process);fail: kthread_stop(sdp->sd_logd_process); return error;}/** * fill_super - Read in superblock * @sb: The VFS superblock * @data: Mount options * @silent: Don't complain if it's not a GFS2 filesystem * * Returns: errno */static int fill_super(struct super_block *sb, void *data, int silent){ struct gfs2_sbd *sdp; struct gfs2_holder mount_gh; int error; sdp = init_sbd(sb); if (!sdp) { printk(KERN_WARNING "GFS2: can't alloc struct gfs2_sbd\n"); return -ENOMEM; } error = gfs2_mount_args(sdp, (char *)data, 0); if (error) { printk(KERN_WARNING "GFS2: can't parse mount arguments\n"); goto fail; } init_vfs(sb, SDF_NOATIME); /* Set up the buffer cache and fill in some fake block size values to allow us to read-in the on-disk superblock. */ sdp->sd_sb.sb_bsize = sb_min_blocksize(sb, GFS2_BASIC_BLOCK); sdp->sd_sb.sb_bsize_shift = sb->s_blocksize_bits; sdp->sd_fsb2bb_shift = sdp->sd_sb.sb_bsize_shift - GFS2_BASIC_BLOCK_SHIFT; sdp->sd_fsb2bb = 1 << sdp->sd_fsb2bb_shift; error = init_names(sdp, silent); if (error) goto fail; gfs2_create_debugfs_file(sdp); error = gfs2_sys_fs_add(sdp); if (error) goto fail; error = gfs2_lm_mount(sdp, silent); if (error) goto fail_sys; error = init_locking(sdp, &mount_gh, DO); if (error) goto fail_lm; error = init_sb(sdp, silent, DO); if (error) goto fail_locking; error = init_inodes(sdp, DO); if (error) goto fail_sb; error = init_per_node(sdp, DO); if (error) goto fail_inodes; error = gfs2_statfs_init(sdp); if (error) { fs_err(sdp, "can't initialize statfs subsystem: %d\n", error); goto fail_per_node; } error = init_threads(sdp, DO); if (error) goto fail_per_node; if (!(sb->s_flags & MS_RDONLY)) { error = gfs2_make_fs_rw(sdp); if (error) { fs_err(sdp, "can't make FS RW: %d\n", error); goto fail_threads; } } gfs2_glock_dq_uninit(&mount_gh); return 0;fail_threads: init_threads(sdp, UNDO);fail_per_node: init_per_node(sdp, UNDO);fail_inodes: init_inodes(sdp, UNDO);fail_sb: init_sb(sdp, 0, UNDO);fail_locking: init_locking(sdp, &mount_gh, UNDO);fail_lm: gfs2_gl_hash_clear(sdp, WAIT); gfs2_lm_unmount(sdp); while (invalidate_inodes(sb)) yield();fail_sys: gfs2_sys_fs_del(sdp);fail: gfs2_delete_debugfs_file(sdp); kfree(sdp); sb->s_fs_info = NULL; return error;}static int gfs2_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, struct vfsmount *mnt){ struct super_block *sb; struct gfs2_sbd *sdp; int error = get_sb_bdev(fs_type, flags, dev_name, data, fill_super, mnt); if (error) goto out; sb = mnt->mnt_sb; sdp = sb->s_fs_info; sdp->sd_gfs2mnt = mnt;out: return error;}static int fill_super_meta(struct super_block *sb, struct super_block *new, void *data, int silent){ struct gfs2_sbd *sdp = sb->s_fs_info; struct inode *inode; int error = 0; new->s_fs_info = sdp; sdp->sd_vfs_meta = sb; init_vfs(new, SDF_NOATIME); /* Get the master inode */ inode = igrab(sdp->sd_master_dir); new->s_root = d_alloc_root(inode); if (!new->s_root) { fs_err(sdp, "can't get root dentry\n"); error = -ENOMEM; iput(inode); } else new->s_root->d_op = &gfs2_dops; return error;}static int set_bdev_super(struct super_block *s, void *data){ s->s_bdev = data; s->s_dev = s->s_bdev->bd_dev; return 0;}static int test_bdev_super(struct super_block *s, void *data){ return s->s_bdev == data;}static struct super_block* get_gfs2_sb(const char *dev_name){ struct kstat stat; struct nameidata nd; struct file_system_type *fstype; struct super_block *sb = NULL, *s; int error; error = path_lookup(dev_name, LOOKUP_FOLLOW, &nd); if (error) { printk(KERN_WARNING "GFS2: path_lookup on %s returned error\n", dev_name); goto out; } error = vfs_getattr(nd.mnt, nd.dentry, &stat); fstype = get_fs_type("gfs2"); list_for_each_entry(s, &fstype->fs_supers, s_instances) { if ((S_ISBLK(stat.mode) && s->s_dev == stat.rdev) || (S_ISDIR(stat.mode) && s == nd.dentry->d_inode->i_sb)) { sb = s; goto free_nd; } } printk(KERN_WARNING "GFS2: Unrecognized block device or " "mount point %s\n", dev_name);free_nd: path_release(&nd);out: return sb;}static int gfs2_get_sb_meta(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, struct vfsmount *mnt){ int error = 0; struct super_block *sb = NULL, *new; struct gfs2_sbd *sdp; sb = get_gfs2_sb(dev_name); if (!sb) { printk(KERN_WARNING "GFS2: gfs2 mount does not exist\n"); error = -ENOENT; goto error; } sdp = sb->s_fs_info; if (sdp->sd_vfs_meta) { printk(KERN_WARNING "GFS2: gfs2meta mount already exists\n"); error = -EBUSY; goto error; } down(&sb->s_bdev->bd_mount_sem); new = sget(fs_type, test_bdev_super, set_bdev_super, sb->s_bdev); up(&sb->s_bdev->bd_mount_sem); if (IS_ERR(new)) { error = PTR_ERR(new); goto error; } module_put(fs_type->owner); new->s_flags = flags; strlcpy(new->s_id, sb->s_id, sizeof(new->s_id)); sb_set_blocksize(new, sb->s_blocksize); error = fill_super_meta(sb, new, data, flags & MS_SILENT ? 1 : 0); if (error) { up_write(&new->s_umount); deactivate_super(new); goto error; } new->s_flags |= MS_ACTIVE; /* Grab a reference to the gfs2 mount point */ atomic_inc(&sdp->sd_gfs2mnt->mnt_count); return simple_set_mnt(mnt, new);error: return error;}static void gfs2_kill_sb(struct super_block *sb){ if (sb->s_fs_info) { gfs2_delete_debugfs_file(sb->s_fs_info); gfs2_meta_syncfs(sb->s_fs_info); } kill_block_super(sb);}static void gfs2_kill_sb_meta(struct super_block *sb){ struct gfs2_sbd *sdp = sb->s_fs_info; generic_shutdown_super(sb); sdp->sd_vfs_meta = NULL; atomic_dec(&sdp->sd_gfs2mnt->mnt_count);}struct file_system_type gfs2_fs_type = { .name = "gfs2", .fs_flags = FS_REQUIRES_DEV, .get_sb = gfs2_get_sb, .kill_sb = gfs2_kill_sb, .owner = THIS_MODULE,};struct file_system_type gfs2meta_fs_type = { .name = "gfs2meta", .fs_flags = FS_REQUIRES_DEV, .get_sb = gfs2_get_sb_meta, .kill_sb = gfs2_kill_sb_meta, .owner = THIS_MODULE,};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -