aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>2011-06-28 06:11:18 -0400
committerEric Van Hensbergen <ericvh@gmail.com>2011-07-23 10:32:52 -0400
commit48e370ff93769ee6e592ddef3bb38686b8147c67 (patch)
tree045a8b0c905be07df33ae06d776e972448a6e447 /fs
parent9e8fb38e7d7a00e5f63bbb331f0ea4c02286d5e6 (diff)
fs/9p: add 9P2000.L unlinkat operation
unlinkat - Remove a directory entry size[4] Tunlinkat tag[2] dirfid[4] name[s] flag[4] size[4] Runlinkat tag[2] older Tremove have the below request format size[4] Tremove tag[2] fid[4] The remove message is used to remove a directory entry either file or directory The remove opreation is actually a directory opertation and should ideally have dirfid, if not we cannot represent the fid on server with anything other than name. We will have to derive the directory name from fid in the Tremove request. NOTE: The operation doesn't clunk the unlink fid. Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/9p/vfs_inode.c48
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
542static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) 542static 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
857int v9fs_vfs_rmdir(struct inode *i, struct dentry *d) 869int 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/**