2012-05-10 20:47:25

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v2 1/3] NFS: Create an NFS v3 stat_to_errno()

From: Bryan Schumaker <[email protected]>

In theory, NFS v3 can have different error versions than NFS v2. v4 is
already using its own nfs4_stat_to_errno() to mapp error codes, so
rather than create something in the generic client for v2 and v3 to
share I instead give v3 its own function.

Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/internal.h | 1 -
fs/nfs/nfs2xdr.c | 3 +-
fs/nfs/nfs3xdr.c | 103 +++++++++++++++++++++++++++++++++++++++++++----------
3 files changed, 87 insertions(+), 20 deletions(-)

diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 1855e8f..4cf76e9 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -207,7 +207,6 @@ extern void nfs_pgheader_init(struct nfs_pageio_descriptor *desc,
void nfs_set_pgio_error(struct nfs_pgio_header *hdr, int error, loff_t pos);

/* nfs2xdr.c */
-extern int nfs_stat_to_errno(enum nfs_stat);
extern struct rpc_procinfo nfs_procedures[];
extern int nfs2_decode_dirent(struct xdr_stream *,
struct nfs_entry *, int);
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index c99008e..baf759b 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -61,6 +61,7 @@
#define NFS_readdirres_sz (1)
#define NFS_statfsres_sz (1+NFS_info_sz)

+static int nfs_stat_to_errno(enum nfs_stat);

/*
* While encoding arguments, set up the reply buffer in advance to
@@ -1111,7 +1112,7 @@ static const struct {
* Returns a local errno value, or -EIO if the NFS status code is
* not recognized. This function is used jointly by NFSv2 and NFSv3.
*/
-int nfs_stat_to_errno(enum nfs_stat status)
+static int nfs_stat_to_errno(enum nfs_stat status)
{
int i;

diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
index ee284c2..902de48 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -86,6 +86,8 @@
XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE))
#define ACL3_setaclres_sz (1+NFS3_post_op_attr_sz)

