Re: [PATCH 4/8] NFS: Add separate mountd status code decoders for each mountd version

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

 



On Fri, 2009-05-01 at 12:36 -0400, Chuck Lever wrote:
> Introduce data structures and xdr_stream-based decoding functions for
> unmarshalling mountd status codes properly.
> 
> Mountd version 3 uses specific standard error return codes that are
> not errno values and not NFS3ERR_ values.  These have a well-defined
> standard mapping to local errno values.  Introduce data structures
> and a decoder function that map these status codes to local errno
> values properly.  This is new functionality (but not used yet).
> 
> Version 1 mountd status values are defined by RFC 1094 as UNIX error
> values (errno values).  Errno values on heterogeneous systems do not
> necessarily match each other.  To avoid exposing possibly incorrect
> errno values to upper layers, the current XDR decoder converts all
> non-zero MNT version 1 status codes to -EACCES.
> 
> The OpenGroup XNFS standard provides a mapping similar to but smaller
> than the version 3 error codes.  Implement a decoder that uses the XNFS
> error codes, replacing the current decoder.
> 
> For both mountd protocol versions, map unrecognized errors to -EACCES.
> 
> Finally we introduce a replacement data structure for mnt_fhstatus
> at this time, which is used by the new XDR decoders.  In addition to
> documenting that the status value returned by the XDR decoders is
> always an errno, this new structure will be expanded in subsequent
> patches.
> 
> Signed-off-by: Chuck Lever <chuck.lever@xxxxxxxxxx>
> ---
> 
>  fs/nfs/mount_clnt.c |  134 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 134 insertions(+), 0 deletions(-)
> 
> diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
> index 7b81914..cdda067 100644
> --- a/fs/nfs/mount_clnt.c
> +++ b/fs/nfs/mount_clnt.c
> @@ -29,6 +29,8 @@
>   * XDR data type sizes
>   */
>  #define encode_dirpath_sz	XDR_QUADLEN(sizeof(u32) + MNTPATHLEN)
> +#define MNT_status_sz		XDR_QUADLEN(sizeof(u32))
> +#define MNT_fhs_status_sz	XDR_QUADLEN(sizeof(u32))

XDR_QUADLEN() applies to strings only. Please just use naked numbers
here. I've already fixed up the previous patch that did this.

>  
>  /*
>   * XDR argument and result sizes
> @@ -61,6 +63,83 @@ enum {
>  
>  static struct rpc_program	mnt_program;
>  
> +/*
> + * Defined by OpenGroup XNFS Version 3W, chapter 8
> + */
> +enum mountstat {
> +	MNT_OK			= 0,
> +	MNT_EPERM		= 1,
> +	MNT_ENOENT		= 2,
> +	MNT_EACCES		= 13,
> +	MNT_EINVAL		= 22,
> +};
> +
> +#define MNT_MAPERRNO(name) \
> +	{ \
> +		.status		= MNT_E##name, \
> +		.errno		= -E##name, \
> +	}

It would be nice to avoid this kind of macro. Please inline instead.

> +
> +static struct {
> +	u32 status;
> +	int errno;
> +} mnt_errtbl[] = {
> +	{
> +		.status		= MNT_OK,
> +		.errno		= 0,
> +	},
> +	MNT_MAPERRNO(PERM),
> +	MNT_MAPERRNO(NOENT),
> +	MNT_MAPERRNO(ACCES),
> +	MNT_MAPERRNO(INVAL),
> +};
> +
> +/*
> + * Defined by RFC 1813, section 5.1.5
> + */
> +enum mountstat3 {
> +	MNT3_OK			= 0,		/* no error */
> +	MNT3ERR_PERM		= 1,		/* Not owner */
> +	MNT3ERR_NOENT		= 2,		/* No such file or directory */
> +	MNT3ERR_IO		= 5,		/* I/O error */
> +	MNT3ERR_ACCES		= 13,		/* Permission denied */
> +	MNT3ERR_NOTDIR		= 20,		/* Not a directory */
> +	MNT3ERR_INVAL		= 22,		/* Invalid argument */
> +	MNT3ERR_NAMETOOLONG	= 63,		/* Filename too long */
> +	MNT3ERR_NOTSUPP		= 10004,	/* Operation not supported */
> +	MNT3ERR_SERVERFAULT	= 10006,	/* A failure on the server */
> +};
> +
> +#define MNT3_MAPERRNO(name) \
> +	{ \
> +		.status		= MNT3ERR_##name, \
> +		.errno		= -E##name, \
> +	}

