blob: 72a5d5b04494ded2468bc4a2f5f30e30c9ca12f7 [file] [log] [blame]
Miklos Szeredie5e55582005-09-09 13:10:28 -07001/*
2 FUSE: Filesystem in Userspace
Miklos Szeredi1729a162008-11-26 12:03:54 +01003 Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu>
Miklos Szeredie5e55582005-09-09 13:10:28 -07004
5 This program can be distributed under the terms of the GNU GPL.
6 See the file COPYING.
7*/
8
9#include "fuse_i.h"
10
11#include <linux/pagemap.h>
12#include <linux/file.h>
Miklos Szeredie5e55582005-09-09 13:10:28 -070013#include <linux/sched.h>
14#include <linux/namei.h>
Miklos Szeredi07e77dc2010-12-07 20:16:56 +010015#include <linux/slab.h>
Miklos Szeredie5e55582005-09-09 13:10:28 -070016
Al Viro8d3af7f2013-05-18 03:03:58 -040017static bool fuse_use_readdirplus(struct inode *dir, struct dir_context *ctx)
Feng Shuo4582a4a2013-01-15 11:23:28 +080018{
19 struct fuse_conn *fc = get_fuse_conn(dir);
20 struct fuse_inode *fi = get_fuse_inode(dir);
21
22 if (!fc->do_readdirplus)
23 return false;
Eric Wong634734b2013-02-06 22:29:01 +000024 if (!fc->readdirplus_auto)
25 return true;
Feng Shuo4582a4a2013-01-15 11:23:28 +080026 if (test_and_clear_bit(FUSE_I_ADVISE_RDPLUS, &fi->state))
27 return true;
Al Viro8d3af7f2013-05-18 03:03:58 -040028 if (ctx->pos == 0)
Feng Shuo4582a4a2013-01-15 11:23:28 +080029 return true;
30 return false;
31}
32
33static void fuse_advise_use_readdirplus(struct inode *dir)
34{
35 struct fuse_inode *fi = get_fuse_inode(dir);
36
37 set_bit(FUSE_I_ADVISE_RDPLUS, &fi->state);
38}
39
Miklos Szeredi0a0898c2006-07-30 03:04:10 -070040#if BITS_PER_LONG >= 64
41static inline void fuse_dentry_settime(struct dentry *entry, u64 time)
42{
43 entry->d_time = time;
44}
45
46static inline u64 fuse_dentry_time(struct dentry *entry)
47{
48 return entry->d_time;
49}
50#else
51/*
52 * On 32 bit archs store the high 32 bits of time in d_fsdata
53 */
54static void fuse_dentry_settime(struct dentry *entry, u64 time)
55{
56 entry->d_time = time;
57 entry->d_fsdata = (void *) (unsigned long) (time >> 32);
58}
59
60static u64 fuse_dentry_time(struct dentry *entry)
61{
62 return (u64) entry->d_time +
63 ((u64) (unsigned long) entry->d_fsdata << 32);
64}
65#endif
66
Miklos Szeredi6f9f1182006-01-06 00:19:39 -080067/*
68 * FUSE caches dentries and attributes with separate timeout. The
69 * time in jiffies until the dentry/attributes are valid is stored in
70 * dentry->d_time and fuse_inode->i_time respectively.
71 */
72
73/*
74 * Calculate the time in jiffies until a dentry/attributes are valid
75 */
Miklos Szeredi0a0898c2006-07-30 03:04:10 -070076static u64 time_to_jiffies(unsigned long sec, unsigned long nsec)
Miklos Szeredie5e55582005-09-09 13:10:28 -070077{
Miklos Szeredi685d16d2006-07-30 03:04:08 -070078 if (sec || nsec) {
79 struct timespec ts = {sec, nsec};
Miklos Szeredi0a0898c2006-07-30 03:04:10 -070080 return get_jiffies_64() + timespec_to_jiffies(&ts);
Miklos Szeredi685d16d2006-07-30 03:04:08 -070081 } else
Miklos Szeredi0a0898c2006-07-30 03:04:10 -070082 return 0;
Miklos Szeredie5e55582005-09-09 13:10:28 -070083}
84
Miklos Szeredi6f9f1182006-01-06 00:19:39 -080085/*
86 * Set dentry and possibly attribute timeouts from the lookup/mk*
87 * replies
88 */
Miklos Szeredi1fb69e72007-10-18 03:06:58 -070089static void fuse_change_entry_timeout(struct dentry *entry,
90 struct fuse_entry_out *o)
Miklos Szeredi0aa7c692006-01-06 00:19:34 -080091{
Miklos Szeredi0a0898c2006-07-30 03:04:10 -070092 fuse_dentry_settime(entry,
93 time_to_jiffies(o->entry_valid, o->entry_valid_nsec));
Miklos Szeredi1fb69e72007-10-18 03:06:58 -070094}
95
96static u64 attr_timeout(struct fuse_attr_out *o)
97{
98 return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
99}
100
101static u64 entry_attr_timeout(struct fuse_entry_out *o)
102{
103 return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800104}
105
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800106/*
107 * Mark the attributes as stale, so that at the next call to
108 * ->getattr() they will be fetched from userspace
109 */
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800110void fuse_invalidate_attr(struct inode *inode)
111{
Miklos Szeredi0a0898c2006-07-30 03:04:10 -0700112 get_fuse_inode(inode)->i_time = 0;
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800113}
114
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800115/*
116 * Just mark the entry as stale, so that a next attempt to look it up
117 * will result in a new lookup call to userspace
118 *
119 * This is called when a dentry is about to become negative and the
120 * timeout is unknown (unlink, rmdir, rename and in some cases
121 * lookup)
122 */
Miklos Szeredidbd561d2008-07-25 01:49:00 -0700123void fuse_invalidate_entry_cache(struct dentry *entry)
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800124{
Miklos Szeredi0a0898c2006-07-30 03:04:10 -0700125 fuse_dentry_settime(entry, 0);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800126}
127
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800128/*
129 * Same as fuse_invalidate_entry_cache(), but also try to remove the
130 * dentry from the hash
131 */
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800132static void fuse_invalidate_entry(struct dentry *entry)
133{
134 d_invalidate(entry);
135 fuse_invalidate_entry_cache(entry);
Miklos Szeredi0aa7c692006-01-06 00:19:34 -0800136}
137
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700138static void fuse_lookup_init(struct fuse_conn *fc, struct fuse_req *req,
139 u64 nodeid, struct qstr *name,
Miklos Szeredie5e55582005-09-09 13:10:28 -0700140 struct fuse_entry_out *outarg)
141{
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700142 memset(outarg, 0, sizeof(struct fuse_entry_out));
Miklos Szeredie5e55582005-09-09 13:10:28 -0700143 req->in.h.opcode = FUSE_LOOKUP;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700144 req->in.h.nodeid = nodeid;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700145 req->in.numargs = 1;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700146 req->in.args[0].size = name->len + 1;
147 req->in.args[0].value = name->name;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700148 req->out.numargs = 1;
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700149 if (fc->minor < 9)
150 req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
151 else
152 req->out.args[0].size = sizeof(struct fuse_entry_out);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700153 req->out.args[0].value = outarg;
154}
155
Miklos Szeredi5c5c5e52008-04-30 00:54:43 -0700156u64 fuse_get_attr_version(struct fuse_conn *fc)
Miklos Szeredi7dca9fd2007-11-28 16:21:59 -0800157{
158 u64 curr_version;
159
160 /*
161 * The spin lock isn't actually needed on 64bit archs, but we
162 * don't yet care too much about such optimizations.
163 */
164 spin_lock(&fc->lock);
165 curr_version = fc->attr_version;
166 spin_unlock(&fc->lock);
167
168 return curr_version;
169}
170
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800171/*
172 * Check whether the dentry is still valid
173 *
174 * If the entry validity timeout has expired and the dentry is
175 * positive, try to redo the lookup. If the lookup results in a
176 * different inode, then let the VFS invalidate the dentry and redo
177 * the lookup once more. If the lookup results in the same inode,
178 * then refresh the attributes, timeouts and mark the dentry valid.
179 */
Al Viro0b728e12012-06-10 16:03:43 -0400180static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
Miklos Szeredie5e55582005-09-09 13:10:28 -0700181{
Nick Piggin34286d62011-01-07 17:49:57 +1100182 struct inode *inode;
Miklos Szeredi28420da2013-06-03 14:40:22 +0200183 struct dentry *parent;
184 struct fuse_conn *fc;
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800185
Miklos Szeredie7c0a162011-03-21 13:58:06 +0100186 inode = ACCESS_ONCE(entry->d_inode);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800187 if (inode && is_bad_inode(inode))
Miklos Szeredie5e55582005-09-09 13:10:28 -0700188 return 0;
Miklos Szeredi0a0898c2006-07-30 03:04:10 -0700189 else if (fuse_dentry_time(entry) < get_jiffies_64()) {
Miklos Szeredie5e55582005-09-09 13:10:28 -0700190 int err;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700191 struct fuse_entry_out outarg;
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800192 struct fuse_req *req;
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100193 struct fuse_forget_link *forget;
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700194 u64 attr_version;
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800195
Miklos Szeredi50322fe2006-02-28 16:59:03 -0800196 /* For negative dentries, always do a fresh lookup */
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800197 if (!inode)
198 return 0;
199
Al Viro0b728e12012-06-10 16:03:43 -0400200 if (flags & LOOKUP_RCU)
Miklos Szeredie7c0a162011-03-21 13:58:06 +0100201 return -ECHILD;
202
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800203 fc = get_fuse_conn(inode);
Maxim Patlasovb111c8c2012-10-26 19:48:30 +0400204 req = fuse_get_req_nopages(fc);
Miklos Szeredice1d5a42006-04-10 22:54:58 -0700205 if (IS_ERR(req))
Miklos Szeredie5e55582005-09-09 13:10:28 -0700206 return 0;
207
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100208 forget = fuse_alloc_forget();
209 if (!forget) {
Miklos Szeredi2d510132006-11-25 11:09:20 -0800210 fuse_put_request(fc, req);
211 return 0;
212 }
213
Miklos Szeredi7dca9fd2007-11-28 16:21:59 -0800214 attr_version = fuse_get_attr_version(fc);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700215
Miklos Szeredie956edd2006-10-17 00:10:12 -0700216 parent = dget_parent(entry);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700217 fuse_lookup_init(fc, req, get_node_id(parent->d_inode),
218 &entry->d_name, &outarg);
Tejun Heob93f8582008-11-26 12:03:55 +0100219 fuse_request_send(fc, req);
Miklos Szeredie956edd2006-10-17 00:10:12 -0700220 dput(parent);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700221 err = req->out.h.error;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800222 fuse_put_request(fc, req);
Miklos Szeredi50322fe2006-02-28 16:59:03 -0800223 /* Zero nodeid is same as -ENOENT */
224 if (!err && !outarg.nodeid)
225 err = -ENOENT;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700226 if (!err) {
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800227 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700228 if (outarg.nodeid != get_node_id(inode)) {
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100229 fuse_queue_forget(fc, forget, outarg.nodeid, 1);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700230 return 0;
231 }
Miklos Szeredi8da5ff22006-10-17 00:10:08 -0700232 spin_lock(&fc->lock);
Miklos Szeredi1729a162008-11-26 12:03:54 +0100233 fi->nlookup++;
Miklos Szeredi8da5ff22006-10-17 00:10:08 -0700234 spin_unlock(&fc->lock);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700235 }
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100236 kfree(forget);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700237 if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
Miklos Szeredie5e55582005-09-09 13:10:28 -0700238 return 0;
239
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700240 fuse_change_attributes(inode, &outarg.attr,
241 entry_attr_timeout(&outarg),
242 attr_version);
243 fuse_change_entry_timeout(entry, &outarg);
Miklos Szeredi28420da2013-06-03 14:40:22 +0200244 } else if (inode) {
245 fc = get_fuse_conn(inode);
246 if (fc->readdirplus_auto) {
247 parent = dget_parent(entry);
248 fuse_advise_use_readdirplus(parent->d_inode);
249 dput(parent);
250 }
Miklos Szeredie5e55582005-09-09 13:10:28 -0700251 }
252 return 1;
253}
254
Miklos Szeredi8bfc0162006-01-16 22:14:28 -0800255static int invalid_nodeid(u64 nodeid)
Miklos Szeredi2827d0b22005-11-28 13:44:16 -0800256{
257 return !nodeid || nodeid == FUSE_ROOT_ID;
258}
259
Al Viro42695902009-02-20 05:59:13 +0000260const struct dentry_operations fuse_dentry_operations = {
Miklos Szeredie5e55582005-09-09 13:10:28 -0700261 .d_revalidate = fuse_dentry_revalidate,
262};
263
Timo Savolaa5bfffac2007-04-08 16:04:00 -0700264int fuse_valid_type(int m)
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800265{
266 return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) ||
267 S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
268}
269
Miklos Szeredid2a85162006-10-17 00:10:11 -0700270/*
271 * Add a directory inode to a dentry, ensuring that no other dentry
272 * refers to this inode. Called with fc->inst_mutex.
273 */
Miklos Szeredi0de62562008-07-25 01:48:59 -0700274static struct dentry *fuse_d_add_directory(struct dentry *entry,
275 struct inode *inode)
Miklos Szeredid2a85162006-10-17 00:10:11 -0700276{
277 struct dentry *alias = d_find_alias(inode);
Miklos Szeredi0de62562008-07-25 01:48:59 -0700278 if (alias && !(alias->d_flags & DCACHE_DISCONNECTED)) {
Miklos Szeredid2a85162006-10-17 00:10:11 -0700279 /* This tries to shrink the subtree below alias */
280 fuse_invalidate_entry(alias);
281 dput(alias);
Al Virob3d9b7a2012-06-09 13:51:19 -0400282 if (!hlist_empty(&inode->i_dentry))
Miklos Szeredi0de62562008-07-25 01:48:59 -0700283 return ERR_PTR(-EBUSY);
284 } else {
285 dput(alias);
Miklos Szeredid2a85162006-10-17 00:10:11 -0700286 }
Miklos Szeredi0de62562008-07-25 01:48:59 -0700287 return d_splice_alias(inode, entry);
Miklos Szeredid2a85162006-10-17 00:10:11 -0700288}
289
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700290int fuse_lookup_name(struct super_block *sb, u64 nodeid, struct qstr *name,
291 struct fuse_entry_out *outarg, struct inode **inode)
292{
293 struct fuse_conn *fc = get_fuse_conn_super(sb);
294 struct fuse_req *req;
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100295 struct fuse_forget_link *forget;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700296 u64 attr_version;
297 int err;
298
299 *inode = NULL;
300 err = -ENAMETOOLONG;
301 if (name->len > FUSE_NAME_MAX)
302 goto out;
303
Maxim Patlasovb111c8c2012-10-26 19:48:30 +0400304 req = fuse_get_req_nopages(fc);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700305 err = PTR_ERR(req);
306 if (IS_ERR(req))
307 goto out;
308
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100309 forget = fuse_alloc_forget();
310 err = -ENOMEM;
311 if (!forget) {
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700312 fuse_put_request(fc, req);
313 goto out;
314 }
315
316 attr_version = fuse_get_attr_version(fc);
317
318 fuse_lookup_init(fc, req, nodeid, name, outarg);
Tejun Heob93f8582008-11-26 12:03:55 +0100319 fuse_request_send(fc, req);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700320 err = req->out.h.error;
321 fuse_put_request(fc, req);
322 /* Zero nodeid is same as -ENOENT, but with valid timeout */
323 if (err || !outarg->nodeid)
324 goto out_put_forget;
325
326 err = -EIO;
327 if (!outarg->nodeid)
328 goto out_put_forget;
329 if (!fuse_valid_type(outarg->attr.mode))
330 goto out_put_forget;
331
332 *inode = fuse_iget(sb, outarg->nodeid, outarg->generation,
333 &outarg->attr, entry_attr_timeout(outarg),
334 attr_version);
335 err = -ENOMEM;
336 if (!*inode) {
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100337 fuse_queue_forget(fc, forget, outarg->nodeid, 1);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700338 goto out;
339 }
340 err = 0;
341
342 out_put_forget:
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100343 kfree(forget);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700344 out:
345 return err;
346}
347
Miklos Szeredi0aa7c692006-01-06 00:19:34 -0800348static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
Al Viro00cd8dd2012-06-10 17:13:09 -0400349 unsigned int flags)
Miklos Szeredie5e55582005-09-09 13:10:28 -0700350{
351 int err;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700352 struct fuse_entry_out outarg;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700353 struct inode *inode;
Miklos Szeredi0de62562008-07-25 01:48:59 -0700354 struct dentry *newent;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700355 struct fuse_conn *fc = get_fuse_conn(dir);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700356 bool outarg_valid = true;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700357
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700358 err = fuse_lookup_name(dir->i_sb, get_node_id(dir), &entry->d_name,
359 &outarg, &inode);
360 if (err == -ENOENT) {
361 outarg_valid = false;
362 err = 0;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800363 }
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700364 if (err)
365 goto out_err;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800366
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700367 err = -EIO;
368 if (inode && get_node_id(inode) == FUSE_ROOT_ID)
369 goto out_iput;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700370
Miklos Szeredid2a85162006-10-17 00:10:11 -0700371 if (inode && S_ISDIR(inode->i_mode)) {
372 mutex_lock(&fc->inst_mutex);
Miklos Szeredi0de62562008-07-25 01:48:59 -0700373 newent = fuse_d_add_directory(entry, inode);
Miklos Szeredid2a85162006-10-17 00:10:11 -0700374 mutex_unlock(&fc->inst_mutex);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700375 err = PTR_ERR(newent);
376 if (IS_ERR(newent))
377 goto out_iput;
378 } else {
Miklos Szeredi0de62562008-07-25 01:48:59 -0700379 newent = d_splice_alias(inode, entry);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700380 }
Miklos Szeredid2a85162006-10-17 00:10:11 -0700381
Miklos Szeredi0de62562008-07-25 01:48:59 -0700382 entry = newent ? newent : entry;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700383 if (outarg_valid)
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700384 fuse_change_entry_timeout(entry, &outarg);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800385 else
386 fuse_invalidate_entry_cache(entry);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700387
Feng Shuo4582a4a2013-01-15 11:23:28 +0800388 fuse_advise_use_readdirplus(dir);
Miklos Szeredi0de62562008-07-25 01:48:59 -0700389 return newent;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700390
391 out_iput:
392 iput(inode);
393 out_err:
394 return ERR_PTR(err);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700395}
396
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800397/*
398 * Atomic create+open operation
399 *
400 * If the filesystem doesn't support this, then fall back to separate
401 * 'mknod' + 'open' requests.
402 */
Al Virod9585272012-06-22 12:39:14 +0400403static int fuse_create_open(struct inode *dir, struct dentry *entry,
Al Viro30d90492012-06-22 12:40:19 +0400404 struct file *file, unsigned flags,
Al Virod9585272012-06-22 12:39:14 +0400405 umode_t mode, int *opened)
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800406{
407 int err;
408 struct inode *inode;
409 struct fuse_conn *fc = get_fuse_conn(dir);
410 struct fuse_req *req;
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100411 struct fuse_forget_link *forget;
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200412 struct fuse_create_in inarg;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800413 struct fuse_open_out outopen;
414 struct fuse_entry_out outentry;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800415 struct fuse_file *ff;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800416
Miklos Szerediaf109bc2012-08-15 13:01:24 +0200417 /* Userspace expects S_IFREG in create mode */
418 BUG_ON((mode & S_IFMT) != S_IFREG);
419
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100420 forget = fuse_alloc_forget();
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200421 err = -ENOMEM;
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100422 if (!forget)
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200423 goto out_err;
Miklos Szeredi51eb01e2006-06-25 05:48:50 -0700424
Maxim Patlasovb111c8c2012-10-26 19:48:30 +0400425 req = fuse_get_req_nopages(fc);
Miklos Szeredi51eb01e2006-06-25 05:48:50 -0700426 err = PTR_ERR(req);
Miklos Szeredice1d5a42006-04-10 22:54:58 -0700427 if (IS_ERR(req))
Miklos Szeredi51eb01e2006-06-25 05:48:50 -0700428 goto out_put_forget_req;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800429
Miklos Szeredice1d5a42006-04-10 22:54:58 -0700430 err = -ENOMEM;
Tejun Heoacf99432008-11-26 12:03:55 +0100431 ff = fuse_file_alloc(fc);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800432 if (!ff)
433 goto out_put_request;
434
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200435 if (!fc->dont_mask)
436 mode &= ~current_umask();
437
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800438 flags &= ~O_NOCTTY;
439 memset(&inarg, 0, sizeof(inarg));
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700440 memset(&outentry, 0, sizeof(outentry));
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800441 inarg.flags = flags;
442 inarg.mode = mode;
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200443 inarg.umask = current_umask();
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800444 req->in.h.opcode = FUSE_CREATE;
445 req->in.h.nodeid = get_node_id(dir);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800446 req->in.numargs = 2;
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200447 req->in.args[0].size = fc->minor < 12 ? sizeof(struct fuse_open_in) :
448 sizeof(inarg);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800449 req->in.args[0].value = &inarg;
450 req->in.args[1].size = entry->d_name.len + 1;
451 req->in.args[1].value = entry->d_name.name;
452 req->out.numargs = 2;
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700453 if (fc->minor < 9)
454 req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
455 else
456 req->out.args[0].size = sizeof(outentry);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800457 req->out.args[0].value = &outentry;
458 req->out.args[1].size = sizeof(outopen);
459 req->out.args[1].value = &outopen;
Tejun Heob93f8582008-11-26 12:03:55 +0100460 fuse_request_send(fc, req);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800461 err = req->out.h.error;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200462 if (err)
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800463 goto out_free_ff;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800464
465 err = -EIO;
Miklos Szeredi2827d0b22005-11-28 13:44:16 -0800466 if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid))
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800467 goto out_free_ff;
468
Miklos Szeredi51eb01e2006-06-25 05:48:50 -0700469 fuse_put_request(fc, req);
Miklos Szeredic7b71432009-04-28 16:56:37 +0200470 ff->fh = outopen.fh;
471 ff->nodeid = outentry.nodeid;
472 ff->open_flags = outopen.open_flags;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800473 inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700474 &outentry.attr, entry_attr_timeout(&outentry), 0);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800475 if (!inode) {
476 flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
Miklos Szeredi8b0797a2009-04-28 16:56:39 +0200477 fuse_sync_release(ff, flags);
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100478 fuse_queue_forget(fc, forget, outentry.nodeid, 1);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200479 err = -ENOMEM;
480 goto out_err;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800481 }
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100482 kfree(forget);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800483 d_instantiate(entry, inode);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700484 fuse_change_entry_timeout(entry, &outentry);
Miklos Szeredi0952b2a2008-02-06 01:38:38 -0800485 fuse_invalidate_attr(dir);
Al Viro30d90492012-06-22 12:40:19 +0400486 err = finish_open(file, entry, generic_file_open, opened);
487 if (err) {
Miklos Szeredi8b0797a2009-04-28 16:56:39 +0200488 fuse_sync_release(ff, flags);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200489 } else {
490 file->private_data = fuse_file_get(ff);
491 fuse_finish_open(inode, file);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800492 }
Al Virod9585272012-06-22 12:39:14 +0400493 return err;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800494
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200495out_free_ff:
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800496 fuse_file_free(ff);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200497out_put_request:
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800498 fuse_put_request(fc, req);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200499out_put_forget_req:
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100500 kfree(forget);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200501out_err:
Al Virod9585272012-06-22 12:39:14 +0400502 return err;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200503}
504
505static int fuse_mknod(struct inode *, struct dentry *, umode_t, dev_t);
Al Virod9585272012-06-22 12:39:14 +0400506static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
Al Viro30d90492012-06-22 12:40:19 +0400507 struct file *file, unsigned flags,
Al Virod9585272012-06-22 12:39:14 +0400508 umode_t mode, int *opened)
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200509{
510 int err;
511 struct fuse_conn *fc = get_fuse_conn(dir);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200512 struct dentry *res = NULL;
513
514 if (d_unhashed(entry)) {
Al Viro00cd8dd2012-06-10 17:13:09 -0400515 res = fuse_lookup(dir, entry, 0);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200516 if (IS_ERR(res))
Al Virod9585272012-06-22 12:39:14 +0400517 return PTR_ERR(res);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200518
519 if (res)
520 entry = res;
521 }
522
523 if (!(flags & O_CREAT) || entry->d_inode)
524 goto no_open;
525
526 /* Only creates */
Al Viro47237682012-06-10 05:01:45 -0400527 *opened |= FILE_CREATED;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200528
529 if (fc->no_create)
530 goto mknod;
531
Al Viro30d90492012-06-22 12:40:19 +0400532 err = fuse_create_open(dir, entry, file, flags, mode, opened);
Al Virod9585272012-06-22 12:39:14 +0400533 if (err == -ENOSYS) {
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200534 fc->no_create = 1;
535 goto mknod;
536 }
537out_dput:
538 dput(res);
Al Virod9585272012-06-22 12:39:14 +0400539 return err;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200540
541mknod:
542 err = fuse_mknod(dir, entry, mode, 0);
Al Virod9585272012-06-22 12:39:14 +0400543 if (err)
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200544 goto out_dput;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200545no_open:
Al Viroe45198a2012-06-10 06:48:09 -0400546 return finish_no_open(file, res);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800547}
548
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800549/*
550 * Code shared between mknod, mkdir, symlink and link
551 */
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700552static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
553 struct inode *dir, struct dentry *entry,
Al Viro541af6a2011-07-26 03:17:33 -0400554 umode_t mode)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700555{
556 struct fuse_entry_out outarg;
557 struct inode *inode;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700558 int err;
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100559 struct fuse_forget_link *forget;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800560
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100561 forget = fuse_alloc_forget();
562 if (!forget) {
Miklos Szeredi2d510132006-11-25 11:09:20 -0800563 fuse_put_request(fc, req);
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100564 return -ENOMEM;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800565 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700566
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700567 memset(&outarg, 0, sizeof(outarg));
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700568 req->in.h.nodeid = get_node_id(dir);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700569 req->out.numargs = 1;
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700570 if (fc->minor < 9)
571 req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
572 else
573 req->out.args[0].size = sizeof(outarg);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700574 req->out.args[0].value = &outarg;
Tejun Heob93f8582008-11-26 12:03:55 +0100575 fuse_request_send(fc, req);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700576 err = req->out.h.error;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800577 fuse_put_request(fc, req);
578 if (err)
579 goto out_put_forget_req;
580
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800581 err = -EIO;
582 if (invalid_nodeid(outarg.nodeid))
Miklos Szeredi2d510132006-11-25 11:09:20 -0800583 goto out_put_forget_req;
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800584
585 if ((outarg.attr.mode ^ mode) & S_IFMT)
Miklos Szeredi2d510132006-11-25 11:09:20 -0800586 goto out_put_forget_req;
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800587
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700588 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700589 &outarg.attr, entry_attr_timeout(&outarg), 0);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700590 if (!inode) {
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100591 fuse_queue_forget(fc, forget, outarg.nodeid, 1);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700592 return -ENOMEM;
593 }
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100594 kfree(forget);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700595
Miklos Szeredid2a85162006-10-17 00:10:11 -0700596 if (S_ISDIR(inode->i_mode)) {
597 struct dentry *alias;
598 mutex_lock(&fc->inst_mutex);
599 alias = d_find_alias(inode);
600 if (alias) {
601 /* New directory must have moved since mkdir */
602 mutex_unlock(&fc->inst_mutex);
603 dput(alias);
604 iput(inode);
605 return -EBUSY;
606 }
607 d_instantiate(entry, inode);
608 mutex_unlock(&fc->inst_mutex);
609 } else
610 d_instantiate(entry, inode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700611
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700612 fuse_change_entry_timeout(entry, &outarg);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700613 fuse_invalidate_attr(dir);
614 return 0;
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800615
Miklos Szeredi2d510132006-11-25 11:09:20 -0800616 out_put_forget_req:
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100617 kfree(forget);
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800618 return err;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700619}
620
Al Viro1a67aaf2011-07-26 01:52:52 -0400621static int fuse_mknod(struct inode *dir, struct dentry *entry, umode_t mode,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700622 dev_t rdev)
623{
624 struct fuse_mknod_in inarg;
625 struct fuse_conn *fc = get_fuse_conn(dir);
Maxim Patlasovb111c8c2012-10-26 19:48:30 +0400626 struct fuse_req *req = fuse_get_req_nopages(fc);
Miklos Szeredice1d5a42006-04-10 22:54:58 -0700627 if (IS_ERR(req))
628 return PTR_ERR(req);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700629
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200630 if (!fc->dont_mask)
631 mode &= ~current_umask();
632
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700633 memset(&inarg, 0, sizeof(inarg));
634 inarg.mode = mode;
635 inarg.rdev = new_encode_dev(rdev);
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200636 inarg.umask = current_umask();
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700637 req->in.h.opcode = FUSE_MKNOD;
638 req->in.numargs = 2;
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200639 req->in.args[0].size = fc->minor < 12 ? FUSE_COMPAT_MKNOD_IN_SIZE :
640 sizeof(inarg);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700641 req->in.args[0].value = &inarg;
642 req->in.args[1].size = entry->d_name.len + 1;
643 req->in.args[1].value = entry->d_name.name;
644 return create_new_entry(fc, req, dir, entry, mode);
645}
646
Al Viro4acdaf22011-07-26 01:42:34 -0400647static int fuse_create(struct inode *dir, struct dentry *entry, umode_t mode,
Al Viroebfc3b42012-06-10 18:05:36 -0400648 bool excl)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700649{
650 return fuse_mknod(dir, entry, mode, 0);
651}
652
Al Viro18bb1db2011-07-26 01:41:39 -0400653static int fuse_mkdir(struct inode *dir, struct dentry *entry, umode_t mode)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700654{
655 struct fuse_mkdir_in inarg;
656 struct fuse_conn *fc = get_fuse_conn(dir);
Maxim Patlasovb111c8c2012-10-26 19:48:30 +0400657 struct fuse_req *req = fuse_get_req_nopages(fc);
Miklos Szeredice1d5a42006-04-10 22:54:58 -0700658 if (IS_ERR(req))
659 return PTR_ERR(req);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700660
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200661 if (!fc->dont_mask)
662 mode &= ~current_umask();
663
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700664 memset(&inarg, 0, sizeof(inarg));
665 inarg.mode = mode;
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200666 inarg.umask = current_umask();
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700667 req->in.h.opcode = FUSE_MKDIR;
668 req->in.numargs = 2;
669 req->in.args[0].size = sizeof(inarg);
670 req->in.args[0].value = &inarg;
671 req->in.args[1].size = entry->d_name.len + 1;
672 req->in.args[1].value = entry->d_name.name;
673 return create_new_entry(fc, req, dir, entry, S_IFDIR);
674}
675
676static int fuse_symlink(struct inode *dir, struct dentry *entry,
677 const char *link)
678{
679 struct fuse_conn *fc = get_fuse_conn(dir);
680 unsigned len = strlen(link) + 1;
Maxim Patlasovb111c8c2012-10-26 19:48:30 +0400681 struct fuse_req *req = fuse_get_req_nopages(fc);
Miklos Szeredice1d5a42006-04-10 22:54:58 -0700682 if (IS_ERR(req))
683 return PTR_ERR(req);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700684
685 req->in.h.opcode = FUSE_SYMLINK;
686 req->in.numargs = 2;
687 req->in.args[0].size = entry->d_name.len + 1;
688 req->in.args[0].value = entry->d_name.name;
689 req->in.args[1].size = len;
690 req->in.args[1].value = link;
691 return create_new_entry(fc, req, dir, entry, S_IFLNK);
692}
693
694static int fuse_unlink(struct inode *dir, struct dentry *entry)
695{
696 int err;
697 struct fuse_conn *fc = get_fuse_conn(dir);
Maxim Patlasovb111c8c2012-10-26 19:48:30 +0400698 struct fuse_req *req = fuse_get_req_nopages(fc);
Miklos Szeredice1d5a42006-04-10 22:54:58 -0700699 if (IS_ERR(req))
700 return PTR_ERR(req);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700701
702 req->in.h.opcode = FUSE_UNLINK;
703 req->in.h.nodeid = get_node_id(dir);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700704 req->in.numargs = 1;
705 req->in.args[0].size = entry->d_name.len + 1;
706 req->in.args[0].value = entry->d_name.name;
Tejun Heob93f8582008-11-26 12:03:55 +0100707 fuse_request_send(fc, req);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700708 err = req->out.h.error;
709 fuse_put_request(fc, req);
710 if (!err) {
711 struct inode *inode = entry->d_inode;
Miklos Szerediac45d612012-03-05 15:48:11 +0100712 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700713
Miklos Szerediac45d612012-03-05 15:48:11 +0100714 spin_lock(&fc->lock);
715 fi->attr_version = ++fc->attr_version;
Miklos Szeredidfca7ce2013-02-04 15:57:42 +0100716 /*
717 * If i_nlink == 0 then unlink doesn't make sense, yet this can
718 * happen if userspace filesystem is careless. It would be
719 * difficult to enforce correct nlink usage so just ignore this
720 * condition here
721 */
722 if (inode->i_nlink > 0)
723 drop_nlink(inode);
Miklos Szerediac45d612012-03-05 15:48:11 +0100724 spin_unlock(&fc->lock);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700725 fuse_invalidate_attr(inode);
726 fuse_invalidate_attr(dir);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800727 fuse_invalidate_entry_cache(entry);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700728 } else if (err == -EINTR)
729 fuse_invalidate_entry(entry);
730 return err;
731}
732
733static int fuse_rmdir(struct inode *dir, struct dentry *entry)
734{
735 int err;
736 struct fuse_conn *fc = get_fuse_conn(dir);
Maxim Patlasovb111c8c2012-10-26 19:48:30 +0400737 struct fuse_req *req = fuse_get_req_nopages(fc);
Miklos Szeredice1d5a42006-04-10 22:54:58 -0700738 if (IS_ERR(req))
739 return PTR_ERR(req);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700740
741 req->in.h.opcode = FUSE_RMDIR;
742 req->in.h.nodeid = get_node_id(dir);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700743 req->in.numargs = 1;
744 req->in.args[0].size = entry->d_name.len + 1;
745 req->in.args[0].value = entry->d_name.name;
Tejun Heob93f8582008-11-26 12:03:55 +0100746 fuse_request_send(fc, req);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700747 err = req->out.h.error;
748 fuse_put_request(fc, req);
749 if (!err) {
Dave Hansence71ec32006-09-30 23:29:06 -0700750 clear_nlink(entry->d_inode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700751 fuse_invalidate_attr(dir);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800752 fuse_invalidate_entry_cache(entry);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700753 } else if (err == -EINTR)
754 fuse_invalidate_entry(entry);
755 return err;
756}
757
758static int fuse_rename(struct inode *olddir, struct dentry *oldent,
759 struct inode *newdir, struct dentry *newent)
760{
761 int err;
762 struct fuse_rename_in inarg;
763 struct fuse_conn *fc = get_fuse_conn(olddir);
Maxim Patlasovb111c8c2012-10-26 19:48:30 +0400764 struct fuse_req *req = fuse_get_req_nopages(fc);
Sage Weile4eaac02011-05-24 13:06:07 -0700765
Miklos Szeredice1d5a42006-04-10 22:54:58 -0700766 if (IS_ERR(req))
767 return PTR_ERR(req);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700768
769 memset(&inarg, 0, sizeof(inarg));
770 inarg.newdir = get_node_id(newdir);
771 req->in.h.opcode = FUSE_RENAME;
772 req->in.h.nodeid = get_node_id(olddir);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700773 req->in.numargs = 3;
774 req->in.args[0].size = sizeof(inarg);
775 req->in.args[0].value = &inarg;
776 req->in.args[1].size = oldent->d_name.len + 1;
777 req->in.args[1].value = oldent->d_name.name;
778 req->in.args[2].size = newent->d_name.len + 1;
779 req->in.args[2].value = newent->d_name.name;
Tejun Heob93f8582008-11-26 12:03:55 +0100780 fuse_request_send(fc, req);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700781 err = req->out.h.error;
782 fuse_put_request(fc, req);
783 if (!err) {
Miklos Szeredi08b63302007-11-28 16:22:03 -0800784 /* ctime changes */
785 fuse_invalidate_attr(oldent->d_inode);
786
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700787 fuse_invalidate_attr(olddir);
788 if (olddir != newdir)
789 fuse_invalidate_attr(newdir);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800790
791 /* newent will end up negative */
Miklos Szeredi5219f342009-11-04 10:24:52 +0100792 if (newent->d_inode) {
793 fuse_invalidate_attr(newent->d_inode);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800794 fuse_invalidate_entry_cache(newent);
Miklos Szeredi5219f342009-11-04 10:24:52 +0100795 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700796 } else if (err == -EINTR) {
797 /* If request was interrupted, DEITY only knows if the
798 rename actually took place. If the invalidation
799 fails (e.g. some process has CWD under the renamed
800 directory), then there can be inconsistency between
801 the dcache and the real filesystem. Tough luck. */
802 fuse_invalidate_entry(oldent);
803 if (newent->d_inode)
804 fuse_invalidate_entry(newent);
805 }
806
807 return err;
808}
809
810static int fuse_link(struct dentry *entry, struct inode *newdir,
811 struct dentry *newent)
812{
813 int err;
814 struct fuse_link_in inarg;
815 struct inode *inode = entry->d_inode;
816 struct fuse_conn *fc = get_fuse_conn(inode);
Maxim Patlasovb111c8c2012-10-26 19:48:30 +0400817 struct fuse_req *req = fuse_get_req_nopages(fc);
Miklos Szeredice1d5a42006-04-10 22:54:58 -0700818 if (IS_ERR(req))
819 return PTR_ERR(req);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700820
821 memset(&inarg, 0, sizeof(inarg));
822 inarg.oldnodeid = get_node_id(inode);
823 req->in.h.opcode = FUSE_LINK;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700824 req->in.numargs = 2;
825 req->in.args[0].size = sizeof(inarg);
826 req->in.args[0].value = &inarg;
827 req->in.args[1].size = newent->d_name.len + 1;
828 req->in.args[1].value = newent->d_name.name;
829 err = create_new_entry(fc, req, newdir, newent, inode->i_mode);
830 /* Contrary to "normal" filesystems it can happen that link
831 makes two "logical" inodes point to the same "physical"
832 inode. We invalidate the attributes of the old one, so it
833 will reflect changes in the backing inode (link count,
834 etc.)
835 */
Miklos Szerediac45d612012-03-05 15:48:11 +0100836 if (!err) {
837 struct fuse_inode *fi = get_fuse_inode(inode);
838
839 spin_lock(&fc->lock);
840 fi->attr_version = ++fc->attr_version;
841 inc_nlink(inode);
842 spin_unlock(&fc->lock);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700843 fuse_invalidate_attr(inode);
Miklos Szerediac45d612012-03-05 15:48:11 +0100844 } else if (err == -EINTR) {
845 fuse_invalidate_attr(inode);
846 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700847 return err;
848}
849
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700850static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
851 struct kstat *stat)
852{
Miklos Szeredi203627b2012-05-10 19:49:38 +0400853 unsigned int blkbits;
854
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700855 stat->dev = inode->i_sb->s_dev;
856 stat->ino = attr->ino;
857 stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
858 stat->nlink = attr->nlink;
Eric W. Biederman499dcf22012-02-07 16:26:03 -0800859 stat->uid = make_kuid(&init_user_ns, attr->uid);
860 stat->gid = make_kgid(&init_user_ns, attr->gid);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700861 stat->rdev = inode->i_rdev;
862 stat->atime.tv_sec = attr->atime;
863 stat->atime.tv_nsec = attr->atimensec;
864 stat->mtime.tv_sec = attr->mtime;
865 stat->mtime.tv_nsec = attr->mtimensec;
866 stat->ctime.tv_sec = attr->ctime;
867 stat->ctime.tv_nsec = attr->ctimensec;
868 stat->size = attr->size;
869 stat->blocks = attr->blocks;
Miklos Szeredi203627b2012-05-10 19:49:38 +0400870
871 if (attr->blksize != 0)
872 blkbits = ilog2(attr->blksize);
873 else
874 blkbits = inode->i_sb->s_blocksize_bits;
875
876 stat->blksize = 1 << blkbits;
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700877}
878
Miklos Szeredic79e3222007-10-18 03:06:59 -0700879static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
880 struct file *file)
Miklos Szeredie5e55582005-09-09 13:10:28 -0700881{
882 int err;
Miklos Szeredic79e3222007-10-18 03:06:59 -0700883 struct fuse_getattr_in inarg;
884 struct fuse_attr_out outarg;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700885 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700886 struct fuse_req *req;
887 u64 attr_version;
888
Maxim Patlasovb111c8c2012-10-26 19:48:30 +0400889 req = fuse_get_req_nopages(fc);
Miklos Szeredice1d5a42006-04-10 22:54:58 -0700890 if (IS_ERR(req))
891 return PTR_ERR(req);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700892
Miklos Szeredi7dca9fd2007-11-28 16:21:59 -0800893 attr_version = fuse_get_attr_version(fc);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700894
Miklos Szeredic79e3222007-10-18 03:06:59 -0700895 memset(&inarg, 0, sizeof(inarg));
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700896 memset(&outarg, 0, sizeof(outarg));
Miklos Szeredic79e3222007-10-18 03:06:59 -0700897 /* Directories have separate file-handle space */
898 if (file && S_ISREG(inode->i_mode)) {
899 struct fuse_file *ff = file->private_data;
900
901 inarg.getattr_flags |= FUSE_GETATTR_FH;
902 inarg.fh = ff->fh;
903 }
Miklos Szeredie5e55582005-09-09 13:10:28 -0700904 req->in.h.opcode = FUSE_GETATTR;
905 req->in.h.nodeid = get_node_id(inode);
Miklos Szeredic79e3222007-10-18 03:06:59 -0700906 req->in.numargs = 1;
907 req->in.args[0].size = sizeof(inarg);
908 req->in.args[0].value = &inarg;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700909 req->out.numargs = 1;
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700910 if (fc->minor < 9)
911 req->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
912 else
913 req->out.args[0].size = sizeof(outarg);
Miklos Szeredic79e3222007-10-18 03:06:59 -0700914 req->out.args[0].value = &outarg;
Tejun Heob93f8582008-11-26 12:03:55 +0100915 fuse_request_send(fc, req);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700916 err = req->out.h.error;
917 fuse_put_request(fc, req);
918 if (!err) {
Miklos Szeredic79e3222007-10-18 03:06:59 -0700919 if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
Miklos Szeredie5e55582005-09-09 13:10:28 -0700920 make_bad_inode(inode);
921 err = -EIO;
922 } else {
Miklos Szeredic79e3222007-10-18 03:06:59 -0700923 fuse_change_attributes(inode, &outarg.attr,
924 attr_timeout(&outarg),
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700925 attr_version);
926 if (stat)
Miklos Szeredic79e3222007-10-18 03:06:59 -0700927 fuse_fillattr(inode, &outarg.attr, stat);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700928 }
929 }
930 return err;
931}
932
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800933int fuse_update_attributes(struct inode *inode, struct kstat *stat,
934 struct file *file, bool *refreshed)
935{
936 struct fuse_inode *fi = get_fuse_inode(inode);
937 int err;
938 bool r;
939
940 if (fi->i_time < get_jiffies_64()) {
941 r = true;
942 err = fuse_do_getattr(inode, stat, file);
943 } else {
944 r = false;
945 err = 0;
946 if (stat) {
947 generic_fillattr(inode, stat);
948 stat->mode = fi->orig_i_mode;
Pavel Shilovsky45c72cd2012-05-10 19:49:38 +0400949 stat->ino = fi->orig_ino;
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800950 }
951 }
952
953 if (refreshed != NULL)
954 *refreshed = r;
955
956 return err;
957}
958
John Muir3b463ae2009-05-31 11:13:57 -0400959int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid,
John Muir451d0f52011-12-06 21:50:06 +0100960 u64 child_nodeid, struct qstr *name)
John Muir3b463ae2009-05-31 11:13:57 -0400961{
962 int err = -ENOTDIR;
963 struct inode *parent;
964 struct dentry *dir;
965 struct dentry *entry;
966
967 parent = ilookup5(sb, parent_nodeid, fuse_inode_eq, &parent_nodeid);
968 if (!parent)
969 return -ENOENT;
970
971 mutex_lock(&parent->i_mutex);
972 if (!S_ISDIR(parent->i_mode))
973 goto unlock;
974
975 err = -ENOENT;
976 dir = d_find_alias(parent);
977 if (!dir)
978 goto unlock;
979
980 entry = d_lookup(dir, name);
981 dput(dir);
982 if (!entry)
983 goto unlock;
984
985 fuse_invalidate_attr(parent);
986 fuse_invalidate_entry(entry);
John Muir451d0f52011-12-06 21:50:06 +0100987
988 if (child_nodeid != 0 && entry->d_inode) {
989 mutex_lock(&entry->d_inode->i_mutex);
990 if (get_node_id(entry->d_inode) != child_nodeid) {
991 err = -ENOENT;
992 goto badentry;
993 }
994 if (d_mountpoint(entry)) {
995 err = -EBUSY;
996 goto badentry;
997 }
998 if (S_ISDIR(entry->d_inode->i_mode)) {
999 shrink_dcache_parent(entry);
1000 if (!simple_empty(entry)) {
1001 err = -ENOTEMPTY;
1002 goto badentry;
1003 }
1004 entry->d_inode->i_flags |= S_DEAD;
1005 }
1006 dont_mount(entry);
1007 clear_nlink(entry->d_inode);
1008 err = 0;
1009 badentry:
1010 mutex_unlock(&entry->d_inode->i_mutex);
1011 if (!err)
1012 d_delete(entry);
1013 } else {
1014 err = 0;
1015 }
John Muir3b463ae2009-05-31 11:13:57 -04001016 dput(entry);
John Muir3b463ae2009-05-31 11:13:57 -04001017
1018 unlock:
1019 mutex_unlock(&parent->i_mutex);
1020 iput(parent);
1021 return err;
1022}
1023
Miklos Szeredi87729a52005-09-09 13:10:34 -07001024/*
1025 * Calling into a user-controlled filesystem gives the filesystem
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001026 * daemon ptrace-like capabilities over the current process. This
Miklos Szeredi87729a52005-09-09 13:10:34 -07001027 * means, that the filesystem daemon is able to record the exact
1028 * filesystem operations performed, and can also control the behavior
1029 * of the requester process in otherwise impossible ways. For example
1030 * it can delay the operation for arbitrary length of time allowing
1031 * DoS against the requester.
1032 *
1033 * For this reason only those processes can call into the filesystem,
1034 * for which the owner of the mount has ptrace privilege. This
1035 * excludes processes started by other users, suid or sgid processes.
1036 */
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001037int fuse_allow_current_process(struct fuse_conn *fc)
Miklos Szeredi87729a52005-09-09 13:10:34 -07001038{
David Howellsc69e8d92008-11-14 10:39:19 +11001039 const struct cred *cred;
David Howellsc69e8d92008-11-14 10:39:19 +11001040
Miklos Szeredi87729a52005-09-09 13:10:34 -07001041 if (fc->flags & FUSE_ALLOW_OTHER)
1042 return 1;
1043
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001044 cred = current_cred();
Eric W. Biederman499dcf22012-02-07 16:26:03 -08001045 if (uid_eq(cred->euid, fc->user_id) &&
1046 uid_eq(cred->suid, fc->user_id) &&
1047 uid_eq(cred->uid, fc->user_id) &&
1048 gid_eq(cred->egid, fc->group_id) &&
1049 gid_eq(cred->sgid, fc->group_id) &&
1050 gid_eq(cred->gid, fc->group_id))
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001051 return 1;
Miklos Szeredi87729a52005-09-09 13:10:34 -07001052
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001053 return 0;
Miklos Szeredi87729a52005-09-09 13:10:34 -07001054}
1055
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001056static int fuse_access(struct inode *inode, int mask)
1057{
1058 struct fuse_conn *fc = get_fuse_conn(inode);
1059 struct fuse_req *req;
1060 struct fuse_access_in inarg;
1061 int err;
1062
1063 if (fc->no_access)
1064 return 0;
1065
Maxim Patlasovb111c8c2012-10-26 19:48:30 +04001066 req = fuse_get_req_nopages(fc);
Miklos Szeredice1d5a42006-04-10 22:54:58 -07001067 if (IS_ERR(req))
1068 return PTR_ERR(req);
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001069
1070 memset(&inarg, 0, sizeof(inarg));
Al Viroe6305c42008-07-15 21:03:57 -04001071 inarg.mask = mask & (MAY_READ | MAY_WRITE | MAY_EXEC);
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001072 req->in.h.opcode = FUSE_ACCESS;
1073 req->in.h.nodeid = get_node_id(inode);
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001074 req->in.numargs = 1;
1075 req->in.args[0].size = sizeof(inarg);
1076 req->in.args[0].value = &inarg;
Tejun Heob93f8582008-11-26 12:03:55 +01001077 fuse_request_send(fc, req);
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001078 err = req->out.h.error;
1079 fuse_put_request(fc, req);
1080 if (err == -ENOSYS) {
1081 fc->no_access = 1;
1082 err = 0;
1083 }
1084 return err;
1085}
1086
Al Viro10556cb2011-06-20 19:28:19 -04001087static int fuse_perm_getattr(struct inode *inode, int mask)
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001088{
Al Viro10556cb2011-06-20 19:28:19 -04001089 if (mask & MAY_NOT_BLOCK)
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001090 return -ECHILD;
1091
1092 return fuse_do_getattr(inode, NULL, NULL);
1093}
1094
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001095/*
1096 * Check permission. The two basic access models of FUSE are:
1097 *
1098 * 1) Local access checking ('default_permissions' mount option) based
1099 * on file mode. This is the plain old disk filesystem permission
1100 * modell.
1101 *
1102 * 2) "Remote" access checking, where server is responsible for
1103 * checking permission in each inode operation. An exception to this
1104 * is if ->permission() was invoked from sys_access() in which case an
1105 * access request is sent. Execute permission is still checked
1106 * locally based on file mode.
1107 */
Al Viro10556cb2011-06-20 19:28:19 -04001108static int fuse_permission(struct inode *inode, int mask)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001109{
1110 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi244f6382007-10-16 23:31:02 -07001111 bool refreshed = false;
1112 int err = 0;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001113
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001114 if (!fuse_allow_current_process(fc))
Miklos Szeredie5e55582005-09-09 13:10:28 -07001115 return -EACCES;
Miklos Szeredi244f6382007-10-16 23:31:02 -07001116
1117 /*
Miklos Szeredie8e96152007-10-16 23:31:06 -07001118 * If attributes are needed, refresh them before proceeding
Miklos Szeredi244f6382007-10-16 23:31:02 -07001119 */
Miklos Szeredie8e96152007-10-16 23:31:06 -07001120 if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) ||
1121 ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) {
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001122 struct fuse_inode *fi = get_fuse_inode(inode);
1123
1124 if (fi->i_time < get_jiffies_64()) {
1125 refreshed = true;
1126
Al Viro10556cb2011-06-20 19:28:19 -04001127 err = fuse_perm_getattr(inode, mask);
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001128 if (err)
1129 return err;
1130 }
Miklos Szeredi244f6382007-10-16 23:31:02 -07001131 }
1132
1133 if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
Al Viro2830ba72011-06-20 19:16:29 -04001134 err = generic_permission(inode, mask);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001135
1136 /* If permission is denied, try to refresh file
1137 attributes. This is also needed, because the root
1138 node will at first have no permissions */
Miklos Szeredi244f6382007-10-16 23:31:02 -07001139 if (err == -EACCES && !refreshed) {
Al Viro10556cb2011-06-20 19:28:19 -04001140 err = fuse_perm_getattr(inode, mask);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001141 if (!err)
Al Viro2830ba72011-06-20 19:16:29 -04001142 err = generic_permission(inode, mask);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001143 }
1144
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001145 /* Note: the opposite of the above test does not
1146 exist. So if permissions are revoked this won't be
1147 noticed immediately, only after the attribute
1148 timeout has expired */
Eric Paris9cfcac82010-07-23 11:43:51 -04001149 } else if (mask & (MAY_ACCESS | MAY_CHDIR)) {
Al Viro10556cb2011-06-20 19:28:19 -04001150 if (mask & MAY_NOT_BLOCK)
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001151 return -ECHILD;
1152
Miklos Szeredie8e96152007-10-16 23:31:06 -07001153 err = fuse_access(inode, mask);
1154 } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
1155 if (!(inode->i_mode & S_IXUGO)) {
1156 if (refreshed)
1157 return -EACCES;
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001158
Al Viro10556cb2011-06-20 19:28:19 -04001159 err = fuse_perm_getattr(inode, mask);
Miklos Szeredie8e96152007-10-16 23:31:06 -07001160 if (!err && !(inode->i_mode & S_IXUGO))
1161 return -EACCES;
1162 }
Miklos Szeredie5e55582005-09-09 13:10:28 -07001163 }
Miklos Szeredi244f6382007-10-16 23:31:02 -07001164 return err;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001165}
1166
1167static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
Al Viro8d3af7f2013-05-18 03:03:58 -04001168 struct dir_context *ctx)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001169{
1170 while (nbytes >= FUSE_NAME_OFFSET) {
1171 struct fuse_dirent *dirent = (struct fuse_dirent *) buf;
1172 size_t reclen = FUSE_DIRENT_SIZE(dirent);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001173 if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
1174 return -EIO;
1175 if (reclen > nbytes)
1176 break;
1177
Al Viro8d3af7f2013-05-18 03:03:58 -04001178 if (!dir_emit(ctx, dirent->name, dirent->namelen,
1179 dirent->ino, dirent->type))
Miklos Szeredie5e55582005-09-09 13:10:28 -07001180 break;
1181
1182 buf += reclen;
1183 nbytes -= reclen;
Al Viro8d3af7f2013-05-18 03:03:58 -04001184 ctx->pos = dirent->off;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001185 }
1186
1187 return 0;
1188}
1189
Anand V. Avati0b05b182012-08-19 08:53:23 -04001190static int fuse_direntplus_link(struct file *file,
1191 struct fuse_direntplus *direntplus,
1192 u64 attr_version)
1193{
1194 int err;
1195 struct fuse_entry_out *o = &direntplus->entry_out;
1196 struct fuse_dirent *dirent = &direntplus->dirent;
1197 struct dentry *parent = file->f_path.dentry;
1198 struct qstr name = QSTR_INIT(dirent->name, dirent->namelen);
1199 struct dentry *dentry;
1200 struct dentry *alias;
1201 struct inode *dir = parent->d_inode;
1202 struct fuse_conn *fc;
1203 struct inode *inode;
1204
1205 if (!o->nodeid) {
1206 /*
1207 * Unlike in the case of fuse_lookup, zero nodeid does not mean
1208 * ENOENT. Instead, it only means the userspace filesystem did
1209 * not want to return attributes/handle for this entry.
1210 *
1211 * So do nothing.
1212 */
1213 return 0;
1214 }
1215
1216 if (name.name[0] == '.') {
1217 /*
1218 * We could potentially refresh the attributes of the directory
1219 * and its parent?
1220 */
1221 if (name.len == 1)
1222 return 0;
1223 if (name.name[1] == '.' && name.len == 2)
1224 return 0;
1225 }
Miklos Szeredia28ef452013-07-17 14:53:53 +02001226
1227 if (invalid_nodeid(o->nodeid))
1228 return -EIO;
1229 if (!fuse_valid_type(o->attr.mode))
1230 return -EIO;
1231
Anand V. Avati0b05b182012-08-19 08:53:23 -04001232 fc = get_fuse_conn(dir);
1233
1234 name.hash = full_name_hash(name.name, name.len);
1235 dentry = d_lookup(parent, &name);
Niels de Vos53ce9a32013-07-17 14:53:53 +02001236 if (dentry) {
Anand V. Avati0b05b182012-08-19 08:53:23 -04001237 inode = dentry->d_inode;
Niels de Vos53ce9a32013-07-17 14:53:53 +02001238 if (!inode) {
1239 d_drop(dentry);
Miklos Szeredia28ef452013-07-17 14:53:53 +02001240 } else if (get_node_id(inode) != o->nodeid ||
1241 ((o->attr.mode ^ inode->i_mode) & S_IFMT)) {
Niels de Vos53ce9a32013-07-17 14:53:53 +02001242 err = d_invalidate(dentry);
1243 if (err)
1244 goto out;
Miklos Szeredia28ef452013-07-17 14:53:53 +02001245 } else if (is_bad_inode(inode)) {
1246 err = -EIO;
1247 goto out;
Niels de Vos53ce9a32013-07-17 14:53:53 +02001248 } else {
Anand V. Avati0b05b182012-08-19 08:53:23 -04001249 struct fuse_inode *fi;
1250 fi = get_fuse_inode(inode);
1251 spin_lock(&fc->lock);
1252 fi->nlookup++;
1253 spin_unlock(&fc->lock);
1254
Miklos Szeredifa2b7212013-07-17 14:53:53 +02001255 fuse_change_attributes(inode, &o->attr,
1256 entry_attr_timeout(o),
1257 attr_version);
1258
Anand V. Avati0b05b182012-08-19 08:53:23 -04001259 /*
1260 * The other branch to 'found' comes via fuse_iget()
1261 * which bumps nlookup inside
1262 */
1263 goto found;
1264 }
Anand V. Avati0b05b182012-08-19 08:53:23 -04001265 dput(dentry);
Anand V. Avati0b05b182012-08-19 08:53:23 -04001266 }
1267
1268 dentry = d_alloc(parent, &name);
1269 err = -ENOMEM;
1270 if (!dentry)
1271 goto out;
1272
1273 inode = fuse_iget(dir->i_sb, o->nodeid, o->generation,
1274 &o->attr, entry_attr_timeout(o), attr_version);
1275 if (!inode)
1276 goto out;
1277
Miklos Szeredi29149412013-07-17 14:53:53 +02001278 if (S_ISDIR(inode->i_mode)) {
1279 mutex_lock(&fc->inst_mutex);
1280 alias = fuse_d_add_directory(dentry, inode);
1281 mutex_unlock(&fc->inst_mutex);
1282 err = PTR_ERR(alias);
1283 if (IS_ERR(alias)) {
1284 iput(inode);
1285 goto out;
1286 }
1287 } else {
1288 alias = d_splice_alias(inode, dentry);
1289 }
1290
Anand V. Avati0b05b182012-08-19 08:53:23 -04001291 if (alias) {
1292 dput(dentry);
1293 dentry = alias;
1294 }
1295
1296found:
Anand V. Avati0b05b182012-08-19 08:53:23 -04001297 fuse_change_entry_timeout(dentry, o);
1298
1299 err = 0;
1300out:
Miklos Szeredic7263bc2013-07-17 14:53:54 +02001301 dput(dentry);
Anand V. Avati0b05b182012-08-19 08:53:23 -04001302 return err;
1303}
1304
1305static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file,
Al Viro8d3af7f2013-05-18 03:03:58 -04001306 struct dir_context *ctx, u64 attr_version)
Anand V. Avati0b05b182012-08-19 08:53:23 -04001307{
1308 struct fuse_direntplus *direntplus;
1309 struct fuse_dirent *dirent;
1310 size_t reclen;
1311 int over = 0;
1312 int ret;
1313
1314 while (nbytes >= FUSE_NAME_OFFSET_DIRENTPLUS) {
1315 direntplus = (struct fuse_direntplus *) buf;
1316 dirent = &direntplus->dirent;
1317 reclen = FUSE_DIRENTPLUS_SIZE(direntplus);
1318
1319 if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
1320 return -EIO;
1321 if (reclen > nbytes)
1322 break;
1323
1324 if (!over) {
1325 /* We fill entries into dstbuf only as much as
1326 it can hold. But we still continue iterating
1327 over remaining entries to link them. If not,
1328 we need to send a FORGET for each of those
1329 which we did not link.
1330 */
Al Viro8d3af7f2013-05-18 03:03:58 -04001331 over = !dir_emit(ctx, dirent->name, dirent->namelen,
1332 dirent->ino, dirent->type);
1333 ctx->pos = dirent->off;
Anand V. Avati0b05b182012-08-19 08:53:23 -04001334 }
1335
1336 buf += reclen;
1337 nbytes -= reclen;
1338
1339 ret = fuse_direntplus_link(file, direntplus, attr_version);
1340 if (ret)
1341 fuse_force_forget(file, direntplus->entry_out.nodeid);
1342 }
1343
1344 return 0;
1345}
1346
Al Viro8d3af7f2013-05-18 03:03:58 -04001347static int fuse_readdir(struct file *file, struct dir_context *ctx)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001348{
Feng Shuo4582a4a2013-01-15 11:23:28 +08001349 int plus, err;
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001350 size_t nbytes;
1351 struct page *page;
Al Viro496ad9a2013-01-23 17:07:38 -05001352 struct inode *inode = file_inode(file);
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001353 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi248d86e2006-01-06 00:19:39 -08001354 struct fuse_req *req;
Anand V. Avati0b05b182012-08-19 08:53:23 -04001355 u64 attr_version = 0;
Miklos Szeredi248d86e2006-01-06 00:19:39 -08001356
1357 if (is_bad_inode(inode))
1358 return -EIO;
1359
Maxim Patlasovb111c8c2012-10-26 19:48:30 +04001360 req = fuse_get_req(fc, 1);
Miklos Szeredice1d5a42006-04-10 22:54:58 -07001361 if (IS_ERR(req))
1362 return PTR_ERR(req);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001363
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001364 page = alloc_page(GFP_KERNEL);
1365 if (!page) {
1366 fuse_put_request(fc, req);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001367 return -ENOMEM;
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001368 }
Feng Shuo4582a4a2013-01-15 11:23:28 +08001369
Al Viro8d3af7f2013-05-18 03:03:58 -04001370 plus = fuse_use_readdirplus(inode, ctx);
Miklos Szeredif4975c62009-04-02 14:25:34 +02001371 req->out.argpages = 1;
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001372 req->num_pages = 1;
1373 req->pages[0] = page;
Maxim Patlasov85f40ae2012-10-26 19:49:33 +04001374 req->page_descs[0].length = PAGE_SIZE;
Feng Shuo4582a4a2013-01-15 11:23:28 +08001375 if (plus) {
Anand V. Avati0b05b182012-08-19 08:53:23 -04001376 attr_version = fuse_get_attr_version(fc);
Al Viro8d3af7f2013-05-18 03:03:58 -04001377 fuse_read_fill(req, file, ctx->pos, PAGE_SIZE,
Anand V. Avati0b05b182012-08-19 08:53:23 -04001378 FUSE_READDIRPLUS);
1379 } else {
Al Viro8d3af7f2013-05-18 03:03:58 -04001380 fuse_read_fill(req, file, ctx->pos, PAGE_SIZE,
Anand V. Avati0b05b182012-08-19 08:53:23 -04001381 FUSE_READDIR);
1382 }
Tejun Heob93f8582008-11-26 12:03:55 +01001383 fuse_request_send(fc, req);
Miklos Szeredi361b1eb52006-01-16 22:14:45 -08001384 nbytes = req->out.args[0].size;
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001385 err = req->out.h.error;
1386 fuse_put_request(fc, req);
Anand V. Avati0b05b182012-08-19 08:53:23 -04001387 if (!err) {
Feng Shuo4582a4a2013-01-15 11:23:28 +08001388 if (plus) {
Anand V. Avati0b05b182012-08-19 08:53:23 -04001389 err = parse_dirplusfile(page_address(page), nbytes,
Al Viro8d3af7f2013-05-18 03:03:58 -04001390 file, ctx,
Anand V. Avati0b05b182012-08-19 08:53:23 -04001391 attr_version);
1392 } else {
1393 err = parse_dirfile(page_address(page), nbytes, file,
Al Viro8d3af7f2013-05-18 03:03:58 -04001394 ctx);
Anand V. Avati0b05b182012-08-19 08:53:23 -04001395 }
1396 }
Miklos Szeredie5e55582005-09-09 13:10:28 -07001397
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001398 __free_page(page);
Miklos Szeredib36c31b2005-09-09 13:10:38 -07001399 fuse_invalidate_attr(inode); /* atime changed */
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001400 return err;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001401}
1402
1403static char *read_link(struct dentry *dentry)
1404{
1405 struct inode *inode = dentry->d_inode;
1406 struct fuse_conn *fc = get_fuse_conn(inode);
Maxim Patlasovb111c8c2012-10-26 19:48:30 +04001407 struct fuse_req *req = fuse_get_req_nopages(fc);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001408 char *link;
1409
Miklos Szeredice1d5a42006-04-10 22:54:58 -07001410 if (IS_ERR(req))
David Howellse231c2e2008-02-07 00:15:26 -08001411 return ERR_CAST(req);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001412
1413 link = (char *) __get_free_page(GFP_KERNEL);
1414 if (!link) {
1415 link = ERR_PTR(-ENOMEM);
1416 goto out;
1417 }
1418 req->in.h.opcode = FUSE_READLINK;
1419 req->in.h.nodeid = get_node_id(inode);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001420 req->out.argvar = 1;
1421 req->out.numargs = 1;
1422 req->out.args[0].size = PAGE_SIZE - 1;
1423 req->out.args[0].value = link;
Tejun Heob93f8582008-11-26 12:03:55 +01001424 fuse_request_send(fc, req);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001425 if (req->out.h.error) {
1426 free_page((unsigned long) link);
1427 link = ERR_PTR(req->out.h.error);
1428 } else
1429 link[req->out.args[0].size] = '\0';
1430 out:
1431 fuse_put_request(fc, req);
Miklos Szeredib36c31b2005-09-09 13:10:38 -07001432 fuse_invalidate_attr(inode); /* atime changed */
Miklos Szeredie5e55582005-09-09 13:10:28 -07001433 return link;
1434}
1435
1436static void free_link(char *link)
1437{
1438 if (!IS_ERR(link))
1439 free_page((unsigned long) link);
1440}
1441
1442static void *fuse_follow_link(struct dentry *dentry, struct nameidata *nd)
1443{
1444 nd_set_link(nd, read_link(dentry));
1445 return NULL;
1446}
1447
1448static void fuse_put_link(struct dentry *dentry, struct nameidata *nd, void *c)
1449{
1450 free_link(nd_get_link(nd));
1451}
1452
1453static int fuse_dir_open(struct inode *inode, struct file *file)
1454{
Miklos Szeredi91fe96b2009-04-28 16:56:37 +02001455 return fuse_open_common(inode, file, true);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001456}
1457
1458static int fuse_dir_release(struct inode *inode, struct file *file)
1459{
Miklos Szeredi8b0797a2009-04-28 16:56:39 +02001460 fuse_release_common(file, FUSE_RELEASEDIR);
1461
1462 return 0;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001463}
1464
Josef Bacik02c24a82011-07-16 20:44:56 -04001465static int fuse_dir_fsync(struct file *file, loff_t start, loff_t end,
1466 int datasync)
Miklos Szeredi82547982005-09-09 13:10:38 -07001467{
Josef Bacik02c24a82011-07-16 20:44:56 -04001468 return fuse_fsync_common(file, start, end, datasync, 1);
Miklos Szeredi82547982005-09-09 13:10:38 -07001469}
1470
Miklos Szeredib18da0c2011-12-13 11:58:49 +01001471static long fuse_dir_ioctl(struct file *file, unsigned int cmd,
1472 unsigned long arg)
1473{
1474 struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1475
1476 /* FUSE_IOCTL_DIR only supported for API version >= 7.18 */
1477 if (fc->minor < 18)
1478 return -ENOTTY;
1479
1480 return fuse_ioctl_common(file, cmd, arg, FUSE_IOCTL_DIR);
1481}
1482
1483static long fuse_dir_compat_ioctl(struct file *file, unsigned int cmd,
1484 unsigned long arg)
1485{
1486 struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1487
1488 if (fc->minor < 18)
1489 return -ENOTTY;
1490
1491 return fuse_ioctl_common(file, cmd, arg,
1492 FUSE_IOCTL_COMPAT | FUSE_IOCTL_DIR);
1493}
1494
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001495static bool update_mtime(unsigned ivalid)
1496{
1497 /* Always update if mtime is explicitly set */
1498 if (ivalid & ATTR_MTIME_SET)
1499 return true;
1500
1501 /* If it's an open(O_TRUNC) or an ftruncate(), don't update */
1502 if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE)))
1503 return false;
1504
1505 /* In all other cases update */
1506 return true;
1507}
1508
Miklos Szeredibefc6492005-11-07 00:59:52 -08001509static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001510{
1511 unsigned ivalid = iattr->ia_valid;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001512
1513 if (ivalid & ATTR_MODE)
Miklos Szeredibefc6492005-11-07 00:59:52 -08001514 arg->valid |= FATTR_MODE, arg->mode = iattr->ia_mode;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001515 if (ivalid & ATTR_UID)
Eric W. Biederman499dcf22012-02-07 16:26:03 -08001516 arg->valid |= FATTR_UID, arg->uid = from_kuid(&init_user_ns, iattr->ia_uid);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001517 if (ivalid & ATTR_GID)
Eric W. Biederman499dcf22012-02-07 16:26:03 -08001518 arg->valid |= FATTR_GID, arg->gid = from_kgid(&init_user_ns, iattr->ia_gid);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001519 if (ivalid & ATTR_SIZE)
Miklos Szeredibefc6492005-11-07 00:59:52 -08001520 arg->valid |= FATTR_SIZE, arg->size = iattr->ia_size;
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001521 if (ivalid & ATTR_ATIME) {
1522 arg->valid |= FATTR_ATIME;
Miklos Szeredibefc6492005-11-07 00:59:52 -08001523 arg->atime = iattr->ia_atime.tv_sec;
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001524 arg->atimensec = iattr->ia_atime.tv_nsec;
1525 if (!(ivalid & ATTR_ATIME_SET))
1526 arg->valid |= FATTR_ATIME_NOW;
1527 }
1528 if ((ivalid & ATTR_MTIME) && update_mtime(ivalid)) {
1529 arg->valid |= FATTR_MTIME;
Miklos Szeredibefc6492005-11-07 00:59:52 -08001530 arg->mtime = iattr->ia_mtime.tv_sec;
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001531 arg->mtimensec = iattr->ia_mtime.tv_nsec;
1532 if (!(ivalid & ATTR_MTIME_SET))
1533 arg->valid |= FATTR_MTIME_NOW;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001534 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001535}
1536
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001537/*
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001538 * Prevent concurrent writepages on inode
1539 *
1540 * This is done by adding a negative bias to the inode write counter
1541 * and waiting for all pending writes to finish.
1542 */
1543void fuse_set_nowrite(struct inode *inode)
1544{
1545 struct fuse_conn *fc = get_fuse_conn(inode);
1546 struct fuse_inode *fi = get_fuse_inode(inode);
1547
1548 BUG_ON(!mutex_is_locked(&inode->i_mutex));
1549
1550 spin_lock(&fc->lock);
1551 BUG_ON(fi->writectr < 0);
1552 fi->writectr += FUSE_NOWRITE;
1553 spin_unlock(&fc->lock);
1554 wait_event(fi->page_waitq, fi->writectr == FUSE_NOWRITE);
1555}
1556
1557/*
1558 * Allow writepages on inode
1559 *
1560 * Remove the bias from the writecounter and send any queued
1561 * writepages.
1562 */
1563static void __fuse_release_nowrite(struct inode *inode)
1564{
1565 struct fuse_inode *fi = get_fuse_inode(inode);
1566
1567 BUG_ON(fi->writectr != FUSE_NOWRITE);
1568 fi->writectr = 0;
1569 fuse_flush_writepages(inode);
1570}
1571
1572void fuse_release_nowrite(struct inode *inode)
1573{
1574 struct fuse_conn *fc = get_fuse_conn(inode);
1575
1576 spin_lock(&fc->lock);
1577 __fuse_release_nowrite(inode);
1578 spin_unlock(&fc->lock);
1579}
1580
1581/*
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001582 * Set attributes, and at the same time refresh them.
1583 *
1584 * Truncation is slightly complicated, because the 'truncate' request
1585 * may fail, in which case we don't want to touch the mapping.
Miklos Szeredi9ffbb912006-10-17 00:10:06 -07001586 * vmtruncate() doesn't allow for this case, so do the rlimit checking
1587 * and the actual truncation by hand.
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001588 */
Maxim Patlasovefb9fa92012-12-18 14:05:08 +04001589int fuse_do_setattr(struct inode *inode, struct iattr *attr,
1590 struct file *file)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001591{
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001592 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001593 struct fuse_req *req;
1594 struct fuse_setattr_in inarg;
1595 struct fuse_attr_out outarg;
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001596 bool is_truncate = false;
1597 loff_t oldsize;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001598 int err;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001599
Christoph Hellwigdb78b872010-06-04 11:30:03 +02001600 if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS))
1601 attr->ia_valid |= ATTR_FORCE;
1602
1603 err = inode_change_ok(inode, attr);
1604 if (err)
1605 return err;
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001606
Miklos Szeredi8d56add2011-02-25 14:44:58 +01001607 if (attr->ia_valid & ATTR_OPEN) {
1608 if (fc->atomic_o_trunc)
1609 return 0;
1610 file = NULL;
1611 }
Miklos Szeredi6ff958e2007-10-18 03:07:02 -07001612
Christoph Hellwig2c27c652010-06-04 11:30:04 +02001613 if (attr->ia_valid & ATTR_SIZE)
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001614 is_truncate = true;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001615
Maxim Patlasovb111c8c2012-10-26 19:48:30 +04001616 req = fuse_get_req_nopages(fc);
Miklos Szeredice1d5a42006-04-10 22:54:58 -07001617 if (IS_ERR(req))
1618 return PTR_ERR(req);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001619
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001620 if (is_truncate)
1621 fuse_set_nowrite(inode);
1622
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001623 memset(&inarg, 0, sizeof(inarg));
Miklos Szeredi0e9663e2007-10-18 03:07:05 -07001624 memset(&outarg, 0, sizeof(outarg));
Miklos Szeredibefc6492005-11-07 00:59:52 -08001625 iattr_to_fattr(attr, &inarg);
Miklos Szeredi49d49142007-10-18 03:07:00 -07001626 if (file) {
1627 struct fuse_file *ff = file->private_data;
1628 inarg.valid |= FATTR_FH;
1629 inarg.fh = ff->fh;
1630 }
Miklos Szeredif3332112007-10-18 03:07:04 -07001631 if (attr->ia_valid & ATTR_SIZE) {
1632 /* For mandatory locking in truncate */
1633 inarg.valid |= FATTR_LOCKOWNER;
1634 inarg.lock_owner = fuse_lock_owner_id(fc, current->files);
1635 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001636 req->in.h.opcode = FUSE_SETATTR;
1637 req->in.h.nodeid = get_node_id(inode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001638 req->in.numargs = 1;
1639 req->in.args[0].size = sizeof(inarg);
1640 req->in.args[0].value = &inarg;
1641 req->out.numargs = 1;
Miklos Szeredi0e9663e2007-10-18 03:07:05 -07001642 if (fc->minor < 9)
1643 req->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
1644 else
1645 req->out.args[0].size = sizeof(outarg);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001646 req->out.args[0].value = &outarg;
Tejun Heob93f8582008-11-26 12:03:55 +01001647 fuse_request_send(fc, req);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001648 err = req->out.h.error;
1649 fuse_put_request(fc, req);
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001650 if (err) {
1651 if (err == -EINTR)
1652 fuse_invalidate_attr(inode);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001653 goto error;
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001654 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001655
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001656 if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
1657 make_bad_inode(inode);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001658 err = -EIO;
1659 goto error;
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001660 }
1661
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001662 spin_lock(&fc->lock);
1663 fuse_change_attributes_common(inode, &outarg.attr,
1664 attr_timeout(&outarg));
1665 oldsize = inode->i_size;
1666 i_size_write(inode, outarg.attr.size);
1667
1668 if (is_truncate) {
1669 /* NOTE: this may release/reacquire fc->lock */
1670 __fuse_release_nowrite(inode);
1671 }
1672 spin_unlock(&fc->lock);
1673
1674 /*
1675 * Only call invalidate_inode_pages2() after removing
1676 * FUSE_NOWRITE, otherwise fuse_launder_page() would deadlock.
1677 */
1678 if (S_ISREG(inode->i_mode) && oldsize != outarg.attr.size) {
npiggin@suse.dec08d3b02009-08-21 02:35:06 +10001679 truncate_pagecache(inode, oldsize, outarg.attr.size);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001680 invalidate_inode_pages2(inode->i_mapping);
1681 }
1682
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001683 return 0;
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001684
1685error:
1686 if (is_truncate)
1687 fuse_release_nowrite(inode);
1688
1689 return err;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001690}
1691
Miklos Szeredi49d49142007-10-18 03:07:00 -07001692static int fuse_setattr(struct dentry *entry, struct iattr *attr)
1693{
Maxim Patlasovefb9fa92012-12-18 14:05:08 +04001694 struct inode *inode = entry->d_inode;
1695
1696 if (!fuse_allow_current_process(get_fuse_conn(inode)))
1697 return -EACCES;
1698
Miklos Szeredi49d49142007-10-18 03:07:00 -07001699 if (attr->ia_valid & ATTR_FILE)
Maxim Patlasovefb9fa92012-12-18 14:05:08 +04001700 return fuse_do_setattr(inode, attr, attr->ia_file);
Miklos Szeredi49d49142007-10-18 03:07:00 -07001701 else
Maxim Patlasovefb9fa92012-12-18 14:05:08 +04001702 return fuse_do_setattr(inode, attr, NULL);
Miklos Szeredi49d49142007-10-18 03:07:00 -07001703}
1704
Miklos Szeredie5e55582005-09-09 13:10:28 -07001705static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
1706 struct kstat *stat)
1707{
1708 struct inode *inode = entry->d_inode;
Miklos Szeredi244f6382007-10-16 23:31:02 -07001709 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi244f6382007-10-16 23:31:02 -07001710
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001711 if (!fuse_allow_current_process(fc))
Miklos Szeredi244f6382007-10-16 23:31:02 -07001712 return -EACCES;
1713
Miklos Szeredibcb4be82007-11-28 16:21:59 -08001714 return fuse_update_attributes(inode, stat, NULL, NULL);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001715}
1716
Miklos Szeredi92a87802005-09-09 13:10:31 -07001717static int fuse_setxattr(struct dentry *entry, const char *name,
1718 const void *value, size_t size, int flags)
1719{
1720 struct inode *inode = entry->d_inode;
1721 struct fuse_conn *fc = get_fuse_conn(inode);
1722 struct fuse_req *req;
1723 struct fuse_setxattr_in inarg;
1724 int err;
1725
Miklos Szeredi92a87802005-09-09 13:10:31 -07001726 if (fc->no_setxattr)
1727 return -EOPNOTSUPP;
1728
Maxim Patlasovb111c8c2012-10-26 19:48:30 +04001729 req = fuse_get_req_nopages(fc);
Miklos Szeredice1d5a42006-04-10 22:54:58 -07001730 if (IS_ERR(req))
1731 return PTR_ERR(req);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001732
1733 memset(&inarg, 0, sizeof(inarg));
1734 inarg.size = size;
1735 inarg.flags = flags;
1736 req->in.h.opcode = FUSE_SETXATTR;
1737 req->in.h.nodeid = get_node_id(inode);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001738 req->in.numargs = 3;
1739 req->in.args[0].size = sizeof(inarg);
1740 req->in.args[0].value = &inarg;
1741 req->in.args[1].size = strlen(name) + 1;
1742 req->in.args[1].value = name;
1743 req->in.args[2].size = size;
1744 req->in.args[2].value = value;
Tejun Heob93f8582008-11-26 12:03:55 +01001745 fuse_request_send(fc, req);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001746 err = req->out.h.error;
1747 fuse_put_request(fc, req);
1748 if (err == -ENOSYS) {
1749 fc->no_setxattr = 1;
1750 err = -EOPNOTSUPP;
1751 }
1752 return err;
1753}
1754
1755static ssize_t fuse_getxattr(struct dentry *entry, const char *name,
1756 void *value, size_t size)
1757{
1758 struct inode *inode = entry->d_inode;
1759 struct fuse_conn *fc = get_fuse_conn(inode);
1760 struct fuse_req *req;
1761 struct fuse_getxattr_in inarg;
1762 struct fuse_getxattr_out outarg;
1763 ssize_t ret;
1764
1765 if (fc->no_getxattr)
1766 return -EOPNOTSUPP;
1767
Maxim Patlasovb111c8c2012-10-26 19:48:30 +04001768 req = fuse_get_req_nopages(fc);
Miklos Szeredice1d5a42006-04-10 22:54:58 -07001769 if (IS_ERR(req))
1770 return PTR_ERR(req);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001771
1772 memset(&inarg, 0, sizeof(inarg));
1773 inarg.size = size;
1774 req->in.h.opcode = FUSE_GETXATTR;
1775 req->in.h.nodeid = get_node_id(inode);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001776 req->in.numargs = 2;
1777 req->in.args[0].size = sizeof(inarg);
1778 req->in.args[0].value = &inarg;
1779 req->in.args[1].size = strlen(name) + 1;
1780 req->in.args[1].value = name;
1781 /* This is really two different operations rolled into one */
1782 req->out.numargs = 1;
1783 if (size) {
1784 req->out.argvar = 1;
1785 req->out.args[0].size = size;
1786 req->out.args[0].value = value;
1787 } else {
1788 req->out.args[0].size = sizeof(outarg);
1789 req->out.args[0].value = &outarg;
1790 }
Tejun Heob93f8582008-11-26 12:03:55 +01001791 fuse_request_send(fc, req);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001792 ret = req->out.h.error;
1793 if (!ret)
1794 ret = size ? req->out.args[0].size : outarg.size;
1795 else {
1796 if (ret == -ENOSYS) {
1797 fc->no_getxattr = 1;
1798 ret = -EOPNOTSUPP;
1799 }
1800 }
1801 fuse_put_request(fc, req);
1802 return ret;
1803}
1804
1805static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
1806{
1807 struct inode *inode = entry->d_inode;
1808 struct fuse_conn *fc = get_fuse_conn(inode);
1809 struct fuse_req *req;
1810 struct fuse_getxattr_in inarg;
1811 struct fuse_getxattr_out outarg;
1812 ssize_t ret;
1813
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001814 if (!fuse_allow_current_process(fc))
Miklos Szeredie57ac682007-10-18 03:06:58 -07001815 return -EACCES;
1816
Miklos Szeredi92a87802005-09-09 13:10:31 -07001817 if (fc->no_listxattr)
1818 return -EOPNOTSUPP;
1819
Maxim Patlasovb111c8c2012-10-26 19:48:30 +04001820 req = fuse_get_req_nopages(fc);
Miklos Szeredice1d5a42006-04-10 22:54:58 -07001821 if (IS_ERR(req))
1822 return PTR_ERR(req);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001823
1824 memset(&inarg, 0, sizeof(inarg));
1825 inarg.size = size;
1826 req->in.h.opcode = FUSE_LISTXATTR;
1827 req->in.h.nodeid = get_node_id(inode);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001828 req->in.numargs = 1;
1829 req->in.args[0].size = sizeof(inarg);
1830 req->in.args[0].value = &inarg;
1831 /* This is really two different operations rolled into one */
1832 req->out.numargs = 1;
1833 if (size) {
1834 req->out.argvar = 1;
1835 req->out.args[0].size = size;
1836 req->out.args[0].value = list;
1837 } else {
1838 req->out.args[0].size = sizeof(outarg);
1839 req->out.args[0].value = &outarg;
1840 }
Tejun Heob93f8582008-11-26 12:03:55 +01001841 fuse_request_send(fc, req);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001842 ret = req->out.h.error;
1843 if (!ret)
1844 ret = size ? req->out.args[0].size : outarg.size;
1845 else {
1846 if (ret == -ENOSYS) {
1847 fc->no_listxattr = 1;
1848 ret = -EOPNOTSUPP;
1849 }
1850 }
1851 fuse_put_request(fc, req);
1852 return ret;
1853}
1854
1855static int fuse_removexattr(struct dentry *entry, const char *name)
1856{
1857 struct inode *inode = entry->d_inode;
1858 struct fuse_conn *fc = get_fuse_conn(inode);
1859 struct fuse_req *req;
1860 int err;
1861
1862 if (fc->no_removexattr)
1863 return -EOPNOTSUPP;
1864
Maxim Patlasovb111c8c2012-10-26 19:48:30 +04001865 req = fuse_get_req_nopages(fc);
Miklos Szeredice1d5a42006-04-10 22:54:58 -07001866 if (IS_ERR(req))
1867 return PTR_ERR(req);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001868
1869 req->in.h.opcode = FUSE_REMOVEXATTR;
1870 req->in.h.nodeid = get_node_id(inode);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001871 req->in.numargs = 1;
1872 req->in.args[0].size = strlen(name) + 1;
1873 req->in.args[0].value = name;
Tejun Heob93f8582008-11-26 12:03:55 +01001874 fuse_request_send(fc, req);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001875 err = req->out.h.error;
1876 fuse_put_request(fc, req);
1877 if (err == -ENOSYS) {
1878 fc->no_removexattr = 1;
1879 err = -EOPNOTSUPP;
1880 }
1881 return err;
1882}
1883
Arjan van de Ven754661f2007-02-12 00:55:38 -08001884static const struct inode_operations fuse_dir_inode_operations = {
Miklos Szeredie5e55582005-09-09 13:10:28 -07001885 .lookup = fuse_lookup,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001886 .mkdir = fuse_mkdir,
1887 .symlink = fuse_symlink,
1888 .unlink = fuse_unlink,
1889 .rmdir = fuse_rmdir,
1890 .rename = fuse_rename,
1891 .link = fuse_link,
1892 .setattr = fuse_setattr,
1893 .create = fuse_create,
Miklos Szeredic8ccbe02012-06-05 15:10:22 +02001894 .atomic_open = fuse_atomic_open,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001895 .mknod = fuse_mknod,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001896 .permission = fuse_permission,
1897 .getattr = fuse_getattr,
Miklos Szeredi92a87802005-09-09 13:10:31 -07001898 .setxattr = fuse_setxattr,
1899 .getxattr = fuse_getxattr,
1900 .listxattr = fuse_listxattr,
1901 .removexattr = fuse_removexattr,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001902};
1903
Arjan van de Ven4b6f5d22006-03-28 01:56:42 -08001904static const struct file_operations fuse_dir_operations = {
Miklos Szeredib6aeade2005-09-09 13:10:30 -07001905 .llseek = generic_file_llseek,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001906 .read = generic_read_dir,
Al Viro8d3af7f2013-05-18 03:03:58 -04001907 .iterate = fuse_readdir,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001908 .open = fuse_dir_open,
1909 .release = fuse_dir_release,
Miklos Szeredi82547982005-09-09 13:10:38 -07001910 .fsync = fuse_dir_fsync,
Miklos Szeredib18da0c2011-12-13 11:58:49 +01001911 .unlocked_ioctl = fuse_dir_ioctl,
1912 .compat_ioctl = fuse_dir_compat_ioctl,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001913};
1914
Arjan van de Ven754661f2007-02-12 00:55:38 -08001915static const struct inode_operations fuse_common_inode_operations = {
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001916 .setattr = fuse_setattr,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001917 .permission = fuse_permission,
1918 .getattr = fuse_getattr,
Miklos Szeredi92a87802005-09-09 13:10:31 -07001919 .setxattr = fuse_setxattr,
1920 .getxattr = fuse_getxattr,
1921 .listxattr = fuse_listxattr,
1922 .removexattr = fuse_removexattr,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001923};
1924
Arjan van de Ven754661f2007-02-12 00:55:38 -08001925static const struct inode_operations fuse_symlink_inode_operations = {
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001926 .setattr = fuse_setattr,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001927 .follow_link = fuse_follow_link,
1928 .put_link = fuse_put_link,
1929 .readlink = generic_readlink,
1930 .getattr = fuse_getattr,
Miklos Szeredi92a87802005-09-09 13:10:31 -07001931 .setxattr = fuse_setxattr,
1932 .getxattr = fuse_getxattr,
1933 .listxattr = fuse_listxattr,
1934 .removexattr = fuse_removexattr,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001935};
1936
1937void fuse_init_common(struct inode *inode)
1938{
1939 inode->i_op = &fuse_common_inode_operations;
1940}
1941
1942void fuse_init_dir(struct inode *inode)
1943{
1944 inode->i_op = &fuse_dir_inode_operations;
1945 inode->i_fop = &fuse_dir_operations;
1946}
1947
1948void fuse_init_symlink(struct inode *inode)
1949{
1950 inode->i_op = &fuse_symlink_inode_operations;
1951}