⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ops_fstype.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	/* 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 + -