From 48e370ff93769ee6e592ddef3bb38686b8147c67 Mon Sep 17 00:00:00 2001 From: Aneesh Kumar K.V Date: Tue, 28 Jun 2011 15:41:18 +0530 Subject: 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 Signed-off-by: Eric Van Hensbergen --- fs/9p/vfs_inode.c | 48 ++++++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 18 deletions(-) (limited to 'fs') 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, /** * v9fs_remove - helper function to remove files and directories * @dir: directory inode that is being deleted - * @file: dentry that is being deleted + * @dentry: dentry that is being deleted * @rmdir: removing a directory * */ -static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) +static int v9fs_remove(struct inode *dir, struct dentry *dentry, int flags) { - int retval; - struct p9_fid *v9fid; - struct inode *file_inode; - - P9_DPRINTK(P9_DEBUG_VFS, "inode: %p dentry: %p rmdir: %d\n", dir, file, - rmdir); + struct inode *inode; + int retval = -EOPNOTSUPP; + struct p9_fid *v9fid, *dfid; + struct v9fs_session_info *v9ses; - file_inode = file->d_inode; - v9fid = v9fs_fid_clone(file); - if (IS_ERR(v9fid)) - return PTR_ERR(v9fid); + P9_DPRINTK(P9_DEBUG_VFS, "inode: %p dentry: %p rmdir: %x\n", + dir, dentry, flags); - retval = p9_client_remove(v9fid); + v9ses = v9fs_inode2v9ses(dir); + inode = dentry->d_inode; + dfid = v9fs_fid_lookup(dentry->d_parent); + if (IS_ERR(dfid)) { + retval = PTR_ERR(dfid); + P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", retval); + return retval; + } + if (v9fs_proto_dotl(v9ses)) + retval = p9_client_unlinkat(dfid, dentry->d_name.name, flags); + if (retval == -EOPNOTSUPP) { + /* Try the one based on path */ + v9fid = v9fs_fid_clone(dentry); + if (IS_ERR(v9fid)) + return PTR_ERR(v9fid); + retval = p9_client_remove(v9fid); + } if (!retval) { /* * directories on unlink should have zero * link count */ - if (rmdir) { - clear_nlink(file_inode); + if (flags & AT_REMOVEDIR) { + clear_nlink(inode); drop_nlink(dir); } else - drop_nlink(file_inode); + drop_nlink(inode); - v9fs_invalidate_inode_attr(file_inode); + v9fs_invalidate_inode_attr(inode); v9fs_invalidate_inode_attr(dir); } return retval; @@ -856,7 +868,7 @@ int v9fs_vfs_unlink(struct inode *i, struct dentry *d) int v9fs_vfs_rmdir(struct inode *i, struct dentry *d) { - return v9fs_remove(i, d, 1); + return v9fs_remove(i, d, AT_REMOVEDIR); } /** -- cgit v1.2.3