xref: /openbmc/linux/fs/fuse/dir.c (revision 5efd00e4)
1e5e5558eSMiklos Szeredi /*
2e5e5558eSMiklos Szeredi   FUSE: Filesystem in Userspace
31729a16cSMiklos Szeredi   Copyright (C) 2001-2008  Miklos Szeredi <miklos@szeredi.hu>
4e5e5558eSMiklos Szeredi 
5e5e5558eSMiklos Szeredi   This program can be distributed under the terms of the GNU GPL.
6e5e5558eSMiklos Szeredi   See the file COPYING.
7e5e5558eSMiklos Szeredi */
8e5e5558eSMiklos Szeredi 
9e5e5558eSMiklos Szeredi #include "fuse_i.h"
10e5e5558eSMiklos Szeredi 
11e5e5558eSMiklos Szeredi #include <linux/pagemap.h>
12e5e5558eSMiklos Szeredi #include <linux/file.h>
13bf109c64SMax Reitz #include <linux/fs_context.h>
14e5e5558eSMiklos Szeredi #include <linux/sched.h>
15e5e5558eSMiklos Szeredi #include <linux/namei.h>
1607e77dcaSMiklos Szeredi #include <linux/slab.h>
17703c7362SSeth Forshee #include <linux/xattr.h>
18261aaba7SMiklos Szeredi #include <linux/iversion.h>
1960bcc88aSSeth Forshee #include <linux/posix_acl.h>
203e2b6fdbSVivek Goyal #include <linux/security.h>
213e2b6fdbSVivek Goyal #include <linux/types.h>
223e2b6fdbSVivek Goyal #include <linux/kernel.h>
23e5e5558eSMiklos Szeredi 
244582a4abSFeng Shuo static void fuse_advise_use_readdirplus(struct inode *dir)
254582a4abSFeng Shuo {
264582a4abSFeng Shuo 	struct fuse_inode *fi = get_fuse_inode(dir);
274582a4abSFeng Shuo 
284582a4abSFeng Shuo 	set_bit(FUSE_I_ADVISE_RDPLUS, &fi->state);
294582a4abSFeng Shuo }
304582a4abSFeng Shuo 
3130c6a23dSKhazhismel Kumykov #if BITS_PER_LONG >= 64
3230c6a23dSKhazhismel Kumykov static inline void __fuse_dentry_settime(struct dentry *entry, u64 time)
3330c6a23dSKhazhismel Kumykov {
3430c6a23dSKhazhismel Kumykov 	entry->d_fsdata = (void *) time;
3530c6a23dSKhazhismel Kumykov }
3630c6a23dSKhazhismel Kumykov 
3730c6a23dSKhazhismel Kumykov static inline u64 fuse_dentry_time(const struct dentry *entry)
3830c6a23dSKhazhismel Kumykov {
3930c6a23dSKhazhismel Kumykov 	return (u64)entry->d_fsdata;
4030c6a23dSKhazhismel Kumykov }
4130c6a23dSKhazhismel Kumykov 
4230c6a23dSKhazhismel Kumykov #else
43f75fdf22SMiklos Szeredi union fuse_dentry {
44f75fdf22SMiklos Szeredi 	u64 time;
45f75fdf22SMiklos Szeredi 	struct rcu_head rcu;
46f75fdf22SMiklos Szeredi };
47f75fdf22SMiklos Szeredi 
4830c6a23dSKhazhismel Kumykov static inline void __fuse_dentry_settime(struct dentry *dentry, u64 time)
4930c6a23dSKhazhismel Kumykov {
5030c6a23dSKhazhismel Kumykov 	((union fuse_dentry *) dentry->d_fsdata)->time = time;
5130c6a23dSKhazhismel Kumykov }
5230c6a23dSKhazhismel Kumykov 
5330c6a23dSKhazhismel Kumykov static inline u64 fuse_dentry_time(const struct dentry *entry)
5430c6a23dSKhazhismel Kumykov {
5530c6a23dSKhazhismel Kumykov 	return ((union fuse_dentry *) entry->d_fsdata)->time;
5630c6a23dSKhazhismel Kumykov }
5730c6a23dSKhazhismel Kumykov #endif
5830c6a23dSKhazhismel Kumykov 
598fab0106SMiklos Szeredi static void fuse_dentry_settime(struct dentry *dentry, u64 time)
600a0898cfSMiklos Szeredi {
618fab0106SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn_super(dentry->d_sb);
628fab0106SMiklos Szeredi 	bool delete = !time && fc->delete_stale;
638fab0106SMiklos Szeredi 	/*
648fab0106SMiklos Szeredi 	 * Mess with DCACHE_OP_DELETE because dput() will be faster without it.
658fab0106SMiklos Szeredi 	 * Don't care about races, either way it's just an optimization
668fab0106SMiklos Szeredi 	 */
678fab0106SMiklos Szeredi 	if ((!delete && (dentry->d_flags & DCACHE_OP_DELETE)) ||
688fab0106SMiklos Szeredi 	    (delete && !(dentry->d_flags & DCACHE_OP_DELETE))) {
698fab0106SMiklos Szeredi 		spin_lock(&dentry->d_lock);
708fab0106SMiklos Szeredi 		if (!delete)
718fab0106SMiklos Szeredi 			dentry->d_flags &= ~DCACHE_OP_DELETE;
728fab0106SMiklos Szeredi 		else
738fab0106SMiklos Szeredi 			dentry->d_flags |= DCACHE_OP_DELETE;
748fab0106SMiklos Szeredi 		spin_unlock(&dentry->d_lock);
750a0898cfSMiklos Szeredi 	}
760a0898cfSMiklos Szeredi 
7730c6a23dSKhazhismel Kumykov 	__fuse_dentry_settime(dentry, time);
780a0898cfSMiklos Szeredi }
790a0898cfSMiklos Szeredi 
806f9f1180SMiklos Szeredi /*
816f9f1180SMiklos Szeredi  * FUSE caches dentries and attributes with separate timeout.  The
826f9f1180SMiklos Szeredi  * time in jiffies until the dentry/attributes are valid is stored in
83f75fdf22SMiklos Szeredi  * dentry->d_fsdata and fuse_inode->i_time respectively.
846f9f1180SMiklos Szeredi  */
856f9f1180SMiklos Szeredi 
866f9f1180SMiklos Szeredi /*
876f9f1180SMiklos Szeredi  * Calculate the time in jiffies until a dentry/attributes are valid
886f9f1180SMiklos Szeredi  */
89bcb6f6d2SMiklos Szeredi static u64 time_to_jiffies(u64 sec, u32 nsec)
90e5e5558eSMiklos Szeredi {
91685d16ddSMiklos Szeredi 	if (sec || nsec) {
92bcb6f6d2SMiklos Szeredi 		struct timespec64 ts = {
93bcb6f6d2SMiklos Szeredi 			sec,
9421067527SDavid Sheets 			min_t(u32, nsec, NSEC_PER_SEC - 1)
95bcb6f6d2SMiklos Szeredi 		};
96bcb6f6d2SMiklos Szeredi 
97bcb6f6d2SMiklos Szeredi 		return get_jiffies_64() + timespec64_to_jiffies(&ts);
98685d16ddSMiklos Szeredi 	} else
990a0898cfSMiklos Szeredi 		return 0;
100e5e5558eSMiklos Szeredi }
101e5e5558eSMiklos Szeredi 
1026f9f1180SMiklos Szeredi /*
1036f9f1180SMiklos Szeredi  * Set dentry and possibly attribute timeouts from the lookup/mk*
1046f9f1180SMiklos Szeredi  * replies
1056f9f1180SMiklos Szeredi  */
106d123d8e1SMiklos Szeredi void fuse_change_entry_timeout(struct dentry *entry, struct fuse_entry_out *o)
1070aa7c699SMiklos Szeredi {
1080a0898cfSMiklos Szeredi 	fuse_dentry_settime(entry,
1090a0898cfSMiklos Szeredi 		time_to_jiffies(o->entry_valid, o->entry_valid_nsec));
1101fb69e78SMiklos Szeredi }
1111fb69e78SMiklos Szeredi 
1121fb69e78SMiklos Szeredi static u64 attr_timeout(struct fuse_attr_out *o)
1131fb69e78SMiklos Szeredi {
1141fb69e78SMiklos Szeredi 	return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
1151fb69e78SMiklos Szeredi }
1161fb69e78SMiklos Szeredi 
117d123d8e1SMiklos Szeredi u64 entry_attr_timeout(struct fuse_entry_out *o)
1181fb69e78SMiklos Szeredi {
1191fb69e78SMiklos Szeredi 	return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
1208cbdf1e6SMiklos Szeredi }
1218cbdf1e6SMiklos Szeredi 
122fa5eee57SMiklos Szeredi void fuse_invalidate_attr_mask(struct inode *inode, u32 mask)
1232f1e8196SMiklos Szeredi {
1242f1e8196SMiklos Szeredi 	set_mask_bits(&get_fuse_inode(inode)->inval_mask, 0, mask);
1252f1e8196SMiklos Szeredi }
1262f1e8196SMiklos Szeredi 
1276f9f1180SMiklos Szeredi /*
1286f9f1180SMiklos Szeredi  * Mark the attributes as stale, so that at the next call to
1296f9f1180SMiklos Szeredi  * ->getattr() they will be fetched from userspace
1306f9f1180SMiklos Szeredi  */
1318cbdf1e6SMiklos Szeredi void fuse_invalidate_attr(struct inode *inode)
1328cbdf1e6SMiklos Szeredi {
1332f1e8196SMiklos Szeredi 	fuse_invalidate_attr_mask(inode, STATX_BASIC_STATS);
1348cbdf1e6SMiklos Szeredi }
1358cbdf1e6SMiklos Szeredi 
136261aaba7SMiklos Szeredi static void fuse_dir_changed(struct inode *dir)
137261aaba7SMiklos Szeredi {
138261aaba7SMiklos Szeredi 	fuse_invalidate_attr(dir);
139261aaba7SMiklos Szeredi 	inode_maybe_inc_iversion(dir, false);
140261aaba7SMiklos Szeredi }
141261aaba7SMiklos Szeredi 
142451418fcSAndrew Gallagher /**
143451418fcSAndrew Gallagher  * Mark the attributes as stale due to an atime change.  Avoid the invalidate if
144451418fcSAndrew Gallagher  * atime is not used.
145451418fcSAndrew Gallagher  */
146451418fcSAndrew Gallagher void fuse_invalidate_atime(struct inode *inode)
147451418fcSAndrew Gallagher {
148451418fcSAndrew Gallagher 	if (!IS_RDONLY(inode))
1492f1e8196SMiklos Szeredi 		fuse_invalidate_attr_mask(inode, STATX_ATIME);
150451418fcSAndrew Gallagher }
151451418fcSAndrew Gallagher 
1526f9f1180SMiklos Szeredi /*
1536f9f1180SMiklos Szeredi  * Just mark the entry as stale, so that a next attempt to look it up
1546f9f1180SMiklos Szeredi  * will result in a new lookup call to userspace
1556f9f1180SMiklos Szeredi  *
1566f9f1180SMiklos Szeredi  * This is called when a dentry is about to become negative and the
1576f9f1180SMiklos Szeredi  * timeout is unknown (unlink, rmdir, rename and in some cases
1586f9f1180SMiklos Szeredi  * lookup)
1596f9f1180SMiklos Szeredi  */
160dbd561d2SMiklos Szeredi void fuse_invalidate_entry_cache(struct dentry *entry)
1618cbdf1e6SMiklos Szeredi {
1620a0898cfSMiklos Szeredi 	fuse_dentry_settime(entry, 0);
1638cbdf1e6SMiklos Szeredi }
1648cbdf1e6SMiklos Szeredi 
1656f9f1180SMiklos Szeredi /*
1666f9f1180SMiklos Szeredi  * Same as fuse_invalidate_entry_cache(), but also try to remove the
1676f9f1180SMiklos Szeredi  * dentry from the hash
1686f9f1180SMiklos Szeredi  */
1698cbdf1e6SMiklos Szeredi static void fuse_invalidate_entry(struct dentry *entry)
1708cbdf1e6SMiklos Szeredi {
1718cbdf1e6SMiklos Szeredi 	d_invalidate(entry);
1728cbdf1e6SMiklos Szeredi 	fuse_invalidate_entry_cache(entry);
1730aa7c699SMiklos Szeredi }
1740aa7c699SMiklos Szeredi 
1757078187aSMiklos Szeredi static void fuse_lookup_init(struct fuse_conn *fc, struct fuse_args *args,
17613983d06SAl Viro 			     u64 nodeid, const struct qstr *name,
177e5e5558eSMiklos Szeredi 			     struct fuse_entry_out *outarg)
178e5e5558eSMiklos Szeredi {
1790e9663eeSMiklos Szeredi 	memset(outarg, 0, sizeof(struct fuse_entry_out));
180d5b48543SMiklos Szeredi 	args->opcode = FUSE_LOOKUP;
181d5b48543SMiklos Szeredi 	args->nodeid = nodeid;
182d5b48543SMiklos Szeredi 	args->in_numargs = 1;
183d5b48543SMiklos Szeredi 	args->in_args[0].size = name->len + 1;
184d5b48543SMiklos Szeredi 	args->in_args[0].value = name->name;
185d5b48543SMiklos Szeredi 	args->out_numargs = 1;
186d5b48543SMiklos Szeredi 	args->out_args[0].size = sizeof(struct fuse_entry_out);
187d5b48543SMiklos Szeredi 	args->out_args[0].value = outarg;
188e5e5558eSMiklos Szeredi }
189e5e5558eSMiklos Szeredi 
1906f9f1180SMiklos Szeredi /*
1916f9f1180SMiklos Szeredi  * Check whether the dentry is still valid
1926f9f1180SMiklos Szeredi  *
1936f9f1180SMiklos Szeredi  * If the entry validity timeout has expired and the dentry is
1946f9f1180SMiklos Szeredi  * positive, try to redo the lookup.  If the lookup results in a
1956f9f1180SMiklos Szeredi  * different inode, then let the VFS invalidate the dentry and redo
1966f9f1180SMiklos Szeredi  * the lookup once more.  If the lookup results in the same inode,
1976f9f1180SMiklos Szeredi  * then refresh the attributes, timeouts and mark the dentry valid.
1986f9f1180SMiklos Szeredi  */
1990b728e19SAl Viro static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
200e5e5558eSMiklos Szeredi {
20134286d66SNick Piggin 	struct inode *inode;
20228420dadSMiklos Szeredi 	struct dentry *parent;
203fcee216bSMax Reitz 	struct fuse_mount *fm;
2046314efeeSMiklos Szeredi 	struct fuse_inode *fi;
205e2a6b952SMiklos Szeredi 	int ret;
2068cbdf1e6SMiklos Szeredi 
2072b0143b5SDavid Howells 	inode = d_inode_rcu(entry);
2085d069dbeSMiklos Szeredi 	if (inode && fuse_is_bad(inode))
209e2a6b952SMiklos Szeredi 		goto invalid;
210154210ccSAnand Avati 	else if (time_before64(fuse_dentry_time(entry), get_jiffies_64()) ||
211df8629afSMiklos Szeredi 		 (flags & (LOOKUP_EXCL | LOOKUP_REVAL))) {
212e5e5558eSMiklos Szeredi 		struct fuse_entry_out outarg;
2137078187aSMiklos Szeredi 		FUSE_ARGS(args);
21407e77dcaSMiklos Szeredi 		struct fuse_forget_link *forget;
2151fb69e78SMiklos Szeredi 		u64 attr_version;
2168cbdf1e6SMiklos Szeredi 
21750322fe7SMiklos Szeredi 		/* For negative dentries, always do a fresh lookup */
2188cbdf1e6SMiklos Szeredi 		if (!inode)
219e2a6b952SMiklos Szeredi 			goto invalid;
2208cbdf1e6SMiklos Szeredi 
221e2a6b952SMiklos Szeredi 		ret = -ECHILD;
2220b728e19SAl Viro 		if (flags & LOOKUP_RCU)
223e2a6b952SMiklos Szeredi 			goto out;
224e7c0a167SMiklos Szeredi 
225fcee216bSMax Reitz 		fm = get_fuse_mount(inode);
226e5e5558eSMiklos Szeredi 
22707e77dcaSMiklos Szeredi 		forget = fuse_alloc_forget();
228e2a6b952SMiklos Szeredi 		ret = -ENOMEM;
2297078187aSMiklos Szeredi 		if (!forget)
230e2a6b952SMiklos Szeredi 			goto out;
2312d51013eSMiklos Szeredi 
232fcee216bSMax Reitz 		attr_version = fuse_get_attr_version(fm->fc);
2331fb69e78SMiklos Szeredi 
234e956edd0SMiklos Szeredi 		parent = dget_parent(entry);
235fcee216bSMax Reitz 		fuse_lookup_init(fm->fc, &args, get_node_id(d_inode(parent)),
236c180eebeSMiklos Szeredi 				 &entry->d_name, &outarg);
237fcee216bSMax Reitz 		ret = fuse_simple_request(fm, &args);
238e956edd0SMiklos Szeredi 		dput(parent);
23950322fe7SMiklos Szeredi 		/* Zero nodeid is same as -ENOENT */
2407078187aSMiklos Szeredi 		if (!ret && !outarg.nodeid)
2417078187aSMiklos Szeredi 			ret = -ENOENT;
2427078187aSMiklos Szeredi 		if (!ret) {
2436314efeeSMiklos Szeredi 			fi = get_fuse_inode(inode);
244bf109c64SMax Reitz 			if (outarg.nodeid != get_node_id(inode) ||
245bf109c64SMax Reitz 			    (bool) IS_AUTOMOUNT(inode) != (bool) (outarg.attr.flags & FUSE_ATTR_SUBMOUNT)) {
246fcee216bSMax Reitz 				fuse_queue_forget(fm->fc, forget,
247fcee216bSMax Reitz 						  outarg.nodeid, 1);
248e2a6b952SMiklos Szeredi 				goto invalid;
2499e6268dbSMiklos Szeredi 			}
250c9d8f5f0SKirill Tkhai 			spin_lock(&fi->lock);
2519e6268dbSMiklos Szeredi 			fi->nlookup++;
252c9d8f5f0SKirill Tkhai 			spin_unlock(&fi->lock);
2539e6268dbSMiklos Szeredi 		}
25407e77dcaSMiklos Szeredi 		kfree(forget);
2557078187aSMiklos Szeredi 		if (ret == -ENOMEM)
2567078187aSMiklos Szeredi 			goto out;
257eb59bd17SMiklos Szeredi 		if (ret || fuse_invalid_attr(&outarg.attr) ||
25815db1683SAmir Goldstein 		    fuse_stale_inode(inode, outarg.generation, &outarg.attr))
259e2a6b952SMiklos Szeredi 			goto invalid;
260e5e5558eSMiklos Szeredi 
26160bcc88aSSeth Forshee 		forget_all_cached_acls(inode);
2621fb69e78SMiklos Szeredi 		fuse_change_attributes(inode, &outarg.attr,
2631fb69e78SMiklos Szeredi 				       entry_attr_timeout(&outarg),
2641fb69e78SMiklos Szeredi 				       attr_version);
2651fb69e78SMiklos Szeredi 		fuse_change_entry_timeout(entry, &outarg);
26628420dadSMiklos Szeredi 	} else if (inode) {
2676314efeeSMiklos Szeredi 		fi = get_fuse_inode(inode);
2686314efeeSMiklos Szeredi 		if (flags & LOOKUP_RCU) {
2696314efeeSMiklos Szeredi 			if (test_bit(FUSE_I_INIT_RDPLUS, &fi->state))
2706314efeeSMiklos Szeredi 				return -ECHILD;
2716314efeeSMiklos Szeredi 		} else if (test_and_clear_bit(FUSE_I_INIT_RDPLUS, &fi->state)) {
27228420dadSMiklos Szeredi 			parent = dget_parent(entry);
2732b0143b5SDavid Howells 			fuse_advise_use_readdirplus(d_inode(parent));
27428420dadSMiklos Szeredi 			dput(parent);
275e5e5558eSMiklos Szeredi 		}
27628420dadSMiklos Szeredi 	}
277e2a6b952SMiklos Szeredi 	ret = 1;
278e2a6b952SMiklos Szeredi out:
279e2a6b952SMiklos Szeredi 	return ret;
280e2a6b952SMiklos Szeredi 
281e2a6b952SMiklos Szeredi invalid:
282e2a6b952SMiklos Szeredi 	ret = 0;
283e2a6b952SMiklos Szeredi 	goto out;
284e5e5558eSMiklos Szeredi }
285e5e5558eSMiklos Szeredi 
28630c6a23dSKhazhismel Kumykov #if BITS_PER_LONG < 64
287f75fdf22SMiklos Szeredi static int fuse_dentry_init(struct dentry *dentry)
288f75fdf22SMiklos Szeredi {
289dc69e98cSKhazhismel Kumykov 	dentry->d_fsdata = kzalloc(sizeof(union fuse_dentry),
290dc69e98cSKhazhismel Kumykov 				   GFP_KERNEL_ACCOUNT | __GFP_RECLAIMABLE);
291f75fdf22SMiklos Szeredi 
292f75fdf22SMiklos Szeredi 	return dentry->d_fsdata ? 0 : -ENOMEM;
293f75fdf22SMiklos Szeredi }
294f75fdf22SMiklos Szeredi static void fuse_dentry_release(struct dentry *dentry)
295f75fdf22SMiklos Szeredi {
296f75fdf22SMiklos Szeredi 	union fuse_dentry *fd = dentry->d_fsdata;
297f75fdf22SMiklos Szeredi 
298f75fdf22SMiklos Szeredi 	kfree_rcu(fd, rcu);
299f75fdf22SMiklos Szeredi }
30030c6a23dSKhazhismel Kumykov #endif
301f75fdf22SMiklos Szeredi 
3028fab0106SMiklos Szeredi static int fuse_dentry_delete(const struct dentry *dentry)
3038fab0106SMiklos Szeredi {
3048fab0106SMiklos Szeredi 	return time_before64(fuse_dentry_time(dentry), get_jiffies_64());
3058fab0106SMiklos Szeredi }
3068fab0106SMiklos Szeredi 
307bf109c64SMax Reitz /*
308bf109c64SMax Reitz  * Create a fuse_mount object with a new superblock (with path->dentry
309bf109c64SMax Reitz  * as the root), and return that mount so it can be auto-mounted on
310bf109c64SMax Reitz  * @path.
311bf109c64SMax Reitz  */
312bf109c64SMax Reitz static struct vfsmount *fuse_dentry_automount(struct path *path)
313bf109c64SMax Reitz {
314bf109c64SMax Reitz 	struct fs_context *fsc;
315bf109c64SMax Reitz 	struct vfsmount *mnt;
316bf109c64SMax Reitz 	struct fuse_inode *mp_fi = get_fuse_inode(d_inode(path->dentry));
317bf109c64SMax Reitz 
318bf109c64SMax Reitz 	fsc = fs_context_for_submount(path->mnt->mnt_sb->s_type, path->dentry);
31929e0e4dfSGreg Kurz 	if (IS_ERR(fsc))
32029e0e4dfSGreg Kurz 		return ERR_CAST(fsc);
321bf109c64SMax Reitz 
322266eb3f2SGreg Kurz 	/* Pass the FUSE inode of the mount for fuse_get_tree_submount() */
323266eb3f2SGreg Kurz 	fsc->fs_private = mp_fi;
324266eb3f2SGreg Kurz 
325bf109c64SMax Reitz 	/* Create the submount */
32629e0e4dfSGreg Kurz 	mnt = fc_mount(fsc);
32729e0e4dfSGreg Kurz 	if (!IS_ERR(mnt))
328bf109c64SMax Reitz 		mntget(mnt);
32929e0e4dfSGreg Kurz 
330bf109c64SMax Reitz 	put_fs_context(fsc);
331bf109c64SMax Reitz 	return mnt;
332bf109c64SMax Reitz }
333bf109c64SMax Reitz 
3344269590aSAl Viro const struct dentry_operations fuse_dentry_operations = {
335e5e5558eSMiklos Szeredi 	.d_revalidate	= fuse_dentry_revalidate,
3368fab0106SMiklos Szeredi 	.d_delete	= fuse_dentry_delete,
33730c6a23dSKhazhismel Kumykov #if BITS_PER_LONG < 64
338f75fdf22SMiklos Szeredi 	.d_init		= fuse_dentry_init,
339f75fdf22SMiklos Szeredi 	.d_release	= fuse_dentry_release,
34030c6a23dSKhazhismel Kumykov #endif
341bf109c64SMax Reitz 	.d_automount	= fuse_dentry_automount,
342e5e5558eSMiklos Szeredi };
343e5e5558eSMiklos Szeredi 
3440ce267ffSMiklos Szeredi const struct dentry_operations fuse_root_dentry_operations = {
34530c6a23dSKhazhismel Kumykov #if BITS_PER_LONG < 64
3460ce267ffSMiklos Szeredi 	.d_init		= fuse_dentry_init,
3470ce267ffSMiklos Szeredi 	.d_release	= fuse_dentry_release,
34830c6a23dSKhazhismel Kumykov #endif
3490ce267ffSMiklos Szeredi };
3500ce267ffSMiklos Szeredi 
351a5bfffacSTimo Savola int fuse_valid_type(int m)
35239ee059aSMiklos Szeredi {
35339ee059aSMiklos Szeredi 	return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) ||
35439ee059aSMiklos Szeredi 		S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
35539ee059aSMiklos Szeredi }
35639ee059aSMiklos Szeredi 
357eb59bd17SMiklos Szeredi bool fuse_invalid_attr(struct fuse_attr *attr)
358eb59bd17SMiklos Szeredi {
359eb59bd17SMiklos Szeredi 	return !fuse_valid_type(attr->mode) ||
360eb59bd17SMiklos Szeredi 		attr->size > LLONG_MAX;
361eb59bd17SMiklos Szeredi }
362eb59bd17SMiklos Szeredi 
36313983d06SAl Viro int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name,
364c180eebeSMiklos Szeredi 		     struct fuse_entry_out *outarg, struct inode **inode)
365c180eebeSMiklos Szeredi {
366fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount_super(sb);
3677078187aSMiklos Szeredi 	FUSE_ARGS(args);
36807e77dcaSMiklos Szeredi 	struct fuse_forget_link *forget;
369c180eebeSMiklos Szeredi 	u64 attr_version;
370c180eebeSMiklos Szeredi 	int err;
371c180eebeSMiklos Szeredi 
372c180eebeSMiklos Szeredi 	*inode = NULL;
373c180eebeSMiklos Szeredi 	err = -ENAMETOOLONG;
374c180eebeSMiklos Szeredi 	if (name->len > FUSE_NAME_MAX)
375c180eebeSMiklos Szeredi 		goto out;
376c180eebeSMiklos Szeredi 
377c180eebeSMiklos Szeredi 
37807e77dcaSMiklos Szeredi 	forget = fuse_alloc_forget();
37907e77dcaSMiklos Szeredi 	err = -ENOMEM;
3807078187aSMiklos Szeredi 	if (!forget)
381c180eebeSMiklos Szeredi 		goto out;
382c180eebeSMiklos Szeredi 
383fcee216bSMax Reitz 	attr_version = fuse_get_attr_version(fm->fc);
384c180eebeSMiklos Szeredi 
385fcee216bSMax Reitz 	fuse_lookup_init(fm->fc, &args, nodeid, name, outarg);
386fcee216bSMax Reitz 	err = fuse_simple_request(fm, &args);
387c180eebeSMiklos Szeredi 	/* Zero nodeid is same as -ENOENT, but with valid timeout */
388c180eebeSMiklos Szeredi 	if (err || !outarg->nodeid)
389c180eebeSMiklos Szeredi 		goto out_put_forget;
390c180eebeSMiklos Szeredi 
391c180eebeSMiklos Szeredi 	err = -EIO;
392c180eebeSMiklos Szeredi 	if (!outarg->nodeid)
393c180eebeSMiklos Szeredi 		goto out_put_forget;
394eb59bd17SMiklos Szeredi 	if (fuse_invalid_attr(&outarg->attr))
395c180eebeSMiklos Szeredi 		goto out_put_forget;
396c180eebeSMiklos Szeredi 
397c180eebeSMiklos Szeredi 	*inode = fuse_iget(sb, outarg->nodeid, outarg->generation,
398c180eebeSMiklos Szeredi 			   &outarg->attr, entry_attr_timeout(outarg),
399c180eebeSMiklos Szeredi 			   attr_version);
400c180eebeSMiklos Szeredi 	err = -ENOMEM;
401c180eebeSMiklos Szeredi 	if (!*inode) {
402fcee216bSMax Reitz 		fuse_queue_forget(fm->fc, forget, outarg->nodeid, 1);
403c180eebeSMiklos Szeredi 		goto out;
404c180eebeSMiklos Szeredi 	}
405c180eebeSMiklos Szeredi 	err = 0;
406c180eebeSMiklos Szeredi 
407c180eebeSMiklos Szeredi  out_put_forget:
40807e77dcaSMiklos Szeredi 	kfree(forget);
409c180eebeSMiklos Szeredi  out:
410c180eebeSMiklos Szeredi 	return err;
411c180eebeSMiklos Szeredi }
412c180eebeSMiklos Szeredi 
4130aa7c699SMiklos Szeredi static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
41400cd8dd3SAl Viro 				  unsigned int flags)
415e5e5558eSMiklos Szeredi {
416e5e5558eSMiklos Szeredi 	int err;
417e5e5558eSMiklos Szeredi 	struct fuse_entry_out outarg;
418c180eebeSMiklos Szeredi 	struct inode *inode;
4190de6256dSMiklos Szeredi 	struct dentry *newent;
420c180eebeSMiklos Szeredi 	bool outarg_valid = true;
42163576c13SMiklos Szeredi 	bool locked;
422e5e5558eSMiklos Szeredi 
4235d069dbeSMiklos Szeredi 	if (fuse_is_bad(dir))
4245d069dbeSMiklos Szeredi 		return ERR_PTR(-EIO);
4255d069dbeSMiklos Szeredi 
42663576c13SMiklos Szeredi 	locked = fuse_lock_inode(dir);
427c180eebeSMiklos Szeredi 	err = fuse_lookup_name(dir->i_sb, get_node_id(dir), &entry->d_name,
428c180eebeSMiklos Szeredi 			       &outarg, &inode);
42963576c13SMiklos Szeredi 	fuse_unlock_inode(dir, locked);
430c180eebeSMiklos Szeredi 	if (err == -ENOENT) {
431c180eebeSMiklos Szeredi 		outarg_valid = false;
432c180eebeSMiklos Szeredi 		err = 0;
4332d51013eSMiklos Szeredi 	}
434c180eebeSMiklos Szeredi 	if (err)
435c180eebeSMiklos Szeredi 		goto out_err;
4362d51013eSMiklos Szeredi 
437ee4e5271SMiklos Szeredi 	err = -EIO;
438c180eebeSMiklos Szeredi 	if (inode && get_node_id(inode) == FUSE_ROOT_ID)
439c180eebeSMiklos Szeredi 		goto out_iput;
440e5e5558eSMiklos Szeredi 
44141d28bcaSAl Viro 	newent = d_splice_alias(inode, entry);
442c180eebeSMiklos Szeredi 	err = PTR_ERR(newent);
443c180eebeSMiklos Szeredi 	if (IS_ERR(newent))
4445835f339SMiklos Szeredi 		goto out_err;
445d2a85164SMiklos Szeredi 
4460de6256dSMiklos Szeredi 	entry = newent ? newent : entry;
447c180eebeSMiklos Szeredi 	if (outarg_valid)
4481fb69e78SMiklos Szeredi 		fuse_change_entry_timeout(entry, &outarg);
4498cbdf1e6SMiklos Szeredi 	else
4508cbdf1e6SMiklos Szeredi 		fuse_invalidate_entry_cache(entry);
451c180eebeSMiklos Szeredi 
4526c26f717SMiklos Szeredi 	if (inode)
4534582a4abSFeng Shuo 		fuse_advise_use_readdirplus(dir);
4540de6256dSMiklos Szeredi 	return newent;
455c180eebeSMiklos Szeredi 
456c180eebeSMiklos Szeredi  out_iput:
457c180eebeSMiklos Szeredi 	iput(inode);
458c180eebeSMiklos Szeredi  out_err:
459c180eebeSMiklos Szeredi 	return ERR_PTR(err);
460e5e5558eSMiklos Szeredi }
461e5e5558eSMiklos Szeredi 
4623e2b6fdbSVivek Goyal static int get_security_context(struct dentry *entry, umode_t mode,
4633e2b6fdbSVivek Goyal 				void **security_ctx, u32 *security_ctxlen)
4643e2b6fdbSVivek Goyal {
4653e2b6fdbSVivek Goyal 	struct fuse_secctx *fctx;
4663e2b6fdbSVivek Goyal 	struct fuse_secctx_header *header;
4673e2b6fdbSVivek Goyal 	void *ctx = NULL, *ptr;
4683e2b6fdbSVivek Goyal 	u32 ctxlen, total_len = sizeof(*header);
4693e2b6fdbSVivek Goyal 	int err, nr_ctx = 0;
4703e2b6fdbSVivek Goyal 	const char *name;
4713e2b6fdbSVivek Goyal 	size_t namelen;
4723e2b6fdbSVivek Goyal 
4733e2b6fdbSVivek Goyal 	err = security_dentry_init_security(entry, mode, &entry->d_name,
4743e2b6fdbSVivek Goyal 					    &name, &ctx, &ctxlen);
4753e2b6fdbSVivek Goyal 	if (err) {
4763e2b6fdbSVivek Goyal 		if (err != -EOPNOTSUPP)
4773e2b6fdbSVivek Goyal 			goto out_err;
4783e2b6fdbSVivek Goyal 		/* No LSM is supporting this security hook. Ignore error */
4793e2b6fdbSVivek Goyal 		ctxlen = 0;
4803e2b6fdbSVivek Goyal 		ctx = NULL;
4813e2b6fdbSVivek Goyal 	}
4823e2b6fdbSVivek Goyal 
4833e2b6fdbSVivek Goyal 	if (ctxlen) {
4843e2b6fdbSVivek Goyal 		nr_ctx = 1;
4853e2b6fdbSVivek Goyal 		namelen = strlen(name) + 1;
4863e2b6fdbSVivek Goyal 		err = -EIO;
4873e2b6fdbSVivek Goyal 		if (WARN_ON(namelen > XATTR_NAME_MAX + 1 || ctxlen > S32_MAX))
4883e2b6fdbSVivek Goyal 			goto out_err;
4893e2b6fdbSVivek Goyal 		total_len += FUSE_REC_ALIGN(sizeof(*fctx) + namelen + ctxlen);
4903e2b6fdbSVivek Goyal 	}
4913e2b6fdbSVivek Goyal 
4923e2b6fdbSVivek Goyal 	err = -ENOMEM;
4933e2b6fdbSVivek Goyal 	header = ptr = kzalloc(total_len, GFP_KERNEL);
4943e2b6fdbSVivek Goyal 	if (!ptr)
4953e2b6fdbSVivek Goyal 		goto out_err;
4963e2b6fdbSVivek Goyal 
4973e2b6fdbSVivek Goyal 	header->nr_secctx = nr_ctx;
4983e2b6fdbSVivek Goyal 	header->size = total_len;
4993e2b6fdbSVivek Goyal 	ptr += sizeof(*header);
5003e2b6fdbSVivek Goyal 	if (nr_ctx) {
5013e2b6fdbSVivek Goyal 		fctx = ptr;
5023e2b6fdbSVivek Goyal 		fctx->size = ctxlen;
5033e2b6fdbSVivek Goyal 		ptr += sizeof(*fctx);
5043e2b6fdbSVivek Goyal 
5053e2b6fdbSVivek Goyal 		strcpy(ptr, name);
5063e2b6fdbSVivek Goyal 		ptr += namelen;
5073e2b6fdbSVivek Goyal 
5083e2b6fdbSVivek Goyal 		memcpy(ptr, ctx, ctxlen);
5093e2b6fdbSVivek Goyal 	}
5103e2b6fdbSVivek Goyal 	*security_ctxlen = total_len;
5113e2b6fdbSVivek Goyal 	*security_ctx = header;
5123e2b6fdbSVivek Goyal 	err = 0;
5133e2b6fdbSVivek Goyal out_err:
5143e2b6fdbSVivek Goyal 	kfree(ctx);
5153e2b6fdbSVivek Goyal 	return err;
5163e2b6fdbSVivek Goyal }
5173e2b6fdbSVivek Goyal 
5186f9f1180SMiklos Szeredi /*
5196f9f1180SMiklos Szeredi  * Atomic create+open operation
5206f9f1180SMiklos Szeredi  *
5216f9f1180SMiklos Szeredi  * If the filesystem doesn't support this, then fall back to separate
5226f9f1180SMiklos Szeredi  * 'mknod' + 'open' requests.
5236f9f1180SMiklos Szeredi  */
524d9585277SAl Viro static int fuse_create_open(struct inode *dir, struct dentry *entry,
52554d601cbSMiklos Szeredi 			    struct file *file, unsigned int flags,
526b452a458SAl Viro 			    umode_t mode)
527fd72faacSMiklos Szeredi {
528fd72faacSMiklos Szeredi 	int err;
529fd72faacSMiklos Szeredi 	struct inode *inode;
530fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(dir);
5317078187aSMiklos Szeredi 	FUSE_ARGS(args);
53207e77dcaSMiklos Szeredi 	struct fuse_forget_link *forget;
533e0a43ddcSMiklos Szeredi 	struct fuse_create_in inarg;
534fd72faacSMiklos Szeredi 	struct fuse_open_out outopen;
535fd72faacSMiklos Szeredi 	struct fuse_entry_out outentry;
536ebf84d0cSKirill Tkhai 	struct fuse_inode *fi;
537fd72faacSMiklos Szeredi 	struct fuse_file *ff;
5383e2b6fdbSVivek Goyal 	void *security_ctx = NULL;
5393e2b6fdbSVivek Goyal 	u32 security_ctxlen;
540fd72faacSMiklos Szeredi 
541af109bcaSMiklos Szeredi 	/* Userspace expects S_IFREG in create mode */
542af109bcaSMiklos Szeredi 	BUG_ON((mode & S_IFMT) != S_IFREG);
543af109bcaSMiklos Szeredi 
54407e77dcaSMiklos Szeredi 	forget = fuse_alloc_forget();
545c8ccbe03SMiklos Szeredi 	err = -ENOMEM;
54607e77dcaSMiklos Szeredi 	if (!forget)
547c8ccbe03SMiklos Szeredi 		goto out_err;
54851eb01e7SMiklos Szeredi 
549ce1d5a49SMiklos Szeredi 	err = -ENOMEM;
550fcee216bSMax Reitz 	ff = fuse_file_alloc(fm);
551fd72faacSMiklos Szeredi 	if (!ff)
5527078187aSMiklos Szeredi 		goto out_put_forget_req;
553fd72faacSMiklos Szeredi 
554fcee216bSMax Reitz 	if (!fm->fc->dont_mask)
555e0a43ddcSMiklos Szeredi 		mode &= ~current_umask();
556e0a43ddcSMiklos Szeredi 
557fd72faacSMiklos Szeredi 	flags &= ~O_NOCTTY;
558fd72faacSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
5590e9663eeSMiklos Szeredi 	memset(&outentry, 0, sizeof(outentry));
560fd72faacSMiklos Szeredi 	inarg.flags = flags;
561fd72faacSMiklos Szeredi 	inarg.mode = mode;
562e0a43ddcSMiklos Szeredi 	inarg.umask = current_umask();
563643a666aSVivek Goyal 
564643a666aSVivek Goyal 	if (fm->fc->handle_killpriv_v2 && (flags & O_TRUNC) &&
565643a666aSVivek Goyal 	    !(flags & O_EXCL) && !capable(CAP_FSETID)) {
566643a666aSVivek Goyal 		inarg.open_flags |= FUSE_OPEN_KILL_SUIDGID;
567643a666aSVivek Goyal 	}
568643a666aSVivek Goyal 
569d5b48543SMiklos Szeredi 	args.opcode = FUSE_CREATE;
570d5b48543SMiklos Szeredi 	args.nodeid = get_node_id(dir);
571d5b48543SMiklos Szeredi 	args.in_numargs = 2;
572d5b48543SMiklos Szeredi 	args.in_args[0].size = sizeof(inarg);
573d5b48543SMiklos Szeredi 	args.in_args[0].value = &inarg;
574d5b48543SMiklos Szeredi 	args.in_args[1].size = entry->d_name.len + 1;
575d5b48543SMiklos Szeredi 	args.in_args[1].value = entry->d_name.name;
576d5b48543SMiklos Szeredi 	args.out_numargs = 2;
577d5b48543SMiklos Szeredi 	args.out_args[0].size = sizeof(outentry);
578d5b48543SMiklos Szeredi 	args.out_args[0].value = &outentry;
579d5b48543SMiklos Szeredi 	args.out_args[1].size = sizeof(outopen);
580d5b48543SMiklos Szeredi 	args.out_args[1].value = &outopen;
5813e2b6fdbSVivek Goyal 
5823e2b6fdbSVivek Goyal 	if (fm->fc->init_security) {
5833e2b6fdbSVivek Goyal 		err = get_security_context(entry, mode, &security_ctx,
5843e2b6fdbSVivek Goyal 					   &security_ctxlen);
5853e2b6fdbSVivek Goyal 		if (err)
5863e2b6fdbSVivek Goyal 			goto out_put_forget_req;
5873e2b6fdbSVivek Goyal 
5883e2b6fdbSVivek Goyal 		args.in_numargs = 3;
5893e2b6fdbSVivek Goyal 		args.in_args[2].size = security_ctxlen;
5903e2b6fdbSVivek Goyal 		args.in_args[2].value = security_ctx;
5913e2b6fdbSVivek Goyal 	}
5923e2b6fdbSVivek Goyal 
593fcee216bSMax Reitz 	err = fuse_simple_request(fm, &args);
5943e2b6fdbSVivek Goyal 	kfree(security_ctx);
595c8ccbe03SMiklos Szeredi 	if (err)
596fd72faacSMiklos Szeredi 		goto out_free_ff;
597fd72faacSMiklos Szeredi 
598fd72faacSMiklos Szeredi 	err = -EIO;
599eb59bd17SMiklos Szeredi 	if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid) ||
600eb59bd17SMiklos Szeredi 	    fuse_invalid_attr(&outentry.attr))
601fd72faacSMiklos Szeredi 		goto out_free_ff;
602fd72faacSMiklos Szeredi 
603c7b7143cSMiklos Szeredi 	ff->fh = outopen.fh;
604c7b7143cSMiklos Szeredi 	ff->nodeid = outentry.nodeid;
605c7b7143cSMiklos Szeredi 	ff->open_flags = outopen.open_flags;
606fd72faacSMiklos Szeredi 	inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
6071fb69e78SMiklos Szeredi 			  &outentry.attr, entry_attr_timeout(&outentry), 0);
608fd72faacSMiklos Szeredi 	if (!inode) {
609fd72faacSMiklos Szeredi 		flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
610ebf84d0cSKirill Tkhai 		fuse_sync_release(NULL, ff, flags);
611fcee216bSMax Reitz 		fuse_queue_forget(fm->fc, forget, outentry.nodeid, 1);
612c8ccbe03SMiklos Szeredi 		err = -ENOMEM;
613c8ccbe03SMiklos Szeredi 		goto out_err;
614fd72faacSMiklos Szeredi 	}
61507e77dcaSMiklos Szeredi 	kfree(forget);
616fd72faacSMiklos Szeredi 	d_instantiate(entry, inode);
6171fb69e78SMiklos Szeredi 	fuse_change_entry_timeout(entry, &outentry);
618261aaba7SMiklos Szeredi 	fuse_dir_changed(dir);
619be12af3eSAl Viro 	err = finish_open(file, entry, generic_file_open);
62030d90494SAl Viro 	if (err) {
621ebf84d0cSKirill Tkhai 		fi = get_fuse_inode(inode);
622ebf84d0cSKirill Tkhai 		fuse_sync_release(fi, ff, flags);
623c8ccbe03SMiklos Szeredi 	} else {
624267d8444SMiklos Szeredi 		file->private_data = ff;
625c7b7143cSMiklos Szeredi 		fuse_finish_open(inode, file);
626c8ccbe03SMiklos Szeredi 	}
627d9585277SAl Viro 	return err;
628fd72faacSMiklos Szeredi 
629fd72faacSMiklos Szeredi out_free_ff:
630fd72faacSMiklos Szeredi 	fuse_file_free(ff);
63151eb01e7SMiklos Szeredi out_put_forget_req:
63207e77dcaSMiklos Szeredi 	kfree(forget);
633c8ccbe03SMiklos Szeredi out_err:
634d9585277SAl Viro 	return err;
635c8ccbe03SMiklos Szeredi }
636c8ccbe03SMiklos Szeredi 
637549c7297SChristian Brauner static int fuse_mknod(struct user_namespace *, struct inode *, struct dentry *,
638549c7297SChristian Brauner 		      umode_t, dev_t);
639d9585277SAl Viro static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
64030d90494SAl Viro 			    struct file *file, unsigned flags,
64144907d79SAl Viro 			    umode_t mode)
642c8ccbe03SMiklos Szeredi {
643c8ccbe03SMiklos Szeredi 	int err;
644c8ccbe03SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
645c8ccbe03SMiklos Szeredi 	struct dentry *res = NULL;
646c8ccbe03SMiklos Szeredi 
6475d069dbeSMiklos Szeredi 	if (fuse_is_bad(dir))
6485d069dbeSMiklos Szeredi 		return -EIO;
6495d069dbeSMiklos Szeredi 
65000699ad8SAl Viro 	if (d_in_lookup(entry)) {
65100cd8dd3SAl Viro 		res = fuse_lookup(dir, entry, 0);
652c8ccbe03SMiklos Szeredi 		if (IS_ERR(res))
653d9585277SAl Viro 			return PTR_ERR(res);
654c8ccbe03SMiklos Szeredi 
655c8ccbe03SMiklos Szeredi 		if (res)
656c8ccbe03SMiklos Szeredi 			entry = res;
657c8ccbe03SMiklos Szeredi 	}
658c8ccbe03SMiklos Szeredi 
6592b0143b5SDavid Howells 	if (!(flags & O_CREAT) || d_really_is_positive(entry))
660c8ccbe03SMiklos Szeredi 		goto no_open;
661c8ccbe03SMiklos Szeredi 
662c8ccbe03SMiklos Szeredi 	/* Only creates */
66373a09dd9SAl Viro 	file->f_mode |= FMODE_CREATED;
664c8ccbe03SMiklos Szeredi 
665c8ccbe03SMiklos Szeredi 	if (fc->no_create)
666c8ccbe03SMiklos Szeredi 		goto mknod;
667c8ccbe03SMiklos Szeredi 
668b452a458SAl Viro 	err = fuse_create_open(dir, entry, file, flags, mode);
669d9585277SAl Viro 	if (err == -ENOSYS) {
670c8ccbe03SMiklos Szeredi 		fc->no_create = 1;
671c8ccbe03SMiklos Szeredi 		goto mknod;
672c8ccbe03SMiklos Szeredi 	}
673c8ccbe03SMiklos Szeredi out_dput:
674c8ccbe03SMiklos Szeredi 	dput(res);
675d9585277SAl Viro 	return err;
676c8ccbe03SMiklos Szeredi 
677c8ccbe03SMiklos Szeredi mknod:
678549c7297SChristian Brauner 	err = fuse_mknod(&init_user_ns, dir, entry, mode, 0);
679d9585277SAl Viro 	if (err)
680c8ccbe03SMiklos Szeredi 		goto out_dput;
681c8ccbe03SMiklos Szeredi no_open:
682e45198a6SAl Viro 	return finish_no_open(file, res);
683fd72faacSMiklos Szeredi }
684fd72faacSMiklos Szeredi 
6856f9f1180SMiklos Szeredi /*
6866f9f1180SMiklos Szeredi  * Code shared between mknod, mkdir, symlink and link
6876f9f1180SMiklos Szeredi  */
688fcee216bSMax Reitz static int create_new_entry(struct fuse_mount *fm, struct fuse_args *args,
6899e6268dbSMiklos Szeredi 			    struct inode *dir, struct dentry *entry,
690541af6a0SAl Viro 			    umode_t mode)
6919e6268dbSMiklos Szeredi {
6929e6268dbSMiklos Szeredi 	struct fuse_entry_out outarg;
6939e6268dbSMiklos Szeredi 	struct inode *inode;
694c971e6a0SAl Viro 	struct dentry *d;
6959e6268dbSMiklos Szeredi 	int err;
69607e77dcaSMiklos Szeredi 	struct fuse_forget_link *forget;
6973e2b6fdbSVivek Goyal 	void *security_ctx = NULL;
6983e2b6fdbSVivek Goyal 	u32 security_ctxlen;
6992d51013eSMiklos Szeredi 
7005d069dbeSMiklos Szeredi 	if (fuse_is_bad(dir))
7015d069dbeSMiklos Szeredi 		return -EIO;
7025d069dbeSMiklos Szeredi 
70307e77dcaSMiklos Szeredi 	forget = fuse_alloc_forget();
7047078187aSMiklos Szeredi 	if (!forget)
70507e77dcaSMiklos Szeredi 		return -ENOMEM;
7069e6268dbSMiklos Szeredi 
7070e9663eeSMiklos Szeredi 	memset(&outarg, 0, sizeof(outarg));
708d5b48543SMiklos Szeredi 	args->nodeid = get_node_id(dir);
709d5b48543SMiklos Szeredi 	args->out_numargs = 1;
710d5b48543SMiklos Szeredi 	args->out_args[0].size = sizeof(outarg);
711d5b48543SMiklos Szeredi 	args->out_args[0].value = &outarg;
7123e2b6fdbSVivek Goyal 
7133e2b6fdbSVivek Goyal 	if (fm->fc->init_security && args->opcode != FUSE_LINK) {
7143e2b6fdbSVivek Goyal 		err = get_security_context(entry, mode, &security_ctx,
7153e2b6fdbSVivek Goyal 					   &security_ctxlen);
7163e2b6fdbSVivek Goyal 		if (err)
7173e2b6fdbSVivek Goyal 			goto out_put_forget_req;
7183e2b6fdbSVivek Goyal 
7193e2b6fdbSVivek Goyal 		BUG_ON(args->in_numargs != 2);
7203e2b6fdbSVivek Goyal 
7213e2b6fdbSVivek Goyal 		args->in_numargs = 3;
7223e2b6fdbSVivek Goyal 		args->in_args[2].size = security_ctxlen;
7233e2b6fdbSVivek Goyal 		args->in_args[2].value = security_ctx;
7243e2b6fdbSVivek Goyal 	}
7253e2b6fdbSVivek Goyal 
726fcee216bSMax Reitz 	err = fuse_simple_request(fm, args);
7273e2b6fdbSVivek Goyal 	kfree(security_ctx);
7282d51013eSMiklos Szeredi 	if (err)
7292d51013eSMiklos Szeredi 		goto out_put_forget_req;
7302d51013eSMiklos Szeredi 
73139ee059aSMiklos Szeredi 	err = -EIO;
732eb59bd17SMiklos Szeredi 	if (invalid_nodeid(outarg.nodeid) || fuse_invalid_attr(&outarg.attr))
7332d51013eSMiklos Szeredi 		goto out_put_forget_req;
73439ee059aSMiklos Szeredi 
73539ee059aSMiklos Szeredi 	if ((outarg.attr.mode ^ mode) & S_IFMT)
7362d51013eSMiklos Szeredi 		goto out_put_forget_req;
73739ee059aSMiklos Szeredi 
7389e6268dbSMiklos Szeredi 	inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
7391fb69e78SMiklos Szeredi 			  &outarg.attr, entry_attr_timeout(&outarg), 0);
7409e6268dbSMiklos Szeredi 	if (!inode) {
741fcee216bSMax Reitz 		fuse_queue_forget(fm->fc, forget, outarg.nodeid, 1);
7429e6268dbSMiklos Szeredi 		return -ENOMEM;
7439e6268dbSMiklos Szeredi 	}
74407e77dcaSMiklos Szeredi 	kfree(forget);
7459e6268dbSMiklos Szeredi 
746c971e6a0SAl Viro 	d_drop(entry);
747c971e6a0SAl Viro 	d = d_splice_alias(inode, entry);
748c971e6a0SAl Viro 	if (IS_ERR(d))
749c971e6a0SAl Viro 		return PTR_ERR(d);
750d2a85164SMiklos Szeredi 
751c971e6a0SAl Viro 	if (d) {
752c971e6a0SAl Viro 		fuse_change_entry_timeout(d, &outarg);
753c971e6a0SAl Viro 		dput(d);
754c971e6a0SAl Viro 	} else {
7551fb69e78SMiklos Szeredi 		fuse_change_entry_timeout(entry, &outarg);
756c971e6a0SAl Viro 	}
757261aaba7SMiklos Szeredi 	fuse_dir_changed(dir);
7589e6268dbSMiklos Szeredi 	return 0;
75939ee059aSMiklos Szeredi 
7602d51013eSMiklos Szeredi  out_put_forget_req:
76107e77dcaSMiklos Szeredi 	kfree(forget);
76239ee059aSMiklos Szeredi 	return err;
7639e6268dbSMiklos Szeredi }
7649e6268dbSMiklos Szeredi 
765549c7297SChristian Brauner static int fuse_mknod(struct user_namespace *mnt_userns, struct inode *dir,
766549c7297SChristian Brauner 		      struct dentry *entry, umode_t mode, dev_t rdev)
7679e6268dbSMiklos Szeredi {
7689e6268dbSMiklos Szeredi 	struct fuse_mknod_in inarg;
769fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(dir);
7707078187aSMiklos Szeredi 	FUSE_ARGS(args);
7719e6268dbSMiklos Szeredi 
772fcee216bSMax Reitz 	if (!fm->fc->dont_mask)
773e0a43ddcSMiklos Szeredi 		mode &= ~current_umask();
774e0a43ddcSMiklos Szeredi 
7759e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
7769e6268dbSMiklos Szeredi 	inarg.mode = mode;
7779e6268dbSMiklos Szeredi 	inarg.rdev = new_encode_dev(rdev);
778e0a43ddcSMiklos Szeredi 	inarg.umask = current_umask();
779d5b48543SMiklos Szeredi 	args.opcode = FUSE_MKNOD;
780d5b48543SMiklos Szeredi 	args.in_numargs = 2;
781d5b48543SMiklos Szeredi 	args.in_args[0].size = sizeof(inarg);
782d5b48543SMiklos Szeredi 	args.in_args[0].value = &inarg;
783d5b48543SMiklos Szeredi 	args.in_args[1].size = entry->d_name.len + 1;
784d5b48543SMiklos Szeredi 	args.in_args[1].value = entry->d_name.name;
785fcee216bSMax Reitz 	return create_new_entry(fm, &args, dir, entry, mode);
7869e6268dbSMiklos Szeredi }
7879e6268dbSMiklos Szeredi 
788549c7297SChristian Brauner static int fuse_create(struct user_namespace *mnt_userns, struct inode *dir,
789549c7297SChristian Brauner 		       struct dentry *entry, umode_t mode, bool excl)
7909e6268dbSMiklos Szeredi {
791549c7297SChristian Brauner 	return fuse_mknod(&init_user_ns, dir, entry, mode, 0);
7929e6268dbSMiklos Szeredi }
7939e6268dbSMiklos Szeredi 
794549c7297SChristian Brauner static int fuse_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
795549c7297SChristian Brauner 		      struct dentry *entry, umode_t mode)
7969e6268dbSMiklos Szeredi {
7979e6268dbSMiklos Szeredi 	struct fuse_mkdir_in inarg;
798fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(dir);
7997078187aSMiklos Szeredi 	FUSE_ARGS(args);
8009e6268dbSMiklos Szeredi 
801fcee216bSMax Reitz 	if (!fm->fc->dont_mask)
802e0a43ddcSMiklos Szeredi 		mode &= ~current_umask();
803e0a43ddcSMiklos Szeredi 
8049e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
8059e6268dbSMiklos Szeredi 	inarg.mode = mode;
806e0a43ddcSMiklos Szeredi 	inarg.umask = current_umask();
807d5b48543SMiklos Szeredi 	args.opcode = FUSE_MKDIR;
808d5b48543SMiklos Szeredi 	args.in_numargs = 2;
809d5b48543SMiklos Szeredi 	args.in_args[0].size = sizeof(inarg);
810d5b48543SMiklos Szeredi 	args.in_args[0].value = &inarg;
811d5b48543SMiklos Szeredi 	args.in_args[1].size = entry->d_name.len + 1;
812d5b48543SMiklos Szeredi 	args.in_args[1].value = entry->d_name.name;
813fcee216bSMax Reitz 	return create_new_entry(fm, &args, dir, entry, S_IFDIR);
8149e6268dbSMiklos Szeredi }
8159e6268dbSMiklos Szeredi 
816549c7297SChristian Brauner static int fuse_symlink(struct user_namespace *mnt_userns, struct inode *dir,
817549c7297SChristian Brauner 			struct dentry *entry, const char *link)
8189e6268dbSMiklos Szeredi {
819fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(dir);
8209e6268dbSMiklos Szeredi 	unsigned len = strlen(link) + 1;
8217078187aSMiklos Szeredi 	FUSE_ARGS(args);
8229e6268dbSMiklos Szeredi 
823d5b48543SMiklos Szeredi 	args.opcode = FUSE_SYMLINK;
824d5b48543SMiklos Szeredi 	args.in_numargs = 2;
825d5b48543SMiklos Szeredi 	args.in_args[0].size = entry->d_name.len + 1;
826d5b48543SMiklos Szeredi 	args.in_args[0].value = entry->d_name.name;
827d5b48543SMiklos Szeredi 	args.in_args[1].size = len;
828d5b48543SMiklos Szeredi 	args.in_args[1].value = link;
829fcee216bSMax Reitz 	return create_new_entry(fm, &args, dir, entry, S_IFLNK);
8309e6268dbSMiklos Szeredi }
8319e6268dbSMiklos Szeredi 
8325c791fe1SMiklos Szeredi void fuse_flush_time_update(struct inode *inode)
8335c791fe1SMiklos Szeredi {
8345c791fe1SMiklos Szeredi 	int err = sync_inode_metadata(inode, 1);
8355c791fe1SMiklos Szeredi 
8365c791fe1SMiklos Szeredi 	mapping_set_error(inode->i_mapping, err);
8375c791fe1SMiklos Szeredi }
8385c791fe1SMiklos Szeredi 
83997f044f6SMiklos Szeredi static void fuse_update_ctime_in_cache(struct inode *inode)
84031f3267bSMaxim Patlasov {
84131f3267bSMaxim Patlasov 	if (!IS_NOCMTIME(inode)) {
842c2050a45SDeepa Dinamani 		inode->i_ctime = current_time(inode);
84331f3267bSMaxim Patlasov 		mark_inode_dirty_sync(inode);
8445c791fe1SMiklos Szeredi 		fuse_flush_time_update(inode);
84531f3267bSMaxim Patlasov 	}
84631f3267bSMaxim Patlasov }
84731f3267bSMaxim Patlasov 
84897f044f6SMiklos Szeredi void fuse_update_ctime(struct inode *inode)
84997f044f6SMiklos Szeredi {
850fa5eee57SMiklos Szeredi 	fuse_invalidate_attr_mask(inode, STATX_CTIME);
85197f044f6SMiklos Szeredi 	fuse_update_ctime_in_cache(inode);
85297f044f6SMiklos Szeredi }
85397f044f6SMiklos Szeredi 
854cefd1b83SMiklos Szeredi static void fuse_entry_unlinked(struct dentry *entry)
855cefd1b83SMiklos Szeredi {
856cefd1b83SMiklos Szeredi 	struct inode *inode = d_inode(entry);
857cefd1b83SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
858cefd1b83SMiklos Szeredi 	struct fuse_inode *fi = get_fuse_inode(inode);
859cefd1b83SMiklos Szeredi 
860cefd1b83SMiklos Szeredi 	spin_lock(&fi->lock);
861cefd1b83SMiklos Szeredi 	fi->attr_version = atomic64_inc_return(&fc->attr_version);
862cefd1b83SMiklos Szeredi 	/*
863cefd1b83SMiklos Szeredi 	 * If i_nlink == 0 then unlink doesn't make sense, yet this can
864cefd1b83SMiklos Szeredi 	 * happen if userspace filesystem is careless.  It would be
865cefd1b83SMiklos Szeredi 	 * difficult to enforce correct nlink usage so just ignore this
866cefd1b83SMiklos Szeredi 	 * condition here
867cefd1b83SMiklos Szeredi 	 */
868cefd1b83SMiklos Szeredi 	if (S_ISDIR(inode->i_mode))
869cefd1b83SMiklos Szeredi 		clear_nlink(inode);
870cefd1b83SMiklos Szeredi 	else if (inode->i_nlink > 0)
871cefd1b83SMiklos Szeredi 		drop_nlink(inode);
872cefd1b83SMiklos Szeredi 	spin_unlock(&fi->lock);
873cefd1b83SMiklos Szeredi 	fuse_invalidate_entry_cache(entry);
874cefd1b83SMiklos Szeredi 	fuse_update_ctime(inode);
875cefd1b83SMiklos Szeredi }
876cefd1b83SMiklos Szeredi 
8779e6268dbSMiklos Szeredi static int fuse_unlink(struct inode *dir, struct dentry *entry)
8789e6268dbSMiklos Szeredi {
8799e6268dbSMiklos Szeredi 	int err;
880fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(dir);
8817078187aSMiklos Szeredi 	FUSE_ARGS(args);
8829e6268dbSMiklos Szeredi 
8835d069dbeSMiklos Szeredi 	if (fuse_is_bad(dir))
8845d069dbeSMiklos Szeredi 		return -EIO;
8855d069dbeSMiklos Szeredi 
886d5b48543SMiklos Szeredi 	args.opcode = FUSE_UNLINK;
887d5b48543SMiklos Szeredi 	args.nodeid = get_node_id(dir);
888d5b48543SMiklos Szeredi 	args.in_numargs = 1;
889d5b48543SMiklos Szeredi 	args.in_args[0].size = entry->d_name.len + 1;
890d5b48543SMiklos Szeredi 	args.in_args[0].value = entry->d_name.name;
891fcee216bSMax Reitz 	err = fuse_simple_request(fm, &args);
8929e6268dbSMiklos Szeredi 	if (!err) {
893261aaba7SMiklos Szeredi 		fuse_dir_changed(dir);
894cefd1b83SMiklos Szeredi 		fuse_entry_unlinked(entry);
8959e6268dbSMiklos Szeredi 	} else if (err == -EINTR)
8969e6268dbSMiklos Szeredi 		fuse_invalidate_entry(entry);
8979e6268dbSMiklos Szeredi 	return err;
8989e6268dbSMiklos Szeredi }
8999e6268dbSMiklos Szeredi 
9009e6268dbSMiklos Szeredi static int fuse_rmdir(struct inode *dir, struct dentry *entry)
9019e6268dbSMiklos Szeredi {
9029e6268dbSMiklos Szeredi 	int err;
903fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(dir);
9047078187aSMiklos Szeredi 	FUSE_ARGS(args);
9059e6268dbSMiklos Szeredi 
9065d069dbeSMiklos Szeredi 	if (fuse_is_bad(dir))
9075d069dbeSMiklos Szeredi 		return -EIO;
9085d069dbeSMiklos Szeredi 
909d5b48543SMiklos Szeredi 	args.opcode = FUSE_RMDIR;
910d5b48543SMiklos Szeredi 	args.nodeid = get_node_id(dir);
911d5b48543SMiklos Szeredi 	args.in_numargs = 1;
912d5b48543SMiklos Szeredi 	args.in_args[0].size = entry->d_name.len + 1;
913d5b48543SMiklos Szeredi 	args.in_args[0].value = entry->d_name.name;
914fcee216bSMax Reitz 	err = fuse_simple_request(fm, &args);
9159e6268dbSMiklos Szeredi 	if (!err) {
916261aaba7SMiklos Szeredi 		fuse_dir_changed(dir);
917cefd1b83SMiklos Szeredi 		fuse_entry_unlinked(entry);
9189e6268dbSMiklos Szeredi 	} else if (err == -EINTR)
9199e6268dbSMiklos Szeredi 		fuse_invalidate_entry(entry);
9209e6268dbSMiklos Szeredi 	return err;
9219e6268dbSMiklos Szeredi }
9229e6268dbSMiklos Szeredi 
9231560c974SMiklos Szeredi static int fuse_rename_common(struct inode *olddir, struct dentry *oldent,
9241560c974SMiklos Szeredi 			      struct inode *newdir, struct dentry *newent,
9251560c974SMiklos Szeredi 			      unsigned int flags, int opcode, size_t argsize)
9269e6268dbSMiklos Szeredi {
9279e6268dbSMiklos Szeredi 	int err;
9281560c974SMiklos Szeredi 	struct fuse_rename2_in inarg;
929fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(olddir);
9307078187aSMiklos Szeredi 	FUSE_ARGS(args);
9319e6268dbSMiklos Szeredi 
9321560c974SMiklos Szeredi 	memset(&inarg, 0, argsize);
9339e6268dbSMiklos Szeredi 	inarg.newdir = get_node_id(newdir);
9341560c974SMiklos Szeredi 	inarg.flags = flags;
935d5b48543SMiklos Szeredi 	args.opcode = opcode;
936d5b48543SMiklos Szeredi 	args.nodeid = get_node_id(olddir);
937d5b48543SMiklos Szeredi 	args.in_numargs = 3;
938d5b48543SMiklos Szeredi 	args.in_args[0].size = argsize;
939d5b48543SMiklos Szeredi 	args.in_args[0].value = &inarg;
940d5b48543SMiklos Szeredi 	args.in_args[1].size = oldent->d_name.len + 1;
941d5b48543SMiklos Szeredi 	args.in_args[1].value = oldent->d_name.name;
942d5b48543SMiklos Szeredi 	args.in_args[2].size = newent->d_name.len + 1;
943d5b48543SMiklos Szeredi 	args.in_args[2].value = newent->d_name.name;
944fcee216bSMax Reitz 	err = fuse_simple_request(fm, &args);
9459e6268dbSMiklos Szeredi 	if (!err) {
94608b63307SMiklos Szeredi 		/* ctime changes */
9472b0143b5SDavid Howells 		fuse_update_ctime(d_inode(oldent));
94808b63307SMiklos Szeredi 
949371e8fd0SMiklos Szeredi 		if (flags & RENAME_EXCHANGE)
9502b0143b5SDavid Howells 			fuse_update_ctime(d_inode(newent));
9511560c974SMiklos Szeredi 
952261aaba7SMiklos Szeredi 		fuse_dir_changed(olddir);
9539e6268dbSMiklos Szeredi 		if (olddir != newdir)
954261aaba7SMiklos Szeredi 			fuse_dir_changed(newdir);
9558cbdf1e6SMiklos Szeredi 
9568cbdf1e6SMiklos Szeredi 		/* newent will end up negative */
957cefd1b83SMiklos Szeredi 		if (!(flags & RENAME_EXCHANGE) && d_really_is_positive(newent))
958cefd1b83SMiklos Szeredi 			fuse_entry_unlinked(newent);
9599e6268dbSMiklos Szeredi 	} else if (err == -EINTR) {
9609e6268dbSMiklos Szeredi 		/* If request was interrupted, DEITY only knows if the
9619e6268dbSMiklos Szeredi 		   rename actually took place.  If the invalidation
9629e6268dbSMiklos Szeredi 		   fails (e.g. some process has CWD under the renamed
9639e6268dbSMiklos Szeredi 		   directory), then there can be inconsistency between
9649e6268dbSMiklos Szeredi 		   the dcache and the real filesystem.  Tough luck. */
9659e6268dbSMiklos Szeredi 		fuse_invalidate_entry(oldent);
9662b0143b5SDavid Howells 		if (d_really_is_positive(newent))
9679e6268dbSMiklos Szeredi 			fuse_invalidate_entry(newent);
9689e6268dbSMiklos Szeredi 	}
9699e6268dbSMiklos Szeredi 
9709e6268dbSMiklos Szeredi 	return err;
9719e6268dbSMiklos Szeredi }
9729e6268dbSMiklos Szeredi 
973549c7297SChristian Brauner static int fuse_rename2(struct user_namespace *mnt_userns, struct inode *olddir,
974549c7297SChristian Brauner 			struct dentry *oldent, struct inode *newdir,
975549c7297SChristian Brauner 			struct dentry *newent, unsigned int flags)
9761560c974SMiklos Szeredi {
9771560c974SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(olddir);
9781560c974SMiklos Szeredi 	int err;
9791560c974SMiklos Szeredi 
9805d069dbeSMiklos Szeredi 	if (fuse_is_bad(olddir))
9815d069dbeSMiklos Szeredi 		return -EIO;
9825d069dbeSMiklos Szeredi 
983519525faSVivek Goyal 	if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT))
9841560c974SMiklos Szeredi 		return -EINVAL;
9851560c974SMiklos Szeredi 
9864237ba43SMiklos Szeredi 	if (flags) {
9871560c974SMiklos Szeredi 		if (fc->no_rename2 || fc->minor < 23)
9881560c974SMiklos Szeredi 			return -EINVAL;
9891560c974SMiklos Szeredi 
9901560c974SMiklos Szeredi 		err = fuse_rename_common(olddir, oldent, newdir, newent, flags,
9914237ba43SMiklos Szeredi 					 FUSE_RENAME2,
9924237ba43SMiklos Szeredi 					 sizeof(struct fuse_rename2_in));
9931560c974SMiklos Szeredi 		if (err == -ENOSYS) {
9941560c974SMiklos Szeredi 			fc->no_rename2 = 1;
9951560c974SMiklos Szeredi 			err = -EINVAL;
9961560c974SMiklos Szeredi 		}
9974237ba43SMiklos Szeredi 	} else {
9984237ba43SMiklos Szeredi 		err = fuse_rename_common(olddir, oldent, newdir, newent, 0,
9994237ba43SMiklos Szeredi 					 FUSE_RENAME,
10004237ba43SMiklos Szeredi 					 sizeof(struct fuse_rename_in));
10014237ba43SMiklos Szeredi 	}
10021560c974SMiklos Szeredi 
10034237ba43SMiklos Szeredi 	return err;
10044237ba43SMiklos Szeredi }
10054237ba43SMiklos Szeredi 
10069e6268dbSMiklos Szeredi static int fuse_link(struct dentry *entry, struct inode *newdir,
10079e6268dbSMiklos Szeredi 		     struct dentry *newent)
10089e6268dbSMiklos Szeredi {
10099e6268dbSMiklos Szeredi 	int err;
10109e6268dbSMiklos Szeredi 	struct fuse_link_in inarg;
10112b0143b5SDavid Howells 	struct inode *inode = d_inode(entry);
1012fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(inode);
10137078187aSMiklos Szeredi 	FUSE_ARGS(args);
10149e6268dbSMiklos Szeredi 
10159e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
10169e6268dbSMiklos Szeredi 	inarg.oldnodeid = get_node_id(inode);
1017d5b48543SMiklos Szeredi 	args.opcode = FUSE_LINK;
1018d5b48543SMiklos Szeredi 	args.in_numargs = 2;
1019d5b48543SMiklos Szeredi 	args.in_args[0].size = sizeof(inarg);
1020d5b48543SMiklos Szeredi 	args.in_args[0].value = &inarg;
1021d5b48543SMiklos Szeredi 	args.in_args[1].size = newent->d_name.len + 1;
1022d5b48543SMiklos Szeredi 	args.in_args[1].value = newent->d_name.name;
1023fcee216bSMax Reitz 	err = create_new_entry(fm, &args, newdir, newent, inode->i_mode);
102497f044f6SMiklos Szeredi 	if (!err)
102597f044f6SMiklos Szeredi 		fuse_update_ctime_in_cache(inode);
102697f044f6SMiklos Szeredi 	else if (err == -EINTR)
1027ac45d613SMiklos Szeredi 		fuse_invalidate_attr(inode);
102897f044f6SMiklos Szeredi 
10299e6268dbSMiklos Szeredi 	return err;
10309e6268dbSMiklos Szeredi }
10319e6268dbSMiklos Szeredi 
10321fb69e78SMiklos Szeredi static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
10331fb69e78SMiklos Szeredi 			  struct kstat *stat)
10341fb69e78SMiklos Szeredi {
1035203627bbSMiklos Szeredi 	unsigned int blkbits;
10368373200bSPavel Emelyanov 	struct fuse_conn *fc = get_fuse_conn(inode);
10378373200bSPavel Emelyanov 
10381fb69e78SMiklos Szeredi 	stat->dev = inode->i_sb->s_dev;
10391fb69e78SMiklos Szeredi 	stat->ino = attr->ino;
10401fb69e78SMiklos Szeredi 	stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
10411fb69e78SMiklos Szeredi 	stat->nlink = attr->nlink;
10428cb08329SEric W. Biederman 	stat->uid = make_kuid(fc->user_ns, attr->uid);
10438cb08329SEric W. Biederman 	stat->gid = make_kgid(fc->user_ns, attr->gid);
10441fb69e78SMiklos Szeredi 	stat->rdev = inode->i_rdev;
10451fb69e78SMiklos Szeredi 	stat->atime.tv_sec = attr->atime;
10461fb69e78SMiklos Szeredi 	stat->atime.tv_nsec = attr->atimensec;
10471fb69e78SMiklos Szeredi 	stat->mtime.tv_sec = attr->mtime;
10481fb69e78SMiklos Szeredi 	stat->mtime.tv_nsec = attr->mtimensec;
10491fb69e78SMiklos Szeredi 	stat->ctime.tv_sec = attr->ctime;
10501fb69e78SMiklos Szeredi 	stat->ctime.tv_nsec = attr->ctimensec;
10511fb69e78SMiklos Szeredi 	stat->size = attr->size;
10521fb69e78SMiklos Szeredi 	stat->blocks = attr->blocks;
1053203627bbSMiklos Szeredi 
1054203627bbSMiklos Szeredi 	if (attr->blksize != 0)
1055203627bbSMiklos Szeredi 		blkbits = ilog2(attr->blksize);
1056203627bbSMiklos Szeredi 	else
1057203627bbSMiklos Szeredi 		blkbits = inode->i_sb->s_blocksize_bits;
1058203627bbSMiklos Szeredi 
1059203627bbSMiklos Szeredi 	stat->blksize = 1 << blkbits;
10601fb69e78SMiklos Szeredi }
10611fb69e78SMiklos Szeredi 
1062c79e322fSMiklos Szeredi static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
1063c79e322fSMiklos Szeredi 			   struct file *file)
1064e5e5558eSMiklos Szeredi {
1065e5e5558eSMiklos Szeredi 	int err;
1066c79e322fSMiklos Szeredi 	struct fuse_getattr_in inarg;
1067c79e322fSMiklos Szeredi 	struct fuse_attr_out outarg;
1068fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(inode);
10697078187aSMiklos Szeredi 	FUSE_ARGS(args);
10701fb69e78SMiklos Szeredi 	u64 attr_version;
10711fb69e78SMiklos Szeredi 
1072fcee216bSMax Reitz 	attr_version = fuse_get_attr_version(fm->fc);
10731fb69e78SMiklos Szeredi 
1074c79e322fSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
10750e9663eeSMiklos Szeredi 	memset(&outarg, 0, sizeof(outarg));
1076c79e322fSMiklos Szeredi 	/* Directories have separate file-handle space */
1077c79e322fSMiklos Szeredi 	if (file && S_ISREG(inode->i_mode)) {
1078c79e322fSMiklos Szeredi 		struct fuse_file *ff = file->private_data;
1079c79e322fSMiklos Szeredi 
1080c79e322fSMiklos Szeredi 		inarg.getattr_flags |= FUSE_GETATTR_FH;
1081c79e322fSMiklos Szeredi 		inarg.fh = ff->fh;
1082c79e322fSMiklos Szeredi 	}
1083d5b48543SMiklos Szeredi 	args.opcode = FUSE_GETATTR;
1084d5b48543SMiklos Szeredi 	args.nodeid = get_node_id(inode);
1085d5b48543SMiklos Szeredi 	args.in_numargs = 1;
1086d5b48543SMiklos Szeredi 	args.in_args[0].size = sizeof(inarg);
1087d5b48543SMiklos Szeredi 	args.in_args[0].value = &inarg;
1088d5b48543SMiklos Szeredi 	args.out_numargs = 1;
1089d5b48543SMiklos Szeredi 	args.out_args[0].size = sizeof(outarg);
1090d5b48543SMiklos Szeredi 	args.out_args[0].value = &outarg;
1091fcee216bSMax Reitz 	err = fuse_simple_request(fm, &args);
1092e5e5558eSMiklos Szeredi 	if (!err) {
1093eb59bd17SMiklos Szeredi 		if (fuse_invalid_attr(&outarg.attr) ||
10946e3e2c43SAl Viro 		    inode_wrong_type(inode, outarg.attr.mode)) {
10955d069dbeSMiklos Szeredi 			fuse_make_bad(inode);
1096e5e5558eSMiklos Szeredi 			err = -EIO;
1097e5e5558eSMiklos Szeredi 		} else {
1098c79e322fSMiklos Szeredi 			fuse_change_attributes(inode, &outarg.attr,
1099c79e322fSMiklos Szeredi 					       attr_timeout(&outarg),
11001fb69e78SMiklos Szeredi 					       attr_version);
11011fb69e78SMiklos Szeredi 			if (stat)
1102c79e322fSMiklos Szeredi 				fuse_fillattr(inode, &outarg.attr, stat);
1103e5e5558eSMiklos Szeredi 		}
1104e5e5558eSMiklos Szeredi 	}
1105e5e5558eSMiklos Szeredi 	return err;
1106e5e5558eSMiklos Szeredi }
1107e5e5558eSMiklos Szeredi 
11085b97eeacSMiklos Szeredi static int fuse_update_get_attr(struct inode *inode, struct file *file,
11092f1e8196SMiklos Szeredi 				struct kstat *stat, u32 request_mask,
11102f1e8196SMiklos Szeredi 				unsigned int flags)
1111bcb4be80SMiklos Szeredi {
1112bcb4be80SMiklos Szeredi 	struct fuse_inode *fi = get_fuse_inode(inode);
11135b97eeacSMiklos Szeredi 	int err = 0;
1114bf5c1898SMiklos Szeredi 	bool sync;
1115ec855375SMiklos Szeredi 	u32 inval_mask = READ_ONCE(fi->inval_mask);
1116ec855375SMiklos Szeredi 	u32 cache_mask = fuse_get_cache_mask(inode);
1117bcb4be80SMiklos Szeredi 
1118bf5c1898SMiklos Szeredi 	if (flags & AT_STATX_FORCE_SYNC)
1119bf5c1898SMiklos Szeredi 		sync = true;
1120bf5c1898SMiklos Szeredi 	else if (flags & AT_STATX_DONT_SYNC)
1121bf5c1898SMiklos Szeredi 		sync = false;
1122ec855375SMiklos Szeredi 	else if (request_mask & inval_mask & ~cache_mask)
11232f1e8196SMiklos Szeredi 		sync = true;
1124bf5c1898SMiklos Szeredi 	else
1125bf5c1898SMiklos Szeredi 		sync = time_before64(fi->i_time, get_jiffies_64());
1126bf5c1898SMiklos Szeredi 
1127bf5c1898SMiklos Szeredi 	if (sync) {
112860bcc88aSSeth Forshee 		forget_all_cached_acls(inode);
1129bcb4be80SMiklos Szeredi 		err = fuse_do_getattr(inode, stat, file);
11305b97eeacSMiklos Szeredi 	} else if (stat) {
11310d56a451SChristian Brauner 		generic_fillattr(&init_user_ns, inode, stat);
1132bcb4be80SMiklos Szeredi 		stat->mode = fi->orig_i_mode;
113345c72cd7SPavel Shilovsky 		stat->ino = fi->orig_ino;
1134bcb4be80SMiklos Szeredi 	}
1135bcb4be80SMiklos Szeredi 
1136bcb4be80SMiklos Szeredi 	return err;
1137bcb4be80SMiklos Szeredi }
1138bcb4be80SMiklos Szeredi 
1139c6c745b8SMiklos Szeredi int fuse_update_attributes(struct inode *inode, struct file *file, u32 mask)
11405b97eeacSMiklos Szeredi {
1141c6c745b8SMiklos Szeredi 	return fuse_update_get_attr(inode, file, NULL, mask, 0);
11425b97eeacSMiklos Szeredi }
11435b97eeacSMiklos Szeredi 
1144fcee216bSMax Reitz int fuse_reverse_inval_entry(struct fuse_conn *fc, u64 parent_nodeid,
1145451d0f59SJohn Muir 			     u64 child_nodeid, struct qstr *name)
11463b463ae0SJohn Muir {
11473b463ae0SJohn Muir 	int err = -ENOTDIR;
11483b463ae0SJohn Muir 	struct inode *parent;
11493b463ae0SJohn Muir 	struct dentry *dir;
11503b463ae0SJohn Muir 	struct dentry *entry;
11513b463ae0SJohn Muir 
1152fcee216bSMax Reitz 	parent = fuse_ilookup(fc, parent_nodeid, NULL);
11533b463ae0SJohn Muir 	if (!parent)
11543b463ae0SJohn Muir 		return -ENOENT;
11553b463ae0SJohn Muir 
1156bda9a719SMiklos Szeredi 	inode_lock_nested(parent, I_MUTEX_PARENT);
11573b463ae0SJohn Muir 	if (!S_ISDIR(parent->i_mode))
11583b463ae0SJohn Muir 		goto unlock;
11593b463ae0SJohn Muir 
11603b463ae0SJohn Muir 	err = -ENOENT;
11613b463ae0SJohn Muir 	dir = d_find_alias(parent);
11623b463ae0SJohn Muir 	if (!dir)
11633b463ae0SJohn Muir 		goto unlock;
11643b463ae0SJohn Muir 
11658387ff25SLinus Torvalds 	name->hash = full_name_hash(dir, name->name, name->len);
11663b463ae0SJohn Muir 	entry = d_lookup(dir, name);
11673b463ae0SJohn Muir 	dput(dir);
11683b463ae0SJohn Muir 	if (!entry)
11693b463ae0SJohn Muir 		goto unlock;
11703b463ae0SJohn Muir 
1171261aaba7SMiklos Szeredi 	fuse_dir_changed(parent);
11723b463ae0SJohn Muir 	fuse_invalidate_entry(entry);
1173451d0f59SJohn Muir 
11742b0143b5SDavid Howells 	if (child_nodeid != 0 && d_really_is_positive(entry)) {
11755955102cSAl Viro 		inode_lock(d_inode(entry));
11762b0143b5SDavid Howells 		if (get_node_id(d_inode(entry)) != child_nodeid) {
1177451d0f59SJohn Muir 			err = -ENOENT;
1178451d0f59SJohn Muir 			goto badentry;
1179451d0f59SJohn Muir 		}
1180451d0f59SJohn Muir 		if (d_mountpoint(entry)) {
1181451d0f59SJohn Muir 			err = -EBUSY;
1182451d0f59SJohn Muir 			goto badentry;
1183451d0f59SJohn Muir 		}
1184e36cb0b8SDavid Howells 		if (d_is_dir(entry)) {
1185451d0f59SJohn Muir 			shrink_dcache_parent(entry);
1186451d0f59SJohn Muir 			if (!simple_empty(entry)) {
1187451d0f59SJohn Muir 				err = -ENOTEMPTY;
1188451d0f59SJohn Muir 				goto badentry;
1189451d0f59SJohn Muir 			}
11902b0143b5SDavid Howells 			d_inode(entry)->i_flags |= S_DEAD;
1191451d0f59SJohn Muir 		}
1192451d0f59SJohn Muir 		dont_mount(entry);
11932b0143b5SDavid Howells 		clear_nlink(d_inode(entry));
11943b463ae0SJohn Muir 		err = 0;
1195451d0f59SJohn Muir  badentry:
11965955102cSAl Viro 		inode_unlock(d_inode(entry));
1197451d0f59SJohn Muir 		if (!err)
1198451d0f59SJohn Muir 			d_delete(entry);
1199451d0f59SJohn Muir 	} else {
1200451d0f59SJohn Muir 		err = 0;
1201451d0f59SJohn Muir 	}
1202451d0f59SJohn Muir 	dput(entry);
12033b463ae0SJohn Muir 
12043b463ae0SJohn Muir  unlock:
12055955102cSAl Viro 	inode_unlock(parent);
12063b463ae0SJohn Muir 	iput(parent);
12073b463ae0SJohn Muir 	return err;
12083b463ae0SJohn Muir }
12093b463ae0SJohn Muir 
121087729a55SMiklos Szeredi /*
121187729a55SMiklos Szeredi  * Calling into a user-controlled filesystem gives the filesystem
1212c2132c1bSAnatol Pomozov  * daemon ptrace-like capabilities over the current process.  This
121387729a55SMiklos Szeredi  * means, that the filesystem daemon is able to record the exact
121487729a55SMiklos Szeredi  * filesystem operations performed, and can also control the behavior
121587729a55SMiklos Szeredi  * of the requester process in otherwise impossible ways.  For example
121687729a55SMiklos Szeredi  * it can delay the operation for arbitrary length of time allowing
121787729a55SMiklos Szeredi  * DoS against the requester.
121887729a55SMiklos Szeredi  *
121987729a55SMiklos Szeredi  * For this reason only those processes can call into the filesystem,
122087729a55SMiklos Szeredi  * for which the owner of the mount has ptrace privilege.  This
122187729a55SMiklos Szeredi  * excludes processes started by other users, suid or sgid processes.
122287729a55SMiklos Szeredi  */
1223c2132c1bSAnatol Pomozov int fuse_allow_current_process(struct fuse_conn *fc)
122487729a55SMiklos Szeredi {
1225c69e8d9cSDavid Howells 	const struct cred *cred;
1226c69e8d9cSDavid Howells 
122729433a29SMiklos Szeredi 	if (fc->allow_other)
122873f03c2bSSeth Forshee 		return current_in_userns(fc->user_ns);
122987729a55SMiklos Szeredi 
1230c2132c1bSAnatol Pomozov 	cred = current_cred();
1231499dcf20SEric W. Biederman 	if (uid_eq(cred->euid, fc->user_id) &&
1232499dcf20SEric W. Biederman 	    uid_eq(cred->suid, fc->user_id) &&
1233499dcf20SEric W. Biederman 	    uid_eq(cred->uid,  fc->user_id) &&
1234499dcf20SEric W. Biederman 	    gid_eq(cred->egid, fc->group_id) &&
1235499dcf20SEric W. Biederman 	    gid_eq(cred->sgid, fc->group_id) &&
1236499dcf20SEric W. Biederman 	    gid_eq(cred->gid,  fc->group_id))
1237c2132c1bSAnatol Pomozov 		return 1;
123887729a55SMiklos Szeredi 
1239c2132c1bSAnatol Pomozov 	return 0;
124087729a55SMiklos Szeredi }
124187729a55SMiklos Szeredi 
124231d40d74SMiklos Szeredi static int fuse_access(struct inode *inode, int mask)
124331d40d74SMiklos Szeredi {
1244fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(inode);
12457078187aSMiklos Szeredi 	FUSE_ARGS(args);
124631d40d74SMiklos Szeredi 	struct fuse_access_in inarg;
124731d40d74SMiklos Szeredi 	int err;
124831d40d74SMiklos Szeredi 
1249698fa1d1SMiklos Szeredi 	BUG_ON(mask & MAY_NOT_BLOCK);
1250698fa1d1SMiklos Szeredi 
1251fcee216bSMax Reitz 	if (fm->fc->no_access)
125231d40d74SMiklos Szeredi 		return 0;
125331d40d74SMiklos Szeredi 
125431d40d74SMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
1255e6305c43SAl Viro 	inarg.mask = mask & (MAY_READ | MAY_WRITE | MAY_EXEC);
1256d5b48543SMiklos Szeredi 	args.opcode = FUSE_ACCESS;
1257d5b48543SMiklos Szeredi 	args.nodeid = get_node_id(inode);
1258d5b48543SMiklos Szeredi 	args.in_numargs = 1;
1259d5b48543SMiklos Szeredi 	args.in_args[0].size = sizeof(inarg);
1260d5b48543SMiklos Szeredi 	args.in_args[0].value = &inarg;
1261fcee216bSMax Reitz 	err = fuse_simple_request(fm, &args);
126231d40d74SMiklos Szeredi 	if (err == -ENOSYS) {
1263fcee216bSMax Reitz 		fm->fc->no_access = 1;
126431d40d74SMiklos Szeredi 		err = 0;
126531d40d74SMiklos Szeredi 	}
126631d40d74SMiklos Szeredi 	return err;
126731d40d74SMiklos Szeredi }
126831d40d74SMiklos Szeredi 
126910556cb2SAl Viro static int fuse_perm_getattr(struct inode *inode, int mask)
127019690ddbSMiklos Szeredi {
127110556cb2SAl Viro 	if (mask & MAY_NOT_BLOCK)
127219690ddbSMiklos Szeredi 		return -ECHILD;
127319690ddbSMiklos Szeredi 
127460bcc88aSSeth Forshee 	forget_all_cached_acls(inode);
127519690ddbSMiklos Szeredi 	return fuse_do_getattr(inode, NULL, NULL);
127619690ddbSMiklos Szeredi }
127719690ddbSMiklos Szeredi 
12786f9f1180SMiklos Szeredi /*
12796f9f1180SMiklos Szeredi  * Check permission.  The two basic access models of FUSE are:
12806f9f1180SMiklos Szeredi  *
12816f9f1180SMiklos Szeredi  * 1) Local access checking ('default_permissions' mount option) based
12826f9f1180SMiklos Szeredi  * on file mode.  This is the plain old disk filesystem permission
12836f9f1180SMiklos Szeredi  * modell.
12846f9f1180SMiklos Szeredi  *
12856f9f1180SMiklos Szeredi  * 2) "Remote" access checking, where server is responsible for
12866f9f1180SMiklos Szeredi  * checking permission in each inode operation.  An exception to this
12876f9f1180SMiklos Szeredi  * is if ->permission() was invoked from sys_access() in which case an
12886f9f1180SMiklos Szeredi  * access request is sent.  Execute permission is still checked
12896f9f1180SMiklos Szeredi  * locally based on file mode.
12906f9f1180SMiklos Szeredi  */
1291549c7297SChristian Brauner static int fuse_permission(struct user_namespace *mnt_userns,
1292549c7297SChristian Brauner 			   struct inode *inode, int mask)
1293e5e5558eSMiklos Szeredi {
1294e5e5558eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
1295244f6385SMiklos Szeredi 	bool refreshed = false;
1296244f6385SMiklos Szeredi 	int err = 0;
1297e5e5558eSMiklos Szeredi 
12985d069dbeSMiklos Szeredi 	if (fuse_is_bad(inode))
12995d069dbeSMiklos Szeredi 		return -EIO;
13005d069dbeSMiklos Szeredi 
1301c2132c1bSAnatol Pomozov 	if (!fuse_allow_current_process(fc))
1302e5e5558eSMiklos Szeredi 		return -EACCES;
1303244f6385SMiklos Szeredi 
1304244f6385SMiklos Szeredi 	/*
1305e8e96157SMiklos Szeredi 	 * If attributes are needed, refresh them before proceeding
1306244f6385SMiklos Szeredi 	 */
130729433a29SMiklos Szeredi 	if (fc->default_permissions ||
1308e8e96157SMiklos Szeredi 	    ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) {
130919690ddbSMiklos Szeredi 		struct fuse_inode *fi = get_fuse_inode(inode);
1310d233c7ddSMiklos Szeredi 		u32 perm_mask = STATX_MODE | STATX_UID | STATX_GID;
131119690ddbSMiklos Szeredi 
1312d233c7ddSMiklos Szeredi 		if (perm_mask & READ_ONCE(fi->inval_mask) ||
1313d233c7ddSMiklos Szeredi 		    time_before64(fi->i_time, get_jiffies_64())) {
131419690ddbSMiklos Szeredi 			refreshed = true;
131519690ddbSMiklos Szeredi 
131610556cb2SAl Viro 			err = fuse_perm_getattr(inode, mask);
1317244f6385SMiklos Szeredi 			if (err)
1318244f6385SMiklos Szeredi 				return err;
13191fb69e78SMiklos Szeredi 		}
132019690ddbSMiklos Szeredi 	}
1321244f6385SMiklos Szeredi 
132229433a29SMiklos Szeredi 	if (fc->default_permissions) {
132347291baaSChristian Brauner 		err = generic_permission(&init_user_ns, inode, mask);
13241e9a4ed9SMiklos Szeredi 
13251e9a4ed9SMiklos Szeredi 		/* If permission is denied, try to refresh file
13261e9a4ed9SMiklos Szeredi 		   attributes.  This is also needed, because the root
13271e9a4ed9SMiklos Szeredi 		   node will at first have no permissions */
1328244f6385SMiklos Szeredi 		if (err == -EACCES && !refreshed) {
132910556cb2SAl Viro 			err = fuse_perm_getattr(inode, mask);
13301e9a4ed9SMiklos Szeredi 			if (!err)
133147291baaSChristian Brauner 				err = generic_permission(&init_user_ns,
133247291baaSChristian Brauner 							 inode, mask);
13331e9a4ed9SMiklos Szeredi 		}
13341e9a4ed9SMiklos Szeredi 
13356f9f1180SMiklos Szeredi 		/* Note: the opposite of the above test does not
13366f9f1180SMiklos Szeredi 		   exist.  So if permissions are revoked this won't be
13376f9f1180SMiklos Szeredi 		   noticed immediately, only after the attribute
13386f9f1180SMiklos Szeredi 		   timeout has expired */
13399cfcac81SEric Paris 	} else if (mask & (MAY_ACCESS | MAY_CHDIR)) {
1340e8e96157SMiklos Szeredi 		err = fuse_access(inode, mask);
1341e8e96157SMiklos Szeredi 	} else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
1342e8e96157SMiklos Szeredi 		if (!(inode->i_mode & S_IXUGO)) {
1343e8e96157SMiklos Szeredi 			if (refreshed)
1344e5e5558eSMiklos Szeredi 				return -EACCES;
134531d40d74SMiklos Szeredi 
134610556cb2SAl Viro 			err = fuse_perm_getattr(inode, mask);
1347e8e96157SMiklos Szeredi 			if (!err && !(inode->i_mode & S_IXUGO))
1348e8e96157SMiklos Szeredi 				return -EACCES;
1349e8e96157SMiklos Szeredi 		}
1350e5e5558eSMiklos Szeredi 	}
1351244f6385SMiklos Szeredi 	return err;
1352e5e5558eSMiklos Szeredi }
1353e5e5558eSMiklos Szeredi 
13545571f1e6SDan Schatzberg static int fuse_readlink_page(struct inode *inode, struct page *page)
1355e5e5558eSMiklos Szeredi {
1356fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(inode);
13574c29afecSMiklos Szeredi 	struct fuse_page_desc desc = { .length = PAGE_SIZE - 1 };
13584c29afecSMiklos Szeredi 	struct fuse_args_pages ap = {
13594c29afecSMiklos Szeredi 		.num_pages = 1,
13604c29afecSMiklos Szeredi 		.pages = &page,
13614c29afecSMiklos Szeredi 		.descs = &desc,
13624c29afecSMiklos Szeredi 	};
13634c29afecSMiklos Szeredi 	char *link;
13644c29afecSMiklos Szeredi 	ssize_t res;
1365e5e5558eSMiklos Szeredi 
13664c29afecSMiklos Szeredi 	ap.args.opcode = FUSE_READLINK;
13674c29afecSMiklos Szeredi 	ap.args.nodeid = get_node_id(inode);
13684c29afecSMiklos Szeredi 	ap.args.out_pages = true;
13694c29afecSMiklos Szeredi 	ap.args.out_argvar = true;
13704c29afecSMiklos Szeredi 	ap.args.page_zeroing = true;
13714c29afecSMiklos Szeredi 	ap.args.out_numargs = 1;
13724c29afecSMiklos Szeredi 	ap.args.out_args[0].size = desc.length;
1373fcee216bSMax Reitz 	res = fuse_simple_request(fm, &ap.args);
13746b255391SAl Viro 
1375451418fcSAndrew Gallagher 	fuse_invalidate_atime(inode);
13765571f1e6SDan Schatzberg 
13774c29afecSMiklos Szeredi 	if (res < 0)
13784c29afecSMiklos Szeredi 		return res;
13794c29afecSMiklos Szeredi 
13804c29afecSMiklos Szeredi 	if (WARN_ON(res >= PAGE_SIZE))
13814c29afecSMiklos Szeredi 		return -EIO;
13824c29afecSMiklos Szeredi 
13834c29afecSMiklos Szeredi 	link = page_address(page);
13844c29afecSMiklos Szeredi 	link[res] = '\0';
13854c29afecSMiklos Szeredi 
13864c29afecSMiklos Szeredi 	return 0;
13875571f1e6SDan Schatzberg }
13885571f1e6SDan Schatzberg 
13895571f1e6SDan Schatzberg static const char *fuse_get_link(struct dentry *dentry, struct inode *inode,
13905571f1e6SDan Schatzberg 				 struct delayed_call *callback)
13915571f1e6SDan Schatzberg {
13925571f1e6SDan Schatzberg 	struct fuse_conn *fc = get_fuse_conn(inode);
13935571f1e6SDan Schatzberg 	struct page *page;
13945571f1e6SDan Schatzberg 	int err;
13955571f1e6SDan Schatzberg 
13965571f1e6SDan Schatzberg 	err = -EIO;
13975d069dbeSMiklos Szeredi 	if (fuse_is_bad(inode))
13985571f1e6SDan Schatzberg 		goto out_err;
13995571f1e6SDan Schatzberg 
14005571f1e6SDan Schatzberg 	if (fc->cache_symlinks)
14015571f1e6SDan Schatzberg 		return page_get_link(dentry, inode, callback);
14025571f1e6SDan Schatzberg 
14035571f1e6SDan Schatzberg 	err = -ECHILD;
14045571f1e6SDan Schatzberg 	if (!dentry)
14055571f1e6SDan Schatzberg 		goto out_err;
14065571f1e6SDan Schatzberg 
14075571f1e6SDan Schatzberg 	page = alloc_page(GFP_KERNEL);
14085571f1e6SDan Schatzberg 	err = -ENOMEM;
14095571f1e6SDan Schatzberg 	if (!page)
14105571f1e6SDan Schatzberg 		goto out_err;
14115571f1e6SDan Schatzberg 
14125571f1e6SDan Schatzberg 	err = fuse_readlink_page(inode, page);
14135571f1e6SDan Schatzberg 	if (err) {
14145571f1e6SDan Schatzberg 		__free_page(page);
14155571f1e6SDan Schatzberg 		goto out_err;
14165571f1e6SDan Schatzberg 	}
14175571f1e6SDan Schatzberg 
14185571f1e6SDan Schatzberg 	set_delayed_call(callback, page_put_link, page);
14195571f1e6SDan Schatzberg 
14205571f1e6SDan Schatzberg 	return page_address(page);
14215571f1e6SDan Schatzberg 
14225571f1e6SDan Schatzberg out_err:
14235571f1e6SDan Schatzberg 	return ERR_PTR(err);
1424e5e5558eSMiklos Szeredi }
1425e5e5558eSMiklos Szeredi 
1426e5e5558eSMiklos Szeredi static int fuse_dir_open(struct inode *inode, struct file *file)
1427e5e5558eSMiklos Szeredi {
142891fe96b4SMiklos Szeredi 	return fuse_open_common(inode, file, true);
1429e5e5558eSMiklos Szeredi }
1430e5e5558eSMiklos Szeredi 
1431e5e5558eSMiklos Szeredi static int fuse_dir_release(struct inode *inode, struct file *file)
1432e5e5558eSMiklos Szeredi {
14332e64ff15SChad Austin 	fuse_release_common(file, true);
14348b0797a4SMiklos Szeredi 
14358b0797a4SMiklos Szeredi 	return 0;
1436e5e5558eSMiklos Szeredi }
1437e5e5558eSMiklos Szeredi 
143802c24a82SJosef Bacik static int fuse_dir_fsync(struct file *file, loff_t start, loff_t end,
143902c24a82SJosef Bacik 			  int datasync)
144082547981SMiklos Szeredi {
1441a9c2d1e8SMiklos Szeredi 	struct inode *inode = file->f_mapping->host;
1442a9c2d1e8SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
1443a9c2d1e8SMiklos Szeredi 	int err;
1444a9c2d1e8SMiklos Szeredi 
14455d069dbeSMiklos Szeredi 	if (fuse_is_bad(inode))
1446a9c2d1e8SMiklos Szeredi 		return -EIO;
1447a9c2d1e8SMiklos Szeredi 
1448a9c2d1e8SMiklos Szeredi 	if (fc->no_fsyncdir)
1449a9c2d1e8SMiklos Szeredi 		return 0;
1450a9c2d1e8SMiklos Szeredi 
1451a9c2d1e8SMiklos Szeredi 	inode_lock(inode);
1452a9c2d1e8SMiklos Szeredi 	err = fuse_fsync_common(file, start, end, datasync, FUSE_FSYNCDIR);
1453a9c2d1e8SMiklos Szeredi 	if (err == -ENOSYS) {
1454a9c2d1e8SMiklos Szeredi 		fc->no_fsyncdir = 1;
1455a9c2d1e8SMiklos Szeredi 		err = 0;
1456a9c2d1e8SMiklos Szeredi 	}
1457a9c2d1e8SMiklos Szeredi 	inode_unlock(inode);
1458a9c2d1e8SMiklos Szeredi 
1459a9c2d1e8SMiklos Szeredi 	return err;
146082547981SMiklos Szeredi }
146182547981SMiklos Szeredi 
1462b18da0c5SMiklos Szeredi static long fuse_dir_ioctl(struct file *file, unsigned int cmd,
1463b18da0c5SMiklos Szeredi 			    unsigned long arg)
1464b18da0c5SMiklos Szeredi {
1465b18da0c5SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1466b18da0c5SMiklos Szeredi 
1467b18da0c5SMiklos Szeredi 	/* FUSE_IOCTL_DIR only supported for API version >= 7.18 */
1468b18da0c5SMiklos Szeredi 	if (fc->minor < 18)
1469b18da0c5SMiklos Szeredi 		return -ENOTTY;
1470b18da0c5SMiklos Szeredi 
1471b18da0c5SMiklos Szeredi 	return fuse_ioctl_common(file, cmd, arg, FUSE_IOCTL_DIR);
1472b18da0c5SMiklos Szeredi }
1473b18da0c5SMiklos Szeredi 
1474b18da0c5SMiklos Szeredi static long fuse_dir_compat_ioctl(struct file *file, unsigned int cmd,
1475b18da0c5SMiklos Szeredi 				   unsigned long arg)
1476b18da0c5SMiklos Szeredi {
1477b18da0c5SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1478b18da0c5SMiklos Szeredi 
1479b18da0c5SMiklos Szeredi 	if (fc->minor < 18)
1480b18da0c5SMiklos Szeredi 		return -ENOTTY;
1481b18da0c5SMiklos Szeredi 
1482b18da0c5SMiklos Szeredi 	return fuse_ioctl_common(file, cmd, arg,
1483b18da0c5SMiklos Szeredi 				 FUSE_IOCTL_COMPAT | FUSE_IOCTL_DIR);
1484b18da0c5SMiklos Szeredi }
1485b18da0c5SMiklos Szeredi 
1486b0aa7606SMaxim Patlasov static bool update_mtime(unsigned ivalid, bool trust_local_mtime)
148717637cbaSMiklos Szeredi {
148817637cbaSMiklos Szeredi 	/* Always update if mtime is explicitly set  */
148917637cbaSMiklos Szeredi 	if (ivalid & ATTR_MTIME_SET)
149017637cbaSMiklos Szeredi 		return true;
149117637cbaSMiklos Szeredi 
1492b0aa7606SMaxim Patlasov 	/* Or if kernel i_mtime is the official one */
1493b0aa7606SMaxim Patlasov 	if (trust_local_mtime)
1494b0aa7606SMaxim Patlasov 		return true;
1495b0aa7606SMaxim Patlasov 
149617637cbaSMiklos Szeredi 	/* If it's an open(O_TRUNC) or an ftruncate(), don't update */
149717637cbaSMiklos Szeredi 	if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE)))
149817637cbaSMiklos Szeredi 		return false;
149917637cbaSMiklos Szeredi 
150017637cbaSMiklos Szeredi 	/* In all other cases update */
150117637cbaSMiklos Szeredi 	return true;
150217637cbaSMiklos Szeredi }
150317637cbaSMiklos Szeredi 
15048cb08329SEric W. Biederman static void iattr_to_fattr(struct fuse_conn *fc, struct iattr *iattr,
15058cb08329SEric W. Biederman 			   struct fuse_setattr_in *arg, bool trust_local_cmtime)
15069e6268dbSMiklos Szeredi {
15079e6268dbSMiklos Szeredi 	unsigned ivalid = iattr->ia_valid;
15089e6268dbSMiklos Szeredi 
15099e6268dbSMiklos Szeredi 	if (ivalid & ATTR_MODE)
1510befc649cSMiklos Szeredi 		arg->valid |= FATTR_MODE,   arg->mode = iattr->ia_mode;
15119e6268dbSMiklos Szeredi 	if (ivalid & ATTR_UID)
15128cb08329SEric W. Biederman 		arg->valid |= FATTR_UID,    arg->uid = from_kuid(fc->user_ns, iattr->ia_uid);
15139e6268dbSMiklos Szeredi 	if (ivalid & ATTR_GID)
15148cb08329SEric W. Biederman 		arg->valid |= FATTR_GID,    arg->gid = from_kgid(fc->user_ns, iattr->ia_gid);
15159e6268dbSMiklos Szeredi 	if (ivalid & ATTR_SIZE)
1516befc649cSMiklos Szeredi 		arg->valid |= FATTR_SIZE,   arg->size = iattr->ia_size;
151717637cbaSMiklos Szeredi 	if (ivalid & ATTR_ATIME) {
151817637cbaSMiklos Szeredi 		arg->valid |= FATTR_ATIME;
1519befc649cSMiklos Szeredi 		arg->atime = iattr->ia_atime.tv_sec;
152017637cbaSMiklos Szeredi 		arg->atimensec = iattr->ia_atime.tv_nsec;
152117637cbaSMiklos Szeredi 		if (!(ivalid & ATTR_ATIME_SET))
152217637cbaSMiklos Szeredi 			arg->valid |= FATTR_ATIME_NOW;
152317637cbaSMiklos Szeredi 	}
15243ad22c62SMaxim Patlasov 	if ((ivalid & ATTR_MTIME) && update_mtime(ivalid, trust_local_cmtime)) {
152517637cbaSMiklos Szeredi 		arg->valid |= FATTR_MTIME;
1526befc649cSMiklos Szeredi 		arg->mtime = iattr->ia_mtime.tv_sec;
152717637cbaSMiklos Szeredi 		arg->mtimensec = iattr->ia_mtime.tv_nsec;
15283ad22c62SMaxim Patlasov 		if (!(ivalid & ATTR_MTIME_SET) && !trust_local_cmtime)
152917637cbaSMiklos Szeredi 			arg->valid |= FATTR_MTIME_NOW;
15309e6268dbSMiklos Szeredi 	}
15313ad22c62SMaxim Patlasov 	if ((ivalid & ATTR_CTIME) && trust_local_cmtime) {
15323ad22c62SMaxim Patlasov 		arg->valid |= FATTR_CTIME;
15333ad22c62SMaxim Patlasov 		arg->ctime = iattr->ia_ctime.tv_sec;
15343ad22c62SMaxim Patlasov 		arg->ctimensec = iattr->ia_ctime.tv_nsec;
15353ad22c62SMaxim Patlasov 	}
15369e6268dbSMiklos Szeredi }
15379e6268dbSMiklos Szeredi 
15386f9f1180SMiklos Szeredi /*
15393be5a52bSMiklos Szeredi  * Prevent concurrent writepages on inode
15403be5a52bSMiklos Szeredi  *
15413be5a52bSMiklos Szeredi  * This is done by adding a negative bias to the inode write counter
15423be5a52bSMiklos Szeredi  * and waiting for all pending writes to finish.
15433be5a52bSMiklos Szeredi  */
15443be5a52bSMiklos Szeredi void fuse_set_nowrite(struct inode *inode)
15453be5a52bSMiklos Szeredi {
15463be5a52bSMiklos Szeredi 	struct fuse_inode *fi = get_fuse_inode(inode);
15473be5a52bSMiklos Szeredi 
15485955102cSAl Viro 	BUG_ON(!inode_is_locked(inode));
15493be5a52bSMiklos Szeredi 
1550f15ecfefSKirill Tkhai 	spin_lock(&fi->lock);
15513be5a52bSMiklos Szeredi 	BUG_ON(fi->writectr < 0);
15523be5a52bSMiklos Szeredi 	fi->writectr += FUSE_NOWRITE;
1553f15ecfefSKirill Tkhai 	spin_unlock(&fi->lock);
15543be5a52bSMiklos Szeredi 	wait_event(fi->page_waitq, fi->writectr == FUSE_NOWRITE);
15553be5a52bSMiklos Szeredi }
15563be5a52bSMiklos Szeredi 
15573be5a52bSMiklos Szeredi /*
15583be5a52bSMiklos Szeredi  * Allow writepages on inode
15593be5a52bSMiklos Szeredi  *
15603be5a52bSMiklos Szeredi  * Remove the bias from the writecounter and send any queued
15613be5a52bSMiklos Szeredi  * writepages.
15623be5a52bSMiklos Szeredi  */
15633be5a52bSMiklos Szeredi static void __fuse_release_nowrite(struct inode *inode)
15643be5a52bSMiklos Szeredi {
15653be5a52bSMiklos Szeredi 	struct fuse_inode *fi = get_fuse_inode(inode);
15663be5a52bSMiklos Szeredi 
15673be5a52bSMiklos Szeredi 	BUG_ON(fi->writectr != FUSE_NOWRITE);
15683be5a52bSMiklos Szeredi 	fi->writectr = 0;
15693be5a52bSMiklos Szeredi 	fuse_flush_writepages(inode);
15703be5a52bSMiklos Szeredi }
15713be5a52bSMiklos Szeredi 
15723be5a52bSMiklos Szeredi void fuse_release_nowrite(struct inode *inode)
15733be5a52bSMiklos Szeredi {
1574f15ecfefSKirill Tkhai 	struct fuse_inode *fi = get_fuse_inode(inode);
15753be5a52bSMiklos Szeredi 
1576f15ecfefSKirill Tkhai 	spin_lock(&fi->lock);
15773be5a52bSMiklos Szeredi 	__fuse_release_nowrite(inode);
1578f15ecfefSKirill Tkhai 	spin_unlock(&fi->lock);
15793be5a52bSMiklos Szeredi }
15803be5a52bSMiklos Szeredi 
15817078187aSMiklos Szeredi static void fuse_setattr_fill(struct fuse_conn *fc, struct fuse_args *args,
1582b0aa7606SMaxim Patlasov 			      struct inode *inode,
1583b0aa7606SMaxim Patlasov 			      struct fuse_setattr_in *inarg_p,
1584b0aa7606SMaxim Patlasov 			      struct fuse_attr_out *outarg_p)
1585b0aa7606SMaxim Patlasov {
1586d5b48543SMiklos Szeredi 	args->opcode = FUSE_SETATTR;
1587d5b48543SMiklos Szeredi 	args->nodeid = get_node_id(inode);
1588d5b48543SMiklos Szeredi 	args->in_numargs = 1;
1589d5b48543SMiklos Szeredi 	args->in_args[0].size = sizeof(*inarg_p);
1590d5b48543SMiklos Szeredi 	args->in_args[0].value = inarg_p;
1591d5b48543SMiklos Szeredi 	args->out_numargs = 1;
1592d5b48543SMiklos Szeredi 	args->out_args[0].size = sizeof(*outarg_p);
1593d5b48543SMiklos Szeredi 	args->out_args[0].value = outarg_p;
1594b0aa7606SMaxim Patlasov }
1595b0aa7606SMaxim Patlasov 
1596b0aa7606SMaxim Patlasov /*
1597b0aa7606SMaxim Patlasov  * Flush inode->i_mtime to the server
1598b0aa7606SMaxim Patlasov  */
1599ab9e13f7SMaxim Patlasov int fuse_flush_times(struct inode *inode, struct fuse_file *ff)
1600b0aa7606SMaxim Patlasov {
1601fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(inode);
16027078187aSMiklos Szeredi 	FUSE_ARGS(args);
1603b0aa7606SMaxim Patlasov 	struct fuse_setattr_in inarg;
1604b0aa7606SMaxim Patlasov 	struct fuse_attr_out outarg;
1605b0aa7606SMaxim Patlasov 
1606b0aa7606SMaxim Patlasov 	memset(&inarg, 0, sizeof(inarg));
1607b0aa7606SMaxim Patlasov 	memset(&outarg, 0, sizeof(outarg));
1608b0aa7606SMaxim Patlasov 
1609ab9e13f7SMaxim Patlasov 	inarg.valid = FATTR_MTIME;
1610b0aa7606SMaxim Patlasov 	inarg.mtime = inode->i_mtime.tv_sec;
1611b0aa7606SMaxim Patlasov 	inarg.mtimensec = inode->i_mtime.tv_nsec;
1612fcee216bSMax Reitz 	if (fm->fc->minor >= 23) {
1613ab9e13f7SMaxim Patlasov 		inarg.valid |= FATTR_CTIME;
1614ab9e13f7SMaxim Patlasov 		inarg.ctime = inode->i_ctime.tv_sec;
1615ab9e13f7SMaxim Patlasov 		inarg.ctimensec = inode->i_ctime.tv_nsec;
1616ab9e13f7SMaxim Patlasov 	}
16171e18bda8SMiklos Szeredi 	if (ff) {
16181e18bda8SMiklos Szeredi 		inarg.valid |= FATTR_FH;
16191e18bda8SMiklos Szeredi 		inarg.fh = ff->fh;
16201e18bda8SMiklos Szeredi 	}
1621fcee216bSMax Reitz 	fuse_setattr_fill(fm->fc, &args, inode, &inarg, &outarg);
1622b0aa7606SMaxim Patlasov 
1623fcee216bSMax Reitz 	return fuse_simple_request(fm, &args);
1624b0aa7606SMaxim Patlasov }
1625b0aa7606SMaxim Patlasov 
16263be5a52bSMiklos Szeredi /*
16276f9f1180SMiklos Szeredi  * Set attributes, and at the same time refresh them.
16286f9f1180SMiklos Szeredi  *
16296f9f1180SMiklos Szeredi  * Truncation is slightly complicated, because the 'truncate' request
16306f9f1180SMiklos Szeredi  * may fail, in which case we don't want to touch the mapping.
16319ffbb916SMiklos Szeredi  * vmtruncate() doesn't allow for this case, so do the rlimit checking
16329ffbb916SMiklos Szeredi  * and the actual truncation by hand.
16336f9f1180SMiklos Szeredi  */
163462490330SJan Kara int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
163549d4914fSMiklos Szeredi 		    struct file *file)
16369e6268dbSMiklos Szeredi {
163762490330SJan Kara 	struct inode *inode = d_inode(dentry);
1638fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(inode);
1639fcee216bSMax Reitz 	struct fuse_conn *fc = fm->fc;
164006a7c3c2SMaxim Patlasov 	struct fuse_inode *fi = get_fuse_inode(inode);
16418bcbbe9cSJan Kara 	struct address_space *mapping = inode->i_mapping;
16427078187aSMiklos Szeredi 	FUSE_ARGS(args);
16439e6268dbSMiklos Szeredi 	struct fuse_setattr_in inarg;
16449e6268dbSMiklos Szeredi 	struct fuse_attr_out outarg;
16453be5a52bSMiklos Szeredi 	bool is_truncate = false;
1646c15016b7SMiklos Szeredi 	bool is_wb = fc->writeback_cache && S_ISREG(inode->i_mode);
16473be5a52bSMiklos Szeredi 	loff_t oldsize;
16489e6268dbSMiklos Szeredi 	int err;
1649c15016b7SMiklos Szeredi 	bool trust_local_cmtime = is_wb;
16506ae330caSVivek Goyal 	bool fault_blocked = false;
16519e6268dbSMiklos Szeredi 
165229433a29SMiklos Szeredi 	if (!fc->default_permissions)
1653db78b877SChristoph Hellwig 		attr->ia_valid |= ATTR_FORCE;
1654db78b877SChristoph Hellwig 
16552f221d6fSChristian Brauner 	err = setattr_prepare(&init_user_ns, dentry, attr);
16561e9a4ed9SMiklos Szeredi 	if (err)
16571e9a4ed9SMiklos Szeredi 		return err;
16581e9a4ed9SMiklos Szeredi 
16596ae330caSVivek Goyal 	if (attr->ia_valid & ATTR_SIZE) {
16606ae330caSVivek Goyal 		if (WARN_ON(!S_ISREG(inode->i_mode)))
16616ae330caSVivek Goyal 			return -EIO;
16626ae330caSVivek Goyal 		is_truncate = true;
16636ae330caSVivek Goyal 	}
16646ae330caSVivek Goyal 
16656ae330caSVivek Goyal 	if (FUSE_IS_DAX(inode) && is_truncate) {
16668bcbbe9cSJan Kara 		filemap_invalidate_lock(mapping);
16676ae330caSVivek Goyal 		fault_blocked = true;
16686ae330caSVivek Goyal 		err = fuse_dax_break_layouts(inode, 0, 0);
16696ae330caSVivek Goyal 		if (err) {
16708bcbbe9cSJan Kara 			filemap_invalidate_unlock(mapping);
16716ae330caSVivek Goyal 			return err;
16726ae330caSVivek Goyal 		}
16736ae330caSVivek Goyal 	}
16746ae330caSVivek Goyal 
16758d56adddSMiklos Szeredi 	if (attr->ia_valid & ATTR_OPEN) {
1676df0e91d4SMiklos Szeredi 		/* This is coming from open(..., ... | O_TRUNC); */
1677df0e91d4SMiklos Szeredi 		WARN_ON(!(attr->ia_valid & ATTR_SIZE));
1678df0e91d4SMiklos Szeredi 		WARN_ON(attr->ia_size != 0);
1679df0e91d4SMiklos Szeredi 		if (fc->atomic_o_trunc) {
1680df0e91d4SMiklos Szeredi 			/*
1681df0e91d4SMiklos Szeredi 			 * No need to send request to userspace, since actual
1682df0e91d4SMiklos Szeredi 			 * truncation has already been done by OPEN.  But still
1683df0e91d4SMiklos Szeredi 			 * need to truncate page cache.
1684df0e91d4SMiklos Szeredi 			 */
1685df0e91d4SMiklos Szeredi 			i_size_write(inode, 0);
1686df0e91d4SMiklos Szeredi 			truncate_pagecache(inode, 0);
16876ae330caSVivek Goyal 			goto out;
1688df0e91d4SMiklos Szeredi 		}
16898d56adddSMiklos Szeredi 		file = NULL;
16908d56adddSMiklos Szeredi 	}
16916ff958edSMiklos Szeredi 
1692b24e7598SMiklos Szeredi 	/* Flush dirty data/metadata before non-truncate SETATTR */
1693c15016b7SMiklos Szeredi 	if (is_wb &&
1694b24e7598SMiklos Szeredi 	    attr->ia_valid &
1695b24e7598SMiklos Szeredi 			(ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_MTIME_SET |
1696b24e7598SMiklos Szeredi 			 ATTR_TIMES_SET)) {
1697b24e7598SMiklos Szeredi 		err = write_inode_now(inode, true);
1698b24e7598SMiklos Szeredi 		if (err)
1699b24e7598SMiklos Szeredi 			return err;
1700b24e7598SMiklos Szeredi 
1701b24e7598SMiklos Szeredi 		fuse_set_nowrite(inode);
1702b24e7598SMiklos Szeredi 		fuse_release_nowrite(inode);
1703b24e7598SMiklos Szeredi 	}
1704b24e7598SMiklos Szeredi 
170506a7c3c2SMaxim Patlasov 	if (is_truncate) {
17063be5a52bSMiklos Szeredi 		fuse_set_nowrite(inode);
170706a7c3c2SMaxim Patlasov 		set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
17083ad22c62SMaxim Patlasov 		if (trust_local_cmtime && attr->ia_size != inode->i_size)
17093ad22c62SMaxim Patlasov 			attr->ia_valid |= ATTR_MTIME | ATTR_CTIME;
171006a7c3c2SMaxim Patlasov 	}
17113be5a52bSMiklos Szeredi 
17129e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
17130e9663eeSMiklos Szeredi 	memset(&outarg, 0, sizeof(outarg));
17148cb08329SEric W. Biederman 	iattr_to_fattr(fc, attr, &inarg, trust_local_cmtime);
171549d4914fSMiklos Szeredi 	if (file) {
171649d4914fSMiklos Szeredi 		struct fuse_file *ff = file->private_data;
171749d4914fSMiklos Szeredi 		inarg.valid |= FATTR_FH;
171849d4914fSMiklos Szeredi 		inarg.fh = ff->fh;
171949d4914fSMiklos Szeredi 	}
172031792161SVivek Goyal 
172131792161SVivek Goyal 	/* Kill suid/sgid for non-directory chown unconditionally */
172231792161SVivek Goyal 	if (fc->handle_killpriv_v2 && !S_ISDIR(inode->i_mode) &&
172331792161SVivek Goyal 	    attr->ia_valid & (ATTR_UID | ATTR_GID))
172431792161SVivek Goyal 		inarg.valid |= FATTR_KILL_SUIDGID;
172531792161SVivek Goyal 
1726f3332114SMiklos Szeredi 	if (attr->ia_valid & ATTR_SIZE) {
1727f3332114SMiklos Szeredi 		/* For mandatory locking in truncate */
1728f3332114SMiklos Szeredi 		inarg.valid |= FATTR_LOCKOWNER;
1729f3332114SMiklos Szeredi 		inarg.lock_owner = fuse_lock_owner_id(fc, current->files);
173031792161SVivek Goyal 
173131792161SVivek Goyal 		/* Kill suid/sgid for truncate only if no CAP_FSETID */
173231792161SVivek Goyal 		if (fc->handle_killpriv_v2 && !capable(CAP_FSETID))
173331792161SVivek Goyal 			inarg.valid |= FATTR_KILL_SUIDGID;
1734f3332114SMiklos Szeredi 	}
17357078187aSMiklos Szeredi 	fuse_setattr_fill(fc, &args, inode, &inarg, &outarg);
1736fcee216bSMax Reitz 	err = fuse_simple_request(fm, &args);
1737e00d2c2dSMiklos Szeredi 	if (err) {
1738e00d2c2dSMiklos Szeredi 		if (err == -EINTR)
1739e00d2c2dSMiklos Szeredi 			fuse_invalidate_attr(inode);
17403be5a52bSMiklos Szeredi 		goto error;
1741e00d2c2dSMiklos Szeredi 	}
1742e00d2c2dSMiklos Szeredi 
1743eb59bd17SMiklos Szeredi 	if (fuse_invalid_attr(&outarg.attr) ||
17446e3e2c43SAl Viro 	    inode_wrong_type(inode, outarg.attr.mode)) {
17455d069dbeSMiklos Szeredi 		fuse_make_bad(inode);
17463be5a52bSMiklos Szeredi 		err = -EIO;
17473be5a52bSMiklos Szeredi 		goto error;
17489e6268dbSMiklos Szeredi 	}
17499e6268dbSMiklos Szeredi 
1750f15ecfefSKirill Tkhai 	spin_lock(&fi->lock);
1751b0aa7606SMaxim Patlasov 	/* the kernel maintains i_mtime locally */
17523ad22c62SMaxim Patlasov 	if (trust_local_cmtime) {
17533ad22c62SMaxim Patlasov 		if (attr->ia_valid & ATTR_MTIME)
1754b0aa7606SMaxim Patlasov 			inode->i_mtime = attr->ia_mtime;
17553ad22c62SMaxim Patlasov 		if (attr->ia_valid & ATTR_CTIME)
17563ad22c62SMaxim Patlasov 			inode->i_ctime = attr->ia_ctime;
17571e18bda8SMiklos Szeredi 		/* FIXME: clear I_DIRTY_SYNC? */
1758b0aa7606SMaxim Patlasov 	}
1759b0aa7606SMaxim Patlasov 
17603be5a52bSMiklos Szeredi 	fuse_change_attributes_common(inode, &outarg.attr,
17614b52f059SMiklos Szeredi 				      attr_timeout(&outarg),
17624b52f059SMiklos Szeredi 				      fuse_get_cache_mask(inode));
17633be5a52bSMiklos Szeredi 	oldsize = inode->i_size;
17648373200bSPavel Emelyanov 	/* see the comment in fuse_change_attributes() */
1765c15016b7SMiklos Szeredi 	if (!is_wb || is_truncate)
17663be5a52bSMiklos Szeredi 		i_size_write(inode, outarg.attr.size);
17673be5a52bSMiklos Szeredi 
17683be5a52bSMiklos Szeredi 	if (is_truncate) {
1769f15ecfefSKirill Tkhai 		/* NOTE: this may release/reacquire fi->lock */
17703be5a52bSMiklos Szeredi 		__fuse_release_nowrite(inode);
17713be5a52bSMiklos Szeredi 	}
1772f15ecfefSKirill Tkhai 	spin_unlock(&fi->lock);
17733be5a52bSMiklos Szeredi 
17743be5a52bSMiklos Szeredi 	/*
17753be5a52bSMiklos Szeredi 	 * Only call invalidate_inode_pages2() after removing
17762bf06b8eSMatthew Wilcox (Oracle) 	 * FUSE_NOWRITE, otherwise fuse_launder_folio() would deadlock.
17773be5a52bSMiklos Szeredi 	 */
17788373200bSPavel Emelyanov 	if ((is_truncate || !is_wb) &&
17798373200bSPavel Emelyanov 	    S_ISREG(inode->i_mode) && oldsize != outarg.attr.size) {
17807caef267SKirill A. Shutemov 		truncate_pagecache(inode, outarg.attr.size);
17818bcbbe9cSJan Kara 		invalidate_inode_pages2(mapping);
17823be5a52bSMiklos Szeredi 	}
17833be5a52bSMiklos Szeredi 
178406a7c3c2SMaxim Patlasov 	clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
17856ae330caSVivek Goyal out:
17866ae330caSVivek Goyal 	if (fault_blocked)
17878bcbbe9cSJan Kara 		filemap_invalidate_unlock(mapping);
17886ae330caSVivek Goyal 
1789e00d2c2dSMiklos Szeredi 	return 0;
17903be5a52bSMiklos Szeredi 
17913be5a52bSMiklos Szeredi error:
17923be5a52bSMiklos Szeredi 	if (is_truncate)
17933be5a52bSMiklos Szeredi 		fuse_release_nowrite(inode);
17943be5a52bSMiklos Szeredi 
179506a7c3c2SMaxim Patlasov 	clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
17966ae330caSVivek Goyal 
17976ae330caSVivek Goyal 	if (fault_blocked)
17988bcbbe9cSJan Kara 		filemap_invalidate_unlock(mapping);
17993be5a52bSMiklos Szeredi 	return err;
18009e6268dbSMiklos Szeredi }
18019e6268dbSMiklos Szeredi 
1802549c7297SChristian Brauner static int fuse_setattr(struct user_namespace *mnt_userns, struct dentry *entry,
1803549c7297SChristian Brauner 			struct iattr *attr)
180449d4914fSMiklos Szeredi {
18052b0143b5SDavid Howells 	struct inode *inode = d_inode(entry);
18065e940c1dSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
1807a09f99edSMiklos Szeredi 	struct file *file = (attr->ia_valid & ATTR_FILE) ? attr->ia_file : NULL;
18085e2b8828SMiklos Szeredi 	int ret;
1809efb9fa9eSMaxim Patlasov 
18105d069dbeSMiklos Szeredi 	if (fuse_is_bad(inode))
18115d069dbeSMiklos Szeredi 		return -EIO;
18125d069dbeSMiklos Szeredi 
1813efb9fa9eSMaxim Patlasov 	if (!fuse_allow_current_process(get_fuse_conn(inode)))
1814efb9fa9eSMaxim Patlasov 		return -EACCES;
1815efb9fa9eSMaxim Patlasov 
1816a09f99edSMiklos Szeredi 	if (attr->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) {
1817a09f99edSMiklos Szeredi 		attr->ia_valid &= ~(ATTR_KILL_SUID | ATTR_KILL_SGID |
1818a09f99edSMiklos Szeredi 				    ATTR_MODE);
18195e940c1dSMiklos Szeredi 
1820a09f99edSMiklos Szeredi 		/*
18215e940c1dSMiklos Szeredi 		 * The only sane way to reliably kill suid/sgid is to do it in
18225e940c1dSMiklos Szeredi 		 * the userspace filesystem
18235e940c1dSMiklos Szeredi 		 *
18245e940c1dSMiklos Szeredi 		 * This should be done on write(), truncate() and chown().
18255e940c1dSMiklos Szeredi 		 */
18268981bdfdSVivek Goyal 		if (!fc->handle_killpriv && !fc->handle_killpriv_v2) {
18275e940c1dSMiklos Szeredi 			/*
18285e940c1dSMiklos Szeredi 			 * ia_mode calculation may have used stale i_mode.
18295e940c1dSMiklos Szeredi 			 * Refresh and recalculate.
1830a09f99edSMiklos Szeredi 			 */
1831a09f99edSMiklos Szeredi 			ret = fuse_do_getattr(inode, NULL, file);
1832a09f99edSMiklos Szeredi 			if (ret)
1833a09f99edSMiklos Szeredi 				return ret;
1834a09f99edSMiklos Szeredi 
1835a09f99edSMiklos Szeredi 			attr->ia_mode = inode->i_mode;
1836c01638f5SMiklos Szeredi 			if (inode->i_mode & S_ISUID) {
1837a09f99edSMiklos Szeredi 				attr->ia_valid |= ATTR_MODE;
1838a09f99edSMiklos Szeredi 				attr->ia_mode &= ~S_ISUID;
1839a09f99edSMiklos Szeredi 			}
1840c01638f5SMiklos Szeredi 			if ((inode->i_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
1841a09f99edSMiklos Szeredi 				attr->ia_valid |= ATTR_MODE;
1842a09f99edSMiklos Szeredi 				attr->ia_mode &= ~S_ISGID;
1843a09f99edSMiklos Szeredi 			}
1844a09f99edSMiklos Szeredi 		}
18455e940c1dSMiklos Szeredi 	}
1846a09f99edSMiklos Szeredi 	if (!attr->ia_valid)
1847a09f99edSMiklos Szeredi 		return 0;
1848a09f99edSMiklos Szeredi 
1849abb5a14fSLinus Torvalds 	ret = fuse_do_setattr(entry, attr, file);
18505e2b8828SMiklos Szeredi 	if (!ret) {
185160bcc88aSSeth Forshee 		/*
185260bcc88aSSeth Forshee 		 * If filesystem supports acls it may have updated acl xattrs in
185360bcc88aSSeth Forshee 		 * the filesystem, so forget cached acls for the inode.
185460bcc88aSSeth Forshee 		 */
185560bcc88aSSeth Forshee 		if (fc->posix_acl)
185660bcc88aSSeth Forshee 			forget_all_cached_acls(inode);
185760bcc88aSSeth Forshee 
18585e2b8828SMiklos Szeredi 		/* Directory mode changed, may need to revalidate access */
18595e2b8828SMiklos Szeredi 		if (d_is_dir(entry) && (attr->ia_valid & ATTR_MODE))
18605e2b8828SMiklos Szeredi 			fuse_invalidate_entry_cache(entry);
18615e2b8828SMiklos Szeredi 	}
18625e2b8828SMiklos Szeredi 	return ret;
186349d4914fSMiklos Szeredi }
186449d4914fSMiklos Szeredi 
1865549c7297SChristian Brauner static int fuse_getattr(struct user_namespace *mnt_userns,
1866549c7297SChristian Brauner 			const struct path *path, struct kstat *stat,
1867a528d35eSDavid Howells 			u32 request_mask, unsigned int flags)
1868e5e5558eSMiklos Szeredi {
1869a528d35eSDavid Howells 	struct inode *inode = d_inode(path->dentry);
1870244f6385SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
1871244f6385SMiklos Szeredi 
18725d069dbeSMiklos Szeredi 	if (fuse_is_bad(inode))
18735d069dbeSMiklos Szeredi 		return -EIO;
18745d069dbeSMiklos Szeredi 
18755157da2cSMiklos Szeredi 	if (!fuse_allow_current_process(fc)) {
18765157da2cSMiklos Szeredi 		if (!request_mask) {
18775157da2cSMiklos Szeredi 			/*
18785157da2cSMiklos Szeredi 			 * If user explicitly requested *nothing* then don't
18795157da2cSMiklos Szeredi 			 * error out, but return st_dev only.
18805157da2cSMiklos Szeredi 			 */
18815157da2cSMiklos Szeredi 			stat->result_mask = 0;
18825157da2cSMiklos Szeredi 			stat->dev = inode->i_sb->s_dev;
18835157da2cSMiklos Szeredi 			return 0;
18845157da2cSMiklos Szeredi 		}
1885244f6385SMiklos Szeredi 		return -EACCES;
18865157da2cSMiklos Szeredi 	}
1887244f6385SMiklos Szeredi 
18882f1e8196SMiklos Szeredi 	return fuse_update_get_attr(inode, NULL, stat, request_mask, flags);
1889e5e5558eSMiklos Szeredi }
1890e5e5558eSMiklos Szeredi 
1891754661f1SArjan van de Ven static const struct inode_operations fuse_dir_inode_operations = {
1892e5e5558eSMiklos Szeredi 	.lookup		= fuse_lookup,
18939e6268dbSMiklos Szeredi 	.mkdir		= fuse_mkdir,
18949e6268dbSMiklos Szeredi 	.symlink	= fuse_symlink,
18959e6268dbSMiklos Szeredi 	.unlink		= fuse_unlink,
18969e6268dbSMiklos Szeredi 	.rmdir		= fuse_rmdir,
18972773bf00SMiklos Szeredi 	.rename		= fuse_rename2,
18989e6268dbSMiklos Szeredi 	.link		= fuse_link,
18999e6268dbSMiklos Szeredi 	.setattr	= fuse_setattr,
19009e6268dbSMiklos Szeredi 	.create		= fuse_create,
1901c8ccbe03SMiklos Szeredi 	.atomic_open	= fuse_atomic_open,
19029e6268dbSMiklos Szeredi 	.mknod		= fuse_mknod,
1903e5e5558eSMiklos Szeredi 	.permission	= fuse_permission,
1904e5e5558eSMiklos Szeredi 	.getattr	= fuse_getattr,
190592a8780eSMiklos Szeredi 	.listxattr	= fuse_listxattr,
190660bcc88aSSeth Forshee 	.get_acl	= fuse_get_acl,
190760bcc88aSSeth Forshee 	.set_acl	= fuse_set_acl,
190872227eacSMiklos Szeredi 	.fileattr_get	= fuse_fileattr_get,
190972227eacSMiklos Szeredi 	.fileattr_set	= fuse_fileattr_set,
1910e5e5558eSMiklos Szeredi };
1911e5e5558eSMiklos Szeredi 
19124b6f5d20SArjan van de Ven static const struct file_operations fuse_dir_operations = {
1913b6aeadedSMiklos Szeredi 	.llseek		= generic_file_llseek,
1914e5e5558eSMiklos Szeredi 	.read		= generic_read_dir,
1915d9b3dbdcSAl Viro 	.iterate_shared	= fuse_readdir,
1916e5e5558eSMiklos Szeredi 	.open		= fuse_dir_open,
1917e5e5558eSMiklos Szeredi 	.release	= fuse_dir_release,
191882547981SMiklos Szeredi 	.fsync		= fuse_dir_fsync,
1919b18da0c5SMiklos Szeredi 	.unlocked_ioctl	= fuse_dir_ioctl,
1920b18da0c5SMiklos Szeredi 	.compat_ioctl	= fuse_dir_compat_ioctl,
1921e5e5558eSMiklos Szeredi };
1922e5e5558eSMiklos Szeredi 
1923754661f1SArjan van de Ven static const struct inode_operations fuse_common_inode_operations = {
19249e6268dbSMiklos Szeredi 	.setattr	= fuse_setattr,
1925e5e5558eSMiklos Szeredi 	.permission	= fuse_permission,
1926e5e5558eSMiklos Szeredi 	.getattr	= fuse_getattr,
192792a8780eSMiklos Szeredi 	.listxattr	= fuse_listxattr,
192860bcc88aSSeth Forshee 	.get_acl	= fuse_get_acl,
192960bcc88aSSeth Forshee 	.set_acl	= fuse_set_acl,
193072227eacSMiklos Szeredi 	.fileattr_get	= fuse_fileattr_get,
193172227eacSMiklos Szeredi 	.fileattr_set	= fuse_fileattr_set,
1932e5e5558eSMiklos Szeredi };
1933e5e5558eSMiklos Szeredi 
1934754661f1SArjan van de Ven static const struct inode_operations fuse_symlink_inode_operations = {
19359e6268dbSMiklos Szeredi 	.setattr	= fuse_setattr,
19366b255391SAl Viro 	.get_link	= fuse_get_link,
1937e5e5558eSMiklos Szeredi 	.getattr	= fuse_getattr,
193892a8780eSMiklos Szeredi 	.listxattr	= fuse_listxattr,
1939e5e5558eSMiklos Szeredi };
1940e5e5558eSMiklos Szeredi 
1941e5e5558eSMiklos Szeredi void fuse_init_common(struct inode *inode)
1942e5e5558eSMiklos Szeredi {
1943e5e5558eSMiklos Szeredi 	inode->i_op = &fuse_common_inode_operations;
1944e5e5558eSMiklos Szeredi }
1945e5e5558eSMiklos Szeredi 
1946e5e5558eSMiklos Szeredi void fuse_init_dir(struct inode *inode)
1947e5e5558eSMiklos Szeredi {
1948ab2257e9SMiklos Szeredi 	struct fuse_inode *fi = get_fuse_inode(inode);
1949ab2257e9SMiklos Szeredi 
1950e5e5558eSMiklos Szeredi 	inode->i_op = &fuse_dir_inode_operations;
1951e5e5558eSMiklos Szeredi 	inode->i_fop = &fuse_dir_operations;
1952ab2257e9SMiklos Szeredi 
1953ab2257e9SMiklos Szeredi 	spin_lock_init(&fi->rdc.lock);
1954ab2257e9SMiklos Szeredi 	fi->rdc.cached = false;
1955ab2257e9SMiklos Szeredi 	fi->rdc.size = 0;
1956ab2257e9SMiklos Szeredi 	fi->rdc.pos = 0;
1957ab2257e9SMiklos Szeredi 	fi->rdc.version = 0;
1958e5e5558eSMiklos Szeredi }
1959e5e5558eSMiklos Szeredi 
1960*5efd00e4SMatthew Wilcox (Oracle) static int fuse_symlink_read_folio(struct file *null, struct folio *folio)
19615571f1e6SDan Schatzberg {
1962*5efd00e4SMatthew Wilcox (Oracle) 	int err = fuse_readlink_page(folio->mapping->host, &folio->page);
19635571f1e6SDan Schatzberg 
19645571f1e6SDan Schatzberg 	if (!err)
1965*5efd00e4SMatthew Wilcox (Oracle) 		folio_mark_uptodate(folio);
19665571f1e6SDan Schatzberg 
1967*5efd00e4SMatthew Wilcox (Oracle) 	folio_unlock(folio);
19685571f1e6SDan Schatzberg 
19695571f1e6SDan Schatzberg 	return err;
19705571f1e6SDan Schatzberg }
19715571f1e6SDan Schatzberg 
19725571f1e6SDan Schatzberg static const struct address_space_operations fuse_symlink_aops = {
1973*5efd00e4SMatthew Wilcox (Oracle) 	.read_folio	= fuse_symlink_read_folio,
19745571f1e6SDan Schatzberg };
19755571f1e6SDan Schatzberg 
1976e5e5558eSMiklos Szeredi void fuse_init_symlink(struct inode *inode)
1977e5e5558eSMiklos Szeredi {
1978e5e5558eSMiklos Szeredi 	inode->i_op = &fuse_symlink_inode_operations;
19795571f1e6SDan Schatzberg 	inode->i_data.a_ops = &fuse_symlink_aops;
19805571f1e6SDan Schatzberg 	inode_nohighmem(inode);
1981e5e5558eSMiklos Szeredi }
1982