aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/mount_clnt.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/mount_clnt.c')
-rw-r--r--fs/nfs/mount_clnt.c116
1 files changed, 116 insertions, 0 deletions
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
index 79b5954b8a1b..8429885bc729 100644
--- a/fs/nfs/mount_clnt.c
+++ b/fs/nfs/mount_clnt.c
@@ -29,6 +29,8 @@
29 * XDR data type sizes 29 * XDR data type sizes
30 */ 30 */
31#define encode_dirpath_sz (1 + XDR_QUADLEN(MNTPATHLEN)) 31#define encode_dirpath_sz (1 + XDR_QUADLEN(MNTPATHLEN))
32#define MNT_status_sz (1)
33#define MNT_fhs_status_sz (1)
32 34
33/* 35/*
34 * XDR argument and result sizes 36 * XDR argument and result sizes
@@ -61,6 +63,65 @@ enum {
61 63
62static struct rpc_program mnt_program; 64static struct rpc_program mnt_program;
63 65
66/*
67 * Defined by OpenGroup XNFS Version 3W, chapter 8
68 */
69enum mountstat {
70 MNT_OK = 0,
71 MNT_EPERM = 1,
72 MNT_ENOENT = 2,
73 MNT_EACCES = 13,
74 MNT_EINVAL = 22,
75};
76
77static struct {
78 u32 status;
79 int errno;
80} mnt_errtbl[] = {
81 { .status = MNT_OK, .errno = 0, },
82 { .status = MNT_EPERM, .errno = -EPERM, },
83 { .status = MNT_ENOENT, .errno = -ENOENT, },
84 { .status = MNT_EACCES, .errno = -EACCES, },
85 { .status = MNT_EINVAL, .errno = -EINVAL, },
86};
87
88/*
89 * Defined by RFC 1813, section 5.1.5
90 */
91enum mountstat3 {
92 MNT3_OK = 0, /* no error */
93 MNT3ERR_PERM = 1, /* Not owner */
94 MNT3ERR_NOENT = 2, /* No such file or directory */
95 MNT3ERR_IO = 5, /* I/O error */
96 MNT3ERR_ACCES = 13, /* Permission denied */
97 MNT3ERR_NOTDIR = 20, /* Not a directory */
98 MNT3ERR_INVAL = 22, /* Invalid argument */
99 MNT3ERR_NAMETOOLONG = 63, /* Filename too long */
100 MNT3ERR_NOTSUPP = 10004, /* Operation not supported */
101 MNT3ERR_SERVERFAULT = 10006, /* A failure on the server */
102};
103
104static struct {
105 u32 status;
106 int errno;
107} mnt3_errtbl[] = {
108 { .status = MNT3_OK, .errno = 0, },
109 { .status = MNT3ERR_PERM, .errno = -EPERM, },
110 { .status = MNT3ERR_NOENT, .errno = -ENOENT, },
111 { .status = MNT3ERR_IO, .errno = -EIO, },
112 { .status = MNT3ERR_ACCES, .errno = -EACCES, },
113 { .status = MNT3ERR_NOTDIR, .errno = -ENOTDIR, },
114 { .status = MNT3ERR_INVAL, .errno = -EINVAL, },
115 { .status = MNT3ERR_NAMETOOLONG, .errno = -ENAMETOOLONG, },
116 { .status = MNT3ERR_NOTSUPP, .errno = -ENOTSUPP, },
117 { .status = MNT3ERR_SERVERFAULT, .errno = -ESERVERFAULT, },
118};
119
120struct mountres {
121 int errno;
122 struct nfs_fh *fh;
123};
124
64struct mnt_fhstatus { 125struct mnt_fhstatus {
65 u32 status; 126 u32 status;
66 struct nfs_fh *fh; 127 struct nfs_fh *fh;
@@ -179,6 +240,61 @@ static int xdr_decode_fhstatus(struct rpc_rqst *req, __be32 *p,
179 return 0; 240 return 0;
180} 241}
181 242
243/*
244 * RFC 1094: "A non-zero status indicates some sort of error. In this
245 * case, the status is a UNIX error number." This can be problematic
246 * if the server and client use different errno values for the same
247 * error.
248 *
249 * However, the OpenGroup XNFS spec provides a simple mapping that is
250 * independent of local errno values on the server and the client.
251 */
252static int decode_status(struct xdr_stream *xdr, struct mountres *res)
253{
254 unsigned int i;
255 u32 status;
256 __be32 *p;
257
258 p = xdr_inline_decode(xdr, sizeof(status));
259 if (unlikely(p == NULL))
260 return -EIO;
261 status = ntohl(*p);
262
263 for (i = 0; i <= ARRAY_SIZE(mnt_errtbl); i++) {
264 if (mnt_errtbl[i].status == status) {
265 res->errno = mnt_errtbl[i].errno;
266 return 0;
267 }
268 }
269
270 dprintk("NFS: unrecognized MNT status code: %u\n", status);
271 res->errno = -EACCES;
272 return 0;
273}
274
275static int decode_fhs_status(struct xdr_stream *xdr, struct mountres *res)
276{
277 unsigned int i;
278 u32 status;
279 __be32 *p;
280
281 p = xdr_inline_decode(xdr, sizeof(status));
282 if (unlikely(p == NULL))
283 return -EIO;
284 status = ntohl(*p);
285
286 for (i = 0; i <= ARRAY_SIZE(mnt3_errtbl); i++) {
287 if (mnt3_errtbl[i].status == status) {
288 res->errno = mnt3_errtbl[i].errno;
289 return 0;
290 }
291 }
292
293 dprintk("NFS: unrecognized MNT3 status code: %u\n", status);
294 res->errno = -EACCES;
295 return 0;
296}
297
182static int xdr_decode_fhstatus3(struct rpc_rqst *req, __be32 *p, 298static int xdr_decode_fhstatus3(struct rpc_rqst *req, __be32 *p,
183 struct mnt_fhstatus *res) 299 struct mnt_fhstatus *res)
184{ 300{