cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

vfs_inode.c (35224B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * This file contains vfs inode ops for the 9P2000 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#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
     10
     11#include <linux/module.h>
     12#include <linux/errno.h>
     13#include <linux/fs.h>
     14#include <linux/file.h>
     15#include <linux/pagemap.h>
     16#include <linux/stat.h>
     17#include <linux/string.h>
     18#include <linux/inet.h>
     19#include <linux/namei.h>
     20#include <linux/idr.h>
     21#include <linux/sched.h>
     22#include <linux/slab.h>
     23#include <linux/xattr.h>
     24#include <linux/posix_acl.h>
     25#include <net/9p/9p.h>
     26#include <net/9p/client.h>
     27
     28#include "v9fs.h"
     29#include "v9fs_vfs.h"
     30#include "fid.h"
     31#include "cache.h"
     32#include "xattr.h"
     33#include "acl.h"
     34
     35static const struct inode_operations v9fs_dir_inode_operations;
     36static const struct inode_operations v9fs_dir_inode_operations_dotu;
     37static const struct inode_operations v9fs_file_inode_operations;
     38static const struct inode_operations v9fs_symlink_inode_operations;
     39
     40/**
     41 * unixmode2p9mode - convert unix mode bits to plan 9
     42 * @v9ses: v9fs session information
     43 * @mode: mode to convert
     44 *
     45 */
     46
     47static u32 unixmode2p9mode(struct v9fs_session_info *v9ses, umode_t mode)
     48{
     49	int res;
     50
     51	res = mode & 0777;
     52	if (S_ISDIR(mode))
     53		res |= P9_DMDIR;
     54	if (v9fs_proto_dotu(v9ses)) {
     55		if (v9ses->nodev == 0) {
     56			if (S_ISSOCK(mode))
     57				res |= P9_DMSOCKET;
     58			if (S_ISFIFO(mode))
     59				res |= P9_DMNAMEDPIPE;
     60			if (S_ISBLK(mode))
     61				res |= P9_DMDEVICE;
     62			if (S_ISCHR(mode))
     63				res |= P9_DMDEVICE;
     64		}
     65
     66		if ((mode & S_ISUID) == S_ISUID)
     67			res |= P9_DMSETUID;
     68		if ((mode & S_ISGID) == S_ISGID)
     69			res |= P9_DMSETGID;
     70		if ((mode & S_ISVTX) == S_ISVTX)
     71			res |= P9_DMSETVTX;
     72	}
     73	return res;
     74}
     75
     76/**
     77 * p9mode2perm- convert plan9 mode bits to unix permission bits
     78 * @v9ses: v9fs session information
     79 * @stat: p9_wstat from which mode need to be derived
     80 *
     81 */
     82static int p9mode2perm(struct v9fs_session_info *v9ses,
     83		       struct p9_wstat *stat)
     84{
     85	int res;
     86	int mode = stat->mode;
     87
     88	res = mode & S_IALLUGO;
     89	if (v9fs_proto_dotu(v9ses)) {
     90		if ((mode & P9_DMSETUID) == P9_DMSETUID)
     91			res |= S_ISUID;
     92
     93		if ((mode & P9_DMSETGID) == P9_DMSETGID)
     94			res |= S_ISGID;
     95
     96		if ((mode & P9_DMSETVTX) == P9_DMSETVTX)
     97			res |= S_ISVTX;
     98	}
     99	return res;
    100}
    101
    102/**
    103 * p9mode2unixmode- convert plan9 mode bits to unix mode bits
    104 * @v9ses: v9fs session information
    105 * @stat: p9_wstat from which mode need to be derived
    106 * @rdev: major number, minor number in case of device files.
    107 *
    108 */
    109static umode_t p9mode2unixmode(struct v9fs_session_info *v9ses,
    110			       struct p9_wstat *stat, dev_t *rdev)
    111{
    112	int res, r;
    113	u32 mode = stat->mode;
    114
    115	*rdev = 0;
    116	res = p9mode2perm(v9ses, stat);
    117
    118	if ((mode & P9_DMDIR) == P9_DMDIR)
    119		res |= S_IFDIR;
    120	else if ((mode & P9_DMSYMLINK) && (v9fs_proto_dotu(v9ses)))
    121		res |= S_IFLNK;
    122	else if ((mode & P9_DMSOCKET) && (v9fs_proto_dotu(v9ses))
    123		 && (v9ses->nodev == 0))
    124		res |= S_IFSOCK;
    125	else if ((mode & P9_DMNAMEDPIPE) && (v9fs_proto_dotu(v9ses))
    126		 && (v9ses->nodev == 0))
    127		res |= S_IFIFO;
    128	else if ((mode & P9_DMDEVICE) && (v9fs_proto_dotu(v9ses))
    129		 && (v9ses->nodev == 0)) {
    130		char type = 0;
    131		int major = -1, minor = -1;
    132
    133		r = sscanf(stat->extension, "%c %i %i", &type, &major, &minor);
    134		if (r != 3) {
    135			p9_debug(P9_DEBUG_ERROR,
    136				 "invalid device string, umode will be bogus: %s\n",
    137				 stat->extension);
    138			return res;
    139		}
    140		switch (type) {
    141		case 'c':
    142			res |= S_IFCHR;
    143			break;
    144		case 'b':
    145			res |= S_IFBLK;
    146			break;
    147		default:
    148			p9_debug(P9_DEBUG_ERROR, "Unknown special type %c %s\n",
    149				 type, stat->extension);
    150		}
    151		*rdev = MKDEV(major, minor);
    152	} else
    153		res |= S_IFREG;
    154
    155	return res;
    156}
    157
    158/**
    159 * v9fs_uflags2omode- convert posix open flags to plan 9 mode bits
    160 * @uflags: flags to convert
    161 * @extended: if .u extensions are active
    162 */
    163
    164int v9fs_uflags2omode(int uflags, int extended)
    165{
    166	int ret;
    167
    168	ret = 0;
    169	switch (uflags&3) {
    170	default:
    171	case O_RDONLY:
    172		ret = P9_OREAD;
    173		break;
    174
    175	case O_WRONLY:
    176		ret = P9_OWRITE;
    177		break;
    178
    179	case O_RDWR:
    180		ret = P9_ORDWR;
    181		break;
    182	}
    183
    184	if (extended) {
    185		if (uflags & O_EXCL)
    186			ret |= P9_OEXCL;
    187
    188		if (uflags & O_APPEND)
    189			ret |= P9_OAPPEND;
    190	}
    191
    192	return ret;
    193}
    194
    195/**
    196 * v9fs_blank_wstat - helper function to setup a 9P stat structure
    197 * @wstat: structure to initialize
    198 *
    199 */
    200
    201void
    202v9fs_blank_wstat(struct p9_wstat *wstat)
    203{
    204	wstat->type = ~0;
    205	wstat->dev = ~0;
    206	wstat->qid.type = ~0;
    207	wstat->qid.version = ~0;
    208	*((long long *)&wstat->qid.path) = ~0;
    209	wstat->mode = ~0;
    210	wstat->atime = ~0;
    211	wstat->mtime = ~0;
    212	wstat->length = ~0;
    213	wstat->name = NULL;
    214	wstat->uid = NULL;
    215	wstat->gid = NULL;
    216	wstat->muid = NULL;
    217	wstat->n_uid = INVALID_UID;
    218	wstat->n_gid = INVALID_GID;
    219	wstat->n_muid = INVALID_UID;
    220	wstat->extension = NULL;
    221}
    222
    223/**
    224 * v9fs_alloc_inode - helper function to allocate an inode
    225 * @sb: The superblock to allocate the inode from
    226 */
    227struct inode *v9fs_alloc_inode(struct super_block *sb)
    228{
    229	struct v9fs_inode *v9inode;
    230
    231	v9inode = alloc_inode_sb(sb, v9fs_inode_cache, GFP_KERNEL);
    232	if (!v9inode)
    233		return NULL;
    234	v9inode->writeback_fid = NULL;
    235	v9inode->cache_validity = 0;
    236	mutex_init(&v9inode->v_mutex);
    237	return &v9inode->netfs.inode;
    238}
    239
    240/**
    241 * v9fs_free_inode - destroy an inode
    242 * @inode: The inode to be freed
    243 */
    244
    245void v9fs_free_inode(struct inode *inode)
    246{
    247	kmem_cache_free(v9fs_inode_cache, V9FS_I(inode));
    248}
    249
    250/*
    251 * Set parameters for the netfs library
    252 */
    253static void v9fs_set_netfs_context(struct inode *inode)
    254{
    255	struct v9fs_inode *v9inode = V9FS_I(inode);
    256	netfs_inode_init(&v9inode->netfs, &v9fs_req_ops);
    257}
    258
    259int v9fs_init_inode(struct v9fs_session_info *v9ses,
    260		    struct inode *inode, umode_t mode, dev_t rdev)
    261{
    262	int err = 0;
    263
    264	inode_init_owner(&init_user_ns, inode, NULL, mode);
    265	inode->i_blocks = 0;
    266	inode->i_rdev = rdev;
    267	inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
    268	inode->i_mapping->a_ops = &v9fs_addr_operations;
    269	inode->i_private = NULL;
    270
    271	switch (mode & S_IFMT) {
    272	case S_IFIFO:
    273	case S_IFBLK:
    274	case S_IFCHR:
    275	case S_IFSOCK:
    276		if (v9fs_proto_dotl(v9ses)) {
    277			inode->i_op = &v9fs_file_inode_operations_dotl;
    278		} else if (v9fs_proto_dotu(v9ses)) {
    279			inode->i_op = &v9fs_file_inode_operations;
    280		} else {
    281			p9_debug(P9_DEBUG_ERROR,
    282				 "special files without extended mode\n");
    283			err = -EINVAL;
    284			goto error;
    285		}
    286		init_special_inode(inode, inode->i_mode, inode->i_rdev);
    287		break;
    288	case S_IFREG:
    289		if (v9fs_proto_dotl(v9ses)) {
    290			inode->i_op = &v9fs_file_inode_operations_dotl;
    291			if (v9ses->cache == CACHE_LOOSE ||
    292			    v9ses->cache == CACHE_FSCACHE)
    293				inode->i_fop =
    294					&v9fs_cached_file_operations_dotl;
    295			else if (v9ses->cache == CACHE_MMAP)
    296				inode->i_fop = &v9fs_mmap_file_operations_dotl;
    297			else
    298				inode->i_fop = &v9fs_file_operations_dotl;
    299		} else {
    300			inode->i_op = &v9fs_file_inode_operations;
    301			if (v9ses->cache == CACHE_LOOSE ||
    302			    v9ses->cache == CACHE_FSCACHE)
    303				inode->i_fop =
    304					&v9fs_cached_file_operations;
    305			else if (v9ses->cache == CACHE_MMAP)
    306				inode->i_fop = &v9fs_mmap_file_operations;
    307			else
    308				inode->i_fop = &v9fs_file_operations;
    309		}
    310
    311		break;
    312	case S_IFLNK:
    313		if (!v9fs_proto_dotu(v9ses) && !v9fs_proto_dotl(v9ses)) {
    314			p9_debug(P9_DEBUG_ERROR,
    315				 "extended modes used with legacy protocol\n");
    316			err = -EINVAL;
    317			goto error;
    318		}
    319
    320		if (v9fs_proto_dotl(v9ses))
    321			inode->i_op = &v9fs_symlink_inode_operations_dotl;
    322		else
    323			inode->i_op = &v9fs_symlink_inode_operations;
    324
    325		break;
    326	case S_IFDIR:
    327		inc_nlink(inode);
    328		if (v9fs_proto_dotl(v9ses))
    329			inode->i_op = &v9fs_dir_inode_operations_dotl;
    330		else if (v9fs_proto_dotu(v9ses))
    331			inode->i_op = &v9fs_dir_inode_operations_dotu;
    332		else
    333			inode->i_op = &v9fs_dir_inode_operations;
    334
    335		if (v9fs_proto_dotl(v9ses))
    336			inode->i_fop = &v9fs_dir_operations_dotl;
    337		else
    338			inode->i_fop = &v9fs_dir_operations;
    339
    340		break;
    341	default:
    342		p9_debug(P9_DEBUG_ERROR, "BAD mode 0x%hx S_IFMT 0x%x\n",
    343			 mode, mode & S_IFMT);
    344		err = -EINVAL;
    345		goto error;
    346	}
    347
    348	v9fs_set_netfs_context(inode);
    349error:
    350	return err;
    351
    352}
    353
    354/**
    355 * v9fs_get_inode - helper function to setup an inode
    356 * @sb: superblock
    357 * @mode: mode to setup inode with
    358 * @rdev: The device numbers to set
    359 */
    360
    361struct inode *v9fs_get_inode(struct super_block *sb, umode_t mode, dev_t rdev)
    362{
    363	int err;
    364	struct inode *inode;
    365	struct v9fs_session_info *v9ses = sb->s_fs_info;
    366
    367	p9_debug(P9_DEBUG_VFS, "super block: %p mode: %ho\n", sb, mode);
    368
    369	inode = new_inode(sb);
    370	if (!inode) {
    371		pr_warn("%s (%d): Problem allocating inode\n",
    372			__func__, task_pid_nr(current));
    373		return ERR_PTR(-ENOMEM);
    374	}
    375	err = v9fs_init_inode(v9ses, inode, mode, rdev);
    376	if (err) {
    377		iput(inode);
    378		return ERR_PTR(err);
    379	}
    380	return inode;
    381}
    382
    383/**
    384 * v9fs_evict_inode - Remove an inode from the inode cache
    385 * @inode: inode to release
    386 *
    387 */
    388void v9fs_evict_inode(struct inode *inode)
    389{
    390	struct v9fs_inode *v9inode = V9FS_I(inode);
    391	__le32 version;
    392
    393	truncate_inode_pages_final(&inode->i_data);
    394	version = cpu_to_le32(v9inode->qid.version);
    395	fscache_clear_inode_writeback(v9fs_inode_cookie(v9inode), inode,
    396				      &version);
    397	clear_inode(inode);
    398	filemap_fdatawrite(&inode->i_data);
    399
    400	fscache_relinquish_cookie(v9fs_inode_cookie(v9inode), false);
    401	/* clunk the fid stashed in writeback_fid */
    402	if (v9inode->writeback_fid) {
    403		p9_client_clunk(v9inode->writeback_fid);
    404		v9inode->writeback_fid = NULL;
    405	}
    406}
    407
    408static int v9fs_test_inode(struct inode *inode, void *data)
    409{
    410	int umode;
    411	dev_t rdev;
    412	struct v9fs_inode *v9inode = V9FS_I(inode);
    413	struct p9_wstat *st = (struct p9_wstat *)data;
    414	struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
    415
    416	umode = p9mode2unixmode(v9ses, st, &rdev);
    417	/* don't match inode of different type */
    418	if (inode_wrong_type(inode, umode))
    419		return 0;
    420
    421	/* compare qid details */
    422	if (memcmp(&v9inode->qid.version,
    423		   &st->qid.version, sizeof(v9inode->qid.version)))
    424		return 0;
    425
    426	if (v9inode->qid.type != st->qid.type)
    427		return 0;
    428
    429	if (v9inode->qid.path != st->qid.path)
    430		return 0;
    431	return 1;
    432}
    433
    434static int v9fs_test_new_inode(struct inode *inode, void *data)
    435{
    436	return 0;
    437}
    438
    439static int v9fs_set_inode(struct inode *inode,  void *data)
    440{
    441	struct v9fs_inode *v9inode = V9FS_I(inode);
    442	struct p9_wstat *st = (struct p9_wstat *)data;
    443
    444	memcpy(&v9inode->qid, &st->qid, sizeof(st->qid));
    445	return 0;
    446}
    447
    448static struct inode *v9fs_qid_iget(struct super_block *sb,
    449				   struct p9_qid *qid,
    450				   struct p9_wstat *st,
    451				   int new)
    452{
    453	dev_t rdev;
    454	int retval;
    455	umode_t umode;
    456	unsigned long i_ino;
    457	struct inode *inode;
    458	struct v9fs_session_info *v9ses = sb->s_fs_info;
    459	int (*test)(struct inode *inode, void *data);
    460
    461	if (new)
    462		test = v9fs_test_new_inode;
    463	else
    464		test = v9fs_test_inode;
    465
    466	i_ino = v9fs_qid2ino(qid);
    467	inode = iget5_locked(sb, i_ino, test, v9fs_set_inode, st);
    468	if (!inode)
    469		return ERR_PTR(-ENOMEM);
    470	if (!(inode->i_state & I_NEW))
    471		return inode;
    472	/*
    473	 * initialize the inode with the stat info
    474	 * FIXME!! we may need support for stale inodes
    475	 * later.
    476	 */
    477	inode->i_ino = i_ino;
    478	umode = p9mode2unixmode(v9ses, st, &rdev);
    479	retval = v9fs_init_inode(v9ses, inode, umode, rdev);
    480	if (retval)
    481		goto error;
    482
    483	v9fs_stat2inode(st, inode, sb, 0);
    484	v9fs_cache_inode_get_cookie(inode);
    485	unlock_new_inode(inode);
    486	return inode;
    487error:
    488	iget_failed(inode);
    489	return ERR_PTR(retval);
    490
    491}
    492
    493struct inode *
    494v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
    495		    struct super_block *sb, int new)
    496{
    497	struct p9_wstat *st;
    498	struct inode *inode = NULL;
    499
    500	st = p9_client_stat(fid);
    501	if (IS_ERR(st))
    502		return ERR_CAST(st);
    503
    504	inode = v9fs_qid_iget(sb, &st->qid, st, new);
    505	p9stat_free(st);
    506	kfree(st);
    507	return inode;
    508}
    509
    510/**
    511 * v9fs_at_to_dotl_flags- convert Linux specific AT flags to
    512 * plan 9 AT flag.
    513 * @flags: flags to convert
    514 */
    515static int v9fs_at_to_dotl_flags(int flags)
    516{
    517	int rflags = 0;
    518
    519	if (flags & AT_REMOVEDIR)
    520		rflags |= P9_DOTL_AT_REMOVEDIR;
    521
    522	return rflags;
    523}
    524
    525/**
    526 * v9fs_dec_count - helper functon to drop i_nlink.
    527 *
    528 * If a directory had nlink <= 2 (including . and ..), then we should not drop
    529 * the link count, which indicates the underlying exported fs doesn't maintain
    530 * nlink accurately. e.g.
    531 * - overlayfs sets nlink to 1 for merged dir
    532 * - ext4 (with dir_nlink feature enabled) sets nlink to 1 if a dir has more
    533 *   than EXT4_LINK_MAX (65000) links.
    534 *
    535 * @inode: inode whose nlink is being dropped
    536 */
    537static void v9fs_dec_count(struct inode *inode)
    538{
    539	if (!S_ISDIR(inode->i_mode) || inode->i_nlink > 2)
    540		drop_nlink(inode);
    541}
    542
    543/**
    544 * v9fs_remove - helper function to remove files and directories
    545 * @dir: directory inode that is being deleted
    546 * @dentry:  dentry that is being deleted
    547 * @flags: removing a directory
    548 *
    549 */
    550
    551static int v9fs_remove(struct inode *dir, struct dentry *dentry, int flags)
    552{
    553	struct inode *inode;
    554	int retval = -EOPNOTSUPP;
    555	struct p9_fid *v9fid, *dfid;
    556	struct v9fs_session_info *v9ses;
    557
    558	p9_debug(P9_DEBUG_VFS, "inode: %p dentry: %p rmdir: %x\n",
    559		 dir, dentry, flags);
    560
    561	v9ses = v9fs_inode2v9ses(dir);
    562	inode = d_inode(dentry);
    563	dfid = v9fs_parent_fid(dentry);
    564	if (IS_ERR(dfid)) {
    565		retval = PTR_ERR(dfid);
    566		p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", retval);
    567		return retval;
    568	}
    569	if (v9fs_proto_dotl(v9ses))
    570		retval = p9_client_unlinkat(dfid, dentry->d_name.name,
    571					    v9fs_at_to_dotl_flags(flags));
    572	p9_client_clunk(dfid);
    573	if (retval == -EOPNOTSUPP) {
    574		/* Try the one based on path */
    575		v9fid = v9fs_fid_clone(dentry);
    576		if (IS_ERR(v9fid))
    577			return PTR_ERR(v9fid);
    578		retval = p9_client_remove(v9fid);
    579	}
    580	if (!retval) {
    581		/*
    582		 * directories on unlink should have zero
    583		 * link count
    584		 */
    585		if (flags & AT_REMOVEDIR) {
    586			clear_nlink(inode);
    587			v9fs_dec_count(dir);
    588		} else
    589			v9fs_dec_count(inode);
    590
    591		v9fs_invalidate_inode_attr(inode);
    592		v9fs_invalidate_inode_attr(dir);
    593
    594		/* invalidate all fids associated with dentry */
    595		/* NOTE: This will not include open fids */
    596		dentry->d_op->d_release(dentry);
    597	}
    598	return retval;
    599}
    600
    601/**
    602 * v9fs_create - Create a file
    603 * @v9ses: session information
    604 * @dir: directory that dentry is being created in
    605 * @dentry:  dentry that is being created
    606 * @extension: 9p2000.u extension string to support devices, etc.
    607 * @perm: create permissions
    608 * @mode: open mode
    609 *
    610 */
    611static struct p9_fid *
    612v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
    613		struct dentry *dentry, char *extension, u32 perm, u8 mode)
    614{
    615	int err;
    616	const unsigned char *name;
    617	struct p9_fid *dfid, *ofid = NULL, *fid = NULL;
    618	struct inode *inode;
    619
    620	p9_debug(P9_DEBUG_VFS, "name %pd\n", dentry);
    621
    622	err = 0;
    623	name = dentry->d_name.name;
    624	dfid = v9fs_parent_fid(dentry);
    625	if (IS_ERR(dfid)) {
    626		err = PTR_ERR(dfid);
    627		p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
    628		return ERR_PTR(err);
    629	}
    630
    631	/* clone a fid to use for creation */
    632	ofid = clone_fid(dfid);
    633	if (IS_ERR(ofid)) {
    634		err = PTR_ERR(ofid);
    635		p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
    636		p9_client_clunk(dfid);
    637		return ERR_PTR(err);
    638	}
    639
    640	err = p9_client_fcreate(ofid, name, perm, mode, extension);
    641	if (err < 0) {
    642		p9_debug(P9_DEBUG_VFS, "p9_client_fcreate failed %d\n", err);
    643		p9_client_clunk(dfid);
    644		goto error;
    645	}
    646
    647	if (!(perm & P9_DMLINK)) {
    648		/* now walk from the parent so we can get unopened fid */
    649		fid = p9_client_walk(dfid, 1, &name, 1);
    650		if (IS_ERR(fid)) {
    651			err = PTR_ERR(fid);
    652			p9_debug(P9_DEBUG_VFS,
    653				   "p9_client_walk failed %d\n", err);
    654			fid = NULL;
    655			p9_client_clunk(dfid);
    656			goto error;
    657		}
    658		/*
    659		 * instantiate inode and assign the unopened fid to the dentry
    660		 */
    661		inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
    662		if (IS_ERR(inode)) {
    663			err = PTR_ERR(inode);
    664			p9_debug(P9_DEBUG_VFS,
    665				   "inode creation failed %d\n", err);
    666			p9_client_clunk(dfid);
    667			goto error;
    668		}
    669		v9fs_fid_add(dentry, fid);
    670		d_instantiate(dentry, inode);
    671	}
    672	p9_client_clunk(dfid);
    673	return ofid;
    674error:
    675	if (ofid)
    676		p9_client_clunk(ofid);
    677
    678	if (fid)
    679		p9_client_clunk(fid);
    680
    681	return ERR_PTR(err);
    682}
    683
    684/**
    685 * v9fs_vfs_create - VFS hook to create a regular file
    686 * @mnt_userns: The user namespace of the mount
    687 * @dir: The parent directory
    688 * @dentry: The name of file to be created
    689 * @mode: The UNIX file mode to set
    690 * @excl: True if the file must not yet exist
    691 *
    692 * open(.., O_CREAT) is handled in v9fs_vfs_atomic_open().  This is only called
    693 * for mknod(2).
    694 *
    695 */
    696
    697static int
    698v9fs_vfs_create(struct user_namespace *mnt_userns, struct inode *dir,
    699		struct dentry *dentry, umode_t mode, bool excl)
    700{
    701	struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir);
    702	u32 perm = unixmode2p9mode(v9ses, mode);
    703	struct p9_fid *fid;
    704
    705	/* P9_OEXCL? */
    706	fid = v9fs_create(v9ses, dir, dentry, NULL, perm, P9_ORDWR);
    707	if (IS_ERR(fid))
    708		return PTR_ERR(fid);
    709
    710	v9fs_invalidate_inode_attr(dir);
    711	p9_client_clunk(fid);
    712
    713	return 0;
    714}
    715
    716/**
    717 * v9fs_vfs_mkdir - VFS mkdir hook to create a directory
    718 * @mnt_userns: The user namespace of the mount
    719 * @dir:  inode that is being unlinked
    720 * @dentry: dentry that is being unlinked
    721 * @mode: mode for new directory
    722 *
    723 */
    724
    725static int v9fs_vfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
    726			  struct dentry *dentry, umode_t mode)
    727{
    728	int err;
    729	u32 perm;
    730	struct p9_fid *fid;
    731	struct v9fs_session_info *v9ses;
    732
    733	p9_debug(P9_DEBUG_VFS, "name %pd\n", dentry);
    734	err = 0;
    735	v9ses = v9fs_inode2v9ses(dir);
    736	perm = unixmode2p9mode(v9ses, mode | S_IFDIR);
    737	fid = v9fs_create(v9ses, dir, dentry, NULL, perm, P9_OREAD);
    738	if (IS_ERR(fid)) {
    739		err = PTR_ERR(fid);
    740		fid = NULL;
    741	} else {
    742		inc_nlink(dir);
    743		v9fs_invalidate_inode_attr(dir);
    744	}
    745
    746	if (fid)
    747		p9_client_clunk(fid);
    748
    749	return err;
    750}
    751
    752/**
    753 * v9fs_vfs_lookup - VFS lookup hook to "walk" to a new inode
    754 * @dir:  inode that is being walked from
    755 * @dentry: dentry that is being walked to?
    756 * @flags: lookup flags (unused)
    757 *
    758 */
    759
    760struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
    761				      unsigned int flags)
    762{
    763	struct dentry *res;
    764	struct v9fs_session_info *v9ses;
    765	struct p9_fid *dfid, *fid;
    766	struct inode *inode;
    767	const unsigned char *name;
    768
    769	p9_debug(P9_DEBUG_VFS, "dir: %p dentry: (%pd) %p flags: %x\n",
    770		 dir, dentry, dentry, flags);
    771
    772	if (dentry->d_name.len > NAME_MAX)
    773		return ERR_PTR(-ENAMETOOLONG);
    774
    775	v9ses = v9fs_inode2v9ses(dir);
    776	/* We can walk d_parent because we hold the dir->i_mutex */
    777	dfid = v9fs_parent_fid(dentry);
    778	if (IS_ERR(dfid))
    779		return ERR_CAST(dfid);
    780
    781	/*
    782	 * Make sure we don't use a wrong inode due to parallel
    783	 * unlink. For cached mode create calls request for new
    784	 * inode. But with cache disabled, lookup should do this.
    785	 */
    786	name = dentry->d_name.name;
    787	fid = p9_client_walk(dfid, 1, &name, 1);
    788	p9_client_clunk(dfid);
    789	if (fid == ERR_PTR(-ENOENT))
    790		inode = NULL;
    791	else if (IS_ERR(fid))
    792		inode = ERR_CAST(fid);
    793	else if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
    794		inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
    795	else
    796		inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
    797	/*
    798	 * If we had a rename on the server and a parallel lookup
    799	 * for the new name, then make sure we instantiate with
    800	 * the new name. ie look up for a/b, while on server somebody
    801	 * moved b under k and client parallely did a lookup for
    802	 * k/b.
    803	 */
    804	res = d_splice_alias(inode, dentry);
    805	if (!IS_ERR(fid)) {
    806		if (!res)
    807			v9fs_fid_add(dentry, fid);
    808		else if (!IS_ERR(res))
    809			v9fs_fid_add(res, fid);
    810		else
    811			p9_client_clunk(fid);
    812	}
    813	return res;
    814}
    815
    816static int
    817v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
    818		     struct file *file, unsigned int flags, umode_t mode)
    819{
    820	int err;
    821	u32 perm;
    822	struct v9fs_inode *v9inode;
    823	struct v9fs_session_info *v9ses;
    824	struct p9_fid *fid, *inode_fid;
    825	struct dentry *res = NULL;
    826	struct inode *inode;
    827
    828	if (d_in_lookup(dentry)) {
    829		res = v9fs_vfs_lookup(dir, dentry, 0);
    830		if (IS_ERR(res))
    831			return PTR_ERR(res);
    832
    833		if (res)
    834			dentry = res;
    835	}
    836
    837	/* Only creates */
    838	if (!(flags & O_CREAT) || d_really_is_positive(dentry))
    839		return finish_no_open(file, res);
    840
    841	err = 0;
    842
    843	v9ses = v9fs_inode2v9ses(dir);
    844	perm = unixmode2p9mode(v9ses, mode);
    845	fid = v9fs_create(v9ses, dir, dentry, NULL, perm,
    846				v9fs_uflags2omode(flags,
    847						v9fs_proto_dotu(v9ses)));
    848	if (IS_ERR(fid)) {
    849		err = PTR_ERR(fid);
    850		fid = NULL;
    851		goto error;
    852	}
    853
    854	v9fs_invalidate_inode_attr(dir);
    855	inode = d_inode(dentry);
    856	v9inode = V9FS_I(inode);
    857	mutex_lock(&v9inode->v_mutex);
    858	if ((v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) &&
    859	    !v9inode->writeback_fid &&
    860	    ((flags & O_ACCMODE) != O_RDONLY)) {
    861		/*
    862		 * clone a fid and add it to writeback_fid
    863		 * we do it during open time instead of
    864		 * page dirty time via write_begin/page_mkwrite
    865		 * because we want write after unlink usecase
    866		 * to work.
    867		 */
    868		inode_fid = v9fs_writeback_fid(dentry);
    869		if (IS_ERR(inode_fid)) {
    870			err = PTR_ERR(inode_fid);
    871			mutex_unlock(&v9inode->v_mutex);
    872			goto error;
    873		}
    874		v9inode->writeback_fid = (void *) inode_fid;
    875	}
    876	mutex_unlock(&v9inode->v_mutex);
    877	err = finish_open(file, dentry, generic_file_open);
    878	if (err)
    879		goto error;
    880
    881	file->private_data = fid;
    882	if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
    883		fscache_use_cookie(v9fs_inode_cookie(v9inode),
    884				   file->f_mode & FMODE_WRITE);
    885	v9fs_open_fid_add(inode, fid);
    886
    887	file->f_mode |= FMODE_CREATED;
    888out:
    889	dput(res);
    890	return err;
    891
    892error:
    893	if (fid)
    894		p9_client_clunk(fid);
    895	goto out;
    896}
    897
    898/**
    899 * v9fs_vfs_unlink - VFS unlink hook to delete an inode
    900 * @i:  inode that is being unlinked
    901 * @d: dentry that is being unlinked
    902 *
    903 */
    904
    905int v9fs_vfs_unlink(struct inode *i, struct dentry *d)
    906{
    907	return v9fs_remove(i, d, 0);
    908}
    909
    910/**
    911 * v9fs_vfs_rmdir - VFS unlink hook to delete a directory
    912 * @i:  inode that is being unlinked
    913 * @d: dentry that is being unlinked
    914 *
    915 */
    916
    917int v9fs_vfs_rmdir(struct inode *i, struct dentry *d)
    918{
    919	return v9fs_remove(i, d, AT_REMOVEDIR);
    920}
    921
    922/**
    923 * v9fs_vfs_rename - VFS hook to rename an inode
    924 * @mnt_userns: The user namespace of the mount
    925 * @old_dir:  old dir inode
    926 * @old_dentry: old dentry
    927 * @new_dir: new dir inode
    928 * @new_dentry: new dentry
    929 * @flags: RENAME_* flags
    930 *
    931 */
    932
    933int
    934v9fs_vfs_rename(struct user_namespace *mnt_userns, struct inode *old_dir,
    935		struct dentry *old_dentry, struct inode *new_dir,
    936		struct dentry *new_dentry, unsigned int flags)
    937{
    938	int retval;
    939	struct inode *old_inode;
    940	struct inode *new_inode;
    941	struct v9fs_session_info *v9ses;
    942	struct p9_fid *oldfid, *dfid;
    943	struct p9_fid *olddirfid;
    944	struct p9_fid *newdirfid;
    945	struct p9_wstat wstat;
    946
    947	if (flags)
    948		return -EINVAL;
    949
    950	p9_debug(P9_DEBUG_VFS, "\n");
    951	retval = 0;
    952	old_inode = d_inode(old_dentry);
    953	new_inode = d_inode(new_dentry);
    954	v9ses = v9fs_inode2v9ses(old_inode);
    955	oldfid = v9fs_fid_lookup(old_dentry);
    956	if (IS_ERR(oldfid))
    957		return PTR_ERR(oldfid);
    958
    959	dfid = v9fs_parent_fid(old_dentry);
    960	olddirfid = clone_fid(dfid);
    961	if (dfid && !IS_ERR(dfid))
    962		p9_client_clunk(dfid);
    963
    964	if (IS_ERR(olddirfid)) {
    965		retval = PTR_ERR(olddirfid);
    966		goto done;
    967	}
    968
    969	dfid = v9fs_parent_fid(new_dentry);
    970	newdirfid = clone_fid(dfid);
    971	p9_client_clunk(dfid);
    972
    973	if (IS_ERR(newdirfid)) {
    974		retval = PTR_ERR(newdirfid);
    975		goto clunk_olddir;
    976	}
    977
    978	down_write(&v9ses->rename_sem);
    979	if (v9fs_proto_dotl(v9ses)) {
    980		retval = p9_client_renameat(olddirfid, old_dentry->d_name.name,
    981					    newdirfid, new_dentry->d_name.name);
    982		if (retval == -EOPNOTSUPP)
    983			retval = p9_client_rename(oldfid, newdirfid,
    984						  new_dentry->d_name.name);
    985		if (retval != -EOPNOTSUPP)
    986			goto clunk_newdir;
    987	}
    988	if (old_dentry->d_parent != new_dentry->d_parent) {
    989		/*
    990		 * 9P .u can only handle file rename in the same directory
    991		 */
    992
    993		p9_debug(P9_DEBUG_ERROR, "old dir and new dir are different\n");
    994		retval = -EXDEV;
    995		goto clunk_newdir;
    996	}
    997	v9fs_blank_wstat(&wstat);
    998	wstat.muid = v9ses->uname;
    999	wstat.name = new_dentry->d_name.name;
   1000	retval = p9_client_wstat(oldfid, &wstat);
   1001
   1002clunk_newdir:
   1003	if (!retval) {
   1004		if (new_inode) {
   1005			if (S_ISDIR(new_inode->i_mode))
   1006				clear_nlink(new_inode);
   1007			else
   1008				v9fs_dec_count(new_inode);
   1009		}
   1010		if (S_ISDIR(old_inode->i_mode)) {
   1011			if (!new_inode)
   1012				inc_nlink(new_dir);
   1013			v9fs_dec_count(old_dir);
   1014		}
   1015		v9fs_invalidate_inode_attr(old_inode);
   1016		v9fs_invalidate_inode_attr(old_dir);
   1017		v9fs_invalidate_inode_attr(new_dir);
   1018
   1019		/* successful rename */
   1020		d_move(old_dentry, new_dentry);
   1021	}
   1022	up_write(&v9ses->rename_sem);
   1023	p9_client_clunk(newdirfid);
   1024
   1025clunk_olddir:
   1026	p9_client_clunk(olddirfid);
   1027
   1028done:
   1029	p9_client_clunk(oldfid);
   1030	return retval;
   1031}
   1032
   1033/**
   1034 * v9fs_vfs_getattr - retrieve file metadata
   1035 * @mnt_userns: The user namespace of the mount
   1036 * @path: Object to query
   1037 * @stat: metadata structure to populate
   1038 * @request_mask: Mask of STATX_xxx flags indicating the caller's interests
   1039 * @flags: AT_STATX_xxx setting
   1040 *
   1041 */
   1042
   1043static int
   1044v9fs_vfs_getattr(struct user_namespace *mnt_userns, const struct path *path,
   1045		 struct kstat *stat, u32 request_mask, unsigned int flags)
   1046{
   1047	struct dentry *dentry = path->dentry;
   1048	struct v9fs_session_info *v9ses;
   1049	struct p9_fid *fid;
   1050	struct p9_wstat *st;
   1051
   1052	p9_debug(P9_DEBUG_VFS, "dentry: %p\n", dentry);
   1053	v9ses = v9fs_dentry2v9ses(dentry);
   1054	if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
   1055		generic_fillattr(&init_user_ns, d_inode(dentry), stat);
   1056		return 0;
   1057	}
   1058	fid = v9fs_fid_lookup(dentry);
   1059	if (IS_ERR(fid))
   1060		return PTR_ERR(fid);
   1061
   1062	st = p9_client_stat(fid);
   1063	p9_client_clunk(fid);
   1064	if (IS_ERR(st))
   1065		return PTR_ERR(st);
   1066
   1067	v9fs_stat2inode(st, d_inode(dentry), dentry->d_sb, 0);
   1068	generic_fillattr(&init_user_ns, d_inode(dentry), stat);
   1069
   1070	p9stat_free(st);
   1071	kfree(st);
   1072	return 0;
   1073}
   1074
   1075/**
   1076 * v9fs_vfs_setattr - set file metadata
   1077 * @mnt_userns: The user namespace of the mount
   1078 * @dentry: file whose metadata to set
   1079 * @iattr: metadata assignment structure
   1080 *
   1081 */
   1082
   1083static int v9fs_vfs_setattr(struct user_namespace *mnt_userns,
   1084			    struct dentry *dentry, struct iattr *iattr)
   1085{
   1086	int retval, use_dentry = 0;
   1087	struct inode *inode = d_inode(dentry);
   1088	struct v9fs_inode *v9inode = V9FS_I(inode);
   1089	struct v9fs_session_info *v9ses;
   1090	struct p9_fid *fid = NULL;
   1091	struct p9_wstat wstat;
   1092
   1093	p9_debug(P9_DEBUG_VFS, "\n");
   1094	retval = setattr_prepare(&init_user_ns, dentry, iattr);
   1095	if (retval)
   1096		return retval;
   1097
   1098	retval = -EPERM;
   1099	v9ses = v9fs_dentry2v9ses(dentry);
   1100	if (iattr->ia_valid & ATTR_FILE) {
   1101		fid = iattr->ia_file->private_data;
   1102		WARN_ON(!fid);
   1103	}
   1104	if (!fid) {
   1105		fid = v9fs_fid_lookup(dentry);
   1106		use_dentry = 1;
   1107	}
   1108	if (IS_ERR(fid))
   1109		return PTR_ERR(fid);
   1110
   1111	v9fs_blank_wstat(&wstat);
   1112	if (iattr->ia_valid & ATTR_MODE)
   1113		wstat.mode = unixmode2p9mode(v9ses, iattr->ia_mode);
   1114
   1115	if (iattr->ia_valid & ATTR_MTIME)
   1116		wstat.mtime = iattr->ia_mtime.tv_sec;
   1117
   1118	if (iattr->ia_valid & ATTR_ATIME)
   1119		wstat.atime = iattr->ia_atime.tv_sec;
   1120
   1121	if (iattr->ia_valid & ATTR_SIZE)
   1122		wstat.length = iattr->ia_size;
   1123
   1124	if (v9fs_proto_dotu(v9ses)) {
   1125		if (iattr->ia_valid & ATTR_UID)
   1126			wstat.n_uid = iattr->ia_uid;
   1127
   1128		if (iattr->ia_valid & ATTR_GID)
   1129			wstat.n_gid = iattr->ia_gid;
   1130	}
   1131
   1132	/* Write all dirty data */
   1133	if (d_is_reg(dentry))
   1134		filemap_write_and_wait(inode->i_mapping);
   1135
   1136	retval = p9_client_wstat(fid, &wstat);
   1137
   1138	if (use_dentry)
   1139		p9_client_clunk(fid);
   1140
   1141	if (retval < 0)
   1142		return retval;
   1143
   1144	if ((iattr->ia_valid & ATTR_SIZE) &&
   1145	    iattr->ia_size != i_size_read(inode)) {
   1146		truncate_setsize(inode, iattr->ia_size);
   1147		fscache_resize_cookie(v9fs_inode_cookie(v9inode), iattr->ia_size);
   1148	}
   1149
   1150	v9fs_invalidate_inode_attr(inode);
   1151
   1152	setattr_copy(&init_user_ns, inode, iattr);
   1153	mark_inode_dirty(inode);
   1154	return 0;
   1155}
   1156
   1157/**
   1158 * v9fs_stat2inode - populate an inode structure with mistat info
   1159 * @stat: Plan 9 metadata (mistat) structure
   1160 * @inode: inode to populate
   1161 * @sb: superblock of filesystem
   1162 * @flags: control flags (e.g. V9FS_STAT2INODE_KEEP_ISIZE)
   1163 *
   1164 */
   1165
   1166void
   1167v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode,
   1168		 struct super_block *sb, unsigned int flags)
   1169{
   1170	umode_t mode;
   1171	struct v9fs_session_info *v9ses = sb->s_fs_info;
   1172	struct v9fs_inode *v9inode = V9FS_I(inode);
   1173
   1174	set_nlink(inode, 1);
   1175
   1176	inode->i_atime.tv_sec = stat->atime;
   1177	inode->i_mtime.tv_sec = stat->mtime;
   1178	inode->i_ctime.tv_sec = stat->mtime;
   1179
   1180	inode->i_uid = v9ses->dfltuid;
   1181	inode->i_gid = v9ses->dfltgid;
   1182
   1183	if (v9fs_proto_dotu(v9ses)) {
   1184		inode->i_uid = stat->n_uid;
   1185		inode->i_gid = stat->n_gid;
   1186	}
   1187	if ((S_ISREG(inode->i_mode)) || (S_ISDIR(inode->i_mode))) {
   1188		if (v9fs_proto_dotu(v9ses)) {
   1189			unsigned int i_nlink;
   1190			/*
   1191			 * Hadlink support got added later to the .u extension.
   1192			 * So there can be a server out there that doesn't
   1193			 * support this even with .u extension. That would
   1194			 * just leave us with stat->extension being an empty
   1195			 * string, though.
   1196			 */
   1197			/* HARDLINKCOUNT %u */
   1198			if (sscanf(stat->extension,
   1199				   " HARDLINKCOUNT %u", &i_nlink) == 1)
   1200				set_nlink(inode, i_nlink);
   1201		}
   1202	}
   1203	mode = p9mode2perm(v9ses, stat);
   1204	mode |= inode->i_mode & ~S_IALLUGO;
   1205	inode->i_mode = mode;
   1206
   1207	if (!(flags & V9FS_STAT2INODE_KEEP_ISIZE))
   1208		v9fs_i_size_write(inode, stat->length);
   1209	/* not real number of blocks, but 512 byte ones ... */
   1210	inode->i_blocks = (stat->length + 512 - 1) >> 9;
   1211	v9inode->cache_validity &= ~V9FS_INO_INVALID_ATTR;
   1212}
   1213
   1214/**
   1215 * v9fs_qid2ino - convert qid into inode number
   1216 * @qid: qid to hash
   1217 *
   1218 * BUG: potential for inode number collisions?
   1219 */
   1220
   1221ino_t v9fs_qid2ino(struct p9_qid *qid)
   1222{
   1223	u64 path = qid->path + 2;
   1224	ino_t i = 0;
   1225
   1226	if (sizeof(ino_t) == sizeof(path))
   1227		memcpy(&i, &path, sizeof(ino_t));
   1228	else
   1229		i = (ino_t) (path ^ (path >> 32));
   1230
   1231	return i;
   1232}
   1233
   1234/**
   1235 * v9fs_vfs_get_link - follow a symlink path
   1236 * @dentry: dentry for symlink
   1237 * @inode: inode for symlink
   1238 * @done: delayed call for when we are done with the return value
   1239 */
   1240
   1241static const char *v9fs_vfs_get_link(struct dentry *dentry,
   1242				     struct inode *inode,
   1243				     struct delayed_call *done)
   1244{
   1245	struct v9fs_session_info *v9ses;
   1246	struct p9_fid *fid;
   1247	struct p9_wstat *st;
   1248	char *res;
   1249
   1250	if (!dentry)
   1251		return ERR_PTR(-ECHILD);
   1252
   1253	v9ses = v9fs_dentry2v9ses(dentry);
   1254	if (!v9fs_proto_dotu(v9ses))
   1255		return ERR_PTR(-EBADF);
   1256
   1257	p9_debug(P9_DEBUG_VFS, "%pd\n", dentry);
   1258	fid = v9fs_fid_lookup(dentry);
   1259
   1260	if (IS_ERR(fid))
   1261		return ERR_CAST(fid);
   1262
   1263	st = p9_client_stat(fid);
   1264	p9_client_clunk(fid);
   1265	if (IS_ERR(st))
   1266		return ERR_CAST(st);
   1267
   1268	if (!(st->mode & P9_DMSYMLINK)) {
   1269		p9stat_free(st);
   1270		kfree(st);
   1271		return ERR_PTR(-EINVAL);
   1272	}
   1273	res = st->extension;
   1274	st->extension = NULL;
   1275	if (strlen(res) >= PATH_MAX)
   1276		res[PATH_MAX - 1] = '\0';
   1277
   1278	p9stat_free(st);
   1279	kfree(st);
   1280	set_delayed_call(done, kfree_link, res);
   1281	return res;
   1282}
   1283
   1284/**
   1285 * v9fs_vfs_mkspecial - create a special file
   1286 * @dir: inode to create special file in
   1287 * @dentry: dentry to create
   1288 * @perm: mode to create special file
   1289 * @extension: 9p2000.u format extension string representing special file
   1290 *
   1291 */
   1292
   1293static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
   1294	u32 perm, const char *extension)
   1295{
   1296	struct p9_fid *fid;
   1297	struct v9fs_session_info *v9ses;
   1298
   1299	v9ses = v9fs_inode2v9ses(dir);
   1300	if (!v9fs_proto_dotu(v9ses)) {
   1301		p9_debug(P9_DEBUG_ERROR, "not extended\n");
   1302		return -EPERM;
   1303	}
   1304
   1305	fid = v9fs_create(v9ses, dir, dentry, (char *) extension, perm,
   1306								P9_OREAD);
   1307	if (IS_ERR(fid))
   1308		return PTR_ERR(fid);
   1309
   1310	v9fs_invalidate_inode_attr(dir);
   1311	p9_client_clunk(fid);
   1312	return 0;
   1313}
   1314
   1315/**
   1316 * v9fs_vfs_symlink - helper function to create symlinks
   1317 * @mnt_userns: The user namespace of the mount
   1318 * @dir: directory inode containing symlink
   1319 * @dentry: dentry for symlink
   1320 * @symname: symlink data
   1321 *
   1322 * See Also: 9P2000.u RFC for more information
   1323 *
   1324 */
   1325
   1326static int
   1327v9fs_vfs_symlink(struct user_namespace *mnt_userns, struct inode *dir,
   1328		 struct dentry *dentry, const char *symname)
   1329{
   1330	p9_debug(P9_DEBUG_VFS, " %lu,%pd,%s\n",
   1331		 dir->i_ino, dentry, symname);
   1332
   1333	return v9fs_vfs_mkspecial(dir, dentry, P9_DMSYMLINK, symname);
   1334}
   1335
   1336#define U32_MAX_DIGITS 10
   1337
   1338/**
   1339 * v9fs_vfs_link - create a hardlink
   1340 * @old_dentry: dentry for file to link to
   1341 * @dir: inode destination for new link
   1342 * @dentry: dentry for link
   1343 *
   1344 */
   1345
   1346static int
   1347v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
   1348	      struct dentry *dentry)
   1349{
   1350	int retval;
   1351	char name[1 + U32_MAX_DIGITS + 2]; /* sign + number + \n + \0 */
   1352	struct p9_fid *oldfid;
   1353
   1354	p9_debug(P9_DEBUG_VFS, " %lu,%pd,%pd\n",
   1355		 dir->i_ino, dentry, old_dentry);
   1356
   1357	oldfid = v9fs_fid_clone(old_dentry);
   1358	if (IS_ERR(oldfid))
   1359		return PTR_ERR(oldfid);
   1360
   1361	sprintf(name, "%d\n", oldfid->fid);
   1362	retval = v9fs_vfs_mkspecial(dir, dentry, P9_DMLINK, name);
   1363	if (!retval) {
   1364		v9fs_refresh_inode(oldfid, d_inode(old_dentry));
   1365		v9fs_invalidate_inode_attr(dir);
   1366	}
   1367	p9_client_clunk(oldfid);
   1368	return retval;
   1369}
   1370
   1371/**
   1372 * v9fs_vfs_mknod - create a special file
   1373 * @mnt_userns: The user namespace of the mount
   1374 * @dir: inode destination for new link
   1375 * @dentry: dentry for file
   1376 * @mode: mode for creation
   1377 * @rdev: device associated with special file
   1378 *
   1379 */
   1380
   1381static int
   1382v9fs_vfs_mknod(struct user_namespace *mnt_userns, struct inode *dir,
   1383	       struct dentry *dentry, umode_t mode, dev_t rdev)
   1384{
   1385	struct v9fs_session_info *v9ses = v9fs_inode2v9ses(dir);
   1386	int retval;
   1387	char name[2 + U32_MAX_DIGITS + 1 + U32_MAX_DIGITS + 1];
   1388	u32 perm;
   1389
   1390	p9_debug(P9_DEBUG_VFS, " %lu,%pd mode: %x MAJOR: %u MINOR: %u\n",
   1391		 dir->i_ino, dentry, mode,
   1392		 MAJOR(rdev), MINOR(rdev));
   1393
   1394	/* build extension */
   1395	if (S_ISBLK(mode))
   1396		sprintf(name, "b %u %u", MAJOR(rdev), MINOR(rdev));
   1397	else if (S_ISCHR(mode))
   1398		sprintf(name, "c %u %u", MAJOR(rdev), MINOR(rdev));
   1399	else
   1400		*name = 0;
   1401
   1402	perm = unixmode2p9mode(v9ses, mode);
   1403	retval = v9fs_vfs_mkspecial(dir, dentry, perm, name);
   1404
   1405	return retval;
   1406}
   1407
   1408int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode)
   1409{
   1410	int umode;
   1411	dev_t rdev;
   1412	struct p9_wstat *st;
   1413	struct v9fs_session_info *v9ses;
   1414	unsigned int flags;
   1415
   1416	v9ses = v9fs_inode2v9ses(inode);
   1417	st = p9_client_stat(fid);
   1418	if (IS_ERR(st))
   1419		return PTR_ERR(st);
   1420	/*
   1421	 * Don't update inode if the file type is different
   1422	 */
   1423	umode = p9mode2unixmode(v9ses, st, &rdev);
   1424	if (inode_wrong_type(inode, umode))
   1425		goto out;
   1426
   1427	/*
   1428	 * We don't want to refresh inode->i_size,
   1429	 * because we may have cached data
   1430	 */
   1431	flags = (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) ?
   1432		V9FS_STAT2INODE_KEEP_ISIZE : 0;
   1433	v9fs_stat2inode(st, inode, inode->i_sb, flags);
   1434out:
   1435	p9stat_free(st);
   1436	kfree(st);
   1437	return 0;
   1438}
   1439
   1440static const struct inode_operations v9fs_dir_inode_operations_dotu = {
   1441	.create = v9fs_vfs_create,
   1442	.lookup = v9fs_vfs_lookup,
   1443	.atomic_open = v9fs_vfs_atomic_open,
   1444	.symlink = v9fs_vfs_symlink,
   1445	.link = v9fs_vfs_link,
   1446	.unlink = v9fs_vfs_unlink,
   1447	.mkdir = v9fs_vfs_mkdir,
   1448	.rmdir = v9fs_vfs_rmdir,
   1449	.mknod = v9fs_vfs_mknod,
   1450	.rename = v9fs_vfs_rename,
   1451	.getattr = v9fs_vfs_getattr,
   1452	.setattr = v9fs_vfs_setattr,
   1453};
   1454
   1455static const struct inode_operations v9fs_dir_inode_operations = {
   1456	.create = v9fs_vfs_create,
   1457	.lookup = v9fs_vfs_lookup,
   1458	.atomic_open = v9fs_vfs_atomic_open,
   1459	.unlink = v9fs_vfs_unlink,
   1460	.mkdir = v9fs_vfs_mkdir,
   1461	.rmdir = v9fs_vfs_rmdir,
   1462	.mknod = v9fs_vfs_mknod,
   1463	.rename = v9fs_vfs_rename,
   1464	.getattr = v9fs_vfs_getattr,
   1465	.setattr = v9fs_vfs_setattr,
   1466};
   1467
   1468static const struct inode_operations v9fs_file_inode_operations = {
   1469	.getattr = v9fs_vfs_getattr,
   1470	.setattr = v9fs_vfs_setattr,
   1471};
   1472
   1473static const struct inode_operations v9fs_symlink_inode_operations = {
   1474	.get_link = v9fs_vfs_get_link,
   1475	.getattr = v9fs_vfs_getattr,
   1476	.setattr = v9fs_vfs_setattr,
   1477};
   1478