xref: /openbmc/linux/fs/fuse/dir.c (revision cefd1b83275d4c587bdeb2fe7aed07908642f875)
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>
20e5e5558eSMiklos Szeredi 
214582a4abSFeng Shuo static void fuse_advise_use_readdirplus(struct inode *dir)
224582a4abSFeng Shuo {
234582a4abSFeng Shuo 	struct fuse_inode *fi = get_fuse_inode(dir);
244582a4abSFeng Shuo 
254582a4abSFeng Shuo 	set_bit(FUSE_I_ADVISE_RDPLUS, &fi->state);
264582a4abSFeng Shuo }
274582a4abSFeng Shuo 
2830c6a23dSKhazhismel Kumykov #if BITS_PER_LONG >= 64
2930c6a23dSKhazhismel Kumykov static inline void __fuse_dentry_settime(struct dentry *entry, u64 time)
3030c6a23dSKhazhismel Kumykov {
3130c6a23dSKhazhismel Kumykov 	entry->d_fsdata = (void *) time;
3230c6a23dSKhazhismel Kumykov }
3330c6a23dSKhazhismel Kumykov 
3430c6a23dSKhazhismel Kumykov static inline u64 fuse_dentry_time(const struct dentry *entry)
3530c6a23dSKhazhismel Kumykov {
3630c6a23dSKhazhismel Kumykov 	return (u64)entry->d_fsdata;
3730c6a23dSKhazhismel Kumykov }
3830c6a23dSKhazhismel Kumykov 
3930c6a23dSKhazhismel Kumykov #else
40f75fdf22SMiklos Szeredi union fuse_dentry {
41f75fdf22SMiklos Szeredi 	u64 time;
42f75fdf22SMiklos Szeredi 	struct rcu_head rcu;
43f75fdf22SMiklos Szeredi };
44f75fdf22SMiklos Szeredi 
4530c6a23dSKhazhismel Kumykov static inline void __fuse_dentry_settime(struct dentry *dentry, u64 time)
4630c6a23dSKhazhismel Kumykov {
4730c6a23dSKhazhismel Kumykov 	((union fuse_dentry *) dentry->d_fsdata)->time = time;
4830c6a23dSKhazhismel Kumykov }
4930c6a23dSKhazhismel Kumykov 
5030c6a23dSKhazhismel Kumykov static inline u64 fuse_dentry_time(const struct dentry *entry)
5130c6a23dSKhazhismel Kumykov {
5230c6a23dSKhazhismel Kumykov 	return ((union fuse_dentry *) entry->d_fsdata)->time;
5330c6a23dSKhazhismel Kumykov }
5430c6a23dSKhazhismel Kumykov #endif
5530c6a23dSKhazhismel Kumykov 
568fab0106SMiklos Szeredi static void fuse_dentry_settime(struct dentry *dentry, u64 time)
570a0898cfSMiklos Szeredi {
588fab0106SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn_super(dentry->d_sb);
598fab0106SMiklos Szeredi 	bool delete = !time && fc->delete_stale;
608fab0106SMiklos Szeredi 	/*
618fab0106SMiklos Szeredi 	 * Mess with DCACHE_OP_DELETE because dput() will be faster without it.
628fab0106SMiklos Szeredi 	 * Don't care about races, either way it's just an optimization
638fab0106SMiklos Szeredi 	 */
648fab0106SMiklos Szeredi 	if ((!delete && (dentry->d_flags & DCACHE_OP_DELETE)) ||
658fab0106SMiklos Szeredi 	    (delete && !(dentry->d_flags & DCACHE_OP_DELETE))) {
668fab0106SMiklos Szeredi 		spin_lock(&dentry->d_lock);
678fab0106SMiklos Szeredi 		if (!delete)
688fab0106SMiklos Szeredi 			dentry->d_flags &= ~DCACHE_OP_DELETE;
698fab0106SMiklos Szeredi 		else
708fab0106SMiklos Szeredi 			dentry->d_flags |= DCACHE_OP_DELETE;
718fab0106SMiklos Szeredi 		spin_unlock(&dentry->d_lock);
720a0898cfSMiklos Szeredi 	}
730a0898cfSMiklos Szeredi 
7430c6a23dSKhazhismel Kumykov 	__fuse_dentry_settime(dentry, time);
750a0898cfSMiklos Szeredi }
760a0898cfSMiklos Szeredi 
776f9f1180SMiklos Szeredi /*
786f9f1180SMiklos Szeredi  * FUSE caches dentries and attributes with separate timeout.  The
796f9f1180SMiklos Szeredi  * time in jiffies until the dentry/attributes are valid is stored in
80f75fdf22SMiklos Szeredi  * dentry->d_fsdata and fuse_inode->i_time respectively.
816f9f1180SMiklos Szeredi  */
826f9f1180SMiklos Szeredi 
836f9f1180SMiklos Szeredi /*
846f9f1180SMiklos Szeredi  * Calculate the time in jiffies until a dentry/attributes are valid
856f9f1180SMiklos Szeredi  */
86bcb6f6d2SMiklos Szeredi static u64 time_to_jiffies(u64 sec, u32 nsec)
87e5e5558eSMiklos Szeredi {
88685d16ddSMiklos Szeredi 	if (sec || nsec) {
89bcb6f6d2SMiklos Szeredi 		struct timespec64 ts = {
90bcb6f6d2SMiklos Szeredi 			sec,
9121067527SDavid Sheets 			min_t(u32, nsec, NSEC_PER_SEC - 1)
92bcb6f6d2SMiklos Szeredi 		};
93bcb6f6d2SMiklos Szeredi 
94bcb6f6d2SMiklos Szeredi 		return get_jiffies_64() + timespec64_to_jiffies(&ts);
95685d16ddSMiklos Szeredi 	} else
960a0898cfSMiklos Szeredi 		return 0;
97e5e5558eSMiklos Szeredi }
98e5e5558eSMiklos Szeredi 
996f9f1180SMiklos Szeredi /*
1006f9f1180SMiklos Szeredi  * Set dentry and possibly attribute timeouts from the lookup/mk*
1016f9f1180SMiklos Szeredi  * replies
1026f9f1180SMiklos Szeredi  */
103d123d8e1SMiklos Szeredi void fuse_change_entry_timeout(struct dentry *entry, struct fuse_entry_out *o)
1040aa7c699SMiklos Szeredi {
1050a0898cfSMiklos Szeredi 	fuse_dentry_settime(entry,
1060a0898cfSMiklos Szeredi 		time_to_jiffies(o->entry_valid, o->entry_valid_nsec));
1071fb69e78SMiklos Szeredi }
1081fb69e78SMiklos Szeredi 
1091fb69e78SMiklos Szeredi static u64 attr_timeout(struct fuse_attr_out *o)
1101fb69e78SMiklos Szeredi {
1111fb69e78SMiklos Szeredi 	return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
1121fb69e78SMiklos Szeredi }
1131fb69e78SMiklos Szeredi 
114d123d8e1SMiklos Szeredi u64 entry_attr_timeout(struct fuse_entry_out *o)
1151fb69e78SMiklos Szeredi {
1161fb69e78SMiklos Szeredi 	return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
1178cbdf1e6SMiklos Szeredi }
1188cbdf1e6SMiklos Szeredi 
1192f1e8196SMiklos Szeredi static void fuse_invalidate_attr_mask(struct inode *inode, u32 mask)
1202f1e8196SMiklos Szeredi {
1212f1e8196SMiklos Szeredi 	set_mask_bits(&get_fuse_inode(inode)->inval_mask, 0, mask);
1222f1e8196SMiklos Szeredi }
1232f1e8196SMiklos Szeredi 
1246f9f1180SMiklos Szeredi /*
1256f9f1180SMiklos Szeredi  * Mark the attributes as stale, so that at the next call to
1266f9f1180SMiklos Szeredi  * ->getattr() they will be fetched from userspace
1276f9f1180SMiklos Szeredi  */
1288cbdf1e6SMiklos Szeredi void fuse_invalidate_attr(struct inode *inode)
1298cbdf1e6SMiklos Szeredi {
1302f1e8196SMiklos Szeredi 	fuse_invalidate_attr_mask(inode, STATX_BASIC_STATS);
1318cbdf1e6SMiklos Szeredi }
1328cbdf1e6SMiklos Szeredi 
133261aaba7SMiklos Szeredi static void fuse_dir_changed(struct inode *dir)
134261aaba7SMiklos Szeredi {
135261aaba7SMiklos Szeredi 	fuse_invalidate_attr(dir);
136261aaba7SMiklos Szeredi 	inode_maybe_inc_iversion(dir, false);
137261aaba7SMiklos Szeredi }
138261aaba7SMiklos Szeredi 
139451418fcSAndrew Gallagher /**
140451418fcSAndrew Gallagher  * Mark the attributes as stale due to an atime change.  Avoid the invalidate if
141451418fcSAndrew Gallagher  * atime is not used.
142451418fcSAndrew Gallagher  */
143451418fcSAndrew Gallagher void fuse_invalidate_atime(struct inode *inode)
144451418fcSAndrew Gallagher {
145451418fcSAndrew Gallagher 	if (!IS_RDONLY(inode))
1462f1e8196SMiklos Szeredi 		fuse_invalidate_attr_mask(inode, STATX_ATIME);
147451418fcSAndrew Gallagher }
148451418fcSAndrew Gallagher 
1496f9f1180SMiklos Szeredi /*
1506f9f1180SMiklos Szeredi  * Just mark the entry as stale, so that a next attempt to look it up
1516f9f1180SMiklos Szeredi  * will result in a new lookup call to userspace
1526f9f1180SMiklos Szeredi  *
1536f9f1180SMiklos Szeredi  * This is called when a dentry is about to become negative and the
1546f9f1180SMiklos Szeredi  * timeout is unknown (unlink, rmdir, rename and in some cases
1556f9f1180SMiklos Szeredi  * lookup)
1566f9f1180SMiklos Szeredi  */
157dbd561d2SMiklos Szeredi void fuse_invalidate_entry_cache(struct dentry *entry)
1588cbdf1e6SMiklos Szeredi {
1590a0898cfSMiklos Szeredi 	fuse_dentry_settime(entry, 0);
1608cbdf1e6SMiklos Szeredi }
1618cbdf1e6SMiklos Szeredi 
1626f9f1180SMiklos Szeredi /*
1636f9f1180SMiklos Szeredi  * Same as fuse_invalidate_entry_cache(), but also try to remove the
1646f9f1180SMiklos Szeredi  * dentry from the hash
1656f9f1180SMiklos Szeredi  */
1668cbdf1e6SMiklos Szeredi static void fuse_invalidate_entry(struct dentry *entry)
1678cbdf1e6SMiklos Szeredi {
1688cbdf1e6SMiklos Szeredi 	d_invalidate(entry);
1698cbdf1e6SMiklos Szeredi 	fuse_invalidate_entry_cache(entry);
1700aa7c699SMiklos Szeredi }
1710aa7c699SMiklos Szeredi 
1727078187aSMiklos Szeredi static void fuse_lookup_init(struct fuse_conn *fc, struct fuse_args *args,
17313983d06SAl Viro 			     u64 nodeid, const struct qstr *name,
174e5e5558eSMiklos Szeredi 			     struct fuse_entry_out *outarg)
175e5e5558eSMiklos Szeredi {
1760e9663eeSMiklos Szeredi 	memset(outarg, 0, sizeof(struct fuse_entry_out));
177d5b48543SMiklos Szeredi 	args->opcode = FUSE_LOOKUP;
178d5b48543SMiklos Szeredi 	args->nodeid = nodeid;
179d5b48543SMiklos Szeredi 	args->in_numargs = 1;
180d5b48543SMiklos Szeredi 	args->in_args[0].size = name->len + 1;
181d5b48543SMiklos Szeredi 	args->in_args[0].value = name->name;
182d5b48543SMiklos Szeredi 	args->out_numargs = 1;
183d5b48543SMiklos Szeredi 	args->out_args[0].size = sizeof(struct fuse_entry_out);
184d5b48543SMiklos Szeredi 	args->out_args[0].value = outarg;
185e5e5558eSMiklos Szeredi }
186e5e5558eSMiklos Szeredi 
1876f9f1180SMiklos Szeredi /*
1886f9f1180SMiklos Szeredi  * Check whether the dentry is still valid
1896f9f1180SMiklos Szeredi  *
1906f9f1180SMiklos Szeredi  * If the entry validity timeout has expired and the dentry is
1916f9f1180SMiklos Szeredi  * positive, try to redo the lookup.  If the lookup results in a
1926f9f1180SMiklos Szeredi  * different inode, then let the VFS invalidate the dentry and redo
1936f9f1180SMiklos Szeredi  * the lookup once more.  If the lookup results in the same inode,
1946f9f1180SMiklos Szeredi  * then refresh the attributes, timeouts and mark the dentry valid.
1956f9f1180SMiklos Szeredi  */
1960b728e19SAl Viro static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
197e5e5558eSMiklos Szeredi {
19834286d66SNick Piggin 	struct inode *inode;
19928420dadSMiklos Szeredi 	struct dentry *parent;
200fcee216bSMax Reitz 	struct fuse_mount *fm;
2016314efeeSMiklos Szeredi 	struct fuse_inode *fi;
202e2a6b952SMiklos Szeredi 	int ret;
2038cbdf1e6SMiklos Szeredi 
2042b0143b5SDavid Howells 	inode = d_inode_rcu(entry);
2055d069dbeSMiklos Szeredi 	if (inode && fuse_is_bad(inode))
206e2a6b952SMiklos Szeredi 		goto invalid;
207154210ccSAnand Avati 	else if (time_before64(fuse_dentry_time(entry), get_jiffies_64()) ||
208df8629afSMiklos Szeredi 		 (flags & (LOOKUP_EXCL | LOOKUP_REVAL))) {
209e5e5558eSMiklos Szeredi 		struct fuse_entry_out outarg;
2107078187aSMiklos Szeredi 		FUSE_ARGS(args);
21107e77dcaSMiklos Szeredi 		struct fuse_forget_link *forget;
2121fb69e78SMiklos Szeredi 		u64 attr_version;
2138cbdf1e6SMiklos Szeredi 
21450322fe7SMiklos Szeredi 		/* For negative dentries, always do a fresh lookup */
2158cbdf1e6SMiklos Szeredi 		if (!inode)
216e2a6b952SMiklos Szeredi 			goto invalid;
2178cbdf1e6SMiklos Szeredi 
218e2a6b952SMiklos Szeredi 		ret = -ECHILD;
2190b728e19SAl Viro 		if (flags & LOOKUP_RCU)
220e2a6b952SMiklos Szeredi 			goto out;
221e7c0a167SMiklos Szeredi 
222fcee216bSMax Reitz 		fm = get_fuse_mount(inode);
223e5e5558eSMiklos Szeredi 
22407e77dcaSMiklos Szeredi 		forget = fuse_alloc_forget();
225e2a6b952SMiklos Szeredi 		ret = -ENOMEM;
2267078187aSMiklos Szeredi 		if (!forget)
227e2a6b952SMiklos Szeredi 			goto out;
2282d51013eSMiklos Szeredi 
229fcee216bSMax Reitz 		attr_version = fuse_get_attr_version(fm->fc);
2301fb69e78SMiklos Szeredi 
231e956edd0SMiklos Szeredi 		parent = dget_parent(entry);
232fcee216bSMax Reitz 		fuse_lookup_init(fm->fc, &args, get_node_id(d_inode(parent)),
233c180eebeSMiklos Szeredi 				 &entry->d_name, &outarg);
234fcee216bSMax Reitz 		ret = fuse_simple_request(fm, &args);
235e956edd0SMiklos Szeredi 		dput(parent);
23650322fe7SMiklos Szeredi 		/* Zero nodeid is same as -ENOENT */
2377078187aSMiklos Szeredi 		if (!ret && !outarg.nodeid)
2387078187aSMiklos Szeredi 			ret = -ENOENT;
2397078187aSMiklos Szeredi 		if (!ret) {
2406314efeeSMiklos Szeredi 			fi = get_fuse_inode(inode);
241bf109c64SMax Reitz 			if (outarg.nodeid != get_node_id(inode) ||
242bf109c64SMax Reitz 			    (bool) IS_AUTOMOUNT(inode) != (bool) (outarg.attr.flags & FUSE_ATTR_SUBMOUNT)) {
243fcee216bSMax Reitz 				fuse_queue_forget(fm->fc, forget,
244fcee216bSMax Reitz 						  outarg.nodeid, 1);
245e2a6b952SMiklos Szeredi 				goto invalid;
2469e6268dbSMiklos Szeredi 			}
247c9d8f5f0SKirill Tkhai 			spin_lock(&fi->lock);
2489e6268dbSMiklos Szeredi 			fi->nlookup++;
249c9d8f5f0SKirill Tkhai 			spin_unlock(&fi->lock);
2509e6268dbSMiklos Szeredi 		}
25107e77dcaSMiklos Szeredi 		kfree(forget);
2527078187aSMiklos Szeredi 		if (ret == -ENOMEM)
2537078187aSMiklos Szeredi 			goto out;
254eb59bd17SMiklos Szeredi 		if (ret || fuse_invalid_attr(&outarg.attr) ||
25515db1683SAmir Goldstein 		    fuse_stale_inode(inode, outarg.generation, &outarg.attr))
256e2a6b952SMiklos Szeredi 			goto invalid;
257e5e5558eSMiklos Szeredi 
25860bcc88aSSeth Forshee 		forget_all_cached_acls(inode);
2591fb69e78SMiklos Szeredi 		fuse_change_attributes(inode, &outarg.attr,
2601fb69e78SMiklos Szeredi 				       entry_attr_timeout(&outarg),
2611fb69e78SMiklos Szeredi 				       attr_version);
2621fb69e78SMiklos Szeredi 		fuse_change_entry_timeout(entry, &outarg);
26328420dadSMiklos Szeredi 	} else if (inode) {
2646314efeeSMiklos Szeredi 		fi = get_fuse_inode(inode);
2656314efeeSMiklos Szeredi 		if (flags & LOOKUP_RCU) {
2666314efeeSMiklos Szeredi 			if (test_bit(FUSE_I_INIT_RDPLUS, &fi->state))
2676314efeeSMiklos Szeredi 				return -ECHILD;
2686314efeeSMiklos Szeredi 		} else if (test_and_clear_bit(FUSE_I_INIT_RDPLUS, &fi->state)) {
26928420dadSMiklos Szeredi 			parent = dget_parent(entry);
2702b0143b5SDavid Howells 			fuse_advise_use_readdirplus(d_inode(parent));
27128420dadSMiklos Szeredi 			dput(parent);
272e5e5558eSMiklos Szeredi 		}
27328420dadSMiklos Szeredi 	}
274e2a6b952SMiklos Szeredi 	ret = 1;
275e2a6b952SMiklos Szeredi out:
276e2a6b952SMiklos Szeredi 	return ret;
277e2a6b952SMiklos Szeredi 
278e2a6b952SMiklos Szeredi invalid:
279e2a6b952SMiklos Szeredi 	ret = 0;
280e2a6b952SMiklos Szeredi 	goto out;
281e5e5558eSMiklos Szeredi }
282e5e5558eSMiklos Szeredi 
28330c6a23dSKhazhismel Kumykov #if BITS_PER_LONG < 64
284f75fdf22SMiklos Szeredi static int fuse_dentry_init(struct dentry *dentry)
285f75fdf22SMiklos Szeredi {
286dc69e98cSKhazhismel Kumykov 	dentry->d_fsdata = kzalloc(sizeof(union fuse_dentry),
287dc69e98cSKhazhismel Kumykov 				   GFP_KERNEL_ACCOUNT | __GFP_RECLAIMABLE);
288f75fdf22SMiklos Szeredi 
289f75fdf22SMiklos Szeredi 	return dentry->d_fsdata ? 0 : -ENOMEM;
290f75fdf22SMiklos Szeredi }
291f75fdf22SMiklos Szeredi static void fuse_dentry_release(struct dentry *dentry)
292f75fdf22SMiklos Szeredi {
293f75fdf22SMiklos Szeredi 	union fuse_dentry *fd = dentry->d_fsdata;
294f75fdf22SMiklos Szeredi 
295f75fdf22SMiklos Szeredi 	kfree_rcu(fd, rcu);
296f75fdf22SMiklos Szeredi }
29730c6a23dSKhazhismel Kumykov #endif
298f75fdf22SMiklos Szeredi 
2998fab0106SMiklos Szeredi static int fuse_dentry_delete(const struct dentry *dentry)
3008fab0106SMiklos Szeredi {
3018fab0106SMiklos Szeredi 	return time_before64(fuse_dentry_time(dentry), get_jiffies_64());
3028fab0106SMiklos Szeredi }
3038fab0106SMiklos Szeredi 
304bf109c64SMax Reitz /*
305bf109c64SMax Reitz  * Create a fuse_mount object with a new superblock (with path->dentry
306bf109c64SMax Reitz  * as the root), and return that mount so it can be auto-mounted on
307bf109c64SMax Reitz  * @path.
308bf109c64SMax Reitz  */
309bf109c64SMax Reitz static struct vfsmount *fuse_dentry_automount(struct path *path)
310bf109c64SMax Reitz {
311bf109c64SMax Reitz 	struct fs_context *fsc;
312bf109c64SMax Reitz 	struct vfsmount *mnt;
313bf109c64SMax Reitz 	struct fuse_inode *mp_fi = get_fuse_inode(d_inode(path->dentry));
314bf109c64SMax Reitz 
315bf109c64SMax Reitz 	fsc = fs_context_for_submount(path->mnt->mnt_sb->s_type, path->dentry);
31629e0e4dfSGreg Kurz 	if (IS_ERR(fsc))
31729e0e4dfSGreg Kurz 		return ERR_CAST(fsc);
318bf109c64SMax Reitz 
319266eb3f2SGreg Kurz 	/* Pass the FUSE inode of the mount for fuse_get_tree_submount() */
320266eb3f2SGreg Kurz 	fsc->fs_private = mp_fi;
321266eb3f2SGreg Kurz 
322bf109c64SMax Reitz 	/* Create the submount */
32329e0e4dfSGreg Kurz 	mnt = fc_mount(fsc);
32429e0e4dfSGreg Kurz 	if (!IS_ERR(mnt))
325bf109c64SMax Reitz 		mntget(mnt);
32629e0e4dfSGreg Kurz 
327bf109c64SMax Reitz 	put_fs_context(fsc);
328bf109c64SMax Reitz 	return mnt;
329bf109c64SMax Reitz }
330bf109c64SMax Reitz 
3314269590aSAl Viro const struct dentry_operations fuse_dentry_operations = {
332e5e5558eSMiklos Szeredi 	.d_revalidate	= fuse_dentry_revalidate,
3338fab0106SMiklos Szeredi 	.d_delete	= fuse_dentry_delete,
33430c6a23dSKhazhismel Kumykov #if BITS_PER_LONG < 64
335f75fdf22SMiklos Szeredi 	.d_init		= fuse_dentry_init,
336f75fdf22SMiklos Szeredi 	.d_release	= fuse_dentry_release,
33730c6a23dSKhazhismel Kumykov #endif
338bf109c64SMax Reitz 	.d_automount	= fuse_dentry_automount,
339e5e5558eSMiklos Szeredi };
340e5e5558eSMiklos Szeredi 
3410ce267ffSMiklos Szeredi const struct dentry_operations fuse_root_dentry_operations = {
34230c6a23dSKhazhismel Kumykov #if BITS_PER_LONG < 64
3430ce267ffSMiklos Szeredi 	.d_init		= fuse_dentry_init,
3440ce267ffSMiklos Szeredi 	.d_release	= fuse_dentry_release,
34530c6a23dSKhazhismel Kumykov #endif
3460ce267ffSMiklos Szeredi };
3470ce267ffSMiklos Szeredi 
348a5bfffacSTimo Savola int fuse_valid_type(int m)
34939ee059aSMiklos Szeredi {
35039ee059aSMiklos Szeredi 	return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) ||
35139ee059aSMiklos Szeredi 		S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
35239ee059aSMiklos Szeredi }
35339ee059aSMiklos Szeredi 
354eb59bd17SMiklos Szeredi bool fuse_invalid_attr(struct fuse_attr *attr)
355eb59bd17SMiklos Szeredi {
356eb59bd17SMiklos Szeredi 	return !fuse_valid_type(attr->mode) ||
357eb59bd17SMiklos Szeredi 		attr->size > LLONG_MAX;
358eb59bd17SMiklos Szeredi }
359eb59bd17SMiklos Szeredi 
36013983d06SAl Viro int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name,
361c180eebeSMiklos Szeredi 		     struct fuse_entry_out *outarg, struct inode **inode)
362c180eebeSMiklos Szeredi {
363fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount_super(sb);
3647078187aSMiklos Szeredi 	FUSE_ARGS(args);
36507e77dcaSMiklos Szeredi 	struct fuse_forget_link *forget;
366c180eebeSMiklos Szeredi 	u64 attr_version;
367c180eebeSMiklos Szeredi 	int err;
368c180eebeSMiklos Szeredi 
369c180eebeSMiklos Szeredi 	*inode = NULL;
370c180eebeSMiklos Szeredi 	err = -ENAMETOOLONG;
371c180eebeSMiklos Szeredi 	if (name->len > FUSE_NAME_MAX)
372c180eebeSMiklos Szeredi 		goto out;
373c180eebeSMiklos Szeredi 
374c180eebeSMiklos Szeredi 
37507e77dcaSMiklos Szeredi 	forget = fuse_alloc_forget();
37607e77dcaSMiklos Szeredi 	err = -ENOMEM;
3777078187aSMiklos Szeredi 	if (!forget)
378c180eebeSMiklos Szeredi 		goto out;
379c180eebeSMiklos Szeredi 
380fcee216bSMax Reitz 	attr_version = fuse_get_attr_version(fm->fc);
381c180eebeSMiklos Szeredi 
382fcee216bSMax Reitz 	fuse_lookup_init(fm->fc, &args, nodeid, name, outarg);
383fcee216bSMax Reitz 	err = fuse_simple_request(fm, &args);
384c180eebeSMiklos Szeredi 	/* Zero nodeid is same as -ENOENT, but with valid timeout */
385c180eebeSMiklos Szeredi 	if (err || !outarg->nodeid)
386c180eebeSMiklos Szeredi 		goto out_put_forget;
387c180eebeSMiklos Szeredi 
388c180eebeSMiklos Szeredi 	err = -EIO;
389c180eebeSMiklos Szeredi 	if (!outarg->nodeid)
390c180eebeSMiklos Szeredi 		goto out_put_forget;
391eb59bd17SMiklos Szeredi 	if (fuse_invalid_attr(&outarg->attr))
392c180eebeSMiklos Szeredi 		goto out_put_forget;
393c180eebeSMiklos Szeredi 
394c180eebeSMiklos Szeredi 	*inode = fuse_iget(sb, outarg->nodeid, outarg->generation,
395c180eebeSMiklos Szeredi 			   &outarg->attr, entry_attr_timeout(outarg),
396c180eebeSMiklos Szeredi 			   attr_version);
397c180eebeSMiklos Szeredi 	err = -ENOMEM;
398c180eebeSMiklos Szeredi 	if (!*inode) {
399fcee216bSMax Reitz 		fuse_queue_forget(fm->fc, forget, outarg->nodeid, 1);
400c180eebeSMiklos Szeredi 		goto out;
401c180eebeSMiklos Szeredi 	}
402c180eebeSMiklos Szeredi 	err = 0;
403c180eebeSMiklos Szeredi 
404c180eebeSMiklos Szeredi  out_put_forget:
40507e77dcaSMiklos Szeredi 	kfree(forget);
406c180eebeSMiklos Szeredi  out:
407c180eebeSMiklos Szeredi 	return err;
408c180eebeSMiklos Szeredi }
409c180eebeSMiklos Szeredi 
4100aa7c699SMiklos Szeredi static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
41100cd8dd3SAl Viro 				  unsigned int flags)
412e5e5558eSMiklos Szeredi {
413e5e5558eSMiklos Szeredi 	int err;
414e5e5558eSMiklos Szeredi 	struct fuse_entry_out outarg;
415c180eebeSMiklos Szeredi 	struct inode *inode;
4160de6256dSMiklos Szeredi 	struct dentry *newent;
417c180eebeSMiklos Szeredi 	bool outarg_valid = true;
41863576c13SMiklos Szeredi 	bool locked;
419e5e5558eSMiklos Szeredi 
4205d069dbeSMiklos Szeredi 	if (fuse_is_bad(dir))
4215d069dbeSMiklos Szeredi 		return ERR_PTR(-EIO);
4225d069dbeSMiklos Szeredi 
42363576c13SMiklos Szeredi 	locked = fuse_lock_inode(dir);
424c180eebeSMiklos Szeredi 	err = fuse_lookup_name(dir->i_sb, get_node_id(dir), &entry->d_name,
425c180eebeSMiklos Szeredi 			       &outarg, &inode);
42663576c13SMiklos Szeredi 	fuse_unlock_inode(dir, locked);
427c180eebeSMiklos Szeredi 	if (err == -ENOENT) {
428c180eebeSMiklos Szeredi 		outarg_valid = false;
429c180eebeSMiklos Szeredi 		err = 0;
4302d51013eSMiklos Szeredi 	}
431c180eebeSMiklos Szeredi 	if (err)
432c180eebeSMiklos Szeredi 		goto out_err;
4332d51013eSMiklos Szeredi 
434ee4e5271SMiklos Szeredi 	err = -EIO;
435c180eebeSMiklos Szeredi 	if (inode && get_node_id(inode) == FUSE_ROOT_ID)
436c180eebeSMiklos Szeredi 		goto out_iput;
437e5e5558eSMiklos Szeredi 
43841d28bcaSAl Viro 	newent = d_splice_alias(inode, entry);
439c180eebeSMiklos Szeredi 	err = PTR_ERR(newent);
440c180eebeSMiklos Szeredi 	if (IS_ERR(newent))
4415835f339SMiklos Szeredi 		goto out_err;
442d2a85164SMiklos Szeredi 
4430de6256dSMiklos Szeredi 	entry = newent ? newent : entry;
444c180eebeSMiklos Szeredi 	if (outarg_valid)
4451fb69e78SMiklos Szeredi 		fuse_change_entry_timeout(entry, &outarg);
4468cbdf1e6SMiklos Szeredi 	else
4478cbdf1e6SMiklos Szeredi 		fuse_invalidate_entry_cache(entry);
448c180eebeSMiklos Szeredi 
4496c26f717SMiklos Szeredi 	if (inode)
4504582a4abSFeng Shuo 		fuse_advise_use_readdirplus(dir);
4510de6256dSMiklos Szeredi 	return newent;
452c180eebeSMiklos Szeredi 
453c180eebeSMiklos Szeredi  out_iput:
454c180eebeSMiklos Szeredi 	iput(inode);
455c180eebeSMiklos Szeredi  out_err:
456c180eebeSMiklos Szeredi 	return ERR_PTR(err);
457e5e5558eSMiklos Szeredi }
458e5e5558eSMiklos Szeredi 
4596f9f1180SMiklos Szeredi /*
4606f9f1180SMiklos Szeredi  * Atomic create+open operation
4616f9f1180SMiklos Szeredi  *
4626f9f1180SMiklos Szeredi  * If the filesystem doesn't support this, then fall back to separate
4636f9f1180SMiklos Szeredi  * 'mknod' + 'open' requests.
4646f9f1180SMiklos Szeredi  */
465d9585277SAl Viro static int fuse_create_open(struct inode *dir, struct dentry *entry,
46654d601cbSMiklos Szeredi 			    struct file *file, unsigned int flags,
467b452a458SAl Viro 			    umode_t mode)
468fd72faacSMiklos Szeredi {
469fd72faacSMiklos Szeredi 	int err;
470fd72faacSMiklos Szeredi 	struct inode *inode;
471fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(dir);
4727078187aSMiklos Szeredi 	FUSE_ARGS(args);
47307e77dcaSMiklos Szeredi 	struct fuse_forget_link *forget;
474e0a43ddcSMiklos Szeredi 	struct fuse_create_in inarg;
475fd72faacSMiklos Szeredi 	struct fuse_open_out outopen;
476fd72faacSMiklos Szeredi 	struct fuse_entry_out outentry;
477ebf84d0cSKirill Tkhai 	struct fuse_inode *fi;
478fd72faacSMiklos Szeredi 	struct fuse_file *ff;
479fd72faacSMiklos Szeredi 
480af109bcaSMiklos Szeredi 	/* Userspace expects S_IFREG in create mode */
481af109bcaSMiklos Szeredi 	BUG_ON((mode & S_IFMT) != S_IFREG);
482af109bcaSMiklos Szeredi 
48307e77dcaSMiklos Szeredi 	forget = fuse_alloc_forget();
484c8ccbe03SMiklos Szeredi 	err = -ENOMEM;
48507e77dcaSMiklos Szeredi 	if (!forget)
486c8ccbe03SMiklos Szeredi 		goto out_err;
48751eb01e7SMiklos Szeredi 
488ce1d5a49SMiklos Szeredi 	err = -ENOMEM;
489fcee216bSMax Reitz 	ff = fuse_file_alloc(fm);
490fd72faacSMiklos Szeredi 	if (!ff)
4917078187aSMiklos Szeredi 		goto out_put_forget_req;
492fd72faacSMiklos Szeredi 
493fcee216bSMax Reitz 	if (!fm->fc->dont_mask)
494e0a43ddcSMiklos Szeredi 		mode &= ~current_umask();
495e0a43ddcSMiklos Szeredi 
496fd72faacSMiklos Szeredi 	flags &= ~O_NOCTTY;
497fd72faacSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
4980e9663eeSMiklos Szeredi 	memset(&outentry, 0, sizeof(outentry));
499fd72faacSMiklos Szeredi 	inarg.flags = flags;
500fd72faacSMiklos Szeredi 	inarg.mode = mode;
501e0a43ddcSMiklos Szeredi 	inarg.umask = current_umask();
502643a666aSVivek Goyal 
503643a666aSVivek Goyal 	if (fm->fc->handle_killpriv_v2 && (flags & O_TRUNC) &&
504643a666aSVivek Goyal 	    !(flags & O_EXCL) && !capable(CAP_FSETID)) {
505643a666aSVivek Goyal 		inarg.open_flags |= FUSE_OPEN_KILL_SUIDGID;
506643a666aSVivek Goyal 	}
507643a666aSVivek Goyal 
508d5b48543SMiklos Szeredi 	args.opcode = FUSE_CREATE;
509d5b48543SMiklos Szeredi 	args.nodeid = get_node_id(dir);
510d5b48543SMiklos Szeredi 	args.in_numargs = 2;
511d5b48543SMiklos Szeredi 	args.in_args[0].size = sizeof(inarg);
512d5b48543SMiklos Szeredi 	args.in_args[0].value = &inarg;
513d5b48543SMiklos Szeredi 	args.in_args[1].size = entry->d_name.len + 1;
514d5b48543SMiklos Szeredi 	args.in_args[1].value = entry->d_name.name;
515d5b48543SMiklos Szeredi 	args.out_numargs = 2;
516d5b48543SMiklos Szeredi 	args.out_args[0].size = sizeof(outentry);
517d5b48543SMiklos Szeredi 	args.out_args[0].value = &outentry;
518d5b48543SMiklos Szeredi 	args.out_args[1].size = sizeof(outopen);
519d5b48543SMiklos Szeredi 	args.out_args[1].value = &outopen;
520fcee216bSMax Reitz 	err = fuse_simple_request(fm, &args);
521c8ccbe03SMiklos Szeredi 	if (err)
522fd72faacSMiklos Szeredi 		goto out_free_ff;
523fd72faacSMiklos Szeredi 
524fd72faacSMiklos Szeredi 	err = -EIO;
525eb59bd17SMiklos Szeredi 	if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid) ||
526eb59bd17SMiklos Szeredi 	    fuse_invalid_attr(&outentry.attr))
527fd72faacSMiklos Szeredi 		goto out_free_ff;
528fd72faacSMiklos Szeredi 
529c7b7143cSMiklos Szeredi 	ff->fh = outopen.fh;
530c7b7143cSMiklos Szeredi 	ff->nodeid = outentry.nodeid;
531c7b7143cSMiklos Szeredi 	ff->open_flags = outopen.open_flags;
532fd72faacSMiklos Szeredi 	inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
5331fb69e78SMiklos Szeredi 			  &outentry.attr, entry_attr_timeout(&outentry), 0);
534fd72faacSMiklos Szeredi 	if (!inode) {
535fd72faacSMiklos Szeredi 		flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
536ebf84d0cSKirill Tkhai 		fuse_sync_release(NULL, ff, flags);
537fcee216bSMax Reitz 		fuse_queue_forget(fm->fc, forget, outentry.nodeid, 1);
538c8ccbe03SMiklos Szeredi 		err = -ENOMEM;
539c8ccbe03SMiklos Szeredi 		goto out_err;
540fd72faacSMiklos Szeredi 	}
54107e77dcaSMiklos Szeredi 	kfree(forget);
542fd72faacSMiklos Szeredi 	d_instantiate(entry, inode);
5431fb69e78SMiklos Szeredi 	fuse_change_entry_timeout(entry, &outentry);
544261aaba7SMiklos Szeredi 	fuse_dir_changed(dir);
545be12af3eSAl Viro 	err = finish_open(file, entry, generic_file_open);
54630d90494SAl Viro 	if (err) {
547ebf84d0cSKirill Tkhai 		fi = get_fuse_inode(inode);
548ebf84d0cSKirill Tkhai 		fuse_sync_release(fi, ff, flags);
549c8ccbe03SMiklos Szeredi 	} else {
550267d8444SMiklos Szeredi 		file->private_data = ff;
551c7b7143cSMiklos Szeredi 		fuse_finish_open(inode, file);
552c8ccbe03SMiklos Szeredi 	}
553d9585277SAl Viro 	return err;
554fd72faacSMiklos Szeredi 
555fd72faacSMiklos Szeredi out_free_ff:
556fd72faacSMiklos Szeredi 	fuse_file_free(ff);
55751eb01e7SMiklos Szeredi out_put_forget_req:
55807e77dcaSMiklos Szeredi 	kfree(forget);
559c8ccbe03SMiklos Szeredi out_err:
560d9585277SAl Viro 	return err;
561c8ccbe03SMiklos Szeredi }
562c8ccbe03SMiklos Szeredi 
563549c7297SChristian Brauner static int fuse_mknod(struct user_namespace *, struct inode *, struct dentry *,
564549c7297SChristian Brauner 		      umode_t, dev_t);
565d9585277SAl Viro static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
56630d90494SAl Viro 			    struct file *file, unsigned flags,
56744907d79SAl Viro 			    umode_t mode)
568c8ccbe03SMiklos Szeredi {
569c8ccbe03SMiklos Szeredi 	int err;
570c8ccbe03SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
571c8ccbe03SMiklos Szeredi 	struct dentry *res = NULL;
572c8ccbe03SMiklos Szeredi 
5735d069dbeSMiklos Szeredi 	if (fuse_is_bad(dir))
5745d069dbeSMiklos Szeredi 		return -EIO;
5755d069dbeSMiklos Szeredi 
57600699ad8SAl Viro 	if (d_in_lookup(entry)) {
57700cd8dd3SAl Viro 		res = fuse_lookup(dir, entry, 0);
578c8ccbe03SMiklos Szeredi 		if (IS_ERR(res))
579d9585277SAl Viro 			return PTR_ERR(res);
580c8ccbe03SMiklos Szeredi 
581c8ccbe03SMiklos Szeredi 		if (res)
582c8ccbe03SMiklos Szeredi 			entry = res;
583c8ccbe03SMiklos Szeredi 	}
584c8ccbe03SMiklos Szeredi 
5852b0143b5SDavid Howells 	if (!(flags & O_CREAT) || d_really_is_positive(entry))
586c8ccbe03SMiklos Szeredi 		goto no_open;
587c8ccbe03SMiklos Szeredi 
588c8ccbe03SMiklos Szeredi 	/* Only creates */
58973a09dd9SAl Viro 	file->f_mode |= FMODE_CREATED;
590c8ccbe03SMiklos Szeredi 
591c8ccbe03SMiklos Szeredi 	if (fc->no_create)
592c8ccbe03SMiklos Szeredi 		goto mknod;
593c8ccbe03SMiklos Szeredi 
594b452a458SAl Viro 	err = fuse_create_open(dir, entry, file, flags, mode);
595d9585277SAl Viro 	if (err == -ENOSYS) {
596c8ccbe03SMiklos Szeredi 		fc->no_create = 1;
597c8ccbe03SMiklos Szeredi 		goto mknod;
598c8ccbe03SMiklos Szeredi 	}
599c8ccbe03SMiklos Szeredi out_dput:
600c8ccbe03SMiklos Szeredi 	dput(res);
601d9585277SAl Viro 	return err;
602c8ccbe03SMiklos Szeredi 
603c8ccbe03SMiklos Szeredi mknod:
604549c7297SChristian Brauner 	err = fuse_mknod(&init_user_ns, dir, entry, mode, 0);
605d9585277SAl Viro 	if (err)
606c8ccbe03SMiklos Szeredi 		goto out_dput;
607c8ccbe03SMiklos Szeredi no_open:
608e45198a6SAl Viro 	return finish_no_open(file, res);
609fd72faacSMiklos Szeredi }
610fd72faacSMiklos Szeredi 
6116f9f1180SMiklos Szeredi /*
6126f9f1180SMiklos Szeredi  * Code shared between mknod, mkdir, symlink and link
6136f9f1180SMiklos Szeredi  */
614fcee216bSMax Reitz static int create_new_entry(struct fuse_mount *fm, struct fuse_args *args,
6159e6268dbSMiklos Szeredi 			    struct inode *dir, struct dentry *entry,
616541af6a0SAl Viro 			    umode_t mode)
6179e6268dbSMiklos Szeredi {
6189e6268dbSMiklos Szeredi 	struct fuse_entry_out outarg;
6199e6268dbSMiklos Szeredi 	struct inode *inode;
620c971e6a0SAl Viro 	struct dentry *d;
6219e6268dbSMiklos Szeredi 	int err;
62207e77dcaSMiklos Szeredi 	struct fuse_forget_link *forget;
6232d51013eSMiklos Szeredi 
6245d069dbeSMiklos Szeredi 	if (fuse_is_bad(dir))
6255d069dbeSMiklos Szeredi 		return -EIO;
6265d069dbeSMiklos Szeredi 
62707e77dcaSMiklos Szeredi 	forget = fuse_alloc_forget();
6287078187aSMiklos Szeredi 	if (!forget)
62907e77dcaSMiklos Szeredi 		return -ENOMEM;
6309e6268dbSMiklos Szeredi 
6310e9663eeSMiklos Szeredi 	memset(&outarg, 0, sizeof(outarg));
632d5b48543SMiklos Szeredi 	args->nodeid = get_node_id(dir);
633d5b48543SMiklos Szeredi 	args->out_numargs = 1;
634d5b48543SMiklos Szeredi 	args->out_args[0].size = sizeof(outarg);
635d5b48543SMiklos Szeredi 	args->out_args[0].value = &outarg;
636fcee216bSMax Reitz 	err = fuse_simple_request(fm, args);
6372d51013eSMiklos Szeredi 	if (err)
6382d51013eSMiklos Szeredi 		goto out_put_forget_req;
6392d51013eSMiklos Szeredi 
64039ee059aSMiklos Szeredi 	err = -EIO;
641eb59bd17SMiklos Szeredi 	if (invalid_nodeid(outarg.nodeid) || fuse_invalid_attr(&outarg.attr))
6422d51013eSMiklos Szeredi 		goto out_put_forget_req;
64339ee059aSMiklos Szeredi 
64439ee059aSMiklos Szeredi 	if ((outarg.attr.mode ^ mode) & S_IFMT)
6452d51013eSMiklos Szeredi 		goto out_put_forget_req;
64639ee059aSMiklos Szeredi 
6479e6268dbSMiklos Szeredi 	inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
6481fb69e78SMiklos Szeredi 			  &outarg.attr, entry_attr_timeout(&outarg), 0);
6499e6268dbSMiklos Szeredi 	if (!inode) {
650fcee216bSMax Reitz 		fuse_queue_forget(fm->fc, forget, outarg.nodeid, 1);
6519e6268dbSMiklos Szeredi 		return -ENOMEM;
6529e6268dbSMiklos Szeredi 	}
65307e77dcaSMiklos Szeredi 	kfree(forget);
6549e6268dbSMiklos Szeredi 
655c971e6a0SAl Viro 	d_drop(entry);
656c971e6a0SAl Viro 	d = d_splice_alias(inode, entry);
657c971e6a0SAl Viro 	if (IS_ERR(d))
658c971e6a0SAl Viro 		return PTR_ERR(d);
659d2a85164SMiklos Szeredi 
660c971e6a0SAl Viro 	if (d) {
661c971e6a0SAl Viro 		fuse_change_entry_timeout(d, &outarg);
662c971e6a0SAl Viro 		dput(d);
663c971e6a0SAl Viro 	} else {
6641fb69e78SMiklos Szeredi 		fuse_change_entry_timeout(entry, &outarg);
665c971e6a0SAl Viro 	}
666261aaba7SMiklos Szeredi 	fuse_dir_changed(dir);
6679e6268dbSMiklos Szeredi 	return 0;
66839ee059aSMiklos Szeredi 
6692d51013eSMiklos Szeredi  out_put_forget_req:
67007e77dcaSMiklos Szeredi 	kfree(forget);
67139ee059aSMiklos Szeredi 	return err;
6729e6268dbSMiklos Szeredi }
6739e6268dbSMiklos Szeredi 
674549c7297SChristian Brauner static int fuse_mknod(struct user_namespace *mnt_userns, struct inode *dir,
675549c7297SChristian Brauner 		      struct dentry *entry, umode_t mode, dev_t rdev)
6769e6268dbSMiklos Szeredi {
6779e6268dbSMiklos Szeredi 	struct fuse_mknod_in inarg;
678fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(dir);
6797078187aSMiklos Szeredi 	FUSE_ARGS(args);
6809e6268dbSMiklos Szeredi 
681fcee216bSMax Reitz 	if (!fm->fc->dont_mask)
682e0a43ddcSMiklos Szeredi 		mode &= ~current_umask();
683e0a43ddcSMiklos Szeredi 
6849e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
6859e6268dbSMiklos Szeredi 	inarg.mode = mode;
6869e6268dbSMiklos Szeredi 	inarg.rdev = new_encode_dev(rdev);
687e0a43ddcSMiklos Szeredi 	inarg.umask = current_umask();
688d5b48543SMiklos Szeredi 	args.opcode = FUSE_MKNOD;
689d5b48543SMiklos Szeredi 	args.in_numargs = 2;
690d5b48543SMiklos Szeredi 	args.in_args[0].size = sizeof(inarg);
691d5b48543SMiklos Szeredi 	args.in_args[0].value = &inarg;
692d5b48543SMiklos Szeredi 	args.in_args[1].size = entry->d_name.len + 1;
693d5b48543SMiklos Szeredi 	args.in_args[1].value = entry->d_name.name;
694fcee216bSMax Reitz 	return create_new_entry(fm, &args, dir, entry, mode);
6959e6268dbSMiklos Szeredi }
6969e6268dbSMiklos Szeredi 
697549c7297SChristian Brauner static int fuse_create(struct user_namespace *mnt_userns, struct inode *dir,
698549c7297SChristian Brauner 		       struct dentry *entry, umode_t mode, bool excl)
6999e6268dbSMiklos Szeredi {
700549c7297SChristian Brauner 	return fuse_mknod(&init_user_ns, dir, entry, mode, 0);
7019e6268dbSMiklos Szeredi }
7029e6268dbSMiklos Szeredi 
703549c7297SChristian Brauner static int fuse_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
704549c7297SChristian Brauner 		      struct dentry *entry, umode_t mode)
7059e6268dbSMiklos Szeredi {
7069e6268dbSMiklos Szeredi 	struct fuse_mkdir_in inarg;
707fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(dir);
7087078187aSMiklos Szeredi 	FUSE_ARGS(args);
7099e6268dbSMiklos Szeredi 
710fcee216bSMax Reitz 	if (!fm->fc->dont_mask)
711e0a43ddcSMiklos Szeredi 		mode &= ~current_umask();
712e0a43ddcSMiklos Szeredi 
7139e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
7149e6268dbSMiklos Szeredi 	inarg.mode = mode;
715e0a43ddcSMiklos Szeredi 	inarg.umask = current_umask();
716d5b48543SMiklos Szeredi 	args.opcode = FUSE_MKDIR;
717d5b48543SMiklos Szeredi 	args.in_numargs = 2;
718d5b48543SMiklos Szeredi 	args.in_args[0].size = sizeof(inarg);
719d5b48543SMiklos Szeredi 	args.in_args[0].value = &inarg;
720d5b48543SMiklos Szeredi 	args.in_args[1].size = entry->d_name.len + 1;
721d5b48543SMiklos Szeredi 	args.in_args[1].value = entry->d_name.name;
722fcee216bSMax Reitz 	return create_new_entry(fm, &args, dir, entry, S_IFDIR);
7239e6268dbSMiklos Szeredi }
7249e6268dbSMiklos Szeredi 
725549c7297SChristian Brauner static int fuse_symlink(struct user_namespace *mnt_userns, struct inode *dir,
726549c7297SChristian Brauner 			struct dentry *entry, const char *link)
7279e6268dbSMiklos Szeredi {
728fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(dir);
7299e6268dbSMiklos Szeredi 	unsigned len = strlen(link) + 1;
7307078187aSMiklos Szeredi 	FUSE_ARGS(args);
7319e6268dbSMiklos Szeredi 
732d5b48543SMiklos Szeredi 	args.opcode = FUSE_SYMLINK;
733d5b48543SMiklos Szeredi 	args.in_numargs = 2;
734d5b48543SMiklos Szeredi 	args.in_args[0].size = entry->d_name.len + 1;
735d5b48543SMiklos Szeredi 	args.in_args[0].value = entry->d_name.name;
736d5b48543SMiklos Szeredi 	args.in_args[1].size = len;
737d5b48543SMiklos Szeredi 	args.in_args[1].value = link;
738fcee216bSMax Reitz 	return create_new_entry(fm, &args, dir, entry, S_IFLNK);
7399e6268dbSMiklos Szeredi }
7409e6268dbSMiklos Szeredi 
7415c791fe1SMiklos Szeredi void fuse_flush_time_update(struct inode *inode)
7425c791fe1SMiklos Szeredi {
7435c791fe1SMiklos Szeredi 	int err = sync_inode_metadata(inode, 1);
7445c791fe1SMiklos Szeredi 
7455c791fe1SMiklos Szeredi 	mapping_set_error(inode->i_mapping, err);
7465c791fe1SMiklos Szeredi }
7475c791fe1SMiklos Szeredi 
748703c7362SSeth Forshee void fuse_update_ctime(struct inode *inode)
74931f3267bSMaxim Patlasov {
750371e8fd0SMiklos Szeredi 	fuse_invalidate_attr(inode);
75131f3267bSMaxim Patlasov 	if (!IS_NOCMTIME(inode)) {
752c2050a45SDeepa Dinamani 		inode->i_ctime = current_time(inode);
75331f3267bSMaxim Patlasov 		mark_inode_dirty_sync(inode);
7545c791fe1SMiklos Szeredi 		fuse_flush_time_update(inode);
75531f3267bSMaxim Patlasov 	}
75631f3267bSMaxim Patlasov }
75731f3267bSMaxim Patlasov 
758*cefd1b83SMiklos Szeredi static void fuse_entry_unlinked(struct dentry *entry)
759*cefd1b83SMiklos Szeredi {
760*cefd1b83SMiklos Szeredi 	struct inode *inode = d_inode(entry);
761*cefd1b83SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
762*cefd1b83SMiklos Szeredi 	struct fuse_inode *fi = get_fuse_inode(inode);
763*cefd1b83SMiklos Szeredi 
764*cefd1b83SMiklos Szeredi 	spin_lock(&fi->lock);
765*cefd1b83SMiklos Szeredi 	fi->attr_version = atomic64_inc_return(&fc->attr_version);
766*cefd1b83SMiklos Szeredi 	/*
767*cefd1b83SMiklos Szeredi 	 * If i_nlink == 0 then unlink doesn't make sense, yet this can
768*cefd1b83SMiklos Szeredi 	 * happen if userspace filesystem is careless.  It would be
769*cefd1b83SMiklos Szeredi 	 * difficult to enforce correct nlink usage so just ignore this
770*cefd1b83SMiklos Szeredi 	 * condition here
771*cefd1b83SMiklos Szeredi 	 */
772*cefd1b83SMiklos Szeredi 	if (S_ISDIR(inode->i_mode))
773*cefd1b83SMiklos Szeredi 		clear_nlink(inode);
774*cefd1b83SMiklos Szeredi 	else if (inode->i_nlink > 0)
775*cefd1b83SMiklos Szeredi 		drop_nlink(inode);
776*cefd1b83SMiklos Szeredi 	spin_unlock(&fi->lock);
777*cefd1b83SMiklos Szeredi 	fuse_invalidate_entry_cache(entry);
778*cefd1b83SMiklos Szeredi 	fuse_update_ctime(inode);
779*cefd1b83SMiklos Szeredi }
780*cefd1b83SMiklos Szeredi 
7819e6268dbSMiklos Szeredi static int fuse_unlink(struct inode *dir, struct dentry *entry)
7829e6268dbSMiklos Szeredi {
7839e6268dbSMiklos Szeredi 	int err;
784fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(dir);
7857078187aSMiklos Szeredi 	FUSE_ARGS(args);
7869e6268dbSMiklos Szeredi 
7875d069dbeSMiklos Szeredi 	if (fuse_is_bad(dir))
7885d069dbeSMiklos Szeredi 		return -EIO;
7895d069dbeSMiklos Szeredi 
790d5b48543SMiklos Szeredi 	args.opcode = FUSE_UNLINK;
791d5b48543SMiklos Szeredi 	args.nodeid = get_node_id(dir);
792d5b48543SMiklos Szeredi 	args.in_numargs = 1;
793d5b48543SMiklos Szeredi 	args.in_args[0].size = entry->d_name.len + 1;
794d5b48543SMiklos Szeredi 	args.in_args[0].value = entry->d_name.name;
795fcee216bSMax Reitz 	err = fuse_simple_request(fm, &args);
7969e6268dbSMiklos Szeredi 	if (!err) {
797261aaba7SMiklos Szeredi 		fuse_dir_changed(dir);
798*cefd1b83SMiklos Szeredi 		fuse_entry_unlinked(entry);
7999e6268dbSMiklos Szeredi 	} else if (err == -EINTR)
8009e6268dbSMiklos Szeredi 		fuse_invalidate_entry(entry);
8019e6268dbSMiklos Szeredi 	return err;
8029e6268dbSMiklos Szeredi }
8039e6268dbSMiklos Szeredi 
8049e6268dbSMiklos Szeredi static int fuse_rmdir(struct inode *dir, struct dentry *entry)
8059e6268dbSMiklos Szeredi {
8069e6268dbSMiklos Szeredi 	int err;
807fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(dir);
8087078187aSMiklos Szeredi 	FUSE_ARGS(args);
8099e6268dbSMiklos Szeredi 
8105d069dbeSMiklos Szeredi 	if (fuse_is_bad(dir))
8115d069dbeSMiklos Szeredi 		return -EIO;
8125d069dbeSMiklos Szeredi 
813d5b48543SMiklos Szeredi 	args.opcode = FUSE_RMDIR;
814d5b48543SMiklos Szeredi 	args.nodeid = get_node_id(dir);
815d5b48543SMiklos Szeredi 	args.in_numargs = 1;
816d5b48543SMiklos Szeredi 	args.in_args[0].size = entry->d_name.len + 1;
817d5b48543SMiklos Szeredi 	args.in_args[0].value = entry->d_name.name;
818fcee216bSMax Reitz 	err = fuse_simple_request(fm, &args);
8199e6268dbSMiklos Szeredi 	if (!err) {
820261aaba7SMiklos Szeredi 		fuse_dir_changed(dir);
821*cefd1b83SMiklos Szeredi 		fuse_entry_unlinked(entry);
8229e6268dbSMiklos Szeredi 	} else if (err == -EINTR)
8239e6268dbSMiklos Szeredi 		fuse_invalidate_entry(entry);
8249e6268dbSMiklos Szeredi 	return err;
8259e6268dbSMiklos Szeredi }
8269e6268dbSMiklos Szeredi 
8271560c974SMiklos Szeredi static int fuse_rename_common(struct inode *olddir, struct dentry *oldent,
8281560c974SMiklos Szeredi 			      struct inode *newdir, struct dentry *newent,
8291560c974SMiklos Szeredi 			      unsigned int flags, int opcode, size_t argsize)
8309e6268dbSMiklos Szeredi {
8319e6268dbSMiklos Szeredi 	int err;
8321560c974SMiklos Szeredi 	struct fuse_rename2_in inarg;
833fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(olddir);
8347078187aSMiklos Szeredi 	FUSE_ARGS(args);
8359e6268dbSMiklos Szeredi 
8361560c974SMiklos Szeredi 	memset(&inarg, 0, argsize);
8379e6268dbSMiklos Szeredi 	inarg.newdir = get_node_id(newdir);
8381560c974SMiklos Szeredi 	inarg.flags = flags;
839d5b48543SMiklos Szeredi 	args.opcode = opcode;
840d5b48543SMiklos Szeredi 	args.nodeid = get_node_id(olddir);
841d5b48543SMiklos Szeredi 	args.in_numargs = 3;
842d5b48543SMiklos Szeredi 	args.in_args[0].size = argsize;
843d5b48543SMiklos Szeredi 	args.in_args[0].value = &inarg;
844d5b48543SMiklos Szeredi 	args.in_args[1].size = oldent->d_name.len + 1;
845d5b48543SMiklos Szeredi 	args.in_args[1].value = oldent->d_name.name;
846d5b48543SMiklos Szeredi 	args.in_args[2].size = newent->d_name.len + 1;
847d5b48543SMiklos Szeredi 	args.in_args[2].value = newent->d_name.name;
848fcee216bSMax Reitz 	err = fuse_simple_request(fm, &args);
8499e6268dbSMiklos Szeredi 	if (!err) {
85008b63307SMiklos Szeredi 		/* ctime changes */
8512b0143b5SDavid Howells 		fuse_update_ctime(d_inode(oldent));
85208b63307SMiklos Szeredi 
853371e8fd0SMiklos Szeredi 		if (flags & RENAME_EXCHANGE)
8542b0143b5SDavid Howells 			fuse_update_ctime(d_inode(newent));
8551560c974SMiklos Szeredi 
856261aaba7SMiklos Szeredi 		fuse_dir_changed(olddir);
8579e6268dbSMiklos Szeredi 		if (olddir != newdir)
858261aaba7SMiklos Szeredi 			fuse_dir_changed(newdir);
8598cbdf1e6SMiklos Szeredi 
8608cbdf1e6SMiklos Szeredi 		/* newent will end up negative */
861*cefd1b83SMiklos Szeredi 		if (!(flags & RENAME_EXCHANGE) && d_really_is_positive(newent))
862*cefd1b83SMiklos Szeredi 			fuse_entry_unlinked(newent);
8639e6268dbSMiklos Szeredi 	} else if (err == -EINTR) {
8649e6268dbSMiklos Szeredi 		/* If request was interrupted, DEITY only knows if the
8659e6268dbSMiklos Szeredi 		   rename actually took place.  If the invalidation
8669e6268dbSMiklos Szeredi 		   fails (e.g. some process has CWD under the renamed
8679e6268dbSMiklos Szeredi 		   directory), then there can be inconsistency between
8689e6268dbSMiklos Szeredi 		   the dcache and the real filesystem.  Tough luck. */
8699e6268dbSMiklos Szeredi 		fuse_invalidate_entry(oldent);
8702b0143b5SDavid Howells 		if (d_really_is_positive(newent))
8719e6268dbSMiklos Szeredi 			fuse_invalidate_entry(newent);
8729e6268dbSMiklos Szeredi 	}
8739e6268dbSMiklos Szeredi 
8749e6268dbSMiklos Szeredi 	return err;
8759e6268dbSMiklos Szeredi }
8769e6268dbSMiklos Szeredi 
877549c7297SChristian Brauner static int fuse_rename2(struct user_namespace *mnt_userns, struct inode *olddir,
878549c7297SChristian Brauner 			struct dentry *oldent, struct inode *newdir,
879549c7297SChristian Brauner 			struct dentry *newent, unsigned int flags)
8801560c974SMiklos Szeredi {
8811560c974SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(olddir);
8821560c974SMiklos Szeredi 	int err;
8831560c974SMiklos Szeredi 
8845d069dbeSMiklos Szeredi 	if (fuse_is_bad(olddir))
8855d069dbeSMiklos Szeredi 		return -EIO;
8865d069dbeSMiklos Szeredi 
887519525faSVivek Goyal 	if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT))
8881560c974SMiklos Szeredi 		return -EINVAL;
8891560c974SMiklos Szeredi 
8904237ba43SMiklos Szeredi 	if (flags) {
8911560c974SMiklos Szeredi 		if (fc->no_rename2 || fc->minor < 23)
8921560c974SMiklos Szeredi 			return -EINVAL;
8931560c974SMiklos Szeredi 
8941560c974SMiklos Szeredi 		err = fuse_rename_common(olddir, oldent, newdir, newent, flags,
8954237ba43SMiklos Szeredi 					 FUSE_RENAME2,
8964237ba43SMiklos Szeredi 					 sizeof(struct fuse_rename2_in));
8971560c974SMiklos Szeredi 		if (err == -ENOSYS) {
8981560c974SMiklos Szeredi 			fc->no_rename2 = 1;
8991560c974SMiklos Szeredi 			err = -EINVAL;
9001560c974SMiklos Szeredi 		}
9014237ba43SMiklos Szeredi 	} else {
9024237ba43SMiklos Szeredi 		err = fuse_rename_common(olddir, oldent, newdir, newent, 0,
9034237ba43SMiklos Szeredi 					 FUSE_RENAME,
9044237ba43SMiklos Szeredi 					 sizeof(struct fuse_rename_in));
9054237ba43SMiklos Szeredi 	}
9061560c974SMiklos Szeredi 
9074237ba43SMiklos Szeredi 	return err;
9084237ba43SMiklos Szeredi }
9094237ba43SMiklos Szeredi 
9109e6268dbSMiklos Szeredi static int fuse_link(struct dentry *entry, struct inode *newdir,
9119e6268dbSMiklos Szeredi 		     struct dentry *newent)
9129e6268dbSMiklos Szeredi {
9139e6268dbSMiklos Szeredi 	int err;
9149e6268dbSMiklos Szeredi 	struct fuse_link_in inarg;
9152b0143b5SDavid Howells 	struct inode *inode = d_inode(entry);
916fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(inode);
9177078187aSMiklos Szeredi 	FUSE_ARGS(args);
9189e6268dbSMiklos Szeredi 
9199e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
9209e6268dbSMiklos Szeredi 	inarg.oldnodeid = get_node_id(inode);
921d5b48543SMiklos Szeredi 	args.opcode = FUSE_LINK;
922d5b48543SMiklos Szeredi 	args.in_numargs = 2;
923d5b48543SMiklos Szeredi 	args.in_args[0].size = sizeof(inarg);
924d5b48543SMiklos Szeredi 	args.in_args[0].value = &inarg;
925d5b48543SMiklos Szeredi 	args.in_args[1].size = newent->d_name.len + 1;
926d5b48543SMiklos Szeredi 	args.in_args[1].value = newent->d_name.name;
927fcee216bSMax Reitz 	err = create_new_entry(fm, &args, newdir, newent, inode->i_mode);
9289e6268dbSMiklos Szeredi 	/* Contrary to "normal" filesystems it can happen that link
9299e6268dbSMiklos Szeredi 	   makes two "logical" inodes point to the same "physical"
9309e6268dbSMiklos Szeredi 	   inode.  We invalidate the attributes of the old one, so it
9319e6268dbSMiklos Szeredi 	   will reflect changes in the backing inode (link count,
9329e6268dbSMiklos Szeredi 	   etc.)
9339e6268dbSMiklos Szeredi 	*/
934ac45d613SMiklos Szeredi 	if (!err) {
935ac45d613SMiklos Szeredi 		struct fuse_inode *fi = get_fuse_inode(inode);
936ac45d613SMiklos Szeredi 
937f15ecfefSKirill Tkhai 		spin_lock(&fi->lock);
938fcee216bSMax Reitz 		fi->attr_version = atomic64_inc_return(&fm->fc->attr_version);
939c634da71SMiklos Szeredi 		if (likely(inode->i_nlink < UINT_MAX))
940ac45d613SMiklos Szeredi 			inc_nlink(inode);
941f15ecfefSKirill Tkhai 		spin_unlock(&fi->lock);
94231f3267bSMaxim Patlasov 		fuse_update_ctime(inode);
943ac45d613SMiklos Szeredi 	} else if (err == -EINTR) {
944ac45d613SMiklos Szeredi 		fuse_invalidate_attr(inode);
945ac45d613SMiklos Szeredi 	}
9469e6268dbSMiklos Szeredi 	return err;
9479e6268dbSMiklos Szeredi }
9489e6268dbSMiklos Szeredi 
9491fb69e78SMiklos Szeredi static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
9501fb69e78SMiklos Szeredi 			  struct kstat *stat)
9511fb69e78SMiklos Szeredi {
952203627bbSMiklos Szeredi 	unsigned int blkbits;
9538373200bSPavel Emelyanov 	struct fuse_conn *fc = get_fuse_conn(inode);
9548373200bSPavel Emelyanov 
9558373200bSPavel Emelyanov 	/* see the comment in fuse_change_attributes() */
956b0aa7606SMaxim Patlasov 	if (fc->writeback_cache && S_ISREG(inode->i_mode)) {
9578373200bSPavel Emelyanov 		attr->size = i_size_read(inode);
958b0aa7606SMaxim Patlasov 		attr->mtime = inode->i_mtime.tv_sec;
959b0aa7606SMaxim Patlasov 		attr->mtimensec = inode->i_mtime.tv_nsec;
96031f3267bSMaxim Patlasov 		attr->ctime = inode->i_ctime.tv_sec;
96131f3267bSMaxim Patlasov 		attr->ctimensec = inode->i_ctime.tv_nsec;
962b0aa7606SMaxim Patlasov 	}
963203627bbSMiklos Szeredi 
9641fb69e78SMiklos Szeredi 	stat->dev = inode->i_sb->s_dev;
9651fb69e78SMiklos Szeredi 	stat->ino = attr->ino;
9661fb69e78SMiklos Szeredi 	stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
9671fb69e78SMiklos Szeredi 	stat->nlink = attr->nlink;
9688cb08329SEric W. Biederman 	stat->uid = make_kuid(fc->user_ns, attr->uid);
9698cb08329SEric W. Biederman 	stat->gid = make_kgid(fc->user_ns, attr->gid);
9701fb69e78SMiklos Szeredi 	stat->rdev = inode->i_rdev;
9711fb69e78SMiklos Szeredi 	stat->atime.tv_sec = attr->atime;
9721fb69e78SMiklos Szeredi 	stat->atime.tv_nsec = attr->atimensec;
9731fb69e78SMiklos Szeredi 	stat->mtime.tv_sec = attr->mtime;
9741fb69e78SMiklos Szeredi 	stat->mtime.tv_nsec = attr->mtimensec;
9751fb69e78SMiklos Szeredi 	stat->ctime.tv_sec = attr->ctime;
9761fb69e78SMiklos Szeredi 	stat->ctime.tv_nsec = attr->ctimensec;
9771fb69e78SMiklos Szeredi 	stat->size = attr->size;
9781fb69e78SMiklos Szeredi 	stat->blocks = attr->blocks;
979203627bbSMiklos Szeredi 
980203627bbSMiklos Szeredi 	if (attr->blksize != 0)
981203627bbSMiklos Szeredi 		blkbits = ilog2(attr->blksize);
982203627bbSMiklos Szeredi 	else
983203627bbSMiklos Szeredi 		blkbits = inode->i_sb->s_blocksize_bits;
984203627bbSMiklos Szeredi 
985203627bbSMiklos Szeredi 	stat->blksize = 1 << blkbits;
9861fb69e78SMiklos Szeredi }
9871fb69e78SMiklos Szeredi 
988c79e322fSMiklos Szeredi static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
989c79e322fSMiklos Szeredi 			   struct file *file)
990e5e5558eSMiklos Szeredi {
991e5e5558eSMiklos Szeredi 	int err;
992c79e322fSMiklos Szeredi 	struct fuse_getattr_in inarg;
993c79e322fSMiklos Szeredi 	struct fuse_attr_out outarg;
994fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(inode);
9957078187aSMiklos Szeredi 	FUSE_ARGS(args);
9961fb69e78SMiklos Szeredi 	u64 attr_version;
9971fb69e78SMiklos Szeredi 
998fcee216bSMax Reitz 	attr_version = fuse_get_attr_version(fm->fc);
9991fb69e78SMiklos Szeredi 
1000c79e322fSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
10010e9663eeSMiklos Szeredi 	memset(&outarg, 0, sizeof(outarg));
1002c79e322fSMiklos Szeredi 	/* Directories have separate file-handle space */
1003c79e322fSMiklos Szeredi 	if (file && S_ISREG(inode->i_mode)) {
1004c79e322fSMiklos Szeredi 		struct fuse_file *ff = file->private_data;
1005c79e322fSMiklos Szeredi 
1006c79e322fSMiklos Szeredi 		inarg.getattr_flags |= FUSE_GETATTR_FH;
1007c79e322fSMiklos Szeredi 		inarg.fh = ff->fh;
1008c79e322fSMiklos Szeredi 	}
1009d5b48543SMiklos Szeredi 	args.opcode = FUSE_GETATTR;
1010d5b48543SMiklos Szeredi 	args.nodeid = get_node_id(inode);
1011d5b48543SMiklos Szeredi 	args.in_numargs = 1;
1012d5b48543SMiklos Szeredi 	args.in_args[0].size = sizeof(inarg);
1013d5b48543SMiklos Szeredi 	args.in_args[0].value = &inarg;
1014d5b48543SMiklos Szeredi 	args.out_numargs = 1;
1015d5b48543SMiklos Szeredi 	args.out_args[0].size = sizeof(outarg);
1016d5b48543SMiklos Szeredi 	args.out_args[0].value = &outarg;
1017fcee216bSMax Reitz 	err = fuse_simple_request(fm, &args);
1018e5e5558eSMiklos Szeredi 	if (!err) {
1019eb59bd17SMiklos Szeredi 		if (fuse_invalid_attr(&outarg.attr) ||
10206e3e2c43SAl Viro 		    inode_wrong_type(inode, outarg.attr.mode)) {
10215d069dbeSMiklos Szeredi 			fuse_make_bad(inode);
1022e5e5558eSMiklos Szeredi 			err = -EIO;
1023e5e5558eSMiklos Szeredi 		} else {
1024c79e322fSMiklos Szeredi 			fuse_change_attributes(inode, &outarg.attr,
1025c79e322fSMiklos Szeredi 					       attr_timeout(&outarg),
10261fb69e78SMiklos Szeredi 					       attr_version);
10271fb69e78SMiklos Szeredi 			if (stat)
1028c79e322fSMiklos Szeredi 				fuse_fillattr(inode, &outarg.attr, stat);
1029e5e5558eSMiklos Szeredi 		}
1030e5e5558eSMiklos Szeredi 	}
1031e5e5558eSMiklos Szeredi 	return err;
1032e5e5558eSMiklos Szeredi }
1033e5e5558eSMiklos Szeredi 
10345b97eeacSMiklos Szeredi static int fuse_update_get_attr(struct inode *inode, struct file *file,
10352f1e8196SMiklos Szeredi 				struct kstat *stat, u32 request_mask,
10362f1e8196SMiklos Szeredi 				unsigned int flags)
1037bcb4be80SMiklos Szeredi {
1038bcb4be80SMiklos Szeredi 	struct fuse_inode *fi = get_fuse_inode(inode);
10395b97eeacSMiklos Szeredi 	int err = 0;
1040bf5c1898SMiklos Szeredi 	bool sync;
1041bcb4be80SMiklos Szeredi 
1042bf5c1898SMiklos Szeredi 	if (flags & AT_STATX_FORCE_SYNC)
1043bf5c1898SMiklos Szeredi 		sync = true;
1044bf5c1898SMiklos Szeredi 	else if (flags & AT_STATX_DONT_SYNC)
1045bf5c1898SMiklos Szeredi 		sync = false;
10462f1e8196SMiklos Szeredi 	else if (request_mask & READ_ONCE(fi->inval_mask))
10472f1e8196SMiklos Szeredi 		sync = true;
1048bf5c1898SMiklos Szeredi 	else
1049bf5c1898SMiklos Szeredi 		sync = time_before64(fi->i_time, get_jiffies_64());
1050bf5c1898SMiklos Szeredi 
1051bf5c1898SMiklos Szeredi 	if (sync) {
105260bcc88aSSeth Forshee 		forget_all_cached_acls(inode);
1053bcb4be80SMiklos Szeredi 		err = fuse_do_getattr(inode, stat, file);
10545b97eeacSMiklos Szeredi 	} else if (stat) {
10550d56a451SChristian Brauner 		generic_fillattr(&init_user_ns, inode, stat);
1056bcb4be80SMiklos Szeredi 		stat->mode = fi->orig_i_mode;
105745c72cd7SPavel Shilovsky 		stat->ino = fi->orig_ino;
1058bcb4be80SMiklos Szeredi 	}
1059bcb4be80SMiklos Szeredi 
1060bcb4be80SMiklos Szeredi 	return err;
1061bcb4be80SMiklos Szeredi }
1062bcb4be80SMiklos Szeredi 
10635b97eeacSMiklos Szeredi int fuse_update_attributes(struct inode *inode, struct file *file)
10645b97eeacSMiklos Szeredi {
1065802dc049SMiklos Szeredi 	/* Do *not* need to get atime for internal purposes */
1066802dc049SMiklos Szeredi 	return fuse_update_get_attr(inode, file, NULL,
1067802dc049SMiklos Szeredi 				    STATX_BASIC_STATS & ~STATX_ATIME, 0);
10685b97eeacSMiklos Szeredi }
10695b97eeacSMiklos Szeredi 
1070fcee216bSMax Reitz int fuse_reverse_inval_entry(struct fuse_conn *fc, u64 parent_nodeid,
1071451d0f59SJohn Muir 			     u64 child_nodeid, struct qstr *name)
10723b463ae0SJohn Muir {
10733b463ae0SJohn Muir 	int err = -ENOTDIR;
10743b463ae0SJohn Muir 	struct inode *parent;
10753b463ae0SJohn Muir 	struct dentry *dir;
10763b463ae0SJohn Muir 	struct dentry *entry;
10773b463ae0SJohn Muir 
1078fcee216bSMax Reitz 	parent = fuse_ilookup(fc, parent_nodeid, NULL);
10793b463ae0SJohn Muir 	if (!parent)
10803b463ae0SJohn Muir 		return -ENOENT;
10813b463ae0SJohn Muir 
1082bda9a719SMiklos Szeredi 	inode_lock_nested(parent, I_MUTEX_PARENT);
10833b463ae0SJohn Muir 	if (!S_ISDIR(parent->i_mode))
10843b463ae0SJohn Muir 		goto unlock;
10853b463ae0SJohn Muir 
10863b463ae0SJohn Muir 	err = -ENOENT;
10873b463ae0SJohn Muir 	dir = d_find_alias(parent);
10883b463ae0SJohn Muir 	if (!dir)
10893b463ae0SJohn Muir 		goto unlock;
10903b463ae0SJohn Muir 
10918387ff25SLinus Torvalds 	name->hash = full_name_hash(dir, name->name, name->len);
10923b463ae0SJohn Muir 	entry = d_lookup(dir, name);
10933b463ae0SJohn Muir 	dput(dir);
10943b463ae0SJohn Muir 	if (!entry)
10953b463ae0SJohn Muir 		goto unlock;
10963b463ae0SJohn Muir 
1097261aaba7SMiklos Szeredi 	fuse_dir_changed(parent);
10983b463ae0SJohn Muir 	fuse_invalidate_entry(entry);
1099451d0f59SJohn Muir 
11002b0143b5SDavid Howells 	if (child_nodeid != 0 && d_really_is_positive(entry)) {
11015955102cSAl Viro 		inode_lock(d_inode(entry));
11022b0143b5SDavid Howells 		if (get_node_id(d_inode(entry)) != child_nodeid) {
1103451d0f59SJohn Muir 			err = -ENOENT;
1104451d0f59SJohn Muir 			goto badentry;
1105451d0f59SJohn Muir 		}
1106451d0f59SJohn Muir 		if (d_mountpoint(entry)) {
1107451d0f59SJohn Muir 			err = -EBUSY;
1108451d0f59SJohn Muir 			goto badentry;
1109451d0f59SJohn Muir 		}
1110e36cb0b8SDavid Howells 		if (d_is_dir(entry)) {
1111451d0f59SJohn Muir 			shrink_dcache_parent(entry);
1112451d0f59SJohn Muir 			if (!simple_empty(entry)) {
1113451d0f59SJohn Muir 				err = -ENOTEMPTY;
1114451d0f59SJohn Muir 				goto badentry;
1115451d0f59SJohn Muir 			}
11162b0143b5SDavid Howells 			d_inode(entry)->i_flags |= S_DEAD;
1117451d0f59SJohn Muir 		}
1118451d0f59SJohn Muir 		dont_mount(entry);
11192b0143b5SDavid Howells 		clear_nlink(d_inode(entry));
11203b463ae0SJohn Muir 		err = 0;
1121451d0f59SJohn Muir  badentry:
11225955102cSAl Viro 		inode_unlock(d_inode(entry));
1123451d0f59SJohn Muir 		if (!err)
1124451d0f59SJohn Muir 			d_delete(entry);
1125451d0f59SJohn Muir 	} else {
1126451d0f59SJohn Muir 		err = 0;
1127451d0f59SJohn Muir 	}
1128451d0f59SJohn Muir 	dput(entry);
11293b463ae0SJohn Muir 
11303b463ae0SJohn Muir  unlock:
11315955102cSAl Viro 	inode_unlock(parent);
11323b463ae0SJohn Muir 	iput(parent);
11333b463ae0SJohn Muir 	return err;
11343b463ae0SJohn Muir }
11353b463ae0SJohn Muir 
113687729a55SMiklos Szeredi /*
113787729a55SMiklos Szeredi  * Calling into a user-controlled filesystem gives the filesystem
1138c2132c1bSAnatol Pomozov  * daemon ptrace-like capabilities over the current process.  This
113987729a55SMiklos Szeredi  * means, that the filesystem daemon is able to record the exact
114087729a55SMiklos Szeredi  * filesystem operations performed, and can also control the behavior
114187729a55SMiklos Szeredi  * of the requester process in otherwise impossible ways.  For example
114287729a55SMiklos Szeredi  * it can delay the operation for arbitrary length of time allowing
114387729a55SMiklos Szeredi  * DoS against the requester.
114487729a55SMiklos Szeredi  *
114587729a55SMiklos Szeredi  * For this reason only those processes can call into the filesystem,
114687729a55SMiklos Szeredi  * for which the owner of the mount has ptrace privilege.  This
114787729a55SMiklos Szeredi  * excludes processes started by other users, suid or sgid processes.
114887729a55SMiklos Szeredi  */
1149c2132c1bSAnatol Pomozov int fuse_allow_current_process(struct fuse_conn *fc)
115087729a55SMiklos Szeredi {
1151c69e8d9cSDavid Howells 	const struct cred *cred;
1152c69e8d9cSDavid Howells 
115329433a29SMiklos Szeredi 	if (fc->allow_other)
115473f03c2bSSeth Forshee 		return current_in_userns(fc->user_ns);
115587729a55SMiklos Szeredi 
1156c2132c1bSAnatol Pomozov 	cred = current_cred();
1157499dcf20SEric W. Biederman 	if (uid_eq(cred->euid, fc->user_id) &&
1158499dcf20SEric W. Biederman 	    uid_eq(cred->suid, fc->user_id) &&
1159499dcf20SEric W. Biederman 	    uid_eq(cred->uid,  fc->user_id) &&
1160499dcf20SEric W. Biederman 	    gid_eq(cred->egid, fc->group_id) &&
1161499dcf20SEric W. Biederman 	    gid_eq(cred->sgid, fc->group_id) &&
1162499dcf20SEric W. Biederman 	    gid_eq(cred->gid,  fc->group_id))
1163c2132c1bSAnatol Pomozov 		return 1;
116487729a55SMiklos Szeredi 
1165c2132c1bSAnatol Pomozov 	return 0;
116687729a55SMiklos Szeredi }
116787729a55SMiklos Szeredi 
116831d40d74SMiklos Szeredi static int fuse_access(struct inode *inode, int mask)
116931d40d74SMiklos Szeredi {
1170fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(inode);
11717078187aSMiklos Szeredi 	FUSE_ARGS(args);
117231d40d74SMiklos Szeredi 	struct fuse_access_in inarg;
117331d40d74SMiklos Szeredi 	int err;
117431d40d74SMiklos Szeredi 
1175698fa1d1SMiklos Szeredi 	BUG_ON(mask & MAY_NOT_BLOCK);
1176698fa1d1SMiklos Szeredi 
1177fcee216bSMax Reitz 	if (fm->fc->no_access)
117831d40d74SMiklos Szeredi 		return 0;
117931d40d74SMiklos Szeredi 
118031d40d74SMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
1181e6305c43SAl Viro 	inarg.mask = mask & (MAY_READ | MAY_WRITE | MAY_EXEC);
1182d5b48543SMiklos Szeredi 	args.opcode = FUSE_ACCESS;
1183d5b48543SMiklos Szeredi 	args.nodeid = get_node_id(inode);
1184d5b48543SMiklos Szeredi 	args.in_numargs = 1;
1185d5b48543SMiklos Szeredi 	args.in_args[0].size = sizeof(inarg);
1186d5b48543SMiklos Szeredi 	args.in_args[0].value = &inarg;
1187fcee216bSMax Reitz 	err = fuse_simple_request(fm, &args);
118831d40d74SMiklos Szeredi 	if (err == -ENOSYS) {
1189fcee216bSMax Reitz 		fm->fc->no_access = 1;
119031d40d74SMiklos Szeredi 		err = 0;
119131d40d74SMiklos Szeredi 	}
119231d40d74SMiklos Szeredi 	return err;
119331d40d74SMiklos Szeredi }
119431d40d74SMiklos Szeredi 
119510556cb2SAl Viro static int fuse_perm_getattr(struct inode *inode, int mask)
119619690ddbSMiklos Szeredi {
119710556cb2SAl Viro 	if (mask & MAY_NOT_BLOCK)
119819690ddbSMiklos Szeredi 		return -ECHILD;
119919690ddbSMiklos Szeredi 
120060bcc88aSSeth Forshee 	forget_all_cached_acls(inode);
120119690ddbSMiklos Szeredi 	return fuse_do_getattr(inode, NULL, NULL);
120219690ddbSMiklos Szeredi }
120319690ddbSMiklos Szeredi 
12046f9f1180SMiklos Szeredi /*
12056f9f1180SMiklos Szeredi  * Check permission.  The two basic access models of FUSE are:
12066f9f1180SMiklos Szeredi  *
12076f9f1180SMiklos Szeredi  * 1) Local access checking ('default_permissions' mount option) based
12086f9f1180SMiklos Szeredi  * on file mode.  This is the plain old disk filesystem permission
12096f9f1180SMiklos Szeredi  * modell.
12106f9f1180SMiklos Szeredi  *
12116f9f1180SMiklos Szeredi  * 2) "Remote" access checking, where server is responsible for
12126f9f1180SMiklos Szeredi  * checking permission in each inode operation.  An exception to this
12136f9f1180SMiklos Szeredi  * is if ->permission() was invoked from sys_access() in which case an
12146f9f1180SMiklos Szeredi  * access request is sent.  Execute permission is still checked
12156f9f1180SMiklos Szeredi  * locally based on file mode.
12166f9f1180SMiklos Szeredi  */
1217549c7297SChristian Brauner static int fuse_permission(struct user_namespace *mnt_userns,
1218549c7297SChristian Brauner 			   struct inode *inode, int mask)
1219e5e5558eSMiklos Szeredi {
1220e5e5558eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
1221244f6385SMiklos Szeredi 	bool refreshed = false;
1222244f6385SMiklos Szeredi 	int err = 0;
1223e5e5558eSMiklos Szeredi 
12245d069dbeSMiklos Szeredi 	if (fuse_is_bad(inode))
12255d069dbeSMiklos Szeredi 		return -EIO;
12265d069dbeSMiklos Szeredi 
1227c2132c1bSAnatol Pomozov 	if (!fuse_allow_current_process(fc))
1228e5e5558eSMiklos Szeredi 		return -EACCES;
1229244f6385SMiklos Szeredi 
1230244f6385SMiklos Szeredi 	/*
1231e8e96157SMiklos Szeredi 	 * If attributes are needed, refresh them before proceeding
1232244f6385SMiklos Szeredi 	 */
123329433a29SMiklos Szeredi 	if (fc->default_permissions ||
1234e8e96157SMiklos Szeredi 	    ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) {
123519690ddbSMiklos Szeredi 		struct fuse_inode *fi = get_fuse_inode(inode);
1236d233c7ddSMiklos Szeredi 		u32 perm_mask = STATX_MODE | STATX_UID | STATX_GID;
123719690ddbSMiklos Szeredi 
1238d233c7ddSMiklos Szeredi 		if (perm_mask & READ_ONCE(fi->inval_mask) ||
1239d233c7ddSMiklos Szeredi 		    time_before64(fi->i_time, get_jiffies_64())) {
124019690ddbSMiklos Szeredi 			refreshed = true;
124119690ddbSMiklos Szeredi 
124210556cb2SAl Viro 			err = fuse_perm_getattr(inode, mask);
1243244f6385SMiklos Szeredi 			if (err)
1244244f6385SMiklos Szeredi 				return err;
12451fb69e78SMiklos Szeredi 		}
124619690ddbSMiklos Szeredi 	}
1247244f6385SMiklos Szeredi 
124829433a29SMiklos Szeredi 	if (fc->default_permissions) {
124947291baaSChristian Brauner 		err = generic_permission(&init_user_ns, inode, mask);
12501e9a4ed9SMiklos Szeredi 
12511e9a4ed9SMiklos Szeredi 		/* If permission is denied, try to refresh file
12521e9a4ed9SMiklos Szeredi 		   attributes.  This is also needed, because the root
12531e9a4ed9SMiklos Szeredi 		   node will at first have no permissions */
1254244f6385SMiklos Szeredi 		if (err == -EACCES && !refreshed) {
125510556cb2SAl Viro 			err = fuse_perm_getattr(inode, mask);
12561e9a4ed9SMiklos Szeredi 			if (!err)
125747291baaSChristian Brauner 				err = generic_permission(&init_user_ns,
125847291baaSChristian Brauner 							 inode, mask);
12591e9a4ed9SMiklos Szeredi 		}
12601e9a4ed9SMiklos Szeredi 
12616f9f1180SMiklos Szeredi 		/* Note: the opposite of the above test does not
12626f9f1180SMiklos Szeredi 		   exist.  So if permissions are revoked this won't be
12636f9f1180SMiklos Szeredi 		   noticed immediately, only after the attribute
12646f9f1180SMiklos Szeredi 		   timeout has expired */
12659cfcac81SEric Paris 	} else if (mask & (MAY_ACCESS | MAY_CHDIR)) {
1266e8e96157SMiklos Szeredi 		err = fuse_access(inode, mask);
1267e8e96157SMiklos Szeredi 	} else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
1268e8e96157SMiklos Szeredi 		if (!(inode->i_mode & S_IXUGO)) {
1269e8e96157SMiklos Szeredi 			if (refreshed)
1270e5e5558eSMiklos Szeredi 				return -EACCES;
127131d40d74SMiklos Szeredi 
127210556cb2SAl Viro 			err = fuse_perm_getattr(inode, mask);
1273e8e96157SMiklos Szeredi 			if (!err && !(inode->i_mode & S_IXUGO))
1274e8e96157SMiklos Szeredi 				return -EACCES;
1275e8e96157SMiklos Szeredi 		}
1276e5e5558eSMiklos Szeredi 	}
1277244f6385SMiklos Szeredi 	return err;
1278e5e5558eSMiklos Szeredi }
1279e5e5558eSMiklos Szeredi 
12805571f1e6SDan Schatzberg static int fuse_readlink_page(struct inode *inode, struct page *page)
1281e5e5558eSMiklos Szeredi {
1282fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(inode);
12834c29afecSMiklos Szeredi 	struct fuse_page_desc desc = { .length = PAGE_SIZE - 1 };
12844c29afecSMiklos Szeredi 	struct fuse_args_pages ap = {
12854c29afecSMiklos Szeredi 		.num_pages = 1,
12864c29afecSMiklos Szeredi 		.pages = &page,
12874c29afecSMiklos Szeredi 		.descs = &desc,
12884c29afecSMiklos Szeredi 	};
12894c29afecSMiklos Szeredi 	char *link;
12904c29afecSMiklos Szeredi 	ssize_t res;
1291e5e5558eSMiklos Szeredi 
12924c29afecSMiklos Szeredi 	ap.args.opcode = FUSE_READLINK;
12934c29afecSMiklos Szeredi 	ap.args.nodeid = get_node_id(inode);
12944c29afecSMiklos Szeredi 	ap.args.out_pages = true;
12954c29afecSMiklos Szeredi 	ap.args.out_argvar = true;
12964c29afecSMiklos Szeredi 	ap.args.page_zeroing = true;
12974c29afecSMiklos Szeredi 	ap.args.out_numargs = 1;
12984c29afecSMiklos Szeredi 	ap.args.out_args[0].size = desc.length;
1299fcee216bSMax Reitz 	res = fuse_simple_request(fm, &ap.args);
13006b255391SAl Viro 
1301451418fcSAndrew Gallagher 	fuse_invalidate_atime(inode);
13025571f1e6SDan Schatzberg 
13034c29afecSMiklos Szeredi 	if (res < 0)
13044c29afecSMiklos Szeredi 		return res;
13054c29afecSMiklos Szeredi 
13064c29afecSMiklos Szeredi 	if (WARN_ON(res >= PAGE_SIZE))
13074c29afecSMiklos Szeredi 		return -EIO;
13084c29afecSMiklos Szeredi 
13094c29afecSMiklos Szeredi 	link = page_address(page);
13104c29afecSMiklos Szeredi 	link[res] = '\0';
13114c29afecSMiklos Szeredi 
13124c29afecSMiklos Szeredi 	return 0;
13135571f1e6SDan Schatzberg }
13145571f1e6SDan Schatzberg 
13155571f1e6SDan Schatzberg static const char *fuse_get_link(struct dentry *dentry, struct inode *inode,
13165571f1e6SDan Schatzberg 				 struct delayed_call *callback)
13175571f1e6SDan Schatzberg {
13185571f1e6SDan Schatzberg 	struct fuse_conn *fc = get_fuse_conn(inode);
13195571f1e6SDan Schatzberg 	struct page *page;
13205571f1e6SDan Schatzberg 	int err;
13215571f1e6SDan Schatzberg 
13225571f1e6SDan Schatzberg 	err = -EIO;
13235d069dbeSMiklos Szeredi 	if (fuse_is_bad(inode))
13245571f1e6SDan Schatzberg 		goto out_err;
13255571f1e6SDan Schatzberg 
13265571f1e6SDan Schatzberg 	if (fc->cache_symlinks)
13275571f1e6SDan Schatzberg 		return page_get_link(dentry, inode, callback);
13285571f1e6SDan Schatzberg 
13295571f1e6SDan Schatzberg 	err = -ECHILD;
13305571f1e6SDan Schatzberg 	if (!dentry)
13315571f1e6SDan Schatzberg 		goto out_err;
13325571f1e6SDan Schatzberg 
13335571f1e6SDan Schatzberg 	page = alloc_page(GFP_KERNEL);
13345571f1e6SDan Schatzberg 	err = -ENOMEM;
13355571f1e6SDan Schatzberg 	if (!page)
13365571f1e6SDan Schatzberg 		goto out_err;
13375571f1e6SDan Schatzberg 
13385571f1e6SDan Schatzberg 	err = fuse_readlink_page(inode, page);
13395571f1e6SDan Schatzberg 	if (err) {
13405571f1e6SDan Schatzberg 		__free_page(page);
13415571f1e6SDan Schatzberg 		goto out_err;
13425571f1e6SDan Schatzberg 	}
13435571f1e6SDan Schatzberg 
13445571f1e6SDan Schatzberg 	set_delayed_call(callback, page_put_link, page);
13455571f1e6SDan Schatzberg 
13465571f1e6SDan Schatzberg 	return page_address(page);
13475571f1e6SDan Schatzberg 
13485571f1e6SDan Schatzberg out_err:
13495571f1e6SDan Schatzberg 	return ERR_PTR(err);
1350e5e5558eSMiklos Szeredi }
1351e5e5558eSMiklos Szeredi 
1352e5e5558eSMiklos Szeredi static int fuse_dir_open(struct inode *inode, struct file *file)
1353e5e5558eSMiklos Szeredi {
135491fe96b4SMiklos Szeredi 	return fuse_open_common(inode, file, true);
1355e5e5558eSMiklos Szeredi }
1356e5e5558eSMiklos Szeredi 
1357e5e5558eSMiklos Szeredi static int fuse_dir_release(struct inode *inode, struct file *file)
1358e5e5558eSMiklos Szeredi {
13592e64ff15SChad Austin 	fuse_release_common(file, true);
13608b0797a4SMiklos Szeredi 
13618b0797a4SMiklos Szeredi 	return 0;
1362e5e5558eSMiklos Szeredi }
1363e5e5558eSMiklos Szeredi 
136402c24a82SJosef Bacik static int fuse_dir_fsync(struct file *file, loff_t start, loff_t end,
136502c24a82SJosef Bacik 			  int datasync)
136682547981SMiklos Szeredi {
1367a9c2d1e8SMiklos Szeredi 	struct inode *inode = file->f_mapping->host;
1368a9c2d1e8SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
1369a9c2d1e8SMiklos Szeredi 	int err;
1370a9c2d1e8SMiklos Szeredi 
13715d069dbeSMiklos Szeredi 	if (fuse_is_bad(inode))
1372a9c2d1e8SMiklos Szeredi 		return -EIO;
1373a9c2d1e8SMiklos Szeredi 
1374a9c2d1e8SMiklos Szeredi 	if (fc->no_fsyncdir)
1375a9c2d1e8SMiklos Szeredi 		return 0;
1376a9c2d1e8SMiklos Szeredi 
1377a9c2d1e8SMiklos Szeredi 	inode_lock(inode);
1378a9c2d1e8SMiklos Szeredi 	err = fuse_fsync_common(file, start, end, datasync, FUSE_FSYNCDIR);
1379a9c2d1e8SMiklos Szeredi 	if (err == -ENOSYS) {
1380a9c2d1e8SMiklos Szeredi 		fc->no_fsyncdir = 1;
1381a9c2d1e8SMiklos Szeredi 		err = 0;
1382a9c2d1e8SMiklos Szeredi 	}
1383a9c2d1e8SMiklos Szeredi 	inode_unlock(inode);
1384a9c2d1e8SMiklos Szeredi 
1385a9c2d1e8SMiklos Szeredi 	return err;
138682547981SMiklos Szeredi }
138782547981SMiklos Szeredi 
1388b18da0c5SMiklos Szeredi static long fuse_dir_ioctl(struct file *file, unsigned int cmd,
1389b18da0c5SMiklos Szeredi 			    unsigned long arg)
1390b18da0c5SMiklos Szeredi {
1391b18da0c5SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1392b18da0c5SMiklos Szeredi 
1393b18da0c5SMiklos Szeredi 	/* FUSE_IOCTL_DIR only supported for API version >= 7.18 */
1394b18da0c5SMiklos Szeredi 	if (fc->minor < 18)
1395b18da0c5SMiklos Szeredi 		return -ENOTTY;
1396b18da0c5SMiklos Szeredi 
1397b18da0c5SMiklos Szeredi 	return fuse_ioctl_common(file, cmd, arg, FUSE_IOCTL_DIR);
1398b18da0c5SMiklos Szeredi }
1399b18da0c5SMiklos Szeredi 
1400b18da0c5SMiklos Szeredi static long fuse_dir_compat_ioctl(struct file *file, unsigned int cmd,
1401b18da0c5SMiklos Szeredi 				   unsigned long arg)
1402b18da0c5SMiklos Szeredi {
1403b18da0c5SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1404b18da0c5SMiklos Szeredi 
1405b18da0c5SMiklos Szeredi 	if (fc->minor < 18)
1406b18da0c5SMiklos Szeredi 		return -ENOTTY;
1407b18da0c5SMiklos Szeredi 
1408b18da0c5SMiklos Szeredi 	return fuse_ioctl_common(file, cmd, arg,
1409b18da0c5SMiklos Szeredi 				 FUSE_IOCTL_COMPAT | FUSE_IOCTL_DIR);
1410b18da0c5SMiklos Szeredi }
1411b18da0c5SMiklos Szeredi 
1412b0aa7606SMaxim Patlasov static bool update_mtime(unsigned ivalid, bool trust_local_mtime)
141317637cbaSMiklos Szeredi {
141417637cbaSMiklos Szeredi 	/* Always update if mtime is explicitly set  */
141517637cbaSMiklos Szeredi 	if (ivalid & ATTR_MTIME_SET)
141617637cbaSMiklos Szeredi 		return true;
141717637cbaSMiklos Szeredi 
1418b0aa7606SMaxim Patlasov 	/* Or if kernel i_mtime is the official one */
1419b0aa7606SMaxim Patlasov 	if (trust_local_mtime)
1420b0aa7606SMaxim Patlasov 		return true;
1421b0aa7606SMaxim Patlasov 
142217637cbaSMiklos Szeredi 	/* If it's an open(O_TRUNC) or an ftruncate(), don't update */
142317637cbaSMiklos Szeredi 	if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE)))
142417637cbaSMiklos Szeredi 		return false;
142517637cbaSMiklos Szeredi 
142617637cbaSMiklos Szeredi 	/* In all other cases update */
142717637cbaSMiklos Szeredi 	return true;
142817637cbaSMiklos Szeredi }
142917637cbaSMiklos Szeredi 
14308cb08329SEric W. Biederman static void iattr_to_fattr(struct fuse_conn *fc, struct iattr *iattr,
14318cb08329SEric W. Biederman 			   struct fuse_setattr_in *arg, bool trust_local_cmtime)
14329e6268dbSMiklos Szeredi {
14339e6268dbSMiklos Szeredi 	unsigned ivalid = iattr->ia_valid;
14349e6268dbSMiklos Szeredi 
14359e6268dbSMiklos Szeredi 	if (ivalid & ATTR_MODE)
1436befc649cSMiklos Szeredi 		arg->valid |= FATTR_MODE,   arg->mode = iattr->ia_mode;
14379e6268dbSMiklos Szeredi 	if (ivalid & ATTR_UID)
14388cb08329SEric W. Biederman 		arg->valid |= FATTR_UID,    arg->uid = from_kuid(fc->user_ns, iattr->ia_uid);
14399e6268dbSMiklos Szeredi 	if (ivalid & ATTR_GID)
14408cb08329SEric W. Biederman 		arg->valid |= FATTR_GID,    arg->gid = from_kgid(fc->user_ns, iattr->ia_gid);
14419e6268dbSMiklos Szeredi 	if (ivalid & ATTR_SIZE)
1442befc649cSMiklos Szeredi 		arg->valid |= FATTR_SIZE,   arg->size = iattr->ia_size;
144317637cbaSMiklos Szeredi 	if (ivalid & ATTR_ATIME) {
144417637cbaSMiklos Szeredi 		arg->valid |= FATTR_ATIME;
1445befc649cSMiklos Szeredi 		arg->atime = iattr->ia_atime.tv_sec;
144617637cbaSMiklos Szeredi 		arg->atimensec = iattr->ia_atime.tv_nsec;
144717637cbaSMiklos Szeredi 		if (!(ivalid & ATTR_ATIME_SET))
144817637cbaSMiklos Szeredi 			arg->valid |= FATTR_ATIME_NOW;
144917637cbaSMiklos Szeredi 	}
14503ad22c62SMaxim Patlasov 	if ((ivalid & ATTR_MTIME) && update_mtime(ivalid, trust_local_cmtime)) {
145117637cbaSMiklos Szeredi 		arg->valid |= FATTR_MTIME;
1452befc649cSMiklos Szeredi 		arg->mtime = iattr->ia_mtime.tv_sec;
145317637cbaSMiklos Szeredi 		arg->mtimensec = iattr->ia_mtime.tv_nsec;
14543ad22c62SMaxim Patlasov 		if (!(ivalid & ATTR_MTIME_SET) && !trust_local_cmtime)
145517637cbaSMiklos Szeredi 			arg->valid |= FATTR_MTIME_NOW;
14569e6268dbSMiklos Szeredi 	}
14573ad22c62SMaxim Patlasov 	if ((ivalid & ATTR_CTIME) && trust_local_cmtime) {
14583ad22c62SMaxim Patlasov 		arg->valid |= FATTR_CTIME;
14593ad22c62SMaxim Patlasov 		arg->ctime = iattr->ia_ctime.tv_sec;
14603ad22c62SMaxim Patlasov 		arg->ctimensec = iattr->ia_ctime.tv_nsec;
14613ad22c62SMaxim Patlasov 	}
14629e6268dbSMiklos Szeredi }
14639e6268dbSMiklos Szeredi 
14646f9f1180SMiklos Szeredi /*
14653be5a52bSMiklos Szeredi  * Prevent concurrent writepages on inode
14663be5a52bSMiklos Szeredi  *
14673be5a52bSMiklos Szeredi  * This is done by adding a negative bias to the inode write counter
14683be5a52bSMiklos Szeredi  * and waiting for all pending writes to finish.
14693be5a52bSMiklos Szeredi  */
14703be5a52bSMiklos Szeredi void fuse_set_nowrite(struct inode *inode)
14713be5a52bSMiklos Szeredi {
14723be5a52bSMiklos Szeredi 	struct fuse_inode *fi = get_fuse_inode(inode);
14733be5a52bSMiklos Szeredi 
14745955102cSAl Viro 	BUG_ON(!inode_is_locked(inode));
14753be5a52bSMiklos Szeredi 
1476f15ecfefSKirill Tkhai 	spin_lock(&fi->lock);
14773be5a52bSMiklos Szeredi 	BUG_ON(fi->writectr < 0);
14783be5a52bSMiklos Szeredi 	fi->writectr += FUSE_NOWRITE;
1479f15ecfefSKirill Tkhai 	spin_unlock(&fi->lock);
14803be5a52bSMiklos Szeredi 	wait_event(fi->page_waitq, fi->writectr == FUSE_NOWRITE);
14813be5a52bSMiklos Szeredi }
14823be5a52bSMiklos Szeredi 
14833be5a52bSMiklos Szeredi /*
14843be5a52bSMiklos Szeredi  * Allow writepages on inode
14853be5a52bSMiklos Szeredi  *
14863be5a52bSMiklos Szeredi  * Remove the bias from the writecounter and send any queued
14873be5a52bSMiklos Szeredi  * writepages.
14883be5a52bSMiklos Szeredi  */
14893be5a52bSMiklos Szeredi static void __fuse_release_nowrite(struct inode *inode)
14903be5a52bSMiklos Szeredi {
14913be5a52bSMiklos Szeredi 	struct fuse_inode *fi = get_fuse_inode(inode);
14923be5a52bSMiklos Szeredi 
14933be5a52bSMiklos Szeredi 	BUG_ON(fi->writectr != FUSE_NOWRITE);
14943be5a52bSMiklos Szeredi 	fi->writectr = 0;
14953be5a52bSMiklos Szeredi 	fuse_flush_writepages(inode);
14963be5a52bSMiklos Szeredi }
14973be5a52bSMiklos Szeredi 
14983be5a52bSMiklos Szeredi void fuse_release_nowrite(struct inode *inode)
14993be5a52bSMiklos Szeredi {
1500f15ecfefSKirill Tkhai 	struct fuse_inode *fi = get_fuse_inode(inode);
15013be5a52bSMiklos Szeredi 
1502f15ecfefSKirill Tkhai 	spin_lock(&fi->lock);
15033be5a52bSMiklos Szeredi 	__fuse_release_nowrite(inode);
1504f15ecfefSKirill Tkhai 	spin_unlock(&fi->lock);
15053be5a52bSMiklos Szeredi }
15063be5a52bSMiklos Szeredi 
15077078187aSMiklos Szeredi static void fuse_setattr_fill(struct fuse_conn *fc, struct fuse_args *args,
1508b0aa7606SMaxim Patlasov 			      struct inode *inode,
1509b0aa7606SMaxim Patlasov 			      struct fuse_setattr_in *inarg_p,
1510b0aa7606SMaxim Patlasov 			      struct fuse_attr_out *outarg_p)
1511b0aa7606SMaxim Patlasov {
1512d5b48543SMiklos Szeredi 	args->opcode = FUSE_SETATTR;
1513d5b48543SMiklos Szeredi 	args->nodeid = get_node_id(inode);
1514d5b48543SMiklos Szeredi 	args->in_numargs = 1;
1515d5b48543SMiklos Szeredi 	args->in_args[0].size = sizeof(*inarg_p);
1516d5b48543SMiklos Szeredi 	args->in_args[0].value = inarg_p;
1517d5b48543SMiklos Szeredi 	args->out_numargs = 1;
1518d5b48543SMiklos Szeredi 	args->out_args[0].size = sizeof(*outarg_p);
1519d5b48543SMiklos Szeredi 	args->out_args[0].value = outarg_p;
1520b0aa7606SMaxim Patlasov }
1521b0aa7606SMaxim Patlasov 
1522b0aa7606SMaxim Patlasov /*
1523b0aa7606SMaxim Patlasov  * Flush inode->i_mtime to the server
1524b0aa7606SMaxim Patlasov  */
1525ab9e13f7SMaxim Patlasov int fuse_flush_times(struct inode *inode, struct fuse_file *ff)
1526b0aa7606SMaxim Patlasov {
1527fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(inode);
15287078187aSMiklos Szeredi 	FUSE_ARGS(args);
1529b0aa7606SMaxim Patlasov 	struct fuse_setattr_in inarg;
1530b0aa7606SMaxim Patlasov 	struct fuse_attr_out outarg;
1531b0aa7606SMaxim Patlasov 
1532b0aa7606SMaxim Patlasov 	memset(&inarg, 0, sizeof(inarg));
1533b0aa7606SMaxim Patlasov 	memset(&outarg, 0, sizeof(outarg));
1534b0aa7606SMaxim Patlasov 
1535ab9e13f7SMaxim Patlasov 	inarg.valid = FATTR_MTIME;
1536b0aa7606SMaxim Patlasov 	inarg.mtime = inode->i_mtime.tv_sec;
1537b0aa7606SMaxim Patlasov 	inarg.mtimensec = inode->i_mtime.tv_nsec;
1538fcee216bSMax Reitz 	if (fm->fc->minor >= 23) {
1539ab9e13f7SMaxim Patlasov 		inarg.valid |= FATTR_CTIME;
1540ab9e13f7SMaxim Patlasov 		inarg.ctime = inode->i_ctime.tv_sec;
1541ab9e13f7SMaxim Patlasov 		inarg.ctimensec = inode->i_ctime.tv_nsec;
1542ab9e13f7SMaxim Patlasov 	}
15431e18bda8SMiklos Szeredi 	if (ff) {
15441e18bda8SMiklos Szeredi 		inarg.valid |= FATTR_FH;
15451e18bda8SMiklos Szeredi 		inarg.fh = ff->fh;
15461e18bda8SMiklos Szeredi 	}
1547fcee216bSMax Reitz 	fuse_setattr_fill(fm->fc, &args, inode, &inarg, &outarg);
1548b0aa7606SMaxim Patlasov 
1549fcee216bSMax Reitz 	return fuse_simple_request(fm, &args);
1550b0aa7606SMaxim Patlasov }
1551b0aa7606SMaxim Patlasov 
15523be5a52bSMiklos Szeredi /*
15536f9f1180SMiklos Szeredi  * Set attributes, and at the same time refresh them.
15546f9f1180SMiklos Szeredi  *
15556f9f1180SMiklos Szeredi  * Truncation is slightly complicated, because the 'truncate' request
15566f9f1180SMiklos Szeredi  * may fail, in which case we don't want to touch the mapping.
15579ffbb916SMiklos Szeredi  * vmtruncate() doesn't allow for this case, so do the rlimit checking
15589ffbb916SMiklos Szeredi  * and the actual truncation by hand.
15596f9f1180SMiklos Szeredi  */
156062490330SJan Kara int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
156149d4914fSMiklos Szeredi 		    struct file *file)
15629e6268dbSMiklos Szeredi {
156362490330SJan Kara 	struct inode *inode = d_inode(dentry);
1564fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(inode);
1565fcee216bSMax Reitz 	struct fuse_conn *fc = fm->fc;
156606a7c3c2SMaxim Patlasov 	struct fuse_inode *fi = get_fuse_inode(inode);
15678bcbbe9cSJan Kara 	struct address_space *mapping = inode->i_mapping;
15687078187aSMiklos Szeredi 	FUSE_ARGS(args);
15699e6268dbSMiklos Szeredi 	struct fuse_setattr_in inarg;
15709e6268dbSMiklos Szeredi 	struct fuse_attr_out outarg;
15713be5a52bSMiklos Szeredi 	bool is_truncate = false;
15728373200bSPavel Emelyanov 	bool is_wb = fc->writeback_cache;
15733be5a52bSMiklos Szeredi 	loff_t oldsize;
15749e6268dbSMiklos Szeredi 	int err;
15753ad22c62SMaxim Patlasov 	bool trust_local_cmtime = is_wb && S_ISREG(inode->i_mode);
15766ae330caSVivek Goyal 	bool fault_blocked = false;
15779e6268dbSMiklos Szeredi 
157829433a29SMiklos Szeredi 	if (!fc->default_permissions)
1579db78b877SChristoph Hellwig 		attr->ia_valid |= ATTR_FORCE;
1580db78b877SChristoph Hellwig 
15812f221d6fSChristian Brauner 	err = setattr_prepare(&init_user_ns, dentry, attr);
15821e9a4ed9SMiklos Szeredi 	if (err)
15831e9a4ed9SMiklos Szeredi 		return err;
15841e9a4ed9SMiklos Szeredi 
15856ae330caSVivek Goyal 	if (attr->ia_valid & ATTR_SIZE) {
15866ae330caSVivek Goyal 		if (WARN_ON(!S_ISREG(inode->i_mode)))
15876ae330caSVivek Goyal 			return -EIO;
15886ae330caSVivek Goyal 		is_truncate = true;
15896ae330caSVivek Goyal 	}
15906ae330caSVivek Goyal 
15916ae330caSVivek Goyal 	if (FUSE_IS_DAX(inode) && is_truncate) {
15928bcbbe9cSJan Kara 		filemap_invalidate_lock(mapping);
15936ae330caSVivek Goyal 		fault_blocked = true;
15946ae330caSVivek Goyal 		err = fuse_dax_break_layouts(inode, 0, 0);
15956ae330caSVivek Goyal 		if (err) {
15968bcbbe9cSJan Kara 			filemap_invalidate_unlock(mapping);
15976ae330caSVivek Goyal 			return err;
15986ae330caSVivek Goyal 		}
15996ae330caSVivek Goyal 	}
16006ae330caSVivek Goyal 
16018d56adddSMiklos Szeredi 	if (attr->ia_valid & ATTR_OPEN) {
1602df0e91d4SMiklos Szeredi 		/* This is coming from open(..., ... | O_TRUNC); */
1603df0e91d4SMiklos Szeredi 		WARN_ON(!(attr->ia_valid & ATTR_SIZE));
1604df0e91d4SMiklos Szeredi 		WARN_ON(attr->ia_size != 0);
1605df0e91d4SMiklos Szeredi 		if (fc->atomic_o_trunc) {
1606df0e91d4SMiklos Szeredi 			/*
1607df0e91d4SMiklos Szeredi 			 * No need to send request to userspace, since actual
1608df0e91d4SMiklos Szeredi 			 * truncation has already been done by OPEN.  But still
1609df0e91d4SMiklos Szeredi 			 * need to truncate page cache.
1610df0e91d4SMiklos Szeredi 			 */
1611df0e91d4SMiklos Szeredi 			i_size_write(inode, 0);
1612df0e91d4SMiklos Szeredi 			truncate_pagecache(inode, 0);
16136ae330caSVivek Goyal 			goto out;
1614df0e91d4SMiklos Szeredi 		}
16158d56adddSMiklos Szeredi 		file = NULL;
16168d56adddSMiklos Szeredi 	}
16176ff958edSMiklos Szeredi 
1618b24e7598SMiklos Szeredi 	/* Flush dirty data/metadata before non-truncate SETATTR */
1619b24e7598SMiklos Szeredi 	if (is_wb && S_ISREG(inode->i_mode) &&
1620b24e7598SMiklos Szeredi 	    attr->ia_valid &
1621b24e7598SMiklos Szeredi 			(ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_MTIME_SET |
1622b24e7598SMiklos Szeredi 			 ATTR_TIMES_SET)) {
1623b24e7598SMiklos Szeredi 		err = write_inode_now(inode, true);
1624b24e7598SMiklos Szeredi 		if (err)
1625b24e7598SMiklos Szeredi 			return err;
1626b24e7598SMiklos Szeredi 
1627b24e7598SMiklos Szeredi 		fuse_set_nowrite(inode);
1628b24e7598SMiklos Szeredi 		fuse_release_nowrite(inode);
1629b24e7598SMiklos Szeredi 	}
1630b24e7598SMiklos Szeredi 
163106a7c3c2SMaxim Patlasov 	if (is_truncate) {
16323be5a52bSMiklos Szeredi 		fuse_set_nowrite(inode);
163306a7c3c2SMaxim Patlasov 		set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
16343ad22c62SMaxim Patlasov 		if (trust_local_cmtime && attr->ia_size != inode->i_size)
16353ad22c62SMaxim Patlasov 			attr->ia_valid |= ATTR_MTIME | ATTR_CTIME;
163606a7c3c2SMaxim Patlasov 	}
16373be5a52bSMiklos Szeredi 
16389e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
16390e9663eeSMiklos Szeredi 	memset(&outarg, 0, sizeof(outarg));
16408cb08329SEric W. Biederman 	iattr_to_fattr(fc, attr, &inarg, trust_local_cmtime);
164149d4914fSMiklos Szeredi 	if (file) {
164249d4914fSMiklos Szeredi 		struct fuse_file *ff = file->private_data;
164349d4914fSMiklos Szeredi 		inarg.valid |= FATTR_FH;
164449d4914fSMiklos Szeredi 		inarg.fh = ff->fh;
164549d4914fSMiklos Szeredi 	}
164631792161SVivek Goyal 
164731792161SVivek Goyal 	/* Kill suid/sgid for non-directory chown unconditionally */
164831792161SVivek Goyal 	if (fc->handle_killpriv_v2 && !S_ISDIR(inode->i_mode) &&
164931792161SVivek Goyal 	    attr->ia_valid & (ATTR_UID | ATTR_GID))
165031792161SVivek Goyal 		inarg.valid |= FATTR_KILL_SUIDGID;
165131792161SVivek Goyal 
1652f3332114SMiklos Szeredi 	if (attr->ia_valid & ATTR_SIZE) {
1653f3332114SMiklos Szeredi 		/* For mandatory locking in truncate */
1654f3332114SMiklos Szeredi 		inarg.valid |= FATTR_LOCKOWNER;
1655f3332114SMiklos Szeredi 		inarg.lock_owner = fuse_lock_owner_id(fc, current->files);
165631792161SVivek Goyal 
165731792161SVivek Goyal 		/* Kill suid/sgid for truncate only if no CAP_FSETID */
165831792161SVivek Goyal 		if (fc->handle_killpriv_v2 && !capable(CAP_FSETID))
165931792161SVivek Goyal 			inarg.valid |= FATTR_KILL_SUIDGID;
1660f3332114SMiklos Szeredi 	}
16617078187aSMiklos Szeredi 	fuse_setattr_fill(fc, &args, inode, &inarg, &outarg);
1662fcee216bSMax Reitz 	err = fuse_simple_request(fm, &args);
1663e00d2c2dSMiklos Szeredi 	if (err) {
1664e00d2c2dSMiklos Szeredi 		if (err == -EINTR)
1665e00d2c2dSMiklos Szeredi 			fuse_invalidate_attr(inode);
16663be5a52bSMiklos Szeredi 		goto error;
1667e00d2c2dSMiklos Szeredi 	}
1668e00d2c2dSMiklos Szeredi 
1669eb59bd17SMiklos Szeredi 	if (fuse_invalid_attr(&outarg.attr) ||
16706e3e2c43SAl Viro 	    inode_wrong_type(inode, outarg.attr.mode)) {
16715d069dbeSMiklos Szeredi 		fuse_make_bad(inode);
16723be5a52bSMiklos Szeredi 		err = -EIO;
16733be5a52bSMiklos Szeredi 		goto error;
16749e6268dbSMiklos Szeredi 	}
16759e6268dbSMiklos Szeredi 
1676f15ecfefSKirill Tkhai 	spin_lock(&fi->lock);
1677b0aa7606SMaxim Patlasov 	/* the kernel maintains i_mtime locally */
16783ad22c62SMaxim Patlasov 	if (trust_local_cmtime) {
16793ad22c62SMaxim Patlasov 		if (attr->ia_valid & ATTR_MTIME)
1680b0aa7606SMaxim Patlasov 			inode->i_mtime = attr->ia_mtime;
16813ad22c62SMaxim Patlasov 		if (attr->ia_valid & ATTR_CTIME)
16823ad22c62SMaxim Patlasov 			inode->i_ctime = attr->ia_ctime;
16831e18bda8SMiklos Szeredi 		/* FIXME: clear I_DIRTY_SYNC? */
1684b0aa7606SMaxim Patlasov 	}
1685b0aa7606SMaxim Patlasov 
16863be5a52bSMiklos Szeredi 	fuse_change_attributes_common(inode, &outarg.attr,
16873be5a52bSMiklos Szeredi 				      attr_timeout(&outarg));
16883be5a52bSMiklos Szeredi 	oldsize = inode->i_size;
16898373200bSPavel Emelyanov 	/* see the comment in fuse_change_attributes() */
16908373200bSPavel Emelyanov 	if (!is_wb || is_truncate || !S_ISREG(inode->i_mode))
16913be5a52bSMiklos Szeredi 		i_size_write(inode, outarg.attr.size);
16923be5a52bSMiklos Szeredi 
16933be5a52bSMiklos Szeredi 	if (is_truncate) {
1694f15ecfefSKirill Tkhai 		/* NOTE: this may release/reacquire fi->lock */
16953be5a52bSMiklos Szeredi 		__fuse_release_nowrite(inode);
16963be5a52bSMiklos Szeredi 	}
1697f15ecfefSKirill Tkhai 	spin_unlock(&fi->lock);
16983be5a52bSMiklos Szeredi 
16993be5a52bSMiklos Szeredi 	/*
17003be5a52bSMiklos Szeredi 	 * Only call invalidate_inode_pages2() after removing
17013be5a52bSMiklos Szeredi 	 * FUSE_NOWRITE, otherwise fuse_launder_page() would deadlock.
17023be5a52bSMiklos Szeredi 	 */
17038373200bSPavel Emelyanov 	if ((is_truncate || !is_wb) &&
17048373200bSPavel Emelyanov 	    S_ISREG(inode->i_mode) && oldsize != outarg.attr.size) {
17057caef267SKirill A. Shutemov 		truncate_pagecache(inode, outarg.attr.size);
17068bcbbe9cSJan Kara 		invalidate_inode_pages2(mapping);
17073be5a52bSMiklos Szeredi 	}
17083be5a52bSMiklos Szeredi 
170906a7c3c2SMaxim Patlasov 	clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
17106ae330caSVivek Goyal out:
17116ae330caSVivek Goyal 	if (fault_blocked)
17128bcbbe9cSJan Kara 		filemap_invalidate_unlock(mapping);
17136ae330caSVivek Goyal 
1714e00d2c2dSMiklos Szeredi 	return 0;
17153be5a52bSMiklos Szeredi 
17163be5a52bSMiklos Szeredi error:
17173be5a52bSMiklos Szeredi 	if (is_truncate)
17183be5a52bSMiklos Szeredi 		fuse_release_nowrite(inode);
17193be5a52bSMiklos Szeredi 
172006a7c3c2SMaxim Patlasov 	clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
17216ae330caSVivek Goyal 
17226ae330caSVivek Goyal 	if (fault_blocked)
17238bcbbe9cSJan Kara 		filemap_invalidate_unlock(mapping);
17243be5a52bSMiklos Szeredi 	return err;
17259e6268dbSMiklos Szeredi }
17269e6268dbSMiklos Szeredi 
1727549c7297SChristian Brauner static int fuse_setattr(struct user_namespace *mnt_userns, struct dentry *entry,
1728549c7297SChristian Brauner 			struct iattr *attr)
172949d4914fSMiklos Szeredi {
17302b0143b5SDavid Howells 	struct inode *inode = d_inode(entry);
17315e940c1dSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
1732a09f99edSMiklos Szeredi 	struct file *file = (attr->ia_valid & ATTR_FILE) ? attr->ia_file : NULL;
17335e2b8828SMiklos Szeredi 	int ret;
1734efb9fa9eSMaxim Patlasov 
17355d069dbeSMiklos Szeredi 	if (fuse_is_bad(inode))
17365d069dbeSMiklos Szeredi 		return -EIO;
17375d069dbeSMiklos Szeredi 
1738efb9fa9eSMaxim Patlasov 	if (!fuse_allow_current_process(get_fuse_conn(inode)))
1739efb9fa9eSMaxim Patlasov 		return -EACCES;
1740efb9fa9eSMaxim Patlasov 
1741a09f99edSMiklos Szeredi 	if (attr->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) {
1742a09f99edSMiklos Szeredi 		attr->ia_valid &= ~(ATTR_KILL_SUID | ATTR_KILL_SGID |
1743a09f99edSMiklos Szeredi 				    ATTR_MODE);
17445e940c1dSMiklos Szeredi 
1745a09f99edSMiklos Szeredi 		/*
17465e940c1dSMiklos Szeredi 		 * The only sane way to reliably kill suid/sgid is to do it in
17475e940c1dSMiklos Szeredi 		 * the userspace filesystem
17485e940c1dSMiklos Szeredi 		 *
17495e940c1dSMiklos Szeredi 		 * This should be done on write(), truncate() and chown().
17505e940c1dSMiklos Szeredi 		 */
17518981bdfdSVivek Goyal 		if (!fc->handle_killpriv && !fc->handle_killpriv_v2) {
17525e940c1dSMiklos Szeredi 			/*
17535e940c1dSMiklos Szeredi 			 * ia_mode calculation may have used stale i_mode.
17545e940c1dSMiklos Szeredi 			 * Refresh and recalculate.
1755a09f99edSMiklos Szeredi 			 */
1756a09f99edSMiklos Szeredi 			ret = fuse_do_getattr(inode, NULL, file);
1757a09f99edSMiklos Szeredi 			if (ret)
1758a09f99edSMiklos Szeredi 				return ret;
1759a09f99edSMiklos Szeredi 
1760a09f99edSMiklos Szeredi 			attr->ia_mode = inode->i_mode;
1761c01638f5SMiklos Szeredi 			if (inode->i_mode & S_ISUID) {
1762a09f99edSMiklos Szeredi 				attr->ia_valid |= ATTR_MODE;
1763a09f99edSMiklos Szeredi 				attr->ia_mode &= ~S_ISUID;
1764a09f99edSMiklos Szeredi 			}
1765c01638f5SMiklos Szeredi 			if ((inode->i_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
1766a09f99edSMiklos Szeredi 				attr->ia_valid |= ATTR_MODE;
1767a09f99edSMiklos Szeredi 				attr->ia_mode &= ~S_ISGID;
1768a09f99edSMiklos Szeredi 			}
1769a09f99edSMiklos Szeredi 		}
17705e940c1dSMiklos Szeredi 	}
1771a09f99edSMiklos Szeredi 	if (!attr->ia_valid)
1772a09f99edSMiklos Szeredi 		return 0;
1773a09f99edSMiklos Szeredi 
1774abb5a14fSLinus Torvalds 	ret = fuse_do_setattr(entry, attr, file);
17755e2b8828SMiklos Szeredi 	if (!ret) {
177660bcc88aSSeth Forshee 		/*
177760bcc88aSSeth Forshee 		 * If filesystem supports acls it may have updated acl xattrs in
177860bcc88aSSeth Forshee 		 * the filesystem, so forget cached acls for the inode.
177960bcc88aSSeth Forshee 		 */
178060bcc88aSSeth Forshee 		if (fc->posix_acl)
178160bcc88aSSeth Forshee 			forget_all_cached_acls(inode);
178260bcc88aSSeth Forshee 
17835e2b8828SMiklos Szeredi 		/* Directory mode changed, may need to revalidate access */
17845e2b8828SMiklos Szeredi 		if (d_is_dir(entry) && (attr->ia_valid & ATTR_MODE))
17855e2b8828SMiklos Szeredi 			fuse_invalidate_entry_cache(entry);
17865e2b8828SMiklos Szeredi 	}
17875e2b8828SMiklos Szeredi 	return ret;
178849d4914fSMiklos Szeredi }
178949d4914fSMiklos Szeredi 
1790549c7297SChristian Brauner static int fuse_getattr(struct user_namespace *mnt_userns,
1791549c7297SChristian Brauner 			const struct path *path, struct kstat *stat,
1792a528d35eSDavid Howells 			u32 request_mask, unsigned int flags)
1793e5e5558eSMiklos Szeredi {
1794a528d35eSDavid Howells 	struct inode *inode = d_inode(path->dentry);
1795244f6385SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
1796244f6385SMiklos Szeredi 
17975d069dbeSMiklos Szeredi 	if (fuse_is_bad(inode))
17985d069dbeSMiklos Szeredi 		return -EIO;
17995d069dbeSMiklos Szeredi 
18005157da2cSMiklos Szeredi 	if (!fuse_allow_current_process(fc)) {
18015157da2cSMiklos Szeredi 		if (!request_mask) {
18025157da2cSMiklos Szeredi 			/*
18035157da2cSMiklos Szeredi 			 * If user explicitly requested *nothing* then don't
18045157da2cSMiklos Szeredi 			 * error out, but return st_dev only.
18055157da2cSMiklos Szeredi 			 */
18065157da2cSMiklos Szeredi 			stat->result_mask = 0;
18075157da2cSMiklos Szeredi 			stat->dev = inode->i_sb->s_dev;
18085157da2cSMiklos Szeredi 			return 0;
18095157da2cSMiklos Szeredi 		}
1810244f6385SMiklos Szeredi 		return -EACCES;
18115157da2cSMiklos Szeredi 	}
1812244f6385SMiklos Szeredi 
18132f1e8196SMiklos Szeredi 	return fuse_update_get_attr(inode, NULL, stat, request_mask, flags);
1814e5e5558eSMiklos Szeredi }
1815e5e5558eSMiklos Szeredi 
1816754661f1SArjan van de Ven static const struct inode_operations fuse_dir_inode_operations = {
1817e5e5558eSMiklos Szeredi 	.lookup		= fuse_lookup,
18189e6268dbSMiklos Szeredi 	.mkdir		= fuse_mkdir,
18199e6268dbSMiklos Szeredi 	.symlink	= fuse_symlink,
18209e6268dbSMiklos Szeredi 	.unlink		= fuse_unlink,
18219e6268dbSMiklos Szeredi 	.rmdir		= fuse_rmdir,
18222773bf00SMiklos Szeredi 	.rename		= fuse_rename2,
18239e6268dbSMiklos Szeredi 	.link		= fuse_link,
18249e6268dbSMiklos Szeredi 	.setattr	= fuse_setattr,
18259e6268dbSMiklos Szeredi 	.create		= fuse_create,
1826c8ccbe03SMiklos Szeredi 	.atomic_open	= fuse_atomic_open,
18279e6268dbSMiklos Szeredi 	.mknod		= fuse_mknod,
1828e5e5558eSMiklos Szeredi 	.permission	= fuse_permission,
1829e5e5558eSMiklos Szeredi 	.getattr	= fuse_getattr,
183092a8780eSMiklos Szeredi 	.listxattr	= fuse_listxattr,
183160bcc88aSSeth Forshee 	.get_acl	= fuse_get_acl,
183260bcc88aSSeth Forshee 	.set_acl	= fuse_set_acl,
183372227eacSMiklos Szeredi 	.fileattr_get	= fuse_fileattr_get,
183472227eacSMiklos Szeredi 	.fileattr_set	= fuse_fileattr_set,
1835e5e5558eSMiklos Szeredi };
1836e5e5558eSMiklos Szeredi 
18374b6f5d20SArjan van de Ven static const struct file_operations fuse_dir_operations = {
1838b6aeadedSMiklos Szeredi 	.llseek		= generic_file_llseek,
1839e5e5558eSMiklos Szeredi 	.read		= generic_read_dir,
1840d9b3dbdcSAl Viro 	.iterate_shared	= fuse_readdir,
1841e5e5558eSMiklos Szeredi 	.open		= fuse_dir_open,
1842e5e5558eSMiklos Szeredi 	.release	= fuse_dir_release,
184382547981SMiklos Szeredi 	.fsync		= fuse_dir_fsync,
1844b18da0c5SMiklos Szeredi 	.unlocked_ioctl	= fuse_dir_ioctl,
1845b18da0c5SMiklos Szeredi 	.compat_ioctl	= fuse_dir_compat_ioctl,
1846e5e5558eSMiklos Szeredi };
1847e5e5558eSMiklos Szeredi 
1848754661f1SArjan van de Ven static const struct inode_operations fuse_common_inode_operations = {
18499e6268dbSMiklos Szeredi 	.setattr	= fuse_setattr,
1850e5e5558eSMiklos Szeredi 	.permission	= fuse_permission,
1851e5e5558eSMiklos Szeredi 	.getattr	= fuse_getattr,
185292a8780eSMiklos Szeredi 	.listxattr	= fuse_listxattr,
185360bcc88aSSeth Forshee 	.get_acl	= fuse_get_acl,
185460bcc88aSSeth Forshee 	.set_acl	= fuse_set_acl,
185572227eacSMiklos Szeredi 	.fileattr_get	= fuse_fileattr_get,
185672227eacSMiklos Szeredi 	.fileattr_set	= fuse_fileattr_set,
1857e5e5558eSMiklos Szeredi };
1858e5e5558eSMiklos Szeredi 
1859754661f1SArjan van de Ven static const struct inode_operations fuse_symlink_inode_operations = {
18609e6268dbSMiklos Szeredi 	.setattr	= fuse_setattr,
18616b255391SAl Viro 	.get_link	= fuse_get_link,
1862e5e5558eSMiklos Szeredi 	.getattr	= fuse_getattr,
186392a8780eSMiklos Szeredi 	.listxattr	= fuse_listxattr,
1864e5e5558eSMiklos Szeredi };
1865e5e5558eSMiklos Szeredi 
1866e5e5558eSMiklos Szeredi void fuse_init_common(struct inode *inode)
1867e5e5558eSMiklos Szeredi {
1868e5e5558eSMiklos Szeredi 	inode->i_op = &fuse_common_inode_operations;
1869e5e5558eSMiklos Szeredi }
1870e5e5558eSMiklos Szeredi 
1871e5e5558eSMiklos Szeredi void fuse_init_dir(struct inode *inode)
1872e5e5558eSMiklos Szeredi {
1873ab2257e9SMiklos Szeredi 	struct fuse_inode *fi = get_fuse_inode(inode);
1874ab2257e9SMiklos Szeredi 
1875e5e5558eSMiklos Szeredi 	inode->i_op = &fuse_dir_inode_operations;
1876e5e5558eSMiklos Szeredi 	inode->i_fop = &fuse_dir_operations;
1877ab2257e9SMiklos Szeredi 
1878ab2257e9SMiklos Szeredi 	spin_lock_init(&fi->rdc.lock);
1879ab2257e9SMiklos Szeredi 	fi->rdc.cached = false;
1880ab2257e9SMiklos Szeredi 	fi->rdc.size = 0;
1881ab2257e9SMiklos Szeredi 	fi->rdc.pos = 0;
1882ab2257e9SMiklos Szeredi 	fi->rdc.version = 0;
1883e5e5558eSMiklos Szeredi }
1884e5e5558eSMiklos Szeredi 
18855571f1e6SDan Schatzberg static int fuse_symlink_readpage(struct file *null, struct page *page)
18865571f1e6SDan Schatzberg {
18875571f1e6SDan Schatzberg 	int err = fuse_readlink_page(page->mapping->host, page);
18885571f1e6SDan Schatzberg 
18895571f1e6SDan Schatzberg 	if (!err)
18905571f1e6SDan Schatzberg 		SetPageUptodate(page);
18915571f1e6SDan Schatzberg 
18925571f1e6SDan Schatzberg 	unlock_page(page);
18935571f1e6SDan Schatzberg 
18945571f1e6SDan Schatzberg 	return err;
18955571f1e6SDan Schatzberg }
18965571f1e6SDan Schatzberg 
18975571f1e6SDan Schatzberg static const struct address_space_operations fuse_symlink_aops = {
18985571f1e6SDan Schatzberg 	.readpage	= fuse_symlink_readpage,
18995571f1e6SDan Schatzberg };
19005571f1e6SDan Schatzberg 
1901e5e5558eSMiklos Szeredi void fuse_init_symlink(struct inode *inode)
1902e5e5558eSMiklos Szeredi {
1903e5e5558eSMiklos Szeredi 	inode->i_op = &fuse_symlink_inode_operations;
19045571f1e6SDan Schatzberg 	inode->i_data.a_ops = &fuse_symlink_aops;
19055571f1e6SDan Schatzberg 	inode_nohighmem(inode);
1906e5e5558eSMiklos Szeredi }
1907