aboutsummaryrefslogtreecommitdiffstats
path: root/fs/9p/vfs_inode.c
diff options
context:
space:
mode:
authorVenkateswararao Jujjuri (JV) <jvrao@linux.vnet.ibm.com>2010-06-17 21:27:46 -0400
committerEric Van Hensbergen <ericvh@gmail.com>2010-08-02 15:28:32 -0400
commit5643135a28464e7c19d8d23a9e0804697a62c84b (patch)
treed7141110fab0f3d71a95fe18b0b77cbaca645c80 /fs/9p/vfs_inode.c
parent01a622bd7409bb7af38e784cff814e5e723f7951 (diff)
fs/9p: This patch implements TLCREATE for 9p2000.L protocol.
SYNOPSIS size[4] Tlcreate tag[2] fid[4] name[s] flags[4] mode[4] gid[4] size[4] Rlcreate tag[2] qid[13] iounit[4] DESCRIPTION The Tlreate request asks the file server to create a new regular file with the name supplied, in the directory (dir) represented by fid. The mode argument specifies the permissions to use. New file is created with the uid if the fid and with supplied gid. The flags argument represent Linux access mode flags with which the caller is requesting to open the file with. Protocol allows all the Linux access modes but it is upto the server to allow/disallow any of these acess modes. If the server doesn't support any of the access mode, it is expected to return error. Signed-off-by: Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com> Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
Diffstat (limited to 'fs/9p/vfs_inode.c')
-rw-r--r--fs/9p/vfs_inode.c114
1 files changed, 113 insertions, 1 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 39dc79567322..2ac245902a4f 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -642,6 +642,118 @@ error:
642} 642}
643 643
644/** 644/**
645 * v9fs_vfs_create_dotl - VFS hook to create files for 9P2000.L protocol.
646 * @dir: directory inode that is being created
647 * @dentry: dentry that is being deleted
648 * @mode: create permissions
649 * @nd: path information
650 *
651 */
652
653static int
654v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int mode,
655 struct nameidata *nd)
656{
657 int err = 0;
658 char *name = NULL;
659 gid_t gid;
660 int flags;
661 struct v9fs_session_info *v9ses;
662 struct p9_fid *fid = NULL;
663 struct p9_fid *dfid, *ofid;
664 struct file *filp;
665 struct p9_qid qid;
666 struct inode *inode;
667
668 v9ses = v9fs_inode2v9ses(dir);
669 if (nd && nd->flags & LOOKUP_OPEN)
670 flags = nd->intent.open.flags - 1;
671 else
672 flags = O_RDWR;
673
674 name = (char *) dentry->d_name.name;
675 P9_DPRINTK(P9_DEBUG_VFS, "v9fs_vfs_create_dotl: name:%s flags:0x%x "
676 "mode:0x%x\n", name, flags, mode);
677
678 dfid = v9fs_fid_lookup(dentry->d_parent);
679 if (IS_ERR(dfid)) {
680 err = PTR_ERR(dfid);
681 P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
682 return err;
683 }
684
685 /* clone a fid to use for creation */
686 ofid = p9_client_walk(dfid, 0, NULL, 1);
687 if (IS_ERR(ofid)) {
688 err = PTR_ERR(ofid);
689 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
690 return err;
691 }
692
693 gid = v9fs_get_fsgid_for_create(dir);
694 err = p9_client_create_dotl(ofid, name, flags, mode, gid, &qid);
695 if (err < 0) {
696 P9_DPRINTK(P9_DEBUG_VFS,
697 "p9_client_open_dotl failed in creat %d\n",
698 err);
699 goto error;
700 }
701
702 /* No need to populate the inode if we are not opening the file AND
703 * not in cached mode.
704 */
705 if (!v9ses->cache && !(nd && nd->flags & LOOKUP_OPEN)) {
706 /* Not in cached mode. No need to populate inode with stat */
707 dentry->d_op = &v9fs_dentry_operations;
708 p9_client_clunk(ofid);
709 d_instantiate(dentry, NULL);
710 return 0;
711 }
712
713 /* Now walk from the parent so we can get an unopened fid. */
714 fid = p9_client_walk(dfid, 1, &name, 1);
715 if (IS_ERR(fid)) {
716 err = PTR_ERR(fid);
717 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
718 fid = NULL;
719 goto error;
720 }
721
722 /* instantiate inode and assign the unopened fid to dentry */
723 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb);
724 if (IS_ERR(inode)) {
725 err = PTR_ERR(inode);
726 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err);
727 goto error;
728 }
729 dentry->d_op = &v9fs_cached_dentry_operations;
730 d_instantiate(dentry, inode);
731 err = v9fs_fid_add(dentry, fid);
732 if (err < 0)
733 goto error;
734
735 /* if we are opening a file, assign the open fid to the file */
736 if (nd && nd->flags & LOOKUP_OPEN) {
737 filp = lookup_instantiate_filp(nd, dentry, v9fs_open_created);
738 if (IS_ERR(filp)) {
739 p9_client_clunk(ofid);
740 return PTR_ERR(filp);
741 }
742 filp->private_data = ofid;
743 } else
744 p9_client_clunk(ofid);
745
746 return 0;
747
748error:
749 if (ofid)
750 p9_client_clunk(ofid);
751 if (fid)
752 p9_client_clunk(fid);
753 return err;
754}
755
756/**
645 * v9fs_vfs_create - VFS hook to create files 757 * v9fs_vfs_create - VFS hook to create files
646 * @dir: directory inode that is being created 758 * @dir: directory inode that is being created
647 * @dentry: dentry that is being deleted 759 * @dentry: dentry that is being deleted
@@ -1808,7 +1920,7 @@ static const struct inode_operations v9fs_dir_inode_operations_dotu = {
1808}; 1920};
1809 1921
1810static const struct inode_operations v9fs_dir_inode_operations_dotl = { 1922static const struct inode_operations v9fs_dir_inode_operations_dotl = {
1811 .create = v9fs_vfs_create, 1923 .create = v9fs_vfs_create_dotl,
1812 .lookup = v9fs_vfs_lookup, 1924 .lookup = v9fs_vfs_lookup,
1813 .link = v9fs_vfs_link_dotl, 1925 .link = v9fs_vfs_link_dotl,
1814 .symlink = v9fs_vfs_symlink_dotl, 1926 .symlink = v9fs_vfs_symlink_dotl,