xref: /openbmc/linux/fs/fuse/dir.c (revision b9ba347f27f2508e3da023688d047e111cbbe2da)
1e5e5558eSMiklos Szeredi /*
2e5e5558eSMiklos Szeredi   FUSE: Filesystem in Userspace
351eb01e7SMiklos Szeredi   Copyright (C) 2001-2006  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  */
660aa7c699SMiklos Szeredi static void fuse_change_timeout(struct dentry *entry, struct fuse_entry_out *o)
670aa7c699SMiklos Szeredi {
680a0898cfSMiklos Szeredi 	fuse_dentry_settime(entry,
690a0898cfSMiklos Szeredi 		time_to_jiffies(o->entry_valid, o->entry_valid_nsec));
708cbdf1e6SMiklos Szeredi 	if (entry->d_inode)
718cbdf1e6SMiklos Szeredi 		get_fuse_inode(entry->d_inode)->i_time =
728cbdf1e6SMiklos Szeredi 			time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
738cbdf1e6SMiklos Szeredi }
748cbdf1e6SMiklos Szeredi 
756f9f1180SMiklos Szeredi /*
766f9f1180SMiklos Szeredi  * Mark the attributes as stale, so that at the next call to
776f9f1180SMiklos Szeredi  * ->getattr() they will be fetched from userspace
786f9f1180SMiklos Szeredi  */
798cbdf1e6SMiklos Szeredi void fuse_invalidate_attr(struct inode *inode)
808cbdf1e6SMiklos Szeredi {
810a0898cfSMiklos Szeredi 	get_fuse_inode(inode)->i_time = 0;
828cbdf1e6SMiklos Szeredi }
838cbdf1e6SMiklos Szeredi 
846f9f1180SMiklos Szeredi /*
856f9f1180SMiklos Szeredi  * Just mark the entry as stale, so that a next attempt to look it up
866f9f1180SMiklos Szeredi  * will result in a new lookup call to userspace
876f9f1180SMiklos Szeredi  *
886f9f1180SMiklos Szeredi  * This is called when a dentry is about to become negative and the
896f9f1180SMiklos Szeredi  * timeout is unknown (unlink, rmdir, rename and in some cases
906f9f1180SMiklos Szeredi  * lookup)
916f9f1180SMiklos Szeredi  */
928cbdf1e6SMiklos Szeredi static void fuse_invalidate_entry_cache(struct dentry *entry)
938cbdf1e6SMiklos Szeredi {
940a0898cfSMiklos Szeredi 	fuse_dentry_settime(entry, 0);
958cbdf1e6SMiklos Szeredi }
968cbdf1e6SMiklos Szeredi 
976f9f1180SMiklos Szeredi /*
986f9f1180SMiklos Szeredi  * Same as fuse_invalidate_entry_cache(), but also try to remove the
996f9f1180SMiklos Szeredi  * dentry from the hash
1006f9f1180SMiklos Szeredi  */
1018cbdf1e6SMiklos Szeredi static void fuse_invalidate_entry(struct dentry *entry)
1028cbdf1e6SMiklos Szeredi {
1038cbdf1e6SMiklos Szeredi 	d_invalidate(entry);
1048cbdf1e6SMiklos Szeredi 	fuse_invalidate_entry_cache(entry);
1050aa7c699SMiklos Szeredi }
1060aa7c699SMiklos Szeredi 
107e5e5558eSMiklos Szeredi static void fuse_lookup_init(struct fuse_req *req, struct inode *dir,
108e5e5558eSMiklos Szeredi 			     struct dentry *entry,
109e5e5558eSMiklos Szeredi 			     struct fuse_entry_out *outarg)
110e5e5558eSMiklos Szeredi {
111e5e5558eSMiklos Szeredi 	req->in.h.opcode = FUSE_LOOKUP;
112e5e5558eSMiklos Szeredi 	req->in.h.nodeid = get_node_id(dir);
113e5e5558eSMiklos Szeredi 	req->in.numargs = 1;
114e5e5558eSMiklos Szeredi 	req->in.args[0].size = entry->d_name.len + 1;
115e5e5558eSMiklos Szeredi 	req->in.args[0].value = entry->d_name.name;
116e5e5558eSMiklos Szeredi 	req->out.numargs = 1;
117e5e5558eSMiklos Szeredi 	req->out.args[0].size = sizeof(struct fuse_entry_out);
118e5e5558eSMiklos Szeredi 	req->out.args[0].value = outarg;
119e5e5558eSMiklos Szeredi }
120e5e5558eSMiklos Szeredi 
1216f9f1180SMiklos Szeredi /*
1226f9f1180SMiklos Szeredi  * Check whether the dentry is still valid
1236f9f1180SMiklos Szeredi  *
1246f9f1180SMiklos Szeredi  * If the entry validity timeout has expired and the dentry is
1256f9f1180SMiklos Szeredi  * positive, try to redo the lookup.  If the lookup results in a
1266f9f1180SMiklos Szeredi  * different inode, then let the VFS invalidate the dentry and redo
1276f9f1180SMiklos Szeredi  * the lookup once more.  If the lookup results in the same inode,
1286f9f1180SMiklos Szeredi  * then refresh the attributes, timeouts and mark the dentry valid.
1296f9f1180SMiklos Szeredi  */
130e5e5558eSMiklos Szeredi static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
131e5e5558eSMiklos Szeredi {
1328cbdf1e6SMiklos Szeredi 	struct inode *inode = entry->d_inode;
1338cbdf1e6SMiklos Szeredi 
1348cbdf1e6SMiklos Szeredi 	if (inode && is_bad_inode(inode))
135e5e5558eSMiklos Szeredi 		return 0;
1360a0898cfSMiklos Szeredi 	else if (fuse_dentry_time(entry) < get_jiffies_64()) {
137e5e5558eSMiklos Szeredi 		int err;
138e5e5558eSMiklos Szeredi 		struct fuse_entry_out outarg;
1398cbdf1e6SMiklos Szeredi 		struct fuse_conn *fc;
1408cbdf1e6SMiklos Szeredi 		struct fuse_req *req;
1412d51013eSMiklos Szeredi 		struct fuse_req *forget_req;
142e956edd0SMiklos Szeredi 		struct dentry *parent;
1438cbdf1e6SMiklos Szeredi 
14450322fe7SMiklos Szeredi 		/* For negative dentries, always do a fresh lookup */
1458cbdf1e6SMiklos Szeredi 		if (!inode)
1468cbdf1e6SMiklos Szeredi 			return 0;
1478cbdf1e6SMiklos Szeredi 
1488cbdf1e6SMiklos Szeredi 		fc = get_fuse_conn(inode);
149ce1d5a49SMiklos Szeredi 		req = fuse_get_req(fc);
150ce1d5a49SMiklos Szeredi 		if (IS_ERR(req))
151e5e5558eSMiklos Szeredi 			return 0;
152e5e5558eSMiklos Szeredi 
1532d51013eSMiklos Szeredi 		forget_req = fuse_get_req(fc);
1542d51013eSMiklos Szeredi 		if (IS_ERR(forget_req)) {
1552d51013eSMiklos Szeredi 			fuse_put_request(fc, req);
1562d51013eSMiklos Szeredi 			return 0;
1572d51013eSMiklos Szeredi 		}
1582d51013eSMiklos Szeredi 
159e956edd0SMiklos Szeredi 		parent = dget_parent(entry);
160e956edd0SMiklos Szeredi 		fuse_lookup_init(req, parent->d_inode, entry, &outarg);
1617c352bdfSMiklos Szeredi 		request_send(fc, req);
162e956edd0SMiklos Szeredi 		dput(parent);
163e5e5558eSMiklos Szeredi 		err = req->out.h.error;
1642d51013eSMiklos Szeredi 		fuse_put_request(fc, req);
16550322fe7SMiklos Szeredi 		/* Zero nodeid is same as -ENOENT */
16650322fe7SMiklos Szeredi 		if (!err && !outarg.nodeid)
16750322fe7SMiklos Szeredi 			err = -ENOENT;
1689e6268dbSMiklos Szeredi 		if (!err) {
1698cbdf1e6SMiklos Szeredi 			struct fuse_inode *fi = get_fuse_inode(inode);
1709e6268dbSMiklos Szeredi 			if (outarg.nodeid != get_node_id(inode)) {
1712d51013eSMiklos Szeredi 				fuse_send_forget(fc, forget_req,
1722d51013eSMiklos Szeredi 						 outarg.nodeid, 1);
1739e6268dbSMiklos Szeredi 				return 0;
1749e6268dbSMiklos Szeredi 			}
1758da5ff23SMiklos Szeredi 			spin_lock(&fc->lock);
1769e6268dbSMiklos Szeredi 			fi->nlookup ++;
1778da5ff23SMiklos Szeredi 			spin_unlock(&fc->lock);
1789e6268dbSMiklos Szeredi 		}
1792d51013eSMiklos Szeredi 		fuse_put_request(fc, forget_req);
1809e6268dbSMiklos Szeredi 		if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
181e5e5558eSMiklos Szeredi 			return 0;
182e5e5558eSMiklos Szeredi 
183e5e5558eSMiklos Szeredi 		fuse_change_attributes(inode, &outarg.attr);
1840aa7c699SMiklos Szeredi 		fuse_change_timeout(entry, &outarg);
185e5e5558eSMiklos Szeredi 	}
186e5e5558eSMiklos Szeredi 	return 1;
187e5e5558eSMiklos Szeredi }
188e5e5558eSMiklos Szeredi 
1898bfc016dSMiklos Szeredi static int invalid_nodeid(u64 nodeid)
1902827d0b2SMiklos Szeredi {
1912827d0b2SMiklos Szeredi 	return !nodeid || nodeid == FUSE_ROOT_ID;
1922827d0b2SMiklos Szeredi }
1932827d0b2SMiklos Szeredi 
194e5e5558eSMiklos Szeredi static struct dentry_operations fuse_dentry_operations = {
195e5e5558eSMiklos Szeredi 	.d_revalidate	= fuse_dentry_revalidate,
196e5e5558eSMiklos Szeredi };
197e5e5558eSMiklos Szeredi 
198a5bfffacSTimo Savola int fuse_valid_type(int m)
19939ee059aSMiklos Szeredi {
20039ee059aSMiklos Szeredi 	return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) ||
20139ee059aSMiklos Szeredi 		S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
20239ee059aSMiklos Szeredi }
20339ee059aSMiklos Szeredi 
204d2a85164SMiklos Szeredi /*
205d2a85164SMiklos Szeredi  * Add a directory inode to a dentry, ensuring that no other dentry
206d2a85164SMiklos Szeredi  * refers to this inode.  Called with fc->inst_mutex.
207d2a85164SMiklos Szeredi  */
208d2a85164SMiklos Szeredi static int fuse_d_add_directory(struct dentry *entry, struct inode *inode)
209d2a85164SMiklos Szeredi {
210d2a85164SMiklos Szeredi 	struct dentry *alias = d_find_alias(inode);
211d2a85164SMiklos Szeredi 	if (alias) {
212d2a85164SMiklos Szeredi 		/* This tries to shrink the subtree below alias */
213d2a85164SMiklos Szeredi 		fuse_invalidate_entry(alias);
214d2a85164SMiklos Szeredi 		dput(alias);
215d2a85164SMiklos Szeredi 		if (!list_empty(&inode->i_dentry))
216d2a85164SMiklos Szeredi 			return -EBUSY;
217d2a85164SMiklos Szeredi 	}
218d2a85164SMiklos Szeredi 	d_add(entry, inode);
219d2a85164SMiklos Szeredi 	return 0;
220d2a85164SMiklos Szeredi }
221d2a85164SMiklos Szeredi 
2220aa7c699SMiklos Szeredi static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
2230aa7c699SMiklos Szeredi 				  struct nameidata *nd)
224e5e5558eSMiklos Szeredi {
225e5e5558eSMiklos Szeredi 	int err;
226e5e5558eSMiklos Szeredi 	struct fuse_entry_out outarg;
227e5e5558eSMiklos Szeredi 	struct inode *inode = NULL;
228e5e5558eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
229e5e5558eSMiklos Szeredi 	struct fuse_req *req;
2302d51013eSMiklos Szeredi 	struct fuse_req *forget_req;
231e5e5558eSMiklos Szeredi 
232e5e5558eSMiklos Szeredi 	if (entry->d_name.len > FUSE_NAME_MAX)
2330aa7c699SMiklos Szeredi 		return ERR_PTR(-ENAMETOOLONG);
234e5e5558eSMiklos Szeredi 
235ce1d5a49SMiklos Szeredi 	req = fuse_get_req(fc);
236ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
237ce1d5a49SMiklos Szeredi 		return ERR_PTR(PTR_ERR(req));
238e5e5558eSMiklos Szeredi 
2392d51013eSMiklos Szeredi 	forget_req = fuse_get_req(fc);
2402d51013eSMiklos Szeredi 	if (IS_ERR(forget_req)) {
2412d51013eSMiklos Szeredi 		fuse_put_request(fc, req);
2422d51013eSMiklos Szeredi 		return ERR_PTR(PTR_ERR(forget_req));
2432d51013eSMiklos Szeredi 	}
2442d51013eSMiklos Szeredi 
245e5e5558eSMiklos Szeredi 	fuse_lookup_init(req, dir, entry, &outarg);
246e5e5558eSMiklos Szeredi 	request_send(fc, req);
247e5e5558eSMiklos Szeredi 	err = req->out.h.error;
2482d51013eSMiklos Szeredi 	fuse_put_request(fc, req);
24950322fe7SMiklos Szeredi 	/* Zero nodeid is same as -ENOENT, but with valid timeout */
25050322fe7SMiklos Szeredi 	if (!err && outarg.nodeid &&
251a5bfffacSTimo Savola 	    (invalid_nodeid(outarg.nodeid) ||
252a5bfffacSTimo Savola 	     !fuse_valid_type(outarg.attr.mode)))
253ee4e5271SMiklos Szeredi 		err = -EIO;
2548cbdf1e6SMiklos Szeredi 	if (!err && outarg.nodeid) {
255e5e5558eSMiklos Szeredi 		inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
2569e6268dbSMiklos Szeredi 				  &outarg.attr);
257e5e5558eSMiklos Szeredi 		if (!inode) {
2582d51013eSMiklos Szeredi 			fuse_send_forget(fc, forget_req, outarg.nodeid, 1);
2590aa7c699SMiklos Szeredi 			return ERR_PTR(-ENOMEM);
260e5e5558eSMiklos Szeredi 		}
261e5e5558eSMiklos Szeredi 	}
2622d51013eSMiklos Szeredi 	fuse_put_request(fc, forget_req);
263e5e5558eSMiklos Szeredi 	if (err && err != -ENOENT)
2640aa7c699SMiklos Szeredi 		return ERR_PTR(err);
265e5e5558eSMiklos Szeredi 
266d2a85164SMiklos Szeredi 	if (inode && S_ISDIR(inode->i_mode)) {
267d2a85164SMiklos Szeredi 		mutex_lock(&fc->inst_mutex);
268d2a85164SMiklos Szeredi 		err = fuse_d_add_directory(entry, inode);
269d2a85164SMiklos Szeredi 		mutex_unlock(&fc->inst_mutex);
270d2a85164SMiklos Szeredi 		if (err) {
2710aa7c699SMiklos Szeredi 			iput(inode);
272d2a85164SMiklos Szeredi 			return ERR_PTR(err);
273e5e5558eSMiklos Szeredi 		}
274d2a85164SMiklos Szeredi 	} else
2750aa7c699SMiklos Szeredi 		d_add(entry, inode);
276d2a85164SMiklos Szeredi 
277e5e5558eSMiklos Szeredi 	entry->d_op = &fuse_dentry_operations;
2788cbdf1e6SMiklos Szeredi 	if (!err)
2790aa7c699SMiklos Szeredi 		fuse_change_timeout(entry, &outarg);
2808cbdf1e6SMiklos Szeredi 	else
2818cbdf1e6SMiklos Szeredi 		fuse_invalidate_entry_cache(entry);
2820aa7c699SMiklos Szeredi 	return NULL;
283e5e5558eSMiklos Szeredi }
284e5e5558eSMiklos Szeredi 
2856f9f1180SMiklos Szeredi /*
28651eb01e7SMiklos Szeredi  * Synchronous release for the case when something goes wrong in CREATE_OPEN
28751eb01e7SMiklos Szeredi  */
28851eb01e7SMiklos Szeredi static void fuse_sync_release(struct fuse_conn *fc, struct fuse_file *ff,
28951eb01e7SMiklos Szeredi 			      u64 nodeid, int flags)
29051eb01e7SMiklos Szeredi {
29151eb01e7SMiklos Szeredi 	struct fuse_req *req;
29251eb01e7SMiklos Szeredi 
29351eb01e7SMiklos Szeredi 	req = fuse_release_fill(ff, nodeid, flags, FUSE_RELEASE);
29451eb01e7SMiklos Szeredi 	req->force = 1;
29551eb01e7SMiklos Szeredi 	request_send(fc, req);
29651eb01e7SMiklos Szeredi 	fuse_put_request(fc, req);
29751eb01e7SMiklos Szeredi }
29851eb01e7SMiklos Szeredi 
29951eb01e7SMiklos Szeredi /*
3006f9f1180SMiklos Szeredi  * Atomic create+open operation
3016f9f1180SMiklos Szeredi  *
3026f9f1180SMiklos Szeredi  * If the filesystem doesn't support this, then fall back to separate
3036f9f1180SMiklos Szeredi  * 'mknod' + 'open' requests.
3046f9f1180SMiklos Szeredi  */
305fd72faacSMiklos Szeredi static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
306fd72faacSMiklos Szeredi 			    struct nameidata *nd)
307fd72faacSMiklos Szeredi {
308fd72faacSMiklos Szeredi 	int err;
309fd72faacSMiklos Szeredi 	struct inode *inode;
310fd72faacSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
311fd72faacSMiklos Szeredi 	struct fuse_req *req;
31251eb01e7SMiklos Szeredi 	struct fuse_req *forget_req;
313fd72faacSMiklos Szeredi 	struct fuse_open_in inarg;
314fd72faacSMiklos Szeredi 	struct fuse_open_out outopen;
315fd72faacSMiklos Szeredi 	struct fuse_entry_out outentry;
316fd72faacSMiklos Szeredi 	struct fuse_file *ff;
317fd72faacSMiklos Szeredi 	struct file *file;
318fd72faacSMiklos Szeredi 	int flags = nd->intent.open.flags - 1;
319fd72faacSMiklos Szeredi 
320fd72faacSMiklos Szeredi 	if (fc->no_create)
321ce1d5a49SMiklos Szeredi 		return -ENOSYS;
322fd72faacSMiklos Szeredi 
32351eb01e7SMiklos Szeredi 	forget_req = fuse_get_req(fc);
32451eb01e7SMiklos Szeredi 	if (IS_ERR(forget_req))
32551eb01e7SMiklos Szeredi 		return PTR_ERR(forget_req);
32651eb01e7SMiklos Szeredi 
327ce1d5a49SMiklos Szeredi 	req = fuse_get_req(fc);
32851eb01e7SMiklos Szeredi 	err = PTR_ERR(req);
329ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
33051eb01e7SMiklos Szeredi 		goto out_put_forget_req;
331fd72faacSMiklos Szeredi 
332ce1d5a49SMiklos Szeredi 	err = -ENOMEM;
333fd72faacSMiklos Szeredi 	ff = fuse_file_alloc();
334fd72faacSMiklos Szeredi 	if (!ff)
335fd72faacSMiklos Szeredi 		goto out_put_request;
336fd72faacSMiklos Szeredi 
337fd72faacSMiklos Szeredi 	flags &= ~O_NOCTTY;
338fd72faacSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
339fd72faacSMiklos Szeredi 	inarg.flags = flags;
340fd72faacSMiklos Szeredi 	inarg.mode = mode;
341fd72faacSMiklos Szeredi 	req->in.h.opcode = FUSE_CREATE;
342fd72faacSMiklos Szeredi 	req->in.h.nodeid = get_node_id(dir);
343fd72faacSMiklos Szeredi 	req->in.numargs = 2;
344fd72faacSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
345fd72faacSMiklos Szeredi 	req->in.args[0].value = &inarg;
346fd72faacSMiklos Szeredi 	req->in.args[1].size = entry->d_name.len + 1;
347fd72faacSMiklos Szeredi 	req->in.args[1].value = entry->d_name.name;
348fd72faacSMiklos Szeredi 	req->out.numargs = 2;
349fd72faacSMiklos Szeredi 	req->out.args[0].size = sizeof(outentry);
350fd72faacSMiklos Szeredi 	req->out.args[0].value = &outentry;
351fd72faacSMiklos Szeredi 	req->out.args[1].size = sizeof(outopen);
352fd72faacSMiklos Szeredi 	req->out.args[1].value = &outopen;
353fd72faacSMiklos Szeredi 	request_send(fc, req);
354fd72faacSMiklos Szeredi 	err = req->out.h.error;
355fd72faacSMiklos Szeredi 	if (err) {
356fd72faacSMiklos Szeredi 		if (err == -ENOSYS)
357fd72faacSMiklos Szeredi 			fc->no_create = 1;
358fd72faacSMiklos Szeredi 		goto out_free_ff;
359fd72faacSMiklos Szeredi 	}
360fd72faacSMiklos Szeredi 
361fd72faacSMiklos Szeredi 	err = -EIO;
3622827d0b2SMiklos Szeredi 	if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid))
363fd72faacSMiklos Szeredi 		goto out_free_ff;
364fd72faacSMiklos Szeredi 
36551eb01e7SMiklos Szeredi 	fuse_put_request(fc, req);
366fd72faacSMiklos Szeredi 	inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
367fd72faacSMiklos Szeredi 			  &outentry.attr);
368fd72faacSMiklos Szeredi 	if (!inode) {
369fd72faacSMiklos Szeredi 		flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
370fd72faacSMiklos Szeredi 		ff->fh = outopen.fh;
37151eb01e7SMiklos Szeredi 		fuse_sync_release(fc, ff, outentry.nodeid, flags);
37251eb01e7SMiklos Szeredi 		fuse_send_forget(fc, forget_req, outentry.nodeid, 1);
37351eb01e7SMiklos Szeredi 		return -ENOMEM;
374fd72faacSMiklos Szeredi 	}
37551eb01e7SMiklos Szeredi 	fuse_put_request(fc, forget_req);
376fd72faacSMiklos Szeredi 	d_instantiate(entry, inode);
3770aa7c699SMiklos Szeredi 	fuse_change_timeout(entry, &outentry);
378fd72faacSMiklos Szeredi 	file = lookup_instantiate_filp(nd, entry, generic_file_open);
379fd72faacSMiklos Szeredi 	if (IS_ERR(file)) {
380fd72faacSMiklos Szeredi 		ff->fh = outopen.fh;
38151eb01e7SMiklos Szeredi 		fuse_sync_release(fc, ff, outentry.nodeid, flags);
382fd72faacSMiklos Szeredi 		return PTR_ERR(file);
383fd72faacSMiklos Szeredi 	}
384fd72faacSMiklos Szeredi 	fuse_finish_open(inode, file, ff, &outopen);
385fd72faacSMiklos Szeredi 	return 0;
386fd72faacSMiklos Szeredi 
387fd72faacSMiklos Szeredi  out_free_ff:
388fd72faacSMiklos Szeredi 	fuse_file_free(ff);
389fd72faacSMiklos Szeredi  out_put_request:
390fd72faacSMiklos Szeredi 	fuse_put_request(fc, req);
39151eb01e7SMiklos Szeredi  out_put_forget_req:
39251eb01e7SMiklos Szeredi 	fuse_put_request(fc, forget_req);
393fd72faacSMiklos Szeredi 	return err;
394fd72faacSMiklos Szeredi }
395fd72faacSMiklos Szeredi 
3966f9f1180SMiklos Szeredi /*
3976f9f1180SMiklos Szeredi  * Code shared between mknod, mkdir, symlink and link
3986f9f1180SMiklos Szeredi  */
3999e6268dbSMiklos Szeredi static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
4009e6268dbSMiklos Szeredi 			    struct inode *dir, struct dentry *entry,
4019e6268dbSMiklos Szeredi 			    int mode)
4029e6268dbSMiklos Szeredi {
4039e6268dbSMiklos Szeredi 	struct fuse_entry_out outarg;
4049e6268dbSMiklos Szeredi 	struct inode *inode;
4059e6268dbSMiklos Szeredi 	int err;
4062d51013eSMiklos Szeredi 	struct fuse_req *forget_req;
4072d51013eSMiklos Szeredi 
4082d51013eSMiklos Szeredi 	forget_req = fuse_get_req(fc);
4092d51013eSMiklos Szeredi 	if (IS_ERR(forget_req)) {
4102d51013eSMiklos Szeredi 		fuse_put_request(fc, req);
4112d51013eSMiklos Szeredi 		return PTR_ERR(forget_req);
4122d51013eSMiklos Szeredi 	}
4139e6268dbSMiklos Szeredi 
4149e6268dbSMiklos Szeredi 	req->in.h.nodeid = get_node_id(dir);
4159e6268dbSMiklos Szeredi 	req->out.numargs = 1;
4169e6268dbSMiklos Szeredi 	req->out.args[0].size = sizeof(outarg);
4179e6268dbSMiklos Szeredi 	req->out.args[0].value = &outarg;
4189e6268dbSMiklos Szeredi 	request_send(fc, req);
4199e6268dbSMiklos Szeredi 	err = req->out.h.error;
4209e6268dbSMiklos Szeredi 	fuse_put_request(fc, req);
4212d51013eSMiklos Szeredi 	if (err)
4222d51013eSMiklos Szeredi 		goto out_put_forget_req;
4232d51013eSMiklos Szeredi 
42439ee059aSMiklos Szeredi 	err = -EIO;
42539ee059aSMiklos Szeredi 	if (invalid_nodeid(outarg.nodeid))
4262d51013eSMiklos Szeredi 		goto out_put_forget_req;
42739ee059aSMiklos Szeredi 
42839ee059aSMiklos Szeredi 	if ((outarg.attr.mode ^ mode) & S_IFMT)
4292d51013eSMiklos Szeredi 		goto out_put_forget_req;
43039ee059aSMiklos Szeredi 
4319e6268dbSMiklos Szeredi 	inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
4329e6268dbSMiklos Szeredi 			  &outarg.attr);
4339e6268dbSMiklos Szeredi 	if (!inode) {
4342d51013eSMiklos Szeredi 		fuse_send_forget(fc, forget_req, outarg.nodeid, 1);
4359e6268dbSMiklos Szeredi 		return -ENOMEM;
4369e6268dbSMiklos Szeredi 	}
4372d51013eSMiklos Szeredi 	fuse_put_request(fc, forget_req);
4389e6268dbSMiklos Szeredi 
439d2a85164SMiklos Szeredi 	if (S_ISDIR(inode->i_mode)) {
440d2a85164SMiklos Szeredi 		struct dentry *alias;
441d2a85164SMiklos Szeredi 		mutex_lock(&fc->inst_mutex);
442d2a85164SMiklos Szeredi 		alias = d_find_alias(inode);
443d2a85164SMiklos Szeredi 		if (alias) {
444d2a85164SMiklos Szeredi 			/* New directory must have moved since mkdir */
445d2a85164SMiklos Szeredi 			mutex_unlock(&fc->inst_mutex);
446d2a85164SMiklos Szeredi 			dput(alias);
4479e6268dbSMiklos Szeredi 			iput(inode);
448d2a85164SMiklos Szeredi 			return -EBUSY;
4499e6268dbSMiklos Szeredi 		}
4509e6268dbSMiklos Szeredi 		d_instantiate(entry, inode);
451d2a85164SMiklos Szeredi 		mutex_unlock(&fc->inst_mutex);
452d2a85164SMiklos Szeredi 	} else
453d2a85164SMiklos Szeredi 		d_instantiate(entry, inode);
454d2a85164SMiklos Szeredi 
4550aa7c699SMiklos Szeredi 	fuse_change_timeout(entry, &outarg);
4569e6268dbSMiklos Szeredi 	fuse_invalidate_attr(dir);
4579e6268dbSMiklos Szeredi 	return 0;
45839ee059aSMiklos Szeredi 
4592d51013eSMiklos Szeredi  out_put_forget_req:
4602d51013eSMiklos Szeredi 	fuse_put_request(fc, forget_req);
46139ee059aSMiklos Szeredi 	return err;
4629e6268dbSMiklos Szeredi }
4639e6268dbSMiklos Szeredi 
4649e6268dbSMiklos Szeredi static int fuse_mknod(struct inode *dir, struct dentry *entry, int mode,
4659e6268dbSMiklos Szeredi 		      dev_t rdev)
4669e6268dbSMiklos Szeredi {
4679e6268dbSMiklos Szeredi 	struct fuse_mknod_in inarg;
4689e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
469ce1d5a49SMiklos Szeredi 	struct fuse_req *req = fuse_get_req(fc);
470ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
471ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
4729e6268dbSMiklos Szeredi 
4739e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
4749e6268dbSMiklos Szeredi 	inarg.mode = mode;
4759e6268dbSMiklos Szeredi 	inarg.rdev = new_encode_dev(rdev);
4769e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_MKNOD;
4779e6268dbSMiklos Szeredi 	req->in.numargs = 2;
4789e6268dbSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
4799e6268dbSMiklos Szeredi 	req->in.args[0].value = &inarg;
4809e6268dbSMiklos Szeredi 	req->in.args[1].size = entry->d_name.len + 1;
4819e6268dbSMiklos Szeredi 	req->in.args[1].value = entry->d_name.name;
4829e6268dbSMiklos Szeredi 	return create_new_entry(fc, req, dir, entry, mode);
4839e6268dbSMiklos Szeredi }
4849e6268dbSMiklos Szeredi 
4859e6268dbSMiklos Szeredi static int fuse_create(struct inode *dir, struct dentry *entry, int mode,
4869e6268dbSMiklos Szeredi 		       struct nameidata *nd)
4879e6268dbSMiklos Szeredi {
488*b9ba347fSMiklos Szeredi 	if (nd && (nd->flags & LOOKUP_OPEN)) {
489fd72faacSMiklos Szeredi 		int err = fuse_create_open(dir, entry, mode, nd);
490fd72faacSMiklos Szeredi 		if (err != -ENOSYS)
491fd72faacSMiklos Szeredi 			return err;
492fd72faacSMiklos Szeredi 		/* Fall back on mknod */
493fd72faacSMiklos Szeredi 	}
4949e6268dbSMiklos Szeredi 	return fuse_mknod(dir, entry, mode, 0);
4959e6268dbSMiklos Szeredi }
4969e6268dbSMiklos Szeredi 
4979e6268dbSMiklos Szeredi static int fuse_mkdir(struct inode *dir, struct dentry *entry, int mode)
4989e6268dbSMiklos Szeredi {
4999e6268dbSMiklos Szeredi 	struct fuse_mkdir_in inarg;
5009e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
501ce1d5a49SMiklos Szeredi 	struct fuse_req *req = fuse_get_req(fc);
502ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
503ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
5049e6268dbSMiklos Szeredi 
5059e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
5069e6268dbSMiklos Szeredi 	inarg.mode = mode;
5079e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_MKDIR;
5089e6268dbSMiklos Szeredi 	req->in.numargs = 2;
5099e6268dbSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
5109e6268dbSMiklos Szeredi 	req->in.args[0].value = &inarg;
5119e6268dbSMiklos Szeredi 	req->in.args[1].size = entry->d_name.len + 1;
5129e6268dbSMiklos Szeredi 	req->in.args[1].value = entry->d_name.name;
5139e6268dbSMiklos Szeredi 	return create_new_entry(fc, req, dir, entry, S_IFDIR);
5149e6268dbSMiklos Szeredi }
5159e6268dbSMiklos Szeredi 
5169e6268dbSMiklos Szeredi static int fuse_symlink(struct inode *dir, struct dentry *entry,
5179e6268dbSMiklos Szeredi 			const char *link)
5189e6268dbSMiklos Szeredi {
5199e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
5209e6268dbSMiklos Szeredi 	unsigned len = strlen(link) + 1;
521ce1d5a49SMiklos Szeredi 	struct fuse_req *req = fuse_get_req(fc);
522ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
523ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
5249e6268dbSMiklos Szeredi 
5259e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_SYMLINK;
5269e6268dbSMiklos Szeredi 	req->in.numargs = 2;
5279e6268dbSMiklos Szeredi 	req->in.args[0].size = entry->d_name.len + 1;
5289e6268dbSMiklos Szeredi 	req->in.args[0].value = entry->d_name.name;
5299e6268dbSMiklos Szeredi 	req->in.args[1].size = len;
5309e6268dbSMiklos Szeredi 	req->in.args[1].value = link;
5319e6268dbSMiklos Szeredi 	return create_new_entry(fc, req, dir, entry, S_IFLNK);
5329e6268dbSMiklos Szeredi }
5339e6268dbSMiklos Szeredi 
5349e6268dbSMiklos Szeredi static int fuse_unlink(struct inode *dir, struct dentry *entry)
5359e6268dbSMiklos Szeredi {
5369e6268dbSMiklos Szeredi 	int err;
5379e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
538ce1d5a49SMiklos Szeredi 	struct fuse_req *req = fuse_get_req(fc);
539ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
540ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
5419e6268dbSMiklos Szeredi 
5429e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_UNLINK;
5439e6268dbSMiklos Szeredi 	req->in.h.nodeid = get_node_id(dir);
5449e6268dbSMiklos Szeredi 	req->in.numargs = 1;
5459e6268dbSMiklos Szeredi 	req->in.args[0].size = entry->d_name.len + 1;
5469e6268dbSMiklos Szeredi 	req->in.args[0].value = entry->d_name.name;
5479e6268dbSMiklos Szeredi 	request_send(fc, req);
5489e6268dbSMiklos Szeredi 	err = req->out.h.error;
5499e6268dbSMiklos Szeredi 	fuse_put_request(fc, req);
5509e6268dbSMiklos Szeredi 	if (!err) {
5519e6268dbSMiklos Szeredi 		struct inode *inode = entry->d_inode;
5529e6268dbSMiklos Szeredi 
5539e6268dbSMiklos Szeredi 		/* Set nlink to zero so the inode can be cleared, if
5549e6268dbSMiklos Szeredi                    the inode does have more links this will be
5559e6268dbSMiklos Szeredi                    discovered at the next lookup/getattr */
556ce71ec36SDave Hansen 		clear_nlink(inode);
5579e6268dbSMiklos Szeredi 		fuse_invalidate_attr(inode);
5589e6268dbSMiklos Szeredi 		fuse_invalidate_attr(dir);
5598cbdf1e6SMiklos Szeredi 		fuse_invalidate_entry_cache(entry);
5609e6268dbSMiklos Szeredi 	} else if (err == -EINTR)
5619e6268dbSMiklos Szeredi 		fuse_invalidate_entry(entry);
5629e6268dbSMiklos Szeredi 	return err;
5639e6268dbSMiklos Szeredi }
5649e6268dbSMiklos Szeredi 
5659e6268dbSMiklos Szeredi static int fuse_rmdir(struct inode *dir, struct dentry *entry)
5669e6268dbSMiklos Szeredi {
5679e6268dbSMiklos Szeredi 	int err;
5689e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(dir);
569ce1d5a49SMiklos Szeredi 	struct fuse_req *req = fuse_get_req(fc);
570ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
571ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
5729e6268dbSMiklos Szeredi 
5739e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_RMDIR;
5749e6268dbSMiklos Szeredi 	req->in.h.nodeid = get_node_id(dir);
5759e6268dbSMiklos Szeredi 	req->in.numargs = 1;
5769e6268dbSMiklos Szeredi 	req->in.args[0].size = entry->d_name.len + 1;
5779e6268dbSMiklos Szeredi 	req->in.args[0].value = entry->d_name.name;
5789e6268dbSMiklos Szeredi 	request_send(fc, req);
5799e6268dbSMiklos Szeredi 	err = req->out.h.error;
5809e6268dbSMiklos Szeredi 	fuse_put_request(fc, req);
5819e6268dbSMiklos Szeredi 	if (!err) {
582ce71ec36SDave Hansen 		clear_nlink(entry->d_inode);
5839e6268dbSMiklos Szeredi 		fuse_invalidate_attr(dir);
5848cbdf1e6SMiklos Szeredi 		fuse_invalidate_entry_cache(entry);
5859e6268dbSMiklos Szeredi 	} else if (err == -EINTR)
5869e6268dbSMiklos Szeredi 		fuse_invalidate_entry(entry);
5879e6268dbSMiklos Szeredi 	return err;
5889e6268dbSMiklos Szeredi }
5899e6268dbSMiklos Szeredi 
5909e6268dbSMiklos Szeredi static int fuse_rename(struct inode *olddir, struct dentry *oldent,
5919e6268dbSMiklos Szeredi 		       struct inode *newdir, struct dentry *newent)
5929e6268dbSMiklos Szeredi {
5939e6268dbSMiklos Szeredi 	int err;
5949e6268dbSMiklos Szeredi 	struct fuse_rename_in inarg;
5959e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(olddir);
596ce1d5a49SMiklos Szeredi 	struct fuse_req *req = fuse_get_req(fc);
597ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
598ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
5999e6268dbSMiklos Szeredi 
6009e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
6019e6268dbSMiklos Szeredi 	inarg.newdir = get_node_id(newdir);
6029e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_RENAME;
6039e6268dbSMiklos Szeredi 	req->in.h.nodeid = get_node_id(olddir);
6049e6268dbSMiklos Szeredi 	req->in.numargs = 3;
6059e6268dbSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
6069e6268dbSMiklos Szeredi 	req->in.args[0].value = &inarg;
6079e6268dbSMiklos Szeredi 	req->in.args[1].size = oldent->d_name.len + 1;
6089e6268dbSMiklos Szeredi 	req->in.args[1].value = oldent->d_name.name;
6099e6268dbSMiklos Szeredi 	req->in.args[2].size = newent->d_name.len + 1;
6109e6268dbSMiklos Szeredi 	req->in.args[2].value = newent->d_name.name;
6119e6268dbSMiklos Szeredi 	request_send(fc, req);
6129e6268dbSMiklos Szeredi 	err = req->out.h.error;
6139e6268dbSMiklos Szeredi 	fuse_put_request(fc, req);
6149e6268dbSMiklos Szeredi 	if (!err) {
6159e6268dbSMiklos Szeredi 		fuse_invalidate_attr(olddir);
6169e6268dbSMiklos Szeredi 		if (olddir != newdir)
6179e6268dbSMiklos Szeredi 			fuse_invalidate_attr(newdir);
6188cbdf1e6SMiklos Szeredi 
6198cbdf1e6SMiklos Szeredi 		/* newent will end up negative */
6208cbdf1e6SMiklos Szeredi 		if (newent->d_inode)
6218cbdf1e6SMiklos Szeredi 			fuse_invalidate_entry_cache(newent);
6229e6268dbSMiklos Szeredi 	} else if (err == -EINTR) {
6239e6268dbSMiklos Szeredi 		/* If request was interrupted, DEITY only knows if the
6249e6268dbSMiklos Szeredi 		   rename actually took place.  If the invalidation
6259e6268dbSMiklos Szeredi 		   fails (e.g. some process has CWD under the renamed
6269e6268dbSMiklos Szeredi 		   directory), then there can be inconsistency between
6279e6268dbSMiklos Szeredi 		   the dcache and the real filesystem.  Tough luck. */
6289e6268dbSMiklos Szeredi 		fuse_invalidate_entry(oldent);
6299e6268dbSMiklos Szeredi 		if (newent->d_inode)
6309e6268dbSMiklos Szeredi 			fuse_invalidate_entry(newent);
6319e6268dbSMiklos Szeredi 	}
6329e6268dbSMiklos Szeredi 
6339e6268dbSMiklos Szeredi 	return err;
6349e6268dbSMiklos Szeredi }
6359e6268dbSMiklos Szeredi 
6369e6268dbSMiklos Szeredi static int fuse_link(struct dentry *entry, struct inode *newdir,
6379e6268dbSMiklos Szeredi 		     struct dentry *newent)
6389e6268dbSMiklos Szeredi {
6399e6268dbSMiklos Szeredi 	int err;
6409e6268dbSMiklos Szeredi 	struct fuse_link_in inarg;
6419e6268dbSMiklos Szeredi 	struct inode *inode = entry->d_inode;
6429e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
643ce1d5a49SMiklos Szeredi 	struct fuse_req *req = fuse_get_req(fc);
644ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
645ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
6469e6268dbSMiklos Szeredi 
6479e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
6489e6268dbSMiklos Szeredi 	inarg.oldnodeid = get_node_id(inode);
6499e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_LINK;
6509e6268dbSMiklos Szeredi 	req->in.numargs = 2;
6519e6268dbSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
6529e6268dbSMiklos Szeredi 	req->in.args[0].value = &inarg;
6539e6268dbSMiklos Szeredi 	req->in.args[1].size = newent->d_name.len + 1;
6549e6268dbSMiklos Szeredi 	req->in.args[1].value = newent->d_name.name;
6559e6268dbSMiklos Szeredi 	err = create_new_entry(fc, req, newdir, newent, inode->i_mode);
6569e6268dbSMiklos Szeredi 	/* Contrary to "normal" filesystems it can happen that link
6579e6268dbSMiklos Szeredi 	   makes two "logical" inodes point to the same "physical"
6589e6268dbSMiklos Szeredi 	   inode.  We invalidate the attributes of the old one, so it
6599e6268dbSMiklos Szeredi 	   will reflect changes in the backing inode (link count,
6609e6268dbSMiklos Szeredi 	   etc.)
6619e6268dbSMiklos Szeredi 	*/
6629e6268dbSMiklos Szeredi 	if (!err || err == -EINTR)
6639e6268dbSMiklos Szeredi 		fuse_invalidate_attr(inode);
6649e6268dbSMiklos Szeredi 	return err;
6659e6268dbSMiklos Szeredi }
6669e6268dbSMiklos Szeredi 
667e5e5558eSMiklos Szeredi int fuse_do_getattr(struct inode *inode)
668e5e5558eSMiklos Szeredi {
669e5e5558eSMiklos Szeredi 	int err;
670e5e5558eSMiklos Szeredi 	struct fuse_attr_out arg;
671e5e5558eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
672ce1d5a49SMiklos Szeredi 	struct fuse_req *req = fuse_get_req(fc);
673ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
674ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
675e5e5558eSMiklos Szeredi 
676e5e5558eSMiklos Szeredi 	req->in.h.opcode = FUSE_GETATTR;
677e5e5558eSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
678e5e5558eSMiklos Szeredi 	req->out.numargs = 1;
679e5e5558eSMiklos Szeredi 	req->out.args[0].size = sizeof(arg);
680e5e5558eSMiklos Szeredi 	req->out.args[0].value = &arg;
681e5e5558eSMiklos Szeredi 	request_send(fc, req);
682e5e5558eSMiklos Szeredi 	err = req->out.h.error;
683e5e5558eSMiklos Szeredi 	fuse_put_request(fc, req);
684e5e5558eSMiklos Szeredi 	if (!err) {
685e5e5558eSMiklos Szeredi 		if ((inode->i_mode ^ arg.attr.mode) & S_IFMT) {
686e5e5558eSMiklos Szeredi 			make_bad_inode(inode);
687e5e5558eSMiklos Szeredi 			err = -EIO;
688e5e5558eSMiklos Szeredi 		} else {
689e5e5558eSMiklos Szeredi 			struct fuse_inode *fi = get_fuse_inode(inode);
690e5e5558eSMiklos Szeredi 			fuse_change_attributes(inode, &arg.attr);
691e5e5558eSMiklos Szeredi 			fi->i_time = time_to_jiffies(arg.attr_valid,
692e5e5558eSMiklos Szeredi 						     arg.attr_valid_nsec);
693e5e5558eSMiklos Szeredi 		}
694e5e5558eSMiklos Szeredi 	}
695e5e5558eSMiklos Szeredi 	return err;
696e5e5558eSMiklos Szeredi }
697e5e5558eSMiklos Szeredi 
69887729a55SMiklos Szeredi /*
69987729a55SMiklos Szeredi  * Calling into a user-controlled filesystem gives the filesystem
70087729a55SMiklos Szeredi  * daemon ptrace-like capabilities over the requester process.  This
70187729a55SMiklos Szeredi  * means, that the filesystem daemon is able to record the exact
70287729a55SMiklos Szeredi  * filesystem operations performed, and can also control the behavior
70387729a55SMiklos Szeredi  * of the requester process in otherwise impossible ways.  For example
70487729a55SMiklos Szeredi  * it can delay the operation for arbitrary length of time allowing
70587729a55SMiklos Szeredi  * DoS against the requester.
70687729a55SMiklos Szeredi  *
70787729a55SMiklos Szeredi  * For this reason only those processes can call into the filesystem,
70887729a55SMiklos Szeredi  * for which the owner of the mount has ptrace privilege.  This
70987729a55SMiklos Szeredi  * excludes processes started by other users, suid or sgid processes.
71087729a55SMiklos Szeredi  */
71187729a55SMiklos Szeredi static int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task)
71287729a55SMiklos Szeredi {
71387729a55SMiklos Szeredi 	if (fc->flags & FUSE_ALLOW_OTHER)
71487729a55SMiklos Szeredi 		return 1;
71587729a55SMiklos Szeredi 
71687729a55SMiklos Szeredi 	if (task->euid == fc->user_id &&
71787729a55SMiklos Szeredi 	    task->suid == fc->user_id &&
71887729a55SMiklos Szeredi 	    task->uid == fc->user_id &&
71987729a55SMiklos Szeredi 	    task->egid == fc->group_id &&
72087729a55SMiklos Szeredi 	    task->sgid == fc->group_id &&
72187729a55SMiklos Szeredi 	    task->gid == fc->group_id)
72287729a55SMiklos Szeredi 		return 1;
72387729a55SMiklos Szeredi 
72487729a55SMiklos Szeredi 	return 0;
72587729a55SMiklos Szeredi }
72687729a55SMiklos Szeredi 
7276f9f1180SMiklos Szeredi /*
7286f9f1180SMiklos Szeredi  * Check whether the inode attributes are still valid
7296f9f1180SMiklos Szeredi  *
7306f9f1180SMiklos Szeredi  * If the attribute validity timeout has expired, then fetch the fresh
7316f9f1180SMiklos Szeredi  * attributes with a 'getattr' request
7326f9f1180SMiklos Szeredi  *
7336f9f1180SMiklos Szeredi  * I'm not sure why cached attributes are never returned for the root
7346f9f1180SMiklos Szeredi  * inode, this is probably being too cautious.
7356f9f1180SMiklos Szeredi  */
736e5e5558eSMiklos Szeredi static int fuse_revalidate(struct dentry *entry)
737e5e5558eSMiklos Szeredi {
738e5e5558eSMiklos Szeredi 	struct inode *inode = entry->d_inode;
739e5e5558eSMiklos Szeredi 	struct fuse_inode *fi = get_fuse_inode(inode);
740e5e5558eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
741e5e5558eSMiklos Szeredi 
74287729a55SMiklos Szeredi 	if (!fuse_allow_task(fc, current))
743e5e5558eSMiklos Szeredi 		return -EACCES;
74487729a55SMiklos Szeredi 	if (get_node_id(inode) != FUSE_ROOT_ID &&
7450a0898cfSMiklos Szeredi 	    fi->i_time >= get_jiffies_64())
746e5e5558eSMiklos Szeredi 		return 0;
747e5e5558eSMiklos Szeredi 
748e5e5558eSMiklos Szeredi 	return fuse_do_getattr(inode);
749e5e5558eSMiklos Szeredi }
750e5e5558eSMiklos Szeredi 
75131d40d74SMiklos Szeredi static int fuse_access(struct inode *inode, int mask)
75231d40d74SMiklos Szeredi {
75331d40d74SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
75431d40d74SMiklos Szeredi 	struct fuse_req *req;
75531d40d74SMiklos Szeredi 	struct fuse_access_in inarg;
75631d40d74SMiklos Szeredi 	int err;
75731d40d74SMiklos Szeredi 
75831d40d74SMiklos Szeredi 	if (fc->no_access)
75931d40d74SMiklos Szeredi 		return 0;
76031d40d74SMiklos Szeredi 
761ce1d5a49SMiklos Szeredi 	req = fuse_get_req(fc);
762ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
763ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
76431d40d74SMiklos Szeredi 
76531d40d74SMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
76631d40d74SMiklos Szeredi 	inarg.mask = mask;
76731d40d74SMiklos Szeredi 	req->in.h.opcode = FUSE_ACCESS;
76831d40d74SMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
76931d40d74SMiklos Szeredi 	req->in.numargs = 1;
77031d40d74SMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
77131d40d74SMiklos Szeredi 	req->in.args[0].value = &inarg;
77231d40d74SMiklos Szeredi 	request_send(fc, req);
77331d40d74SMiklos Szeredi 	err = req->out.h.error;
77431d40d74SMiklos Szeredi 	fuse_put_request(fc, req);
77531d40d74SMiklos Szeredi 	if (err == -ENOSYS) {
77631d40d74SMiklos Szeredi 		fc->no_access = 1;
77731d40d74SMiklos Szeredi 		err = 0;
77831d40d74SMiklos Szeredi 	}
77931d40d74SMiklos Szeredi 	return err;
78031d40d74SMiklos Szeredi }
78131d40d74SMiklos Szeredi 
7826f9f1180SMiklos Szeredi /*
7836f9f1180SMiklos Szeredi  * Check permission.  The two basic access models of FUSE are:
7846f9f1180SMiklos Szeredi  *
7856f9f1180SMiklos Szeredi  * 1) Local access checking ('default_permissions' mount option) based
7866f9f1180SMiklos Szeredi  * on file mode.  This is the plain old disk filesystem permission
7876f9f1180SMiklos Szeredi  * modell.
7886f9f1180SMiklos Szeredi  *
7896f9f1180SMiklos Szeredi  * 2) "Remote" access checking, where server is responsible for
7906f9f1180SMiklos Szeredi  * checking permission in each inode operation.  An exception to this
7916f9f1180SMiklos Szeredi  * is if ->permission() was invoked from sys_access() in which case an
7926f9f1180SMiklos Szeredi  * access request is sent.  Execute permission is still checked
7936f9f1180SMiklos Szeredi  * locally based on file mode.
7946f9f1180SMiklos Szeredi  */
795e5e5558eSMiklos Szeredi static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
796e5e5558eSMiklos Szeredi {
797e5e5558eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
798e5e5558eSMiklos Szeredi 
79987729a55SMiklos Szeredi 	if (!fuse_allow_task(fc, current))
800e5e5558eSMiklos Szeredi 		return -EACCES;
8011e9a4ed9SMiklos Szeredi 	else if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
8021e9a4ed9SMiklos Szeredi 		int err = generic_permission(inode, mask, NULL);
8031e9a4ed9SMiklos Szeredi 
8041e9a4ed9SMiklos Szeredi 		/* If permission is denied, try to refresh file
8051e9a4ed9SMiklos Szeredi 		   attributes.  This is also needed, because the root
8061e9a4ed9SMiklos Szeredi 		   node will at first have no permissions */
8071e9a4ed9SMiklos Szeredi 		if (err == -EACCES) {
8081e9a4ed9SMiklos Szeredi 		 	err = fuse_do_getattr(inode);
8091e9a4ed9SMiklos Szeredi 			if (!err)
8101e9a4ed9SMiklos Szeredi 				err = generic_permission(inode, mask, NULL);
8111e9a4ed9SMiklos Szeredi 		}
8121e9a4ed9SMiklos Szeredi 
8136f9f1180SMiklos Szeredi 		/* Note: the opposite of the above test does not
8146f9f1180SMiklos Szeredi 		   exist.  So if permissions are revoked this won't be
8156f9f1180SMiklos Szeredi 		   noticed immediately, only after the attribute
8166f9f1180SMiklos Szeredi 		   timeout has expired */
8171e9a4ed9SMiklos Szeredi 
8181e9a4ed9SMiklos Szeredi 		return err;
8191e9a4ed9SMiklos Szeredi 	} else {
820e5e5558eSMiklos Szeredi 		int mode = inode->i_mode;
821e5e5558eSMiklos Szeredi 		if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO))
822e5e5558eSMiklos Szeredi 			return -EACCES;
82331d40d74SMiklos Szeredi 
824650a8983SMiklos Szeredi 		if (nd && (nd->flags & (LOOKUP_ACCESS | LOOKUP_CHDIR)))
82531d40d74SMiklos Szeredi 			return fuse_access(inode, mask);
826e5e5558eSMiklos Szeredi 		return 0;
827e5e5558eSMiklos Szeredi 	}
828e5e5558eSMiklos Szeredi }
829e5e5558eSMiklos Szeredi 
830e5e5558eSMiklos Szeredi static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
831e5e5558eSMiklos Szeredi 			 void *dstbuf, filldir_t filldir)
832e5e5558eSMiklos Szeredi {
833e5e5558eSMiklos Szeredi 	while (nbytes >= FUSE_NAME_OFFSET) {
834e5e5558eSMiklos Szeredi 		struct fuse_dirent *dirent = (struct fuse_dirent *) buf;
835e5e5558eSMiklos Szeredi 		size_t reclen = FUSE_DIRENT_SIZE(dirent);
836e5e5558eSMiklos Szeredi 		int over;
837e5e5558eSMiklos Szeredi 		if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
838e5e5558eSMiklos Szeredi 			return -EIO;
839e5e5558eSMiklos Szeredi 		if (reclen > nbytes)
840e5e5558eSMiklos Szeredi 			break;
841e5e5558eSMiklos Szeredi 
842e5e5558eSMiklos Szeredi 		over = filldir(dstbuf, dirent->name, dirent->namelen,
843e5e5558eSMiklos Szeredi 			       file->f_pos, dirent->ino, dirent->type);
844e5e5558eSMiklos Szeredi 		if (over)
845e5e5558eSMiklos Szeredi 			break;
846e5e5558eSMiklos Szeredi 
847e5e5558eSMiklos Szeredi 		buf += reclen;
848e5e5558eSMiklos Szeredi 		nbytes -= reclen;
849e5e5558eSMiklos Szeredi 		file->f_pos = dirent->off;
850e5e5558eSMiklos Szeredi 	}
851e5e5558eSMiklos Szeredi 
852e5e5558eSMiklos Szeredi 	return 0;
853e5e5558eSMiklos Szeredi }
854e5e5558eSMiklos Szeredi 
855e5e5558eSMiklos Szeredi static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
856e5e5558eSMiklos Szeredi {
85704730fefSMiklos Szeredi 	int err;
85804730fefSMiklos Szeredi 	size_t nbytes;
85904730fefSMiklos Szeredi 	struct page *page;
8607706a9d6SJosef Sipek 	struct inode *inode = file->f_path.dentry->d_inode;
86104730fefSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
862248d86e8SMiklos Szeredi 	struct fuse_req *req;
863248d86e8SMiklos Szeredi 
864248d86e8SMiklos Szeredi 	if (is_bad_inode(inode))
865248d86e8SMiklos Szeredi 		return -EIO;
866248d86e8SMiklos Szeredi 
867ce1d5a49SMiklos Szeredi 	req = fuse_get_req(fc);
868ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
869ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
870e5e5558eSMiklos Szeredi 
87104730fefSMiklos Szeredi 	page = alloc_page(GFP_KERNEL);
87204730fefSMiklos Szeredi 	if (!page) {
87304730fefSMiklos Szeredi 		fuse_put_request(fc, req);
874e5e5558eSMiklos Szeredi 		return -ENOMEM;
87504730fefSMiklos Szeredi 	}
87604730fefSMiklos Szeredi 	req->num_pages = 1;
87704730fefSMiklos Szeredi 	req->pages[0] = page;
878361b1eb5SMiklos Szeredi 	fuse_read_fill(req, file, inode, file->f_pos, PAGE_SIZE, FUSE_READDIR);
879361b1eb5SMiklos Szeredi 	request_send(fc, req);
880361b1eb5SMiklos Szeredi 	nbytes = req->out.args[0].size;
88104730fefSMiklos Szeredi 	err = req->out.h.error;
88204730fefSMiklos Szeredi 	fuse_put_request(fc, req);
88304730fefSMiklos Szeredi 	if (!err)
88404730fefSMiklos Szeredi 		err = parse_dirfile(page_address(page), nbytes, file, dstbuf,
88504730fefSMiklos Szeredi 				    filldir);
886e5e5558eSMiklos Szeredi 
88704730fefSMiklos Szeredi 	__free_page(page);
888b36c31baSMiklos Szeredi 	fuse_invalidate_attr(inode); /* atime changed */
88904730fefSMiklos Szeredi 	return err;
890e5e5558eSMiklos Szeredi }
891e5e5558eSMiklos Szeredi 
892e5e5558eSMiklos Szeredi static char *read_link(struct dentry *dentry)
893e5e5558eSMiklos Szeredi {
894e5e5558eSMiklos Szeredi 	struct inode *inode = dentry->d_inode;
895e5e5558eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
896ce1d5a49SMiklos Szeredi 	struct fuse_req *req = fuse_get_req(fc);
897e5e5558eSMiklos Szeredi 	char *link;
898e5e5558eSMiklos Szeredi 
899ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
900ce1d5a49SMiklos Szeredi 		return ERR_PTR(PTR_ERR(req));
901e5e5558eSMiklos Szeredi 
902e5e5558eSMiklos Szeredi 	link = (char *) __get_free_page(GFP_KERNEL);
903e5e5558eSMiklos Szeredi 	if (!link) {
904e5e5558eSMiklos Szeredi 		link = ERR_PTR(-ENOMEM);
905e5e5558eSMiklos Szeredi 		goto out;
906e5e5558eSMiklos Szeredi 	}
907e5e5558eSMiklos Szeredi 	req->in.h.opcode = FUSE_READLINK;
908e5e5558eSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
909e5e5558eSMiklos Szeredi 	req->out.argvar = 1;
910e5e5558eSMiklos Szeredi 	req->out.numargs = 1;
911e5e5558eSMiklos Szeredi 	req->out.args[0].size = PAGE_SIZE - 1;
912e5e5558eSMiklos Szeredi 	req->out.args[0].value = link;
913e5e5558eSMiklos Szeredi 	request_send(fc, req);
914e5e5558eSMiklos Szeredi 	if (req->out.h.error) {
915e5e5558eSMiklos Szeredi 		free_page((unsigned long) link);
916e5e5558eSMiklos Szeredi 		link = ERR_PTR(req->out.h.error);
917e5e5558eSMiklos Szeredi 	} else
918e5e5558eSMiklos Szeredi 		link[req->out.args[0].size] = '\0';
919e5e5558eSMiklos Szeredi  out:
920e5e5558eSMiklos Szeredi 	fuse_put_request(fc, req);
921b36c31baSMiklos Szeredi 	fuse_invalidate_attr(inode); /* atime changed */
922e5e5558eSMiklos Szeredi 	return link;
923e5e5558eSMiklos Szeredi }
924e5e5558eSMiklos Szeredi 
925e5e5558eSMiklos Szeredi static void free_link(char *link)
926e5e5558eSMiklos Szeredi {
927e5e5558eSMiklos Szeredi 	if (!IS_ERR(link))
928e5e5558eSMiklos Szeredi 		free_page((unsigned long) link);
929e5e5558eSMiklos Szeredi }
930e5e5558eSMiklos Szeredi 
931e5e5558eSMiklos Szeredi static void *fuse_follow_link(struct dentry *dentry, struct nameidata *nd)
932e5e5558eSMiklos Szeredi {
933e5e5558eSMiklos Szeredi 	nd_set_link(nd, read_link(dentry));
934e5e5558eSMiklos Szeredi 	return NULL;
935e5e5558eSMiklos Szeredi }
936e5e5558eSMiklos Szeredi 
937e5e5558eSMiklos Szeredi static void fuse_put_link(struct dentry *dentry, struct nameidata *nd, void *c)
938e5e5558eSMiklos Szeredi {
939e5e5558eSMiklos Szeredi 	free_link(nd_get_link(nd));
940e5e5558eSMiklos Szeredi }
941e5e5558eSMiklos Szeredi 
942e5e5558eSMiklos Szeredi static int fuse_dir_open(struct inode *inode, struct file *file)
943e5e5558eSMiklos Szeredi {
94404730fefSMiklos Szeredi 	return fuse_open_common(inode, file, 1);
945e5e5558eSMiklos Szeredi }
946e5e5558eSMiklos Szeredi 
947e5e5558eSMiklos Szeredi static int fuse_dir_release(struct inode *inode, struct file *file)
948e5e5558eSMiklos Szeredi {
94904730fefSMiklos Szeredi 	return fuse_release_common(inode, file, 1);
950e5e5558eSMiklos Szeredi }
951e5e5558eSMiklos Szeredi 
95282547981SMiklos Szeredi static int fuse_dir_fsync(struct file *file, struct dentry *de, int datasync)
95382547981SMiklos Szeredi {
95482547981SMiklos Szeredi 	/* nfsd can call this with no file */
95582547981SMiklos Szeredi 	return file ? fuse_fsync_common(file, de, datasync, 1) : 0;
95682547981SMiklos Szeredi }
95782547981SMiklos Szeredi 
958befc649cSMiklos Szeredi static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
9599e6268dbSMiklos Szeredi {
9609e6268dbSMiklos Szeredi 	unsigned ivalid = iattr->ia_valid;
9619e6268dbSMiklos Szeredi 
9629e6268dbSMiklos Szeredi 	if (ivalid & ATTR_MODE)
963befc649cSMiklos Szeredi 		arg->valid |= FATTR_MODE,   arg->mode = iattr->ia_mode;
9649e6268dbSMiklos Szeredi 	if (ivalid & ATTR_UID)
965befc649cSMiklos Szeredi 		arg->valid |= FATTR_UID,    arg->uid = iattr->ia_uid;
9669e6268dbSMiklos Szeredi 	if (ivalid & ATTR_GID)
967befc649cSMiklos Szeredi 		arg->valid |= FATTR_GID,    arg->gid = iattr->ia_gid;
9689e6268dbSMiklos Szeredi 	if (ivalid & ATTR_SIZE)
969befc649cSMiklos Szeredi 		arg->valid |= FATTR_SIZE,   arg->size = iattr->ia_size;
9709e6268dbSMiklos Szeredi 	/* You can only _set_ these together (they may change by themselves) */
9719e6268dbSMiklos Szeredi 	if ((ivalid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME)) {
972befc649cSMiklos Szeredi 		arg->valid |= FATTR_ATIME | FATTR_MTIME;
973befc649cSMiklos Szeredi 		arg->atime = iattr->ia_atime.tv_sec;
974befc649cSMiklos Szeredi 		arg->mtime = iattr->ia_mtime.tv_sec;
9759e6268dbSMiklos Szeredi 	}
976befc649cSMiklos Szeredi 	if (ivalid & ATTR_FILE) {
977befc649cSMiklos Szeredi 		struct fuse_file *ff = iattr->ia_file->private_data;
978befc649cSMiklos Szeredi 		arg->valid |= FATTR_FH;
979befc649cSMiklos Szeredi 		arg->fh = ff->fh;
980befc649cSMiklos Szeredi 	}
9819e6268dbSMiklos Szeredi }
9829e6268dbSMiklos Szeredi 
9839ffbb916SMiklos Szeredi static void fuse_vmtruncate(struct inode *inode, loff_t offset)
9849ffbb916SMiklos Szeredi {
9859ffbb916SMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
9869ffbb916SMiklos Szeredi 	int need_trunc;
9879ffbb916SMiklos Szeredi 
9889ffbb916SMiklos Szeredi 	spin_lock(&fc->lock);
9899ffbb916SMiklos Szeredi 	need_trunc = inode->i_size > offset;
9909ffbb916SMiklos Szeredi 	i_size_write(inode, offset);
9919ffbb916SMiklos Szeredi 	spin_unlock(&fc->lock);
9929ffbb916SMiklos Szeredi 
9939ffbb916SMiklos Szeredi 	if (need_trunc) {
9949ffbb916SMiklos Szeredi 		struct address_space *mapping = inode->i_mapping;
9959ffbb916SMiklos Szeredi 		unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
9969ffbb916SMiklos Szeredi 		truncate_inode_pages(mapping, offset);
9979ffbb916SMiklos Szeredi 	}
9989ffbb916SMiklos Szeredi }
9999ffbb916SMiklos Szeredi 
10006f9f1180SMiklos Szeredi /*
10016f9f1180SMiklos Szeredi  * Set attributes, and at the same time refresh them.
10026f9f1180SMiklos Szeredi  *
10036f9f1180SMiklos Szeredi  * Truncation is slightly complicated, because the 'truncate' request
10046f9f1180SMiklos Szeredi  * may fail, in which case we don't want to touch the mapping.
10059ffbb916SMiklos Szeredi  * vmtruncate() doesn't allow for this case, so do the rlimit checking
10069ffbb916SMiklos Szeredi  * and the actual truncation by hand.
10076f9f1180SMiklos Szeredi  */
10089e6268dbSMiklos Szeredi static int fuse_setattr(struct dentry *entry, struct iattr *attr)
10099e6268dbSMiklos Szeredi {
10109e6268dbSMiklos Szeredi 	struct inode *inode = entry->d_inode;
10119e6268dbSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
10129e6268dbSMiklos Szeredi 	struct fuse_inode *fi = get_fuse_inode(inode);
10139e6268dbSMiklos Szeredi 	struct fuse_req *req;
10149e6268dbSMiklos Szeredi 	struct fuse_setattr_in inarg;
10159e6268dbSMiklos Szeredi 	struct fuse_attr_out outarg;
10169e6268dbSMiklos Szeredi 	int err;
10179e6268dbSMiklos Szeredi 	int is_truncate = 0;
10189e6268dbSMiklos Szeredi 
10191e9a4ed9SMiklos Szeredi 	if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
10201e9a4ed9SMiklos Szeredi 		err = inode_change_ok(inode, attr);
10211e9a4ed9SMiklos Szeredi 		if (err)
10221e9a4ed9SMiklos Szeredi 			return err;
10231e9a4ed9SMiklos Szeredi 	}
10241e9a4ed9SMiklos Szeredi 
10259e6268dbSMiklos Szeredi 	if (attr->ia_valid & ATTR_SIZE) {
10269e6268dbSMiklos Szeredi 		unsigned long limit;
10279e6268dbSMiklos Szeredi 		is_truncate = 1;
1028b2d2272fSMiklos Szeredi 		if (IS_SWAPFILE(inode))
1029b2d2272fSMiklos Szeredi 			return -ETXTBSY;
10309e6268dbSMiklos Szeredi 		limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
10319e6268dbSMiklos Szeredi 		if (limit != RLIM_INFINITY && attr->ia_size > (loff_t) limit) {
10329e6268dbSMiklos Szeredi 			send_sig(SIGXFSZ, current, 0);
10339e6268dbSMiklos Szeredi 			return -EFBIG;
10349e6268dbSMiklos Szeredi 		}
10359e6268dbSMiklos Szeredi 	}
10369e6268dbSMiklos Szeredi 
1037ce1d5a49SMiklos Szeredi 	req = fuse_get_req(fc);
1038ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1039ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
10409e6268dbSMiklos Szeredi 
10419e6268dbSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
1042befc649cSMiklos Szeredi 	iattr_to_fattr(attr, &inarg);
10439e6268dbSMiklos Szeredi 	req->in.h.opcode = FUSE_SETATTR;
10449e6268dbSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
10459e6268dbSMiklos Szeredi 	req->in.numargs = 1;
10469e6268dbSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
10479e6268dbSMiklos Szeredi 	req->in.args[0].value = &inarg;
10489e6268dbSMiklos Szeredi 	req->out.numargs = 1;
10499e6268dbSMiklos Szeredi 	req->out.args[0].size = sizeof(outarg);
10509e6268dbSMiklos Szeredi 	req->out.args[0].value = &outarg;
10519e6268dbSMiklos Szeredi 	request_send(fc, req);
10529e6268dbSMiklos Szeredi 	err = req->out.h.error;
10539e6268dbSMiklos Szeredi 	fuse_put_request(fc, req);
10549e6268dbSMiklos Szeredi 	if (!err) {
10559e6268dbSMiklos Szeredi 		if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
10569e6268dbSMiklos Szeredi 			make_bad_inode(inode);
10579e6268dbSMiklos Szeredi 			err = -EIO;
10589e6268dbSMiklos Szeredi 		} else {
10599ffbb916SMiklos Szeredi 			if (is_truncate)
10609ffbb916SMiklos Szeredi 				fuse_vmtruncate(inode, outarg.attr.size);
10619e6268dbSMiklos Szeredi 			fuse_change_attributes(inode, &outarg.attr);
10629e6268dbSMiklos Szeredi 			fi->i_time = time_to_jiffies(outarg.attr_valid,
10639e6268dbSMiklos Szeredi 						     outarg.attr_valid_nsec);
10649e6268dbSMiklos Szeredi 		}
10659e6268dbSMiklos Szeredi 	} else if (err == -EINTR)
10669e6268dbSMiklos Szeredi 		fuse_invalidate_attr(inode);
10679e6268dbSMiklos Szeredi 
10689e6268dbSMiklos Szeredi 	return err;
10699e6268dbSMiklos Szeredi }
10709e6268dbSMiklos Szeredi 
1071e5e5558eSMiklos Szeredi static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
1072e5e5558eSMiklos Szeredi 			struct kstat *stat)
1073e5e5558eSMiklos Szeredi {
1074e5e5558eSMiklos Szeredi 	struct inode *inode = entry->d_inode;
1075e5e5558eSMiklos Szeredi 	int err = fuse_revalidate(entry);
1076e5e5558eSMiklos Szeredi 	if (!err)
1077e5e5558eSMiklos Szeredi 		generic_fillattr(inode, stat);
1078e5e5558eSMiklos Szeredi 
1079e5e5558eSMiklos Szeredi 	return err;
1080e5e5558eSMiklos Szeredi }
1081e5e5558eSMiklos Szeredi 
108292a8780eSMiklos Szeredi static int fuse_setxattr(struct dentry *entry, const char *name,
108392a8780eSMiklos Szeredi 			 const void *value, size_t size, int flags)
108492a8780eSMiklos Szeredi {
108592a8780eSMiklos Szeredi 	struct inode *inode = entry->d_inode;
108692a8780eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
108792a8780eSMiklos Szeredi 	struct fuse_req *req;
108892a8780eSMiklos Szeredi 	struct fuse_setxattr_in inarg;
108992a8780eSMiklos Szeredi 	int err;
109092a8780eSMiklos Szeredi 
109192a8780eSMiklos Szeredi 	if (fc->no_setxattr)
109292a8780eSMiklos Szeredi 		return -EOPNOTSUPP;
109392a8780eSMiklos Szeredi 
1094ce1d5a49SMiklos Szeredi 	req = fuse_get_req(fc);
1095ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1096ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
109792a8780eSMiklos Szeredi 
109892a8780eSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
109992a8780eSMiklos Szeredi 	inarg.size = size;
110092a8780eSMiklos Szeredi 	inarg.flags = flags;
110192a8780eSMiklos Szeredi 	req->in.h.opcode = FUSE_SETXATTR;
110292a8780eSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
110392a8780eSMiklos Szeredi 	req->in.numargs = 3;
110492a8780eSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
110592a8780eSMiklos Szeredi 	req->in.args[0].value = &inarg;
110692a8780eSMiklos Szeredi 	req->in.args[1].size = strlen(name) + 1;
110792a8780eSMiklos Szeredi 	req->in.args[1].value = name;
110892a8780eSMiklos Szeredi 	req->in.args[2].size = size;
110992a8780eSMiklos Szeredi 	req->in.args[2].value = value;
111092a8780eSMiklos Szeredi 	request_send(fc, req);
111192a8780eSMiklos Szeredi 	err = req->out.h.error;
111292a8780eSMiklos Szeredi 	fuse_put_request(fc, req);
111392a8780eSMiklos Szeredi 	if (err == -ENOSYS) {
111492a8780eSMiklos Szeredi 		fc->no_setxattr = 1;
111592a8780eSMiklos Szeredi 		err = -EOPNOTSUPP;
111692a8780eSMiklos Szeredi 	}
111792a8780eSMiklos Szeredi 	return err;
111892a8780eSMiklos Szeredi }
111992a8780eSMiklos Szeredi 
112092a8780eSMiklos Szeredi static ssize_t fuse_getxattr(struct dentry *entry, const char *name,
112192a8780eSMiklos Szeredi 			     void *value, size_t size)
112292a8780eSMiklos Szeredi {
112392a8780eSMiklos Szeredi 	struct inode *inode = entry->d_inode;
112492a8780eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
112592a8780eSMiklos Szeredi 	struct fuse_req *req;
112692a8780eSMiklos Szeredi 	struct fuse_getxattr_in inarg;
112792a8780eSMiklos Szeredi 	struct fuse_getxattr_out outarg;
112892a8780eSMiklos Szeredi 	ssize_t ret;
112992a8780eSMiklos Szeredi 
113092a8780eSMiklos Szeredi 	if (fc->no_getxattr)
113192a8780eSMiklos Szeredi 		return -EOPNOTSUPP;
113292a8780eSMiklos Szeredi 
1133ce1d5a49SMiklos Szeredi 	req = fuse_get_req(fc);
1134ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1135ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
113692a8780eSMiklos Szeredi 
113792a8780eSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
113892a8780eSMiklos Szeredi 	inarg.size = size;
113992a8780eSMiklos Szeredi 	req->in.h.opcode = FUSE_GETXATTR;
114092a8780eSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
114192a8780eSMiklos Szeredi 	req->in.numargs = 2;
114292a8780eSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
114392a8780eSMiklos Szeredi 	req->in.args[0].value = &inarg;
114492a8780eSMiklos Szeredi 	req->in.args[1].size = strlen(name) + 1;
114592a8780eSMiklos Szeredi 	req->in.args[1].value = name;
114692a8780eSMiklos Szeredi 	/* This is really two different operations rolled into one */
114792a8780eSMiklos Szeredi 	req->out.numargs = 1;
114892a8780eSMiklos Szeredi 	if (size) {
114992a8780eSMiklos Szeredi 		req->out.argvar = 1;
115092a8780eSMiklos Szeredi 		req->out.args[0].size = size;
115192a8780eSMiklos Szeredi 		req->out.args[0].value = value;
115292a8780eSMiklos Szeredi 	} else {
115392a8780eSMiklos Szeredi 		req->out.args[0].size = sizeof(outarg);
115492a8780eSMiklos Szeredi 		req->out.args[0].value = &outarg;
115592a8780eSMiklos Szeredi 	}
115692a8780eSMiklos Szeredi 	request_send(fc, req);
115792a8780eSMiklos Szeredi 	ret = req->out.h.error;
115892a8780eSMiklos Szeredi 	if (!ret)
115992a8780eSMiklos Szeredi 		ret = size ? req->out.args[0].size : outarg.size;
116092a8780eSMiklos Szeredi 	else {
116192a8780eSMiklos Szeredi 		if (ret == -ENOSYS) {
116292a8780eSMiklos Szeredi 			fc->no_getxattr = 1;
116392a8780eSMiklos Szeredi 			ret = -EOPNOTSUPP;
116492a8780eSMiklos Szeredi 		}
116592a8780eSMiklos Szeredi 	}
116692a8780eSMiklos Szeredi 	fuse_put_request(fc, req);
116792a8780eSMiklos Szeredi 	return ret;
116892a8780eSMiklos Szeredi }
116992a8780eSMiklos Szeredi 
117092a8780eSMiklos Szeredi static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
117192a8780eSMiklos Szeredi {
117292a8780eSMiklos Szeredi 	struct inode *inode = entry->d_inode;
117392a8780eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
117492a8780eSMiklos Szeredi 	struct fuse_req *req;
117592a8780eSMiklos Szeredi 	struct fuse_getxattr_in inarg;
117692a8780eSMiklos Szeredi 	struct fuse_getxattr_out outarg;
117792a8780eSMiklos Szeredi 	ssize_t ret;
117892a8780eSMiklos Szeredi 
117992a8780eSMiklos Szeredi 	if (fc->no_listxattr)
118092a8780eSMiklos Szeredi 		return -EOPNOTSUPP;
118192a8780eSMiklos Szeredi 
1182ce1d5a49SMiklos Szeredi 	req = fuse_get_req(fc);
1183ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1184ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
118592a8780eSMiklos Szeredi 
118692a8780eSMiklos Szeredi 	memset(&inarg, 0, sizeof(inarg));
118792a8780eSMiklos Szeredi 	inarg.size = size;
118892a8780eSMiklos Szeredi 	req->in.h.opcode = FUSE_LISTXATTR;
118992a8780eSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
119092a8780eSMiklos Szeredi 	req->in.numargs = 1;
119192a8780eSMiklos Szeredi 	req->in.args[0].size = sizeof(inarg);
119292a8780eSMiklos Szeredi 	req->in.args[0].value = &inarg;
119392a8780eSMiklos Szeredi 	/* This is really two different operations rolled into one */
119492a8780eSMiklos Szeredi 	req->out.numargs = 1;
119592a8780eSMiklos Szeredi 	if (size) {
119692a8780eSMiklos Szeredi 		req->out.argvar = 1;
119792a8780eSMiklos Szeredi 		req->out.args[0].size = size;
119892a8780eSMiklos Szeredi 		req->out.args[0].value = list;
119992a8780eSMiklos Szeredi 	} else {
120092a8780eSMiklos Szeredi 		req->out.args[0].size = sizeof(outarg);
120192a8780eSMiklos Szeredi 		req->out.args[0].value = &outarg;
120292a8780eSMiklos Szeredi 	}
120392a8780eSMiklos Szeredi 	request_send(fc, req);
120492a8780eSMiklos Szeredi 	ret = req->out.h.error;
120592a8780eSMiklos Szeredi 	if (!ret)
120692a8780eSMiklos Szeredi 		ret = size ? req->out.args[0].size : outarg.size;
120792a8780eSMiklos Szeredi 	else {
120892a8780eSMiklos Szeredi 		if (ret == -ENOSYS) {
120992a8780eSMiklos Szeredi 			fc->no_listxattr = 1;
121092a8780eSMiklos Szeredi 			ret = -EOPNOTSUPP;
121192a8780eSMiklos Szeredi 		}
121292a8780eSMiklos Szeredi 	}
121392a8780eSMiklos Szeredi 	fuse_put_request(fc, req);
121492a8780eSMiklos Szeredi 	return ret;
121592a8780eSMiklos Szeredi }
121692a8780eSMiklos Szeredi 
121792a8780eSMiklos Szeredi static int fuse_removexattr(struct dentry *entry, const char *name)
121892a8780eSMiklos Szeredi {
121992a8780eSMiklos Szeredi 	struct inode *inode = entry->d_inode;
122092a8780eSMiklos Szeredi 	struct fuse_conn *fc = get_fuse_conn(inode);
122192a8780eSMiklos Szeredi 	struct fuse_req *req;
122292a8780eSMiklos Szeredi 	int err;
122392a8780eSMiklos Szeredi 
122492a8780eSMiklos Szeredi 	if (fc->no_removexattr)
122592a8780eSMiklos Szeredi 		return -EOPNOTSUPP;
122692a8780eSMiklos Szeredi 
1227ce1d5a49SMiklos Szeredi 	req = fuse_get_req(fc);
1228ce1d5a49SMiklos Szeredi 	if (IS_ERR(req))
1229ce1d5a49SMiklos Szeredi 		return PTR_ERR(req);
123092a8780eSMiklos Szeredi 
123192a8780eSMiklos Szeredi 	req->in.h.opcode = FUSE_REMOVEXATTR;
123292a8780eSMiklos Szeredi 	req->in.h.nodeid = get_node_id(inode);
123392a8780eSMiklos Szeredi 	req->in.numargs = 1;
123492a8780eSMiklos Szeredi 	req->in.args[0].size = strlen(name) + 1;
123592a8780eSMiklos Szeredi 	req->in.args[0].value = name;
123692a8780eSMiklos Szeredi 	request_send(fc, req);
123792a8780eSMiklos Szeredi 	err = req->out.h.error;
123892a8780eSMiklos Szeredi 	fuse_put_request(fc, req);
123992a8780eSMiklos Szeredi 	if (err == -ENOSYS) {
124092a8780eSMiklos Szeredi 		fc->no_removexattr = 1;
124192a8780eSMiklos Szeredi 		err = -EOPNOTSUPP;
124292a8780eSMiklos Szeredi 	}
124392a8780eSMiklos Szeredi 	return err;
124492a8780eSMiklos Szeredi }
124592a8780eSMiklos Szeredi 
1246754661f1SArjan van de Ven static const struct inode_operations fuse_dir_inode_operations = {
1247e5e5558eSMiklos Szeredi 	.lookup		= fuse_lookup,
12489e6268dbSMiklos Szeredi 	.mkdir		= fuse_mkdir,
12499e6268dbSMiklos Szeredi 	.symlink	= fuse_symlink,
12509e6268dbSMiklos Szeredi 	.unlink		= fuse_unlink,
12519e6268dbSMiklos Szeredi 	.rmdir		= fuse_rmdir,
12529e6268dbSMiklos Szeredi 	.rename		= fuse_rename,
12539e6268dbSMiklos Szeredi 	.link		= fuse_link,
12549e6268dbSMiklos Szeredi 	.setattr	= fuse_setattr,
12559e6268dbSMiklos Szeredi 	.create		= fuse_create,
12569e6268dbSMiklos Szeredi 	.mknod		= fuse_mknod,
1257e5e5558eSMiklos Szeredi 	.permission	= fuse_permission,
1258e5e5558eSMiklos Szeredi 	.getattr	= fuse_getattr,
125992a8780eSMiklos Szeredi 	.setxattr	= fuse_setxattr,
126092a8780eSMiklos Szeredi 	.getxattr	= fuse_getxattr,
126192a8780eSMiklos Szeredi 	.listxattr	= fuse_listxattr,
126292a8780eSMiklos Szeredi 	.removexattr	= fuse_removexattr,
1263e5e5558eSMiklos Szeredi };
1264e5e5558eSMiklos Szeredi 
12654b6f5d20SArjan van de Ven static const struct file_operations fuse_dir_operations = {
1266b6aeadedSMiklos Szeredi 	.llseek		= generic_file_llseek,
1267e5e5558eSMiklos Szeredi 	.read		= generic_read_dir,
1268e5e5558eSMiklos Szeredi 	.readdir	= fuse_readdir,
1269e5e5558eSMiklos Szeredi 	.open		= fuse_dir_open,
1270e5e5558eSMiklos Szeredi 	.release	= fuse_dir_release,
127182547981SMiklos Szeredi 	.fsync		= fuse_dir_fsync,
1272e5e5558eSMiklos Szeredi };
1273e5e5558eSMiklos Szeredi 
1274754661f1SArjan van de Ven static const struct inode_operations fuse_common_inode_operations = {
12759e6268dbSMiklos Szeredi 	.setattr	= fuse_setattr,
1276e5e5558eSMiklos Szeredi 	.permission	= fuse_permission,
1277e5e5558eSMiklos Szeredi 	.getattr	= fuse_getattr,
127892a8780eSMiklos Szeredi 	.setxattr	= fuse_setxattr,
127992a8780eSMiklos Szeredi 	.getxattr	= fuse_getxattr,
128092a8780eSMiklos Szeredi 	.listxattr	= fuse_listxattr,
128192a8780eSMiklos Szeredi 	.removexattr	= fuse_removexattr,
1282e5e5558eSMiklos Szeredi };
1283e5e5558eSMiklos Szeredi 
1284754661f1SArjan van de Ven static const struct inode_operations fuse_symlink_inode_operations = {
12859e6268dbSMiklos Szeredi 	.setattr	= fuse_setattr,
1286e5e5558eSMiklos Szeredi 	.follow_link	= fuse_follow_link,
1287e5e5558eSMiklos Szeredi 	.put_link	= fuse_put_link,
1288e5e5558eSMiklos Szeredi 	.readlink	= generic_readlink,
1289e5e5558eSMiklos Szeredi 	.getattr	= fuse_getattr,
129092a8780eSMiklos Szeredi 	.setxattr	= fuse_setxattr,
129192a8780eSMiklos Szeredi 	.getxattr	= fuse_getxattr,
129292a8780eSMiklos Szeredi 	.listxattr	= fuse_listxattr,
129392a8780eSMiklos Szeredi 	.removexattr	= fuse_removexattr,
1294e5e5558eSMiklos Szeredi };
1295e5e5558eSMiklos Szeredi 
1296e5e5558eSMiklos Szeredi void fuse_init_common(struct inode *inode)
1297e5e5558eSMiklos Szeredi {
1298e5e5558eSMiklos Szeredi 	inode->i_op = &fuse_common_inode_operations;
1299e5e5558eSMiklos Szeredi }
1300e5e5558eSMiklos Szeredi 
1301e5e5558eSMiklos Szeredi void fuse_init_dir(struct inode *inode)
1302e5e5558eSMiklos Szeredi {
1303e5e5558eSMiklos Szeredi 	inode->i_op = &fuse_dir_inode_operations;
1304e5e5558eSMiklos Szeredi 	inode->i_fop = &fuse_dir_operations;
1305e5e5558eSMiklos Szeredi }
1306e5e5558eSMiklos Szeredi 
1307e5e5558eSMiklos Szeredi void fuse_init_symlink(struct inode *inode)
1308e5e5558eSMiklos Szeredi {
1309e5e5558eSMiklos Szeredi 	inode->i_op = &fuse_symlink_inode_operations;
1310e5e5558eSMiklos Szeredi }
1311