Linux Audio

Check our new training course

Linux BSP development engineering services

Need help to port Linux and bootloaders to your hardware?
Loading...
v6.2
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * This file contains vfs inode ops for the 9P2000.L protocol.
   4 *
   5 *  Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
   6 *  Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
   7 */
   8
   9#include <linux/module.h>
  10#include <linux/errno.h>
  11#include <linux/fs.h>
  12#include <linux/file.h>
  13#include <linux/pagemap.h>
  14#include <linux/stat.h>
  15#include <linux/string.h>
  16#include <linux/inet.h>
  17#include <linux/namei.h>
  18#include <linux/sched.h>
  19#include <linux/slab.h>
  20#include <linux/xattr.h>
  21#include <linux/posix_acl.h>
  22#include <net/9p/9p.h>
  23#include <net/9p/client.h>
  24
  25#include "v9fs.h"
  26#include "v9fs_vfs.h"
  27#include "fid.h"
  28#include "cache.h"
  29#include "xattr.h"
  30#include "acl.h"
  31
  32static int
  33v9fs_vfs_mknod_dotl(struct user_namespace *mnt_userns, struct inode *dir,
  34		    struct dentry *dentry, umode_t omode, dev_t rdev);
  35
  36/**
  37 * v9fs_get_fsgid_for_create - Helper function to get the gid for a new object
  38 * @dir_inode: The directory inode
  39 *
  40 * Helper function to get the gid for creating a
  41 * new file system object. This checks the S_ISGID to determine the owning
  42 * group of the new file system object.
  43 */
  44
  45static kgid_t v9fs_get_fsgid_for_create(struct inode *dir_inode)
  46{
  47	BUG_ON(dir_inode == NULL);
  48
  49	if (dir_inode->i_mode & S_ISGID) {
  50		/* set_gid bit is set.*/
  51		return dir_inode->i_gid;
  52	}
  53	return current_fsgid();
  54}
  55
  56static int v9fs_test_inode_dotl(struct inode *inode, void *data)
  57{
  58	struct v9fs_inode *v9inode = V9FS_I(inode);
  59	struct p9_stat_dotl *st = (struct p9_stat_dotl *)data;
  60
  61	/* don't match inode of different type */
  62	if (inode_wrong_type(inode, st->st_mode))
  63		return 0;
  64
  65	if (inode->i_generation != st->st_gen)
  66		return 0;
  67
  68	/* compare qid details */
  69	if (memcmp(&v9inode->qid.version,
  70		   &st->qid.version, sizeof(v9inode->qid.version)))
  71		return 0;
  72
  73	if (v9inode->qid.type != st->qid.type)
  74		return 0;
  75
  76	if (v9inode->qid.path != st->qid.path)
  77		return 0;
  78	return 1;
  79}
  80
  81/* Always get a new inode */
  82static int v9fs_test_new_inode_dotl(struct inode *inode, void *data)
  83{
  84	return 0;
  85}
  86
  87static int v9fs_set_inode_dotl(struct inode *inode,  void *data)
  88{
  89	struct v9fs_inode *v9inode = V9FS_I(inode);
  90	struct p9_stat_dotl *st = (struct p9_stat_dotl *)data;
  91
  92	memcpy(&v9inode->qid, &st->qid, sizeof(st->qid));
  93	inode->i_generation = st->st_gen;
  94	return 0;
  95}
  96
  97static struct inode *v9fs_qid_iget_dotl(struct super_block *sb,
  98					struct p9_qid *qid,
  99					struct p9_fid *fid,
 100					struct p9_stat_dotl *st,
 101					int new)
 102{
 103	int retval;
 104	unsigned long i_ino;
 105	struct inode *inode;
 106	struct v9fs_session_info *v9ses = sb->s_fs_info;
 107	int (*test)(struct inode *inode, void *data);
 108
 109	if (new)
 110		test = v9fs_test_new_inode_dotl;
 111	else
 112		test = v9fs_test_inode_dotl;
 113
 114	i_ino = v9fs_qid2ino(qid);
 115	inode = iget5_locked(sb, i_ino, test, v9fs_set_inode_dotl, st);
 116	if (!inode)
 117		return ERR_PTR(-ENOMEM);
 118	if (!(inode->i_state & I_NEW))
 119		return inode;
 120	/*
 121	 * initialize the inode with the stat info
 122	 * FIXME!! we may need support for stale inodes
 123	 * later.
 124	 */
 125	inode->i_ino = i_ino;
 126	retval = v9fs_init_inode(v9ses, inode,
 127				 st->st_mode, new_decode_dev(st->st_rdev));
 128	if (retval)
 129		goto error;
 130
 131	v9fs_stat2inode_dotl(st, inode, 0);
 
 132	v9fs_cache_inode_get_cookie(inode);
 133	retval = v9fs_get_acl(inode, fid);
 134	if (retval)
 135		goto error;
 136
 137	unlock_new_inode(inode);
 138	return inode;
 139error:
 140	iget_failed(inode);
 141	return ERR_PTR(retval);
 142
 143}
 144
 145struct inode *
 146v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid,
 147			 struct super_block *sb, int new)
 148{
 149	struct p9_stat_dotl *st;
 150	struct inode *inode = NULL;
 151
 152	st = p9_client_getattr_dotl(fid, P9_STATS_BASIC | P9_STATS_GEN);
 153	if (IS_ERR(st))
 154		return ERR_CAST(st);
 155
 156	inode = v9fs_qid_iget_dotl(sb, &st->qid, fid, st, new);
 157	kfree(st);
 158	return inode;
 159}
 160
 161struct dotl_openflag_map {
 162	int open_flag;
 163	int dotl_flag;
 164};
 165
 166static int v9fs_mapped_dotl_flags(int flags)
 167{
 168	int i;
 169	int rflags = 0;
 170	struct dotl_openflag_map dotl_oflag_map[] = {
 171		{ O_CREAT,	P9_DOTL_CREATE },
 172		{ O_EXCL,	P9_DOTL_EXCL },
 173		{ O_NOCTTY,	P9_DOTL_NOCTTY },
 174		{ O_APPEND,	P9_DOTL_APPEND },
 175		{ O_NONBLOCK,	P9_DOTL_NONBLOCK },
 176		{ O_DSYNC,	P9_DOTL_DSYNC },
 177		{ FASYNC,	P9_DOTL_FASYNC },
 178		{ O_DIRECT,	P9_DOTL_DIRECT },
 179		{ O_LARGEFILE,	P9_DOTL_LARGEFILE },
 180		{ O_DIRECTORY,	P9_DOTL_DIRECTORY },
 181		{ O_NOFOLLOW,	P9_DOTL_NOFOLLOW },
 182		{ O_NOATIME,	P9_DOTL_NOATIME },
 183		{ O_CLOEXEC,	P9_DOTL_CLOEXEC },
 184		{ O_SYNC,	P9_DOTL_SYNC},
 185	};
 186	for (i = 0; i < ARRAY_SIZE(dotl_oflag_map); i++) {
 187		if (flags & dotl_oflag_map[i].open_flag)
 188			rflags |= dotl_oflag_map[i].dotl_flag;
 189	}
 190	return rflags;
 191}
 192
 193/**
 194 * v9fs_open_to_dotl_flags- convert Linux specific open flags to
 195 * plan 9 open flag.
 196 * @flags: flags to convert
 197 */
 198int v9fs_open_to_dotl_flags(int flags)
 199{
 200	int rflags = 0;
 201
 202	/*
 203	 * We have same bits for P9_DOTL_READONLY, P9_DOTL_WRONLY
 204	 * and P9_DOTL_NOACCESS
 205	 */
 206	rflags |= flags & O_ACCMODE;
 207	rflags |= v9fs_mapped_dotl_flags(flags);
 208
 209	return rflags;
 210}
 211
 212/**
 213 * v9fs_vfs_create_dotl - VFS hook to create files for 9P2000.L protocol.
 214 * @mnt_userns: The user namespace of the mount
 215 * @dir: directory inode that is being created
 216 * @dentry:  dentry that is being deleted
 217 * @omode: create permissions
 218 * @excl: True if the file must not yet exist
 219 *
 220 */
 221static int
 222v9fs_vfs_create_dotl(struct user_namespace *mnt_userns, struct inode *dir,
 223		     struct dentry *dentry, umode_t omode, bool excl)
 224{
 225	return v9fs_vfs_mknod_dotl(mnt_userns, dir, dentry, omode, 0);
 226}
 227
 228static int
 229v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
 230			  struct file *file, unsigned int flags, umode_t omode)
 231{
 232	int err = 0;
 233	kgid_t gid;
 234	umode_t mode;
 
 235	const unsigned char *name = NULL;
 236	struct p9_qid qid;
 237	struct inode *inode;
 238	struct p9_fid *fid = NULL;
 239	struct v9fs_inode *v9inode;
 240	struct p9_fid *dfid = NULL, *ofid = NULL, *inode_fid = NULL;
 241	struct v9fs_session_info *v9ses;
 242	struct posix_acl *pacl = NULL, *dacl = NULL;
 243	struct dentry *res = NULL;
 244
 245	if (d_in_lookup(dentry)) {
 246		res = v9fs_vfs_lookup(dir, dentry, 0);
 247		if (IS_ERR(res))
 248			return PTR_ERR(res);
 249
 250		if (res)
 251			dentry = res;
 252	}
 253
 254	/* Only creates */
 255	if (!(flags & O_CREAT) || d_really_is_positive(dentry))
 256		return	finish_no_open(file, res);
 257
 258	v9ses = v9fs_inode2v9ses(dir);
 259
 260	name = dentry->d_name.name;
 261	p9_debug(P9_DEBUG_VFS, "name:%s flags:0x%x mode:0x%x\n",
 262		 name, flags, omode);
 263
 264	dfid = v9fs_parent_fid(dentry);
 265	if (IS_ERR(dfid)) {
 266		err = PTR_ERR(dfid);
 267		p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
 268		goto out;
 269	}
 270
 271	/* clone a fid to use for creation */
 272	ofid = clone_fid(dfid);
 273	if (IS_ERR(ofid)) {
 274		err = PTR_ERR(ofid);
 275		p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
 276		goto out;
 277	}
 278
 279	gid = v9fs_get_fsgid_for_create(dir);
 280
 281	mode = omode;
 282	/* Update mode based on ACL value */
 283	err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
 284	if (err) {
 285		p9_debug(P9_DEBUG_VFS, "Failed to get acl values in creat %d\n",
 286			 err);
 287		goto out;
 288	}
 289	err = p9_client_create_dotl(ofid, name, v9fs_open_to_dotl_flags(flags),
 290				    mode, gid, &qid);
 
 
 
 
 
 291	if (err < 0) {
 292		p9_debug(P9_DEBUG_VFS, "p9_client_open_dotl failed in creat %d\n",
 293			 err);
 294		goto out;
 295	}
 296	v9fs_invalidate_inode_attr(dir);
 297
 298	/* instantiate inode and assign the unopened fid to the dentry */
 299	fid = p9_client_walk(dfid, 1, &name, 1);
 300	if (IS_ERR(fid)) {
 301		err = PTR_ERR(fid);
 302		p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
 303		goto out;
 304	}
 305	inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
 306	if (IS_ERR(inode)) {
 307		err = PTR_ERR(inode);
 308		p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", err);
 309		goto out;
 310	}
 311	/* Now set the ACL based on the default value */
 312	v9fs_set_create_acl(inode, fid, dacl, pacl);
 313
 314	v9fs_fid_add(dentry, &fid);
 315	d_instantiate(dentry, inode);
 316
 317	v9inode = V9FS_I(inode);
 318	mutex_lock(&v9inode->v_mutex);
 319	if ((v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) &&
 320	    !v9inode->writeback_fid &&
 321	    ((flags & O_ACCMODE) != O_RDONLY)) {
 322		/*
 323		 * clone a fid and add it to writeback_fid
 324		 * we do it during open time instead of
 325		 * page dirty time via write_begin/page_mkwrite
 326		 * because we want write after unlink usecase
 327		 * to work.
 328		 */
 329		inode_fid = v9fs_writeback_fid(dentry);
 330		if (IS_ERR(inode_fid)) {
 331			err = PTR_ERR(inode_fid);
 332			mutex_unlock(&v9inode->v_mutex);
 333			goto out;
 334		}
 335		v9inode->writeback_fid = (void *) inode_fid;
 336	}
 337	mutex_unlock(&v9inode->v_mutex);
 338	/* Since we are opening a file, assign the open fid to the file */
 339	err = finish_open(file, dentry, generic_file_open);
 340	if (err)
 341		goto out;
 342	file->private_data = ofid;
 343	if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
 
 
 344		fscache_use_cookie(v9fs_inode_cookie(v9inode),
 345				   file->f_mode & FMODE_WRITE);
 
 
 
 346	v9fs_open_fid_add(inode, &ofid);
 347	file->f_mode |= FMODE_CREATED;
 348out:
 349	p9_fid_put(dfid);
 350	p9_fid_put(ofid);
 351	p9_fid_put(fid);
 352	v9fs_put_acl(dacl, pacl);
 353	dput(res);
 354	return err;
 355}
 356
 357/**
 358 * v9fs_vfs_mkdir_dotl - VFS mkdir hook to create a directory
 359 * @mnt_userns: The user namespace of the mount
 360 * @dir:  inode that is being unlinked
 361 * @dentry: dentry that is being unlinked
 362 * @omode: mode for new directory
 363 *
 364 */
 365
 366static int v9fs_vfs_mkdir_dotl(struct user_namespace *mnt_userns,
 367			       struct inode *dir, struct dentry *dentry,
 368			       umode_t omode)
 369{
 370	int err;
 371	struct v9fs_session_info *v9ses;
 372	struct p9_fid *fid = NULL, *dfid = NULL;
 373	kgid_t gid;
 374	const unsigned char *name;
 375	umode_t mode;
 376	struct inode *inode;
 377	struct p9_qid qid;
 378	struct posix_acl *dacl = NULL, *pacl = NULL;
 379
 380	p9_debug(P9_DEBUG_VFS, "name %pd\n", dentry);
 381	err = 0;
 382	v9ses = v9fs_inode2v9ses(dir);
 383
 384	omode |= S_IFDIR;
 385	if (dir->i_mode & S_ISGID)
 386		omode |= S_ISGID;
 387
 388	dfid = v9fs_parent_fid(dentry);
 389	if (IS_ERR(dfid)) {
 390		err = PTR_ERR(dfid);
 391		p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
 392		goto error;
 393	}
 394
 395	gid = v9fs_get_fsgid_for_create(dir);
 396	mode = omode;
 397	/* Update mode based on ACL value */
 398	err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
 399	if (err) {
 400		p9_debug(P9_DEBUG_VFS, "Failed to get acl values in mkdir %d\n",
 401			 err);
 402		goto error;
 403	}
 404	name = dentry->d_name.name;
 405	err = p9_client_mkdir_dotl(dfid, name, mode, gid, &qid);
 406	if (err < 0)
 407		goto error;
 408	fid = p9_client_walk(dfid, 1, &name, 1);
 409	if (IS_ERR(fid)) {
 410		err = PTR_ERR(fid);
 411		p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
 412			 err);
 413		goto error;
 414	}
 415
 416	/* instantiate inode and assign the unopened fid to the dentry */
 417	if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
 418		inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
 419		if (IS_ERR(inode)) {
 420			err = PTR_ERR(inode);
 421			p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n",
 422				 err);
 423			goto error;
 424		}
 425		v9fs_fid_add(dentry, &fid);
 426		v9fs_set_create_acl(inode, fid, dacl, pacl);
 427		d_instantiate(dentry, inode);
 428		err = 0;
 429	} else {
 430		/*
 431		 * Not in cached mode. No need to populate
 432		 * inode with stat. We need to get an inode
 433		 * so that we can set the acl with dentry
 434		 */
 435		inode = v9fs_get_inode(dir->i_sb, mode, 0);
 436		if (IS_ERR(inode)) {
 437			err = PTR_ERR(inode);
 438			goto error;
 439		}
 440		v9fs_set_create_acl(inode, fid, dacl, pacl);
 441		d_instantiate(dentry, inode);
 442	}
 443	inc_nlink(dir);
 444	v9fs_invalidate_inode_attr(dir);
 445error:
 446	p9_fid_put(fid);
 447	v9fs_put_acl(dacl, pacl);
 448	p9_fid_put(dfid);
 449	return err;
 450}
 451
 452static int
 453v9fs_vfs_getattr_dotl(struct user_namespace *mnt_userns,
 454		      const struct path *path, struct kstat *stat,
 455		      u32 request_mask, unsigned int flags)
 456{
 457	struct dentry *dentry = path->dentry;
 458	struct v9fs_session_info *v9ses;
 459	struct p9_fid *fid;
 
 460	struct p9_stat_dotl *st;
 461
 462	p9_debug(P9_DEBUG_VFS, "dentry: %p\n", dentry);
 463	v9ses = v9fs_dentry2v9ses(dentry);
 464	if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
 465		generic_fillattr(&init_user_ns, d_inode(dentry), stat);
 466		return 0;
 
 
 
 
 
 
 
 
 467	}
 468	fid = v9fs_fid_lookup(dentry);
 469	if (IS_ERR(fid))
 470		return PTR_ERR(fid);
 471
 472	/* Ask for all the fields in stat structure. Server will return
 473	 * whatever it supports
 474	 */
 475
 476	st = p9_client_getattr_dotl(fid, P9_STATS_ALL);
 477	p9_fid_put(fid);
 478	if (IS_ERR(st))
 479		return PTR_ERR(st);
 480
 481	v9fs_stat2inode_dotl(st, d_inode(dentry), 0);
 482	generic_fillattr(&init_user_ns, d_inode(dentry), stat);
 483	/* Change block size to what the server returned */
 484	stat->blksize = st->st_blksize;
 485
 486	kfree(st);
 487	return 0;
 488}
 489
 490/*
 491 * Attribute flags.
 492 */
 493#define P9_ATTR_MODE		(1 << 0)
 494#define P9_ATTR_UID		(1 << 1)
 495#define P9_ATTR_GID		(1 << 2)
 496#define P9_ATTR_SIZE		(1 << 3)
 497#define P9_ATTR_ATIME		(1 << 4)
 498#define P9_ATTR_MTIME		(1 << 5)
 499#define P9_ATTR_CTIME		(1 << 6)
 500#define P9_ATTR_ATIME_SET	(1 << 7)
 501#define P9_ATTR_MTIME_SET	(1 << 8)
 502
 503struct dotl_iattr_map {
 504	int iattr_valid;
 505	int p9_iattr_valid;
 506};
 507
 508static int v9fs_mapped_iattr_valid(int iattr_valid)
 509{
 510	int i;
 511	int p9_iattr_valid = 0;
 512	struct dotl_iattr_map dotl_iattr_map[] = {
 513		{ ATTR_MODE,		P9_ATTR_MODE },
 514		{ ATTR_UID,		P9_ATTR_UID },
 515		{ ATTR_GID,		P9_ATTR_GID },
 516		{ ATTR_SIZE,		P9_ATTR_SIZE },
 517		{ ATTR_ATIME,		P9_ATTR_ATIME },
 518		{ ATTR_MTIME,		P9_ATTR_MTIME },
 519		{ ATTR_CTIME,		P9_ATTR_CTIME },
 520		{ ATTR_ATIME_SET,	P9_ATTR_ATIME_SET },
 521		{ ATTR_MTIME_SET,	P9_ATTR_MTIME_SET },
 522	};
 523	for (i = 0; i < ARRAY_SIZE(dotl_iattr_map); i++) {
 524		if (iattr_valid & dotl_iattr_map[i].iattr_valid)
 525			p9_iattr_valid |= dotl_iattr_map[i].p9_iattr_valid;
 526	}
 527	return p9_iattr_valid;
 528}
 529
 530/**
 531 * v9fs_vfs_setattr_dotl - set file metadata
 532 * @mnt_userns: The user namespace of the mount
 533 * @dentry: file whose metadata to set
 534 * @iattr: metadata assignment structure
 535 *
 536 */
 537
 538int v9fs_vfs_setattr_dotl(struct user_namespace *mnt_userns,
 539			  struct dentry *dentry, struct iattr *iattr)
 540{
 541	int retval, use_dentry = 0;
 
 
 542	struct p9_fid *fid = NULL;
 543	struct p9_iattr_dotl p9attr = {
 544		.uid = INVALID_UID,
 545		.gid = INVALID_GID,
 546	};
 547	struct inode *inode = d_inode(dentry);
 548
 549	p9_debug(P9_DEBUG_VFS, "\n");
 550
 551	retval = setattr_prepare(&init_user_ns, dentry, iattr);
 552	if (retval)
 553		return retval;
 554
 
 
 555	p9attr.valid = v9fs_mapped_iattr_valid(iattr->ia_valid);
 556	if (iattr->ia_valid & ATTR_MODE)
 557		p9attr.mode = iattr->ia_mode;
 558	if (iattr->ia_valid & ATTR_UID)
 559		p9attr.uid = iattr->ia_uid;
 560	if (iattr->ia_valid & ATTR_GID)
 561		p9attr.gid = iattr->ia_gid;
 562	if (iattr->ia_valid & ATTR_SIZE)
 563		p9attr.size = iattr->ia_size;
 564	if (iattr->ia_valid & ATTR_ATIME_SET) {
 565		p9attr.atime_sec = iattr->ia_atime.tv_sec;
 566		p9attr.atime_nsec = iattr->ia_atime.tv_nsec;
 567	}
 568	if (iattr->ia_valid & ATTR_MTIME_SET) {
 569		p9attr.mtime_sec = iattr->ia_mtime.tv_sec;
 570		p9attr.mtime_nsec = iattr->ia_mtime.tv_nsec;
 571	}
 572
 573	if (iattr->ia_valid & ATTR_FILE) {
 574		fid = iattr->ia_file->private_data;
 575		WARN_ON(!fid);
 576	}
 577	if (!fid) {
 578		fid = v9fs_fid_lookup(dentry);
 579		use_dentry = 1;
 580	}
 581	if (IS_ERR(fid))
 582		return PTR_ERR(fid);
 583
 584	/* Write all dirty data */
 585	if (S_ISREG(inode->i_mode))
 586		filemap_write_and_wait(inode->i_mapping);
 
 
 
 
 587
 588	retval = p9_client_setattr(fid, &p9attr);
 589	if (retval < 0) {
 590		if (use_dentry)
 591			p9_fid_put(fid);
 592		return retval;
 593	}
 594
 595	if ((iattr->ia_valid & ATTR_SIZE) &&
 596	    iattr->ia_size != i_size_read(inode))
 597		truncate_setsize(inode, iattr->ia_size);
 
 
 
 
 
 
 
 
 598
 599	v9fs_invalidate_inode_attr(inode);
 600	setattr_copy(&init_user_ns, inode, iattr);
 601	mark_inode_dirty(inode);
 602	if (iattr->ia_valid & ATTR_MODE) {
 603		/* We also want to update ACL when we update mode bits */
 604		retval = v9fs_acl_chmod(inode, fid);
 605		if (retval < 0) {
 606			if (use_dentry)
 607				p9_fid_put(fid);
 608			return retval;
 609		}
 610	}
 611	if (use_dentry)
 612		p9_fid_put(fid);
 613
 614	return 0;
 615}
 616
 617/**
 618 * v9fs_stat2inode_dotl - populate an inode structure with stat info
 619 * @stat: stat structure
 620 * @inode: inode to populate
 621 * @flags: ctrl flags (e.g. V9FS_STAT2INODE_KEEP_ISIZE)
 622 *
 623 */
 624
 625void
 626v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode,
 627		      unsigned int flags)
 628{
 629	umode_t mode;
 630	struct v9fs_inode *v9inode = V9FS_I(inode);
 631
 632	if ((stat->st_result_mask & P9_STATS_BASIC) == P9_STATS_BASIC) {
 633		inode->i_atime.tv_sec = stat->st_atime_sec;
 634		inode->i_atime.tv_nsec = stat->st_atime_nsec;
 635		inode->i_mtime.tv_sec = stat->st_mtime_sec;
 636		inode->i_mtime.tv_nsec = stat->st_mtime_nsec;
 637		inode->i_ctime.tv_sec = stat->st_ctime_sec;
 638		inode->i_ctime.tv_nsec = stat->st_ctime_nsec;
 639		inode->i_uid = stat->st_uid;
 640		inode->i_gid = stat->st_gid;
 641		set_nlink(inode, stat->st_nlink);
 642
 643		mode = stat->st_mode & S_IALLUGO;
 644		mode |= inode->i_mode & ~S_IALLUGO;
 645		inode->i_mode = mode;
 646
 
 647		if (!(flags & V9FS_STAT2INODE_KEEP_ISIZE))
 648			v9fs_i_size_write(inode, stat->st_size);
 649		inode->i_blocks = stat->st_blocks;
 650	} else {
 651		if (stat->st_result_mask & P9_STATS_ATIME) {
 652			inode->i_atime.tv_sec = stat->st_atime_sec;
 653			inode->i_atime.tv_nsec = stat->st_atime_nsec;
 654		}
 655		if (stat->st_result_mask & P9_STATS_MTIME) {
 656			inode->i_mtime.tv_sec = stat->st_mtime_sec;
 657			inode->i_mtime.tv_nsec = stat->st_mtime_nsec;
 658		}
 659		if (stat->st_result_mask & P9_STATS_CTIME) {
 660			inode->i_ctime.tv_sec = stat->st_ctime_sec;
 661			inode->i_ctime.tv_nsec = stat->st_ctime_nsec;
 662		}
 663		if (stat->st_result_mask & P9_STATS_UID)
 664			inode->i_uid = stat->st_uid;
 665		if (stat->st_result_mask & P9_STATS_GID)
 666			inode->i_gid = stat->st_gid;
 667		if (stat->st_result_mask & P9_STATS_NLINK)
 668			set_nlink(inode, stat->st_nlink);
 669		if (stat->st_result_mask & P9_STATS_MODE) {
 670			mode = stat->st_mode & S_IALLUGO;
 671			mode |= inode->i_mode & ~S_IALLUGO;
 672			inode->i_mode = mode;
 673		}
 674		if (!(flags & V9FS_STAT2INODE_KEEP_ISIZE) &&
 675		    stat->st_result_mask & P9_STATS_SIZE)
 
 676			v9fs_i_size_write(inode, stat->st_size);
 
 677		if (stat->st_result_mask & P9_STATS_BLOCKS)
 678			inode->i_blocks = stat->st_blocks;
 679	}
 680	if (stat->st_result_mask & P9_STATS_GEN)
 681		inode->i_generation = stat->st_gen;
 682
 683	/* Currently we don't support P9_STATS_BTIME and P9_STATS_DATA_VERSION
 684	 * because the inode structure does not have fields for them.
 685	 */
 686	v9inode->cache_validity &= ~V9FS_INO_INVALID_ATTR;
 687}
 688
 689static int
 690v9fs_vfs_symlink_dotl(struct user_namespace *mnt_userns, struct inode *dir,
 691		      struct dentry *dentry, const char *symname)
 692{
 693	int err;
 694	kgid_t gid;
 695	const unsigned char *name;
 696	struct p9_qid qid;
 697	struct inode *inode;
 698	struct p9_fid *dfid;
 699	struct p9_fid *fid = NULL;
 700	struct v9fs_session_info *v9ses;
 701
 702	name = dentry->d_name.name;
 703	p9_debug(P9_DEBUG_VFS, "%lu,%s,%s\n", dir->i_ino, name, symname);
 704	v9ses = v9fs_inode2v9ses(dir);
 705
 706	dfid = v9fs_parent_fid(dentry);
 707	if (IS_ERR(dfid)) {
 708		err = PTR_ERR(dfid);
 709		p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
 710		return err;
 711	}
 712
 713	gid = v9fs_get_fsgid_for_create(dir);
 714
 715	/* Server doesn't alter fid on TSYMLINK. Hence no need to clone it. */
 716	err = p9_client_symlink(dfid, name, symname, gid, &qid);
 717
 718	if (err < 0) {
 719		p9_debug(P9_DEBUG_VFS, "p9_client_symlink failed %d\n", err);
 720		goto error;
 721	}
 722
 723	v9fs_invalidate_inode_attr(dir);
 724	if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
 725		/* Now walk from the parent so we can get an unopened fid. */
 726		fid = p9_client_walk(dfid, 1, &name, 1);
 727		if (IS_ERR(fid)) {
 728			err = PTR_ERR(fid);
 729			p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
 730				 err);
 731			goto error;
 732		}
 733
 734		/* instantiate inode and assign the unopened fid to dentry */
 735		inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
 736		if (IS_ERR(inode)) {
 737			err = PTR_ERR(inode);
 738			p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n",
 739				 err);
 740			goto error;
 741		}
 742		v9fs_fid_add(dentry, &fid);
 743		d_instantiate(dentry, inode);
 744		err = 0;
 745	} else {
 746		/* Not in cached mode. No need to populate inode with stat */
 747		inode = v9fs_get_inode(dir->i_sb, S_IFLNK, 0);
 748		if (IS_ERR(inode)) {
 749			err = PTR_ERR(inode);
 750			goto error;
 751		}
 752		d_instantiate(dentry, inode);
 753	}
 754
 755error:
 756	p9_fid_put(fid);
 757	p9_fid_put(dfid);
 758	return err;
 759}
 760
 761/**
 762 * v9fs_vfs_link_dotl - create a hardlink for dotl
 763 * @old_dentry: dentry for file to link to
 764 * @dir: inode destination for new link
 765 * @dentry: dentry for link
 766 *
 767 */
 768
 769static int
 770v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir,
 771		struct dentry *dentry)
 772{
 773	int err;
 774	struct p9_fid *dfid, *oldfid;
 775	struct v9fs_session_info *v9ses;
 776
 777	p9_debug(P9_DEBUG_VFS, "dir ino: %lu, old_name: %pd, new_name: %pd\n",
 778		 dir->i_ino, old_dentry, dentry);
 779
 780	v9ses = v9fs_inode2v9ses(dir);
 781	dfid = v9fs_parent_fid(dentry);
 782	if (IS_ERR(dfid))
 783		return PTR_ERR(dfid);
 784
 785	oldfid = v9fs_fid_lookup(old_dentry);
 786	if (IS_ERR(oldfid)) {
 787		p9_fid_put(dfid);
 788		return PTR_ERR(oldfid);
 789	}
 790
 791	err = p9_client_link(dfid, oldfid, dentry->d_name.name);
 792
 793	p9_fid_put(dfid);
 794	p9_fid_put(oldfid);
 795	if (err < 0) {
 796		p9_debug(P9_DEBUG_VFS, "p9_client_link failed %d\n", err);
 797		return err;
 798	}
 799
 800	v9fs_invalidate_inode_attr(dir);
 801	if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
 802		/* Get the latest stat info from server. */
 803		struct p9_fid *fid;
 804
 805		fid = v9fs_fid_lookup(old_dentry);
 806		if (IS_ERR(fid))
 807			return PTR_ERR(fid);
 808
 809		v9fs_refresh_inode_dotl(fid, d_inode(old_dentry));
 810		p9_fid_put(fid);
 811	}
 812	ihold(d_inode(old_dentry));
 813	d_instantiate(dentry, d_inode(old_dentry));
 814
 815	return err;
 816}
 817
 818/**
 819 * v9fs_vfs_mknod_dotl - create a special file
 820 * @mnt_userns: The user namespace of the mount
 821 * @dir: inode destination for new link
 822 * @dentry: dentry for file
 823 * @omode: mode for creation
 824 * @rdev: device associated with special file
 825 *
 826 */
 827static int
 828v9fs_vfs_mknod_dotl(struct user_namespace *mnt_userns, struct inode *dir,
 829		    struct dentry *dentry, umode_t omode, dev_t rdev)
 830{
 831	int err;
 832	kgid_t gid;
 833	const unsigned char *name;
 834	umode_t mode;
 835	struct v9fs_session_info *v9ses;
 836	struct p9_fid *fid = NULL, *dfid = NULL;
 837	struct inode *inode;
 838	struct p9_qid qid;
 839	struct posix_acl *dacl = NULL, *pacl = NULL;
 840
 841	p9_debug(P9_DEBUG_VFS, " %lu,%pd mode: %x MAJOR: %u MINOR: %u\n",
 842		 dir->i_ino, dentry, omode,
 843		 MAJOR(rdev), MINOR(rdev));
 844
 845	v9ses = v9fs_inode2v9ses(dir);
 846	dfid = v9fs_parent_fid(dentry);
 847	if (IS_ERR(dfid)) {
 848		err = PTR_ERR(dfid);
 849		p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
 850		goto error;
 851	}
 852
 853	gid = v9fs_get_fsgid_for_create(dir);
 854	mode = omode;
 855	/* Update mode based on ACL value */
 856	err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
 857	if (err) {
 858		p9_debug(P9_DEBUG_VFS, "Failed to get acl values in mknod %d\n",
 859			 err);
 860		goto error;
 861	}
 862	name = dentry->d_name.name;
 863
 864	err = p9_client_mknod_dotl(dfid, name, mode, rdev, gid, &qid);
 865	if (err < 0)
 866		goto error;
 867
 868	v9fs_invalidate_inode_attr(dir);
 869	fid = p9_client_walk(dfid, 1, &name, 1);
 870	if (IS_ERR(fid)) {
 871		err = PTR_ERR(fid);
 872		p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
 873			 err);
 874		goto error;
 875	}
 876
 877	/* instantiate inode and assign the unopened fid to the dentry */
 878	if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
 879		inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
 880		if (IS_ERR(inode)) {
 881			err = PTR_ERR(inode);
 882			p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n",
 883				 err);
 884			goto error;
 885		}
 886		v9fs_set_create_acl(inode, fid, dacl, pacl);
 887		v9fs_fid_add(dentry, &fid);
 888		d_instantiate(dentry, inode);
 889		err = 0;
 890	} else {
 891		/*
 892		 * Not in cached mode. No need to populate inode with stat.
 893		 * socket syscall returns a fd, so we need instantiate
 894		 */
 895		inode = v9fs_get_inode(dir->i_sb, mode, rdev);
 896		if (IS_ERR(inode)) {
 897			err = PTR_ERR(inode);
 898			goto error;
 899		}
 900		v9fs_set_create_acl(inode, fid, dacl, pacl);
 901		d_instantiate(dentry, inode);
 902	}
 903error:
 904	p9_fid_put(fid);
 905	v9fs_put_acl(dacl, pacl);
 906	p9_fid_put(dfid);
 907
 908	return err;
 909}
 910
 911/**
 912 * v9fs_vfs_get_link_dotl - follow a symlink path
 913 * @dentry: dentry for symlink
 914 * @inode: inode for symlink
 915 * @done: destructor for return value
 916 */
 917
 918static const char *
 919v9fs_vfs_get_link_dotl(struct dentry *dentry,
 920		       struct inode *inode,
 921		       struct delayed_call *done)
 922{
 923	struct p9_fid *fid;
 924	char *target;
 925	int retval;
 926
 927	if (!dentry)
 928		return ERR_PTR(-ECHILD);
 929
 930	p9_debug(P9_DEBUG_VFS, "%pd\n", dentry);
 931
 932	fid = v9fs_fid_lookup(dentry);
 933	if (IS_ERR(fid))
 934		return ERR_CAST(fid);
 935	retval = p9_client_readlink(fid, &target);
 936	p9_fid_put(fid);
 937	if (retval)
 938		return ERR_PTR(retval);
 939	set_delayed_call(done, kfree_link, target);
 940	return target;
 941}
 942
 943int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode)
 944{
 945	struct p9_stat_dotl *st;
 946	struct v9fs_session_info *v9ses;
 947	unsigned int flags;
 948
 949	v9ses = v9fs_inode2v9ses(inode);
 950	st = p9_client_getattr_dotl(fid, P9_STATS_ALL);
 951	if (IS_ERR(st))
 952		return PTR_ERR(st);
 953	/*
 954	 * Don't update inode if the file type is different
 955	 */
 956	if (inode_wrong_type(inode, st->st_mode))
 957		goto out;
 958
 959	/*
 960	 * We don't want to refresh inode->i_size,
 961	 * because we may have cached data
 962	 */
 963	flags = (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) ?
 964		V9FS_STAT2INODE_KEEP_ISIZE : 0;
 965	v9fs_stat2inode_dotl(st, inode, flags);
 966out:
 967	kfree(st);
 968	return 0;
 969}
 970
 971const struct inode_operations v9fs_dir_inode_operations_dotl = {
 972	.create = v9fs_vfs_create_dotl,
 973	.atomic_open = v9fs_vfs_atomic_open_dotl,
 974	.lookup = v9fs_vfs_lookup,
 975	.link = v9fs_vfs_link_dotl,
 976	.symlink = v9fs_vfs_symlink_dotl,
 977	.unlink = v9fs_vfs_unlink,
 978	.mkdir = v9fs_vfs_mkdir_dotl,
 979	.rmdir = v9fs_vfs_rmdir,
 980	.mknod = v9fs_vfs_mknod_dotl,
 981	.rename = v9fs_vfs_rename,
 982	.getattr = v9fs_vfs_getattr_dotl,
 983	.setattr = v9fs_vfs_setattr_dotl,
 984	.listxattr = v9fs_listxattr,
 985	.get_inode_acl = v9fs_iop_get_inode_acl,
 986	.get_acl = v9fs_iop_get_acl,
 987	.set_acl = v9fs_iop_set_acl,
 988};
 989
 990const struct inode_operations v9fs_file_inode_operations_dotl = {
 991	.getattr = v9fs_vfs_getattr_dotl,
 992	.setattr = v9fs_vfs_setattr_dotl,
 993	.listxattr = v9fs_listxattr,
 994	.get_inode_acl = v9fs_iop_get_inode_acl,
 995	.get_acl = v9fs_iop_get_acl,
 996	.set_acl = v9fs_iop_set_acl,
 997};
 998
 999const struct inode_operations v9fs_symlink_inode_operations_dotl = {
1000	.get_link = v9fs_vfs_get_link_dotl,
1001	.getattr = v9fs_vfs_getattr_dotl,
1002	.setattr = v9fs_vfs_setattr_dotl,
1003	.listxattr = v9fs_listxattr,
1004};
v6.8
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * This file contains vfs inode ops for the 9P2000.L protocol.
   4 *
   5 *  Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
   6 *  Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
   7 */
   8
   9#include <linux/module.h>
  10#include <linux/errno.h>
  11#include <linux/fs.h>
  12#include <linux/file.h>
  13#include <linux/pagemap.h>
  14#include <linux/stat.h>
  15#include <linux/string.h>
 
  16#include <linux/namei.h>
  17#include <linux/sched.h>
  18#include <linux/slab.h>
  19#include <linux/xattr.h>
  20#include <linux/posix_acl.h>
  21#include <net/9p/9p.h>
  22#include <net/9p/client.h>
  23
  24#include "v9fs.h"
  25#include "v9fs_vfs.h"
  26#include "fid.h"
  27#include "cache.h"
  28#include "xattr.h"
  29#include "acl.h"
  30
  31static int
  32v9fs_vfs_mknod_dotl(struct mnt_idmap *idmap, struct inode *dir,
  33		    struct dentry *dentry, umode_t omode, dev_t rdev);
  34
  35/**
  36 * v9fs_get_fsgid_for_create - Helper function to get the gid for a new object
  37 * @dir_inode: The directory inode
  38 *
  39 * Helper function to get the gid for creating a
  40 * new file system object. This checks the S_ISGID to determine the owning
  41 * group of the new file system object.
  42 */
  43
  44static kgid_t v9fs_get_fsgid_for_create(struct inode *dir_inode)
  45{
  46	BUG_ON(dir_inode == NULL);
  47
  48	if (dir_inode->i_mode & S_ISGID) {
  49		/* set_gid bit is set.*/
  50		return dir_inode->i_gid;
  51	}
  52	return current_fsgid();
  53}
  54
  55static int v9fs_test_inode_dotl(struct inode *inode, void *data)
  56{
  57	struct v9fs_inode *v9inode = V9FS_I(inode);
  58	struct p9_stat_dotl *st = (struct p9_stat_dotl *)data;
  59
  60	/* don't match inode of different type */
  61	if (inode_wrong_type(inode, st->st_mode))
  62		return 0;
  63
  64	if (inode->i_generation != st->st_gen)
  65		return 0;
  66
  67	/* compare qid details */
  68	if (memcmp(&v9inode->qid.version,
  69		   &st->qid.version, sizeof(v9inode->qid.version)))
  70		return 0;
  71
  72	if (v9inode->qid.type != st->qid.type)
  73		return 0;
  74
  75	if (v9inode->qid.path != st->qid.path)
  76		return 0;
  77	return 1;
  78}
  79
  80/* Always get a new inode */
  81static int v9fs_test_new_inode_dotl(struct inode *inode, void *data)
  82{
  83	return 0;
  84}
  85
  86static int v9fs_set_inode_dotl(struct inode *inode,  void *data)
  87{
  88	struct v9fs_inode *v9inode = V9FS_I(inode);
  89	struct p9_stat_dotl *st = (struct p9_stat_dotl *)data;
  90
  91	memcpy(&v9inode->qid, &st->qid, sizeof(st->qid));
  92	inode->i_generation = st->st_gen;
  93	return 0;
  94}
  95
  96static struct inode *v9fs_qid_iget_dotl(struct super_block *sb,
  97					struct p9_qid *qid,
  98					struct p9_fid *fid,
  99					struct p9_stat_dotl *st,
 100					int new)
 101{
 102	int retval;
 103	unsigned long i_ino;
 104	struct inode *inode;
 105	struct v9fs_session_info *v9ses = sb->s_fs_info;
 106	int (*test)(struct inode *inode, void *data);
 107
 108	if (new)
 109		test = v9fs_test_new_inode_dotl;
 110	else
 111		test = v9fs_test_inode_dotl;
 112
 113	i_ino = v9fs_qid2ino(qid);
 114	inode = iget5_locked(sb, i_ino, test, v9fs_set_inode_dotl, st);
 115	if (!inode)
 116		return ERR_PTR(-ENOMEM);
 117	if (!(inode->i_state & I_NEW))
 118		return inode;
 119	/*
 120	 * initialize the inode with the stat info
 121	 * FIXME!! we may need support for stale inodes
 122	 * later.
 123	 */
 124	inode->i_ino = i_ino;
 125	retval = v9fs_init_inode(v9ses, inode,
 126				 st->st_mode, new_decode_dev(st->st_rdev));
 127	if (retval)
 128		goto error;
 129
 130	v9fs_stat2inode_dotl(st, inode, 0);
 131	v9fs_set_netfs_context(inode);
 132	v9fs_cache_inode_get_cookie(inode);
 133	retval = v9fs_get_acl(inode, fid);
 134	if (retval)
 135		goto error;
 136
 137	unlock_new_inode(inode);
 138	return inode;
 139error:
 140	iget_failed(inode);
 141	return ERR_PTR(retval);
 142
 143}
 144
 145struct inode *
 146v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid,
 147			 struct super_block *sb, int new)
 148{
 149	struct p9_stat_dotl *st;
 150	struct inode *inode = NULL;
 151
 152	st = p9_client_getattr_dotl(fid, P9_STATS_BASIC | P9_STATS_GEN);
 153	if (IS_ERR(st))
 154		return ERR_CAST(st);
 155
 156	inode = v9fs_qid_iget_dotl(sb, &st->qid, fid, st, new);
 157	kfree(st);
 158	return inode;
 159}
 160
 161struct dotl_openflag_map {
 162	int open_flag;
 163	int dotl_flag;
 164};
 165
 166static int v9fs_mapped_dotl_flags(int flags)
 167{
 168	int i;
 169	int rflags = 0;
 170	struct dotl_openflag_map dotl_oflag_map[] = {
 171		{ O_CREAT,	P9_DOTL_CREATE },
 172		{ O_EXCL,	P9_DOTL_EXCL },
 173		{ O_NOCTTY,	P9_DOTL_NOCTTY },
 174		{ O_APPEND,	P9_DOTL_APPEND },
 175		{ O_NONBLOCK,	P9_DOTL_NONBLOCK },
 176		{ O_DSYNC,	P9_DOTL_DSYNC },
 177		{ FASYNC,	P9_DOTL_FASYNC },
 178		{ O_DIRECT,	P9_DOTL_DIRECT },
 179		{ O_LARGEFILE,	P9_DOTL_LARGEFILE },
 180		{ O_DIRECTORY,	P9_DOTL_DIRECTORY },
 181		{ O_NOFOLLOW,	P9_DOTL_NOFOLLOW },
 182		{ O_NOATIME,	P9_DOTL_NOATIME },
 183		{ O_CLOEXEC,	P9_DOTL_CLOEXEC },
 184		{ O_SYNC,	P9_DOTL_SYNC},
 185	};
 186	for (i = 0; i < ARRAY_SIZE(dotl_oflag_map); i++) {
 187		if (flags & dotl_oflag_map[i].open_flag)
 188			rflags |= dotl_oflag_map[i].dotl_flag;
 189	}
 190	return rflags;
 191}
 192
 193/**
 194 * v9fs_open_to_dotl_flags- convert Linux specific open flags to
 195 * plan 9 open flag.
 196 * @flags: flags to convert
 197 */
 198int v9fs_open_to_dotl_flags(int flags)
 199{
 200	int rflags = 0;
 201
 202	/*
 203	 * We have same bits for P9_DOTL_READONLY, P9_DOTL_WRONLY
 204	 * and P9_DOTL_NOACCESS
 205	 */
 206	rflags |= flags & O_ACCMODE;
 207	rflags |= v9fs_mapped_dotl_flags(flags);
 208
 209	return rflags;
 210}
 211
 212/**
 213 * v9fs_vfs_create_dotl - VFS hook to create files for 9P2000.L protocol.
 214 * @idmap: The user namespace of the mount
 215 * @dir: directory inode that is being created
 216 * @dentry:  dentry that is being deleted
 217 * @omode: create permissions
 218 * @excl: True if the file must not yet exist
 219 *
 220 */
 221static int
 222v9fs_vfs_create_dotl(struct mnt_idmap *idmap, struct inode *dir,
 223		     struct dentry *dentry, umode_t omode, bool excl)
 224{
 225	return v9fs_vfs_mknod_dotl(idmap, dir, dentry, omode, 0);
 226}
 227
 228static int
 229v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
 230			  struct file *file, unsigned int flags, umode_t omode)
 231{
 232	int err = 0;
 233	kgid_t gid;
 234	umode_t mode;
 235	int p9_omode = v9fs_open_to_dotl_flags(flags);
 236	const unsigned char *name = NULL;
 237	struct p9_qid qid;
 238	struct inode *inode;
 239	struct p9_fid *fid = NULL;
 240	struct p9_fid *dfid = NULL, *ofid = NULL;
 
 241	struct v9fs_session_info *v9ses;
 242	struct posix_acl *pacl = NULL, *dacl = NULL;
 243	struct dentry *res = NULL;
 244
 245	if (d_in_lookup(dentry)) {
 246		res = v9fs_vfs_lookup(dir, dentry, 0);
 247		if (IS_ERR(res))
 248			return PTR_ERR(res);
 249
 250		if (res)
 251			dentry = res;
 252	}
 253
 254	/* Only creates */
 255	if (!(flags & O_CREAT) || d_really_is_positive(dentry))
 256		return	finish_no_open(file, res);
 257
 258	v9ses = v9fs_inode2v9ses(dir);
 259
 260	name = dentry->d_name.name;
 261	p9_debug(P9_DEBUG_VFS, "name:%s flags:0x%x mode:0x%x\n",
 262		 name, flags, omode);
 263
 264	dfid = v9fs_parent_fid(dentry);
 265	if (IS_ERR(dfid)) {
 266		err = PTR_ERR(dfid);
 267		p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
 268		goto out;
 269	}
 270
 271	/* clone a fid to use for creation */
 272	ofid = clone_fid(dfid);
 273	if (IS_ERR(ofid)) {
 274		err = PTR_ERR(ofid);
 275		p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
 276		goto out;
 277	}
 278
 279	gid = v9fs_get_fsgid_for_create(dir);
 280
 281	mode = omode;
 282	/* Update mode based on ACL value */
 283	err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
 284	if (err) {
 285		p9_debug(P9_DEBUG_VFS, "Failed to get acl values in create %d\n",
 286			 err);
 287		goto out;
 288	}
 289
 290	if ((v9ses->cache & CACHE_WRITEBACK) && (p9_omode & P9_OWRITE)) {
 291		p9_omode = (p9_omode & ~P9_OWRITE) | P9_ORDWR;
 292		p9_debug(P9_DEBUG_CACHE,
 293			"write-only file with writeback enabled, creating w/ O_RDWR\n");
 294	}
 295	err = p9_client_create_dotl(ofid, name, p9_omode, mode, gid, &qid);
 296	if (err < 0) {
 297		p9_debug(P9_DEBUG_VFS, "p9_client_open_dotl failed in create %d\n",
 298			 err);
 299		goto out;
 300	}
 301	v9fs_invalidate_inode_attr(dir);
 302
 303	/* instantiate inode and assign the unopened fid to the dentry */
 304	fid = p9_client_walk(dfid, 1, &name, 1);
 305	if (IS_ERR(fid)) {
 306		err = PTR_ERR(fid);
 307		p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
 308		goto out;
 309	}
 310	inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
 311	if (IS_ERR(inode)) {
 312		err = PTR_ERR(inode);
 313		p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", err);
 314		goto out;
 315	}
 316	/* Now set the ACL based on the default value */
 317	v9fs_set_create_acl(inode, fid, dacl, pacl);
 318
 319	v9fs_fid_add(dentry, &fid);
 320	d_instantiate(dentry, inode);
 321
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 322	/* Since we are opening a file, assign the open fid to the file */
 323	err = finish_open(file, dentry, generic_file_open);
 324	if (err)
 325		goto out;
 326	file->private_data = ofid;
 327#ifdef CONFIG_9P_FSCACHE
 328	if (v9ses->cache & CACHE_FSCACHE) {
 329		struct v9fs_inode *v9inode = V9FS_I(inode);
 330		fscache_use_cookie(v9fs_inode_cookie(v9inode),
 331				   file->f_mode & FMODE_WRITE);
 332	}
 333#endif
 334	v9fs_fid_add_modes(ofid, v9ses->flags, v9ses->cache, flags);
 335	v9fs_open_fid_add(inode, &ofid);
 336	file->f_mode |= FMODE_CREATED;
 337out:
 338	p9_fid_put(dfid);
 339	p9_fid_put(ofid);
 340	p9_fid_put(fid);
 341	v9fs_put_acl(dacl, pacl);
 342	dput(res);
 343	return err;
 344}
 345
 346/**
 347 * v9fs_vfs_mkdir_dotl - VFS mkdir hook to create a directory
 348 * @idmap: The idmap of the mount
 349 * @dir:  inode that is being unlinked
 350 * @dentry: dentry that is being unlinked
 351 * @omode: mode for new directory
 352 *
 353 */
 354
 355static int v9fs_vfs_mkdir_dotl(struct mnt_idmap *idmap,
 356			       struct inode *dir, struct dentry *dentry,
 357			       umode_t omode)
 358{
 359	int err;
 360	struct v9fs_session_info *v9ses;
 361	struct p9_fid *fid = NULL, *dfid = NULL;
 362	kgid_t gid;
 363	const unsigned char *name;
 364	umode_t mode;
 365	struct inode *inode;
 366	struct p9_qid qid;
 367	struct posix_acl *dacl = NULL, *pacl = NULL;
 368
 369	p9_debug(P9_DEBUG_VFS, "name %pd\n", dentry);
 
 370	v9ses = v9fs_inode2v9ses(dir);
 371
 372	omode |= S_IFDIR;
 373	if (dir->i_mode & S_ISGID)
 374		omode |= S_ISGID;
 375
 376	dfid = v9fs_parent_fid(dentry);
 377	if (IS_ERR(dfid)) {
 378		err = PTR_ERR(dfid);
 379		p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
 380		goto error;
 381	}
 382
 383	gid = v9fs_get_fsgid_for_create(dir);
 384	mode = omode;
 385	/* Update mode based on ACL value */
 386	err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
 387	if (err) {
 388		p9_debug(P9_DEBUG_VFS, "Failed to get acl values in mkdir %d\n",
 389			 err);
 390		goto error;
 391	}
 392	name = dentry->d_name.name;
 393	err = p9_client_mkdir_dotl(dfid, name, mode, gid, &qid);
 394	if (err < 0)
 395		goto error;
 396	fid = p9_client_walk(dfid, 1, &name, 1);
 397	if (IS_ERR(fid)) {
 398		err = PTR_ERR(fid);
 399		p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
 400			 err);
 401		goto error;
 402	}
 403
 404	/* instantiate inode and assign the unopened fid to the dentry */
 405	if (v9ses->cache & (CACHE_META|CACHE_LOOSE)) {
 406		inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
 407		if (IS_ERR(inode)) {
 408			err = PTR_ERR(inode);
 409			p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n",
 410				 err);
 411			goto error;
 412		}
 413		v9fs_fid_add(dentry, &fid);
 414		v9fs_set_create_acl(inode, fid, dacl, pacl);
 415		d_instantiate(dentry, inode);
 416		err = 0;
 417	} else {
 418		/*
 419		 * Not in cached mode. No need to populate
 420		 * inode with stat. We need to get an inode
 421		 * so that we can set the acl with dentry
 422		 */
 423		inode = v9fs_get_inode(dir->i_sb, mode, 0);
 424		if (IS_ERR(inode)) {
 425			err = PTR_ERR(inode);
 426			goto error;
 427		}
 428		v9fs_set_create_acl(inode, fid, dacl, pacl);
 429		d_instantiate(dentry, inode);
 430	}
 431	inc_nlink(dir);
 432	v9fs_invalidate_inode_attr(dir);
 433error:
 434	p9_fid_put(fid);
 435	v9fs_put_acl(dacl, pacl);
 436	p9_fid_put(dfid);
 437	return err;
 438}
 439
 440static int
 441v9fs_vfs_getattr_dotl(struct mnt_idmap *idmap,
 442		      const struct path *path, struct kstat *stat,
 443		      u32 request_mask, unsigned int flags)
 444{
 445	struct dentry *dentry = path->dentry;
 446	struct v9fs_session_info *v9ses;
 447	struct p9_fid *fid;
 448	struct inode *inode = d_inode(dentry);
 449	struct p9_stat_dotl *st;
 450
 451	p9_debug(P9_DEBUG_VFS, "dentry: %p\n", dentry);
 452	v9ses = v9fs_dentry2v9ses(dentry);
 453	if (v9ses->cache & (CACHE_META|CACHE_LOOSE)) {
 454		generic_fillattr(&nop_mnt_idmap, request_mask, inode, stat);
 455		return 0;
 456	} else if (v9ses->cache) {
 457		if (S_ISREG(inode->i_mode)) {
 458			int retval = filemap_fdatawrite(inode->i_mapping);
 459
 460			if (retval)
 461				p9_debug(P9_DEBUG_ERROR,
 462				    "flushing writeback during getattr returned %d\n", retval);
 463		}
 464	}
 465	fid = v9fs_fid_lookup(dentry);
 466	if (IS_ERR(fid))
 467		return PTR_ERR(fid);
 468
 469	/* Ask for all the fields in stat structure. Server will return
 470	 * whatever it supports
 471	 */
 472
 473	st = p9_client_getattr_dotl(fid, P9_STATS_ALL);
 474	p9_fid_put(fid);
 475	if (IS_ERR(st))
 476		return PTR_ERR(st);
 477
 478	v9fs_stat2inode_dotl(st, d_inode(dentry), 0);
 479	generic_fillattr(&nop_mnt_idmap, request_mask, d_inode(dentry), stat);
 480	/* Change block size to what the server returned */
 481	stat->blksize = st->st_blksize;
 482
 483	kfree(st);
 484	return 0;
 485}
 486
 487/*
 488 * Attribute flags.
 489 */
 490#define P9_ATTR_MODE		(1 << 0)
 491#define P9_ATTR_UID		(1 << 1)
 492#define P9_ATTR_GID		(1 << 2)
 493#define P9_ATTR_SIZE		(1 << 3)
 494#define P9_ATTR_ATIME		(1 << 4)
 495#define P9_ATTR_MTIME		(1 << 5)
 496#define P9_ATTR_CTIME		(1 << 6)
 497#define P9_ATTR_ATIME_SET	(1 << 7)
 498#define P9_ATTR_MTIME_SET	(1 << 8)
 499
 500struct dotl_iattr_map {
 501	int iattr_valid;
 502	int p9_iattr_valid;
 503};
 504
 505static int v9fs_mapped_iattr_valid(int iattr_valid)
 506{
 507	int i;
 508	int p9_iattr_valid = 0;
 509	struct dotl_iattr_map dotl_iattr_map[] = {
 510		{ ATTR_MODE,		P9_ATTR_MODE },
 511		{ ATTR_UID,		P9_ATTR_UID },
 512		{ ATTR_GID,		P9_ATTR_GID },
 513		{ ATTR_SIZE,		P9_ATTR_SIZE },
 514		{ ATTR_ATIME,		P9_ATTR_ATIME },
 515		{ ATTR_MTIME,		P9_ATTR_MTIME },
 516		{ ATTR_CTIME,		P9_ATTR_CTIME },
 517		{ ATTR_ATIME_SET,	P9_ATTR_ATIME_SET },
 518		{ ATTR_MTIME_SET,	P9_ATTR_MTIME_SET },
 519	};
 520	for (i = 0; i < ARRAY_SIZE(dotl_iattr_map); i++) {
 521		if (iattr_valid & dotl_iattr_map[i].iattr_valid)
 522			p9_iattr_valid |= dotl_iattr_map[i].p9_iattr_valid;
 523	}
 524	return p9_iattr_valid;
 525}
 526
 527/**
 528 * v9fs_vfs_setattr_dotl - set file metadata
 529 * @idmap: idmap of the mount
 530 * @dentry: file whose metadata to set
 531 * @iattr: metadata assignment structure
 532 *
 533 */
 534
 535int v9fs_vfs_setattr_dotl(struct mnt_idmap *idmap,
 536			  struct dentry *dentry, struct iattr *iattr)
 537{
 538	int retval, use_dentry = 0;
 539	struct inode *inode = d_inode(dentry);
 540	struct v9fs_session_info __maybe_unused *v9ses;
 541	struct p9_fid *fid = NULL;
 542	struct p9_iattr_dotl p9attr = {
 543		.uid = INVALID_UID,
 544		.gid = INVALID_GID,
 545	};
 
 546
 547	p9_debug(P9_DEBUG_VFS, "\n");
 548
 549	retval = setattr_prepare(&nop_mnt_idmap, dentry, iattr);
 550	if (retval)
 551		return retval;
 552
 553	v9ses = v9fs_dentry2v9ses(dentry);
 554
 555	p9attr.valid = v9fs_mapped_iattr_valid(iattr->ia_valid);
 556	if (iattr->ia_valid & ATTR_MODE)
 557		p9attr.mode = iattr->ia_mode;
 558	if (iattr->ia_valid & ATTR_UID)
 559		p9attr.uid = iattr->ia_uid;
 560	if (iattr->ia_valid & ATTR_GID)
 561		p9attr.gid = iattr->ia_gid;
 562	if (iattr->ia_valid & ATTR_SIZE)
 563		p9attr.size = iattr->ia_size;
 564	if (iattr->ia_valid & ATTR_ATIME_SET) {
 565		p9attr.atime_sec = iattr->ia_atime.tv_sec;
 566		p9attr.atime_nsec = iattr->ia_atime.tv_nsec;
 567	}
 568	if (iattr->ia_valid & ATTR_MTIME_SET) {
 569		p9attr.mtime_sec = iattr->ia_mtime.tv_sec;
 570		p9attr.mtime_nsec = iattr->ia_mtime.tv_nsec;
 571	}
 572
 573	if (iattr->ia_valid & ATTR_FILE) {
 574		fid = iattr->ia_file->private_data;
 575		WARN_ON(!fid);
 576	}
 577	if (!fid) {
 578		fid = v9fs_fid_lookup(dentry);
 579		use_dentry = 1;
 580	}
 581	if (IS_ERR(fid))
 582		return PTR_ERR(fid);
 583
 584	/* Write all dirty data */
 585	if (S_ISREG(inode->i_mode)) {
 586		retval = filemap_fdatawrite(inode->i_mapping);
 587		if (retval < 0)
 588			p9_debug(P9_DEBUG_ERROR,
 589			    "Flushing file prior to setattr failed: %d\n", retval);
 590	}
 591
 592	retval = p9_client_setattr(fid, &p9attr);
 593	if (retval < 0) {
 594		if (use_dentry)
 595			p9_fid_put(fid);
 596		return retval;
 597	}
 598
 599	if ((iattr->ia_valid & ATTR_SIZE) && iattr->ia_size !=
 600		 i_size_read(inode)) {
 601		truncate_setsize(inode, iattr->ia_size);
 602		netfs_resize_file(netfs_inode(inode), iattr->ia_size, true);
 603
 604#ifdef CONFIG_9P_FSCACHE
 605		if (v9ses->cache & CACHE_FSCACHE)
 606			fscache_resize_cookie(v9fs_inode_cookie(V9FS_I(inode)),
 607				iattr->ia_size);
 608#endif
 609	}
 610
 611	v9fs_invalidate_inode_attr(inode);
 612	setattr_copy(&nop_mnt_idmap, inode, iattr);
 613	mark_inode_dirty(inode);
 614	if (iattr->ia_valid & ATTR_MODE) {
 615		/* We also want to update ACL when we update mode bits */
 616		retval = v9fs_acl_chmod(inode, fid);
 617		if (retval < 0) {
 618			if (use_dentry)
 619				p9_fid_put(fid);
 620			return retval;
 621		}
 622	}
 623	if (use_dentry)
 624		p9_fid_put(fid);
 625
 626	return 0;
 627}
 628
 629/**
 630 * v9fs_stat2inode_dotl - populate an inode structure with stat info
 631 * @stat: stat structure
 632 * @inode: inode to populate
 633 * @flags: ctrl flags (e.g. V9FS_STAT2INODE_KEEP_ISIZE)
 634 *
 635 */
 636
 637void
 638v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode,
 639		      unsigned int flags)
 640{
 641	umode_t mode;
 642	struct v9fs_inode *v9inode = V9FS_I(inode);
 643
 644	if ((stat->st_result_mask & P9_STATS_BASIC) == P9_STATS_BASIC) {
 645		inode_set_atime(inode, stat->st_atime_sec,
 646				stat->st_atime_nsec);
 647		inode_set_mtime(inode, stat->st_mtime_sec,
 648				stat->st_mtime_nsec);
 649		inode_set_ctime(inode, stat->st_ctime_sec,
 650				stat->st_ctime_nsec);
 651		inode->i_uid = stat->st_uid;
 652		inode->i_gid = stat->st_gid;
 653		set_nlink(inode, stat->st_nlink);
 654
 655		mode = stat->st_mode & S_IALLUGO;
 656		mode |= inode->i_mode & ~S_IALLUGO;
 657		inode->i_mode = mode;
 658
 659		v9inode->netfs.remote_i_size = stat->st_size;
 660		if (!(flags & V9FS_STAT2INODE_KEEP_ISIZE))
 661			v9fs_i_size_write(inode, stat->st_size);
 662		inode->i_blocks = stat->st_blocks;
 663	} else {
 664		if (stat->st_result_mask & P9_STATS_ATIME) {
 665			inode_set_atime(inode, stat->st_atime_sec,
 666					stat->st_atime_nsec);
 667		}
 668		if (stat->st_result_mask & P9_STATS_MTIME) {
 669			inode_set_mtime(inode, stat->st_mtime_sec,
 670					stat->st_mtime_nsec);
 671		}
 672		if (stat->st_result_mask & P9_STATS_CTIME) {
 673			inode_set_ctime(inode, stat->st_ctime_sec,
 674					stat->st_ctime_nsec);
 675		}
 676		if (stat->st_result_mask & P9_STATS_UID)
 677			inode->i_uid = stat->st_uid;
 678		if (stat->st_result_mask & P9_STATS_GID)
 679			inode->i_gid = stat->st_gid;
 680		if (stat->st_result_mask & P9_STATS_NLINK)
 681			set_nlink(inode, stat->st_nlink);
 682		if (stat->st_result_mask & P9_STATS_MODE) {
 683			mode = stat->st_mode & S_IALLUGO;
 684			mode |= inode->i_mode & ~S_IALLUGO;
 685			inode->i_mode = mode;
 686		}
 687		if (!(flags & V9FS_STAT2INODE_KEEP_ISIZE) &&
 688		    stat->st_result_mask & P9_STATS_SIZE) {
 689			v9inode->netfs.remote_i_size = stat->st_size;
 690			v9fs_i_size_write(inode, stat->st_size);
 691		}
 692		if (stat->st_result_mask & P9_STATS_BLOCKS)
 693			inode->i_blocks = stat->st_blocks;
 694	}
 695	if (stat->st_result_mask & P9_STATS_GEN)
 696		inode->i_generation = stat->st_gen;
 697
 698	/* Currently we don't support P9_STATS_BTIME and P9_STATS_DATA_VERSION
 699	 * because the inode structure does not have fields for them.
 700	 */
 701	v9inode->cache_validity &= ~V9FS_INO_INVALID_ATTR;
 702}
 703
 704static int
 705v9fs_vfs_symlink_dotl(struct mnt_idmap *idmap, struct inode *dir,
 706		      struct dentry *dentry, const char *symname)
 707{
 708	int err;
 709	kgid_t gid;
 710	const unsigned char *name;
 711	struct p9_qid qid;
 712	struct inode *inode;
 713	struct p9_fid *dfid;
 714	struct p9_fid *fid = NULL;
 715	struct v9fs_session_info *v9ses;
 716
 717	name = dentry->d_name.name;
 718	p9_debug(P9_DEBUG_VFS, "%lu,%s,%s\n", dir->i_ino, name, symname);
 719	v9ses = v9fs_inode2v9ses(dir);
 720
 721	dfid = v9fs_parent_fid(dentry);
 722	if (IS_ERR(dfid)) {
 723		err = PTR_ERR(dfid);
 724		p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
 725		return err;
 726	}
 727
 728	gid = v9fs_get_fsgid_for_create(dir);
 729
 730	/* Server doesn't alter fid on TSYMLINK. Hence no need to clone it. */
 731	err = p9_client_symlink(dfid, name, symname, gid, &qid);
 732
 733	if (err < 0) {
 734		p9_debug(P9_DEBUG_VFS, "p9_client_symlink failed %d\n", err);
 735		goto error;
 736	}
 737
 738	v9fs_invalidate_inode_attr(dir);
 739	if (v9ses->cache & (CACHE_META|CACHE_LOOSE)) {
 740		/* Now walk from the parent so we can get an unopened fid. */
 741		fid = p9_client_walk(dfid, 1, &name, 1);
 742		if (IS_ERR(fid)) {
 743			err = PTR_ERR(fid);
 744			p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
 745				 err);
 746			goto error;
 747		}
 748
 749		/* instantiate inode and assign the unopened fid to dentry */
 750		inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
 751		if (IS_ERR(inode)) {
 752			err = PTR_ERR(inode);
 753			p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n",
 754				 err);
 755			goto error;
 756		}
 757		v9fs_fid_add(dentry, &fid);
 758		d_instantiate(dentry, inode);
 759		err = 0;
 760	} else {
 761		/* Not in cached mode. No need to populate inode with stat */
 762		inode = v9fs_get_inode(dir->i_sb, S_IFLNK, 0);
 763		if (IS_ERR(inode)) {
 764			err = PTR_ERR(inode);
 765			goto error;
 766		}
 767		d_instantiate(dentry, inode);
 768	}
 769
 770error:
 771	p9_fid_put(fid);
 772	p9_fid_put(dfid);
 773	return err;
 774}
 775
 776/**
 777 * v9fs_vfs_link_dotl - create a hardlink for dotl
 778 * @old_dentry: dentry for file to link to
 779 * @dir: inode destination for new link
 780 * @dentry: dentry for link
 781 *
 782 */
 783
 784static int
 785v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir,
 786		struct dentry *dentry)
 787{
 788	int err;
 789	struct p9_fid *dfid, *oldfid;
 790	struct v9fs_session_info *v9ses;
 791
 792	p9_debug(P9_DEBUG_VFS, "dir ino: %lu, old_name: %pd, new_name: %pd\n",
 793		 dir->i_ino, old_dentry, dentry);
 794
 795	v9ses = v9fs_inode2v9ses(dir);
 796	dfid = v9fs_parent_fid(dentry);
 797	if (IS_ERR(dfid))
 798		return PTR_ERR(dfid);
 799
 800	oldfid = v9fs_fid_lookup(old_dentry);
 801	if (IS_ERR(oldfid)) {
 802		p9_fid_put(dfid);
 803		return PTR_ERR(oldfid);
 804	}
 805
 806	err = p9_client_link(dfid, oldfid, dentry->d_name.name);
 807
 808	p9_fid_put(dfid);
 809	p9_fid_put(oldfid);
 810	if (err < 0) {
 811		p9_debug(P9_DEBUG_VFS, "p9_client_link failed %d\n", err);
 812		return err;
 813	}
 814
 815	v9fs_invalidate_inode_attr(dir);
 816	if (v9ses->cache & (CACHE_META|CACHE_LOOSE)) {
 817		/* Get the latest stat info from server. */
 818		struct p9_fid *fid;
 819
 820		fid = v9fs_fid_lookup(old_dentry);
 821		if (IS_ERR(fid))
 822			return PTR_ERR(fid);
 823
 824		v9fs_refresh_inode_dotl(fid, d_inode(old_dentry));
 825		p9_fid_put(fid);
 826	}
 827	ihold(d_inode(old_dentry));
 828	d_instantiate(dentry, d_inode(old_dentry));
 829
 830	return err;
 831}
 832
 833/**
 834 * v9fs_vfs_mknod_dotl - create a special file
 835 * @idmap: The idmap of the mount
 836 * @dir: inode destination for new link
 837 * @dentry: dentry for file
 838 * @omode: mode for creation
 839 * @rdev: device associated with special file
 840 *
 841 */
 842static int
 843v9fs_vfs_mknod_dotl(struct mnt_idmap *idmap, struct inode *dir,
 844		    struct dentry *dentry, umode_t omode, dev_t rdev)
 845{
 846	int err;
 847	kgid_t gid;
 848	const unsigned char *name;
 849	umode_t mode;
 850	struct v9fs_session_info *v9ses;
 851	struct p9_fid *fid = NULL, *dfid = NULL;
 852	struct inode *inode;
 853	struct p9_qid qid;
 854	struct posix_acl *dacl = NULL, *pacl = NULL;
 855
 856	p9_debug(P9_DEBUG_VFS, " %lu,%pd mode: %x MAJOR: %u MINOR: %u\n",
 857		 dir->i_ino, dentry, omode,
 858		 MAJOR(rdev), MINOR(rdev));
 859
 860	v9ses = v9fs_inode2v9ses(dir);
 861	dfid = v9fs_parent_fid(dentry);
 862	if (IS_ERR(dfid)) {
 863		err = PTR_ERR(dfid);
 864		p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
 865		goto error;
 866	}
 867
 868	gid = v9fs_get_fsgid_for_create(dir);
 869	mode = omode;
 870	/* Update mode based on ACL value */
 871	err = v9fs_acl_mode(dir, &mode, &dacl, &pacl);
 872	if (err) {
 873		p9_debug(P9_DEBUG_VFS, "Failed to get acl values in mknod %d\n",
 874			 err);
 875		goto error;
 876	}
 877	name = dentry->d_name.name;
 878
 879	err = p9_client_mknod_dotl(dfid, name, mode, rdev, gid, &qid);
 880	if (err < 0)
 881		goto error;
 882
 883	v9fs_invalidate_inode_attr(dir);
 884	fid = p9_client_walk(dfid, 1, &name, 1);
 885	if (IS_ERR(fid)) {
 886		err = PTR_ERR(fid);
 887		p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n",
 888			 err);
 889		goto error;
 890	}
 891
 892	/* instantiate inode and assign the unopened fid to the dentry */
 893	if (v9ses->cache & (CACHE_META|CACHE_LOOSE)) {
 894		inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
 895		if (IS_ERR(inode)) {
 896			err = PTR_ERR(inode);
 897			p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n",
 898				 err);
 899			goto error;
 900		}
 901		v9fs_set_create_acl(inode, fid, dacl, pacl);
 902		v9fs_fid_add(dentry, &fid);
 903		d_instantiate(dentry, inode);
 904		err = 0;
 905	} else {
 906		/*
 907		 * Not in cached mode. No need to populate inode with stat.
 908		 * socket syscall returns a fd, so we need instantiate
 909		 */
 910		inode = v9fs_get_inode(dir->i_sb, mode, rdev);
 911		if (IS_ERR(inode)) {
 912			err = PTR_ERR(inode);
 913			goto error;
 914		}
 915		v9fs_set_create_acl(inode, fid, dacl, pacl);
 916		d_instantiate(dentry, inode);
 917	}
 918error:
 919	p9_fid_put(fid);
 920	v9fs_put_acl(dacl, pacl);
 921	p9_fid_put(dfid);
 922
 923	return err;
 924}
 925
 926/**
 927 * v9fs_vfs_get_link_dotl - follow a symlink path
 928 * @dentry: dentry for symlink
 929 * @inode: inode for symlink
 930 * @done: destructor for return value
 931 */
 932
 933static const char *
 934v9fs_vfs_get_link_dotl(struct dentry *dentry,
 935		       struct inode *inode,
 936		       struct delayed_call *done)
 937{
 938	struct p9_fid *fid;
 939	char *target;
 940	int retval;
 941
 942	if (!dentry)
 943		return ERR_PTR(-ECHILD);
 944
 945	p9_debug(P9_DEBUG_VFS, "%pd\n", dentry);
 946
 947	fid = v9fs_fid_lookup(dentry);
 948	if (IS_ERR(fid))
 949		return ERR_CAST(fid);
 950	retval = p9_client_readlink(fid, &target);
 951	p9_fid_put(fid);
 952	if (retval)
 953		return ERR_PTR(retval);
 954	set_delayed_call(done, kfree_link, target);
 955	return target;
 956}
 957
 958int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode)
 959{
 960	struct p9_stat_dotl *st;
 961	struct v9fs_session_info *v9ses;
 962	unsigned int flags;
 963
 964	v9ses = v9fs_inode2v9ses(inode);
 965	st = p9_client_getattr_dotl(fid, P9_STATS_ALL);
 966	if (IS_ERR(st))
 967		return PTR_ERR(st);
 968	/*
 969	 * Don't update inode if the file type is different
 970	 */
 971	if (inode_wrong_type(inode, st->st_mode))
 972		goto out;
 973
 974	/*
 975	 * We don't want to refresh inode->i_size,
 976	 * because we may have cached data
 977	 */
 978	flags = (v9ses->cache & CACHE_LOOSE) ?
 979		V9FS_STAT2INODE_KEEP_ISIZE : 0;
 980	v9fs_stat2inode_dotl(st, inode, flags);
 981out:
 982	kfree(st);
 983	return 0;
 984}
 985
 986const struct inode_operations v9fs_dir_inode_operations_dotl = {
 987	.create = v9fs_vfs_create_dotl,
 988	.atomic_open = v9fs_vfs_atomic_open_dotl,
 989	.lookup = v9fs_vfs_lookup,
 990	.link = v9fs_vfs_link_dotl,
 991	.symlink = v9fs_vfs_symlink_dotl,
 992	.unlink = v9fs_vfs_unlink,
 993	.mkdir = v9fs_vfs_mkdir_dotl,
 994	.rmdir = v9fs_vfs_rmdir,
 995	.mknod = v9fs_vfs_mknod_dotl,
 996	.rename = v9fs_vfs_rename,
 997	.getattr = v9fs_vfs_getattr_dotl,
 998	.setattr = v9fs_vfs_setattr_dotl,
 999	.listxattr = v9fs_listxattr,
1000	.get_inode_acl = v9fs_iop_get_inode_acl,
1001	.get_acl = v9fs_iop_get_acl,
1002	.set_acl = v9fs_iop_set_acl,
1003};
1004
1005const struct inode_operations v9fs_file_inode_operations_dotl = {
1006	.getattr = v9fs_vfs_getattr_dotl,
1007	.setattr = v9fs_vfs_setattr_dotl,
1008	.listxattr = v9fs_listxattr,
1009	.get_inode_acl = v9fs_iop_get_inode_acl,
1010	.get_acl = v9fs_iop_get_acl,
1011	.set_acl = v9fs_iop_set_acl,
1012};
1013
1014const struct inode_operations v9fs_symlink_inode_operations_dotl = {
1015	.get_link = v9fs_vfs_get_link_dotl,
1016	.getattr = v9fs_vfs_getattr_dotl,
1017	.setattr = v9fs_vfs_setattr_dotl,
1018	.listxattr = v9fs_listxattr,
1019};