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