File: /usr/src/linux/fs/nfs/nfs3proc.c

1     /*
2      *  linux/fs/nfs/nfs3proc.c
3      *
4      *  Client-side NFSv3 procedures stubs.
5      *
6      *  Copyright (C) 1997, Olaf Kirch
7      */
8     
9     #include <linux/mm.h>
10     #include <linux/utsname.h>
11     #include <linux/errno.h>
12     #include <linux/string.h>
13     #include <linux/sunrpc/clnt.h>
14     #include <linux/nfs.h>
15     #include <linux/nfs3.h>
16     #include <linux/nfs_fs.h>
17     
18     #define NFSDBG_FACILITY		NFSDBG_PROC
19     
20     /*
21      * Bare-bones access to getattr: this is for nfs_read_super.
22      */
23     static int
24     nfs3_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
25     		   struct nfs_fattr *fattr)
26     {
27     	int	status;
28     
29     	dprintk("NFS call  getroot\n");
30     	fattr->valid = 0;
31     	status = rpc_call(server->client, NFS3PROC_GETATTR, fhandle, fattr, 0);
32     	dprintk("NFS reply getroot\n");
33     	return status;
34     }
35     
36     /*
37      * One function for each procedure in the NFS protocol.
38      */
39     static int
40     nfs3_proc_getattr(struct inode *inode, struct nfs_fattr *fattr)
41     {
42     	int	status;
43     
44     	dprintk("NFS call  getattr\n");
45     	fattr->valid = 0;
46     	status = rpc_call(NFS_CLIENT(inode), NFS3PROC_GETATTR,
47     			  NFS_FH(inode), fattr, 0);
48     	dprintk("NFS reply getattr\n");
49     	return status;
50     }
51     
52     static int
53     nfs3_proc_setattr(struct inode *inode, struct nfs_fattr *fattr,
54     			struct iattr *sattr)
55     {
56     	struct nfs3_sattrargs	arg = { NFS_FH(inode), sattr, 0, 0 };
57     	int	status;
58     
59     	dprintk("NFS call  setattr\n");
60     	fattr->valid = 0;
61     	status = rpc_call(NFS_CLIENT(inode), NFS3PROC_SETATTR, &arg, fattr, 0);
62     	dprintk("NFS reply setattr\n");
63     	return status;
64     }
65     
66     static int
67     nfs3_proc_lookup(struct inode *dir, struct qstr *name,
68     		 struct nfs_fh *fhandle, struct nfs_fattr *fattr)
69     {
70     	struct nfs_fattr	dir_attr;
71     	struct nfs3_diropargs	arg = { NFS_FH(dir), name->name, name->len };
72     	struct nfs3_diropres	res = { &dir_attr, fhandle, fattr };
73     	int			status;
74     
75     	dprintk("NFS call  lookup %s\n", name->name);
76     	dir_attr.valid = 0;
77     	fattr->valid = 0;
78     	status = rpc_call(NFS_CLIENT(dir), NFS3PROC_LOOKUP, &arg, &res, 0);
79     	if (status >= 0 && !(fattr->valid & NFS_ATTR_FATTR))
80     		status = rpc_call(NFS_CLIENT(dir), NFS3PROC_GETATTR,
81     			 fhandle, fattr, 0);
82     	dprintk("NFS reply lookup: %d\n", status);
83     	nfs_refresh_inode(dir, &dir_attr);
84     	return status;
85     }
86     
87     static int
88     nfs3_proc_access(struct inode *inode, int mode, int ruid)
89     {
90     	struct nfs_fattr	fattr;
91     	struct nfs3_accessargs	arg = { NFS_FH(inode), 0 };
92     	struct nfs3_accessres	res = { &fattr, 0 };
93     	int	status, flags;
94     
95     	dprintk("NFS call  access\n");
96     	fattr.valid = 0;
97     
98     	if (mode & MAY_READ)
99     		arg.access |= NFS3_ACCESS_READ;
100     	if (S_ISDIR(inode->i_mode)) {
101     		if (mode & MAY_WRITE)
102     			arg.access |= NFS3_ACCESS_MODIFY | NFS3_ACCESS_EXTEND | NFS3_ACCESS_DELETE;
103     		if (mode & MAY_EXEC)
104     			arg.access |= NFS3_ACCESS_LOOKUP;
105     	} else {
106     		if (mode & MAY_WRITE)
107     			arg.access |= NFS3_ACCESS_MODIFY | NFS3_ACCESS_EXTEND;
108     		if (mode & MAY_EXEC)
109     			arg.access |= NFS3_ACCESS_EXECUTE;
110     	}
111     	flags = (ruid) ? RPC_CALL_REALUID : 0;
112     	status = rpc_call(NFS_CLIENT(inode), NFS3PROC_ACCESS, &arg, &res, flags);
113     	nfs_refresh_inode(inode, &fattr);
114     	dprintk("NFS reply access\n");
115     
116     	if (status == 0 && (arg.access & res.access) != arg.access)
117     		status = -EACCES;
118     	return status;
119     }
120     
121     static int
122     nfs3_proc_readlink(struct inode *inode, void *buffer, unsigned int buflen)
123     {
124     	struct nfs_fattr	fattr;
125     	struct nfs3_readlinkargs args = { NFS_FH(inode), buffer, buflen };
126     	struct nfs3_readlinkres	res = { &fattr, buffer, buflen };
127     	int			status;
128     
129     	dprintk("NFS call  readlink\n");
130     	fattr.valid = 0;
131     	status = rpc_call(NFS_CLIENT(inode), NFS3PROC_READLINK,
132     			  &args, &res, 0);
133     	nfs_refresh_inode(inode, &fattr);
134     	dprintk("NFS reply readlink: %d\n", status);
135     	return status;
136     }
137     
138     static int
139     nfs3_proc_read(struct inode *inode, struct rpc_cred *cred,
140     	       struct nfs_fattr *fattr, int flags,
141     	       loff_t offset, unsigned int count, void *buffer, int *eofp)
142     {
143     	struct nfs_readargs	arg = { NFS_FH(inode), offset, count, 1,
144     					{{buffer, count}, {0,0}, {0,0}, {0,0},
145     					 {0,0}, {0,0}, {0,0}, {0,0}} };
146     	struct nfs_readres	res = { fattr, count, 0 };
147     	struct rpc_message	msg = { NFS3PROC_READ, &arg, &res, cred };
148     	int			status;
149     
150     	dprintk("NFS call  read %d @ %Ld\n", count, (long long)offset);
151     	fattr->valid = 0;
152     	status = rpc_call_sync(NFS_CLIENT(inode), &msg, flags);
153     	dprintk("NFS reply read: %d\n", status);
154     	*eofp = res.eof;
155     	return status;
156     }
157     
158     static int
159     nfs3_proc_write(struct inode *inode, struct rpc_cred *cred,
160     		struct nfs_fattr *fattr, int flags,
161     		loff_t offset, unsigned int count,
162     		void *buffer, struct nfs_writeverf *verf)
163     {
164     	struct nfs_writeargs	arg = { NFS_FH(inode), offset, count,
165     					NFS_FILE_SYNC, 1,
166     					{{buffer, count}, {0,0}, {0,0}, {0,0},
167     					 {0,0}, {0,0}, {0,0}, {0,0}} };
168     	struct nfs_writeres	res = { fattr, verf, 0 };
169     	struct rpc_message	msg = { NFS3PROC_WRITE, &arg, &res, cred };
170     	int			status, rpcflags = 0;
171     
172     	dprintk("NFS call  write %d @ %Ld\n", count, (long long)offset);
173     	fattr->valid = 0;
174     	if (flags & NFS_RW_SWAP)
175     		rpcflags |= NFS_RPC_SWAPFLAGS;
176     	arg.stable = (flags & NFS_RW_SYNC) ? NFS_FILE_SYNC : NFS_UNSTABLE;
177     
178     	status = rpc_call_sync(NFS_CLIENT(inode), &msg, rpcflags);
179     
180     	dprintk("NFS reply read: %d\n", status);
181     	return status < 0? status : res.count;
182     }
183     
184     /*
185      * Create a regular file.
186      * For now, we don't implement O_EXCL.
187      */
188     static int
189     nfs3_proc_create(struct inode *dir, struct qstr *name, struct iattr *sattr,
190     		 int flags, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
191     {
192     	struct nfs_fattr	dir_attr;
193     	struct nfs3_createargs	arg = { NFS_FH(dir), name->name, name->len,
194     					sattr, 0, { 0, 0 } };
195     	struct nfs3_diropres	res = { &dir_attr, fhandle, fattr };
196     	int			status;
197     
198     	dprintk("NFS call  create %s\n", name->name);
199     	arg.createmode = NFS3_CREATE_UNCHECKED;
200     	if (flags & O_EXCL) {
201     		arg.createmode  = NFS3_CREATE_EXCLUSIVE;
202     		arg.verifier[0] = jiffies;
203     		arg.verifier[1] = current->pid;
204     	}
205     
206     again:
207     	dir_attr.valid = 0;
208     	fattr->valid = 0;
209     	status = rpc_call(NFS_CLIENT(dir), NFS3PROC_CREATE, &arg, &res, 0);
210     	nfs_refresh_inode(dir, &dir_attr);
211     
212     	/* If the server doesn't support the exclusive creation semantics,
213     	 * try again with simple 'guarded' mode. */
214     	if (status == NFSERR_NOTSUPP) {
215     		switch (arg.createmode) {
216     			case NFS3_CREATE_EXCLUSIVE:
217     				arg.createmode = NFS3_CREATE_GUARDED;
218     				break;
219     
220     			case NFS3_CREATE_GUARDED:
221     				arg.createmode = NFS3_CREATE_UNCHECKED;
222     				break;
223     
224     			case NFS3_CREATE_UNCHECKED:
225     				goto exit;
226     		}
227     		goto again;
228     	}
229     
230     exit:
231     	dprintk("NFS reply create: %d\n", status);
232     
233     	/* When we created the file with exclusive semantics, make
234     	 * sure we set the attributes afterwards. */
235     	if (status == 0 && arg.createmode == NFS3_CREATE_EXCLUSIVE) {
236     		struct nfs3_sattrargs	arg = { fhandle, sattr, 0, 0 };
237     		dprintk("NFS call  setattr (post-create)\n");
238     
239     		/* Note: we could use a guarded setattr here, but I'm
240     		 * not sure this buys us anything (and I'd have
241     		 * to revamp the NFSv3 XDR code) */
242     		fattr->valid = 0;
243     		status = rpc_call(NFS_CLIENT(dir), NFS3PROC_SETATTR,
244     						&arg, fattr, 0);
245     		dprintk("NFS reply setattr (post-create): %d\n", status);
246     	}
247     
248     	return status;
249     }
250     
251     static int
252     nfs3_proc_remove(struct inode *dir, struct qstr *name)
253     {
254     	struct nfs_fattr	dir_attr;
255     	struct nfs3_diropargs	arg = { NFS_FH(dir), name->name, name->len };
256     	struct rpc_message	msg = { NFS3PROC_REMOVE, &arg, &dir_attr, NULL };
257     	int			status;
258     
259     	dprintk("NFS call  remove %s\n", name->name);
260     	dir_attr.valid = 0;
261     	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
262     	nfs_refresh_inode(dir, &dir_attr);
263     	dprintk("NFS reply remove: %d\n", status);
264     	return status;
265     }
266     
267     static int
268     nfs3_proc_unlink_setup(struct rpc_message *msg, struct dentry *dir, struct qstr *name)
269     {
270     	struct nfs3_diropargs	*arg;
271     	struct nfs_fattr	*res;
272     
273     	arg = (struct nfs3_diropargs *)kmalloc(sizeof(*arg)+sizeof(*res), GFP_KERNEL);
274     	if (!arg)
275     		return -ENOMEM;
276     	res = (struct nfs_fattr*)(arg + 1);
277     	arg->fh = NFS_FH(dir->d_inode);
278     	arg->name = name->name;
279     	arg->len = name->len;
280     	res->valid = 0;
281     	msg->rpc_proc = NFS3PROC_REMOVE;
282     	msg->rpc_argp = arg;
283     	msg->rpc_resp = res;
284     	return 0;
285     }
286     
287     static void
288     nfs3_proc_unlink_done(struct dentry *dir, struct rpc_message *msg)
289     {
290     	struct nfs_fattr	*dir_attr;
291     
292     	if (msg->rpc_argp) {
293     		dir_attr = (struct nfs_fattr*)msg->rpc_resp;
294     		nfs_refresh_inode(dir->d_inode, dir_attr);
295     		kfree(msg->rpc_argp);
296     	}
297     }
298     
299     static int
300     nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name,
301     		 struct inode *new_dir, struct qstr *new_name)
302     {
303     	struct nfs_fattr	old_dir_attr, new_dir_attr;
304     	struct nfs3_renameargs	arg = { NFS_FH(old_dir),
305     					old_name->name, old_name->len,
306     					NFS_FH(new_dir),
307     					new_name->name, new_name->len };
308     	struct nfs3_renameres	res = { &old_dir_attr, &new_dir_attr };
309     	int			status;
310     
311     	dprintk("NFS call  rename %s -> %s\n", old_name->name, new_name->name);
312     	old_dir_attr.valid = 0;
313     	new_dir_attr.valid = 0;
314     	status = rpc_call(NFS_CLIENT(old_dir), NFS3PROC_RENAME, &arg, &res, 0);
315     	nfs_refresh_inode(old_dir, &old_dir_attr);
316     	nfs_refresh_inode(new_dir, &new_dir_attr);
317     	dprintk("NFS reply rename: %d\n", status);
318     	return status;
319     }
320     
321     static int
322     nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
323     {
324     	struct nfs_fattr	dir_attr, fattr;
325     	struct nfs3_linkargs	arg = { NFS_FH(inode), NFS_FH(dir),
326     					name->name, name->len };
327     	struct nfs3_linkres	res = { &dir_attr, &fattr };
328     	int			status;
329     
330     	dprintk("NFS call  link %s\n", name->name);
331     	dir_attr.valid = 0;
332     	fattr.valid = 0;
333     	status = rpc_call(NFS_CLIENT(inode), NFS3PROC_LINK, &arg, &res, 0);
334     	nfs_refresh_inode(dir, &dir_attr);
335     	nfs_refresh_inode(inode, &fattr);
336     	dprintk("NFS reply link: %d\n", status);
337     	return status;
338     }
339     
340     static int
341     nfs3_proc_symlink(struct inode *dir, struct qstr *name, struct qstr *path,
342     		  struct iattr *sattr, struct nfs_fh *fhandle,
343     		  struct nfs_fattr *fattr)
344     {
345     	struct nfs_fattr	dir_attr;
346     	struct nfs3_symlinkargs	arg = { NFS_FH(dir), name->name, name->len,
347     					path->name, path->len, sattr };
348     	struct nfs3_diropres	res = { &dir_attr, fhandle, fattr };
349     	int			status;
350     
351     	dprintk("NFS call  symlink %s -> %s\n", name->name, path->name);
352     	dir_attr.valid = 0;
353     	fattr->valid = 0;
354     	status = rpc_call(NFS_CLIENT(dir), NFS3PROC_SYMLINK, &arg, &res, 0);
355     	nfs_refresh_inode(dir, &dir_attr);
356     	dprintk("NFS reply symlink: %d\n", status);
357     	return status;
358     }
359     
360     static int
361     nfs3_proc_mkdir(struct inode *dir, struct qstr *name, struct iattr *sattr,
362     		struct nfs_fh *fhandle, struct nfs_fattr *fattr)
363     {
364     	struct nfs_fattr	dir_attr;
365     	struct nfs3_createargs	arg = { NFS_FH(dir), name->name, name->len,
366     					sattr, 0, { 0, 0 } };
367     	struct nfs3_diropres	res = { &dir_attr, fhandle, fattr };
368     	int			status;
369     
370     	dprintk("NFS call  mkdir %s\n", name->name);
371     	dir_attr.valid = 0;
372     	fattr->valid = 0;
373     	status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKDIR, &arg, &res, 0);
374     	nfs_refresh_inode(dir, &dir_attr);
375     	dprintk("NFS reply mkdir: %d\n", status);
376     	return status;
377     }
378     
379     static int
380     nfs3_proc_rmdir(struct inode *dir, struct qstr *name)
381     {
382     	struct nfs_fattr	dir_attr;
383     	struct nfs3_diropargs	arg = { NFS_FH(dir), name->name, name->len };
384     	int			status;
385     
386     	dprintk("NFS call  rmdir %s\n", name->name);
387     	dir_attr.valid = 0;
388     	status = rpc_call(NFS_CLIENT(dir), NFS3PROC_RMDIR, &arg, &dir_attr, 0);
389     	nfs_refresh_inode(dir, &dir_attr);
390     	dprintk("NFS reply rmdir: %d\n", status);
391     	return status;
392     }
393     
394     /*
395      * The READDIR implementation is somewhat hackish - we pass the user buffer
396      * to the encode function, which installs it in the receive iovec.
397      * The decode function itself doesn't perform any decoding, it just makes
398      * sure the reply is syntactically correct.
399      *
400      * Also note that this implementation handles both plain readdir and
401      * readdirplus.
402      */
403     static int
404     nfs3_proc_readdir(struct inode *dir, struct rpc_cred *cred,
405     		  u64 cookie, void *entry,
406     		  unsigned int size, int plus)
407     {
408     	struct nfs_fattr	dir_attr;
409     	struct nfs3_readdirargs	arg = { NFS_FH(dir), cookie, {0, 0}, 0, 0, 0 };
410     	struct nfs3_readdirres	res = { &dir_attr, 0, 0, 0, 0 };
411     	struct rpc_message	msg = { NFS3PROC_READDIR, &arg, &res, cred };
412     	u32			*verf = NFS_COOKIEVERF(dir);
413     	int			status;
414     
415     	arg.buffer  = entry;
416     	arg.bufsiz  = size;
417     	arg.verf[0] = verf[0];
418     	arg.verf[1] = verf[1];
419     	arg.plus    = plus;
420     	res.buffer  = entry;
421     	res.bufsiz  = size;
422     	res.verf    = verf;
423     	res.plus    = plus;
424     
425     	if (plus)
426     		msg.rpc_proc = NFS3PROC_READDIRPLUS;
427     
428     	dprintk("NFS call  readdir%s %d\n",
429     			plus? "plus" : "", (unsigned int) cookie);
430     
431     	dir_attr.valid = 0;
432     	status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
433     	nfs_refresh_inode(dir, &dir_attr);
434     	dprintk("NFS reply readdir: %d\n", status);
435     	return status;
436     }
437     
438     static int
439     nfs3_proc_mknod(struct inode *dir, struct qstr *name, struct iattr *sattr,
440     		dev_t rdev, struct nfs_fh *fh, struct nfs_fattr *fattr)
441     {
442     	struct nfs_fattr	dir_attr;
443     	struct nfs3_mknodargs	arg = { NFS_FH(dir), name->name, name->len, 0,
444     					sattr, rdev };
445     	struct nfs3_diropres	res = { &dir_attr, fh, fattr };
446     	int			status;
447     
448     	switch (sattr->ia_mode & S_IFMT) {
449     	case S_IFBLK:	arg.type = NF3BLK;  break;
450     	case S_IFCHR:	arg.type = NF3CHR;  break;
451     	case S_IFIFO:	arg.type = NF3FIFO; break;
452     	case S_IFSOCK:	arg.type = NF3SOCK; break;
453     	default:	return -EINVAL;
454     	}
455     
456     	dprintk("NFS call  mknod %s %x\n", name->name, rdev);
457     	dir_attr.valid = 0;
458     	fattr->valid = 0;
459     	status = rpc_call(NFS_CLIENT(dir), NFS3PROC_MKNOD, &arg, &res, 0);
460     	nfs_refresh_inode(dir, &dir_attr);
461     	dprintk("NFS reply mknod: %d\n", status);
462     	return status;
463     }
464     
465     /*
466      * This is a combo call of fsstat and fsinfo
467      */
468     static int
469     nfs3_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
470     		 struct nfs_fsinfo *info)
471     {
472     	int	status;
473     
474     	dprintk("NFS call  fsstat\n");
475     	memset((char *)info, 0, sizeof(*info));
476     	status = rpc_call(server->client, NFS3PROC_FSSTAT, fhandle, info, 0);
477     	if (status < 0)
478     		goto error;
479     	status = rpc_call(server->client, NFS3PROC_FSINFO, fhandle, info, 0);
480     
481     error:
482     	dprintk("NFS reply statfs: %d\n", status);
483     	return status;
484     }
485     
486     extern u32 *nfs3_decode_dirent(u32 *, struct nfs_entry *, int);
487     
488     struct nfs_rpc_ops	nfs_v3_clientops = {
489     	3,			/* protocol version */
490     	nfs3_proc_get_root,
491     	nfs3_proc_getattr,
492     	nfs3_proc_setattr,
493     	nfs3_proc_lookup,
494     	nfs3_proc_access,
495     	nfs3_proc_readlink,
496     	nfs3_proc_read,
497     	nfs3_proc_write,
498     	NULL,			/* commit */
499     	nfs3_proc_create,
500     	nfs3_proc_remove,
501     	nfs3_proc_unlink_setup,
502     	nfs3_proc_unlink_done,
503     	nfs3_proc_rename,
504     	nfs3_proc_link,
505     	nfs3_proc_symlink,
506     	nfs3_proc_mkdir,
507     	nfs3_proc_rmdir,
508     	nfs3_proc_readdir,
509     	nfs3_proc_mknod,
510     	nfs3_proc_statfs,
511     	nfs3_decode_dirent,
512     };
513