qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 02/02] 9p: Implement TMKDIR


From: M. Mohan Kumar
Subject: [Qemu-devel] [PATCH 02/02] 9p: Implement TMKDIR
Date: Mon, 7 Jun 2010 11:50:28 +0530

Implement TMKDIR as part of 2000.L Work

Synopsis

    size[4] Tmkdir tag[2] fid[4] name[s] mode[4] gid[4]

    size[4] Rmkdir tag[2] qid[13]

Description

    mkdir asks the file server to create a directory with given name,
    mode and gid. The qid for the new directory is returned with
    the mkdir reply message.

Note: 72 is selected as the opcode for TMKDIR from the reserved list.

Signed-off-by: M. Mohan Kumar <address@hidden>
---
 fs/9p/vfs_inode.c       |   76 ++++++++++++++++++++++++++++++++++++++++++++++-
 include/net/9p/9p.h     |    2 +
 include/net/9p/client.h |    2 +
 net/9p/client.c         |   33 ++++++++++++++++++++
 4 files changed, 112 insertions(+), 1 deletions(-)

Note: This patch needs to be applied on top of Venkateswararao Jujjuri's
"Add a helper function to get fsgid for a file create".
Message Id: address@hidden

diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index a4e4ab8..f73be10 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -715,6 +715,80 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry 
*dentry, int mode)
        return err;
 }
 
+
+/**
+ * v9fs_vfs_mkdir_dotl - VFS mkdir hook to create a directory
+ * @dir:  inode that is being unlinked
+ * @dentry: dentry that is being unlinked
+ * @mode: mode for new directory
+ *
+ */
+
+static int v9fs_vfs_mkdir_dotl(struct inode *dir, struct dentry *dentry, int 
mode)
+{
+       int err;
+       struct v9fs_session_info *v9ses;
+       struct p9_fid *fid = NULL, *dfid = NULL;
+       gid_t gid;
+       char *name;
+       struct inode *inode;
+       struct p9_qid qid;
+
+       P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name);
+       err = 0;
+       v9ses = v9fs_inode2v9ses(dir);
+
+       mode |= S_IFDIR;
+       dfid = v9fs_fid_lookup(dentry->d_parent);
+       if (IS_ERR(dfid)) {
+               err = PTR_ERR(dfid);
+               P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
+               dfid = NULL;
+               goto error;
+       }
+
+       gid = v9fs_get_fsgid_for_create(dentry->d_parent);
+       if (gid < 0) {
+               P9_DPRINTK(P9_DEBUG_VFS, "v9fs_get_fsgid_for_create failed\n");
+               goto error;
+       }
+
+       name = (char *) dentry->d_name.name;
+       err = p9_client_mkdir_dotl(dfid, name, mode, gid, &qid);
+       if (err < 0)
+               goto error;
+
+       /* instantiate inode and assign the unopened fid to the dentry */
+       if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
+               fid = p9_client_walk(dfid, 1, &name, 1);
+               if (IS_ERR(fid)) {
+                       err = PTR_ERR(fid);
+                       P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
+                               err);
+                       fid = NULL;
+                       goto error;
+               }
+
+               inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb);
+               if (IS_ERR(inode)) {
+                       err = PTR_ERR(inode);
+                       P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
+                               err);
+                       goto error;
+               }
+               dentry->d_op = &v9fs_cached_dentry_operations;
+               d_instantiate(dentry, inode);
+               err = v9fs_fid_add(dentry, fid);
+               if (err < 0)
+                       goto error;
+               fid = NULL;
+       }
+error:
+       if (fid)
+               p9_client_clunk(fid);
+       return err;
+}
+
 /**
  * v9fs_vfs_lookup - VFS lookup hook to "walk" to a new inode
  * @dir:  inode that is being walked from
@@ -1643,7 +1717,7 @@ static const struct inode_operations 
v9fs_dir_inode_operations_dotl = {
        .symlink = v9fs_vfs_symlink_dotl,
        .link = v9fs_vfs_link_dotl,
        .unlink = v9fs_vfs_unlink,
-       .mkdir = v9fs_vfs_mkdir,
+       .mkdir = v9fs_vfs_mkdir_dotl,
        .rmdir = v9fs_vfs_rmdir,
        .mknod = v9fs_vfs_mknod_dotl,
        .rename = v9fs_vfs_rename,
diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h
index 8b52904..77391ca 100644
--- a/include/net/9p/9p.h
+++ b/include/net/9p/9p.h
@@ -147,6 +147,8 @@ enum p9_msg_t {
        P9_RREADDIR,
        P9_TLINK = 70,
        P9_RLINK,
+       P9_TMKDIR = 72,
+       P9_RMKDIR,
        P9_TVERSION = 100,
        P9_RVERSION,
        P9_TAUTH = 102,
diff --git a/include/net/9p/client.h b/include/net/9p/client.h
index dc5e83d..6836279 100644
--- a/include/net/9p/client.h
+++ b/include/net/9p/client.h
@@ -246,6 +246,8 @@ struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid 
*fid);
 
 int p9_client_mknod_dotl(struct p9_fid *oldfid, char *name, int mode,
                        dev_t rdev, gid_t gid, struct p9_qid *);
+int p9_client_mkdir_dotl(struct p9_fid *fid, char *name, int mode,
+                               gid_t gid, struct p9_qid *);
 struct p9_req_t *p9_tag_lookup(struct p9_client *, u16);
 void p9_client_cb(struct p9_client *c, struct p9_req_t *req);
 
diff --git a/net/9p/client.c b/net/9p/client.c
index 641d2be..4f53da8 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -1648,3 +1648,36 @@ error:
 
 }
 EXPORT_SYMBOL(p9_client_mknod_dotl);
+
+int p9_client_mkdir_dotl(struct p9_fid *fid, char *name, int mode,
+                               gid_t gid, struct p9_qid *qid)
+{
+       int err;
+       struct p9_client *clnt;
+       struct p9_req_t *req;
+
+       err = 0;
+       clnt = fid->clnt;
+       P9_DPRINTK(P9_DEBUG_9P, ">>> TMKDIR fid %d name %s mode %d gid %d\n",
+                fid->fid, name, mode, gid);
+       req = p9_client_rpc(clnt, P9_TMKDIR, "dsdd", fid->fid, name, mode,
+               gid);
+       if (IS_ERR(req)) {
+               err = PTR_ERR(req);
+               goto error;
+       }
+
+       err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid);
+       if (err) {
+               p9pdu_dump(1, req->rc);
+               goto error;
+       }
+       P9_DPRINTK(P9_DEBUG_9P, "<<< RMKDIR qid %x.%llx.%x\n", qid->type,
+                               (unsigned long long)qid->path, qid->version);
+
+error:
+       p9_free_req(clnt, req);
+       return err;
+
+}
+EXPORT_SYMBOL(p9_client_mkdir_dotl);
-- 
1.6.6.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]