See above

> +static struct {
> +	u32 status;
> +	int errno;
> +} mnt3_errtbl[] = {
> +	{
> +		.status		= MNT3_OK,
> +		.errno		= 0,
> +	},
> +	MNT3_MAPERRNO(PERM),
> +	MNT3_MAPERRNO(NOENT),
> +	MNT3_MAPERRNO(IO),
> +	MNT3_MAPERRNO(ACCES),
> +	MNT3_MAPERRNO(NOTDIR),
> +	MNT3_MAPERRNO(INVAL),
> +	MNT3_MAPERRNO(NAMETOOLONG),
> +	MNT3_MAPERRNO(NOTSUPP),
> +	MNT3_MAPERRNO(SERVERFAULT),
> +};
> +
> +struct mountres {
> +	int errno;
> +	struct nfs_fh *fh;
> +};
> +
>  struct mnt_fhstatus {
>  	u32 status;
>  	struct nfs_fh *fh;
> @@ -179,6 +258,61 @@ static int xdr_decode_fhstatus(struct rpc_rqst *req, __be32 *p,
>  	return 0;
>  }
>  
> +/*
> + * RFC 1094: "A non-zero status indicates some sort of error.  In this
> + * case, the status is a UNIX error number."  This can be problematic
> + * if the server and client use different errno values for the same
> + * error.
> + *
> + * However, the OpenGroup XNFS spec provides a simple mapping that is
> + * independent of local errno values on the server and the client.
> + */
> +static int decode_status(struct xdr_stream *xdr, struct mountres *res)
> +{
> +	unsigned int i;
> +	u32 status;
> +	__be32 *p;
> +
> +	p = xdr_inline_decode(xdr, sizeof(status));
> +	if (unlikely(p == NULL))
> +		return -EIO;
> +	status = ntohl(*p);
> +
> +	for (i = 0; i <= ARRAY_SIZE(mnt_errtbl); i++) {
> +		if (mnt_errtbl[i].status == status) {
> +			res->errno = mnt_errtbl[i].errno;
> +			return 0;
> +		}
> +	}
> +
> +	dprintk("NFS: unrecognized MNT status code: %u\n", status);
> +	res->errno = -EACCES;
> +	return 0;
> +}
> +
> +static int decode_fhs_status(struct xdr_stream *xdr, struct mountres *res)
> +{
> +	unsigned int i;
> +	u32 status;
> +	__be32 *p;
> +
> +	p = xdr_inline_decode(xdr, sizeof(status));
> +	if (unlikely(p == NULL))
> +		return -EIO;
> +	status = ntohl(*p);
> +
> +	for (i = 0; i <= ARRAY_SIZE(mnt3_errtbl); i++) {
> +		if (mnt3_errtbl[i].status == status) {
> +			res->errno = mnt3_errtbl[i].errno;
> +			return 0;
> +		}
> +	}
> +
> +	dprintk("NFS: unrecognized MNT3 status code: %u\n", status);
> +	res->errno = -EACCES;
> +	return 0;
> +}
> +
>  static int xdr_decode_fhstatus3(struct rpc_rqst *req, __be32 *p,
>  				struct mnt_fhstatus *res)
>  {
> 

-- 
Trond Myklebust
Linux NFS client maintainer

NetApp
Trond.Myklebust@xxxxxxxxxx
www.netapp.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