xref: /openbmc/linux/fs/fuse/dir.c (revision 72227eac177dd126355ab8d8bd71b46af56c5cf3)
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) ||
255eb59bd17SMiklos Szeredi 		    (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
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 fuse_mount *parent_fm = get_fuse_mount_super(path->mnt->mnt_sb);
313bf109c64SMax Reitz 	struct fuse_conn *fc = parent_fm->fc;
314bf109c64SMax Reitz 	struct fuse_mount *fm;
315bf109c64SMax Reitz 	struct vfsmount *mnt;
316bf109c64SMax Reitz 	struct fuse_inode *mp_fi = get_fuse_inode(d_inode(path->dentry));
317bf109c64SMax Reitz 	struct super_block *sb;
318bf109c64SMax Reitz 	int err;
319bf109c64SMax Reitz 
320bf109c64SMax Reitz 	fsc = fs_context_for_submount(path->mnt->mnt_sb->s_type, path->dentry);
321bf109c64SMax Reitz 	if (IS_ERR(fsc)) {
322bf109c64SMax Reitz 		err = PTR_ERR(fsc);
323bf109c64SMax Reitz 		goto out;
324bf109c64SMax Reitz 	}
325bf109c64SMax Reitz 
326bf109c64SMax Reitz 	err = -ENOMEM;
327bf109c64SMax Reitz 	fm = kzalloc(sizeof(struct fuse_mount), GFP_KERNEL);
328bf109c64SMax Reitz 	if (!fm)
329bf109c64SMax Reitz 		goto out_put_fsc;
330bf109c64SMax Reitz 
331bf109c64SMax Reitz 	fsc->s_fs_info = fm;
332bf109c64SMax Reitz 	sb = sget_fc(fsc, NULL, set_anon_super_fc);
333bf109c64SMax Reitz 	if (IS_ERR(sb)) {
334bf109c64SMax Reitz 		err = PTR_ERR(sb);
335514b5e3fSMiklos Szeredi 		kfree(fm);
336bf109c64SMax Reitz 		goto out_put_fsc;
337bf109c64SMax Reitz 	}
338bf109c64SMax Reitz 	fm->fc = fuse_conn_get(fc);
339bf109c64SMax Reitz 
340bf109c64SMax Reitz 	/* Initialize superblock, making @mp_fi its root */
341bf109c64SMax Reitz 	err = fuse_fill_super_submount(sb, mp_fi);
342bf109c64SMax Reitz 	if (err)
343bf109c64SMax Reitz 		goto out_put_sb;
344bf109c64SMax Reitz 
345bf109c64SMax Reitz 	sb->s_flags |= SB_ACTIVE;
346bf109c64SMax Reitz 	fsc->root = dget(sb->s_root);
347bf109c64SMax Reitz 	/* We are done configuring the superblock, so unlock it */
348bf109c64SMax Reitz 	up_write(&sb->s_umount);
349bf109c64SMax Reitz 
350bf109c64SMax Reitz 	down_write(&fc->killsb);
351bf109c64SMax Reitz 	list_add_tail(&fm->fc_entry, &fc->mounts);
352bf109c64SMax Reitz 	up_write(&fc->killsb);
353bf109c64SMax Reitz 
354bf109c64SMax Reitz 	/* Create the submount */
355bf109c64SMax Reitz 	mnt = vfs_create_mount(fsc);
356bf109c64SMax Reitz 	if (IS_ERR(mnt)) {
357bf109c64SMax Reitz 		err = PTR_ERR(mnt);
358bf109c64SMax Reitz 		goto out_put_fsc;
359bf109c64SMax Reitz 	}
360bf109c64SMax Reitz 	mntget(mnt);
361bf109c64SMax Reitz 	put_fs_context(fsc);
362bf109c64SMax Reitz 	return mnt;
363bf109c64SMax Reitz 
364bf109c64SMax Reitz out_put_sb:
365bf109c64SMax Reitz 	/*
366bf109c64SMax Reitz 	 * Only jump here when fsc->root is NULL and sb is still locked
367bf109c64SMax Reitz 	 * (otherwise put_fs_context() will put the superblock)
368bf109c64SMax Reitz 	 */
369bf109c64SMax Reitz 	deactivate_locked_super(sb);
370bf109c64SMax Reitz out_put_fsc:
371bf109c64SMax Reitz 	put_fs_context(fsc);
372bf109c64SMax Reitz out:
373bf109c64SMax Reitz 	return ERR_PTR(err);
374bf109c64SMax Reitz }
375bf109c64SMax Reitz 
3764269590aSAl Viro const struct dentry_operations fuse_dentry_operations = {
377e5e5558eSMiklos Szeredi 	.d_revalidate	= fuse_dentry_revalidate,
3788fab0106SMiklos Szeredi 	.d_delete	= fuse_dentry_delete,
37930c6a23dSKhazhismel Kumykov #if BITS_PER_LONG < 64
380f75fdf22SMiklos Szeredi 	.d_init		= fuse_dentry_init,
381f75fdf22SMiklos Szeredi 	.d_release	= fuse_dentry_release,
38230c6a23dSKhazhismel Kumykov #endif
383bf109c64SMax Reitz 	.d_automount	= fuse_dentry_automount,
384e5e5558eSMiklos Szeredi };
385e5e5558eSMiklos Szeredi 
3860ce267ffSMiklos Szeredi const struct dentry_operations fuse_root_dentry_operations = {
38730c6a23dSKhazhismel Kumykov #if BITS_PER_LONG < 64
3880ce267ffSMiklos Szeredi 	.d_init		= fuse_dentry_init,
3890ce267ffSMiklos Szeredi 	.d_release	= fuse_dentry_release,
39030c6a23dSKhazhismel Kumykov #endif
3910ce267ffSMiklos Szeredi };
3920ce267ffSMiklos Szeredi 
393a5bfffacSTimo Savola int fuse_valid_type(int m)
39439ee059aSMiklos Szeredi {
39539ee059aSMiklos Szeredi 	return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) ||
39639ee059aSMiklos Szeredi 		S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
39739ee059aSMiklos Szeredi }
39839ee059aSMiklos Szeredi 
399eb59bd17SMiklos Szeredi bool fuse_invalid_attr(struct fuse_attr *attr)
400eb59bd17SMiklos Szeredi {
401eb59bd17SMiklos Szeredi 	return !fuse_valid_type(attr->mode) ||
402eb59bd17SMiklos Szeredi 		attr->size > LLONG_MAX;
403eb59bd17SMiklos Szeredi }
404eb59bd17SMiklos Szeredi 
40513983d06SAl Viro int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name,
406c180eebeSMiklos Szeredi 		     struct fuse_entry_out *outarg, struct inode **inode)
407c180eebeSMiklos Szeredi {
408fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount_super(sb);
4097078187aSMiklos Szeredi 	FUSE_ARGS(args);
41007e77dcaSMiklos Szeredi 	struct fuse_forget_link *forget;
411c180eebeSMiklos Szeredi 	u64 attr_version;
412c180eebeSMiklos Szeredi 	int err;
413c180eebeSMiklos Szeredi 
414c180eebeSMiklos Szeredi 	*inode = NULL;
415c180eebeSMiklos Szeredi 	err = -ENAMETOOLONG;
416c180eebeSMiklos Szeredi 	if (name->len > FUSE_NAME_MAX)
417c180eebeSMiklos Szeredi 		goto out;
418c180eebeSMiklos Szeredi 
419c180eebeSMiklos Szeredi 
42007e77dcaSMiklos Szeredi 	forget = fuse_alloc_forget();
42107e77dcaSMiklos Szeredi 	err = -ENOMEM;
4227078187aSMiklos Szeredi 	if (!forget)
423c180eebeSMiklos Szeredi 		goto out;
424c180eebeSMiklos Szeredi 
425fcee216bSMax Reitz 	attr_version = fuse_get_attr_version(fm->fc);
426c180eebeSMiklos Szeredi 
427fcee216bSMax Reitz 	fuse_lookup_init(fm->fc, &args, nodeid, name, outarg);
428fcee216bSMax Reitz 	err = fuse_simple_request(fm, &args);
429c180eebeSMiklos Szeredi 	/* Zero nodeid is same as -ENOENT, but with valid timeout */
430c180eebeSMiklos Szeredi 	if (err || !outarg->nodeid)
431c180eebeSMiklos Szeredi 		goto out_put_forget;
432c180eebeSMiklos Szeredi 
433c180eebeSMiklos Szeredi 	err = -EIO;
434c180eebeSMiklos Szeredi 	if (!outarg->nodeid)
435c180eebeSMiklos Szeredi 		goto out_put_forget;
436eb59bd17SMiklos Szeredi 	if (fuse_invalid_attr(&outarg->attr))
437c180eebeSMiklos Szeredi 		goto out_put_forget;
438c180eebeSMiklos Szeredi 
439c180eebeSMiklos Szeredi 	*inode = fuse_iget(sb, outarg->nodeid, outarg->generation,
440c180eebeSMiklos Szeredi 			   &outarg->attr, entry_attr_timeout(outarg),
441c180eebeSMiklos Szeredi 			   attr_version);
442c180eebeSMiklos Szeredi 	err = -ENOMEM;
443c180eebeSMiklos Szeredi 	if (!*inode) {
444fcee216bSMax Reitz 		fuse_queue_forget(fm->fc, forget, outarg->nodeid, 1);
445c180eebeSMiklos Szeredi 		goto out;
446c180eebeSMiklos Szeredi 	}
447c180eebeSMiklos Szeredi 	err = 0;
448c180eebeSMiklos Szeredi 
449c180eebeSMiklos Szeredi  out_put_forget:
45007e77dcaSMiklos Szeredi 	kfree(forget);
451c180eebeSMiklos Szeredi  out:
452c180eebeSMiklos Szeredi 	return err;
453c180eebeSMiklos Szeredi }
454c180eebeSMiklos Szeredi 
4550aa7c699SMiklos Szeredi static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
45600cd8dd3SAl Viro 				  unsigned int flags)
457e5e5558eSMiklos Szeredi {
458e5e5558eSMiklos Szeredi 	int err;
459e5e5558eSMiklos Szeredi 	struct fuse_entry_out outarg;
460c180eebeSMiklos Szeredi 	struct inode *inode;
4610de6256dSMiklos Szeredi 	struct dentry *newent;
462c180eebeSMiklos Szeredi 	bool outarg_valid = true;
46363576c13SMiklos Szeredi 	bool locked;
464e5e5558eSMiklos Szeredi 
4655d069dbeSMiklos Szeredi 	if (fuse_is_bad(dir))
4665d069dbeSMiklos Szeredi 		return ERR_PTR(-EIO);
4675d069dbeSMiklos Szeredi 
46863576c13SMiklos Szeredi 	locked = fuse_lock_inode(dir);
469c180eebeSMiklos Szeredi 	err = fuse_lookup_name(dir->i_sb, get_node_id(dir), &entry->d_name,
470c180eebeSMiklos Szeredi 			       &outarg, &inode);
47163576c13SMiklos Szeredi 	fuse_unlock_inode(dir, locked);
472c180eebeSMiklos Szeredi 	if (err == -ENOENT) {
473c180eebeSMiklos Szeredi 		outarg_valid = false;
474c180eebeSMiklos Szeredi 		err = 0;
4752d51013eSMiklos Szeredi 	}
476c180eebeSMiklos Szeredi 	if (err)
477c180eebeSMiklos Szeredi 		goto out_err;
4782d51013eSMiklos Szeredi 
479ee4e5271SMiklos Szeredi 	err = -EIO;
480c180eebeSMiklos Szeredi 	if (inode && get_node_id(inode) == FUSE_ROOT_ID)
481c180eebeSMiklos Szeredi 		goto out_iput;
482e5e5558eSMiklos Szeredi 
48341d28bcaSAl Viro 	newent = d_splice_alias(inode, entry);
484c180eebeSMiklos Szeredi 	err = PTR_ERR(newent);
485c180eebeSMiklos Szeredi 	if (IS_ERR(newent))
4865835f339SMiklos Szeredi 		goto out_err;
487d2a85164SMiklos Szeredi 
4880de6256dSMiklos Szeredi 	entry = newent ? newent : entry;
489c180eebeSMiklos Szeredi 	if (outarg_valid)
4901fb69e78SMiklos Szeredi 		fuse_change_entry_timeout(entry, &outarg);
4918cbdf1e6SMiklos Szeredi 	else
4928cbdf1e6SMiklos Szeredi 		fuse_invalidate_entry_cache(entry);
493c180eebeSMiklos Szeredi 
4946c26f717SMiklos Szeredi 	if (inode)
4954582a4abSFeng Shuo 		fuse_advise_use_readdirplus(dir);
4960de6256dSMiklos Szeredi 	return newent;
497c180eebeSMiklos Szeredi 
498c180eebeSMiklos Szeredi  out_iput:
499c180eebeSMiklos Szeredi 	iput(inode);
500c180eebeSMiklos Szeredi  out_err:
501c180eebeSMiklos Szeredi 	return ERR_PTR(err);
502e5e5558eSMiklos Szeredi }
503e5e5558eSMiklos Szeredi 
5046f9f1180SMiklos Szeredi /*
5056f9f1180SMiklos Szeredi  * Atomic create+open operation
5066f9f1180SMiklos Szeredi  *
5076f9f1180SMiklos Szeredi  * If the filesystem doesn't support this, then fall back to separate
5086f9f1180SMiklos Szeredi  * 'mknod' + 'open' requests.
5096f9f1180SMiklos Szeredi  */
510d9585277SAl Viro static int fuse_create_open(struct inode *dir, struct dentry *entry,
51154d601cbSMiklos Szeredi 			    struct file *file, unsigned int flags,
512b452a458SAl Viro 			    umode_t mode)
513fd72faacSMiklos Szeredi {
514fd72faacSMiklos Szeredi 	int err;
515fd72faacSMiklos Szeredi 	struct inode *inode;
516fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(dir);
5177078187aSMiklos Szeredi 	FUSE_ARGS(args);
51807e77dcaSMiklos Szeredi 	struct fuse_forget_link *forget;
519e0a43ddcSMiklos Szeredi 	struct fuse_create_in inarg;
520fd72faacSMiklos Szeredi 	struct fuse_open_out outopen;
521fd72faacSMiklos Szeredi 	struct fuse_entry_out outentry;
522ebf84d0cSKirill Tkhai 	struct fuse_inode *fi;
523fd72faacSMiklos Szeredi 	struct fuse_file *ff;
524fd72faacSMiklos Szeredi 
525af109bcaSMiklos Szeredi 	/* Userspace expects S_IFREG in create mode */
526af109bcaSMiklos Szeredi 	BUG_ON((mode & S_IFMT) != S_IFREG);
527af109bcaSMiklos Szeredi 
52807e77dcaSMiklos Szeredi 	forget = fuse_alloc_forget();
529c8ccbe03SMiklos Szeredi 	err = -ENOMEM;
53007e77dcaSMiklos Szeredi 	if (!forget)
531c8ccbe03SMiklos Szeredi 		goto out_err;
53251eb01e7SMiklos Szeredi 
533ce1d5a49SMiklos Szeredi 	err = -ENOMEM;
534fcee216bSMax Reitz 	ff = fuse_file_alloc(fm);
535fd72faacSMiklos Szeredi 	if (!ff)
5367078187aSMiklos Szeredi 		goto out_put_forget_req;
537fd72faacSMiklos Szeredi 
538fcee216bSMax Reitz 	if (!fm->fc->dont_mask)
539e0a43ddcSMiklos Szeredi 		mode &= ~current_umask();
540e0a43ddcSMiklos Szeredi 
541fd72faacSMiklos Szeredi 	flags &= ~O_NOCTTY;
542fd72faacSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
5430e9663eeSMiklos Szeredi 	memset(&outentry, 0, sizeof(outentry));
544fd72faacSMiklos Szeredi 	inarg.flags = flags;
545fd72faacSMiklos Szeredi 	inarg.mode = mode;
546e0a43ddcSMiklos Szeredi 	inarg.umask = current_umask();
547643a666aSVivek Goyal 
548643a666aSVivek Goyal 	if (fm->fc->handle_killpriv_v2 && (flags & O_TRUNC) &&
549643a666aSVivek Goyal 	    !(flags & O_EXCL) && !capable(CAP_FSETID)) {
550643a666aSVivek Goyal 		inarg.open_flags |= FUSE_OPEN_KILL_SUIDGID;
551643a666aSVivek Goyal 	}
552643a666aSVivek Goyal 
553d5b48543SMiklos Szeredi 	args.opcode = FUSE_CREATE;
554d5b48543SMiklos Szeredi 	args.nodeid = get_node_id(dir);
555d5b48543SMiklos Szeredi 	args.in_numargs = 2;
556d5b48543SMiklos Szeredi 	args.in_args[0].size = sizeof(inarg);
557d5b48543SMiklos Szeredi 	args.in_args[0].value = &inarg;
558d5b48543SMiklos Szeredi 	args.in_args[1].size = entry->d_name.len + 1;
559d5b48543SMiklos Szeredi 	args.in_args[1].value = entry->d_name.name;
560d5b48543SMiklos Szeredi 	args.out_numargs = 2;
561d5b48543SMiklos Szeredi 	args.out_args[0].size = sizeof(outentry);
562d5b48543SMiklos Szeredi 	args.out_args[0].value = &outentry;
563d5b48543SMiklos Szeredi 	args.out_args[1].size = sizeof(outopen);
564d5b48543SMiklos Szeredi 	args.out_args[1].value = &outopen;
565fcee216bSMax Reitz 	err = fuse_simple_request(fm, &args);
566c8ccbe03SMiklos Szeredi 	if (err)
567fd72faacSMiklos Szeredi 		goto out_free_ff;
568fd72faacSMiklos Szeredi 
569fd72faacSMiklos Szeredi 	err = -EIO;
570eb59bd17SMiklos Szeredi 	if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid) ||
571eb59bd17SMiklos Szeredi 	    fuse_invalid_attr(&outentry.attr))
572fd72faacSMiklos Szeredi 		goto out_free_ff;
573fd72faacSMiklos Szeredi 
574c7b7143cSMiklos Szeredi 	ff->fh = outopen.fh;
575c7b7143cSMiklos Szeredi 	ff->nodeid = outentry.nodeid;
576c7b7143cSMiklos Szeredi 	ff->open_flags = outopen.open_flags;
577fd72faacSMiklos Szeredi 	inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
5781fb69e78SMiklos Szeredi 			  &outentry.attr, entry_attr_timeout(&outentry), 0);
579fd72faacSMiklos Szeredi 	if (!inode) {
580fd72faacSMiklos Szeredi 		flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
581ebf84d0cSKirill Tkhai 		fuse_sync_release(NULL, ff, flags);
582fcee216bSMax Reitz 		fuse_queue_forget(fm->fc, forget, outentry.nodeid, 1);
583c8ccbe03SMiklos Szeredi 		err = -ENOMEM;
584c8ccbe03SMiklos Szeredi 		goto out_err;
585fd72faacSMiklos Szeredi 	}
58607e77dcaSMiklos Szeredi 	kfree(forget);
587fd72faacSMiklos Szeredi 	d_instantiate(entry, inode);
5881fb69e78SMiklos Szeredi 	fuse_change_entry_timeout(entry, &outentry);
589261aaba7SMiklos Szeredi 	fuse_dir_changed(dir);
590be12af3eSAl Viro 	err = finish_open(file, entry, generic_file_open);
59130d90494SAl Viro 	if (err) {
592ebf84d0cSKirill Tkhai 		fi = get_fuse_inode(inode);
593ebf84d0cSKirill Tkhai 		fuse_sync_release(fi, ff, flags);
594c8ccbe03SMiklos Szeredi 	} else {
595267d8444SMiklos Szeredi 		file->private_data = ff;
596c7b7143cSMiklos Szeredi 		fuse_finish_open(inode, file);
597c8ccbe03SMiklos Szeredi 	}
598d9585277SAl Viro 	return err;
599fd72faacSMiklos Szeredi 
600fd72faacSMiklos Szeredi out_free_ff:
601fd72faacSMiklos Szeredi 	fuse_file_free(ff);
60251eb01e7SMiklos Szeredi out_put_forget_req:
60307e77dcaSMiklos Szeredi 	kfree(forget);
604c8ccbe03SMiklos Szeredi out_err:
605d9585277SAl Viro 	return err;
606c8ccbe03SMiklos Szeredi }
607c8ccbe03SMiklos Szeredi 
608549c7297SChristian Brauner static int fuse_mknod(struct user_namespace *, struct inode *, struct dentry *,
609549c7297SChristian Brauner 		      umode_t, dev_t);
610d9585277SAl Viro static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
61130d90494SAl Viro 			    struct file *file, unsigned flags,
61244907d79SAl Viro 			    umode_t mode)
613c8ccbe03SMiklos Szeredi {
614c8ccbe03SMiklos Szeredi 	int err;
615c8ccbe03SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
616c8ccbe03SMiklos Szeredi 	struct dentry *res = NULL;
617c8ccbe03SMiklos Szeredi 
6185d069dbeSMiklos Szeredi 	if (fuse_is_bad(dir))
6195d069dbeSMiklos Szeredi 		return -EIO;
6205d069dbeSMiklos Szeredi 
62100699ad8SAl Viro 	if (d_in_lookup(entry)) {
62200cd8dd3SAl Viro 		res = fuse_lookup(dir, entry, 0);
623c8ccbe03SMiklos Szeredi 		if (IS_ERR(res))
624d9585277SAl Viro 			return PTR_ERR(res);
625c8ccbe03SMiklos Szeredi 
626c8ccbe03SMiklos Szeredi 		if (res)
627c8ccbe03SMiklos Szeredi 			entry = res;
628c8ccbe03SMiklos Szeredi 	}
629c8ccbe03SMiklos Szeredi 
6302b0143b5SDavid Howells 	if (!(flags & O_CREAT) || d_really_is_positive(entry))
631c8ccbe03SMiklos Szeredi 		goto no_open;
632c8ccbe03SMiklos Szeredi 
633c8ccbe03SMiklos Szeredi 	/* Only creates */
63473a09dd9SAl Viro 	file->f_mode |= FMODE_CREATED;
635c8ccbe03SMiklos Szeredi 
636c8ccbe03SMiklos Szeredi 	if (fc->no_create)
637c8ccbe03SMiklos Szeredi 		goto mknod;
638c8ccbe03SMiklos Szeredi 
639b452a458SAl Viro 	err = fuse_create_open(dir, entry, file, flags, mode);
640d9585277SAl Viro 	if (err == -ENOSYS) {
641c8ccbe03SMiklos Szeredi 		fc->no_create = 1;
642c8ccbe03SMiklos Szeredi 		goto mknod;
643c8ccbe03SMiklos Szeredi 	}
644c8ccbe03SMiklos Szeredi out_dput:
645c8ccbe03SMiklos Szeredi 	dput(res);
646d9585277SAl Viro 	return err;
647c8ccbe03SMiklos Szeredi 
648c8ccbe03SMiklos Szeredi mknod:
649549c7297SChristian Brauner 	err = fuse_mknod(&init_user_ns, dir, entry, mode, 0);
650d9585277SAl Viro 	if (err)
651c8ccbe03SMiklos Szeredi 		goto out_dput;
652c8ccbe03SMiklos Szeredi no_open:
653e45198a6SAl Viro 	return finish_no_open(file, res);
654fd72faacSMiklos Szeredi }
655fd72faacSMiklos Szeredi 
6566f9f1180SMiklos Szeredi /*
6576f9f1180SMiklos Szeredi  * Code shared between mknod, mkdir, symlink and link
6586f9f1180SMiklos Szeredi  */
659fcee216bSMax Reitz static int create_new_entry(struct fuse_mount *fm, struct fuse_args *args,
6609e6268dbSMiklos Szeredi 			    struct inode *dir, struct dentry *entry,
661541af6a0SAl Viro 			    umode_t mode)
6629e6268dbSMiklos Szeredi {
6639e6268dbSMiklos Szeredi 	struct fuse_entry_out outarg;
6649e6268dbSMiklos Szeredi 	struct inode *inode;
665c971e6a0SAl Viro 	struct dentry *d;
6669e6268dbSMiklos Szeredi 	int err;
66707e77dcaSMiklos Szeredi 	struct fuse_forget_link *forget;
6682d51013eSMiklos Szeredi 
6695d069dbeSMiklos Szeredi 	if (fuse_is_bad(dir))
6705d069dbeSMiklos Szeredi 		return -EIO;
6715d069dbeSMiklos Szeredi 
67207e77dcaSMiklos Szeredi 	forget = fuse_alloc_forget();
6737078187aSMiklos Szeredi 	if (!forget)
67407e77dcaSMiklos Szeredi 		return -ENOMEM;
6759e6268dbSMiklos Szeredi 
6760e9663eeSMiklos Szeredi 	memset(&outarg, 0, sizeof(outarg));
677d5b48543SMiklos Szeredi 	args->nodeid = get_node_id(dir);
678d5b48543SMiklos Szeredi 	args->out_numargs = 1;
679d5b48543SMiklos Szeredi 	args->out_args[0].size = sizeof(outarg);
680d5b48543SMiklos Szeredi 	args->out_args[0].value = &outarg;
681fcee216bSMax Reitz 	err = fuse_simple_request(fm, args);
6822d51013eSMiklos Szeredi 	if (err)
6832d51013eSMiklos Szeredi 		goto out_put_forget_req;
6842d51013eSMiklos Szeredi 
68539ee059aSMiklos Szeredi 	err = -EIO;
686eb59bd17SMiklos Szeredi 	if (invalid_nodeid(outarg.nodeid) || fuse_invalid_attr(&outarg.attr))
6872d51013eSMiklos Szeredi 		goto out_put_forget_req;
68839ee059aSMiklos Szeredi 
68939ee059aSMiklos Szeredi 	if ((outarg.attr.mode ^ mode) & S_IFMT)
6902d51013eSMiklos Szeredi 		goto out_put_forget_req;
69139ee059aSMiklos Szeredi 
6929e6268dbSMiklos Szeredi 	inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
6931fb69e78SMiklos Szeredi 			  &outarg.attr, entry_attr_timeout(&outarg), 0);
6949e6268dbSMiklos Szeredi 	if (!inode) {
695fcee216bSMax Reitz 		fuse_queue_forget(fm->fc, forget, outarg.nodeid, 1);
6969e6268dbSMiklos Szeredi 		return -ENOMEM;
6979e6268dbSMiklos Szeredi 	}
69807e77dcaSMiklos Szeredi 	kfree(forget);
6999e6268dbSMiklos Szeredi 
700c971e6a0SAl Viro 	d_drop(entry);
701c971e6a0SAl Viro 	d = d_splice_alias(inode, entry);
702c971e6a0SAl Viro 	if (IS_ERR(d))
703c971e6a0SAl Viro 		return PTR_ERR(d);
704d2a85164SMiklos Szeredi 
705c971e6a0SAl Viro 	if (d) {
706c971e6a0SAl Viro 		fuse_change_entry_timeout(d, &outarg);
707c971e6a0SAl Viro 		dput(d);
708c971e6a0SAl Viro 	} else {
7091fb69e78SMiklos Szeredi 		fuse_change_entry_timeout(entry, &outarg);
710c971e6a0SAl Viro 	}
711261aaba7SMiklos Szeredi 	fuse_dir_changed(dir);
7129e6268dbSMiklos Szeredi 	return 0;
71339ee059aSMiklos Szeredi 
7142d51013eSMiklos Szeredi  out_put_forget_req:
71507e77dcaSMiklos Szeredi 	kfree(forget);
71639ee059aSMiklos Szeredi 	return err;
7179e6268dbSMiklos Szeredi }
7189e6268dbSMiklos Szeredi 
719549c7297SChristian Brauner static int fuse_mknod(struct user_namespace *mnt_userns, struct inode *dir,
720549c7297SChristian Brauner 		      struct dentry *entry, umode_t mode, dev_t rdev)
7219e6268dbSMiklos Szeredi {
7229e6268dbSMiklos Szeredi 	struct fuse_mknod_in inarg;
723fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(dir);
7247078187aSMiklos Szeredi 	FUSE_ARGS(args);
7259e6268dbSMiklos Szeredi 
726fcee216bSMax Reitz 	if (!fm->fc->dont_mask)
727e0a43ddcSMiklos Szeredi 		mode &= ~current_umask();
728e0a43ddcSMiklos Szeredi 
7299e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
7309e6268dbSMiklos Szeredi 	inarg.mode = mode;
7319e6268dbSMiklos Szeredi 	inarg.rdev = new_encode_dev(rdev);
732e0a43ddcSMiklos Szeredi 	inarg.umask = current_umask();
733d5b48543SMiklos Szeredi 	args.opcode = FUSE_MKNOD;
734d5b48543SMiklos Szeredi 	args.in_numargs = 2;
735d5b48543SMiklos Szeredi 	args.in_args[0].size = sizeof(inarg);
736d5b48543SMiklos Szeredi 	args.in_args[0].value = &inarg;
737d5b48543SMiklos Szeredi 	args.in_args[1].size = entry->d_name.len + 1;
738d5b48543SMiklos Szeredi 	args.in_args[1].value = entry->d_name.name;
739fcee216bSMax Reitz 	return create_new_entry(fm, &args, dir, entry, mode);
7409e6268dbSMiklos Szeredi }
7419e6268dbSMiklos Szeredi 
742549c7297SChristian Brauner static int fuse_create(struct user_namespace *mnt_userns, struct inode *dir,
743549c7297SChristian Brauner 		       struct dentry *entry, umode_t mode, bool excl)
7449e6268dbSMiklos Szeredi {
745549c7297SChristian Brauner 	return fuse_mknod(&init_user_ns, dir, entry, mode, 0);
7469e6268dbSMiklos Szeredi }
7479e6268dbSMiklos Szeredi 
748549c7297SChristian Brauner static int fuse_mkdir(struct user_namespace *mnt_userns, struct inode *dir,
749549c7297SChristian Brauner 		      struct dentry *entry, umode_t mode)
7509e6268dbSMiklos Szeredi {
7519e6268dbSMiklos Szeredi 	struct fuse_mkdir_in inarg;
752fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(dir);
7537078187aSMiklos Szeredi 	FUSE_ARGS(args);
7549e6268dbSMiklos Szeredi 
755fcee216bSMax Reitz 	if (!fm->fc->dont_mask)
756e0a43ddcSMiklos Szeredi 		mode &= ~current_umask();
757e0a43ddcSMiklos Szeredi 
7589e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
7599e6268dbSMiklos Szeredi 	inarg.mode = mode;
760e0a43ddcSMiklos Szeredi 	inarg.umask = current_umask();
761d5b48543SMiklos Szeredi 	args.opcode = FUSE_MKDIR;
762d5b48543SMiklos Szeredi 	args.in_numargs = 2;
763d5b48543SMiklos Szeredi 	args.in_args[0].size = sizeof(inarg);
764d5b48543SMiklos Szeredi 	args.in_args[0].value = &inarg;
765d5b48543SMiklos Szeredi 	args.in_args[1].size = entry->d_name.len + 1;
766d5b48543SMiklos Szeredi 	args.in_args[1].value = entry->d_name.name;
767fcee216bSMax Reitz 	return create_new_entry(fm, &args, dir, entry, S_IFDIR);
7689e6268dbSMiklos Szeredi }
7699e6268dbSMiklos Szeredi 
770549c7297SChristian Brauner static int fuse_symlink(struct user_namespace *mnt_userns, struct inode *dir,
771549c7297SChristian Brauner 			struct dentry *entry, const char *link)
7729e6268dbSMiklos Szeredi {
773fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(dir);
7749e6268dbSMiklos Szeredi 	unsigned len = strlen(link) + 1;
7757078187aSMiklos Szeredi 	FUSE_ARGS(args);
7769e6268dbSMiklos Szeredi 
777d5b48543SMiklos Szeredi 	args.opcode = FUSE_SYMLINK;
778d5b48543SMiklos Szeredi 	args.in_numargs = 2;
779d5b48543SMiklos Szeredi 	args.in_args[0].size = entry->d_name.len + 1;
780d5b48543SMiklos Szeredi 	args.in_args[0].value = entry->d_name.name;
781d5b48543SMiklos Szeredi 	args.in_args[1].size = len;
782d5b48543SMiklos Szeredi 	args.in_args[1].value = link;
783fcee216bSMax Reitz 	return create_new_entry(fm, &args, dir, entry, S_IFLNK);
7849e6268dbSMiklos Szeredi }
7859e6268dbSMiklos Szeredi 
786703c7362SSeth Forshee void fuse_update_ctime(struct inode *inode)
78731f3267bSMaxim Patlasov {
78831f3267bSMaxim Patlasov 	if (!IS_NOCMTIME(inode)) {
789c2050a45SDeepa Dinamani 		inode->i_ctime = current_time(inode);
79031f3267bSMaxim Patlasov 		mark_inode_dirty_sync(inode);
79131f3267bSMaxim Patlasov 	}
79231f3267bSMaxim Patlasov }
79331f3267bSMaxim Patlasov 
7949e6268dbSMiklos Szeredi static int fuse_unlink(struct inode *dir, struct dentry *entry)
7959e6268dbSMiklos Szeredi {
7969e6268dbSMiklos Szeredi 	int err;
797fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(dir);
7987078187aSMiklos Szeredi 	FUSE_ARGS(args);
7999e6268dbSMiklos Szeredi 
8005d069dbeSMiklos Szeredi 	if (fuse_is_bad(dir))
8015d069dbeSMiklos Szeredi 		return -EIO;
8025d069dbeSMiklos Szeredi 
803d5b48543SMiklos Szeredi 	args.opcode = FUSE_UNLINK;
804d5b48543SMiklos Szeredi 	args.nodeid = get_node_id(dir);
805d5b48543SMiklos Szeredi 	args.in_numargs = 1;
806d5b48543SMiklos Szeredi 	args.in_args[0].size = entry->d_name.len + 1;
807d5b48543SMiklos Szeredi 	args.in_args[0].value = entry->d_name.name;
808fcee216bSMax Reitz 	err = fuse_simple_request(fm, &args);
8099e6268dbSMiklos Szeredi 	if (!err) {
8102b0143b5SDavid Howells 		struct inode *inode = d_inode(entry);
811ac45d613SMiklos Szeredi 		struct fuse_inode *fi = get_fuse_inode(inode);
8129e6268dbSMiklos Szeredi 
813f15ecfefSKirill Tkhai 		spin_lock(&fi->lock);
814fcee216bSMax Reitz 		fi->attr_version = atomic64_inc_return(&fm->fc->attr_version);
815dfca7cebSMiklos Szeredi 		/*
816dfca7cebSMiklos Szeredi 		 * If i_nlink == 0 then unlink doesn't make sense, yet this can
817dfca7cebSMiklos Szeredi 		 * happen if userspace filesystem is careless.  It would be
818dfca7cebSMiklos Szeredi 		 * difficult to enforce correct nlink usage so just ignore this
819dfca7cebSMiklos Szeredi 		 * condition here
820dfca7cebSMiklos Szeredi 		 */
821dfca7cebSMiklos Szeredi 		if (inode->i_nlink > 0)
822ac45d613SMiklos Szeredi 			drop_nlink(inode);
823f15ecfefSKirill Tkhai 		spin_unlock(&fi->lock);
8249e6268dbSMiklos Szeredi 		fuse_invalidate_attr(inode);
825261aaba7SMiklos Szeredi 		fuse_dir_changed(dir);
8268cbdf1e6SMiklos Szeredi 		fuse_invalidate_entry_cache(entry);
82731f3267bSMaxim Patlasov 		fuse_update_ctime(inode);
8289e6268dbSMiklos Szeredi 	} else if (err == -EINTR)
8299e6268dbSMiklos Szeredi 		fuse_invalidate_entry(entry);
8309e6268dbSMiklos Szeredi 	return err;
8319e6268dbSMiklos Szeredi }
8329e6268dbSMiklos Szeredi 
8339e6268dbSMiklos Szeredi static int fuse_rmdir(struct inode *dir, struct dentry *entry)
8349e6268dbSMiklos Szeredi {
8359e6268dbSMiklos Szeredi 	int err;
836fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(dir);
8377078187aSMiklos Szeredi 	FUSE_ARGS(args);
8389e6268dbSMiklos Szeredi 
8395d069dbeSMiklos Szeredi 	if (fuse_is_bad(dir))
8405d069dbeSMiklos Szeredi 		return -EIO;
8415d069dbeSMiklos Szeredi 
842d5b48543SMiklos Szeredi 	args.opcode = FUSE_RMDIR;
843d5b48543SMiklos Szeredi 	args.nodeid = get_node_id(dir);
844d5b48543SMiklos Szeredi 	args.in_numargs = 1;
845d5b48543SMiklos Szeredi 	args.in_args[0].size = entry->d_name.len + 1;
846d5b48543SMiklos Szeredi 	args.in_args[0].value = entry->d_name.name;
847fcee216bSMax Reitz 	err = fuse_simple_request(fm, &args);
8489e6268dbSMiklos Szeredi 	if (!err) {
8492b0143b5SDavid Howells 		clear_nlink(d_inode(entry));
850261aaba7SMiklos Szeredi 		fuse_dir_changed(dir);
8518cbdf1e6SMiklos Szeredi 		fuse_invalidate_entry_cache(entry);
8529e6268dbSMiklos Szeredi 	} else if (err == -EINTR)
8539e6268dbSMiklos Szeredi 		fuse_invalidate_entry(entry);
8549e6268dbSMiklos Szeredi 	return err;
8559e6268dbSMiklos Szeredi }
8569e6268dbSMiklos Szeredi 
8571560c974SMiklos Szeredi static int fuse_rename_common(struct inode *olddir, struct dentry *oldent,
8581560c974SMiklos Szeredi 			      struct inode *newdir, struct dentry *newent,
8591560c974SMiklos Szeredi 			      unsigned int flags, int opcode, size_t argsize)
8609e6268dbSMiklos Szeredi {
8619e6268dbSMiklos Szeredi 	int err;
8621560c974SMiklos Szeredi 	struct fuse_rename2_in inarg;
863fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(olddir);
8647078187aSMiklos Szeredi 	FUSE_ARGS(args);
8659e6268dbSMiklos Szeredi 
8661560c974SMiklos Szeredi 	memset(&inarg, 0, argsize);
8679e6268dbSMiklos Szeredi 	inarg.newdir = get_node_id(newdir);
8681560c974SMiklos Szeredi 	inarg.flags = flags;
869d5b48543SMiklos Szeredi 	args.opcode = opcode;
870d5b48543SMiklos Szeredi 	args.nodeid = get_node_id(olddir);
871d5b48543SMiklos Szeredi 	args.in_numargs = 3;
872d5b48543SMiklos Szeredi 	args.in_args[0].size = argsize;
873d5b48543SMiklos Szeredi 	args.in_args[0].value = &inarg;
874d5b48543SMiklos Szeredi 	args.in_args[1].size = oldent->d_name.len + 1;
875d5b48543SMiklos Szeredi 	args.in_args[1].value = oldent->d_name.name;
876d5b48543SMiklos Szeredi 	args.in_args[2].size = newent->d_name.len + 1;
877d5b48543SMiklos Szeredi 	args.in_args[2].value = newent->d_name.name;
878fcee216bSMax Reitz 	err = fuse_simple_request(fm, &args);
8799e6268dbSMiklos Szeredi 	if (!err) {
88008b63307SMiklos Szeredi 		/* ctime changes */
8812b0143b5SDavid Howells 		fuse_invalidate_attr(d_inode(oldent));
8822b0143b5SDavid Howells 		fuse_update_ctime(d_inode(oldent));
88308b63307SMiklos Szeredi 
8841560c974SMiklos Szeredi 		if (flags & RENAME_EXCHANGE) {
8852b0143b5SDavid Howells 			fuse_invalidate_attr(d_inode(newent));
8862b0143b5SDavid Howells 			fuse_update_ctime(d_inode(newent));
8871560c974SMiklos Szeredi 		}
8881560c974SMiklos Szeredi 
889261aaba7SMiklos Szeredi 		fuse_dir_changed(olddir);
8909e6268dbSMiklos Szeredi 		if (olddir != newdir)
891261aaba7SMiklos Szeredi 			fuse_dir_changed(newdir);
8928cbdf1e6SMiklos Szeredi 
8938cbdf1e6SMiklos Szeredi 		/* newent will end up negative */
8942b0143b5SDavid Howells 		if (!(flags & RENAME_EXCHANGE) && d_really_is_positive(newent)) {
8952b0143b5SDavid Howells 			fuse_invalidate_attr(d_inode(newent));
8968cbdf1e6SMiklos Szeredi 			fuse_invalidate_entry_cache(newent);
8972b0143b5SDavid Howells 			fuse_update_ctime(d_inode(newent));
8985219f346SMiklos Szeredi 		}
8999e6268dbSMiklos Szeredi 	} else if (err == -EINTR) {
9009e6268dbSMiklos Szeredi 		/* If request was interrupted, DEITY only knows if the
9019e6268dbSMiklos Szeredi 		   rename actually took place.  If the invalidation
9029e6268dbSMiklos Szeredi 		   fails (e.g. some process has CWD under the renamed
9039e6268dbSMiklos Szeredi 		   directory), then there can be inconsistency between
9049e6268dbSMiklos Szeredi 		   the dcache and the real filesystem.  Tough luck. */
9059e6268dbSMiklos Szeredi 		fuse_invalidate_entry(oldent);
9062b0143b5SDavid Howells 		if (d_really_is_positive(newent))
9079e6268dbSMiklos Szeredi 			fuse_invalidate_entry(newent);
9089e6268dbSMiklos Szeredi 	}
9099e6268dbSMiklos Szeredi 
9109e6268dbSMiklos Szeredi 	return err;
9119e6268dbSMiklos Szeredi }
9129e6268dbSMiklos Szeredi 
913549c7297SChristian Brauner static int fuse_rename2(struct user_namespace *mnt_userns, struct inode *olddir,
914549c7297SChristian Brauner 			struct dentry *oldent, struct inode *newdir,
915549c7297SChristian Brauner 			struct dentry *newent, unsigned int flags)
9161560c974SMiklos Szeredi {
9171560c974SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(olddir);
9181560c974SMiklos Szeredi 	int err;
9191560c974SMiklos Szeredi 
9205d069dbeSMiklos Szeredi 	if (fuse_is_bad(olddir))
9215d069dbeSMiklos Szeredi 		return -EIO;
9225d069dbeSMiklos Szeredi 
923519525faSVivek Goyal 	if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT))
9241560c974SMiklos Szeredi 		return -EINVAL;
9251560c974SMiklos Szeredi 
9264237ba43SMiklos Szeredi 	if (flags) {
9271560c974SMiklos Szeredi 		if (fc->no_rename2 || fc->minor < 23)
9281560c974SMiklos Szeredi 			return -EINVAL;
9291560c974SMiklos Szeredi 
9301560c974SMiklos Szeredi 		err = fuse_rename_common(olddir, oldent, newdir, newent, flags,
9314237ba43SMiklos Szeredi 					 FUSE_RENAME2,
9324237ba43SMiklos Szeredi 					 sizeof(struct fuse_rename2_in));
9331560c974SMiklos Szeredi 		if (err == -ENOSYS) {
9341560c974SMiklos Szeredi 			fc->no_rename2 = 1;
9351560c974SMiklos Szeredi 			err = -EINVAL;
9361560c974SMiklos Szeredi 		}
9374237ba43SMiklos Szeredi 	} else {
9384237ba43SMiklos Szeredi 		err = fuse_rename_common(olddir, oldent, newdir, newent, 0,
9394237ba43SMiklos Szeredi 					 FUSE_RENAME,
9404237ba43SMiklos Szeredi 					 sizeof(struct fuse_rename_in));
9414237ba43SMiklos Szeredi 	}
9421560c974SMiklos Szeredi 
9434237ba43SMiklos Szeredi 	return err;
9444237ba43SMiklos Szeredi }
9454237ba43SMiklos Szeredi 
9469e6268dbSMiklos Szeredi static int fuse_link(struct dentry *entry, struct inode *newdir,
9479e6268dbSMiklos Szeredi 		     struct dentry *newent)
9489e6268dbSMiklos Szeredi {
9499e6268dbSMiklos Szeredi 	int err;
9509e6268dbSMiklos Szeredi 	struct fuse_link_in inarg;
9512b0143b5SDavid Howells 	struct inode *inode = d_inode(entry);
952fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(inode);
9537078187aSMiklos Szeredi 	FUSE_ARGS(args);
9549e6268dbSMiklos Szeredi 
9559e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
9569e6268dbSMiklos Szeredi 	inarg.oldnodeid = get_node_id(inode);
957d5b48543SMiklos Szeredi 	args.opcode = FUSE_LINK;
958d5b48543SMiklos Szeredi 	args.in_numargs = 2;
959d5b48543SMiklos Szeredi 	args.in_args[0].size = sizeof(inarg);
960d5b48543SMiklos Szeredi 	args.in_args[0].value = &inarg;
961d5b48543SMiklos Szeredi 	args.in_args[1].size = newent->d_name.len + 1;
962d5b48543SMiklos Szeredi 	args.in_args[1].value = newent->d_name.name;
963fcee216bSMax Reitz 	err = create_new_entry(fm, &args, newdir, newent, inode->i_mode);
9649e6268dbSMiklos Szeredi 	/* Contrary to "normal" filesystems it can happen that link
9659e6268dbSMiklos Szeredi 	   makes two "logical" inodes point to the same "physical"
9669e6268dbSMiklos Szeredi 	   inode.  We invalidate the attributes of the old one, so it
9679e6268dbSMiklos Szeredi 	   will reflect changes in the backing inode (link count,
9689e6268dbSMiklos Szeredi 	   etc.)
9699e6268dbSMiklos Szeredi 	*/
970ac45d613SMiklos Szeredi 	if (!err) {
971ac45d613SMiklos Szeredi 		struct fuse_inode *fi = get_fuse_inode(inode);
972ac45d613SMiklos Szeredi 
973f15ecfefSKirill Tkhai 		spin_lock(&fi->lock);
974fcee216bSMax Reitz 		fi->attr_version = atomic64_inc_return(&fm->fc->attr_version);
975c634da71SMiklos Szeredi 		if (likely(inode->i_nlink < UINT_MAX))
976ac45d613SMiklos Szeredi 			inc_nlink(inode);
977f15ecfefSKirill Tkhai 		spin_unlock(&fi->lock);
9789e6268dbSMiklos Szeredi 		fuse_invalidate_attr(inode);
97931f3267bSMaxim Patlasov 		fuse_update_ctime(inode);
980ac45d613SMiklos Szeredi 	} else if (err == -EINTR) {
981ac45d613SMiklos Szeredi 		fuse_invalidate_attr(inode);
982ac45d613SMiklos Szeredi 	}
9839e6268dbSMiklos Szeredi 	return err;
9849e6268dbSMiklos Szeredi }
9859e6268dbSMiklos Szeredi 
9861fb69e78SMiklos Szeredi static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
9871fb69e78SMiklos Szeredi 			  struct kstat *stat)
9881fb69e78SMiklos Szeredi {
989203627bbSMiklos Szeredi 	unsigned int blkbits;
9908373200bSPavel Emelyanov 	struct fuse_conn *fc = get_fuse_conn(inode);
9918373200bSPavel Emelyanov 
9928373200bSPavel Emelyanov 	/* see the comment in fuse_change_attributes() */
993b0aa7606SMaxim Patlasov 	if (fc->writeback_cache && S_ISREG(inode->i_mode)) {
9948373200bSPavel Emelyanov 		attr->size = i_size_read(inode);
995b0aa7606SMaxim Patlasov 		attr->mtime = inode->i_mtime.tv_sec;
996b0aa7606SMaxim Patlasov 		attr->mtimensec = inode->i_mtime.tv_nsec;
99731f3267bSMaxim Patlasov 		attr->ctime = inode->i_ctime.tv_sec;
99831f3267bSMaxim Patlasov 		attr->ctimensec = inode->i_ctime.tv_nsec;
999b0aa7606SMaxim Patlasov 	}
1000203627bbSMiklos Szeredi 
10011fb69e78SMiklos Szeredi 	stat->dev = inode->i_sb->s_dev;
10021fb69e78SMiklos Szeredi 	stat->ino = attr->ino;
10031fb69e78SMiklos Szeredi 	stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
10041fb69e78SMiklos Szeredi 	stat->nlink = attr->nlink;
10058cb08329SEric W. Biederman 	stat->uid = make_kuid(fc->user_ns, attr->uid);
10068cb08329SEric W. Biederman 	stat->gid = make_kgid(fc->user_ns, attr->gid);
10071fb69e78SMiklos Szeredi 	stat->rdev = inode->i_rdev;
10081fb69e78SMiklos Szeredi 	stat->atime.tv_sec = attr->atime;
10091fb69e78SMiklos Szeredi 	stat->atime.tv_nsec = attr->atimensec;
10101fb69e78SMiklos Szeredi 	stat->mtime.tv_sec = attr->mtime;
10111fb69e78SMiklos Szeredi 	stat->mtime.tv_nsec = attr->mtimensec;
10121fb69e78SMiklos Szeredi 	stat->ctime.tv_sec = attr->ctime;
10131fb69e78SMiklos Szeredi 	stat->ctime.tv_nsec = attr->ctimensec;
10141fb69e78SMiklos Szeredi 	stat->size = attr->size;
10151fb69e78SMiklos Szeredi 	stat->blocks = attr->blocks;
1016203627bbSMiklos Szeredi 
1017203627bbSMiklos Szeredi 	if (attr->blksize != 0)
1018203627bbSMiklos Szeredi 		blkbits = ilog2(attr->blksize);
1019203627bbSMiklos Szeredi 	else
1020203627bbSMiklos Szeredi 		blkbits = inode->i_sb->s_blocksize_bits;
1021203627bbSMiklos Szeredi 
1022203627bbSMiklos Szeredi 	stat->blksize = 1 << blkbits;
10231fb69e78SMiklos Szeredi }
10241fb69e78SMiklos Szeredi 
1025c79e322fSMiklos Szeredi static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
1026c79e322fSMiklos Szeredi 			   struct file *file)
1027e5e5558eSMiklos Szeredi {
1028e5e5558eSMiklos Szeredi 	int err;
1029c79e322fSMiklos Szeredi 	struct fuse_getattr_in inarg;
1030c79e322fSMiklos Szeredi 	struct fuse_attr_out outarg;
1031fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(inode);
10327078187aSMiklos Szeredi 	FUSE_ARGS(args);
10331fb69e78SMiklos Szeredi 	u64 attr_version;
10341fb69e78SMiklos Szeredi 
1035fcee216bSMax Reitz 	attr_version = fuse_get_attr_version(fm->fc);
10361fb69e78SMiklos Szeredi 
1037c79e322fSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
10380e9663eeSMiklos Szeredi 	memset(&outarg, 0, sizeof(outarg));
1039c79e322fSMiklos Szeredi 	/* Directories have separate file-handle space */
1040c79e322fSMiklos Szeredi 	if (file && S_ISREG(inode->i_mode)) {
1041c79e322fSMiklos Szeredi 		struct fuse_file *ff = file->private_data;
1042c79e322fSMiklos Szeredi 
1043c79e322fSMiklos Szeredi 		inarg.getattr_flags |= FUSE_GETATTR_FH;
1044c79e322fSMiklos Szeredi 		inarg.fh = ff->fh;
1045c79e322fSMiklos Szeredi 	}
1046d5b48543SMiklos Szeredi 	args.opcode = FUSE_GETATTR;
1047d5b48543SMiklos Szeredi 	args.nodeid = get_node_id(inode);
1048d5b48543SMiklos Szeredi 	args.in_numargs = 1;
1049d5b48543SMiklos Szeredi 	args.in_args[0].size = sizeof(inarg);
1050d5b48543SMiklos Szeredi 	args.in_args[0].value = &inarg;
1051d5b48543SMiklos Szeredi 	args.out_numargs = 1;
1052d5b48543SMiklos Szeredi 	args.out_args[0].size = sizeof(outarg);
1053d5b48543SMiklos Szeredi 	args.out_args[0].value = &outarg;
1054fcee216bSMax Reitz 	err = fuse_simple_request(fm, &args);
1055e5e5558eSMiklos Szeredi 	if (!err) {
1056eb59bd17SMiklos Szeredi 		if (fuse_invalid_attr(&outarg.attr) ||
1057eb59bd17SMiklos Szeredi 		    (inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
10585d069dbeSMiklos Szeredi 			fuse_make_bad(inode);
1059e5e5558eSMiklos Szeredi 			err = -EIO;
1060e5e5558eSMiklos Szeredi 		} else {
1061c79e322fSMiklos Szeredi 			fuse_change_attributes(inode, &outarg.attr,
1062c79e322fSMiklos Szeredi 					       attr_timeout(&outarg),
10631fb69e78SMiklos Szeredi 					       attr_version);
10641fb69e78SMiklos Szeredi 			if (stat)
1065c79e322fSMiklos Szeredi 				fuse_fillattr(inode, &outarg.attr, stat);
1066e5e5558eSMiklos Szeredi 		}
1067e5e5558eSMiklos Szeredi 	}
1068e5e5558eSMiklos Szeredi 	return err;
1069e5e5558eSMiklos Szeredi }
1070e5e5558eSMiklos Szeredi 
10715b97eeacSMiklos Szeredi static int fuse_update_get_attr(struct inode *inode, struct file *file,
10722f1e8196SMiklos Szeredi 				struct kstat *stat, u32 request_mask,
10732f1e8196SMiklos Szeredi 				unsigned int flags)
1074bcb4be80SMiklos Szeredi {
1075bcb4be80SMiklos Szeredi 	struct fuse_inode *fi = get_fuse_inode(inode);
10765b97eeacSMiklos Szeredi 	int err = 0;
1077bf5c1898SMiklos Szeredi 	bool sync;
1078bcb4be80SMiklos Szeredi 
1079bf5c1898SMiklos Szeredi 	if (flags & AT_STATX_FORCE_SYNC)
1080bf5c1898SMiklos Szeredi 		sync = true;
1081bf5c1898SMiklos Szeredi 	else if (flags & AT_STATX_DONT_SYNC)
1082bf5c1898SMiklos Szeredi 		sync = false;
10832f1e8196SMiklos Szeredi 	else if (request_mask & READ_ONCE(fi->inval_mask))
10842f1e8196SMiklos Szeredi 		sync = true;
1085bf5c1898SMiklos Szeredi 	else
1086bf5c1898SMiklos Szeredi 		sync = time_before64(fi->i_time, get_jiffies_64());
1087bf5c1898SMiklos Szeredi 
1088bf5c1898SMiklos Szeredi 	if (sync) {
108960bcc88aSSeth Forshee 		forget_all_cached_acls(inode);
1090bcb4be80SMiklos Szeredi 		err = fuse_do_getattr(inode, stat, file);
10915b97eeacSMiklos Szeredi 	} else if (stat) {
10920d56a451SChristian Brauner 		generic_fillattr(&init_user_ns, inode, stat);
1093bcb4be80SMiklos Szeredi 		stat->mode = fi->orig_i_mode;
109445c72cd7SPavel Shilovsky 		stat->ino = fi->orig_ino;
1095bcb4be80SMiklos Szeredi 	}
1096bcb4be80SMiklos Szeredi 
1097bcb4be80SMiklos Szeredi 	return err;
1098bcb4be80SMiklos Szeredi }
1099bcb4be80SMiklos Szeredi 
11005b97eeacSMiklos Szeredi int fuse_update_attributes(struct inode *inode, struct file *file)
11015b97eeacSMiklos Szeredi {
1102802dc049SMiklos Szeredi 	/* Do *not* need to get atime for internal purposes */
1103802dc049SMiklos Szeredi 	return fuse_update_get_attr(inode, file, NULL,
1104802dc049SMiklos Szeredi 				    STATX_BASIC_STATS & ~STATX_ATIME, 0);
11055b97eeacSMiklos Szeredi }
11065b97eeacSMiklos Szeredi 
1107fcee216bSMax Reitz int fuse_reverse_inval_entry(struct fuse_conn *fc, u64 parent_nodeid,
1108451d0f59SJohn Muir 			     u64 child_nodeid, struct qstr *name)
11093b463ae0SJohn Muir {
11103b463ae0SJohn Muir 	int err = -ENOTDIR;
11113b463ae0SJohn Muir 	struct inode *parent;
11123b463ae0SJohn Muir 	struct dentry *dir;
11133b463ae0SJohn Muir 	struct dentry *entry;
11143b463ae0SJohn Muir 
1115fcee216bSMax Reitz 	parent = fuse_ilookup(fc, parent_nodeid, NULL);
11163b463ae0SJohn Muir 	if (!parent)
11173b463ae0SJohn Muir 		return -ENOENT;
11183b463ae0SJohn Muir 
11195955102cSAl Viro 	inode_lock(parent);
11203b463ae0SJohn Muir 	if (!S_ISDIR(parent->i_mode))
11213b463ae0SJohn Muir 		goto unlock;
11223b463ae0SJohn Muir 
11233b463ae0SJohn Muir 	err = -ENOENT;
11243b463ae0SJohn Muir 	dir = d_find_alias(parent);
11253b463ae0SJohn Muir 	if (!dir)
11263b463ae0SJohn Muir 		goto unlock;
11273b463ae0SJohn Muir 
11288387ff25SLinus Torvalds 	name->hash = full_name_hash(dir, name->name, name->len);
11293b463ae0SJohn Muir 	entry = d_lookup(dir, name);
11303b463ae0SJohn Muir 	dput(dir);
11313b463ae0SJohn Muir 	if (!entry)
11323b463ae0SJohn Muir 		goto unlock;
11333b463ae0SJohn Muir 
1134261aaba7SMiklos Szeredi 	fuse_dir_changed(parent);
11353b463ae0SJohn Muir 	fuse_invalidate_entry(entry);
1136451d0f59SJohn Muir 
11372b0143b5SDavid Howells 	if (child_nodeid != 0 && d_really_is_positive(entry)) {
11385955102cSAl Viro 		inode_lock(d_inode(entry));
11392b0143b5SDavid Howells 		if (get_node_id(d_inode(entry)) != child_nodeid) {
1140451d0f59SJohn Muir 			err = -ENOENT;
1141451d0f59SJohn Muir 			goto badentry;
1142451d0f59SJohn Muir 		}
1143451d0f59SJohn Muir 		if (d_mountpoint(entry)) {
1144451d0f59SJohn Muir 			err = -EBUSY;
1145451d0f59SJohn Muir 			goto badentry;
1146451d0f59SJohn Muir 		}
1147e36cb0b8SDavid Howells 		if (d_is_dir(entry)) {
1148451d0f59SJohn Muir 			shrink_dcache_parent(entry);
1149451d0f59SJohn Muir 			if (!simple_empty(entry)) {
1150451d0f59SJohn Muir 				err = -ENOTEMPTY;
1151451d0f59SJohn Muir 				goto badentry;
1152451d0f59SJohn Muir 			}
11532b0143b5SDavid Howells 			d_inode(entry)->i_flags |= S_DEAD;
1154451d0f59SJohn Muir 		}
1155451d0f59SJohn Muir 		dont_mount(entry);
11562b0143b5SDavid Howells 		clear_nlink(d_inode(entry));
11573b463ae0SJohn Muir 		err = 0;
1158451d0f59SJohn Muir  badentry:
11595955102cSAl Viro 		inode_unlock(d_inode(entry));
1160451d0f59SJohn Muir 		if (!err)
1161451d0f59SJohn Muir 			d_delete(entry);
1162451d0f59SJohn Muir 	} else {
1163451d0f59SJohn Muir 		err = 0;
1164451d0f59SJohn Muir 	}
1165451d0f59SJohn Muir 	dput(entry);
11663b463ae0SJohn Muir 
11673b463ae0SJohn Muir  unlock:
11685955102cSAl Viro 	inode_unlock(parent);
11693b463ae0SJohn Muir 	iput(parent);
11703b463ae0SJohn Muir 	return err;
11713b463ae0SJohn Muir }
11723b463ae0SJohn Muir 
117387729a55SMiklos Szeredi /*
117487729a55SMiklos Szeredi  * Calling into a user-controlled filesystem gives the filesystem
1175c2132c1bSAnatol Pomozov  * daemon ptrace-like capabilities over the current process.  This
117687729a55SMiklos Szeredi  * means, that the filesystem daemon is able to record the exact
117787729a55SMiklos Szeredi  * filesystem operations performed, and can also control the behavior
117887729a55SMiklos Szeredi  * of the requester process in otherwise impossible ways.  For example
117987729a55SMiklos Szeredi  * it can delay the operation for arbitrary length of time allowing
118087729a55SMiklos Szeredi  * DoS against the requester.
118187729a55SMiklos Szeredi  *
118287729a55SMiklos Szeredi  * For this reason only those processes can call into the filesystem,
118387729a55SMiklos Szeredi  * for which the owner of the mount has ptrace privilege.  This
118487729a55SMiklos Szeredi  * excludes processes started by other users, suid or sgid processes.
118587729a55SMiklos Szeredi  */
1186c2132c1bSAnatol Pomozov int fuse_allow_current_process(struct fuse_conn *fc)
118787729a55SMiklos Szeredi {
1188c69e8d9cSDavid Howells 	const struct cred *cred;
1189c69e8d9cSDavid Howells 
119029433a29SMiklos Szeredi 	if (fc->allow_other)
119173f03c2bSSeth Forshee 		return current_in_userns(fc->user_ns);
119287729a55SMiklos Szeredi 
1193c2132c1bSAnatol Pomozov 	cred = current_cred();
1194499dcf20SEric W. Biederman 	if (uid_eq(cred->euid, fc->user_id) &&
1195499dcf20SEric W. Biederman 	    uid_eq(cred->suid, fc->user_id) &&
1196499dcf20SEric W. Biederman 	    uid_eq(cred->uid,  fc->user_id) &&
1197499dcf20SEric W. Biederman 	    gid_eq(cred->egid, fc->group_id) &&
1198499dcf20SEric W. Biederman 	    gid_eq(cred->sgid, fc->group_id) &&
1199499dcf20SEric W. Biederman 	    gid_eq(cred->gid,  fc->group_id))
1200c2132c1bSAnatol Pomozov 		return 1;
120187729a55SMiklos Szeredi 
1202c2132c1bSAnatol Pomozov 	return 0;
120387729a55SMiklos Szeredi }
120487729a55SMiklos Szeredi 
120531d40d74SMiklos Szeredi static int fuse_access(struct inode *inode, int mask)
120631d40d74SMiklos Szeredi {
1207fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(inode);
12087078187aSMiklos Szeredi 	FUSE_ARGS(args);
120931d40d74SMiklos Szeredi 	struct fuse_access_in inarg;
121031d40d74SMiklos Szeredi 	int err;
121131d40d74SMiklos Szeredi 
1212698fa1d1SMiklos Szeredi 	BUG_ON(mask & MAY_NOT_BLOCK);
1213698fa1d1SMiklos Szeredi 
1214fcee216bSMax Reitz 	if (fm->fc->no_access)
121531d40d74SMiklos Szeredi 		return 0;
121631d40d74SMiklos Szeredi 
121731d40d74SMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
1218e6305c43SAl Viro 	inarg.mask = mask & (MAY_READ | MAY_WRITE | MAY_EXEC);
1219d5b48543SMiklos Szeredi 	args.opcode = FUSE_ACCESS;
1220d5b48543SMiklos Szeredi 	args.nodeid = get_node_id(inode);
1221d5b48543SMiklos Szeredi 	args.in_numargs = 1;
1222d5b48543SMiklos Szeredi 	args.in_args[0].size = sizeof(inarg);
1223d5b48543SMiklos Szeredi 	args.in_args[0].value = &inarg;
1224fcee216bSMax Reitz 	err = fuse_simple_request(fm, &args);
122531d40d74SMiklos Szeredi 	if (err == -ENOSYS) {
1226fcee216bSMax Reitz 		fm->fc->no_access = 1;
122731d40d74SMiklos Szeredi 		err = 0;
122831d40d74SMiklos Szeredi 	}
122931d40d74SMiklos Szeredi 	return err;
123031d40d74SMiklos Szeredi }
123131d40d74SMiklos Szeredi 
123210556cb2SAl Viro static int fuse_perm_getattr(struct inode *inode, int mask)
123319690ddbSMiklos Szeredi {
123410556cb2SAl Viro 	if (mask & MAY_NOT_BLOCK)
123519690ddbSMiklos Szeredi 		return -ECHILD;
123619690ddbSMiklos Szeredi 
123760bcc88aSSeth Forshee 	forget_all_cached_acls(inode);
123819690ddbSMiklos Szeredi 	return fuse_do_getattr(inode, NULL, NULL);
123919690ddbSMiklos Szeredi }
124019690ddbSMiklos Szeredi 
12416f9f1180SMiklos Szeredi /*
12426f9f1180SMiklos Szeredi  * Check permission.  The two basic access models of FUSE are:
12436f9f1180SMiklos Szeredi  *
12446f9f1180SMiklos Szeredi  * 1) Local access checking ('default_permissions' mount option) based
12456f9f1180SMiklos Szeredi  * on file mode.  This is the plain old disk filesystem permission
12466f9f1180SMiklos Szeredi  * modell.
12476f9f1180SMiklos Szeredi  *
12486f9f1180SMiklos Szeredi  * 2) "Remote" access checking, where server is responsible for
12496f9f1180SMiklos Szeredi  * checking permission in each inode operation.  An exception to this
12506f9f1180SMiklos Szeredi  * is if ->permission() was invoked from sys_access() in which case an
12516f9f1180SMiklos Szeredi  * access request is sent.  Execute permission is still checked
12526f9f1180SMiklos Szeredi  * locally based on file mode.
12536f9f1180SMiklos Szeredi  */
1254549c7297SChristian Brauner static int fuse_permission(struct user_namespace *mnt_userns,
1255549c7297SChristian Brauner 			   struct inode *inode, int mask)
1256e5e5558eSMiklos Szeredi {
1257e5e5558eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
1258244f6385SMiklos Szeredi 	bool refreshed = false;
1259244f6385SMiklos Szeredi 	int err = 0;
1260e5e5558eSMiklos Szeredi 
12615d069dbeSMiklos Szeredi 	if (fuse_is_bad(inode))
12625d069dbeSMiklos Szeredi 		return -EIO;
12635d069dbeSMiklos Szeredi 
1264c2132c1bSAnatol Pomozov 	if (!fuse_allow_current_process(fc))
1265e5e5558eSMiklos Szeredi 		return -EACCES;
1266244f6385SMiklos Szeredi 
1267244f6385SMiklos Szeredi 	/*
1268e8e96157SMiklos Szeredi 	 * If attributes are needed, refresh them before proceeding
1269244f6385SMiklos Szeredi 	 */
127029433a29SMiklos Szeredi 	if (fc->default_permissions ||
1271e8e96157SMiklos Szeredi 	    ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) {
127219690ddbSMiklos Szeredi 		struct fuse_inode *fi = get_fuse_inode(inode);
1273d233c7ddSMiklos Szeredi 		u32 perm_mask = STATX_MODE | STATX_UID | STATX_GID;
127419690ddbSMiklos Szeredi 
1275d233c7ddSMiklos Szeredi 		if (perm_mask & READ_ONCE(fi->inval_mask) ||
1276d233c7ddSMiklos Szeredi 		    time_before64(fi->i_time, get_jiffies_64())) {
127719690ddbSMiklos Szeredi 			refreshed = true;
127819690ddbSMiklos Szeredi 
127910556cb2SAl Viro 			err = fuse_perm_getattr(inode, mask);
1280244f6385SMiklos Szeredi 			if (err)
1281244f6385SMiklos Szeredi 				return err;
12821fb69e78SMiklos Szeredi 		}
128319690ddbSMiklos Szeredi 	}
1284244f6385SMiklos Szeredi 
128529433a29SMiklos Szeredi 	if (fc->default_permissions) {
128647291baaSChristian Brauner 		err = generic_permission(&init_user_ns, inode, mask);
12871e9a4ed9SMiklos Szeredi 
12881e9a4ed9SMiklos Szeredi 		/* If permission is denied, try to refresh file
12891e9a4ed9SMiklos Szeredi 		   attributes.  This is also needed, because the root
12901e9a4ed9SMiklos Szeredi 		   node will at first have no permissions */
1291244f6385SMiklos Szeredi 		if (err == -EACCES && !refreshed) {
129210556cb2SAl Viro 			err = fuse_perm_getattr(inode, mask);
12931e9a4ed9SMiklos Szeredi 			if (!err)
129447291baaSChristian Brauner 				err = generic_permission(&init_user_ns,
129547291baaSChristian Brauner 							 inode, mask);
12961e9a4ed9SMiklos Szeredi 		}
12971e9a4ed9SMiklos Szeredi 
12986f9f1180SMiklos Szeredi 		/* Note: the opposite of the above test does not
12996f9f1180SMiklos Szeredi 		   exist.  So if permissions are revoked this won't be
13006f9f1180SMiklos Szeredi 		   noticed immediately, only after the attribute
13016f9f1180SMiklos Szeredi 		   timeout has expired */
13029cfcac81SEric Paris 	} else if (mask & (MAY_ACCESS | MAY_CHDIR)) {
1303e8e96157SMiklos Szeredi 		err = fuse_access(inode, mask);
1304e8e96157SMiklos Szeredi 	} else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
1305e8e96157SMiklos Szeredi 		if (!(inode->i_mode & S_IXUGO)) {
1306e8e96157SMiklos Szeredi 			if (refreshed)
1307e5e5558eSMiklos Szeredi 				return -EACCES;
130831d40d74SMiklos Szeredi 
130910556cb2SAl Viro 			err = fuse_perm_getattr(inode, mask);
1310e8e96157SMiklos Szeredi 			if (!err && !(inode->i_mode & S_IXUGO))
1311e8e96157SMiklos Szeredi 				return -EACCES;
1312e8e96157SMiklos Szeredi 		}
1313e5e5558eSMiklos Szeredi 	}
1314244f6385SMiklos Szeredi 	return err;
1315e5e5558eSMiklos Szeredi }
1316e5e5558eSMiklos Szeredi 
13175571f1e6SDan Schatzberg static int fuse_readlink_page(struct inode *inode, struct page *page)
1318e5e5558eSMiklos Szeredi {
1319fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(inode);
13204c29afecSMiklos Szeredi 	struct fuse_page_desc desc = { .length = PAGE_SIZE - 1 };
13214c29afecSMiklos Szeredi 	struct fuse_args_pages ap = {
13224c29afecSMiklos Szeredi 		.num_pages = 1,
13234c29afecSMiklos Szeredi 		.pages = &page,
13244c29afecSMiklos Szeredi 		.descs = &desc,
13254c29afecSMiklos Szeredi 	};
13264c29afecSMiklos Szeredi 	char *link;
13274c29afecSMiklos Szeredi 	ssize_t res;
1328e5e5558eSMiklos Szeredi 
13294c29afecSMiklos Szeredi 	ap.args.opcode = FUSE_READLINK;
13304c29afecSMiklos Szeredi 	ap.args.nodeid = get_node_id(inode);
13314c29afecSMiklos Szeredi 	ap.args.out_pages = true;
13324c29afecSMiklos Szeredi 	ap.args.out_argvar = true;
13334c29afecSMiklos Szeredi 	ap.args.page_zeroing = true;
13344c29afecSMiklos Szeredi 	ap.args.out_numargs = 1;
13354c29afecSMiklos Szeredi 	ap.args.out_args[0].size = desc.length;
1336fcee216bSMax Reitz 	res = fuse_simple_request(fm, &ap.args);
13376b255391SAl Viro 
1338451418fcSAndrew Gallagher 	fuse_invalidate_atime(inode);
13395571f1e6SDan Schatzberg 
13404c29afecSMiklos Szeredi 	if (res < 0)
13414c29afecSMiklos Szeredi 		return res;
13424c29afecSMiklos Szeredi 
13434c29afecSMiklos Szeredi 	if (WARN_ON(res >= PAGE_SIZE))
13444c29afecSMiklos Szeredi 		return -EIO;
13454c29afecSMiklos Szeredi 
13464c29afecSMiklos Szeredi 	link = page_address(page);
13474c29afecSMiklos Szeredi 	link[res] = '\0';
13484c29afecSMiklos Szeredi 
13494c29afecSMiklos Szeredi 	return 0;
13505571f1e6SDan Schatzberg }
13515571f1e6SDan Schatzberg 
13525571f1e6SDan Schatzberg static const char *fuse_get_link(struct dentry *dentry, struct inode *inode,
13535571f1e6SDan Schatzberg 				 struct delayed_call *callback)
13545571f1e6SDan Schatzberg {
13555571f1e6SDan Schatzberg 	struct fuse_conn *fc = get_fuse_conn(inode);
13565571f1e6SDan Schatzberg 	struct page *page;
13575571f1e6SDan Schatzberg 	int err;
13585571f1e6SDan Schatzberg 
13595571f1e6SDan Schatzberg 	err = -EIO;
13605d069dbeSMiklos Szeredi 	if (fuse_is_bad(inode))
13615571f1e6SDan Schatzberg 		goto out_err;
13625571f1e6SDan Schatzberg 
13635571f1e6SDan Schatzberg 	if (fc->cache_symlinks)
13645571f1e6SDan Schatzberg 		return page_get_link(dentry, inode, callback);
13655571f1e6SDan Schatzberg 
13665571f1e6SDan Schatzberg 	err = -ECHILD;
13675571f1e6SDan Schatzberg 	if (!dentry)
13685571f1e6SDan Schatzberg 		goto out_err;
13695571f1e6SDan Schatzberg 
13705571f1e6SDan Schatzberg 	page = alloc_page(GFP_KERNEL);
13715571f1e6SDan Schatzberg 	err = -ENOMEM;
13725571f1e6SDan Schatzberg 	if (!page)
13735571f1e6SDan Schatzberg 		goto out_err;
13745571f1e6SDan Schatzberg 
13755571f1e6SDan Schatzberg 	err = fuse_readlink_page(inode, page);
13765571f1e6SDan Schatzberg 	if (err) {
13775571f1e6SDan Schatzberg 		__free_page(page);
13785571f1e6SDan Schatzberg 		goto out_err;
13795571f1e6SDan Schatzberg 	}
13805571f1e6SDan Schatzberg 
13815571f1e6SDan Schatzberg 	set_delayed_call(callback, page_put_link, page);
13825571f1e6SDan Schatzberg 
13835571f1e6SDan Schatzberg 	return page_address(page);
13845571f1e6SDan Schatzberg 
13855571f1e6SDan Schatzberg out_err:
13865571f1e6SDan Schatzberg 	return ERR_PTR(err);
1387e5e5558eSMiklos Szeredi }
1388e5e5558eSMiklos Szeredi 
1389e5e5558eSMiklos Szeredi static int fuse_dir_open(struct inode *inode, struct file *file)
1390e5e5558eSMiklos Szeredi {
139191fe96b4SMiklos Szeredi 	return fuse_open_common(inode, file, true);
1392e5e5558eSMiklos Szeredi }
1393e5e5558eSMiklos Szeredi 
1394e5e5558eSMiklos Szeredi static int fuse_dir_release(struct inode *inode, struct file *file)
1395e5e5558eSMiklos Szeredi {
13962e64ff15SChad Austin 	fuse_release_common(file, true);
13978b0797a4SMiklos Szeredi 
13988b0797a4SMiklos Szeredi 	return 0;
1399e5e5558eSMiklos Szeredi }
1400e5e5558eSMiklos Szeredi 
140102c24a82SJosef Bacik static int fuse_dir_fsync(struct file *file, loff_t start, loff_t end,
140202c24a82SJosef Bacik 			  int datasync)
140382547981SMiklos Szeredi {
1404a9c2d1e8SMiklos Szeredi 	struct inode *inode = file->f_mapping->host;
1405a9c2d1e8SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
1406a9c2d1e8SMiklos Szeredi 	int err;
1407a9c2d1e8SMiklos Szeredi 
14085d069dbeSMiklos Szeredi 	if (fuse_is_bad(inode))
1409a9c2d1e8SMiklos Szeredi 		return -EIO;
1410a9c2d1e8SMiklos Szeredi 
1411a9c2d1e8SMiklos Szeredi 	if (fc->no_fsyncdir)
1412a9c2d1e8SMiklos Szeredi 		return 0;
1413a9c2d1e8SMiklos Szeredi 
1414a9c2d1e8SMiklos Szeredi 	inode_lock(inode);
1415a9c2d1e8SMiklos Szeredi 	err = fuse_fsync_common(file, start, end, datasync, FUSE_FSYNCDIR);
1416a9c2d1e8SMiklos Szeredi 	if (err == -ENOSYS) {
1417a9c2d1e8SMiklos Szeredi 		fc->no_fsyncdir = 1;
1418a9c2d1e8SMiklos Szeredi 		err = 0;
1419a9c2d1e8SMiklos Szeredi 	}
1420a9c2d1e8SMiklos Szeredi 	inode_unlock(inode);
1421a9c2d1e8SMiklos Szeredi 
1422a9c2d1e8SMiklos Szeredi 	return err;
142382547981SMiklos Szeredi }
142482547981SMiklos Szeredi 
1425b18da0c5SMiklos Szeredi static long fuse_dir_ioctl(struct file *file, unsigned int cmd,
1426b18da0c5SMiklos Szeredi 			    unsigned long arg)
1427b18da0c5SMiklos Szeredi {
1428b18da0c5SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1429b18da0c5SMiklos Szeredi 
1430b18da0c5SMiklos Szeredi 	/* FUSE_IOCTL_DIR only supported for API version >= 7.18 */
1431b18da0c5SMiklos Szeredi 	if (fc->minor < 18)
1432b18da0c5SMiklos Szeredi 		return -ENOTTY;
1433b18da0c5SMiklos Szeredi 
1434b18da0c5SMiklos Szeredi 	return fuse_ioctl_common(file, cmd, arg, FUSE_IOCTL_DIR);
1435b18da0c5SMiklos Szeredi }
1436b18da0c5SMiklos Szeredi 
1437b18da0c5SMiklos Szeredi static long fuse_dir_compat_ioctl(struct file *file, unsigned int cmd,
1438b18da0c5SMiklos Szeredi 				   unsigned long arg)
1439b18da0c5SMiklos Szeredi {
1440b18da0c5SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1441b18da0c5SMiklos Szeredi 
1442b18da0c5SMiklos Szeredi 	if (fc->minor < 18)
1443b18da0c5SMiklos Szeredi 		return -ENOTTY;
1444b18da0c5SMiklos Szeredi 
1445b18da0c5SMiklos Szeredi 	return fuse_ioctl_common(file, cmd, arg,
1446b18da0c5SMiklos Szeredi 				 FUSE_IOCTL_COMPAT | FUSE_IOCTL_DIR);
1447b18da0c5SMiklos Szeredi }
1448b18da0c5SMiklos Szeredi 
1449b0aa7606SMaxim Patlasov static bool update_mtime(unsigned ivalid, bool trust_local_mtime)
145017637cbaSMiklos Szeredi {
145117637cbaSMiklos Szeredi 	/* Always update if mtime is explicitly set  */
145217637cbaSMiklos Szeredi 	if (ivalid & ATTR_MTIME_SET)
145317637cbaSMiklos Szeredi 		return true;
145417637cbaSMiklos Szeredi 
1455b0aa7606SMaxim Patlasov 	/* Or if kernel i_mtime is the official one */
1456b0aa7606SMaxim Patlasov 	if (trust_local_mtime)
1457b0aa7606SMaxim Patlasov 		return true;
1458b0aa7606SMaxim Patlasov 
145917637cbaSMiklos Szeredi 	/* If it's an open(O_TRUNC) or an ftruncate(), don't update */
146017637cbaSMiklos Szeredi 	if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE)))
146117637cbaSMiklos Szeredi 		return false;
146217637cbaSMiklos Szeredi 
146317637cbaSMiklos Szeredi 	/* In all other cases update */
146417637cbaSMiklos Szeredi 	return true;
146517637cbaSMiklos Szeredi }
146617637cbaSMiklos Szeredi 
14678cb08329SEric W. Biederman static void iattr_to_fattr(struct fuse_conn *fc, struct iattr *iattr,
14688cb08329SEric W. Biederman 			   struct fuse_setattr_in *arg, bool trust_local_cmtime)
14699e6268dbSMiklos Szeredi {
14709e6268dbSMiklos Szeredi 	unsigned ivalid = iattr->ia_valid;
14719e6268dbSMiklos Szeredi 
14729e6268dbSMiklos Szeredi 	if (ivalid & ATTR_MODE)
1473befc649cSMiklos Szeredi 		arg->valid |= FATTR_MODE,   arg->mode = iattr->ia_mode;
14749e6268dbSMiklos Szeredi 	if (ivalid & ATTR_UID)
14758cb08329SEric W. Biederman 		arg->valid |= FATTR_UID,    arg->uid = from_kuid(fc->user_ns, iattr->ia_uid);
14769e6268dbSMiklos Szeredi 	if (ivalid & ATTR_GID)
14778cb08329SEric W. Biederman 		arg->valid |= FATTR_GID,    arg->gid = from_kgid(fc->user_ns, iattr->ia_gid);
14789e6268dbSMiklos Szeredi 	if (ivalid & ATTR_SIZE)
1479befc649cSMiklos Szeredi 		arg->valid |= FATTR_SIZE,   arg->size = iattr->ia_size;
148017637cbaSMiklos Szeredi 	if (ivalid & ATTR_ATIME) {
148117637cbaSMiklos Szeredi 		arg->valid |= FATTR_ATIME;
1482befc649cSMiklos Szeredi 		arg->atime = iattr->ia_atime.tv_sec;
148317637cbaSMiklos Szeredi 		arg->atimensec = iattr->ia_atime.tv_nsec;
148417637cbaSMiklos Szeredi 		if (!(ivalid & ATTR_ATIME_SET))
148517637cbaSMiklos Szeredi 			arg->valid |= FATTR_ATIME_NOW;
148617637cbaSMiklos Szeredi 	}
14873ad22c62SMaxim Patlasov 	if ((ivalid & ATTR_MTIME) && update_mtime(ivalid, trust_local_cmtime)) {
148817637cbaSMiklos Szeredi 		arg->valid |= FATTR_MTIME;
1489befc649cSMiklos Szeredi 		arg->mtime = iattr->ia_mtime.tv_sec;
149017637cbaSMiklos Szeredi 		arg->mtimensec = iattr->ia_mtime.tv_nsec;
14913ad22c62SMaxim Patlasov 		if (!(ivalid & ATTR_MTIME_SET) && !trust_local_cmtime)
149217637cbaSMiklos Szeredi 			arg->valid |= FATTR_MTIME_NOW;
14939e6268dbSMiklos Szeredi 	}
14943ad22c62SMaxim Patlasov 	if ((ivalid & ATTR_CTIME) && trust_local_cmtime) {
14953ad22c62SMaxim Patlasov 		arg->valid |= FATTR_CTIME;
14963ad22c62SMaxim Patlasov 		arg->ctime = iattr->ia_ctime.tv_sec;
14973ad22c62SMaxim Patlasov 		arg->ctimensec = iattr->ia_ctime.tv_nsec;
14983ad22c62SMaxim Patlasov 	}
14999e6268dbSMiklos Szeredi }
15009e6268dbSMiklos Szeredi 
15016f9f1180SMiklos Szeredi /*
15023be5a52bSMiklos Szeredi  * Prevent concurrent writepages on inode
15033be5a52bSMiklos Szeredi  *
15043be5a52bSMiklos Szeredi  * This is done by adding a negative bias to the inode write counter
15053be5a52bSMiklos Szeredi  * and waiting for all pending writes to finish.
15063be5a52bSMiklos Szeredi  */
15073be5a52bSMiklos Szeredi void fuse_set_nowrite(struct inode *inode)
15083be5a52bSMiklos Szeredi {
15093be5a52bSMiklos Szeredi 	struct fuse_inode *fi = get_fuse_inode(inode);
15103be5a52bSMiklos Szeredi 
15115955102cSAl Viro 	BUG_ON(!inode_is_locked(inode));
15123be5a52bSMiklos Szeredi 
1513f15ecfefSKirill Tkhai 	spin_lock(&fi->lock);
15143be5a52bSMiklos Szeredi 	BUG_ON(fi->writectr < 0);
15153be5a52bSMiklos Szeredi 	fi->writectr += FUSE_NOWRITE;
1516f15ecfefSKirill Tkhai 	spin_unlock(&fi->lock);
15173be5a52bSMiklos Szeredi 	wait_event(fi->page_waitq, fi->writectr == FUSE_NOWRITE);
15183be5a52bSMiklos Szeredi }
15193be5a52bSMiklos Szeredi 
15203be5a52bSMiklos Szeredi /*
15213be5a52bSMiklos Szeredi  * Allow writepages on inode
15223be5a52bSMiklos Szeredi  *
15233be5a52bSMiklos Szeredi  * Remove the bias from the writecounter and send any queued
15243be5a52bSMiklos Szeredi  * writepages.
15253be5a52bSMiklos Szeredi  */
15263be5a52bSMiklos Szeredi static void __fuse_release_nowrite(struct inode *inode)
15273be5a52bSMiklos Szeredi {
15283be5a52bSMiklos Szeredi 	struct fuse_inode *fi = get_fuse_inode(inode);
15293be5a52bSMiklos Szeredi 
15303be5a52bSMiklos Szeredi 	BUG_ON(fi->writectr != FUSE_NOWRITE);
15313be5a52bSMiklos Szeredi 	fi->writectr = 0;
15323be5a52bSMiklos Szeredi 	fuse_flush_writepages(inode);
15333be5a52bSMiklos Szeredi }
15343be5a52bSMiklos Szeredi 
15353be5a52bSMiklos Szeredi void fuse_release_nowrite(struct inode *inode)
15363be5a52bSMiklos Szeredi {
1537f15ecfefSKirill Tkhai 	struct fuse_inode *fi = get_fuse_inode(inode);
15383be5a52bSMiklos Szeredi 
1539f15ecfefSKirill Tkhai 	spin_lock(&fi->lock);
15403be5a52bSMiklos Szeredi 	__fuse_release_nowrite(inode);
1541f15ecfefSKirill Tkhai 	spin_unlock(&fi->lock);
15423be5a52bSMiklos Szeredi }
15433be5a52bSMiklos Szeredi 
15447078187aSMiklos Szeredi static void fuse_setattr_fill(struct fuse_conn *fc, struct fuse_args *args,
1545b0aa7606SMaxim Patlasov 			      struct inode *inode,
1546b0aa7606SMaxim Patlasov 			      struct fuse_setattr_in *inarg_p,
1547b0aa7606SMaxim Patlasov 			      struct fuse_attr_out *outarg_p)
1548b0aa7606SMaxim Patlasov {
1549d5b48543SMiklos Szeredi 	args->opcode = FUSE_SETATTR;
1550d5b48543SMiklos Szeredi 	args->nodeid = get_node_id(inode);
1551d5b48543SMiklos Szeredi 	args->in_numargs = 1;
1552d5b48543SMiklos Szeredi 	args->in_args[0].size = sizeof(*inarg_p);
1553d5b48543SMiklos Szeredi 	args->in_args[0].value = inarg_p;
1554d5b48543SMiklos Szeredi 	args->out_numargs = 1;
1555d5b48543SMiklos Szeredi 	args->out_args[0].size = sizeof(*outarg_p);
1556d5b48543SMiklos Szeredi 	args->out_args[0].value = outarg_p;
1557b0aa7606SMaxim Patlasov }
1558b0aa7606SMaxim Patlasov 
1559b0aa7606SMaxim Patlasov /*
1560b0aa7606SMaxim Patlasov  * Flush inode->i_mtime to the server
1561b0aa7606SMaxim Patlasov  */
1562ab9e13f7SMaxim Patlasov int fuse_flush_times(struct inode *inode, struct fuse_file *ff)
1563b0aa7606SMaxim Patlasov {
1564fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(inode);
15657078187aSMiklos Szeredi 	FUSE_ARGS(args);
1566b0aa7606SMaxim Patlasov 	struct fuse_setattr_in inarg;
1567b0aa7606SMaxim Patlasov 	struct fuse_attr_out outarg;
1568b0aa7606SMaxim Patlasov 
1569b0aa7606SMaxim Patlasov 	memset(&inarg, 0, sizeof(inarg));
1570b0aa7606SMaxim Patlasov 	memset(&outarg, 0, sizeof(outarg));
1571b0aa7606SMaxim Patlasov 
1572ab9e13f7SMaxim Patlasov 	inarg.valid = FATTR_MTIME;
1573b0aa7606SMaxim Patlasov 	inarg.mtime = inode->i_mtime.tv_sec;
1574b0aa7606SMaxim Patlasov 	inarg.mtimensec = inode->i_mtime.tv_nsec;
1575fcee216bSMax Reitz 	if (fm->fc->minor >= 23) {
1576ab9e13f7SMaxim Patlasov 		inarg.valid |= FATTR_CTIME;
1577ab9e13f7SMaxim Patlasov 		inarg.ctime = inode->i_ctime.tv_sec;
1578ab9e13f7SMaxim Patlasov 		inarg.ctimensec = inode->i_ctime.tv_nsec;
1579ab9e13f7SMaxim Patlasov 	}
15801e18bda8SMiklos Szeredi 	if (ff) {
15811e18bda8SMiklos Szeredi 		inarg.valid |= FATTR_FH;
15821e18bda8SMiklos Szeredi 		inarg.fh = ff->fh;
15831e18bda8SMiklos Szeredi 	}
1584fcee216bSMax Reitz 	fuse_setattr_fill(fm->fc, &args, inode, &inarg, &outarg);
1585b0aa7606SMaxim Patlasov 
1586fcee216bSMax Reitz 	return fuse_simple_request(fm, &args);
1587b0aa7606SMaxim Patlasov }
1588b0aa7606SMaxim Patlasov 
15893be5a52bSMiklos Szeredi /*
15906f9f1180SMiklos Szeredi  * Set attributes, and at the same time refresh them.
15916f9f1180SMiklos Szeredi  *
15926f9f1180SMiklos Szeredi  * Truncation is slightly complicated, because the 'truncate' request
15936f9f1180SMiklos Szeredi  * may fail, in which case we don't want to touch the mapping.
15949ffbb916SMiklos Szeredi  * vmtruncate() doesn't allow for this case, so do the rlimit checking
15959ffbb916SMiklos Szeredi  * and the actual truncation by hand.
15966f9f1180SMiklos Szeredi  */
159762490330SJan Kara int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
159849d4914fSMiklos Szeredi 		    struct file *file)
15999e6268dbSMiklos Szeredi {
160062490330SJan Kara 	struct inode *inode = d_inode(dentry);
1601fcee216bSMax Reitz 	struct fuse_mount *fm = get_fuse_mount(inode);
1602fcee216bSMax Reitz 	struct fuse_conn *fc = fm->fc;
160306a7c3c2SMaxim Patlasov 	struct fuse_inode *fi = get_fuse_inode(inode);
16047078187aSMiklos Szeredi 	FUSE_ARGS(args);
16059e6268dbSMiklos Szeredi 	struct fuse_setattr_in inarg;
16069e6268dbSMiklos Szeredi 	struct fuse_attr_out outarg;
16073be5a52bSMiklos Szeredi 	bool is_truncate = false;
16088373200bSPavel Emelyanov 	bool is_wb = fc->writeback_cache;
16093be5a52bSMiklos Szeredi 	loff_t oldsize;
16109e6268dbSMiklos Szeredi 	int err;
16113ad22c62SMaxim Patlasov 	bool trust_local_cmtime = is_wb && S_ISREG(inode->i_mode);
16126ae330caSVivek Goyal 	bool fault_blocked = false;
16139e6268dbSMiklos Szeredi 
161429433a29SMiklos Szeredi 	if (!fc->default_permissions)
1615db78b877SChristoph Hellwig 		attr->ia_valid |= ATTR_FORCE;
1616db78b877SChristoph Hellwig 
16172f221d6fSChristian Brauner 	err = setattr_prepare(&init_user_ns, dentry, attr);
16181e9a4ed9SMiklos Szeredi 	if (err)
16191e9a4ed9SMiklos Szeredi 		return err;
16201e9a4ed9SMiklos Szeredi 
16216ae330caSVivek Goyal 	if (attr->ia_valid & ATTR_SIZE) {
16226ae330caSVivek Goyal 		if (WARN_ON(!S_ISREG(inode->i_mode)))
16236ae330caSVivek Goyal 			return -EIO;
16246ae330caSVivek Goyal 		is_truncate = true;
16256ae330caSVivek Goyal 	}
16266ae330caSVivek Goyal 
16276ae330caSVivek Goyal 	if (FUSE_IS_DAX(inode) && is_truncate) {
16286ae330caSVivek Goyal 		down_write(&fi->i_mmap_sem);
16296ae330caSVivek Goyal 		fault_blocked = true;
16306ae330caSVivek Goyal 		err = fuse_dax_break_layouts(inode, 0, 0);
16316ae330caSVivek Goyal 		if (err) {
16326ae330caSVivek Goyal 			up_write(&fi->i_mmap_sem);
16336ae330caSVivek Goyal 			return err;
16346ae330caSVivek Goyal 		}
16356ae330caSVivek Goyal 	}
16366ae330caSVivek Goyal 
16378d56adddSMiklos Szeredi 	if (attr->ia_valid & ATTR_OPEN) {
1638df0e91d4SMiklos Szeredi 		/* This is coming from open(..., ... | O_TRUNC); */
1639df0e91d4SMiklos Szeredi 		WARN_ON(!(attr->ia_valid & ATTR_SIZE));
1640df0e91d4SMiklos Szeredi 		WARN_ON(attr->ia_size != 0);
1641df0e91d4SMiklos Szeredi 		if (fc->atomic_o_trunc) {
1642df0e91d4SMiklos Szeredi 			/*
1643df0e91d4SMiklos Szeredi 			 * No need to send request to userspace, since actual
1644df0e91d4SMiklos Szeredi 			 * truncation has already been done by OPEN.  But still
1645df0e91d4SMiklos Szeredi 			 * need to truncate page cache.
1646df0e91d4SMiklos Szeredi 			 */
1647df0e91d4SMiklos Szeredi 			i_size_write(inode, 0);
1648df0e91d4SMiklos Szeredi 			truncate_pagecache(inode, 0);
16496ae330caSVivek Goyal 			goto out;
1650df0e91d4SMiklos Szeredi 		}
16518d56adddSMiklos Szeredi 		file = NULL;
16528d56adddSMiklos Szeredi 	}
16536ff958edSMiklos Szeredi 
1654b24e7598SMiklos Szeredi 	/* Flush dirty data/metadata before non-truncate SETATTR */
1655b24e7598SMiklos Szeredi 	if (is_wb && S_ISREG(inode->i_mode) &&
1656b24e7598SMiklos Szeredi 	    attr->ia_valid &
1657b24e7598SMiklos Szeredi 			(ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_MTIME_SET |
1658b24e7598SMiklos Szeredi 			 ATTR_TIMES_SET)) {
1659b24e7598SMiklos Szeredi 		err = write_inode_now(inode, true);
1660b24e7598SMiklos Szeredi 		if (err)
1661b24e7598SMiklos Szeredi 			return err;
1662b24e7598SMiklos Szeredi 
1663b24e7598SMiklos Szeredi 		fuse_set_nowrite(inode);
1664b24e7598SMiklos Szeredi 		fuse_release_nowrite(inode);
1665b24e7598SMiklos Szeredi 	}
1666b24e7598SMiklos Szeredi 
166706a7c3c2SMaxim Patlasov 	if (is_truncate) {
16683be5a52bSMiklos Szeredi 		fuse_set_nowrite(inode);
166906a7c3c2SMaxim Patlasov 		set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
16703ad22c62SMaxim Patlasov 		if (trust_local_cmtime && attr->ia_size != inode->i_size)
16713ad22c62SMaxim Patlasov 			attr->ia_valid |= ATTR_MTIME | ATTR_CTIME;
167206a7c3c2SMaxim Patlasov 	}
16733be5a52bSMiklos Szeredi 
16749e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
16750e9663eeSMiklos Szeredi 	memset(&outarg, 0, sizeof(outarg));
16768cb08329SEric W. Biederman 	iattr_to_fattr(fc, attr, &inarg, trust_local_cmtime);
167749d4914fSMiklos Szeredi 	if (file) {
167849d4914fSMiklos Szeredi 		struct fuse_file *ff = file->private_data;
167949d4914fSMiklos Szeredi 		inarg.valid |= FATTR_FH;
168049d4914fSMiklos Szeredi 		inarg.fh = ff->fh;
168149d4914fSMiklos Szeredi 	}
168231792161SVivek Goyal 
168331792161SVivek Goyal 	/* Kill suid/sgid for non-directory chown unconditionally */
168431792161SVivek Goyal 	if (fc->handle_killpriv_v2 && !S_ISDIR(inode->i_mode) &&
168531792161SVivek Goyal 	    attr->ia_valid & (ATTR_UID | ATTR_GID))
168631792161SVivek Goyal 		inarg.valid |= FATTR_KILL_SUIDGID;
168731792161SVivek Goyal 
1688f3332114SMiklos Szeredi 	if (attr->ia_valid & ATTR_SIZE) {
1689f3332114SMiklos Szeredi 		/* For mandatory locking in truncate */
1690f3332114SMiklos Szeredi 		inarg.valid |= FATTR_LOCKOWNER;
1691f3332114SMiklos Szeredi 		inarg.lock_owner = fuse_lock_owner_id(fc, current->files);
169231792161SVivek Goyal 
169331792161SVivek Goyal 		/* Kill suid/sgid for truncate only if no CAP_FSETID */
169431792161SVivek Goyal 		if (fc->handle_killpriv_v2 && !capable(CAP_FSETID))
169531792161SVivek Goyal 			inarg.valid |= FATTR_KILL_SUIDGID;
1696f3332114SMiklos Szeredi 	}
16977078187aSMiklos Szeredi 	fuse_setattr_fill(fc, &args, inode, &inarg, &outarg);
1698fcee216bSMax Reitz 	err = fuse_simple_request(fm, &args);
1699e00d2c2dSMiklos Szeredi 	if (err) {
1700e00d2c2dSMiklos Szeredi 		if (err == -EINTR)
1701e00d2c2dSMiklos Szeredi 			fuse_invalidate_attr(inode);
17023be5a52bSMiklos Szeredi 		goto error;
1703e00d2c2dSMiklos Szeredi 	}
1704e00d2c2dSMiklos Szeredi 
1705eb59bd17SMiklos Szeredi 	if (fuse_invalid_attr(&outarg.attr) ||
1706eb59bd17SMiklos Szeredi 	    (inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
17075d069dbeSMiklos Szeredi 		fuse_make_bad(inode);
17083be5a52bSMiklos Szeredi 		err = -EIO;
17093be5a52bSMiklos Szeredi 		goto error;
17109e6268dbSMiklos Szeredi 	}
17119e6268dbSMiklos Szeredi 
1712f15ecfefSKirill Tkhai 	spin_lock(&fi->lock);
1713b0aa7606SMaxim Patlasov 	/* the kernel maintains i_mtime locally */
17143ad22c62SMaxim Patlasov 	if (trust_local_cmtime) {
17153ad22c62SMaxim Patlasov 		if (attr->ia_valid & ATTR_MTIME)
1716b0aa7606SMaxim Patlasov 			inode->i_mtime = attr->ia_mtime;
17173ad22c62SMaxim Patlasov 		if (attr->ia_valid & ATTR_CTIME)
17183ad22c62SMaxim Patlasov 			inode->i_ctime = attr->ia_ctime;
17191e18bda8SMiklos Szeredi 		/* FIXME: clear I_DIRTY_SYNC? */
1720b0aa7606SMaxim Patlasov 	}
1721b0aa7606SMaxim Patlasov 
17223be5a52bSMiklos Szeredi 	fuse_change_attributes_common(inode, &outarg.attr,
17233be5a52bSMiklos Szeredi 				      attr_timeout(&outarg));
17243be5a52bSMiklos Szeredi 	oldsize = inode->i_size;
17258373200bSPavel Emelyanov 	/* see the comment in fuse_change_attributes() */
17268373200bSPavel Emelyanov 	if (!is_wb || is_truncate || !S_ISREG(inode->i_mode))
17273be5a52bSMiklos Szeredi 		i_size_write(inode, outarg.attr.size);
17283be5a52bSMiklos Szeredi 
17293be5a52bSMiklos Szeredi 	if (is_truncate) {
1730f15ecfefSKirill Tkhai 		/* NOTE: this may release/reacquire fi->lock */
17313be5a52bSMiklos Szeredi 		__fuse_release_nowrite(inode);
17323be5a52bSMiklos Szeredi 	}
1733f15ecfefSKirill Tkhai 	spin_unlock(&fi->lock);
17343be5a52bSMiklos Szeredi 
17353be5a52bSMiklos Szeredi 	/*
17363be5a52bSMiklos Szeredi 	 * Only call invalidate_inode_pages2() after removing
17373be5a52bSMiklos Szeredi 	 * FUSE_NOWRITE, otherwise fuse_launder_page() would deadlock.
17383be5a52bSMiklos Szeredi 	 */
17398373200bSPavel Emelyanov 	if ((is_truncate || !is_wb) &&
17408373200bSPavel Emelyanov 	    S_ISREG(inode->i_mode) && oldsize != outarg.attr.size) {
17417caef267SKirill A. Shutemov 		truncate_pagecache(inode, outarg.attr.size);
17423be5a52bSMiklos Szeredi 		invalidate_inode_pages2(inode->i_mapping);
17433be5a52bSMiklos Szeredi 	}
17443be5a52bSMiklos Szeredi 
174506a7c3c2SMaxim Patlasov 	clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
17466ae330caSVivek Goyal out:
17476ae330caSVivek Goyal 	if (fault_blocked)
17486ae330caSVivek Goyal 		up_write(&fi->i_mmap_sem);
17496ae330caSVivek Goyal 
1750e00d2c2dSMiklos Szeredi 	return 0;
17513be5a52bSMiklos Szeredi 
17523be5a52bSMiklos Szeredi error:
17533be5a52bSMiklos Szeredi 	if (is_truncate)
17543be5a52bSMiklos Szeredi 		fuse_release_nowrite(inode);
17553be5a52bSMiklos Szeredi 
175606a7c3c2SMaxim Patlasov 	clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
17576ae330caSVivek Goyal 
17586ae330caSVivek Goyal 	if (fault_blocked)
17596ae330caSVivek Goyal 		up_write(&fi->i_mmap_sem);
17603be5a52bSMiklos Szeredi 	return err;
17619e6268dbSMiklos Szeredi }
17629e6268dbSMiklos Szeredi 
1763549c7297SChristian Brauner static int fuse_setattr(struct user_namespace *mnt_userns, struct dentry *entry,
1764549c7297SChristian Brauner 			struct iattr *attr)
176549d4914fSMiklos Szeredi {
17662b0143b5SDavid Howells 	struct inode *inode = d_inode(entry);
17675e940c1dSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
1768a09f99edSMiklos Szeredi 	struct file *file = (attr->ia_valid & ATTR_FILE) ? attr->ia_file : NULL;
17695e2b8828SMiklos Szeredi 	int ret;
1770efb9fa9eSMaxim Patlasov 
17715d069dbeSMiklos Szeredi 	if (fuse_is_bad(inode))
17725d069dbeSMiklos Szeredi 		return -EIO;
17735d069dbeSMiklos Szeredi 
1774efb9fa9eSMaxim Patlasov 	if (!fuse_allow_current_process(get_fuse_conn(inode)))
1775efb9fa9eSMaxim Patlasov 		return -EACCES;
1776efb9fa9eSMaxim Patlasov 
1777a09f99edSMiklos Szeredi 	if (attr->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) {
1778a09f99edSMiklos Szeredi 		attr->ia_valid &= ~(ATTR_KILL_SUID | ATTR_KILL_SGID |
1779a09f99edSMiklos Szeredi 				    ATTR_MODE);
17805e940c1dSMiklos Szeredi 
1781a09f99edSMiklos Szeredi 		/*
17825e940c1dSMiklos Szeredi 		 * The only sane way to reliably kill suid/sgid is to do it in
17835e940c1dSMiklos Szeredi 		 * the userspace filesystem
17845e940c1dSMiklos Szeredi 		 *
17855e940c1dSMiklos Szeredi 		 * This should be done on write(), truncate() and chown().
17865e940c1dSMiklos Szeredi 		 */
17878981bdfdSVivek Goyal 		if (!fc->handle_killpriv && !fc->handle_killpriv_v2) {
17885e940c1dSMiklos Szeredi 			/*
17895e940c1dSMiklos Szeredi 			 * ia_mode calculation may have used stale i_mode.
17905e940c1dSMiklos Szeredi 			 * Refresh and recalculate.
1791a09f99edSMiklos Szeredi 			 */
1792a09f99edSMiklos Szeredi 			ret = fuse_do_getattr(inode, NULL, file);
1793a09f99edSMiklos Szeredi 			if (ret)
1794a09f99edSMiklos Szeredi 				return ret;
1795a09f99edSMiklos Szeredi 
1796a09f99edSMiklos Szeredi 			attr->ia_mode = inode->i_mode;
1797c01638f5SMiklos Szeredi 			if (inode->i_mode & S_ISUID) {
1798a09f99edSMiklos Szeredi 				attr->ia_valid |= ATTR_MODE;
1799a09f99edSMiklos Szeredi 				attr->ia_mode &= ~S_ISUID;
1800a09f99edSMiklos Szeredi 			}
1801c01638f5SMiklos Szeredi 			if ((inode->i_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
1802a09f99edSMiklos Szeredi 				attr->ia_valid |= ATTR_MODE;
1803a09f99edSMiklos Szeredi 				attr->ia_mode &= ~S_ISGID;
1804a09f99edSMiklos Szeredi 			}
1805a09f99edSMiklos Szeredi 		}
18065e940c1dSMiklos Szeredi 	}
1807a09f99edSMiklos Szeredi 	if (!attr->ia_valid)
1808a09f99edSMiklos Szeredi 		return 0;
1809a09f99edSMiklos Szeredi 
1810abb5a14fSLinus Torvalds 	ret = fuse_do_setattr(entry, attr, file);
18115e2b8828SMiklos Szeredi 	if (!ret) {
181260bcc88aSSeth Forshee 		/*
181360bcc88aSSeth Forshee 		 * If filesystem supports acls it may have updated acl xattrs in
181460bcc88aSSeth Forshee 		 * the filesystem, so forget cached acls for the inode.
181560bcc88aSSeth Forshee 		 */
181660bcc88aSSeth Forshee 		if (fc->posix_acl)
181760bcc88aSSeth Forshee 			forget_all_cached_acls(inode);
181860bcc88aSSeth Forshee 
18195e2b8828SMiklos Szeredi 		/* Directory mode changed, may need to revalidate access */
18205e2b8828SMiklos Szeredi 		if (d_is_dir(entry) && (attr->ia_valid & ATTR_MODE))
18215e2b8828SMiklos Szeredi 			fuse_invalidate_entry_cache(entry);
18225e2b8828SMiklos Szeredi 	}
18235e2b8828SMiklos Szeredi 	return ret;
182449d4914fSMiklos Szeredi }
182549d4914fSMiklos Szeredi 
1826549c7297SChristian Brauner static int fuse_getattr(struct user_namespace *mnt_userns,
1827549c7297SChristian Brauner 			const struct path *path, struct kstat *stat,
1828a528d35eSDavid Howells 			u32 request_mask, unsigned int flags)
1829e5e5558eSMiklos Szeredi {
1830a528d35eSDavid Howells 	struct inode *inode = d_inode(path->dentry);
1831244f6385SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
1832244f6385SMiklos Szeredi 
18335d069dbeSMiklos Szeredi 	if (fuse_is_bad(inode))
18345d069dbeSMiklos Szeredi 		return -EIO;
18355d069dbeSMiklos Szeredi 
18365157da2cSMiklos Szeredi 	if (!fuse_allow_current_process(fc)) {
18375157da2cSMiklos Szeredi 		if (!request_mask) {
18385157da2cSMiklos Szeredi 			/*
18395157da2cSMiklos Szeredi 			 * If user explicitly requested *nothing* then don't
18405157da2cSMiklos Szeredi 			 * error out, but return st_dev only.
18415157da2cSMiklos Szeredi 			 */
18425157da2cSMiklos Szeredi 			stat->result_mask = 0;
18435157da2cSMiklos Szeredi 			stat->dev = inode->i_sb->s_dev;
18445157da2cSMiklos Szeredi 			return 0;
18455157da2cSMiklos Szeredi 		}
1846244f6385SMiklos Szeredi 		return -EACCES;
18475157da2cSMiklos Szeredi 	}
1848244f6385SMiklos Szeredi 
18492f1e8196SMiklos Szeredi 	return fuse_update_get_attr(inode, NULL, stat, request_mask, flags);
1850e5e5558eSMiklos Szeredi }
1851e5e5558eSMiklos Szeredi 
1852754661f1SArjan van de Ven static const struct inode_operations fuse_dir_inode_operations = {
1853e5e5558eSMiklos Szeredi 	.lookup		= fuse_lookup,
18549e6268dbSMiklos Szeredi 	.mkdir		= fuse_mkdir,
18559e6268dbSMiklos Szeredi 	.symlink	= fuse_symlink,
18569e6268dbSMiklos Szeredi 	.unlink		= fuse_unlink,
18579e6268dbSMiklos Szeredi 	.rmdir		= fuse_rmdir,
18582773bf00SMiklos Szeredi 	.rename		= fuse_rename2,
18599e6268dbSMiklos Szeredi 	.link		= fuse_link,
18609e6268dbSMiklos Szeredi 	.setattr	= fuse_setattr,
18619e6268dbSMiklos Szeredi 	.create		= fuse_create,
1862c8ccbe03SMiklos Szeredi 	.atomic_open	= fuse_atomic_open,
18639e6268dbSMiklos Szeredi 	.mknod		= fuse_mknod,
1864e5e5558eSMiklos Szeredi 	.permission	= fuse_permission,
1865e5e5558eSMiklos Szeredi 	.getattr	= fuse_getattr,
186692a8780eSMiklos Szeredi 	.listxattr	= fuse_listxattr,
186760bcc88aSSeth Forshee 	.get_acl	= fuse_get_acl,
186860bcc88aSSeth Forshee 	.set_acl	= fuse_set_acl,
1869*72227eacSMiklos Szeredi 	.fileattr_get	= fuse_fileattr_get,
1870*72227eacSMiklos Szeredi 	.fileattr_set	= fuse_fileattr_set,
1871e5e5558eSMiklos Szeredi };
1872e5e5558eSMiklos Szeredi 
18734b6f5d20SArjan van de Ven static const struct file_operations fuse_dir_operations = {
1874b6aeadedSMiklos Szeredi 	.llseek		= generic_file_llseek,
1875e5e5558eSMiklos Szeredi 	.read		= generic_read_dir,
1876d9b3dbdcSAl Viro 	.iterate_shared	= fuse_readdir,
1877e5e5558eSMiklos Szeredi 	.open		= fuse_dir_open,
1878e5e5558eSMiklos Szeredi 	.release	= fuse_dir_release,
187982547981SMiklos Szeredi 	.fsync		= fuse_dir_fsync,
1880b18da0c5SMiklos Szeredi 	.unlocked_ioctl	= fuse_dir_ioctl,
1881b18da0c5SMiklos Szeredi 	.compat_ioctl	= fuse_dir_compat_ioctl,
1882e5e5558eSMiklos Szeredi };
1883e5e5558eSMiklos Szeredi 
1884754661f1SArjan van de Ven static const struct inode_operations fuse_common_inode_operations = {
18859e6268dbSMiklos Szeredi 	.setattr	= fuse_setattr,
1886e5e5558eSMiklos Szeredi 	.permission	= fuse_permission,
1887e5e5558eSMiklos Szeredi 	.getattr	= fuse_getattr,
188892a8780eSMiklos Szeredi 	.listxattr	= fuse_listxattr,
188960bcc88aSSeth Forshee 	.get_acl	= fuse_get_acl,
189060bcc88aSSeth Forshee 	.set_acl	= fuse_set_acl,
1891*72227eacSMiklos Szeredi 	.fileattr_get	= fuse_fileattr_get,
1892*72227eacSMiklos Szeredi 	.fileattr_set	= fuse_fileattr_set,
1893e5e5558eSMiklos Szeredi };
1894e5e5558eSMiklos Szeredi 
1895754661f1SArjan van de Ven static const struct inode_operations fuse_symlink_inode_operations = {
18969e6268dbSMiklos Szeredi 	.setattr	= fuse_setattr,
18976b255391SAl Viro 	.get_link	= fuse_get_link,
1898e5e5558eSMiklos Szeredi 	.getattr	= fuse_getattr,
189992a8780eSMiklos Szeredi 	.listxattr	= fuse_listxattr,
1900e5e5558eSMiklos Szeredi };
1901e5e5558eSMiklos Szeredi 
1902e5e5558eSMiklos Szeredi void fuse_init_common(struct inode *inode)
1903e5e5558eSMiklos Szeredi {
1904e5e5558eSMiklos Szeredi 	inode->i_op = &fuse_common_inode_operations;
1905e5e5558eSMiklos Szeredi }
1906e5e5558eSMiklos Szeredi 
1907e5e5558eSMiklos Szeredi void fuse_init_dir(struct inode *inode)
1908e5e5558eSMiklos Szeredi {
1909ab2257e9SMiklos Szeredi 	struct fuse_inode *fi = get_fuse_inode(inode);
1910ab2257e9SMiklos Szeredi 
1911e5e5558eSMiklos Szeredi 	inode->i_op = &fuse_dir_inode_operations;
1912e5e5558eSMiklos Szeredi 	inode->i_fop = &fuse_dir_operations;
1913ab2257e9SMiklos Szeredi 
1914ab2257e9SMiklos Szeredi 	spin_lock_init(&fi->rdc.lock);
1915ab2257e9SMiklos Szeredi 	fi->rdc.cached = false;
1916ab2257e9SMiklos Szeredi 	fi->rdc.size = 0;
1917ab2257e9SMiklos Szeredi 	fi->rdc.pos = 0;
1918ab2257e9SMiklos Szeredi 	fi->rdc.version = 0;
1919e5e5558eSMiklos Szeredi }
1920e5e5558eSMiklos Szeredi 
19215571f1e6SDan Schatzberg static int fuse_symlink_readpage(struct file *null, struct page *page)
19225571f1e6SDan Schatzberg {
19235571f1e6SDan Schatzberg 	int err = fuse_readlink_page(page->mapping->host, page);
19245571f1e6SDan Schatzberg 
19255571f1e6SDan Schatzberg 	if (!err)
19265571f1e6SDan Schatzberg 		SetPageUptodate(page);
19275571f1e6SDan Schatzberg 
19285571f1e6SDan Schatzberg 	unlock_page(page);
19295571f1e6SDan Schatzberg 
19305571f1e6SDan Schatzberg 	return err;
19315571f1e6SDan Schatzberg }
19325571f1e6SDan Schatzberg 
19335571f1e6SDan Schatzberg static const struct address_space_operations fuse_symlink_aops = {
19345571f1e6SDan Schatzberg 	.readpage	= fuse_symlink_readpage,
19355571f1e6SDan Schatzberg };
19365571f1e6SDan Schatzberg 
1937e5e5558eSMiklos Szeredi void fuse_init_symlink(struct inode *inode)
1938e5e5558eSMiklos Szeredi {
1939e5e5558eSMiklos Szeredi 	inode->i_op = &fuse_symlink_inode_operations;
19405571f1e6SDan Schatzberg 	inode->i_data.a_ops = &fuse_symlink_aops;
19415571f1e6SDan Schatzberg 	inode_nohighmem(inode);
1942e5e5558eSMiklos Szeredi }
1943