Blame view

fs/nfs/mount_clnt.c 11.7 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
  /*
19207231c   Chuck Lever   NFS: Clean up in-...
2
   * In-kernel MOUNT protocol client
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3
4
5
6
7
8
9
10
11
12
13
14
   *
   * Copyright (C) 1997, Olaf Kirch <okir@monad.swb.de>
   */
  
  #include <linux/types.h>
  #include <linux/socket.h>
  #include <linux/kernel.h>
  #include <linux/errno.h>
  #include <linux/uio.h>
  #include <linux/net.h>
  #include <linux/in.h>
  #include <linux/sunrpc/clnt.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
15
16
  #include <linux/sunrpc/sched.h>
  #include <linux/nfs_fs.h>
8491945f1   Steve Dickson   NFS: Client mount...
17
  #include "internal.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18
19
  
  #ifdef RPC_DEBUG
3ea97309e   Chuck Lever   NFS: Remake nfsro...
20
  # define NFSDBG_FACILITY	NFSDBG_MOUNT
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
21
  #endif
2ad780978   Chuck Lever   NFS: Clean up MNT...
22
  /*
29a1bd6bf   Chuck Lever   NFS: Use xdr_stre...
23
24
25
26
27
28
29
30
   * Defined by RFC 1094, section A.3; and RFC 1813, section 5.1.4
   */
  #define MNTPATHLEN		(1024)
  
  /*
   * XDR data type sizes
   */
  #define encode_dirpath_sz	(1 + XDR_QUADLEN(MNTPATHLEN))
fb1252957   Chuck Lever   NFS: Add separate...
31
32
  #define MNT_status_sz		(1)
  #define MNT_fhs_status_sz	(1)
4fdcd9966   Chuck Lever   NFS: add new file...
33
34
  #define MNT_fhandle_sz		XDR_QUADLEN(NFS2_FHSIZE)
  #define MNT_fhandle3_sz		(1 + XDR_QUADLEN(NFS3_FHSIZE))
a14017db2   Chuck Lever   NFS: add XDR deco...
35
  #define MNT_authflav3_sz	(1 + NFS_MAX_SECFLAVORS)
29a1bd6bf   Chuck Lever   NFS: Use xdr_stre...
36
37
38
39
40
  
  /*
   * XDR argument and result sizes
   */
  #define MNT_enc_dirpath_sz	encode_dirpath_sz
8e02f6b9a   Chuck Lever   NFS: Update MNT a...
41
42
43
  #define MNT_dec_mountres_sz	(MNT_status_sz + MNT_fhandle_sz)
  #define MNT_dec_mountres3_sz	(MNT_status_sz + MNT_fhandle_sz + \
  				 MNT_authflav3_sz)