+static int nfs3_stat_to_errno(enum nfs_stat);
+
/*
* Map file type to S_IFMT bits
*/
@@ -1388,7 +1390,7 @@ static int nfs3_xdr_dec_getattr3res(struct rpc_rqst *req,
out:
return error;
out_default:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -1427,7 +1429,7 @@ static int nfs3_xdr_dec_setattr3res(struct rpc_rqst *req,
out:
return error;
out_status:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -1475,7 +1477,7 @@ out_default:
error = decode_post_op_attr(xdr, result->dir_attr);
if (unlikely(error))
goto out;
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -1516,7 +1518,7 @@ static int nfs3_xdr_dec_access3res(struct rpc_rqst *req,
out:
return error;
out_default:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -1557,7 +1559,7 @@ static int nfs3_xdr_dec_readlink3res(struct rpc_rqst *req,
out:
return error;
out_default:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -1639,7 +1641,7 @@ static int nfs3_xdr_dec_read3res(struct rpc_rqst *req, struct xdr_stream *xdr,
out:
return error;
out_status:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -1709,7 +1711,7 @@ static int nfs3_xdr_dec_write3res(struct rpc_rqst *req, struct xdr_stream *xdr,
out:
return error;
out_status:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -1773,7 +1775,7 @@ out_default:
error = decode_wcc_data(xdr, result->dir_attr);
if (unlikely(error))
goto out;
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -1812,7 +1814,7 @@ static int nfs3_xdr_dec_remove3res(struct rpc_rqst *req,
out:
return error;
out_status:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -1856,7 +1858,7 @@ static int nfs3_xdr_dec_rename3res(struct rpc_rqst *req,
out:
return error;
out_status:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -1899,7 +1901,7 @@ static int nfs3_xdr_dec_link3res(struct rpc_rqst *req, struct xdr_stream *xdr,
out:
return error;
out_status:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/**
@@ -2091,7 +2093,7 @@ out_default:
error = decode_post_op_attr(xdr, result->dir_attr);
if (unlikely(error))
goto out;
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -2159,7 +2161,7 @@ static int nfs3_xdr_dec_fsstat3res(struct rpc_rqst *req,
out:
return error;
out_status:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -2235,7 +2237,7 @@ static int nfs3_xdr_dec_fsinfo3res(struct rpc_rqst *req,
out:
return error;
out_status:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -2298,7 +2300,7 @@ static int nfs3_xdr_dec_pathconf3res(struct rpc_rqst *req,
out:
return error;
out_status:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -2339,7 +2341,7 @@ static int nfs3_xdr_dec_commit3res(struct rpc_rqst *req,
out:
return error;
out_status:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

#ifdef CONFIG_NFS_V3_ACL
@@ -2404,7 +2406,7 @@ static int nfs3_xdr_dec_getacl3res(struct rpc_rqst *req,
out:
return error;
out_default:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

static int nfs3_xdr_dec_setacl3res(struct rpc_rqst *req,
@@ -2423,11 +2425,76 @@ static int nfs3_xdr_dec_setacl3res(struct rpc_rqst *req,
out:
return error;
out_default:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

#endif /* CONFIG_NFS_V3_ACL */

+
+/*
+ * We need to translate between nfs status return values and
+ * the local errno values which may not be the same.
+ */
+static const struct {
+ int stat;
+ int errno;
+} nfs_errtbl[] = {
+ { NFS_OK, 0 },
+ { NFSERR_PERM, -EPERM },
+ { NFSERR_NOENT, -ENOENT },
+ { NFSERR_IO, -errno_NFSERR_IO},
+ { NFSERR_NXIO, -ENXIO },
+/* { NFSERR_EAGAIN, -EAGAIN }, */
+ { NFSERR_ACCES, -EACCES },
+ { NFSERR_EXIST, -EEXIST },
+ { NFSERR_XDEV, -EXDEV },
+ { NFSERR_NODEV, -ENODEV },
+ { NFSERR_NOTDIR, -ENOTDIR },
+ { NFSERR_ISDIR, -EISDIR },
+ { NFSERR_INVAL, -EINVAL },
+ { NFSERR_FBIG, -EFBIG },
+ { NFSERR_NOSPC, -ENOSPC },
+ { NFSERR_ROFS, -EROFS },
+ { NFSERR_MLINK, -EMLINK },
+ { NFSERR_NAMETOOLONG, -ENAMETOOLONG },
+ { NFSERR_NOTEMPTY, -ENOTEMPTY },
+ { NFSERR_DQUOT, -EDQUOT },
+ { NFSERR_STALE, -ESTALE },
+ { NFSERR_REMOTE, -EREMOTE },
+#ifdef EWFLUSH
+ { NFSERR_WFLUSH, -EWFLUSH },
+#endif
+ { NFSERR_BADHANDLE, -EBADHANDLE },
+ { NFSERR_NOT_SYNC, -ENOTSYNC },
+ { NFSERR_BAD_COOKIE, -EBADCOOKIE },
+ { NFSERR_NOTSUPP, -ENOTSUPP },
+ { NFSERR_TOOSMALL, -ETOOSMALL },
+ { NFSERR_SERVERFAULT, -EREMOTEIO },
+ { NFSERR_BADTYPE, -EBADTYPE },
+ { NFSERR_JUKEBOX, -EJUKEBOX },
+ { -1, -EIO }
+};
+
+/**
+ * nfs3_stat_to_errno - convert an NFS status code to a local errno
+ * @status: NFS status code to convert
+ *
+ * Returns a local errno value, or -EIO if the NFS status code is
+ * not recognized. This function is used jointly by NFSv2 and NFSv3.
+ */
+static int nfs3_stat_to_errno(enum nfs_stat status)
+{
+ int i;
+
+ for (i = 0; nfs_errtbl[i].stat != -1; i++) {
+ if (nfs_errtbl[i].stat == (int)status)
+ return nfs_errtbl[i].errno;
+ }
+ dprintk("NFS: Unrecognized nfs status value: %u\n", status);
+ return nfs_errtbl[i].errno;
+}
+
+
#define PROC(proc, argtype, restype, timer) \
[NFS3PROC_##proc] = { \
.p_proc = NFS3PROC_##proc, \
--
1.7.10.1



2012-05-11 12:40:49

by Anna Schumaker

[permalink] [raw]
Subject: Re: [PATCH v2 1/3] NFS: Create an NFS v3 stat_to_errno()

On 05/11/2012 04:12 AM, Lev Solomonov wrote:

> On Thu, May 10, 2012 at 11:47 PM, <[email protected]> wrote:
>> From: Bryan Schumaker <[email protected]>
>>
>> In theory, NFS v3 can have different error versions than NFS v2. v4 is
>> already using its own nfs4_stat_to_errno() to mapp error codes, so
>
> ^mapp^map ?


Good catch. Trond, should I resend the patch?


2012-05-11 22:20:24

by Myklebust, Trond

[permalink] [raw]
Subject: Re: [PATCH v2 1/3] NFS: Create an NFS v3 stat_to_errno()

Hi Peter,

I agree that it might indeed make sense to do that.

Cheers
Trond
--
Trond Myklebust
Linux NFS client maintainer

NetApp
[email protected]
http://www.netapp.com

On May 11, 2012, at 11:29 AM, Peter Staubach wrote:

> Hi.
>
> I'm wondering whether it makes sense to introduce a set of NFS3ERR_ defines for the NFSv3 error numbers? And remove the NFSERR_ error codes which aren't valid for NFSv2? And fix the NFSv2 error number to errno mapping to only include the NFSv2 valid error numbers?
>
> Thanx...
>
> ps
>
>
> -----Original Message-----
> From: [email protected] [mailto:[email protected]] On Behalf Of [email protected]
> Sent: Thursday, May 10, 2012 4:47 PM
> To: [email protected]
> Cc: [email protected]; Bryan Schumaker
> Subject: [PATCH v2 1/3] NFS: Create an NFS v3 stat_to_errno()
>
> From: Bryan Schumaker <[email protected]>
>
> In theory, NFS v3 can have different error versions than NFS v2. v4 is already using its own nfs4_stat_to_errno() to mapp error codes, so rather than create something in the generic client for v2 and v3 to share I instead give v3 its own function.
>
> Signed-off-by: Bryan Schumaker <[email protected]>
> ---
> fs/nfs/internal.h | 1 -
> fs/nfs/nfs2xdr.c | 3 +-
> fs/nfs/nfs3xdr.c | 103 +++++++++++++++++++++++++++++++++++++++++++----------
> 3 files changed, 87 insertions(+), 20 deletions(-)
>
> diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 1855e8f..4cf76e9 100644
> --- a/fs/nfs/internal.h
> +++ b/fs/nfs/internal.h
> @@ -207,7 +207,6 @@ extern void nfs_pgheader_init(struct nfs_pageio_descriptor *desc, void nfs_set_pgio_error(struct nfs_pgio_header *hdr, int error, loff_t pos);
>
> /* nfs2xdr.c */
> -extern int nfs_stat_to_errno(enum nfs_stat); extern struct rpc_procinfo nfs_procedures[]; extern int nfs2_decode_dirent(struct xdr_stream *,
> struct nfs_entry *, int);
> diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index c99008e..baf759b 100644
> --- a/fs/nfs/nfs2xdr.c
> +++ b/fs/nfs/nfs2xdr.c
> @@ -61,6 +61,7 @@
> #define NFS_readdirres_sz (1)
> #define NFS_statfsres_sz (1+NFS_info_sz)
>
> +static int nfs_stat_to_errno(enum nfs_stat);
>
> /*
> * While encoding arguments, set up the reply buffer in advance to @@ -1111,7 +1112,7 @@ static const struct {
> * Returns a local errno value, or -EIO if the NFS status code is
> * not recognized. This function is used jointly by NFSv2 and NFSv3.
> */
> -int nfs_stat_to_errno(enum nfs_stat status)
> +static int nfs_stat_to_errno(enum nfs_stat status)
> {
> int i;
>
> diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index ee284c2..902de48 100644
> --- a/fs/nfs/nfs3xdr.c
> +++ b/fs/nfs/nfs3xdr.c
> @@ -86,6 +86,8 @@
> XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE))
> #define ACL3_setaclres_sz (1+NFS3_post_op_attr_sz)
>
> +static int nfs3_stat_to_errno(enum nfs_stat);
> +
> /*
> * Map file type to S_IFMT bits
> */
> @@ -1388,7 +1390,7 @@ static int nfs3_xdr_dec_getattr3res(struct rpc_rqst *req,
> out:
> return error;
> out_default:
> - return nfs_stat_to_errno(status);
> + return nfs3_stat_to_errno(status);
> }
>
> /*
> @@ -1427,7 +1429,7 @@ static int nfs3_xdr_dec_setattr3res(struct rpc_rqst *req,
> out:
> return error;
> out_status:
> - return nfs_stat_to_errno(status);
> + return nfs3_stat_to_errno(status);
> }
>
> /*
> @@ -1475,7 +1477,7 @@ out_default:
> error = decode_post_op_attr(xdr, result->dir_attr);
> if (unlikely(error))
> goto out;
> - return nfs_stat_to_errno(status);
> + return nfs3_stat_to_errno(status);
> }
>
> /*
> @@ -1516,7 +1518,7 @@ static int nfs3_xdr_dec_access3res(struct rpc_rqst *req,
> out:
> return error;
> out_default:
> - return nfs_stat_to_errno(status);
> + return nfs3_stat_to_errno(status);
> }
>
> /*
> @@ -1557,7 +1559,7 @@ static int nfs3_xdr_dec_readlink3res(struct rpc_rqst *req,
> out:
> return error;
> out_default:
> - return nfs_stat_to_errno(status);
> + return nfs3_stat_to_errno(status);
> }
>
> /*
> @@ -1639,7 +1641,7 @@ static int nfs3_xdr_dec_read3res(struct rpc_rqst *req, struct xdr_stream *xdr,
> out:
> return error;
> out_status:
> - return nfs_stat_to_errno(status);
> + return nfs3_stat_to_errno(status);
> }
>
> /*
> @@ -1709,7 +1711,7 @@ static int nfs3_xdr_dec_write3res(struct rpc_rqst *req, struct xdr_stream *xdr,
> out:
> return error;
> out_status:
> - return nfs_stat_to_errno(status);
> + return nfs3_stat_to_errno(status);
> }
>
> /*
> @@ -1773,7 +1775,7 @@ out_default:
> error = decode_wcc_data(xdr, result->dir_attr);
> if (unlikely(error))
> goto out;
> - return nfs_stat_to_errno(status);
> + return nfs3_stat_to_errno(status);
> }
>
> /*
> @@ -1812,7 +1814,7 @@ static int nfs3_xdr_dec_remove3res(struct rpc_rqst *req,
> out:
> return error;
> out_status:
> - return nfs_stat_to_errno(status);
> + return nfs3_stat_to_errno(status);
> }
>
> /*
> @@ -1856,7 +1858,7 @@ static int nfs3_xdr_dec_rename3res(struct rpc_rqst *req,
> out:
> return error;
> out_status:
> - return nfs_stat_to_errno(status);
> + return nfs3_stat_to_errno(status);
> }
>
> /*
> @@ -1899,7 +1901,7 @@ static int nfs3_xdr_dec_link3res(struct rpc_rqst *req, struct xdr_stream *xdr,
> out:
> return error;
> out_status:
> - return nfs_stat_to_errno(status);
> + return nfs3_stat_to_errno(status);
> }
>
> /**
> @@ -2091,7 +2093,7 @@ out_default:
> error = decode_post_op_attr(xdr, result->dir_attr);
> if (unlikely(error))
> goto out;
> - return nfs_stat_to_errno(status);
> + return nfs3_stat_to_errno(status);
> }
>
> /*
> @@ -2159,7 +2161,7 @@ static int nfs3_xdr_dec_fsstat3res(struct rpc_rqst *req,
> out:
> return error;
> out_status:
> - return nfs_stat_to_errno(status);
> + return nfs3_stat_to_errno(status);
> }
>
> /*
> @@ -2235,7 +2237,7 @@ static int nfs3_xdr_dec_fsinfo3res(struct rpc_rqst *req,
> out:
> return error;
> out_status:
> - return nfs_stat_to_errno(status);
> + return nfs3_stat_to_errno(status);
> }
>
> /*
> @@ -2298,7 +2300,7 @@ static int nfs3_xdr_dec_pathconf3res(struct rpc_rqst *req,
> out:
> return error;
> out_status:
> - return nfs_stat_to_errno(status);
> + return nfs3_stat_to_errno(status);
> }
>
> /*
> @@ -2339,7 +2341,7 @@ static int nfs3_xdr_dec_commit3res(struct rpc_rqst *req,
> out:
> return error;
> out_status:
> - return nfs_stat_to_errno(status);
> + return nfs3_stat_to_errno(status);
> }
>
> #ifdef CONFIG_NFS_V3_ACL
> @@ -2404,7 +2406,7 @@ static int nfs3_xdr_dec_getacl3res(struct rpc_rqst *req,
> out:
> return error;
> out_default:
> - return nfs_stat_to_errno(status);
> + return nfs3_stat_to_errno(status);
> }
>
> static int nfs3_xdr_dec_setacl3res(struct rpc_rqst *req, @@ -2423,11 +2425,76 @@ static int nfs3_xdr_dec_setacl3res(struct rpc_rqst *req,
> out:
> return error;
> out_default:
> - return nfs_stat_to_errno(status);
> + return nfs3_stat_to_errno(status);
> }
>
> #endif /* CONFIG_NFS_V3_ACL */
>
> +
> +/*
> + * We need to translate between nfs status return values and
> + * the local errno values which may not be the same.
> + */
> +static const struct {
> + int stat;
> + int errno;
> +} nfs_errtbl[] = {
> + { NFS_OK, 0 },
> + { NFSERR_PERM, -EPERM },
> + { NFSERR_NOENT, -ENOENT },
> + { NFSERR_IO, -errno_NFSERR_IO},
> + { NFSERR_NXIO, -ENXIO },
> +/* { NFSERR_EAGAIN, -EAGAIN }, */
> + { NFSERR_ACCES, -EACCES },
> + { NFSERR_EXIST, -EEXIST },
> + { NFSERR_XDEV, -EXDEV },
> + { NFSERR_NODEV, -ENODEV },
> + { NFSERR_NOTDIR, -ENOTDIR },
> + { NFSERR_ISDIR, -EISDIR },
> + { NFSERR_INVAL, -EINVAL },
> + { NFSERR_FBIG, -EFBIG },
> + { NFSERR_NOSPC, -ENOSPC },
> + { NFSERR_ROFS, -EROFS },
> + { NFSERR_MLINK, -EMLINK },
> + { NFSERR_NAMETOOLONG, -ENAMETOOLONG },
> + { NFSERR_NOTEMPTY, -ENOTEMPTY },
> + { NFSERR_DQUOT, -EDQUOT },
> + { NFSERR_STALE, -ESTALE },
> + { NFSERR_REMOTE, -EREMOTE },
> +#ifdef EWFLUSH
> + { NFSERR_WFLUSH, -EWFLUSH },
> +#endif
> + { NFSERR_BADHANDLE, -EBADHANDLE },
> + { NFSERR_NOT_SYNC, -ENOTSYNC },
> + { NFSERR_BAD_COOKIE, -EBADCOOKIE },
> + { NFSERR_NOTSUPP, -ENOTSUPP },
> + { NFSERR_TOOSMALL, -ETOOSMALL },
> + { NFSERR_SERVERFAULT, -EREMOTEIO },
> + { NFSERR_BADTYPE, -EBADTYPE },
> + { NFSERR_JUKEBOX, -EJUKEBOX },
> + { -1, -EIO }
> +};
> +
> +/**
> + * nfs3_stat_to_errno - convert an NFS status code to a local errno
> + * @status: NFS status code to convert
> + *
> + * Returns a local errno value, or -EIO if the NFS status code is
> + * not recognized. This function is used jointly by NFSv2 and NFSv3.
> + */
> +static int nfs3_stat_to_errno(enum nfs_stat status) {
> + int i;
> +
> + for (i = 0; nfs_errtbl[i].stat != -1; i++) {
> + if (nfs_errtbl[i].stat == (int)status)
> + return nfs_errtbl[i].errno;
> + }
> + dprintk("NFS: Unrecognized nfs status value: %u\n", status);
> + return nfs_errtbl[i].errno;
> +}
> +
> +
> #define PROC(proc, argtype, restype, timer) \
> [NFS3PROC_##proc] = { \
> .p_proc = NFS3PROC_##proc, \
> --
> 1.7.10.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html


2012-05-11 16:10:34

by Anna Schumaker

[permalink] [raw]
Subject: Re: [PATCH v2 1/3] NFS: Create an NFS v3 stat_to_errno()

On 05/11/2012 10:32 AM, Myklebust, Trond wrote:

> Yes, please resend


Here is a new patch with a fixed commit message. Let me know if I should rename everything to "NFS3ERR_*"

- Bryan

>From 49585b06eee64b0695422afa759ae6c791eb8fe4 Mon Sep 17 00:00:00 2001
From: Bryan Schumaker <[email protected]>
Date: Mon, 30 Apr 2012 14:36:30 -0400
Subject: [PATCH 1/3] NFS: Create an NFS v3 stat_to_errno()

In theory, NFS v3 can have different error versions than NFS v2. v4 is
already using its own nfs4_stat_to_errno() to map error codes, so
rather than create something in the generic client for v2 and v3 to
share I instead give v3 its own function.

Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/internal.h | 1 -
fs/nfs/nfs2xdr.c | 3 +-
fs/nfs/nfs3xdr.c | 103 +++++++++++++++++++++++++++++++++++++++++++----------
3 files changed, 87 insertions(+), 20 deletions(-)

diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 1855e8f..4cf76e9 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -207,7 +207,6 @@ extern void nfs_pgheader_init(struct nfs_pageio_descriptor *desc,
void nfs_set_pgio_error(struct nfs_pgio_header *hdr, int error, loff_t pos);

/* nfs2xdr.c */
-extern int nfs_stat_to_errno(enum nfs_stat);
extern struct rpc_procinfo nfs_procedures[];
extern int nfs2_decode_dirent(struct xdr_stream *,
struct nfs_entry *, int);
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index c99008e..baf759b 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -61,6 +61,7 @@
#define NFS_readdirres_sz (1)
#define NFS_statfsres_sz (1+NFS_info_sz)

+static int nfs_stat_to_errno(enum nfs_stat);

/*
* While encoding arguments, set up the reply buffer in advance to
@@ -1111,7 +1112,7 @@ static const struct {
* Returns a local errno value, or -EIO if the NFS status code is
* not recognized. This function is used jointly by NFSv2 and NFSv3.
*/
-int nfs_stat_to_errno(enum nfs_stat status)
+static int nfs_stat_to_errno(enum nfs_stat status)
{
int i;

diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
index ee284c2..902de48 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -86,6 +86,8 @@
XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE))
#define ACL3_setaclres_sz (1+NFS3_post_op_attr_sz)

+static int nfs3_stat_to_errno(enum nfs_stat);
+
/*
* Map file type to S_IFMT bits
*/
@@ -1388,7 +1390,7 @@ static int nfs3_xdr_dec_getattr3res(struct rpc_rqst *req,
out:
return error;
out_default:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -1427,7 +1429,7 @@ static int nfs3_xdr_dec_setattr3res(struct rpc_rqst *req,
out:
return error;
out_status:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -1475,7 +1477,7 @@ out_default:
error = decode_post_op_attr(xdr, result->dir_attr);
if (unlikely(error))
goto out;
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -1516,7 +1518,7 @@ static int nfs3_xdr_dec_access3res(struct rpc_rqst *req,
out:
return error;
out_default:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -1557,7 +1559,7 @@ static int nfs3_xdr_dec_readlink3res(struct rpc_rqst *req,
out:
return error;
out_default:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -1639,7 +1641,7 @@ static int nfs3_xdr_dec_read3res(struct rpc_rqst *req, struct xdr_stream *xdr,
out:
return error;
out_status:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -1709,7 +1711,7 @@ static int nfs3_xdr_dec_write3res(struct rpc_rqst *req, struct xdr_stream *xdr,
out:
return error;
out_status:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -1773,7 +1775,7 @@ out_default:
error = decode_wcc_data(xdr, result->dir_attr);
if (unlikely(error))
goto out;
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -1812,7 +1814,7 @@ static int nfs3_xdr_dec_remove3res(struct rpc_rqst *req,
out:
return error;
out_status:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -1856,7 +1858,7 @@ static int nfs3_xdr_dec_rename3res(struct rpc_rqst *req,
out:
return error;
out_status:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -1899,7 +1901,7 @@ static int nfs3_xdr_dec_link3res(struct rpc_rqst *req, struct xdr_stream *xdr,
out:
return error;
out_status:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/**
@@ -2091,7 +2093,7 @@ out_default:
error = decode_post_op_attr(xdr, result->dir_attr);
if (unlikely(error))
goto out;
- return nfs_stat_to_errno(status);
out:
return error;
out_status:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -2235,7 +2237,7 @@ static int nfs3_xdr_dec_fsinfo3res(struct rpc_rqst *req,
out:
return error;
out_status:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -2298,7 +2300,7 @@ static int nfs3_xdr_dec_pathconf3res(struct rpc_rqst *req,
out:
return error;
out_status:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -2339,7 +2341,7 @@ static int nfs3_xdr_dec_commit3res(struct rpc_rqst *req,
out:
return error;
out_status:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

#ifdef CONFIG_NFS_V3_ACL
@@ -2404,7 +2406,7 @@ static int nfs3_xdr_dec_getacl3res(struct rpc_rqst *req,
out:
return error;
out_default:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

static int nfs3_xdr_dec_setacl3res(struct rpc_rqst *req,
@@ -2423,11 +2425,76 @@ static int nfs3_xdr_dec_setacl3res(struct rpc_rqst *req,
out:
return error;
out_default:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

#endif /* CONFIG_NFS_V3_ACL */

+
+/*
+ * We need to translate between nfs status return values and
+ * the local errno values which may not be the same.
+ */
+static const struct {
+ int stat;
+ int errno;
+} nfs_errtbl[] = {
+ { NFS_OK, 0 },
+ { NFSERR_PERM, -EPERM },
+ { NFSERR_NOENT, -ENOENT },
+ { NFSERR_IO, -errno_NFSERR_IO},
+ { NFSERR_NXIO, -ENXIO },
+/* { NFSERR_EAGAIN, -EAGAIN }, */
+ { NFSERR_ACCES, -EACCES },
+ { NFSERR_EXIST, -EEXIST },
+ { NFSERR_XDEV, -EXDEV },
+ { NFSERR_NODEV, -ENODEV },
+ { NFSERR_NOTDIR, -ENOTDIR },
+ { NFSERR_ISDIR, -EISDIR },
+ { NFSERR_INVAL, -EINVAL },
+ { NFSERR_FBIG, -EFBIG },
+ { NFSERR_NOSPC, -ENOSPC },
+ { NFSERR_ROFS, -EROFS },
+ { NFSERR_MLINK, -EMLINK },
+ { NFSERR_NAMETOOLONG, -ENAMETOOLONG },
+ { NFSERR_NOTEMPTY, -ENOTEMPTY },
+ { NFSERR_DQUOT, -EDQUOT },
+ { NFSERR_STALE, -ESTALE },
+ { NFSERR_REMOTE, -EREMOTE },
+#ifdef EWFLUSH
+ { NFSERR_WFLUSH, -EWFLUSH },
+#endif
+ { NFSERR_BADHANDLE, -EBADHANDLE },
+ { NFSERR_NOT_SYNC, -ENOTSYNC },
+ { NFSERR_BAD_COOKIE, -EBADCOOKIE },
+ { NFSERR_NOTSUPP, -ENOTSUPP },
+ { NFSERR_TOOSMALL, -ETOOSMALL },
+ { NFSERR_SERVERFAULT, -EREMOTEIO },
+ { NFSERR_BADTYPE, -EBADTYPE },
+ { NFSERR_JUKEBOX, -EJUKEBOX },
+ { -1, -EIO }
+};
+
+/**
+ * nfs3_stat_to_errno - convert an NFS status code to a local errno
+ * @status: NFS status code to convert
+ *
+ * Returns a local errno value, or -EIO if the NFS status code is
+ * not recognized. This function is used jointly by NFSv2 and NFSv3.
+ */
+static int nfs3_stat_to_errno(enum nfs_stat status)
+{
+ int i;
+
+ for (i = 0; nfs_errtbl[i].stat != -1; i++) {
+ if (nfs_errtbl[i].stat == (int)status)
+ return nfs_errtbl[i].errno;
+ }
+ dprintk("NFS: Unrecognized nfs status value: %u\n", status);
+ return nfs_errtbl[i].errno;
+}
+
+
#define PROC(proc, argtype, restype, timer) \
[NFS3PROC_##proc] = { \
.p_proc = NFS3PROC_##proc, \
--
1.7.10.1


>
> Cheers
> Trond
> --
> Trond Myklebust
> Linux NFS client maintainer
>
> NetApp
> [email protected]
> http://www.netapp.com
>
> On May 11, 2012, at 8:40 AM, Bryan Schumaker wrote:
>
>> On 05/11/2012 04:12 AM, Lev Solomonov wrote:
>>
>>> On Thu, May 10, 2012 at 11:47 PM, <[email protected]> wrote:
>>>> From: Bryan Schumaker <[email protected]>
>>>>
>>>> In theory, NFS v3 can have different error versions than NFS v2. v4 is
>>>> already using its own nfs4_stat_to_errno() to mapp error codes, so
>>>
>>> ^mapp^map ?
>>
>>
>> Good catch. Trond, should I resend the patch?
>>
>



2012-05-10 20:47:26

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v2 3/3] NFS: Turn v3 on by default

From: Bryan Schumaker <[email protected]>

Most users will use NFS v3 or possibly v4 so this makes it easier for
them.

Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/Kconfig | 1 +
1 file changed, 1 insertion(+)

diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
index 66b0f4c..f90f4f5 100644
--- a/fs/nfs/Kconfig
+++ b/fs/nfs/Kconfig
@@ -42,6 +42,7 @@ config NFS_V2
config NFS_V3
bool "NFS client support for NFS version 3"
depends on NFS_FS
+ default y
help
This option enables support for version 3 of the NFS protocol
(RFC 1813) in the kernel's NFS client.
--
1.7.10.1


2012-05-11 14:32:36

by Myklebust, Trond

[permalink] [raw]
Subject: Re: [PATCH v2 1/3] NFS: Create an NFS v3 stat_to_errno()

Yes, please resend

Cheers
Trond
--
Trond Myklebust
Linux NFS client maintainer

NetApp
[email protected]
http://www.netapp.com

On May 11, 2012, at 8:40 AM, Bryan Schumaker wrote:

> On 05/11/2012 04:12 AM, Lev Solomonov wrote:
>
>> On Thu, May 10, 2012 at 11:47 PM, <[email protected]> wrote:
>>> From: Bryan Schumaker <[email protected]>
>>>
>>> In theory, NFS v3 can have different error versions than NFS v2. v4 is
>>> already using its own nfs4_stat_to_errno() to mapp error codes, so
>>
>> ^mapp^map ?
>
>
> Good catch. Trond, should I resend the patch?
>


2012-05-11 15:33:32

by Peter Staubach

[permalink] [raw]
Subject: RE: [PATCH v2 1/3] NFS: Create an NFS v3 stat_to_errno()

Hi.

I'm wondering whether it makes sense to introduce a set of NFS3ERR_ defines for the NFSv3 error numbers? And remove the NFSERR_ error codes which aren't valid for NFSv2? And fix the NFSv2 error number to errno mapping to only include the NFSv2 valid error numbers?

Thanx...

ps


-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of [email protected]
Sent: Thursday, May 10, 2012 4:47 PM
To: [email protected]
Cc: [email protected]; Bryan Schumaker
Subject: [PATCH v2 1/3] NFS: Create an NFS v3 stat_to_errno()

From: Bryan Schumaker <[email protected]>

In theory, NFS v3 can have different error versions than NFS v2. v4 is already using its own nfs4_stat_to_errno() to mapp error codes, so rather than create something in the generic client for v2 and v3 to share I instead give v3 its own function.

Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/internal.h | 1 -
fs/nfs/nfs2xdr.c | 3 +-
fs/nfs/nfs3xdr.c | 103 +++++++++++++++++++++++++++++++++++++++++++----------
3 files changed, 87 insertions(+), 20 deletions(-)

diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 1855e8f..4cf76e9 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -207,7 +207,6 @@ extern void nfs_pgheader_init(struct nfs_pageio_descriptor *desc, void nfs_set_pgio_error(struct nfs_pgio_header *hdr, int error, loff_t pos);

/* nfs2xdr.c */
-extern int nfs_stat_to_errno(enum nfs_stat); extern struct rpc_procinfo nfs_procedures[]; extern int nfs2_decode_dirent(struct xdr_stream *,
struct nfs_entry *, int);
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index c99008e..baf759b 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -61,6 +61,7 @@
#define NFS_readdirres_sz (1)
#define NFS_statfsres_sz (1+NFS_info_sz)

+static int nfs_stat_to_errno(enum nfs_stat);

/*
* While encoding arguments, set up the reply buffer in advance to @@ -1111,7 +1112,7 @@ static const struct {
* Returns a local errno value, or -EIO if the NFS status code is
* not recognized. This function is used jointly by NFSv2 and NFSv3.
*/
-int nfs_stat_to_errno(enum nfs_stat status)
+static int nfs_stat_to_errno(enum nfs_stat status)
{
int i;

diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index ee284c2..902de48 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -86,6 +86,8 @@
XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE))
#define ACL3_setaclres_sz (1+NFS3_post_op_attr_sz)

+static int nfs3_stat_to_errno(enum nfs_stat);
+
/*
* Map file type to S_IFMT bits
*/
@@ -1388,7 +1390,7 @@ static int nfs3_xdr_dec_getattr3res(struct rpc_rqst *req,
out:
return error;
out_default:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -1427,7 +1429,7 @@ static int nfs3_xdr_dec_setattr3res(struct rpc_rqst *req,
out:
return error;
out_status:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -1475,7 +1477,7 @@ out_default:
error = decode_post_op_attr(xdr, result->dir_attr);
if (unlikely(error))
goto out;
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -1516,7 +1518,7 @@ static int nfs3_xdr_dec_access3res(struct rpc_rqst *req,
out:
return error;
out_default:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -1557,7 +1559,7 @@ static int nfs3_xdr_dec_readlink3res(struct rpc_rqst *req,
out:
return error;
out_default:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -1639,7 +1641,7 @@ static int nfs3_xdr_dec_read3res(struct rpc_rqst *req, struct xdr_stream *xdr,
out:
return error;
out_status:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -1709,7 +1711,7 @@ static int nfs3_xdr_dec_write3res(struct rpc_rqst *req, struct xdr_stream *xdr,
out:
return error;
out_status:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -1773,7 +1775,7 @@ out_default:
error = decode_wcc_data(xdr, result->dir_attr);
if (unlikely(error))
goto out;
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -1812,7 +1814,7 @@ static int nfs3_xdr_dec_remove3res(struct rpc_rqst *req,
out:
return error;
out_status:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -1856,7 +1858,7 @@ static int nfs3_xdr_dec_rename3res(struct rpc_rqst *req,
out:
return error;
out_status:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -1899,7 +1901,7 @@ static int nfs3_xdr_dec_link3res(struct rpc_rqst *req, struct xdr_stream *xdr,
out:
return error;
out_status:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/**
@@ -2091,7 +2093,7 @@ out_default:
error = decode_post_op_attr(xdr, result->dir_attr);
if (unlikely(error))
goto out;
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -2159,7 +2161,7 @@ static int nfs3_xdr_dec_fsstat3res(struct rpc_rqst *req,
out:
return error;
out_status:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -2235,7 +2237,7 @@ static int nfs3_xdr_dec_fsinfo3res(struct rpc_rqst *req,
out:
return error;
out_status:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -2298,7 +2300,7 @@ static int nfs3_xdr_dec_pathconf3res(struct rpc_rqst *req,
out:
return error;
out_status:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

/*
@@ -2339,7 +2341,7 @@ static int nfs3_xdr_dec_commit3res(struct rpc_rqst *req,
out:
return error;
out_status:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

#ifdef CONFIG_NFS_V3_ACL
@@ -2404,7 +2406,7 @@ static int nfs3_xdr_dec_getacl3res(struct rpc_rqst *req,
out:
return error;
out_default:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

static int nfs3_xdr_dec_setacl3res(struct rpc_rqst *req, @@ -2423,11 +2425,76 @@ static int nfs3_xdr_dec_setacl3res(struct rpc_rqst *req,
out:
return error;
out_default:
- return nfs_stat_to_errno(status);
+ return nfs3_stat_to_errno(status);
}

#endif /* CONFIG_NFS_V3_ACL */

+
+/*
+ * We need to translate between nfs status return values and
+ * the local errno values which may not be the same.
+ */
+static const struct {
+ int stat;
+ int errno;
+} nfs_errtbl[] = {
+ { NFS_OK, 0 },
+ { NFSERR_PERM, -EPERM },
+ { NFSERR_NOENT, -ENOENT },
+ { NFSERR_IO, -errno_NFSERR_IO},
+ { NFSERR_NXIO, -ENXIO },
+/* { NFSERR_EAGAIN, -EAGAIN }, */
+ { NFSERR_ACCES, -EACCES },
+ { NFSERR_EXIST, -EEXIST },
+ { NFSERR_XDEV, -EXDEV },
+ { NFSERR_NODEV, -ENODEV },
+ { NFSERR_NOTDIR, -ENOTDIR },
+ { NFSERR_ISDIR, -EISDIR },
+ { NFSERR_INVAL, -EINVAL },
+ { NFSERR_FBIG, -EFBIG },
+ { NFSERR_NOSPC, -ENOSPC },
+ { NFSERR_ROFS, -EROFS },
+ { NFSERR_MLINK, -EMLINK },
+ { NFSERR_NAMETOOLONG, -ENAMETOOLONG },
+ { NFSERR_NOTEMPTY, -ENOTEMPTY },
+ { NFSERR_DQUOT, -EDQUOT },
+ { NFSERR_STALE, -ESTALE },
+ { NFSERR_REMOTE, -EREMOTE },
+#ifdef EWFLUSH
+ { NFSERR_WFLUSH, -EWFLUSH },
+#endif
+ { NFSERR_BADHANDLE, -EBADHANDLE },
+ { NFSERR_NOT_SYNC, -ENOTSYNC },
+ { NFSERR_BAD_COOKIE, -EBADCOOKIE },
+ { NFSERR_NOTSUPP, -ENOTSUPP },
+ { NFSERR_TOOSMALL, -ETOOSMALL },
+ { NFSERR_SERVERFAULT, -EREMOTEIO },
+ { NFSERR_BADTYPE, -EBADTYPE },
+ { NFSERR_JUKEBOX, -EJUKEBOX },
+ { -1, -EIO }
+};
+
+/**
+ * nfs3_stat_to_errno - convert an NFS status code to a local errno
+ * @status: NFS status code to convert
+ *
+ * Returns a local errno value, or -EIO if the NFS status code is
+ * not recognized. This function is used jointly by NFSv2 and NFSv3.
+ */
+static int nfs3_stat_to_errno(enum nfs_stat status) {
+ int i;
+
+ for (i = 0; nfs_errtbl[i].stat != -1; i++) {
+ if (nfs_errtbl[i].stat == (int)status)
+ return nfs_errtbl[i].errno;
+ }
+ dprintk("NFS: Unrecognized nfs status value: %u\n", status);
+ return nfs_errtbl[i].errno;
+}
+
+
#define PROC(proc, argtype, restype, timer) \
[NFS3PROC_##proc] = { \
.p_proc = NFS3PROC_##proc, \
--
1.7.10.1

2012-05-11 14:32:53

by Myklebust, Trond

[permalink] [raw]
Subject: Re: [PATCH v2 1/3] NFS: Create an NFS v3 stat_to_errno()

Yes, please resend

Cheers
Trond
--
Trond Myklebust
Linux NFS client maintainer

NetApp
[email protected]
http://www.netapp.com

On May 11, 2012, at 8:40 AM, Bryan Schumaker wrote:

> On 05/11/2012 04:12 AM, Lev Solomonov wrote:
>
>> On Thu, May 10, 2012 at 11:47 PM, <[email protected]> wrote:
>>> From: Bryan Schumaker <[email protected]>
>>>
>>> In theory, NFS v3 can have different error versions than NFS v2. v4 is
>>> already using its own nfs4_stat_to_errno() to mapp error codes, so
>>
>> ^mapp^map ?
>
>
> Good catch. Trond, should I resend the patch?
>


2012-05-10 20:47:26

by Anna Schumaker

[permalink] [raw]
Subject: [PATCH v2 2/3] NFS: Make v2 configurable

From: Bryan Schumaker <[email protected]>

With this patch NFS v2 can be disabled during Kconfig. I default the
option to "y" to match the current behavior.

Signed-off-by: Bryan Schumaker <[email protected]>
---
fs/nfs/Kconfig | 10 ++++++++++
fs/nfs/Makefile | 5 +++--
fs/nfs/client.c | 16 ++++++++++++++--
3 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
index 2a0e6c5..66b0f4c 100644
--- a/fs/nfs/Kconfig
+++ b/fs/nfs/Kconfig
@@ -29,6 +29,16 @@ config NFS_FS

If unsure, say N.

+config NFS_V2
+ bool "NFS client support for NFS version 2"
+ depends on NFS_FS
+ default y
+ help
+ This option enables support for version 2 of the NFS protocol
+ (RFC 1094) in the kernel's NFS client.
+
+ If unsure, say Y.
+
config NFS_V3
bool "NFS client support for NFS version 3"
depends on NFS_FS
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
index b58613d..7ddd45d 100644
--- a/fs/nfs/Makefile
+++ b/fs/nfs/Makefile
@@ -4,11 +4,12 @@

obj-$(CONFIG_NFS_FS) += nfs.o

-nfs-y := client.o dir.o file.o getroot.o inode.o super.o nfs2xdr.o \
- direct.o pagelist.o proc.o read.o symlink.o unlink.o \
+nfs-y := client.o dir.o file.o getroot.o inode.o super.o \
+ direct.o pagelist.o read.o symlink.o unlink.o \
write.o namespace.o mount_clnt.o \
dns_resolve.o cache_lib.o
nfs-$(CONFIG_ROOT_NFS) += nfsroot.o
+nfs-$(CONFIG_NFS_V2) += proc.o nfs2xdr.o
nfs-$(CONFIG_NFS_V3) += nfs3proc.o nfs3xdr.o
nfs-$(CONFIG_NFS_V3_ACL) += nfs3acl.o
nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index a8f8de6..8f1c652 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -90,7 +90,9 @@ static bool nfs4_disable_idmapping = true;
* RPC cruft for NFS
*/
static const struct rpc_version *nfs_version[5] = {
+#ifdef CONFIG_NFS_V2
[2] = &nfs_version2,
+#endif
#ifdef CONFIG_NFS_V3
[3] = &nfs_version3,
#endif
@@ -847,7 +849,7 @@ static int nfs_init_server(struct nfs_server *server,
.hostname = data->nfs_server.hostname,
.addr = (const struct sockaddr *)&data->nfs_server.address,
.addrlen = data->nfs_server.addrlen,
- .rpc_ops = &nfs_v2_clientops,
+ .rpc_ops = NULL,
.proto = data->nfs_server.protocol,
.net = data->net,
};
@@ -857,10 +859,20 @@ static int nfs_init_server(struct nfs_server *server,

dprintk("--> nfs_init_server()\n");

+ switch (data->version) {
+#ifdef CONFIG_NFS_V2
+ case 2:
+ cl_init.rpc_ops = &nfs_v2_clientops;
+ break;
+#endif
#ifdef CONFIG_NFS_V3
- if (data->version == 3)
+ case 3:
cl_init.rpc_ops = &nfs_v3_clientops;
+ break;
#endif
+ default:
+ return -EPROTONOSUPPORT;
+ }

nfs_init_timeout_values(&timeparms, data->nfs_server.protocol,
data->timeo, data->retrans);
--
1.7.10.1