Re: [PATCH] NFS: Add SECINFO_NO_NAME call

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



If I'm not mistaken, this adds another NFSv4 proc, which would "break" nfsstat.  Does this mean I'm now allowed again to add a separate proc for "get migration status" instead of piggybacking on FS_LOCATIONS?

On Apr 13, 2011, at 2:55 PM, Bryan Schumaker wrote:

> 
> If the client is using NFS v4.1 and the initial mount attempt fails
> with -EPERM, we can use SECINFO_NO_NAME to determine what secflavor
> to use.  This should be more efficient than the guess-and-check
> method used with NFS v4.0.
> 
> Signed-off-by: Bryan Schumaker <bjschuma@xxxxxxxxxx>
> 
> ---
> fs/nfs/internal.h       |    3 ++
> fs/nfs/namespace.c      |    2 +-
> fs/nfs/nfs4_fs.h        |    2 +
> fs/nfs/nfs4proc.c       |   67 ++++++++++++++++++++++++++++++++++++++++++++++-
> fs/nfs/nfs4xdr.c        |   66 ++++++++++++++++++++++++++++++++++++++++++++++
> include/linux/nfs4.h    |    1 +
> include/linux/nfs_xdr.h |    8 +++++
> 7 files changed, 147 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
> index ce118ce..361a3a3 100644
> --- a/fs/nfs/internal.h
> +++ b/fs/nfs/internal.h
> @@ -266,6 +266,9 @@ extern void nfs_sb_deactive(struct super_block *sb);
> extern char *nfs_path(char **p, struct dentry *dentry,
> 		      char *buffer, ssize_t buflen);
> extern struct vfsmount *nfs_d_automount(struct path *path);
> +#ifdef CONFIG_NFS_V4
> +rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *);
> +#endif
> 
> /* getroot.c */
> extern struct dentry *nfs_get_root(struct super_block *, struct nfs_fh *,
> diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
> index 1f063ba..8102391 100644
> --- a/fs/nfs/namespace.c
> +++ b/fs/nfs/namespace.c
> @@ -119,7 +119,7 @@ Elong:
> }
> 
> #ifdef CONFIG_NFS_V4
> -static rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *flavors)
> +rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *flavors)
> {
> 	struct gss_api_mech *mech;
> 	struct xdr_netobj oid;
> diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
> index e1c261d..9f6bfa6 100644
> --- a/fs/nfs/nfs4_fs.h
> +++ b/fs/nfs/nfs4_fs.h
> @@ -65,6 +65,8 @@ struct nfs4_minor_version_ops {
> 			int cache_reply);
> 	int	(*validate_stateid)(struct nfs_delegation *,
> 			const nfs4_stateid *);
> +	int	(*find_root_sec)(struct nfs_server *, struct nfs_fh *,
> +			struct nfs_fsinfo *);
> 	const struct nfs4_state_recovery_ops *reboot_recovery_ops;
> 	const struct nfs4_state_recovery_ops *nograce_recovery_ops;
> 	const struct nfs4_state_maintenance_ops *state_renewal_ops;
> diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
> index b8e1ac6..d78762c 100644
> --- a/fs/nfs/nfs4proc.c
> +++ b/fs/nfs/nfs4proc.c
> @@ -2234,9 +2234,10 @@ static int nfs4_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle,
> static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
> 			      struct nfs_fsinfo *info)
> {
> +	int minor_version = server->nfs_client->cl_minorversion;
> 	int status = nfs4_lookup_root(server, fhandle, info);
> 	if ((status == -EPERM) && !(server->flags & NFS_MOUNT_SECFLAVOUR))
> -		status = nfs4_find_root_sec(server, fhandle, info);
> +		status = nfs_v4_minor_ops[minor_version]->find_root_sec(server, fhandle, info);
> 	if (status == 0)
> 		status = nfs4_server_capabilities(server, fhandle);
> 	if (status == 0)
> @@ -5803,6 +5804,68 @@ out:
> 	rpc_put_task(task);
> 	return status;
> }
> +
> +static int
> +_nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle,
> +		    struct nfs_fsinfo *info, struct nfs4_secinfo_flavors *flavors)
> +{
> +	struct nfs41_secinfo_no_name_args args = {
> +		.style = SECINFO_STYLE_CURRENT_FH,
> +	};
> +	struct nfs4_secinfo_res res = {
> +		.flavors = flavors,
> +	};
> +	struct rpc_message msg = {
> +		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SECINFO_NO_NAME],
> +		.rpc_argp = &args,
> +		.rpc_resp = &res,
> +	};
> +	return nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
> +}
> +
> +static int
> +nfs41_proc_secinfo_no_name(struct nfs_server *server, struct nfs_fh *fhandle,
> +			   struct nfs_fsinfo *info, struct nfs4_secinfo_flavors *flavors)
> +{
> +	struct nfs4_exception exception = { };
> +	int err;
> +	do {
> +		err = nfs4_handle_exception(server,
> +					_nfs41_proc_secinfo_no_name(server, fhandle, info, flavors),
> +					&exception);
> +	} while (exception.retry);
> +	return err;
> +}
> +
> +static int
> +nfs41_find_root_sec(struct nfs_server *server, struct nfs_fh *fhandle,
> +		    struct nfs_fsinfo *info)
> +{
> +	int err;
> +	struct page *page;
> +	rpc_authflavor_t flavor;
> +	struct nfs4_secinfo_flavors *flavors;
> +
> +	page = alloc_page(GFP_KERNEL);
> +	if (!page) {
> +		err = -ENOMEM;
> +		goto out;
> +	}
> +
> +	flavors = page_address(page);
> +	err = nfs41_proc_secinfo_no_name(server, fhandle, info, flavors);
> +	if (err)
> +		goto out_freepage;
> +
> +	flavor = nfs_find_best_sec(flavors);
> +	if (err == 0)
> +		err = nfs4_lookup_root_sec(server, fhandle, info, flavor);
> +
> +out_freepage:
> +	put_page(page);
> +out:
> +	return err;
> +}
> #endif /* CONFIG_NFS_V4_1 */
> 
> struct nfs4_state_recovery_ops nfs40_reboot_recovery_ops = {
> @@ -5864,6 +5927,7 @@ static const struct nfs4_minor_version_ops nfs_v4_0_minor_ops = {
> 	.minor_version = 0,
> 	.call_sync = _nfs4_call_sync,
> 	.validate_stateid = nfs4_validate_delegation_stateid,
> +	.find_root_sec = nfs4_find_root_sec,
> 	.reboot_recovery_ops = &nfs40_reboot_recovery_ops,
> 	.nograce_recovery_ops = &nfs40_nograce_recovery_ops,
> 	.state_renewal_ops = &nfs40_state_renewal_ops,
> @@ -5874,6 +5938,7 @@ static const struct nfs4_minor_version_ops nfs_v4_1_minor_ops = {
> 	.minor_version = 1,
> 	.call_sync = _nfs4_call_sync_session,
> 	.validate_stateid = nfs41_validate_delegation_stateid,
> +	.find_root_sec = nfs41_find_root_sec,
> 	.reboot_recovery_ops = &nfs41_reboot_recovery_ops,
> 	.nograce_recovery_ops = &nfs41_nograce_recovery_ops,
> 	.state_renewal_ops = &nfs41_state_renewal_ops,
> diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
> index ba952bd..00952b2 100644
> --- a/fs/nfs/nfs4xdr.c
> +++ b/fs/nfs/nfs4xdr.c
> @@ -338,6 +338,8 @@ static int nfs4_stat_to_errno(int);
> 				1 /* layoutupdate4 layout type */ + \
> 				1 /* NULL filelayout layoutupdate4 payload */)
> #define decode_layoutcommit_maxsz (op_decode_hdr_maxsz + 3)
> +#define encode_secinfo_no_name_maxsz (op_encode_hdr_maxsz + 4)
> +#define decode_secinfo_no_name_maxsz decode_secinfo_maxsz
> 
> #else /* CONFIG_NFS_V4_1 */
> #define encode_sequence_maxsz	0
> @@ -760,6 +762,12 @@ static int nfs4_stat_to_errno(int);
> 				decode_putfh_maxsz + \
> 				decode_layoutcommit_maxsz + \
> 				decode_getattr_maxsz)
> +#define NFS4_enc_secinfo_no_name_sz	(compound_encode_hdr_maxsz + \
> +					encode_putrootfh_maxsz +\
> +					encode_secinfo_no_name_maxsz)
> +#define NFS4_dec_secinfo_no_name_sz	(compound_decode_hdr_maxsz + \
> +					decode_putrootfh_maxsz + \
> +					decode_secinfo_no_name_maxsz)
> 
> 
> const u32 nfs41_maxwrite_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
> @@ -1890,6 +1898,20 @@ encode_layoutcommit(struct xdr_stream *xdr,
> 	hdr->replen += decode_layoutcommit_maxsz;
> 	return 0;
> }
> +
> +static int
> +encode_secinfo_no_name(struct xdr_stream *xdr,
> +		       const struct nfs41_secinfo_no_name_args *args,
> +		       struct compound_hdr *hdr)
> +{
> +	__be32 *p;
> +	p = reserve_space(xdr, 8);
> +	*p++ = cpu_to_be32(OP_SECINFO_NO_NAME);
> +	*p++ = cpu_to_be32(args->style);
> +	hdr->nops++;
> +	hdr->replen += decode_secinfo_no_name_maxsz;
> +	return 0;
> +}
> #endif /* CONFIG_NFS_V4_1 */
> 
> /*
> @@ -2723,6 +2745,25 @@ static int nfs4_xdr_enc_layoutcommit(struct rpc_rqst *req,
> 	encode_nops(&hdr);
> 	return 0;
> }
> +
> +/*
> + * Encode SECINFO_NO_NAME request
> + */
> +static int nfs4_xdr_enc_secinfo_no_name(struct rpc_rqst *req,
> +					struct xdr_stream *xdr,
> +					struct nfs41_secinfo_no_name_args *args)
> +{
> +	struct compound_hdr hdr = {
> +		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
> +	};
> +
> +	encode_compound_hdr(xdr, req, &hdr);
> +	encode_sequence(xdr, &args->seq_args, &hdr);
> +	encode_putrootfh(xdr, &hdr);
> +	encode_secinfo_no_name(xdr, args, &hdr);
> +	encode_nops(&hdr);
> +	return 0;
> +}
> #endif /* CONFIG_NFS_V4_1 */
> 
> static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
> @@ -6348,6 +6389,30 @@ static int nfs4_xdr_dec_layoutcommit(struct rpc_rqst *rqstp,
> out:
> 	return status;
> }
> +
> +/*
> + * Decode SECINFO_NO_NAME response
> + */
> +static int nfs4_xdr_dec_secinfo_no_name(struct rpc_rqst *rqstp,
> +					struct xdr_stream *xdr,
> +					struct nfs4_secinfo_res *res)
> +{
> +	struct compound_hdr hdr;
> +	int status;
> +
> +	status = decode_compound_hdr(xdr, &hdr);
> +	if (status)
> +		goto out;
> +	status = decode_sequence(xdr, &res->seq_res, rqstp);
> +	if (status)
> +		goto out;
> +	status = decode_putrootfh(xdr);
> +	if (status)
> +		goto out;
> +	status = decode_secinfo(xdr, res);
> +out:
> +	return status;
> +}
> #endif /* CONFIG_NFS_V4_1 */
> 
> /**
> @@ -6547,6 +6612,7 @@ struct rpc_procinfo	nfs4_procedures[] = {
> 	PROC(GETDEVICEINFO,	enc_getdeviceinfo,	dec_getdeviceinfo),
> 	PROC(LAYOUTGET,		enc_layoutget,		dec_layoutget),
> 	PROC(LAYOUTCOMMIT,	enc_layoutcommit,	dec_layoutcommit),
> +	PROC(SECINFO_NO_NAME,	enc_secinfo_no_name,	dec_secinfo_no_name),
> #endif /* CONFIG_NFS_V4_1 */
> };
> 
> diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
> index 178fafe..7668f25 100644
> --- a/include/linux/nfs4.h
> +++ b/include/linux/nfs4.h
> @@ -562,6 +562,7 @@ enum {
> 	NFSPROC4_CLNT_LAYOUTGET,
> 	NFSPROC4_CLNT_GETDEVICEINFO,
> 	NFSPROC4_CLNT_LAYOUTCOMMIT,
> +	NFSPROC4_CLNT_SECINFO_NO_NAME,
> };
> 
> /* nfs41 types */
> diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
> index 78b101e..a8123b7 100644
> --- a/include/linux/nfs_xdr.h
> +++ b/include/linux/nfs_xdr.h
> @@ -1060,6 +1060,14 @@ struct nfs41_reclaim_complete_args {
> struct nfs41_reclaim_complete_res {
> 	struct nfs4_sequence_res	seq_res;
> };
> +
> +#define SECINFO_STYLE_CURRENT_FH 0
> +#define SECINFO_STYLE_PARENT 1
> +struct nfs41_secinfo_no_name_args {
> +	int				style;
> +	struct nfs4_sequence_args	seq_args;
> +};
> +
> #endif /* CONFIG_NFS_V4_1 */
> 
> struct nfs_page;
> -- 
> 1.7.4.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
Chuck Lever
chuck[dot]lever[at]oracle[dot]com



--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux