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