xref: /openbmc/linux/fs/fuse/dir.c (revision 1e18bda8)
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>
13e5e5558eSMiklos Szeredi #include <linux/sched.h>
14e5e5558eSMiklos Szeredi #include <linux/namei.h>
1507e77dcaSMiklos Szeredi #include <linux/slab.h>
16e5e5558eSMiklos Szeredi 
178d3af7f3SAl Viro static bool fuse_use_readdirplus(struct inode *dir, struct dir_context *ctx)
184582a4abSFeng Shuo {
194582a4abSFeng Shuo 	struct fuse_conn *fc = get_fuse_conn(dir);
204582a4abSFeng Shuo 	struct fuse_inode *fi = get_fuse_inode(dir);
214582a4abSFeng Shuo 
224582a4abSFeng Shuo 	if (!fc->do_readdirplus)
234582a4abSFeng Shuo 		return false;
24634734b6SEric Wong 	if (!fc->readdirplus_auto)
25634734b6SEric Wong 		return true;
264582a4abSFeng Shuo 	if (test_and_clear_bit(FUSE_I_ADVISE_RDPLUS, &fi->state))
274582a4abSFeng Shuo 		return true;
288d3af7f3SAl Viro 	if (ctx->pos == 0)
294582a4abSFeng Shuo 		return true;
304582a4abSFeng Shuo 	return false;
314582a4abSFeng Shuo }
324582a4abSFeng Shuo 
334582a4abSFeng Shuo static void fuse_advise_use_readdirplus(struct inode *dir)
344582a4abSFeng Shuo {
354582a4abSFeng Shuo 	struct fuse_inode *fi = get_fuse_inode(dir);
364582a4abSFeng Shuo 
374582a4abSFeng Shuo 	set_bit(FUSE_I_ADVISE_RDPLUS, &fi->state);
384582a4abSFeng Shuo }
394582a4abSFeng Shuo 
400a0898cfSMiklos Szeredi #if BITS_PER_LONG >= 64
410a0898cfSMiklos Szeredi static inline void fuse_dentry_settime(struct dentry *entry, u64 time)
420a0898cfSMiklos Szeredi {
430a0898cfSMiklos Szeredi 	entry->d_time = time;
440a0898cfSMiklos Szeredi }
450a0898cfSMiklos Szeredi 
460a0898cfSMiklos Szeredi static inline u64 fuse_dentry_time(struct dentry *entry)
470a0898cfSMiklos Szeredi {
480a0898cfSMiklos Szeredi 	return entry->d_time;
490a0898cfSMiklos Szeredi }
500a0898cfSMiklos Szeredi #else
510a0898cfSMiklos Szeredi /*
520a0898cfSMiklos Szeredi  * On 32 bit archs store the high 32 bits of time in d_fsdata
530a0898cfSMiklos Szeredi  */
540a0898cfSMiklos Szeredi static void fuse_dentry_settime(struct dentry *entry, u64 time)
550a0898cfSMiklos Szeredi {
560a0898cfSMiklos Szeredi 	entry->d_time = time;
570a0898cfSMiklos Szeredi 	entry->d_fsdata = (void *) (unsigned long) (time >> 32);
580a0898cfSMiklos Szeredi }
590a0898cfSMiklos Szeredi 
600a0898cfSMiklos Szeredi static u64 fuse_dentry_time(struct dentry *entry)
610a0898cfSMiklos Szeredi {
620a0898cfSMiklos Szeredi 	return (u64) entry->d_time +
630a0898cfSMiklos Szeredi 		((u64) (unsigned long) entry->d_fsdata << 32);
640a0898cfSMiklos Szeredi }
650a0898cfSMiklos Szeredi #endif
660a0898cfSMiklos Szeredi 
676f9f1180SMiklos Szeredi /*
686f9f1180SMiklos Szeredi  * FUSE caches dentries and attributes with separate timeout.  The
696f9f1180SMiklos Szeredi  * time in jiffies until the dentry/attributes are valid is stored in
706f9f1180SMiklos Szeredi  * dentry->d_time and fuse_inode->i_time respectively.
716f9f1180SMiklos Szeredi  */
726f9f1180SMiklos Szeredi 
736f9f1180SMiklos Szeredi /*
746f9f1180SMiklos Szeredi  * Calculate the time in jiffies until a dentry/attributes are valid
756f9f1180SMiklos Szeredi  */
760a0898cfSMiklos Szeredi static u64 time_to_jiffies(unsigned long sec, unsigned long nsec)
77e5e5558eSMiklos Szeredi {
78685d16ddSMiklos Szeredi 	if (sec || nsec) {
79e5e5558eSMiklos Szeredi 		struct timespec ts = {sec, nsec};
800a0898cfSMiklos Szeredi 		return get_jiffies_64() + timespec_to_jiffies(&ts);
81685d16ddSMiklos Szeredi 	} else
820a0898cfSMiklos Szeredi 		return 0;
83e5e5558eSMiklos Szeredi }
84e5e5558eSMiklos Szeredi 
856f9f1180SMiklos Szeredi /*
866f9f1180SMiklos Szeredi  * Set dentry and possibly attribute timeouts from the lookup/mk*
876f9f1180SMiklos Szeredi  * replies
886f9f1180SMiklos Szeredi  */
891fb69e78SMiklos Szeredi static void fuse_change_entry_timeout(struct dentry *entry,
901fb69e78SMiklos Szeredi 				      struct fuse_entry_out *o)
910aa7c699SMiklos Szeredi {
920a0898cfSMiklos Szeredi 	fuse_dentry_settime(entry,
930a0898cfSMiklos Szeredi 		time_to_jiffies(o->entry_valid, o->entry_valid_nsec));
941fb69e78SMiklos Szeredi }
951fb69e78SMiklos Szeredi 
961fb69e78SMiklos Szeredi static u64 attr_timeout(struct fuse_attr_out *o)
971fb69e78SMiklos Szeredi {
981fb69e78SMiklos Szeredi 	return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
991fb69e78SMiklos Szeredi }
1001fb69e78SMiklos Szeredi 
1011fb69e78SMiklos Szeredi static u64 entry_attr_timeout(struct fuse_entry_out *o)
1021fb69e78SMiklos Szeredi {
1031fb69e78SMiklos Szeredi 	return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
1048cbdf1e6SMiklos Szeredi }
1058cbdf1e6SMiklos Szeredi 
1066f9f1180SMiklos Szeredi /*
1076f9f1180SMiklos Szeredi  * Mark the attributes as stale, so that at the next call to
1086f9f1180SMiklos Szeredi  * ->getattr() they will be fetched from userspace
1096f9f1180SMiklos Szeredi  */
1108cbdf1e6SMiklos Szeredi void fuse_invalidate_attr(struct inode *inode)
1118cbdf1e6SMiklos Szeredi {
1120a0898cfSMiklos Szeredi 	get_fuse_inode(inode)->i_time = 0;
1138cbdf1e6SMiklos Szeredi }
1148cbdf1e6SMiklos Szeredi 
115451418fcSAndrew Gallagher /**
116451418fcSAndrew Gallagher  * Mark the attributes as stale due to an atime change.  Avoid the invalidate if
117451418fcSAndrew Gallagher  * atime is not used.
118451418fcSAndrew Gallagher  */
119451418fcSAndrew Gallagher void fuse_invalidate_atime(struct inode *inode)
120451418fcSAndrew Gallagher {
121451418fcSAndrew Gallagher 	if (!IS_RDONLY(inode))
122451418fcSAndrew Gallagher 		fuse_invalidate_attr(inode);
123451418fcSAndrew Gallagher }
124451418fcSAndrew Gallagher 
1256f9f1180SMiklos Szeredi /*
1266f9f1180SMiklos Szeredi  * Just mark the entry as stale, so that a next attempt to look it up
1276f9f1180SMiklos Szeredi  * will result in a new lookup call to userspace
1286f9f1180SMiklos Szeredi  *
1296f9f1180SMiklos Szeredi  * This is called when a dentry is about to become negative and the
1306f9f1180SMiklos Szeredi  * timeout is unknown (unlink, rmdir, rename and in some cases
1316f9f1180SMiklos Szeredi  * lookup)
1326f9f1180SMiklos Szeredi  */
133dbd561d2SMiklos Szeredi void fuse_invalidate_entry_cache(struct dentry *entry)
1348cbdf1e6SMiklos Szeredi {
1350a0898cfSMiklos Szeredi 	fuse_dentry_settime(entry, 0);
1368cbdf1e6SMiklos Szeredi }
1378cbdf1e6SMiklos Szeredi 
1386f9f1180SMiklos Szeredi /*
1396f9f1180SMiklos Szeredi  * Same as fuse_invalidate_entry_cache(), but also try to remove the
1406f9f1180SMiklos Szeredi  * dentry from the hash
1416f9f1180SMiklos Szeredi  */
1428cbdf1e6SMiklos Szeredi static void fuse_invalidate_entry(struct dentry *entry)
1438cbdf1e6SMiklos Szeredi {
1448cbdf1e6SMiklos Szeredi 	d_invalidate(entry);
1458cbdf1e6SMiklos Szeredi 	fuse_invalidate_entry_cache(entry);
1460aa7c699SMiklos Szeredi }
1470aa7c699SMiklos Szeredi 
148c180eebeSMiklos Szeredi static void fuse_lookup_init(struct fuse_conn *fc, struct fuse_req *req,
149c180eebeSMiklos Szeredi 			     u64 nodeid, struct qstr *name,
150e5e5558eSMiklos Szeredi 			     struct fuse_entry_out *outarg)
151e5e5558eSMiklos Szeredi {
1520e9663eeSMiklos Szeredi 	memset(outarg, 0, sizeof(struct fuse_entry_out));
153e5e5558eSMiklos Szeredi 	req->in.h.opcode = FUSE_LOOKUP;
154c180eebeSMiklos Szeredi 	req->in.h.nodeid = nodeid;
155e5e5558eSMiklos Szeredi 	req->in.numargs = 1;
156c180eebeSMiklos Szeredi 	req->in.args[0].size = name->len + 1;
157c180eebeSMiklos Szeredi 	req->in.args[0].value = name->name;
158e5e5558eSMiklos Szeredi 	req->out.numargs = 1;
1590e9663eeSMiklos Szeredi 	if (fc->minor < 9)
1600e9663eeSMiklos Szeredi 		req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
1610e9663eeSMiklos Szeredi 	else
162e5e5558eSMiklos Szeredi 		req->out.args[0].size = sizeof(struct fuse_entry_out);
163e5e5558eSMiklos Szeredi 	req->out.args[0].value = outarg;
164e5e5558eSMiklos Szeredi }
165e5e5558eSMiklos Szeredi 
1665c5c5e51SMiklos Szeredi u64 fuse_get_attr_version(struct fuse_conn *fc)
1677dca9fd3SMiklos Szeredi {
1687dca9fd3SMiklos Szeredi 	u64 curr_version;
1697dca9fd3SMiklos Szeredi 
1707dca9fd3SMiklos Szeredi 	/*
1717dca9fd3SMiklos Szeredi 	 * The spin lock isn't actually needed on 64bit archs, but we
1727dca9fd3SMiklos Szeredi 	 * don't yet care too much about such optimizations.
1737dca9fd3SMiklos Szeredi 	 */
1747dca9fd3SMiklos Szeredi 	spin_lock(&fc->lock);
1757dca9fd3SMiklos Szeredi 	curr_version = fc->attr_version;
1767dca9fd3SMiklos Szeredi 	spin_unlock(&fc->lock);
1777dca9fd3SMiklos Szeredi 
1787dca9fd3SMiklos Szeredi 	return curr_version;
1797dca9fd3SMiklos Szeredi }
1807dca9fd3SMiklos Szeredi 
1816f9f1180SMiklos Szeredi /*
1826f9f1180SMiklos Szeredi  * Check whether the dentry is still valid
1836f9f1180SMiklos Szeredi  *
1846f9f1180SMiklos Szeredi  * If the entry validity timeout has expired and the dentry is
1856f9f1180SMiklos Szeredi  * positive, try to redo the lookup.  If the lookup results in a
1866f9f1180SMiklos Szeredi  * different inode, then let the VFS invalidate the dentry and redo
1876f9f1180SMiklos Szeredi  * the lookup once more.  If the lookup results in the same inode,
1886f9f1180SMiklos Szeredi  * then refresh the attributes, timeouts and mark the dentry valid.
1896f9f1180SMiklos Szeredi  */
1900b728e19SAl Viro static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
191e5e5558eSMiklos Szeredi {
19234286d66SNick Piggin 	struct inode *inode;
19328420dadSMiklos Szeredi 	struct dentry *parent;
19428420dadSMiklos Szeredi 	struct fuse_conn *fc;
1956314efeeSMiklos Szeredi 	struct fuse_inode *fi;
196e2a6b952SMiklos Szeredi 	int ret;
1978cbdf1e6SMiklos Szeredi 
198e7c0a167SMiklos Szeredi 	inode = ACCESS_ONCE(entry->d_inode);
1998cbdf1e6SMiklos Szeredi 	if (inode && is_bad_inode(inode))
200e2a6b952SMiklos Szeredi 		goto invalid;
2010a0898cfSMiklos Szeredi 	else if (fuse_dentry_time(entry) < get_jiffies_64()) {
202e5e5558eSMiklos Szeredi 		int err;
203e5e5558eSMiklos Szeredi 		struct fuse_entry_out outarg;
2048cbdf1e6SMiklos Szeredi 		struct fuse_req *req;
20507e77dcaSMiklos Szeredi 		struct fuse_forget_link *forget;
2061fb69e78SMiklos Szeredi 		u64 attr_version;
2078cbdf1e6SMiklos Szeredi 
20850322fe7SMiklos Szeredi 		/* For negative dentries, always do a fresh lookup */
2098cbdf1e6SMiklos Szeredi 		if (!inode)
210e2a6b952SMiklos Szeredi 			goto invalid;
2118cbdf1e6SMiklos Szeredi 
212e2a6b952SMiklos Szeredi 		ret = -ECHILD;
2130b728e19SAl Viro 		if (flags & LOOKUP_RCU)
214e2a6b952SMiklos Szeredi 			goto out;
215e7c0a167SMiklos Szeredi 
2168cbdf1e6SMiklos Szeredi 		fc = get_fuse_conn(inode);
217b111c8c0SMaxim Patlasov 		req = fuse_get_req_nopages(fc);
218e2a6b952SMiklos Szeredi 		ret = PTR_ERR(req);
219ce1d5a49SMiklos Szeredi 		if (IS_ERR(req))
220e2a6b952SMiklos Szeredi 			goto out;
221e5e5558eSMiklos Szeredi 
22207e77dcaSMiklos Szeredi 		forget = fuse_alloc_forget();
22307e77dcaSMiklos Szeredi 		if (!forget) {
2242d51013eSMiklos Szeredi 			fuse_put_request(fc, req);
225e2a6b952SMiklos Szeredi 			ret = -ENOMEM;
226e2a6b952SMiklos Szeredi 			goto out;
2272d51013eSMiklos Szeredi 		}
2282d51013eSMiklos Szeredi 
2297dca9fd3SMiklos Szeredi 		attr_version = fuse_get_attr_version(fc);
2301fb69e78SMiklos Szeredi 
231e956edd0SMiklos Szeredi 		parent = dget_parent(entry);
232c180eebeSMiklos Szeredi 		fuse_lookup_init(fc, req, get_node_id(parent->d_inode),
233c180eebeSMiklos Szeredi 				 &entry->d_name, &outarg);
234b93f858aSTejun Heo 		fuse_request_send(fc, req);
235e956edd0SMiklos Szeredi 		dput(parent);
236e5e5558eSMiklos Szeredi 		err = req->out.h.error;
2372d51013eSMiklos Szeredi 		fuse_put_request(fc, req);
23850322fe7SMiklos Szeredi 		/* Zero nodeid is same as -ENOENT */
23950322fe7SMiklos Szeredi 		if (!err && !outarg.nodeid)
24050322fe7SMiklos Szeredi 			err = -ENOENT;
2419e6268dbSMiklos Szeredi 		if (!err) {
2426314efeeSMiklos Szeredi 			fi = get_fuse_inode(inode);
2439e6268dbSMiklos Szeredi 			if (outarg.nodeid != get_node_id(inode)) {
24407e77dcaSMiklos Szeredi 				fuse_queue_forget(fc, forget, outarg.nodeid, 1);
245e2a6b952SMiklos Szeredi 				goto invalid;
2469e6268dbSMiklos Szeredi 			}
2478da5ff23SMiklos Szeredi 			spin_lock(&fc->lock);
2489e6268dbSMiklos Szeredi 			fi->nlookup++;
2498da5ff23SMiklos Szeredi 			spin_unlock(&fc->lock);
2509e6268dbSMiklos Szeredi 		}
25107e77dcaSMiklos Szeredi 		kfree(forget);
2529e6268dbSMiklos Szeredi 		if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
253e2a6b952SMiklos Szeredi 			goto invalid;
254e5e5558eSMiklos Szeredi 
2551fb69e78SMiklos Szeredi 		fuse_change_attributes(inode, &outarg.attr,
2561fb69e78SMiklos Szeredi 				       entry_attr_timeout(&outarg),
2571fb69e78SMiklos Szeredi 				       attr_version);
2581fb69e78SMiklos Szeredi 		fuse_change_entry_timeout(entry, &outarg);
25928420dadSMiklos Szeredi 	} else if (inode) {
2606314efeeSMiklos Szeredi 		fi = get_fuse_inode(inode);
2616314efeeSMiklos Szeredi 		if (flags & LOOKUP_RCU) {
2626314efeeSMiklos Szeredi 			if (test_bit(FUSE_I_INIT_RDPLUS, &fi->state))
2636314efeeSMiklos Szeredi 				return -ECHILD;
2646314efeeSMiklos Szeredi 		} else if (test_and_clear_bit(FUSE_I_INIT_RDPLUS, &fi->state)) {
26528420dadSMiklos Szeredi 			parent = dget_parent(entry);
26628420dadSMiklos Szeredi 			fuse_advise_use_readdirplus(parent->d_inode);
26728420dadSMiklos Szeredi 			dput(parent);
268e5e5558eSMiklos Szeredi 		}
26928420dadSMiklos Szeredi 	}
270e2a6b952SMiklos Szeredi 	ret = 1;
271e2a6b952SMiklos Szeredi out:
272e2a6b952SMiklos Szeredi 	return ret;
273e2a6b952SMiklos Szeredi 
274e2a6b952SMiklos Szeredi invalid:
275e2a6b952SMiklos Szeredi 	ret = 0;
2763c70b8eeSMiklos Szeredi 
2773c70b8eeSMiklos Szeredi 	if (!(flags & LOOKUP_RCU) && check_submounts_and_drop(entry) != 0)
27846ea1562SAnand Avati 		ret = 1;
279e2a6b952SMiklos Szeredi 	goto out;
280e5e5558eSMiklos Szeredi }
281e5e5558eSMiklos Szeredi 
2828bfc016dSMiklos Szeredi static int invalid_nodeid(u64 nodeid)
2832827d0b2SMiklos Szeredi {
2842827d0b2SMiklos Szeredi 	return !nodeid || nodeid == FUSE_ROOT_ID;
2852827d0b2SMiklos Szeredi }
2862827d0b2SMiklos Szeredi 
2874269590aSAl Viro const struct dentry_operations fuse_dentry_operations = {
288e5e5558eSMiklos Szeredi 	.d_revalidate	= fuse_dentry_revalidate,
289e5e5558eSMiklos Szeredi };
290e5e5558eSMiklos Szeredi 
291a5bfffacSTimo Savola int fuse_valid_type(int m)
29239ee059aSMiklos Szeredi {
29339ee059aSMiklos Szeredi 	return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) ||
29439ee059aSMiklos Szeredi 		S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
29539ee059aSMiklos Szeredi }
29639ee059aSMiklos Szeredi 
297c180eebeSMiklos Szeredi int fuse_lookup_name(struct super_block *sb, u64 nodeid, struct qstr *name,
298c180eebeSMiklos Szeredi 		     struct fuse_entry_out *outarg, struct inode **inode)
299c180eebeSMiklos Szeredi {
300c180eebeSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn_super(sb);
301c180eebeSMiklos Szeredi 	struct fuse_req *req;
30207e77dcaSMiklos Szeredi 	struct fuse_forget_link *forget;
303c180eebeSMiklos Szeredi 	u64 attr_version;
304c180eebeSMiklos Szeredi 	int err;
305c180eebeSMiklos Szeredi 
306c180eebeSMiklos Szeredi 	*inode = NULL;
307c180eebeSMiklos Szeredi 	err = -ENAMETOOLONG;
308c180eebeSMiklos Szeredi 	if (name->len > FUSE_NAME_MAX)
309c180eebeSMiklos Szeredi 		goto out;
310c180eebeSMiklos Szeredi 
311b111c8c0SMaxim Patlasov 	req = fuse_get_req_nopages(fc);
312c180eebeSMiklos Szeredi 	err = PTR_ERR(req);
313c180eebeSMiklos Szeredi 	if (IS_ERR(req))
314c180eebeSMiklos Szeredi 		goto out;
315c180eebeSMiklos Szeredi 
31607e77dcaSMiklos Szeredi 	forget = fuse_alloc_forget();
31707e77dcaSMiklos Szeredi 	err = -ENOMEM;
31807e77dcaSMiklos Szeredi 	if (!forget) {
319c180eebeSMiklos Szeredi 		fuse_put_request(fc, req);
320c180eebeSMiklos Szeredi 		goto out;
321c180eebeSMiklos Szeredi 	}
322c180eebeSMiklos Szeredi 
323c180eebeSMiklos Szeredi 	attr_version = fuse_get_attr_version(fc);
324c180eebeSMiklos Szeredi 
325c180eebeSMiklos Szeredi 	fuse_lookup_init(fc, req, nodeid, name, outarg);
326b93f858aSTejun Heo 	fuse_request_send(fc, req);
327c180eebeSMiklos Szeredi 	err = req->out.h.error;
328c180eebeSMiklos Szeredi 	fuse_put_request(fc, req);
329c180eebeSMiklos Szeredi 	/* Zero nodeid is same as -ENOENT, but with valid timeout */
330c180eebeSMiklos Szeredi 	if (err || !outarg->nodeid)
331c180eebeSMiklos Szeredi 		goto out_put_forget;
332c180eebeSMiklos Szeredi 
333c180eebeSMiklos Szeredi 	err = -EIO;
334c180eebeSMiklos Szeredi 	if (!outarg->nodeid)
335c180eebeSMiklos Szeredi 		goto out_put_forget;
336c180eebeSMiklos Szeredi 	if (!fuse_valid_type(outarg->attr.mode))
337c180eebeSMiklos Szeredi 		goto out_put_forget;
338c180eebeSMiklos Szeredi 
339c180eebeSMiklos Szeredi 	*inode = fuse_iget(sb, outarg->nodeid, outarg->generation,
340c180eebeSMiklos Szeredi 			   &outarg->attr, entry_attr_timeout(outarg),
341c180eebeSMiklos Szeredi 			   attr_version);
342c180eebeSMiklos Szeredi 	err = -ENOMEM;
343c180eebeSMiklos Szeredi 	if (!*inode) {
34407e77dcaSMiklos Szeredi 		fuse_queue_forget(fc, forget, outarg->nodeid, 1);
345c180eebeSMiklos Szeredi 		goto out;
346c180eebeSMiklos Szeredi 	}
347c180eebeSMiklos Szeredi 	err = 0;
348c180eebeSMiklos Szeredi 
349c180eebeSMiklos Szeredi  out_put_forget:
35007e77dcaSMiklos Szeredi 	kfree(forget);
351c180eebeSMiklos Szeredi  out:
352c180eebeSMiklos Szeredi 	return err;
353c180eebeSMiklos Szeredi }
354c180eebeSMiklos Szeredi 
3550aa7c699SMiklos Szeredi static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
35600cd8dd3SAl Viro 				  unsigned int flags)
357e5e5558eSMiklos Szeredi {
358e5e5558eSMiklos Szeredi 	int err;
359e5e5558eSMiklos Szeredi 	struct fuse_entry_out outarg;
360c180eebeSMiklos Szeredi 	struct inode *inode;
3610de6256dSMiklos Szeredi 	struct dentry *newent;
362c180eebeSMiklos Szeredi 	bool outarg_valid = true;
363e5e5558eSMiklos Szeredi 
364c180eebeSMiklos Szeredi 	err = fuse_lookup_name(dir->i_sb, get_node_id(dir), &entry->d_name,
365c180eebeSMiklos Szeredi 			       &outarg, &inode);
366c180eebeSMiklos Szeredi 	if (err == -ENOENT) {
367c180eebeSMiklos Szeredi 		outarg_valid = false;
368c180eebeSMiklos Szeredi 		err = 0;
3692d51013eSMiklos Szeredi 	}
370c180eebeSMiklos Szeredi 	if (err)
371c180eebeSMiklos Szeredi 		goto out_err;
3722d51013eSMiklos Szeredi 
373ee4e5271SMiklos Szeredi 	err = -EIO;
374c180eebeSMiklos Szeredi 	if (inode && get_node_id(inode) == FUSE_ROOT_ID)
375c180eebeSMiklos Szeredi 		goto out_iput;
376e5e5558eSMiklos Szeredi 
377b70a80e7SMiklos Szeredi 	newent = d_materialise_unique(entry, inode);
378c180eebeSMiklos Szeredi 	err = PTR_ERR(newent);
379c180eebeSMiklos Szeredi 	if (IS_ERR(newent))
3805835f339SMiklos Szeredi 		goto out_err;
381d2a85164SMiklos Szeredi 
3820de6256dSMiklos Szeredi 	entry = newent ? newent : entry;
383c180eebeSMiklos Szeredi 	if (outarg_valid)
3841fb69e78SMiklos Szeredi 		fuse_change_entry_timeout(entry, &outarg);
3858cbdf1e6SMiklos Szeredi 	else
3868cbdf1e6SMiklos Szeredi 		fuse_invalidate_entry_cache(entry);
387c180eebeSMiklos Szeredi 
3884582a4abSFeng Shuo 	fuse_advise_use_readdirplus(dir);
3890de6256dSMiklos Szeredi 	return newent;
390c180eebeSMiklos Szeredi 
391c180eebeSMiklos Szeredi  out_iput:
392c180eebeSMiklos Szeredi 	iput(inode);
393c180eebeSMiklos Szeredi  out_err:
394c180eebeSMiklos Szeredi 	return ERR_PTR(err);
395e5e5558eSMiklos Szeredi }
396e5e5558eSMiklos Szeredi 
3976f9f1180SMiklos Szeredi /*
3986f9f1180SMiklos Szeredi  * Atomic create+open operation
3996f9f1180SMiklos Szeredi  *
4006f9f1180SMiklos Szeredi  * If the filesystem doesn't support this, then fall back to separate
4016f9f1180SMiklos Szeredi  * 'mknod' + 'open' requests.
4026f9f1180SMiklos Szeredi  */
403d9585277SAl Viro static int fuse_create_open(struct inode *dir, struct dentry *entry,
40430d90494SAl Viro 			    struct file *file, unsigned flags,
40547237687SAl Viro 			    umode_t mode, int *opened)
406fd72faacSMiklos Szeredi {
407fd72faacSMiklos Szeredi 	int err;
408fd72faacSMiklos Szeredi 	struct inode *inode;
409fd72faacSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
410fd72faacSMiklos Szeredi 	struct fuse_req *req;
41107e77dcaSMiklos Szeredi 	struct fuse_forget_link *forget;
412e0a43ddcSMiklos Szeredi 	struct fuse_create_in inarg;
413fd72faacSMiklos Szeredi 	struct fuse_open_out outopen;
414fd72faacSMiklos Szeredi 	struct fuse_entry_out outentry;
415fd72faacSMiklos Szeredi 	struct fuse_file *ff;
416fd72faacSMiklos Szeredi 
417af109bcaSMiklos Szeredi 	/* Userspace expects S_IFREG in create mode */
418af109bcaSMiklos Szeredi 	BUG_ON((mode & S_IFMT) != S_IFREG);
419af109bcaSMiklos Szeredi 
42007e77dcaSMiklos Szeredi 	forget = fuse_alloc_forget();
421c8ccbe03SMiklos Szeredi 	err = -ENOMEM;
42207e77dcaSMiklos Szeredi 	if (!forget)
423c8ccbe03SMiklos Szeredi 		goto out_err;
42451eb01e7SMiklos Szeredi 
425b111c8c0SMaxim Patlasov 	req = fuse_get_req_nopages(fc);
42651eb01e7SMiklos Szeredi 	err = PTR_ERR(req);
427ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
42851eb01e7SMiklos Szeredi 		goto out_put_forget_req;
429fd72faacSMiklos Szeredi 
430ce1d5a49SMiklos Szeredi 	err = -ENOMEM;
431acf99433STejun Heo 	ff = fuse_file_alloc(fc);
432fd72faacSMiklos Szeredi 	if (!ff)
433fd72faacSMiklos Szeredi 		goto out_put_request;
434fd72faacSMiklos Szeredi 
435e0a43ddcSMiklos Szeredi 	if (!fc->dont_mask)
436e0a43ddcSMiklos Szeredi 		mode &= ~current_umask();
437e0a43ddcSMiklos Szeredi 
438fd72faacSMiklos Szeredi 	flags &= ~O_NOCTTY;
439fd72faacSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
4400e9663eeSMiklos Szeredi 	memset(&outentry, 0, sizeof(outentry));
441fd72faacSMiklos Szeredi 	inarg.flags = flags;
442fd72faacSMiklos Szeredi 	inarg.mode = mode;
443e0a43ddcSMiklos Szeredi 	inarg.umask = current_umask();
444fd72faacSMiklos Szeredi 	req->in.h.opcode = FUSE_CREATE;
445fd72faacSMiklos Szeredi 	req->in.h.nodeid = get_node_id(dir);
446fd72faacSMiklos Szeredi 	req->in.numargs = 2;
447e0a43ddcSMiklos Szeredi 	req->in.args[0].size = fc->minor < 12 ? sizeof(struct fuse_open_in) :
448e0a43ddcSMiklos Szeredi 						sizeof(inarg);
449fd72faacSMiklos Szeredi 	req->in.args[0].value = &inarg;
450fd72faacSMiklos Szeredi 	req->in.args[1].size = entry->d_name.len + 1;
451fd72faacSMiklos Szeredi 	req->in.args[1].value = entry->d_name.name;
452fd72faacSMiklos Szeredi 	req->out.numargs = 2;
4530e9663eeSMiklos Szeredi 	if (fc->minor < 9)
4540e9663eeSMiklos Szeredi 		req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
4550e9663eeSMiklos Szeredi 	else
456fd72faacSMiklos Szeredi 		req->out.args[0].size = sizeof(outentry);
457fd72faacSMiklos Szeredi 	req->out.args[0].value = &outentry;
458fd72faacSMiklos Szeredi 	req->out.args[1].size = sizeof(outopen);
459fd72faacSMiklos Szeredi 	req->out.args[1].value = &outopen;
460b93f858aSTejun Heo 	fuse_request_send(fc, req);
461fd72faacSMiklos Szeredi 	err = req->out.h.error;
462c8ccbe03SMiklos Szeredi 	if (err)
463fd72faacSMiklos Szeredi 		goto out_free_ff;
464fd72faacSMiklos Szeredi 
465fd72faacSMiklos Szeredi 	err = -EIO;
4662827d0b2SMiklos Szeredi 	if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid))
467fd72faacSMiklos Szeredi 		goto out_free_ff;
468fd72faacSMiklos Szeredi 
46951eb01e7SMiklos Szeredi 	fuse_put_request(fc, req);
470c7b7143cSMiklos Szeredi 	ff->fh = outopen.fh;
471c7b7143cSMiklos Szeredi 	ff->nodeid = outentry.nodeid;
472c7b7143cSMiklos Szeredi 	ff->open_flags = outopen.open_flags;
473fd72faacSMiklos Szeredi 	inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
4741fb69e78SMiklos Szeredi 			  &outentry.attr, entry_attr_timeout(&outentry), 0);
475fd72faacSMiklos Szeredi 	if (!inode) {
476fd72faacSMiklos Szeredi 		flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
4778b0797a4SMiklos Szeredi 		fuse_sync_release(ff, flags);
47807e77dcaSMiklos Szeredi 		fuse_queue_forget(fc, forget, outentry.nodeid, 1);
479c8ccbe03SMiklos Szeredi 		err = -ENOMEM;
480c8ccbe03SMiklos Szeredi 		goto out_err;
481fd72faacSMiklos Szeredi 	}
48207e77dcaSMiklos Szeredi 	kfree(forget);
483fd72faacSMiklos Szeredi 	d_instantiate(entry, inode);
4841fb69e78SMiklos Szeredi 	fuse_change_entry_timeout(entry, &outentry);
4850952b2a4SMiklos Szeredi 	fuse_invalidate_attr(dir);
48630d90494SAl Viro 	err = finish_open(file, entry, generic_file_open, opened);
48730d90494SAl Viro 	if (err) {
4888b0797a4SMiklos Szeredi 		fuse_sync_release(ff, flags);
489c8ccbe03SMiklos Szeredi 	} else {
490c7b7143cSMiklos Szeredi 		file->private_data = fuse_file_get(ff);
491c7b7143cSMiklos Szeredi 		fuse_finish_open(inode, file);
492c8ccbe03SMiklos Szeredi 	}
493d9585277SAl Viro 	return err;
494fd72faacSMiklos Szeredi 
495fd72faacSMiklos Szeredi out_free_ff:
496fd72faacSMiklos Szeredi 	fuse_file_free(ff);
497fd72faacSMiklos Szeredi out_put_request:
498fd72faacSMiklos Szeredi 	fuse_put_request(fc, req);
49951eb01e7SMiklos Szeredi out_put_forget_req:
50007e77dcaSMiklos Szeredi 	kfree(forget);
501c8ccbe03SMiklos Szeredi out_err:
502d9585277SAl Viro 	return err;
503c8ccbe03SMiklos Szeredi }
504c8ccbe03SMiklos Szeredi 
505c8ccbe03SMiklos Szeredi static int fuse_mknod(struct inode *, struct dentry *, umode_t, dev_t);
506d9585277SAl Viro static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
50730d90494SAl Viro 			    struct file *file, unsigned flags,
50847237687SAl Viro 			    umode_t mode, int *opened)
509c8ccbe03SMiklos Szeredi {
510c8ccbe03SMiklos Szeredi 	int err;
511c8ccbe03SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
512c8ccbe03SMiklos Szeredi 	struct dentry *res = NULL;
513c8ccbe03SMiklos Szeredi 
514c8ccbe03SMiklos Szeredi 	if (d_unhashed(entry)) {
51500cd8dd3SAl Viro 		res = fuse_lookup(dir, entry, 0);
516c8ccbe03SMiklos Szeredi 		if (IS_ERR(res))
517d9585277SAl Viro 			return PTR_ERR(res);
518c8ccbe03SMiklos Szeredi 
519c8ccbe03SMiklos Szeredi 		if (res)
520c8ccbe03SMiklos Szeredi 			entry = res;
521c8ccbe03SMiklos Szeredi 	}
522c8ccbe03SMiklos Szeredi 
523c8ccbe03SMiklos Szeredi 	if (!(flags & O_CREAT) || entry->d_inode)
524c8ccbe03SMiklos Szeredi 		goto no_open;
525c8ccbe03SMiklos Szeredi 
526c8ccbe03SMiklos Szeredi 	/* Only creates */
52747237687SAl Viro 	*opened |= FILE_CREATED;
528c8ccbe03SMiklos Szeredi 
529c8ccbe03SMiklos Szeredi 	if (fc->no_create)
530c8ccbe03SMiklos Szeredi 		goto mknod;
531c8ccbe03SMiklos Szeredi 
53230d90494SAl Viro 	err = fuse_create_open(dir, entry, file, flags, mode, opened);
533d9585277SAl Viro 	if (err == -ENOSYS) {
534c8ccbe03SMiklos Szeredi 		fc->no_create = 1;
535c8ccbe03SMiklos Szeredi 		goto mknod;
536c8ccbe03SMiklos Szeredi 	}
537c8ccbe03SMiklos Szeredi out_dput:
538c8ccbe03SMiklos Szeredi 	dput(res);
539d9585277SAl Viro 	return err;
540c8ccbe03SMiklos Szeredi 
541c8ccbe03SMiklos Szeredi mknod:
542c8ccbe03SMiklos Szeredi 	err = fuse_mknod(dir, entry, mode, 0);
543d9585277SAl Viro 	if (err)
544c8ccbe03SMiklos Szeredi 		goto out_dput;
545c8ccbe03SMiklos Szeredi no_open:
546e45198a6SAl Viro 	return finish_no_open(file, res);
547fd72faacSMiklos Szeredi }
548fd72faacSMiklos Szeredi 
5496f9f1180SMiklos Szeredi /*
5506f9f1180SMiklos Szeredi  * Code shared between mknod, mkdir, symlink and link
5516f9f1180SMiklos Szeredi  */
5529e6268dbSMiklos Szeredi static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
5539e6268dbSMiklos Szeredi 			    struct inode *dir, struct dentry *entry,
554541af6a0SAl Viro 			    umode_t mode)
5559e6268dbSMiklos Szeredi {
5569e6268dbSMiklos Szeredi 	struct fuse_entry_out outarg;
5579e6268dbSMiklos Szeredi 	struct inode *inode;
5589e6268dbSMiklos Szeredi 	int err;
55907e77dcaSMiklos Szeredi 	struct fuse_forget_link *forget;
5602d51013eSMiklos Szeredi 
56107e77dcaSMiklos Szeredi 	forget = fuse_alloc_forget();
56207e77dcaSMiklos Szeredi 	if (!forget) {
5632d51013eSMiklos Szeredi 		fuse_put_request(fc, req);
56407e77dcaSMiklos Szeredi 		return -ENOMEM;
5652d51013eSMiklos Szeredi 	}
5669e6268dbSMiklos Szeredi 
5670e9663eeSMiklos Szeredi 	memset(&outarg, 0, sizeof(outarg));
5689e6268dbSMiklos Szeredi 	req->in.h.nodeid = get_node_id(dir);
5699e6268dbSMiklos Szeredi 	req->out.numargs = 1;
5700e9663eeSMiklos Szeredi 	if (fc->minor < 9)
5710e9663eeSMiklos Szeredi 		req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
5720e9663eeSMiklos Szeredi 	else
5739e6268dbSMiklos Szeredi 		req->out.args[0].size = sizeof(outarg);
5749e6268dbSMiklos Szeredi 	req->out.args[0].value = &outarg;
575b93f858aSTejun Heo 	fuse_request_send(fc, req);
5769e6268dbSMiklos Szeredi 	err = req->out.h.error;
5779e6268dbSMiklos Szeredi 	fuse_put_request(fc, req);
5782d51013eSMiklos Szeredi 	if (err)
5792d51013eSMiklos Szeredi 		goto out_put_forget_req;
5802d51013eSMiklos Szeredi 
58139ee059aSMiklos Szeredi 	err = -EIO;
58239ee059aSMiklos Szeredi 	if (invalid_nodeid(outarg.nodeid))
5832d51013eSMiklos Szeredi 		goto out_put_forget_req;
58439ee059aSMiklos Szeredi 
58539ee059aSMiklos Szeredi 	if ((outarg.attr.mode ^ mode) & S_IFMT)
5862d51013eSMiklos Szeredi 		goto out_put_forget_req;
58739ee059aSMiklos Szeredi 
5889e6268dbSMiklos Szeredi 	inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
5891fb69e78SMiklos Szeredi 			  &outarg.attr, entry_attr_timeout(&outarg), 0);
5909e6268dbSMiklos Szeredi 	if (!inode) {
59107e77dcaSMiklos Szeredi 		fuse_queue_forget(fc, forget, outarg.nodeid, 1);
5929e6268dbSMiklos Szeredi 		return -ENOMEM;
5939e6268dbSMiklos Szeredi 	}
59407e77dcaSMiklos Szeredi 	kfree(forget);
5959e6268dbSMiklos Szeredi 
596b70a80e7SMiklos Szeredi 	err = d_instantiate_no_diralias(entry, inode);
597b70a80e7SMiklos Szeredi 	if (err)
598b70a80e7SMiklos Szeredi 		return err;
599d2a85164SMiklos Szeredi 
6001fb69e78SMiklos Szeredi 	fuse_change_entry_timeout(entry, &outarg);
6019e6268dbSMiklos Szeredi 	fuse_invalidate_attr(dir);
6029e6268dbSMiklos Szeredi 	return 0;
60339ee059aSMiklos Szeredi 
6042d51013eSMiklos Szeredi  out_put_forget_req:
60507e77dcaSMiklos Szeredi 	kfree(forget);
60639ee059aSMiklos Szeredi 	return err;
6079e6268dbSMiklos Szeredi }
6089e6268dbSMiklos Szeredi 
6091a67aafbSAl Viro static int fuse_mknod(struct inode *dir, struct dentry *entry, umode_t mode,
6109e6268dbSMiklos Szeredi 		      dev_t rdev)
6119e6268dbSMiklos Szeredi {
6129e6268dbSMiklos Szeredi 	struct fuse_mknod_in inarg;
6139e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
614b111c8c0SMaxim Patlasov 	struct fuse_req *req = fuse_get_req_nopages(fc);
615ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
616ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
6179e6268dbSMiklos Szeredi 
618e0a43ddcSMiklos Szeredi 	if (!fc->dont_mask)
619e0a43ddcSMiklos Szeredi 		mode &= ~current_umask();
620e0a43ddcSMiklos Szeredi 
6219e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
6229e6268dbSMiklos Szeredi 	inarg.mode = mode;
6239e6268dbSMiklos Szeredi 	inarg.rdev = new_encode_dev(rdev);
624e0a43ddcSMiklos Szeredi 	inarg.umask = current_umask();
6259e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_MKNOD;
6269e6268dbSMiklos Szeredi 	req->in.numargs = 2;
627e0a43ddcSMiklos Szeredi 	req->in.args[0].size = fc->minor < 12 ? FUSE_COMPAT_MKNOD_IN_SIZE :
628e0a43ddcSMiklos Szeredi 						sizeof(inarg);
6299e6268dbSMiklos Szeredi 	req->in.args[0].value = &inarg;
6309e6268dbSMiklos Szeredi 	req->in.args[1].size = entry->d_name.len + 1;
6319e6268dbSMiklos Szeredi 	req->in.args[1].value = entry->d_name.name;
6329e6268dbSMiklos Szeredi 	return create_new_entry(fc, req, dir, entry, mode);
6339e6268dbSMiklos Szeredi }
6349e6268dbSMiklos Szeredi 
6354acdaf27SAl Viro static int fuse_create(struct inode *dir, struct dentry *entry, umode_t mode,
636ebfc3b49SAl Viro 		       bool excl)
6379e6268dbSMiklos Szeredi {
6389e6268dbSMiklos Szeredi 	return fuse_mknod(dir, entry, mode, 0);
6399e6268dbSMiklos Szeredi }
6409e6268dbSMiklos Szeredi 
64118bb1db3SAl Viro static int fuse_mkdir(struct inode *dir, struct dentry *entry, umode_t mode)
6429e6268dbSMiklos Szeredi {
6439e6268dbSMiklos Szeredi 	struct fuse_mkdir_in inarg;
6449e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
645b111c8c0SMaxim Patlasov 	struct fuse_req *req = fuse_get_req_nopages(fc);
646ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
647ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
6489e6268dbSMiklos Szeredi 
649e0a43ddcSMiklos Szeredi 	if (!fc->dont_mask)
650e0a43ddcSMiklos Szeredi 		mode &= ~current_umask();
651e0a43ddcSMiklos Szeredi 
6529e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
6539e6268dbSMiklos Szeredi 	inarg.mode = mode;
654e0a43ddcSMiklos Szeredi 	inarg.umask = current_umask();
6559e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_MKDIR;
6569e6268dbSMiklos Szeredi 	req->in.numargs = 2;
6579e6268dbSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
6589e6268dbSMiklos Szeredi 	req->in.args[0].value = &inarg;
6599e6268dbSMiklos Szeredi 	req->in.args[1].size = entry->d_name.len + 1;
6609e6268dbSMiklos Szeredi 	req->in.args[1].value = entry->d_name.name;
6619e6268dbSMiklos Szeredi 	return create_new_entry(fc, req, dir, entry, S_IFDIR);
6629e6268dbSMiklos Szeredi }
6639e6268dbSMiklos Szeredi 
6649e6268dbSMiklos Szeredi static int fuse_symlink(struct inode *dir, struct dentry *entry,
6659e6268dbSMiklos Szeredi 			const char *link)
6669e6268dbSMiklos Szeredi {
6679e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
6689e6268dbSMiklos Szeredi 	unsigned len = strlen(link) + 1;
669b111c8c0SMaxim Patlasov 	struct fuse_req *req = fuse_get_req_nopages(fc);
670ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
671ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
6729e6268dbSMiklos Szeredi 
6739e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_SYMLINK;
6749e6268dbSMiklos Szeredi 	req->in.numargs = 2;
6759e6268dbSMiklos Szeredi 	req->in.args[0].size = entry->d_name.len + 1;
6769e6268dbSMiklos Szeredi 	req->in.args[0].value = entry->d_name.name;
6779e6268dbSMiklos Szeredi 	req->in.args[1].size = len;
6789e6268dbSMiklos Szeredi 	req->in.args[1].value = link;
6799e6268dbSMiklos Szeredi 	return create_new_entry(fc, req, dir, entry, S_IFLNK);
6809e6268dbSMiklos Szeredi }
6819e6268dbSMiklos Szeredi 
6829e6268dbSMiklos Szeredi static int fuse_unlink(struct inode *dir, struct dentry *entry)
6839e6268dbSMiklos Szeredi {
6849e6268dbSMiklos Szeredi 	int err;
6859e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
686b111c8c0SMaxim Patlasov 	struct fuse_req *req = fuse_get_req_nopages(fc);
687ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
688ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
6899e6268dbSMiklos Szeredi 
6909e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_UNLINK;
6919e6268dbSMiklos Szeredi 	req->in.h.nodeid = get_node_id(dir);
6929e6268dbSMiklos Szeredi 	req->in.numargs = 1;
6939e6268dbSMiklos Szeredi 	req->in.args[0].size = entry->d_name.len + 1;
6949e6268dbSMiklos Szeredi 	req->in.args[0].value = entry->d_name.name;
695b93f858aSTejun Heo 	fuse_request_send(fc, req);
6969e6268dbSMiklos Szeredi 	err = req->out.h.error;
6979e6268dbSMiklos Szeredi 	fuse_put_request(fc, req);
6989e6268dbSMiklos Szeredi 	if (!err) {
6999e6268dbSMiklos Szeredi 		struct inode *inode = entry->d_inode;
700ac45d613SMiklos Szeredi 		struct fuse_inode *fi = get_fuse_inode(inode);
7019e6268dbSMiklos Szeredi 
702ac45d613SMiklos Szeredi 		spin_lock(&fc->lock);
703ac45d613SMiklos Szeredi 		fi->attr_version = ++fc->attr_version;
704dfca7cebSMiklos Szeredi 		/*
705dfca7cebSMiklos Szeredi 		 * If i_nlink == 0 then unlink doesn't make sense, yet this can
706dfca7cebSMiklos Szeredi 		 * happen if userspace filesystem is careless.  It would be
707dfca7cebSMiklos Szeredi 		 * difficult to enforce correct nlink usage so just ignore this
708dfca7cebSMiklos Szeredi 		 * condition here
709dfca7cebSMiklos Szeredi 		 */
710dfca7cebSMiklos Szeredi 		if (inode->i_nlink > 0)
711ac45d613SMiklos Szeredi 			drop_nlink(inode);
712ac45d613SMiklos Szeredi 		spin_unlock(&fc->lock);
7139e6268dbSMiklos Szeredi 		fuse_invalidate_attr(inode);
7149e6268dbSMiklos Szeredi 		fuse_invalidate_attr(dir);
7158cbdf1e6SMiklos Szeredi 		fuse_invalidate_entry_cache(entry);
7169e6268dbSMiklos Szeredi 	} else if (err == -EINTR)
7179e6268dbSMiklos Szeredi 		fuse_invalidate_entry(entry);
7189e6268dbSMiklos Szeredi 	return err;
7199e6268dbSMiklos Szeredi }
7209e6268dbSMiklos Szeredi 
7219e6268dbSMiklos Szeredi static int fuse_rmdir(struct inode *dir, struct dentry *entry)
7229e6268dbSMiklos Szeredi {
7239e6268dbSMiklos Szeredi 	int err;
7249e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
725b111c8c0SMaxim Patlasov 	struct fuse_req *req = fuse_get_req_nopages(fc);
726ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
727ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
7289e6268dbSMiklos Szeredi 
7299e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_RMDIR;
7309e6268dbSMiklos Szeredi 	req->in.h.nodeid = get_node_id(dir);
7319e6268dbSMiklos Szeredi 	req->in.numargs = 1;
7329e6268dbSMiklos Szeredi 	req->in.args[0].size = entry->d_name.len + 1;
7339e6268dbSMiklos Szeredi 	req->in.args[0].value = entry->d_name.name;
734b93f858aSTejun Heo 	fuse_request_send(fc, req);
7359e6268dbSMiklos Szeredi 	err = req->out.h.error;
7369e6268dbSMiklos Szeredi 	fuse_put_request(fc, req);
7379e6268dbSMiklos Szeredi 	if (!err) {
738ce71ec36SDave Hansen 		clear_nlink(entry->d_inode);
7399e6268dbSMiklos Szeredi 		fuse_invalidate_attr(dir);
7408cbdf1e6SMiklos Szeredi 		fuse_invalidate_entry_cache(entry);
7419e6268dbSMiklos Szeredi 	} else if (err == -EINTR)
7429e6268dbSMiklos Szeredi 		fuse_invalidate_entry(entry);
7439e6268dbSMiklos Szeredi 	return err;
7449e6268dbSMiklos Szeredi }
7459e6268dbSMiklos Szeredi 
7469e6268dbSMiklos Szeredi static int fuse_rename(struct inode *olddir, struct dentry *oldent,
7479e6268dbSMiklos Szeredi 		       struct inode *newdir, struct dentry *newent)
7489e6268dbSMiklos Szeredi {
7499e6268dbSMiklos Szeredi 	int err;
7509e6268dbSMiklos Szeredi 	struct fuse_rename_in inarg;
7519e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(olddir);
752b111c8c0SMaxim Patlasov 	struct fuse_req *req = fuse_get_req_nopages(fc);
753e4eaac06SSage Weil 
754ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
755ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
7569e6268dbSMiklos Szeredi 
7579e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
7589e6268dbSMiklos Szeredi 	inarg.newdir = get_node_id(newdir);
7599e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_RENAME;
7609e6268dbSMiklos Szeredi 	req->in.h.nodeid = get_node_id(olddir);
7619e6268dbSMiklos Szeredi 	req->in.numargs = 3;
7629e6268dbSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
7639e6268dbSMiklos Szeredi 	req->in.args[0].value = &inarg;
7649e6268dbSMiklos Szeredi 	req->in.args[1].size = oldent->d_name.len + 1;
7659e6268dbSMiklos Szeredi 	req->in.args[1].value = oldent->d_name.name;
7669e6268dbSMiklos Szeredi 	req->in.args[2].size = newent->d_name.len + 1;
7679e6268dbSMiklos Szeredi 	req->in.args[2].value = newent->d_name.name;
768b93f858aSTejun Heo 	fuse_request_send(fc, req);
7699e6268dbSMiklos Szeredi 	err = req->out.h.error;
7709e6268dbSMiklos Szeredi 	fuse_put_request(fc, req);
7719e6268dbSMiklos Szeredi 	if (!err) {
77208b63307SMiklos Szeredi 		/* ctime changes */
77308b63307SMiklos Szeredi 		fuse_invalidate_attr(oldent->d_inode);
77408b63307SMiklos Szeredi 
7759e6268dbSMiklos Szeredi 		fuse_invalidate_attr(olddir);
7769e6268dbSMiklos Szeredi 		if (olddir != newdir)
7779e6268dbSMiklos Szeredi 			fuse_invalidate_attr(newdir);
7788cbdf1e6SMiklos Szeredi 
7798cbdf1e6SMiklos Szeredi 		/* newent will end up negative */
7805219f346SMiklos Szeredi 		if (newent->d_inode) {
7815219f346SMiklos Szeredi 			fuse_invalidate_attr(newent->d_inode);
7828cbdf1e6SMiklos Szeredi 			fuse_invalidate_entry_cache(newent);
7835219f346SMiklos Szeredi 		}
7849e6268dbSMiklos Szeredi 	} else if (err == -EINTR) {
7859e6268dbSMiklos Szeredi 		/* If request was interrupted, DEITY only knows if the
7869e6268dbSMiklos Szeredi 		   rename actually took place.  If the invalidation
7879e6268dbSMiklos Szeredi 		   fails (e.g. some process has CWD under the renamed
7889e6268dbSMiklos Szeredi 		   directory), then there can be inconsistency between
7899e6268dbSMiklos Szeredi 		   the dcache and the real filesystem.  Tough luck. */
7909e6268dbSMiklos Szeredi 		fuse_invalidate_entry(oldent);
7919e6268dbSMiklos Szeredi 		if (newent->d_inode)
7929e6268dbSMiklos Szeredi 			fuse_invalidate_entry(newent);
7939e6268dbSMiklos Szeredi 	}
7949e6268dbSMiklos Szeredi 
7959e6268dbSMiklos Szeredi 	return err;
7969e6268dbSMiklos Szeredi }
7979e6268dbSMiklos Szeredi 
7989e6268dbSMiklos Szeredi static int fuse_link(struct dentry *entry, struct inode *newdir,
7999e6268dbSMiklos Szeredi 		     struct dentry *newent)
8009e6268dbSMiklos Szeredi {
8019e6268dbSMiklos Szeredi 	int err;
8029e6268dbSMiklos Szeredi 	struct fuse_link_in inarg;
8039e6268dbSMiklos Szeredi 	struct inode *inode = entry->d_inode;
8049e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
805b111c8c0SMaxim Patlasov 	struct fuse_req *req = fuse_get_req_nopages(fc);
806ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
807ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
8089e6268dbSMiklos Szeredi 
8099e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
8109e6268dbSMiklos Szeredi 	inarg.oldnodeid = get_node_id(inode);
8119e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_LINK;
8129e6268dbSMiklos Szeredi 	req->in.numargs = 2;
8139e6268dbSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
8149e6268dbSMiklos Szeredi 	req->in.args[0].value = &inarg;
8159e6268dbSMiklos Szeredi 	req->in.args[1].size = newent->d_name.len + 1;
8169e6268dbSMiklos Szeredi 	req->in.args[1].value = newent->d_name.name;
8179e6268dbSMiklos Szeredi 	err = create_new_entry(fc, req, newdir, newent, inode->i_mode);
8189e6268dbSMiklos Szeredi 	/* Contrary to "normal" filesystems it can happen that link
8199e6268dbSMiklos Szeredi 	   makes two "logical" inodes point to the same "physical"
8209e6268dbSMiklos Szeredi 	   inode.  We invalidate the attributes of the old one, so it
8219e6268dbSMiklos Szeredi 	   will reflect changes in the backing inode (link count,
8229e6268dbSMiklos Szeredi 	   etc.)
8239e6268dbSMiklos Szeredi 	*/
824ac45d613SMiklos Szeredi 	if (!err) {
825ac45d613SMiklos Szeredi 		struct fuse_inode *fi = get_fuse_inode(inode);
826ac45d613SMiklos Szeredi 
827ac45d613SMiklos Szeredi 		spin_lock(&fc->lock);
828ac45d613SMiklos Szeredi 		fi->attr_version = ++fc->attr_version;
829ac45d613SMiklos Szeredi 		inc_nlink(inode);
830ac45d613SMiklos Szeredi 		spin_unlock(&fc->lock);
8319e6268dbSMiklos Szeredi 		fuse_invalidate_attr(inode);
832ac45d613SMiklos Szeredi 	} else if (err == -EINTR) {
833ac45d613SMiklos Szeredi 		fuse_invalidate_attr(inode);
834ac45d613SMiklos Szeredi 	}
8359e6268dbSMiklos Szeredi 	return err;
8369e6268dbSMiklos Szeredi }
8379e6268dbSMiklos Szeredi 
8381fb69e78SMiklos Szeredi static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
8391fb69e78SMiklos Szeredi 			  struct kstat *stat)
8401fb69e78SMiklos Szeredi {
841203627bbSMiklos Szeredi 	unsigned int blkbits;
8428373200bSPavel Emelyanov 	struct fuse_conn *fc = get_fuse_conn(inode);
8438373200bSPavel Emelyanov 
8448373200bSPavel Emelyanov 	/* see the comment in fuse_change_attributes() */
845b0aa7606SMaxim Patlasov 	if (fc->writeback_cache && S_ISREG(inode->i_mode)) {
8468373200bSPavel Emelyanov 		attr->size = i_size_read(inode);
847b0aa7606SMaxim Patlasov 		attr->mtime = inode->i_mtime.tv_sec;
848b0aa7606SMaxim Patlasov 		attr->mtimensec = inode->i_mtime.tv_nsec;
849b0aa7606SMaxim Patlasov 	}
850203627bbSMiklos Szeredi 
8511fb69e78SMiklos Szeredi 	stat->dev = inode->i_sb->s_dev;
8521fb69e78SMiklos Szeredi 	stat->ino = attr->ino;
8531fb69e78SMiklos Szeredi 	stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
8541fb69e78SMiklos Szeredi 	stat->nlink = attr->nlink;
855499dcf20SEric W. Biederman 	stat->uid = make_kuid(&init_user_ns, attr->uid);
856499dcf20SEric W. Biederman 	stat->gid = make_kgid(&init_user_ns, attr->gid);
8571fb69e78SMiklos Szeredi 	stat->rdev = inode->i_rdev;
8581fb69e78SMiklos Szeredi 	stat->atime.tv_sec = attr->atime;
8591fb69e78SMiklos Szeredi 	stat->atime.tv_nsec = attr->atimensec;
8601fb69e78SMiklos Szeredi 	stat->mtime.tv_sec = attr->mtime;
8611fb69e78SMiklos Szeredi 	stat->mtime.tv_nsec = attr->mtimensec;
8621fb69e78SMiklos Szeredi 	stat->ctime.tv_sec = attr->ctime;
8631fb69e78SMiklos Szeredi 	stat->ctime.tv_nsec = attr->ctimensec;
8641fb69e78SMiklos Szeredi 	stat->size = attr->size;
8651fb69e78SMiklos Szeredi 	stat->blocks = attr->blocks;
866203627bbSMiklos Szeredi 
867203627bbSMiklos Szeredi 	if (attr->blksize != 0)
868203627bbSMiklos Szeredi 		blkbits = ilog2(attr->blksize);
869203627bbSMiklos Szeredi 	else
870203627bbSMiklos Szeredi 		blkbits = inode->i_sb->s_blocksize_bits;
871203627bbSMiklos Szeredi 
872203627bbSMiklos Szeredi 	stat->blksize = 1 << blkbits;
8731fb69e78SMiklos Szeredi }
8741fb69e78SMiklos Szeredi 
875c79e322fSMiklos Szeredi static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
876c79e322fSMiklos Szeredi 			   struct file *file)
877e5e5558eSMiklos Szeredi {
878e5e5558eSMiklos Szeredi 	int err;
879c79e322fSMiklos Szeredi 	struct fuse_getattr_in inarg;
880c79e322fSMiklos Szeredi 	struct fuse_attr_out outarg;
881e5e5558eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
8821fb69e78SMiklos Szeredi 	struct fuse_req *req;
8831fb69e78SMiklos Szeredi 	u64 attr_version;
8841fb69e78SMiklos Szeredi 
885b111c8c0SMaxim Patlasov 	req = fuse_get_req_nopages(fc);
886ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
887ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
888e5e5558eSMiklos Szeredi 
8897dca9fd3SMiklos Szeredi 	attr_version = fuse_get_attr_version(fc);
8901fb69e78SMiklos Szeredi 
891c79e322fSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
8920e9663eeSMiklos Szeredi 	memset(&outarg, 0, sizeof(outarg));
893c79e322fSMiklos Szeredi 	/* Directories have separate file-handle space */
894c79e322fSMiklos Szeredi 	if (file && S_ISREG(inode->i_mode)) {
895c79e322fSMiklos Szeredi 		struct fuse_file *ff = file->private_data;
896c79e322fSMiklos Szeredi 
897c79e322fSMiklos Szeredi 		inarg.getattr_flags |= FUSE_GETATTR_FH;
898c79e322fSMiklos Szeredi 		inarg.fh = ff->fh;
899c79e322fSMiklos Szeredi 	}
900e5e5558eSMiklos Szeredi 	req->in.h.opcode = FUSE_GETATTR;
901e5e5558eSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
902c79e322fSMiklos Szeredi 	req->in.numargs = 1;
903c79e322fSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
904c79e322fSMiklos Szeredi 	req->in.args[0].value = &inarg;
905e5e5558eSMiklos Szeredi 	req->out.numargs = 1;
9060e9663eeSMiklos Szeredi 	if (fc->minor < 9)
9070e9663eeSMiklos Szeredi 		req->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
9080e9663eeSMiklos Szeredi 	else
909c79e322fSMiklos Szeredi 		req->out.args[0].size = sizeof(outarg);
910c79e322fSMiklos Szeredi 	req->out.args[0].value = &outarg;
911b93f858aSTejun Heo 	fuse_request_send(fc, req);
912e5e5558eSMiklos Szeredi 	err = req->out.h.error;
913e5e5558eSMiklos Szeredi 	fuse_put_request(fc, req);
914e5e5558eSMiklos Szeredi 	if (!err) {
915c79e322fSMiklos Szeredi 		if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
916e5e5558eSMiklos Szeredi 			make_bad_inode(inode);
917e5e5558eSMiklos Szeredi 			err = -EIO;
918e5e5558eSMiklos Szeredi 		} else {
919c79e322fSMiklos Szeredi 			fuse_change_attributes(inode, &outarg.attr,
920c79e322fSMiklos Szeredi 					       attr_timeout(&outarg),
9211fb69e78SMiklos Szeredi 					       attr_version);
9221fb69e78SMiklos Szeredi 			if (stat)
923c79e322fSMiklos Szeredi 				fuse_fillattr(inode, &outarg.attr, stat);
924e5e5558eSMiklos Szeredi 		}
925e5e5558eSMiklos Szeredi 	}
926e5e5558eSMiklos Szeredi 	return err;
927e5e5558eSMiklos Szeredi }
928e5e5558eSMiklos Szeredi 
929bcb4be80SMiklos Szeredi int fuse_update_attributes(struct inode *inode, struct kstat *stat,
930bcb4be80SMiklos Szeredi 			   struct file *file, bool *refreshed)
931bcb4be80SMiklos Szeredi {
932bcb4be80SMiklos Szeredi 	struct fuse_inode *fi = get_fuse_inode(inode);
933bcb4be80SMiklos Szeredi 	int err;
934bcb4be80SMiklos Szeredi 	bool r;
935bcb4be80SMiklos Szeredi 
936bcb4be80SMiklos Szeredi 	if (fi->i_time < get_jiffies_64()) {
937bcb4be80SMiklos Szeredi 		r = true;
938bcb4be80SMiklos Szeredi 		err = fuse_do_getattr(inode, stat, file);
939bcb4be80SMiklos Szeredi 	} else {
940bcb4be80SMiklos Szeredi 		r = false;
941bcb4be80SMiklos Szeredi 		err = 0;
942bcb4be80SMiklos Szeredi 		if (stat) {
943bcb4be80SMiklos Szeredi 			generic_fillattr(inode, stat);
944bcb4be80SMiklos Szeredi 			stat->mode = fi->orig_i_mode;
94545c72cd7SPavel Shilovsky 			stat->ino = fi->orig_ino;
946bcb4be80SMiklos Szeredi 		}
947bcb4be80SMiklos Szeredi 	}
948bcb4be80SMiklos Szeredi 
949bcb4be80SMiklos Szeredi 	if (refreshed != NULL)
950bcb4be80SMiklos Szeredi 		*refreshed = r;
951bcb4be80SMiklos Szeredi 
952bcb4be80SMiklos Szeredi 	return err;
953bcb4be80SMiklos Szeredi }
954bcb4be80SMiklos Szeredi 
9553b463ae0SJohn Muir int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid,
956451d0f59SJohn Muir 			     u64 child_nodeid, struct qstr *name)
9573b463ae0SJohn Muir {
9583b463ae0SJohn Muir 	int err = -ENOTDIR;
9593b463ae0SJohn Muir 	struct inode *parent;
9603b463ae0SJohn Muir 	struct dentry *dir;
9613b463ae0SJohn Muir 	struct dentry *entry;
9623b463ae0SJohn Muir 
9633b463ae0SJohn Muir 	parent = ilookup5(sb, parent_nodeid, fuse_inode_eq, &parent_nodeid);
9643b463ae0SJohn Muir 	if (!parent)
9653b463ae0SJohn Muir 		return -ENOENT;
9663b463ae0SJohn Muir 
9673b463ae0SJohn Muir 	mutex_lock(&parent->i_mutex);
9683b463ae0SJohn Muir 	if (!S_ISDIR(parent->i_mode))
9693b463ae0SJohn Muir 		goto unlock;
9703b463ae0SJohn Muir 
9713b463ae0SJohn Muir 	err = -ENOENT;
9723b463ae0SJohn Muir 	dir = d_find_alias(parent);
9733b463ae0SJohn Muir 	if (!dir)
9743b463ae0SJohn Muir 		goto unlock;
9753b463ae0SJohn Muir 
9763b463ae0SJohn Muir 	entry = d_lookup(dir, name);
9773b463ae0SJohn Muir 	dput(dir);
9783b463ae0SJohn Muir 	if (!entry)
9793b463ae0SJohn Muir 		goto unlock;
9803b463ae0SJohn Muir 
9813b463ae0SJohn Muir 	fuse_invalidate_attr(parent);
9823b463ae0SJohn Muir 	fuse_invalidate_entry(entry);
983451d0f59SJohn Muir 
984451d0f59SJohn Muir 	if (child_nodeid != 0 && entry->d_inode) {
985451d0f59SJohn Muir 		mutex_lock(&entry->d_inode->i_mutex);
986451d0f59SJohn Muir 		if (get_node_id(entry->d_inode) != child_nodeid) {
987451d0f59SJohn Muir 			err = -ENOENT;
988451d0f59SJohn Muir 			goto badentry;
989451d0f59SJohn Muir 		}
990451d0f59SJohn Muir 		if (d_mountpoint(entry)) {
991451d0f59SJohn Muir 			err = -EBUSY;
992451d0f59SJohn Muir 			goto badentry;
993451d0f59SJohn Muir 		}
994451d0f59SJohn Muir 		if (S_ISDIR(entry->d_inode->i_mode)) {
995451d0f59SJohn Muir 			shrink_dcache_parent(entry);
996451d0f59SJohn Muir 			if (!simple_empty(entry)) {
997451d0f59SJohn Muir 				err = -ENOTEMPTY;
998451d0f59SJohn Muir 				goto badentry;
999451d0f59SJohn Muir 			}
1000451d0f59SJohn Muir 			entry->d_inode->i_flags |= S_DEAD;
1001451d0f59SJohn Muir 		}
1002451d0f59SJohn Muir 		dont_mount(entry);
1003451d0f59SJohn Muir 		clear_nlink(entry->d_inode);
10043b463ae0SJohn Muir 		err = 0;
1005451d0f59SJohn Muir  badentry:
1006451d0f59SJohn Muir 		mutex_unlock(&entry->d_inode->i_mutex);
1007451d0f59SJohn Muir 		if (!err)
1008451d0f59SJohn Muir 			d_delete(entry);
1009451d0f59SJohn Muir 	} else {
1010451d0f59SJohn Muir 		err = 0;
1011451d0f59SJohn Muir 	}
1012451d0f59SJohn Muir 	dput(entry);
10133b463ae0SJohn Muir 
10143b463ae0SJohn Muir  unlock:
10153b463ae0SJohn Muir 	mutex_unlock(&parent->i_mutex);
10163b463ae0SJohn Muir 	iput(parent);
10173b463ae0SJohn Muir 	return err;
10183b463ae0SJohn Muir }
10193b463ae0SJohn Muir 
102087729a55SMiklos Szeredi /*
102187729a55SMiklos Szeredi  * Calling into a user-controlled filesystem gives the filesystem
1022c2132c1bSAnatol Pomozov  * daemon ptrace-like capabilities over the current process.  This
102387729a55SMiklos Szeredi  * means, that the filesystem daemon is able to record the exact
102487729a55SMiklos Szeredi  * filesystem operations performed, and can also control the behavior
102587729a55SMiklos Szeredi  * of the requester process in otherwise impossible ways.  For example
102687729a55SMiklos Szeredi  * it can delay the operation for arbitrary length of time allowing
102787729a55SMiklos Szeredi  * DoS against the requester.
102887729a55SMiklos Szeredi  *
102987729a55SMiklos Szeredi  * For this reason only those processes can call into the filesystem,
103087729a55SMiklos Szeredi  * for which the owner of the mount has ptrace privilege.  This
103187729a55SMiklos Szeredi  * excludes processes started by other users, suid or sgid processes.
103287729a55SMiklos Szeredi  */
1033c2132c1bSAnatol Pomozov int fuse_allow_current_process(struct fuse_conn *fc)
103487729a55SMiklos Szeredi {
1035c69e8d9cSDavid Howells 	const struct cred *cred;
1036c69e8d9cSDavid Howells 
103787729a55SMiklos Szeredi 	if (fc->flags & FUSE_ALLOW_OTHER)
103887729a55SMiklos Szeredi 		return 1;
103987729a55SMiklos Szeredi 
1040c2132c1bSAnatol Pomozov 	cred = current_cred();
1041499dcf20SEric W. Biederman 	if (uid_eq(cred->euid, fc->user_id) &&
1042499dcf20SEric W. Biederman 	    uid_eq(cred->suid, fc->user_id) &&
1043499dcf20SEric W. Biederman 	    uid_eq(cred->uid,  fc->user_id) &&
1044499dcf20SEric W. Biederman 	    gid_eq(cred->egid, fc->group_id) &&
1045499dcf20SEric W. Biederman 	    gid_eq(cred->sgid, fc->group_id) &&
1046499dcf20SEric W. Biederman 	    gid_eq(cred->gid,  fc->group_id))
1047c2132c1bSAnatol Pomozov 		return 1;
104887729a55SMiklos Szeredi 
1049c2132c1bSAnatol Pomozov 	return 0;
105087729a55SMiklos Szeredi }
105187729a55SMiklos Szeredi 
105231d40d74SMiklos Szeredi static int fuse_access(struct inode *inode, int mask)
105331d40d74SMiklos Szeredi {
105431d40d74SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
105531d40d74SMiklos Szeredi 	struct fuse_req *req;
105631d40d74SMiklos Szeredi 	struct fuse_access_in inarg;
105731d40d74SMiklos Szeredi 	int err;
105831d40d74SMiklos Szeredi 
1059698fa1d1SMiklos Szeredi 	BUG_ON(mask & MAY_NOT_BLOCK);
1060698fa1d1SMiklos Szeredi 
106131d40d74SMiklos Szeredi 	if (fc->no_access)
106231d40d74SMiklos Szeredi 		return 0;
106331d40d74SMiklos Szeredi 
1064b111c8c0SMaxim Patlasov 	req = fuse_get_req_nopages(fc);
1065ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1066ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
106731d40d74SMiklos Szeredi 
106831d40d74SMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
1069e6305c43SAl Viro 	inarg.mask = mask & (MAY_READ | MAY_WRITE | MAY_EXEC);
107031d40d74SMiklos Szeredi 	req->in.h.opcode = FUSE_ACCESS;
107131d40d74SMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
107231d40d74SMiklos Szeredi 	req->in.numargs = 1;
107331d40d74SMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
107431d40d74SMiklos Szeredi 	req->in.args[0].value = &inarg;
1075b93f858aSTejun Heo 	fuse_request_send(fc, req);
107631d40d74SMiklos Szeredi 	err = req->out.h.error;
107731d40d74SMiklos Szeredi 	fuse_put_request(fc, req);
107831d40d74SMiklos Szeredi 	if (err == -ENOSYS) {
107931d40d74SMiklos Szeredi 		fc->no_access = 1;
108031d40d74SMiklos Szeredi 		err = 0;
108131d40d74SMiklos Szeredi 	}
108231d40d74SMiklos Szeredi 	return err;
108331d40d74SMiklos Szeredi }
108431d40d74SMiklos Szeredi 
108510556cb2SAl Viro static int fuse_perm_getattr(struct inode *inode, int mask)
108619690ddbSMiklos Szeredi {
108710556cb2SAl Viro 	if (mask & MAY_NOT_BLOCK)
108819690ddbSMiklos Szeredi 		return -ECHILD;
108919690ddbSMiklos Szeredi 
109019690ddbSMiklos Szeredi 	return fuse_do_getattr(inode, NULL, NULL);
109119690ddbSMiklos Szeredi }
109219690ddbSMiklos Szeredi 
10936f9f1180SMiklos Szeredi /*
10946f9f1180SMiklos Szeredi  * Check permission.  The two basic access models of FUSE are:
10956f9f1180SMiklos Szeredi  *
10966f9f1180SMiklos Szeredi  * 1) Local access checking ('default_permissions' mount option) based
10976f9f1180SMiklos Szeredi  * on file mode.  This is the plain old disk filesystem permission
10986f9f1180SMiklos Szeredi  * modell.
10996f9f1180SMiklos Szeredi  *
11006f9f1180SMiklos Szeredi  * 2) "Remote" access checking, where server is responsible for
11016f9f1180SMiklos Szeredi  * checking permission in each inode operation.  An exception to this
11026f9f1180SMiklos Szeredi  * is if ->permission() was invoked from sys_access() in which case an
11036f9f1180SMiklos Szeredi  * access request is sent.  Execute permission is still checked
11046f9f1180SMiklos Szeredi  * locally based on file mode.
11056f9f1180SMiklos Szeredi  */
110610556cb2SAl Viro static int fuse_permission(struct inode *inode, int mask)
1107e5e5558eSMiklos Szeredi {
1108e5e5558eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
1109244f6385SMiklos Szeredi 	bool refreshed = false;
1110244f6385SMiklos Szeredi 	int err = 0;
1111e5e5558eSMiklos Szeredi 
1112c2132c1bSAnatol Pomozov 	if (!fuse_allow_current_process(fc))
1113e5e5558eSMiklos Szeredi 		return -EACCES;
1114244f6385SMiklos Szeredi 
1115244f6385SMiklos Szeredi 	/*
1116e8e96157SMiklos Szeredi 	 * If attributes are needed, refresh them before proceeding
1117244f6385SMiklos Szeredi 	 */
1118e8e96157SMiklos Szeredi 	if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) ||
1119e8e96157SMiklos Szeredi 	    ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) {
112019690ddbSMiklos Szeredi 		struct fuse_inode *fi = get_fuse_inode(inode);
112119690ddbSMiklos Szeredi 
112219690ddbSMiklos Szeredi 		if (fi->i_time < get_jiffies_64()) {
112319690ddbSMiklos Szeredi 			refreshed = true;
112419690ddbSMiklos Szeredi 
112510556cb2SAl Viro 			err = fuse_perm_getattr(inode, mask);
1126244f6385SMiklos Szeredi 			if (err)
1127244f6385SMiklos Szeredi 				return err;
11281fb69e78SMiklos Szeredi 		}
112919690ddbSMiklos Szeredi 	}
1130244f6385SMiklos Szeredi 
1131244f6385SMiklos Szeredi 	if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
11322830ba7fSAl Viro 		err = generic_permission(inode, mask);
11331e9a4ed9SMiklos Szeredi 
11341e9a4ed9SMiklos Szeredi 		/* If permission is denied, try to refresh file
11351e9a4ed9SMiklos Szeredi 		   attributes.  This is also needed, because the root
11361e9a4ed9SMiklos Szeredi 		   node will at first have no permissions */
1137244f6385SMiklos Szeredi 		if (err == -EACCES && !refreshed) {
113810556cb2SAl Viro 			err = fuse_perm_getattr(inode, mask);
11391e9a4ed9SMiklos Szeredi 			if (!err)
11402830ba7fSAl Viro 				err = generic_permission(inode, mask);
11411e9a4ed9SMiklos Szeredi 		}
11421e9a4ed9SMiklos Szeredi 
11436f9f1180SMiklos Szeredi 		/* Note: the opposite of the above test does not
11446f9f1180SMiklos Szeredi 		   exist.  So if permissions are revoked this won't be
11456f9f1180SMiklos Szeredi 		   noticed immediately, only after the attribute
11466f9f1180SMiklos Szeredi 		   timeout has expired */
11479cfcac81SEric Paris 	} else if (mask & (MAY_ACCESS | MAY_CHDIR)) {
1148e8e96157SMiklos Szeredi 		err = fuse_access(inode, mask);
1149e8e96157SMiklos Szeredi 	} else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
1150e8e96157SMiklos Szeredi 		if (!(inode->i_mode & S_IXUGO)) {
1151e8e96157SMiklos Szeredi 			if (refreshed)
1152e5e5558eSMiklos Szeredi 				return -EACCES;
115331d40d74SMiklos Szeredi 
115410556cb2SAl Viro 			err = fuse_perm_getattr(inode, mask);
1155e8e96157SMiklos Szeredi 			if (!err && !(inode->i_mode & S_IXUGO))
1156e8e96157SMiklos Szeredi 				return -EACCES;
1157e8e96157SMiklos Szeredi 		}
1158e5e5558eSMiklos Szeredi 	}
1159244f6385SMiklos Szeredi 	return err;
1160e5e5558eSMiklos Szeredi }
1161e5e5558eSMiklos Szeredi 
1162e5e5558eSMiklos Szeredi static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
11638d3af7f3SAl Viro 			 struct dir_context *ctx)
1164e5e5558eSMiklos Szeredi {
1165e5e5558eSMiklos Szeredi 	while (nbytes >= FUSE_NAME_OFFSET) {
1166e5e5558eSMiklos Szeredi 		struct fuse_dirent *dirent = (struct fuse_dirent *) buf;
1167e5e5558eSMiklos Szeredi 		size_t reclen = FUSE_DIRENT_SIZE(dirent);
1168e5e5558eSMiklos Szeredi 		if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
1169e5e5558eSMiklos Szeredi 			return -EIO;
1170e5e5558eSMiklos Szeredi 		if (reclen > nbytes)
1171e5e5558eSMiklos Szeredi 			break;
1172efeb9e60SMiklos Szeredi 		if (memchr(dirent->name, '/', dirent->namelen) != NULL)
1173efeb9e60SMiklos Szeredi 			return -EIO;
1174e5e5558eSMiklos Szeredi 
11758d3af7f3SAl Viro 		if (!dir_emit(ctx, dirent->name, dirent->namelen,
11768d3af7f3SAl Viro 			       dirent->ino, dirent->type))
1177e5e5558eSMiklos Szeredi 			break;
1178e5e5558eSMiklos Szeredi 
1179e5e5558eSMiklos Szeredi 		buf += reclen;
1180e5e5558eSMiklos Szeredi 		nbytes -= reclen;
11818d3af7f3SAl Viro 		ctx->pos = dirent->off;
1182e5e5558eSMiklos Szeredi 	}
1183e5e5558eSMiklos Szeredi 
1184e5e5558eSMiklos Szeredi 	return 0;
1185e5e5558eSMiklos Szeredi }
1186e5e5558eSMiklos Szeredi 
11870b05b183SAnand V. Avati static int fuse_direntplus_link(struct file *file,
11880b05b183SAnand V. Avati 				struct fuse_direntplus *direntplus,
11890b05b183SAnand V. Avati 				u64 attr_version)
11900b05b183SAnand V. Avati {
11910b05b183SAnand V. Avati 	int err;
11920b05b183SAnand V. Avati 	struct fuse_entry_out *o = &direntplus->entry_out;
11930b05b183SAnand V. Avati 	struct fuse_dirent *dirent = &direntplus->dirent;
11940b05b183SAnand V. Avati 	struct dentry *parent = file->f_path.dentry;
11950b05b183SAnand V. Avati 	struct qstr name = QSTR_INIT(dirent->name, dirent->namelen);
11960b05b183SAnand V. Avati 	struct dentry *dentry;
11970b05b183SAnand V. Avati 	struct dentry *alias;
11980b05b183SAnand V. Avati 	struct inode *dir = parent->d_inode;
11990b05b183SAnand V. Avati 	struct fuse_conn *fc;
12000b05b183SAnand V. Avati 	struct inode *inode;
12010b05b183SAnand V. Avati 
12020b05b183SAnand V. Avati 	if (!o->nodeid) {
12030b05b183SAnand V. Avati 		/*
12040b05b183SAnand V. Avati 		 * Unlike in the case of fuse_lookup, zero nodeid does not mean
12050b05b183SAnand V. Avati 		 * ENOENT. Instead, it only means the userspace filesystem did
12060b05b183SAnand V. Avati 		 * not want to return attributes/handle for this entry.
12070b05b183SAnand V. Avati 		 *
12080b05b183SAnand V. Avati 		 * So do nothing.
12090b05b183SAnand V. Avati 		 */
12100b05b183SAnand V. Avati 		return 0;
12110b05b183SAnand V. Avati 	}
12120b05b183SAnand V. Avati 
12130b05b183SAnand V. Avati 	if (name.name[0] == '.') {
12140b05b183SAnand V. Avati 		/*
12150b05b183SAnand V. Avati 		 * We could potentially refresh the attributes of the directory
12160b05b183SAnand V. Avati 		 * and its parent?
12170b05b183SAnand V. Avati 		 */
12180b05b183SAnand V. Avati 		if (name.len == 1)
12190b05b183SAnand V. Avati 			return 0;
12200b05b183SAnand V. Avati 		if (name.name[1] == '.' && name.len == 2)
12210b05b183SAnand V. Avati 			return 0;
12220b05b183SAnand V. Avati 	}
1223a28ef45cSMiklos Szeredi 
1224a28ef45cSMiklos Szeredi 	if (invalid_nodeid(o->nodeid))
1225a28ef45cSMiklos Szeredi 		return -EIO;
1226a28ef45cSMiklos Szeredi 	if (!fuse_valid_type(o->attr.mode))
1227a28ef45cSMiklos Szeredi 		return -EIO;
1228a28ef45cSMiklos Szeredi 
12290b05b183SAnand V. Avati 	fc = get_fuse_conn(dir);
12300b05b183SAnand V. Avati 
12310b05b183SAnand V. Avati 	name.hash = full_name_hash(name.name, name.len);
12320b05b183SAnand V. Avati 	dentry = d_lookup(parent, &name);
123353ce9a33SNiels de Vos 	if (dentry) {
12340b05b183SAnand V. Avati 		inode = dentry->d_inode;
123553ce9a33SNiels de Vos 		if (!inode) {
123653ce9a33SNiels de Vos 			d_drop(dentry);
1237a28ef45cSMiklos Szeredi 		} else if (get_node_id(inode) != o->nodeid ||
1238a28ef45cSMiklos Szeredi 			   ((o->attr.mode ^ inode->i_mode) & S_IFMT)) {
123953ce9a33SNiels de Vos 			err = d_invalidate(dentry);
124053ce9a33SNiels de Vos 			if (err)
124153ce9a33SNiels de Vos 				goto out;
1242a28ef45cSMiklos Szeredi 		} else if (is_bad_inode(inode)) {
1243a28ef45cSMiklos Szeredi 			err = -EIO;
1244a28ef45cSMiklos Szeredi 			goto out;
124553ce9a33SNiels de Vos 		} else {
12460b05b183SAnand V. Avati 			struct fuse_inode *fi;
12470b05b183SAnand V. Avati 			fi = get_fuse_inode(inode);
12480b05b183SAnand V. Avati 			spin_lock(&fc->lock);
12490b05b183SAnand V. Avati 			fi->nlookup++;
12500b05b183SAnand V. Avati 			spin_unlock(&fc->lock);
12510b05b183SAnand V. Avati 
1252fa2b7213SMiklos Szeredi 			fuse_change_attributes(inode, &o->attr,
1253fa2b7213SMiklos Szeredi 					       entry_attr_timeout(o),
1254fa2b7213SMiklos Szeredi 					       attr_version);
1255fa2b7213SMiklos Szeredi 
12560b05b183SAnand V. Avati 			/*
12570b05b183SAnand V. Avati 			 * The other branch to 'found' comes via fuse_iget()
12580b05b183SAnand V. Avati 			 * which bumps nlookup inside
12590b05b183SAnand V. Avati 			 */
12600b05b183SAnand V. Avati 			goto found;
12610b05b183SAnand V. Avati 		}
12620b05b183SAnand V. Avati 		dput(dentry);
12630b05b183SAnand V. Avati 	}
12640b05b183SAnand V. Avati 
12650b05b183SAnand V. Avati 	dentry = d_alloc(parent, &name);
12660b05b183SAnand V. Avati 	err = -ENOMEM;
12670b05b183SAnand V. Avati 	if (!dentry)
12680b05b183SAnand V. Avati 		goto out;
12690b05b183SAnand V. Avati 
12700b05b183SAnand V. Avati 	inode = fuse_iget(dir->i_sb, o->nodeid, o->generation,
12710b05b183SAnand V. Avati 			  &o->attr, entry_attr_timeout(o), attr_version);
12720b05b183SAnand V. Avati 	if (!inode)
12730b05b183SAnand V. Avati 		goto out;
12740b05b183SAnand V. Avati 
1275b70a80e7SMiklos Szeredi 	alias = d_materialise_unique(dentry, inode);
12760b05b183SAnand V. Avati 	err = PTR_ERR(alias);
12775835f339SMiklos Szeredi 	if (IS_ERR(alias))
12780b05b183SAnand V. Avati 		goto out;
12792914941eSMiklos Szeredi 
12800b05b183SAnand V. Avati 	if (alias) {
12810b05b183SAnand V. Avati 		dput(dentry);
12820b05b183SAnand V. Avati 		dentry = alias;
12830b05b183SAnand V. Avati 	}
12840b05b183SAnand V. Avati 
12850b05b183SAnand V. Avati found:
12866314efeeSMiklos Szeredi 	if (fc->readdirplus_auto)
12876314efeeSMiklos Szeredi 		set_bit(FUSE_I_INIT_RDPLUS, &get_fuse_inode(inode)->state);
12880b05b183SAnand V. Avati 	fuse_change_entry_timeout(dentry, o);
12890b05b183SAnand V. Avati 
12900b05b183SAnand V. Avati 	err = 0;
12910b05b183SAnand V. Avati out:
12920b05b183SAnand V. Avati 	dput(dentry);
12930b05b183SAnand V. Avati 	return err;
12940b05b183SAnand V. Avati }
12950b05b183SAnand V. Avati 
12960b05b183SAnand V. Avati static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file,
12978d3af7f3SAl Viro 			     struct dir_context *ctx, u64 attr_version)
12980b05b183SAnand V. Avati {
12990b05b183SAnand V. Avati 	struct fuse_direntplus *direntplus;
13000b05b183SAnand V. Avati 	struct fuse_dirent *dirent;
13010b05b183SAnand V. Avati 	size_t reclen;
13020b05b183SAnand V. Avati 	int over = 0;
13030b05b183SAnand V. Avati 	int ret;
13040b05b183SAnand V. Avati 
13050b05b183SAnand V. Avati 	while (nbytes >= FUSE_NAME_OFFSET_DIRENTPLUS) {
13060b05b183SAnand V. Avati 		direntplus = (struct fuse_direntplus *) buf;
13070b05b183SAnand V. Avati 		dirent = &direntplus->dirent;
13080b05b183SAnand V. Avati 		reclen = FUSE_DIRENTPLUS_SIZE(direntplus);
13090b05b183SAnand V. Avati 
13100b05b183SAnand V. Avati 		if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
13110b05b183SAnand V. Avati 			return -EIO;
13120b05b183SAnand V. Avati 		if (reclen > nbytes)
13130b05b183SAnand V. Avati 			break;
1314efeb9e60SMiklos Szeredi 		if (memchr(dirent->name, '/', dirent->namelen) != NULL)
1315efeb9e60SMiklos Szeredi 			return -EIO;
13160b05b183SAnand V. Avati 
13170b05b183SAnand V. Avati 		if (!over) {
13180b05b183SAnand V. Avati 			/* We fill entries into dstbuf only as much as
13190b05b183SAnand V. Avati 			   it can hold. But we still continue iterating
13200b05b183SAnand V. Avati 			   over remaining entries to link them. If not,
13210b05b183SAnand V. Avati 			   we need to send a FORGET for each of those
13220b05b183SAnand V. Avati 			   which we did not link.
13230b05b183SAnand V. Avati 			*/
13248d3af7f3SAl Viro 			over = !dir_emit(ctx, dirent->name, dirent->namelen,
13258d3af7f3SAl Viro 				       dirent->ino, dirent->type);
13268d3af7f3SAl Viro 			ctx->pos = dirent->off;
13270b05b183SAnand V. Avati 		}
13280b05b183SAnand V. Avati 
13290b05b183SAnand V. Avati 		buf += reclen;
13300b05b183SAnand V. Avati 		nbytes -= reclen;
13310b05b183SAnand V. Avati 
13320b05b183SAnand V. Avati 		ret = fuse_direntplus_link(file, direntplus, attr_version);
13330b05b183SAnand V. Avati 		if (ret)
13340b05b183SAnand V. Avati 			fuse_force_forget(file, direntplus->entry_out.nodeid);
13350b05b183SAnand V. Avati 	}
13360b05b183SAnand V. Avati 
13370b05b183SAnand V. Avati 	return 0;
13380b05b183SAnand V. Avati }
13390b05b183SAnand V. Avati 
13408d3af7f3SAl Viro static int fuse_readdir(struct file *file, struct dir_context *ctx)
1341e5e5558eSMiklos Szeredi {
13424582a4abSFeng Shuo 	int plus, err;
134304730fefSMiklos Szeredi 	size_t nbytes;
134404730fefSMiklos Szeredi 	struct page *page;
1345496ad9aaSAl Viro 	struct inode *inode = file_inode(file);
134604730fefSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
1347248d86e8SMiklos Szeredi 	struct fuse_req *req;
13480b05b183SAnand V. Avati 	u64 attr_version = 0;
1349248d86e8SMiklos Szeredi 
1350248d86e8SMiklos Szeredi 	if (is_bad_inode(inode))
1351248d86e8SMiklos Szeredi 		return -EIO;
1352248d86e8SMiklos Szeredi 
1353b111c8c0SMaxim Patlasov 	req = fuse_get_req(fc, 1);
1354ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1355ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
1356e5e5558eSMiklos Szeredi 
135704730fefSMiklos Szeredi 	page = alloc_page(GFP_KERNEL);
135804730fefSMiklos Szeredi 	if (!page) {
135904730fefSMiklos Szeredi 		fuse_put_request(fc, req);
1360e5e5558eSMiklos Szeredi 		return -ENOMEM;
136104730fefSMiklos Szeredi 	}
13624582a4abSFeng Shuo 
13638d3af7f3SAl Viro 	plus = fuse_use_readdirplus(inode, ctx);
1364f4975c67SMiklos Szeredi 	req->out.argpages = 1;
136504730fefSMiklos Szeredi 	req->num_pages = 1;
136604730fefSMiklos Szeredi 	req->pages[0] = page;
136785f40aecSMaxim Patlasov 	req->page_descs[0].length = PAGE_SIZE;
13684582a4abSFeng Shuo 	if (plus) {
13690b05b183SAnand V. Avati 		attr_version = fuse_get_attr_version(fc);
13708d3af7f3SAl Viro 		fuse_read_fill(req, file, ctx->pos, PAGE_SIZE,
13710b05b183SAnand V. Avati 			       FUSE_READDIRPLUS);
13720b05b183SAnand V. Avati 	} else {
13738d3af7f3SAl Viro 		fuse_read_fill(req, file, ctx->pos, PAGE_SIZE,
13740b05b183SAnand V. Avati 			       FUSE_READDIR);
13750b05b183SAnand V. Avati 	}
1376b93f858aSTejun Heo 	fuse_request_send(fc, req);
1377361b1eb5SMiklos Szeredi 	nbytes = req->out.args[0].size;
137804730fefSMiklos Szeredi 	err = req->out.h.error;
137904730fefSMiklos Szeredi 	fuse_put_request(fc, req);
13800b05b183SAnand V. Avati 	if (!err) {
13814582a4abSFeng Shuo 		if (plus) {
13820b05b183SAnand V. Avati 			err = parse_dirplusfile(page_address(page), nbytes,
13838d3af7f3SAl Viro 						file, ctx,
13840b05b183SAnand V. Avati 						attr_version);
13850b05b183SAnand V. Avati 		} else {
13860b05b183SAnand V. Avati 			err = parse_dirfile(page_address(page), nbytes, file,
13878d3af7f3SAl Viro 					    ctx);
13880b05b183SAnand V. Avati 		}
13890b05b183SAnand V. Avati 	}
1390e5e5558eSMiklos Szeredi 
139104730fefSMiklos Szeredi 	__free_page(page);
1392451418fcSAndrew Gallagher 	fuse_invalidate_atime(inode);
139304730fefSMiklos Szeredi 	return err;
1394e5e5558eSMiklos Szeredi }
1395e5e5558eSMiklos Szeredi 
1396e5e5558eSMiklos Szeredi static char *read_link(struct dentry *dentry)
1397e5e5558eSMiklos Szeredi {
1398e5e5558eSMiklos Szeredi 	struct inode *inode = dentry->d_inode;
1399e5e5558eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
1400b111c8c0SMaxim Patlasov 	struct fuse_req *req = fuse_get_req_nopages(fc);
1401e5e5558eSMiklos Szeredi 	char *link;
1402e5e5558eSMiklos Szeredi 
1403ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1404e231c2eeSDavid Howells 		return ERR_CAST(req);
1405e5e5558eSMiklos Szeredi 
1406e5e5558eSMiklos Szeredi 	link = (char *) __get_free_page(GFP_KERNEL);
1407e5e5558eSMiklos Szeredi 	if (!link) {
1408e5e5558eSMiklos Szeredi 		link = ERR_PTR(-ENOMEM);
1409e5e5558eSMiklos Szeredi 		goto out;
1410e5e5558eSMiklos Szeredi 	}
1411e5e5558eSMiklos Szeredi 	req->in.h.opcode = FUSE_READLINK;
1412e5e5558eSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
1413e5e5558eSMiklos Szeredi 	req->out.argvar = 1;
1414e5e5558eSMiklos Szeredi 	req->out.numargs = 1;
1415e5e5558eSMiklos Szeredi 	req->out.args[0].size = PAGE_SIZE - 1;
1416e5e5558eSMiklos Szeredi 	req->out.args[0].value = link;
1417b93f858aSTejun Heo 	fuse_request_send(fc, req);
1418e5e5558eSMiklos Szeredi 	if (req->out.h.error) {
1419e5e5558eSMiklos Szeredi 		free_page((unsigned long) link);
1420e5e5558eSMiklos Szeredi 		link = ERR_PTR(req->out.h.error);
1421e5e5558eSMiklos Szeredi 	} else
1422e5e5558eSMiklos Szeredi 		link[req->out.args[0].size] = '\0';
1423e5e5558eSMiklos Szeredi  out:
1424e5e5558eSMiklos Szeredi 	fuse_put_request(fc, req);
1425451418fcSAndrew Gallagher 	fuse_invalidate_atime(inode);
1426e5e5558eSMiklos Szeredi 	return link;
1427e5e5558eSMiklos Szeredi }
1428e5e5558eSMiklos Szeredi 
1429e5e5558eSMiklos Szeredi static void free_link(char *link)
1430e5e5558eSMiklos Szeredi {
1431e5e5558eSMiklos Szeredi 	if (!IS_ERR(link))
1432e5e5558eSMiklos Szeredi 		free_page((unsigned long) link);
1433e5e5558eSMiklos Szeredi }
1434e5e5558eSMiklos Szeredi 
1435e5e5558eSMiklos Szeredi static void *fuse_follow_link(struct dentry *dentry, struct nameidata *nd)
1436e5e5558eSMiklos Szeredi {
1437e5e5558eSMiklos Szeredi 	nd_set_link(nd, read_link(dentry));
1438e5e5558eSMiklos Szeredi 	return NULL;
1439e5e5558eSMiklos Szeredi }
1440e5e5558eSMiklos Szeredi 
1441e5e5558eSMiklos Szeredi static void fuse_put_link(struct dentry *dentry, struct nameidata *nd, void *c)
1442e5e5558eSMiklos Szeredi {
1443e5e5558eSMiklos Szeredi 	free_link(nd_get_link(nd));
1444e5e5558eSMiklos Szeredi }
1445e5e5558eSMiklos Szeredi 
1446e5e5558eSMiklos Szeredi static int fuse_dir_open(struct inode *inode, struct file *file)
1447e5e5558eSMiklos Szeredi {
144891fe96b4SMiklos Szeredi 	return fuse_open_common(inode, file, true);
1449e5e5558eSMiklos Szeredi }
1450e5e5558eSMiklos Szeredi 
1451e5e5558eSMiklos Szeredi static int fuse_dir_release(struct inode *inode, struct file *file)
1452e5e5558eSMiklos Szeredi {
14538b0797a4SMiklos Szeredi 	fuse_release_common(file, FUSE_RELEASEDIR);
14548b0797a4SMiklos Szeredi 
14558b0797a4SMiklos Szeredi 	return 0;
1456e5e5558eSMiklos Szeredi }
1457e5e5558eSMiklos Szeredi 
145802c24a82SJosef Bacik static int fuse_dir_fsync(struct file *file, loff_t start, loff_t end,
145902c24a82SJosef Bacik 			  int datasync)
146082547981SMiklos Szeredi {
146102c24a82SJosef Bacik 	return fuse_fsync_common(file, start, end, datasync, 1);
146282547981SMiklos Szeredi }
146382547981SMiklos Szeredi 
1464b18da0c5SMiklos Szeredi static long fuse_dir_ioctl(struct file *file, unsigned int cmd,
1465b18da0c5SMiklos Szeredi 			    unsigned long arg)
1466b18da0c5SMiklos Szeredi {
1467b18da0c5SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1468b18da0c5SMiklos Szeredi 
1469b18da0c5SMiklos Szeredi 	/* FUSE_IOCTL_DIR only supported for API version >= 7.18 */
1470b18da0c5SMiklos Szeredi 	if (fc->minor < 18)
1471b18da0c5SMiklos Szeredi 		return -ENOTTY;
1472b18da0c5SMiklos Szeredi 
1473b18da0c5SMiklos Szeredi 	return fuse_ioctl_common(file, cmd, arg, FUSE_IOCTL_DIR);
1474b18da0c5SMiklos Szeredi }
1475b18da0c5SMiklos Szeredi 
1476b18da0c5SMiklos Szeredi static long fuse_dir_compat_ioctl(struct file *file, unsigned int cmd,
1477b18da0c5SMiklos Szeredi 				   unsigned long arg)
1478b18da0c5SMiklos Szeredi {
1479b18da0c5SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1480b18da0c5SMiklos Szeredi 
1481b18da0c5SMiklos Szeredi 	if (fc->minor < 18)
1482b18da0c5SMiklos Szeredi 		return -ENOTTY;
1483b18da0c5SMiklos Szeredi 
1484b18da0c5SMiklos Szeredi 	return fuse_ioctl_common(file, cmd, arg,
1485b18da0c5SMiklos Szeredi 				 FUSE_IOCTL_COMPAT | FUSE_IOCTL_DIR);
1486b18da0c5SMiklos Szeredi }
1487b18da0c5SMiklos Szeredi 
1488b0aa7606SMaxim Patlasov static bool update_mtime(unsigned ivalid, bool trust_local_mtime)
148917637cbaSMiklos Szeredi {
149017637cbaSMiklos Szeredi 	/* Always update if mtime is explicitly set  */
149117637cbaSMiklos Szeredi 	if (ivalid & ATTR_MTIME_SET)
149217637cbaSMiklos Szeredi 		return true;
149317637cbaSMiklos Szeredi 
1494b0aa7606SMaxim Patlasov 	/* Or if kernel i_mtime is the official one */
1495b0aa7606SMaxim Patlasov 	if (trust_local_mtime)
1496b0aa7606SMaxim Patlasov 		return true;
1497b0aa7606SMaxim Patlasov 
149817637cbaSMiklos Szeredi 	/* If it's an open(O_TRUNC) or an ftruncate(), don't update */
149917637cbaSMiklos Szeredi 	if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE)))
150017637cbaSMiklos Szeredi 		return false;
150117637cbaSMiklos Szeredi 
150217637cbaSMiklos Szeredi 	/* In all other cases update */
150317637cbaSMiklos Szeredi 	return true;
150417637cbaSMiklos Szeredi }
150517637cbaSMiklos Szeredi 
1506b0aa7606SMaxim Patlasov static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg,
1507b0aa7606SMaxim Patlasov 			   bool trust_local_mtime)
15089e6268dbSMiklos Szeredi {
15099e6268dbSMiklos Szeredi 	unsigned ivalid = iattr->ia_valid;
15109e6268dbSMiklos Szeredi 
15119e6268dbSMiklos Szeredi 	if (ivalid & ATTR_MODE)
1512befc649cSMiklos Szeredi 		arg->valid |= FATTR_MODE,   arg->mode = iattr->ia_mode;
15139e6268dbSMiklos Szeredi 	if (ivalid & ATTR_UID)
1514499dcf20SEric W. Biederman 		arg->valid |= FATTR_UID,    arg->uid = from_kuid(&init_user_ns, iattr->ia_uid);
15159e6268dbSMiklos Szeredi 	if (ivalid & ATTR_GID)
1516499dcf20SEric W. Biederman 		arg->valid |= FATTR_GID,    arg->gid = from_kgid(&init_user_ns, iattr->ia_gid);
15179e6268dbSMiklos Szeredi 	if (ivalid & ATTR_SIZE)
1518befc649cSMiklos Szeredi 		arg->valid |= FATTR_SIZE,   arg->size = iattr->ia_size;
151917637cbaSMiklos Szeredi 	if (ivalid & ATTR_ATIME) {
152017637cbaSMiklos Szeredi 		arg->valid |= FATTR_ATIME;
1521befc649cSMiklos Szeredi 		arg->atime = iattr->ia_atime.tv_sec;
152217637cbaSMiklos Szeredi 		arg->atimensec = iattr->ia_atime.tv_nsec;
152317637cbaSMiklos Szeredi 		if (!(ivalid & ATTR_ATIME_SET))
152417637cbaSMiklos Szeredi 			arg->valid |= FATTR_ATIME_NOW;
152517637cbaSMiklos Szeredi 	}
1526b0aa7606SMaxim Patlasov 	if ((ivalid & ATTR_MTIME) && update_mtime(ivalid, trust_local_mtime)) {
152717637cbaSMiklos Szeredi 		arg->valid |= FATTR_MTIME;
1528befc649cSMiklos Szeredi 		arg->mtime = iattr->ia_mtime.tv_sec;
152917637cbaSMiklos Szeredi 		arg->mtimensec = iattr->ia_mtime.tv_nsec;
1530b0aa7606SMaxim Patlasov 		if (!(ivalid & ATTR_MTIME_SET) && !trust_local_mtime)
153117637cbaSMiklos Szeredi 			arg->valid |= FATTR_MTIME_NOW;
15329e6268dbSMiklos Szeredi 	}
15339e6268dbSMiklos Szeredi }
15349e6268dbSMiklos Szeredi 
15356f9f1180SMiklos Szeredi /*
15363be5a52bSMiklos Szeredi  * Prevent concurrent writepages on inode
15373be5a52bSMiklos Szeredi  *
15383be5a52bSMiklos Szeredi  * This is done by adding a negative bias to the inode write counter
15393be5a52bSMiklos Szeredi  * and waiting for all pending writes to finish.
15403be5a52bSMiklos Szeredi  */
15413be5a52bSMiklos Szeredi void fuse_set_nowrite(struct inode *inode)
15423be5a52bSMiklos Szeredi {
15433be5a52bSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
15443be5a52bSMiklos Szeredi 	struct fuse_inode *fi = get_fuse_inode(inode);
15453be5a52bSMiklos Szeredi 
15463be5a52bSMiklos Szeredi 	BUG_ON(!mutex_is_locked(&inode->i_mutex));
15473be5a52bSMiklos Szeredi 
15483be5a52bSMiklos Szeredi 	spin_lock(&fc->lock);
15493be5a52bSMiklos Szeredi 	BUG_ON(fi->writectr < 0);
15503be5a52bSMiklos Szeredi 	fi->writectr += FUSE_NOWRITE;
15513be5a52bSMiklos Szeredi 	spin_unlock(&fc->lock);
15523be5a52bSMiklos Szeredi 	wait_event(fi->page_waitq, fi->writectr == FUSE_NOWRITE);
15533be5a52bSMiklos Szeredi }
15543be5a52bSMiklos Szeredi 
15553be5a52bSMiklos Szeredi /*
15563be5a52bSMiklos Szeredi  * Allow writepages on inode
15573be5a52bSMiklos Szeredi  *
15583be5a52bSMiklos Szeredi  * Remove the bias from the writecounter and send any queued
15593be5a52bSMiklos Szeredi  * writepages.
15603be5a52bSMiklos Szeredi  */
15613be5a52bSMiklos Szeredi static void __fuse_release_nowrite(struct inode *inode)
15623be5a52bSMiklos Szeredi {
15633be5a52bSMiklos Szeredi 	struct fuse_inode *fi = get_fuse_inode(inode);
15643be5a52bSMiklos Szeredi 
15653be5a52bSMiklos Szeredi 	BUG_ON(fi->writectr != FUSE_NOWRITE);
15663be5a52bSMiklos Szeredi 	fi->writectr = 0;
15673be5a52bSMiklos Szeredi 	fuse_flush_writepages(inode);
15683be5a52bSMiklos Szeredi }
15693be5a52bSMiklos Szeredi 
15703be5a52bSMiklos Szeredi void fuse_release_nowrite(struct inode *inode)
15713be5a52bSMiklos Szeredi {
15723be5a52bSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
15733be5a52bSMiklos Szeredi 
15743be5a52bSMiklos Szeredi 	spin_lock(&fc->lock);
15753be5a52bSMiklos Szeredi 	__fuse_release_nowrite(inode);
15763be5a52bSMiklos Szeredi 	spin_unlock(&fc->lock);
15773be5a52bSMiklos Szeredi }
15783be5a52bSMiklos Szeredi 
1579b0aa7606SMaxim Patlasov static void fuse_setattr_fill(struct fuse_conn *fc, struct fuse_req *req,
1580b0aa7606SMaxim Patlasov 			      struct inode *inode,
1581b0aa7606SMaxim Patlasov 			      struct fuse_setattr_in *inarg_p,
1582b0aa7606SMaxim Patlasov 			      struct fuse_attr_out *outarg_p)
1583b0aa7606SMaxim Patlasov {
1584b0aa7606SMaxim Patlasov 	req->in.h.opcode = FUSE_SETATTR;
1585b0aa7606SMaxim Patlasov 	req->in.h.nodeid = get_node_id(inode);
1586b0aa7606SMaxim Patlasov 	req->in.numargs = 1;
1587b0aa7606SMaxim Patlasov 	req->in.args[0].size = sizeof(*inarg_p);
1588b0aa7606SMaxim Patlasov 	req->in.args[0].value = inarg_p;
1589b0aa7606SMaxim Patlasov 	req->out.numargs = 1;
1590b0aa7606SMaxim Patlasov 	if (fc->minor < 9)
1591b0aa7606SMaxim Patlasov 		req->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
1592b0aa7606SMaxim Patlasov 	else
1593b0aa7606SMaxim Patlasov 		req->out.args[0].size = sizeof(*outarg_p);
1594b0aa7606SMaxim Patlasov 	req->out.args[0].value = outarg_p;
1595b0aa7606SMaxim Patlasov }
1596b0aa7606SMaxim Patlasov 
1597b0aa7606SMaxim Patlasov /*
1598b0aa7606SMaxim Patlasov  * Flush inode->i_mtime to the server
1599b0aa7606SMaxim Patlasov  */
1600*1e18bda8SMiklos Szeredi int fuse_flush_mtime(struct inode *inode, struct fuse_file *ff)
1601b0aa7606SMaxim Patlasov {
1602b0aa7606SMaxim Patlasov 	struct fuse_conn *fc = get_fuse_conn(inode);
1603*1e18bda8SMiklos Szeredi 	struct fuse_req *req;
1604b0aa7606SMaxim Patlasov 	struct fuse_setattr_in inarg;
1605b0aa7606SMaxim Patlasov 	struct fuse_attr_out outarg;
1606b0aa7606SMaxim Patlasov 	int err;
1607b0aa7606SMaxim Patlasov 
1608b0aa7606SMaxim Patlasov 	req = fuse_get_req_nopages(fc);
1609b0aa7606SMaxim Patlasov 	if (IS_ERR(req))
1610b0aa7606SMaxim Patlasov 		return PTR_ERR(req);
1611b0aa7606SMaxim Patlasov 
1612b0aa7606SMaxim Patlasov 	memset(&inarg, 0, sizeof(inarg));
1613b0aa7606SMaxim Patlasov 	memset(&outarg, 0, sizeof(outarg));
1614b0aa7606SMaxim Patlasov 
1615b0aa7606SMaxim Patlasov 	inarg.valid |= FATTR_MTIME;
1616b0aa7606SMaxim Patlasov 	inarg.mtime = inode->i_mtime.tv_sec;
1617b0aa7606SMaxim Patlasov 	inarg.mtimensec = inode->i_mtime.tv_nsec;
1618*1e18bda8SMiklos Szeredi 	if (ff) {
1619*1e18bda8SMiklos Szeredi 		inarg.valid |= FATTR_FH;
1620*1e18bda8SMiklos Szeredi 		inarg.fh = ff->fh;
1621*1e18bda8SMiklos Szeredi 	}
1622b0aa7606SMaxim Patlasov 	fuse_setattr_fill(fc, req, inode, &inarg, &outarg);
1623b0aa7606SMaxim Patlasov 	fuse_request_send(fc, req);
1624b0aa7606SMaxim Patlasov 	err = req->out.h.error;
1625b0aa7606SMaxim Patlasov 	fuse_put_request(fc, req);
1626b0aa7606SMaxim Patlasov 
1627b0aa7606SMaxim Patlasov 	return err;
1628b0aa7606SMaxim Patlasov }
1629b0aa7606SMaxim Patlasov 
16303be5a52bSMiklos Szeredi /*
16316f9f1180SMiklos Szeredi  * Set attributes, and at the same time refresh them.
16326f9f1180SMiklos Szeredi  *
16336f9f1180SMiklos Szeredi  * Truncation is slightly complicated, because the 'truncate' request
16346f9f1180SMiklos Szeredi  * may fail, in which case we don't want to touch the mapping.
16359ffbb916SMiklos Szeredi  * vmtruncate() doesn't allow for this case, so do the rlimit checking
16369ffbb916SMiklos Szeredi  * and the actual truncation by hand.
16376f9f1180SMiklos Szeredi  */
1638efb9fa9eSMaxim Patlasov int fuse_do_setattr(struct inode *inode, struct iattr *attr,
163949d4914fSMiklos Szeredi 		    struct file *file)
16409e6268dbSMiklos Szeredi {
16419e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
164206a7c3c2SMaxim Patlasov 	struct fuse_inode *fi = get_fuse_inode(inode);
16439e6268dbSMiklos Szeredi 	struct fuse_req *req;
16449e6268dbSMiklos Szeredi 	struct fuse_setattr_in inarg;
16459e6268dbSMiklos Szeredi 	struct fuse_attr_out outarg;
16463be5a52bSMiklos Szeredi 	bool is_truncate = false;
16478373200bSPavel Emelyanov 	bool is_wb = fc->writeback_cache;
16483be5a52bSMiklos Szeredi 	loff_t oldsize;
16499e6268dbSMiklos Szeredi 	int err;
1650b0aa7606SMaxim Patlasov 	bool trust_local_mtime = is_wb && S_ISREG(inode->i_mode);
16519e6268dbSMiklos Szeredi 
1652db78b877SChristoph Hellwig 	if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS))
1653db78b877SChristoph Hellwig 		attr->ia_valid |= ATTR_FORCE;
1654db78b877SChristoph Hellwig 
16551e9a4ed9SMiklos Szeredi 	err = inode_change_ok(inode, attr);
16561e9a4ed9SMiklos Szeredi 	if (err)
16571e9a4ed9SMiklos Szeredi 		return err;
16581e9a4ed9SMiklos Szeredi 
16598d56adddSMiklos Szeredi 	if (attr->ia_valid & ATTR_OPEN) {
16608d56adddSMiklos Szeredi 		if (fc->atomic_o_trunc)
16616ff958edSMiklos Szeredi 			return 0;
16628d56adddSMiklos Szeredi 		file = NULL;
16638d56adddSMiklos Szeredi 	}
16646ff958edSMiklos Szeredi 
16652c27c65eSChristoph Hellwig 	if (attr->ia_valid & ATTR_SIZE)
16663be5a52bSMiklos Szeredi 		is_truncate = true;
16679e6268dbSMiklos Szeredi 
1668b111c8c0SMaxim Patlasov 	req = fuse_get_req_nopages(fc);
1669ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1670ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
16719e6268dbSMiklos Szeredi 
167206a7c3c2SMaxim Patlasov 	if (is_truncate) {
16733be5a52bSMiklos Szeredi 		fuse_set_nowrite(inode);
167406a7c3c2SMaxim Patlasov 		set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
1675009dd694SMaxim Patlasov 		if (trust_local_mtime && attr->ia_size != inode->i_size)
1676009dd694SMaxim Patlasov 			attr->ia_valid |= ATTR_MTIME;
167706a7c3c2SMaxim Patlasov 	}
16783be5a52bSMiklos Szeredi 
16799e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
16800e9663eeSMiklos Szeredi 	memset(&outarg, 0, sizeof(outarg));
1681b0aa7606SMaxim Patlasov 	iattr_to_fattr(attr, &inarg, trust_local_mtime);
168249d4914fSMiklos Szeredi 	if (file) {
168349d4914fSMiklos Szeredi 		struct fuse_file *ff = file->private_data;
168449d4914fSMiklos Szeredi 		inarg.valid |= FATTR_FH;
168549d4914fSMiklos Szeredi 		inarg.fh = ff->fh;
168649d4914fSMiklos Szeredi 	}
1687f3332114SMiklos Szeredi 	if (attr->ia_valid & ATTR_SIZE) {
1688f3332114SMiklos Szeredi 		/* For mandatory locking in truncate */
1689f3332114SMiklos Szeredi 		inarg.valid |= FATTR_LOCKOWNER;
1690f3332114SMiklos Szeredi 		inarg.lock_owner = fuse_lock_owner_id(fc, current->files);
1691f3332114SMiklos Szeredi 	}
1692b0aa7606SMaxim Patlasov 	fuse_setattr_fill(fc, req, inode, &inarg, &outarg);
1693b93f858aSTejun Heo 	fuse_request_send(fc, req);
16949e6268dbSMiklos Szeredi 	err = req->out.h.error;
16959e6268dbSMiklos Szeredi 	fuse_put_request(fc, req);
1696e00d2c2dSMiklos Szeredi 	if (err) {
1697e00d2c2dSMiklos Szeredi 		if (err == -EINTR)
1698e00d2c2dSMiklos Szeredi 			fuse_invalidate_attr(inode);
16993be5a52bSMiklos Szeredi 		goto error;
1700e00d2c2dSMiklos Szeredi 	}
1701e00d2c2dSMiklos Szeredi 
17029e6268dbSMiklos Szeredi 	if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
17039e6268dbSMiklos Szeredi 		make_bad_inode(inode);
17043be5a52bSMiklos Szeredi 		err = -EIO;
17053be5a52bSMiklos Szeredi 		goto error;
17069e6268dbSMiklos Szeredi 	}
17079e6268dbSMiklos Szeredi 
17083be5a52bSMiklos Szeredi 	spin_lock(&fc->lock);
1709b0aa7606SMaxim Patlasov 	/* the kernel maintains i_mtime locally */
1710b0aa7606SMaxim Patlasov 	if (trust_local_mtime && (attr->ia_valid & ATTR_MTIME)) {
1711b0aa7606SMaxim Patlasov 		inode->i_mtime = attr->ia_mtime;
1712*1e18bda8SMiklos Szeredi 		/* FIXME: clear I_DIRTY_SYNC? */
1713b0aa7606SMaxim Patlasov 	}
1714b0aa7606SMaxim Patlasov 
17153be5a52bSMiklos Szeredi 	fuse_change_attributes_common(inode, &outarg.attr,
17163be5a52bSMiklos Szeredi 				      attr_timeout(&outarg));
17173be5a52bSMiklos Szeredi 	oldsize = inode->i_size;
17188373200bSPavel Emelyanov 	/* see the comment in fuse_change_attributes() */
17198373200bSPavel Emelyanov 	if (!is_wb || is_truncate || !S_ISREG(inode->i_mode))
17203be5a52bSMiklos Szeredi 		i_size_write(inode, outarg.attr.size);
17213be5a52bSMiklos Szeredi 
17223be5a52bSMiklos Szeredi 	if (is_truncate) {
17233be5a52bSMiklos Szeredi 		/* NOTE: this may release/reacquire fc->lock */
17243be5a52bSMiklos Szeredi 		__fuse_release_nowrite(inode);
17253be5a52bSMiklos Szeredi 	}
17263be5a52bSMiklos Szeredi 	spin_unlock(&fc->lock);
17273be5a52bSMiklos Szeredi 
17283be5a52bSMiklos Szeredi 	/*
17293be5a52bSMiklos Szeredi 	 * Only call invalidate_inode_pages2() after removing
17303be5a52bSMiklos Szeredi 	 * FUSE_NOWRITE, otherwise fuse_launder_page() would deadlock.
17313be5a52bSMiklos Szeredi 	 */
17328373200bSPavel Emelyanov 	if ((is_truncate || !is_wb) &&
17338373200bSPavel Emelyanov 	    S_ISREG(inode->i_mode) && oldsize != outarg.attr.size) {
17347caef267SKirill A. Shutemov 		truncate_pagecache(inode, outarg.attr.size);
17353be5a52bSMiklos Szeredi 		invalidate_inode_pages2(inode->i_mapping);
17363be5a52bSMiklos Szeredi 	}
17373be5a52bSMiklos Szeredi 
173806a7c3c2SMaxim Patlasov 	clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
1739e00d2c2dSMiklos Szeredi 	return 0;
17403be5a52bSMiklos Szeredi 
17413be5a52bSMiklos Szeredi error:
17423be5a52bSMiklos Szeredi 	if (is_truncate)
17433be5a52bSMiklos Szeredi 		fuse_release_nowrite(inode);
17443be5a52bSMiklos Szeredi 
174506a7c3c2SMaxim Patlasov 	clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
17463be5a52bSMiklos Szeredi 	return err;
17479e6268dbSMiklos Szeredi }
17489e6268dbSMiklos Szeredi 
174949d4914fSMiklos Szeredi static int fuse_setattr(struct dentry *entry, struct iattr *attr)
175049d4914fSMiklos Szeredi {
1751efb9fa9eSMaxim Patlasov 	struct inode *inode = entry->d_inode;
1752efb9fa9eSMaxim Patlasov 
1753efb9fa9eSMaxim Patlasov 	if (!fuse_allow_current_process(get_fuse_conn(inode)))
1754efb9fa9eSMaxim Patlasov 		return -EACCES;
1755efb9fa9eSMaxim Patlasov 
175649d4914fSMiklos Szeredi 	if (attr->ia_valid & ATTR_FILE)
1757efb9fa9eSMaxim Patlasov 		return fuse_do_setattr(inode, attr, attr->ia_file);
175849d4914fSMiklos Szeredi 	else
1759efb9fa9eSMaxim Patlasov 		return fuse_do_setattr(inode, attr, NULL);
176049d4914fSMiklos Szeredi }
176149d4914fSMiklos Szeredi 
1762e5e5558eSMiklos Szeredi static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
1763e5e5558eSMiklos Szeredi 			struct kstat *stat)
1764e5e5558eSMiklos Szeredi {
1765e5e5558eSMiklos Szeredi 	struct inode *inode = entry->d_inode;
1766244f6385SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
1767244f6385SMiklos Szeredi 
1768c2132c1bSAnatol Pomozov 	if (!fuse_allow_current_process(fc))
1769244f6385SMiklos Szeredi 		return -EACCES;
1770244f6385SMiklos Szeredi 
1771bcb4be80SMiklos Szeredi 	return fuse_update_attributes(inode, stat, NULL, NULL);
1772e5e5558eSMiklos Szeredi }
1773e5e5558eSMiklos Szeredi 
177492a8780eSMiklos Szeredi static int fuse_setxattr(struct dentry *entry, const char *name,
177592a8780eSMiklos Szeredi 			 const void *value, size_t size, int flags)
177692a8780eSMiklos Szeredi {
177792a8780eSMiklos Szeredi 	struct inode *inode = entry->d_inode;
177892a8780eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
177992a8780eSMiklos Szeredi 	struct fuse_req *req;
178092a8780eSMiklos Szeredi 	struct fuse_setxattr_in inarg;
178192a8780eSMiklos Szeredi 	int err;
178292a8780eSMiklos Szeredi 
178392a8780eSMiklos Szeredi 	if (fc->no_setxattr)
178492a8780eSMiklos Szeredi 		return -EOPNOTSUPP;
178592a8780eSMiklos Szeredi 
1786b111c8c0SMaxim Patlasov 	req = fuse_get_req_nopages(fc);
1787ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1788ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
178992a8780eSMiklos Szeredi 
179092a8780eSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
179192a8780eSMiklos Szeredi 	inarg.size = size;
179292a8780eSMiklos Szeredi 	inarg.flags = flags;
179392a8780eSMiklos Szeredi 	req->in.h.opcode = FUSE_SETXATTR;
179492a8780eSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
179592a8780eSMiklos Szeredi 	req->in.numargs = 3;
179692a8780eSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
179792a8780eSMiklos Szeredi 	req->in.args[0].value = &inarg;
179892a8780eSMiklos Szeredi 	req->in.args[1].size = strlen(name) + 1;
179992a8780eSMiklos Szeredi 	req->in.args[1].value = name;
180092a8780eSMiklos Szeredi 	req->in.args[2].size = size;
180192a8780eSMiklos Szeredi 	req->in.args[2].value = value;
1802b93f858aSTejun Heo 	fuse_request_send(fc, req);
180392a8780eSMiklos Szeredi 	err = req->out.h.error;
180492a8780eSMiklos Szeredi 	fuse_put_request(fc, req);
180592a8780eSMiklos Szeredi 	if (err == -ENOSYS) {
180692a8780eSMiklos Szeredi 		fc->no_setxattr = 1;
180792a8780eSMiklos Szeredi 		err = -EOPNOTSUPP;
180892a8780eSMiklos Szeredi 	}
1809d331a415SAnand Avati 	if (!err)
1810d331a415SAnand Avati 		fuse_invalidate_attr(inode);
181192a8780eSMiklos Szeredi 	return err;
181292a8780eSMiklos Szeredi }
181392a8780eSMiklos Szeredi 
181492a8780eSMiklos Szeredi static ssize_t fuse_getxattr(struct dentry *entry, const char *name,
181592a8780eSMiklos Szeredi 			     void *value, size_t size)
181692a8780eSMiklos Szeredi {
181792a8780eSMiklos Szeredi 	struct inode *inode = entry->d_inode;
181892a8780eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
181992a8780eSMiklos Szeredi 	struct fuse_req *req;
182092a8780eSMiklos Szeredi 	struct fuse_getxattr_in inarg;
182192a8780eSMiklos Szeredi 	struct fuse_getxattr_out outarg;
182292a8780eSMiklos Szeredi 	ssize_t ret;
182392a8780eSMiklos Szeredi 
182492a8780eSMiklos Szeredi 	if (fc->no_getxattr)
182592a8780eSMiklos Szeredi 		return -EOPNOTSUPP;
182692a8780eSMiklos Szeredi 
1827b111c8c0SMaxim Patlasov 	req = fuse_get_req_nopages(fc);
1828ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1829ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
183092a8780eSMiklos Szeredi 
183192a8780eSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
183292a8780eSMiklos Szeredi 	inarg.size = size;
183392a8780eSMiklos Szeredi 	req->in.h.opcode = FUSE_GETXATTR;
183492a8780eSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
183592a8780eSMiklos Szeredi 	req->in.numargs = 2;
183692a8780eSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
183792a8780eSMiklos Szeredi 	req->in.args[0].value = &inarg;
183892a8780eSMiklos Szeredi 	req->in.args[1].size = strlen(name) + 1;
183992a8780eSMiklos Szeredi 	req->in.args[1].value = name;
184092a8780eSMiklos Szeredi 	/* This is really two different operations rolled into one */
184192a8780eSMiklos Szeredi 	req->out.numargs = 1;
184292a8780eSMiklos Szeredi 	if (size) {
184392a8780eSMiklos Szeredi 		req->out.argvar = 1;
184492a8780eSMiklos Szeredi 		req->out.args[0].size = size;
184592a8780eSMiklos Szeredi 		req->out.args[0].value = value;
184692a8780eSMiklos Szeredi 	} else {
184792a8780eSMiklos Szeredi 		req->out.args[0].size = sizeof(outarg);
184892a8780eSMiklos Szeredi 		req->out.args[0].value = &outarg;
184992a8780eSMiklos Szeredi 	}
1850b93f858aSTejun Heo 	fuse_request_send(fc, req);
185192a8780eSMiklos Szeredi 	ret = req->out.h.error;
185292a8780eSMiklos Szeredi 	if (!ret)
185392a8780eSMiklos Szeredi 		ret = size ? req->out.args[0].size : outarg.size;
185492a8780eSMiklos Szeredi 	else {
185592a8780eSMiklos Szeredi 		if (ret == -ENOSYS) {
185692a8780eSMiklos Szeredi 			fc->no_getxattr = 1;
185792a8780eSMiklos Szeredi 			ret = -EOPNOTSUPP;
185892a8780eSMiklos Szeredi 		}
185992a8780eSMiklos Szeredi 	}
186092a8780eSMiklos Szeredi 	fuse_put_request(fc, req);
186192a8780eSMiklos Szeredi 	return ret;
186292a8780eSMiklos Szeredi }
186392a8780eSMiklos Szeredi 
186492a8780eSMiklos Szeredi static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
186592a8780eSMiklos Szeredi {
186692a8780eSMiklos Szeredi 	struct inode *inode = entry->d_inode;
186792a8780eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
186892a8780eSMiklos Szeredi 	struct fuse_req *req;
186992a8780eSMiklos Szeredi 	struct fuse_getxattr_in inarg;
187092a8780eSMiklos Szeredi 	struct fuse_getxattr_out outarg;
187192a8780eSMiklos Szeredi 	ssize_t ret;
187292a8780eSMiklos Szeredi 
1873c2132c1bSAnatol Pomozov 	if (!fuse_allow_current_process(fc))
1874e57ac683SMiklos Szeredi 		return -EACCES;
1875e57ac683SMiklos Szeredi 
187692a8780eSMiklos Szeredi 	if (fc->no_listxattr)
187792a8780eSMiklos Szeredi 		return -EOPNOTSUPP;
187892a8780eSMiklos Szeredi 
1879b111c8c0SMaxim Patlasov 	req = fuse_get_req_nopages(fc);
1880ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1881ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
188292a8780eSMiklos Szeredi 
188392a8780eSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
188492a8780eSMiklos Szeredi 	inarg.size = size;
188592a8780eSMiklos Szeredi 	req->in.h.opcode = FUSE_LISTXATTR;
188692a8780eSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
188792a8780eSMiklos Szeredi 	req->in.numargs = 1;
188892a8780eSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
188992a8780eSMiklos Szeredi 	req->in.args[0].value = &inarg;
189092a8780eSMiklos Szeredi 	/* This is really two different operations rolled into one */
189192a8780eSMiklos Szeredi 	req->out.numargs = 1;
189292a8780eSMiklos Szeredi 	if (size) {
189392a8780eSMiklos Szeredi 		req->out.argvar = 1;
189492a8780eSMiklos Szeredi 		req->out.args[0].size = size;
189592a8780eSMiklos Szeredi 		req->out.args[0].value = list;
189692a8780eSMiklos Szeredi 	} else {
189792a8780eSMiklos Szeredi 		req->out.args[0].size = sizeof(outarg);
189892a8780eSMiklos Szeredi 		req->out.args[0].value = &outarg;
189992a8780eSMiklos Szeredi 	}
1900b93f858aSTejun Heo 	fuse_request_send(fc, req);
190192a8780eSMiklos Szeredi 	ret = req->out.h.error;
190292a8780eSMiklos Szeredi 	if (!ret)
190392a8780eSMiklos Szeredi 		ret = size ? req->out.args[0].size : outarg.size;
190492a8780eSMiklos Szeredi 	else {
190592a8780eSMiklos Szeredi 		if (ret == -ENOSYS) {
190692a8780eSMiklos Szeredi 			fc->no_listxattr = 1;
190792a8780eSMiklos Szeredi 			ret = -EOPNOTSUPP;
190892a8780eSMiklos Szeredi 		}
190992a8780eSMiklos Szeredi 	}
191092a8780eSMiklos Szeredi 	fuse_put_request(fc, req);
191192a8780eSMiklos Szeredi 	return ret;
191292a8780eSMiklos Szeredi }
191392a8780eSMiklos Szeredi 
191492a8780eSMiklos Szeredi static int fuse_removexattr(struct dentry *entry, const char *name)
191592a8780eSMiklos Szeredi {
191692a8780eSMiklos Szeredi 	struct inode *inode = entry->d_inode;
191792a8780eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
191892a8780eSMiklos Szeredi 	struct fuse_req *req;
191992a8780eSMiklos Szeredi 	int err;
192092a8780eSMiklos Szeredi 
192192a8780eSMiklos Szeredi 	if (fc->no_removexattr)
192292a8780eSMiklos Szeredi 		return -EOPNOTSUPP;
192392a8780eSMiklos Szeredi 
1924b111c8c0SMaxim Patlasov 	req = fuse_get_req_nopages(fc);
1925ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1926ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
192792a8780eSMiklos Szeredi 
192892a8780eSMiklos Szeredi 	req->in.h.opcode = FUSE_REMOVEXATTR;
192992a8780eSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
193092a8780eSMiklos Szeredi 	req->in.numargs = 1;
193192a8780eSMiklos Szeredi 	req->in.args[0].size = strlen(name) + 1;
193292a8780eSMiklos Szeredi 	req->in.args[0].value = name;
1933b93f858aSTejun Heo 	fuse_request_send(fc, req);
193492a8780eSMiklos Szeredi 	err = req->out.h.error;
193592a8780eSMiklos Szeredi 	fuse_put_request(fc, req);
193692a8780eSMiklos Szeredi 	if (err == -ENOSYS) {
193792a8780eSMiklos Szeredi 		fc->no_removexattr = 1;
193892a8780eSMiklos Szeredi 		err = -EOPNOTSUPP;
193992a8780eSMiklos Szeredi 	}
1940d331a415SAnand Avati 	if (!err)
1941d331a415SAnand Avati 		fuse_invalidate_attr(inode);
194292a8780eSMiklos Szeredi 	return err;
194392a8780eSMiklos Szeredi }
194492a8780eSMiklos Szeredi 
1945b0aa7606SMaxim Patlasov static int fuse_update_time(struct inode *inode, struct timespec *now,
1946b0aa7606SMaxim Patlasov 			    int flags)
1947b0aa7606SMaxim Patlasov {
1948b0aa7606SMaxim Patlasov 	if (flags & S_MTIME) {
1949b0aa7606SMaxim Patlasov 		inode->i_mtime = *now;
1950*1e18bda8SMiklos Szeredi 		mark_inode_dirty_sync(inode);
1951b0aa7606SMaxim Patlasov 		BUG_ON(!S_ISREG(inode->i_mode));
1952b0aa7606SMaxim Patlasov 	}
1953b0aa7606SMaxim Patlasov 	return 0;
1954b0aa7606SMaxim Patlasov }
1955b0aa7606SMaxim Patlasov 
1956754661f1SArjan van de Ven static const struct inode_operations fuse_dir_inode_operations = {
1957e5e5558eSMiklos Szeredi 	.lookup		= fuse_lookup,
19589e6268dbSMiklos Szeredi 	.mkdir		= fuse_mkdir,
19599e6268dbSMiklos Szeredi 	.symlink	= fuse_symlink,
19609e6268dbSMiklos Szeredi 	.unlink		= fuse_unlink,
19619e6268dbSMiklos Szeredi 	.rmdir		= fuse_rmdir,
19629e6268dbSMiklos Szeredi 	.rename		= fuse_rename,
19639e6268dbSMiklos Szeredi 	.link		= fuse_link,
19649e6268dbSMiklos Szeredi 	.setattr	= fuse_setattr,
19659e6268dbSMiklos Szeredi 	.create		= fuse_create,
1966c8ccbe03SMiklos Szeredi 	.atomic_open	= fuse_atomic_open,
19679e6268dbSMiklos Szeredi 	.mknod		= fuse_mknod,
1968e5e5558eSMiklos Szeredi 	.permission	= fuse_permission,
1969e5e5558eSMiklos Szeredi 	.getattr	= fuse_getattr,
197092a8780eSMiklos Szeredi 	.setxattr	= fuse_setxattr,
197192a8780eSMiklos Szeredi 	.getxattr	= fuse_getxattr,
197292a8780eSMiklos Szeredi 	.listxattr	= fuse_listxattr,
197392a8780eSMiklos Szeredi 	.removexattr	= fuse_removexattr,
1974e5e5558eSMiklos Szeredi };
1975e5e5558eSMiklos Szeredi 
19764b6f5d20SArjan van de Ven static const struct file_operations fuse_dir_operations = {
1977b6aeadedSMiklos Szeredi 	.llseek		= generic_file_llseek,
1978e5e5558eSMiklos Szeredi 	.read		= generic_read_dir,
19798d3af7f3SAl Viro 	.iterate	= fuse_readdir,
1980e5e5558eSMiklos Szeredi 	.open		= fuse_dir_open,
1981e5e5558eSMiklos Szeredi 	.release	= fuse_dir_release,
198282547981SMiklos Szeredi 	.fsync		= fuse_dir_fsync,
1983b18da0c5SMiklos Szeredi 	.unlocked_ioctl	= fuse_dir_ioctl,
1984b18da0c5SMiklos Szeredi 	.compat_ioctl	= fuse_dir_compat_ioctl,
1985e5e5558eSMiklos Szeredi };
1986e5e5558eSMiklos Szeredi 
1987754661f1SArjan van de Ven static const struct inode_operations fuse_common_inode_operations = {
19889e6268dbSMiklos Szeredi 	.setattr	= fuse_setattr,
1989e5e5558eSMiklos Szeredi 	.permission	= fuse_permission,
1990e5e5558eSMiklos Szeredi 	.getattr	= fuse_getattr,
199192a8780eSMiklos Szeredi 	.setxattr	= fuse_setxattr,
199292a8780eSMiklos Szeredi 	.getxattr	= fuse_getxattr,
199392a8780eSMiklos Szeredi 	.listxattr	= fuse_listxattr,
199492a8780eSMiklos Szeredi 	.removexattr	= fuse_removexattr,
1995b0aa7606SMaxim Patlasov 	.update_time	= fuse_update_time,
1996e5e5558eSMiklos Szeredi };
1997e5e5558eSMiklos Szeredi 
1998754661f1SArjan van de Ven static const struct inode_operations fuse_symlink_inode_operations = {
19999e6268dbSMiklos Szeredi 	.setattr	= fuse_setattr,
2000e5e5558eSMiklos Szeredi 	.follow_link	= fuse_follow_link,
2001e5e5558eSMiklos Szeredi 	.put_link	= fuse_put_link,
2002e5e5558eSMiklos Szeredi 	.readlink	= generic_readlink,
2003e5e5558eSMiklos Szeredi 	.getattr	= fuse_getattr,
200492a8780eSMiklos Szeredi 	.setxattr	= fuse_setxattr,
200592a8780eSMiklos Szeredi 	.getxattr	= fuse_getxattr,
200692a8780eSMiklos Szeredi 	.listxattr	= fuse_listxattr,
200792a8780eSMiklos Szeredi 	.removexattr	= fuse_removexattr,
2008e5e5558eSMiklos Szeredi };
2009e5e5558eSMiklos Szeredi 
2010e5e5558eSMiklos Szeredi void fuse_init_common(struct inode *inode)
2011e5e5558eSMiklos Szeredi {
2012e5e5558eSMiklos Szeredi 	inode->i_op = &fuse_common_inode_operations;
2013e5e5558eSMiklos Szeredi }
2014e5e5558eSMiklos Szeredi 
2015e5e5558eSMiklos Szeredi void fuse_init_dir(struct inode *inode)
2016e5e5558eSMiklos Szeredi {
2017e5e5558eSMiklos Szeredi 	inode->i_op = &fuse_dir_inode_operations;
2018e5e5558eSMiklos Szeredi 	inode->i_fop = &fuse_dir_operations;
2019e5e5558eSMiklos Szeredi }
2020e5e5558eSMiklos Szeredi 
2021e5e5558eSMiklos Szeredi void fuse_init_symlink(struct inode *inode)
2022e5e5558eSMiklos Szeredi {
2023e5e5558eSMiklos Szeredi 	inode->i_op = &fuse_symlink_inode_operations;
2024e5e5558eSMiklos Szeredi }
2025