xref: /openbmc/linux/fs/fuse/dir.c (revision 7caef26767c1727d7abfbbbfbe8b2bb473430d48)
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 
1156f9f1180SMiklos Szeredi /*
1166f9f1180SMiklos Szeredi  * Just mark the entry as stale, so that a next attempt to look it up
1176f9f1180SMiklos Szeredi  * will result in a new lookup call to userspace
1186f9f1180SMiklos Szeredi  *
1196f9f1180SMiklos Szeredi  * This is called when a dentry is about to become negative and the
1206f9f1180SMiklos Szeredi  * timeout is unknown (unlink, rmdir, rename and in some cases
1216f9f1180SMiklos Szeredi  * lookup)
1226f9f1180SMiklos Szeredi  */
123dbd561d2SMiklos Szeredi void fuse_invalidate_entry_cache(struct dentry *entry)
1248cbdf1e6SMiklos Szeredi {
1250a0898cfSMiklos Szeredi 	fuse_dentry_settime(entry, 0);
1268cbdf1e6SMiklos Szeredi }
1278cbdf1e6SMiklos Szeredi 
1286f9f1180SMiklos Szeredi /*
1296f9f1180SMiklos Szeredi  * Same as fuse_invalidate_entry_cache(), but also try to remove the
1306f9f1180SMiklos Szeredi  * dentry from the hash
1316f9f1180SMiklos Szeredi  */
1328cbdf1e6SMiklos Szeredi static void fuse_invalidate_entry(struct dentry *entry)
1338cbdf1e6SMiklos Szeredi {
1348cbdf1e6SMiklos Szeredi 	d_invalidate(entry);
1358cbdf1e6SMiklos Szeredi 	fuse_invalidate_entry_cache(entry);
1360aa7c699SMiklos Szeredi }
1370aa7c699SMiklos Szeredi 
138c180eebeSMiklos Szeredi static void fuse_lookup_init(struct fuse_conn *fc, struct fuse_req *req,
139c180eebeSMiklos Szeredi 			     u64 nodeid, struct qstr *name,
140e5e5558eSMiklos Szeredi 			     struct fuse_entry_out *outarg)
141e5e5558eSMiklos Szeredi {
1420e9663eeSMiklos Szeredi 	memset(outarg, 0, sizeof(struct fuse_entry_out));
143e5e5558eSMiklos Szeredi 	req->in.h.opcode = FUSE_LOOKUP;
144c180eebeSMiklos Szeredi 	req->in.h.nodeid = nodeid;
145e5e5558eSMiklos Szeredi 	req->in.numargs = 1;
146c180eebeSMiklos Szeredi 	req->in.args[0].size = name->len + 1;
147c180eebeSMiklos Szeredi 	req->in.args[0].value = name->name;
148e5e5558eSMiklos Szeredi 	req->out.numargs = 1;
1490e9663eeSMiklos Szeredi 	if (fc->minor < 9)
1500e9663eeSMiklos Szeredi 		req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
1510e9663eeSMiklos Szeredi 	else
152e5e5558eSMiklos Szeredi 		req->out.args[0].size = sizeof(struct fuse_entry_out);
153e5e5558eSMiklos Szeredi 	req->out.args[0].value = outarg;
154e5e5558eSMiklos Szeredi }
155e5e5558eSMiklos Szeredi 
1565c5c5e51SMiklos Szeredi u64 fuse_get_attr_version(struct fuse_conn *fc)
1577dca9fd3SMiklos Szeredi {
1587dca9fd3SMiklos Szeredi 	u64 curr_version;
1597dca9fd3SMiklos Szeredi 
1607dca9fd3SMiklos Szeredi 	/*
1617dca9fd3SMiklos Szeredi 	 * The spin lock isn't actually needed on 64bit archs, but we
1627dca9fd3SMiklos Szeredi 	 * don't yet care too much about such optimizations.
1637dca9fd3SMiklos Szeredi 	 */
1647dca9fd3SMiklos Szeredi 	spin_lock(&fc->lock);
1657dca9fd3SMiklos Szeredi 	curr_version = fc->attr_version;
1667dca9fd3SMiklos Szeredi 	spin_unlock(&fc->lock);
1677dca9fd3SMiklos Szeredi 
1687dca9fd3SMiklos Szeredi 	return curr_version;
1697dca9fd3SMiklos Szeredi }
1707dca9fd3SMiklos Szeredi 
1716f9f1180SMiklos Szeredi /*
1726f9f1180SMiklos Szeredi  * Check whether the dentry is still valid
1736f9f1180SMiklos Szeredi  *
1746f9f1180SMiklos Szeredi  * If the entry validity timeout has expired and the dentry is
1756f9f1180SMiklos Szeredi  * positive, try to redo the lookup.  If the lookup results in a
1766f9f1180SMiklos Szeredi  * different inode, then let the VFS invalidate the dentry and redo
1776f9f1180SMiklos Szeredi  * the lookup once more.  If the lookup results in the same inode,
1786f9f1180SMiklos Szeredi  * then refresh the attributes, timeouts and mark the dentry valid.
1796f9f1180SMiklos Szeredi  */
1800b728e19SAl Viro static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
181e5e5558eSMiklos Szeredi {
18234286d66SNick Piggin 	struct inode *inode;
18328420dadSMiklos Szeredi 	struct dentry *parent;
18428420dadSMiklos Szeredi 	struct fuse_conn *fc;
185e2a6b952SMiklos Szeredi 	int ret;
1868cbdf1e6SMiklos Szeredi 
187e7c0a167SMiklos Szeredi 	inode = ACCESS_ONCE(entry->d_inode);
1888cbdf1e6SMiklos Szeredi 	if (inode && is_bad_inode(inode))
189e2a6b952SMiklos Szeredi 		goto invalid;
1900a0898cfSMiklos Szeredi 	else if (fuse_dentry_time(entry) < get_jiffies_64()) {
191e5e5558eSMiklos Szeredi 		int err;
192e5e5558eSMiklos Szeredi 		struct fuse_entry_out outarg;
1938cbdf1e6SMiklos Szeredi 		struct fuse_req *req;
19407e77dcaSMiklos Szeredi 		struct fuse_forget_link *forget;
1951fb69e78SMiklos Szeredi 		u64 attr_version;
1968cbdf1e6SMiklos Szeredi 
19750322fe7SMiklos Szeredi 		/* For negative dentries, always do a fresh lookup */
1988cbdf1e6SMiklos Szeredi 		if (!inode)
199e2a6b952SMiklos Szeredi 			goto invalid;
2008cbdf1e6SMiklos Szeredi 
201e2a6b952SMiklos Szeredi 		ret = -ECHILD;
2020b728e19SAl Viro 		if (flags & LOOKUP_RCU)
203e2a6b952SMiklos Szeredi 			goto out;
204e7c0a167SMiklos Szeredi 
2058cbdf1e6SMiklos Szeredi 		fc = get_fuse_conn(inode);
206b111c8c0SMaxim Patlasov 		req = fuse_get_req_nopages(fc);
207e2a6b952SMiklos Szeredi 		ret = PTR_ERR(req);
208ce1d5a49SMiklos Szeredi 		if (IS_ERR(req))
209e2a6b952SMiklos Szeredi 			goto out;
210e5e5558eSMiklos Szeredi 
21107e77dcaSMiklos Szeredi 		forget = fuse_alloc_forget();
21207e77dcaSMiklos Szeredi 		if (!forget) {
2132d51013eSMiklos Szeredi 			fuse_put_request(fc, req);
214e2a6b952SMiklos Szeredi 			ret = -ENOMEM;
215e2a6b952SMiklos Szeredi 			goto out;
2162d51013eSMiklos Szeredi 		}
2172d51013eSMiklos Szeredi 
2187dca9fd3SMiklos Szeredi 		attr_version = fuse_get_attr_version(fc);
2191fb69e78SMiklos Szeredi 
220e956edd0SMiklos Szeredi 		parent = dget_parent(entry);
221c180eebeSMiklos Szeredi 		fuse_lookup_init(fc, req, get_node_id(parent->d_inode),
222c180eebeSMiklos Szeredi 				 &entry->d_name, &outarg);
223b93f858aSTejun Heo 		fuse_request_send(fc, req);
224e956edd0SMiklos Szeredi 		dput(parent);
225e5e5558eSMiklos Szeredi 		err = req->out.h.error;
2262d51013eSMiklos Szeredi 		fuse_put_request(fc, req);
22750322fe7SMiklos Szeredi 		/* Zero nodeid is same as -ENOENT */
22850322fe7SMiklos Szeredi 		if (!err && !outarg.nodeid)
22950322fe7SMiklos Szeredi 			err = -ENOENT;
2309e6268dbSMiklos Szeredi 		if (!err) {
2318cbdf1e6SMiklos Szeredi 			struct fuse_inode *fi = get_fuse_inode(inode);
2329e6268dbSMiklos Szeredi 			if (outarg.nodeid != get_node_id(inode)) {
23307e77dcaSMiklos Szeredi 				fuse_queue_forget(fc, forget, outarg.nodeid, 1);
234e2a6b952SMiklos Szeredi 				goto invalid;
2359e6268dbSMiklos Szeredi 			}
2368da5ff23SMiklos Szeredi 			spin_lock(&fc->lock);
2379e6268dbSMiklos Szeredi 			fi->nlookup++;
2388da5ff23SMiklos Szeredi 			spin_unlock(&fc->lock);
2399e6268dbSMiklos Szeredi 		}
24007e77dcaSMiklos Szeredi 		kfree(forget);
2419e6268dbSMiklos Szeredi 		if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
242e2a6b952SMiklos Szeredi 			goto invalid;
243e5e5558eSMiklos Szeredi 
2441fb69e78SMiklos Szeredi 		fuse_change_attributes(inode, &outarg.attr,
2451fb69e78SMiklos Szeredi 				       entry_attr_timeout(&outarg),
2461fb69e78SMiklos Szeredi 				       attr_version);
2471fb69e78SMiklos Szeredi 		fuse_change_entry_timeout(entry, &outarg);
24828420dadSMiklos Szeredi 	} else if (inode) {
24928420dadSMiklos Szeredi 		fc = get_fuse_conn(inode);
25028420dadSMiklos Szeredi 		if (fc->readdirplus_auto) {
25128420dadSMiklos Szeredi 			parent = dget_parent(entry);
25228420dadSMiklos Szeredi 			fuse_advise_use_readdirplus(parent->d_inode);
25328420dadSMiklos Szeredi 			dput(parent);
254e5e5558eSMiklos Szeredi 		}
25528420dadSMiklos Szeredi 	}
256e2a6b952SMiklos Szeredi 	ret = 1;
257e2a6b952SMiklos Szeredi out:
258e2a6b952SMiklos Szeredi 	return ret;
259e2a6b952SMiklos Szeredi 
260e2a6b952SMiklos Szeredi invalid:
261e2a6b952SMiklos Szeredi 	ret = 0;
26246ea1562SAnand Avati 	if (check_submounts_and_drop(entry) != 0)
26346ea1562SAnand Avati 		ret = 1;
264e2a6b952SMiklos Szeredi 	goto out;
265e5e5558eSMiklos Szeredi }
266e5e5558eSMiklos Szeredi 
2678bfc016dSMiklos Szeredi static int invalid_nodeid(u64 nodeid)
2682827d0b2SMiklos Szeredi {
2692827d0b2SMiklos Szeredi 	return !nodeid || nodeid == FUSE_ROOT_ID;
2702827d0b2SMiklos Szeredi }
2712827d0b2SMiklos Szeredi 
2724269590aSAl Viro const struct dentry_operations fuse_dentry_operations = {
273e5e5558eSMiklos Szeredi 	.d_revalidate	= fuse_dentry_revalidate,
274e5e5558eSMiklos Szeredi };
275e5e5558eSMiklos Szeredi 
276a5bfffacSTimo Savola int fuse_valid_type(int m)
27739ee059aSMiklos Szeredi {
27839ee059aSMiklos Szeredi 	return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) ||
27939ee059aSMiklos Szeredi 		S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
28039ee059aSMiklos Szeredi }
28139ee059aSMiklos Szeredi 
282c180eebeSMiklos Szeredi int fuse_lookup_name(struct super_block *sb, u64 nodeid, struct qstr *name,
283c180eebeSMiklos Szeredi 		     struct fuse_entry_out *outarg, struct inode **inode)
284c180eebeSMiklos Szeredi {
285c180eebeSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn_super(sb);
286c180eebeSMiklos Szeredi 	struct fuse_req *req;
28707e77dcaSMiklos Szeredi 	struct fuse_forget_link *forget;
288c180eebeSMiklos Szeredi 	u64 attr_version;
289c180eebeSMiklos Szeredi 	int err;
290c180eebeSMiklos Szeredi 
291c180eebeSMiklos Szeredi 	*inode = NULL;
292c180eebeSMiklos Szeredi 	err = -ENAMETOOLONG;
293c180eebeSMiklos Szeredi 	if (name->len > FUSE_NAME_MAX)
294c180eebeSMiklos Szeredi 		goto out;
295c180eebeSMiklos Szeredi 
296b111c8c0SMaxim Patlasov 	req = fuse_get_req_nopages(fc);
297c180eebeSMiklos Szeredi 	err = PTR_ERR(req);
298c180eebeSMiklos Szeredi 	if (IS_ERR(req))
299c180eebeSMiklos Szeredi 		goto out;
300c180eebeSMiklos Szeredi 
30107e77dcaSMiklos Szeredi 	forget = fuse_alloc_forget();
30207e77dcaSMiklos Szeredi 	err = -ENOMEM;
30307e77dcaSMiklos Szeredi 	if (!forget) {
304c180eebeSMiklos Szeredi 		fuse_put_request(fc, req);
305c180eebeSMiklos Szeredi 		goto out;
306c180eebeSMiklos Szeredi 	}
307c180eebeSMiklos Szeredi 
308c180eebeSMiklos Szeredi 	attr_version = fuse_get_attr_version(fc);
309c180eebeSMiklos Szeredi 
310c180eebeSMiklos Szeredi 	fuse_lookup_init(fc, req, nodeid, name, outarg);
311b93f858aSTejun Heo 	fuse_request_send(fc, req);
312c180eebeSMiklos Szeredi 	err = req->out.h.error;
313c180eebeSMiklos Szeredi 	fuse_put_request(fc, req);
314c180eebeSMiklos Szeredi 	/* Zero nodeid is same as -ENOENT, but with valid timeout */
315c180eebeSMiklos Szeredi 	if (err || !outarg->nodeid)
316c180eebeSMiklos Szeredi 		goto out_put_forget;
317c180eebeSMiklos Szeredi 
318c180eebeSMiklos Szeredi 	err = -EIO;
319c180eebeSMiklos Szeredi 	if (!outarg->nodeid)
320c180eebeSMiklos Szeredi 		goto out_put_forget;
321c180eebeSMiklos Szeredi 	if (!fuse_valid_type(outarg->attr.mode))
322c180eebeSMiklos Szeredi 		goto out_put_forget;
323c180eebeSMiklos Szeredi 
324c180eebeSMiklos Szeredi 	*inode = fuse_iget(sb, outarg->nodeid, outarg->generation,
325c180eebeSMiklos Szeredi 			   &outarg->attr, entry_attr_timeout(outarg),
326c180eebeSMiklos Szeredi 			   attr_version);
327c180eebeSMiklos Szeredi 	err = -ENOMEM;
328c180eebeSMiklos Szeredi 	if (!*inode) {
32907e77dcaSMiklos Szeredi 		fuse_queue_forget(fc, forget, outarg->nodeid, 1);
330c180eebeSMiklos Szeredi 		goto out;
331c180eebeSMiklos Szeredi 	}
332c180eebeSMiklos Szeredi 	err = 0;
333c180eebeSMiklos Szeredi 
334c180eebeSMiklos Szeredi  out_put_forget:
33507e77dcaSMiklos Szeredi 	kfree(forget);
336c180eebeSMiklos Szeredi  out:
337c180eebeSMiklos Szeredi 	return err;
338c180eebeSMiklos Szeredi }
339c180eebeSMiklos Szeredi 
3405835f339SMiklos Szeredi static struct dentry *fuse_materialise_dentry(struct dentry *dentry,
3415835f339SMiklos Szeredi 					      struct inode *inode)
3425835f339SMiklos Szeredi {
3435835f339SMiklos Szeredi 	struct dentry *newent;
3445835f339SMiklos Szeredi 
3455835f339SMiklos Szeredi 	if (inode && S_ISDIR(inode->i_mode)) {
3465835f339SMiklos Szeredi 		struct fuse_conn *fc = get_fuse_conn(inode);
3475835f339SMiklos Szeredi 
3485835f339SMiklos Szeredi 		mutex_lock(&fc->inst_mutex);
3495835f339SMiklos Szeredi 		newent = d_materialise_unique(dentry, inode);
3505835f339SMiklos Szeredi 		mutex_unlock(&fc->inst_mutex);
3515835f339SMiklos Szeredi 	} else {
3525835f339SMiklos Szeredi 		newent = d_materialise_unique(dentry, inode);
3535835f339SMiklos Szeredi 	}
3545835f339SMiklos Szeredi 
3555835f339SMiklos Szeredi 	return newent;
3565835f339SMiklos Szeredi }
3575835f339SMiklos Szeredi 
3580aa7c699SMiklos Szeredi static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
35900cd8dd3SAl Viro 				  unsigned int flags)
360e5e5558eSMiklos Szeredi {
361e5e5558eSMiklos Szeredi 	int err;
362e5e5558eSMiklos Szeredi 	struct fuse_entry_out outarg;
363c180eebeSMiklos Szeredi 	struct inode *inode;
3640de6256dSMiklos Szeredi 	struct dentry *newent;
365c180eebeSMiklos Szeredi 	bool outarg_valid = true;
366e5e5558eSMiklos Szeredi 
367c180eebeSMiklos Szeredi 	err = fuse_lookup_name(dir->i_sb, get_node_id(dir), &entry->d_name,
368c180eebeSMiklos Szeredi 			       &outarg, &inode);
369c180eebeSMiklos Szeredi 	if (err == -ENOENT) {
370c180eebeSMiklos Szeredi 		outarg_valid = false;
371c180eebeSMiklos Szeredi 		err = 0;
3722d51013eSMiklos Szeredi 	}
373c180eebeSMiklos Szeredi 	if (err)
374c180eebeSMiklos Szeredi 		goto out_err;
3752d51013eSMiklos Szeredi 
376ee4e5271SMiklos Szeredi 	err = -EIO;
377c180eebeSMiklos Szeredi 	if (inode && get_node_id(inode) == FUSE_ROOT_ID)
378c180eebeSMiklos Szeredi 		goto out_iput;
379e5e5558eSMiklos Szeredi 
3805835f339SMiklos Szeredi 	newent = fuse_materialise_dentry(entry, inode);
381c180eebeSMiklos Szeredi 	err = PTR_ERR(newent);
382c180eebeSMiklos Szeredi 	if (IS_ERR(newent))
3835835f339SMiklos Szeredi 		goto out_err;
384d2a85164SMiklos Szeredi 
3850de6256dSMiklos Szeredi 	entry = newent ? newent : entry;
386c180eebeSMiklos Szeredi 	if (outarg_valid)
3871fb69e78SMiklos Szeredi 		fuse_change_entry_timeout(entry, &outarg);
3888cbdf1e6SMiklos Szeredi 	else
3898cbdf1e6SMiklos Szeredi 		fuse_invalidate_entry_cache(entry);
390c180eebeSMiklos Szeredi 
3914582a4abSFeng Shuo 	fuse_advise_use_readdirplus(dir);
3920de6256dSMiklos Szeredi 	return newent;
393c180eebeSMiklos Szeredi 
394c180eebeSMiklos Szeredi  out_iput:
395c180eebeSMiklos Szeredi 	iput(inode);
396c180eebeSMiklos Szeredi  out_err:
397c180eebeSMiklos Szeredi 	return ERR_PTR(err);
398e5e5558eSMiklos Szeredi }
399e5e5558eSMiklos Szeredi 
4006f9f1180SMiklos Szeredi /*
4016f9f1180SMiklos Szeredi  * Atomic create+open operation
4026f9f1180SMiklos Szeredi  *
4036f9f1180SMiklos Szeredi  * If the filesystem doesn't support this, then fall back to separate
4046f9f1180SMiklos Szeredi  * 'mknod' + 'open' requests.
4056f9f1180SMiklos Szeredi  */
406d9585277SAl Viro static int fuse_create_open(struct inode *dir, struct dentry *entry,
40730d90494SAl Viro 			    struct file *file, unsigned flags,
40847237687SAl Viro 			    umode_t mode, int *opened)
409fd72faacSMiklos Szeredi {
410fd72faacSMiklos Szeredi 	int err;
411fd72faacSMiklos Szeredi 	struct inode *inode;
412fd72faacSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
413fd72faacSMiklos Szeredi 	struct fuse_req *req;
41407e77dcaSMiklos Szeredi 	struct fuse_forget_link *forget;
415e0a43ddcSMiklos Szeredi 	struct fuse_create_in inarg;
416fd72faacSMiklos Szeredi 	struct fuse_open_out outopen;
417fd72faacSMiklos Szeredi 	struct fuse_entry_out outentry;
418fd72faacSMiklos Szeredi 	struct fuse_file *ff;
419fd72faacSMiklos Szeredi 
420af109bcaSMiklos Szeredi 	/* Userspace expects S_IFREG in create mode */
421af109bcaSMiklos Szeredi 	BUG_ON((mode & S_IFMT) != S_IFREG);
422af109bcaSMiklos Szeredi 
42307e77dcaSMiklos Szeredi 	forget = fuse_alloc_forget();
424c8ccbe03SMiklos Szeredi 	err = -ENOMEM;
42507e77dcaSMiklos Szeredi 	if (!forget)
426c8ccbe03SMiklos Szeredi 		goto out_err;
42751eb01e7SMiklos Szeredi 
428b111c8c0SMaxim Patlasov 	req = fuse_get_req_nopages(fc);
42951eb01e7SMiklos Szeredi 	err = PTR_ERR(req);
430ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
43151eb01e7SMiklos Szeredi 		goto out_put_forget_req;
432fd72faacSMiklos Szeredi 
433ce1d5a49SMiklos Szeredi 	err = -ENOMEM;
434acf99433STejun Heo 	ff = fuse_file_alloc(fc);
435fd72faacSMiklos Szeredi 	if (!ff)
436fd72faacSMiklos Szeredi 		goto out_put_request;
437fd72faacSMiklos Szeredi 
438e0a43ddcSMiklos Szeredi 	if (!fc->dont_mask)
439e0a43ddcSMiklos Szeredi 		mode &= ~current_umask();
440e0a43ddcSMiklos Szeredi 
441fd72faacSMiklos Szeredi 	flags &= ~O_NOCTTY;
442fd72faacSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
4430e9663eeSMiklos Szeredi 	memset(&outentry, 0, sizeof(outentry));
444fd72faacSMiklos Szeredi 	inarg.flags = flags;
445fd72faacSMiklos Szeredi 	inarg.mode = mode;
446e0a43ddcSMiklos Szeredi 	inarg.umask = current_umask();
447fd72faacSMiklos Szeredi 	req->in.h.opcode = FUSE_CREATE;
448fd72faacSMiklos Szeredi 	req->in.h.nodeid = get_node_id(dir);
449fd72faacSMiklos Szeredi 	req->in.numargs = 2;
450e0a43ddcSMiklos Szeredi 	req->in.args[0].size = fc->minor < 12 ? sizeof(struct fuse_open_in) :
451e0a43ddcSMiklos Szeredi 						sizeof(inarg);
452fd72faacSMiklos Szeredi 	req->in.args[0].value = &inarg;
453fd72faacSMiklos Szeredi 	req->in.args[1].size = entry->d_name.len + 1;
454fd72faacSMiklos Szeredi 	req->in.args[1].value = entry->d_name.name;
455fd72faacSMiklos Szeredi 	req->out.numargs = 2;
4560e9663eeSMiklos Szeredi 	if (fc->minor < 9)
4570e9663eeSMiklos Szeredi 		req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
4580e9663eeSMiklos Szeredi 	else
459fd72faacSMiklos Szeredi 		req->out.args[0].size = sizeof(outentry);
460fd72faacSMiklos Szeredi 	req->out.args[0].value = &outentry;
461fd72faacSMiklos Szeredi 	req->out.args[1].size = sizeof(outopen);
462fd72faacSMiklos Szeredi 	req->out.args[1].value = &outopen;
463b93f858aSTejun Heo 	fuse_request_send(fc, req);
464fd72faacSMiklos Szeredi 	err = req->out.h.error;
465c8ccbe03SMiklos Szeredi 	if (err)
466fd72faacSMiklos Szeredi 		goto out_free_ff;
467fd72faacSMiklos Szeredi 
468fd72faacSMiklos Szeredi 	err = -EIO;
4692827d0b2SMiklos Szeredi 	if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid))
470fd72faacSMiklos Szeredi 		goto out_free_ff;
471fd72faacSMiklos Szeredi 
47251eb01e7SMiklos Szeredi 	fuse_put_request(fc, req);
473c7b7143cSMiklos Szeredi 	ff->fh = outopen.fh;
474c7b7143cSMiklos Szeredi 	ff->nodeid = outentry.nodeid;
475c7b7143cSMiklos Szeredi 	ff->open_flags = outopen.open_flags;
476fd72faacSMiklos Szeredi 	inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
4771fb69e78SMiklos Szeredi 			  &outentry.attr, entry_attr_timeout(&outentry), 0);
478fd72faacSMiklos Szeredi 	if (!inode) {
479fd72faacSMiklos Szeredi 		flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
4808b0797a4SMiklos Szeredi 		fuse_sync_release(ff, flags);
48107e77dcaSMiklos Szeredi 		fuse_queue_forget(fc, forget, outentry.nodeid, 1);
482c8ccbe03SMiklos Szeredi 		err = -ENOMEM;
483c8ccbe03SMiklos Szeredi 		goto out_err;
484fd72faacSMiklos Szeredi 	}
48507e77dcaSMiklos Szeredi 	kfree(forget);
486fd72faacSMiklos Szeredi 	d_instantiate(entry, inode);
4871fb69e78SMiklos Szeredi 	fuse_change_entry_timeout(entry, &outentry);
4880952b2a4SMiklos Szeredi 	fuse_invalidate_attr(dir);
48930d90494SAl Viro 	err = finish_open(file, entry, generic_file_open, opened);
49030d90494SAl Viro 	if (err) {
4918b0797a4SMiklos Szeredi 		fuse_sync_release(ff, flags);
492c8ccbe03SMiklos Szeredi 	} else {
493c7b7143cSMiklos Szeredi 		file->private_data = fuse_file_get(ff);
494c7b7143cSMiklos Szeredi 		fuse_finish_open(inode, file);
495c8ccbe03SMiklos Szeredi 	}
496d9585277SAl Viro 	return err;
497fd72faacSMiklos Szeredi 
498fd72faacSMiklos Szeredi out_free_ff:
499fd72faacSMiklos Szeredi 	fuse_file_free(ff);
500fd72faacSMiklos Szeredi out_put_request:
501fd72faacSMiklos Szeredi 	fuse_put_request(fc, req);
50251eb01e7SMiklos Szeredi out_put_forget_req:
50307e77dcaSMiklos Szeredi 	kfree(forget);
504c8ccbe03SMiklos Szeredi out_err:
505d9585277SAl Viro 	return err;
506c8ccbe03SMiklos Szeredi }
507c8ccbe03SMiklos Szeredi 
508c8ccbe03SMiklos Szeredi static int fuse_mknod(struct inode *, struct dentry *, umode_t, dev_t);
509d9585277SAl Viro static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
51030d90494SAl Viro 			    struct file *file, unsigned flags,
51147237687SAl Viro 			    umode_t mode, int *opened)
512c8ccbe03SMiklos Szeredi {
513c8ccbe03SMiklos Szeredi 	int err;
514c8ccbe03SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
515c8ccbe03SMiklos Szeredi 	struct dentry *res = NULL;
516c8ccbe03SMiklos Szeredi 
517c8ccbe03SMiklos Szeredi 	if (d_unhashed(entry)) {
51800cd8dd3SAl Viro 		res = fuse_lookup(dir, entry, 0);
519c8ccbe03SMiklos Szeredi 		if (IS_ERR(res))
520d9585277SAl Viro 			return PTR_ERR(res);
521c8ccbe03SMiklos Szeredi 
522c8ccbe03SMiklos Szeredi 		if (res)
523c8ccbe03SMiklos Szeredi 			entry = res;
524c8ccbe03SMiklos Szeredi 	}
525c8ccbe03SMiklos Szeredi 
526c8ccbe03SMiklos Szeredi 	if (!(flags & O_CREAT) || entry->d_inode)
527c8ccbe03SMiklos Szeredi 		goto no_open;
528c8ccbe03SMiklos Szeredi 
529c8ccbe03SMiklos Szeredi 	/* Only creates */
53047237687SAl Viro 	*opened |= FILE_CREATED;
531c8ccbe03SMiklos Szeredi 
532c8ccbe03SMiklos Szeredi 	if (fc->no_create)
533c8ccbe03SMiklos Szeredi 		goto mknod;
534c8ccbe03SMiklos Szeredi 
53530d90494SAl Viro 	err = fuse_create_open(dir, entry, file, flags, mode, opened);
536d9585277SAl Viro 	if (err == -ENOSYS) {
537c8ccbe03SMiklos Szeredi 		fc->no_create = 1;
538c8ccbe03SMiklos Szeredi 		goto mknod;
539c8ccbe03SMiklos Szeredi 	}
540c8ccbe03SMiklos Szeredi out_dput:
541c8ccbe03SMiklos Szeredi 	dput(res);
542d9585277SAl Viro 	return err;
543c8ccbe03SMiklos Szeredi 
544c8ccbe03SMiklos Szeredi mknod:
545c8ccbe03SMiklos Szeredi 	err = fuse_mknod(dir, entry, mode, 0);
546d9585277SAl Viro 	if (err)
547c8ccbe03SMiklos Szeredi 		goto out_dput;
548c8ccbe03SMiklos Szeredi no_open:
549e45198a6SAl Viro 	return finish_no_open(file, res);
550fd72faacSMiklos Szeredi }
551fd72faacSMiklos Szeredi 
5526f9f1180SMiklos Szeredi /*
5536f9f1180SMiklos Szeredi  * Code shared between mknod, mkdir, symlink and link
5546f9f1180SMiklos Szeredi  */
5559e6268dbSMiklos Szeredi static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
5569e6268dbSMiklos Szeredi 			    struct inode *dir, struct dentry *entry,
557541af6a0SAl Viro 			    umode_t mode)
5589e6268dbSMiklos Szeredi {
5599e6268dbSMiklos Szeredi 	struct fuse_entry_out outarg;
5609e6268dbSMiklos Szeredi 	struct inode *inode;
5619e6268dbSMiklos Szeredi 	int err;
56207e77dcaSMiklos Szeredi 	struct fuse_forget_link *forget;
5632d51013eSMiklos Szeredi 
56407e77dcaSMiklos Szeredi 	forget = fuse_alloc_forget();
56507e77dcaSMiklos Szeredi 	if (!forget) {
5662d51013eSMiklos Szeredi 		fuse_put_request(fc, req);
56707e77dcaSMiklos Szeredi 		return -ENOMEM;
5682d51013eSMiklos Szeredi 	}
5699e6268dbSMiklos Szeredi 
5700e9663eeSMiklos Szeredi 	memset(&outarg, 0, sizeof(outarg));
5719e6268dbSMiklos Szeredi 	req->in.h.nodeid = get_node_id(dir);
5729e6268dbSMiklos Szeredi 	req->out.numargs = 1;
5730e9663eeSMiklos Szeredi 	if (fc->minor < 9)
5740e9663eeSMiklos Szeredi 		req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
5750e9663eeSMiklos Szeredi 	else
5769e6268dbSMiklos Szeredi 		req->out.args[0].size = sizeof(outarg);
5779e6268dbSMiklos Szeredi 	req->out.args[0].value = &outarg;
578b93f858aSTejun Heo 	fuse_request_send(fc, req);
5799e6268dbSMiklos Szeredi 	err = req->out.h.error;
5809e6268dbSMiklos Szeredi 	fuse_put_request(fc, req);
5812d51013eSMiklos Szeredi 	if (err)
5822d51013eSMiklos Szeredi 		goto out_put_forget_req;
5832d51013eSMiklos Szeredi 
58439ee059aSMiklos Szeredi 	err = -EIO;
58539ee059aSMiklos Szeredi 	if (invalid_nodeid(outarg.nodeid))
5862d51013eSMiklos Szeredi 		goto out_put_forget_req;
58739ee059aSMiklos Szeredi 
58839ee059aSMiklos Szeredi 	if ((outarg.attr.mode ^ mode) & S_IFMT)
5892d51013eSMiklos Szeredi 		goto out_put_forget_req;
59039ee059aSMiklos Szeredi 
5919e6268dbSMiklos Szeredi 	inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
5921fb69e78SMiklos Szeredi 			  &outarg.attr, entry_attr_timeout(&outarg), 0);
5939e6268dbSMiklos Szeredi 	if (!inode) {
59407e77dcaSMiklos Szeredi 		fuse_queue_forget(fc, forget, outarg.nodeid, 1);
5959e6268dbSMiklos Szeredi 		return -ENOMEM;
5969e6268dbSMiklos Szeredi 	}
59707e77dcaSMiklos Szeredi 	kfree(forget);
5989e6268dbSMiklos Szeredi 
599d2a85164SMiklos Szeredi 	if (S_ISDIR(inode->i_mode)) {
600d2a85164SMiklos Szeredi 		struct dentry *alias;
601d2a85164SMiklos Szeredi 		mutex_lock(&fc->inst_mutex);
602d2a85164SMiklos Szeredi 		alias = d_find_alias(inode);
603d2a85164SMiklos Szeredi 		if (alias) {
604d2a85164SMiklos Szeredi 			/* New directory must have moved since mkdir */
605d2a85164SMiklos Szeredi 			mutex_unlock(&fc->inst_mutex);
606d2a85164SMiklos Szeredi 			dput(alias);
6079e6268dbSMiklos Szeredi 			iput(inode);
608d2a85164SMiklos Szeredi 			return -EBUSY;
6099e6268dbSMiklos Szeredi 		}
6109e6268dbSMiklos Szeredi 		d_instantiate(entry, inode);
611d2a85164SMiklos Szeredi 		mutex_unlock(&fc->inst_mutex);
612d2a85164SMiklos Szeredi 	} else
613d2a85164SMiklos Szeredi 		d_instantiate(entry, inode);
614d2a85164SMiklos Szeredi 
6151fb69e78SMiklos Szeredi 	fuse_change_entry_timeout(entry, &outarg);
6169e6268dbSMiklos Szeredi 	fuse_invalidate_attr(dir);
6179e6268dbSMiklos Szeredi 	return 0;
61839ee059aSMiklos Szeredi 
6192d51013eSMiklos Szeredi  out_put_forget_req:
62007e77dcaSMiklos Szeredi 	kfree(forget);
62139ee059aSMiklos Szeredi 	return err;
6229e6268dbSMiklos Szeredi }
6239e6268dbSMiklos Szeredi 
6241a67aafbSAl Viro static int fuse_mknod(struct inode *dir, struct dentry *entry, umode_t mode,
6259e6268dbSMiklos Szeredi 		      dev_t rdev)
6269e6268dbSMiklos Szeredi {
6279e6268dbSMiklos Szeredi 	struct fuse_mknod_in inarg;
6289e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
629b111c8c0SMaxim Patlasov 	struct fuse_req *req = fuse_get_req_nopages(fc);
630ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
631ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
6329e6268dbSMiklos Szeredi 
633e0a43ddcSMiklos Szeredi 	if (!fc->dont_mask)
634e0a43ddcSMiklos Szeredi 		mode &= ~current_umask();
635e0a43ddcSMiklos Szeredi 
6369e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
6379e6268dbSMiklos Szeredi 	inarg.mode = mode;
6389e6268dbSMiklos Szeredi 	inarg.rdev = new_encode_dev(rdev);
639e0a43ddcSMiklos Szeredi 	inarg.umask = current_umask();
6409e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_MKNOD;
6419e6268dbSMiklos Szeredi 	req->in.numargs = 2;
642e0a43ddcSMiklos Szeredi 	req->in.args[0].size = fc->minor < 12 ? FUSE_COMPAT_MKNOD_IN_SIZE :
643e0a43ddcSMiklos Szeredi 						sizeof(inarg);
6449e6268dbSMiklos Szeredi 	req->in.args[0].value = &inarg;
6459e6268dbSMiklos Szeredi 	req->in.args[1].size = entry->d_name.len + 1;
6469e6268dbSMiklos Szeredi 	req->in.args[1].value = entry->d_name.name;
6479e6268dbSMiklos Szeredi 	return create_new_entry(fc, req, dir, entry, mode);
6489e6268dbSMiklos Szeredi }
6499e6268dbSMiklos Szeredi 
6504acdaf27SAl Viro static int fuse_create(struct inode *dir, struct dentry *entry, umode_t mode,
651ebfc3b49SAl Viro 		       bool excl)
6529e6268dbSMiklos Szeredi {
6539e6268dbSMiklos Szeredi 	return fuse_mknod(dir, entry, mode, 0);
6549e6268dbSMiklos Szeredi }
6559e6268dbSMiklos Szeredi 
65618bb1db3SAl Viro static int fuse_mkdir(struct inode *dir, struct dentry *entry, umode_t mode)
6579e6268dbSMiklos Szeredi {
6589e6268dbSMiklos Szeredi 	struct fuse_mkdir_in inarg;
6599e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
660b111c8c0SMaxim Patlasov 	struct fuse_req *req = fuse_get_req_nopages(fc);
661ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
662ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
6639e6268dbSMiklos Szeredi 
664e0a43ddcSMiklos Szeredi 	if (!fc->dont_mask)
665e0a43ddcSMiklos Szeredi 		mode &= ~current_umask();
666e0a43ddcSMiklos Szeredi 
6679e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
6689e6268dbSMiklos Szeredi 	inarg.mode = mode;
669e0a43ddcSMiklos Szeredi 	inarg.umask = current_umask();
6709e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_MKDIR;
6719e6268dbSMiklos Szeredi 	req->in.numargs = 2;
6729e6268dbSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
6739e6268dbSMiklos Szeredi 	req->in.args[0].value = &inarg;
6749e6268dbSMiklos Szeredi 	req->in.args[1].size = entry->d_name.len + 1;
6759e6268dbSMiklos Szeredi 	req->in.args[1].value = entry->d_name.name;
6769e6268dbSMiklos Szeredi 	return create_new_entry(fc, req, dir, entry, S_IFDIR);
6779e6268dbSMiklos Szeredi }
6789e6268dbSMiklos Szeredi 
6799e6268dbSMiklos Szeredi static int fuse_symlink(struct inode *dir, struct dentry *entry,
6809e6268dbSMiklos Szeredi 			const char *link)
6819e6268dbSMiklos Szeredi {
6829e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
6839e6268dbSMiklos Szeredi 	unsigned len = strlen(link) + 1;
684b111c8c0SMaxim Patlasov 	struct fuse_req *req = fuse_get_req_nopages(fc);
685ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
686ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
6879e6268dbSMiklos Szeredi 
6889e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_SYMLINK;
6899e6268dbSMiklos Szeredi 	req->in.numargs = 2;
6909e6268dbSMiklos Szeredi 	req->in.args[0].size = entry->d_name.len + 1;
6919e6268dbSMiklos Szeredi 	req->in.args[0].value = entry->d_name.name;
6929e6268dbSMiklos Szeredi 	req->in.args[1].size = len;
6939e6268dbSMiklos Szeredi 	req->in.args[1].value = link;
6949e6268dbSMiklos Szeredi 	return create_new_entry(fc, req, dir, entry, S_IFLNK);
6959e6268dbSMiklos Szeredi }
6969e6268dbSMiklos Szeredi 
6979e6268dbSMiklos Szeredi static int fuse_unlink(struct inode *dir, struct dentry *entry)
6989e6268dbSMiklos Szeredi {
6999e6268dbSMiklos Szeredi 	int err;
7009e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
701b111c8c0SMaxim Patlasov 	struct fuse_req *req = fuse_get_req_nopages(fc);
702ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
703ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
7049e6268dbSMiklos Szeredi 
7059e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_UNLINK;
7069e6268dbSMiklos Szeredi 	req->in.h.nodeid = get_node_id(dir);
7079e6268dbSMiklos Szeredi 	req->in.numargs = 1;
7089e6268dbSMiklos Szeredi 	req->in.args[0].size = entry->d_name.len + 1;
7099e6268dbSMiklos Szeredi 	req->in.args[0].value = entry->d_name.name;
710b93f858aSTejun Heo 	fuse_request_send(fc, req);
7119e6268dbSMiklos Szeredi 	err = req->out.h.error;
7129e6268dbSMiklos Szeredi 	fuse_put_request(fc, req);
7139e6268dbSMiklos Szeredi 	if (!err) {
7149e6268dbSMiklos Szeredi 		struct inode *inode = entry->d_inode;
715ac45d613SMiklos Szeredi 		struct fuse_inode *fi = get_fuse_inode(inode);
7169e6268dbSMiklos Szeredi 
717ac45d613SMiklos Szeredi 		spin_lock(&fc->lock);
718ac45d613SMiklos Szeredi 		fi->attr_version = ++fc->attr_version;
719dfca7cebSMiklos Szeredi 		/*
720dfca7cebSMiklos Szeredi 		 * If i_nlink == 0 then unlink doesn't make sense, yet this can
721dfca7cebSMiklos Szeredi 		 * happen if userspace filesystem is careless.  It would be
722dfca7cebSMiklos Szeredi 		 * difficult to enforce correct nlink usage so just ignore this
723dfca7cebSMiklos Szeredi 		 * condition here
724dfca7cebSMiklos Szeredi 		 */
725dfca7cebSMiklos Szeredi 		if (inode->i_nlink > 0)
726ac45d613SMiklos Szeredi 			drop_nlink(inode);
727ac45d613SMiklos Szeredi 		spin_unlock(&fc->lock);
7289e6268dbSMiklos Szeredi 		fuse_invalidate_attr(inode);
7299e6268dbSMiklos Szeredi 		fuse_invalidate_attr(dir);
7308cbdf1e6SMiklos Szeredi 		fuse_invalidate_entry_cache(entry);
7319e6268dbSMiklos Szeredi 	} else if (err == -EINTR)
7329e6268dbSMiklos Szeredi 		fuse_invalidate_entry(entry);
7339e6268dbSMiklos Szeredi 	return err;
7349e6268dbSMiklos Szeredi }
7359e6268dbSMiklos Szeredi 
7369e6268dbSMiklos Szeredi static int fuse_rmdir(struct inode *dir, struct dentry *entry)
7379e6268dbSMiklos Szeredi {
7389e6268dbSMiklos Szeredi 	int err;
7399e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
740b111c8c0SMaxim Patlasov 	struct fuse_req *req = fuse_get_req_nopages(fc);
741ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
742ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
7439e6268dbSMiklos Szeredi 
7449e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_RMDIR;
7459e6268dbSMiklos Szeredi 	req->in.h.nodeid = get_node_id(dir);
7469e6268dbSMiklos Szeredi 	req->in.numargs = 1;
7479e6268dbSMiklos Szeredi 	req->in.args[0].size = entry->d_name.len + 1;
7489e6268dbSMiklos Szeredi 	req->in.args[0].value = entry->d_name.name;
749b93f858aSTejun Heo 	fuse_request_send(fc, req);
7509e6268dbSMiklos Szeredi 	err = req->out.h.error;
7519e6268dbSMiklos Szeredi 	fuse_put_request(fc, req);
7529e6268dbSMiklos Szeredi 	if (!err) {
753ce71ec36SDave Hansen 		clear_nlink(entry->d_inode);
7549e6268dbSMiklos Szeredi 		fuse_invalidate_attr(dir);
7558cbdf1e6SMiklos Szeredi 		fuse_invalidate_entry_cache(entry);
7569e6268dbSMiklos Szeredi 	} else if (err == -EINTR)
7579e6268dbSMiklos Szeredi 		fuse_invalidate_entry(entry);
7589e6268dbSMiklos Szeredi 	return err;
7599e6268dbSMiklos Szeredi }
7609e6268dbSMiklos Szeredi 
7619e6268dbSMiklos Szeredi static int fuse_rename(struct inode *olddir, struct dentry *oldent,
7629e6268dbSMiklos Szeredi 		       struct inode *newdir, struct dentry *newent)
7639e6268dbSMiklos Szeredi {
7649e6268dbSMiklos Szeredi 	int err;
7659e6268dbSMiklos Szeredi 	struct fuse_rename_in inarg;
7669e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(olddir);
767b111c8c0SMaxim Patlasov 	struct fuse_req *req = fuse_get_req_nopages(fc);
768e4eaac06SSage Weil 
769ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
770ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
7719e6268dbSMiklos Szeredi 
7729e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
7739e6268dbSMiklos Szeredi 	inarg.newdir = get_node_id(newdir);
7749e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_RENAME;
7759e6268dbSMiklos Szeredi 	req->in.h.nodeid = get_node_id(olddir);
7769e6268dbSMiklos Szeredi 	req->in.numargs = 3;
7779e6268dbSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
7789e6268dbSMiklos Szeredi 	req->in.args[0].value = &inarg;
7799e6268dbSMiklos Szeredi 	req->in.args[1].size = oldent->d_name.len + 1;
7809e6268dbSMiklos Szeredi 	req->in.args[1].value = oldent->d_name.name;
7819e6268dbSMiklos Szeredi 	req->in.args[2].size = newent->d_name.len + 1;
7829e6268dbSMiklos Szeredi 	req->in.args[2].value = newent->d_name.name;
783b93f858aSTejun Heo 	fuse_request_send(fc, req);
7849e6268dbSMiklos Szeredi 	err = req->out.h.error;
7859e6268dbSMiklos Szeredi 	fuse_put_request(fc, req);
7869e6268dbSMiklos Szeredi 	if (!err) {
78708b63307SMiklos Szeredi 		/* ctime changes */
78808b63307SMiklos Szeredi 		fuse_invalidate_attr(oldent->d_inode);
78908b63307SMiklos Szeredi 
7909e6268dbSMiklos Szeredi 		fuse_invalidate_attr(olddir);
7919e6268dbSMiklos Szeredi 		if (olddir != newdir)
7929e6268dbSMiklos Szeredi 			fuse_invalidate_attr(newdir);
7938cbdf1e6SMiklos Szeredi 
7948cbdf1e6SMiklos Szeredi 		/* newent will end up negative */
7955219f346SMiklos Szeredi 		if (newent->d_inode) {
7965219f346SMiklos Szeredi 			fuse_invalidate_attr(newent->d_inode);
7978cbdf1e6SMiklos Szeredi 			fuse_invalidate_entry_cache(newent);
7985219f346SMiklos Szeredi 		}
7999e6268dbSMiklos Szeredi 	} else if (err == -EINTR) {
8009e6268dbSMiklos Szeredi 		/* If request was interrupted, DEITY only knows if the
8019e6268dbSMiklos Szeredi 		   rename actually took place.  If the invalidation
8029e6268dbSMiklos Szeredi 		   fails (e.g. some process has CWD under the renamed
8039e6268dbSMiklos Szeredi 		   directory), then there can be inconsistency between
8049e6268dbSMiklos Szeredi 		   the dcache and the real filesystem.  Tough luck. */
8059e6268dbSMiklos Szeredi 		fuse_invalidate_entry(oldent);
8069e6268dbSMiklos Szeredi 		if (newent->d_inode)
8079e6268dbSMiklos Szeredi 			fuse_invalidate_entry(newent);
8089e6268dbSMiklos Szeredi 	}
8099e6268dbSMiklos Szeredi 
8109e6268dbSMiklos Szeredi 	return err;
8119e6268dbSMiklos Szeredi }
8129e6268dbSMiklos Szeredi 
8139e6268dbSMiklos Szeredi static int fuse_link(struct dentry *entry, struct inode *newdir,
8149e6268dbSMiklos Szeredi 		     struct dentry *newent)
8159e6268dbSMiklos Szeredi {
8169e6268dbSMiklos Szeredi 	int err;
8179e6268dbSMiklos Szeredi 	struct fuse_link_in inarg;
8189e6268dbSMiklos Szeredi 	struct inode *inode = entry->d_inode;
8199e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
820b111c8c0SMaxim Patlasov 	struct fuse_req *req = fuse_get_req_nopages(fc);
821ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
822ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
8239e6268dbSMiklos Szeredi 
8249e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
8259e6268dbSMiklos Szeredi 	inarg.oldnodeid = get_node_id(inode);
8269e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_LINK;
8279e6268dbSMiklos Szeredi 	req->in.numargs = 2;
8289e6268dbSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
8299e6268dbSMiklos Szeredi 	req->in.args[0].value = &inarg;
8309e6268dbSMiklos Szeredi 	req->in.args[1].size = newent->d_name.len + 1;
8319e6268dbSMiklos Szeredi 	req->in.args[1].value = newent->d_name.name;
8329e6268dbSMiklos Szeredi 	err = create_new_entry(fc, req, newdir, newent, inode->i_mode);
8339e6268dbSMiklos Szeredi 	/* Contrary to "normal" filesystems it can happen that link
8349e6268dbSMiklos Szeredi 	   makes two "logical" inodes point to the same "physical"
8359e6268dbSMiklos Szeredi 	   inode.  We invalidate the attributes of the old one, so it
8369e6268dbSMiklos Szeredi 	   will reflect changes in the backing inode (link count,
8379e6268dbSMiklos Szeredi 	   etc.)
8389e6268dbSMiklos Szeredi 	*/
839ac45d613SMiklos Szeredi 	if (!err) {
840ac45d613SMiklos Szeredi 		struct fuse_inode *fi = get_fuse_inode(inode);
841ac45d613SMiklos Szeredi 
842ac45d613SMiklos Szeredi 		spin_lock(&fc->lock);
843ac45d613SMiklos Szeredi 		fi->attr_version = ++fc->attr_version;
844ac45d613SMiklos Szeredi 		inc_nlink(inode);
845ac45d613SMiklos Szeredi 		spin_unlock(&fc->lock);
8469e6268dbSMiklos Szeredi 		fuse_invalidate_attr(inode);
847ac45d613SMiklos Szeredi 	} else if (err == -EINTR) {
848ac45d613SMiklos Szeredi 		fuse_invalidate_attr(inode);
849ac45d613SMiklos Szeredi 	}
8509e6268dbSMiklos Szeredi 	return err;
8519e6268dbSMiklos Szeredi }
8529e6268dbSMiklos Szeredi 
8531fb69e78SMiklos Szeredi static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
8541fb69e78SMiklos Szeredi 			  struct kstat *stat)
8551fb69e78SMiklos Szeredi {
856203627bbSMiklos Szeredi 	unsigned int blkbits;
857203627bbSMiklos Szeredi 
8581fb69e78SMiklos Szeredi 	stat->dev = inode->i_sb->s_dev;
8591fb69e78SMiklos Szeredi 	stat->ino = attr->ino;
8601fb69e78SMiklos Szeredi 	stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
8611fb69e78SMiklos Szeredi 	stat->nlink = attr->nlink;
862499dcf20SEric W. Biederman 	stat->uid = make_kuid(&init_user_ns, attr->uid);
863499dcf20SEric W. Biederman 	stat->gid = make_kgid(&init_user_ns, attr->gid);
8641fb69e78SMiklos Szeredi 	stat->rdev = inode->i_rdev;
8651fb69e78SMiklos Szeredi 	stat->atime.tv_sec = attr->atime;
8661fb69e78SMiklos Szeredi 	stat->atime.tv_nsec = attr->atimensec;
8671fb69e78SMiklos Szeredi 	stat->mtime.tv_sec = attr->mtime;
8681fb69e78SMiklos Szeredi 	stat->mtime.tv_nsec = attr->mtimensec;
8691fb69e78SMiklos Szeredi 	stat->ctime.tv_sec = attr->ctime;
8701fb69e78SMiklos Szeredi 	stat->ctime.tv_nsec = attr->ctimensec;
8711fb69e78SMiklos Szeredi 	stat->size = attr->size;
8721fb69e78SMiklos Szeredi 	stat->blocks = attr->blocks;
873203627bbSMiklos Szeredi 
874203627bbSMiklos Szeredi 	if (attr->blksize != 0)
875203627bbSMiklos Szeredi 		blkbits = ilog2(attr->blksize);
876203627bbSMiklos Szeredi 	else
877203627bbSMiklos Szeredi 		blkbits = inode->i_sb->s_blocksize_bits;
878203627bbSMiklos Szeredi 
879203627bbSMiklos Szeredi 	stat->blksize = 1 << blkbits;
8801fb69e78SMiklos Szeredi }
8811fb69e78SMiklos Szeredi 
882c79e322fSMiklos Szeredi static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
883c79e322fSMiklos Szeredi 			   struct file *file)
884e5e5558eSMiklos Szeredi {
885e5e5558eSMiklos Szeredi 	int err;
886c79e322fSMiklos Szeredi 	struct fuse_getattr_in inarg;
887c79e322fSMiklos Szeredi 	struct fuse_attr_out outarg;
888e5e5558eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
8891fb69e78SMiklos Szeredi 	struct fuse_req *req;
8901fb69e78SMiklos Szeredi 	u64 attr_version;
8911fb69e78SMiklos Szeredi 
892b111c8c0SMaxim Patlasov 	req = fuse_get_req_nopages(fc);
893ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
894ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
895e5e5558eSMiklos Szeredi 
8967dca9fd3SMiklos Szeredi 	attr_version = fuse_get_attr_version(fc);
8971fb69e78SMiklos Szeredi 
898c79e322fSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
8990e9663eeSMiklos Szeredi 	memset(&outarg, 0, sizeof(outarg));
900c79e322fSMiklos Szeredi 	/* Directories have separate file-handle space */
901c79e322fSMiklos Szeredi 	if (file && S_ISREG(inode->i_mode)) {
902c79e322fSMiklos Szeredi 		struct fuse_file *ff = file->private_data;
903c79e322fSMiklos Szeredi 
904c79e322fSMiklos Szeredi 		inarg.getattr_flags |= FUSE_GETATTR_FH;
905c79e322fSMiklos Szeredi 		inarg.fh = ff->fh;
906c79e322fSMiklos Szeredi 	}
907e5e5558eSMiklos Szeredi 	req->in.h.opcode = FUSE_GETATTR;
908e5e5558eSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
909c79e322fSMiklos Szeredi 	req->in.numargs = 1;
910c79e322fSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
911c79e322fSMiklos Szeredi 	req->in.args[0].value = &inarg;
912e5e5558eSMiklos Szeredi 	req->out.numargs = 1;
9130e9663eeSMiklos Szeredi 	if (fc->minor < 9)
9140e9663eeSMiklos Szeredi 		req->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
9150e9663eeSMiklos Szeredi 	else
916c79e322fSMiklos Szeredi 		req->out.args[0].size = sizeof(outarg);
917c79e322fSMiklos Szeredi 	req->out.args[0].value = &outarg;
918b93f858aSTejun Heo 	fuse_request_send(fc, req);
919e5e5558eSMiklos Szeredi 	err = req->out.h.error;
920e5e5558eSMiklos Szeredi 	fuse_put_request(fc, req);
921e5e5558eSMiklos Szeredi 	if (!err) {
922c79e322fSMiklos Szeredi 		if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
923e5e5558eSMiklos Szeredi 			make_bad_inode(inode);
924e5e5558eSMiklos Szeredi 			err = -EIO;
925e5e5558eSMiklos Szeredi 		} else {
926c79e322fSMiklos Szeredi 			fuse_change_attributes(inode, &outarg.attr,
927c79e322fSMiklos Szeredi 					       attr_timeout(&outarg),
9281fb69e78SMiklos Szeredi 					       attr_version);
9291fb69e78SMiklos Szeredi 			if (stat)
930c79e322fSMiklos Szeredi 				fuse_fillattr(inode, &outarg.attr, stat);
931e5e5558eSMiklos Szeredi 		}
932e5e5558eSMiklos Szeredi 	}
933e5e5558eSMiklos Szeredi 	return err;
934e5e5558eSMiklos Szeredi }
935e5e5558eSMiklos Szeredi 
936bcb4be80SMiklos Szeredi int fuse_update_attributes(struct inode *inode, struct kstat *stat,
937bcb4be80SMiklos Szeredi 			   struct file *file, bool *refreshed)
938bcb4be80SMiklos Szeredi {
939bcb4be80SMiklos Szeredi 	struct fuse_inode *fi = get_fuse_inode(inode);
940bcb4be80SMiklos Szeredi 	int err;
941bcb4be80SMiklos Szeredi 	bool r;
942bcb4be80SMiklos Szeredi 
943bcb4be80SMiklos Szeredi 	if (fi->i_time < get_jiffies_64()) {
944bcb4be80SMiklos Szeredi 		r = true;
945bcb4be80SMiklos Szeredi 		err = fuse_do_getattr(inode, stat, file);
946bcb4be80SMiklos Szeredi 	} else {
947bcb4be80SMiklos Szeredi 		r = false;
948bcb4be80SMiklos Szeredi 		err = 0;
949bcb4be80SMiklos Szeredi 		if (stat) {
950bcb4be80SMiklos Szeredi 			generic_fillattr(inode, stat);
951bcb4be80SMiklos Szeredi 			stat->mode = fi->orig_i_mode;
95245c72cd7SPavel Shilovsky 			stat->ino = fi->orig_ino;
953bcb4be80SMiklos Szeredi 		}
954bcb4be80SMiklos Szeredi 	}
955bcb4be80SMiklos Szeredi 
956bcb4be80SMiklos Szeredi 	if (refreshed != NULL)
957bcb4be80SMiklos Szeredi 		*refreshed = r;
958bcb4be80SMiklos Szeredi 
959bcb4be80SMiklos Szeredi 	return err;
960bcb4be80SMiklos Szeredi }
961bcb4be80SMiklos Szeredi 
9623b463ae0SJohn Muir int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid,
963451d0f59SJohn Muir 			     u64 child_nodeid, struct qstr *name)
9643b463ae0SJohn Muir {
9653b463ae0SJohn Muir 	int err = -ENOTDIR;
9663b463ae0SJohn Muir 	struct inode *parent;
9673b463ae0SJohn Muir 	struct dentry *dir;
9683b463ae0SJohn Muir 	struct dentry *entry;
9693b463ae0SJohn Muir 
9703b463ae0SJohn Muir 	parent = ilookup5(sb, parent_nodeid, fuse_inode_eq, &parent_nodeid);
9713b463ae0SJohn Muir 	if (!parent)
9723b463ae0SJohn Muir 		return -ENOENT;
9733b463ae0SJohn Muir 
9743b463ae0SJohn Muir 	mutex_lock(&parent->i_mutex);
9753b463ae0SJohn Muir 	if (!S_ISDIR(parent->i_mode))
9763b463ae0SJohn Muir 		goto unlock;
9773b463ae0SJohn Muir 
9783b463ae0SJohn Muir 	err = -ENOENT;
9793b463ae0SJohn Muir 	dir = d_find_alias(parent);
9803b463ae0SJohn Muir 	if (!dir)
9813b463ae0SJohn Muir 		goto unlock;
9823b463ae0SJohn Muir 
9833b463ae0SJohn Muir 	entry = d_lookup(dir, name);
9843b463ae0SJohn Muir 	dput(dir);
9853b463ae0SJohn Muir 	if (!entry)
9863b463ae0SJohn Muir 		goto unlock;
9873b463ae0SJohn Muir 
9883b463ae0SJohn Muir 	fuse_invalidate_attr(parent);
9893b463ae0SJohn Muir 	fuse_invalidate_entry(entry);
990451d0f59SJohn Muir 
991451d0f59SJohn Muir 	if (child_nodeid != 0 && entry->d_inode) {
992451d0f59SJohn Muir 		mutex_lock(&entry->d_inode->i_mutex);
993451d0f59SJohn Muir 		if (get_node_id(entry->d_inode) != child_nodeid) {
994451d0f59SJohn Muir 			err = -ENOENT;
995451d0f59SJohn Muir 			goto badentry;
996451d0f59SJohn Muir 		}
997451d0f59SJohn Muir 		if (d_mountpoint(entry)) {
998451d0f59SJohn Muir 			err = -EBUSY;
999451d0f59SJohn Muir 			goto badentry;
1000451d0f59SJohn Muir 		}
1001451d0f59SJohn Muir 		if (S_ISDIR(entry->d_inode->i_mode)) {
1002451d0f59SJohn Muir 			shrink_dcache_parent(entry);
1003451d0f59SJohn Muir 			if (!simple_empty(entry)) {
1004451d0f59SJohn Muir 				err = -ENOTEMPTY;
1005451d0f59SJohn Muir 				goto badentry;
1006451d0f59SJohn Muir 			}
1007451d0f59SJohn Muir 			entry->d_inode->i_flags |= S_DEAD;
1008451d0f59SJohn Muir 		}
1009451d0f59SJohn Muir 		dont_mount(entry);
1010451d0f59SJohn Muir 		clear_nlink(entry->d_inode);
10113b463ae0SJohn Muir 		err = 0;
1012451d0f59SJohn Muir  badentry:
1013451d0f59SJohn Muir 		mutex_unlock(&entry->d_inode->i_mutex);
1014451d0f59SJohn Muir 		if (!err)
1015451d0f59SJohn Muir 			d_delete(entry);
1016451d0f59SJohn Muir 	} else {
1017451d0f59SJohn Muir 		err = 0;
1018451d0f59SJohn Muir 	}
1019451d0f59SJohn Muir 	dput(entry);
10203b463ae0SJohn Muir 
10213b463ae0SJohn Muir  unlock:
10223b463ae0SJohn Muir 	mutex_unlock(&parent->i_mutex);
10233b463ae0SJohn Muir 	iput(parent);
10243b463ae0SJohn Muir 	return err;
10253b463ae0SJohn Muir }
10263b463ae0SJohn Muir 
102787729a55SMiklos Szeredi /*
102887729a55SMiklos Szeredi  * Calling into a user-controlled filesystem gives the filesystem
1029c2132c1bSAnatol Pomozov  * daemon ptrace-like capabilities over the current process.  This
103087729a55SMiklos Szeredi  * means, that the filesystem daemon is able to record the exact
103187729a55SMiklos Szeredi  * filesystem operations performed, and can also control the behavior
103287729a55SMiklos Szeredi  * of the requester process in otherwise impossible ways.  For example
103387729a55SMiklos Szeredi  * it can delay the operation for arbitrary length of time allowing
103487729a55SMiklos Szeredi  * DoS against the requester.
103587729a55SMiklos Szeredi  *
103687729a55SMiklos Szeredi  * For this reason only those processes can call into the filesystem,
103787729a55SMiklos Szeredi  * for which the owner of the mount has ptrace privilege.  This
103887729a55SMiklos Szeredi  * excludes processes started by other users, suid or sgid processes.
103987729a55SMiklos Szeredi  */
1040c2132c1bSAnatol Pomozov int fuse_allow_current_process(struct fuse_conn *fc)
104187729a55SMiklos Szeredi {
1042c69e8d9cSDavid Howells 	const struct cred *cred;
1043c69e8d9cSDavid Howells 
104487729a55SMiklos Szeredi 	if (fc->flags & FUSE_ALLOW_OTHER)
104587729a55SMiklos Szeredi 		return 1;
104687729a55SMiklos Szeredi 
1047c2132c1bSAnatol Pomozov 	cred = current_cred();
1048499dcf20SEric W. Biederman 	if (uid_eq(cred->euid, fc->user_id) &&
1049499dcf20SEric W. Biederman 	    uid_eq(cred->suid, fc->user_id) &&
1050499dcf20SEric W. Biederman 	    uid_eq(cred->uid,  fc->user_id) &&
1051499dcf20SEric W. Biederman 	    gid_eq(cred->egid, fc->group_id) &&
1052499dcf20SEric W. Biederman 	    gid_eq(cred->sgid, fc->group_id) &&
1053499dcf20SEric W. Biederman 	    gid_eq(cred->gid,  fc->group_id))
1054c2132c1bSAnatol Pomozov 		return 1;
105587729a55SMiklos Szeredi 
1056c2132c1bSAnatol Pomozov 	return 0;
105787729a55SMiklos Szeredi }
105887729a55SMiklos Szeredi 
105931d40d74SMiklos Szeredi static int fuse_access(struct inode *inode, int mask)
106031d40d74SMiklos Szeredi {
106131d40d74SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
106231d40d74SMiklos Szeredi 	struct fuse_req *req;
106331d40d74SMiklos Szeredi 	struct fuse_access_in inarg;
106431d40d74SMiklos Szeredi 	int err;
106531d40d74SMiklos Szeredi 
106631d40d74SMiklos Szeredi 	if (fc->no_access)
106731d40d74SMiklos Szeredi 		return 0;
106831d40d74SMiklos Szeredi 
1069b111c8c0SMaxim Patlasov 	req = fuse_get_req_nopages(fc);
1070ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1071ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
107231d40d74SMiklos Szeredi 
107331d40d74SMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
1074e6305c43SAl Viro 	inarg.mask = mask & (MAY_READ | MAY_WRITE | MAY_EXEC);
107531d40d74SMiklos Szeredi 	req->in.h.opcode = FUSE_ACCESS;
107631d40d74SMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
107731d40d74SMiklos Szeredi 	req->in.numargs = 1;
107831d40d74SMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
107931d40d74SMiklos Szeredi 	req->in.args[0].value = &inarg;
1080b93f858aSTejun Heo 	fuse_request_send(fc, req);
108131d40d74SMiklos Szeredi 	err = req->out.h.error;
108231d40d74SMiklos Szeredi 	fuse_put_request(fc, req);
108331d40d74SMiklos Szeredi 	if (err == -ENOSYS) {
108431d40d74SMiklos Szeredi 		fc->no_access = 1;
108531d40d74SMiklos Szeredi 		err = 0;
108631d40d74SMiklos Szeredi 	}
108731d40d74SMiklos Szeredi 	return err;
108831d40d74SMiklos Szeredi }
108931d40d74SMiklos Szeredi 
109010556cb2SAl Viro static int fuse_perm_getattr(struct inode *inode, int mask)
109119690ddbSMiklos Szeredi {
109210556cb2SAl Viro 	if (mask & MAY_NOT_BLOCK)
109319690ddbSMiklos Szeredi 		return -ECHILD;
109419690ddbSMiklos Szeredi 
109519690ddbSMiklos Szeredi 	return fuse_do_getattr(inode, NULL, NULL);
109619690ddbSMiklos Szeredi }
109719690ddbSMiklos Szeredi 
10986f9f1180SMiklos Szeredi /*
10996f9f1180SMiklos Szeredi  * Check permission.  The two basic access models of FUSE are:
11006f9f1180SMiklos Szeredi  *
11016f9f1180SMiklos Szeredi  * 1) Local access checking ('default_permissions' mount option) based
11026f9f1180SMiklos Szeredi  * on file mode.  This is the plain old disk filesystem permission
11036f9f1180SMiklos Szeredi  * modell.
11046f9f1180SMiklos Szeredi  *
11056f9f1180SMiklos Szeredi  * 2) "Remote" access checking, where server is responsible for
11066f9f1180SMiklos Szeredi  * checking permission in each inode operation.  An exception to this
11076f9f1180SMiklos Szeredi  * is if ->permission() was invoked from sys_access() in which case an
11086f9f1180SMiklos Szeredi  * access request is sent.  Execute permission is still checked
11096f9f1180SMiklos Szeredi  * locally based on file mode.
11106f9f1180SMiklos Szeredi  */
111110556cb2SAl Viro static int fuse_permission(struct inode *inode, int mask)
1112e5e5558eSMiklos Szeredi {
1113e5e5558eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
1114244f6385SMiklos Szeredi 	bool refreshed = false;
1115244f6385SMiklos Szeredi 	int err = 0;
1116e5e5558eSMiklos Szeredi 
1117c2132c1bSAnatol Pomozov 	if (!fuse_allow_current_process(fc))
1118e5e5558eSMiklos Szeredi 		return -EACCES;
1119244f6385SMiklos Szeredi 
1120244f6385SMiklos Szeredi 	/*
1121e8e96157SMiklos Szeredi 	 * If attributes are needed, refresh them before proceeding
1122244f6385SMiklos Szeredi 	 */
1123e8e96157SMiklos Szeredi 	if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) ||
1124e8e96157SMiklos Szeredi 	    ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) {
112519690ddbSMiklos Szeredi 		struct fuse_inode *fi = get_fuse_inode(inode);
112619690ddbSMiklos Szeredi 
112719690ddbSMiklos Szeredi 		if (fi->i_time < get_jiffies_64()) {
112819690ddbSMiklos Szeredi 			refreshed = true;
112919690ddbSMiklos Szeredi 
113010556cb2SAl Viro 			err = fuse_perm_getattr(inode, mask);
1131244f6385SMiklos Szeredi 			if (err)
1132244f6385SMiklos Szeredi 				return err;
11331fb69e78SMiklos Szeredi 		}
113419690ddbSMiklos Szeredi 	}
1135244f6385SMiklos Szeredi 
1136244f6385SMiklos Szeredi 	if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
11372830ba7fSAl Viro 		err = generic_permission(inode, mask);
11381e9a4ed9SMiklos Szeredi 
11391e9a4ed9SMiklos Szeredi 		/* If permission is denied, try to refresh file
11401e9a4ed9SMiklos Szeredi 		   attributes.  This is also needed, because the root
11411e9a4ed9SMiklos Szeredi 		   node will at first have no permissions */
1142244f6385SMiklos Szeredi 		if (err == -EACCES && !refreshed) {
114310556cb2SAl Viro 			err = fuse_perm_getattr(inode, mask);
11441e9a4ed9SMiklos Szeredi 			if (!err)
11452830ba7fSAl Viro 				err = generic_permission(inode, mask);
11461e9a4ed9SMiklos Szeredi 		}
11471e9a4ed9SMiklos Szeredi 
11486f9f1180SMiklos Szeredi 		/* Note: the opposite of the above test does not
11496f9f1180SMiklos Szeredi 		   exist.  So if permissions are revoked this won't be
11506f9f1180SMiklos Szeredi 		   noticed immediately, only after the attribute
11516f9f1180SMiklos Szeredi 		   timeout has expired */
11529cfcac81SEric Paris 	} else if (mask & (MAY_ACCESS | MAY_CHDIR)) {
115310556cb2SAl Viro 		if (mask & MAY_NOT_BLOCK)
115419690ddbSMiklos Szeredi 			return -ECHILD;
115519690ddbSMiklos Szeredi 
1156e8e96157SMiklos Szeredi 		err = fuse_access(inode, mask);
1157e8e96157SMiklos Szeredi 	} else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
1158e8e96157SMiklos Szeredi 		if (!(inode->i_mode & S_IXUGO)) {
1159e8e96157SMiklos Szeredi 			if (refreshed)
1160e5e5558eSMiklos Szeredi 				return -EACCES;
116131d40d74SMiklos Szeredi 
116210556cb2SAl Viro 			err = fuse_perm_getattr(inode, mask);
1163e8e96157SMiklos Szeredi 			if (!err && !(inode->i_mode & S_IXUGO))
1164e8e96157SMiklos Szeredi 				return -EACCES;
1165e8e96157SMiklos Szeredi 		}
1166e5e5558eSMiklos Szeredi 	}
1167244f6385SMiklos Szeredi 	return err;
1168e5e5558eSMiklos Szeredi }
1169e5e5558eSMiklos Szeredi 
1170e5e5558eSMiklos Szeredi static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
11718d3af7f3SAl Viro 			 struct dir_context *ctx)
1172e5e5558eSMiklos Szeredi {
1173e5e5558eSMiklos Szeredi 	while (nbytes >= FUSE_NAME_OFFSET) {
1174e5e5558eSMiklos Szeredi 		struct fuse_dirent *dirent = (struct fuse_dirent *) buf;
1175e5e5558eSMiklos Szeredi 		size_t reclen = FUSE_DIRENT_SIZE(dirent);
1176e5e5558eSMiklos Szeredi 		if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
1177e5e5558eSMiklos Szeredi 			return -EIO;
1178e5e5558eSMiklos Szeredi 		if (reclen > nbytes)
1179e5e5558eSMiklos Szeredi 			break;
1180efeb9e60SMiklos Szeredi 		if (memchr(dirent->name, '/', dirent->namelen) != NULL)
1181efeb9e60SMiklos Szeredi 			return -EIO;
1182e5e5558eSMiklos Szeredi 
11838d3af7f3SAl Viro 		if (!dir_emit(ctx, dirent->name, dirent->namelen,
11848d3af7f3SAl Viro 			       dirent->ino, dirent->type))
1185e5e5558eSMiklos Szeredi 			break;
1186e5e5558eSMiklos Szeredi 
1187e5e5558eSMiklos Szeredi 		buf += reclen;
1188e5e5558eSMiklos Szeredi 		nbytes -= reclen;
11898d3af7f3SAl Viro 		ctx->pos = dirent->off;
1190e5e5558eSMiklos Szeredi 	}
1191e5e5558eSMiklos Szeredi 
1192e5e5558eSMiklos Szeredi 	return 0;
1193e5e5558eSMiklos Szeredi }
1194e5e5558eSMiklos Szeredi 
11950b05b183SAnand V. Avati static int fuse_direntplus_link(struct file *file,
11960b05b183SAnand V. Avati 				struct fuse_direntplus *direntplus,
11970b05b183SAnand V. Avati 				u64 attr_version)
11980b05b183SAnand V. Avati {
11990b05b183SAnand V. Avati 	int err;
12000b05b183SAnand V. Avati 	struct fuse_entry_out *o = &direntplus->entry_out;
12010b05b183SAnand V. Avati 	struct fuse_dirent *dirent = &direntplus->dirent;
12020b05b183SAnand V. Avati 	struct dentry *parent = file->f_path.dentry;
12030b05b183SAnand V. Avati 	struct qstr name = QSTR_INIT(dirent->name, dirent->namelen);
12040b05b183SAnand V. Avati 	struct dentry *dentry;
12050b05b183SAnand V. Avati 	struct dentry *alias;
12060b05b183SAnand V. Avati 	struct inode *dir = parent->d_inode;
12070b05b183SAnand V. Avati 	struct fuse_conn *fc;
12080b05b183SAnand V. Avati 	struct inode *inode;
12090b05b183SAnand V. Avati 
12100b05b183SAnand V. Avati 	if (!o->nodeid) {
12110b05b183SAnand V. Avati 		/*
12120b05b183SAnand V. Avati 		 * Unlike in the case of fuse_lookup, zero nodeid does not mean
12130b05b183SAnand V. Avati 		 * ENOENT. Instead, it only means the userspace filesystem did
12140b05b183SAnand V. Avati 		 * not want to return attributes/handle for this entry.
12150b05b183SAnand V. Avati 		 *
12160b05b183SAnand V. Avati 		 * So do nothing.
12170b05b183SAnand V. Avati 		 */
12180b05b183SAnand V. Avati 		return 0;
12190b05b183SAnand V. Avati 	}
12200b05b183SAnand V. Avati 
12210b05b183SAnand V. Avati 	if (name.name[0] == '.') {
12220b05b183SAnand V. Avati 		/*
12230b05b183SAnand V. Avati 		 * We could potentially refresh the attributes of the directory
12240b05b183SAnand V. Avati 		 * and its parent?
12250b05b183SAnand V. Avati 		 */
12260b05b183SAnand V. Avati 		if (name.len == 1)
12270b05b183SAnand V. Avati 			return 0;
12280b05b183SAnand V. Avati 		if (name.name[1] == '.' && name.len == 2)
12290b05b183SAnand V. Avati 			return 0;
12300b05b183SAnand V. Avati 	}
1231a28ef45cSMiklos Szeredi 
1232a28ef45cSMiklos Szeredi 	if (invalid_nodeid(o->nodeid))
1233a28ef45cSMiklos Szeredi 		return -EIO;
1234a28ef45cSMiklos Szeredi 	if (!fuse_valid_type(o->attr.mode))
1235a28ef45cSMiklos Szeredi 		return -EIO;
1236a28ef45cSMiklos Szeredi 
12370b05b183SAnand V. Avati 	fc = get_fuse_conn(dir);
12380b05b183SAnand V. Avati 
12390b05b183SAnand V. Avati 	name.hash = full_name_hash(name.name, name.len);
12400b05b183SAnand V. Avati 	dentry = d_lookup(parent, &name);
124153ce9a33SNiels de Vos 	if (dentry) {
12420b05b183SAnand V. Avati 		inode = dentry->d_inode;
124353ce9a33SNiels de Vos 		if (!inode) {
124453ce9a33SNiels de Vos 			d_drop(dentry);
1245a28ef45cSMiklos Szeredi 		} else if (get_node_id(inode) != o->nodeid ||
1246a28ef45cSMiklos Szeredi 			   ((o->attr.mode ^ inode->i_mode) & S_IFMT)) {
124753ce9a33SNiels de Vos 			err = d_invalidate(dentry);
124853ce9a33SNiels de Vos 			if (err)
124953ce9a33SNiels de Vos 				goto out;
1250a28ef45cSMiklos Szeredi 		} else if (is_bad_inode(inode)) {
1251a28ef45cSMiklos Szeredi 			err = -EIO;
1252a28ef45cSMiklos Szeredi 			goto out;
125353ce9a33SNiels de Vos 		} else {
12540b05b183SAnand V. Avati 			struct fuse_inode *fi;
12550b05b183SAnand V. Avati 			fi = get_fuse_inode(inode);
12560b05b183SAnand V. Avati 			spin_lock(&fc->lock);
12570b05b183SAnand V. Avati 			fi->nlookup++;
12580b05b183SAnand V. Avati 			spin_unlock(&fc->lock);
12590b05b183SAnand V. Avati 
1260fa2b7213SMiklos Szeredi 			fuse_change_attributes(inode, &o->attr,
1261fa2b7213SMiklos Szeredi 					       entry_attr_timeout(o),
1262fa2b7213SMiklos Szeredi 					       attr_version);
1263fa2b7213SMiklos Szeredi 
12640b05b183SAnand V. Avati 			/*
12650b05b183SAnand V. Avati 			 * The other branch to 'found' comes via fuse_iget()
12660b05b183SAnand V. Avati 			 * which bumps nlookup inside
12670b05b183SAnand V. Avati 			 */
12680b05b183SAnand V. Avati 			goto found;
12690b05b183SAnand V. Avati 		}
12700b05b183SAnand V. Avati 		dput(dentry);
12710b05b183SAnand V. Avati 	}
12720b05b183SAnand V. Avati 
12730b05b183SAnand V. Avati 	dentry = d_alloc(parent, &name);
12740b05b183SAnand V. Avati 	err = -ENOMEM;
12750b05b183SAnand V. Avati 	if (!dentry)
12760b05b183SAnand V. Avati 		goto out;
12770b05b183SAnand V. Avati 
12780b05b183SAnand V. Avati 	inode = fuse_iget(dir->i_sb, o->nodeid, o->generation,
12790b05b183SAnand V. Avati 			  &o->attr, entry_attr_timeout(o), attr_version);
12800b05b183SAnand V. Avati 	if (!inode)
12810b05b183SAnand V. Avati 		goto out;
12820b05b183SAnand V. Avati 
12835835f339SMiklos Szeredi 	alias = fuse_materialise_dentry(dentry, inode);
12840b05b183SAnand V. Avati 	err = PTR_ERR(alias);
12855835f339SMiklos Szeredi 	if (IS_ERR(alias))
12860b05b183SAnand V. Avati 		goto out;
12872914941eSMiklos Szeredi 
12880b05b183SAnand V. Avati 	if (alias) {
12890b05b183SAnand V. Avati 		dput(dentry);
12900b05b183SAnand V. Avati 		dentry = alias;
12910b05b183SAnand V. Avati 	}
12920b05b183SAnand V. Avati 
12930b05b183SAnand V. Avati found:
12940b05b183SAnand V. Avati 	fuse_change_entry_timeout(dentry, o);
12950b05b183SAnand V. Avati 
12960b05b183SAnand V. Avati 	err = 0;
12970b05b183SAnand V. Avati out:
12980b05b183SAnand V. Avati 	dput(dentry);
12990b05b183SAnand V. Avati 	return err;
13000b05b183SAnand V. Avati }
13010b05b183SAnand V. Avati 
13020b05b183SAnand V. Avati static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file,
13038d3af7f3SAl Viro 			     struct dir_context *ctx, u64 attr_version)
13040b05b183SAnand V. Avati {
13050b05b183SAnand V. Avati 	struct fuse_direntplus *direntplus;
13060b05b183SAnand V. Avati 	struct fuse_dirent *dirent;
13070b05b183SAnand V. Avati 	size_t reclen;
13080b05b183SAnand V. Avati 	int over = 0;
13090b05b183SAnand V. Avati 	int ret;
13100b05b183SAnand V. Avati 
13110b05b183SAnand V. Avati 	while (nbytes >= FUSE_NAME_OFFSET_DIRENTPLUS) {
13120b05b183SAnand V. Avati 		direntplus = (struct fuse_direntplus *) buf;
13130b05b183SAnand V. Avati 		dirent = &direntplus->dirent;
13140b05b183SAnand V. Avati 		reclen = FUSE_DIRENTPLUS_SIZE(direntplus);
13150b05b183SAnand V. Avati 
13160b05b183SAnand V. Avati 		if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
13170b05b183SAnand V. Avati 			return -EIO;
13180b05b183SAnand V. Avati 		if (reclen > nbytes)
13190b05b183SAnand V. Avati 			break;
1320efeb9e60SMiklos Szeredi 		if (memchr(dirent->name, '/', dirent->namelen) != NULL)
1321efeb9e60SMiklos Szeredi 			return -EIO;
13220b05b183SAnand V. Avati 
13230b05b183SAnand V. Avati 		if (!over) {
13240b05b183SAnand V. Avati 			/* We fill entries into dstbuf only as much as
13250b05b183SAnand V. Avati 			   it can hold. But we still continue iterating
13260b05b183SAnand V. Avati 			   over remaining entries to link them. If not,
13270b05b183SAnand V. Avati 			   we need to send a FORGET for each of those
13280b05b183SAnand V. Avati 			   which we did not link.
13290b05b183SAnand V. Avati 			*/
13308d3af7f3SAl Viro 			over = !dir_emit(ctx, dirent->name, dirent->namelen,
13318d3af7f3SAl Viro 				       dirent->ino, dirent->type);
13328d3af7f3SAl Viro 			ctx->pos = dirent->off;
13330b05b183SAnand V. Avati 		}
13340b05b183SAnand V. Avati 
13350b05b183SAnand V. Avati 		buf += reclen;
13360b05b183SAnand V. Avati 		nbytes -= reclen;
13370b05b183SAnand V. Avati 
13380b05b183SAnand V. Avati 		ret = fuse_direntplus_link(file, direntplus, attr_version);
13390b05b183SAnand V. Avati 		if (ret)
13400b05b183SAnand V. Avati 			fuse_force_forget(file, direntplus->entry_out.nodeid);
13410b05b183SAnand V. Avati 	}
13420b05b183SAnand V. Avati 
13430b05b183SAnand V. Avati 	return 0;
13440b05b183SAnand V. Avati }
13450b05b183SAnand V. Avati 
13468d3af7f3SAl Viro static int fuse_readdir(struct file *file, struct dir_context *ctx)
1347e5e5558eSMiklos Szeredi {
13484582a4abSFeng Shuo 	int plus, err;
134904730fefSMiklos Szeredi 	size_t nbytes;
135004730fefSMiklos Szeredi 	struct page *page;
1351496ad9aaSAl Viro 	struct inode *inode = file_inode(file);
135204730fefSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
1353248d86e8SMiklos Szeredi 	struct fuse_req *req;
13540b05b183SAnand V. Avati 	u64 attr_version = 0;
1355248d86e8SMiklos Szeredi 
1356248d86e8SMiklos Szeredi 	if (is_bad_inode(inode))
1357248d86e8SMiklos Szeredi 		return -EIO;
1358248d86e8SMiklos Szeredi 
1359b111c8c0SMaxim Patlasov 	req = fuse_get_req(fc, 1);
1360ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1361ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
1362e5e5558eSMiklos Szeredi 
136304730fefSMiklos Szeredi 	page = alloc_page(GFP_KERNEL);
136404730fefSMiklos Szeredi 	if (!page) {
136504730fefSMiklos Szeredi 		fuse_put_request(fc, req);
1366e5e5558eSMiklos Szeredi 		return -ENOMEM;
136704730fefSMiklos Szeredi 	}
13684582a4abSFeng Shuo 
13698d3af7f3SAl Viro 	plus = fuse_use_readdirplus(inode, ctx);
1370f4975c67SMiklos Szeredi 	req->out.argpages = 1;
137104730fefSMiklos Szeredi 	req->num_pages = 1;
137204730fefSMiklos Szeredi 	req->pages[0] = page;
137385f40aecSMaxim Patlasov 	req->page_descs[0].length = PAGE_SIZE;
13744582a4abSFeng Shuo 	if (plus) {
13750b05b183SAnand V. Avati 		attr_version = fuse_get_attr_version(fc);
13768d3af7f3SAl Viro 		fuse_read_fill(req, file, ctx->pos, PAGE_SIZE,
13770b05b183SAnand V. Avati 			       FUSE_READDIRPLUS);
13780b05b183SAnand V. Avati 	} else {
13798d3af7f3SAl Viro 		fuse_read_fill(req, file, ctx->pos, PAGE_SIZE,
13800b05b183SAnand V. Avati 			       FUSE_READDIR);
13810b05b183SAnand V. Avati 	}
1382b93f858aSTejun Heo 	fuse_request_send(fc, req);
1383361b1eb5SMiklos Szeredi 	nbytes = req->out.args[0].size;
138404730fefSMiklos Szeredi 	err = req->out.h.error;
138504730fefSMiklos Szeredi 	fuse_put_request(fc, req);
13860b05b183SAnand V. Avati 	if (!err) {
13874582a4abSFeng Shuo 		if (plus) {
13880b05b183SAnand V. Avati 			err = parse_dirplusfile(page_address(page), nbytes,
13898d3af7f3SAl Viro 						file, ctx,
13900b05b183SAnand V. Avati 						attr_version);
13910b05b183SAnand V. Avati 		} else {
13920b05b183SAnand V. Avati 			err = parse_dirfile(page_address(page), nbytes, file,
13938d3af7f3SAl Viro 					    ctx);
13940b05b183SAnand V. Avati 		}
13950b05b183SAnand V. Avati 	}
1396e5e5558eSMiklos Szeredi 
139704730fefSMiklos Szeredi 	__free_page(page);
1398b36c31baSMiklos Szeredi 	fuse_invalidate_attr(inode); /* atime changed */
139904730fefSMiklos Szeredi 	return err;
1400e5e5558eSMiklos Szeredi }
1401e5e5558eSMiklos Szeredi 
1402e5e5558eSMiklos Szeredi static char *read_link(struct dentry *dentry)
1403e5e5558eSMiklos Szeredi {
1404e5e5558eSMiklos Szeredi 	struct inode *inode = dentry->d_inode;
1405e5e5558eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
1406b111c8c0SMaxim Patlasov 	struct fuse_req *req = fuse_get_req_nopages(fc);
1407e5e5558eSMiklos Szeredi 	char *link;
1408e5e5558eSMiklos Szeredi 
1409ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1410e231c2eeSDavid Howells 		return ERR_CAST(req);
1411e5e5558eSMiklos Szeredi 
1412e5e5558eSMiklos Szeredi 	link = (char *) __get_free_page(GFP_KERNEL);
1413e5e5558eSMiklos Szeredi 	if (!link) {
1414e5e5558eSMiklos Szeredi 		link = ERR_PTR(-ENOMEM);
1415e5e5558eSMiklos Szeredi 		goto out;
1416e5e5558eSMiklos Szeredi 	}
1417e5e5558eSMiklos Szeredi 	req->in.h.opcode = FUSE_READLINK;
1418e5e5558eSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
1419e5e5558eSMiklos Szeredi 	req->out.argvar = 1;
1420e5e5558eSMiklos Szeredi 	req->out.numargs = 1;
1421e5e5558eSMiklos Szeredi 	req->out.args[0].size = PAGE_SIZE - 1;
1422e5e5558eSMiklos Szeredi 	req->out.args[0].value = link;
1423b93f858aSTejun Heo 	fuse_request_send(fc, req);
1424e5e5558eSMiklos Szeredi 	if (req->out.h.error) {
1425e5e5558eSMiklos Szeredi 		free_page((unsigned long) link);
1426e5e5558eSMiklos Szeredi 		link = ERR_PTR(req->out.h.error);
1427e5e5558eSMiklos Szeredi 	} else
1428e5e5558eSMiklos Szeredi 		link[req->out.args[0].size] = '\0';
1429e5e5558eSMiklos Szeredi  out:
1430e5e5558eSMiklos Szeredi 	fuse_put_request(fc, req);
1431b36c31baSMiklos Szeredi 	fuse_invalidate_attr(inode); /* atime changed */
1432e5e5558eSMiklos Szeredi 	return link;
1433e5e5558eSMiklos Szeredi }
1434e5e5558eSMiklos Szeredi 
1435e5e5558eSMiklos Szeredi static void free_link(char *link)
1436e5e5558eSMiklos Szeredi {
1437e5e5558eSMiklos Szeredi 	if (!IS_ERR(link))
1438e5e5558eSMiklos Szeredi 		free_page((unsigned long) link);
1439e5e5558eSMiklos Szeredi }
1440e5e5558eSMiklos Szeredi 
1441e5e5558eSMiklos Szeredi static void *fuse_follow_link(struct dentry *dentry, struct nameidata *nd)
1442e5e5558eSMiklos Szeredi {
1443e5e5558eSMiklos Szeredi 	nd_set_link(nd, read_link(dentry));
1444e5e5558eSMiklos Szeredi 	return NULL;
1445e5e5558eSMiklos Szeredi }
1446e5e5558eSMiklos Szeredi 
1447e5e5558eSMiklos Szeredi static void fuse_put_link(struct dentry *dentry, struct nameidata *nd, void *c)
1448e5e5558eSMiklos Szeredi {
1449e5e5558eSMiklos Szeredi 	free_link(nd_get_link(nd));
1450e5e5558eSMiklos Szeredi }
1451e5e5558eSMiklos Szeredi 
1452e5e5558eSMiklos Szeredi static int fuse_dir_open(struct inode *inode, struct file *file)
1453e5e5558eSMiklos Szeredi {
145491fe96b4SMiklos Szeredi 	return fuse_open_common(inode, file, true);
1455e5e5558eSMiklos Szeredi }
1456e5e5558eSMiklos Szeredi 
1457e5e5558eSMiklos Szeredi static int fuse_dir_release(struct inode *inode, struct file *file)
1458e5e5558eSMiklos Szeredi {
14598b0797a4SMiklos Szeredi 	fuse_release_common(file, FUSE_RELEASEDIR);
14608b0797a4SMiklos Szeredi 
14618b0797a4SMiklos Szeredi 	return 0;
1462e5e5558eSMiklos Szeredi }
1463e5e5558eSMiklos Szeredi 
146402c24a82SJosef Bacik static int fuse_dir_fsync(struct file *file, loff_t start, loff_t end,
146502c24a82SJosef Bacik 			  int datasync)
146682547981SMiklos Szeredi {
146702c24a82SJosef Bacik 	return fuse_fsync_common(file, start, end, datasync, 1);
146882547981SMiklos Szeredi }
146982547981SMiklos Szeredi 
1470b18da0c5SMiklos Szeredi static long fuse_dir_ioctl(struct file *file, unsigned int cmd,
1471b18da0c5SMiklos Szeredi 			    unsigned long arg)
1472b18da0c5SMiklos Szeredi {
1473b18da0c5SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1474b18da0c5SMiklos Szeredi 
1475b18da0c5SMiklos Szeredi 	/* FUSE_IOCTL_DIR only supported for API version >= 7.18 */
1476b18da0c5SMiklos Szeredi 	if (fc->minor < 18)
1477b18da0c5SMiklos Szeredi 		return -ENOTTY;
1478b18da0c5SMiklos Szeredi 
1479b18da0c5SMiklos Szeredi 	return fuse_ioctl_common(file, cmd, arg, FUSE_IOCTL_DIR);
1480b18da0c5SMiklos Szeredi }
1481b18da0c5SMiklos Szeredi 
1482b18da0c5SMiklos Szeredi static long fuse_dir_compat_ioctl(struct file *file, unsigned int cmd,
1483b18da0c5SMiklos Szeredi 				   unsigned long arg)
1484b18da0c5SMiklos Szeredi {
1485b18da0c5SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1486b18da0c5SMiklos Szeredi 
1487b18da0c5SMiklos Szeredi 	if (fc->minor < 18)
1488b18da0c5SMiklos Szeredi 		return -ENOTTY;
1489b18da0c5SMiklos Szeredi 
1490b18da0c5SMiklos Szeredi 	return fuse_ioctl_common(file, cmd, arg,
1491b18da0c5SMiklos Szeredi 				 FUSE_IOCTL_COMPAT | FUSE_IOCTL_DIR);
1492b18da0c5SMiklos Szeredi }
1493b18da0c5SMiklos Szeredi 
149417637cbaSMiklos Szeredi static bool update_mtime(unsigned ivalid)
149517637cbaSMiklos Szeredi {
149617637cbaSMiklos Szeredi 	/* Always update if mtime is explicitly set  */
149717637cbaSMiklos Szeredi 	if (ivalid & ATTR_MTIME_SET)
149817637cbaSMiklos Szeredi 		return true;
149917637cbaSMiklos Szeredi 
150017637cbaSMiklos Szeredi 	/* If it's an open(O_TRUNC) or an ftruncate(), don't update */
150117637cbaSMiklos Szeredi 	if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE)))
150217637cbaSMiklos Szeredi 		return false;
150317637cbaSMiklos Szeredi 
150417637cbaSMiklos Szeredi 	/* In all other cases update */
150517637cbaSMiklos Szeredi 	return true;
150617637cbaSMiklos Szeredi }
150717637cbaSMiklos Szeredi 
1508befc649cSMiklos Szeredi static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
15099e6268dbSMiklos Szeredi {
15109e6268dbSMiklos Szeredi 	unsigned ivalid = iattr->ia_valid;
15119e6268dbSMiklos Szeredi 
15129e6268dbSMiklos Szeredi 	if (ivalid & ATTR_MODE)
1513befc649cSMiklos Szeredi 		arg->valid |= FATTR_MODE,   arg->mode = iattr->ia_mode;
15149e6268dbSMiklos Szeredi 	if (ivalid & ATTR_UID)
1515499dcf20SEric W. Biederman 		arg->valid |= FATTR_UID,    arg->uid = from_kuid(&init_user_ns, iattr->ia_uid);
15169e6268dbSMiklos Szeredi 	if (ivalid & ATTR_GID)
1517499dcf20SEric W. Biederman 		arg->valid |= FATTR_GID,    arg->gid = from_kgid(&init_user_ns, iattr->ia_gid);
15189e6268dbSMiklos Szeredi 	if (ivalid & ATTR_SIZE)
1519befc649cSMiklos Szeredi 		arg->valid |= FATTR_SIZE,   arg->size = iattr->ia_size;
152017637cbaSMiklos Szeredi 	if (ivalid & ATTR_ATIME) {
152117637cbaSMiklos Szeredi 		arg->valid |= FATTR_ATIME;
1522befc649cSMiklos Szeredi 		arg->atime = iattr->ia_atime.tv_sec;
152317637cbaSMiklos Szeredi 		arg->atimensec = iattr->ia_atime.tv_nsec;
152417637cbaSMiklos Szeredi 		if (!(ivalid & ATTR_ATIME_SET))
152517637cbaSMiklos Szeredi 			arg->valid |= FATTR_ATIME_NOW;
152617637cbaSMiklos Szeredi 	}
152717637cbaSMiklos Szeredi 	if ((ivalid & ATTR_MTIME) && update_mtime(ivalid)) {
152817637cbaSMiklos Szeredi 		arg->valid |= FATTR_MTIME;
1529befc649cSMiklos Szeredi 		arg->mtime = iattr->ia_mtime.tv_sec;
153017637cbaSMiklos Szeredi 		arg->mtimensec = iattr->ia_mtime.tv_nsec;
153117637cbaSMiklos Szeredi 		if (!(ivalid & ATTR_MTIME_SET))
153217637cbaSMiklos Szeredi 			arg->valid |= FATTR_MTIME_NOW;
15339e6268dbSMiklos Szeredi 	}
15349e6268dbSMiklos Szeredi }
15359e6268dbSMiklos Szeredi 
15366f9f1180SMiklos Szeredi /*
15373be5a52bSMiklos Szeredi  * Prevent concurrent writepages on inode
15383be5a52bSMiklos Szeredi  *
15393be5a52bSMiklos Szeredi  * This is done by adding a negative bias to the inode write counter
15403be5a52bSMiklos Szeredi  * and waiting for all pending writes to finish.
15413be5a52bSMiklos Szeredi  */
15423be5a52bSMiklos Szeredi void fuse_set_nowrite(struct inode *inode)
15433be5a52bSMiklos Szeredi {
15443be5a52bSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
15453be5a52bSMiklos Szeredi 	struct fuse_inode *fi = get_fuse_inode(inode);
15463be5a52bSMiklos Szeredi 
15473be5a52bSMiklos Szeredi 	BUG_ON(!mutex_is_locked(&inode->i_mutex));
15483be5a52bSMiklos Szeredi 
15493be5a52bSMiklos Szeredi 	spin_lock(&fc->lock);
15503be5a52bSMiklos Szeredi 	BUG_ON(fi->writectr < 0);
15513be5a52bSMiklos Szeredi 	fi->writectr += FUSE_NOWRITE;
15523be5a52bSMiklos Szeredi 	spin_unlock(&fc->lock);
15533be5a52bSMiklos Szeredi 	wait_event(fi->page_waitq, fi->writectr == FUSE_NOWRITE);
15543be5a52bSMiklos Szeredi }
15553be5a52bSMiklos Szeredi 
15563be5a52bSMiklos Szeredi /*
15573be5a52bSMiklos Szeredi  * Allow writepages on inode
15583be5a52bSMiklos Szeredi  *
15593be5a52bSMiklos Szeredi  * Remove the bias from the writecounter and send any queued
15603be5a52bSMiklos Szeredi  * writepages.
15613be5a52bSMiklos Szeredi  */
15623be5a52bSMiklos Szeredi static void __fuse_release_nowrite(struct inode *inode)
15633be5a52bSMiklos Szeredi {
15643be5a52bSMiklos Szeredi 	struct fuse_inode *fi = get_fuse_inode(inode);
15653be5a52bSMiklos Szeredi 
15663be5a52bSMiklos Szeredi 	BUG_ON(fi->writectr != FUSE_NOWRITE);
15673be5a52bSMiklos Szeredi 	fi->writectr = 0;
15683be5a52bSMiklos Szeredi 	fuse_flush_writepages(inode);
15693be5a52bSMiklos Szeredi }
15703be5a52bSMiklos Szeredi 
15713be5a52bSMiklos Szeredi void fuse_release_nowrite(struct inode *inode)
15723be5a52bSMiklos Szeredi {
15733be5a52bSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
15743be5a52bSMiklos Szeredi 
15753be5a52bSMiklos Szeredi 	spin_lock(&fc->lock);
15763be5a52bSMiklos Szeredi 	__fuse_release_nowrite(inode);
15773be5a52bSMiklos Szeredi 	spin_unlock(&fc->lock);
15783be5a52bSMiklos Szeredi }
15793be5a52bSMiklos Szeredi 
15803be5a52bSMiklos Szeredi /*
15816f9f1180SMiklos Szeredi  * Set attributes, and at the same time refresh them.
15826f9f1180SMiklos Szeredi  *
15836f9f1180SMiklos Szeredi  * Truncation is slightly complicated, because the 'truncate' request
15846f9f1180SMiklos Szeredi  * may fail, in which case we don't want to touch the mapping.
15859ffbb916SMiklos Szeredi  * vmtruncate() doesn't allow for this case, so do the rlimit checking
15869ffbb916SMiklos Szeredi  * and the actual truncation by hand.
15876f9f1180SMiklos Szeredi  */
1588efb9fa9eSMaxim Patlasov int fuse_do_setattr(struct inode *inode, struct iattr *attr,
158949d4914fSMiklos Szeredi 		    struct file *file)
15909e6268dbSMiklos Szeredi {
15919e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
159206a7c3c2SMaxim Patlasov 	struct fuse_inode *fi = get_fuse_inode(inode);
15939e6268dbSMiklos Szeredi 	struct fuse_req *req;
15949e6268dbSMiklos Szeredi 	struct fuse_setattr_in inarg;
15959e6268dbSMiklos Szeredi 	struct fuse_attr_out outarg;
15963be5a52bSMiklos Szeredi 	bool is_truncate = false;
15973be5a52bSMiklos Szeredi 	loff_t oldsize;
15989e6268dbSMiklos Szeredi 	int err;
15999e6268dbSMiklos Szeredi 
1600db78b877SChristoph Hellwig 	if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS))
1601db78b877SChristoph Hellwig 		attr->ia_valid |= ATTR_FORCE;
1602db78b877SChristoph Hellwig 
16031e9a4ed9SMiklos Szeredi 	err = inode_change_ok(inode, attr);
16041e9a4ed9SMiklos Szeredi 	if (err)
16051e9a4ed9SMiklos Szeredi 		return err;
16061e9a4ed9SMiklos Szeredi 
16078d56adddSMiklos Szeredi 	if (attr->ia_valid & ATTR_OPEN) {
16088d56adddSMiklos Szeredi 		if (fc->atomic_o_trunc)
16096ff958edSMiklos Szeredi 			return 0;
16108d56adddSMiklos Szeredi 		file = NULL;
16118d56adddSMiklos Szeredi 	}
16126ff958edSMiklos Szeredi 
16132c27c65eSChristoph Hellwig 	if (attr->ia_valid & ATTR_SIZE)
16143be5a52bSMiklos Szeredi 		is_truncate = true;
16159e6268dbSMiklos Szeredi 
1616b111c8c0SMaxim Patlasov 	req = fuse_get_req_nopages(fc);
1617ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1618ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
16199e6268dbSMiklos Szeredi 
162006a7c3c2SMaxim Patlasov 	if (is_truncate) {
16213be5a52bSMiklos Szeredi 		fuse_set_nowrite(inode);
162206a7c3c2SMaxim Patlasov 		set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
162306a7c3c2SMaxim Patlasov 	}
16243be5a52bSMiklos Szeredi 
16259e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
16260e9663eeSMiklos Szeredi 	memset(&outarg, 0, sizeof(outarg));
1627befc649cSMiklos Szeredi 	iattr_to_fattr(attr, &inarg);
162849d4914fSMiklos Szeredi 	if (file) {
162949d4914fSMiklos Szeredi 		struct fuse_file *ff = file->private_data;
163049d4914fSMiklos Szeredi 		inarg.valid |= FATTR_FH;
163149d4914fSMiklos Szeredi 		inarg.fh = ff->fh;
163249d4914fSMiklos Szeredi 	}
1633f3332114SMiklos Szeredi 	if (attr->ia_valid & ATTR_SIZE) {
1634f3332114SMiklos Szeredi 		/* For mandatory locking in truncate */
1635f3332114SMiklos Szeredi 		inarg.valid |= FATTR_LOCKOWNER;
1636f3332114SMiklos Szeredi 		inarg.lock_owner = fuse_lock_owner_id(fc, current->files);
1637f3332114SMiklos Szeredi 	}
16389e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_SETATTR;
16399e6268dbSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
16409e6268dbSMiklos Szeredi 	req->in.numargs = 1;
16419e6268dbSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
16429e6268dbSMiklos Szeredi 	req->in.args[0].value = &inarg;
16439e6268dbSMiklos Szeredi 	req->out.numargs = 1;
16440e9663eeSMiklos Szeredi 	if (fc->minor < 9)
16450e9663eeSMiklos Szeredi 		req->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
16460e9663eeSMiklos Szeredi 	else
16479e6268dbSMiklos Szeredi 		req->out.args[0].size = sizeof(outarg);
16489e6268dbSMiklos Szeredi 	req->out.args[0].value = &outarg;
1649b93f858aSTejun Heo 	fuse_request_send(fc, req);
16509e6268dbSMiklos Szeredi 	err = req->out.h.error;
16519e6268dbSMiklos Szeredi 	fuse_put_request(fc, req);
1652e00d2c2dSMiklos Szeredi 	if (err) {
1653e00d2c2dSMiklos Szeredi 		if (err == -EINTR)
1654e00d2c2dSMiklos Szeredi 			fuse_invalidate_attr(inode);
16553be5a52bSMiklos Szeredi 		goto error;
1656e00d2c2dSMiklos Szeredi 	}
1657e00d2c2dSMiklos Szeredi 
16589e6268dbSMiklos Szeredi 	if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
16599e6268dbSMiklos Szeredi 		make_bad_inode(inode);
16603be5a52bSMiklos Szeredi 		err = -EIO;
16613be5a52bSMiklos Szeredi 		goto error;
16629e6268dbSMiklos Szeredi 	}
16639e6268dbSMiklos Szeredi 
16643be5a52bSMiklos Szeredi 	spin_lock(&fc->lock);
16653be5a52bSMiklos Szeredi 	fuse_change_attributes_common(inode, &outarg.attr,
16663be5a52bSMiklos Szeredi 				      attr_timeout(&outarg));
16673be5a52bSMiklos Szeredi 	oldsize = inode->i_size;
16683be5a52bSMiklos Szeredi 	i_size_write(inode, outarg.attr.size);
16693be5a52bSMiklos Szeredi 
16703be5a52bSMiklos Szeredi 	if (is_truncate) {
16713be5a52bSMiklos Szeredi 		/* NOTE: this may release/reacquire fc->lock */
16723be5a52bSMiklos Szeredi 		__fuse_release_nowrite(inode);
16733be5a52bSMiklos Szeredi 	}
16743be5a52bSMiklos Szeredi 	spin_unlock(&fc->lock);
16753be5a52bSMiklos Szeredi 
16763be5a52bSMiklos Szeredi 	/*
16773be5a52bSMiklos Szeredi 	 * Only call invalidate_inode_pages2() after removing
16783be5a52bSMiklos Szeredi 	 * FUSE_NOWRITE, otherwise fuse_launder_page() would deadlock.
16793be5a52bSMiklos Szeredi 	 */
16803be5a52bSMiklos Szeredi 	if (S_ISREG(inode->i_mode) && oldsize != outarg.attr.size) {
1681*7caef267SKirill A. Shutemov 		truncate_pagecache(inode, outarg.attr.size);
16823be5a52bSMiklos Szeredi 		invalidate_inode_pages2(inode->i_mapping);
16833be5a52bSMiklos Szeredi 	}
16843be5a52bSMiklos Szeredi 
168506a7c3c2SMaxim Patlasov 	clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
1686e00d2c2dSMiklos Szeredi 	return 0;
16873be5a52bSMiklos Szeredi 
16883be5a52bSMiklos Szeredi error:
16893be5a52bSMiklos Szeredi 	if (is_truncate)
16903be5a52bSMiklos Szeredi 		fuse_release_nowrite(inode);
16913be5a52bSMiklos Szeredi 
169206a7c3c2SMaxim Patlasov 	clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
16933be5a52bSMiklos Szeredi 	return err;
16949e6268dbSMiklos Szeredi }
16959e6268dbSMiklos Szeredi 
169649d4914fSMiklos Szeredi static int fuse_setattr(struct dentry *entry, struct iattr *attr)
169749d4914fSMiklos Szeredi {
1698efb9fa9eSMaxim Patlasov 	struct inode *inode = entry->d_inode;
1699efb9fa9eSMaxim Patlasov 
1700efb9fa9eSMaxim Patlasov 	if (!fuse_allow_current_process(get_fuse_conn(inode)))
1701efb9fa9eSMaxim Patlasov 		return -EACCES;
1702efb9fa9eSMaxim Patlasov 
170349d4914fSMiklos Szeredi 	if (attr->ia_valid & ATTR_FILE)
1704efb9fa9eSMaxim Patlasov 		return fuse_do_setattr(inode, attr, attr->ia_file);
170549d4914fSMiklos Szeredi 	else
1706efb9fa9eSMaxim Patlasov 		return fuse_do_setattr(inode, attr, NULL);
170749d4914fSMiklos Szeredi }
170849d4914fSMiklos Szeredi 
1709e5e5558eSMiklos Szeredi static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
1710e5e5558eSMiklos Szeredi 			struct kstat *stat)
1711e5e5558eSMiklos Szeredi {
1712e5e5558eSMiklos Szeredi 	struct inode *inode = entry->d_inode;
1713244f6385SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
1714244f6385SMiklos Szeredi 
1715c2132c1bSAnatol Pomozov 	if (!fuse_allow_current_process(fc))
1716244f6385SMiklos Szeredi 		return -EACCES;
1717244f6385SMiklos Szeredi 
1718bcb4be80SMiklos Szeredi 	return fuse_update_attributes(inode, stat, NULL, NULL);
1719e5e5558eSMiklos Szeredi }
1720e5e5558eSMiklos Szeredi 
172192a8780eSMiklos Szeredi static int fuse_setxattr(struct dentry *entry, const char *name,
172292a8780eSMiklos Szeredi 			 const void *value, size_t size, int flags)
172392a8780eSMiklos Szeredi {
172492a8780eSMiklos Szeredi 	struct inode *inode = entry->d_inode;
172592a8780eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
172692a8780eSMiklos Szeredi 	struct fuse_req *req;
172792a8780eSMiklos Szeredi 	struct fuse_setxattr_in inarg;
172892a8780eSMiklos Szeredi 	int err;
172992a8780eSMiklos Szeredi 
173092a8780eSMiklos Szeredi 	if (fc->no_setxattr)
173192a8780eSMiklos Szeredi 		return -EOPNOTSUPP;
173292a8780eSMiklos Szeredi 
1733b111c8c0SMaxim Patlasov 	req = fuse_get_req_nopages(fc);
1734ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1735ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
173692a8780eSMiklos Szeredi 
173792a8780eSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
173892a8780eSMiklos Szeredi 	inarg.size = size;
173992a8780eSMiklos Szeredi 	inarg.flags = flags;
174092a8780eSMiklos Szeredi 	req->in.h.opcode = FUSE_SETXATTR;
174192a8780eSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
174292a8780eSMiklos Szeredi 	req->in.numargs = 3;
174392a8780eSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
174492a8780eSMiklos Szeredi 	req->in.args[0].value = &inarg;
174592a8780eSMiklos Szeredi 	req->in.args[1].size = strlen(name) + 1;
174692a8780eSMiklos Szeredi 	req->in.args[1].value = name;
174792a8780eSMiklos Szeredi 	req->in.args[2].size = size;
174892a8780eSMiklos Szeredi 	req->in.args[2].value = value;
1749b93f858aSTejun Heo 	fuse_request_send(fc, req);
175092a8780eSMiklos Szeredi 	err = req->out.h.error;
175192a8780eSMiklos Szeredi 	fuse_put_request(fc, req);
175292a8780eSMiklos Szeredi 	if (err == -ENOSYS) {
175392a8780eSMiklos Szeredi 		fc->no_setxattr = 1;
175492a8780eSMiklos Szeredi 		err = -EOPNOTSUPP;
175592a8780eSMiklos Szeredi 	}
1756d331a415SAnand Avati 	if (!err)
1757d331a415SAnand Avati 		fuse_invalidate_attr(inode);
175892a8780eSMiklos Szeredi 	return err;
175992a8780eSMiklos Szeredi }
176092a8780eSMiklos Szeredi 
176192a8780eSMiklos Szeredi static ssize_t fuse_getxattr(struct dentry *entry, const char *name,
176292a8780eSMiklos Szeredi 			     void *value, size_t size)
176392a8780eSMiklos Szeredi {
176492a8780eSMiklos Szeredi 	struct inode *inode = entry->d_inode;
176592a8780eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
176692a8780eSMiklos Szeredi 	struct fuse_req *req;
176792a8780eSMiklos Szeredi 	struct fuse_getxattr_in inarg;
176892a8780eSMiklos Szeredi 	struct fuse_getxattr_out outarg;
176992a8780eSMiklos Szeredi 	ssize_t ret;
177092a8780eSMiklos Szeredi 
177192a8780eSMiklos Szeredi 	if (fc->no_getxattr)
177292a8780eSMiklos Szeredi 		return -EOPNOTSUPP;
177392a8780eSMiklos Szeredi 
1774b111c8c0SMaxim Patlasov 	req = fuse_get_req_nopages(fc);
1775ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1776ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
177792a8780eSMiklos Szeredi 
177892a8780eSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
177992a8780eSMiklos Szeredi 	inarg.size = size;
178092a8780eSMiklos Szeredi 	req->in.h.opcode = FUSE_GETXATTR;
178192a8780eSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
178292a8780eSMiklos Szeredi 	req->in.numargs = 2;
178392a8780eSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
178492a8780eSMiklos Szeredi 	req->in.args[0].value = &inarg;
178592a8780eSMiklos Szeredi 	req->in.args[1].size = strlen(name) + 1;
178692a8780eSMiklos Szeredi 	req->in.args[1].value = name;
178792a8780eSMiklos Szeredi 	/* This is really two different operations rolled into one */
178892a8780eSMiklos Szeredi 	req->out.numargs = 1;
178992a8780eSMiklos Szeredi 	if (size) {
179092a8780eSMiklos Szeredi 		req->out.argvar = 1;
179192a8780eSMiklos Szeredi 		req->out.args[0].size = size;
179292a8780eSMiklos Szeredi 		req->out.args[0].value = value;
179392a8780eSMiklos Szeredi 	} else {
179492a8780eSMiklos Szeredi 		req->out.args[0].size = sizeof(outarg);
179592a8780eSMiklos Szeredi 		req->out.args[0].value = &outarg;
179692a8780eSMiklos Szeredi 	}
1797b93f858aSTejun Heo 	fuse_request_send(fc, req);
179892a8780eSMiklos Szeredi 	ret = req->out.h.error;
179992a8780eSMiklos Szeredi 	if (!ret)
180092a8780eSMiklos Szeredi 		ret = size ? req->out.args[0].size : outarg.size;
180192a8780eSMiklos Szeredi 	else {
180292a8780eSMiklos Szeredi 		if (ret == -ENOSYS) {
180392a8780eSMiklos Szeredi 			fc->no_getxattr = 1;
180492a8780eSMiklos Szeredi 			ret = -EOPNOTSUPP;
180592a8780eSMiklos Szeredi 		}
180692a8780eSMiklos Szeredi 	}
180792a8780eSMiklos Szeredi 	fuse_put_request(fc, req);
180892a8780eSMiklos Szeredi 	return ret;
180992a8780eSMiklos Szeredi }
181092a8780eSMiklos Szeredi 
181192a8780eSMiklos Szeredi static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
181292a8780eSMiklos Szeredi {
181392a8780eSMiklos Szeredi 	struct inode *inode = entry->d_inode;
181492a8780eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
181592a8780eSMiklos Szeredi 	struct fuse_req *req;
181692a8780eSMiklos Szeredi 	struct fuse_getxattr_in inarg;
181792a8780eSMiklos Szeredi 	struct fuse_getxattr_out outarg;
181892a8780eSMiklos Szeredi 	ssize_t ret;
181992a8780eSMiklos Szeredi 
1820c2132c1bSAnatol Pomozov 	if (!fuse_allow_current_process(fc))
1821e57ac683SMiklos Szeredi 		return -EACCES;
1822e57ac683SMiklos Szeredi 
182392a8780eSMiklos Szeredi 	if (fc->no_listxattr)
182492a8780eSMiklos Szeredi 		return -EOPNOTSUPP;
182592a8780eSMiklos Szeredi 
1826b111c8c0SMaxim Patlasov 	req = fuse_get_req_nopages(fc);
1827ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1828ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
182992a8780eSMiklos Szeredi 
183092a8780eSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
183192a8780eSMiklos Szeredi 	inarg.size = size;
183292a8780eSMiklos Szeredi 	req->in.h.opcode = FUSE_LISTXATTR;
183392a8780eSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
183492a8780eSMiklos Szeredi 	req->in.numargs = 1;
183592a8780eSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
183692a8780eSMiklos Szeredi 	req->in.args[0].value = &inarg;
183792a8780eSMiklos Szeredi 	/* This is really two different operations rolled into one */
183892a8780eSMiklos Szeredi 	req->out.numargs = 1;
183992a8780eSMiklos Szeredi 	if (size) {
184092a8780eSMiklos Szeredi 		req->out.argvar = 1;
184192a8780eSMiklos Szeredi 		req->out.args[0].size = size;
184292a8780eSMiklos Szeredi 		req->out.args[0].value = list;
184392a8780eSMiklos Szeredi 	} else {
184492a8780eSMiklos Szeredi 		req->out.args[0].size = sizeof(outarg);
184592a8780eSMiklos Szeredi 		req->out.args[0].value = &outarg;
184692a8780eSMiklos Szeredi 	}
1847b93f858aSTejun Heo 	fuse_request_send(fc, req);
184892a8780eSMiklos Szeredi 	ret = req->out.h.error;
184992a8780eSMiklos Szeredi 	if (!ret)
185092a8780eSMiklos Szeredi 		ret = size ? req->out.args[0].size : outarg.size;
185192a8780eSMiklos Szeredi 	else {
185292a8780eSMiklos Szeredi 		if (ret == -ENOSYS) {
185392a8780eSMiklos Szeredi 			fc->no_listxattr = 1;
185492a8780eSMiklos Szeredi 			ret = -EOPNOTSUPP;
185592a8780eSMiklos Szeredi 		}
185692a8780eSMiklos Szeredi 	}
185792a8780eSMiklos Szeredi 	fuse_put_request(fc, req);
185892a8780eSMiklos Szeredi 	return ret;
185992a8780eSMiklos Szeredi }
186092a8780eSMiklos Szeredi 
186192a8780eSMiklos Szeredi static int fuse_removexattr(struct dentry *entry, const char *name)
186292a8780eSMiklos Szeredi {
186392a8780eSMiklos Szeredi 	struct inode *inode = entry->d_inode;
186492a8780eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
186592a8780eSMiklos Szeredi 	struct fuse_req *req;
186692a8780eSMiklos Szeredi 	int err;
186792a8780eSMiklos Szeredi 
186892a8780eSMiklos Szeredi 	if (fc->no_removexattr)
186992a8780eSMiklos Szeredi 		return -EOPNOTSUPP;
187092a8780eSMiklos Szeredi 
1871b111c8c0SMaxim Patlasov 	req = fuse_get_req_nopages(fc);
1872ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1873ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
187492a8780eSMiklos Szeredi 
187592a8780eSMiklos Szeredi 	req->in.h.opcode = FUSE_REMOVEXATTR;
187692a8780eSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
187792a8780eSMiklos Szeredi 	req->in.numargs = 1;
187892a8780eSMiklos Szeredi 	req->in.args[0].size = strlen(name) + 1;
187992a8780eSMiklos Szeredi 	req->in.args[0].value = name;
1880b93f858aSTejun Heo 	fuse_request_send(fc, req);
188192a8780eSMiklos Szeredi 	err = req->out.h.error;
188292a8780eSMiklos Szeredi 	fuse_put_request(fc, req);
188392a8780eSMiklos Szeredi 	if (err == -ENOSYS) {
188492a8780eSMiklos Szeredi 		fc->no_removexattr = 1;
188592a8780eSMiklos Szeredi 		err = -EOPNOTSUPP;
188692a8780eSMiklos Szeredi 	}
1887d331a415SAnand Avati 	if (!err)
1888d331a415SAnand Avati 		fuse_invalidate_attr(inode);
188992a8780eSMiklos Szeredi 	return err;
189092a8780eSMiklos Szeredi }
189192a8780eSMiklos Szeredi 
1892754661f1SArjan van de Ven static const struct inode_operations fuse_dir_inode_operations = {
1893e5e5558eSMiklos Szeredi 	.lookup		= fuse_lookup,
18949e6268dbSMiklos Szeredi 	.mkdir		= fuse_mkdir,
18959e6268dbSMiklos Szeredi 	.symlink	= fuse_symlink,
18969e6268dbSMiklos Szeredi 	.unlink		= fuse_unlink,
18979e6268dbSMiklos Szeredi 	.rmdir		= fuse_rmdir,
18989e6268dbSMiklos Szeredi 	.rename		= fuse_rename,
18999e6268dbSMiklos Szeredi 	.link		= fuse_link,
19009e6268dbSMiklos Szeredi 	.setattr	= fuse_setattr,
19019e6268dbSMiklos Szeredi 	.create		= fuse_create,
1902c8ccbe03SMiklos Szeredi 	.atomic_open	= fuse_atomic_open,
19039e6268dbSMiklos Szeredi 	.mknod		= fuse_mknod,
1904e5e5558eSMiklos Szeredi 	.permission	= fuse_permission,
1905e5e5558eSMiklos Szeredi 	.getattr	= fuse_getattr,
190692a8780eSMiklos Szeredi 	.setxattr	= fuse_setxattr,
190792a8780eSMiklos Szeredi 	.getxattr	= fuse_getxattr,
190892a8780eSMiklos Szeredi 	.listxattr	= fuse_listxattr,
190992a8780eSMiklos Szeredi 	.removexattr	= fuse_removexattr,
1910e5e5558eSMiklos Szeredi };
1911e5e5558eSMiklos Szeredi 
19124b6f5d20SArjan van de Ven static const struct file_operations fuse_dir_operations = {
1913b6aeadedSMiklos Szeredi 	.llseek		= generic_file_llseek,
1914e5e5558eSMiklos Szeredi 	.read		= generic_read_dir,
19158d3af7f3SAl Viro 	.iterate	= fuse_readdir,
1916e5e5558eSMiklos Szeredi 	.open		= fuse_dir_open,
1917e5e5558eSMiklos Szeredi 	.release	= fuse_dir_release,
191882547981SMiklos Szeredi 	.fsync		= fuse_dir_fsync,
1919b18da0c5SMiklos Szeredi 	.unlocked_ioctl	= fuse_dir_ioctl,
1920b18da0c5SMiklos Szeredi 	.compat_ioctl	= fuse_dir_compat_ioctl,
1921e5e5558eSMiklos Szeredi };
1922e5e5558eSMiklos Szeredi 
1923754661f1SArjan van de Ven static const struct inode_operations fuse_common_inode_operations = {
19249e6268dbSMiklos Szeredi 	.setattr	= fuse_setattr,
1925e5e5558eSMiklos Szeredi 	.permission	= fuse_permission,
1926e5e5558eSMiklos Szeredi 	.getattr	= fuse_getattr,
192792a8780eSMiklos Szeredi 	.setxattr	= fuse_setxattr,
192892a8780eSMiklos Szeredi 	.getxattr	= fuse_getxattr,
192992a8780eSMiklos Szeredi 	.listxattr	= fuse_listxattr,
193092a8780eSMiklos Szeredi 	.removexattr	= fuse_removexattr,
1931e5e5558eSMiklos Szeredi };
1932e5e5558eSMiklos Szeredi 
1933754661f1SArjan van de Ven static const struct inode_operations fuse_symlink_inode_operations = {
19349e6268dbSMiklos Szeredi 	.setattr	= fuse_setattr,
1935e5e5558eSMiklos Szeredi 	.follow_link	= fuse_follow_link,
1936e5e5558eSMiklos Szeredi 	.put_link	= fuse_put_link,
1937e5e5558eSMiklos Szeredi 	.readlink	= generic_readlink,
1938e5e5558eSMiklos Szeredi 	.getattr	= fuse_getattr,
193992a8780eSMiklos Szeredi 	.setxattr	= fuse_setxattr,
194092a8780eSMiklos Szeredi 	.getxattr	= fuse_getxattr,
194192a8780eSMiklos Szeredi 	.listxattr	= fuse_listxattr,
194292a8780eSMiklos Szeredi 	.removexattr	= fuse_removexattr,
1943e5e5558eSMiklos Szeredi };
1944e5e5558eSMiklos Szeredi 
1945e5e5558eSMiklos Szeredi void fuse_init_common(struct inode *inode)
1946e5e5558eSMiklos Szeredi {
1947e5e5558eSMiklos Szeredi 	inode->i_op = &fuse_common_inode_operations;
1948e5e5558eSMiklos Szeredi }
1949e5e5558eSMiklos Szeredi 
1950e5e5558eSMiklos Szeredi void fuse_init_dir(struct inode *inode)
1951e5e5558eSMiklos Szeredi {
1952e5e5558eSMiklos Szeredi 	inode->i_op = &fuse_dir_inode_operations;
1953e5e5558eSMiklos Szeredi 	inode->i_fop = &fuse_dir_operations;
1954e5e5558eSMiklos Szeredi }
1955e5e5558eSMiklos Szeredi 
1956e5e5558eSMiklos Szeredi void fuse_init_symlink(struct inode *inode)
1957e5e5558eSMiklos Szeredi {
1958e5e5558eSMiklos Szeredi 	inode->i_op = &fuse_symlink_inode_operations;
1959e5e5558eSMiklos Szeredi }
1960