diff options
author | Benjamin Coddington <bcodding@redhat.com> | 2019-09-13 08:29:03 -0400 |
---|---|---|
committer | Anna Schumaker <Anna.Schumaker@Netapp.com> | 2019-09-20 15:15:24 -0400 |
commit | 17fd6e457b30e2e025fce4399fe20ae69c7081dd (patch) | |
tree | 778449585f89a86340062b736e5c253f224a7803 /fs | |
parent | 406cd91533dcc5e82ef2373c39e6a531d944131e (diff) |
NFSv3: use nfs_add_or_obtain() to create and reference inodes
Signed-off-by: Benjamin Coddington <bcodding@redhat.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/nfs3proc.c | 45 |
1 files changed, 36 insertions, 9 deletions
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index a3ad2d46fd42..9eb2f1a503ab 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c | |||
@@ -279,15 +279,17 @@ static struct nfs3_createdata *nfs3_alloc_createdata(void) | |||
279 | return data; | 279 | return data; |
280 | } | 280 | } |
281 | 281 | ||
282 | static int nfs3_do_create(struct inode *dir, struct dentry *dentry, struct nfs3_createdata *data) | 282 | static struct dentry * |
283 | nfs3_do_create(struct inode *dir, struct dentry *dentry, struct nfs3_createdata *data) | ||
283 | { | 284 | { |
284 | int status; | 285 | int status; |
285 | 286 | ||
286 | status = rpc_call_sync(NFS_CLIENT(dir), &data->msg, 0); | 287 | status = rpc_call_sync(NFS_CLIENT(dir), &data->msg, 0); |
287 | nfs_post_op_update_inode(dir, data->res.dir_attr); | 288 | nfs_post_op_update_inode(dir, data->res.dir_attr); |
288 | if (status == 0) | 289 | if (status != 0) |
289 | status = nfs_instantiate(dentry, data->res.fh, data->res.fattr, NULL); | 290 | return ERR_PTR(status); |
290 | return status; | 291 | |
292 | return nfs_add_or_obtain(dentry, data->res.fh, data->res.fattr, NULL); | ||
291 | } | 293 | } |
292 | 294 | ||
293 | static void nfs3_free_createdata(struct nfs3_createdata *data) | 295 | static void nfs3_free_createdata(struct nfs3_createdata *data) |
@@ -304,6 +306,7 @@ nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | |||
304 | { | 306 | { |
305 | struct posix_acl *default_acl, *acl; | 307 | struct posix_acl *default_acl, *acl; |
306 | struct nfs3_createdata *data; | 308 | struct nfs3_createdata *data; |
309 | struct dentry *d_alias; | ||
307 | int status = -ENOMEM; | 310 | int status = -ENOMEM; |
308 | 311 | ||
309 | dprintk("NFS call create %pd\n", dentry); | 312 | dprintk("NFS call create %pd\n", dentry); |
@@ -330,7 +333,8 @@ nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | |||
330 | goto out; | 333 | goto out; |
331 | 334 | ||
332 | for (;;) { | 335 | for (;;) { |
333 | status = nfs3_do_create(dir, dentry, data); | 336 | d_alias = nfs3_do_create(dir, dentry, data); |
337 | status = PTR_ERR_OR_ZERO(d_alias); | ||
334 | 338 | ||
335 | if (status != -ENOTSUPP) | 339 | if (status != -ENOTSUPP) |
336 | break; | 340 | break; |
@@ -355,6 +359,9 @@ nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | |||
355 | if (status != 0) | 359 | if (status != 0) |
356 | goto out_release_acls; | 360 | goto out_release_acls; |
357 | 361 | ||
362 | if (d_alias) | ||
363 | dentry = d_alias; | ||
364 | |||
358 | /* When we created the file with exclusive semantics, make | 365 | /* When we created the file with exclusive semantics, make |
359 | * sure we set the attributes afterwards. */ | 366 | * sure we set the attributes afterwards. */ |
360 | if (data->arg.create.createmode == NFS3_CREATE_EXCLUSIVE) { | 367 | if (data->arg.create.createmode == NFS3_CREATE_EXCLUSIVE) { |
@@ -372,11 +379,13 @@ nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | |||
372 | nfs_post_op_update_inode(d_inode(dentry), data->res.fattr); | 379 | nfs_post_op_update_inode(d_inode(dentry), data->res.fattr); |
373 | dprintk("NFS reply setattr (post-create): %d\n", status); | 380 | dprintk("NFS reply setattr (post-create): %d\n", status); |
374 | if (status != 0) | 381 | if (status != 0) |
375 | goto out_release_acls; | 382 | goto out_dput; |
376 | } | 383 | } |
377 | 384 | ||
378 | status = nfs3_proc_setacls(d_inode(dentry), acl, default_acl); | 385 | status = nfs3_proc_setacls(d_inode(dentry), acl, default_acl); |
379 | 386 | ||
387 | out_dput: | ||
388 | dput(d_alias); | ||
380 | out_release_acls: | 389 | out_release_acls: |
381 | posix_acl_release(acl); | 390 | posix_acl_release(acl); |
382 | posix_acl_release(default_acl); | 391 | posix_acl_release(default_acl); |
@@ -504,6 +513,7 @@ nfs3_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page, | |||
504 | unsigned int len, struct iattr *sattr) | 513 | unsigned int len, struct iattr *sattr) |
505 | { | 514 | { |
506 | struct nfs3_createdata *data; | 515 | struct nfs3_createdata *data; |
516 | struct dentry *d_alias; | ||
507 | int status = -ENOMEM; | 517 | int status = -ENOMEM; |
508 | 518 | ||
509 | if (len > NFS3_MAXPATHLEN) | 519 | if (len > NFS3_MAXPATHLEN) |
@@ -522,7 +532,11 @@ nfs3_proc_symlink(struct inode *dir, struct dentry *dentry, struct page *page, | |||
522 | data->arg.symlink.pathlen = len; | 532 | data->arg.symlink.pathlen = len; |
523 | data->arg.symlink.sattr = sattr; | 533 | data->arg.symlink.sattr = sattr; |
524 | 534 | ||
525 | status = nfs3_do_create(dir, dentry, data); | 535 | d_alias = nfs3_do_create(dir, dentry, data); |
536 | status = PTR_ERR_OR_ZERO(d_alias); | ||
537 | |||
538 | if (status == 0) | ||
539 | dput(d_alias); | ||
526 | 540 | ||
527 | nfs3_free_createdata(data); | 541 | nfs3_free_createdata(data); |
528 | out: | 542 | out: |
@@ -535,6 +549,7 @@ nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr) | |||
535 | { | 549 | { |
536 | struct posix_acl *default_acl, *acl; | 550 | struct posix_acl *default_acl, *acl; |
537 | struct nfs3_createdata *data; | 551 | struct nfs3_createdata *data; |
552 | struct dentry *d_alias; | ||
538 | int status = -ENOMEM; | 553 | int status = -ENOMEM; |
539 | 554 | ||
540 | dprintk("NFS call mkdir %pd\n", dentry); | 555 | dprintk("NFS call mkdir %pd\n", dentry); |
@@ -553,12 +568,18 @@ nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr) | |||
553 | data->arg.mkdir.len = dentry->d_name.len; | 568 | data->arg.mkdir.len = dentry->d_name.len; |
554 | data->arg.mkdir.sattr = sattr; | 569 | data->arg.mkdir.sattr = sattr; |
555 | 570 | ||
556 | status = nfs3_do_create(dir, dentry, data); | 571 | d_alias = nfs3_do_create(dir, dentry, data); |
572 | status = PTR_ERR_OR_ZERO(d_alias); | ||
573 | |||
557 | if (status != 0) | 574 | if (status != 0) |
558 | goto out_release_acls; | 575 | goto out_release_acls; |
559 | 576 | ||
577 | if (d_alias) | ||
578 | dentry = d_alias; | ||
579 | |||
560 | status = nfs3_proc_setacls(d_inode(dentry), acl, default_acl); | 580 | status = nfs3_proc_setacls(d_inode(dentry), acl, default_acl); |
561 | 581 | ||
582 | dput(d_alias); | ||
562 | out_release_acls: | 583 | out_release_acls: |
563 | posix_acl_release(acl); | 584 | posix_acl_release(acl); |
564 | posix_acl_release(default_acl); | 585 | posix_acl_release(default_acl); |
@@ -660,6 +681,7 @@ nfs3_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | |||
660 | { | 681 | { |
661 | struct posix_acl *default_acl, *acl; | 682 | struct posix_acl *default_acl, *acl; |
662 | struct nfs3_createdata *data; | 683 | struct nfs3_createdata *data; |
684 | struct dentry *d_alias; | ||
663 | int status = -ENOMEM; | 685 | int status = -ENOMEM; |
664 | 686 | ||
665 | dprintk("NFS call mknod %pd %u:%u\n", dentry, | 687 | dprintk("NFS call mknod %pd %u:%u\n", dentry, |
@@ -698,12 +720,17 @@ nfs3_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | |||
698 | goto out; | 720 | goto out; |
699 | } | 721 | } |
700 | 722 | ||
701 | status = nfs3_do_create(dir, dentry, data); | 723 | d_alias = nfs3_do_create(dir, dentry, data); |
724 | status = PTR_ERR_OR_ZERO(d_alias); | ||
702 | if (status != 0) | 725 | if (status != 0) |
703 | goto out_release_acls; | 726 | goto out_release_acls; |
704 | 727 | ||
728 | if (d_alias) | ||
729 | dentry = d_alias; | ||
730 | |||
705 | status = nfs3_proc_setacls(d_inode(dentry), acl, default_acl); | 731 | status = nfs3_proc_setacls(d_inode(dentry), acl, default_acl); |
706 | 732 | ||
733 | dput(d_alias); | ||
707 | out_release_acls: | 734 | out_release_acls: |
708 | posix_acl_release(acl); | 735 | posix_acl_release(acl); |
709 | posix_acl_release(default_acl); | 736 | posix_acl_release(default_acl); |