diff options
Diffstat (limited to 'fs/9p')
-rw-r--r-- | fs/9p/vfs_inode.c | 48 |
1 files changed, 30 insertions, 18 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index bce66f56c62c..8bb5507e822f 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -534,38 +534,50 @@ v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, | |||
534 | /** | 534 | /** |
535 | * v9fs_remove - helper function to remove files and directories | 535 | * v9fs_remove - helper function to remove files and directories |
536 | * @dir: directory inode that is being deleted | 536 | * @dir: directory inode that is being deleted |
537 | * @file: dentry that is being deleted | 537 | * @dentry: dentry that is being deleted |
538 | * @rmdir: removing a directory | 538 | * @rmdir: removing a directory |
539 | * | 539 | * |
540 | */ | 540 | */ |
541 | 541 | ||
542 | static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) | 542 | static int v9fs_remove(struct inode *dir, struct dentry *dentry, int flags) |
543 | { | 543 | { |
544 | int retval; | 544 | struct inode *inode; |
545 | struct p9_fid *v9fid; | 545 | int retval = -EOPNOTSUPP; |
546 | struct inode *file_inode; | 546 | struct p9_fid *v9fid, *dfid; |
547 | 547 | struct v9fs_session_info *v9ses; | |
548 | P9_DPRINTK(P9_DEBUG_VFS, "inode: %p dentry: %p rmdir: %d\n", dir, file, | ||
549 | rmdir); | ||
550 | 548 | ||
551 | file_inode = file->d_inode; | 549 | P9_DPRINTK(P9_DEBUG_VFS, "inode: %p dentry: %p rmdir: %x\n", |
552 | v9fid = v9fs_fid_clone(file); | 550 | dir, dentry, flags); |
553 | if (IS_ERR(v9fid)) | ||
554 | return PTR_ERR(v9fid); | ||
555 | 551 | ||
556 | retval = p9_client_remove(v9fid); | 552 | v9ses = v9fs_inode2v9ses(dir); |
553 | inode = dentry->d_inode; | ||
554 | dfid = v9fs_fid_lookup(dentry->d_parent); | ||
555 | if (IS_ERR(dfid)) { | ||
556 | retval = PTR_ERR(dfid); | ||
557 | P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", retval); | ||
558 | return retval; | ||
559 | } | ||
560 | if (v9fs_proto_dotl(v9ses)) | ||
561 | retval = p9_client_unlinkat(dfid, dentry->d_name.name, flags); | ||
562 | if (retval == -EOPNOTSUPP) { | ||
563 | /* Try the one based on path */ | ||
564 | v9fid = v9fs_fid_clone(dentry); | ||
565 | if (IS_ERR(v9fid)) | ||
566 | return PTR_ERR(v9fid); | ||
567 | retval = p9_client_remove(v9fid); | ||
568 | } | ||
557 | if (!retval) { | 569 | if (!retval) { |
558 | /* | 570 | /* |
559 | * directories on unlink should have zero | 571 | * directories on unlink should have zero |
560 | * link count | 572 | * link count |
561 | */ | 573 | */ |
562 | if (rmdir) { | 574 | if (flags & AT_REMOVEDIR) { |
563 | clear_nlink(file_inode); | 575 | clear_nlink(inode); |
564 | drop_nlink(dir); | 576 | drop_nlink(dir); |
565 | } else | 577 | } else |
566 | drop_nlink(file_inode); | 578 | drop_nlink(inode); |
567 | 579 | ||
568 | v9fs_invalidate_inode_attr(file_inode); | 580 | v9fs_invalidate_inode_attr(inode); |
569 | v9fs_invalidate_inode_attr(dir); | 581 | v9fs_invalidate_inode_attr(dir); |
570 | } | 582 | } |
571 | return retval; | 583 | return retval; |
@@ -856,7 +868,7 @@ int v9fs_vfs_unlink(struct inode *i, struct dentry *d) | |||
856 | 868 | ||
857 | int v9fs_vfs_rmdir(struct inode *i, struct dentry *d) | 869 | int v9fs_vfs_rmdir(struct inode *i, struct dentry *d) |
858 | { | 870 | { |
859 | return v9fs_remove(i, d, 1); | 871 | return v9fs_remove(i, d, AT_REMOVEDIR); |
860 | } | 872 | } |
861 | 873 | ||
862 | /** | 874 | /** |