fs/9p: add 9P2000.L renameat operation
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Tue, 28 Jun 2011 10:11:16 +0000 (15:41 +0530)
committerEric Van Hensbergen <ericvh@gmail.com>
Sat, 23 Jul 2011 14:32:51 +0000 (09:32 -0500)
renameat - change name of file or directory

size[4] Trenameat tag[2] olddirfid[4] oldname[s] newdirfid[4] newname[s]
size[4] Rrenameat tag[2]

older Trename have the below request format

size[4] Trename tag[2] fid[4] newdirfid[4] name[s]

The rename message is used to change the name of a file, possibly moving it
to a new directory. The rename opreation is actually a directory opertation
and should ideally have olddirfid, if not we cannot represent the fid on server
with anything other than name. We will have to derive the old directory name
from fid in the Trename request.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
fs/9p/vfs_inode.c
include/net/9p/9p.h
include/net/9p/client.h
net/9p/client.c

index 3bbf705634b2a44265d961ae3ef2394fc2242d3d..bce66f56c62c8b3a5ff0e23ce9358b3252239d13 100644 (file)
@@ -904,9 +904,12 @@ v9fs_vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
 
        down_write(&v9ses->rename_sem);
        if (v9fs_proto_dotl(v9ses)) {
-               retval = p9_client_rename(oldfid, newdirfid,
-                                       (char *) new_dentry->d_name.name);
-               if (retval != -ENOSYS)
+               retval = p9_client_renameat(olddirfid, old_dentry->d_name.name,
+                                           newdirfid, new_dentry->d_name.name);
+               if (retval == -EOPNOTSUPP)
+                       retval = p9_client_rename(oldfid, newdirfid,
+                                                 new_dentry->d_name.name);
+               if (retval != -EOPNOTSUPP)
                        goto clunk_newdir;
        }
        if (old_dentry->d_parent != new_dentry->d_parent) {
index 160193e6ddddce31aaf81b31e28ed91a1d39fee6..61156207c98ca3b1faba65c08fbff9797fa72761 100644 (file)
@@ -181,6 +181,8 @@ enum p9_msg_t {
        P9_RLINK,
        P9_TMKDIR = 72,
        P9_RMKDIR,
+       P9_TRENAMEAT = 74,
+       P9_RRENAMEAT,
        P9_TVERSION = 100,
        P9_RVERSION,
        P9_TAUTH = 102,
index f7a8d036f803730c6eeac29862179fcce981fb56..62ceddf9994a263730c844364e57f229cb74e32a 100644 (file)
@@ -211,7 +211,10 @@ struct p9_dirent {
 };
 
 int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb);
-int p9_client_rename(struct p9_fid *fid, struct p9_fid *newdirfid, char *name);
+int p9_client_rename(struct p9_fid *fid, struct p9_fid *newdirfid,
+                    const char *name);
+int p9_client_renameat(struct p9_fid *olddirfid, const char *old_name,
+                      struct p9_fid *newdirfid, const char *new_name);
 struct p9_client *p9_client_create(const char *dev_name, char *options);
 void p9_client_destroy(struct p9_client *clnt);
 void p9_client_disconnect(struct p9_client *clnt);
index 431eaef697c7d98d782e1fb7600b5192458c982b..c4b77f3835823f835c9df990aeed3ca87fa4745a 100644 (file)
@@ -1666,7 +1666,8 @@ error:
 }
 EXPORT_SYMBOL(p9_client_statfs);
 
-int p9_client_rename(struct p9_fid *fid, struct p9_fid *newdirfid, char *name)
+int p9_client_rename(struct p9_fid *fid,
+                    struct p9_fid *newdirfid, const char *name)
 {
        int err;
        struct p9_req_t *req;
@@ -1693,6 +1694,36 @@ error:
 }
 EXPORT_SYMBOL(p9_client_rename);
 
+int p9_client_renameat(struct p9_fid *olddirfid, const char *old_name,
+                      struct p9_fid *newdirfid, const char *new_name)
+{
+       int err;
+       struct p9_req_t *req;
+       struct p9_client *clnt;
+
+       err = 0;
+       clnt = olddirfid->clnt;
+
+       P9_DPRINTK(P9_DEBUG_9P, ">>> TRENAMEAT olddirfid %d old name %s"
+                  " newdirfid %d new name %s\n", olddirfid->fid, old_name,
+                  newdirfid->fid, new_name);
+
+       req = p9_client_rpc(clnt, P9_TRENAMEAT, "dsds", olddirfid->fid,
+                           old_name, newdirfid->fid, new_name);
+       if (IS_ERR(req)) {
+               err = PTR_ERR(req);
+               goto error;
+       }
+
+       P9_DPRINTK(P9_DEBUG_9P, "<<< RRENAMEAT newdirfid %d new name %s\n",
+                  newdirfid->fid, new_name);
+
+       p9_free_req(clnt, req);
+error:
+       return err;
+}
+EXPORT_SYMBOL(p9_client_renameat);
+
 /*
  * An xattrwalk without @attr_name gives the fid for the lisxattr namespace
  */