aboutsummaryrefslogtreecommitdiffstats
path: root/fs/9p/vfs_inode.c
diff options
context:
space:
mode:
authorM. Mohan Kumar <mohan@in.ibm.com>2010-06-16 04:57:01 -0400
committerEric Van Hensbergen <ericvh@gmail.com>2010-08-02 15:28:30 -0400
commit4b43516ab19b748b48322937fd9307af17541c4d (patch)
tree0ab84e8d69abce9d63e1937b1a807d2243444a01 /fs/9p/vfs_inode.c
parent50cc42ff3d7bc48a436c5a0413459ca7841b505f (diff)
9p: Implement TMKNOD
Synopsis size[4] Tmknod tag[2] fid[4] name[s] mode[4] major[4] minor[4] gid[4] size[4] Rmknod tag[2] qid[13] Description mknod asks the file server to create a device node with given major and minor number, mode and gid. The qid for the new device node is returned with the mknod reply message. [sripathik@in.ibm.com: Fix error handling code] 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>
Diffstat (limited to 'fs/9p/vfs_inode.c')
-rw-r--r--fs/9p/vfs_inode.c106
1 files changed, 103 insertions, 3 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index a7319364544b..4d9f45ec6126 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -302,7 +302,13 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode)
302 case S_IFBLK: 302 case S_IFBLK:
303 case S_IFCHR: 303 case S_IFCHR:
304 case S_IFSOCK: 304 case S_IFSOCK:
305 if (!v9fs_proto_dotu(v9ses)) { 305 if (v9fs_proto_dotl(v9ses)) {
306 inode->i_op = &v9fs_file_inode_operations_dotl;
307 inode->i_fop = &v9fs_file_operations_dotl;
308 } else if (v9fs_proto_dotu(v9ses)) {
309 inode->i_op = &v9fs_file_inode_operations;
310 inode->i_fop = &v9fs_file_operations;
311 } else {
306 P9_DPRINTK(P9_DEBUG_ERROR, 312 P9_DPRINTK(P9_DEBUG_ERROR,
307 "special files without extended mode\n"); 313 "special files without extended mode\n");
308 err = -EINVAL; 314 err = -EINVAL;
@@ -1616,6 +1622,100 @@ v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
1616 return retval; 1622 return retval;
1617} 1623}
1618 1624
1625/**
1626 * v9fs_vfs_mknod_dotl - create a special file
1627 * @dir: inode destination for new link
1628 * @dentry: dentry for file
1629 * @mode: mode for creation
1630 * @rdev: device associated with special file
1631 *
1632 */
1633static int
1634v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int mode,
1635 dev_t rdev)
1636{
1637 int err;
1638 char *name;
1639 struct v9fs_session_info *v9ses;
1640 struct p9_fid *fid = NULL, *dfid = NULL;
1641 struct inode *inode;
1642 gid_t gid;
1643 struct p9_qid qid;
1644 struct dentry *dir_entry;
1645
1646 P9_DPRINTK(P9_DEBUG_VFS,
1647 " %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino,
1648 dentry->d_name.name, mode, MAJOR(rdev), MINOR(rdev));
1649
1650 if (!new_valid_dev(rdev))
1651 return -EINVAL;
1652
1653 v9ses = v9fs_inode2v9ses(dir);
1654 dir_dentry = v9fs_dentry_from_dir_inode(dir);
1655 dfid = v9fs_fid_lookup(dir_entry);
1656 if (IS_ERR(dfid)) {
1657 err = PTR_ERR(dfid);
1658 P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
1659 dfid = NULL;
1660 goto error;
1661 }
1662
1663 gid = v9fs_get_fsgid_for_create(dir);
1664 if (gid < 0) {
1665 P9_DPRINTK(P9_DEBUG_VFS, "v9fs_get_fsgid_for_create failed\n");
1666 goto error;
1667 }
1668
1669 name = (char *) dentry->d_name.name;
1670
1671 err = p9_client_mknod_dotl(dfid, name, mode, rdev, gid, &qid);
1672 if (err < 0)
1673 goto error;
1674
1675 /* instantiate inode and assign the unopened fid to the dentry */
1676 if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
1677 fid = p9_client_walk(dfid, 1, &name, 1);
1678 if (IS_ERR(fid)) {
1679 err = PTR_ERR(fid);
1680 P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
1681 err);
1682 fid = NULL;
1683 goto error;
1684 }
1685
1686 inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb);
1687 if (IS_ERR(inode)) {
1688 err = PTR_ERR(inode);
1689 P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
1690 err);
1691 goto error;
1692 }
1693 dentry->d_op = &v9fs_cached_dentry_operations;
1694 d_instantiate(dentry, inode);
1695 err = v9fs_fid_add(dentry, fid);
1696 if (err < 0)
1697 goto error;
1698 fid = NULL;
1699 } else {
1700 /*
1701 * Not in cached mode. No need to populate inode with stat.
1702 * socket syscall returns a fd, so we need instantiate
1703 */
1704 inode = v9fs_get_inode(dir->i_sb, mode);
1705 if (IS_ERR(inode)) {
1706 err = PTR_ERR(inode);
1707 goto error;
1708 }
1709 dentry->d_op = &v9fs_dentry_operations;
1710 d_instantiate(dentry, inode);
1711 }
1712
1713error:
1714 if (fid)
1715 p9_client_clunk(fid);
1716 return err;
1717}
1718
1619static const struct inode_operations v9fs_dir_inode_operations_dotu = { 1719static const struct inode_operations v9fs_dir_inode_operations_dotu = {
1620 .create = v9fs_vfs_create, 1720 .create = v9fs_vfs_create,
1621 .lookup = v9fs_vfs_lookup, 1721 .lookup = v9fs_vfs_lookup,
@@ -1624,7 +1724,7 @@ static const struct inode_operations v9fs_dir_inode_operations_dotu = {
1624 .unlink = v9fs_vfs_unlink, 1724 .unlink = v9fs_vfs_unlink,
1625 .mkdir = v9fs_vfs_mkdir, 1725 .mkdir = v9fs_vfs_mkdir,
1626 .rmdir = v9fs_vfs_rmdir, 1726 .rmdir = v9fs_vfs_rmdir,
1627 .mknod = v9fs_vfs_mknod, 1727 .mknod = v9fs_vfs_mknod_dotl,
1628 .rename = v9fs_vfs_rename, 1728 .rename = v9fs_vfs_rename,
1629 .getattr = v9fs_vfs_getattr, 1729 .getattr = v9fs_vfs_getattr,
1630 .setattr = v9fs_vfs_setattr, 1730 .setattr = v9fs_vfs_setattr,
@@ -1638,7 +1738,7 @@ static const struct inode_operations v9fs_dir_inode_operations_dotl = {
1638 .unlink = v9fs_vfs_unlink, 1738 .unlink = v9fs_vfs_unlink,
1639 .mkdir = v9fs_vfs_mkdir, 1739 .mkdir = v9fs_vfs_mkdir,
1640 .rmdir = v9fs_vfs_rmdir, 1740 .rmdir = v9fs_vfs_rmdir,
1641 .mknod = v9fs_vfs_mknod, 1741 .mknod = v9fs_vfs_mknod_dotl,
1642 .rename = v9fs_vfs_rename, 1742 .rename = v9fs_vfs_rename,
1643 .getattr = v9fs_vfs_getattr_dotl, 1743 .getattr = v9fs_vfs_getattr_dotl,
1644 .setattr = v9fs_vfs_setattr_dotl, 1744 .setattr = v9fs_vfs_setattr_dotl,