1/*
2 *  linux/fs/nfs/proc.c
3 *
4 *  Copyright (C) 1992, 1993, 1994  Rick Sladkey
5 *
6 *  OS-independent nfs remote procedure call functions
7 *
8 *  Tuned by Alan Cox <A.Cox@swansea.ac.uk> for >3K buffers
9 *  so at last we can have decent(ish) throughput off a
10 *  Sun server.
11 *
12 *  Coding optimized and cleaned up by Florian La Roche.
13 *  Note: Error returns are optimized for NFS_OK, which isn't translated via
14 *  nfs_stat_to_errno(), but happens to be already the right return code.
15 *
16 *  Also, the code currently doesn't check the size of the packet, when
17 *  it decodes the packet.
18 *
19 *  Feel free to fix it and mail me the diffs if it worries you.
20 *
21 *  Completely rewritten to support the new RPC call interface;
22 *  rewrote and moved the entire XDR stuff to xdr.c
23 *  --Olaf Kirch June 1996
24 *
25 *  The code below initializes all auto variables explicitly, otherwise
26 *  it will fail to work as a module (gcc generates a memset call for an
27 *  incomplete struct).
28 */
29
30#include <linux/types.h>
31#include <linux/param.h>
32#include <linux/time.h>
33#include <linux/mm.h>
34#include <linux/errno.h>
35#include <linux/string.h>
36#include <linux/in.h>
37#include <linux/pagemap.h>
38#include <linux/sunrpc/clnt.h>
39#include <linux/nfs.h>
40#include <linux/nfs2.h>
41#include <linux/nfs_fs.h>
42#include <linux/nfs_page.h>
43#include <linux/lockd/bind.h>
44#include "internal.h"
45
46#define NFSDBG_FACILITY		NFSDBG_PROC
47
48/*
49 * wrapper to handle the -EKEYEXPIRED error message. This should generally
50 * only happen if using krb5 auth and a user's TGT expires. NFSv2 doesn't
51 * support the NFSERR_JUKEBOX error code, but we handle this situation in the
52 * same way that we handle that error with NFSv3.
53 */
54static int
55nfs_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
56{
57	int res;
58	do {
59		res = rpc_call_sync(clnt, msg, flags);
60		if (res != -EKEYEXPIRED)
61			break;
62		schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME);
63		res = -ERESTARTSYS;
64	} while (!fatal_signal_pending(current));
65	return res;
66}
67
68#define rpc_call_sync(clnt, msg, flags)	nfs_rpc_wrapper(clnt, msg, flags)
69
70static int
71nfs_async_handle_expired_key(struct rpc_task *task)
72{
73	if (task->tk_status != -EKEYEXPIRED)
74		return 0;
75	task->tk_status = 0;
76	rpc_restart_call(task);
77	rpc_delay(task, NFS_JUKEBOX_RETRY_TIME);
78	return 1;
79}
80
81/*
82 * Bare-bones access to getattr: this is for nfs_read_super.
83 */
84static int
85nfs_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
86		  struct nfs_fsinfo *info)
87{
88	struct nfs_fattr *fattr = info->fattr;
89	struct nfs2_fsstat fsinfo;
90	struct rpc_message msg = {
91		.rpc_proc	= &nfs_procedures[NFSPROC_GETATTR],
92		.rpc_argp	= fhandle,
93		.rpc_resp	= fattr,
94	};
95	int status;
96
97	dprintk("%s: call getattr\n", __func__);
98	nfs_fattr_init(fattr);
99	status = rpc_call_sync(server->client, &msg, 0);
100	/* Retry with default authentication if different */
101	if (status && server->nfs_client->cl_rpcclient != server->client)
102		status = rpc_call_sync(server->nfs_client->cl_rpcclient, &msg, 0);
103	dprintk("%s: reply getattr: %d\n", __func__, status);
104	if (status)
105		return status;
106	dprintk("%s: call statfs\n", __func__);
107	msg.rpc_proc = &nfs_procedures[NFSPROC_STATFS];
108	msg.rpc_resp = &fsinfo;
109	status = rpc_call_sync(server->client, &msg, 0);
110	/* Retry with default authentication if different */
111	if (status && server->nfs_client->cl_rpcclient != server->client)
112		status = rpc_call_sync(server->nfs_client->cl_rpcclient, &msg, 0);
113	dprintk("%s: reply statfs: %d\n", __func__, status);
114	if (status)
115		return status;
116	info->rtmax  = NFS_MAXDATA;
117	info->rtpref = fsinfo.tsize;
118	info->rtmult = fsinfo.bsize;
119	info->wtmax  = NFS_MAXDATA;
120	info->wtpref = fsinfo.tsize;
121	info->wtmult = fsinfo.bsize;
122	info->dtpref = fsinfo.tsize;
123	info->maxfilesize = 0x7FFFFFFF;
124	info->lease_time = 0;
125	return 0;
126}
127
128/*
129 * One function for each procedure in the NFS protocol.
130 */
131static int
132nfs_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
133		struct nfs_fattr *fattr)
134{
135	struct rpc_message msg = {
136		.rpc_proc	= &nfs_procedures[NFSPROC_GETATTR],
137		.rpc_argp	= fhandle,
138		.rpc_resp	= fattr,
139	};
140	int	status;
141
142	dprintk("NFS call  getattr\n");
143	nfs_fattr_init(fattr);
144	status = rpc_call_sync(server->client, &msg, 0);
145	dprintk("NFS reply getattr: %d\n", status);
146	return status;
147}
148
149static int
150nfs_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
151		 struct iattr *sattr)
152{
153	struct inode *inode = dentry->d_inode;
154	struct nfs_sattrargs	arg = {
155		.fh	= NFS_FH(inode),
156		.sattr	= sattr
157	};
158	struct rpc_message msg = {
159		.rpc_proc	= &nfs_procedures[NFSPROC_SETATTR],
160		.rpc_argp	= &arg,
161		.rpc_resp	= fattr,
162	};
163	int	status;
164
165	/* Mask out the non-modebit related stuff from attr->ia_mode */
166	sattr->ia_mode &= S_IALLUGO;
167
168	dprintk("NFS call  setattr\n");
169	if (sattr->ia_valid & ATTR_FILE)
170		msg.rpc_cred = nfs_file_cred(sattr->ia_file);
171	nfs_fattr_init(fattr);
172	status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
173	if (status == 0)
174		nfs_setattr_update_inode(inode, sattr);
175	dprintk("NFS reply setattr: %d\n", status);
176	return status;
177}
178
179static int
180nfs_proc_lookup(struct inode *dir, struct qstr *name,
181		struct nfs_fh *fhandle, struct nfs_fattr *fattr)
182{
183	struct nfs_diropargs	arg = {
184		.fh		= NFS_FH(dir),
185		.name		= name->name,
186		.len		= name->len
187	};
188	struct nfs_diropok	res = {
189		.fh		= fhandle,
190		.fattr		= fattr
191	};
192	struct rpc_message msg = {
193		.rpc_proc	= &nfs_procedures[NFSPROC_LOOKUP],
194		.rpc_argp	= &arg,
195		.rpc_resp	= &res,
196	};
197	int			status;
198
199	dprintk("NFS call  lookup %s\n", name->name);
200	nfs_fattr_init(fattr);
201	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
202	dprintk("NFS reply lookup: %d\n", status);
203	return status;
204}
205
206static int nfs_proc_readlink(struct inode *inode, struct page *page,
207		unsigned int pgbase, unsigned int pglen)
208{
209	struct nfs_readlinkargs	args = {
210		.fh		= NFS_FH(inode),
211		.pgbase		= pgbase,
212		.pglen		= pglen,
213		.pages		= &page
214	};
215	struct rpc_message msg = {
216		.rpc_proc	= &nfs_procedures[NFSPROC_READLINK],
217		.rpc_argp	= &args,
218	};
219	int			status;
220
221	dprintk("NFS call  readlink\n");
222	status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
223	dprintk("NFS reply readlink: %d\n", status);
224	return status;
225}
226
227struct nfs_createdata {
228	struct nfs_createargs arg;
229	struct nfs_diropok res;
230	struct nfs_fh fhandle;
231	struct nfs_fattr fattr;
232};
233
234static struct nfs_createdata *nfs_alloc_createdata(struct inode *dir,
235		struct dentry *dentry, struct iattr *sattr)
236{
237	struct nfs_createdata *data;
238
239	data = kmalloc(sizeof(*data), GFP_KERNEL);
240
241	if (data != NULL) {
242		data->arg.fh = NFS_FH(dir);
243		data->arg.name = dentry->d_name.name;
244		data->arg.len = dentry->d_name.len;
245		data->arg.sattr = sattr;
246		nfs_fattr_init(&data->fattr);
247		data->fhandle.size = 0;
248		data->res.fh = &data->fhandle;
249		data->res.fattr = &data->fattr;
250	}
251	return data;
252};
253
254static void nfs_free_createdata(const struct nfs_createdata *data)
255{
256	kfree(data);
257}
258
259static int
260nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
261		int flags, struct nameidata *nd)
262{
263	struct nfs_createdata *data;
264	struct rpc_message msg = {
265		.rpc_proc	= &nfs_procedures[NFSPROC_CREATE],
266	};
267	int status = -ENOMEM;
268
269	dprintk("NFS call  create %s\n", dentry->d_name.name);
270	data = nfs_alloc_createdata(dir, dentry, sattr);
271	if (data == NULL)
272		goto out;
273	msg.rpc_argp = &data->arg;
274	msg.rpc_resp = &data->res;
275	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
276	nfs_mark_for_revalidate(dir);
277	if (status == 0)
278		status = nfs_instantiate(dentry, data->res.fh, data->res.fattr);
279	nfs_free_createdata(data);
280out:
281	dprintk("NFS reply create: %d\n", status);
282	return status;
283}
284
285/*
286 * In NFSv2, mknod is grafted onto the create call.
287 */
288static int
289nfs_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
290	       dev_t rdev)
291{
292	struct nfs_createdata *data;
293	struct rpc_message msg = {
294		.rpc_proc	= &nfs_procedures[NFSPROC_CREATE],
295	};
296	umode_t mode;
297	int status = -ENOMEM;
298
299	dprintk("NFS call  mknod %s\n", dentry->d_name.name);
300
301	mode = sattr->ia_mode;
302	if (S_ISFIFO(mode)) {
303		sattr->ia_mode = (mode & ~S_IFMT) | S_IFCHR;
304		sattr->ia_valid &= ~ATTR_SIZE;
305	} else if (S_ISCHR(mode) || S_ISBLK(mode)) {
306		sattr->ia_valid |= ATTR_SIZE;
307		sattr->ia_size = new_encode_dev(rdev);/* get out your barf bag */
308	}
309
310	data = nfs_alloc_createdata(dir, dentry, sattr);
311	if (data == NULL)
312		goto out;
313	msg.rpc_argp = &data->arg;
314	msg.rpc_resp = &data->res;
315
316	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
317	nfs_mark_for_revalidate(dir);
318
319	if (status == -EINVAL && S_ISFIFO(mode)) {
320		sattr->ia_mode = mode;
321		nfs_fattr_init(data->res.fattr);
322		status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
323	}
324	if (status == 0)
325		status = nfs_instantiate(dentry, data->res.fh, data->res.fattr);
326	nfs_free_createdata(data);
327out:
328	dprintk("NFS reply mknod: %d\n", status);
329	return status;
330}
331
332static int
333nfs_proc_remove(struct inode *dir, struct qstr *name)
334{
335	struct nfs_removeargs arg = {
336		.fh = NFS_FH(dir),
337		.name.len = name->len,
338		.name.name = name->name,
339	};
340	struct rpc_message msg = {
341		.rpc_proc = &nfs_procedures[NFSPROC_REMOVE],
342		.rpc_argp = &arg,
343	};
344	int			status;
345
346	dprintk("NFS call  remove %s\n", name->name);
347	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
348	nfs_mark_for_revalidate(dir);
349
350	dprintk("NFS reply remove: %d\n", status);
351	return status;
352}
353
354static void
355nfs_proc_unlink_setup(struct rpc_message *msg, struct inode *dir)
356{
357	msg->rpc_proc = &nfs_procedures[NFSPROC_REMOVE];
358}
359
360static int nfs_proc_unlink_done(struct rpc_task *task, struct inode *dir)
361{
362	if (nfs_async_handle_expired_key(task))
363		return 0;
364	nfs_mark_for_revalidate(dir);
365	return 1;
366}
367
368static int
369nfs_proc_rename(struct inode *old_dir, struct qstr *old_name,
370		struct inode *new_dir, struct qstr *new_name)
371{
372	struct nfs_renameargs	arg = {
373		.fromfh		= NFS_FH(old_dir),
374		.fromname	= old_name->name,
375		.fromlen	= old_name->len,
376		.tofh		= NFS_FH(new_dir),
377		.toname		= new_name->name,
378		.tolen		= new_name->len
379	};
380	struct rpc_message msg = {
381		.rpc_proc	= &nfs_procedures[NFSPROC_RENAME],
382		.rpc_argp	= &arg,
383	};
384	int			status;
385
386	dprintk("NFS call  rename %s -> %s\n", old_name->name, new_name->name);
387	status = rpc_call_sync(NFS_CLIENT(old_dir), &msg, 0);
388	nfs_mark_for_revalidate(old_dir);
389	nfs_mark_for_revalidate(new_dir);
390	dprintk("NFS reply rename: %d\n", status);
391	return status;
392}
393
394static int
395nfs_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
396{
397	struct nfs_linkargs	arg = {
398		.fromfh		= NFS_FH(inode),
399		.tofh		= NFS_FH(dir),
400		.toname		= name->name,
401		.tolen		= name->len
402	};
403	struct rpc_message msg = {
404		.rpc_proc	= &nfs_procedures[NFSPROC_LINK],
405		.rpc_argp	= &arg,
406	};
407	int			status;
408
409	dprintk("NFS call  link %s\n", name->name);
410	status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
411	nfs_mark_for_revalidate(inode);
412	nfs_mark_for_revalidate(dir);
413	dprintk("NFS reply link: %d\n", status);
414	return status;
415}
416
417static int
418nfs_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page,
419		 unsigned int len, struct iattr *sattr)
420{
421	struct nfs_fh *fh;
422	struct nfs_fattr *fattr;
423	struct nfs_symlinkargs	arg = {
424		.fromfh		= NFS_FH(dir),
425		.fromname	= dentry->d_name.name,
426		.fromlen	= dentry->d_name.len,
427		.pages		= &page,
428		.pathlen	= len,
429		.sattr		= sattr
430	};
431	struct rpc_message msg = {
432		.rpc_proc	= &nfs_procedures[NFSPROC_SYMLINK],
433		.rpc_argp	= &arg,
434	};
435	int status = -ENAMETOOLONG;
436
437	dprintk("NFS call  symlink %s\n", dentry->d_name.name);
438
439	if (len > NFS2_MAXPATHLEN)
440		goto out;
441
442	fh = nfs_alloc_fhandle();
443	fattr = nfs_alloc_fattr();
444	status = -ENOMEM;
445	if (fh == NULL || fattr == NULL)
446		goto out;
447
448	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
449	nfs_mark_for_revalidate(dir);
450
451	/*
452	 * V2 SYMLINK requests don't return any attributes.  Setting the
453	 * filehandle size to zero indicates to nfs_instantiate that it
454	 * should fill in the data with a LOOKUP call on the wire.
455	 */
456	if (status == 0)
457		status = nfs_instantiate(dentry, fh, fattr);
458
459	nfs_free_fattr(fattr);
460	nfs_free_fhandle(fh);
461out:
462	dprintk("NFS reply symlink: %d\n", status);
463	return status;
464}
465
466static int
467nfs_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
468{
469	struct nfs_createdata *data;
470	struct rpc_message msg = {
471		.rpc_proc	= &nfs_procedures[NFSPROC_MKDIR],
472	};
473	int status = -ENOMEM;
474
475	dprintk("NFS call  mkdir %s\n", dentry->d_name.name);
476	data = nfs_alloc_createdata(dir, dentry, sattr);
477	if (data == NULL)
478		goto out;
479	msg.rpc_argp = &data->arg;
480	msg.rpc_resp = &data->res;
481
482	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
483	nfs_mark_for_revalidate(dir);
484	if (status == 0)
485		status = nfs_instantiate(dentry, data->res.fh, data->res.fattr);
486	nfs_free_createdata(data);
487out:
488	dprintk("NFS reply mkdir: %d\n", status);
489	return status;
490}
491
492static int
493nfs_proc_rmdir(struct inode *dir, struct qstr *name)
494{
495	struct nfs_diropargs	arg = {
496		.fh		= NFS_FH(dir),
497		.name		= name->name,
498		.len		= name->len
499	};
500	struct rpc_message msg = {
501		.rpc_proc	= &nfs_procedures[NFSPROC_RMDIR],
502		.rpc_argp	= &arg,
503	};
504	int			status;
505
506	dprintk("NFS call  rmdir %s\n", name->name);
507	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
508	nfs_mark_for_revalidate(dir);
509	dprintk("NFS reply rmdir: %d\n", status);
510	return status;
511}
512
513/*
514 * The READDIR implementation is somewhat hackish - we pass a temporary
515 * buffer to the encode function, which installs it in the receive
516 * the receive iovec. The decode function just parses the reply to make
517 * sure it is syntactically correct; the entries itself are decoded
518 * from nfs_readdir by calling the decode_entry function directly.
519 */
520static int
521nfs_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
522		 u64 cookie, struct page *page, unsigned int count, int plus)
523{
524	struct inode		*dir = dentry->d_inode;
525	struct nfs_readdirargs	arg = {
526		.fh		= NFS_FH(dir),
527		.cookie		= cookie,
528		.count		= count,
529		.pages		= &page,
530	};
531	struct rpc_message	msg = {
532		.rpc_proc	= &nfs_procedures[NFSPROC_READDIR],
533		.rpc_argp	= &arg,
534		.rpc_cred	= cred,
535	};
536	int			status;
537
538	dprintk("NFS call  readdir %d\n", (unsigned int)cookie);
539	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
540
541	nfs_invalidate_atime(dir);
542
543	dprintk("NFS reply readdir: %d\n", status);
544	return status;
545}
546
547static int
548nfs_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
549			struct nfs_fsstat *stat)
550{
551	struct nfs2_fsstat fsinfo;
552	struct rpc_message msg = {
553		.rpc_proc	= &nfs_procedures[NFSPROC_STATFS],
554		.rpc_argp	= fhandle,
555		.rpc_resp	= &fsinfo,
556	};
557	int	status;
558
559	dprintk("NFS call  statfs\n");
560	nfs_fattr_init(stat->fattr);
561	status = rpc_call_sync(server->client, &msg, 0);
562	dprintk("NFS reply statfs: %d\n", status);
563	if (status)
564		goto out;
565	stat->tbytes = (u64)fsinfo.blocks * fsinfo.bsize;
566	stat->fbytes = (u64)fsinfo.bfree  * fsinfo.bsize;
567	stat->abytes = (u64)fsinfo.bavail * fsinfo.bsize;
568	stat->tfiles = 0;
569	stat->ffiles = 0;
570	stat->afiles = 0;
571out:
572	return status;
573}
574
575static int
576nfs_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
577			struct nfs_fsinfo *info)
578{
579	struct nfs2_fsstat fsinfo;
580	struct rpc_message msg = {
581		.rpc_proc	= &nfs_procedures[NFSPROC_STATFS],
582		.rpc_argp	= fhandle,
583		.rpc_resp	= &fsinfo,
584	};
585	int	status;
586
587	dprintk("NFS call  fsinfo\n");
588	nfs_fattr_init(info->fattr);
589	status = rpc_call_sync(server->client, &msg, 0);
590	dprintk("NFS reply fsinfo: %d\n", status);
591	if (status)
592		goto out;
593	info->rtmax  = NFS_MAXDATA;
594	info->rtpref = fsinfo.tsize;
595	info->rtmult = fsinfo.bsize;
596	info->wtmax  = NFS_MAXDATA;
597	info->wtpref = fsinfo.tsize;
598	info->wtmult = fsinfo.bsize;
599	info->dtpref = fsinfo.tsize;
600	info->maxfilesize = 0x7FFFFFFF;
601	info->lease_time = 0;
602out:
603	return status;
604}
605
606static int
607nfs_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
608		  struct nfs_pathconf *info)
609{
610	info->max_link = 0;
611	info->max_namelen = NFS2_MAXNAMLEN;
612	return 0;
613}
614
615static int nfs_read_done(struct rpc_task *task, struct nfs_read_data *data)
616{
617	if (nfs_async_handle_expired_key(task))
618		return -EAGAIN;
619
620	nfs_invalidate_atime(data->inode);
621	if (task->tk_status >= 0) {
622		nfs_refresh_inode(data->inode, data->res.fattr);
623		/* Emulate the eof flag, which isn't normally needed in NFSv2
624		 * as it is guaranteed to always return the file attributes
625		 */
626		if (data->args.offset + data->args.count >= data->res.fattr->size)
627			data->res.eof = 1;
628	}
629	return 0;
630}
631
632static void nfs_proc_read_setup(struct nfs_read_data *data, struct rpc_message *msg)
633{
634	msg->rpc_proc = &nfs_procedures[NFSPROC_READ];
635}
636
637static int nfs_write_done(struct rpc_task *task, struct nfs_write_data *data)
638{
639	if (nfs_async_handle_expired_key(task))
640		return -EAGAIN;
641
642	if (task->tk_status >= 0)
643		nfs_post_op_update_inode_force_wcc(data->inode, data->res.fattr);
644	return 0;
645}
646
647static void nfs_proc_write_setup(struct nfs_write_data *data, struct rpc_message *msg)
648{
649	/* Note: NFSv2 ignores @stable and always uses NFS_FILE_SYNC */
650	data->args.stable = NFS_FILE_SYNC;
651	msg->rpc_proc = &nfs_procedures[NFSPROC_WRITE];
652}
653
654static void
655nfs_proc_commit_setup(struct nfs_write_data *data, struct rpc_message *msg)
656{
657	BUG();
658}
659
660static int
661nfs_proc_lock(struct file *filp, int cmd, struct file_lock *fl)
662{
663	struct inode *inode = filp->f_path.dentry->d_inode;
664
665	return nlmclnt_proc(NFS_SERVER(inode)->nlm_host, cmd, fl);
666}
667
668/* Helper functions for NFS lock bounds checking */
669#define NFS_LOCK32_OFFSET_MAX ((__s32)0x7fffffffUL)
670static int nfs_lock_check_bounds(const struct file_lock *fl)
671{
672	__s32 start, end;
673
674	start = (__s32)fl->fl_start;
675	if ((loff_t)start != fl->fl_start)
676		goto out_einval;
677
678	if (fl->fl_end != OFFSET_MAX) {
679		end = (__s32)fl->fl_end;
680		if ((loff_t)end != fl->fl_end)
681			goto out_einval;
682	} else
683		end = NFS_LOCK32_OFFSET_MAX;
684
685	if (start < 0 || start > end)
686		goto out_einval;
687	return 0;
688out_einval:
689	return -EINVAL;
690}
691
692const struct nfs_rpc_ops nfs_v2_clientops = {
693	.version	= 2,		       /* protocol version */
694	.dentry_ops	= &nfs_dentry_operations,
695	.dir_inode_ops	= &nfs_dir_inode_operations,
696	.file_inode_ops	= &nfs_file_inode_operations,
697	.getroot	= nfs_proc_get_root,
698	.getattr	= nfs_proc_getattr,
699	.setattr	= nfs_proc_setattr,
700	.lookup		= nfs_proc_lookup,
701	.access		= NULL,		       /* access */
702	.readlink	= nfs_proc_readlink,
703	.create		= nfs_proc_create,
704	.remove		= nfs_proc_remove,
705	.unlink_setup	= nfs_proc_unlink_setup,
706	.unlink_done	= nfs_proc_unlink_done,
707	.rename		= nfs_proc_rename,
708	.link		= nfs_proc_link,
709	.symlink	= nfs_proc_symlink,
710	.mkdir		= nfs_proc_mkdir,
711	.rmdir		= nfs_proc_rmdir,
712	.readdir	= nfs_proc_readdir,
713	.mknod		= nfs_proc_mknod,
714	.statfs		= nfs_proc_statfs,
715	.fsinfo		= nfs_proc_fsinfo,
716	.pathconf	= nfs_proc_pathconf,
717	.decode_dirent	= nfs_decode_dirent,
718	.read_setup	= nfs_proc_read_setup,
719	.read_done	= nfs_read_done,
720	.write_setup	= nfs_proc_write_setup,
721	.write_done	= nfs_write_done,
722	.commit_setup	= nfs_proc_commit_setup,
723	.lock		= nfs_proc_lock,
724	.lock_check_bounds = nfs_lock_check_bounds,
725	.close_context	= nfs_close_context,
726};
727