Branch data Line data Source code
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/errno.h>
11 : : #include <linux/string.h>
12 : : #include <linux/sunrpc/clnt.h>
13 : : #include <linux/slab.h>
14 : : #include <linux/nfs.h>
15 : : #include <linux/nfs3.h>
16 : : #include <linux/nfs_fs.h>
17 : : #include <linux/nfs_page.h>
18 : : #include <linux/lockd/bind.h>
19 : : #include <linux/nfs_mount.h>
20 : : #include <linux/freezer.h>
21 : : #include <linux/xattr.h>
22 : :
23 : : #include "iostat.h"
24 : : #include "internal.h"
25 : :
26 : : #define NFSDBG_FACILITY NFSDBG_PROC
27 : :
28 : : /* A wrapper to handle the EJUKEBOX error messages */
29 : : static int
30 : 0 : nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
31 : : {
32 : : int res;
33 : : do {
34 : 0 : res = rpc_call_sync(clnt, msg, flags);
35 [ # # ]: 0 : if (res != -EJUKEBOX)
36 : : break;
37 : : freezable_schedule_timeout_killable_unsafe(NFS_JUKEBOX_RETRY_TIME);
38 : : res = -ERESTARTSYS;
39 [ # # ]: 0 : } while (!fatal_signal_pending(current));
40 : 0 : return res;
41 : : }
42 : :
43 : : #define rpc_call_sync(clnt, msg, flags) nfs3_rpc_wrapper(clnt, msg, flags)
44 : :
45 : : static int
46 : 0 : nfs3_async_handle_jukebox(struct rpc_task *task, struct inode *inode)
47 : : {
48 [ # # ]: 0 : if (task->tk_status != -EJUKEBOX)
49 : : return 0;
50 [ # # ]: 0 : if (task->tk_status == -EJUKEBOX)
51 : : nfs_inc_stats(inode, NFSIOS_DELAY);
52 : 0 : task->tk_status = 0;
53 : 0 : rpc_restart_call(task);
54 : 0 : rpc_delay(task, NFS_JUKEBOX_RETRY_TIME);
55 : 0 : return 1;
56 : : }
57 : :
58 : : static int
59 : 0 : do_proc_get_root(struct rpc_clnt *client, struct nfs_fh *fhandle,
60 : : struct nfs_fsinfo *info)
61 : : {
62 : 0 : struct rpc_message msg = {
63 : : .rpc_proc = &nfs3_procedures[NFS3PROC_FSINFO],
64 : : .rpc_argp = fhandle,
65 : : .rpc_resp = info,
66 : : };
67 : : int status;
68 : :
69 : : dprintk("%s: call fsinfo\n", __func__);
70 : 0 : nfs_fattr_init(info->fattr);
71 : 0 : status = rpc_call_sync(client, &msg, 0);
72 : : dprintk("%s: reply fsinfo: %d\n", __func__, status);
73 [ # # ][ # # ]: 0 : if (status == 0 && !(info->fattr->valid & NFS_ATTR_FATTR)) {
74 : 0 : msg.rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR];
75 : 0 : msg.rpc_resp = info->fattr;
76 : 0 : status = rpc_call_sync(client, &msg, 0);
77 : : dprintk("%s: reply getattr: %d\n", __func__, status);
78 : : }
79 : 0 : return status;
80 : : }
81 : :
82 : : /*
83 : : * Bare-bones access to getattr: this is for nfs_get_root/nfs_get_sb
84 : : */
85 : : static int
86 : 0 : nfs3_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
87 : : struct nfs_fsinfo *info)
88 : : {
89 : : int status;
90 : :
91 : 0 : status = do_proc_get_root(server->client, fhandle, info);
92 [ # # ][ # # ]: 0 : if (status && server->nfs_client->cl_rpcclient != server->client)
93 : 0 : status = do_proc_get_root(server->nfs_client->cl_rpcclient, fhandle, info);
94 : 0 : return status;
95 : : }
96 : :
97 : : /*
98 : : * One function for each procedure in the NFS protocol.
99 : : */
100 : : static int
101 : 0 : nfs3_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
102 : : struct nfs_fattr *fattr, struct nfs4_label *label)
103 : : {
104 : 0 : struct rpc_message msg = {
105 : : .rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR],
106 : : .rpc_argp = fhandle,
107 : : .rpc_resp = fattr,
108 : : };
109 : : int status;
110 : :
111 : : dprintk("NFS call getattr\n");
112 : 0 : nfs_fattr_init(fattr);
113 : 0 : status = rpc_call_sync(server->client, &msg, 0);
114 : : dprintk("NFS reply getattr: %d\n", status);
115 : 0 : return status;
116 : : }
117 : :
118 : : static int
119 : 0 : nfs3_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
120 : : struct iattr *sattr)
121 : : {
122 : 0 : struct inode *inode = dentry->d_inode;
123 : 0 : struct nfs3_sattrargs arg = {
124 : 0 : .fh = NFS_FH(inode),
125 : : .sattr = sattr,
126 : : };
127 : 0 : struct rpc_message msg = {
128 : : .rpc_proc = &nfs3_procedures[NFS3PROC_SETATTR],
129 : : .rpc_argp = &arg,
130 : : .rpc_resp = fattr,
131 : : };
132 : : int status;
133 : :
134 : : dprintk("NFS call setattr\n");
135 [ # # ]: 0 : if (sattr->ia_valid & ATTR_FILE)
136 : 0 : msg.rpc_cred = nfs_file_cred(sattr->ia_file);
137 : 0 : nfs_fattr_init(fattr);
138 : 0 : status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
139 [ # # ]: 0 : if (status == 0)
140 : 0 : nfs_setattr_update_inode(inode, sattr);
141 : : dprintk("NFS reply setattr: %d\n", status);
142 : 0 : return status;
143 : : }
144 : :
145 : : static int
146 : 0 : nfs3_proc_lookup(struct inode *dir, struct qstr *name,
147 : : struct nfs_fh *fhandle, struct nfs_fattr *fattr,
148 : : struct nfs4_label *label)
149 : : {
150 : 0 : struct nfs3_diropargs arg = {
151 : 0 : .fh = NFS_FH(dir),
152 : 0 : .name = name->name,
153 : 0 : .len = name->len
154 : : };
155 : 0 : struct nfs3_diropres res = {
156 : : .fh = fhandle,
157 : : .fattr = fattr
158 : : };
159 : 0 : struct rpc_message msg = {
160 : : .rpc_proc = &nfs3_procedures[NFS3PROC_LOOKUP],
161 : : .rpc_argp = &arg,
162 : : .rpc_resp = &res,
163 : : };
164 : : int status;
165 : :
166 : : dprintk("NFS call lookup %s\n", name->name);
167 : 0 : res.dir_attr = nfs_alloc_fattr();
168 [ # # ]: 0 : if (res.dir_attr == NULL)
169 : : return -ENOMEM;
170 : :
171 : 0 : nfs_fattr_init(fattr);
172 : 0 : status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
173 : 0 : nfs_refresh_inode(dir, res.dir_attr);
174 [ # # ][ # # ]: 0 : if (status >= 0 && !(fattr->valid & NFS_ATTR_FATTR)) {
175 : 0 : msg.rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR];
176 : 0 : msg.rpc_argp = fhandle;
177 : 0 : msg.rpc_resp = fattr;
178 : 0 : status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
179 : : }
180 : 0 : nfs_free_fattr(res.dir_attr);
181 : : dprintk("NFS reply lookup: %d\n", status);
182 : 0 : return status;
183 : : }
184 : :
185 : 0 : static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry)
186 : : {
187 : 0 : struct nfs3_accessargs arg = {
188 : 0 : .fh = NFS_FH(inode),
189 : : };
190 : : struct nfs3_accessres res;
191 : 0 : struct rpc_message msg = {
192 : : .rpc_proc = &nfs3_procedures[NFS3PROC_ACCESS],
193 : : .rpc_argp = &arg,
194 : : .rpc_resp = &res,
195 : 0 : .rpc_cred = entry->cred,
196 : : };
197 : 0 : int mode = entry->mask;
198 : : int status = -ENOMEM;
199 : :
200 : : dprintk("NFS call access\n");
201 : :
202 [ # # ]: 0 : if (mode & MAY_READ)
203 : 0 : arg.access |= NFS3_ACCESS_READ;
204 [ # # ]: 0 : if (S_ISDIR(inode->i_mode)) {
205 [ # # ]: 0 : if (mode & MAY_WRITE)
206 : 0 : arg.access |= NFS3_ACCESS_MODIFY | NFS3_ACCESS_EXTEND | NFS3_ACCESS_DELETE;
207 [ # # ]: 0 : if (mode & MAY_EXEC)
208 : 0 : arg.access |= NFS3_ACCESS_LOOKUP;
209 : : } else {
210 [ # # ]: 0 : if (mode & MAY_WRITE)
211 : 0 : arg.access |= NFS3_ACCESS_MODIFY | NFS3_ACCESS_EXTEND;
212 [ # # ]: 0 : if (mode & MAY_EXEC)
213 : 0 : arg.access |= NFS3_ACCESS_EXECUTE;
214 : : }
215 : :
216 : 0 : res.fattr = nfs_alloc_fattr();
217 [ # # ]: 0 : if (res.fattr == NULL)
218 : : goto out;
219 : :
220 : 0 : status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
221 : 0 : nfs_refresh_inode(inode, res.fattr);
222 [ # # ]: 0 : if (status == 0) {
223 : 0 : entry->mask = 0;
224 [ # # ]: 0 : if (res.access & NFS3_ACCESS_READ)
225 : 0 : entry->mask |= MAY_READ;
226 [ # # ]: 0 : if (res.access & (NFS3_ACCESS_MODIFY | NFS3_ACCESS_EXTEND | NFS3_ACCESS_DELETE))
227 : 0 : entry->mask |= MAY_WRITE;
228 [ # # ]: 0 : if (res.access & (NFS3_ACCESS_LOOKUP|NFS3_ACCESS_EXECUTE))
229 : 0 : entry->mask |= MAY_EXEC;
230 : : }
231 : 0 : nfs_free_fattr(res.fattr);
232 : : out:
233 : : dprintk("NFS reply access: %d\n", status);
234 : 0 : return status;
235 : : }
236 : :
237 : 0 : static int nfs3_proc_readlink(struct inode *inode, struct page *page,
238 : : unsigned int pgbase, unsigned int pglen)
239 : : {
240 : : struct nfs_fattr *fattr;
241 : 0 : struct nfs3_readlinkargs args = {
242 : 0 : .fh = NFS_FH(inode),
243 : : .pgbase = pgbase,
244 : : .pglen = pglen,
245 : : .pages = &page
246 : : };
247 : 0 : struct rpc_message msg = {
248 : : .rpc_proc = &nfs3_procedures[NFS3PROC_READLINK],
249 : : .rpc_argp = &args,
250 : : };
251 : : int status = -ENOMEM;
252 : :
253 : : dprintk("NFS call readlink\n");
254 : 0 : fattr = nfs_alloc_fattr();
255 [ # # ]: 0 : if (fattr == NULL)
256 : : goto out;
257 : 0 : msg.rpc_resp = fattr;
258 : :
259 : 0 : status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
260 : 0 : nfs_refresh_inode(inode, fattr);
261 : : nfs_free_fattr(fattr);
262 : : out:
263 : : dprintk("NFS reply readlink: %d\n", status);
264 : 0 : return status;
265 : : }
266 : :
267 : : struct nfs3_createdata {
268 : : struct rpc_message msg;
269 : : union {
270 : : struct nfs3_createargs create;
271 : : struct nfs3_mkdirargs mkdir;
272 : : struct nfs3_symlinkargs symlink;
273 : : struct nfs3_mknodargs mknod;
274 : : } arg;
275 : : struct nfs3_diropres res;
276 : : struct nfs_fh fh;
277 : : struct nfs_fattr fattr;
278 : : struct nfs_fattr dir_attr;
279 : : };
280 : :
281 : 0 : static struct nfs3_createdata *nfs3_alloc_createdata(void)
282 : : {
283 : : struct nfs3_createdata *data;
284 : :
285 : : data = kzalloc(sizeof(*data), GFP_KERNEL);
286 [ # # ]: 0 : if (data != NULL) {
287 : 0 : data->msg.rpc_argp = &data->arg;
288 : 0 : data->msg.rpc_resp = &data->res;
289 : 0 : data->res.fh = &data->fh;
290 : 0 : data->res.fattr = &data->fattr;
291 : 0 : data->res.dir_attr = &data->dir_attr;
292 : 0 : nfs_fattr_init(data->res.fattr);
293 : 0 : nfs_fattr_init(data->res.dir_attr);
294 : : }
295 : 0 : return data;
296 : : }
297 : :
298 : 0 : static int nfs3_do_create(struct inode *dir, struct dentry *dentry, struct nfs3_createdata *data)
299 : : {
300 : : int status;
301 : :
302 : 0 : status = rpc_call_sync(NFS_CLIENT(dir), &data->msg, 0);
303 : 0 : nfs_post_op_update_inode(dir, data->res.dir_attr);
304 [ # # ]: 0 : if (status == 0)
305 : 0 : status = nfs_instantiate(dentry, data->res.fh, data->res.fattr, NULL);
306 : 0 : return status;
307 : : }
308 : :
309 : : static void nfs3_free_createdata(struct nfs3_createdata *data)
310 : : {
311 : 0 : kfree(data);
312 : : }
313 : :
314 : : /*
315 : : * Create a regular file.
316 : : */
317 : : static int
318 : 0 : nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
319 : : int flags)
320 : : {
321 : : struct posix_acl *default_acl, *acl;
322 : : struct nfs3_createdata *data;
323 : : int status = -ENOMEM;
324 : :
325 : : dprintk("NFS call create %pd\n", dentry);
326 : :
327 : 0 : data = nfs3_alloc_createdata();
328 [ # # ]: 0 : if (data == NULL)
329 : : goto out;
330 : :
331 : 0 : data->msg.rpc_proc = &nfs3_procedures[NFS3PROC_CREATE];
332 : 0 : data->arg.create.fh = NFS_FH(dir);
333 : 0 : data->arg.create.name = dentry->d_name.name;
334 : 0 : data->arg.create.len = dentry->d_name.len;
335 : 0 : data->arg.create.sattr = sattr;
336 : :
337 : 0 : data->arg.create.createmode = NFS3_CREATE_UNCHECKED;
338 [ # # ]: 0 : if (flags & O_EXCL) {
339 : 0 : data->arg.create.createmode = NFS3_CREATE_EXCLUSIVE;
340 : 0 : data->arg.create.verifier[0] = cpu_to_be32(jiffies);
341 [ # # ]: 0 : data->arg.create.verifier[1] = cpu_to_be32(current->pid);
342 : : }
343 : :
344 : 0 : status = posix_acl_create(dir, &sattr->ia_mode, &default_acl, &acl);
345 [ # # ]: 0 : if (status)
346 : : goto out;
347 : :
348 : : for (;;) {
349 : 0 : status = nfs3_do_create(dir, dentry, data);
350 : :
351 [ # # ]: 0 : if (status != -ENOTSUPP)
352 : : break;
353 : : /* If the server doesn't support the exclusive creation
354 : : * semantics, try again with simple 'guarded' mode. */
355 [ # # # # ]: 0 : switch (data->arg.create.createmode) {
356 : : case NFS3_CREATE_EXCLUSIVE:
357 : 0 : data->arg.create.createmode = NFS3_CREATE_GUARDED;
358 : 0 : break;
359 : :
360 : : case NFS3_CREATE_GUARDED:
361 : 0 : data->arg.create.createmode = NFS3_CREATE_UNCHECKED;
362 : 0 : break;
363 : :
364 : : case NFS3_CREATE_UNCHECKED:
365 : : goto out;
366 : : }
367 : 0 : nfs_fattr_init(data->res.dir_attr);
368 : 0 : nfs_fattr_init(data->res.fattr);
369 : 0 : }
370 : :
371 [ # # ]: 0 : if (status != 0)
372 : : goto out_release_acls;
373 : :
374 : : /* When we created the file with exclusive semantics, make
375 : : * sure we set the attributes afterwards. */
376 [ # # ]: 0 : if (data->arg.create.createmode == NFS3_CREATE_EXCLUSIVE) {
377 : : dprintk("NFS call setattr (post-create)\n");
378 : :
379 [ # # ]: 0 : if (!(sattr->ia_valid & ATTR_ATIME_SET))
380 : 0 : sattr->ia_valid |= ATTR_ATIME;
381 [ # # ]: 0 : if (!(sattr->ia_valid & ATTR_MTIME_SET))
382 : 0 : sattr->ia_valid |= ATTR_MTIME;
383 : :
384 : : /* Note: we could use a guarded setattr here, but I'm
385 : : * not sure this buys us anything (and I'd have
386 : : * to revamp the NFSv3 XDR code) */
387 : 0 : status = nfs3_proc_setattr(dentry, data->res.fattr, sattr);
388 : 0 : nfs_post_op_update_inode(dentry->d_inode, data->res.fattr);
389 : : dprintk("NFS reply setattr (post-create): %d\n", status);
390 [ # # ]: 0 : if (status != 0)
391 : : goto out_release_acls;
392 : : }
393 : :
394 : 0 : status = nfs3_proc_setacls(dentry->d_inode, acl, default_acl);
395 : :
396 : : out_release_acls:
397 : 0 : posix_acl_release(acl);
398 : 0 : posix_acl_release(default_acl);
399 : : out:
400 : : nfs3_free_createdata(data);
401 : : dprintk("NFS reply create: %d\n", status);
402 : 0 : return status;
403 : : }
404 : :
405 : : static int
406 : 0 : nfs3_proc_remove(struct inode *dir, struct qstr *name)
407 : : {
408 : 0 : struct nfs_removeargs arg = {
409 : 0 : .fh = NFS_FH(dir),
410 : : .name = *name,
411 : : };
412 : : struct nfs_removeres res;
413 : 0 : struct rpc_message msg = {
414 : : .rpc_proc = &nfs3_procedures[NFS3PROC_REMOVE],
415 : : .rpc_argp = &arg,
416 : : .rpc_resp = &res,
417 : : };
418 : : int status = -ENOMEM;
419 : :
420 : : dprintk("NFS call remove %s\n", name->name);
421 : 0 : res.dir_attr = nfs_alloc_fattr();
422 [ # # ]: 0 : if (res.dir_attr == NULL)
423 : : goto out;
424 : :
425 : 0 : status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
426 : 0 : nfs_post_op_update_inode(dir, res.dir_attr);
427 : 0 : nfs_free_fattr(res.dir_attr);
428 : : out:
429 : : dprintk("NFS reply remove: %d\n", status);
430 : 0 : return status;
431 : : }
432 : :
433 : : static void
434 : 0 : nfs3_proc_unlink_setup(struct rpc_message *msg, struct inode *dir)
435 : : {
436 : 0 : msg->rpc_proc = &nfs3_procedures[NFS3PROC_REMOVE];
437 : 0 : }
438 : :
439 : 0 : static void nfs3_proc_unlink_rpc_prepare(struct rpc_task *task, struct nfs_unlinkdata *data)
440 : : {
441 : 0 : rpc_call_start(task);
442 : 0 : }
443 : :
444 : : static int
445 : 0 : nfs3_proc_unlink_done(struct rpc_task *task, struct inode *dir)
446 : : {
447 : : struct nfs_removeres *res;
448 [ # # ]: 0 : if (nfs3_async_handle_jukebox(task, dir))
449 : : return 0;
450 : 0 : res = task->tk_msg.rpc_resp;
451 : 0 : nfs_post_op_update_inode(dir, res->dir_attr);
452 : 0 : return 1;
453 : : }
454 : :
455 : : static void
456 : 0 : nfs3_proc_rename_setup(struct rpc_message *msg, struct inode *dir)
457 : : {
458 : 0 : msg->rpc_proc = &nfs3_procedures[NFS3PROC_RENAME];
459 : 0 : }
460 : :
461 : 0 : static void nfs3_proc_rename_rpc_prepare(struct rpc_task *task, struct nfs_renamedata *data)
462 : : {
463 : 0 : rpc_call_start(task);
464 : 0 : }
465 : :
466 : : static int
467 : 0 : nfs3_proc_rename_done(struct rpc_task *task, struct inode *old_dir,
468 : : struct inode *new_dir)
469 : : {
470 : : struct nfs_renameres *res;
471 : :
472 [ # # ]: 0 : if (nfs3_async_handle_jukebox(task, old_dir))
473 : : return 0;
474 : 0 : res = task->tk_msg.rpc_resp;
475 : :
476 : 0 : nfs_post_op_update_inode(old_dir, res->old_fattr);
477 : 0 : nfs_post_op_update_inode(new_dir, res->new_fattr);
478 : 0 : return 1;
479 : : }
480 : :
481 : : static int
482 : 0 : nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name,
483 : : struct inode *new_dir, struct qstr *new_name)
484 : : {
485 : 0 : struct nfs_renameargs arg = {
486 : 0 : .old_dir = NFS_FH(old_dir),
487 : : .old_name = old_name,
488 : 0 : .new_dir = NFS_FH(new_dir),
489 : : .new_name = new_name,
490 : : };
491 : : struct nfs_renameres res;
492 : 0 : struct rpc_message msg = {
493 : : .rpc_proc = &nfs3_procedures[NFS3PROC_RENAME],
494 : : .rpc_argp = &arg,
495 : : .rpc_resp = &res,
496 : : };
497 : : int status = -ENOMEM;
498 : :
499 : : dprintk("NFS call rename %s -> %s\n", old_name->name, new_name->name);
500 : :
501 : 0 : res.old_fattr = nfs_alloc_fattr();
502 : 0 : res.new_fattr = nfs_alloc_fattr();
503 [ # # ][ # # ]: 0 : if (res.old_fattr == NULL || res.new_fattr == NULL)
504 : : goto out;
505 : :
506 : 0 : status = rpc_call_sync(NFS_CLIENT(old_dir), &msg, 0);
507 : 0 : nfs_post_op_update_inode(old_dir, res.old_fattr);
508 : 0 : nfs_post_op_update_inode(new_dir, res.new_fattr);
509 : : out:
510 : 0 : nfs_free_fattr(res.old_fattr);
511 : 0 : nfs_free_fattr(res.new_fattr);
512 : : dprintk("NFS reply rename: %d\n", status);
513 : 0 : return status;
514 : : }
515 : :
516 : : static int
517 : 0 : nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
518 : : {
519 : 0 : struct nfs3_linkargs arg = {
520 : 0 : .fromfh = NFS_FH(inode),
521 : 0 : .tofh = NFS_FH(dir),
522 : 0 : .toname = name->name,
523 : 0 : .tolen = name->len
524 : : };
525 : : struct nfs3_linkres res;
526 : 0 : struct rpc_message msg = {
527 : : .rpc_proc = &nfs3_procedures[NFS3PROC_LINK],
528 : : .rpc_argp = &arg,
529 : : .rpc_resp = &res,
530 : : };
531 : : int status = -ENOMEM;
532 : :
533 : : dprintk("NFS call link %s\n", name->name);
534 : 0 : res.fattr = nfs_alloc_fattr();
535 : 0 : res.dir_attr = nfs_alloc_fattr();
536 [ # # ][ # # ]: 0 : if (res.fattr == NULL || res.dir_attr == NULL)
537 : : goto out;
538 : :
539 : 0 : status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
540 : 0 : nfs_post_op_update_inode(dir, res.dir_attr);
541 : 0 : nfs_post_op_update_inode(inode, res.fattr);
542 : : out:
543 : 0 : nfs_free_fattr(res.dir_attr);
544 : 0 : nfs_free_fattr(res.fattr);
545 : : dprintk("NFS reply link: %d\n", status);
546 : 0 : return status;
547 : : }
548 : :
549 : : static int
550 : 0 : nfs3_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page,
551 : : unsigned int len, struct iattr *sattr)
552 : : {
553 : : struct nfs3_createdata *data;
554 : : int status = -ENOMEM;
555 : :
556 [ # # ]: 0 : if (len > NFS3_MAXPATHLEN)
557 : : return -ENAMETOOLONG;
558 : :
559 : : dprintk("NFS call symlink %pd\n", dentry);
560 : :
561 : 0 : data = nfs3_alloc_createdata();
562 [ # # ]: 0 : if (data == NULL)
563 : : goto out;
564 : 0 : data->msg.rpc_proc = &nfs3_procedures[NFS3PROC_SYMLINK];
565 : 0 : data->arg.symlink.fromfh = NFS_FH(dir);
566 : 0 : data->arg.symlink.fromname = dentry->d_name.name;
567 : 0 : data->arg.symlink.fromlen = dentry->d_name.len;
568 : 0 : data->arg.symlink.pages = &page;
569 : 0 : data->arg.symlink.pathlen = len;
570 : 0 : data->arg.symlink.sattr = sattr;
571 : :
572 : 0 : status = nfs3_do_create(dir, dentry, data);
573 : :
574 : : nfs3_free_createdata(data);
575 : : out:
576 : : dprintk("NFS reply symlink: %d\n", status);
577 : 0 : return status;
578 : : }
579 : :
580 : : static int
581 : 0 : nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr)
582 : : {
583 : : struct posix_acl *default_acl, *acl;
584 : : struct nfs3_createdata *data;
585 : : int status = -ENOMEM;
586 : :
587 : : dprintk("NFS call mkdir %pd\n", dentry);
588 : :
589 : 0 : data = nfs3_alloc_createdata();
590 [ # # ]: 0 : if (data == NULL)
591 : : goto out;
592 : :
593 : 0 : status = posix_acl_create(dir, &sattr->ia_mode, &default_acl, &acl);
594 [ # # ]: 0 : if (status)
595 : : goto out;
596 : :
597 : 0 : data->msg.rpc_proc = &nfs3_procedures[NFS3PROC_MKDIR];
598 : 0 : data->arg.mkdir.fh = NFS_FH(dir);
599 : 0 : data->arg.mkdir.name = dentry->d_name.name;
600 : 0 : data->arg.mkdir.len = dentry->d_name.len;
601 : 0 : data->arg.mkdir.sattr = sattr;
602 : :
603 : 0 : status = nfs3_do_create(dir, dentry, data);
604 [ # # ]: 0 : if (status != 0)
605 : : goto out_release_acls;
606 : :
607 : 0 : status = nfs3_proc_setacls(dentry->d_inode, acl, default_acl);
608 : :
609 : : out_release_acls:
610 : 0 : posix_acl_release(acl);
611 : 0 : posix_acl_release(default_acl);
612 : : out:
613 : : nfs3_free_createdata(data);
614 : : dprintk("NFS reply mkdir: %d\n", status);
615 : 0 : return status;
616 : : }
617 : :
618 : : static int
619 : 0 : nfs3_proc_rmdir(struct inode *dir, struct qstr *name)
620 : : {
621 : : struct nfs_fattr *dir_attr;
622 : 0 : struct nfs3_diropargs arg = {
623 : 0 : .fh = NFS_FH(dir),
624 : 0 : .name = name->name,
625 : 0 : .len = name->len
626 : : };
627 : 0 : struct rpc_message msg = {
628 : : .rpc_proc = &nfs3_procedures[NFS3PROC_RMDIR],
629 : : .rpc_argp = &arg,
630 : : };
631 : : int status = -ENOMEM;
632 : :
633 : : dprintk("NFS call rmdir %s\n", name->name);
634 : 0 : dir_attr = nfs_alloc_fattr();
635 [ # # ]: 0 : if (dir_attr == NULL)
636 : : goto out;
637 : :
638 : 0 : msg.rpc_resp = dir_attr;
639 : 0 : status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
640 : 0 : nfs_post_op_update_inode(dir, dir_attr);
641 : : nfs_free_fattr(dir_attr);
642 : : out:
643 : : dprintk("NFS reply rmdir: %d\n", status);
644 : 0 : return status;
645 : : }
646 : :
647 : : /*
648 : : * The READDIR implementation is somewhat hackish - we pass the user buffer
649 : : * to the encode function, which installs it in the receive iovec.
650 : : * The decode function itself doesn't perform any decoding, it just makes
651 : : * sure the reply is syntactically correct.
652 : : *
653 : : * Also note that this implementation handles both plain readdir and
654 : : * readdirplus.
655 : : */
656 : : static int
657 : 0 : nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
658 : : u64 cookie, struct page **pages, unsigned int count, int plus)
659 : : {
660 : 0 : struct inode *dir = dentry->d_inode;
661 : 0 : __be32 *verf = NFS_I(dir)->cookieverf;
662 : 0 : struct nfs3_readdirargs arg = {
663 : 0 : .fh = NFS_FH(dir),
664 : : .cookie = cookie,
665 : 0 : .verf = {verf[0], verf[1]},
666 : : .plus = plus,
667 : : .count = count,
668 : : .pages = pages
669 : : };
670 : 0 : struct nfs3_readdirres res = {
671 : : .verf = verf,
672 : : .plus = plus
673 : : };
674 : 0 : struct rpc_message msg = {
675 : : .rpc_proc = &nfs3_procedures[NFS3PROC_READDIR],
676 : : .rpc_argp = &arg,
677 : : .rpc_resp = &res,
678 : : .rpc_cred = cred
679 : : };
680 : : int status = -ENOMEM;
681 : :
682 [ # # ]: 0 : if (plus)
683 : 0 : msg.rpc_proc = &nfs3_procedures[NFS3PROC_READDIRPLUS];
684 : :
685 : : dprintk("NFS call readdir%s %d\n",
686 : : plus? "plus" : "", (unsigned int) cookie);
687 : :
688 : 0 : res.dir_attr = nfs_alloc_fattr();
689 [ # # ]: 0 : if (res.dir_attr == NULL)
690 : : goto out;
691 : :
692 : 0 : status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
693 : :
694 : 0 : nfs_invalidate_atime(dir);
695 : 0 : nfs_refresh_inode(dir, res.dir_attr);
696 : :
697 : 0 : nfs_free_fattr(res.dir_attr);
698 : : out:
699 : : dprintk("NFS reply readdir%s: %d\n",
700 : : plus? "plus" : "", status);
701 : 0 : return status;
702 : : }
703 : :
704 : : static int
705 : 0 : nfs3_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
706 : : dev_t rdev)
707 : : {
708 : : struct posix_acl *default_acl, *acl;
709 : : struct nfs3_createdata *data;
710 : : int status = -ENOMEM;
711 : :
712 : : dprintk("NFS call mknod %pd %u:%u\n", dentry,
713 : : MAJOR(rdev), MINOR(rdev));
714 : :
715 : 0 : data = nfs3_alloc_createdata();
716 [ # # ]: 0 : if (data == NULL)
717 : : goto out;
718 : :
719 : 0 : status = posix_acl_create(dir, &sattr->ia_mode, &default_acl, &acl);
720 [ # # ]: 0 : if (status)
721 : : goto out;
722 : :
723 : 0 : data->msg.rpc_proc = &nfs3_procedures[NFS3PROC_MKNOD];
724 : 0 : data->arg.mknod.fh = NFS_FH(dir);
725 : 0 : data->arg.mknod.name = dentry->d_name.name;
726 : 0 : data->arg.mknod.len = dentry->d_name.len;
727 : 0 : data->arg.mknod.sattr = sattr;
728 : 0 : data->arg.mknod.rdev = rdev;
729 : :
730 [ # # # # : 0 : switch (sattr->ia_mode & S_IFMT) {
# ]
731 : : case S_IFBLK:
732 : 0 : data->arg.mknod.type = NF3BLK;
733 : 0 : break;
734 : : case S_IFCHR:
735 : 0 : data->arg.mknod.type = NF3CHR;
736 : 0 : break;
737 : : case S_IFIFO:
738 : 0 : data->arg.mknod.type = NF3FIFO;
739 : 0 : break;
740 : : case S_IFSOCK:
741 : 0 : data->arg.mknod.type = NF3SOCK;
742 : 0 : break;
743 : : default:
744 : : status = -EINVAL;
745 : : goto out;
746 : : }
747 : :
748 : 0 : status = nfs3_do_create(dir, dentry, data);
749 [ # # ]: 0 : if (status != 0)
750 : : goto out_release_acls;
751 : :
752 : 0 : status = nfs3_proc_setacls(dentry->d_inode, acl, default_acl);
753 : :
754 : : out_release_acls:
755 : 0 : posix_acl_release(acl);
756 : 0 : posix_acl_release(default_acl);
757 : : out:
758 : : nfs3_free_createdata(data);
759 : : dprintk("NFS reply mknod: %d\n", status);
760 : 0 : return status;
761 : : }
762 : :
763 : : static int
764 : 0 : nfs3_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
765 : : struct nfs_fsstat *stat)
766 : : {
767 : 0 : struct rpc_message msg = {
768 : : .rpc_proc = &nfs3_procedures[NFS3PROC_FSSTAT],
769 : : .rpc_argp = fhandle,
770 : : .rpc_resp = stat,
771 : : };
772 : : int status;
773 : :
774 : : dprintk("NFS call fsstat\n");
775 : 0 : nfs_fattr_init(stat->fattr);
776 : 0 : status = rpc_call_sync(server->client, &msg, 0);
777 : : dprintk("NFS reply fsstat: %d\n", status);
778 : 0 : return status;
779 : : }
780 : :
781 : : static int
782 : 0 : do_proc_fsinfo(struct rpc_clnt *client, struct nfs_fh *fhandle,
783 : : struct nfs_fsinfo *info)
784 : : {
785 : 0 : struct rpc_message msg = {
786 : : .rpc_proc = &nfs3_procedures[NFS3PROC_FSINFO],
787 : : .rpc_argp = fhandle,
788 : : .rpc_resp = info,
789 : : };
790 : : int status;
791 : :
792 : : dprintk("NFS call fsinfo\n");
793 : 0 : nfs_fattr_init(info->fattr);
794 : 0 : status = rpc_call_sync(client, &msg, 0);
795 : : dprintk("NFS reply fsinfo: %d\n", status);
796 : 0 : return status;
797 : : }
798 : :
799 : : /*
800 : : * Bare-bones access to fsinfo: this is for nfs_get_root/nfs_get_sb via
801 : : * nfs_create_server
802 : : */
803 : : static int
804 : 0 : nfs3_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
805 : : struct nfs_fsinfo *info)
806 : : {
807 : : int status;
808 : :
809 : 0 : status = do_proc_fsinfo(server->client, fhandle, info);
810 [ # # ][ # # ]: 0 : if (status && server->nfs_client->cl_rpcclient != server->client)
811 : 0 : status = do_proc_fsinfo(server->nfs_client->cl_rpcclient, fhandle, info);
812 : 0 : return status;
813 : : }
814 : :
815 : : static int
816 : 0 : nfs3_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
817 : : struct nfs_pathconf *info)
818 : : {
819 : 0 : struct rpc_message msg = {
820 : : .rpc_proc = &nfs3_procedures[NFS3PROC_PATHCONF],
821 : : .rpc_argp = fhandle,
822 : : .rpc_resp = info,
823 : : };
824 : : int status;
825 : :
826 : : dprintk("NFS call pathconf\n");
827 : 0 : nfs_fattr_init(info->fattr);
828 : 0 : status = rpc_call_sync(server->client, &msg, 0);
829 : : dprintk("NFS reply pathconf: %d\n", status);
830 : 0 : return status;
831 : : }
832 : :
833 : 0 : static int nfs3_read_done(struct rpc_task *task, struct nfs_read_data *data)
834 : : {
835 : 0 : struct inode *inode = data->header->inode;
836 : :
837 [ # # ]: 0 : if (nfs3_async_handle_jukebox(task, inode))
838 : : return -EAGAIN;
839 : :
840 : 0 : nfs_invalidate_atime(inode);
841 : 0 : nfs_refresh_inode(inode, &data->fattr);
842 : 0 : return 0;
843 : : }
844 : :
845 : 0 : static void nfs3_proc_read_setup(struct nfs_read_data *data, struct rpc_message *msg)
846 : : {
847 : 0 : msg->rpc_proc = &nfs3_procedures[NFS3PROC_READ];
848 : 0 : }
849 : :
850 : 0 : static int nfs3_proc_read_rpc_prepare(struct rpc_task *task, struct nfs_read_data *data)
851 : : {
852 : 0 : rpc_call_start(task);
853 : 0 : return 0;
854 : : }
855 : :
856 : 0 : static int nfs3_write_done(struct rpc_task *task, struct nfs_write_data *data)
857 : : {
858 : 0 : struct inode *inode = data->header->inode;
859 : :
860 [ # # ]: 0 : if (nfs3_async_handle_jukebox(task, inode))
861 : : return -EAGAIN;
862 [ # # ]: 0 : if (task->tk_status >= 0)
863 : 0 : nfs_post_op_update_inode_force_wcc(inode, data->res.fattr);
864 : : return 0;
865 : : }
866 : :
867 : 0 : static void nfs3_proc_write_setup(struct nfs_write_data *data, struct rpc_message *msg)
868 : : {
869 : 0 : msg->rpc_proc = &nfs3_procedures[NFS3PROC_WRITE];
870 : 0 : }
871 : :
872 : 0 : static int nfs3_proc_write_rpc_prepare(struct rpc_task *task, struct nfs_write_data *data)
873 : : {
874 : 0 : rpc_call_start(task);
875 : 0 : return 0;
876 : : }
877 : :
878 : 0 : static void nfs3_proc_commit_rpc_prepare(struct rpc_task *task, struct nfs_commit_data *data)
879 : : {
880 : 0 : rpc_call_start(task);
881 : 0 : }
882 : :
883 : 0 : static int nfs3_commit_done(struct rpc_task *task, struct nfs_commit_data *data)
884 : : {
885 [ # # ]: 0 : if (nfs3_async_handle_jukebox(task, data->inode))
886 : : return -EAGAIN;
887 : 0 : nfs_refresh_inode(data->inode, data->res.fattr);
888 : 0 : return 0;
889 : : }
890 : :
891 : 0 : static void nfs3_proc_commit_setup(struct nfs_commit_data *data, struct rpc_message *msg)
892 : : {
893 : 0 : msg->rpc_proc = &nfs3_procedures[NFS3PROC_COMMIT];
894 : 0 : }
895 : :
896 : : static int
897 : 0 : nfs3_proc_lock(struct file *filp, int cmd, struct file_lock *fl)
898 : : {
899 : 0 : struct inode *inode = file_inode(filp);
900 : :
901 : 0 : return nlmclnt_proc(NFS_SERVER(inode)->nlm_host, cmd, fl);
902 : : }
903 : :
904 : 0 : static int nfs3_have_delegation(struct inode *inode, fmode_t flags)
905 : : {
906 : 0 : return 0;
907 : : }
908 : :
909 : 0 : static int nfs3_return_delegation(struct inode *inode)
910 : : {
911 : 0 : nfs_wb_all(inode);
912 : 0 : return 0;
913 : : }
914 : :
915 : : static const struct inode_operations nfs3_dir_inode_operations = {
916 : : .create = nfs_create,
917 : : .lookup = nfs_lookup,
918 : : .link = nfs_link,
919 : : .unlink = nfs_unlink,
920 : : .symlink = nfs_symlink,
921 : : .mkdir = nfs_mkdir,
922 : : .rmdir = nfs_rmdir,
923 : : .mknod = nfs_mknod,
924 : : .rename = nfs_rename,
925 : : .permission = nfs_permission,
926 : : .getattr = nfs_getattr,
927 : : .setattr = nfs_setattr,
928 : : #ifdef CONFIG_NFS_V3_ACL
929 : : .listxattr = generic_listxattr,
930 : : .getxattr = generic_getxattr,
931 : : .setxattr = generic_setxattr,
932 : : .removexattr = generic_removexattr,
933 : : .get_acl = nfs3_get_acl,
934 : : .set_acl = nfs3_set_acl,
935 : : #endif
936 : : };
937 : :
938 : : static const struct inode_operations nfs3_file_inode_operations = {
939 : : .permission = nfs_permission,
940 : : .getattr = nfs_getattr,
941 : : .setattr = nfs_setattr,
942 : : #ifdef CONFIG_NFS_V3_ACL
943 : : .listxattr = generic_listxattr,
944 : : .getxattr = generic_getxattr,
945 : : .setxattr = generic_setxattr,
946 : : .removexattr = generic_removexattr,
947 : : .get_acl = nfs3_get_acl,
948 : : .set_acl = nfs3_set_acl,
949 : : #endif
950 : : };
951 : :
952 : : const struct nfs_rpc_ops nfs_v3_clientops = {
953 : : .version = 3, /* protocol version */
954 : : .dentry_ops = &nfs_dentry_operations,
955 : : .dir_inode_ops = &nfs3_dir_inode_operations,
956 : : .file_inode_ops = &nfs3_file_inode_operations,
957 : : .file_ops = &nfs_file_operations,
958 : : .getroot = nfs3_proc_get_root,
959 : : .submount = nfs_submount,
960 : : .try_mount = nfs_try_mount,
961 : : .getattr = nfs3_proc_getattr,
962 : : .setattr = nfs3_proc_setattr,
963 : : .lookup = nfs3_proc_lookup,
964 : : .access = nfs3_proc_access,
965 : : .readlink = nfs3_proc_readlink,
966 : : .create = nfs3_proc_create,
967 : : .remove = nfs3_proc_remove,
968 : : .unlink_setup = nfs3_proc_unlink_setup,
969 : : .unlink_rpc_prepare = nfs3_proc_unlink_rpc_prepare,
970 : : .unlink_done = nfs3_proc_unlink_done,
971 : : .rename = nfs3_proc_rename,
972 : : .rename_setup = nfs3_proc_rename_setup,
973 : : .rename_rpc_prepare = nfs3_proc_rename_rpc_prepare,
974 : : .rename_done = nfs3_proc_rename_done,
975 : : .link = nfs3_proc_link,
976 : : .symlink = nfs3_proc_symlink,
977 : : .mkdir = nfs3_proc_mkdir,
978 : : .rmdir = nfs3_proc_rmdir,
979 : : .readdir = nfs3_proc_readdir,
980 : : .mknod = nfs3_proc_mknod,
981 : : .statfs = nfs3_proc_statfs,
982 : : .fsinfo = nfs3_proc_fsinfo,
983 : : .pathconf = nfs3_proc_pathconf,
984 : : .decode_dirent = nfs3_decode_dirent,
985 : : .read_setup = nfs3_proc_read_setup,
986 : : .read_pageio_init = nfs_pageio_init_read,
987 : : .read_rpc_prepare = nfs3_proc_read_rpc_prepare,
988 : : .read_done = nfs3_read_done,
989 : : .write_setup = nfs3_proc_write_setup,
990 : : .write_pageio_init = nfs_pageio_init_write,
991 : : .write_rpc_prepare = nfs3_proc_write_rpc_prepare,
992 : : .write_done = nfs3_write_done,
993 : : .commit_setup = nfs3_proc_commit_setup,
994 : : .commit_rpc_prepare = nfs3_proc_commit_rpc_prepare,
995 : : .commit_done = nfs3_commit_done,
996 : : .lock = nfs3_proc_lock,
997 : : .clear_acl_cache = forget_all_cached_acls,
998 : : .close_context = nfs_close_context,
999 : : .have_delegation = nfs3_have_delegation,
1000 : : .return_delegation = nfs3_return_delegation,
1001 : : .alloc_client = nfs_alloc_client,
1002 : : .init_client = nfs_init_client,
1003 : : .free_client = nfs_free_client,
1004 : : .create_server = nfs3_create_server,
1005 : : .clone_server = nfs3_clone_server,
1006 : : };
|