diff mbox

[V9fs-developer,3/3] 9p: add 9P2000.L unlinkat operation

Message ID 1307383308-5773-3-git-send-email-aneesh.kumar@linux.vnet.ibm.com (mailing list archive)
State Rejected, archived
Delegated to: Eric Van Hensbergen
Headers show

Commit Message

Aneesh Kumar K.V June 6, 2011, 6:01 p.m. UTC
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>
---
 fs/9p/vfs_inode.c       |   43 ++++++++++++++++++++++++++-----------------
 include/net/9p/9p.h     |    2 ++
 include/net/9p/client.h |    1 +
 net/9p/client.c         |   23 +++++++++++++++++++++++
 4 files changed, 52 insertions(+), 17 deletions(-)

Comments

Eric Van Hensbergen June 13, 2011, 9:12 p.m. UTC | #1
Could be wrong, but a quick regression check of your patches fails
against a legacy server.  Are you making sure the new operations are
properly protected by a .L flag?

         -eric


On Mon, Jun 6, 2011 at 1:01 PM, Aneesh Kumar K.V
<aneesh.kumar@linux.vnet.ibm.com> wrote:
> 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>
> ---
>  fs/9p/vfs_inode.c       |   43 ++++++++++++++++++++++++++-----------------
>  include/net/9p/9p.h     |    2 ++
>  include/net/9p/client.h |    1 +
>  net/9p/client.c         |   23 +++++++++++++++++++++++
>  4 files changed, 52 insertions(+), 17 deletions(-)
>
> diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
> index ded6309..f40fdc3 100644
> --- a/fs/9p/vfs_inode.c
> +++ b/fs/9p/vfs_inode.c
> @@ -492,38 +492,47 @@ 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;
> +       struct p9_fid *v9fid, *dfid;
>
> -       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);
> +       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;
> +       }
> +       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;
> @@ -814,7 +823,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);
>  }
>
>  /**
> diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h
> index 094c3dd..fe1efa6 100644
> --- a/include/net/9p/9p.h
> +++ b/include/net/9p/9p.h
> @@ -177,6 +177,8 @@ enum p9_msg_t {
>        P9_RMKDIR,
>        P9_TRENAMEAT = 74,
>        P9_RRENAMEAT,
> +       P9_TUNLINKAT = 76,
> +       P9_RUNLINKAT,
>        P9_TVERSION = 100,
>        P9_RVERSION,
>        P9_TAUTH = 102,
> diff --git a/include/net/9p/client.h b/include/net/9p/client.h
> index 5353cbc..976d12a 100644
> --- a/include/net/9p/client.h
> +++ b/include/net/9p/client.h
> @@ -234,6 +234,7 @@ int p9_client_create_dotl(struct p9_fid *ofid, char *name, u32 flags, u32 mode,
>  int p9_client_clunk(struct p9_fid *fid);
>  int p9_client_fsync(struct p9_fid *fid, int datasync);
>  int p9_client_remove(struct p9_fid *fid);
> +int p9_client_unlinkat(struct p9_fid *dfid, const char *name, int flags);
>  int p9_client_read(struct p9_fid *fid, char *data, char __user *udata,
>                                                        u64 offset, u32 count);
>  int p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
> diff --git a/net/9p/client.c b/net/9p/client.c
> index 677ae8d..d225158 100644
> --- a/net/9p/client.c
> +++ b/net/9p/client.c
> @@ -1281,6 +1281,29 @@ error:
>  }
>  EXPORT_SYMBOL(p9_client_remove);
>
> +int p9_client_unlinkat(struct p9_fid *dfid, const char *name, int flags)
> +{
> +       int err = 0;
> +       struct p9_req_t *req;
> +       struct p9_client *clnt;
> +
> +       P9_DPRINTK(P9_DEBUG_9P, ">>> TUNLINKAT fid %d %s %d\n",
> +                  dfid->fid, name, flags);
> +
> +       clnt = dfid->clnt;
> +       req = p9_client_rpc(clnt, P9_TUNLINKAT, "dsd", dfid->fid, name, flags);
> +       if (IS_ERR(req)) {
> +               err = PTR_ERR(req);
> +               goto error;
> +       }
> +       P9_DPRINTK(P9_DEBUG_9P, "<<< RUNLINKAT fid %d %s\n", dfid->fid, name);
> +
> +       p9_free_req(clnt, req);
> +error:
> +       return err;
> +}
> +EXPORT_SYMBOL(p9_client_unlinkat);
> +
>  int
>  p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
>                                                                u32 count)
> --
> 1.7.4.1
>
>
> ------------------------------------------------------------------------------
> Simplify data backup and recovery for your virtual environment with vRanger.
> Installation's a snap, and flexible recovery options mean your data is safe,
> secure and there when you need it. Discover what all the cheering's about.
> Get your free trial download today.
> http://p.sf.net/sfu/quest-dev2dev2
> _______________________________________________
> V9fs-developer mailing list
> V9fs-developer@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/v9fs-developer
>

------------------------------------------------------------------------------
EditLive Enterprise is the world's most technically advanced content
authoring tool. Experience the power of Track Changes, Inline Image
Editing and ensure content is compliant with Accessibility Checking.
http://p.sf.net/sfu/ephox-dev2dev
diff mbox

Patch

diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index ded6309..f40fdc3 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -492,38 +492,47 @@  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;
+	struct p9_fid *v9fid, *dfid;
 
-	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);
+	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;
+	}
+	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;
@@ -814,7 +823,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);
 }
 
 /**
diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h
index 094c3dd..fe1efa6 100644
--- a/include/net/9p/9p.h
+++ b/include/net/9p/9p.h
@@ -177,6 +177,8 @@  enum p9_msg_t {
 	P9_RMKDIR,
 	P9_TRENAMEAT = 74,
 	P9_RRENAMEAT,
+	P9_TUNLINKAT = 76,
+	P9_RUNLINKAT,
 	P9_TVERSION = 100,
 	P9_RVERSION,
 	P9_TAUTH = 102,
diff --git a/include/net/9p/client.h b/include/net/9p/client.h
index 5353cbc..976d12a 100644
--- a/include/net/9p/client.h
+++ b/include/net/9p/client.h
@@ -234,6 +234,7 @@  int p9_client_create_dotl(struct p9_fid *ofid, char *name, u32 flags, u32 mode,
 int p9_client_clunk(struct p9_fid *fid);
 int p9_client_fsync(struct p9_fid *fid, int datasync);
 int p9_client_remove(struct p9_fid *fid);
+int p9_client_unlinkat(struct p9_fid *dfid, const char *name, int flags);
 int p9_client_read(struct p9_fid *fid, char *data, char __user *udata,
 							u64 offset, u32 count);
 int p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
diff --git a/net/9p/client.c b/net/9p/client.c
index 677ae8d..d225158 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -1281,6 +1281,29 @@  error:
 }
 EXPORT_SYMBOL(p9_client_remove);
 
+int p9_client_unlinkat(struct p9_fid *dfid, const char *name, int flags)
+{
+	int err = 0;
+	struct p9_req_t *req;
+	struct p9_client *clnt;
+
+	P9_DPRINTK(P9_DEBUG_9P, ">>> TUNLINKAT fid %d %s %d\n",
+		   dfid->fid, name, flags);
+
+	clnt = dfid->clnt;
+	req = p9_client_rpc(clnt, P9_TUNLINKAT, "dsd", dfid->fid, name, flags);
+	if (IS_ERR(req)) {
+		err = PTR_ERR(req);
+		goto error;
+	}
+	P9_DPRINTK(P9_DEBUG_9P, "<<< RUNLINKAT fid %d %s\n", dfid->fid, name);
+
+	p9_free_req(clnt, req);
+error:
+	return err;
+}
+EXPORT_SYMBOL(p9_client_unlinkat);
+
 int
 p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
 								u32 count)