xref: /openbmc/linux/fs/fuse/dir.c (revision d24339059d640f108c08ba99ef30e3bafa10f8e4)
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 
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 {
15934286d66SNick Piggin 	struct inode *inode;
1608cbdf1e6SMiklos Szeredi 
161e7c0a167SMiklos Szeredi 	inode = ACCESS_ONCE(entry->d_inode);
1628cbdf1e6SMiklos Szeredi 	if (inode && is_bad_inode(inode))
163e5e5558eSMiklos Szeredi 		return 0;
1640a0898cfSMiklos Szeredi 	else if (fuse_dentry_time(entry) < get_jiffies_64()) {
165e5e5558eSMiklos Szeredi 		int err;
166e5e5558eSMiklos Szeredi 		struct fuse_entry_out outarg;
1678cbdf1e6SMiklos Szeredi 		struct fuse_conn *fc;
1688cbdf1e6SMiklos Szeredi 		struct fuse_req *req;
16907e77dcaSMiklos Szeredi 		struct fuse_forget_link *forget;
170e956edd0SMiklos Szeredi 		struct dentry *parent;
1711fb69e78SMiklos Szeredi 		u64 attr_version;
1728cbdf1e6SMiklos Szeredi 
17350322fe7SMiklos Szeredi 		/* For negative dentries, always do a fresh lookup */
1748cbdf1e6SMiklos Szeredi 		if (!inode)
1758cbdf1e6SMiklos Szeredi 			return 0;
1768cbdf1e6SMiklos Szeredi 
177*d2433905SMiklos Szeredi 		if (nd && (nd->flags & LOOKUP_RCU))
178e7c0a167SMiklos Szeredi 			return -ECHILD;
179e7c0a167SMiklos Szeredi 
1808cbdf1e6SMiklos Szeredi 		fc = get_fuse_conn(inode);
181ce1d5a49SMiklos Szeredi 		req = fuse_get_req(fc);
182ce1d5a49SMiklos Szeredi 		if (IS_ERR(req))
183e5e5558eSMiklos Szeredi 			return 0;
184e5e5558eSMiklos Szeredi 
18507e77dcaSMiklos Szeredi 		forget = fuse_alloc_forget();
18607e77dcaSMiklos Szeredi 		if (!forget) {
1872d51013eSMiklos Szeredi 			fuse_put_request(fc, req);
1882d51013eSMiklos Szeredi 			return 0;
1892d51013eSMiklos Szeredi 		}
1902d51013eSMiklos Szeredi 
1917dca9fd3SMiklos Szeredi 		attr_version = fuse_get_attr_version(fc);
1921fb69e78SMiklos Szeredi 
193e956edd0SMiklos Szeredi 		parent = dget_parent(entry);
194c180eebeSMiklos Szeredi 		fuse_lookup_init(fc, req, get_node_id(parent->d_inode),
195c180eebeSMiklos Szeredi 				 &entry->d_name, &outarg);
196b93f858aSTejun Heo 		fuse_request_send(fc, req);
197e956edd0SMiklos Szeredi 		dput(parent);
198e5e5558eSMiklos Szeredi 		err = req->out.h.error;
1992d51013eSMiklos Szeredi 		fuse_put_request(fc, req);
20050322fe7SMiklos Szeredi 		/* Zero nodeid is same as -ENOENT */
20150322fe7SMiklos Szeredi 		if (!err && !outarg.nodeid)
20250322fe7SMiklos Szeredi 			err = -ENOENT;
2039e6268dbSMiklos Szeredi 		if (!err) {
2048cbdf1e6SMiklos Szeredi 			struct fuse_inode *fi = get_fuse_inode(inode);
2059e6268dbSMiklos Szeredi 			if (outarg.nodeid != get_node_id(inode)) {
20607e77dcaSMiklos Szeredi 				fuse_queue_forget(fc, forget, outarg.nodeid, 1);
2079e6268dbSMiklos Szeredi 				return 0;
2089e6268dbSMiklos Szeredi 			}
2098da5ff23SMiklos Szeredi 			spin_lock(&fc->lock);
2109e6268dbSMiklos Szeredi 			fi->nlookup++;
2118da5ff23SMiklos Szeredi 			spin_unlock(&fc->lock);
2129e6268dbSMiklos Szeredi 		}
21307e77dcaSMiklos Szeredi 		kfree(forget);
2149e6268dbSMiklos Szeredi 		if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
215e5e5558eSMiklos Szeredi 			return 0;
216e5e5558eSMiklos Szeredi 
2171fb69e78SMiklos Szeredi 		fuse_change_attributes(inode, &outarg.attr,
2181fb69e78SMiklos Szeredi 				       entry_attr_timeout(&outarg),
2191fb69e78SMiklos Szeredi 				       attr_version);
2201fb69e78SMiklos Szeredi 		fuse_change_entry_timeout(entry, &outarg);
221e5e5558eSMiklos Szeredi 	}
222e5e5558eSMiklos Szeredi 	return 1;
223e5e5558eSMiklos Szeredi }
224e5e5558eSMiklos Szeredi 
2258bfc016dSMiklos Szeredi static int invalid_nodeid(u64 nodeid)
2262827d0b2SMiklos Szeredi {
2272827d0b2SMiklos Szeredi 	return !nodeid || nodeid == FUSE_ROOT_ID;
2282827d0b2SMiklos Szeredi }
2292827d0b2SMiklos Szeredi 
2304269590aSAl Viro const struct dentry_operations fuse_dentry_operations = {
231e5e5558eSMiklos Szeredi 	.d_revalidate	= fuse_dentry_revalidate,
232e5e5558eSMiklos Szeredi };
233e5e5558eSMiklos Szeredi 
234a5bfffacSTimo Savola int fuse_valid_type(int m)
23539ee059aSMiklos Szeredi {
23639ee059aSMiklos Szeredi 	return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) ||
23739ee059aSMiklos Szeredi 		S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
23839ee059aSMiklos Szeredi }
23939ee059aSMiklos Szeredi 
240d2a85164SMiklos Szeredi /*
241d2a85164SMiklos Szeredi  * Add a directory inode to a dentry, ensuring that no other dentry
242d2a85164SMiklos Szeredi  * refers to this inode.  Called with fc->inst_mutex.
243d2a85164SMiklos Szeredi  */
2440de6256dSMiklos Szeredi static struct dentry *fuse_d_add_directory(struct dentry *entry,
2450de6256dSMiklos Szeredi 					   struct inode *inode)
246d2a85164SMiklos Szeredi {
247d2a85164SMiklos Szeredi 	struct dentry *alias = d_find_alias(inode);
2480de6256dSMiklos Szeredi 	if (alias && !(alias->d_flags & DCACHE_DISCONNECTED)) {
249d2a85164SMiklos Szeredi 		/* This tries to shrink the subtree below alias */
250d2a85164SMiklos Szeredi 		fuse_invalidate_entry(alias);
251d2a85164SMiklos Szeredi 		dput(alias);
252d2a85164SMiklos Szeredi 		if (!list_empty(&inode->i_dentry))
2530de6256dSMiklos Szeredi 			return ERR_PTR(-EBUSY);
2540de6256dSMiklos Szeredi 	} else {
2550de6256dSMiklos Szeredi 		dput(alias);
256d2a85164SMiklos Szeredi 	}
2570de6256dSMiklos Szeredi 	return d_splice_alias(inode, entry);
258d2a85164SMiklos Szeredi }
259d2a85164SMiklos Szeredi 
260c180eebeSMiklos Szeredi int fuse_lookup_name(struct super_block *sb, u64 nodeid, struct qstr *name,
261c180eebeSMiklos Szeredi 		     struct fuse_entry_out *outarg, struct inode **inode)
262c180eebeSMiklos Szeredi {
263c180eebeSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn_super(sb);
264c180eebeSMiklos Szeredi 	struct fuse_req *req;
26507e77dcaSMiklos Szeredi 	struct fuse_forget_link *forget;
266c180eebeSMiklos Szeredi 	u64 attr_version;
267c180eebeSMiklos Szeredi 	int err;
268c180eebeSMiklos Szeredi 
269c180eebeSMiklos Szeredi 	*inode = NULL;
270c180eebeSMiklos Szeredi 	err = -ENAMETOOLONG;
271c180eebeSMiklos Szeredi 	if (name->len > FUSE_NAME_MAX)
272c180eebeSMiklos Szeredi 		goto out;
273c180eebeSMiklos Szeredi 
274c180eebeSMiklos Szeredi 	req = fuse_get_req(fc);
275c180eebeSMiklos Szeredi 	err = PTR_ERR(req);
276c180eebeSMiklos Szeredi 	if (IS_ERR(req))
277c180eebeSMiklos Szeredi 		goto out;
278c180eebeSMiklos Szeredi 
27907e77dcaSMiklos Szeredi 	forget = fuse_alloc_forget();
28007e77dcaSMiklos Szeredi 	err = -ENOMEM;
28107e77dcaSMiklos Szeredi 	if (!forget) {
282c180eebeSMiklos Szeredi 		fuse_put_request(fc, req);
283c180eebeSMiklos Szeredi 		goto out;
284c180eebeSMiklos Szeredi 	}
285c180eebeSMiklos Szeredi 
286c180eebeSMiklos Szeredi 	attr_version = fuse_get_attr_version(fc);
287c180eebeSMiklos Szeredi 
288c180eebeSMiklos Szeredi 	fuse_lookup_init(fc, req, nodeid, name, outarg);
289b93f858aSTejun Heo 	fuse_request_send(fc, req);
290c180eebeSMiklos Szeredi 	err = req->out.h.error;
291c180eebeSMiklos Szeredi 	fuse_put_request(fc, req);
292c180eebeSMiklos Szeredi 	/* Zero nodeid is same as -ENOENT, but with valid timeout */
293c180eebeSMiklos Szeredi 	if (err || !outarg->nodeid)
294c180eebeSMiklos Szeredi 		goto out_put_forget;
295c180eebeSMiklos Szeredi 
296c180eebeSMiklos Szeredi 	err = -EIO;
297c180eebeSMiklos Szeredi 	if (!outarg->nodeid)
298c180eebeSMiklos Szeredi 		goto out_put_forget;
299c180eebeSMiklos Szeredi 	if (!fuse_valid_type(outarg->attr.mode))
300c180eebeSMiklos Szeredi 		goto out_put_forget;
301c180eebeSMiklos Szeredi 
302c180eebeSMiklos Szeredi 	*inode = fuse_iget(sb, outarg->nodeid, outarg->generation,
303c180eebeSMiklos Szeredi 			   &outarg->attr, entry_attr_timeout(outarg),
304c180eebeSMiklos Szeredi 			   attr_version);
305c180eebeSMiklos Szeredi 	err = -ENOMEM;
306c180eebeSMiklos Szeredi 	if (!*inode) {
30707e77dcaSMiklos Szeredi 		fuse_queue_forget(fc, forget, outarg->nodeid, 1);
308c180eebeSMiklos Szeredi 		goto out;
309c180eebeSMiklos Szeredi 	}
310c180eebeSMiklos Szeredi 	err = 0;
311c180eebeSMiklos Szeredi 
312c180eebeSMiklos Szeredi  out_put_forget:
31307e77dcaSMiklos Szeredi 	kfree(forget);
314c180eebeSMiklos Szeredi  out:
315c180eebeSMiklos Szeredi 	return err;
316c180eebeSMiklos Szeredi }
317c180eebeSMiklos Szeredi 
3180aa7c699SMiklos Szeredi static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
3190aa7c699SMiklos Szeredi 				  struct nameidata *nd)
320e5e5558eSMiklos Szeredi {
321e5e5558eSMiklos Szeredi 	int err;
322e5e5558eSMiklos Szeredi 	struct fuse_entry_out outarg;
323c180eebeSMiklos Szeredi 	struct inode *inode;
3240de6256dSMiklos Szeredi 	struct dentry *newent;
325e5e5558eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
326c180eebeSMiklos Szeredi 	bool outarg_valid = true;
327e5e5558eSMiklos Szeredi 
328c180eebeSMiklos Szeredi 	err = fuse_lookup_name(dir->i_sb, get_node_id(dir), &entry->d_name,
329c180eebeSMiklos Szeredi 			       &outarg, &inode);
330c180eebeSMiklos Szeredi 	if (err == -ENOENT) {
331c180eebeSMiklos Szeredi 		outarg_valid = false;
332c180eebeSMiklos Szeredi 		err = 0;
3332d51013eSMiklos Szeredi 	}
334c180eebeSMiklos Szeredi 	if (err)
335c180eebeSMiklos Szeredi 		goto out_err;
3362d51013eSMiklos Szeredi 
337ee4e5271SMiklos Szeredi 	err = -EIO;
338c180eebeSMiklos Szeredi 	if (inode && get_node_id(inode) == FUSE_ROOT_ID)
339c180eebeSMiklos Szeredi 		goto out_iput;
340e5e5558eSMiklos Szeredi 
341d2a85164SMiklos Szeredi 	if (inode && S_ISDIR(inode->i_mode)) {
342d2a85164SMiklos Szeredi 		mutex_lock(&fc->inst_mutex);
3430de6256dSMiklos Szeredi 		newent = fuse_d_add_directory(entry, inode);
344d2a85164SMiklos Szeredi 		mutex_unlock(&fc->inst_mutex);
345c180eebeSMiklos Szeredi 		err = PTR_ERR(newent);
346c180eebeSMiklos Szeredi 		if (IS_ERR(newent))
347c180eebeSMiklos Szeredi 			goto out_iput;
348c180eebeSMiklos Szeredi 	} else {
3490de6256dSMiklos Szeredi 		newent = d_splice_alias(inode, entry);
350c180eebeSMiklos Szeredi 	}
351d2a85164SMiklos Szeredi 
3520de6256dSMiklos Szeredi 	entry = newent ? newent : entry;
353c180eebeSMiklos Szeredi 	if (outarg_valid)
3541fb69e78SMiklos Szeredi 		fuse_change_entry_timeout(entry, &outarg);
3558cbdf1e6SMiklos Szeredi 	else
3568cbdf1e6SMiklos Szeredi 		fuse_invalidate_entry_cache(entry);
357c180eebeSMiklos Szeredi 
3580de6256dSMiklos Szeredi 	return newent;
359c180eebeSMiklos Szeredi 
360c180eebeSMiklos Szeredi  out_iput:
361c180eebeSMiklos Szeredi 	iput(inode);
362c180eebeSMiklos Szeredi  out_err:
363c180eebeSMiklos Szeredi 	return ERR_PTR(err);
364e5e5558eSMiklos Szeredi }
365e5e5558eSMiklos Szeredi 
3666f9f1180SMiklos Szeredi /*
3676f9f1180SMiklos Szeredi  * Atomic create+open operation
3686f9f1180SMiklos Szeredi  *
3696f9f1180SMiklos Szeredi  * If the filesystem doesn't support this, then fall back to separate
3706f9f1180SMiklos Szeredi  * 'mknod' + 'open' requests.
3716f9f1180SMiklos Szeredi  */
372fd72faacSMiklos Szeredi static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
373fd72faacSMiklos Szeredi 			    struct nameidata *nd)
374fd72faacSMiklos Szeredi {
375fd72faacSMiklos Szeredi 	int err;
376fd72faacSMiklos Szeredi 	struct inode *inode;
377fd72faacSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
378fd72faacSMiklos Szeredi 	struct fuse_req *req;
37907e77dcaSMiklos Szeredi 	struct fuse_forget_link *forget;
380e0a43ddcSMiklos Szeredi 	struct fuse_create_in inarg;
381fd72faacSMiklos Szeredi 	struct fuse_open_out outopen;
382fd72faacSMiklos Szeredi 	struct fuse_entry_out outentry;
383fd72faacSMiklos Szeredi 	struct fuse_file *ff;
384fd72faacSMiklos Szeredi 	struct file *file;
385fd72faacSMiklos Szeredi 	int flags = nd->intent.open.flags - 1;
386fd72faacSMiklos Szeredi 
387fd72faacSMiklos Szeredi 	if (fc->no_create)
388ce1d5a49SMiklos Szeredi 		return -ENOSYS;
389fd72faacSMiklos Szeredi 
3901b732396SCsaba Henk 	if (flags & O_DIRECT)
3911b732396SCsaba Henk 		return -EINVAL;
3921b732396SCsaba Henk 
39307e77dcaSMiklos Szeredi 	forget = fuse_alloc_forget();
39407e77dcaSMiklos Szeredi 	if (!forget)
39507e77dcaSMiklos Szeredi 		return -ENOMEM;
39651eb01e7SMiklos Szeredi 
397ce1d5a49SMiklos Szeredi 	req = fuse_get_req(fc);
39851eb01e7SMiklos Szeredi 	err = PTR_ERR(req);
399ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
40051eb01e7SMiklos Szeredi 		goto out_put_forget_req;
401fd72faacSMiklos Szeredi 
402ce1d5a49SMiklos Szeredi 	err = -ENOMEM;
403acf99433STejun Heo 	ff = fuse_file_alloc(fc);
404fd72faacSMiklos Szeredi 	if (!ff)
405fd72faacSMiklos Szeredi 		goto out_put_request;
406fd72faacSMiklos Szeredi 
407e0a43ddcSMiklos Szeredi 	if (!fc->dont_mask)
408e0a43ddcSMiklos Szeredi 		mode &= ~current_umask();
409e0a43ddcSMiklos Szeredi 
410fd72faacSMiklos Szeredi 	flags &= ~O_NOCTTY;
411fd72faacSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
4120e9663eeSMiklos Szeredi 	memset(&outentry, 0, sizeof(outentry));
413fd72faacSMiklos Szeredi 	inarg.flags = flags;
414fd72faacSMiklos Szeredi 	inarg.mode = mode;
415e0a43ddcSMiklos Szeredi 	inarg.umask = current_umask();
416fd72faacSMiklos Szeredi 	req->in.h.opcode = FUSE_CREATE;
417fd72faacSMiklos Szeredi 	req->in.h.nodeid = get_node_id(dir);
418fd72faacSMiklos Szeredi 	req->in.numargs = 2;
419e0a43ddcSMiklos Szeredi 	req->in.args[0].size = fc->minor < 12 ? sizeof(struct fuse_open_in) :
420e0a43ddcSMiklos Szeredi 						sizeof(inarg);
421fd72faacSMiklos Szeredi 	req->in.args[0].value = &inarg;
422fd72faacSMiklos Szeredi 	req->in.args[1].size = entry->d_name.len + 1;
423fd72faacSMiklos Szeredi 	req->in.args[1].value = entry->d_name.name;
424fd72faacSMiklos Szeredi 	req->out.numargs = 2;
4250e9663eeSMiklos Szeredi 	if (fc->minor < 9)
4260e9663eeSMiklos Szeredi 		req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
4270e9663eeSMiklos Szeredi 	else
428fd72faacSMiklos Szeredi 		req->out.args[0].size = sizeof(outentry);
429fd72faacSMiklos Szeredi 	req->out.args[0].value = &outentry;
430fd72faacSMiklos Szeredi 	req->out.args[1].size = sizeof(outopen);
431fd72faacSMiklos Szeredi 	req->out.args[1].value = &outopen;
432b93f858aSTejun Heo 	fuse_request_send(fc, req);
433fd72faacSMiklos Szeredi 	err = req->out.h.error;
434fd72faacSMiklos Szeredi 	if (err) {
435fd72faacSMiklos Szeredi 		if (err == -ENOSYS)
436fd72faacSMiklos Szeredi 			fc->no_create = 1;
437fd72faacSMiklos Szeredi 		goto out_free_ff;
438fd72faacSMiklos Szeredi 	}
439fd72faacSMiklos Szeredi 
440fd72faacSMiklos Szeredi 	err = -EIO;
4412827d0b2SMiklos Szeredi 	if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid))
442fd72faacSMiklos Szeredi 		goto out_free_ff;
443fd72faacSMiklos Szeredi 
44451eb01e7SMiklos Szeredi 	fuse_put_request(fc, req);
445c7b7143cSMiklos Szeredi 	ff->fh = outopen.fh;
446c7b7143cSMiklos Szeredi 	ff->nodeid = outentry.nodeid;
447c7b7143cSMiklos Szeredi 	ff->open_flags = outopen.open_flags;
448fd72faacSMiklos Szeredi 	inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
4491fb69e78SMiklos Szeredi 			  &outentry.attr, entry_attr_timeout(&outentry), 0);
450fd72faacSMiklos Szeredi 	if (!inode) {
451fd72faacSMiklos Szeredi 		flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
4528b0797a4SMiklos Szeredi 		fuse_sync_release(ff, flags);
45307e77dcaSMiklos Szeredi 		fuse_queue_forget(fc, forget, outentry.nodeid, 1);
45451eb01e7SMiklos Szeredi 		return -ENOMEM;
455fd72faacSMiklos Szeredi 	}
45607e77dcaSMiklos Szeredi 	kfree(forget);
457fd72faacSMiklos Szeredi 	d_instantiate(entry, inode);
4581fb69e78SMiklos Szeredi 	fuse_change_entry_timeout(entry, &outentry);
4590952b2a4SMiklos Szeredi 	fuse_invalidate_attr(dir);
460fd72faacSMiklos Szeredi 	file = lookup_instantiate_filp(nd, entry, generic_file_open);
461fd72faacSMiklos Szeredi 	if (IS_ERR(file)) {
4628b0797a4SMiklos Szeredi 		fuse_sync_release(ff, flags);
463fd72faacSMiklos Szeredi 		return PTR_ERR(file);
464fd72faacSMiklos Szeredi 	}
465c7b7143cSMiklos Szeredi 	file->private_data = fuse_file_get(ff);
466c7b7143cSMiklos Szeredi 	fuse_finish_open(inode, file);
467fd72faacSMiklos Szeredi 	return 0;
468fd72faacSMiklos Szeredi 
469fd72faacSMiklos Szeredi  out_free_ff:
470fd72faacSMiklos Szeredi 	fuse_file_free(ff);
471fd72faacSMiklos Szeredi  out_put_request:
472fd72faacSMiklos Szeredi 	fuse_put_request(fc, req);
47351eb01e7SMiklos Szeredi  out_put_forget_req:
47407e77dcaSMiklos Szeredi 	kfree(forget);
475fd72faacSMiklos Szeredi 	return err;
476fd72faacSMiklos Szeredi }
477fd72faacSMiklos Szeredi 
4786f9f1180SMiklos Szeredi /*
4796f9f1180SMiklos Szeredi  * Code shared between mknod, mkdir, symlink and link
4806f9f1180SMiklos Szeredi  */
4819e6268dbSMiklos Szeredi static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
4829e6268dbSMiklos Szeredi 			    struct inode *dir, struct dentry *entry,
4839e6268dbSMiklos Szeredi 			    int mode)
4849e6268dbSMiklos Szeredi {
4859e6268dbSMiklos Szeredi 	struct fuse_entry_out outarg;
4869e6268dbSMiklos Szeredi 	struct inode *inode;
4879e6268dbSMiklos Szeredi 	int err;
48807e77dcaSMiklos Szeredi 	struct fuse_forget_link *forget;
4892d51013eSMiklos Szeredi 
49007e77dcaSMiklos Szeredi 	forget = fuse_alloc_forget();
49107e77dcaSMiklos Szeredi 	if (!forget) {
4922d51013eSMiklos Szeredi 		fuse_put_request(fc, req);
49307e77dcaSMiklos Szeredi 		return -ENOMEM;
4942d51013eSMiklos Szeredi 	}
4959e6268dbSMiklos Szeredi 
4960e9663eeSMiklos Szeredi 	memset(&outarg, 0, sizeof(outarg));
4979e6268dbSMiklos Szeredi 	req->in.h.nodeid = get_node_id(dir);
4989e6268dbSMiklos Szeredi 	req->out.numargs = 1;
4990e9663eeSMiklos Szeredi 	if (fc->minor < 9)
5000e9663eeSMiklos Szeredi 		req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
5010e9663eeSMiklos Szeredi 	else
5029e6268dbSMiklos Szeredi 		req->out.args[0].size = sizeof(outarg);
5039e6268dbSMiklos Szeredi 	req->out.args[0].value = &outarg;
504b93f858aSTejun Heo 	fuse_request_send(fc, req);
5059e6268dbSMiklos Szeredi 	err = req->out.h.error;
5069e6268dbSMiklos Szeredi 	fuse_put_request(fc, req);
5072d51013eSMiklos Szeredi 	if (err)
5082d51013eSMiklos Szeredi 		goto out_put_forget_req;
5092d51013eSMiklos Szeredi 
51039ee059aSMiklos Szeredi 	err = -EIO;
51139ee059aSMiklos Szeredi 	if (invalid_nodeid(outarg.nodeid))
5122d51013eSMiklos Szeredi 		goto out_put_forget_req;
51339ee059aSMiklos Szeredi 
51439ee059aSMiklos Szeredi 	if ((outarg.attr.mode ^ mode) & S_IFMT)
5152d51013eSMiklos Szeredi 		goto out_put_forget_req;
51639ee059aSMiklos Szeredi 
5179e6268dbSMiklos Szeredi 	inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
5181fb69e78SMiklos Szeredi 			  &outarg.attr, entry_attr_timeout(&outarg), 0);
5199e6268dbSMiklos Szeredi 	if (!inode) {
52007e77dcaSMiklos Szeredi 		fuse_queue_forget(fc, forget, outarg.nodeid, 1);
5219e6268dbSMiklos Szeredi 		return -ENOMEM;
5229e6268dbSMiklos Szeredi 	}
52307e77dcaSMiklos Szeredi 	kfree(forget);
5249e6268dbSMiklos Szeredi 
525d2a85164SMiklos Szeredi 	if (S_ISDIR(inode->i_mode)) {
526d2a85164SMiklos Szeredi 		struct dentry *alias;
527d2a85164SMiklos Szeredi 		mutex_lock(&fc->inst_mutex);
528d2a85164SMiklos Szeredi 		alias = d_find_alias(inode);
529d2a85164SMiklos Szeredi 		if (alias) {
530d2a85164SMiklos Szeredi 			/* New directory must have moved since mkdir */
531d2a85164SMiklos Szeredi 			mutex_unlock(&fc->inst_mutex);
532d2a85164SMiklos Szeredi 			dput(alias);
5339e6268dbSMiklos Szeredi 			iput(inode);
534d2a85164SMiklos Szeredi 			return -EBUSY;
5359e6268dbSMiklos Szeredi 		}
5369e6268dbSMiklos Szeredi 		d_instantiate(entry, inode);
537d2a85164SMiklos Szeredi 		mutex_unlock(&fc->inst_mutex);
538d2a85164SMiklos Szeredi 	} else
539d2a85164SMiklos Szeredi 		d_instantiate(entry, inode);
540d2a85164SMiklos Szeredi 
5411fb69e78SMiklos Szeredi 	fuse_change_entry_timeout(entry, &outarg);
5429e6268dbSMiklos Szeredi 	fuse_invalidate_attr(dir);
5439e6268dbSMiklos Szeredi 	return 0;
54439ee059aSMiklos Szeredi 
5452d51013eSMiklos Szeredi  out_put_forget_req:
54607e77dcaSMiklos Szeredi 	kfree(forget);
54739ee059aSMiklos Szeredi 	return err;
5489e6268dbSMiklos Szeredi }
5499e6268dbSMiklos Szeredi 
5509e6268dbSMiklos Szeredi static int fuse_mknod(struct inode *dir, struct dentry *entry, int mode,
5519e6268dbSMiklos Szeredi 		      dev_t rdev)
5529e6268dbSMiklos Szeredi {
5539e6268dbSMiklos Szeredi 	struct fuse_mknod_in inarg;
5549e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
555ce1d5a49SMiklos Szeredi 	struct fuse_req *req = fuse_get_req(fc);
556ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
557ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
5589e6268dbSMiklos Szeredi 
559e0a43ddcSMiklos Szeredi 	if (!fc->dont_mask)
560e0a43ddcSMiklos Szeredi 		mode &= ~current_umask();
561e0a43ddcSMiklos Szeredi 
5629e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
5639e6268dbSMiklos Szeredi 	inarg.mode = mode;
5649e6268dbSMiklos Szeredi 	inarg.rdev = new_encode_dev(rdev);
565e0a43ddcSMiklos Szeredi 	inarg.umask = current_umask();
5669e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_MKNOD;
5679e6268dbSMiklos Szeredi 	req->in.numargs = 2;
568e0a43ddcSMiklos Szeredi 	req->in.args[0].size = fc->minor < 12 ? FUSE_COMPAT_MKNOD_IN_SIZE :
569e0a43ddcSMiklos Szeredi 						sizeof(inarg);
5709e6268dbSMiklos Szeredi 	req->in.args[0].value = &inarg;
5719e6268dbSMiklos Szeredi 	req->in.args[1].size = entry->d_name.len + 1;
5729e6268dbSMiklos Szeredi 	req->in.args[1].value = entry->d_name.name;
5739e6268dbSMiklos Szeredi 	return create_new_entry(fc, req, dir, entry, mode);
5749e6268dbSMiklos Szeredi }
5759e6268dbSMiklos Szeredi 
5769e6268dbSMiklos Szeredi static int fuse_create(struct inode *dir, struct dentry *entry, int mode,
5779e6268dbSMiklos Szeredi 		       struct nameidata *nd)
5789e6268dbSMiklos Szeredi {
579b9ba347fSMiklos Szeredi 	if (nd && (nd->flags & LOOKUP_OPEN)) {
580fd72faacSMiklos Szeredi 		int err = fuse_create_open(dir, entry, mode, nd);
581fd72faacSMiklos Szeredi 		if (err != -ENOSYS)
582fd72faacSMiklos Szeredi 			return err;
583fd72faacSMiklos Szeredi 		/* Fall back on mknod */
584fd72faacSMiklos Szeredi 	}
5859e6268dbSMiklos Szeredi 	return fuse_mknod(dir, entry, mode, 0);
5869e6268dbSMiklos Szeredi }
5879e6268dbSMiklos Szeredi 
5889e6268dbSMiklos Szeredi static int fuse_mkdir(struct inode *dir, struct dentry *entry, int mode)
5899e6268dbSMiklos Szeredi {
5909e6268dbSMiklos Szeredi 	struct fuse_mkdir_in inarg;
5919e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
592ce1d5a49SMiklos Szeredi 	struct fuse_req *req = fuse_get_req(fc);
593ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
594ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
5959e6268dbSMiklos Szeredi 
596e0a43ddcSMiklos Szeredi 	if (!fc->dont_mask)
597e0a43ddcSMiklos Szeredi 		mode &= ~current_umask();
598e0a43ddcSMiklos Szeredi 
5999e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
6009e6268dbSMiklos Szeredi 	inarg.mode = mode;
601e0a43ddcSMiklos Szeredi 	inarg.umask = current_umask();
6029e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_MKDIR;
6039e6268dbSMiklos Szeredi 	req->in.numargs = 2;
6049e6268dbSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
6059e6268dbSMiklos Szeredi 	req->in.args[0].value = &inarg;
6069e6268dbSMiklos Szeredi 	req->in.args[1].size = entry->d_name.len + 1;
6079e6268dbSMiklos Szeredi 	req->in.args[1].value = entry->d_name.name;
6089e6268dbSMiklos Szeredi 	return create_new_entry(fc, req, dir, entry, S_IFDIR);
6099e6268dbSMiklos Szeredi }
6109e6268dbSMiklos Szeredi 
6119e6268dbSMiklos Szeredi static int fuse_symlink(struct inode *dir, struct dentry *entry,
6129e6268dbSMiklos Szeredi 			const char *link)
6139e6268dbSMiklos Szeredi {
6149e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
6159e6268dbSMiklos Szeredi 	unsigned len = strlen(link) + 1;
616ce1d5a49SMiklos Szeredi 	struct fuse_req *req = fuse_get_req(fc);
617ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
618ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
6199e6268dbSMiklos Szeredi 
6209e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_SYMLINK;
6219e6268dbSMiklos Szeredi 	req->in.numargs = 2;
6229e6268dbSMiklos Szeredi 	req->in.args[0].size = entry->d_name.len + 1;
6239e6268dbSMiklos Szeredi 	req->in.args[0].value = entry->d_name.name;
6249e6268dbSMiklos Szeredi 	req->in.args[1].size = len;
6259e6268dbSMiklos Szeredi 	req->in.args[1].value = link;
6269e6268dbSMiklos Szeredi 	return create_new_entry(fc, req, dir, entry, S_IFLNK);
6279e6268dbSMiklos Szeredi }
6289e6268dbSMiklos Szeredi 
6299e6268dbSMiklos Szeredi static int fuse_unlink(struct inode *dir, struct dentry *entry)
6309e6268dbSMiklos Szeredi {
6319e6268dbSMiklos Szeredi 	int err;
6329e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
633ce1d5a49SMiklos Szeredi 	struct fuse_req *req = fuse_get_req(fc);
634ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
635ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
6369e6268dbSMiklos Szeredi 
6379e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_UNLINK;
6389e6268dbSMiklos Szeredi 	req->in.h.nodeid = get_node_id(dir);
6399e6268dbSMiklos Szeredi 	req->in.numargs = 1;
6409e6268dbSMiklos Szeredi 	req->in.args[0].size = entry->d_name.len + 1;
6419e6268dbSMiklos Szeredi 	req->in.args[0].value = entry->d_name.name;
642b93f858aSTejun Heo 	fuse_request_send(fc, req);
6439e6268dbSMiklos Szeredi 	err = req->out.h.error;
6449e6268dbSMiklos Szeredi 	fuse_put_request(fc, req);
6459e6268dbSMiklos Szeredi 	if (!err) {
6469e6268dbSMiklos Szeredi 		struct inode *inode = entry->d_inode;
6479e6268dbSMiklos Szeredi 
6481729a16cSMiklos Szeredi 		/*
6491729a16cSMiklos Szeredi 		 * Set nlink to zero so the inode can be cleared, if the inode
6501729a16cSMiklos Szeredi 		 * does have more links this will be discovered at the next
6511729a16cSMiklos Szeredi 		 * lookup/getattr.
6521729a16cSMiklos Szeredi 		 */
653ce71ec36SDave Hansen 		clear_nlink(inode);
6549e6268dbSMiklos Szeredi 		fuse_invalidate_attr(inode);
6559e6268dbSMiklos Szeredi 		fuse_invalidate_attr(dir);
6568cbdf1e6SMiklos Szeredi 		fuse_invalidate_entry_cache(entry);
6579e6268dbSMiklos Szeredi 	} else if (err == -EINTR)
6589e6268dbSMiklos Szeredi 		fuse_invalidate_entry(entry);
6599e6268dbSMiklos Szeredi 	return err;
6609e6268dbSMiklos Szeredi }
6619e6268dbSMiklos Szeredi 
6629e6268dbSMiklos Szeredi static int fuse_rmdir(struct inode *dir, struct dentry *entry)
6639e6268dbSMiklos Szeredi {
6649e6268dbSMiklos Szeredi 	int err;
6659e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
666ce1d5a49SMiklos Szeredi 	struct fuse_req *req = fuse_get_req(fc);
667ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
668ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
6699e6268dbSMiklos Szeredi 
6709e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_RMDIR;
6719e6268dbSMiklos Szeredi 	req->in.h.nodeid = get_node_id(dir);
6729e6268dbSMiklos Szeredi 	req->in.numargs = 1;
6739e6268dbSMiklos Szeredi 	req->in.args[0].size = entry->d_name.len + 1;
6749e6268dbSMiklos Szeredi 	req->in.args[0].value = entry->d_name.name;
675b93f858aSTejun Heo 	fuse_request_send(fc, req);
6769e6268dbSMiklos Szeredi 	err = req->out.h.error;
6779e6268dbSMiklos Szeredi 	fuse_put_request(fc, req);
6789e6268dbSMiklos Szeredi 	if (!err) {
679ce71ec36SDave Hansen 		clear_nlink(entry->d_inode);
6809e6268dbSMiklos Szeredi 		fuse_invalidate_attr(dir);
6818cbdf1e6SMiklos Szeredi 		fuse_invalidate_entry_cache(entry);
6829e6268dbSMiklos Szeredi 	} else if (err == -EINTR)
6839e6268dbSMiklos Szeredi 		fuse_invalidate_entry(entry);
6849e6268dbSMiklos Szeredi 	return err;
6859e6268dbSMiklos Szeredi }
6869e6268dbSMiklos Szeredi 
6879e6268dbSMiklos Szeredi static int fuse_rename(struct inode *olddir, struct dentry *oldent,
6889e6268dbSMiklos Szeredi 		       struct inode *newdir, struct dentry *newent)
6899e6268dbSMiklos Szeredi {
6909e6268dbSMiklos Szeredi 	int err;
6919e6268dbSMiklos Szeredi 	struct fuse_rename_in inarg;
6929e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(olddir);
693ce1d5a49SMiklos Szeredi 	struct fuse_req *req = fuse_get_req(fc);
694ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
695ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
6969e6268dbSMiklos Szeredi 
6979e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
6989e6268dbSMiklos Szeredi 	inarg.newdir = get_node_id(newdir);
6999e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_RENAME;
7009e6268dbSMiklos Szeredi 	req->in.h.nodeid = get_node_id(olddir);
7019e6268dbSMiklos Szeredi 	req->in.numargs = 3;
7029e6268dbSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
7039e6268dbSMiklos Szeredi 	req->in.args[0].value = &inarg;
7049e6268dbSMiklos Szeredi 	req->in.args[1].size = oldent->d_name.len + 1;
7059e6268dbSMiklos Szeredi 	req->in.args[1].value = oldent->d_name.name;
7069e6268dbSMiklos Szeredi 	req->in.args[2].size = newent->d_name.len + 1;
7079e6268dbSMiklos Szeredi 	req->in.args[2].value = newent->d_name.name;
708b93f858aSTejun Heo 	fuse_request_send(fc, req);
7099e6268dbSMiklos Szeredi 	err = req->out.h.error;
7109e6268dbSMiklos Szeredi 	fuse_put_request(fc, req);
7119e6268dbSMiklos Szeredi 	if (!err) {
71208b63307SMiklos Szeredi 		/* ctime changes */
71308b63307SMiklos Szeredi 		fuse_invalidate_attr(oldent->d_inode);
71408b63307SMiklos Szeredi 
7159e6268dbSMiklos Szeredi 		fuse_invalidate_attr(olddir);
7169e6268dbSMiklos Szeredi 		if (olddir != newdir)
7179e6268dbSMiklos Szeredi 			fuse_invalidate_attr(newdir);
7188cbdf1e6SMiklos Szeredi 
7198cbdf1e6SMiklos Szeredi 		/* newent will end up negative */
7205219f346SMiklos Szeredi 		if (newent->d_inode) {
7215219f346SMiklos Szeredi 			fuse_invalidate_attr(newent->d_inode);
7228cbdf1e6SMiklos Szeredi 			fuse_invalidate_entry_cache(newent);
7235219f346SMiklos Szeredi 		}
7249e6268dbSMiklos Szeredi 	} else if (err == -EINTR) {
7259e6268dbSMiklos Szeredi 		/* If request was interrupted, DEITY only knows if the
7269e6268dbSMiklos Szeredi 		   rename actually took place.  If the invalidation
7279e6268dbSMiklos Szeredi 		   fails (e.g. some process has CWD under the renamed
7289e6268dbSMiklos Szeredi 		   directory), then there can be inconsistency between
7299e6268dbSMiklos Szeredi 		   the dcache and the real filesystem.  Tough luck. */
7309e6268dbSMiklos Szeredi 		fuse_invalidate_entry(oldent);
7319e6268dbSMiklos Szeredi 		if (newent->d_inode)
7329e6268dbSMiklos Szeredi 			fuse_invalidate_entry(newent);
7339e6268dbSMiklos Szeredi 	}
7349e6268dbSMiklos Szeredi 
7359e6268dbSMiklos Szeredi 	return err;
7369e6268dbSMiklos Szeredi }
7379e6268dbSMiklos Szeredi 
7389e6268dbSMiklos Szeredi static int fuse_link(struct dentry *entry, struct inode *newdir,
7399e6268dbSMiklos Szeredi 		     struct dentry *newent)
7409e6268dbSMiklos Szeredi {
7419e6268dbSMiklos Szeredi 	int err;
7429e6268dbSMiklos Szeredi 	struct fuse_link_in inarg;
7439e6268dbSMiklos Szeredi 	struct inode *inode = entry->d_inode;
7449e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
745ce1d5a49SMiklos Szeredi 	struct fuse_req *req = fuse_get_req(fc);
746ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
747ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
7489e6268dbSMiklos Szeredi 
7499e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
7509e6268dbSMiklos Szeredi 	inarg.oldnodeid = get_node_id(inode);
7519e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_LINK;
7529e6268dbSMiklos Szeredi 	req->in.numargs = 2;
7539e6268dbSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
7549e6268dbSMiklos Szeredi 	req->in.args[0].value = &inarg;
7559e6268dbSMiklos Szeredi 	req->in.args[1].size = newent->d_name.len + 1;
7569e6268dbSMiklos Szeredi 	req->in.args[1].value = newent->d_name.name;
7579e6268dbSMiklos Szeredi 	err = create_new_entry(fc, req, newdir, newent, inode->i_mode);
7589e6268dbSMiklos Szeredi 	/* Contrary to "normal" filesystems it can happen that link
7599e6268dbSMiklos Szeredi 	   makes two "logical" inodes point to the same "physical"
7609e6268dbSMiklos Szeredi 	   inode.  We invalidate the attributes of the old one, so it
7619e6268dbSMiklos Szeredi 	   will reflect changes in the backing inode (link count,
7629e6268dbSMiklos Szeredi 	   etc.)
7639e6268dbSMiklos Szeredi 	*/
7649e6268dbSMiklos Szeredi 	if (!err || err == -EINTR)
7659e6268dbSMiklos Szeredi 		fuse_invalidate_attr(inode);
7669e6268dbSMiklos Szeredi 	return err;
7679e6268dbSMiklos Szeredi }
7689e6268dbSMiklos Szeredi 
7691fb69e78SMiklos Szeredi static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
7701fb69e78SMiklos Szeredi 			  struct kstat *stat)
7711fb69e78SMiklos Szeredi {
7721fb69e78SMiklos Szeredi 	stat->dev = inode->i_sb->s_dev;
7731fb69e78SMiklos Szeredi 	stat->ino = attr->ino;
7741fb69e78SMiklos Szeredi 	stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
7751fb69e78SMiklos Szeredi 	stat->nlink = attr->nlink;
7761fb69e78SMiklos Szeredi 	stat->uid = attr->uid;
7771fb69e78SMiklos Szeredi 	stat->gid = attr->gid;
7781fb69e78SMiklos Szeredi 	stat->rdev = inode->i_rdev;
7791fb69e78SMiklos Szeredi 	stat->atime.tv_sec = attr->atime;
7801fb69e78SMiklos Szeredi 	stat->atime.tv_nsec = attr->atimensec;
7811fb69e78SMiklos Szeredi 	stat->mtime.tv_sec = attr->mtime;
7821fb69e78SMiklos Szeredi 	stat->mtime.tv_nsec = attr->mtimensec;
7831fb69e78SMiklos Szeredi 	stat->ctime.tv_sec = attr->ctime;
7841fb69e78SMiklos Szeredi 	stat->ctime.tv_nsec = attr->ctimensec;
7851fb69e78SMiklos Szeredi 	stat->size = attr->size;
7861fb69e78SMiklos Szeredi 	stat->blocks = attr->blocks;
7871fb69e78SMiklos Szeredi 	stat->blksize = (1 << inode->i_blkbits);
7881fb69e78SMiklos Szeredi }
7891fb69e78SMiklos Szeredi 
790c79e322fSMiklos Szeredi static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
791c79e322fSMiklos Szeredi 			   struct file *file)
792e5e5558eSMiklos Szeredi {
793e5e5558eSMiklos Szeredi 	int err;
794c79e322fSMiklos Szeredi 	struct fuse_getattr_in inarg;
795c79e322fSMiklos Szeredi 	struct fuse_attr_out outarg;
796e5e5558eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
7971fb69e78SMiklos Szeredi 	struct fuse_req *req;
7981fb69e78SMiklos Szeredi 	u64 attr_version;
7991fb69e78SMiklos Szeredi 
8001fb69e78SMiklos Szeredi 	req = fuse_get_req(fc);
801ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
802ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
803e5e5558eSMiklos Szeredi 
8047dca9fd3SMiklos Szeredi 	attr_version = fuse_get_attr_version(fc);
8051fb69e78SMiklos Szeredi 
806c79e322fSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
8070e9663eeSMiklos Szeredi 	memset(&outarg, 0, sizeof(outarg));
808c79e322fSMiklos Szeredi 	/* Directories have separate file-handle space */
809c79e322fSMiklos Szeredi 	if (file && S_ISREG(inode->i_mode)) {
810c79e322fSMiklos Szeredi 		struct fuse_file *ff = file->private_data;
811c79e322fSMiklos Szeredi 
812c79e322fSMiklos Szeredi 		inarg.getattr_flags |= FUSE_GETATTR_FH;
813c79e322fSMiklos Szeredi 		inarg.fh = ff->fh;
814c79e322fSMiklos Szeredi 	}
815e5e5558eSMiklos Szeredi 	req->in.h.opcode = FUSE_GETATTR;
816e5e5558eSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
817c79e322fSMiklos Szeredi 	req->in.numargs = 1;
818c79e322fSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
819c79e322fSMiklos Szeredi 	req->in.args[0].value = &inarg;
820e5e5558eSMiklos Szeredi 	req->out.numargs = 1;
8210e9663eeSMiklos Szeredi 	if (fc->minor < 9)
8220e9663eeSMiklos Szeredi 		req->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
8230e9663eeSMiklos Szeredi 	else
824c79e322fSMiklos Szeredi 		req->out.args[0].size = sizeof(outarg);
825c79e322fSMiklos Szeredi 	req->out.args[0].value = &outarg;
826b93f858aSTejun Heo 	fuse_request_send(fc, req);
827e5e5558eSMiklos Szeredi 	err = req->out.h.error;
828e5e5558eSMiklos Szeredi 	fuse_put_request(fc, req);
829e5e5558eSMiklos Szeredi 	if (!err) {
830c79e322fSMiklos Szeredi 		if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
831e5e5558eSMiklos Szeredi 			make_bad_inode(inode);
832e5e5558eSMiklos Szeredi 			err = -EIO;
833e5e5558eSMiklos Szeredi 		} else {
834c79e322fSMiklos Szeredi 			fuse_change_attributes(inode, &outarg.attr,
835c79e322fSMiklos Szeredi 					       attr_timeout(&outarg),
8361fb69e78SMiklos Szeredi 					       attr_version);
8371fb69e78SMiklos Szeredi 			if (stat)
838c79e322fSMiklos Szeredi 				fuse_fillattr(inode, &outarg.attr, stat);
839e5e5558eSMiklos Szeredi 		}
840e5e5558eSMiklos Szeredi 	}
841e5e5558eSMiklos Szeredi 	return err;
842e5e5558eSMiklos Szeredi }
843e5e5558eSMiklos Szeredi 
844bcb4be80SMiklos Szeredi int fuse_update_attributes(struct inode *inode, struct kstat *stat,
845bcb4be80SMiklos Szeredi 			   struct file *file, bool *refreshed)
846bcb4be80SMiklos Szeredi {
847bcb4be80SMiklos Szeredi 	struct fuse_inode *fi = get_fuse_inode(inode);
848bcb4be80SMiklos Szeredi 	int err;
849bcb4be80SMiklos Szeredi 	bool r;
850bcb4be80SMiklos Szeredi 
851bcb4be80SMiklos Szeredi 	if (fi->i_time < get_jiffies_64()) {
852bcb4be80SMiklos Szeredi 		r = true;
853bcb4be80SMiklos Szeredi 		err = fuse_do_getattr(inode, stat, file);
854bcb4be80SMiklos Szeredi 	} else {
855bcb4be80SMiklos Szeredi 		r = false;
856bcb4be80SMiklos Szeredi 		err = 0;
857bcb4be80SMiklos Szeredi 		if (stat) {
858bcb4be80SMiklos Szeredi 			generic_fillattr(inode, stat);
859bcb4be80SMiklos Szeredi 			stat->mode = fi->orig_i_mode;
860bcb4be80SMiklos Szeredi 		}
861bcb4be80SMiklos Szeredi 	}
862bcb4be80SMiklos Szeredi 
863bcb4be80SMiklos Szeredi 	if (refreshed != NULL)
864bcb4be80SMiklos Szeredi 		*refreshed = r;
865bcb4be80SMiklos Szeredi 
866bcb4be80SMiklos Szeredi 	return err;
867bcb4be80SMiklos Szeredi }
868bcb4be80SMiklos Szeredi 
8693b463ae0SJohn Muir int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid,
8703b463ae0SJohn Muir 			     struct qstr *name)
8713b463ae0SJohn Muir {
8723b463ae0SJohn Muir 	int err = -ENOTDIR;
8733b463ae0SJohn Muir 	struct inode *parent;
8743b463ae0SJohn Muir 	struct dentry *dir;
8753b463ae0SJohn Muir 	struct dentry *entry;
8763b463ae0SJohn Muir 
8773b463ae0SJohn Muir 	parent = ilookup5(sb, parent_nodeid, fuse_inode_eq, &parent_nodeid);
8783b463ae0SJohn Muir 	if (!parent)
8793b463ae0SJohn Muir 		return -ENOENT;
8803b463ae0SJohn Muir 
8813b463ae0SJohn Muir 	mutex_lock(&parent->i_mutex);
8823b463ae0SJohn Muir 	if (!S_ISDIR(parent->i_mode))
8833b463ae0SJohn Muir 		goto unlock;
8843b463ae0SJohn Muir 
8853b463ae0SJohn Muir 	err = -ENOENT;
8863b463ae0SJohn Muir 	dir = d_find_alias(parent);
8873b463ae0SJohn Muir 	if (!dir)
8883b463ae0SJohn Muir 		goto unlock;
8893b463ae0SJohn Muir 
8903b463ae0SJohn Muir 	entry = d_lookup(dir, name);
8913b463ae0SJohn Muir 	dput(dir);
8923b463ae0SJohn Muir 	if (!entry)
8933b463ae0SJohn Muir 		goto unlock;
8943b463ae0SJohn Muir 
8953b463ae0SJohn Muir 	fuse_invalidate_attr(parent);
8963b463ae0SJohn Muir 	fuse_invalidate_entry(entry);
8973b463ae0SJohn Muir 	dput(entry);
8983b463ae0SJohn Muir 	err = 0;
8993b463ae0SJohn Muir 
9003b463ae0SJohn Muir  unlock:
9013b463ae0SJohn Muir 	mutex_unlock(&parent->i_mutex);
9023b463ae0SJohn Muir 	iput(parent);
9033b463ae0SJohn Muir 	return err;
9043b463ae0SJohn Muir }
9053b463ae0SJohn Muir 
90687729a55SMiklos Szeredi /*
90787729a55SMiklos Szeredi  * Calling into a user-controlled filesystem gives the filesystem
90887729a55SMiklos Szeredi  * daemon ptrace-like capabilities over the requester process.  This
90987729a55SMiklos Szeredi  * means, that the filesystem daemon is able to record the exact
91087729a55SMiklos Szeredi  * filesystem operations performed, and can also control the behavior
91187729a55SMiklos Szeredi  * of the requester process in otherwise impossible ways.  For example
91287729a55SMiklos Szeredi  * it can delay the operation for arbitrary length of time allowing
91387729a55SMiklos Szeredi  * DoS against the requester.
91487729a55SMiklos Szeredi  *
91587729a55SMiklos Szeredi  * For this reason only those processes can call into the filesystem,
91687729a55SMiklos Szeredi  * for which the owner of the mount has ptrace privilege.  This
91787729a55SMiklos Szeredi  * excludes processes started by other users, suid or sgid processes.
91887729a55SMiklos Szeredi  */
919e57ac683SMiklos Szeredi int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task)
92087729a55SMiklos Szeredi {
921c69e8d9cSDavid Howells 	const struct cred *cred;
922c69e8d9cSDavid Howells 	int ret;
923c69e8d9cSDavid Howells 
92487729a55SMiklos Szeredi 	if (fc->flags & FUSE_ALLOW_OTHER)
92587729a55SMiklos Szeredi 		return 1;
92687729a55SMiklos Szeredi 
927c69e8d9cSDavid Howells 	rcu_read_lock();
928c69e8d9cSDavid Howells 	ret = 0;
929c69e8d9cSDavid Howells 	cred = __task_cred(task);
930c69e8d9cSDavid Howells 	if (cred->euid == fc->user_id &&
931c69e8d9cSDavid Howells 	    cred->suid == fc->user_id &&
932c69e8d9cSDavid Howells 	    cred->uid  == fc->user_id &&
933c69e8d9cSDavid Howells 	    cred->egid == fc->group_id &&
934c69e8d9cSDavid Howells 	    cred->sgid == fc->group_id &&
935c69e8d9cSDavid Howells 	    cred->gid  == fc->group_id)
936c69e8d9cSDavid Howells 		ret = 1;
937c69e8d9cSDavid Howells 	rcu_read_unlock();
93887729a55SMiklos Szeredi 
939c69e8d9cSDavid Howells 	return ret;
94087729a55SMiklos Szeredi }
94187729a55SMiklos Szeredi 
94231d40d74SMiklos Szeredi static int fuse_access(struct inode *inode, int mask)
94331d40d74SMiklos Szeredi {
94431d40d74SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
94531d40d74SMiklos Szeredi 	struct fuse_req *req;
94631d40d74SMiklos Szeredi 	struct fuse_access_in inarg;
94731d40d74SMiklos Szeredi 	int err;
94831d40d74SMiklos Szeredi 
94931d40d74SMiklos Szeredi 	if (fc->no_access)
95031d40d74SMiklos Szeredi 		return 0;
95131d40d74SMiklos Szeredi 
952ce1d5a49SMiklos Szeredi 	req = fuse_get_req(fc);
953ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
954ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
95531d40d74SMiklos Szeredi 
95631d40d74SMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
957e6305c43SAl Viro 	inarg.mask = mask & (MAY_READ | MAY_WRITE | MAY_EXEC);
95831d40d74SMiklos Szeredi 	req->in.h.opcode = FUSE_ACCESS;
95931d40d74SMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
96031d40d74SMiklos Szeredi 	req->in.numargs = 1;
96131d40d74SMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
96231d40d74SMiklos Szeredi 	req->in.args[0].value = &inarg;
963b93f858aSTejun Heo 	fuse_request_send(fc, req);
96431d40d74SMiklos Szeredi 	err = req->out.h.error;
96531d40d74SMiklos Szeredi 	fuse_put_request(fc, req);
96631d40d74SMiklos Szeredi 	if (err == -ENOSYS) {
96731d40d74SMiklos Szeredi 		fc->no_access = 1;
96831d40d74SMiklos Szeredi 		err = 0;
96931d40d74SMiklos Szeredi 	}
97031d40d74SMiklos Szeredi 	return err;
97131d40d74SMiklos Szeredi }
97231d40d74SMiklos Szeredi 
97319690ddbSMiklos Szeredi static int fuse_perm_getattr(struct inode *inode, int flags)
97419690ddbSMiklos Szeredi {
97519690ddbSMiklos Szeredi 	if (flags & IPERM_FLAG_RCU)
97619690ddbSMiklos Szeredi 		return -ECHILD;
97719690ddbSMiklos Szeredi 
97819690ddbSMiklos Szeredi 	return fuse_do_getattr(inode, NULL, NULL);
97919690ddbSMiklos Szeredi }
98019690ddbSMiklos Szeredi 
9816f9f1180SMiklos Szeredi /*
9826f9f1180SMiklos Szeredi  * Check permission.  The two basic access models of FUSE are:
9836f9f1180SMiklos Szeredi  *
9846f9f1180SMiklos Szeredi  * 1) Local access checking ('default_permissions' mount option) based
9856f9f1180SMiklos Szeredi  * on file mode.  This is the plain old disk filesystem permission
9866f9f1180SMiklos Szeredi  * modell.
9876f9f1180SMiklos Szeredi  *
9886f9f1180SMiklos Szeredi  * 2) "Remote" access checking, where server is responsible for
9896f9f1180SMiklos Szeredi  * checking permission in each inode operation.  An exception to this
9906f9f1180SMiklos Szeredi  * is if ->permission() was invoked from sys_access() in which case an
9916f9f1180SMiklos Szeredi  * access request is sent.  Execute permission is still checked
9926f9f1180SMiklos Szeredi  * locally based on file mode.
9936f9f1180SMiklos Szeredi  */
994b74c79e9SNick Piggin static int fuse_permission(struct inode *inode, int mask, unsigned int flags)
995e5e5558eSMiklos Szeredi {
996e5e5558eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
997244f6385SMiklos Szeredi 	bool refreshed = false;
998244f6385SMiklos Szeredi 	int err = 0;
999e5e5558eSMiklos Szeredi 
100087729a55SMiklos Szeredi 	if (!fuse_allow_task(fc, current))
1001e5e5558eSMiklos Szeredi 		return -EACCES;
1002244f6385SMiklos Szeredi 
1003244f6385SMiklos Szeredi 	/*
1004e8e96157SMiklos Szeredi 	 * If attributes are needed, refresh them before proceeding
1005244f6385SMiklos Szeredi 	 */
1006e8e96157SMiklos Szeredi 	if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) ||
1007e8e96157SMiklos Szeredi 	    ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) {
100819690ddbSMiklos Szeredi 		struct fuse_inode *fi = get_fuse_inode(inode);
100919690ddbSMiklos Szeredi 
101019690ddbSMiklos Szeredi 		if (fi->i_time < get_jiffies_64()) {
101119690ddbSMiklos Szeredi 			refreshed = true;
101219690ddbSMiklos Szeredi 
101319690ddbSMiklos Szeredi 			err = fuse_perm_getattr(inode, flags);
1014244f6385SMiklos Szeredi 			if (err)
1015244f6385SMiklos Szeredi 				return err;
10161fb69e78SMiklos Szeredi 		}
101719690ddbSMiklos Szeredi 	}
1018244f6385SMiklos Szeredi 
1019244f6385SMiklos Szeredi 	if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
1020b74c79e9SNick Piggin 		err = generic_permission(inode, mask, flags, NULL);
10211e9a4ed9SMiklos Szeredi 
10221e9a4ed9SMiklos Szeredi 		/* If permission is denied, try to refresh file
10231e9a4ed9SMiklos Szeredi 		   attributes.  This is also needed, because the root
10241e9a4ed9SMiklos Szeredi 		   node will at first have no permissions */
1025244f6385SMiklos Szeredi 		if (err == -EACCES && !refreshed) {
102619690ddbSMiklos Szeredi 			err = fuse_perm_getattr(inode, flags);
10271e9a4ed9SMiklos Szeredi 			if (!err)
1028b74c79e9SNick Piggin 				err = generic_permission(inode, mask,
1029b74c79e9SNick Piggin 							flags, NULL);
10301e9a4ed9SMiklos Szeredi 		}
10311e9a4ed9SMiklos Szeredi 
10326f9f1180SMiklos Szeredi 		/* Note: the opposite of the above test does not
10336f9f1180SMiklos Szeredi 		   exist.  So if permissions are revoked this won't be
10346f9f1180SMiklos Szeredi 		   noticed immediately, only after the attribute
10356f9f1180SMiklos Szeredi 		   timeout has expired */
10369cfcac81SEric Paris 	} else if (mask & (MAY_ACCESS | MAY_CHDIR)) {
103719690ddbSMiklos Szeredi 		if (flags & IPERM_FLAG_RCU)
103819690ddbSMiklos Szeredi 			return -ECHILD;
103919690ddbSMiklos Szeredi 
1040e8e96157SMiklos Szeredi 		err = fuse_access(inode, mask);
1041e8e96157SMiklos Szeredi 	} else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
1042e8e96157SMiklos Szeredi 		if (!(inode->i_mode & S_IXUGO)) {
1043e8e96157SMiklos Szeredi 			if (refreshed)
1044e5e5558eSMiklos Szeredi 				return -EACCES;
104531d40d74SMiklos Szeredi 
104619690ddbSMiklos Szeredi 			err = fuse_perm_getattr(inode, flags);
1047e8e96157SMiklos Szeredi 			if (!err && !(inode->i_mode & S_IXUGO))
1048e8e96157SMiklos Szeredi 				return -EACCES;
1049e8e96157SMiklos Szeredi 		}
1050e5e5558eSMiklos Szeredi 	}
1051244f6385SMiklos Szeredi 	return err;
1052e5e5558eSMiklos Szeredi }
1053e5e5558eSMiklos Szeredi 
1054e5e5558eSMiklos Szeredi static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
1055e5e5558eSMiklos Szeredi 			 void *dstbuf, filldir_t filldir)
1056e5e5558eSMiklos Szeredi {
1057e5e5558eSMiklos Szeredi 	while (nbytes >= FUSE_NAME_OFFSET) {
1058e5e5558eSMiklos Szeredi 		struct fuse_dirent *dirent = (struct fuse_dirent *) buf;
1059e5e5558eSMiklos Szeredi 		size_t reclen = FUSE_DIRENT_SIZE(dirent);
1060e5e5558eSMiklos Szeredi 		int over;
1061e5e5558eSMiklos Szeredi 		if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
1062e5e5558eSMiklos Szeredi 			return -EIO;
1063e5e5558eSMiklos Szeredi 		if (reclen > nbytes)
1064e5e5558eSMiklos Szeredi 			break;
1065e5e5558eSMiklos Szeredi 
1066e5e5558eSMiklos Szeredi 		over = filldir(dstbuf, dirent->name, dirent->namelen,
1067e5e5558eSMiklos Szeredi 			       file->f_pos, dirent->ino, dirent->type);
1068e5e5558eSMiklos Szeredi 		if (over)
1069e5e5558eSMiklos Szeredi 			break;
1070e5e5558eSMiklos Szeredi 
1071e5e5558eSMiklos Szeredi 		buf += reclen;
1072e5e5558eSMiklos Szeredi 		nbytes -= reclen;
1073e5e5558eSMiklos Szeredi 		file->f_pos = dirent->off;
1074e5e5558eSMiklos Szeredi 	}
1075e5e5558eSMiklos Szeredi 
1076e5e5558eSMiklos Szeredi 	return 0;
1077e5e5558eSMiklos Szeredi }
1078e5e5558eSMiklos Szeredi 
1079e5e5558eSMiklos Szeredi static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
1080e5e5558eSMiklos Szeredi {
108104730fefSMiklos Szeredi 	int err;
108204730fefSMiklos Szeredi 	size_t nbytes;
108304730fefSMiklos Szeredi 	struct page *page;
10847706a9d6SJosef Sipek 	struct inode *inode = file->f_path.dentry->d_inode;
108504730fefSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
1086248d86e8SMiklos Szeredi 	struct fuse_req *req;
1087248d86e8SMiklos Szeredi 
1088248d86e8SMiklos Szeredi 	if (is_bad_inode(inode))
1089248d86e8SMiklos Szeredi 		return -EIO;
1090248d86e8SMiklos Szeredi 
1091ce1d5a49SMiklos Szeredi 	req = fuse_get_req(fc);
1092ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1093ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
1094e5e5558eSMiklos Szeredi 
109504730fefSMiklos Szeredi 	page = alloc_page(GFP_KERNEL);
109604730fefSMiklos Szeredi 	if (!page) {
109704730fefSMiklos Szeredi 		fuse_put_request(fc, req);
1098e5e5558eSMiklos Szeredi 		return -ENOMEM;
109904730fefSMiklos Szeredi 	}
1100f4975c67SMiklos Szeredi 	req->out.argpages = 1;
110104730fefSMiklos Szeredi 	req->num_pages = 1;
110204730fefSMiklos Szeredi 	req->pages[0] = page;
11032106cb18SMiklos Szeredi 	fuse_read_fill(req, file, file->f_pos, PAGE_SIZE, FUSE_READDIR);
1104b93f858aSTejun Heo 	fuse_request_send(fc, req);
1105361b1eb5SMiklos Szeredi 	nbytes = req->out.args[0].size;
110604730fefSMiklos Szeredi 	err = req->out.h.error;
110704730fefSMiklos Szeredi 	fuse_put_request(fc, req);
110804730fefSMiklos Szeredi 	if (!err)
110904730fefSMiklos Szeredi 		err = parse_dirfile(page_address(page), nbytes, file, dstbuf,
111004730fefSMiklos Szeredi 				    filldir);
1111e5e5558eSMiklos Szeredi 
111204730fefSMiklos Szeredi 	__free_page(page);
1113b36c31baSMiklos Szeredi 	fuse_invalidate_attr(inode); /* atime changed */
111404730fefSMiklos Szeredi 	return err;
1115e5e5558eSMiklos Szeredi }
1116e5e5558eSMiklos Szeredi 
1117e5e5558eSMiklos Szeredi static char *read_link(struct dentry *dentry)
1118e5e5558eSMiklos Szeredi {
1119e5e5558eSMiklos Szeredi 	struct inode *inode = dentry->d_inode;
1120e5e5558eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
1121ce1d5a49SMiklos Szeredi 	struct fuse_req *req = fuse_get_req(fc);
1122e5e5558eSMiklos Szeredi 	char *link;
1123e5e5558eSMiklos Szeredi 
1124ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1125e231c2eeSDavid Howells 		return ERR_CAST(req);
1126e5e5558eSMiklos Szeredi 
1127e5e5558eSMiklos Szeredi 	link = (char *) __get_free_page(GFP_KERNEL);
1128e5e5558eSMiklos Szeredi 	if (!link) {
1129e5e5558eSMiklos Szeredi 		link = ERR_PTR(-ENOMEM);
1130e5e5558eSMiklos Szeredi 		goto out;
1131e5e5558eSMiklos Szeredi 	}
1132e5e5558eSMiklos Szeredi 	req->in.h.opcode = FUSE_READLINK;
1133e5e5558eSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
1134e5e5558eSMiklos Szeredi 	req->out.argvar = 1;
1135e5e5558eSMiklos Szeredi 	req->out.numargs = 1;
1136e5e5558eSMiklos Szeredi 	req->out.args[0].size = PAGE_SIZE - 1;
1137e5e5558eSMiklos Szeredi 	req->out.args[0].value = link;
1138b93f858aSTejun Heo 	fuse_request_send(fc, req);
1139e5e5558eSMiklos Szeredi 	if (req->out.h.error) {
1140e5e5558eSMiklos Szeredi 		free_page((unsigned long) link);
1141e5e5558eSMiklos Szeredi 		link = ERR_PTR(req->out.h.error);
1142e5e5558eSMiklos Szeredi 	} else
1143e5e5558eSMiklos Szeredi 		link[req->out.args[0].size] = '\0';
1144e5e5558eSMiklos Szeredi  out:
1145e5e5558eSMiklos Szeredi 	fuse_put_request(fc, req);
1146b36c31baSMiklos Szeredi 	fuse_invalidate_attr(inode); /* atime changed */
1147e5e5558eSMiklos Szeredi 	return link;
1148e5e5558eSMiklos Szeredi }
1149e5e5558eSMiklos Szeredi 
1150e5e5558eSMiklos Szeredi static void free_link(char *link)
1151e5e5558eSMiklos Szeredi {
1152e5e5558eSMiklos Szeredi 	if (!IS_ERR(link))
1153e5e5558eSMiklos Szeredi 		free_page((unsigned long) link);
1154e5e5558eSMiklos Szeredi }
1155e5e5558eSMiklos Szeredi 
1156e5e5558eSMiklos Szeredi static void *fuse_follow_link(struct dentry *dentry, struct nameidata *nd)
1157e5e5558eSMiklos Szeredi {
1158e5e5558eSMiklos Szeredi 	nd_set_link(nd, read_link(dentry));
1159e5e5558eSMiklos Szeredi 	return NULL;
1160e5e5558eSMiklos Szeredi }
1161e5e5558eSMiklos Szeredi 
1162e5e5558eSMiklos Szeredi static void fuse_put_link(struct dentry *dentry, struct nameidata *nd, void *c)
1163e5e5558eSMiklos Szeredi {
1164e5e5558eSMiklos Szeredi 	free_link(nd_get_link(nd));
1165e5e5558eSMiklos Szeredi }
1166e5e5558eSMiklos Szeredi 
1167e5e5558eSMiklos Szeredi static int fuse_dir_open(struct inode *inode, struct file *file)
1168e5e5558eSMiklos Szeredi {
116991fe96b4SMiklos Szeredi 	return fuse_open_common(inode, file, true);
1170e5e5558eSMiklos Szeredi }
1171e5e5558eSMiklos Szeredi 
1172e5e5558eSMiklos Szeredi static int fuse_dir_release(struct inode *inode, struct file *file)
1173e5e5558eSMiklos Szeredi {
11748b0797a4SMiklos Szeredi 	fuse_release_common(file, FUSE_RELEASEDIR);
11758b0797a4SMiklos Szeredi 
11768b0797a4SMiklos Szeredi 	return 0;
1177e5e5558eSMiklos Szeredi }
1178e5e5558eSMiklos Szeredi 
11797ea80859SChristoph Hellwig static int fuse_dir_fsync(struct file *file, int datasync)
118082547981SMiklos Szeredi {
11817ea80859SChristoph Hellwig 	return fuse_fsync_common(file, datasync, 1);
118282547981SMiklos Szeredi }
118382547981SMiklos Szeredi 
118417637cbaSMiklos Szeredi static bool update_mtime(unsigned ivalid)
118517637cbaSMiklos Szeredi {
118617637cbaSMiklos Szeredi 	/* Always update if mtime is explicitly set  */
118717637cbaSMiklos Szeredi 	if (ivalid & ATTR_MTIME_SET)
118817637cbaSMiklos Szeredi 		return true;
118917637cbaSMiklos Szeredi 
119017637cbaSMiklos Szeredi 	/* If it's an open(O_TRUNC) or an ftruncate(), don't update */
119117637cbaSMiklos Szeredi 	if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE)))
119217637cbaSMiklos Szeredi 		return false;
119317637cbaSMiklos Szeredi 
119417637cbaSMiklos Szeredi 	/* In all other cases update */
119517637cbaSMiklos Szeredi 	return true;
119617637cbaSMiklos Szeredi }
119717637cbaSMiklos Szeredi 
1198befc649cSMiklos Szeredi static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
11999e6268dbSMiklos Szeredi {
12009e6268dbSMiklos Szeredi 	unsigned ivalid = iattr->ia_valid;
12019e6268dbSMiklos Szeredi 
12029e6268dbSMiklos Szeredi 	if (ivalid & ATTR_MODE)
1203befc649cSMiklos Szeredi 		arg->valid |= FATTR_MODE,   arg->mode = iattr->ia_mode;
12049e6268dbSMiklos Szeredi 	if (ivalid & ATTR_UID)
1205befc649cSMiklos Szeredi 		arg->valid |= FATTR_UID,    arg->uid = iattr->ia_uid;
12069e6268dbSMiklos Szeredi 	if (ivalid & ATTR_GID)
1207befc649cSMiklos Szeredi 		arg->valid |= FATTR_GID,    arg->gid = iattr->ia_gid;
12089e6268dbSMiklos Szeredi 	if (ivalid & ATTR_SIZE)
1209befc649cSMiklos Szeredi 		arg->valid |= FATTR_SIZE,   arg->size = iattr->ia_size;
121017637cbaSMiklos Szeredi 	if (ivalid & ATTR_ATIME) {
121117637cbaSMiklos Szeredi 		arg->valid |= FATTR_ATIME;
1212befc649cSMiklos Szeredi 		arg->atime = iattr->ia_atime.tv_sec;
121317637cbaSMiklos Szeredi 		arg->atimensec = iattr->ia_atime.tv_nsec;
121417637cbaSMiklos Szeredi 		if (!(ivalid & ATTR_ATIME_SET))
121517637cbaSMiklos Szeredi 			arg->valid |= FATTR_ATIME_NOW;
121617637cbaSMiklos Szeredi 	}
121717637cbaSMiklos Szeredi 	if ((ivalid & ATTR_MTIME) && update_mtime(ivalid)) {
121817637cbaSMiklos Szeredi 		arg->valid |= FATTR_MTIME;
1219befc649cSMiklos Szeredi 		arg->mtime = iattr->ia_mtime.tv_sec;
122017637cbaSMiklos Szeredi 		arg->mtimensec = iattr->ia_mtime.tv_nsec;
122117637cbaSMiklos Szeredi 		if (!(ivalid & ATTR_MTIME_SET))
122217637cbaSMiklos Szeredi 			arg->valid |= FATTR_MTIME_NOW;
12239e6268dbSMiklos Szeredi 	}
12249e6268dbSMiklos Szeredi }
12259e6268dbSMiklos Szeredi 
12266f9f1180SMiklos Szeredi /*
12273be5a52bSMiklos Szeredi  * Prevent concurrent writepages on inode
12283be5a52bSMiklos Szeredi  *
12293be5a52bSMiklos Szeredi  * This is done by adding a negative bias to the inode write counter
12303be5a52bSMiklos Szeredi  * and waiting for all pending writes to finish.
12313be5a52bSMiklos Szeredi  */
12323be5a52bSMiklos Szeredi void fuse_set_nowrite(struct inode *inode)
12333be5a52bSMiklos Szeredi {
12343be5a52bSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
12353be5a52bSMiklos Szeredi 	struct fuse_inode *fi = get_fuse_inode(inode);
12363be5a52bSMiklos Szeredi 
12373be5a52bSMiklos Szeredi 	BUG_ON(!mutex_is_locked(&inode->i_mutex));
12383be5a52bSMiklos Szeredi 
12393be5a52bSMiklos Szeredi 	spin_lock(&fc->lock);
12403be5a52bSMiklos Szeredi 	BUG_ON(fi->writectr < 0);
12413be5a52bSMiklos Szeredi 	fi->writectr += FUSE_NOWRITE;
12423be5a52bSMiklos Szeredi 	spin_unlock(&fc->lock);
12433be5a52bSMiklos Szeredi 	wait_event(fi->page_waitq, fi->writectr == FUSE_NOWRITE);
12443be5a52bSMiklos Szeredi }
12453be5a52bSMiklos Szeredi 
12463be5a52bSMiklos Szeredi /*
12473be5a52bSMiklos Szeredi  * Allow writepages on inode
12483be5a52bSMiklos Szeredi  *
12493be5a52bSMiklos Szeredi  * Remove the bias from the writecounter and send any queued
12503be5a52bSMiklos Szeredi  * writepages.
12513be5a52bSMiklos Szeredi  */
12523be5a52bSMiklos Szeredi static void __fuse_release_nowrite(struct inode *inode)
12533be5a52bSMiklos Szeredi {
12543be5a52bSMiklos Szeredi 	struct fuse_inode *fi = get_fuse_inode(inode);
12553be5a52bSMiklos Szeredi 
12563be5a52bSMiklos Szeredi 	BUG_ON(fi->writectr != FUSE_NOWRITE);
12573be5a52bSMiklos Szeredi 	fi->writectr = 0;
12583be5a52bSMiklos Szeredi 	fuse_flush_writepages(inode);
12593be5a52bSMiklos Szeredi }
12603be5a52bSMiklos Szeredi 
12613be5a52bSMiklos Szeredi void fuse_release_nowrite(struct inode *inode)
12623be5a52bSMiklos Szeredi {
12633be5a52bSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
12643be5a52bSMiklos Szeredi 
12653be5a52bSMiklos Szeredi 	spin_lock(&fc->lock);
12663be5a52bSMiklos Szeredi 	__fuse_release_nowrite(inode);
12673be5a52bSMiklos Szeredi 	spin_unlock(&fc->lock);
12683be5a52bSMiklos Szeredi }
12693be5a52bSMiklos Szeredi 
12703be5a52bSMiklos Szeredi /*
12716f9f1180SMiklos Szeredi  * Set attributes, and at the same time refresh them.
12726f9f1180SMiklos Szeredi  *
12736f9f1180SMiklos Szeredi  * Truncation is slightly complicated, because the 'truncate' request
12746f9f1180SMiklos Szeredi  * may fail, in which case we don't want to touch the mapping.
12759ffbb916SMiklos Szeredi  * vmtruncate() doesn't allow for this case, so do the rlimit checking
12769ffbb916SMiklos Szeredi  * and the actual truncation by hand.
12776f9f1180SMiklos Szeredi  */
127849d4914fSMiklos Szeredi static int fuse_do_setattr(struct dentry *entry, struct iattr *attr,
127949d4914fSMiklos Szeredi 			   struct file *file)
12809e6268dbSMiklos Szeredi {
12819e6268dbSMiklos Szeredi 	struct inode *inode = entry->d_inode;
12829e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
12839e6268dbSMiklos Szeredi 	struct fuse_req *req;
12849e6268dbSMiklos Szeredi 	struct fuse_setattr_in inarg;
12859e6268dbSMiklos Szeredi 	struct fuse_attr_out outarg;
12863be5a52bSMiklos Szeredi 	bool is_truncate = false;
12873be5a52bSMiklos Szeredi 	loff_t oldsize;
12889e6268dbSMiklos Szeredi 	int err;
12899e6268dbSMiklos Szeredi 
1290e57ac683SMiklos Szeredi 	if (!fuse_allow_task(fc, current))
1291e57ac683SMiklos Szeredi 		return -EACCES;
1292e57ac683SMiklos Szeredi 
1293db78b877SChristoph Hellwig 	if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS))
1294db78b877SChristoph Hellwig 		attr->ia_valid |= ATTR_FORCE;
1295db78b877SChristoph Hellwig 
12961e9a4ed9SMiklos Szeredi 	err = inode_change_ok(inode, attr);
12971e9a4ed9SMiklos Szeredi 	if (err)
12981e9a4ed9SMiklos Szeredi 		return err;
12991e9a4ed9SMiklos Szeredi 
13008d56adddSMiklos Szeredi 	if (attr->ia_valid & ATTR_OPEN) {
13018d56adddSMiklos Szeredi 		if (fc->atomic_o_trunc)
13026ff958edSMiklos Szeredi 			return 0;
13038d56adddSMiklos Szeredi 		file = NULL;
13048d56adddSMiklos Szeredi 	}
13056ff958edSMiklos Szeredi 
13062c27c65eSChristoph Hellwig 	if (attr->ia_valid & ATTR_SIZE)
13073be5a52bSMiklos Szeredi 		is_truncate = true;
13089e6268dbSMiklos Szeredi 
1309ce1d5a49SMiklos Szeredi 	req = fuse_get_req(fc);
1310ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1311ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
13129e6268dbSMiklos Szeredi 
13133be5a52bSMiklos Szeredi 	if (is_truncate)
13143be5a52bSMiklos Szeredi 		fuse_set_nowrite(inode);
13153be5a52bSMiklos Szeredi 
13169e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
13170e9663eeSMiklos Szeredi 	memset(&outarg, 0, sizeof(outarg));
1318befc649cSMiklos Szeredi 	iattr_to_fattr(attr, &inarg);
131949d4914fSMiklos Szeredi 	if (file) {
132049d4914fSMiklos Szeredi 		struct fuse_file *ff = file->private_data;
132149d4914fSMiklos Szeredi 		inarg.valid |= FATTR_FH;
132249d4914fSMiklos Szeredi 		inarg.fh = ff->fh;
132349d4914fSMiklos Szeredi 	}
1324f3332114SMiklos Szeredi 	if (attr->ia_valid & ATTR_SIZE) {
1325f3332114SMiklos Szeredi 		/* For mandatory locking in truncate */
1326f3332114SMiklos Szeredi 		inarg.valid |= FATTR_LOCKOWNER;
1327f3332114SMiklos Szeredi 		inarg.lock_owner = fuse_lock_owner_id(fc, current->files);
1328f3332114SMiklos Szeredi 	}
13299e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_SETATTR;
13309e6268dbSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
13319e6268dbSMiklos Szeredi 	req->in.numargs = 1;
13329e6268dbSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
13339e6268dbSMiklos Szeredi 	req->in.args[0].value = &inarg;
13349e6268dbSMiklos Szeredi 	req->out.numargs = 1;
13350e9663eeSMiklos Szeredi 	if (fc->minor < 9)
13360e9663eeSMiklos Szeredi 		req->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
13370e9663eeSMiklos Szeredi 	else
13389e6268dbSMiklos Szeredi 		req->out.args[0].size = sizeof(outarg);
13399e6268dbSMiklos Szeredi 	req->out.args[0].value = &outarg;
1340b93f858aSTejun Heo 	fuse_request_send(fc, req);
13419e6268dbSMiklos Szeredi 	err = req->out.h.error;
13429e6268dbSMiklos Szeredi 	fuse_put_request(fc, req);
1343e00d2c2dSMiklos Szeredi 	if (err) {
1344e00d2c2dSMiklos Szeredi 		if (err == -EINTR)
1345e00d2c2dSMiklos Szeredi 			fuse_invalidate_attr(inode);
13463be5a52bSMiklos Szeredi 		goto error;
1347e00d2c2dSMiklos Szeredi 	}
1348e00d2c2dSMiklos Szeredi 
13499e6268dbSMiklos Szeredi 	if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
13509e6268dbSMiklos Szeredi 		make_bad_inode(inode);
13513be5a52bSMiklos Szeredi 		err = -EIO;
13523be5a52bSMiklos Szeredi 		goto error;
13539e6268dbSMiklos Szeredi 	}
13549e6268dbSMiklos Szeredi 
13553be5a52bSMiklos Szeredi 	spin_lock(&fc->lock);
13563be5a52bSMiklos Szeredi 	fuse_change_attributes_common(inode, &outarg.attr,
13573be5a52bSMiklos Szeredi 				      attr_timeout(&outarg));
13583be5a52bSMiklos Szeredi 	oldsize = inode->i_size;
13593be5a52bSMiklos Szeredi 	i_size_write(inode, outarg.attr.size);
13603be5a52bSMiklos Szeredi 
13613be5a52bSMiklos Szeredi 	if (is_truncate) {
13623be5a52bSMiklos Szeredi 		/* NOTE: this may release/reacquire fc->lock */
13633be5a52bSMiklos Szeredi 		__fuse_release_nowrite(inode);
13643be5a52bSMiklos Szeredi 	}
13653be5a52bSMiklos Szeredi 	spin_unlock(&fc->lock);
13663be5a52bSMiklos Szeredi 
13673be5a52bSMiklos Szeredi 	/*
13683be5a52bSMiklos Szeredi 	 * Only call invalidate_inode_pages2() after removing
13693be5a52bSMiklos Szeredi 	 * FUSE_NOWRITE, otherwise fuse_launder_page() would deadlock.
13703be5a52bSMiklos Szeredi 	 */
13713be5a52bSMiklos Szeredi 	if (S_ISREG(inode->i_mode) && oldsize != outarg.attr.size) {
1372c08d3b0eSnpiggin@suse.de 		truncate_pagecache(inode, oldsize, outarg.attr.size);
13733be5a52bSMiklos Szeredi 		invalidate_inode_pages2(inode->i_mapping);
13743be5a52bSMiklos Szeredi 	}
13753be5a52bSMiklos Szeredi 
1376e00d2c2dSMiklos Szeredi 	return 0;
13773be5a52bSMiklos Szeredi 
13783be5a52bSMiklos Szeredi error:
13793be5a52bSMiklos Szeredi 	if (is_truncate)
13803be5a52bSMiklos Szeredi 		fuse_release_nowrite(inode);
13813be5a52bSMiklos Szeredi 
13823be5a52bSMiklos Szeredi 	return err;
13839e6268dbSMiklos Szeredi }
13849e6268dbSMiklos Szeredi 
138549d4914fSMiklos Szeredi static int fuse_setattr(struct dentry *entry, struct iattr *attr)
138649d4914fSMiklos Szeredi {
138749d4914fSMiklos Szeredi 	if (attr->ia_valid & ATTR_FILE)
138849d4914fSMiklos Szeredi 		return fuse_do_setattr(entry, attr, attr->ia_file);
138949d4914fSMiklos Szeredi 	else
139049d4914fSMiklos Szeredi 		return fuse_do_setattr(entry, attr, NULL);
139149d4914fSMiklos Szeredi }
139249d4914fSMiklos Szeredi 
1393e5e5558eSMiklos Szeredi static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
1394e5e5558eSMiklos Szeredi 			struct kstat *stat)
1395e5e5558eSMiklos Szeredi {
1396e5e5558eSMiklos Szeredi 	struct inode *inode = entry->d_inode;
1397244f6385SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
1398244f6385SMiklos Szeredi 
1399244f6385SMiklos Szeredi 	if (!fuse_allow_task(fc, current))
1400244f6385SMiklos Szeredi 		return -EACCES;
1401244f6385SMiklos Szeredi 
1402bcb4be80SMiklos Szeredi 	return fuse_update_attributes(inode, stat, NULL, NULL);
1403e5e5558eSMiklos Szeredi }
1404e5e5558eSMiklos Szeredi 
140592a8780eSMiklos Szeredi static int fuse_setxattr(struct dentry *entry, const char *name,
140692a8780eSMiklos Szeredi 			 const void *value, size_t size, int flags)
140792a8780eSMiklos Szeredi {
140892a8780eSMiklos Szeredi 	struct inode *inode = entry->d_inode;
140992a8780eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
141092a8780eSMiklos Szeredi 	struct fuse_req *req;
141192a8780eSMiklos Szeredi 	struct fuse_setxattr_in inarg;
141292a8780eSMiklos Szeredi 	int err;
141392a8780eSMiklos Szeredi 
141492a8780eSMiklos Szeredi 	if (fc->no_setxattr)
141592a8780eSMiklos Szeredi 		return -EOPNOTSUPP;
141692a8780eSMiklos Szeredi 
1417ce1d5a49SMiklos Szeredi 	req = fuse_get_req(fc);
1418ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1419ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
142092a8780eSMiklos Szeredi 
142192a8780eSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
142292a8780eSMiklos Szeredi 	inarg.size = size;
142392a8780eSMiklos Szeredi 	inarg.flags = flags;
142492a8780eSMiklos Szeredi 	req->in.h.opcode = FUSE_SETXATTR;
142592a8780eSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
142692a8780eSMiklos Szeredi 	req->in.numargs = 3;
142792a8780eSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
142892a8780eSMiklos Szeredi 	req->in.args[0].value = &inarg;
142992a8780eSMiklos Szeredi 	req->in.args[1].size = strlen(name) + 1;
143092a8780eSMiklos Szeredi 	req->in.args[1].value = name;
143192a8780eSMiklos Szeredi 	req->in.args[2].size = size;
143292a8780eSMiklos Szeredi 	req->in.args[2].value = value;
1433b93f858aSTejun Heo 	fuse_request_send(fc, req);
143492a8780eSMiklos Szeredi 	err = req->out.h.error;
143592a8780eSMiklos Szeredi 	fuse_put_request(fc, req);
143692a8780eSMiklos Szeredi 	if (err == -ENOSYS) {
143792a8780eSMiklos Szeredi 		fc->no_setxattr = 1;
143892a8780eSMiklos Szeredi 		err = -EOPNOTSUPP;
143992a8780eSMiklos Szeredi 	}
144092a8780eSMiklos Szeredi 	return err;
144192a8780eSMiklos Szeredi }
144292a8780eSMiklos Szeredi 
144392a8780eSMiklos Szeredi static ssize_t fuse_getxattr(struct dentry *entry, const char *name,
144492a8780eSMiklos Szeredi 			     void *value, size_t size)
144592a8780eSMiklos Szeredi {
144692a8780eSMiklos Szeredi 	struct inode *inode = entry->d_inode;
144792a8780eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
144892a8780eSMiklos Szeredi 	struct fuse_req *req;
144992a8780eSMiklos Szeredi 	struct fuse_getxattr_in inarg;
145092a8780eSMiklos Szeredi 	struct fuse_getxattr_out outarg;
145192a8780eSMiklos Szeredi 	ssize_t ret;
145292a8780eSMiklos Szeredi 
145392a8780eSMiklos Szeredi 	if (fc->no_getxattr)
145492a8780eSMiklos Szeredi 		return -EOPNOTSUPP;
145592a8780eSMiklos Szeredi 
1456ce1d5a49SMiklos Szeredi 	req = fuse_get_req(fc);
1457ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1458ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
145992a8780eSMiklos Szeredi 
146092a8780eSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
146192a8780eSMiklos Szeredi 	inarg.size = size;
146292a8780eSMiklos Szeredi 	req->in.h.opcode = FUSE_GETXATTR;
146392a8780eSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
146492a8780eSMiklos Szeredi 	req->in.numargs = 2;
146592a8780eSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
146692a8780eSMiklos Szeredi 	req->in.args[0].value = &inarg;
146792a8780eSMiklos Szeredi 	req->in.args[1].size = strlen(name) + 1;
146892a8780eSMiklos Szeredi 	req->in.args[1].value = name;
146992a8780eSMiklos Szeredi 	/* This is really two different operations rolled into one */
147092a8780eSMiklos Szeredi 	req->out.numargs = 1;
147192a8780eSMiklos Szeredi 	if (size) {
147292a8780eSMiklos Szeredi 		req->out.argvar = 1;
147392a8780eSMiklos Szeredi 		req->out.args[0].size = size;
147492a8780eSMiklos Szeredi 		req->out.args[0].value = value;
147592a8780eSMiklos Szeredi 	} else {
147692a8780eSMiklos Szeredi 		req->out.args[0].size = sizeof(outarg);
147792a8780eSMiklos Szeredi 		req->out.args[0].value = &outarg;
147892a8780eSMiklos Szeredi 	}
1479b93f858aSTejun Heo 	fuse_request_send(fc, req);
148092a8780eSMiklos Szeredi 	ret = req->out.h.error;
148192a8780eSMiklos Szeredi 	if (!ret)
148292a8780eSMiklos Szeredi 		ret = size ? req->out.args[0].size : outarg.size;
148392a8780eSMiklos Szeredi 	else {
148492a8780eSMiklos Szeredi 		if (ret == -ENOSYS) {
148592a8780eSMiklos Szeredi 			fc->no_getxattr = 1;
148692a8780eSMiklos Szeredi 			ret = -EOPNOTSUPP;
148792a8780eSMiklos Szeredi 		}
148892a8780eSMiklos Szeredi 	}
148992a8780eSMiklos Szeredi 	fuse_put_request(fc, req);
149092a8780eSMiklos Szeredi 	return ret;
149192a8780eSMiklos Szeredi }
149292a8780eSMiklos Szeredi 
149392a8780eSMiklos Szeredi static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
149492a8780eSMiklos Szeredi {
149592a8780eSMiklos Szeredi 	struct inode *inode = entry->d_inode;
149692a8780eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
149792a8780eSMiklos Szeredi 	struct fuse_req *req;
149892a8780eSMiklos Szeredi 	struct fuse_getxattr_in inarg;
149992a8780eSMiklos Szeredi 	struct fuse_getxattr_out outarg;
150092a8780eSMiklos Szeredi 	ssize_t ret;
150192a8780eSMiklos Szeredi 
1502e57ac683SMiklos Szeredi 	if (!fuse_allow_task(fc, current))
1503e57ac683SMiklos Szeredi 		return -EACCES;
1504e57ac683SMiklos Szeredi 
150592a8780eSMiklos Szeredi 	if (fc->no_listxattr)
150692a8780eSMiklos Szeredi 		return -EOPNOTSUPP;
150792a8780eSMiklos Szeredi 
1508ce1d5a49SMiklos Szeredi 	req = fuse_get_req(fc);
1509ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1510ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
151192a8780eSMiklos Szeredi 
151292a8780eSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
151392a8780eSMiklos Szeredi 	inarg.size = size;
151492a8780eSMiklos Szeredi 	req->in.h.opcode = FUSE_LISTXATTR;
151592a8780eSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
151692a8780eSMiklos Szeredi 	req->in.numargs = 1;
151792a8780eSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
151892a8780eSMiklos Szeredi 	req->in.args[0].value = &inarg;
151992a8780eSMiklos Szeredi 	/* This is really two different operations rolled into one */
152092a8780eSMiklos Szeredi 	req->out.numargs = 1;
152192a8780eSMiklos Szeredi 	if (size) {
152292a8780eSMiklos Szeredi 		req->out.argvar = 1;
152392a8780eSMiklos Szeredi 		req->out.args[0].size = size;
152492a8780eSMiklos Szeredi 		req->out.args[0].value = list;
152592a8780eSMiklos Szeredi 	} else {
152692a8780eSMiklos Szeredi 		req->out.args[0].size = sizeof(outarg);
152792a8780eSMiklos Szeredi 		req->out.args[0].value = &outarg;
152892a8780eSMiklos Szeredi 	}
1529b93f858aSTejun Heo 	fuse_request_send(fc, req);
153092a8780eSMiklos Szeredi 	ret = req->out.h.error;
153192a8780eSMiklos Szeredi 	if (!ret)
153292a8780eSMiklos Szeredi 		ret = size ? req->out.args[0].size : outarg.size;
153392a8780eSMiklos Szeredi 	else {
153492a8780eSMiklos Szeredi 		if (ret == -ENOSYS) {
153592a8780eSMiklos Szeredi 			fc->no_listxattr = 1;
153692a8780eSMiklos Szeredi 			ret = -EOPNOTSUPP;
153792a8780eSMiklos Szeredi 		}
153892a8780eSMiklos Szeredi 	}
153992a8780eSMiklos Szeredi 	fuse_put_request(fc, req);
154092a8780eSMiklos Szeredi 	return ret;
154192a8780eSMiklos Szeredi }
154292a8780eSMiklos Szeredi 
154392a8780eSMiklos Szeredi static int fuse_removexattr(struct dentry *entry, const char *name)
154492a8780eSMiklos Szeredi {
154592a8780eSMiklos Szeredi 	struct inode *inode = entry->d_inode;
154692a8780eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
154792a8780eSMiklos Szeredi 	struct fuse_req *req;
154892a8780eSMiklos Szeredi 	int err;
154992a8780eSMiklos Szeredi 
155092a8780eSMiklos Szeredi 	if (fc->no_removexattr)
155192a8780eSMiklos Szeredi 		return -EOPNOTSUPP;
155292a8780eSMiklos Szeredi 
1553ce1d5a49SMiklos Szeredi 	req = fuse_get_req(fc);
1554ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1555ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
155692a8780eSMiklos Szeredi 
155792a8780eSMiklos Szeredi 	req->in.h.opcode = FUSE_REMOVEXATTR;
155892a8780eSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
155992a8780eSMiklos Szeredi 	req->in.numargs = 1;
156092a8780eSMiklos Szeredi 	req->in.args[0].size = strlen(name) + 1;
156192a8780eSMiklos Szeredi 	req->in.args[0].value = name;
1562b93f858aSTejun Heo 	fuse_request_send(fc, req);
156392a8780eSMiklos Szeredi 	err = req->out.h.error;
156492a8780eSMiklos Szeredi 	fuse_put_request(fc, req);
156592a8780eSMiklos Szeredi 	if (err == -ENOSYS) {
156692a8780eSMiklos Szeredi 		fc->no_removexattr = 1;
156792a8780eSMiklos Szeredi 		err = -EOPNOTSUPP;
156892a8780eSMiklos Szeredi 	}
156992a8780eSMiklos Szeredi 	return err;
157092a8780eSMiklos Szeredi }
157192a8780eSMiklos Szeredi 
1572754661f1SArjan van de Ven static const struct inode_operations fuse_dir_inode_operations = {
1573e5e5558eSMiklos Szeredi 	.lookup		= fuse_lookup,
15749e6268dbSMiklos Szeredi 	.mkdir		= fuse_mkdir,
15759e6268dbSMiklos Szeredi 	.symlink	= fuse_symlink,
15769e6268dbSMiklos Szeredi 	.unlink		= fuse_unlink,
15779e6268dbSMiklos Szeredi 	.rmdir		= fuse_rmdir,
15789e6268dbSMiklos Szeredi 	.rename		= fuse_rename,
15799e6268dbSMiklos Szeredi 	.link		= fuse_link,
15809e6268dbSMiklos Szeredi 	.setattr	= fuse_setattr,
15819e6268dbSMiklos Szeredi 	.create		= fuse_create,
15829e6268dbSMiklos Szeredi 	.mknod		= fuse_mknod,
1583e5e5558eSMiklos Szeredi 	.permission	= fuse_permission,
1584e5e5558eSMiklos Szeredi 	.getattr	= fuse_getattr,
158592a8780eSMiklos Szeredi 	.setxattr	= fuse_setxattr,
158692a8780eSMiklos Szeredi 	.getxattr	= fuse_getxattr,
158792a8780eSMiklos Szeredi 	.listxattr	= fuse_listxattr,
158892a8780eSMiklos Szeredi 	.removexattr	= fuse_removexattr,
1589e5e5558eSMiklos Szeredi };
1590e5e5558eSMiklos Szeredi 
15914b6f5d20SArjan van de Ven static const struct file_operations fuse_dir_operations = {
1592b6aeadedSMiklos Szeredi 	.llseek		= generic_file_llseek,
1593e5e5558eSMiklos Szeredi 	.read		= generic_read_dir,
1594e5e5558eSMiklos Szeredi 	.readdir	= fuse_readdir,
1595e5e5558eSMiklos Szeredi 	.open		= fuse_dir_open,
1596e5e5558eSMiklos Szeredi 	.release	= fuse_dir_release,
159782547981SMiklos Szeredi 	.fsync		= fuse_dir_fsync,
1598e5e5558eSMiklos Szeredi };
1599e5e5558eSMiklos Szeredi 
1600754661f1SArjan van de Ven static const struct inode_operations fuse_common_inode_operations = {
16019e6268dbSMiklos Szeredi 	.setattr	= fuse_setattr,
1602e5e5558eSMiklos Szeredi 	.permission	= fuse_permission,
1603e5e5558eSMiklos Szeredi 	.getattr	= fuse_getattr,
160492a8780eSMiklos Szeredi 	.setxattr	= fuse_setxattr,
160592a8780eSMiklos Szeredi 	.getxattr	= fuse_getxattr,
160692a8780eSMiklos Szeredi 	.listxattr	= fuse_listxattr,
160792a8780eSMiklos Szeredi 	.removexattr	= fuse_removexattr,
1608e5e5558eSMiklos Szeredi };
1609e5e5558eSMiklos Szeredi 
1610754661f1SArjan van de Ven static const struct inode_operations fuse_symlink_inode_operations = {
16119e6268dbSMiklos Szeredi 	.setattr	= fuse_setattr,
1612e5e5558eSMiklos Szeredi 	.follow_link	= fuse_follow_link,
1613e5e5558eSMiklos Szeredi 	.put_link	= fuse_put_link,
1614e5e5558eSMiklos Szeredi 	.readlink	= generic_readlink,
1615e5e5558eSMiklos Szeredi 	.getattr	= fuse_getattr,
161692a8780eSMiklos Szeredi 	.setxattr	= fuse_setxattr,
161792a8780eSMiklos Szeredi 	.getxattr	= fuse_getxattr,
161892a8780eSMiklos Szeredi 	.listxattr	= fuse_listxattr,
161992a8780eSMiklos Szeredi 	.removexattr	= fuse_removexattr,
1620e5e5558eSMiklos Szeredi };
1621e5e5558eSMiklos Szeredi 
1622e5e5558eSMiklos Szeredi void fuse_init_common(struct inode *inode)
1623e5e5558eSMiklos Szeredi {
1624e5e5558eSMiklos Szeredi 	inode->i_op = &fuse_common_inode_operations;
1625e5e5558eSMiklos Szeredi }
1626e5e5558eSMiklos Szeredi 
1627e5e5558eSMiklos Szeredi void fuse_init_dir(struct inode *inode)
1628e5e5558eSMiklos Szeredi {
1629e5e5558eSMiklos Szeredi 	inode->i_op = &fuse_dir_inode_operations;
1630e5e5558eSMiklos Szeredi 	inode->i_fop = &fuse_dir_operations;
1631e5e5558eSMiklos Szeredi }
1632e5e5558eSMiklos Szeredi 
1633e5e5558eSMiklos Szeredi void fuse_init_symlink(struct inode *inode)
1634e5e5558eSMiklos Szeredi {
1635e5e5558eSMiklos Szeredi 	inode->i_op = &fuse_symlink_inode_operations;
1636e5e5558eSMiklos Szeredi }
1637