aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorM. Mohan Kumar <mohan@in.ibm.com>2010-06-16 04:57:22 -0400
committerEric Van Hensbergen <ericvh@gmail.com>2010-08-02 15:28:31 -0400
commit01a622bd7409bb7af38e784cff814e5e723f7951 (patch)
tree1b6e0d9806e560d7f89e0efa8981cfba4c213361
parent4b43516ab19b748b48322937fd9307af17541c4d (diff)
9p: Implement TMKDIR
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 <mohan@in.ibm.com> Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com> Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
-rw-r--r--fs/9p/vfs_inode.c83
-rw-r--r--include/net/9p/9p.h4
-rw-r--r--include/net/9p/client.h2
-rw-r--r--net/9p/client.c31
4 files changed, 117 insertions, 3 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 4d9f45ec6126..39dc79567322 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -731,6 +731,83 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
731 return err; 731 return err;
732} 732}
733 733
734
735/**
736 * v9fs_vfs_mkdir_dotl - VFS mkdir hook to create a directory
737 * @dir: inode that is being unlinked
738 * @dentry: dentry that is being unlinked
739 * @mode: mode for new directory
740 *
741 */
742
743static int v9fs_vfs_mkdir_dotl(struct inode *dir, struct dentry *dentry,
744 int mode)
745{
746 int err;
747 struct v9fs_session_info *v9ses;
748 struct p9_fid *fid = NULL, *dfid = NULL;
749 gid_t gid;
750 char *name;
751 struct inode *inode;
752 struct p9_qid qid;
753 struct dentry *dir_dentry;
754
755 P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name);
756 err = 0;
757 v9ses = v9fs_inode2v9ses(dir);
758
759 mode |= S_IFDIR;
760 dir_dentry = v9fs_dentry_from_dir_inode(dir);
761 dfid = v9fs_fid_lookup(dir_dentry);
762 if (IS_ERR(dfid)) {
763 err = PTR_ERR(dfid);
764 P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
765 dfid = NULL;
766 goto error;
767 }
768
769 gid = v9fs_get_fsgid_for_create(dir);
770 if (gid < 0) {
771 P9_DPRINTK(P9_DEBUG_VFS, "v9fs_get_fsgid_for_create failed\n");
772 goto error;
773 }
774
775 name = (char *) dentry->d_name.name;
776 err = p9_client_mkdir_dotl(dfid, name, mode, gid, &qid);
777 if (err < 0)
778 goto error;
779
780 /* instantiate inode and assign the unopened fid to the dentry */
781 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
782 fid = p9_client_walk(dfid, 1, &name, 1);
783 if (IS_ERR(fid)) {
784 err = PTR_ERR(fid);
785 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
786 err);
787 fid = NULL;
788 goto error;
789 }
790
791 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb);
792 if (IS_ERR(inode)) {
793 err = PTR_ERR(inode);
794 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
795 err);
796 goto error;
797 }
798 dentry->d_op = &v9fs_cached_dentry_operations;
799 d_instantiate(dentry, inode);
800 err = v9fs_fid_add(dentry, fid);
801 if (err < 0)
802 goto error;
803 fid = NULL;
804 }
805error:
806 if (fid)
807 p9_client_clunk(fid);
808 return err;
809}
810
734/** 811/**
735 * v9fs_vfs_lookup - VFS lookup hook to "walk" to a new inode 812 * v9fs_vfs_lookup - VFS lookup hook to "walk" to a new inode
736 * @dir: inode that is being walked from 813 * @dir: inode that is being walked from
@@ -1641,7 +1718,7 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int mode,
1641 struct inode *inode; 1718 struct inode *inode;
1642 gid_t gid; 1719 gid_t gid;
1643 struct p9_qid qid; 1720 struct p9_qid qid;
1644 struct dentry *dir_entry; 1721 struct dentry *dir_dentry;
1645 1722
1646 P9_DPRINTK(P9_DEBUG_VFS, 1723 P9_DPRINTK(P9_DEBUG_VFS,
1647 " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino, 1724 " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino,
@@ -1652,7 +1729,7 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int mode,
1652 1729
1653 v9ses = v9fs_inode2v9ses(dir); 1730 v9ses = v9fs_inode2v9ses(dir);
1654 dir_dentry = v9fs_dentry_from_dir_inode(dir); 1731 dir_dentry = v9fs_dentry_from_dir_inode(dir);
1655 dfid = v9fs_fid_lookup(dir_entry); 1732 dfid = v9fs_fid_lookup(dir_dentry);
1656 if (IS_ERR(dfid)) { 1733 if (IS_ERR(dfid)) {
1657 err = PTR_ERR(dfid); 1734 err = PTR_ERR(dfid);
1658 P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err); 1735 P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
@@ -1736,7 +1813,7 @@ static const struct inode_operations v9fs_dir_inode_operations_dotl = {
1736 .link = v9fs_vfs_link_dotl, 1813 .link = v9fs_vfs_link_dotl,
1737 .symlink = v9fs_vfs_symlink_dotl, 1814 .symlink = v9fs_vfs_symlink_dotl,
1738 .unlink = v9fs_vfs_unlink, 1815 .unlink = v9fs_vfs_unlink,
1739 .mkdir = v9fs_vfs_mkdir, 1816 .mkdir = v9fs_vfs_mkdir_dotl,
1740 .rmdir = v9fs_vfs_rmdir, 1817 .rmdir = v9fs_vfs_rmdir,
1741 .mknod = v9fs_vfs_mknod_dotl, 1818 .mknod = v9fs_vfs_mknod_dotl,
1742 .rename = v9fs_vfs_rename, 1819 .rename = v9fs_vfs_rename,
diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h
index ff32091d8063..091b471d8f05 100644
--- a/include/net/9p/9p.h
+++ b/include/net/9p/9p.h
@@ -94,6 +94,8 @@ do { \
94 * @P9_RMKNOD: create a special file object response 94 * @P9_RMKNOD: create a special file object response
95 * @P9_TRENAME: rename request 95 * @P9_TRENAME: rename request
96 * @P9_RRENAME: rename response 96 * @P9_RRENAME: rename response
97 * @P9_TMKDIR: create a directory request
98 * @P9_RMKDIR: create a directory response
97 * @P9_TVERSION: version handshake request 99 * @P9_TVERSION: version handshake request
98 * @P9_RVERSION: version handshake response 100 * @P9_RVERSION: version handshake response
99 * @P9_TAUTH: request to establish authentication channel 101 * @P9_TAUTH: request to establish authentication channel
@@ -149,6 +151,8 @@ enum p9_msg_t {
149 P9_RREADDIR, 151 P9_RREADDIR,
150 P9_TLINK = 70, 152 P9_TLINK = 70,
151 P9_RLINK, 153 P9_RLINK,
154 P9_TMKDIR = 72,
155 P9_RMKDIR,
152 P9_TVERSION = 100, 156 P9_TVERSION = 100,
153 P9_RVERSION, 157 P9_RVERSION,
154 P9_TAUTH = 102, 158 P9_TAUTH = 102,
diff --git a/include/net/9p/client.h b/include/net/9p/client.h
index 6e70358c71d9..55d913a9b797 100644
--- a/include/net/9p/client.h
+++ b/include/net/9p/client.h
@@ -247,6 +247,8 @@ struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid,
247 247
248int p9_client_mknod_dotl(struct p9_fid *oldfid, char *name, int mode, 248int p9_client_mknod_dotl(struct p9_fid *oldfid, char *name, int mode,
249 dev_t rdev, gid_t gid, struct p9_qid *); 249 dev_t rdev, gid_t gid, struct p9_qid *);
250int p9_client_mkdir_dotl(struct p9_fid *fid, char *name, int mode,
251 gid_t gid, struct p9_qid *);
250struct p9_req_t *p9_tag_lookup(struct p9_client *, u16); 252struct p9_req_t *p9_tag_lookup(struct p9_client *, u16);
251void p9_client_cb(struct p9_client *c, struct p9_req_t *req); 253void p9_client_cb(struct p9_client *c, struct p9_req_t *req);
252 254
diff --git a/net/9p/client.c b/net/9p/client.c
index cdfbd6740796..a3bdd341f2ac 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -1653,3 +1653,34 @@ error:
1653 1653
1654} 1654}
1655EXPORT_SYMBOL(p9_client_mknod_dotl); 1655EXPORT_SYMBOL(p9_client_mknod_dotl);
1656
1657int p9_client_mkdir_dotl(struct p9_fid *fid, char *name, int mode,
1658 gid_t gid, struct p9_qid *qid)
1659{
1660 int err;
1661 struct p9_client *clnt;
1662 struct p9_req_t *req;
1663
1664 err = 0;
1665 clnt = fid->clnt;
1666 P9_DPRINTK(P9_DEBUG_9P, ">>> TMKDIR fid %d name %s mode %d gid %d\n",
1667 fid->fid, name, mode, gid);
1668 req = p9_client_rpc(clnt, P9_TMKDIR, "dsdd", fid->fid, name, mode,
1669 gid);
1670 if (IS_ERR(req))
1671 return PTR_ERR(req);
1672
1673 err = p9pdu_readf(req->rc, clnt->proto_version, "Q", qid);
1674 if (err) {
1675 p9pdu_dump(1, req->rc);
1676 goto error;
1677 }
1678 P9_DPRINTK(P9_DEBUG_9P, "<<< RMKDIR qid %x.%llx.%x\n", qid->type,
1679 (unsigned long long)qid->path, qid->version);
1680
1681error:
1682 p9_free_req(clnt, req);
1683 return err;
1684
1685}
1686EXPORT_SYMBOL(p9_client_mkdir_dotl);