diff options
Diffstat (limited to 'fs/nfs/nfs3proc.c')
-rw-r--r-- | fs/nfs/nfs3proc.c | 128 |
1 files changed, 78 insertions, 50 deletions
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index e701002694e5..fabb4f2849a1 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c | |||
@@ -144,14 +144,12 @@ static int | |||
144 | nfs3_proc_lookup(struct inode *dir, struct qstr *name, | 144 | nfs3_proc_lookup(struct inode *dir, struct qstr *name, |
145 | struct nfs_fh *fhandle, struct nfs_fattr *fattr) | 145 | struct nfs_fh *fhandle, struct nfs_fattr *fattr) |
146 | { | 146 | { |
147 | struct nfs_fattr dir_attr; | ||
148 | struct nfs3_diropargs arg = { | 147 | struct nfs3_diropargs arg = { |
149 | .fh = NFS_FH(dir), | 148 | .fh = NFS_FH(dir), |
150 | .name = name->name, | 149 | .name = name->name, |
151 | .len = name->len | 150 | .len = name->len |
152 | }; | 151 | }; |
153 | struct nfs3_diropres res = { | 152 | struct nfs3_diropres res = { |
154 | .dir_attr = &dir_attr, | ||
155 | .fh = fhandle, | 153 | .fh = fhandle, |
156 | .fattr = fattr | 154 | .fattr = fattr |
157 | }; | 155 | }; |
@@ -163,29 +161,30 @@ nfs3_proc_lookup(struct inode *dir, struct qstr *name, | |||
163 | int status; | 161 | int status; |
164 | 162 | ||
165 | dprintk("NFS call lookup %s\n", name->name); | 163 | dprintk("NFS call lookup %s\n", name->name); |
166 | nfs_fattr_init(&dir_attr); | 164 | res.dir_attr = nfs_alloc_fattr(); |
165 | if (res.dir_attr == NULL) | ||
166 | return -ENOMEM; | ||
167 | |||
167 | nfs_fattr_init(fattr); | 168 | nfs_fattr_init(fattr); |
168 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); | 169 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); |
169 | nfs_refresh_inode(dir, &dir_attr); | 170 | nfs_refresh_inode(dir, res.dir_attr); |
170 | if (status >= 0 && !(fattr->valid & NFS_ATTR_FATTR)) { | 171 | if (status >= 0 && !(fattr->valid & NFS_ATTR_FATTR)) { |
171 | msg.rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR]; | 172 | msg.rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR]; |
172 | msg.rpc_argp = fhandle; | 173 | msg.rpc_argp = fhandle; |
173 | msg.rpc_resp = fattr; | 174 | msg.rpc_resp = fattr; |
174 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); | 175 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); |
175 | } | 176 | } |
177 | nfs_free_fattr(res.dir_attr); | ||
176 | dprintk("NFS reply lookup: %d\n", status); | 178 | dprintk("NFS reply lookup: %d\n", status); |
177 | return status; | 179 | return status; |
178 | } | 180 | } |
179 | 181 | ||
180 | static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry) | 182 | static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry) |
181 | { | 183 | { |
182 | struct nfs_fattr fattr; | ||
183 | struct nfs3_accessargs arg = { | 184 | struct nfs3_accessargs arg = { |
184 | .fh = NFS_FH(inode), | 185 | .fh = NFS_FH(inode), |
185 | }; | 186 | }; |
186 | struct nfs3_accessres res = { | 187 | struct nfs3_accessres res; |
187 | .fattr = &fattr, | ||
188 | }; | ||
189 | struct rpc_message msg = { | 188 | struct rpc_message msg = { |
190 | .rpc_proc = &nfs3_procedures[NFS3PROC_ACCESS], | 189 | .rpc_proc = &nfs3_procedures[NFS3PROC_ACCESS], |
191 | .rpc_argp = &arg, | 190 | .rpc_argp = &arg, |
@@ -193,7 +192,7 @@ static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry) | |||
193 | .rpc_cred = entry->cred, | 192 | .rpc_cred = entry->cred, |
194 | }; | 193 | }; |
195 | int mode = entry->mask; | 194 | int mode = entry->mask; |
196 | int status; | 195 | int status = -ENOMEM; |
197 | 196 | ||
198 | dprintk("NFS call access\n"); | 197 | dprintk("NFS call access\n"); |
199 | 198 | ||
@@ -210,9 +209,13 @@ static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry) | |||
210 | if (mode & MAY_EXEC) | 209 | if (mode & MAY_EXEC) |
211 | arg.access |= NFS3_ACCESS_EXECUTE; | 210 | arg.access |= NFS3_ACCESS_EXECUTE; |
212 | } | 211 | } |
213 | nfs_fattr_init(&fattr); | 212 | |
213 | res.fattr = nfs_alloc_fattr(); | ||
214 | if (res.fattr == NULL) | ||
215 | goto out; | ||
216 | |||
214 | status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); | 217 | status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); |
215 | nfs_refresh_inode(inode, &fattr); | 218 | nfs_refresh_inode(inode, res.fattr); |
216 | if (status == 0) { | 219 | if (status == 0) { |
217 | entry->mask = 0; | 220 | entry->mask = 0; |
218 | if (res.access & NFS3_ACCESS_READ) | 221 | if (res.access & NFS3_ACCESS_READ) |
@@ -222,6 +225,8 @@ static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry) | |||
222 | if (res.access & (NFS3_ACCESS_LOOKUP|NFS3_ACCESS_EXECUTE)) | 225 | if (res.access & (NFS3_ACCESS_LOOKUP|NFS3_ACCESS_EXECUTE)) |
223 | entry->mask |= MAY_EXEC; | 226 | entry->mask |= MAY_EXEC; |
224 | } | 227 | } |
228 | nfs_free_fattr(res.fattr); | ||
229 | out: | ||
225 | dprintk("NFS reply access: %d\n", status); | 230 | dprintk("NFS reply access: %d\n", status); |
226 | return status; | 231 | return status; |
227 | } | 232 | } |
@@ -229,7 +234,7 @@ static int nfs3_proc_access(struct inode *inode, struct nfs_access_entry *entry) | |||
229 | static int nfs3_proc_readlink(struct inode *inode, struct page *page, | 234 | static int nfs3_proc_readlink(struct inode *inode, struct page *page, |
230 | unsigned int pgbase, unsigned int pglen) | 235 | unsigned int pgbase, unsigned int pglen) |
231 | { | 236 | { |
232 | struct nfs_fattr fattr; | 237 | struct nfs_fattr *fattr; |
233 | struct nfs3_readlinkargs args = { | 238 | struct nfs3_readlinkargs args = { |
234 | .fh = NFS_FH(inode), | 239 | .fh = NFS_FH(inode), |
235 | .pgbase = pgbase, | 240 | .pgbase = pgbase, |
@@ -239,14 +244,19 @@ static int nfs3_proc_readlink(struct inode *inode, struct page *page, | |||
239 | struct rpc_message msg = { | 244 | struct rpc_message msg = { |
240 | .rpc_proc = &nfs3_procedures[NFS3PROC_READLINK], | 245 | .rpc_proc = &nfs3_procedures[NFS3PROC_READLINK], |
241 | .rpc_argp = &args, | 246 | .rpc_argp = &args, |
242 | .rpc_resp = &fattr, | ||
243 | }; | 247 | }; |
244 | int status; | 248 | int status = -ENOMEM; |
245 | 249 | ||
246 | dprintk("NFS call readlink\n"); | 250 | dprintk("NFS call readlink\n"); |
247 | nfs_fattr_init(&fattr); | 251 | fattr = nfs_alloc_fattr(); |
252 | if (fattr == NULL) | ||
253 | goto out; | ||
254 | msg.rpc_resp = fattr; | ||
255 | |||
248 | status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); | 256 | status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); |
249 | nfs_refresh_inode(inode, &fattr); | 257 | nfs_refresh_inode(inode, fattr); |
258 | nfs_free_fattr(fattr); | ||
259 | out: | ||
250 | dprintk("NFS reply readlink: %d\n", status); | 260 | dprintk("NFS reply readlink: %d\n", status); |
251 | return status; | 261 | return status; |
252 | } | 262 | } |
@@ -396,12 +406,17 @@ nfs3_proc_remove(struct inode *dir, struct qstr *name) | |||
396 | .rpc_argp = &arg, | 406 | .rpc_argp = &arg, |
397 | .rpc_resp = &res, | 407 | .rpc_resp = &res, |
398 | }; | 408 | }; |
399 | int status; | 409 | int status = -ENOMEM; |
400 | 410 | ||
401 | dprintk("NFS call remove %s\n", name->name); | 411 | dprintk("NFS call remove %s\n", name->name); |
402 | nfs_fattr_init(&res.dir_attr); | 412 | res.dir_attr = nfs_alloc_fattr(); |
413 | if (res.dir_attr == NULL) | ||
414 | goto out; | ||
415 | |||
403 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); | 416 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); |
404 | nfs_post_op_update_inode(dir, &res.dir_attr); | 417 | nfs_post_op_update_inode(dir, res.dir_attr); |
418 | nfs_free_fattr(res.dir_attr); | ||
419 | out: | ||
405 | dprintk("NFS reply remove: %d\n", status); | 420 | dprintk("NFS reply remove: %d\n", status); |
406 | return status; | 421 | return status; |
407 | } | 422 | } |
@@ -419,7 +434,7 @@ nfs3_proc_unlink_done(struct rpc_task *task, struct inode *dir) | |||
419 | if (nfs3_async_handle_jukebox(task, dir)) | 434 | if (nfs3_async_handle_jukebox(task, dir)) |
420 | return 0; | 435 | return 0; |
421 | res = task->tk_msg.rpc_resp; | 436 | res = task->tk_msg.rpc_resp; |
422 | nfs_post_op_update_inode(dir, &res->dir_attr); | 437 | nfs_post_op_update_inode(dir, res->dir_attr); |
423 | return 1; | 438 | return 1; |
424 | } | 439 | } |
425 | 440 | ||
@@ -427,7 +442,6 @@ static int | |||
427 | nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name, | 442 | nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name, |
428 | struct inode *new_dir, struct qstr *new_name) | 443 | struct inode *new_dir, struct qstr *new_name) |
429 | { | 444 | { |
430 | struct nfs_fattr old_dir_attr, new_dir_attr; | ||
431 | struct nfs3_renameargs arg = { | 445 | struct nfs3_renameargs arg = { |
432 | .fromfh = NFS_FH(old_dir), | 446 | .fromfh = NFS_FH(old_dir), |
433 | .fromname = old_name->name, | 447 | .fromname = old_name->name, |
@@ -436,23 +450,27 @@ nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name, | |||
436 | .toname = new_name->name, | 450 | .toname = new_name->name, |
437 | .tolen = new_name->len | 451 | .tolen = new_name->len |
438 | }; | 452 | }; |
439 | struct nfs3_renameres res = { | 453 | struct nfs3_renameres res; |
440 | .fromattr = &old_dir_attr, | ||
441 | .toattr = &new_dir_attr | ||
442 | }; | ||
443 | struct rpc_message msg = { | 454 | struct rpc_message msg = { |
444 | .rpc_proc = &nfs3_procedures[NFS3PROC_RENAME], | 455 | .rpc_proc = &nfs3_procedures[NFS3PROC_RENAME], |
445 | .rpc_argp = &arg, | 456 | .rpc_argp = &arg, |
446 | .rpc_resp = &res, | 457 | .rpc_resp = &res, |
447 | }; | 458 | }; |
448 | int status; | 459 | int status = -ENOMEM; |
449 | 460 | ||
450 | dprintk("NFS call rename %s -> %s\n", old_name->name, new_name->name); | 461 | dprintk("NFS call rename %s -> %s\n", old_name->name, new_name->name); |
451 | nfs_fattr_init(&old_dir_attr); | 462 | |
452 | nfs_fattr_init(&new_dir_attr); | 463 | res.fromattr = nfs_alloc_fattr(); |
464 | res.toattr = nfs_alloc_fattr(); | ||
465 | if (res.fromattr == NULL || res.toattr == NULL) | ||
466 | goto out; | ||
467 | |||
453 | status = rpc_call_sync(NFS_CLIENT(old_dir), &msg, 0); | 468 | status = rpc_call_sync(NFS_CLIENT(old_dir), &msg, 0); |
454 | nfs_post_op_update_inode(old_dir, &old_dir_attr); | 469 | nfs_post_op_update_inode(old_dir, res.fromattr); |
455 | nfs_post_op_update_inode(new_dir, &new_dir_attr); | 470 | nfs_post_op_update_inode(new_dir, res.toattr); |
471 | out: | ||
472 | nfs_free_fattr(res.toattr); | ||
473 | nfs_free_fattr(res.fromattr); | ||
456 | dprintk("NFS reply rename: %d\n", status); | 474 | dprintk("NFS reply rename: %d\n", status); |
457 | return status; | 475 | return status; |
458 | } | 476 | } |
@@ -460,30 +478,32 @@ nfs3_proc_rename(struct inode *old_dir, struct qstr *old_name, | |||
460 | static int | 478 | static int |
461 | nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name) | 479 | nfs3_proc_link(struct inode *inode, struct inode *dir, struct qstr *name) |
462 | { | 480 | { |
463 | struct nfs_fattr dir_attr, fattr; | ||
464 | struct nfs3_linkargs arg = { | 481 | struct nfs3_linkargs arg = { |
465 | .fromfh = NFS_FH(inode), | 482 | .fromfh = NFS_FH(inode), |
466 | .tofh = NFS_FH(dir), | 483 | .tofh = NFS_FH(dir), |
467 | .toname = name->name, | 484 | .toname = name->name, |
468 | .tolen = name->len | 485 | .tolen = name->len |
469 | }; | 486 | }; |
470 | struct nfs3_linkres res = { | 487 | struct nfs3_linkres res; |
471 | .dir_attr = &dir_attr, | ||
472 | .fattr = &fattr | ||
473 | }; | ||
474 | struct rpc_message msg = { | 488 | struct rpc_message msg = { |
475 | .rpc_proc = &nfs3_procedures[NFS3PROC_LINK], | 489 | .rpc_proc = &nfs3_procedures[NFS3PROC_LINK], |
476 | .rpc_argp = &arg, | 490 | .rpc_argp = &arg, |
477 | .rpc_resp = &res, | 491 | .rpc_resp = &res, |
478 | }; | 492 | }; |
479 | int status; | 493 | int status = -ENOMEM; |
480 | 494 | ||
481 | dprintk("NFS call link %s\n", name->name); | 495 | dprintk("NFS call link %s\n", name->name); |
482 | nfs_fattr_init(&dir_attr); | 496 | res.fattr = nfs_alloc_fattr(); |
483 | nfs_fattr_init(&fattr); | 497 | res.dir_attr = nfs_alloc_fattr(); |
498 | if (res.fattr == NULL || res.dir_attr == NULL) | ||
499 | goto out; | ||
500 | |||
484 | status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); | 501 | status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0); |
485 | nfs_post_op_update_inode(dir, &dir_attr); | 502 | nfs_post_op_update_inode(dir, res.dir_attr); |
486 | nfs_post_op_update_inode(inode, &fattr); | 503 | nfs_post_op_update_inode(inode, res.fattr); |
504 | out: | ||
505 | nfs_free_fattr(res.dir_attr); | ||
506 | nfs_free_fattr(res.fattr); | ||
487 | dprintk("NFS reply link: %d\n", status); | 507 | dprintk("NFS reply link: %d\n", status); |
488 | return status; | 508 | return status; |
489 | } | 509 | } |
@@ -554,7 +574,7 @@ out: | |||
554 | static int | 574 | static int |
555 | nfs3_proc_rmdir(struct inode *dir, struct qstr *name) | 575 | nfs3_proc_rmdir(struct inode *dir, struct qstr *name) |
556 | { | 576 | { |
557 | struct nfs_fattr dir_attr; | 577 | struct nfs_fattr *dir_attr; |
558 | struct nfs3_diropargs arg = { | 578 | struct nfs3_diropargs arg = { |
559 | .fh = NFS_FH(dir), | 579 | .fh = NFS_FH(dir), |
560 | .name = name->name, | 580 | .name = name->name, |
@@ -563,14 +583,19 @@ nfs3_proc_rmdir(struct inode *dir, struct qstr *name) | |||
563 | struct rpc_message msg = { | 583 | struct rpc_message msg = { |
564 | .rpc_proc = &nfs3_procedures[NFS3PROC_RMDIR], | 584 | .rpc_proc = &nfs3_procedures[NFS3PROC_RMDIR], |
565 | .rpc_argp = &arg, | 585 | .rpc_argp = &arg, |
566 | .rpc_resp = &dir_attr, | ||
567 | }; | 586 | }; |
568 | int status; | 587 | int status = -ENOMEM; |
569 | 588 | ||
570 | dprintk("NFS call rmdir %s\n", name->name); | 589 | dprintk("NFS call rmdir %s\n", name->name); |
571 | nfs_fattr_init(&dir_attr); | 590 | dir_attr = nfs_alloc_fattr(); |
591 | if (dir_attr == NULL) | ||
592 | goto out; | ||
593 | |||
594 | msg.rpc_resp = dir_attr; | ||
572 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); | 595 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); |
573 | nfs_post_op_update_inode(dir, &dir_attr); | 596 | nfs_post_op_update_inode(dir, dir_attr); |
597 | nfs_free_fattr(dir_attr); | ||
598 | out: | ||
574 | dprintk("NFS reply rmdir: %d\n", status); | 599 | dprintk("NFS reply rmdir: %d\n", status); |
575 | return status; | 600 | return status; |
576 | } | 601 | } |
@@ -589,7 +614,6 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, | |||
589 | u64 cookie, struct page *page, unsigned int count, int plus) | 614 | u64 cookie, struct page *page, unsigned int count, int plus) |
590 | { | 615 | { |
591 | struct inode *dir = dentry->d_inode; | 616 | struct inode *dir = dentry->d_inode; |
592 | struct nfs_fattr dir_attr; | ||
593 | __be32 *verf = NFS_COOKIEVERF(dir); | 617 | __be32 *verf = NFS_COOKIEVERF(dir); |
594 | struct nfs3_readdirargs arg = { | 618 | struct nfs3_readdirargs arg = { |
595 | .fh = NFS_FH(dir), | 619 | .fh = NFS_FH(dir), |
@@ -600,7 +624,6 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, | |||
600 | .pages = &page | 624 | .pages = &page |
601 | }; | 625 | }; |
602 | struct nfs3_readdirres res = { | 626 | struct nfs3_readdirres res = { |
603 | .dir_attr = &dir_attr, | ||
604 | .verf = verf, | 627 | .verf = verf, |
605 | .plus = plus | 628 | .plus = plus |
606 | }; | 629 | }; |
@@ -610,7 +633,7 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, | |||
610 | .rpc_resp = &res, | 633 | .rpc_resp = &res, |
611 | .rpc_cred = cred | 634 | .rpc_cred = cred |
612 | }; | 635 | }; |
613 | int status; | 636 | int status = -ENOMEM; |
614 | 637 | ||
615 | if (plus) | 638 | if (plus) |
616 | msg.rpc_proc = &nfs3_procedures[NFS3PROC_READDIRPLUS]; | 639 | msg.rpc_proc = &nfs3_procedures[NFS3PROC_READDIRPLUS]; |
@@ -618,12 +641,17 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, | |||
618 | dprintk("NFS call readdir%s %d\n", | 641 | dprintk("NFS call readdir%s %d\n", |
619 | plus? "plus" : "", (unsigned int) cookie); | 642 | plus? "plus" : "", (unsigned int) cookie); |
620 | 643 | ||
621 | nfs_fattr_init(&dir_attr); | 644 | res.dir_attr = nfs_alloc_fattr(); |
645 | if (res.dir_attr == NULL) | ||
646 | goto out; | ||
647 | |||
622 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); | 648 | status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); |
623 | 649 | ||
624 | nfs_invalidate_atime(dir); | 650 | nfs_invalidate_atime(dir); |
651 | nfs_refresh_inode(dir, res.dir_attr); | ||
625 | 652 | ||
626 | nfs_refresh_inode(dir, &dir_attr); | 653 | nfs_free_fattr(res.dir_attr); |
654 | out: | ||
627 | dprintk("NFS reply readdir: %d\n", status); | 655 | dprintk("NFS reply readdir: %d\n", status); |
628 | return status; | 656 | return status; |
629 | } | 657 | } |