mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	new helpers: vfs_create_mount(), fc_mount()
Create a new helper, vfs_create_mount(), that creates a detached vfsmount object from an fs_context that has a superblock attached to it. Almost all uses will be paired with immediately preceding vfs_get_tree(); add a helper for such combination. Switch vfs_kern_mount() to use this. NOTE: mild behaviour change; passing NULL as 'device name' to something like procfs will change /proc/*/mountstats - "device none" instead on "no device". That is consistent with /proc/mounts et.al. [do'h - EXPORT_SYMBOL_GPL slipped in by mistake; removed] [AV -- remove confused comment from vfs_create_mount()] [AV -- removed the second argument] Reviewed-by: David Howells <dhowells@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
		
							parent
							
								
									9bc61ab18b
								
							
						
					
					
						commit
						8f2918898e
					
				
					 2 changed files with 55 additions and 24 deletions
				
			
		|  | @ -941,12 +941,59 @@ static struct mount *skip_mnt_tree(struct mount *p) | |||
| 	return p; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * vfs_create_mount - Create a mount for a configured superblock | ||||
|  * @fc: The configuration context with the superblock attached | ||||
|  * | ||||
|  * Create a mount to an already configured superblock.  If necessary, the | ||||
|  * caller should invoke vfs_get_tree() before calling this. | ||||
|  * | ||||
|  * Note that this does not attach the mount to anything. | ||||
|  */ | ||||
| struct vfsmount *vfs_create_mount(struct fs_context *fc) | ||||
| { | ||||
| 	struct mount *mnt; | ||||
| 
 | ||||
| 	if (!fc->root) | ||||
| 		return ERR_PTR(-EINVAL); | ||||
| 
 | ||||
| 	mnt = alloc_vfsmnt(fc->source ?: "none"); | ||||
| 	if (!mnt) | ||||
| 		return ERR_PTR(-ENOMEM); | ||||
| 
 | ||||
| 	if (fc->sb_flags & SB_KERNMOUNT) | ||||
| 		mnt->mnt.mnt_flags = MNT_INTERNAL; | ||||
| 
 | ||||
| 	atomic_inc(&fc->root->d_sb->s_active); | ||||
| 	mnt->mnt.mnt_sb		= fc->root->d_sb; | ||||
| 	mnt->mnt.mnt_root	= dget(fc->root); | ||||
| 	mnt->mnt_mountpoint	= mnt->mnt.mnt_root; | ||||
| 	mnt->mnt_parent		= mnt; | ||||
| 
 | ||||
| 	lock_mount_hash(); | ||||
| 	list_add_tail(&mnt->mnt_instance, &mnt->mnt.mnt_sb->s_mounts); | ||||
| 	unlock_mount_hash(); | ||||
| 	return &mnt->mnt; | ||||
| } | ||||
| EXPORT_SYMBOL(vfs_create_mount); | ||||
| 
 | ||||
| struct vfsmount *fc_mount(struct fs_context *fc) | ||||
| { | ||||
| 	int err = vfs_get_tree(fc); | ||||
| 	if (!err) { | ||||
| 		up_write(&fc->root->d_sb->s_umount); | ||||
| 		return vfs_create_mount(fc); | ||||
| 	} | ||||
| 	return ERR_PTR(err); | ||||
| } | ||||
| EXPORT_SYMBOL(fc_mount); | ||||
| 
 | ||||
| struct vfsmount *vfs_kern_mount(struct file_system_type *type, | ||||
| 				int flags, const char *name, | ||||
| 				void *data) | ||||
| { | ||||
| 	struct fs_context *fc; | ||||
| 	struct mount *mnt; | ||||
| 	struct vfsmount *mnt; | ||||
| 	int ret = 0; | ||||
| 
 | ||||
| 	if (!type) | ||||
|  | @ -964,31 +1011,12 @@ struct vfsmount *vfs_kern_mount(struct file_system_type *type, | |||
| 	if (!ret) | ||||
| 		ret = parse_monolithic_mount_data(fc, data); | ||||
| 	if (!ret) | ||||
| 		ret = vfs_get_tree(fc); | ||||
| 	if (ret) { | ||||
| 		put_fs_context(fc); | ||||
| 		return ERR_PTR(ret); | ||||
| 	} | ||||
| 	up_write(&fc->root->d_sb->s_umount); | ||||
| 	mnt = alloc_vfsmnt(name); | ||||
| 	if (!mnt) { | ||||
| 		put_fs_context(fc); | ||||
| 		return ERR_PTR(-ENOMEM); | ||||
| 	} | ||||
| 		mnt = fc_mount(fc); | ||||
| 	else | ||||
| 		mnt = ERR_PTR(ret); | ||||
| 
 | ||||
| 	if (flags & SB_KERNMOUNT) | ||||
| 		mnt->mnt.mnt_flags = MNT_INTERNAL; | ||||
| 
 | ||||
| 	atomic_inc(&fc->root->d_sb->s_active); | ||||
| 	mnt->mnt.mnt_root = dget(fc->root); | ||||
| 	mnt->mnt.mnt_sb = fc->root->d_sb; | ||||
| 	mnt->mnt_mountpoint = mnt->mnt.mnt_root; | ||||
| 	mnt->mnt_parent = mnt; | ||||
| 	lock_mount_hash(); | ||||
| 	list_add_tail(&mnt->mnt_instance, &fc->root->d_sb->s_mounts); | ||||
| 	unlock_mount_hash(); | ||||
| 	put_fs_context(fc); | ||||
| 	return &mnt->mnt; | ||||
| 	return mnt; | ||||
| } | ||||
| EXPORT_SYMBOL_GPL(vfs_kern_mount); | ||||
| 
 | ||||
|  |  | |||
|  | @ -21,6 +21,7 @@ struct super_block; | |||
| struct vfsmount; | ||||
| struct dentry; | ||||
| struct mnt_namespace; | ||||
| struct fs_context; | ||||
| 
 | ||||
| #define MNT_NOSUID	0x01 | ||||
| #define MNT_NODEV	0x02 | ||||
|  | @ -88,6 +89,8 @@ struct path; | |||
| extern struct vfsmount *clone_private_mount(const struct path *path); | ||||
| 
 | ||||
| struct file_system_type; | ||||
| extern struct vfsmount *fc_mount(struct fs_context *fc); | ||||
| extern struct vfsmount *vfs_create_mount(struct fs_context *fc); | ||||
| extern struct vfsmount *vfs_kern_mount(struct file_system_type *type, | ||||
| 				      int flags, const char *name, | ||||
| 				      void *data); | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Al Viro
						Al Viro