xref: /openbmc/linux/fs/9p/vfs_inode_dotl.c (revision fd2421f54423f307ecd31bdebdca6bc317e0c492)
153c06f4eSAneesh Kumar K.V /*
253c06f4eSAneesh Kumar K.V  *  linux/fs/9p/vfs_inode_dotl.c
353c06f4eSAneesh Kumar K.V  *
453c06f4eSAneesh Kumar K.V  * This file contains vfs inode ops for the 9P2000.L protocol.
553c06f4eSAneesh Kumar K.V  *
653c06f4eSAneesh Kumar K.V  *  Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
753c06f4eSAneesh Kumar K.V  *  Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
853c06f4eSAneesh Kumar K.V  *
953c06f4eSAneesh Kumar K.V  *  This program is free software; you can redistribute it and/or modify
1053c06f4eSAneesh Kumar K.V  *  it under the terms of the GNU General Public License version 2
1153c06f4eSAneesh Kumar K.V  *  as published by the Free Software Foundation.
1253c06f4eSAneesh Kumar K.V  *
1353c06f4eSAneesh Kumar K.V  *  This program is distributed in the hope that it will be useful,
1453c06f4eSAneesh Kumar K.V  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
1553c06f4eSAneesh Kumar K.V  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1653c06f4eSAneesh Kumar K.V  *  GNU General Public License for more details.
1753c06f4eSAneesh Kumar K.V  *
1853c06f4eSAneesh Kumar K.V  *  You should have received a copy of the GNU General Public License
1953c06f4eSAneesh Kumar K.V  *  along with this program; if not, write to:
2053c06f4eSAneesh Kumar K.V  *  Free Software Foundation
2153c06f4eSAneesh Kumar K.V  *  51 Franklin Street, Fifth Floor
2253c06f4eSAneesh Kumar K.V  *  Boston, MA  02111-1301  USA
2353c06f4eSAneesh Kumar K.V  *
2453c06f4eSAneesh Kumar K.V  */
2553c06f4eSAneesh Kumar K.V 
2653c06f4eSAneesh Kumar K.V #include <linux/module.h>
2753c06f4eSAneesh Kumar K.V #include <linux/errno.h>
2853c06f4eSAneesh Kumar K.V #include <linux/fs.h>
2953c06f4eSAneesh Kumar K.V #include <linux/file.h>
3053c06f4eSAneesh Kumar K.V #include <linux/pagemap.h>
3153c06f4eSAneesh Kumar K.V #include <linux/stat.h>
3253c06f4eSAneesh Kumar K.V #include <linux/string.h>
3353c06f4eSAneesh Kumar K.V #include <linux/inet.h>
3453c06f4eSAneesh Kumar K.V #include <linux/namei.h>
3553c06f4eSAneesh Kumar K.V #include <linux/idr.h>
3653c06f4eSAneesh Kumar K.V #include <linux/sched.h>
3753c06f4eSAneesh Kumar K.V #include <linux/slab.h>
3853c06f4eSAneesh Kumar K.V #include <linux/xattr.h>
3953c06f4eSAneesh Kumar K.V #include <linux/posix_acl.h>
4053c06f4eSAneesh Kumar K.V #include <net/9p/9p.h>
4153c06f4eSAneesh Kumar K.V #include <net/9p/client.h>
4253c06f4eSAneesh Kumar K.V 
4353c06f4eSAneesh Kumar K.V #include "v9fs.h"
4453c06f4eSAneesh Kumar K.V #include "v9fs_vfs.h"
4553c06f4eSAneesh Kumar K.V #include "fid.h"
4653c06f4eSAneesh Kumar K.V #include "cache.h"
4753c06f4eSAneesh Kumar K.V #include "xattr.h"
4853c06f4eSAneesh Kumar K.V #include "acl.h"
4953c06f4eSAneesh Kumar K.V 
5053c06f4eSAneesh Kumar K.V static int
5153c06f4eSAneesh Kumar K.V v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int omode,
5253c06f4eSAneesh Kumar K.V 		    dev_t rdev);
5353c06f4eSAneesh Kumar K.V 
5453c06f4eSAneesh Kumar K.V /**
5553c06f4eSAneesh Kumar K.V  * v9fs_get_fsgid_for_create - Helper function to get the gid for creating a
5653c06f4eSAneesh Kumar K.V  * new file system object. This checks the S_ISGID to determine the owning
5753c06f4eSAneesh Kumar K.V  * group of the new file system object.
5853c06f4eSAneesh Kumar K.V  */
5953c06f4eSAneesh Kumar K.V 
6053c06f4eSAneesh Kumar K.V static gid_t v9fs_get_fsgid_for_create(struct inode *dir_inode)
6153c06f4eSAneesh Kumar K.V {
6253c06f4eSAneesh Kumar K.V 	BUG_ON(dir_inode == NULL);
6353c06f4eSAneesh Kumar K.V 
6453c06f4eSAneesh Kumar K.V 	if (dir_inode->i_mode & S_ISGID) {
6553c06f4eSAneesh Kumar K.V 		/* set_gid bit is set.*/
6653c06f4eSAneesh Kumar K.V 		return dir_inode->i_gid;
6753c06f4eSAneesh Kumar K.V 	}
6853c06f4eSAneesh Kumar K.V 	return current_fsgid();
6953c06f4eSAneesh Kumar K.V }
7053c06f4eSAneesh Kumar K.V 
7153c06f4eSAneesh Kumar K.V /**
7253c06f4eSAneesh Kumar K.V  * v9fs_dentry_from_dir_inode - helper function to get the dentry from
7353c06f4eSAneesh Kumar K.V  * dir inode.
7453c06f4eSAneesh Kumar K.V  *
7553c06f4eSAneesh Kumar K.V  */
7653c06f4eSAneesh Kumar K.V 
7753c06f4eSAneesh Kumar K.V static struct dentry *v9fs_dentry_from_dir_inode(struct inode *inode)
7853c06f4eSAneesh Kumar K.V {
7953c06f4eSAneesh Kumar K.V 	struct dentry *dentry;
8053c06f4eSAneesh Kumar K.V 
8153c06f4eSAneesh Kumar K.V 	spin_lock(&inode->i_lock);
8253c06f4eSAneesh Kumar K.V 	/* Directory should have only one entry. */
8353c06f4eSAneesh Kumar K.V 	BUG_ON(S_ISDIR(inode->i_mode) && !list_is_singular(&inode->i_dentry));
8453c06f4eSAneesh Kumar K.V 	dentry = list_entry(inode->i_dentry.next, struct dentry, d_alias);
8553c06f4eSAneesh Kumar K.V 	spin_unlock(&inode->i_lock);
8653c06f4eSAneesh Kumar K.V 	return dentry;
8753c06f4eSAneesh Kumar K.V }
8853c06f4eSAneesh Kumar K.V 
89*fd2421f5SAneesh Kumar K.V static int v9fs_test_inode_dotl(struct inode *inode, void *data)
90*fd2421f5SAneesh Kumar K.V {
91*fd2421f5SAneesh Kumar K.V 	struct v9fs_inode *v9inode = V9FS_I(inode);
92*fd2421f5SAneesh Kumar K.V 	struct p9_stat_dotl *st = (struct p9_stat_dotl *)data;
93*fd2421f5SAneesh Kumar K.V 
94*fd2421f5SAneesh Kumar K.V 	/* don't match inode of different type */
95*fd2421f5SAneesh Kumar K.V 	if ((inode->i_mode & S_IFMT) != (st->st_mode & S_IFMT))
96*fd2421f5SAneesh Kumar K.V 		return 0;
97*fd2421f5SAneesh Kumar K.V 
98*fd2421f5SAneesh Kumar K.V 	if (inode->i_generation != st->st_gen)
99*fd2421f5SAneesh Kumar K.V 		return 0;
100*fd2421f5SAneesh Kumar K.V 
101*fd2421f5SAneesh Kumar K.V 	/* compare qid details */
102*fd2421f5SAneesh Kumar K.V 	if (memcmp(&v9inode->qid.version,
103*fd2421f5SAneesh Kumar K.V 		   &st->qid.version, sizeof(v9inode->qid.version)))
104*fd2421f5SAneesh Kumar K.V 		return 0;
105*fd2421f5SAneesh Kumar K.V 
106*fd2421f5SAneesh Kumar K.V 	if (v9inode->qid.type != st->qid.type)
107*fd2421f5SAneesh Kumar K.V 		return 0;
108*fd2421f5SAneesh Kumar K.V 	return 1;
109*fd2421f5SAneesh Kumar K.V }
110*fd2421f5SAneesh Kumar K.V 
111*fd2421f5SAneesh Kumar K.V static int v9fs_set_inode_dotl(struct inode *inode,  void *data)
112*fd2421f5SAneesh Kumar K.V {
113*fd2421f5SAneesh Kumar K.V 	struct v9fs_inode *v9inode = V9FS_I(inode);
114*fd2421f5SAneesh Kumar K.V 	struct p9_stat_dotl *st = (struct p9_stat_dotl *)data;
115*fd2421f5SAneesh Kumar K.V 
116*fd2421f5SAneesh Kumar K.V 	memcpy(&v9inode->qid, &st->qid, sizeof(st->qid));
117*fd2421f5SAneesh Kumar K.V 	inode->i_generation = st->st_gen;
118*fd2421f5SAneesh Kumar K.V 	return 0;
119*fd2421f5SAneesh Kumar K.V }
120*fd2421f5SAneesh Kumar K.V 
1215ffc0cb3SAneesh Kumar K.V static struct inode *v9fs_qid_iget_dotl(struct super_block *sb,
1225ffc0cb3SAneesh Kumar K.V 					struct p9_qid *qid,
1235ffc0cb3SAneesh Kumar K.V 					struct p9_fid *fid,
1245ffc0cb3SAneesh Kumar K.V 					struct p9_stat_dotl *st)
1255ffc0cb3SAneesh Kumar K.V {
1265ffc0cb3SAneesh Kumar K.V 	int retval;
1275ffc0cb3SAneesh Kumar K.V 	unsigned long i_ino;
1285ffc0cb3SAneesh Kumar K.V 	struct inode *inode;
1295ffc0cb3SAneesh Kumar K.V 	struct v9fs_session_info *v9ses = sb->s_fs_info;
1305ffc0cb3SAneesh Kumar K.V 
1315ffc0cb3SAneesh Kumar K.V 	i_ino = v9fs_qid2ino(qid);
132*fd2421f5SAneesh Kumar K.V 	inode = iget5_locked(sb, i_ino, v9fs_test_inode_dotl,
133*fd2421f5SAneesh Kumar K.V 			     v9fs_set_inode_dotl, st);
1345ffc0cb3SAneesh Kumar K.V 	if (!inode)
1355ffc0cb3SAneesh Kumar K.V 		return ERR_PTR(-ENOMEM);
1365ffc0cb3SAneesh Kumar K.V 	if (!(inode->i_state & I_NEW))
1375ffc0cb3SAneesh Kumar K.V 		return inode;
1385ffc0cb3SAneesh Kumar K.V 	/*
1395ffc0cb3SAneesh Kumar K.V 	 * initialize the inode with the stat info
1405ffc0cb3SAneesh Kumar K.V 	 * FIXME!! we may need support for stale inodes
1415ffc0cb3SAneesh Kumar K.V 	 * later.
1425ffc0cb3SAneesh Kumar K.V 	 */
143*fd2421f5SAneesh Kumar K.V 	inode->i_ino = i_ino;
1445ffc0cb3SAneesh Kumar K.V 	retval = v9fs_init_inode(v9ses, inode, st->st_mode);
1455ffc0cb3SAneesh Kumar K.V 	if (retval)
1465ffc0cb3SAneesh Kumar K.V 		goto error;
1475ffc0cb3SAneesh Kumar K.V 
1485ffc0cb3SAneesh Kumar K.V 	v9fs_stat2inode_dotl(st, inode);
1495ffc0cb3SAneesh Kumar K.V #ifdef CONFIG_9P_FSCACHE
1505ffc0cb3SAneesh Kumar K.V 	v9fs_cache_inode_get_cookie(inode);
1515ffc0cb3SAneesh Kumar K.V #endif
1525ffc0cb3SAneesh Kumar K.V 	retval = v9fs_get_acl(inode, fid);
1535ffc0cb3SAneesh Kumar K.V 	if (retval)
1545ffc0cb3SAneesh Kumar K.V 		goto error;
1555ffc0cb3SAneesh Kumar K.V 
1565ffc0cb3SAneesh Kumar K.V 	unlock_new_inode(inode);
1575ffc0cb3SAneesh Kumar K.V 	return inode;
1585ffc0cb3SAneesh Kumar K.V error:
1595ffc0cb3SAneesh Kumar K.V 	unlock_new_inode(inode);
1605ffc0cb3SAneesh Kumar K.V 	iput(inode);
1615ffc0cb3SAneesh Kumar K.V 	return ERR_PTR(retval);
1625ffc0cb3SAneesh Kumar K.V 
1635ffc0cb3SAneesh Kumar K.V }
1645ffc0cb3SAneesh Kumar K.V 
16553c06f4eSAneesh Kumar K.V struct inode *
166a78ce05dSAneesh Kumar K.V v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid,
16753c06f4eSAneesh Kumar K.V 			 struct super_block *sb)
16853c06f4eSAneesh Kumar K.V {
16953c06f4eSAneesh Kumar K.V 	struct p9_stat_dotl *st;
1705ffc0cb3SAneesh Kumar K.V 	struct inode *inode = NULL;
17153c06f4eSAneesh Kumar K.V 
172*fd2421f5SAneesh Kumar K.V 	st = p9_client_getattr_dotl(fid, P9_STATS_BASIC | P9_STATS_GEN);
17353c06f4eSAneesh Kumar K.V 	if (IS_ERR(st))
17453c06f4eSAneesh Kumar K.V 		return ERR_CAST(st);
17553c06f4eSAneesh Kumar K.V 
1765ffc0cb3SAneesh Kumar K.V 	inode = v9fs_qid_iget_dotl(sb, &st->qid, fid, st);
17753c06f4eSAneesh Kumar K.V 	kfree(st);
1785ffc0cb3SAneesh Kumar K.V 	return inode;
17953c06f4eSAneesh Kumar K.V }
18053c06f4eSAneesh Kumar K.V 
18153c06f4eSAneesh Kumar K.V /**
18253c06f4eSAneesh Kumar K.V  * v9fs_vfs_create_dotl - VFS hook to create files for 9P2000.L protocol.
18353c06f4eSAneesh Kumar K.V  * @dir: directory inode that is being created
18453c06f4eSAneesh Kumar K.V  * @dentry:  dentry that is being deleted
18553c06f4eSAneesh Kumar K.V  * @mode: create permissions
18653c06f4eSAneesh Kumar K.V  * @nd: path information
18753c06f4eSAneesh Kumar K.V  *
18853c06f4eSAneesh Kumar K.V  */
18953c06f4eSAneesh Kumar K.V 
19053c06f4eSAneesh Kumar K.V static int
19153c06f4eSAneesh Kumar K.V v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode,
19253c06f4eSAneesh Kumar K.V 		struct nameidata *nd)
19353c06f4eSAneesh Kumar K.V {
19453c06f4eSAneesh Kumar K.V 	int err = 0;
19553c06f4eSAneesh Kumar K.V 	gid_t gid;
19653c06f4eSAneesh Kumar K.V 	int flags;
19753c06f4eSAneesh Kumar K.V 	mode_t mode;
1986b39f6d2SAneesh Kumar K.V 	char *name = NULL;
19953c06f4eSAneesh Kumar K.V 	struct file *filp;
20053c06f4eSAneesh Kumar K.V 	struct p9_qid qid;
20153c06f4eSAneesh Kumar K.V 	struct inode *inode;
2026b39f6d2SAneesh Kumar K.V 	struct p9_fid *fid = NULL;
2036b39f6d2SAneesh Kumar K.V 	struct v9fs_inode *v9inode;
2046b39f6d2SAneesh Kumar K.V 	struct p9_fid *dfid, *ofid, *inode_fid;
2056b39f6d2SAneesh Kumar K.V 	struct v9fs_session_info *v9ses;
20653c06f4eSAneesh Kumar K.V 	struct posix_acl *pacl = NULL, *dacl = NULL;
20753c06f4eSAneesh Kumar K.V 
20853c06f4eSAneesh Kumar K.V 	v9ses = v9fs_inode2v9ses(dir);
209dd7dd556SAl Viro 	if (nd)
2108a5e929dSAl Viro 		flags = nd->intent.open.flags;
21153c06f4eSAneesh Kumar K.V 	else {
21253c06f4eSAneesh Kumar K.V 		/*
21353c06f4eSAneesh Kumar K.V 		 * create call without LOOKUP_OPEN is due
21453c06f4eSAneesh Kumar K.V 		 * to mknod of regular files. So use mknod
21553c06f4eSAneesh Kumar K.V 		 * operation.
21653c06f4eSAneesh Kumar K.V 		 */
21753c06f4eSAneesh Kumar K.V 		return v9fs_vfs_mknod_dotl(dir, dentry, omode, 0);
21853c06f4eSAneesh Kumar K.V 	}
21953c06f4eSAneesh Kumar K.V 
22053c06f4eSAneesh Kumar K.V 	name = (char *) dentry->d_name.name;
22153c06f4eSAneesh Kumar K.V 	P9_DPRINTK(P9_DEBUG_VFS, "v9fs_vfs_create_dotl: name:%s flags:0x%x "
22253c06f4eSAneesh Kumar K.V 			"mode:0x%x\n", name, flags, omode);
22353c06f4eSAneesh Kumar K.V 
22453c06f4eSAneesh Kumar K.V 	dfid = v9fs_fid_lookup(dentry->d_parent);
22553c06f4eSAneesh Kumar K.V 	if (IS_ERR(dfid)) {
22653c06f4eSAneesh Kumar K.V 		err = PTR_ERR(dfid);
22753c06f4eSAneesh Kumar K.V 		P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
22853c06f4eSAneesh Kumar K.V 		return err;
22953c06f4eSAneesh Kumar K.V 	}
23053c06f4eSAneesh Kumar K.V 
23153c06f4eSAneesh Kumar K.V 	/* clone a fid to use for creation */
23253c06f4eSAneesh Kumar K.V 	ofid = p9_client_walk(dfid, 0, NULL, 1);
23353c06f4eSAneesh Kumar K.V 	if (IS_ERR(ofid)) {
23453c06f4eSAneesh Kumar K.V 		err = PTR_ERR(ofid);
23553c06f4eSAneesh Kumar K.V 		P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
23653c06f4eSAneesh Kumar K.V 		return err;
23753c06f4eSAneesh Kumar K.V 	}
23853c06f4eSAneesh Kumar K.V 
23953c06f4eSAneesh Kumar K.V 	gid = v9fs_get_fsgid_for_create(dir);
24053c06f4eSAneesh Kumar K.V 
24153c06f4eSAneesh Kumar K.V 	mode = omode;
24253c06f4eSAneesh Kumar K.V 	/* Update mode based on ACL value */
24353c06f4eSAneesh Kumar K.V 	err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
24453c06f4eSAneesh Kumar K.V 	if (err) {
24553c06f4eSAneesh Kumar K.V 		P9_DPRINTK(P9_DEBUG_VFS,
24653c06f4eSAneesh Kumar K.V 			   "Failed to get acl values in creat %d\n", err);
24753c06f4eSAneesh Kumar K.V 		goto error;
24853c06f4eSAneesh Kumar K.V 	}
24953c06f4eSAneesh Kumar K.V 	err = p9_client_create_dotl(ofid, name, flags, mode, gid, &qid);
25053c06f4eSAneesh Kumar K.V 	if (err < 0) {
25153c06f4eSAneesh Kumar K.V 		P9_DPRINTK(P9_DEBUG_VFS,
25253c06f4eSAneesh Kumar K.V 				"p9_client_open_dotl failed in creat %d\n",
25353c06f4eSAneesh Kumar K.V 				err);
25453c06f4eSAneesh Kumar K.V 		goto error;
25553c06f4eSAneesh Kumar K.V 	}
256d28c61f0SAneesh Kumar K.V 	v9fs_invalidate_inode_attr(dir);
257af7542fcSAneesh Kumar K.V 
25853c06f4eSAneesh Kumar K.V 	/* instantiate inode and assign the unopened fid to the dentry */
25953c06f4eSAneesh Kumar K.V 	fid = p9_client_walk(dfid, 1, &name, 1);
26053c06f4eSAneesh Kumar K.V 	if (IS_ERR(fid)) {
26153c06f4eSAneesh Kumar K.V 		err = PTR_ERR(fid);
262c25a61f5SEric Van Hensbergen 		P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
26353c06f4eSAneesh Kumar K.V 		fid = NULL;
26453c06f4eSAneesh Kumar K.V 		goto error;
26553c06f4eSAneesh Kumar K.V 	}
266a78ce05dSAneesh Kumar K.V 	inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
26753c06f4eSAneesh Kumar K.V 	if (IS_ERR(inode)) {
26853c06f4eSAneesh Kumar K.V 		err = PTR_ERR(inode);
269af7542fcSAneesh Kumar K.V 		P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err);
27053c06f4eSAneesh Kumar K.V 		goto error;
27153c06f4eSAneesh Kumar K.V 	}
27253c06f4eSAneesh Kumar K.V 	d_instantiate(dentry, inode);
27353c06f4eSAneesh Kumar K.V 	err = v9fs_fid_add(dentry, fid);
27453c06f4eSAneesh Kumar K.V 	if (err < 0)
27553c06f4eSAneesh Kumar K.V 		goto error;
276af7542fcSAneesh Kumar K.V 
27753c06f4eSAneesh Kumar K.V 	/* Now set the ACL based on the default value */
27853c06f4eSAneesh Kumar K.V 	v9fs_set_create_acl(dentry, dacl, pacl);
2796b39f6d2SAneesh Kumar K.V 
2806b39f6d2SAneesh Kumar K.V 	v9inode = V9FS_I(inode);
2815a7e0a8cSAneesh Kumar K.V 	mutex_lock(&v9inode->v_mutex);
2827add697aSAneesh Kumar K.V 	if (v9ses->cache && !v9inode->writeback_fid &&
2837add697aSAneesh Kumar K.V 	    ((flags & O_ACCMODE) != O_RDONLY)) {
2843cf387d7SAneesh Kumar K.V 		/*
2856b39f6d2SAneesh Kumar K.V 		 * clone a fid and add it to writeback_fid
2863cf387d7SAneesh Kumar K.V 		 * we do it during open time instead of
2873cf387d7SAneesh Kumar K.V 		 * page dirty time via write_begin/page_mkwrite
2883cf387d7SAneesh Kumar K.V 		 * because we want write after unlink usecase
2893cf387d7SAneesh Kumar K.V 		 * to work.
2903cf387d7SAneesh Kumar K.V 		 */
2913cf387d7SAneesh Kumar K.V 		inode_fid = v9fs_writeback_fid(dentry);
2923cf387d7SAneesh Kumar K.V 		if (IS_ERR(inode_fid)) {
2933cf387d7SAneesh Kumar K.V 			err = PTR_ERR(inode_fid);
2945a7e0a8cSAneesh Kumar K.V 			mutex_unlock(&v9inode->v_mutex);
295398c4f0eSAneesh Kumar K.V 			goto err_clunk_old_fid;
2963cf387d7SAneesh Kumar K.V 		}
2976b39f6d2SAneesh Kumar K.V 		v9inode->writeback_fid = (void *) inode_fid;
2983cf387d7SAneesh Kumar K.V 	}
2995a7e0a8cSAneesh Kumar K.V 	mutex_unlock(&v9inode->v_mutex);
300af7542fcSAneesh Kumar K.V 	/* Since we are opening a file, assign the open fid to the file */
30153c06f4eSAneesh Kumar K.V 	filp = lookup_instantiate_filp(nd, dentry, generic_file_open);
30253c06f4eSAneesh Kumar K.V 	if (IS_ERR(filp)) {
303398c4f0eSAneesh Kumar K.V 		err = PTR_ERR(filp);
304398c4f0eSAneesh Kumar K.V 		goto err_clunk_old_fid;
30553c06f4eSAneesh Kumar K.V 	}
30653c06f4eSAneesh Kumar K.V 	filp->private_data = ofid;
30746848de0SAneesh Kumar K.V #ifdef CONFIG_9P_FSCACHE
30846848de0SAneesh Kumar K.V 	if (v9ses->cache)
30946848de0SAneesh Kumar K.V 		v9fs_cache_inode_set_cookie(inode, filp);
31046848de0SAneesh Kumar K.V #endif
31153c06f4eSAneesh Kumar K.V 	return 0;
31253c06f4eSAneesh Kumar K.V 
31353c06f4eSAneesh Kumar K.V error:
31453c06f4eSAneesh Kumar K.V 	if (fid)
31553c06f4eSAneesh Kumar K.V 		p9_client_clunk(fid);
316398c4f0eSAneesh Kumar K.V err_clunk_old_fid:
317398c4f0eSAneesh Kumar K.V 	if (ofid)
318398c4f0eSAneesh Kumar K.V 		p9_client_clunk(ofid);
31953c06f4eSAneesh Kumar K.V 	return err;
32053c06f4eSAneesh Kumar K.V }
32153c06f4eSAneesh Kumar K.V 
32253c06f4eSAneesh Kumar K.V /**
32353c06f4eSAneesh Kumar K.V  * v9fs_vfs_mkdir_dotl - VFS mkdir hook to create a directory
32453c06f4eSAneesh Kumar K.V  * @dir:  inode that is being unlinked
32553c06f4eSAneesh Kumar K.V  * @dentry: dentry that is being unlinked
32653c06f4eSAneesh Kumar K.V  * @mode: mode for new directory
32753c06f4eSAneesh Kumar K.V  *
32853c06f4eSAneesh Kumar K.V  */
32953c06f4eSAneesh Kumar K.V 
33053c06f4eSAneesh Kumar K.V static int v9fs_vfs_mkdir_dotl(struct inode *dir,
33153c06f4eSAneesh Kumar K.V 			       struct dentry *dentry, int omode)
33253c06f4eSAneesh Kumar K.V {
33353c06f4eSAneesh Kumar K.V 	int err;
33453c06f4eSAneesh Kumar K.V 	struct v9fs_session_info *v9ses;
33553c06f4eSAneesh Kumar K.V 	struct p9_fid *fid = NULL, *dfid = NULL;
33653c06f4eSAneesh Kumar K.V 	gid_t gid;
33753c06f4eSAneesh Kumar K.V 	char *name;
33853c06f4eSAneesh Kumar K.V 	mode_t mode;
33953c06f4eSAneesh Kumar K.V 	struct inode *inode;
34053c06f4eSAneesh Kumar K.V 	struct p9_qid qid;
34153c06f4eSAneesh Kumar K.V 	struct dentry *dir_dentry;
34253c06f4eSAneesh Kumar K.V 	struct posix_acl *dacl = NULL, *pacl = NULL;
34353c06f4eSAneesh Kumar K.V 
34453c06f4eSAneesh Kumar K.V 	P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name);
34553c06f4eSAneesh Kumar K.V 	err = 0;
34653c06f4eSAneesh Kumar K.V 	v9ses = v9fs_inode2v9ses(dir);
34753c06f4eSAneesh Kumar K.V 
34853c06f4eSAneesh Kumar K.V 	omode |= S_IFDIR;
34953c06f4eSAneesh Kumar K.V 	if (dir->i_mode & S_ISGID)
35053c06f4eSAneesh Kumar K.V 		omode |= S_ISGID;
35153c06f4eSAneesh Kumar K.V 
35253c06f4eSAneesh Kumar K.V 	dir_dentry = v9fs_dentry_from_dir_inode(dir);
35353c06f4eSAneesh Kumar K.V 	dfid = v9fs_fid_lookup(dir_dentry);
35453c06f4eSAneesh Kumar K.V 	if (IS_ERR(dfid)) {
35553c06f4eSAneesh Kumar K.V 		err = PTR_ERR(dfid);
35653c06f4eSAneesh Kumar K.V 		P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
35753c06f4eSAneesh Kumar K.V 		dfid = NULL;
35853c06f4eSAneesh Kumar K.V 		goto error;
35953c06f4eSAneesh Kumar K.V 	}
36053c06f4eSAneesh Kumar K.V 
36153c06f4eSAneesh Kumar K.V 	gid = v9fs_get_fsgid_for_create(dir);
36253c06f4eSAneesh Kumar K.V 	mode = omode;
36353c06f4eSAneesh Kumar K.V 	/* Update mode based on ACL value */
36453c06f4eSAneesh Kumar K.V 	err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
36553c06f4eSAneesh Kumar K.V 	if (err) {
36653c06f4eSAneesh Kumar K.V 		P9_DPRINTK(P9_DEBUG_VFS,
36753c06f4eSAneesh Kumar K.V 			   "Failed to get acl values in mkdir %d\n", err);
36853c06f4eSAneesh Kumar K.V 		goto error;
36953c06f4eSAneesh Kumar K.V 	}
37053c06f4eSAneesh Kumar K.V 	name = (char *) dentry->d_name.name;
37153c06f4eSAneesh Kumar K.V 	err = p9_client_mkdir_dotl(dfid, name, mode, gid, &qid);
37253c06f4eSAneesh Kumar K.V 	if (err < 0)
37353c06f4eSAneesh Kumar K.V 		goto error;
37453c06f4eSAneesh Kumar K.V 
37553c06f4eSAneesh Kumar K.V 	/* instantiate inode and assign the unopened fid to the dentry */
37653c06f4eSAneesh Kumar K.V 	if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
37753c06f4eSAneesh Kumar K.V 		fid = p9_client_walk(dfid, 1, &name, 1);
37853c06f4eSAneesh Kumar K.V 		if (IS_ERR(fid)) {
37953c06f4eSAneesh Kumar K.V 			err = PTR_ERR(fid);
38053c06f4eSAneesh Kumar K.V 			P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
38153c06f4eSAneesh Kumar K.V 				err);
38253c06f4eSAneesh Kumar K.V 			fid = NULL;
38353c06f4eSAneesh Kumar K.V 			goto error;
38453c06f4eSAneesh Kumar K.V 		}
38553c06f4eSAneesh Kumar K.V 
386a78ce05dSAneesh Kumar K.V 		inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
38753c06f4eSAneesh Kumar K.V 		if (IS_ERR(inode)) {
38853c06f4eSAneesh Kumar K.V 			err = PTR_ERR(inode);
38953c06f4eSAneesh Kumar K.V 			P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
39053c06f4eSAneesh Kumar K.V 				err);
39153c06f4eSAneesh Kumar K.V 			goto error;
39253c06f4eSAneesh Kumar K.V 		}
39353c06f4eSAneesh Kumar K.V 		d_instantiate(dentry, inode);
39453c06f4eSAneesh Kumar K.V 		err = v9fs_fid_add(dentry, fid);
39553c06f4eSAneesh Kumar K.V 		if (err < 0)
39653c06f4eSAneesh Kumar K.V 			goto error;
39753c06f4eSAneesh Kumar K.V 		fid = NULL;
39853c06f4eSAneesh Kumar K.V 	} else {
39953c06f4eSAneesh Kumar K.V 		/*
40053c06f4eSAneesh Kumar K.V 		 * Not in cached mode. No need to populate
40153c06f4eSAneesh Kumar K.V 		 * inode with stat. We need to get an inode
40253c06f4eSAneesh Kumar K.V 		 * so that we can set the acl with dentry
40353c06f4eSAneesh Kumar K.V 		 */
40453c06f4eSAneesh Kumar K.V 		inode = v9fs_get_inode(dir->i_sb, mode);
40553c06f4eSAneesh Kumar K.V 		if (IS_ERR(inode)) {
40653c06f4eSAneesh Kumar K.V 			err = PTR_ERR(inode);
40753c06f4eSAneesh Kumar K.V 			goto error;
40853c06f4eSAneesh Kumar K.V 		}
40953c06f4eSAneesh Kumar K.V 		d_instantiate(dentry, inode);
41053c06f4eSAneesh Kumar K.V 	}
41153c06f4eSAneesh Kumar K.V 	/* Now set the ACL based on the default value */
41253c06f4eSAneesh Kumar K.V 	v9fs_set_create_acl(dentry, dacl, pacl);
413b271ec47SAneesh Kumar K.V 	inc_nlink(dir);
414d28c61f0SAneesh Kumar K.V 	v9fs_invalidate_inode_attr(dir);
41553c06f4eSAneesh Kumar K.V error:
41653c06f4eSAneesh Kumar K.V 	if (fid)
41753c06f4eSAneesh Kumar K.V 		p9_client_clunk(fid);
41853c06f4eSAneesh Kumar K.V 	return err;
41953c06f4eSAneesh Kumar K.V }
42053c06f4eSAneesh Kumar K.V 
42153c06f4eSAneesh Kumar K.V static int
42253c06f4eSAneesh Kumar K.V v9fs_vfs_getattr_dotl(struct vfsmount *mnt, struct dentry *dentry,
42353c06f4eSAneesh Kumar K.V 		 struct kstat *stat)
42453c06f4eSAneesh Kumar K.V {
42553c06f4eSAneesh Kumar K.V 	int err;
42653c06f4eSAneesh Kumar K.V 	struct v9fs_session_info *v9ses;
42753c06f4eSAneesh Kumar K.V 	struct p9_fid *fid;
42853c06f4eSAneesh Kumar K.V 	struct p9_stat_dotl *st;
42953c06f4eSAneesh Kumar K.V 
43053c06f4eSAneesh Kumar K.V 	P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry);
43153c06f4eSAneesh Kumar K.V 	err = -EPERM;
43242869c8aSAneesh Kumar K.V 	v9ses = v9fs_dentry2v9ses(dentry);
433a1211908SAneesh Kumar K.V 	if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
434a1211908SAneesh Kumar K.V 		generic_fillattr(dentry->d_inode, stat);
435a1211908SAneesh Kumar K.V 		return 0;
436a1211908SAneesh Kumar K.V 	}
43753c06f4eSAneesh Kumar K.V 	fid = v9fs_fid_lookup(dentry);
43853c06f4eSAneesh Kumar K.V 	if (IS_ERR(fid))
43953c06f4eSAneesh Kumar K.V 		return PTR_ERR(fid);
44053c06f4eSAneesh Kumar K.V 
44153c06f4eSAneesh Kumar K.V 	/* Ask for all the fields in stat structure. Server will return
44253c06f4eSAneesh Kumar K.V 	 * whatever it supports
44353c06f4eSAneesh Kumar K.V 	 */
44453c06f4eSAneesh Kumar K.V 
44553c06f4eSAneesh Kumar K.V 	st = p9_client_getattr_dotl(fid, P9_STATS_ALL);
44653c06f4eSAneesh Kumar K.V 	if (IS_ERR(st))
44753c06f4eSAneesh Kumar K.V 		return PTR_ERR(st);
44853c06f4eSAneesh Kumar K.V 
44953c06f4eSAneesh Kumar K.V 	v9fs_stat2inode_dotl(st, dentry->d_inode);
45053c06f4eSAneesh Kumar K.V 	generic_fillattr(dentry->d_inode, stat);
45153c06f4eSAneesh Kumar K.V 	/* Change block size to what the server returned */
45253c06f4eSAneesh Kumar K.V 	stat->blksize = st->st_blksize;
45353c06f4eSAneesh Kumar K.V 
45453c06f4eSAneesh Kumar K.V 	kfree(st);
45553c06f4eSAneesh Kumar K.V 	return 0;
45653c06f4eSAneesh Kumar K.V }
45753c06f4eSAneesh Kumar K.V 
45853c06f4eSAneesh Kumar K.V /**
45953c06f4eSAneesh Kumar K.V  * v9fs_vfs_setattr_dotl - set file metadata
46053c06f4eSAneesh Kumar K.V  * @dentry: file whose metadata to set
46153c06f4eSAneesh Kumar K.V  * @iattr: metadata assignment structure
46253c06f4eSAneesh Kumar K.V  *
46353c06f4eSAneesh Kumar K.V  */
46453c06f4eSAneesh Kumar K.V 
46553c06f4eSAneesh Kumar K.V int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
46653c06f4eSAneesh Kumar K.V {
46753c06f4eSAneesh Kumar K.V 	int retval;
46853c06f4eSAneesh Kumar K.V 	struct v9fs_session_info *v9ses;
46953c06f4eSAneesh Kumar K.V 	struct p9_fid *fid;
47053c06f4eSAneesh Kumar K.V 	struct p9_iattr_dotl p9attr;
47153c06f4eSAneesh Kumar K.V 
47253c06f4eSAneesh Kumar K.V 	P9_DPRINTK(P9_DEBUG_VFS, "\n");
47353c06f4eSAneesh Kumar K.V 
47453c06f4eSAneesh Kumar K.V 	retval = inode_change_ok(dentry->d_inode, iattr);
47553c06f4eSAneesh Kumar K.V 	if (retval)
47653c06f4eSAneesh Kumar K.V 		return retval;
47753c06f4eSAneesh Kumar K.V 
47853c06f4eSAneesh Kumar K.V 	p9attr.valid = iattr->ia_valid;
47953c06f4eSAneesh Kumar K.V 	p9attr.mode = iattr->ia_mode;
48053c06f4eSAneesh Kumar K.V 	p9attr.uid = iattr->ia_uid;
48153c06f4eSAneesh Kumar K.V 	p9attr.gid = iattr->ia_gid;
48253c06f4eSAneesh Kumar K.V 	p9attr.size = iattr->ia_size;
48353c06f4eSAneesh Kumar K.V 	p9attr.atime_sec = iattr->ia_atime.tv_sec;
48453c06f4eSAneesh Kumar K.V 	p9attr.atime_nsec = iattr->ia_atime.tv_nsec;
48553c06f4eSAneesh Kumar K.V 	p9attr.mtime_sec = iattr->ia_mtime.tv_sec;
48653c06f4eSAneesh Kumar K.V 	p9attr.mtime_nsec = iattr->ia_mtime.tv_nsec;
48753c06f4eSAneesh Kumar K.V 
48853c06f4eSAneesh Kumar K.V 	retval = -EPERM;
48942869c8aSAneesh Kumar K.V 	v9ses = v9fs_dentry2v9ses(dentry);
49053c06f4eSAneesh Kumar K.V 	fid = v9fs_fid_lookup(dentry);
49153c06f4eSAneesh Kumar K.V 	if (IS_ERR(fid))
49253c06f4eSAneesh Kumar K.V 		return PTR_ERR(fid);
49353c06f4eSAneesh Kumar K.V 
4943dc5436aSAneesh Kumar K.V 	/* Write all dirty data */
4953dc5436aSAneesh Kumar K.V 	if (S_ISREG(dentry->d_inode->i_mode))
4963dc5436aSAneesh Kumar K.V 		filemap_write_and_wait(dentry->d_inode->i_mapping);
4973dc5436aSAneesh Kumar K.V 
498f10fc50fSAneesh Kumar K.V 	retval = p9_client_setattr(fid, &p9attr);
499f10fc50fSAneesh Kumar K.V 	if (retval < 0)
500f10fc50fSAneesh Kumar K.V 		return retval;
50153c06f4eSAneesh Kumar K.V 
502059c138bSAneesh Kumar K.V 	if ((iattr->ia_valid & ATTR_SIZE) &&
503059c138bSAneesh Kumar K.V 	    iattr->ia_size != i_size_read(dentry->d_inode))
504059c138bSAneesh Kumar K.V 		truncate_setsize(dentry->d_inode, iattr->ia_size);
505059c138bSAneesh Kumar K.V 
506059c138bSAneesh Kumar K.V 	v9fs_invalidate_inode_attr(dentry->d_inode);
50753c06f4eSAneesh Kumar K.V 	setattr_copy(dentry->d_inode, iattr);
50853c06f4eSAneesh Kumar K.V 	mark_inode_dirty(dentry->d_inode);
50953c06f4eSAneesh Kumar K.V 	if (iattr->ia_valid & ATTR_MODE) {
51053c06f4eSAneesh Kumar K.V 		/* We also want to update ACL when we update mode bits */
51153c06f4eSAneesh Kumar K.V 		retval = v9fs_acl_chmod(dentry);
51253c06f4eSAneesh Kumar K.V 		if (retval < 0)
51353c06f4eSAneesh Kumar K.V 			return retval;
51453c06f4eSAneesh Kumar K.V 	}
51553c06f4eSAneesh Kumar K.V 	return 0;
51653c06f4eSAneesh Kumar K.V }
51753c06f4eSAneesh Kumar K.V 
51853c06f4eSAneesh Kumar K.V /**
51953c06f4eSAneesh Kumar K.V  * v9fs_stat2inode_dotl - populate an inode structure with stat info
52053c06f4eSAneesh Kumar K.V  * @stat: stat structure
52153c06f4eSAneesh Kumar K.V  * @inode: inode to populate
52253c06f4eSAneesh Kumar K.V  * @sb: superblock of filesystem
52353c06f4eSAneesh Kumar K.V  *
52453c06f4eSAneesh Kumar K.V  */
52553c06f4eSAneesh Kumar K.V 
52653c06f4eSAneesh Kumar K.V void
52753c06f4eSAneesh Kumar K.V v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode)
52853c06f4eSAneesh Kumar K.V {
529b3cbea03SAneesh Kumar K.V 	struct v9fs_inode *v9inode = V9FS_I(inode);
53053c06f4eSAneesh Kumar K.V 
53153c06f4eSAneesh Kumar K.V 	if ((stat->st_result_mask & P9_STATS_BASIC) == P9_STATS_BASIC) {
53253c06f4eSAneesh Kumar K.V 		inode->i_atime.tv_sec = stat->st_atime_sec;
53353c06f4eSAneesh Kumar K.V 		inode->i_atime.tv_nsec = stat->st_atime_nsec;
53453c06f4eSAneesh Kumar K.V 		inode->i_mtime.tv_sec = stat->st_mtime_sec;
53553c06f4eSAneesh Kumar K.V 		inode->i_mtime.tv_nsec = stat->st_mtime_nsec;
53653c06f4eSAneesh Kumar K.V 		inode->i_ctime.tv_sec = stat->st_ctime_sec;
53753c06f4eSAneesh Kumar K.V 		inode->i_ctime.tv_nsec = stat->st_ctime_nsec;
53853c06f4eSAneesh Kumar K.V 		inode->i_uid = stat->st_uid;
53953c06f4eSAneesh Kumar K.V 		inode->i_gid = stat->st_gid;
54053c06f4eSAneesh Kumar K.V 		inode->i_nlink = stat->st_nlink;
54153c06f4eSAneesh Kumar K.V 		inode->i_mode = stat->st_mode;
54253c06f4eSAneesh Kumar K.V 		inode->i_rdev = new_decode_dev(stat->st_rdev);
54353c06f4eSAneesh Kumar K.V 
54453c06f4eSAneesh Kumar K.V 		if ((S_ISBLK(inode->i_mode)) || (S_ISCHR(inode->i_mode)))
54553c06f4eSAneesh Kumar K.V 			init_special_inode(inode, inode->i_mode, inode->i_rdev);
54653c06f4eSAneesh Kumar K.V 
54753c06f4eSAneesh Kumar K.V 		i_size_write(inode, stat->st_size);
54853c06f4eSAneesh Kumar K.V 		inode->i_blocks = stat->st_blocks;
54953c06f4eSAneesh Kumar K.V 	} else {
55053c06f4eSAneesh Kumar K.V 		if (stat->st_result_mask & P9_STATS_ATIME) {
55153c06f4eSAneesh Kumar K.V 			inode->i_atime.tv_sec = stat->st_atime_sec;
55253c06f4eSAneesh Kumar K.V 			inode->i_atime.tv_nsec = stat->st_atime_nsec;
55353c06f4eSAneesh Kumar K.V 		}
55453c06f4eSAneesh Kumar K.V 		if (stat->st_result_mask & P9_STATS_MTIME) {
55553c06f4eSAneesh Kumar K.V 			inode->i_mtime.tv_sec = stat->st_mtime_sec;
55653c06f4eSAneesh Kumar K.V 			inode->i_mtime.tv_nsec = stat->st_mtime_nsec;
55753c06f4eSAneesh Kumar K.V 		}
55853c06f4eSAneesh Kumar K.V 		if (stat->st_result_mask & P9_STATS_CTIME) {
55953c06f4eSAneesh Kumar K.V 			inode->i_ctime.tv_sec = stat->st_ctime_sec;
56053c06f4eSAneesh Kumar K.V 			inode->i_ctime.tv_nsec = stat->st_ctime_nsec;
56153c06f4eSAneesh Kumar K.V 		}
56253c06f4eSAneesh Kumar K.V 		if (stat->st_result_mask & P9_STATS_UID)
56353c06f4eSAneesh Kumar K.V 			inode->i_uid = stat->st_uid;
56453c06f4eSAneesh Kumar K.V 		if (stat->st_result_mask & P9_STATS_GID)
56553c06f4eSAneesh Kumar K.V 			inode->i_gid = stat->st_gid;
56653c06f4eSAneesh Kumar K.V 		if (stat->st_result_mask & P9_STATS_NLINK)
56753c06f4eSAneesh Kumar K.V 			inode->i_nlink = stat->st_nlink;
56853c06f4eSAneesh Kumar K.V 		if (stat->st_result_mask & P9_STATS_MODE) {
56953c06f4eSAneesh Kumar K.V 			inode->i_mode = stat->st_mode;
57053c06f4eSAneesh Kumar K.V 			if ((S_ISBLK(inode->i_mode)) ||
57153c06f4eSAneesh Kumar K.V 						(S_ISCHR(inode->i_mode)))
57253c06f4eSAneesh Kumar K.V 				init_special_inode(inode, inode->i_mode,
57353c06f4eSAneesh Kumar K.V 								inode->i_rdev);
57453c06f4eSAneesh Kumar K.V 		}
57553c06f4eSAneesh Kumar K.V 		if (stat->st_result_mask & P9_STATS_RDEV)
57653c06f4eSAneesh Kumar K.V 			inode->i_rdev = new_decode_dev(stat->st_rdev);
57753c06f4eSAneesh Kumar K.V 		if (stat->st_result_mask & P9_STATS_SIZE)
57853c06f4eSAneesh Kumar K.V 			i_size_write(inode, stat->st_size);
57953c06f4eSAneesh Kumar K.V 		if (stat->st_result_mask & P9_STATS_BLOCKS)
58053c06f4eSAneesh Kumar K.V 			inode->i_blocks = stat->st_blocks;
58153c06f4eSAneesh Kumar K.V 	}
58253c06f4eSAneesh Kumar K.V 	if (stat->st_result_mask & P9_STATS_GEN)
58353c06f4eSAneesh Kumar K.V 		inode->i_generation = stat->st_gen;
58453c06f4eSAneesh Kumar K.V 
58553c06f4eSAneesh Kumar K.V 	/* Currently we don't support P9_STATS_BTIME and P9_STATS_DATA_VERSION
58653c06f4eSAneesh Kumar K.V 	 * because the inode structure does not have fields for them.
58753c06f4eSAneesh Kumar K.V 	 */
588b3cbea03SAneesh Kumar K.V 	v9inode->cache_validity &= ~V9FS_INO_INVALID_ATTR;
58953c06f4eSAneesh Kumar K.V }
59053c06f4eSAneesh Kumar K.V 
59153c06f4eSAneesh Kumar K.V static int
59253c06f4eSAneesh Kumar K.V v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry,
59353c06f4eSAneesh Kumar K.V 		const char *symname)
59453c06f4eSAneesh Kumar K.V {
59553c06f4eSAneesh Kumar K.V 	int err;
59653c06f4eSAneesh Kumar K.V 	gid_t gid;
597d28c61f0SAneesh Kumar K.V 	char *name;
598d28c61f0SAneesh Kumar K.V 	struct p9_qid qid;
599d28c61f0SAneesh Kumar K.V 	struct inode *inode;
600d28c61f0SAneesh Kumar K.V 	struct p9_fid *dfid;
601d28c61f0SAneesh Kumar K.V 	struct p9_fid *fid = NULL;
602d28c61f0SAneesh Kumar K.V 	struct v9fs_session_info *v9ses;
60353c06f4eSAneesh Kumar K.V 
60453c06f4eSAneesh Kumar K.V 	name = (char *) dentry->d_name.name;
60553c06f4eSAneesh Kumar K.V 	P9_DPRINTK(P9_DEBUG_VFS, "v9fs_vfs_symlink_dotl : %lu,%s,%s\n",
60653c06f4eSAneesh Kumar K.V 			dir->i_ino, name, symname);
60753c06f4eSAneesh Kumar K.V 	v9ses = v9fs_inode2v9ses(dir);
60853c06f4eSAneesh Kumar K.V 
60953c06f4eSAneesh Kumar K.V 	dfid = v9fs_fid_lookup(dentry->d_parent);
61053c06f4eSAneesh Kumar K.V 	if (IS_ERR(dfid)) {
61153c06f4eSAneesh Kumar K.V 		err = PTR_ERR(dfid);
61253c06f4eSAneesh Kumar K.V 		P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
61353c06f4eSAneesh Kumar K.V 		return err;
61453c06f4eSAneesh Kumar K.V 	}
61553c06f4eSAneesh Kumar K.V 
61653c06f4eSAneesh Kumar K.V 	gid = v9fs_get_fsgid_for_create(dir);
61753c06f4eSAneesh Kumar K.V 
61853c06f4eSAneesh Kumar K.V 	/* Server doesn't alter fid on TSYMLINK. Hence no need to clone it. */
61953c06f4eSAneesh Kumar K.V 	err = p9_client_symlink(dfid, name, (char *)symname, gid, &qid);
62053c06f4eSAneesh Kumar K.V 
62153c06f4eSAneesh Kumar K.V 	if (err < 0) {
62253c06f4eSAneesh Kumar K.V 		P9_DPRINTK(P9_DEBUG_VFS, "p9_client_symlink failed %d\n", err);
62353c06f4eSAneesh Kumar K.V 		goto error;
62453c06f4eSAneesh Kumar K.V 	}
62553c06f4eSAneesh Kumar K.V 
626d28c61f0SAneesh Kumar K.V 	v9fs_invalidate_inode_attr(dir);
62753c06f4eSAneesh Kumar K.V 	if (v9ses->cache) {
62853c06f4eSAneesh Kumar K.V 		/* Now walk from the parent so we can get an unopened fid. */
62953c06f4eSAneesh Kumar K.V 		fid = p9_client_walk(dfid, 1, &name, 1);
63053c06f4eSAneesh Kumar K.V 		if (IS_ERR(fid)) {
63153c06f4eSAneesh Kumar K.V 			err = PTR_ERR(fid);
63253c06f4eSAneesh Kumar K.V 			P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
63353c06f4eSAneesh Kumar K.V 					err);
63453c06f4eSAneesh Kumar K.V 			fid = NULL;
63553c06f4eSAneesh Kumar K.V 			goto error;
63653c06f4eSAneesh Kumar K.V 		}
63753c06f4eSAneesh Kumar K.V 
63853c06f4eSAneesh Kumar K.V 		/* instantiate inode and assign the unopened fid to dentry */
639a78ce05dSAneesh Kumar K.V 		inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
64053c06f4eSAneesh Kumar K.V 		if (IS_ERR(inode)) {
64153c06f4eSAneesh Kumar K.V 			err = PTR_ERR(inode);
64253c06f4eSAneesh Kumar K.V 			P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
64353c06f4eSAneesh Kumar K.V 					err);
64453c06f4eSAneesh Kumar K.V 			goto error;
64553c06f4eSAneesh Kumar K.V 		}
64653c06f4eSAneesh Kumar K.V 		d_instantiate(dentry, inode);
64753c06f4eSAneesh Kumar K.V 		err = v9fs_fid_add(dentry, fid);
64853c06f4eSAneesh Kumar K.V 		if (err < 0)
64953c06f4eSAneesh Kumar K.V 			goto error;
65053c06f4eSAneesh Kumar K.V 		fid = NULL;
65153c06f4eSAneesh Kumar K.V 	} else {
65253c06f4eSAneesh Kumar K.V 		/* Not in cached mode. No need to populate inode with stat */
65353c06f4eSAneesh Kumar K.V 		inode = v9fs_get_inode(dir->i_sb, S_IFLNK);
65453c06f4eSAneesh Kumar K.V 		if (IS_ERR(inode)) {
65553c06f4eSAneesh Kumar K.V 			err = PTR_ERR(inode);
65653c06f4eSAneesh Kumar K.V 			goto error;
65753c06f4eSAneesh Kumar K.V 		}
65853c06f4eSAneesh Kumar K.V 		d_instantiate(dentry, inode);
65953c06f4eSAneesh Kumar K.V 	}
66053c06f4eSAneesh Kumar K.V 
66153c06f4eSAneesh Kumar K.V error:
66253c06f4eSAneesh Kumar K.V 	if (fid)
66353c06f4eSAneesh Kumar K.V 		p9_client_clunk(fid);
66453c06f4eSAneesh Kumar K.V 
66553c06f4eSAneesh Kumar K.V 	return err;
66653c06f4eSAneesh Kumar K.V }
66753c06f4eSAneesh Kumar K.V 
66853c06f4eSAneesh Kumar K.V /**
66953c06f4eSAneesh Kumar K.V  * v9fs_vfs_link_dotl - create a hardlink for dotl
67053c06f4eSAneesh Kumar K.V  * @old_dentry: dentry for file to link to
67153c06f4eSAneesh Kumar K.V  * @dir: inode destination for new link
67253c06f4eSAneesh Kumar K.V  * @dentry: dentry for link
67353c06f4eSAneesh Kumar K.V  *
67453c06f4eSAneesh Kumar K.V  */
67553c06f4eSAneesh Kumar K.V 
67653c06f4eSAneesh Kumar K.V static int
67753c06f4eSAneesh Kumar K.V v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir,
67853c06f4eSAneesh Kumar K.V 		struct dentry *dentry)
67953c06f4eSAneesh Kumar K.V {
68053c06f4eSAneesh Kumar K.V 	int err;
68153c06f4eSAneesh Kumar K.V 	char *name;
68253c06f4eSAneesh Kumar K.V 	struct dentry *dir_dentry;
683d28c61f0SAneesh Kumar K.V 	struct p9_fid *dfid, *oldfid;
684d28c61f0SAneesh Kumar K.V 	struct v9fs_session_info *v9ses;
68553c06f4eSAneesh Kumar K.V 
68653c06f4eSAneesh Kumar K.V 	P9_DPRINTK(P9_DEBUG_VFS, "dir ino: %lu, old_name: %s, new_name: %s\n",
68753c06f4eSAneesh Kumar K.V 			dir->i_ino, old_dentry->d_name.name,
68853c06f4eSAneesh Kumar K.V 			dentry->d_name.name);
68953c06f4eSAneesh Kumar K.V 
69053c06f4eSAneesh Kumar K.V 	v9ses = v9fs_inode2v9ses(dir);
69153c06f4eSAneesh Kumar K.V 	dir_dentry = v9fs_dentry_from_dir_inode(dir);
69253c06f4eSAneesh Kumar K.V 	dfid = v9fs_fid_lookup(dir_dentry);
69353c06f4eSAneesh Kumar K.V 	if (IS_ERR(dfid))
69453c06f4eSAneesh Kumar K.V 		return PTR_ERR(dfid);
69553c06f4eSAneesh Kumar K.V 
69653c06f4eSAneesh Kumar K.V 	oldfid = v9fs_fid_lookup(old_dentry);
69753c06f4eSAneesh Kumar K.V 	if (IS_ERR(oldfid))
69853c06f4eSAneesh Kumar K.V 		return PTR_ERR(oldfid);
69953c06f4eSAneesh Kumar K.V 
70053c06f4eSAneesh Kumar K.V 	name = (char *) dentry->d_name.name;
70153c06f4eSAneesh Kumar K.V 
70253c06f4eSAneesh Kumar K.V 	err = p9_client_link(dfid, oldfid, (char *)dentry->d_name.name);
70353c06f4eSAneesh Kumar K.V 
70453c06f4eSAneesh Kumar K.V 	if (err < 0) {
70553c06f4eSAneesh Kumar K.V 		P9_DPRINTK(P9_DEBUG_VFS, "p9_client_link failed %d\n", err);
70653c06f4eSAneesh Kumar K.V 		return err;
70753c06f4eSAneesh Kumar K.V 	}
70853c06f4eSAneesh Kumar K.V 
709d28c61f0SAneesh Kumar K.V 	v9fs_invalidate_inode_attr(dir);
71053c06f4eSAneesh Kumar K.V 	if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
71153c06f4eSAneesh Kumar K.V 		/* Get the latest stat info from server. */
71253c06f4eSAneesh Kumar K.V 		struct p9_fid *fid;
71353c06f4eSAneesh Kumar K.V 		fid = v9fs_fid_lookup(old_dentry);
71453c06f4eSAneesh Kumar K.V 		if (IS_ERR(fid))
71553c06f4eSAneesh Kumar K.V 			return PTR_ERR(fid);
71653c06f4eSAneesh Kumar K.V 
717c06c066aSAneesh Kumar K.V 		v9fs_refresh_inode_dotl(fid, old_dentry->d_inode);
71853c06f4eSAneesh Kumar K.V 	}
71920656a49SAneesh Kumar K.V 	ihold(old_dentry->d_inode);
72053c06f4eSAneesh Kumar K.V 	d_instantiate(dentry, old_dentry->d_inode);
72153c06f4eSAneesh Kumar K.V 
72253c06f4eSAneesh Kumar K.V 	return err;
72353c06f4eSAneesh Kumar K.V }
72453c06f4eSAneesh Kumar K.V 
72553c06f4eSAneesh Kumar K.V /**
72653c06f4eSAneesh Kumar K.V  * v9fs_vfs_mknod_dotl - create a special file
72753c06f4eSAneesh Kumar K.V  * @dir: inode destination for new link
72853c06f4eSAneesh Kumar K.V  * @dentry: dentry for file
72953c06f4eSAneesh Kumar K.V  * @mode: mode for creation
73053c06f4eSAneesh Kumar K.V  * @rdev: device associated with special file
73153c06f4eSAneesh Kumar K.V  *
73253c06f4eSAneesh Kumar K.V  */
73353c06f4eSAneesh Kumar K.V static int
73453c06f4eSAneesh Kumar K.V v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int omode,
73553c06f4eSAneesh Kumar K.V 		dev_t rdev)
73653c06f4eSAneesh Kumar K.V {
73753c06f4eSAneesh Kumar K.V 	int err;
738d28c61f0SAneesh Kumar K.V 	gid_t gid;
73953c06f4eSAneesh Kumar K.V 	char *name;
74053c06f4eSAneesh Kumar K.V 	mode_t mode;
74153c06f4eSAneesh Kumar K.V 	struct v9fs_session_info *v9ses;
74253c06f4eSAneesh Kumar K.V 	struct p9_fid *fid = NULL, *dfid = NULL;
74353c06f4eSAneesh Kumar K.V 	struct inode *inode;
74453c06f4eSAneesh Kumar K.V 	struct p9_qid qid;
74553c06f4eSAneesh Kumar K.V 	struct dentry *dir_dentry;
74653c06f4eSAneesh Kumar K.V 	struct posix_acl *dacl = NULL, *pacl = NULL;
74753c06f4eSAneesh Kumar K.V 
74853c06f4eSAneesh Kumar K.V 	P9_DPRINTK(P9_DEBUG_VFS,
74953c06f4eSAneesh Kumar K.V 		" %lu,%s mode: %x MAJOR: %u MINOR: %u\n", dir->i_ino,
75053c06f4eSAneesh Kumar K.V 		dentry->d_name.name, omode, MAJOR(rdev), MINOR(rdev));
75153c06f4eSAneesh Kumar K.V 
75253c06f4eSAneesh Kumar K.V 	if (!new_valid_dev(rdev))
75353c06f4eSAneesh Kumar K.V 		return -EINVAL;
75453c06f4eSAneesh Kumar K.V 
75553c06f4eSAneesh Kumar K.V 	v9ses = v9fs_inode2v9ses(dir);
75653c06f4eSAneesh Kumar K.V 	dir_dentry = v9fs_dentry_from_dir_inode(dir);
75753c06f4eSAneesh Kumar K.V 	dfid = v9fs_fid_lookup(dir_dentry);
75853c06f4eSAneesh Kumar K.V 	if (IS_ERR(dfid)) {
75953c06f4eSAneesh Kumar K.V 		err = PTR_ERR(dfid);
76053c06f4eSAneesh Kumar K.V 		P9_DPRINTK(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
76153c06f4eSAneesh Kumar K.V 		dfid = NULL;
76253c06f4eSAneesh Kumar K.V 		goto error;
76353c06f4eSAneesh Kumar K.V 	}
76453c06f4eSAneesh Kumar K.V 
76553c06f4eSAneesh Kumar K.V 	gid = v9fs_get_fsgid_for_create(dir);
76653c06f4eSAneesh Kumar K.V 	mode = omode;
76753c06f4eSAneesh Kumar K.V 	/* Update mode based on ACL value */
76853c06f4eSAneesh Kumar K.V 	err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
76953c06f4eSAneesh Kumar K.V 	if (err) {
77053c06f4eSAneesh Kumar K.V 		P9_DPRINTK(P9_DEBUG_VFS,
77153c06f4eSAneesh Kumar K.V 			   "Failed to get acl values in mknod %d\n", err);
77253c06f4eSAneesh Kumar K.V 		goto error;
77353c06f4eSAneesh Kumar K.V 	}
77453c06f4eSAneesh Kumar K.V 	name = (char *) dentry->d_name.name;
77553c06f4eSAneesh Kumar K.V 
77653c06f4eSAneesh Kumar K.V 	err = p9_client_mknod_dotl(dfid, name, mode, rdev, gid, &qid);
77753c06f4eSAneesh Kumar K.V 	if (err < 0)
77853c06f4eSAneesh Kumar K.V 		goto error;
77953c06f4eSAneesh Kumar K.V 
780d28c61f0SAneesh Kumar K.V 	v9fs_invalidate_inode_attr(dir);
78153c06f4eSAneesh Kumar K.V 	/* instantiate inode and assign the unopened fid to the dentry */
78253c06f4eSAneesh Kumar K.V 	if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
78353c06f4eSAneesh Kumar K.V 		fid = p9_client_walk(dfid, 1, &name, 1);
78453c06f4eSAneesh Kumar K.V 		if (IS_ERR(fid)) {
78553c06f4eSAneesh Kumar K.V 			err = PTR_ERR(fid);
78653c06f4eSAneesh Kumar K.V 			P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
78753c06f4eSAneesh Kumar K.V 				err);
78853c06f4eSAneesh Kumar K.V 			fid = NULL;
78953c06f4eSAneesh Kumar K.V 			goto error;
79053c06f4eSAneesh Kumar K.V 		}
79153c06f4eSAneesh Kumar K.V 
792a78ce05dSAneesh Kumar K.V 		inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
79353c06f4eSAneesh Kumar K.V 		if (IS_ERR(inode)) {
79453c06f4eSAneesh Kumar K.V 			err = PTR_ERR(inode);
79553c06f4eSAneesh Kumar K.V 			P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
79653c06f4eSAneesh Kumar K.V 				err);
79753c06f4eSAneesh Kumar K.V 			goto error;
79853c06f4eSAneesh Kumar K.V 		}
79953c06f4eSAneesh Kumar K.V 		d_instantiate(dentry, inode);
80053c06f4eSAneesh Kumar K.V 		err = v9fs_fid_add(dentry, fid);
80153c06f4eSAneesh Kumar K.V 		if (err < 0)
80253c06f4eSAneesh Kumar K.V 			goto error;
80353c06f4eSAneesh Kumar K.V 		fid = NULL;
80453c06f4eSAneesh Kumar K.V 	} else {
80553c06f4eSAneesh Kumar K.V 		/*
80653c06f4eSAneesh Kumar K.V 		 * Not in cached mode. No need to populate inode with stat.
80753c06f4eSAneesh Kumar K.V 		 * socket syscall returns a fd, so we need instantiate
80853c06f4eSAneesh Kumar K.V 		 */
80953c06f4eSAneesh Kumar K.V 		inode = v9fs_get_inode(dir->i_sb, mode);
81053c06f4eSAneesh Kumar K.V 		if (IS_ERR(inode)) {
81153c06f4eSAneesh Kumar K.V 			err = PTR_ERR(inode);
81253c06f4eSAneesh Kumar K.V 			goto error;
81353c06f4eSAneesh Kumar K.V 		}
81453c06f4eSAneesh Kumar K.V 		d_instantiate(dentry, inode);
81553c06f4eSAneesh Kumar K.V 	}
81653c06f4eSAneesh Kumar K.V 	/* Now set the ACL based on the default value */
81753c06f4eSAneesh Kumar K.V 	v9fs_set_create_acl(dentry, dacl, pacl);
81853c06f4eSAneesh Kumar K.V error:
81953c06f4eSAneesh Kumar K.V 	if (fid)
82053c06f4eSAneesh Kumar K.V 		p9_client_clunk(fid);
82153c06f4eSAneesh Kumar K.V 	return err;
82253c06f4eSAneesh Kumar K.V }
82353c06f4eSAneesh Kumar K.V 
82453c06f4eSAneesh Kumar K.V /**
82553c06f4eSAneesh Kumar K.V  * v9fs_vfs_follow_link_dotl - follow a symlink path
82653c06f4eSAneesh Kumar K.V  * @dentry: dentry for symlink
82753c06f4eSAneesh Kumar K.V  * @nd: nameidata
82853c06f4eSAneesh Kumar K.V  *
82953c06f4eSAneesh Kumar K.V  */
83053c06f4eSAneesh Kumar K.V 
83153c06f4eSAneesh Kumar K.V static void *
83253c06f4eSAneesh Kumar K.V v9fs_vfs_follow_link_dotl(struct dentry *dentry, struct nameidata *nd)
83353c06f4eSAneesh Kumar K.V {
83431b6ceacSM. Mohan Kumar 	int retval;
83531b6ceacSM. Mohan Kumar 	struct p9_fid *fid;
83653c06f4eSAneesh Kumar K.V 	char *link = __getname();
83731b6ceacSM. Mohan Kumar 	char *target;
83853c06f4eSAneesh Kumar K.V 
83931b6ceacSM. Mohan Kumar 	P9_DPRINTK(P9_DEBUG_VFS, "%s\n", dentry->d_name.name);
84053c06f4eSAneesh Kumar K.V 
84131b6ceacSM. Mohan Kumar 	if (!link) {
84253c06f4eSAneesh Kumar K.V 		link = ERR_PTR(-ENOMEM);
84331b6ceacSM. Mohan Kumar 		goto ndset;
84453c06f4eSAneesh Kumar K.V 	}
84531b6ceacSM. Mohan Kumar 	fid = v9fs_fid_lookup(dentry);
84631b6ceacSM. Mohan Kumar 	if (IS_ERR(fid)) {
84731b6ceacSM. Mohan Kumar 		__putname(link);
848936bb2d7SAneesh Kumar K.V 		link = ERR_CAST(fid);
84931b6ceacSM. Mohan Kumar 		goto ndset;
85031b6ceacSM. Mohan Kumar 	}
85131b6ceacSM. Mohan Kumar 	retval = p9_client_readlink(fid, &target);
85231b6ceacSM. Mohan Kumar 	if (!retval) {
85331b6ceacSM. Mohan Kumar 		strcpy(link, target);
85431b6ceacSM. Mohan Kumar 		kfree(target);
85531b6ceacSM. Mohan Kumar 		goto ndset;
85631b6ceacSM. Mohan Kumar 	}
85731b6ceacSM. Mohan Kumar 	__putname(link);
85831b6ceacSM. Mohan Kumar 	link = ERR_PTR(retval);
85931b6ceacSM. Mohan Kumar ndset:
86053c06f4eSAneesh Kumar K.V 	nd_set_link(nd, link);
86153c06f4eSAneesh Kumar K.V 	return NULL;
86253c06f4eSAneesh Kumar K.V }
86353c06f4eSAneesh Kumar K.V 
864b3cbea03SAneesh Kumar K.V int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode)
865b3cbea03SAneesh Kumar K.V {
866b3cbea03SAneesh Kumar K.V 	loff_t i_size;
867b3cbea03SAneesh Kumar K.V 	struct p9_stat_dotl *st;
868b3cbea03SAneesh Kumar K.V 	struct v9fs_session_info *v9ses;
869b3cbea03SAneesh Kumar K.V 
870b3cbea03SAneesh Kumar K.V 	v9ses = v9fs_inode2v9ses(inode);
871b3cbea03SAneesh Kumar K.V 	st = p9_client_getattr_dotl(fid, P9_STATS_ALL);
872b3cbea03SAneesh Kumar K.V 	if (IS_ERR(st))
873b3cbea03SAneesh Kumar K.V 		return PTR_ERR(st);
874b3cbea03SAneesh Kumar K.V 
875b3cbea03SAneesh Kumar K.V 	spin_lock(&inode->i_lock);
876b3cbea03SAneesh Kumar K.V 	/*
877b3cbea03SAneesh Kumar K.V 	 * We don't want to refresh inode->i_size,
878b3cbea03SAneesh Kumar K.V 	 * because we may have cached data
879b3cbea03SAneesh Kumar K.V 	 */
880b3cbea03SAneesh Kumar K.V 	i_size = inode->i_size;
881b3cbea03SAneesh Kumar K.V 	v9fs_stat2inode_dotl(st, inode);
882b3cbea03SAneesh Kumar K.V 	if (v9ses->cache)
883b3cbea03SAneesh Kumar K.V 		inode->i_size = i_size;
884b3cbea03SAneesh Kumar K.V 	spin_unlock(&inode->i_lock);
885b3cbea03SAneesh Kumar K.V 	kfree(st);
886b3cbea03SAneesh Kumar K.V 	return 0;
887b3cbea03SAneesh Kumar K.V }
888b3cbea03SAneesh Kumar K.V 
88953c06f4eSAneesh Kumar K.V const struct inode_operations v9fs_dir_inode_operations_dotl = {
89053c06f4eSAneesh Kumar K.V 	.create = v9fs_vfs_create_dotl,
89153c06f4eSAneesh Kumar K.V 	.lookup = v9fs_vfs_lookup,
89253c06f4eSAneesh Kumar K.V 	.link = v9fs_vfs_link_dotl,
89353c06f4eSAneesh Kumar K.V 	.symlink = v9fs_vfs_symlink_dotl,
89453c06f4eSAneesh Kumar K.V 	.unlink = v9fs_vfs_unlink,
89553c06f4eSAneesh Kumar K.V 	.mkdir = v9fs_vfs_mkdir_dotl,
89653c06f4eSAneesh Kumar K.V 	.rmdir = v9fs_vfs_rmdir,
89753c06f4eSAneesh Kumar K.V 	.mknod = v9fs_vfs_mknod_dotl,
89853c06f4eSAneesh Kumar K.V 	.rename = v9fs_vfs_rename,
89953c06f4eSAneesh Kumar K.V 	.getattr = v9fs_vfs_getattr_dotl,
90053c06f4eSAneesh Kumar K.V 	.setattr = v9fs_vfs_setattr_dotl,
90153c06f4eSAneesh Kumar K.V 	.setxattr = generic_setxattr,
90253c06f4eSAneesh Kumar K.V 	.getxattr = generic_getxattr,
90353c06f4eSAneesh Kumar K.V 	.removexattr = generic_removexattr,
90453c06f4eSAneesh Kumar K.V 	.listxattr = v9fs_listxattr,
90553c06f4eSAneesh Kumar K.V 	.check_acl = v9fs_check_acl,
90653c06f4eSAneesh Kumar K.V };
90753c06f4eSAneesh Kumar K.V 
90853c06f4eSAneesh Kumar K.V const struct inode_operations v9fs_file_inode_operations_dotl = {
90953c06f4eSAneesh Kumar K.V 	.getattr = v9fs_vfs_getattr_dotl,
91053c06f4eSAneesh Kumar K.V 	.setattr = v9fs_vfs_setattr_dotl,
91153c06f4eSAneesh Kumar K.V 	.setxattr = generic_setxattr,
91253c06f4eSAneesh Kumar K.V 	.getxattr = generic_getxattr,
91353c06f4eSAneesh Kumar K.V 	.removexattr = generic_removexattr,
91453c06f4eSAneesh Kumar K.V 	.listxattr = v9fs_listxattr,
91553c06f4eSAneesh Kumar K.V 	.check_acl = v9fs_check_acl,
91653c06f4eSAneesh Kumar K.V };
91753c06f4eSAneesh Kumar K.V 
91853c06f4eSAneesh Kumar K.V const struct inode_operations v9fs_symlink_inode_operations_dotl = {
91931b6ceacSM. Mohan Kumar 	.readlink = generic_readlink,
92053c06f4eSAneesh Kumar K.V 	.follow_link = v9fs_vfs_follow_link_dotl,
92153c06f4eSAneesh Kumar K.V 	.put_link = v9fs_vfs_put_link,
92253c06f4eSAneesh Kumar K.V 	.getattr = v9fs_vfs_getattr_dotl,
92353c06f4eSAneesh Kumar K.V 	.setattr = v9fs_vfs_setattr_dotl,
92453c06f4eSAneesh Kumar K.V 	.setxattr = generic_setxattr,
92553c06f4eSAneesh Kumar K.V 	.getxattr = generic_getxattr,
92653c06f4eSAneesh Kumar K.V 	.removexattr = generic_removexattr,
92753c06f4eSAneesh Kumar K.V 	.listxattr = v9fs_listxattr,
92853c06f4eSAneesh Kumar K.V };
929