xref: /openbmc/linux/fs/fuse/dir.c (revision 3b463ae0c6264f70e5d4c0a9c46af20fed43c96e)
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/gfp.h>
14e5e5558eSMiklos Szeredi #include <linux/sched.h>
15e5e5558eSMiklos Szeredi #include <linux/namei.h>
16e5e5558eSMiklos Szeredi 
170a0898cfSMiklos Szeredi #if BITS_PER_LONG >= 64
180a0898cfSMiklos Szeredi static inline void fuse_dentry_settime(struct dentry *entry, u64 time)
190a0898cfSMiklos Szeredi {
200a0898cfSMiklos Szeredi 	entry->d_time = time;
210a0898cfSMiklos Szeredi }
220a0898cfSMiklos Szeredi 
230a0898cfSMiklos Szeredi static inline u64 fuse_dentry_time(struct dentry *entry)
240a0898cfSMiklos Szeredi {
250a0898cfSMiklos Szeredi 	return entry->d_time;
260a0898cfSMiklos Szeredi }
270a0898cfSMiklos Szeredi #else
280a0898cfSMiklos Szeredi /*
290a0898cfSMiklos Szeredi  * On 32 bit archs store the high 32 bits of time in d_fsdata
300a0898cfSMiklos Szeredi  */
310a0898cfSMiklos Szeredi static void fuse_dentry_settime(struct dentry *entry, u64 time)
320a0898cfSMiklos Szeredi {
330a0898cfSMiklos Szeredi 	entry->d_time = time;
340a0898cfSMiklos Szeredi 	entry->d_fsdata = (void *) (unsigned long) (time >> 32);
350a0898cfSMiklos Szeredi }
360a0898cfSMiklos Szeredi 
370a0898cfSMiklos Szeredi static u64 fuse_dentry_time(struct dentry *entry)
380a0898cfSMiklos Szeredi {
390a0898cfSMiklos Szeredi 	return (u64) entry->d_time +
400a0898cfSMiklos Szeredi 		((u64) (unsigned long) entry->d_fsdata << 32);
410a0898cfSMiklos Szeredi }
420a0898cfSMiklos Szeredi #endif
430a0898cfSMiklos Szeredi 
446f9f1180SMiklos Szeredi /*
456f9f1180SMiklos Szeredi  * FUSE caches dentries and attributes with separate timeout.  The
466f9f1180SMiklos Szeredi  * time in jiffies until the dentry/attributes are valid is stored in
476f9f1180SMiklos Szeredi  * dentry->d_time and fuse_inode->i_time respectively.
486f9f1180SMiklos Szeredi  */
496f9f1180SMiklos Szeredi 
506f9f1180SMiklos Szeredi /*
516f9f1180SMiklos Szeredi  * Calculate the time in jiffies until a dentry/attributes are valid
526f9f1180SMiklos Szeredi  */
530a0898cfSMiklos Szeredi static u64 time_to_jiffies(unsigned long sec, unsigned long nsec)
54e5e5558eSMiklos Szeredi {
55685d16ddSMiklos Szeredi 	if (sec || nsec) {
56e5e5558eSMiklos Szeredi 		struct timespec ts = {sec, nsec};
570a0898cfSMiklos Szeredi 		return get_jiffies_64() + timespec_to_jiffies(&ts);
58685d16ddSMiklos Szeredi 	} else
590a0898cfSMiklos Szeredi 		return 0;
60e5e5558eSMiklos Szeredi }
61e5e5558eSMiklos Szeredi 
626f9f1180SMiklos Szeredi /*
636f9f1180SMiklos Szeredi  * Set dentry and possibly attribute timeouts from the lookup/mk*
646f9f1180SMiklos Szeredi  * replies
656f9f1180SMiklos Szeredi  */
661fb69e78SMiklos Szeredi static void fuse_change_entry_timeout(struct dentry *entry,
671fb69e78SMiklos Szeredi 				      struct fuse_entry_out *o)
680aa7c699SMiklos Szeredi {
690a0898cfSMiklos Szeredi 	fuse_dentry_settime(entry,
700a0898cfSMiklos Szeredi 		time_to_jiffies(o->entry_valid, o->entry_valid_nsec));
711fb69e78SMiklos Szeredi }
721fb69e78SMiklos Szeredi 
731fb69e78SMiklos Szeredi static u64 attr_timeout(struct fuse_attr_out *o)
741fb69e78SMiklos Szeredi {
751fb69e78SMiklos Szeredi 	return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
761fb69e78SMiklos Szeredi }
771fb69e78SMiklos Szeredi 
781fb69e78SMiklos Szeredi static u64 entry_attr_timeout(struct fuse_entry_out *o)
791fb69e78SMiklos Szeredi {
801fb69e78SMiklos Szeredi 	return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
818cbdf1e6SMiklos Szeredi }
828cbdf1e6SMiklos Szeredi 
836f9f1180SMiklos Szeredi /*
846f9f1180SMiklos Szeredi  * Mark the attributes as stale, so that at the next call to
856f9f1180SMiklos Szeredi  * ->getattr() they will be fetched from userspace
866f9f1180SMiklos Szeredi  */
878cbdf1e6SMiklos Szeredi void fuse_invalidate_attr(struct inode *inode)
888cbdf1e6SMiklos Szeredi {
890a0898cfSMiklos Szeredi 	get_fuse_inode(inode)->i_time = 0;
908cbdf1e6SMiklos Szeredi }
918cbdf1e6SMiklos Szeredi 
926f9f1180SMiklos Szeredi /*
936f9f1180SMiklos Szeredi  * Just mark the entry as stale, so that a next attempt to look it up
946f9f1180SMiklos Szeredi  * will result in a new lookup call to userspace
956f9f1180SMiklos Szeredi  *
966f9f1180SMiklos Szeredi  * This is called when a dentry is about to become negative and the
976f9f1180SMiklos Szeredi  * timeout is unknown (unlink, rmdir, rename and in some cases
986f9f1180SMiklos Szeredi  * lookup)
996f9f1180SMiklos Szeredi  */
100dbd561d2SMiklos Szeredi void fuse_invalidate_entry_cache(struct dentry *entry)
1018cbdf1e6SMiklos Szeredi {
1020a0898cfSMiklos Szeredi 	fuse_dentry_settime(entry, 0);
1038cbdf1e6SMiklos Szeredi }
1048cbdf1e6SMiklos Szeredi 
1056f9f1180SMiklos Szeredi /*
1066f9f1180SMiklos Szeredi  * Same as fuse_invalidate_entry_cache(), but also try to remove the
1076f9f1180SMiklos Szeredi  * dentry from the hash
1086f9f1180SMiklos Szeredi  */
1098cbdf1e6SMiklos Szeredi static void fuse_invalidate_entry(struct dentry *entry)
1108cbdf1e6SMiklos Szeredi {
1118cbdf1e6SMiklos Szeredi 	d_invalidate(entry);
1128cbdf1e6SMiklos Szeredi 	fuse_invalidate_entry_cache(entry);
1130aa7c699SMiklos Szeredi }
1140aa7c699SMiklos Szeredi 
115c180eebeSMiklos Szeredi static void fuse_lookup_init(struct fuse_conn *fc, struct fuse_req *req,
116c180eebeSMiklos Szeredi 			     u64 nodeid, struct qstr *name,
117e5e5558eSMiklos Szeredi 			     struct fuse_entry_out *outarg)
118e5e5558eSMiklos Szeredi {
1190e9663eeSMiklos Szeredi 	memset(outarg, 0, sizeof(struct fuse_entry_out));
120e5e5558eSMiklos Szeredi 	req->in.h.opcode = FUSE_LOOKUP;
121c180eebeSMiklos Szeredi 	req->in.h.nodeid = nodeid;
122e5e5558eSMiklos Szeredi 	req->in.numargs = 1;
123c180eebeSMiklos Szeredi 	req->in.args[0].size = name->len + 1;
124c180eebeSMiklos Szeredi 	req->in.args[0].value = name->name;
125e5e5558eSMiklos Szeredi 	req->out.numargs = 1;
1260e9663eeSMiklos Szeredi 	if (fc->minor < 9)
1270e9663eeSMiklos Szeredi 		req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
1280e9663eeSMiklos Szeredi 	else
129e5e5558eSMiklos Szeredi 		req->out.args[0].size = sizeof(struct fuse_entry_out);
130e5e5558eSMiklos Szeredi 	req->out.args[0].value = outarg;
131e5e5558eSMiklos Szeredi }
132e5e5558eSMiklos Szeredi 
1335c5c5e51SMiklos Szeredi u64 fuse_get_attr_version(struct fuse_conn *fc)
1347dca9fd3SMiklos Szeredi {
1357dca9fd3SMiklos Szeredi 	u64 curr_version;
1367dca9fd3SMiklos Szeredi 
1377dca9fd3SMiklos Szeredi 	/*
1387dca9fd3SMiklos Szeredi 	 * The spin lock isn't actually needed on 64bit archs, but we
1397dca9fd3SMiklos Szeredi 	 * don't yet care too much about such optimizations.
1407dca9fd3SMiklos Szeredi 	 */
1417dca9fd3SMiklos Szeredi 	spin_lock(&fc->lock);
1427dca9fd3SMiklos Szeredi 	curr_version = fc->attr_version;
1437dca9fd3SMiklos Szeredi 	spin_unlock(&fc->lock);
1447dca9fd3SMiklos Szeredi 
1457dca9fd3SMiklos Szeredi 	return curr_version;
1467dca9fd3SMiklos Szeredi }
1477dca9fd3SMiklos Szeredi 
1486f9f1180SMiklos Szeredi /*
1496f9f1180SMiklos Szeredi  * Check whether the dentry is still valid
1506f9f1180SMiklos Szeredi  *
1516f9f1180SMiklos Szeredi  * If the entry validity timeout has expired and the dentry is
1526f9f1180SMiklos Szeredi  * positive, try to redo the lookup.  If the lookup results in a
1536f9f1180SMiklos Szeredi  * different inode, then let the VFS invalidate the dentry and redo
1546f9f1180SMiklos Szeredi  * the lookup once more.  If the lookup results in the same inode,
1556f9f1180SMiklos Szeredi  * then refresh the attributes, timeouts and mark the dentry valid.
1566f9f1180SMiklos Szeredi  */
157e5e5558eSMiklos Szeredi static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
158e5e5558eSMiklos Szeredi {
1598cbdf1e6SMiklos Szeredi 	struct inode *inode = entry->d_inode;
1608cbdf1e6SMiklos Szeredi 
1618cbdf1e6SMiklos Szeredi 	if (inode && is_bad_inode(inode))
162e5e5558eSMiklos Szeredi 		return 0;
1630a0898cfSMiklos Szeredi 	else if (fuse_dentry_time(entry) < get_jiffies_64()) {
164e5e5558eSMiklos Szeredi 		int err;
165e5e5558eSMiklos Szeredi 		struct fuse_entry_out outarg;
1668cbdf1e6SMiklos Szeredi 		struct fuse_conn *fc;
1678cbdf1e6SMiklos Szeredi 		struct fuse_req *req;
1682d51013eSMiklos Szeredi 		struct fuse_req *forget_req;
169e956edd0SMiklos Szeredi 		struct dentry *parent;
1701fb69e78SMiklos Szeredi 		u64 attr_version;
1718cbdf1e6SMiklos Szeredi 
17250322fe7SMiklos Szeredi 		/* For negative dentries, always do a fresh lookup */
1738cbdf1e6SMiklos Szeredi 		if (!inode)
1748cbdf1e6SMiklos Szeredi 			return 0;
1758cbdf1e6SMiklos Szeredi 
1768cbdf1e6SMiklos Szeredi 		fc = get_fuse_conn(inode);
177ce1d5a49SMiklos Szeredi 		req = fuse_get_req(fc);
178ce1d5a49SMiklos Szeredi 		if (IS_ERR(req))
179e5e5558eSMiklos Szeredi 			return 0;
180e5e5558eSMiklos Szeredi 
1812d51013eSMiklos Szeredi 		forget_req = fuse_get_req(fc);
1822d51013eSMiklos Szeredi 		if (IS_ERR(forget_req)) {
1832d51013eSMiklos Szeredi 			fuse_put_request(fc, req);
1842d51013eSMiklos Szeredi 			return 0;
1852d51013eSMiklos Szeredi 		}
1862d51013eSMiklos Szeredi 
1877dca9fd3SMiklos Szeredi 		attr_version = fuse_get_attr_version(fc);
1881fb69e78SMiklos Szeredi 
189e956edd0SMiklos Szeredi 		parent = dget_parent(entry);
190c180eebeSMiklos Szeredi 		fuse_lookup_init(fc, req, get_node_id(parent->d_inode),
191c180eebeSMiklos Szeredi 				 &entry->d_name, &outarg);
192b93f858aSTejun Heo 		fuse_request_send(fc, req);
193e956edd0SMiklos Szeredi 		dput(parent);
194e5e5558eSMiklos Szeredi 		err = req->out.h.error;
1952d51013eSMiklos Szeredi 		fuse_put_request(fc, req);
19650322fe7SMiklos Szeredi 		/* Zero nodeid is same as -ENOENT */
19750322fe7SMiklos Szeredi 		if (!err && !outarg.nodeid)
19850322fe7SMiklos Szeredi 			err = -ENOENT;
1999e6268dbSMiklos Szeredi 		if (!err) {
2008cbdf1e6SMiklos Szeredi 			struct fuse_inode *fi = get_fuse_inode(inode);
2019e6268dbSMiklos Szeredi 			if (outarg.nodeid != get_node_id(inode)) {
2022d51013eSMiklos Szeredi 				fuse_send_forget(fc, forget_req,
2032d51013eSMiklos Szeredi 						 outarg.nodeid, 1);
2049e6268dbSMiklos Szeredi 				return 0;
2059e6268dbSMiklos Szeredi 			}
2068da5ff23SMiklos Szeredi 			spin_lock(&fc->lock);
2079e6268dbSMiklos Szeredi 			fi->nlookup++;
2088da5ff23SMiklos Szeredi 			spin_unlock(&fc->lock);
2099e6268dbSMiklos Szeredi 		}
2102d51013eSMiklos Szeredi 		fuse_put_request(fc, forget_req);
2119e6268dbSMiklos Szeredi 		if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
212e5e5558eSMiklos Szeredi 			return 0;
213e5e5558eSMiklos Szeredi 
2141fb69e78SMiklos Szeredi 		fuse_change_attributes(inode, &outarg.attr,
2151fb69e78SMiklos Szeredi 				       entry_attr_timeout(&outarg),
2161fb69e78SMiklos Szeredi 				       attr_version);
2171fb69e78SMiklos Szeredi 		fuse_change_entry_timeout(entry, &outarg);
218e5e5558eSMiklos Szeredi 	}
219e5e5558eSMiklos Szeredi 	return 1;
220e5e5558eSMiklos Szeredi }
221e5e5558eSMiklos Szeredi 
2228bfc016dSMiklos Szeredi static int invalid_nodeid(u64 nodeid)
2232827d0b2SMiklos Szeredi {
2242827d0b2SMiklos Szeredi 	return !nodeid || nodeid == FUSE_ROOT_ID;
2252827d0b2SMiklos Szeredi }
2262827d0b2SMiklos Szeredi 
2274269590aSAl Viro const struct dentry_operations fuse_dentry_operations = {
228e5e5558eSMiklos Szeredi 	.d_revalidate	= fuse_dentry_revalidate,
229e5e5558eSMiklos Szeredi };
230e5e5558eSMiklos Szeredi 
231a5bfffacSTimo Savola int fuse_valid_type(int m)
23239ee059aSMiklos Szeredi {
23339ee059aSMiklos Szeredi 	return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) ||
23439ee059aSMiklos Szeredi 		S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
23539ee059aSMiklos Szeredi }
23639ee059aSMiklos Szeredi 
237d2a85164SMiklos Szeredi /*
238d2a85164SMiklos Szeredi  * Add a directory inode to a dentry, ensuring that no other dentry
239d2a85164SMiklos Szeredi  * refers to this inode.  Called with fc->inst_mutex.
240d2a85164SMiklos Szeredi  */
2410de6256dSMiklos Szeredi static struct dentry *fuse_d_add_directory(struct dentry *entry,
2420de6256dSMiklos Szeredi 					   struct inode *inode)
243d2a85164SMiklos Szeredi {
244d2a85164SMiklos Szeredi 	struct dentry *alias = d_find_alias(inode);
2450de6256dSMiklos Szeredi 	if (alias && !(alias->d_flags & DCACHE_DISCONNECTED)) {
246d2a85164SMiklos Szeredi 		/* This tries to shrink the subtree below alias */
247d2a85164SMiklos Szeredi 		fuse_invalidate_entry(alias);
248d2a85164SMiklos Szeredi 		dput(alias);
249d2a85164SMiklos Szeredi 		if (!list_empty(&inode->i_dentry))
2500de6256dSMiklos Szeredi 			return ERR_PTR(-EBUSY);
2510de6256dSMiklos Szeredi 	} else {
2520de6256dSMiklos Szeredi 		dput(alias);
253d2a85164SMiklos Szeredi 	}
2540de6256dSMiklos Szeredi 	return d_splice_alias(inode, entry);
255d2a85164SMiklos Szeredi }
256d2a85164SMiklos Szeredi 
257c180eebeSMiklos Szeredi int fuse_lookup_name(struct super_block *sb, u64 nodeid, struct qstr *name,
258c180eebeSMiklos Szeredi 		     struct fuse_entry_out *outarg, struct inode **inode)
259c180eebeSMiklos Szeredi {
260c180eebeSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn_super(sb);
261c180eebeSMiklos Szeredi 	struct fuse_req *req;
262c180eebeSMiklos Szeredi 	struct fuse_req *forget_req;
263c180eebeSMiklos Szeredi 	u64 attr_version;
264c180eebeSMiklos Szeredi 	int err;
265c180eebeSMiklos Szeredi 
266c180eebeSMiklos Szeredi 	*inode = NULL;
267c180eebeSMiklos Szeredi 	err = -ENAMETOOLONG;
268c180eebeSMiklos Szeredi 	if (name->len > FUSE_NAME_MAX)
269c180eebeSMiklos Szeredi 		goto out;
270c180eebeSMiklos Szeredi 
271c180eebeSMiklos Szeredi 	req = fuse_get_req(fc);
272c180eebeSMiklos Szeredi 	err = PTR_ERR(req);
273c180eebeSMiklos Szeredi 	if (IS_ERR(req))
274c180eebeSMiklos Szeredi 		goto out;
275c180eebeSMiklos Szeredi 
276c180eebeSMiklos Szeredi 	forget_req = fuse_get_req(fc);
277c180eebeSMiklos Szeredi 	err = PTR_ERR(forget_req);
278c180eebeSMiklos Szeredi 	if (IS_ERR(forget_req)) {
279c180eebeSMiklos Szeredi 		fuse_put_request(fc, req);
280c180eebeSMiklos Szeredi 		goto out;
281c180eebeSMiklos Szeredi 	}
282c180eebeSMiklos Szeredi 
283c180eebeSMiklos Szeredi 	attr_version = fuse_get_attr_version(fc);
284c180eebeSMiklos Szeredi 
285c180eebeSMiklos Szeredi 	fuse_lookup_init(fc, req, nodeid, name, outarg);
286b93f858aSTejun Heo 	fuse_request_send(fc, req);
287c180eebeSMiklos Szeredi 	err = req->out.h.error;
288c180eebeSMiklos Szeredi 	fuse_put_request(fc, req);
289c180eebeSMiklos Szeredi 	/* Zero nodeid is same as -ENOENT, but with valid timeout */
290c180eebeSMiklos Szeredi 	if (err || !outarg->nodeid)
291c180eebeSMiklos Szeredi 		goto out_put_forget;
292c180eebeSMiklos Szeredi 
293c180eebeSMiklos Szeredi 	err = -EIO;
294c180eebeSMiklos Szeredi 	if (!outarg->nodeid)
295c180eebeSMiklos Szeredi 		goto out_put_forget;
296c180eebeSMiklos Szeredi 	if (!fuse_valid_type(outarg->attr.mode))
297c180eebeSMiklos Szeredi 		goto out_put_forget;
298c180eebeSMiklos Szeredi 
299c180eebeSMiklos Szeredi 	*inode = fuse_iget(sb, outarg->nodeid, outarg->generation,
300c180eebeSMiklos Szeredi 			   &outarg->attr, entry_attr_timeout(outarg),
301c180eebeSMiklos Szeredi 			   attr_version);
302c180eebeSMiklos Szeredi 	err = -ENOMEM;
303c180eebeSMiklos Szeredi 	if (!*inode) {
304c180eebeSMiklos Szeredi 		fuse_send_forget(fc, forget_req, outarg->nodeid, 1);
305c180eebeSMiklos Szeredi 		goto out;
306c180eebeSMiklos Szeredi 	}
307c180eebeSMiklos Szeredi 	err = 0;
308c180eebeSMiklos Szeredi 
309c180eebeSMiklos Szeredi  out_put_forget:
310c180eebeSMiklos Szeredi 	fuse_put_request(fc, forget_req);
311c180eebeSMiklos Szeredi  out:
312c180eebeSMiklos Szeredi 	return err;
313c180eebeSMiklos Szeredi }
314c180eebeSMiklos Szeredi 
3150aa7c699SMiklos Szeredi static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
3160aa7c699SMiklos Szeredi 				  struct nameidata *nd)
317e5e5558eSMiklos Szeredi {
318e5e5558eSMiklos Szeredi 	int err;
319e5e5558eSMiklos Szeredi 	struct fuse_entry_out outarg;
320c180eebeSMiklos Szeredi 	struct inode *inode;
3210de6256dSMiklos Szeredi 	struct dentry *newent;
322e5e5558eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
323c180eebeSMiklos Szeredi 	bool outarg_valid = true;
324e5e5558eSMiklos Szeredi 
325c180eebeSMiklos Szeredi 	err = fuse_lookup_name(dir->i_sb, get_node_id(dir), &entry->d_name,
326c180eebeSMiklos Szeredi 			       &outarg, &inode);
327c180eebeSMiklos Szeredi 	if (err == -ENOENT) {
328c180eebeSMiklos Szeredi 		outarg_valid = false;
329c180eebeSMiklos Szeredi 		err = 0;
3302d51013eSMiklos Szeredi 	}
331c180eebeSMiklos Szeredi 	if (err)
332c180eebeSMiklos Szeredi 		goto out_err;
3332d51013eSMiklos Szeredi 
334ee4e5271SMiklos Szeredi 	err = -EIO;
335c180eebeSMiklos Szeredi 	if (inode && get_node_id(inode) == FUSE_ROOT_ID)
336c180eebeSMiklos Szeredi 		goto out_iput;
337e5e5558eSMiklos Szeredi 
338d2a85164SMiklos Szeredi 	if (inode && S_ISDIR(inode->i_mode)) {
339d2a85164SMiklos Szeredi 		mutex_lock(&fc->inst_mutex);
3400de6256dSMiklos Szeredi 		newent = fuse_d_add_directory(entry, inode);
341d2a85164SMiklos Szeredi 		mutex_unlock(&fc->inst_mutex);
342c180eebeSMiklos Szeredi 		err = PTR_ERR(newent);
343c180eebeSMiklos Szeredi 		if (IS_ERR(newent))
344c180eebeSMiklos Szeredi 			goto out_iput;
345c180eebeSMiklos Szeredi 	} else {
3460de6256dSMiklos Szeredi 		newent = d_splice_alias(inode, entry);
347c180eebeSMiklos Szeredi 	}
348d2a85164SMiklos Szeredi 
3490de6256dSMiklos Szeredi 	entry = newent ? newent : entry;
350e5e5558eSMiklos Szeredi 	entry->d_op = &fuse_dentry_operations;
351c180eebeSMiklos Szeredi 	if (outarg_valid)
3521fb69e78SMiklos Szeredi 		fuse_change_entry_timeout(entry, &outarg);
3538cbdf1e6SMiklos Szeredi 	else
3548cbdf1e6SMiklos Szeredi 		fuse_invalidate_entry_cache(entry);
355c180eebeSMiklos Szeredi 
3560de6256dSMiklos Szeredi 	return newent;
357c180eebeSMiklos Szeredi 
358c180eebeSMiklos Szeredi  out_iput:
359c180eebeSMiklos Szeredi 	iput(inode);
360c180eebeSMiklos Szeredi  out_err:
361c180eebeSMiklos Szeredi 	return ERR_PTR(err);
362e5e5558eSMiklos Szeredi }
363e5e5558eSMiklos Szeredi 
3646f9f1180SMiklos Szeredi /*
3656f9f1180SMiklos Szeredi  * Atomic create+open operation
3666f9f1180SMiklos Szeredi  *
3676f9f1180SMiklos Szeredi  * If the filesystem doesn't support this, then fall back to separate
3686f9f1180SMiklos Szeredi  * 'mknod' + 'open' requests.
3696f9f1180SMiklos Szeredi  */
370fd72faacSMiklos Szeredi static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
371fd72faacSMiklos Szeredi 			    struct nameidata *nd)
372fd72faacSMiklos Szeredi {
373fd72faacSMiklos Szeredi 	int err;
374fd72faacSMiklos Szeredi 	struct inode *inode;
375fd72faacSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
376fd72faacSMiklos Szeredi 	struct fuse_req *req;
37751eb01e7SMiklos Szeredi 	struct fuse_req *forget_req;
378e0a43ddcSMiklos Szeredi 	struct fuse_create_in inarg;
379fd72faacSMiklos Szeredi 	struct fuse_open_out outopen;
380fd72faacSMiklos Szeredi 	struct fuse_entry_out outentry;
381fd72faacSMiklos Szeredi 	struct fuse_file *ff;
382fd72faacSMiklos Szeredi 	struct file *file;
383fd72faacSMiklos Szeredi 	int flags = nd->intent.open.flags - 1;
384fd72faacSMiklos Szeredi 
385fd72faacSMiklos Szeredi 	if (fc->no_create)
386ce1d5a49SMiklos Szeredi 		return -ENOSYS;
387fd72faacSMiklos Szeredi 
38851eb01e7SMiklos Szeredi 	forget_req = fuse_get_req(fc);
38951eb01e7SMiklos Szeredi 	if (IS_ERR(forget_req))
39051eb01e7SMiklos Szeredi 		return PTR_ERR(forget_req);
39151eb01e7SMiklos Szeredi 
392ce1d5a49SMiklos Szeredi 	req = fuse_get_req(fc);
39351eb01e7SMiklos Szeredi 	err = PTR_ERR(req);
394ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
39551eb01e7SMiklos Szeredi 		goto out_put_forget_req;
396fd72faacSMiklos Szeredi 
397ce1d5a49SMiklos Szeredi 	err = -ENOMEM;
398acf99433STejun Heo 	ff = fuse_file_alloc(fc);
399fd72faacSMiklos Szeredi 	if (!ff)
400fd72faacSMiklos Szeredi 		goto out_put_request;
401fd72faacSMiklos Szeredi 
402e0a43ddcSMiklos Szeredi 	if (!fc->dont_mask)
403e0a43ddcSMiklos Szeredi 		mode &= ~current_umask();
404e0a43ddcSMiklos Szeredi 
405fd72faacSMiklos Szeredi 	flags &= ~O_NOCTTY;
406fd72faacSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
4070e9663eeSMiklos Szeredi 	memset(&outentry, 0, sizeof(outentry));
408fd72faacSMiklos Szeredi 	inarg.flags = flags;
409fd72faacSMiklos Szeredi 	inarg.mode = mode;
410e0a43ddcSMiklos Szeredi 	inarg.umask = current_umask();
411fd72faacSMiklos Szeredi 	req->in.h.opcode = FUSE_CREATE;
412fd72faacSMiklos Szeredi 	req->in.h.nodeid = get_node_id(dir);
413fd72faacSMiklos Szeredi 	req->in.numargs = 2;
414e0a43ddcSMiklos Szeredi 	req->in.args[0].size = fc->minor < 12 ? sizeof(struct fuse_open_in) :
415e0a43ddcSMiklos Szeredi 						sizeof(inarg);
416fd72faacSMiklos Szeredi 	req->in.args[0].value = &inarg;
417fd72faacSMiklos Szeredi 	req->in.args[1].size = entry->d_name.len + 1;
418fd72faacSMiklos Szeredi 	req->in.args[1].value = entry->d_name.name;
419fd72faacSMiklos Szeredi 	req->out.numargs = 2;
4200e9663eeSMiklos Szeredi 	if (fc->minor < 9)
4210e9663eeSMiklos Szeredi 		req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
4220e9663eeSMiklos Szeredi 	else
423fd72faacSMiklos Szeredi 		req->out.args[0].size = sizeof(outentry);
424fd72faacSMiklos Szeredi 	req->out.args[0].value = &outentry;
425fd72faacSMiklos Szeredi 	req->out.args[1].size = sizeof(outopen);
426fd72faacSMiklos Szeredi 	req->out.args[1].value = &outopen;
427b93f858aSTejun Heo 	fuse_request_send(fc, req);
428fd72faacSMiklos Szeredi 	err = req->out.h.error;
429fd72faacSMiklos Szeredi 	if (err) {
430fd72faacSMiklos Szeredi 		if (err == -ENOSYS)
431fd72faacSMiklos Szeredi 			fc->no_create = 1;
432fd72faacSMiklos Szeredi 		goto out_free_ff;
433fd72faacSMiklos Szeredi 	}
434fd72faacSMiklos Szeredi 
435fd72faacSMiklos Szeredi 	err = -EIO;
4362827d0b2SMiklos Szeredi 	if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid))
437fd72faacSMiklos Szeredi 		goto out_free_ff;
438fd72faacSMiklos Szeredi 
43951eb01e7SMiklos Szeredi 	fuse_put_request(fc, req);
440c7b7143cSMiklos Szeredi 	ff->fh = outopen.fh;
441c7b7143cSMiklos Szeredi 	ff->nodeid = outentry.nodeid;
442c7b7143cSMiklos Szeredi 	ff->open_flags = outopen.open_flags;
443fd72faacSMiklos Szeredi 	inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
4441fb69e78SMiklos Szeredi 			  &outentry.attr, entry_attr_timeout(&outentry), 0);
445fd72faacSMiklos Szeredi 	if (!inode) {
446fd72faacSMiklos Szeredi 		flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
4478b0797a4SMiklos Szeredi 		fuse_sync_release(ff, flags);
44851eb01e7SMiklos Szeredi 		fuse_send_forget(fc, forget_req, outentry.nodeid, 1);
44951eb01e7SMiklos Szeredi 		return -ENOMEM;
450fd72faacSMiklos Szeredi 	}
45151eb01e7SMiklos Szeredi 	fuse_put_request(fc, forget_req);
452fd72faacSMiklos Szeredi 	d_instantiate(entry, inode);
4531fb69e78SMiklos Szeredi 	fuse_change_entry_timeout(entry, &outentry);
4540952b2a4SMiklos Szeredi 	fuse_invalidate_attr(dir);
455fd72faacSMiklos Szeredi 	file = lookup_instantiate_filp(nd, entry, generic_file_open);
456fd72faacSMiklos Szeredi 	if (IS_ERR(file)) {
4578b0797a4SMiklos Szeredi 		fuse_sync_release(ff, flags);
458fd72faacSMiklos Szeredi 		return PTR_ERR(file);
459fd72faacSMiklos Szeredi 	}
460c7b7143cSMiklos Szeredi 	file->private_data = fuse_file_get(ff);
461c7b7143cSMiklos Szeredi 	fuse_finish_open(inode, file);
462fd72faacSMiklos Szeredi 	return 0;
463fd72faacSMiklos Szeredi 
464fd72faacSMiklos Szeredi  out_free_ff:
465fd72faacSMiklos Szeredi 	fuse_file_free(ff);
466fd72faacSMiklos Szeredi  out_put_request:
467fd72faacSMiklos Szeredi 	fuse_put_request(fc, req);
46851eb01e7SMiklos Szeredi  out_put_forget_req:
46951eb01e7SMiklos Szeredi 	fuse_put_request(fc, forget_req);
470fd72faacSMiklos Szeredi 	return err;
471fd72faacSMiklos Szeredi }
472fd72faacSMiklos Szeredi 
4736f9f1180SMiklos Szeredi /*
4746f9f1180SMiklos Szeredi  * Code shared between mknod, mkdir, symlink and link
4756f9f1180SMiklos Szeredi  */
4769e6268dbSMiklos Szeredi static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
4779e6268dbSMiklos Szeredi 			    struct inode *dir, struct dentry *entry,
4789e6268dbSMiklos Szeredi 			    int mode)
4799e6268dbSMiklos Szeredi {
4809e6268dbSMiklos Szeredi 	struct fuse_entry_out outarg;
4819e6268dbSMiklos Szeredi 	struct inode *inode;
4829e6268dbSMiklos Szeredi 	int err;
4832d51013eSMiklos Szeredi 	struct fuse_req *forget_req;
4842d51013eSMiklos Szeredi 
4852d51013eSMiklos Szeredi 	forget_req = fuse_get_req(fc);
4862d51013eSMiklos Szeredi 	if (IS_ERR(forget_req)) {
4872d51013eSMiklos Szeredi 		fuse_put_request(fc, req);
4882d51013eSMiklos Szeredi 		return PTR_ERR(forget_req);
4892d51013eSMiklos Szeredi 	}
4909e6268dbSMiklos Szeredi 
4910e9663eeSMiklos Szeredi 	memset(&outarg, 0, sizeof(outarg));
4929e6268dbSMiklos Szeredi 	req->in.h.nodeid = get_node_id(dir);
4939e6268dbSMiklos Szeredi 	req->out.numargs = 1;
4940e9663eeSMiklos Szeredi 	if (fc->minor < 9)
4950e9663eeSMiklos Szeredi 		req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
4960e9663eeSMiklos Szeredi 	else
4979e6268dbSMiklos Szeredi 		req->out.args[0].size = sizeof(outarg);
4989e6268dbSMiklos Szeredi 	req->out.args[0].value = &outarg;
499b93f858aSTejun Heo 	fuse_request_send(fc, req);
5009e6268dbSMiklos Szeredi 	err = req->out.h.error;
5019e6268dbSMiklos Szeredi 	fuse_put_request(fc, req);
5022d51013eSMiklos Szeredi 	if (err)
5032d51013eSMiklos Szeredi 		goto out_put_forget_req;
5042d51013eSMiklos Szeredi 
50539ee059aSMiklos Szeredi 	err = -EIO;
50639ee059aSMiklos Szeredi 	if (invalid_nodeid(outarg.nodeid))
5072d51013eSMiklos Szeredi 		goto out_put_forget_req;
50839ee059aSMiklos Szeredi 
50939ee059aSMiklos Szeredi 	if ((outarg.attr.mode ^ mode) & S_IFMT)
5102d51013eSMiklos Szeredi 		goto out_put_forget_req;
51139ee059aSMiklos Szeredi 
5129e6268dbSMiklos Szeredi 	inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
5131fb69e78SMiklos Szeredi 			  &outarg.attr, entry_attr_timeout(&outarg), 0);
5149e6268dbSMiklos Szeredi 	if (!inode) {
5152d51013eSMiklos Szeredi 		fuse_send_forget(fc, forget_req, outarg.nodeid, 1);
5169e6268dbSMiklos Szeredi 		return -ENOMEM;
5179e6268dbSMiklos Szeredi 	}
5182d51013eSMiklos Szeredi 	fuse_put_request(fc, forget_req);
5199e6268dbSMiklos Szeredi 
520d2a85164SMiklos Szeredi 	if (S_ISDIR(inode->i_mode)) {
521d2a85164SMiklos Szeredi 		struct dentry *alias;
522d2a85164SMiklos Szeredi 		mutex_lock(&fc->inst_mutex);
523d2a85164SMiklos Szeredi 		alias = d_find_alias(inode);
524d2a85164SMiklos Szeredi 		if (alias) {
525d2a85164SMiklos Szeredi 			/* New directory must have moved since mkdir */
526d2a85164SMiklos Szeredi 			mutex_unlock(&fc->inst_mutex);
527d2a85164SMiklos Szeredi 			dput(alias);
5289e6268dbSMiklos Szeredi 			iput(inode);
529d2a85164SMiklos Szeredi 			return -EBUSY;
5309e6268dbSMiklos Szeredi 		}
5319e6268dbSMiklos Szeredi 		d_instantiate(entry, inode);
532d2a85164SMiklos Szeredi 		mutex_unlock(&fc->inst_mutex);
533d2a85164SMiklos Szeredi 	} else
534d2a85164SMiklos Szeredi 		d_instantiate(entry, inode);
535d2a85164SMiklos Szeredi 
5361fb69e78SMiklos Szeredi 	fuse_change_entry_timeout(entry, &outarg);
5379e6268dbSMiklos Szeredi 	fuse_invalidate_attr(dir);
5389e6268dbSMiklos Szeredi 	return 0;
53939ee059aSMiklos Szeredi 
5402d51013eSMiklos Szeredi  out_put_forget_req:
5412d51013eSMiklos Szeredi 	fuse_put_request(fc, forget_req);
54239ee059aSMiklos Szeredi 	return err;
5439e6268dbSMiklos Szeredi }
5449e6268dbSMiklos Szeredi 
5459e6268dbSMiklos Szeredi static int fuse_mknod(struct inode *dir, struct dentry *entry, int mode,
5469e6268dbSMiklos Szeredi 		      dev_t rdev)
5479e6268dbSMiklos Szeredi {
5489e6268dbSMiklos Szeredi 	struct fuse_mknod_in inarg;
5499e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
550ce1d5a49SMiklos Szeredi 	struct fuse_req *req = fuse_get_req(fc);
551ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
552ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
5539e6268dbSMiklos Szeredi 
554e0a43ddcSMiklos Szeredi 	if (!fc->dont_mask)
555e0a43ddcSMiklos Szeredi 		mode &= ~current_umask();
556e0a43ddcSMiklos Szeredi 
5579e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
5589e6268dbSMiklos Szeredi 	inarg.mode = mode;
5599e6268dbSMiklos Szeredi 	inarg.rdev = new_encode_dev(rdev);
560e0a43ddcSMiklos Szeredi 	inarg.umask = current_umask();
5619e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_MKNOD;
5629e6268dbSMiklos Szeredi 	req->in.numargs = 2;
563e0a43ddcSMiklos Szeredi 	req->in.args[0].size = fc->minor < 12 ? FUSE_COMPAT_MKNOD_IN_SIZE :
564e0a43ddcSMiklos Szeredi 						sizeof(inarg);
5659e6268dbSMiklos Szeredi 	req->in.args[0].value = &inarg;
5669e6268dbSMiklos Szeredi 	req->in.args[1].size = entry->d_name.len + 1;
5679e6268dbSMiklos Szeredi 	req->in.args[1].value = entry->d_name.name;
5689e6268dbSMiklos Szeredi 	return create_new_entry(fc, req, dir, entry, mode);
5699e6268dbSMiklos Szeredi }
5709e6268dbSMiklos Szeredi 
5719e6268dbSMiklos Szeredi static int fuse_create(struct inode *dir, struct dentry *entry, int mode,
5729e6268dbSMiklos Szeredi 		       struct nameidata *nd)
5739e6268dbSMiklos Szeredi {
574b9ba347fSMiklos Szeredi 	if (nd && (nd->flags & LOOKUP_OPEN)) {
575fd72faacSMiklos Szeredi 		int err = fuse_create_open(dir, entry, mode, nd);
576fd72faacSMiklos Szeredi 		if (err != -ENOSYS)
577fd72faacSMiklos Szeredi 			return err;
578fd72faacSMiklos Szeredi 		/* Fall back on mknod */
579fd72faacSMiklos Szeredi 	}
5809e6268dbSMiklos Szeredi 	return fuse_mknod(dir, entry, mode, 0);
5819e6268dbSMiklos Szeredi }
5829e6268dbSMiklos Szeredi 
5839e6268dbSMiklos Szeredi static int fuse_mkdir(struct inode *dir, struct dentry *entry, int mode)
5849e6268dbSMiklos Szeredi {
5859e6268dbSMiklos Szeredi 	struct fuse_mkdir_in inarg;
5869e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
587ce1d5a49SMiklos Szeredi 	struct fuse_req *req = fuse_get_req(fc);
588ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
589ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
5909e6268dbSMiklos Szeredi 
591e0a43ddcSMiklos Szeredi 	if (!fc->dont_mask)
592e0a43ddcSMiklos Szeredi 		mode &= ~current_umask();
593e0a43ddcSMiklos Szeredi 
5949e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
5959e6268dbSMiklos Szeredi 	inarg.mode = mode;
596e0a43ddcSMiklos Szeredi 	inarg.umask = current_umask();
5979e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_MKDIR;
5989e6268dbSMiklos Szeredi 	req->in.numargs = 2;
5999e6268dbSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
6009e6268dbSMiklos Szeredi 	req->in.args[0].value = &inarg;
6019e6268dbSMiklos Szeredi 	req->in.args[1].size = entry->d_name.len + 1;
6029e6268dbSMiklos Szeredi 	req->in.args[1].value = entry->d_name.name;
6039e6268dbSMiklos Szeredi 	return create_new_entry(fc, req, dir, entry, S_IFDIR);
6049e6268dbSMiklos Szeredi }
6059e6268dbSMiklos Szeredi 
6069e6268dbSMiklos Szeredi static int fuse_symlink(struct inode *dir, struct dentry *entry,
6079e6268dbSMiklos Szeredi 			const char *link)
6089e6268dbSMiklos Szeredi {
6099e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
6109e6268dbSMiklos Szeredi 	unsigned len = strlen(link) + 1;
611ce1d5a49SMiklos Szeredi 	struct fuse_req *req = fuse_get_req(fc);
612ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
613ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
6149e6268dbSMiklos Szeredi 
6159e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_SYMLINK;
6169e6268dbSMiklos Szeredi 	req->in.numargs = 2;
6179e6268dbSMiklos Szeredi 	req->in.args[0].size = entry->d_name.len + 1;
6189e6268dbSMiklos Szeredi 	req->in.args[0].value = entry->d_name.name;
6199e6268dbSMiklos Szeredi 	req->in.args[1].size = len;
6209e6268dbSMiklos Szeredi 	req->in.args[1].value = link;
6219e6268dbSMiklos Szeredi 	return create_new_entry(fc, req, dir, entry, S_IFLNK);
6229e6268dbSMiklos Szeredi }
6239e6268dbSMiklos Szeredi 
6249e6268dbSMiklos Szeredi static int fuse_unlink(struct inode *dir, struct dentry *entry)
6259e6268dbSMiklos Szeredi {
6269e6268dbSMiklos Szeredi 	int err;
6279e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
628ce1d5a49SMiklos Szeredi 	struct fuse_req *req = fuse_get_req(fc);
629ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
630ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
6319e6268dbSMiklos Szeredi 
6329e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_UNLINK;
6339e6268dbSMiklos Szeredi 	req->in.h.nodeid = get_node_id(dir);
6349e6268dbSMiklos Szeredi 	req->in.numargs = 1;
6359e6268dbSMiklos Szeredi 	req->in.args[0].size = entry->d_name.len + 1;
6369e6268dbSMiklos Szeredi 	req->in.args[0].value = entry->d_name.name;
637b93f858aSTejun Heo 	fuse_request_send(fc, req);
6389e6268dbSMiklos Szeredi 	err = req->out.h.error;
6399e6268dbSMiklos Szeredi 	fuse_put_request(fc, req);
6409e6268dbSMiklos Szeredi 	if (!err) {
6419e6268dbSMiklos Szeredi 		struct inode *inode = entry->d_inode;
6429e6268dbSMiklos Szeredi 
6431729a16cSMiklos Szeredi 		/*
6441729a16cSMiklos Szeredi 		 * Set nlink to zero so the inode can be cleared, if the inode
6451729a16cSMiklos Szeredi 		 * does have more links this will be discovered at the next
6461729a16cSMiklos Szeredi 		 * lookup/getattr.
6471729a16cSMiklos Szeredi 		 */
648ce71ec36SDave Hansen 		clear_nlink(inode);
6499e6268dbSMiklos Szeredi 		fuse_invalidate_attr(inode);
6509e6268dbSMiklos Szeredi 		fuse_invalidate_attr(dir);
6518cbdf1e6SMiklos Szeredi 		fuse_invalidate_entry_cache(entry);
6529e6268dbSMiklos Szeredi 	} else if (err == -EINTR)
6539e6268dbSMiklos Szeredi 		fuse_invalidate_entry(entry);
6549e6268dbSMiklos Szeredi 	return err;
6559e6268dbSMiklos Szeredi }
6569e6268dbSMiklos Szeredi 
6579e6268dbSMiklos Szeredi static int fuse_rmdir(struct inode *dir, struct dentry *entry)
6589e6268dbSMiklos Szeredi {
6599e6268dbSMiklos Szeredi 	int err;
6609e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
661ce1d5a49SMiklos Szeredi 	struct fuse_req *req = fuse_get_req(fc);
662ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
663ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
6649e6268dbSMiklos Szeredi 
6659e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_RMDIR;
6669e6268dbSMiklos Szeredi 	req->in.h.nodeid = get_node_id(dir);
6679e6268dbSMiklos Szeredi 	req->in.numargs = 1;
6689e6268dbSMiklos Szeredi 	req->in.args[0].size = entry->d_name.len + 1;
6699e6268dbSMiklos Szeredi 	req->in.args[0].value = entry->d_name.name;
670b93f858aSTejun Heo 	fuse_request_send(fc, req);
6719e6268dbSMiklos Szeredi 	err = req->out.h.error;
6729e6268dbSMiklos Szeredi 	fuse_put_request(fc, req);
6739e6268dbSMiklos Szeredi 	if (!err) {
674ce71ec36SDave Hansen 		clear_nlink(entry->d_inode);
6759e6268dbSMiklos Szeredi 		fuse_invalidate_attr(dir);
6768cbdf1e6SMiklos Szeredi 		fuse_invalidate_entry_cache(entry);
6779e6268dbSMiklos Szeredi 	} else if (err == -EINTR)
6789e6268dbSMiklos Szeredi 		fuse_invalidate_entry(entry);
6799e6268dbSMiklos Szeredi 	return err;
6809e6268dbSMiklos Szeredi }
6819e6268dbSMiklos Szeredi 
6829e6268dbSMiklos Szeredi static int fuse_rename(struct inode *olddir, struct dentry *oldent,
6839e6268dbSMiklos Szeredi 		       struct inode *newdir, struct dentry *newent)
6849e6268dbSMiklos Szeredi {
6859e6268dbSMiklos Szeredi 	int err;
6869e6268dbSMiklos Szeredi 	struct fuse_rename_in inarg;
6879e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(olddir);
688ce1d5a49SMiklos Szeredi 	struct fuse_req *req = fuse_get_req(fc);
689ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
690ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
6919e6268dbSMiklos Szeredi 
6929e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
6939e6268dbSMiklos Szeredi 	inarg.newdir = get_node_id(newdir);
6949e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_RENAME;
6959e6268dbSMiklos Szeredi 	req->in.h.nodeid = get_node_id(olddir);
6969e6268dbSMiklos Szeredi 	req->in.numargs = 3;
6979e6268dbSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
6989e6268dbSMiklos Szeredi 	req->in.args[0].value = &inarg;
6999e6268dbSMiklos Szeredi 	req->in.args[1].size = oldent->d_name.len + 1;
7009e6268dbSMiklos Szeredi 	req->in.args[1].value = oldent->d_name.name;
7019e6268dbSMiklos Szeredi 	req->in.args[2].size = newent->d_name.len + 1;
7029e6268dbSMiklos Szeredi 	req->in.args[2].value = newent->d_name.name;
703b93f858aSTejun Heo 	fuse_request_send(fc, req);
7049e6268dbSMiklos Szeredi 	err = req->out.h.error;
7059e6268dbSMiklos Szeredi 	fuse_put_request(fc, req);
7069e6268dbSMiklos Szeredi 	if (!err) {
70708b63307SMiklos Szeredi 		/* ctime changes */
70808b63307SMiklos Szeredi 		fuse_invalidate_attr(oldent->d_inode);
70908b63307SMiklos Szeredi 
7109e6268dbSMiklos Szeredi 		fuse_invalidate_attr(olddir);
7119e6268dbSMiklos Szeredi 		if (olddir != newdir)
7129e6268dbSMiklos Szeredi 			fuse_invalidate_attr(newdir);
7138cbdf1e6SMiklos Szeredi 
7148cbdf1e6SMiklos Szeredi 		/* newent will end up negative */
7158cbdf1e6SMiklos Szeredi 		if (newent->d_inode)
7168cbdf1e6SMiklos Szeredi 			fuse_invalidate_entry_cache(newent);
7179e6268dbSMiklos Szeredi 	} else if (err == -EINTR) {
7189e6268dbSMiklos Szeredi 		/* If request was interrupted, DEITY only knows if the
7199e6268dbSMiklos Szeredi 		   rename actually took place.  If the invalidation
7209e6268dbSMiklos Szeredi 		   fails (e.g. some process has CWD under the renamed
7219e6268dbSMiklos Szeredi 		   directory), then there can be inconsistency between
7229e6268dbSMiklos Szeredi 		   the dcache and the real filesystem.  Tough luck. */
7239e6268dbSMiklos Szeredi 		fuse_invalidate_entry(oldent);
7249e6268dbSMiklos Szeredi 		if (newent->d_inode)
7259e6268dbSMiklos Szeredi 			fuse_invalidate_entry(newent);
7269e6268dbSMiklos Szeredi 	}
7279e6268dbSMiklos Szeredi 
7289e6268dbSMiklos Szeredi 	return err;
7299e6268dbSMiklos Szeredi }
7309e6268dbSMiklos Szeredi 
7319e6268dbSMiklos Szeredi static int fuse_link(struct dentry *entry, struct inode *newdir,
7329e6268dbSMiklos Szeredi 		     struct dentry *newent)
7339e6268dbSMiklos Szeredi {
7349e6268dbSMiklos Szeredi 	int err;
7359e6268dbSMiklos Szeredi 	struct fuse_link_in inarg;
7369e6268dbSMiklos Szeredi 	struct inode *inode = entry->d_inode;
7379e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
738ce1d5a49SMiklos Szeredi 	struct fuse_req *req = fuse_get_req(fc);
739ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
740ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
7419e6268dbSMiklos Szeredi 
7429e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
7439e6268dbSMiklos Szeredi 	inarg.oldnodeid = get_node_id(inode);
7449e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_LINK;
7459e6268dbSMiklos Szeredi 	req->in.numargs = 2;
7469e6268dbSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
7479e6268dbSMiklos Szeredi 	req->in.args[0].value = &inarg;
7489e6268dbSMiklos Szeredi 	req->in.args[1].size = newent->d_name.len + 1;
7499e6268dbSMiklos Szeredi 	req->in.args[1].value = newent->d_name.name;
7509e6268dbSMiklos Szeredi 	err = create_new_entry(fc, req, newdir, newent, inode->i_mode);
7519e6268dbSMiklos Szeredi 	/* Contrary to "normal" filesystems it can happen that link
7529e6268dbSMiklos Szeredi 	   makes two "logical" inodes point to the same "physical"
7539e6268dbSMiklos Szeredi 	   inode.  We invalidate the attributes of the old one, so it
7549e6268dbSMiklos Szeredi 	   will reflect changes in the backing inode (link count,
7559e6268dbSMiklos Szeredi 	   etc.)
7569e6268dbSMiklos Szeredi 	*/
7579e6268dbSMiklos Szeredi 	if (!err || err == -EINTR)
7589e6268dbSMiklos Szeredi 		fuse_invalidate_attr(inode);
7599e6268dbSMiklos Szeredi 	return err;
7609e6268dbSMiklos Szeredi }
7619e6268dbSMiklos Szeredi 
7621fb69e78SMiklos Szeredi static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
7631fb69e78SMiklos Szeredi 			  struct kstat *stat)
7641fb69e78SMiklos Szeredi {
7651fb69e78SMiklos Szeredi 	stat->dev = inode->i_sb->s_dev;
7661fb69e78SMiklos Szeredi 	stat->ino = attr->ino;
7671fb69e78SMiklos Szeredi 	stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
7681fb69e78SMiklos Szeredi 	stat->nlink = attr->nlink;
7691fb69e78SMiklos Szeredi 	stat->uid = attr->uid;
7701fb69e78SMiklos Szeredi 	stat->gid = attr->gid;
7711fb69e78SMiklos Szeredi 	stat->rdev = inode->i_rdev;
7721fb69e78SMiklos Szeredi 	stat->atime.tv_sec = attr->atime;
7731fb69e78SMiklos Szeredi 	stat->atime.tv_nsec = attr->atimensec;
7741fb69e78SMiklos Szeredi 	stat->mtime.tv_sec = attr->mtime;
7751fb69e78SMiklos Szeredi 	stat->mtime.tv_nsec = attr->mtimensec;
7761fb69e78SMiklos Szeredi 	stat->ctime.tv_sec = attr->ctime;
7771fb69e78SMiklos Szeredi 	stat->ctime.tv_nsec = attr->ctimensec;
7781fb69e78SMiklos Szeredi 	stat->size = attr->size;
7791fb69e78SMiklos Szeredi 	stat->blocks = attr->blocks;
7801fb69e78SMiklos Szeredi 	stat->blksize = (1 << inode->i_blkbits);
7811fb69e78SMiklos Szeredi }
7821fb69e78SMiklos Szeredi 
783c79e322fSMiklos Szeredi static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
784c79e322fSMiklos Szeredi 			   struct file *file)
785e5e5558eSMiklos Szeredi {
786e5e5558eSMiklos Szeredi 	int err;
787c79e322fSMiklos Szeredi 	struct fuse_getattr_in inarg;
788c79e322fSMiklos Szeredi 	struct fuse_attr_out outarg;
789e5e5558eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
7901fb69e78SMiklos Szeredi 	struct fuse_req *req;
7911fb69e78SMiklos Szeredi 	u64 attr_version;
7921fb69e78SMiklos Szeredi 
7931fb69e78SMiklos Szeredi 	req = fuse_get_req(fc);
794ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
795ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
796e5e5558eSMiklos Szeredi 
7977dca9fd3SMiklos Szeredi 	attr_version = fuse_get_attr_version(fc);
7981fb69e78SMiklos Szeredi 
799c79e322fSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
8000e9663eeSMiklos Szeredi 	memset(&outarg, 0, sizeof(outarg));
801c79e322fSMiklos Szeredi 	/* Directories have separate file-handle space */
802c79e322fSMiklos Szeredi 	if (file && S_ISREG(inode->i_mode)) {
803c79e322fSMiklos Szeredi 		struct fuse_file *ff = file->private_data;
804c79e322fSMiklos Szeredi 
805c79e322fSMiklos Szeredi 		inarg.getattr_flags |= FUSE_GETATTR_FH;
806c79e322fSMiklos Szeredi 		inarg.fh = ff->fh;
807c79e322fSMiklos Szeredi 	}
808e5e5558eSMiklos Szeredi 	req->in.h.opcode = FUSE_GETATTR;
809e5e5558eSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
810c79e322fSMiklos Szeredi 	req->in.numargs = 1;
811c79e322fSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
812c79e322fSMiklos Szeredi 	req->in.args[0].value = &inarg;
813e5e5558eSMiklos Szeredi 	req->out.numargs = 1;
8140e9663eeSMiklos Szeredi 	if (fc->minor < 9)
8150e9663eeSMiklos Szeredi 		req->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
8160e9663eeSMiklos Szeredi 	else
817c79e322fSMiklos Szeredi 		req->out.args[0].size = sizeof(outarg);
818c79e322fSMiklos Szeredi 	req->out.args[0].value = &outarg;
819b93f858aSTejun Heo 	fuse_request_send(fc, req);
820e5e5558eSMiklos Szeredi 	err = req->out.h.error;
821e5e5558eSMiklos Szeredi 	fuse_put_request(fc, req);
822e5e5558eSMiklos Szeredi 	if (!err) {
823c79e322fSMiklos Szeredi 		if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
824e5e5558eSMiklos Szeredi 			make_bad_inode(inode);
825e5e5558eSMiklos Szeredi 			err = -EIO;
826e5e5558eSMiklos Szeredi 		} else {
827c79e322fSMiklos Szeredi 			fuse_change_attributes(inode, &outarg.attr,
828c79e322fSMiklos Szeredi 					       attr_timeout(&outarg),
8291fb69e78SMiklos Szeredi 					       attr_version);
8301fb69e78SMiklos Szeredi 			if (stat)
831c79e322fSMiklos Szeredi 				fuse_fillattr(inode, &outarg.attr, stat);
832e5e5558eSMiklos Szeredi 		}
833e5e5558eSMiklos Szeredi 	}
834e5e5558eSMiklos Szeredi 	return err;
835e5e5558eSMiklos Szeredi }
836e5e5558eSMiklos Szeredi 
837bcb4be80SMiklos Szeredi int fuse_update_attributes(struct inode *inode, struct kstat *stat,
838bcb4be80SMiklos Szeredi 			   struct file *file, bool *refreshed)
839bcb4be80SMiklos Szeredi {
840bcb4be80SMiklos Szeredi 	struct fuse_inode *fi = get_fuse_inode(inode);
841bcb4be80SMiklos Szeredi 	int err;
842bcb4be80SMiklos Szeredi 	bool r;
843bcb4be80SMiklos Szeredi 
844bcb4be80SMiklos Szeredi 	if (fi->i_time < get_jiffies_64()) {
845bcb4be80SMiklos Szeredi 		r = true;
846bcb4be80SMiklos Szeredi 		err = fuse_do_getattr(inode, stat, file);
847bcb4be80SMiklos Szeredi 	} else {
848bcb4be80SMiklos Szeredi 		r = false;
849bcb4be80SMiklos Szeredi 		err = 0;
850bcb4be80SMiklos Szeredi 		if (stat) {
851bcb4be80SMiklos Szeredi 			generic_fillattr(inode, stat);
852bcb4be80SMiklos Szeredi 			stat->mode = fi->orig_i_mode;
853bcb4be80SMiklos Szeredi 		}
854bcb4be80SMiklos Szeredi 	}
855bcb4be80SMiklos Szeredi 
856bcb4be80SMiklos Szeredi 	if (refreshed != NULL)
857bcb4be80SMiklos Szeredi 		*refreshed = r;
858bcb4be80SMiklos Szeredi 
859bcb4be80SMiklos Szeredi 	return err;
860bcb4be80SMiklos Szeredi }
861bcb4be80SMiklos Szeredi 
862*3b463ae0SJohn Muir int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid,
863*3b463ae0SJohn Muir 			     struct qstr *name)
864*3b463ae0SJohn Muir {
865*3b463ae0SJohn Muir 	int err = -ENOTDIR;
866*3b463ae0SJohn Muir 	struct inode *parent;
867*3b463ae0SJohn Muir 	struct dentry *dir;
868*3b463ae0SJohn Muir 	struct dentry *entry;
869*3b463ae0SJohn Muir 
870*3b463ae0SJohn Muir 	parent = ilookup5(sb, parent_nodeid, fuse_inode_eq, &parent_nodeid);
871*3b463ae0SJohn Muir 	if (!parent)
872*3b463ae0SJohn Muir 		return -ENOENT;
873*3b463ae0SJohn Muir 
874*3b463ae0SJohn Muir 	mutex_lock(&parent->i_mutex);
875*3b463ae0SJohn Muir 	if (!S_ISDIR(parent->i_mode))
876*3b463ae0SJohn Muir 		goto unlock;
877*3b463ae0SJohn Muir 
878*3b463ae0SJohn Muir 	err = -ENOENT;
879*3b463ae0SJohn Muir 	dir = d_find_alias(parent);
880*3b463ae0SJohn Muir 	if (!dir)
881*3b463ae0SJohn Muir 		goto unlock;
882*3b463ae0SJohn Muir 
883*3b463ae0SJohn Muir 	entry = d_lookup(dir, name);
884*3b463ae0SJohn Muir 	dput(dir);
885*3b463ae0SJohn Muir 	if (!entry)
886*3b463ae0SJohn Muir 		goto unlock;
887*3b463ae0SJohn Muir 
888*3b463ae0SJohn Muir 	fuse_invalidate_attr(parent);
889*3b463ae0SJohn Muir 	fuse_invalidate_entry(entry);
890*3b463ae0SJohn Muir 	dput(entry);
891*3b463ae0SJohn Muir 	err = 0;
892*3b463ae0SJohn Muir 
893*3b463ae0SJohn Muir  unlock:
894*3b463ae0SJohn Muir 	mutex_unlock(&parent->i_mutex);
895*3b463ae0SJohn Muir 	iput(parent);
896*3b463ae0SJohn Muir 	return err;
897*3b463ae0SJohn Muir }
898*3b463ae0SJohn Muir 
89987729a55SMiklos Szeredi /*
90087729a55SMiklos Szeredi  * Calling into a user-controlled filesystem gives the filesystem
90187729a55SMiklos Szeredi  * daemon ptrace-like capabilities over the requester process.  This
90287729a55SMiklos Szeredi  * means, that the filesystem daemon is able to record the exact
90387729a55SMiklos Szeredi  * filesystem operations performed, and can also control the behavior
90487729a55SMiklos Szeredi  * of the requester process in otherwise impossible ways.  For example
90587729a55SMiklos Szeredi  * it can delay the operation for arbitrary length of time allowing
90687729a55SMiklos Szeredi  * DoS against the requester.
90787729a55SMiklos Szeredi  *
90887729a55SMiklos Szeredi  * For this reason only those processes can call into the filesystem,
90987729a55SMiklos Szeredi  * for which the owner of the mount has ptrace privilege.  This
91087729a55SMiklos Szeredi  * excludes processes started by other users, suid or sgid processes.
91187729a55SMiklos Szeredi  */
912e57ac683SMiklos Szeredi int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task)
91387729a55SMiklos Szeredi {
914c69e8d9cSDavid Howells 	const struct cred *cred;
915c69e8d9cSDavid Howells 	int ret;
916c69e8d9cSDavid Howells 
91787729a55SMiklos Szeredi 	if (fc->flags & FUSE_ALLOW_OTHER)
91887729a55SMiklos Szeredi 		return 1;
91987729a55SMiklos Szeredi 
920c69e8d9cSDavid Howells 	rcu_read_lock();
921c69e8d9cSDavid Howells 	ret = 0;
922c69e8d9cSDavid Howells 	cred = __task_cred(task);
923c69e8d9cSDavid Howells 	if (cred->euid == fc->user_id &&
924c69e8d9cSDavid Howells 	    cred->suid == fc->user_id &&
925c69e8d9cSDavid Howells 	    cred->uid  == fc->user_id &&
926c69e8d9cSDavid Howells 	    cred->egid == fc->group_id &&
927c69e8d9cSDavid Howells 	    cred->sgid == fc->group_id &&
928c69e8d9cSDavid Howells 	    cred->gid  == fc->group_id)
929c69e8d9cSDavid Howells 		ret = 1;
930c69e8d9cSDavid Howells 	rcu_read_unlock();
93187729a55SMiklos Szeredi 
932c69e8d9cSDavid Howells 	return ret;
93387729a55SMiklos Szeredi }
93487729a55SMiklos Szeredi 
93531d40d74SMiklos Szeredi static int fuse_access(struct inode *inode, int mask)
93631d40d74SMiklos Szeredi {
93731d40d74SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
93831d40d74SMiklos Szeredi 	struct fuse_req *req;
93931d40d74SMiklos Szeredi 	struct fuse_access_in inarg;
94031d40d74SMiklos Szeredi 	int err;
94131d40d74SMiklos Szeredi 
94231d40d74SMiklos Szeredi 	if (fc->no_access)
94331d40d74SMiklos Szeredi 		return 0;
94431d40d74SMiklos Szeredi 
945ce1d5a49SMiklos Szeredi 	req = fuse_get_req(fc);
946ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
947ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
94831d40d74SMiklos Szeredi 
94931d40d74SMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
950e6305c43SAl Viro 	inarg.mask = mask & (MAY_READ | MAY_WRITE | MAY_EXEC);
95131d40d74SMiklos Szeredi 	req->in.h.opcode = FUSE_ACCESS;
95231d40d74SMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
95331d40d74SMiklos Szeredi 	req->in.numargs = 1;
95431d40d74SMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
95531d40d74SMiklos Szeredi 	req->in.args[0].value = &inarg;
956b93f858aSTejun Heo 	fuse_request_send(fc, req);
95731d40d74SMiklos Szeredi 	err = req->out.h.error;
95831d40d74SMiklos Szeredi 	fuse_put_request(fc, req);
95931d40d74SMiklos Szeredi 	if (err == -ENOSYS) {
96031d40d74SMiklos Szeredi 		fc->no_access = 1;
96131d40d74SMiklos Szeredi 		err = 0;
96231d40d74SMiklos Szeredi 	}
96331d40d74SMiklos Szeredi 	return err;
96431d40d74SMiklos Szeredi }
96531d40d74SMiklos Szeredi 
9666f9f1180SMiklos Szeredi /*
9676f9f1180SMiklos Szeredi  * Check permission.  The two basic access models of FUSE are:
9686f9f1180SMiklos Szeredi  *
9696f9f1180SMiklos Szeredi  * 1) Local access checking ('default_permissions' mount option) based
9706f9f1180SMiklos Szeredi  * on file mode.  This is the plain old disk filesystem permission
9716f9f1180SMiklos Szeredi  * modell.
9726f9f1180SMiklos Szeredi  *
9736f9f1180SMiklos Szeredi  * 2) "Remote" access checking, where server is responsible for
9746f9f1180SMiklos Szeredi  * checking permission in each inode operation.  An exception to this
9756f9f1180SMiklos Szeredi  * is if ->permission() was invoked from sys_access() in which case an
9766f9f1180SMiklos Szeredi  * access request is sent.  Execute permission is still checked
9776f9f1180SMiklos Szeredi  * locally based on file mode.
9786f9f1180SMiklos Szeredi  */
979e6305c43SAl Viro static int fuse_permission(struct inode *inode, int mask)
980e5e5558eSMiklos Szeredi {
981e5e5558eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
982244f6385SMiklos Szeredi 	bool refreshed = false;
983244f6385SMiklos Szeredi 	int err = 0;
984e5e5558eSMiklos Szeredi 
98587729a55SMiklos Szeredi 	if (!fuse_allow_task(fc, current))
986e5e5558eSMiklos Szeredi 		return -EACCES;
987244f6385SMiklos Szeredi 
988244f6385SMiklos Szeredi 	/*
989e8e96157SMiklos Szeredi 	 * If attributes are needed, refresh them before proceeding
990244f6385SMiklos Szeredi 	 */
991e8e96157SMiklos Szeredi 	if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) ||
992e8e96157SMiklos Szeredi 	    ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) {
993bcb4be80SMiklos Szeredi 		err = fuse_update_attributes(inode, NULL, NULL, &refreshed);
994244f6385SMiklos Szeredi 		if (err)
995244f6385SMiklos Szeredi 			return err;
9961fb69e78SMiklos Szeredi 	}
997244f6385SMiklos Szeredi 
998244f6385SMiklos Szeredi 	if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
9991a823ac9SMiklos Szeredi 		err = generic_permission(inode, mask, NULL);
10001e9a4ed9SMiklos Szeredi 
10011e9a4ed9SMiklos Szeredi 		/* If permission is denied, try to refresh file
10021e9a4ed9SMiklos Szeredi 		   attributes.  This is also needed, because the root
10031e9a4ed9SMiklos Szeredi 		   node will at first have no permissions */
1004244f6385SMiklos Szeredi 		if (err == -EACCES && !refreshed) {
1005c79e322fSMiklos Szeredi 			err = fuse_do_getattr(inode, NULL, NULL);
10061e9a4ed9SMiklos Szeredi 			if (!err)
10071e9a4ed9SMiklos Szeredi 				err = generic_permission(inode, mask, NULL);
10081e9a4ed9SMiklos Szeredi 		}
10091e9a4ed9SMiklos Szeredi 
10106f9f1180SMiklos Szeredi 		/* Note: the opposite of the above test does not
10116f9f1180SMiklos Szeredi 		   exist.  So if permissions are revoked this won't be
10126f9f1180SMiklos Szeredi 		   noticed immediately, only after the attribute
10136f9f1180SMiklos Szeredi 		   timeout has expired */
1014a110343fSAl Viro 	} else if (mask & MAY_ACCESS) {
1015e8e96157SMiklos Szeredi 		err = fuse_access(inode, mask);
1016e8e96157SMiklos Szeredi 	} else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
1017e8e96157SMiklos Szeredi 		if (!(inode->i_mode & S_IXUGO)) {
1018e8e96157SMiklos Szeredi 			if (refreshed)
1019e5e5558eSMiklos Szeredi 				return -EACCES;
102031d40d74SMiklos Szeredi 
1021c79e322fSMiklos Szeredi 			err = fuse_do_getattr(inode, NULL, NULL);
1022e8e96157SMiklos Szeredi 			if (!err && !(inode->i_mode & S_IXUGO))
1023e8e96157SMiklos Szeredi 				return -EACCES;
1024e8e96157SMiklos Szeredi 		}
1025e5e5558eSMiklos Szeredi 	}
1026244f6385SMiklos Szeredi 	return err;
1027e5e5558eSMiklos Szeredi }
1028e5e5558eSMiklos Szeredi 
1029e5e5558eSMiklos Szeredi static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
1030e5e5558eSMiklos Szeredi 			 void *dstbuf, filldir_t filldir)
1031e5e5558eSMiklos Szeredi {
1032e5e5558eSMiklos Szeredi 	while (nbytes >= FUSE_NAME_OFFSET) {
1033e5e5558eSMiklos Szeredi 		struct fuse_dirent *dirent = (struct fuse_dirent *) buf;
1034e5e5558eSMiklos Szeredi 		size_t reclen = FUSE_DIRENT_SIZE(dirent);
1035e5e5558eSMiklos Szeredi 		int over;
1036e5e5558eSMiklos Szeredi 		if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
1037e5e5558eSMiklos Szeredi 			return -EIO;
1038e5e5558eSMiklos Szeredi 		if (reclen > nbytes)
1039e5e5558eSMiklos Szeredi 			break;
1040e5e5558eSMiklos Szeredi 
1041e5e5558eSMiklos Szeredi 		over = filldir(dstbuf, dirent->name, dirent->namelen,
1042e5e5558eSMiklos Szeredi 			       file->f_pos, dirent->ino, dirent->type);
1043e5e5558eSMiklos Szeredi 		if (over)
1044e5e5558eSMiklos Szeredi 			break;
1045e5e5558eSMiklos Szeredi 
1046e5e5558eSMiklos Szeredi 		buf += reclen;
1047e5e5558eSMiklos Szeredi 		nbytes -= reclen;
1048e5e5558eSMiklos Szeredi 		file->f_pos = dirent->off;
1049e5e5558eSMiklos Szeredi 	}
1050e5e5558eSMiklos Szeredi 
1051e5e5558eSMiklos Szeredi 	return 0;
1052e5e5558eSMiklos Szeredi }
1053e5e5558eSMiklos Szeredi 
1054e5e5558eSMiklos Szeredi static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
1055e5e5558eSMiklos Szeredi {
105604730fefSMiklos Szeredi 	int err;
105704730fefSMiklos Szeredi 	size_t nbytes;
105804730fefSMiklos Szeredi 	struct page *page;
10597706a9d6SJosef Sipek 	struct inode *inode = file->f_path.dentry->d_inode;
106004730fefSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
1061248d86e8SMiklos Szeredi 	struct fuse_req *req;
1062248d86e8SMiklos Szeredi 
1063248d86e8SMiklos Szeredi 	if (is_bad_inode(inode))
1064248d86e8SMiklos Szeredi 		return -EIO;
1065248d86e8SMiklos Szeredi 
1066ce1d5a49SMiklos Szeredi 	req = fuse_get_req(fc);
1067ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1068ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
1069e5e5558eSMiklos Szeredi 
107004730fefSMiklos Szeredi 	page = alloc_page(GFP_KERNEL);
107104730fefSMiklos Szeredi 	if (!page) {
107204730fefSMiklos Szeredi 		fuse_put_request(fc, req);
1073e5e5558eSMiklos Szeredi 		return -ENOMEM;
107404730fefSMiklos Szeredi 	}
1075f4975c67SMiklos Szeredi 	req->out.argpages = 1;
107604730fefSMiklos Szeredi 	req->num_pages = 1;
107704730fefSMiklos Szeredi 	req->pages[0] = page;
10782106cb18SMiklos Szeredi 	fuse_read_fill(req, file, file->f_pos, PAGE_SIZE, FUSE_READDIR);
1079b93f858aSTejun Heo 	fuse_request_send(fc, req);
1080361b1eb5SMiklos Szeredi 	nbytes = req->out.args[0].size;
108104730fefSMiklos Szeredi 	err = req->out.h.error;
108204730fefSMiklos Szeredi 	fuse_put_request(fc, req);
108304730fefSMiklos Szeredi 	if (!err)
108404730fefSMiklos Szeredi 		err = parse_dirfile(page_address(page), nbytes, file, dstbuf,
108504730fefSMiklos Szeredi 				    filldir);
1086e5e5558eSMiklos Szeredi 
108704730fefSMiklos Szeredi 	__free_page(page);
1088b36c31baSMiklos Szeredi 	fuse_invalidate_attr(inode); /* atime changed */
108904730fefSMiklos Szeredi 	return err;
1090e5e5558eSMiklos Szeredi }
1091e5e5558eSMiklos Szeredi 
1092e5e5558eSMiklos Szeredi static char *read_link(struct dentry *dentry)
1093e5e5558eSMiklos Szeredi {
1094e5e5558eSMiklos Szeredi 	struct inode *inode = dentry->d_inode;
1095e5e5558eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
1096ce1d5a49SMiklos Szeredi 	struct fuse_req *req = fuse_get_req(fc);
1097e5e5558eSMiklos Szeredi 	char *link;
1098e5e5558eSMiklos Szeredi 
1099ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1100e231c2eeSDavid Howells 		return ERR_CAST(req);
1101e5e5558eSMiklos Szeredi 
1102e5e5558eSMiklos Szeredi 	link = (char *) __get_free_page(GFP_KERNEL);
1103e5e5558eSMiklos Szeredi 	if (!link) {
1104e5e5558eSMiklos Szeredi 		link = ERR_PTR(-ENOMEM);
1105e5e5558eSMiklos Szeredi 		goto out;
1106e5e5558eSMiklos Szeredi 	}
1107e5e5558eSMiklos Szeredi 	req->in.h.opcode = FUSE_READLINK;
1108e5e5558eSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
1109e5e5558eSMiklos Szeredi 	req->out.argvar = 1;
1110e5e5558eSMiklos Szeredi 	req->out.numargs = 1;
1111e5e5558eSMiklos Szeredi 	req->out.args[0].size = PAGE_SIZE - 1;
1112e5e5558eSMiklos Szeredi 	req->out.args[0].value = link;
1113b93f858aSTejun Heo 	fuse_request_send(fc, req);
1114e5e5558eSMiklos Szeredi 	if (req->out.h.error) {
1115e5e5558eSMiklos Szeredi 		free_page((unsigned long) link);
1116e5e5558eSMiklos Szeredi 		link = ERR_PTR(req->out.h.error);
1117e5e5558eSMiklos Szeredi 	} else
1118e5e5558eSMiklos Szeredi 		link[req->out.args[0].size] = '\0';
1119e5e5558eSMiklos Szeredi  out:
1120e5e5558eSMiklos Szeredi 	fuse_put_request(fc, req);
1121b36c31baSMiklos Szeredi 	fuse_invalidate_attr(inode); /* atime changed */
1122e5e5558eSMiklos Szeredi 	return link;
1123e5e5558eSMiklos Szeredi }
1124e5e5558eSMiklos Szeredi 
1125e5e5558eSMiklos Szeredi static void free_link(char *link)
1126e5e5558eSMiklos Szeredi {
1127e5e5558eSMiklos Szeredi 	if (!IS_ERR(link))
1128e5e5558eSMiklos Szeredi 		free_page((unsigned long) link);
1129e5e5558eSMiklos Szeredi }
1130e5e5558eSMiklos Szeredi 
1131e5e5558eSMiklos Szeredi static void *fuse_follow_link(struct dentry *dentry, struct nameidata *nd)
1132e5e5558eSMiklos Szeredi {
1133e5e5558eSMiklos Szeredi 	nd_set_link(nd, read_link(dentry));
1134e5e5558eSMiklos Szeredi 	return NULL;
1135e5e5558eSMiklos Szeredi }
1136e5e5558eSMiklos Szeredi 
1137e5e5558eSMiklos Szeredi static void fuse_put_link(struct dentry *dentry, struct nameidata *nd, void *c)
1138e5e5558eSMiklos Szeredi {
1139e5e5558eSMiklos Szeredi 	free_link(nd_get_link(nd));
1140e5e5558eSMiklos Szeredi }
1141e5e5558eSMiklos Szeredi 
1142e5e5558eSMiklos Szeredi static int fuse_dir_open(struct inode *inode, struct file *file)
1143e5e5558eSMiklos Szeredi {
114491fe96b4SMiklos Szeredi 	return fuse_open_common(inode, file, true);
1145e5e5558eSMiklos Szeredi }
1146e5e5558eSMiklos Szeredi 
1147e5e5558eSMiklos Szeredi static int fuse_dir_release(struct inode *inode, struct file *file)
1148e5e5558eSMiklos Szeredi {
11498b0797a4SMiklos Szeredi 	fuse_release_common(file, FUSE_RELEASEDIR);
11508b0797a4SMiklos Szeredi 
11518b0797a4SMiklos Szeredi 	return 0;
1152e5e5558eSMiklos Szeredi }
1153e5e5558eSMiklos Szeredi 
115482547981SMiklos Szeredi static int fuse_dir_fsync(struct file *file, struct dentry *de, int datasync)
115582547981SMiklos Szeredi {
115682547981SMiklos Szeredi 	/* nfsd can call this with no file */
115782547981SMiklos Szeredi 	return file ? fuse_fsync_common(file, de, datasync, 1) : 0;
115882547981SMiklos Szeredi }
115982547981SMiklos Szeredi 
116017637cbaSMiklos Szeredi static bool update_mtime(unsigned ivalid)
116117637cbaSMiklos Szeredi {
116217637cbaSMiklos Szeredi 	/* Always update if mtime is explicitly set  */
116317637cbaSMiklos Szeredi 	if (ivalid & ATTR_MTIME_SET)
116417637cbaSMiklos Szeredi 		return true;
116517637cbaSMiklos Szeredi 
116617637cbaSMiklos Szeredi 	/* If it's an open(O_TRUNC) or an ftruncate(), don't update */
116717637cbaSMiklos Szeredi 	if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE)))
116817637cbaSMiklos Szeredi 		return false;
116917637cbaSMiklos Szeredi 
117017637cbaSMiklos Szeredi 	/* In all other cases update */
117117637cbaSMiklos Szeredi 	return true;
117217637cbaSMiklos Szeredi }
117317637cbaSMiklos Szeredi 
1174befc649cSMiklos Szeredi static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
11759e6268dbSMiklos Szeredi {
11769e6268dbSMiklos Szeredi 	unsigned ivalid = iattr->ia_valid;
11779e6268dbSMiklos Szeredi 
11789e6268dbSMiklos Szeredi 	if (ivalid & ATTR_MODE)
1179befc649cSMiklos Szeredi 		arg->valid |= FATTR_MODE,   arg->mode = iattr->ia_mode;
11809e6268dbSMiklos Szeredi 	if (ivalid & ATTR_UID)
1181befc649cSMiklos Szeredi 		arg->valid |= FATTR_UID,    arg->uid = iattr->ia_uid;
11829e6268dbSMiklos Szeredi 	if (ivalid & ATTR_GID)
1183befc649cSMiklos Szeredi 		arg->valid |= FATTR_GID,    arg->gid = iattr->ia_gid;
11849e6268dbSMiklos Szeredi 	if (ivalid & ATTR_SIZE)
1185befc649cSMiklos Szeredi 		arg->valid |= FATTR_SIZE,   arg->size = iattr->ia_size;
118617637cbaSMiklos Szeredi 	if (ivalid & ATTR_ATIME) {
118717637cbaSMiklos Szeredi 		arg->valid |= FATTR_ATIME;
1188befc649cSMiklos Szeredi 		arg->atime = iattr->ia_atime.tv_sec;
118917637cbaSMiklos Szeredi 		arg->atimensec = iattr->ia_atime.tv_nsec;
119017637cbaSMiklos Szeredi 		if (!(ivalid & ATTR_ATIME_SET))
119117637cbaSMiklos Szeredi 			arg->valid |= FATTR_ATIME_NOW;
119217637cbaSMiklos Szeredi 	}
119317637cbaSMiklos Szeredi 	if ((ivalid & ATTR_MTIME) && update_mtime(ivalid)) {
119417637cbaSMiklos Szeredi 		arg->valid |= FATTR_MTIME;
1195befc649cSMiklos Szeredi 		arg->mtime = iattr->ia_mtime.tv_sec;
119617637cbaSMiklos Szeredi 		arg->mtimensec = iattr->ia_mtime.tv_nsec;
119717637cbaSMiklos Szeredi 		if (!(ivalid & ATTR_MTIME_SET))
119817637cbaSMiklos Szeredi 			arg->valid |= FATTR_MTIME_NOW;
11999e6268dbSMiklos Szeredi 	}
12009e6268dbSMiklos Szeredi }
12019e6268dbSMiklos Szeredi 
12026f9f1180SMiklos Szeredi /*
12033be5a52bSMiklos Szeredi  * Prevent concurrent writepages on inode
12043be5a52bSMiklos Szeredi  *
12053be5a52bSMiklos Szeredi  * This is done by adding a negative bias to the inode write counter
12063be5a52bSMiklos Szeredi  * and waiting for all pending writes to finish.
12073be5a52bSMiklos Szeredi  */
12083be5a52bSMiklos Szeredi void fuse_set_nowrite(struct inode *inode)
12093be5a52bSMiklos Szeredi {
12103be5a52bSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
12113be5a52bSMiklos Szeredi 	struct fuse_inode *fi = get_fuse_inode(inode);
12123be5a52bSMiklos Szeredi 
12133be5a52bSMiklos Szeredi 	BUG_ON(!mutex_is_locked(&inode->i_mutex));
12143be5a52bSMiklos Szeredi 
12153be5a52bSMiklos Szeredi 	spin_lock(&fc->lock);
12163be5a52bSMiklos Szeredi 	BUG_ON(fi->writectr < 0);
12173be5a52bSMiklos Szeredi 	fi->writectr += FUSE_NOWRITE;
12183be5a52bSMiklos Szeredi 	spin_unlock(&fc->lock);
12193be5a52bSMiklos Szeredi 	wait_event(fi->page_waitq, fi->writectr == FUSE_NOWRITE);
12203be5a52bSMiklos Szeredi }
12213be5a52bSMiklos Szeredi 
12223be5a52bSMiklos Szeredi /*
12233be5a52bSMiklos Szeredi  * Allow writepages on inode
12243be5a52bSMiklos Szeredi  *
12253be5a52bSMiklos Szeredi  * Remove the bias from the writecounter and send any queued
12263be5a52bSMiklos Szeredi  * writepages.
12273be5a52bSMiklos Szeredi  */
12283be5a52bSMiklos Szeredi static void __fuse_release_nowrite(struct inode *inode)
12293be5a52bSMiklos Szeredi {
12303be5a52bSMiklos Szeredi 	struct fuse_inode *fi = get_fuse_inode(inode);
12313be5a52bSMiklos Szeredi 
12323be5a52bSMiklos Szeredi 	BUG_ON(fi->writectr != FUSE_NOWRITE);
12333be5a52bSMiklos Szeredi 	fi->writectr = 0;
12343be5a52bSMiklos Szeredi 	fuse_flush_writepages(inode);
12353be5a52bSMiklos Szeredi }
12363be5a52bSMiklos Szeredi 
12373be5a52bSMiklos Szeredi void fuse_release_nowrite(struct inode *inode)
12383be5a52bSMiklos Szeredi {
12393be5a52bSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
12403be5a52bSMiklos Szeredi 
12413be5a52bSMiklos Szeredi 	spin_lock(&fc->lock);
12423be5a52bSMiklos Szeredi 	__fuse_release_nowrite(inode);
12433be5a52bSMiklos Szeredi 	spin_unlock(&fc->lock);
12443be5a52bSMiklos Szeredi }
12453be5a52bSMiklos Szeredi 
12463be5a52bSMiklos Szeredi /*
12476f9f1180SMiklos Szeredi  * Set attributes, and at the same time refresh them.
12486f9f1180SMiklos Szeredi  *
12496f9f1180SMiklos Szeredi  * Truncation is slightly complicated, because the 'truncate' request
12506f9f1180SMiklos Szeredi  * may fail, in which case we don't want to touch the mapping.
12519ffbb916SMiklos Szeredi  * vmtruncate() doesn't allow for this case, so do the rlimit checking
12529ffbb916SMiklos Szeredi  * and the actual truncation by hand.
12536f9f1180SMiklos Szeredi  */
125449d4914fSMiklos Szeredi static int fuse_do_setattr(struct dentry *entry, struct iattr *attr,
125549d4914fSMiklos Szeredi 			   struct file *file)
12569e6268dbSMiklos Szeredi {
12579e6268dbSMiklos Szeredi 	struct inode *inode = entry->d_inode;
12589e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
12599e6268dbSMiklos Szeredi 	struct fuse_req *req;
12609e6268dbSMiklos Szeredi 	struct fuse_setattr_in inarg;
12619e6268dbSMiklos Szeredi 	struct fuse_attr_out outarg;
12623be5a52bSMiklos Szeredi 	bool is_truncate = false;
12633be5a52bSMiklos Szeredi 	loff_t oldsize;
12649e6268dbSMiklos Szeredi 	int err;
12659e6268dbSMiklos Szeredi 
1266e57ac683SMiklos Szeredi 	if (!fuse_allow_task(fc, current))
1267e57ac683SMiklos Szeredi 		return -EACCES;
1268e57ac683SMiklos Szeredi 
12691e9a4ed9SMiklos Szeredi 	if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
12701e9a4ed9SMiklos Szeredi 		err = inode_change_ok(inode, attr);
12711e9a4ed9SMiklos Szeredi 		if (err)
12721e9a4ed9SMiklos Szeredi 			return err;
12731e9a4ed9SMiklos Szeredi 	}
12741e9a4ed9SMiklos Szeredi 
12756ff958edSMiklos Szeredi 	if ((attr->ia_valid & ATTR_OPEN) && fc->atomic_o_trunc)
12766ff958edSMiklos Szeredi 		return 0;
12776ff958edSMiklos Szeredi 
12789e6268dbSMiklos Szeredi 	if (attr->ia_valid & ATTR_SIZE) {
12799e6268dbSMiklos Szeredi 		unsigned long limit;
1280b2d2272fSMiklos Szeredi 		if (IS_SWAPFILE(inode))
1281b2d2272fSMiklos Szeredi 			return -ETXTBSY;
12829e6268dbSMiklos Szeredi 		limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
12839e6268dbSMiklos Szeredi 		if (limit != RLIM_INFINITY && attr->ia_size > (loff_t) limit) {
12849e6268dbSMiklos Szeredi 			send_sig(SIGXFSZ, current, 0);
12859e6268dbSMiklos Szeredi 			return -EFBIG;
12869e6268dbSMiklos Szeredi 		}
12873be5a52bSMiklos Szeredi 		is_truncate = true;
12889e6268dbSMiklos Szeredi 	}
12899e6268dbSMiklos Szeredi 
1290ce1d5a49SMiklos Szeredi 	req = fuse_get_req(fc);
1291ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1292ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
12939e6268dbSMiklos Szeredi 
12943be5a52bSMiklos Szeredi 	if (is_truncate)
12953be5a52bSMiklos Szeredi 		fuse_set_nowrite(inode);
12963be5a52bSMiklos Szeredi 
12979e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
12980e9663eeSMiklos Szeredi 	memset(&outarg, 0, sizeof(outarg));
1299befc649cSMiklos Szeredi 	iattr_to_fattr(attr, &inarg);
130049d4914fSMiklos Szeredi 	if (file) {
130149d4914fSMiklos Szeredi 		struct fuse_file *ff = file->private_data;
130249d4914fSMiklos Szeredi 		inarg.valid |= FATTR_FH;
130349d4914fSMiklos Szeredi 		inarg.fh = ff->fh;
130449d4914fSMiklos Szeredi 	}
1305f3332114SMiklos Szeredi 	if (attr->ia_valid & ATTR_SIZE) {
1306f3332114SMiklos Szeredi 		/* For mandatory locking in truncate */
1307f3332114SMiklos Szeredi 		inarg.valid |= FATTR_LOCKOWNER;
1308f3332114SMiklos Szeredi 		inarg.lock_owner = fuse_lock_owner_id(fc, current->files);
1309f3332114SMiklos Szeredi 	}
13109e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_SETATTR;
13119e6268dbSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
13129e6268dbSMiklos Szeredi 	req->in.numargs = 1;
13139e6268dbSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
13149e6268dbSMiklos Szeredi 	req->in.args[0].value = &inarg;
13159e6268dbSMiklos Szeredi 	req->out.numargs = 1;
13160e9663eeSMiklos Szeredi 	if (fc->minor < 9)
13170e9663eeSMiklos Szeredi 		req->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
13180e9663eeSMiklos Szeredi 	else
13199e6268dbSMiklos Szeredi 		req->out.args[0].size = sizeof(outarg);
13209e6268dbSMiklos Szeredi 	req->out.args[0].value = &outarg;
1321b93f858aSTejun Heo 	fuse_request_send(fc, req);
13229e6268dbSMiklos Szeredi 	err = req->out.h.error;
13239e6268dbSMiklos Szeredi 	fuse_put_request(fc, req);
1324e00d2c2dSMiklos Szeredi 	if (err) {
1325e00d2c2dSMiklos Szeredi 		if (err == -EINTR)
1326e00d2c2dSMiklos Szeredi 			fuse_invalidate_attr(inode);
13273be5a52bSMiklos Szeredi 		goto error;
1328e00d2c2dSMiklos Szeredi 	}
1329e00d2c2dSMiklos Szeredi 
13309e6268dbSMiklos Szeredi 	if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
13319e6268dbSMiklos Szeredi 		make_bad_inode(inode);
13323be5a52bSMiklos Szeredi 		err = -EIO;
13333be5a52bSMiklos Szeredi 		goto error;
13349e6268dbSMiklos Szeredi 	}
13359e6268dbSMiklos Szeredi 
13363be5a52bSMiklos Szeredi 	spin_lock(&fc->lock);
13373be5a52bSMiklos Szeredi 	fuse_change_attributes_common(inode, &outarg.attr,
13383be5a52bSMiklos Szeredi 				      attr_timeout(&outarg));
13393be5a52bSMiklos Szeredi 	oldsize = inode->i_size;
13403be5a52bSMiklos Szeredi 	i_size_write(inode, outarg.attr.size);
13413be5a52bSMiklos Szeredi 
13423be5a52bSMiklos Szeredi 	if (is_truncate) {
13433be5a52bSMiklos Szeredi 		/* NOTE: this may release/reacquire fc->lock */
13443be5a52bSMiklos Szeredi 		__fuse_release_nowrite(inode);
13453be5a52bSMiklos Szeredi 	}
13463be5a52bSMiklos Szeredi 	spin_unlock(&fc->lock);
13473be5a52bSMiklos Szeredi 
13483be5a52bSMiklos Szeredi 	/*
13493be5a52bSMiklos Szeredi 	 * Only call invalidate_inode_pages2() after removing
13503be5a52bSMiklos Szeredi 	 * FUSE_NOWRITE, otherwise fuse_launder_page() would deadlock.
13513be5a52bSMiklos Szeredi 	 */
13523be5a52bSMiklos Szeredi 	if (S_ISREG(inode->i_mode) && oldsize != outarg.attr.size) {
13533be5a52bSMiklos Szeredi 		if (outarg.attr.size < oldsize)
13543be5a52bSMiklos Szeredi 			fuse_truncate(inode->i_mapping, outarg.attr.size);
13553be5a52bSMiklos Szeredi 		invalidate_inode_pages2(inode->i_mapping);
13563be5a52bSMiklos Szeredi 	}
13573be5a52bSMiklos Szeredi 
1358e00d2c2dSMiklos Szeredi 	return 0;
13593be5a52bSMiklos Szeredi 
13603be5a52bSMiklos Szeredi error:
13613be5a52bSMiklos Szeredi 	if (is_truncate)
13623be5a52bSMiklos Szeredi 		fuse_release_nowrite(inode);
13633be5a52bSMiklos Szeredi 
13643be5a52bSMiklos Szeredi 	return err;
13659e6268dbSMiklos Szeredi }
13669e6268dbSMiklos Szeredi 
136749d4914fSMiklos Szeredi static int fuse_setattr(struct dentry *entry, struct iattr *attr)
136849d4914fSMiklos Szeredi {
136949d4914fSMiklos Szeredi 	if (attr->ia_valid & ATTR_FILE)
137049d4914fSMiklos Szeredi 		return fuse_do_setattr(entry, attr, attr->ia_file);
137149d4914fSMiklos Szeredi 	else
137249d4914fSMiklos Szeredi 		return fuse_do_setattr(entry, attr, NULL);
137349d4914fSMiklos Szeredi }
137449d4914fSMiklos Szeredi 
1375e5e5558eSMiklos Szeredi static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
1376e5e5558eSMiklos Szeredi 			struct kstat *stat)
1377e5e5558eSMiklos Szeredi {
1378e5e5558eSMiklos Szeredi 	struct inode *inode = entry->d_inode;
1379244f6385SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
1380244f6385SMiklos Szeredi 
1381244f6385SMiklos Szeredi 	if (!fuse_allow_task(fc, current))
1382244f6385SMiklos Szeredi 		return -EACCES;
1383244f6385SMiklos Szeredi 
1384bcb4be80SMiklos Szeredi 	return fuse_update_attributes(inode, stat, NULL, NULL);
1385e5e5558eSMiklos Szeredi }
1386e5e5558eSMiklos Szeredi 
138792a8780eSMiklos Szeredi static int fuse_setxattr(struct dentry *entry, const char *name,
138892a8780eSMiklos Szeredi 			 const void *value, size_t size, int flags)
138992a8780eSMiklos Szeredi {
139092a8780eSMiklos Szeredi 	struct inode *inode = entry->d_inode;
139192a8780eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
139292a8780eSMiklos Szeredi 	struct fuse_req *req;
139392a8780eSMiklos Szeredi 	struct fuse_setxattr_in inarg;
139492a8780eSMiklos Szeredi 	int err;
139592a8780eSMiklos Szeredi 
139692a8780eSMiklos Szeredi 	if (fc->no_setxattr)
139792a8780eSMiklos Szeredi 		return -EOPNOTSUPP;
139892a8780eSMiklos Szeredi 
1399ce1d5a49SMiklos Szeredi 	req = fuse_get_req(fc);
1400ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1401ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
140292a8780eSMiklos Szeredi 
140392a8780eSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
140492a8780eSMiklos Szeredi 	inarg.size = size;
140592a8780eSMiklos Szeredi 	inarg.flags = flags;
140692a8780eSMiklos Szeredi 	req->in.h.opcode = FUSE_SETXATTR;
140792a8780eSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
140892a8780eSMiklos Szeredi 	req->in.numargs = 3;
140992a8780eSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
141092a8780eSMiklos Szeredi 	req->in.args[0].value = &inarg;
141192a8780eSMiklos Szeredi 	req->in.args[1].size = strlen(name) + 1;
141292a8780eSMiklos Szeredi 	req->in.args[1].value = name;
141392a8780eSMiklos Szeredi 	req->in.args[2].size = size;
141492a8780eSMiklos Szeredi 	req->in.args[2].value = value;
1415b93f858aSTejun Heo 	fuse_request_send(fc, req);
141692a8780eSMiklos Szeredi 	err = req->out.h.error;
141792a8780eSMiklos Szeredi 	fuse_put_request(fc, req);
141892a8780eSMiklos Szeredi 	if (err == -ENOSYS) {
141992a8780eSMiklos Szeredi 		fc->no_setxattr = 1;
142092a8780eSMiklos Szeredi 		err = -EOPNOTSUPP;
142192a8780eSMiklos Szeredi 	}
142292a8780eSMiklos Szeredi 	return err;
142392a8780eSMiklos Szeredi }
142492a8780eSMiklos Szeredi 
142592a8780eSMiklos Szeredi static ssize_t fuse_getxattr(struct dentry *entry, const char *name,
142692a8780eSMiklos Szeredi 			     void *value, size_t size)
142792a8780eSMiklos Szeredi {
142892a8780eSMiklos Szeredi 	struct inode *inode = entry->d_inode;
142992a8780eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
143092a8780eSMiklos Szeredi 	struct fuse_req *req;
143192a8780eSMiklos Szeredi 	struct fuse_getxattr_in inarg;
143292a8780eSMiklos Szeredi 	struct fuse_getxattr_out outarg;
143392a8780eSMiklos Szeredi 	ssize_t ret;
143492a8780eSMiklos Szeredi 
143592a8780eSMiklos Szeredi 	if (fc->no_getxattr)
143692a8780eSMiklos Szeredi 		return -EOPNOTSUPP;
143792a8780eSMiklos Szeredi 
1438ce1d5a49SMiklos Szeredi 	req = fuse_get_req(fc);
1439ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1440ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
144192a8780eSMiklos Szeredi 
144292a8780eSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
144392a8780eSMiklos Szeredi 	inarg.size = size;
144492a8780eSMiklos Szeredi 	req->in.h.opcode = FUSE_GETXATTR;
144592a8780eSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
144692a8780eSMiklos Szeredi 	req->in.numargs = 2;
144792a8780eSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
144892a8780eSMiklos Szeredi 	req->in.args[0].value = &inarg;
144992a8780eSMiklos Szeredi 	req->in.args[1].size = strlen(name) + 1;
145092a8780eSMiklos Szeredi 	req->in.args[1].value = name;
145192a8780eSMiklos Szeredi 	/* This is really two different operations rolled into one */
145292a8780eSMiklos Szeredi 	req->out.numargs = 1;
145392a8780eSMiklos Szeredi 	if (size) {
145492a8780eSMiklos Szeredi 		req->out.argvar = 1;
145592a8780eSMiklos Szeredi 		req->out.args[0].size = size;
145692a8780eSMiklos Szeredi 		req->out.args[0].value = value;
145792a8780eSMiklos Szeredi 	} else {
145892a8780eSMiklos Szeredi 		req->out.args[0].size = sizeof(outarg);
145992a8780eSMiklos Szeredi 		req->out.args[0].value = &outarg;
146092a8780eSMiklos Szeredi 	}
1461b93f858aSTejun Heo 	fuse_request_send(fc, req);
146292a8780eSMiklos Szeredi 	ret = req->out.h.error;
146392a8780eSMiklos Szeredi 	if (!ret)
146492a8780eSMiklos Szeredi 		ret = size ? req->out.args[0].size : outarg.size;
146592a8780eSMiklos Szeredi 	else {
146692a8780eSMiklos Szeredi 		if (ret == -ENOSYS) {
146792a8780eSMiklos Szeredi 			fc->no_getxattr = 1;
146892a8780eSMiklos Szeredi 			ret = -EOPNOTSUPP;
146992a8780eSMiklos Szeredi 		}
147092a8780eSMiklos Szeredi 	}
147192a8780eSMiklos Szeredi 	fuse_put_request(fc, req);
147292a8780eSMiklos Szeredi 	return ret;
147392a8780eSMiklos Szeredi }
147492a8780eSMiklos Szeredi 
147592a8780eSMiklos Szeredi static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
147692a8780eSMiklos Szeredi {
147792a8780eSMiklos Szeredi 	struct inode *inode = entry->d_inode;
147892a8780eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
147992a8780eSMiklos Szeredi 	struct fuse_req *req;
148092a8780eSMiklos Szeredi 	struct fuse_getxattr_in inarg;
148192a8780eSMiklos Szeredi 	struct fuse_getxattr_out outarg;
148292a8780eSMiklos Szeredi 	ssize_t ret;
148392a8780eSMiklos Szeredi 
1484e57ac683SMiklos Szeredi 	if (!fuse_allow_task(fc, current))
1485e57ac683SMiklos Szeredi 		return -EACCES;
1486e57ac683SMiklos Szeredi 
148792a8780eSMiklos Szeredi 	if (fc->no_listxattr)
148892a8780eSMiklos Szeredi 		return -EOPNOTSUPP;
148992a8780eSMiklos Szeredi 
1490ce1d5a49SMiklos Szeredi 	req = fuse_get_req(fc);
1491ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1492ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
149392a8780eSMiklos Szeredi 
149492a8780eSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
149592a8780eSMiklos Szeredi 	inarg.size = size;
149692a8780eSMiklos Szeredi 	req->in.h.opcode = FUSE_LISTXATTR;
149792a8780eSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
149892a8780eSMiklos Szeredi 	req->in.numargs = 1;
149992a8780eSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
150092a8780eSMiklos Szeredi 	req->in.args[0].value = &inarg;
150192a8780eSMiklos Szeredi 	/* This is really two different operations rolled into one */
150292a8780eSMiklos Szeredi 	req->out.numargs = 1;
150392a8780eSMiklos Szeredi 	if (size) {
150492a8780eSMiklos Szeredi 		req->out.argvar = 1;
150592a8780eSMiklos Szeredi 		req->out.args[0].size = size;
150692a8780eSMiklos Szeredi 		req->out.args[0].value = list;
150792a8780eSMiklos Szeredi 	} else {
150892a8780eSMiklos Szeredi 		req->out.args[0].size = sizeof(outarg);
150992a8780eSMiklos Szeredi 		req->out.args[0].value = &outarg;
151092a8780eSMiklos Szeredi 	}
1511b93f858aSTejun Heo 	fuse_request_send(fc, req);
151292a8780eSMiklos Szeredi 	ret = req->out.h.error;
151392a8780eSMiklos Szeredi 	if (!ret)
151492a8780eSMiklos Szeredi 		ret = size ? req->out.args[0].size : outarg.size;
151592a8780eSMiklos Szeredi 	else {
151692a8780eSMiklos Szeredi 		if (ret == -ENOSYS) {
151792a8780eSMiklos Szeredi 			fc->no_listxattr = 1;
151892a8780eSMiklos Szeredi 			ret = -EOPNOTSUPP;
151992a8780eSMiklos Szeredi 		}
152092a8780eSMiklos Szeredi 	}
152192a8780eSMiklos Szeredi 	fuse_put_request(fc, req);
152292a8780eSMiklos Szeredi 	return ret;
152392a8780eSMiklos Szeredi }
152492a8780eSMiklos Szeredi 
152592a8780eSMiklos Szeredi static int fuse_removexattr(struct dentry *entry, const char *name)
152692a8780eSMiklos Szeredi {
152792a8780eSMiklos Szeredi 	struct inode *inode = entry->d_inode;
152892a8780eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
152992a8780eSMiklos Szeredi 	struct fuse_req *req;
153092a8780eSMiklos Szeredi 	int err;
153192a8780eSMiklos Szeredi 
153292a8780eSMiklos Szeredi 	if (fc->no_removexattr)
153392a8780eSMiklos Szeredi 		return -EOPNOTSUPP;
153492a8780eSMiklos Szeredi 
1535ce1d5a49SMiklos Szeredi 	req = fuse_get_req(fc);
1536ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1537ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
153892a8780eSMiklos Szeredi 
153992a8780eSMiklos Szeredi 	req->in.h.opcode = FUSE_REMOVEXATTR;
154092a8780eSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
154192a8780eSMiklos Szeredi 	req->in.numargs = 1;
154292a8780eSMiklos Szeredi 	req->in.args[0].size = strlen(name) + 1;
154392a8780eSMiklos Szeredi 	req->in.args[0].value = name;
1544b93f858aSTejun Heo 	fuse_request_send(fc, req);
154592a8780eSMiklos Szeredi 	err = req->out.h.error;
154692a8780eSMiklos Szeredi 	fuse_put_request(fc, req);
154792a8780eSMiklos Szeredi 	if (err == -ENOSYS) {
154892a8780eSMiklos Szeredi 		fc->no_removexattr = 1;
154992a8780eSMiklos Szeredi 		err = -EOPNOTSUPP;
155092a8780eSMiklos Szeredi 	}
155192a8780eSMiklos Szeredi 	return err;
155292a8780eSMiklos Szeredi }
155392a8780eSMiklos Szeredi 
1554754661f1SArjan van de Ven static const struct inode_operations fuse_dir_inode_operations = {
1555e5e5558eSMiklos Szeredi 	.lookup		= fuse_lookup,
15569e6268dbSMiklos Szeredi 	.mkdir		= fuse_mkdir,
15579e6268dbSMiklos Szeredi 	.symlink	= fuse_symlink,
15589e6268dbSMiklos Szeredi 	.unlink		= fuse_unlink,
15599e6268dbSMiklos Szeredi 	.rmdir		= fuse_rmdir,
15609e6268dbSMiklos Szeredi 	.rename		= fuse_rename,
15619e6268dbSMiklos Szeredi 	.link		= fuse_link,
15629e6268dbSMiklos Szeredi 	.setattr	= fuse_setattr,
15639e6268dbSMiklos Szeredi 	.create		= fuse_create,
15649e6268dbSMiklos Szeredi 	.mknod		= fuse_mknod,
1565e5e5558eSMiklos Szeredi 	.permission	= fuse_permission,
1566e5e5558eSMiklos Szeredi 	.getattr	= fuse_getattr,
156792a8780eSMiklos Szeredi 	.setxattr	= fuse_setxattr,
156892a8780eSMiklos Szeredi 	.getxattr	= fuse_getxattr,
156992a8780eSMiklos Szeredi 	.listxattr	= fuse_listxattr,
157092a8780eSMiklos Szeredi 	.removexattr	= fuse_removexattr,
1571e5e5558eSMiklos Szeredi };
1572e5e5558eSMiklos Szeredi 
15734b6f5d20SArjan van de Ven static const struct file_operations fuse_dir_operations = {
1574b6aeadedSMiklos Szeredi 	.llseek		= generic_file_llseek,
1575e5e5558eSMiklos Szeredi 	.read		= generic_read_dir,
1576e5e5558eSMiklos Szeredi 	.readdir	= fuse_readdir,
1577e5e5558eSMiklos Szeredi 	.open		= fuse_dir_open,
1578e5e5558eSMiklos Szeredi 	.release	= fuse_dir_release,
157982547981SMiklos Szeredi 	.fsync		= fuse_dir_fsync,
1580e5e5558eSMiklos Szeredi };
1581e5e5558eSMiklos Szeredi 
1582754661f1SArjan van de Ven static const struct inode_operations fuse_common_inode_operations = {
15839e6268dbSMiklos Szeredi 	.setattr	= fuse_setattr,
1584e5e5558eSMiklos Szeredi 	.permission	= fuse_permission,
1585e5e5558eSMiklos Szeredi 	.getattr	= fuse_getattr,
158692a8780eSMiklos Szeredi 	.setxattr	= fuse_setxattr,
158792a8780eSMiklos Szeredi 	.getxattr	= fuse_getxattr,
158892a8780eSMiklos Szeredi 	.listxattr	= fuse_listxattr,
158992a8780eSMiklos Szeredi 	.removexattr	= fuse_removexattr,
1590e5e5558eSMiklos Szeredi };
1591e5e5558eSMiklos Szeredi 
1592754661f1SArjan van de Ven static const struct inode_operations fuse_symlink_inode_operations = {
15939e6268dbSMiklos Szeredi 	.setattr	= fuse_setattr,
1594e5e5558eSMiklos Szeredi 	.follow_link	= fuse_follow_link,
1595e5e5558eSMiklos Szeredi 	.put_link	= fuse_put_link,
1596e5e5558eSMiklos Szeredi 	.readlink	= generic_readlink,
1597e5e5558eSMiklos Szeredi 	.getattr	= fuse_getattr,
159892a8780eSMiklos Szeredi 	.setxattr	= fuse_setxattr,
159992a8780eSMiklos Szeredi 	.getxattr	= fuse_getxattr,
160092a8780eSMiklos Szeredi 	.listxattr	= fuse_listxattr,
160192a8780eSMiklos Szeredi 	.removexattr	= fuse_removexattr,
1602e5e5558eSMiklos Szeredi };
1603e5e5558eSMiklos Szeredi 
1604e5e5558eSMiklos Szeredi void fuse_init_common(struct inode *inode)
1605e5e5558eSMiklos Szeredi {
1606e5e5558eSMiklos Szeredi 	inode->i_op = &fuse_common_inode_operations;
1607e5e5558eSMiklos Szeredi }
1608e5e5558eSMiklos Szeredi 
1609e5e5558eSMiklos Szeredi void fuse_init_dir(struct inode *inode)
1610e5e5558eSMiklos Szeredi {
1611e5e5558eSMiklos Szeredi 	inode->i_op = &fuse_dir_inode_operations;
1612e5e5558eSMiklos Szeredi 	inode->i_fop = &fuse_dir_operations;
1613e5e5558eSMiklos Szeredi }
1614e5e5558eSMiklos Szeredi 
1615e5e5558eSMiklos Szeredi void fuse_init_symlink(struct inode *inode)
1616e5e5558eSMiklos Szeredi {
1617e5e5558eSMiklos Szeredi 	inode->i_op = &fuse_symlink_inode_operations;
1618e5e5558eSMiklos Szeredi }
1619