29a1bd6bf   Chuck Lever   NFS: Use xdr_stre...
44
45
  
  /*
2ad780978   Chuck Lever   NFS: Clean up MNT...
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
   * Defined by RFC 1094, section A.5
   */
  enum {
  	MOUNTPROC_NULL		= 0,
  	MOUNTPROC_MNT		= 1,
  	MOUNTPROC_DUMP		= 2,
  	MOUNTPROC_UMNT		= 3,
  	MOUNTPROC_UMNTALL	= 4,
  	MOUNTPROC_EXPORT	= 5,
  };
  
  /*
   * Defined by RFC 1813, section 5.2
   */
  enum {
  	MOUNTPROC3_NULL		= 0,
  	MOUNTPROC3_MNT		= 1,
  	MOUNTPROC3_DUMP		= 2,
  	MOUNTPROC3_UMNT		= 3,
  	MOUNTPROC3_UMNTALL	= 4,
  	MOUNTPROC3_EXPORT	= 5,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
68
  static struct rpc_program	mnt_program;
fb1252957   Chuck Lever   NFS: Add separate...
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
  /*
   * 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,
  };
  
  static struct {
  	u32 status;
  	int errno;
  } mnt_errtbl[] = {
  	{ .status = MNT_OK,			.errno = 0,		},
  	{ .status = MNT_EPERM,			.errno = -EPERM,	},
  	{ .status = MNT_ENOENT,			.errno = -ENOENT,	},
  	{ .status = MNT_EACCES,			.errno = -EACCES,	},
  	{ .status = MNT_EINVAL,			.errno = -EINVAL,	},
  };
  
  /*
   * 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 */
  };
  
  static struct {
  	u32 status;
  	int errno;
  } mnt3_errtbl[] = {
  	{ .status = MNT3_OK,			.errno = 0,		},
  	{ .status = MNT3ERR_PERM,		.errno = -EPERM,	},
  	{ .status = MNT3ERR_NOENT,		.errno = -ENOENT,	},
  	{ .status = MNT3ERR_IO,			.errno = -EIO,		},
  	{ .status = MNT3ERR_ACCES,		.errno = -EACCES,	},
  	{ .status = MNT3ERR_NOTDIR,		.errno = -ENOTDIR,	},
  	{ .status = MNT3ERR_INVAL,		.errno = -EINVAL,	},
  	{ .status = MNT3ERR_NAMETOOLONG,	.errno = -ENAMETOOLONG,	},
  	{ .status = MNT3ERR_NOTSUPP,		.errno = -ENOTSUPP,	},
fdcb45777   Trond Myklebust   NFS: Fix the mapp...
120
  	{ .status = MNT3ERR_SERVERFAULT,	.errno = -EREMOTEIO,	},
fb1252957   Chuck Lever   NFS: Add separate...
121
122
123
124
125
  };
  
  struct mountres {
  	int errno;
  	struct nfs_fh *fh;
a14017db2   Chuck Lever   NFS: add XDR deco...
126
127
  	unsigned int *auth_count;
  	rpc_authflavor_t *auth_flavors;
fb1252957   Chuck Lever   NFS: Add separate...
128
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
129
  struct mnt_fhstatus {
19207231c   Chuck Lever   NFS: Clean up in-...
130
131
  	u32 status;
  	struct nfs_fh *fh;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
132
  };
3ea97309e   Chuck Lever   NFS: Remake nfsro...
133
134
  /**
   * nfs_mount - Obtain an NFS file handle for the given host and path
c5d120f8e   Chuck Lever   NFS: introduce nf...
135
   * @info: pointer to mount request arguments
3ea97309e   Chuck Lever   NFS: Remake nfsro...
136
137
   *
   * Uses default timeout parameters specified by underlying transport.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
138
   */
c5d120f8e   Chuck Lever   NFS: introduce nf...
139
  int nfs_mount(struct nfs_mount_request *info)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
140
  {
8e02f6b9a   Chuck Lever   NFS: Update MNT a...
141
142
143
144
  	struct mountres	result = {
  		.fh		= info->fh,
  		.auth_count	= info->auth_flav_len,
  		.auth_flavors	= info->auth_flavs,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
145
  	};
dead28da8   Chuck Lever   SUNRPC: eliminate...
146
  	struct rpc_message msg	= {
c5d120f8e   Chuck Lever   NFS: introduce nf...
147
  		.rpc_argp	= info->dirpath,
dead28da8   Chuck Lever   SUNRPC: eliminate...
148
149
  		.rpc_resp	= &result,
  	};
3ea97309e   Chuck Lever   NFS: Remake nfsro...
150
  	struct rpc_create_args args = {
c653ce3f0   Pavel Emelyanov   sunrpc: Add net t...
151
  		.net		= &init_net,
c5d120f8e   Chuck Lever   NFS: introduce nf...
152
153
154
155
  		.protocol	= info->protocol,
  		.address	= info->sap,
  		.addrsize	= info->salen,
  		.servername	= info->hostname,
3ea97309e   Chuck Lever   NFS: Remake nfsro...
156
  		.program	= &mnt_program,
c5d120f8e   Chuck Lever   NFS: introduce nf...
157
  		.version	= info->version,
3ea97309e   Chuck Lever   NFS: Remake nfsro...
158
  		.authflavor	= RPC_AUTH_UNIX,
3ea97309e   Chuck Lever   NFS: Remake nfsro...
159
160
  	};
  	struct rpc_clnt		*mnt_clnt;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
161
  	int			status;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
162

3ea97309e   Chuck Lever   NFS: Remake nfsro...
163
164
  	dprintk("NFS: sending MNT request for %s:%s
  ",
c5d120f8e   Chuck Lever   NFS: introduce nf...
165
166
  		(info->hostname ? info->hostname : "server"),
  			info->dirpath);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
167

50a737f86   Chuck Lever   NFS: "[no]resvpor...
168
169
  	if (info->noresvport)
  		args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
3ea97309e   Chuck Lever   NFS: Remake nfsro...
170
  	mnt_clnt = rpc_create(&args);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
171
  	if (IS_ERR(mnt_clnt))
013a8c1ab   Chuck Lever   NFS: Improve debu...
172
  		goto out_clnt_err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
173

c5d120f8e   Chuck Lever   NFS: introduce nf...
174
  	if (info->version == NFS_MNT3_VERSION)
dead28da8   Chuck Lever   SUNRPC: eliminate...
175
176
  		msg.rpc_proc = &mnt_clnt->cl_procinfo[MOUNTPROC3_MNT];
  	else
2ad780978   Chuck Lever   NFS: Clean up MNT...
177
  		msg.rpc_proc = &mnt_clnt->cl_procinfo[MOUNTPROC_MNT];
dead28da8   Chuck Lever   SUNRPC: eliminate...
178
179
  
  	status = rpc_call_sync(mnt_clnt, &msg, 0);
90c5755ff   Trond Myklebust   SUNRPC: Kill rpc_...
180
  	rpc_shutdown_client(mnt_clnt);
013a8c1ab   Chuck Lever   NFS: Improve debu...
181
182
183
  
  	if (status < 0)
  		goto out_call_err;
8e02f6b9a   Chuck Lever   NFS: Update MNT a...
184
  	if (result.errno != 0)
013a8c1ab   Chuck Lever   NFS: Improve debu...
185
186
187
188
189
190
191
192
193
194
195
  		goto out_mnt_err;
  
  	dprintk("NFS: MNT request succeeded
  ");
  	status = 0;
  
  out:
  	return status;
  
  out_clnt_err:
  	status = PTR_ERR(mnt_clnt);
8e02f6b9a   Chuck Lever   NFS: Update MNT a...
196
197
  	dprintk("NFS: failed to create MNT RPC client, status=%d
  ", status);
013a8c1ab   Chuck Lever   NFS: Improve debu...
198
199
200
  	goto out;
  
  out_call_err:
8e02f6b9a   Chuck Lever   NFS: Update MNT a...
201
202
  	dprintk("NFS: MNT request failed, status=%d
  ", status);
013a8c1ab   Chuck Lever   NFS: Improve debu...
203
204
205
  	goto out;
  
  out_mnt_err:
8e02f6b9a   Chuck Lever   NFS: Update MNT a...
206
207
208
  	dprintk("NFS: MNT server returned result %d
  ", result.errno);
  	status = result.errno;
013a8c1ab   Chuck Lever   NFS: Improve debu...
209
  	goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
210
  }
0b524123c   Chuck Lever   NFS: Add ability ...
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
  /**
   * nfs_umount - Notify a server that we have unmounted this export
   * @info: pointer to umount request arguments
   *
   * MOUNTPROC_UMNT is advisory, so we set a short timeout, and always
   * use UDP.
   */
  void nfs_umount(const struct nfs_mount_request *info)
  {
  	static const struct rpc_timeout nfs_umnt_timeout = {
  		.to_initval = 1 * HZ,
  		.to_maxval = 3 * HZ,
  		.to_retries = 2,
  	};
  	struct rpc_create_args args = {
c653ce3f0   Pavel Emelyanov   sunrpc: Add net t...
226
  		.net		= &init_net,
0b524123c   Chuck Lever   NFS: Add ability ...
227
228
229
230
231
232
233
234
235
236
  		.protocol	= IPPROTO_UDP,
  		.address	= info->sap,
  		.addrsize	= info->salen,
  		.timeout	= &nfs_umnt_timeout,
  		.servername	= info->hostname,
  		.program	= &mnt_program,
  		.version	= info->version,
  		.authflavor	= RPC_AUTH_UNIX,
  		.flags		= RPC_CLNT_CREATE_NOPING,
  	};
0b524123c   Chuck Lever   NFS: Add ability ...
237
238
  	struct rpc_message msg	= {
  		.rpc_argp	= info->dirpath,
0b524123c   Chuck Lever   NFS: Add ability ...
239
240
241
242
243
244
245
246
  	};
  	struct rpc_clnt *clnt;
  	int status;
  
  	if (info->noresvport)
  		args.flags |= RPC_CLNT_CREATE_NONPRIVPORT;
  
  	clnt = rpc_create(&args);
c8b031ebc   Tobias Klauser   NFS: Remove redun...
247
  	if (IS_ERR(clnt))
0b524123c   Chuck Lever   NFS: Add ability ...
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
  		goto out_clnt_err;
  
  	dprintk("NFS: sending UMNT request for %s:%s
  ",
  		(info->hostname ? info->hostname : "server"), info->dirpath);
  
  	if (info->version == NFS_MNT3_VERSION)
  		msg.rpc_proc = &clnt->cl_procinfo[MOUNTPROC3_UMNT];
  	else
  		msg.rpc_proc = &clnt->cl_procinfo[MOUNTPROC_UMNT];
  
  	status = rpc_call_sync(clnt, &msg, 0);
  	rpc_shutdown_client(clnt);
  
  	if (unlikely(status < 0))
  		goto out_call_err;
  
  	return;
  
  out_clnt_err:
  	dprintk("NFS: failed to create UMNT RPC client, status=%ld
  ",
  			PTR_ERR(clnt));
  	return;
  
  out_call_err:
  	dprintk("NFS: UMNT request failed, status=%d
  ", status);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
277
278
279
  /*
   * XDR encode/decode functions for MOUNT
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
280

98eb2b4f9   Chuck Lever   NFS: Avoid return...
281
  static void encode_mntdirpath(struct xdr_stream *xdr, const char *pathname)
29a1bd6bf   Chuck Lever   NFS: Use xdr_stre...
282
283
284
  {
  	const u32 pathname_len = strlen(pathname);
  	__be32 *p;
98eb2b4f9   Chuck Lever   NFS: Avoid return...
285
286
  	BUG_ON(pathname_len > MNTPATHLEN);
  	p = xdr_reserve_space(xdr, 4 + pathname_len);
29a1bd6bf   Chuck Lever   NFS: Use xdr_stre...
287
  	xdr_encode_opaque(p, pathname, pathname_len);
29a1bd6bf   Chuck Lever   NFS: Use xdr_stre...
288
  }
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
289
290
  static void mnt_xdr_enc_dirpath(struct rpc_rqst *req, struct xdr_stream *xdr,
  				const char *dirpath)
29a1bd6bf   Chuck Lever   NFS: Use xdr_stre...
291
  {
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
292
  	encode_mntdirpath(xdr, dirpath);
29a1bd6bf   Chuck Lever   NFS: Use xdr_stre...
293
  }
fb1252957   Chuck Lever   NFS: Add separate...
294
295
296
297
298
299
300
301
302
303
304
305
306
307
  /*
   * 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;
98eb2b4f9   Chuck Lever   NFS: Avoid return...
308
  	p = xdr_inline_decode(xdr, 4);
fb1252957   Chuck Lever   NFS: Add separate...
309
310
  	if (unlikely(p == NULL))
  		return -EIO;
98eb2b4f9   Chuck Lever   NFS: Avoid return...
311
  	status = be32_to_cpup(p);
fb1252957   Chuck Lever   NFS: Add separate...
312

dd8ac1da4   Roel Kluin   nfs: Keep index w...
313
  	for (i = 0; i < ARRAY_SIZE(mnt_errtbl); i++) {
fb1252957   Chuck Lever   NFS: Add separate...
314
315
316
317
318
319
320
321
322
323
324
  		if (mnt_errtbl[i].status == status) {
  			res->errno = mnt_errtbl[i].errno;
  			return 0;
  		}
  	}
  
  	dprintk("NFS: unrecognized MNT status code: %u
  ", status);
  	res->errno = -EACCES;
  	return 0;
  }
4fdcd9966   Chuck Lever   NFS: add new file...
325
326
327
328
329
330
331
332
333
334
335
336
337
  static int decode_fhandle(struct xdr_stream *xdr, struct mountres *res)
  {
  	struct nfs_fh *fh = res->fh;
  	__be32 *p;
  
  	p = xdr_inline_decode(xdr, NFS2_FHSIZE);
  	if (unlikely(p == NULL))
  		return -EIO;
  
  	fh->size = NFS2_FHSIZE;
  	memcpy(fh->data, p, NFS2_FHSIZE);
  	return 0;
  }
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
338
339
340
  static int mnt_xdr_dec_mountres(struct rpc_rqst *req,
  				struct xdr_stream *xdr,
  				struct mountres *res)
8e02f6b9a   Chuck Lever   NFS: Update MNT a...
341
  {
8e02f6b9a   Chuck Lever   NFS: Update MNT a...
342
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
343
  	status = decode_status(xdr, res);
8e02f6b9a   Chuck Lever   NFS: Update MNT a...
344
345
  	if (unlikely(status != 0 || res->errno != 0))
  		return status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
346
  	return decode_fhandle(xdr, res);
8e02f6b9a   Chuck Lever   NFS: Update MNT a...
347
  }
fb1252957   Chuck Lever   NFS: Add separate...
348
349
350
351
352
  static int decode_fhs_status(struct xdr_stream *xdr, struct mountres *res)
  {
  	unsigned int i;
  	u32 status;
  	__be32 *p;
98eb2b4f9   Chuck Lever   NFS: Avoid return...
353
  	p = xdr_inline_decode(xdr, 4);
fb1252957   Chuck Lever   NFS: Add separate...
354
355
  	if (unlikely(p == NULL))
  		return -EIO;
98eb2b4f9   Chuck Lever   NFS: Avoid return...
356
  	status = be32_to_cpup(p);
fb1252957   Chuck Lever   NFS: Add separate...
357

dd8ac1da4   Roel Kluin   nfs: Keep index w...
358
  	for (i = 0; i < ARRAY_SIZE(mnt3_errtbl); i++) {
fb1252957   Chuck Lever   NFS: Add separate...
359
360
361
362
363
364
365
366
367
368
369
  		if (mnt3_errtbl[i].status == status) {
  			res->errno = mnt3_errtbl[i].errno;
  			return 0;
  		}
  	}
  
  	dprintk("NFS: unrecognized MNT3 status code: %u
  ", status);
  	res->errno = -EACCES;
  	return 0;
  }
4fdcd9966   Chuck Lever   NFS: add new file...
370
371
372
373
374
  static int decode_fhandle3(struct xdr_stream *xdr, struct mountres *res)
  {
  	struct nfs_fh *fh = res->fh;
  	u32 size;
  	__be32 *p;
98eb2b4f9   Chuck Lever   NFS: Avoid return...
375
  	p = xdr_inline_decode(xdr, 4);
4fdcd9966   Chuck Lever   NFS: add new file...
376
377
  	if (unlikely(p == NULL))
  		return -EIO;
98eb2b4f9   Chuck Lever   NFS: Avoid return...
378
  	size = be32_to_cpup(p);
4fdcd9966   Chuck Lever   NFS: add new file...
379
380
381
382
383
384
385
386
387
388
389
  	if (size > NFS3_FHSIZE || size == 0)
  		return -EIO;
  
  	p = xdr_inline_decode(xdr, size);
  	if (unlikely(p == NULL))
  		return -EIO;
  
  	fh->size = size;
  	memcpy(fh->data, p, size);
  	return 0;
  }
a14017db2   Chuck Lever   NFS: add XDR deco...
390
391
392
393
394
395
396
397
398
  static int decode_auth_flavors(struct xdr_stream *xdr, struct mountres *res)
  {
  	rpc_authflavor_t *flavors = res->auth_flavors;
  	unsigned int *count = res->auth_count;
  	u32 entries, i;
  	__be32 *p;
  
  	if (*count == 0)
  		return 0;
98eb2b4f9   Chuck Lever   NFS: Avoid return...
399
  	p = xdr_inline_decode(xdr, 4);
a14017db2   Chuck Lever   NFS: add XDR deco...
400
401
  	if (unlikely(p == NULL))
  		return -EIO;
98eb2b4f9   Chuck Lever   NFS: Avoid return...
402
  	entries = be32_to_cpup(p);
a14017db2   Chuck Lever   NFS: add XDR deco...
403
404
405
406
  	dprintk("NFS: received %u auth flavors
  ", entries);
  	if (entries > NFS_MAX_SECFLAVORS)
  		entries = NFS_MAX_SECFLAVORS;
98eb2b4f9   Chuck Lever   NFS: Avoid return...
407
  	p = xdr_inline_decode(xdr, 4 * entries);
a14017db2   Chuck Lever   NFS: add XDR deco...
408
409
410
411
412
413
414
  	if (unlikely(p == NULL))
  		return -EIO;
  
  	if (entries > *count)
  		entries = *count;
  
  	for (i = 0; i < entries; i++) {
98eb2b4f9   Chuck Lever   NFS: Avoid return...
415
  		flavors[i] = be32_to_cpup(p++);
ed58b2917   Chuck Lever   NFS: Remove \t fr...
416
417
  		dprintk("NFS:   auth flavor[%u]: %d
  ", i, flavors[i]);
a14017db2   Chuck Lever   NFS: add XDR deco...
418
419
420
421
422
  	}
  	*count = i;
  
  	return 0;
  }
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
423
424
425
  static int mnt_xdr_dec_mountres3(struct rpc_rqst *req,
  				 struct xdr_stream *xdr,
  				 struct mountres *res)
8e02f6b9a   Chuck Lever   NFS: Update MNT a...
426
  {
8e02f6b9a   Chuck Lever   NFS: Update MNT a...
427
  	int status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
428
  	status = decode_fhs_status(xdr, res);
8e02f6b9a   Chuck Lever   NFS: Update MNT a...
429
430
  	if (unlikely(status != 0 || res->errno != 0))
  		return status;
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
431
  	status = decode_fhandle3(xdr, res);
8e02f6b9a   Chuck Lever   NFS: Update MNT a...
432
433
434
435
  	if (unlikely(status != 0)) {
  		res->errno = -EBADHANDLE;
  		return 0;
  	}
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
436
  	return decode_auth_flavors(xdr, res);
8e02f6b9a   Chuck Lever   NFS: Update MNT a...
437
  }
19207231c   Chuck Lever   NFS: Clean up in-...
438
  static struct rpc_procinfo mnt_procedures[] = {
2ad780978   Chuck Lever   NFS: Clean up MNT...
439
440
  	[MOUNTPROC_MNT] = {
  		.p_proc		= MOUNTPROC_MNT,
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
441
  		.p_encode	= (kxdreproc_t)mnt_xdr_enc_dirpath,
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
442
  		.p_decode	= (kxdrdproc_t)mnt_xdr_dec_mountres,
29a1bd6bf   Chuck Lever   NFS: Use xdr_stre...
443
  		.p_arglen	= MNT_enc_dirpath_sz,
8e02f6b9a   Chuck Lever   NFS: Update MNT a...
444
  		.p_replen	= MNT_dec_mountres_sz,
2ad780978   Chuck Lever   NFS: Clean up MNT...
445
  		.p_statidx	= MOUNTPROC_MNT,
19207231c   Chuck Lever   NFS: Clean up in-...
446
  		.p_name		= "MOUNT",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
447
  	},
0b524123c   Chuck Lever   NFS: Add ability ...
448
449
  	[MOUNTPROC_UMNT] = {
  		.p_proc		= MOUNTPROC_UMNT,
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
450
  		.p_encode	= (kxdreproc_t)mnt_xdr_enc_dirpath,
0b524123c   Chuck Lever   NFS: Add ability ...
451
452
453
454
  		.p_arglen	= MNT_enc_dirpath_sz,
  		.p_statidx	= MOUNTPROC_UMNT,
  		.p_name		= "UMOUNT",
  	},
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
455
456
457
  };
  
  static struct rpc_procinfo mnt3_procedures[] = {
19207231c   Chuck Lever   NFS: Clean up in-...
458
459
  	[MOUNTPROC3_MNT] = {
  		.p_proc		= MOUNTPROC3_MNT,
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
460
  		.p_encode	= (kxdreproc_t)mnt_xdr_enc_dirpath,
bf2695516   Chuck Lever   SUNRPC: New xdr_s...
461
  		.p_decode	= (kxdrdproc_t)mnt_xdr_dec_mountres3,
29a1bd6bf   Chuck Lever   NFS: Use xdr_stre...
462
  		.p_arglen	= MNT_enc_dirpath_sz,
8e02f6b9a   Chuck Lever   NFS: Update MNT a...
463
  		.p_replen	= MNT_dec_mountres3_sz,
19207231c   Chuck Lever   NFS: Clean up in-...
464
465
  		.p_statidx	= MOUNTPROC3_MNT,
  		.p_name		= "MOUNT",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
466
  	},
0b524123c   Chuck Lever   NFS: Add ability ...
467
468
  	[MOUNTPROC3_UMNT] = {
  		.p_proc		= MOUNTPROC3_UMNT,
9f06c719f   Chuck Lever   SUNRPC: New xdr_s...
469
  		.p_encode	= (kxdreproc_t)mnt_xdr_enc_dirpath,
0b524123c   Chuck Lever   NFS: Add ability ...
470
471
472
473
  		.p_arglen	= MNT_enc_dirpath_sz,
  		.p_statidx	= MOUNTPROC3_UMNT,
  		.p_name		= "UMOUNT",
  	},
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
474
  };
19207231c   Chuck Lever   NFS: Clean up in-...
475
476
  static struct rpc_version mnt_version1 = {
  	.number		= 1,
5b362ac37   Chuck Lever   NFS: Fix panic af...
477
  	.nrprocs	= ARRAY_SIZE(mnt_procedures),
19207231c   Chuck Lever   NFS: Clean up in-...
478
  	.procs		= mnt_procedures,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
479
  };
19207231c   Chuck Lever   NFS: Clean up in-...
480
481
  static struct rpc_version mnt_version3 = {
  	.number		= 3,
5b362ac37   Chuck Lever   NFS: Fix panic af...
482
  	.nrprocs	= ARRAY_SIZE(mnt3_procedures),
19207231c   Chuck Lever   NFS: Clean up in-...
483
  	.procs		= mnt3_procedures,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
484
  };
19207231c   Chuck Lever   NFS: Clean up in-...
485
  static struct rpc_version *mnt_version[] = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
486
487
488
489
490
  	NULL,
  	&mnt_version1,
  	NULL,
  	&mnt_version3,
  };
19207231c   Chuck Lever   NFS: Clean up in-...
491
  static struct rpc_stat mnt_stats;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
492

19207231c   Chuck Lever   NFS: Clean up in-...
493
  static struct rpc_program mnt_program = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
494
495
  	.name		= "mount",
  	.number		= NFS_MNT_PROGRAM,
e8c96f8c2   Tobias Klauser   [PATCH] fs: Use A...
496
  	.nrvers		= ARRAY_SIZE(mnt_version),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
497
498
499
  	.version	= mnt_version,
  	.stats		= &mnt_stats,
  };