diff options
Diffstat (limited to 'fs/nfs/super.c')
| -rw-r--r-- | fs/nfs/super.c | 60 | 
1 files changed, 35 insertions, 25 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index dada09b391c6..bdb6d0c2e755 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -176,6 +176,41 @@ void nfs_sb_deactive(struct super_block *sb)  }  EXPORT_SYMBOL_GPL(nfs_sb_deactive); +static int __nfs_list_for_each_server(struct list_head *head, +		int (*fn)(struct nfs_server *, void *), +		void *data) +{ +	struct nfs_server *server, *last = NULL; +	int ret = 0; + +	rcu_read_lock(); +	list_for_each_entry_rcu(server, head, client_link) { +		if (!(server->super && nfs_sb_active(server->super))) +			continue; +		rcu_read_unlock(); +		if (last) +			nfs_sb_deactive(last->super); +		last = server; +		ret = fn(server, data); +		if (ret) +			goto out; +		rcu_read_lock(); +	} +	rcu_read_unlock(); +out: +	if (last) +		nfs_sb_deactive(last->super); +	return ret; +} + +int nfs_client_for_each_server(struct nfs_client *clp, +		int (*fn)(struct nfs_server *, void *), +		void *data) +{ +	return __nfs_list_for_each_server(&clp->cl_superblocks, fn, data); +} +EXPORT_SYMBOL_GPL(nfs_client_for_each_server); +  /*   * Deliver file system statistics to userspace   */ @@ -1179,7 +1214,6 @@ int nfs_get_tree_common(struct fs_context *fc)  	struct super_block *s;  	int (*compare_super)(struct super_block *, struct fs_context *) = nfs_compare_super;  	struct nfs_server *server = ctx->server; -	unsigned long kflags = 0, kflags_out = 0;  	int error;  	ctx->server = NULL; @@ -1239,26 +1273,6 @@ int nfs_get_tree_common(struct fs_context *fc)  		goto error_splat_super;  	} -	if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL) -		kflags |= SECURITY_LSM_NATIVE_LABELS; -	if (ctx->clone_data.sb) { -		if (d_inode(fc->root)->i_fop != &nfs_dir_operations) { -			error = -ESTALE; -			goto error_splat_root; -		} -		/* clone any lsm security options from the parent to the new sb */ -		error = security_sb_clone_mnt_opts(ctx->clone_data.sb, s, kflags, -				&kflags_out); -	} else { -		error = security_sb_set_mnt_opts(s, fc->security, -							kflags, &kflags_out); -	} -	if (error) -		goto error_splat_root; -	if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL && -		!(kflags_out & SECURITY_LSM_NATIVE_LABELS)) -		NFS_SB(s)->caps &= ~NFS_CAP_SECURITY_LABEL; -  	s->s_flags |= SB_ACTIVE;  	error = 0; @@ -1268,10 +1282,6 @@ out:  out_err_nosb:  	nfs_free_server(server);  	goto out; - -error_splat_root: -	dput(fc->root); -	fc->root = NULL;  error_splat_super:  	deactivate_locked_super(s);  	goto out;  |