blob: a75159846a75b8ddf335dcea0a118c6641920844 [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 Szeredi6314efe2013-10-01 16:41:22 +0200185 struct fuse_inode *fi;
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200186 int ret;
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800187
Miklos Szeredie7c0a162011-03-21 13:58:06 +0100188 inode = ACCESS_ONCE(entry->d_inode);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800189 if (inode && is_bad_inode(inode))
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200190 goto invalid;
Miklos Szeredi0a0898c2006-07-30 03:04:10 -0700191 else if (fuse_dentry_time(entry) < get_jiffies_64()) {
Miklos Szeredie5e55582005-09-09 13:10:28 -0700192 int err;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700193 struct fuse_entry_out outarg;
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800194 struct fuse_req *req;
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100195 struct fuse_forget_link *forget;
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700196 u64 attr_version;
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800197
Miklos Szeredi50322fe2006-02-28 16:59:03 -0800198 /* For negative dentries, always do a fresh lookup */
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800199 if (!inode)
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200200 goto invalid;
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800201
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200202 ret = -ECHILD;
Al Viro0b728e12012-06-10 16:03:43 -0400203 if (flags & LOOKUP_RCU)
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200204 goto out;
Miklos Szeredie7c0a162011-03-21 13:58:06 +0100205
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800206 fc = get_fuse_conn(inode);
Maxim Patlasovb111c8c2012-10-26 19:48:30 +0400207 req = fuse_get_req_nopages(fc);
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200208 ret = PTR_ERR(req);
Miklos Szeredice1d5a42006-04-10 22:54:58 -0700209 if (IS_ERR(req))
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200210 goto out;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700211
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100212 forget = fuse_alloc_forget();
213 if (!forget) {
Miklos Szeredi2d510132006-11-25 11:09:20 -0800214 fuse_put_request(fc, req);
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200215 ret = -ENOMEM;
216 goto out;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800217 }
218
Miklos Szeredi7dca9fd2007-11-28 16:21:59 -0800219 attr_version = fuse_get_attr_version(fc);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700220
Miklos Szeredie956edd2006-10-17 00:10:12 -0700221 parent = dget_parent(entry);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700222 fuse_lookup_init(fc, req, get_node_id(parent->d_inode),
223 &entry->d_name, &outarg);
Tejun Heob93f8582008-11-26 12:03:55 +0100224 fuse_request_send(fc, req);
Miklos Szeredie956edd2006-10-17 00:10:12 -0700225 dput(parent);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700226 err = req->out.h.error;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800227 fuse_put_request(fc, req);
Miklos Szeredi50322fe2006-02-28 16:59:03 -0800228 /* Zero nodeid is same as -ENOENT */
229 if (!err && !outarg.nodeid)
230 err = -ENOENT;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700231 if (!err) {
Miklos Szeredi6314efe2013-10-01 16:41:22 +0200232 fi = get_fuse_inode(inode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700233 if (outarg.nodeid != get_node_id(inode)) {
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100234 fuse_queue_forget(fc, forget, outarg.nodeid, 1);
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200235 goto invalid;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700236 }
Miklos Szeredi8da5ff22006-10-17 00:10:08 -0700237 spin_lock(&fc->lock);
Miklos Szeredi1729a162008-11-26 12:03:54 +0100238 fi->nlookup++;
Miklos Szeredi8da5ff22006-10-17 00:10:08 -0700239 spin_unlock(&fc->lock);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700240 }
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100241 kfree(forget);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700242 if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200243 goto invalid;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700244
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700245 fuse_change_attributes(inode, &outarg.attr,
246 entry_attr_timeout(&outarg),
247 attr_version);
248 fuse_change_entry_timeout(entry, &outarg);
Miklos Szeredi28420da2013-06-03 14:40:22 +0200249 } else if (inode) {
Miklos Szeredi6314efe2013-10-01 16:41:22 +0200250 fi = get_fuse_inode(inode);
251 if (flags & LOOKUP_RCU) {
252 if (test_bit(FUSE_I_INIT_RDPLUS, &fi->state))
253 return -ECHILD;
254 } else if (test_and_clear_bit(FUSE_I_INIT_RDPLUS, &fi->state)) {
Miklos Szeredi28420da2013-06-03 14:40:22 +0200255 parent = dget_parent(entry);
256 fuse_advise_use_readdirplus(parent->d_inode);
257 dput(parent);
258 }
Miklos Szeredie5e55582005-09-09 13:10:28 -0700259 }
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200260 ret = 1;
261out:
262 return ret;
263
264invalid:
265 ret = 0;
Miklos Szeredi3c70b8e2013-10-01 16:41:22 +0200266
267 if (!(flags & LOOKUP_RCU) && check_submounts_and_drop(entry) != 0)
Anand Avati46ea1562013-09-05 11:44:44 +0200268 ret = 1;
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200269 goto out;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700270}
271
Miklos Szeredi8bfc0162006-01-16 22:14:28 -0800272static int invalid_nodeid(u64 nodeid)
Miklos Szeredi2827d0b22005-11-28 13:44:16 -0800273{
274 return !nodeid || nodeid == FUSE_ROOT_ID;
275}
276
Al Viro42695902009-02-20 05:59:13 +0000277const struct dentry_operations fuse_dentry_operations = {
Miklos Szeredie5e55582005-09-09 13:10:28 -0700278 .d_revalidate = fuse_dentry_revalidate,
279};
280
Timo Savolaa5bfffac2007-04-08 16:04:00 -0700281int fuse_valid_type(int m)
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800282{
283 return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) ||
284 S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
285}
286
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700287int fuse_lookup_name(struct super_block *sb, u64 nodeid, struct qstr *name,
288 struct fuse_entry_out *outarg, struct inode **inode)
289{
290 struct fuse_conn *fc = get_fuse_conn_super(sb);
291 struct fuse_req *req;
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100292 struct fuse_forget_link *forget;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700293 u64 attr_version;
294 int err;
295
296 *inode = NULL;
297 err = -ENAMETOOLONG;
298 if (name->len > FUSE_NAME_MAX)
299 goto out;
300
Maxim Patlasovb111c8c2012-10-26 19:48:30 +0400301 req = fuse_get_req_nopages(fc);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700302 err = PTR_ERR(req);
303 if (IS_ERR(req))
304 goto out;
305
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100306 forget = fuse_alloc_forget();
307 err = -ENOMEM;
308 if (!forget) {
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700309 fuse_put_request(fc, req);
310 goto out;
311 }
312
313 attr_version = fuse_get_attr_version(fc);
314
315 fuse_lookup_init(fc, req, nodeid, name, outarg);
Tejun Heob93f8582008-11-26 12:03:55 +0100316 fuse_request_send(fc, req);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700317 err = req->out.h.error;
318 fuse_put_request(fc, req);
319 /* Zero nodeid is same as -ENOENT, but with valid timeout */
320 if (err || !outarg->nodeid)
321 goto out_put_forget;
322
323 err = -EIO;
324 if (!outarg->nodeid)
325 goto out_put_forget;
326 if (!fuse_valid_type(outarg->attr.mode))
327 goto out_put_forget;
328
329 *inode = fuse_iget(sb, outarg->nodeid, outarg->generation,
330 &outarg->attr, entry_attr_timeout(outarg),
331 attr_version);
332 err = -ENOMEM;
333 if (!*inode) {
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100334 fuse_queue_forget(fc, forget, outarg->nodeid, 1);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700335 goto out;
336 }
337 err = 0;
338
339 out_put_forget:
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100340 kfree(forget);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700341 out:
342 return err;
343}
344
Miklos Szeredi5835f332013-09-05 11:44:42 +0200345static struct dentry *fuse_materialise_dentry(struct dentry *dentry,
346 struct inode *inode)
347{
348 struct dentry *newent;
349
350 if (inode && S_ISDIR(inode->i_mode)) {
351 struct fuse_conn *fc = get_fuse_conn(inode);
352
353 mutex_lock(&fc->inst_mutex);
354 newent = d_materialise_unique(dentry, inode);
355 mutex_unlock(&fc->inst_mutex);
356 } else {
357 newent = d_materialise_unique(dentry, inode);
358 }
359
360 return newent;
361}
362
Miklos Szeredi0aa7c692006-01-06 00:19:34 -0800363static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
Al Viro00cd8dd2012-06-10 17:13:09 -0400364 unsigned int flags)
Miklos Szeredie5e55582005-09-09 13:10:28 -0700365{
366 int err;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700367 struct fuse_entry_out outarg;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700368 struct inode *inode;
Miklos Szeredi0de62562008-07-25 01:48:59 -0700369 struct dentry *newent;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700370 bool outarg_valid = true;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700371
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700372 err = fuse_lookup_name(dir->i_sb, get_node_id(dir), &entry->d_name,
373 &outarg, &inode);
374 if (err == -ENOENT) {
375 outarg_valid = false;
376 err = 0;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800377 }
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700378 if (err)
379 goto out_err;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800380
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700381 err = -EIO;
382 if (inode && get_node_id(inode) == FUSE_ROOT_ID)
383 goto out_iput;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700384
Miklos Szeredi5835f332013-09-05 11:44:42 +0200385 newent = fuse_materialise_dentry(entry, inode);
386 err = PTR_ERR(newent);
387 if (IS_ERR(newent))
388 goto out_err;
Miklos Szeredid2a85162006-10-17 00:10:11 -0700389
Miklos Szeredi0de62562008-07-25 01:48:59 -0700390 entry = newent ? newent : entry;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700391 if (outarg_valid)
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700392 fuse_change_entry_timeout(entry, &outarg);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800393 else
394 fuse_invalidate_entry_cache(entry);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700395
Feng Shuo4582a4a2013-01-15 11:23:28 +0800396 fuse_advise_use_readdirplus(dir);
Miklos Szeredi0de62562008-07-25 01:48:59 -0700397 return newent;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700398
399 out_iput:
400 iput(inode);
401 out_err:
402 return ERR_PTR(err);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700403}
404
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800405/*
406 * Atomic create+open operation
407 *
408 * If the filesystem doesn't support this, then fall back to separate
409 * 'mknod' + 'open' requests.
410 */
Al Virod9585272012-06-22 12:39:14 +0400411static int fuse_create_open(struct inode *dir, struct dentry *entry,
Al Viro30d90492012-06-22 12:40:19 +0400412 struct file *file, unsigned flags,
Al Virod9585272012-06-22 12:39:14 +0400413 umode_t mode, int *opened)
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800414{
415 int err;
416 struct inode *inode;
417 struct fuse_conn *fc = get_fuse_conn(dir);
418 struct fuse_req *req;
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100419 struct fuse_forget_link *forget;
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200420 struct fuse_create_in inarg;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800421 struct fuse_open_out outopen;
422 struct fuse_entry_out outentry;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800423 struct fuse_file *ff;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800424
Miklos Szerediaf109bc2012-08-15 13:01:24 +0200425 /* Userspace expects S_IFREG in create mode */
426 BUG_ON((mode & S_IFMT) != S_IFREG);
427
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100428 forget = fuse_alloc_forget();
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200429 err = -ENOMEM;
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100430 if (!forget)
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200431 goto out_err;
Miklos Szeredi51eb01e2006-06-25 05:48:50 -0700432
Maxim Patlasovb111c8c2012-10-26 19:48:30 +0400433 req = fuse_get_req_nopages(fc);
Miklos Szeredi51eb01e2006-06-25 05:48:50 -0700434 err = PTR_ERR(req);
Miklos Szeredice1d5a42006-04-10 22:54:58 -0700435 if (IS_ERR(req))
Miklos Szeredi51eb01e2006-06-25 05:48:50 -0700436 goto out_put_forget_req;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800437
Miklos Szeredice1d5a42006-04-10 22:54:58 -0700438 err = -ENOMEM;
Tejun Heoacf99432008-11-26 12:03:55 +0100439 ff = fuse_file_alloc(fc);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800440 if (!ff)
441 goto out_put_request;
442
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200443 if (!fc->dont_mask)
444 mode &= ~current_umask();
445
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800446 flags &= ~O_NOCTTY;
447 memset(&inarg, 0, sizeof(inarg));
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700448 memset(&outentry, 0, sizeof(outentry));
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800449 inarg.flags = flags;
450 inarg.mode = mode;
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200451 inarg.umask = current_umask();
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800452 req->in.h.opcode = FUSE_CREATE;
453 req->in.h.nodeid = get_node_id(dir);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800454 req->in.numargs = 2;
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200455 req->in.args[0].size = fc->minor < 12 ? sizeof(struct fuse_open_in) :
456 sizeof(inarg);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800457 req->in.args[0].value = &inarg;
458 req->in.args[1].size = entry->d_name.len + 1;
459 req->in.args[1].value = entry->d_name.name;
460 req->out.numargs = 2;
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700461 if (fc->minor < 9)
462 req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
463 else
464 req->out.args[0].size = sizeof(outentry);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800465 req->out.args[0].value = &outentry;
466 req->out.args[1].size = sizeof(outopen);
467 req->out.args[1].value = &outopen;
Tejun Heob93f8582008-11-26 12:03:55 +0100468 fuse_request_send(fc, req);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800469 err = req->out.h.error;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200470 if (err)
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800471 goto out_free_ff;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800472
473 err = -EIO;
Miklos Szeredi2827d0b22005-11-28 13:44:16 -0800474 if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid))
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800475 goto out_free_ff;
476
Miklos Szeredi51eb01e2006-06-25 05:48:50 -0700477 fuse_put_request(fc, req);
Miklos Szeredic7b71432009-04-28 16:56:37 +0200478 ff->fh = outopen.fh;
479 ff->nodeid = outentry.nodeid;
480 ff->open_flags = outopen.open_flags;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800481 inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700482 &outentry.attr, entry_attr_timeout(&outentry), 0);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800483 if (!inode) {
484 flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
Miklos Szeredi8b0797a2009-04-28 16:56:39 +0200485 fuse_sync_release(ff, flags);
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100486 fuse_queue_forget(fc, forget, outentry.nodeid, 1);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200487 err = -ENOMEM;
488 goto out_err;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800489 }
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100490 kfree(forget);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800491 d_instantiate(entry, inode);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700492 fuse_change_entry_timeout(entry, &outentry);
Miklos Szeredi0952b2a2008-02-06 01:38:38 -0800493 fuse_invalidate_attr(dir);
Al Viro30d90492012-06-22 12:40:19 +0400494 err = finish_open(file, entry, generic_file_open, opened);
495 if (err) {
Miklos Szeredi8b0797a2009-04-28 16:56:39 +0200496 fuse_sync_release(ff, flags);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200497 } else {
498 file->private_data = fuse_file_get(ff);
499 fuse_finish_open(inode, file);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800500 }
Al Virod9585272012-06-22 12:39:14 +0400501 return err;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800502
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200503out_free_ff:
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800504 fuse_file_free(ff);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200505out_put_request:
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800506 fuse_put_request(fc, req);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200507out_put_forget_req:
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100508 kfree(forget);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200509out_err:
Al Virod9585272012-06-22 12:39:14 +0400510 return err;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200511}
512
513static int fuse_mknod(struct inode *, struct dentry *, umode_t, dev_t);
Al Virod9585272012-06-22 12:39:14 +0400514static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
Al Viro30d90492012-06-22 12:40:19 +0400515 struct file *file, unsigned flags,
Al Virod9585272012-06-22 12:39:14 +0400516 umode_t mode, int *opened)
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200517{
518 int err;
519 struct fuse_conn *fc = get_fuse_conn(dir);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200520 struct dentry *res = NULL;
521
522 if (d_unhashed(entry)) {
Al Viro00cd8dd2012-06-10 17:13:09 -0400523 res = fuse_lookup(dir, entry, 0);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200524 if (IS_ERR(res))
Al Virod9585272012-06-22 12:39:14 +0400525 return PTR_ERR(res);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200526
527 if (res)
528 entry = res;
529 }
530
531 if (!(flags & O_CREAT) || entry->d_inode)
532 goto no_open;
533
534 /* Only creates */
Al Viro47237682012-06-10 05:01:45 -0400535 *opened |= FILE_CREATED;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200536
537 if (fc->no_create)
538 goto mknod;
539
Al Viro30d90492012-06-22 12:40:19 +0400540 err = fuse_create_open(dir, entry, file, flags, mode, opened);
Al Virod9585272012-06-22 12:39:14 +0400541 if (err == -ENOSYS) {
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200542 fc->no_create = 1;
543 goto mknod;
544 }
545out_dput:
546 dput(res);
Al Virod9585272012-06-22 12:39:14 +0400547 return err;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200548
549mknod:
550 err = fuse_mknod(dir, entry, mode, 0);
Al Virod9585272012-06-22 12:39:14 +0400551 if (err)
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200552 goto out_dput;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200553no_open:
Al Viroe45198a2012-06-10 06:48:09 -0400554 return finish_no_open(file, res);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800555}
556
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800557/*
558 * Code shared between mknod, mkdir, symlink and link
559 */
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700560static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
561 struct inode *dir, struct dentry *entry,
Al Viro541af6a2011-07-26 03:17:33 -0400562 umode_t mode)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700563{
564 struct fuse_entry_out outarg;
565 struct inode *inode;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700566 int err;
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100567 struct fuse_forget_link *forget;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800568
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100569 forget = fuse_alloc_forget();
570 if (!forget) {
Miklos Szeredi2d510132006-11-25 11:09:20 -0800571 fuse_put_request(fc, req);
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100572 return -ENOMEM;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800573 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700574
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700575 memset(&outarg, 0, sizeof(outarg));
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700576 req->in.h.nodeid = get_node_id(dir);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700577 req->out.numargs = 1;
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700578 if (fc->minor < 9)
579 req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
580 else
581 req->out.args[0].size = sizeof(outarg);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700582 req->out.args[0].value = &outarg;
Tejun Heob93f8582008-11-26 12:03:55 +0100583 fuse_request_send(fc, req);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700584 err = req->out.h.error;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800585 fuse_put_request(fc, req);
586 if (err)
587 goto out_put_forget_req;
588
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800589 err = -EIO;
590 if (invalid_nodeid(outarg.nodeid))
Miklos Szeredi2d510132006-11-25 11:09:20 -0800591 goto out_put_forget_req;
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800592
593 if ((outarg.attr.mode ^ mode) & S_IFMT)
Miklos Szeredi2d510132006-11-25 11:09:20 -0800594 goto out_put_forget_req;
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800595
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700596 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700597 &outarg.attr, entry_attr_timeout(&outarg), 0);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700598 if (!inode) {
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100599 fuse_queue_forget(fc, forget, outarg.nodeid, 1);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700600 return -ENOMEM;
601 }
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100602 kfree(forget);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700603
Miklos Szeredid2a85162006-10-17 00:10:11 -0700604 if (S_ISDIR(inode->i_mode)) {
605 struct dentry *alias;
606 mutex_lock(&fc->inst_mutex);
607 alias = d_find_alias(inode);
608 if (alias) {
609 /* New directory must have moved since mkdir */
610 mutex_unlock(&fc->inst_mutex);
611 dput(alias);
612 iput(inode);
613 return -EBUSY;
614 }
615 d_instantiate(entry, inode);
616 mutex_unlock(&fc->inst_mutex);
617 } else
618 d_instantiate(entry, inode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700619
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700620 fuse_change_entry_timeout(entry, &outarg);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700621 fuse_invalidate_attr(dir);
622 return 0;
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800623
Miklos Szeredi2d510132006-11-25 11:09:20 -0800624 out_put_forget_req:
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100625 kfree(forget);
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800626 return err;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700627}
628
Al Viro1a67aaf2011-07-26 01:52:52 -0400629static int fuse_mknod(struct inode *dir, struct dentry *entry, umode_t mode,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700630 dev_t rdev)
631{
632 struct fuse_mknod_in inarg;
633 struct fuse_conn *fc = get_fuse_conn(dir);
Maxim Patlasovb111c8c2012-10-26 19:48:30 +0400634 struct fuse_req *req = fuse_get_req_nopages(fc);
Miklos Szeredice1d5a42006-04-10 22:54:58 -0700635 if (IS_ERR(req))
636 return PTR_ERR(req);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700637
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200638 if (!fc->dont_mask)
639 mode &= ~current_umask();
640
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700641 memset(&inarg, 0, sizeof(inarg));
642 inarg.mode = mode;
643 inarg.rdev = new_encode_dev(rdev);
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200644 inarg.umask = current_umask();
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700645 req->in.h.opcode = FUSE_MKNOD;
646 req->in.numargs = 2;
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200647 req->in.args[0].size = fc->minor < 12 ? FUSE_COMPAT_MKNOD_IN_SIZE :
648 sizeof(inarg);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700649 req->in.args[0].value = &inarg;
650 req->in.args[1].size = entry->d_name.len + 1;
651 req->in.args[1].value = entry->d_name.name;
652 return create_new_entry(fc, req, dir, entry, mode);
653}
654
Al Viro4acdaf22011-07-26 01:42:34 -0400655static int fuse_create(struct inode *dir, struct dentry *entry, umode_t mode,
Al Viroebfc3b42012-06-10 18:05:36 -0400656 bool excl)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700657{
658 return fuse_mknod(dir, entry, mode, 0);
659}
660
Al Viro18bb1db2011-07-26 01:41:39 -0400661static int fuse_mkdir(struct inode *dir, struct dentry *entry, umode_t mode)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700662{
663 struct fuse_mkdir_in inarg;
664 struct fuse_conn *fc = get_fuse_conn(dir);
Maxim Patlasovb111c8c2012-10-26 19:48:30 +0400665 struct fuse_req *req = fuse_get_req_nopages(fc);
Miklos Szeredice1d5a42006-04-10 22:54:58 -0700666 if (IS_ERR(req))
667 return PTR_ERR(req);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700668
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200669 if (!fc->dont_mask)
670 mode &= ~current_umask();
671
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700672 memset(&inarg, 0, sizeof(inarg));
673 inarg.mode = mode;
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200674 inarg.umask = current_umask();
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700675 req->in.h.opcode = FUSE_MKDIR;
676 req->in.numargs = 2;
677 req->in.args[0].size = sizeof(inarg);
678 req->in.args[0].value = &inarg;
679 req->in.args[1].size = entry->d_name.len + 1;
680 req->in.args[1].value = entry->d_name.name;
681 return create_new_entry(fc, req, dir, entry, S_IFDIR);
682}
683
684static int fuse_symlink(struct inode *dir, struct dentry *entry,
685 const char *link)
686{
687 struct fuse_conn *fc = get_fuse_conn(dir);
688 unsigned len = strlen(link) + 1;
Maxim Patlasovb111c8c2012-10-26 19:48:30 +0400689 struct fuse_req *req = fuse_get_req_nopages(fc);
Miklos Szeredice1d5a42006-04-10 22:54:58 -0700690 if (IS_ERR(req))
691 return PTR_ERR(req);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700692
693 req->in.h.opcode = FUSE_SYMLINK;
694 req->in.numargs = 2;
695 req->in.args[0].size = entry->d_name.len + 1;
696 req->in.args[0].value = entry->d_name.name;
697 req->in.args[1].size = len;
698 req->in.args[1].value = link;
699 return create_new_entry(fc, req, dir, entry, S_IFLNK);
700}
701
702static int fuse_unlink(struct inode *dir, struct dentry *entry)
703{
704 int err;
705 struct fuse_conn *fc = get_fuse_conn(dir);
Maxim Patlasovb111c8c2012-10-26 19:48:30 +0400706 struct fuse_req *req = fuse_get_req_nopages(fc);
Miklos Szeredice1d5a42006-04-10 22:54:58 -0700707 if (IS_ERR(req))
708 return PTR_ERR(req);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700709
710 req->in.h.opcode = FUSE_UNLINK;
711 req->in.h.nodeid = get_node_id(dir);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700712 req->in.numargs = 1;
713 req->in.args[0].size = entry->d_name.len + 1;
714 req->in.args[0].value = entry->d_name.name;
Tejun Heob93f8582008-11-26 12:03:55 +0100715 fuse_request_send(fc, req);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700716 err = req->out.h.error;
717 fuse_put_request(fc, req);
718 if (!err) {
719 struct inode *inode = entry->d_inode;
Miklos Szerediac45d612012-03-05 15:48:11 +0100720 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700721
Miklos Szerediac45d612012-03-05 15:48:11 +0100722 spin_lock(&fc->lock);
723 fi->attr_version = ++fc->attr_version;
Miklos Szeredidfca7ce2013-02-04 15:57:42 +0100724 /*
725 * If i_nlink == 0 then unlink doesn't make sense, yet this can
726 * happen if userspace filesystem is careless. It would be
727 * difficult to enforce correct nlink usage so just ignore this
728 * condition here
729 */
730 if (inode->i_nlink > 0)
731 drop_nlink(inode);
Miklos Szerediac45d612012-03-05 15:48:11 +0100732 spin_unlock(&fc->lock);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700733 fuse_invalidate_attr(inode);
734 fuse_invalidate_attr(dir);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800735 fuse_invalidate_entry_cache(entry);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700736 } else if (err == -EINTR)
737 fuse_invalidate_entry(entry);
738 return err;
739}
740
741static int fuse_rmdir(struct inode *dir, struct dentry *entry)
742{
743 int err;
744 struct fuse_conn *fc = get_fuse_conn(dir);
Maxim Patlasovb111c8c2012-10-26 19:48:30 +0400745 struct fuse_req *req = fuse_get_req_nopages(fc);
Miklos Szeredice1d5a42006-04-10 22:54:58 -0700746 if (IS_ERR(req))
747 return PTR_ERR(req);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700748
749 req->in.h.opcode = FUSE_RMDIR;
750 req->in.h.nodeid = get_node_id(dir);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700751 req->in.numargs = 1;
752 req->in.args[0].size = entry->d_name.len + 1;
753 req->in.args[0].value = entry->d_name.name;
Tejun Heob93f8582008-11-26 12:03:55 +0100754 fuse_request_send(fc, req);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700755 err = req->out.h.error;
756 fuse_put_request(fc, req);
757 if (!err) {
Dave Hansence71ec32006-09-30 23:29:06 -0700758 clear_nlink(entry->d_inode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700759 fuse_invalidate_attr(dir);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800760 fuse_invalidate_entry_cache(entry);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700761 } else if (err == -EINTR)
762 fuse_invalidate_entry(entry);
763 return err;
764}
765
766static int fuse_rename(struct inode *olddir, struct dentry *oldent,
767 struct inode *newdir, struct dentry *newent)
768{
769 int err;
770 struct fuse_rename_in inarg;
771 struct fuse_conn *fc = get_fuse_conn(olddir);
Maxim Patlasovb111c8c2012-10-26 19:48:30 +0400772 struct fuse_req *req = fuse_get_req_nopages(fc);
Sage Weile4eaac02011-05-24 13:06:07 -0700773
Miklos Szeredice1d5a42006-04-10 22:54:58 -0700774 if (IS_ERR(req))
775 return PTR_ERR(req);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700776
777 memset(&inarg, 0, sizeof(inarg));
778 inarg.newdir = get_node_id(newdir);
779 req->in.h.opcode = FUSE_RENAME;
780 req->in.h.nodeid = get_node_id(olddir);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700781 req->in.numargs = 3;
782 req->in.args[0].size = sizeof(inarg);
783 req->in.args[0].value = &inarg;
784 req->in.args[1].size = oldent->d_name.len + 1;
785 req->in.args[1].value = oldent->d_name.name;
786 req->in.args[2].size = newent->d_name.len + 1;
787 req->in.args[2].value = newent->d_name.name;
Tejun Heob93f8582008-11-26 12:03:55 +0100788 fuse_request_send(fc, req);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700789 err = req->out.h.error;
790 fuse_put_request(fc, req);
791 if (!err) {
Miklos Szeredi08b63302007-11-28 16:22:03 -0800792 /* ctime changes */
793 fuse_invalidate_attr(oldent->d_inode);
794
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700795 fuse_invalidate_attr(olddir);
796 if (olddir != newdir)
797 fuse_invalidate_attr(newdir);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800798
799 /* newent will end up negative */
Miklos Szeredi5219f342009-11-04 10:24:52 +0100800 if (newent->d_inode) {
801 fuse_invalidate_attr(newent->d_inode);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800802 fuse_invalidate_entry_cache(newent);
Miklos Szeredi5219f342009-11-04 10:24:52 +0100803 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700804 } else if (err == -EINTR) {
805 /* If request was interrupted, DEITY only knows if the
806 rename actually took place. If the invalidation
807 fails (e.g. some process has CWD under the renamed
808 directory), then there can be inconsistency between
809 the dcache and the real filesystem. Tough luck. */
810 fuse_invalidate_entry(oldent);
811 if (newent->d_inode)
812 fuse_invalidate_entry(newent);
813 }
814
815 return err;
816}
817
818static int fuse_link(struct dentry *entry, struct inode *newdir,
819 struct dentry *newent)
820{
821 int err;
822 struct fuse_link_in inarg;
823 struct inode *inode = entry->d_inode;
824 struct fuse_conn *fc = get_fuse_conn(inode);
Maxim Patlasovb111c8c2012-10-26 19:48:30 +0400825 struct fuse_req *req = fuse_get_req_nopages(fc);
Miklos Szeredice1d5a42006-04-10 22:54:58 -0700826 if (IS_ERR(req))
827 return PTR_ERR(req);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700828
829 memset(&inarg, 0, sizeof(inarg));
830 inarg.oldnodeid = get_node_id(inode);
831 req->in.h.opcode = FUSE_LINK;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700832 req->in.numargs = 2;
833 req->in.args[0].size = sizeof(inarg);
834 req->in.args[0].value = &inarg;
835 req->in.args[1].size = newent->d_name.len + 1;
836 req->in.args[1].value = newent->d_name.name;
837 err = create_new_entry(fc, req, newdir, newent, inode->i_mode);
838 /* Contrary to "normal" filesystems it can happen that link
839 makes two "logical" inodes point to the same "physical"
840 inode. We invalidate the attributes of the old one, so it
841 will reflect changes in the backing inode (link count,
842 etc.)
843 */
Miklos Szerediac45d612012-03-05 15:48:11 +0100844 if (!err) {
845 struct fuse_inode *fi = get_fuse_inode(inode);
846
847 spin_lock(&fc->lock);
848 fi->attr_version = ++fc->attr_version;
849 inc_nlink(inode);
850 spin_unlock(&fc->lock);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700851 fuse_invalidate_attr(inode);
Miklos Szerediac45d612012-03-05 15:48:11 +0100852 } else if (err == -EINTR) {
853 fuse_invalidate_attr(inode);
854 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700855 return err;
856}
857
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700858static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
859 struct kstat *stat)
860{
Miklos Szeredi203627b2012-05-10 19:49:38 +0400861 unsigned int blkbits;
862
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700863 stat->dev = inode->i_sb->s_dev;
864 stat->ino = attr->ino;
865 stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
866 stat->nlink = attr->nlink;
Eric W. Biederman499dcf22012-02-07 16:26:03 -0800867 stat->uid = make_kuid(&init_user_ns, attr->uid);
868 stat->gid = make_kgid(&init_user_ns, attr->gid);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700869 stat->rdev = inode->i_rdev;
870 stat->atime.tv_sec = attr->atime;
871 stat->atime.tv_nsec = attr->atimensec;
872 stat->mtime.tv_sec = attr->mtime;
873 stat->mtime.tv_nsec = attr->mtimensec;
874 stat->ctime.tv_sec = attr->ctime;
875 stat->ctime.tv_nsec = attr->ctimensec;
876 stat->size = attr->size;
877 stat->blocks = attr->blocks;
Miklos Szeredi203627b2012-05-10 19:49:38 +0400878
879 if (attr->blksize != 0)
880 blkbits = ilog2(attr->blksize);
881 else
882 blkbits = inode->i_sb->s_blocksize_bits;
883
884 stat->blksize = 1 << blkbits;
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700885}
886
Miklos Szeredic79e3222007-10-18 03:06:59 -0700887static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
888 struct file *file)
Miklos Szeredie5e55582005-09-09 13:10:28 -0700889{
890 int err;
Miklos Szeredic79e3222007-10-18 03:06:59 -0700891 struct fuse_getattr_in inarg;
892 struct fuse_attr_out outarg;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700893 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700894 struct fuse_req *req;
895 u64 attr_version;
896
Maxim Patlasovb111c8c2012-10-26 19:48:30 +0400897 req = fuse_get_req_nopages(fc);
Miklos Szeredice1d5a42006-04-10 22:54:58 -0700898 if (IS_ERR(req))
899 return PTR_ERR(req);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700900
Miklos Szeredi7dca9fd2007-11-28 16:21:59 -0800901 attr_version = fuse_get_attr_version(fc);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700902
Miklos Szeredic79e3222007-10-18 03:06:59 -0700903 memset(&inarg, 0, sizeof(inarg));
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700904 memset(&outarg, 0, sizeof(outarg));
Miklos Szeredic79e3222007-10-18 03:06:59 -0700905 /* Directories have separate file-handle space */
906 if (file && S_ISREG(inode->i_mode)) {
907 struct fuse_file *ff = file->private_data;
908
909 inarg.getattr_flags |= FUSE_GETATTR_FH;
910 inarg.fh = ff->fh;
911 }
Miklos Szeredie5e55582005-09-09 13:10:28 -0700912 req->in.h.opcode = FUSE_GETATTR;
913 req->in.h.nodeid = get_node_id(inode);
Miklos Szeredic79e3222007-10-18 03:06:59 -0700914 req->in.numargs = 1;
915 req->in.args[0].size = sizeof(inarg);
916 req->in.args[0].value = &inarg;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700917 req->out.numargs = 1;
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700918 if (fc->minor < 9)
919 req->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
920 else
921 req->out.args[0].size = sizeof(outarg);
Miklos Szeredic79e3222007-10-18 03:06:59 -0700922 req->out.args[0].value = &outarg;
Tejun Heob93f8582008-11-26 12:03:55 +0100923 fuse_request_send(fc, req);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700924 err = req->out.h.error;
925 fuse_put_request(fc, req);
926 if (!err) {
Miklos Szeredic79e3222007-10-18 03:06:59 -0700927 if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
Miklos Szeredie5e55582005-09-09 13:10:28 -0700928 make_bad_inode(inode);
929 err = -EIO;
930 } else {
Miklos Szeredic79e3222007-10-18 03:06:59 -0700931 fuse_change_attributes(inode, &outarg.attr,
932 attr_timeout(&outarg),
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700933 attr_version);
934 if (stat)
Miklos Szeredic79e3222007-10-18 03:06:59 -0700935 fuse_fillattr(inode, &outarg.attr, stat);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700936 }
937 }
938 return err;
939}
940
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800941int fuse_update_attributes(struct inode *inode, struct kstat *stat,
942 struct file *file, bool *refreshed)
943{
944 struct fuse_inode *fi = get_fuse_inode(inode);
945 int err;
946 bool r;
947
948 if (fi->i_time < get_jiffies_64()) {
949 r = true;
950 err = fuse_do_getattr(inode, stat, file);
951 } else {
952 r = false;
953 err = 0;
954 if (stat) {
955 generic_fillattr(inode, stat);
956 stat->mode = fi->orig_i_mode;
Pavel Shilovsky45c72cd2012-05-10 19:49:38 +0400957 stat->ino = fi->orig_ino;
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800958 }
959 }
960
961 if (refreshed != NULL)
962 *refreshed = r;
963
964 return err;
965}
966
John Muir3b463ae2009-05-31 11:13:57 -0400967int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid,
John Muir451d0f52011-12-06 21:50:06 +0100968 u64 child_nodeid, struct qstr *name)
John Muir3b463ae2009-05-31 11:13:57 -0400969{
970 int err = -ENOTDIR;
971 struct inode *parent;
972 struct dentry *dir;
973 struct dentry *entry;
974
975 parent = ilookup5(sb, parent_nodeid, fuse_inode_eq, &parent_nodeid);
976 if (!parent)
977 return -ENOENT;
978
979 mutex_lock(&parent->i_mutex);
980 if (!S_ISDIR(parent->i_mode))
981 goto unlock;
982
983 err = -ENOENT;
984 dir = d_find_alias(parent);
985 if (!dir)
986 goto unlock;
987
988 entry = d_lookup(dir, name);
989 dput(dir);
990 if (!entry)
991 goto unlock;
992
993 fuse_invalidate_attr(parent);
994 fuse_invalidate_entry(entry);
John Muir451d0f52011-12-06 21:50:06 +0100995
996 if (child_nodeid != 0 && entry->d_inode) {
997 mutex_lock(&entry->d_inode->i_mutex);
998 if (get_node_id(entry->d_inode) != child_nodeid) {
999 err = -ENOENT;
1000 goto badentry;
1001 }
1002 if (d_mountpoint(entry)) {
1003 err = -EBUSY;
1004 goto badentry;
1005 }
1006 if (S_ISDIR(entry->d_inode->i_mode)) {
1007 shrink_dcache_parent(entry);
1008 if (!simple_empty(entry)) {
1009 err = -ENOTEMPTY;
1010 goto badentry;
1011 }
1012 entry->d_inode->i_flags |= S_DEAD;
1013 }
1014 dont_mount(entry);
1015 clear_nlink(entry->d_inode);
1016 err = 0;
1017 badentry:
1018 mutex_unlock(&entry->d_inode->i_mutex);
1019 if (!err)
1020 d_delete(entry);
1021 } else {
1022 err = 0;
1023 }
John Muir3b463ae2009-05-31 11:13:57 -04001024 dput(entry);
John Muir3b463ae2009-05-31 11:13:57 -04001025
1026 unlock:
1027 mutex_unlock(&parent->i_mutex);
1028 iput(parent);
1029 return err;
1030}
1031
Miklos Szeredi87729a52005-09-09 13:10:34 -07001032/*
1033 * Calling into a user-controlled filesystem gives the filesystem
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001034 * daemon ptrace-like capabilities over the current process. This
Miklos Szeredi87729a52005-09-09 13:10:34 -07001035 * means, that the filesystem daemon is able to record the exact
1036 * filesystem operations performed, and can also control the behavior
1037 * of the requester process in otherwise impossible ways. For example
1038 * it can delay the operation for arbitrary length of time allowing
1039 * DoS against the requester.
1040 *
1041 * For this reason only those processes can call into the filesystem,
1042 * for which the owner of the mount has ptrace privilege. This
1043 * excludes processes started by other users, suid or sgid processes.
1044 */
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001045int fuse_allow_current_process(struct fuse_conn *fc)
Miklos Szeredi87729a52005-09-09 13:10:34 -07001046{
David Howellsc69e8d92008-11-14 10:39:19 +11001047 const struct cred *cred;
David Howellsc69e8d92008-11-14 10:39:19 +11001048
Miklos Szeredi87729a52005-09-09 13:10:34 -07001049 if (fc->flags & FUSE_ALLOW_OTHER)
1050 return 1;
1051
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001052 cred = current_cred();
Eric W. Biederman499dcf22012-02-07 16:26:03 -08001053 if (uid_eq(cred->euid, fc->user_id) &&
1054 uid_eq(cred->suid, fc->user_id) &&
1055 uid_eq(cred->uid, fc->user_id) &&
1056 gid_eq(cred->egid, fc->group_id) &&
1057 gid_eq(cred->sgid, fc->group_id) &&
1058 gid_eq(cred->gid, fc->group_id))
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001059 return 1;
Miklos Szeredi87729a52005-09-09 13:10:34 -07001060
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001061 return 0;
Miklos Szeredi87729a52005-09-09 13:10:34 -07001062}
1063
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001064static int fuse_access(struct inode *inode, int mask)
1065{
1066 struct fuse_conn *fc = get_fuse_conn(inode);
1067 struct fuse_req *req;
1068 struct fuse_access_in inarg;
1069 int err;
1070
1071 if (fc->no_access)
1072 return 0;
1073
Maxim Patlasovb111c8c2012-10-26 19:48:30 +04001074 req = fuse_get_req_nopages(fc);
Miklos Szeredice1d5a42006-04-10 22:54:58 -07001075 if (IS_ERR(req))
1076 return PTR_ERR(req);
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001077
1078 memset(&inarg, 0, sizeof(inarg));
Al Viroe6305c42008-07-15 21:03:57 -04001079 inarg.mask = mask & (MAY_READ | MAY_WRITE | MAY_EXEC);
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001080 req->in.h.opcode = FUSE_ACCESS;
1081 req->in.h.nodeid = get_node_id(inode);
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001082 req->in.numargs = 1;
1083 req->in.args[0].size = sizeof(inarg);
1084 req->in.args[0].value = &inarg;
Tejun Heob93f8582008-11-26 12:03:55 +01001085 fuse_request_send(fc, req);
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001086 err = req->out.h.error;
1087 fuse_put_request(fc, req);
1088 if (err == -ENOSYS) {
1089 fc->no_access = 1;
1090 err = 0;
1091 }
1092 return err;
1093}
1094
Al Viro10556cb22011-06-20 19:28:19 -04001095static int fuse_perm_getattr(struct inode *inode, int mask)
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001096{
Al Viro10556cb22011-06-20 19:28:19 -04001097 if (mask & MAY_NOT_BLOCK)
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001098 return -ECHILD;
1099
1100 return fuse_do_getattr(inode, NULL, NULL);
1101}
1102
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001103/*
1104 * Check permission. The two basic access models of FUSE are:
1105 *
1106 * 1) Local access checking ('default_permissions' mount option) based
1107 * on file mode. This is the plain old disk filesystem permission
1108 * modell.
1109 *
1110 * 2) "Remote" access checking, where server is responsible for
1111 * checking permission in each inode operation. An exception to this
1112 * is if ->permission() was invoked from sys_access() in which case an
1113 * access request is sent. Execute permission is still checked
1114 * locally based on file mode.
1115 */
Al Viro10556cb22011-06-20 19:28:19 -04001116static int fuse_permission(struct inode *inode, int mask)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001117{
1118 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi244f6382007-10-16 23:31:02 -07001119 bool refreshed = false;
1120 int err = 0;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001121
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001122 if (!fuse_allow_current_process(fc))
Miklos Szeredie5e55582005-09-09 13:10:28 -07001123 return -EACCES;
Miklos Szeredi244f6382007-10-16 23:31:02 -07001124
1125 /*
Miklos Szeredie8e96152007-10-16 23:31:06 -07001126 * If attributes are needed, refresh them before proceeding
Miklos Szeredi244f6382007-10-16 23:31:02 -07001127 */
Miklos Szeredie8e96152007-10-16 23:31:06 -07001128 if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) ||
1129 ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) {
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001130 struct fuse_inode *fi = get_fuse_inode(inode);
1131
1132 if (fi->i_time < get_jiffies_64()) {
1133 refreshed = true;
1134
Al Viro10556cb22011-06-20 19:28:19 -04001135 err = fuse_perm_getattr(inode, mask);
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001136 if (err)
1137 return err;
1138 }
Miklos Szeredi244f6382007-10-16 23:31:02 -07001139 }
1140
1141 if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
Al Viro2830ba72011-06-20 19:16:29 -04001142 err = generic_permission(inode, mask);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001143
1144 /* If permission is denied, try to refresh file
1145 attributes. This is also needed, because the root
1146 node will at first have no permissions */
Miklos Szeredi244f6382007-10-16 23:31:02 -07001147 if (err == -EACCES && !refreshed) {
Al Viro10556cb22011-06-20 19:28:19 -04001148 err = fuse_perm_getattr(inode, mask);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001149 if (!err)
Al Viro2830ba72011-06-20 19:16:29 -04001150 err = generic_permission(inode, mask);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001151 }
1152
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001153 /* Note: the opposite of the above test does not
1154 exist. So if permissions are revoked this won't be
1155 noticed immediately, only after the attribute
1156 timeout has expired */
Eric Paris9cfcac82010-07-23 11:43:51 -04001157 } else if (mask & (MAY_ACCESS | MAY_CHDIR)) {
Al Viro10556cb22011-06-20 19:28:19 -04001158 if (mask & MAY_NOT_BLOCK)
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001159 return -ECHILD;
1160
Miklos Szeredie8e96152007-10-16 23:31:06 -07001161 err = fuse_access(inode, mask);
1162 } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
1163 if (!(inode->i_mode & S_IXUGO)) {
1164 if (refreshed)
1165 return -EACCES;
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001166
Al Viro10556cb22011-06-20 19:28:19 -04001167 err = fuse_perm_getattr(inode, mask);
Miklos Szeredie8e96152007-10-16 23:31:06 -07001168 if (!err && !(inode->i_mode & S_IXUGO))
1169 return -EACCES;
1170 }
Miklos Szeredie5e55582005-09-09 13:10:28 -07001171 }
Miklos Szeredi244f6382007-10-16 23:31:02 -07001172 return err;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001173}
1174
1175static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
Al Viro8d3af7f2013-05-18 03:03:58 -04001176 struct dir_context *ctx)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001177{
1178 while (nbytes >= FUSE_NAME_OFFSET) {
1179 struct fuse_dirent *dirent = (struct fuse_dirent *) buf;
1180 size_t reclen = FUSE_DIRENT_SIZE(dirent);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001181 if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
1182 return -EIO;
1183 if (reclen > nbytes)
1184 break;
Miklos Szerediefeb9e62013-09-03 14:28:38 +02001185 if (memchr(dirent->name, '/', dirent->namelen) != NULL)
1186 return -EIO;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001187
Al Viro8d3af7f2013-05-18 03:03:58 -04001188 if (!dir_emit(ctx, dirent->name, dirent->namelen,
1189 dirent->ino, dirent->type))
Miklos Szeredie5e55582005-09-09 13:10:28 -07001190 break;
1191
1192 buf += reclen;
1193 nbytes -= reclen;
Al Viro8d3af7f2013-05-18 03:03:58 -04001194 ctx->pos = dirent->off;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001195 }
1196
1197 return 0;
1198}
1199
Anand V. Avati0b05b182012-08-19 08:53:23 -04001200static int fuse_direntplus_link(struct file *file,
1201 struct fuse_direntplus *direntplus,
1202 u64 attr_version)
1203{
1204 int err;
1205 struct fuse_entry_out *o = &direntplus->entry_out;
1206 struct fuse_dirent *dirent = &direntplus->dirent;
1207 struct dentry *parent = file->f_path.dentry;
1208 struct qstr name = QSTR_INIT(dirent->name, dirent->namelen);
1209 struct dentry *dentry;
1210 struct dentry *alias;
1211 struct inode *dir = parent->d_inode;
1212 struct fuse_conn *fc;
1213 struct inode *inode;
1214
1215 if (!o->nodeid) {
1216 /*
1217 * Unlike in the case of fuse_lookup, zero nodeid does not mean
1218 * ENOENT. Instead, it only means the userspace filesystem did
1219 * not want to return attributes/handle for this entry.
1220 *
1221 * So do nothing.
1222 */
1223 return 0;
1224 }
1225
1226 if (name.name[0] == '.') {
1227 /*
1228 * We could potentially refresh the attributes of the directory
1229 * and its parent?
1230 */
1231 if (name.len == 1)
1232 return 0;
1233 if (name.name[1] == '.' && name.len == 2)
1234 return 0;
1235 }
Miklos Szeredia28ef452013-07-17 14:53:53 +02001236
1237 if (invalid_nodeid(o->nodeid))
1238 return -EIO;
1239 if (!fuse_valid_type(o->attr.mode))
1240 return -EIO;
1241
Anand V. Avati0b05b182012-08-19 08:53:23 -04001242 fc = get_fuse_conn(dir);
1243
1244 name.hash = full_name_hash(name.name, name.len);
1245 dentry = d_lookup(parent, &name);
Niels de Vos53ce9a32013-07-17 14:53:53 +02001246 if (dentry) {
Anand V. Avati0b05b182012-08-19 08:53:23 -04001247 inode = dentry->d_inode;
Niels de Vos53ce9a32013-07-17 14:53:53 +02001248 if (!inode) {
1249 d_drop(dentry);
Miklos Szeredia28ef452013-07-17 14:53:53 +02001250 } else if (get_node_id(inode) != o->nodeid ||
1251 ((o->attr.mode ^ inode->i_mode) & S_IFMT)) {
Niels de Vos53ce9a32013-07-17 14:53:53 +02001252 err = d_invalidate(dentry);
1253 if (err)
1254 goto out;
Miklos Szeredia28ef452013-07-17 14:53:53 +02001255 } else if (is_bad_inode(inode)) {
1256 err = -EIO;
1257 goto out;
Niels de Vos53ce9a32013-07-17 14:53:53 +02001258 } else {
Anand V. Avati0b05b182012-08-19 08:53:23 -04001259 struct fuse_inode *fi;
1260 fi = get_fuse_inode(inode);
1261 spin_lock(&fc->lock);
1262 fi->nlookup++;
1263 spin_unlock(&fc->lock);
1264
Miklos Szeredifa2b7212013-07-17 14:53:53 +02001265 fuse_change_attributes(inode, &o->attr,
1266 entry_attr_timeout(o),
1267 attr_version);
1268
Anand V. Avati0b05b182012-08-19 08:53:23 -04001269 /*
1270 * The other branch to 'found' comes via fuse_iget()
1271 * which bumps nlookup inside
1272 */
1273 goto found;
1274 }
Anand V. Avati0b05b182012-08-19 08:53:23 -04001275 dput(dentry);
Anand V. Avati0b05b182012-08-19 08:53:23 -04001276 }
1277
1278 dentry = d_alloc(parent, &name);
1279 err = -ENOMEM;
1280 if (!dentry)
1281 goto out;
1282
1283 inode = fuse_iget(dir->i_sb, o->nodeid, o->generation,
1284 &o->attr, entry_attr_timeout(o), attr_version);
1285 if (!inode)
1286 goto out;
1287
Miklos Szeredi5835f332013-09-05 11:44:42 +02001288 alias = fuse_materialise_dentry(dentry, inode);
1289 err = PTR_ERR(alias);
1290 if (IS_ERR(alias))
1291 goto out;
Miklos Szeredi29149412013-07-17 14:53:53 +02001292
Anand V. Avati0b05b182012-08-19 08:53:23 -04001293 if (alias) {
1294 dput(dentry);
1295 dentry = alias;
1296 }
1297
1298found:
Miklos Szeredi6314efe2013-10-01 16:41:22 +02001299 if (fc->readdirplus_auto)
1300 set_bit(FUSE_I_INIT_RDPLUS, &get_fuse_inode(inode)->state);
Anand V. Avati0b05b182012-08-19 08:53:23 -04001301 fuse_change_entry_timeout(dentry, o);
1302
1303 err = 0;
1304out:
Miklos Szeredic7263bc2013-07-17 14:53:54 +02001305 dput(dentry);
Anand V. Avati0b05b182012-08-19 08:53:23 -04001306 return err;
1307}
1308
1309static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file,
Al Viro8d3af7f2013-05-18 03:03:58 -04001310 struct dir_context *ctx, u64 attr_version)
Anand V. Avati0b05b182012-08-19 08:53:23 -04001311{
1312 struct fuse_direntplus *direntplus;
1313 struct fuse_dirent *dirent;
1314 size_t reclen;
1315 int over = 0;
1316 int ret;
1317
1318 while (nbytes >= FUSE_NAME_OFFSET_DIRENTPLUS) {
1319 direntplus = (struct fuse_direntplus *) buf;
1320 dirent = &direntplus->dirent;
1321 reclen = FUSE_DIRENTPLUS_SIZE(direntplus);
1322
1323 if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
1324 return -EIO;
1325 if (reclen > nbytes)
1326 break;
Miklos Szerediefeb9e62013-09-03 14:28:38 +02001327 if (memchr(dirent->name, '/', dirent->namelen) != NULL)
1328 return -EIO;
Anand V. Avati0b05b182012-08-19 08:53:23 -04001329
1330 if (!over) {
1331 /* We fill entries into dstbuf only as much as
1332 it can hold. But we still continue iterating
1333 over remaining entries to link them. If not,
1334 we need to send a FORGET for each of those
1335 which we did not link.
1336 */
Al Viro8d3af7f2013-05-18 03:03:58 -04001337 over = !dir_emit(ctx, dirent->name, dirent->namelen,
1338 dirent->ino, dirent->type);
1339 ctx->pos = dirent->off;
Anand V. Avati0b05b182012-08-19 08:53:23 -04001340 }
1341
1342 buf += reclen;
1343 nbytes -= reclen;
1344
1345 ret = fuse_direntplus_link(file, direntplus, attr_version);
1346 if (ret)
1347 fuse_force_forget(file, direntplus->entry_out.nodeid);
1348 }
1349
1350 return 0;
1351}
1352
Al Viro8d3af7f2013-05-18 03:03:58 -04001353static int fuse_readdir(struct file *file, struct dir_context *ctx)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001354{
Feng Shuo4582a4a2013-01-15 11:23:28 +08001355 int plus, err;
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001356 size_t nbytes;
1357 struct page *page;
Al Viro496ad9a2013-01-23 17:07:38 -05001358 struct inode *inode = file_inode(file);
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001359 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi248d86e2006-01-06 00:19:39 -08001360 struct fuse_req *req;
Anand V. Avati0b05b182012-08-19 08:53:23 -04001361 u64 attr_version = 0;
Miklos Szeredi248d86e2006-01-06 00:19:39 -08001362
1363 if (is_bad_inode(inode))
1364 return -EIO;
1365
Maxim Patlasovb111c8c2012-10-26 19:48:30 +04001366 req = fuse_get_req(fc, 1);
Miklos Szeredice1d5a42006-04-10 22:54:58 -07001367 if (IS_ERR(req))
1368 return PTR_ERR(req);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001369
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001370 page = alloc_page(GFP_KERNEL);
1371 if (!page) {
1372 fuse_put_request(fc, req);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001373 return -ENOMEM;
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001374 }
Feng Shuo4582a4a2013-01-15 11:23:28 +08001375
Al Viro8d3af7f2013-05-18 03:03:58 -04001376 plus = fuse_use_readdirplus(inode, ctx);
Miklos Szeredif4975c62009-04-02 14:25:34 +02001377 req->out.argpages = 1;
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001378 req->num_pages = 1;
1379 req->pages[0] = page;
Maxim Patlasov85f40ae2012-10-26 19:49:33 +04001380 req->page_descs[0].length = PAGE_SIZE;
Feng Shuo4582a4a2013-01-15 11:23:28 +08001381 if (plus) {
Anand V. Avati0b05b182012-08-19 08:53:23 -04001382 attr_version = fuse_get_attr_version(fc);
Al Viro8d3af7f2013-05-18 03:03:58 -04001383 fuse_read_fill(req, file, ctx->pos, PAGE_SIZE,
Anand V. Avati0b05b182012-08-19 08:53:23 -04001384 FUSE_READDIRPLUS);
1385 } else {
Al Viro8d3af7f2013-05-18 03:03:58 -04001386 fuse_read_fill(req, file, ctx->pos, PAGE_SIZE,
Anand V. Avati0b05b182012-08-19 08:53:23 -04001387 FUSE_READDIR);
1388 }
Tejun Heob93f8582008-11-26 12:03:55 +01001389 fuse_request_send(fc, req);
Miklos Szeredi361b1eb52006-01-16 22:14:45 -08001390 nbytes = req->out.args[0].size;
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001391 err = req->out.h.error;
1392 fuse_put_request(fc, req);
Anand V. Avati0b05b182012-08-19 08:53:23 -04001393 if (!err) {
Feng Shuo4582a4a2013-01-15 11:23:28 +08001394 if (plus) {
Anand V. Avati0b05b182012-08-19 08:53:23 -04001395 err = parse_dirplusfile(page_address(page), nbytes,
Al Viro8d3af7f2013-05-18 03:03:58 -04001396 file, ctx,
Anand V. Avati0b05b182012-08-19 08:53:23 -04001397 attr_version);
1398 } else {
1399 err = parse_dirfile(page_address(page), nbytes, file,
Al Viro8d3af7f2013-05-18 03:03:58 -04001400 ctx);
Anand V. Avati0b05b182012-08-19 08:53:23 -04001401 }
1402 }
Miklos Szeredie5e55582005-09-09 13:10:28 -07001403
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001404 __free_page(page);
Miklos Szeredib36c31b2005-09-09 13:10:38 -07001405 fuse_invalidate_attr(inode); /* atime changed */
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001406 return err;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001407}
1408
1409static char *read_link(struct dentry *dentry)
1410{
1411 struct inode *inode = dentry->d_inode;
1412 struct fuse_conn *fc = get_fuse_conn(inode);
Maxim Patlasovb111c8c2012-10-26 19:48:30 +04001413 struct fuse_req *req = fuse_get_req_nopages(fc);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001414 char *link;
1415
Miklos Szeredice1d5a42006-04-10 22:54:58 -07001416 if (IS_ERR(req))
David Howellse231c2e2008-02-07 00:15:26 -08001417 return ERR_CAST(req);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001418
1419 link = (char *) __get_free_page(GFP_KERNEL);
1420 if (!link) {
1421 link = ERR_PTR(-ENOMEM);
1422 goto out;
1423 }
1424 req->in.h.opcode = FUSE_READLINK;
1425 req->in.h.nodeid = get_node_id(inode);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001426 req->out.argvar = 1;
1427 req->out.numargs = 1;
1428 req->out.args[0].size = PAGE_SIZE - 1;
1429 req->out.args[0].value = link;
Tejun Heob93f8582008-11-26 12:03:55 +01001430 fuse_request_send(fc, req);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001431 if (req->out.h.error) {
1432 free_page((unsigned long) link);
1433 link = ERR_PTR(req->out.h.error);
1434 } else
1435 link[req->out.args[0].size] = '\0';
1436 out:
1437 fuse_put_request(fc, req);
Miklos Szeredib36c31b2005-09-09 13:10:38 -07001438 fuse_invalidate_attr(inode); /* atime changed */
Miklos Szeredie5e55582005-09-09 13:10:28 -07001439 return link;
1440}
1441
1442static void free_link(char *link)
1443{
1444 if (!IS_ERR(link))
1445 free_page((unsigned long) link);
1446}
1447
1448static void *fuse_follow_link(struct dentry *dentry, struct nameidata *nd)
1449{
1450 nd_set_link(nd, read_link(dentry));
1451 return NULL;
1452}
1453
1454static void fuse_put_link(struct dentry *dentry, struct nameidata *nd, void *c)
1455{
1456 free_link(nd_get_link(nd));
1457}
1458
1459static int fuse_dir_open(struct inode *inode, struct file *file)
1460{
Miklos Szeredi91fe96b2009-04-28 16:56:37 +02001461 return fuse_open_common(inode, file, true);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001462}
1463
1464static int fuse_dir_release(struct inode *inode, struct file *file)
1465{
Miklos Szeredi8b0797a2009-04-28 16:56:39 +02001466 fuse_release_common(file, FUSE_RELEASEDIR);
1467
1468 return 0;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001469}
1470
Josef Bacik02c24a82011-07-16 20:44:56 -04001471static int fuse_dir_fsync(struct file *file, loff_t start, loff_t end,
1472 int datasync)
Miklos Szeredi82547982005-09-09 13:10:38 -07001473{
Josef Bacik02c24a82011-07-16 20:44:56 -04001474 return fuse_fsync_common(file, start, end, datasync, 1);
Miklos Szeredi82547982005-09-09 13:10:38 -07001475}
1476
Miklos Szeredib18da0c2011-12-13 11:58:49 +01001477static long fuse_dir_ioctl(struct file *file, unsigned int cmd,
1478 unsigned long arg)
1479{
1480 struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1481
1482 /* FUSE_IOCTL_DIR only supported for API version >= 7.18 */
1483 if (fc->minor < 18)
1484 return -ENOTTY;
1485
1486 return fuse_ioctl_common(file, cmd, arg, FUSE_IOCTL_DIR);
1487}
1488
1489static long fuse_dir_compat_ioctl(struct file *file, unsigned int cmd,
1490 unsigned long arg)
1491{
1492 struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1493
1494 if (fc->minor < 18)
1495 return -ENOTTY;
1496
1497 return fuse_ioctl_common(file, cmd, arg,
1498 FUSE_IOCTL_COMPAT | FUSE_IOCTL_DIR);
1499}
1500
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001501static bool update_mtime(unsigned ivalid)
1502{
1503 /* Always update if mtime is explicitly set */
1504 if (ivalid & ATTR_MTIME_SET)
1505 return true;
1506
1507 /* If it's an open(O_TRUNC) or an ftruncate(), don't update */
1508 if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE)))
1509 return false;
1510
1511 /* In all other cases update */
1512 return true;
1513}
1514
Miklos Szeredibefc6492005-11-07 00:59:52 -08001515static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001516{
1517 unsigned ivalid = iattr->ia_valid;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001518
1519 if (ivalid & ATTR_MODE)
Miklos Szeredibefc6492005-11-07 00:59:52 -08001520 arg->valid |= FATTR_MODE, arg->mode = iattr->ia_mode;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001521 if (ivalid & ATTR_UID)
Eric W. Biederman499dcf22012-02-07 16:26:03 -08001522 arg->valid |= FATTR_UID, arg->uid = from_kuid(&init_user_ns, iattr->ia_uid);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001523 if (ivalid & ATTR_GID)
Eric W. Biederman499dcf22012-02-07 16:26:03 -08001524 arg->valid |= FATTR_GID, arg->gid = from_kgid(&init_user_ns, iattr->ia_gid);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001525 if (ivalid & ATTR_SIZE)
Miklos Szeredibefc6492005-11-07 00:59:52 -08001526 arg->valid |= FATTR_SIZE, arg->size = iattr->ia_size;
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001527 if (ivalid & ATTR_ATIME) {
1528 arg->valid |= FATTR_ATIME;
Miklos Szeredibefc6492005-11-07 00:59:52 -08001529 arg->atime = iattr->ia_atime.tv_sec;
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001530 arg->atimensec = iattr->ia_atime.tv_nsec;
1531 if (!(ivalid & ATTR_ATIME_SET))
1532 arg->valid |= FATTR_ATIME_NOW;
1533 }
1534 if ((ivalid & ATTR_MTIME) && update_mtime(ivalid)) {
1535 arg->valid |= FATTR_MTIME;
Miklos Szeredibefc6492005-11-07 00:59:52 -08001536 arg->mtime = iattr->ia_mtime.tv_sec;
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001537 arg->mtimensec = iattr->ia_mtime.tv_nsec;
1538 if (!(ivalid & ATTR_MTIME_SET))
1539 arg->valid |= FATTR_MTIME_NOW;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001540 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001541}
1542
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001543/*
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001544 * Prevent concurrent writepages on inode
1545 *
1546 * This is done by adding a negative bias to the inode write counter
1547 * and waiting for all pending writes to finish.
1548 */
1549void fuse_set_nowrite(struct inode *inode)
1550{
1551 struct fuse_conn *fc = get_fuse_conn(inode);
1552 struct fuse_inode *fi = get_fuse_inode(inode);
1553
1554 BUG_ON(!mutex_is_locked(&inode->i_mutex));
1555
1556 spin_lock(&fc->lock);
1557 BUG_ON(fi->writectr < 0);
1558 fi->writectr += FUSE_NOWRITE;
1559 spin_unlock(&fc->lock);
1560 wait_event(fi->page_waitq, fi->writectr == FUSE_NOWRITE);
1561}
1562
1563/*
1564 * Allow writepages on inode
1565 *
1566 * Remove the bias from the writecounter and send any queued
1567 * writepages.
1568 */
1569static void __fuse_release_nowrite(struct inode *inode)
1570{
1571 struct fuse_inode *fi = get_fuse_inode(inode);
1572
1573 BUG_ON(fi->writectr != FUSE_NOWRITE);
1574 fi->writectr = 0;
1575 fuse_flush_writepages(inode);
1576}
1577
1578void fuse_release_nowrite(struct inode *inode)
1579{
1580 struct fuse_conn *fc = get_fuse_conn(inode);
1581
1582 spin_lock(&fc->lock);
1583 __fuse_release_nowrite(inode);
1584 spin_unlock(&fc->lock);
1585}
1586
1587/*
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001588 * Set attributes, and at the same time refresh them.
1589 *
1590 * Truncation is slightly complicated, because the 'truncate' request
1591 * may fail, in which case we don't want to touch the mapping.
Miklos Szeredi9ffbb912006-10-17 00:10:06 -07001592 * vmtruncate() doesn't allow for this case, so do the rlimit checking
1593 * and the actual truncation by hand.
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001594 */
Maxim Patlasovefb9fa92012-12-18 14:05:08 +04001595int fuse_do_setattr(struct inode *inode, struct iattr *attr,
1596 struct file *file)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001597{
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001598 struct fuse_conn *fc = get_fuse_conn(inode);
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001599 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001600 struct fuse_req *req;
1601 struct fuse_setattr_in inarg;
1602 struct fuse_attr_out outarg;
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001603 bool is_truncate = false;
1604 loff_t oldsize;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001605 int err;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001606
Christoph Hellwigdb78b872010-06-04 11:30:03 +02001607 if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS))
1608 attr->ia_valid |= ATTR_FORCE;
1609
1610 err = inode_change_ok(inode, attr);
1611 if (err)
1612 return err;
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001613
Miklos Szeredi8d56add2011-02-25 14:44:58 +01001614 if (attr->ia_valid & ATTR_OPEN) {
1615 if (fc->atomic_o_trunc)
1616 return 0;
1617 file = NULL;
1618 }
Miklos Szeredi6ff958e2007-10-18 03:07:02 -07001619
Christoph Hellwig2c27c652010-06-04 11:30:04 +02001620 if (attr->ia_valid & ATTR_SIZE)
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001621 is_truncate = true;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001622
Maxim Patlasovb111c8c2012-10-26 19:48:30 +04001623 req = fuse_get_req_nopages(fc);
Miklos Szeredice1d5a42006-04-10 22:54:58 -07001624 if (IS_ERR(req))
1625 return PTR_ERR(req);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001626
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001627 if (is_truncate) {
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001628 fuse_set_nowrite(inode);
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001629 set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
1630 }
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001631
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001632 memset(&inarg, 0, sizeof(inarg));
Miklos Szeredi0e9663e2007-10-18 03:07:05 -07001633 memset(&outarg, 0, sizeof(outarg));
Miklos Szeredibefc6492005-11-07 00:59:52 -08001634 iattr_to_fattr(attr, &inarg);
Miklos Szeredi49d49142007-10-18 03:07:00 -07001635 if (file) {
1636 struct fuse_file *ff = file->private_data;
1637 inarg.valid |= FATTR_FH;
1638 inarg.fh = ff->fh;
1639 }
Miklos Szeredif3332112007-10-18 03:07:04 -07001640 if (attr->ia_valid & ATTR_SIZE) {
1641 /* For mandatory locking in truncate */
1642 inarg.valid |= FATTR_LOCKOWNER;
1643 inarg.lock_owner = fuse_lock_owner_id(fc, current->files);
1644 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001645 req->in.h.opcode = FUSE_SETATTR;
1646 req->in.h.nodeid = get_node_id(inode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001647 req->in.numargs = 1;
1648 req->in.args[0].size = sizeof(inarg);
1649 req->in.args[0].value = &inarg;
1650 req->out.numargs = 1;
Miklos Szeredi0e9663e2007-10-18 03:07:05 -07001651 if (fc->minor < 9)
1652 req->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
1653 else
1654 req->out.args[0].size = sizeof(outarg);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001655 req->out.args[0].value = &outarg;
Tejun Heob93f8582008-11-26 12:03:55 +01001656 fuse_request_send(fc, req);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001657 err = req->out.h.error;
1658 fuse_put_request(fc, req);
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001659 if (err) {
1660 if (err == -EINTR)
1661 fuse_invalidate_attr(inode);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001662 goto error;
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001663 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001664
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001665 if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
1666 make_bad_inode(inode);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001667 err = -EIO;
1668 goto error;
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001669 }
1670
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001671 spin_lock(&fc->lock);
1672 fuse_change_attributes_common(inode, &outarg.attr,
1673 attr_timeout(&outarg));
1674 oldsize = inode->i_size;
1675 i_size_write(inode, outarg.attr.size);
1676
1677 if (is_truncate) {
1678 /* NOTE: this may release/reacquire fc->lock */
1679 __fuse_release_nowrite(inode);
1680 }
1681 spin_unlock(&fc->lock);
1682
1683 /*
1684 * Only call invalidate_inode_pages2() after removing
1685 * FUSE_NOWRITE, otherwise fuse_launder_page() would deadlock.
1686 */
1687 if (S_ISREG(inode->i_mode) && oldsize != outarg.attr.size) {
Kirill A. Shutemov7caef262013-09-12 15:13:56 -07001688 truncate_pagecache(inode, outarg.attr.size);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001689 invalidate_inode_pages2(inode->i_mapping);
1690 }
1691
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001692 clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001693 return 0;
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001694
1695error:
1696 if (is_truncate)
1697 fuse_release_nowrite(inode);
1698
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001699 clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001700 return err;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001701}
1702
Miklos Szeredi49d49142007-10-18 03:07:00 -07001703static int fuse_setattr(struct dentry *entry, struct iattr *attr)
1704{
Maxim Patlasovefb9fa92012-12-18 14:05:08 +04001705 struct inode *inode = entry->d_inode;
1706
1707 if (!fuse_allow_current_process(get_fuse_conn(inode)))
1708 return -EACCES;
1709
Miklos Szeredi49d49142007-10-18 03:07:00 -07001710 if (attr->ia_valid & ATTR_FILE)
Maxim Patlasovefb9fa92012-12-18 14:05:08 +04001711 return fuse_do_setattr(inode, attr, attr->ia_file);
Miklos Szeredi49d49142007-10-18 03:07:00 -07001712 else
Maxim Patlasovefb9fa92012-12-18 14:05:08 +04001713 return fuse_do_setattr(inode, attr, NULL);
Miklos Szeredi49d49142007-10-18 03:07:00 -07001714}
1715
Miklos Szeredie5e55582005-09-09 13:10:28 -07001716static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
1717 struct kstat *stat)
1718{
1719 struct inode *inode = entry->d_inode;
Miklos Szeredi244f6382007-10-16 23:31:02 -07001720 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi244f6382007-10-16 23:31:02 -07001721
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001722 if (!fuse_allow_current_process(fc))
Miklos Szeredi244f6382007-10-16 23:31:02 -07001723 return -EACCES;
1724
Miklos Szeredibcb4be82007-11-28 16:21:59 -08001725 return fuse_update_attributes(inode, stat, NULL, NULL);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001726}
1727
Miklos Szeredi92a87802005-09-09 13:10:31 -07001728static int fuse_setxattr(struct dentry *entry, const char *name,
1729 const void *value, size_t size, int flags)
1730{
1731 struct inode *inode = entry->d_inode;
1732 struct fuse_conn *fc = get_fuse_conn(inode);
1733 struct fuse_req *req;
1734 struct fuse_setxattr_in inarg;
1735 int err;
1736
Miklos Szeredi92a87802005-09-09 13:10:31 -07001737 if (fc->no_setxattr)
1738 return -EOPNOTSUPP;
1739
Maxim Patlasovb111c8c2012-10-26 19:48:30 +04001740 req = fuse_get_req_nopages(fc);
Miklos Szeredice1d5a42006-04-10 22:54:58 -07001741 if (IS_ERR(req))
1742 return PTR_ERR(req);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001743
1744 memset(&inarg, 0, sizeof(inarg));
1745 inarg.size = size;
1746 inarg.flags = flags;
1747 req->in.h.opcode = FUSE_SETXATTR;
1748 req->in.h.nodeid = get_node_id(inode);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001749 req->in.numargs = 3;
1750 req->in.args[0].size = sizeof(inarg);
1751 req->in.args[0].value = &inarg;
1752 req->in.args[1].size = strlen(name) + 1;
1753 req->in.args[1].value = name;
1754 req->in.args[2].size = size;
1755 req->in.args[2].value = value;
Tejun Heob93f8582008-11-26 12:03:55 +01001756 fuse_request_send(fc, req);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001757 err = req->out.h.error;
1758 fuse_put_request(fc, req);
1759 if (err == -ENOSYS) {
1760 fc->no_setxattr = 1;
1761 err = -EOPNOTSUPP;
1762 }
Anand Avatid331a412013-08-20 02:21:07 -04001763 if (!err)
1764 fuse_invalidate_attr(inode);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001765 return err;
1766}
1767
1768static ssize_t fuse_getxattr(struct dentry *entry, const char *name,
1769 void *value, size_t size)
1770{
1771 struct inode *inode = entry->d_inode;
1772 struct fuse_conn *fc = get_fuse_conn(inode);
1773 struct fuse_req *req;
1774 struct fuse_getxattr_in inarg;
1775 struct fuse_getxattr_out outarg;
1776 ssize_t ret;
1777
1778 if (fc->no_getxattr)
1779 return -EOPNOTSUPP;
1780
Maxim Patlasovb111c8c2012-10-26 19:48:30 +04001781 req = fuse_get_req_nopages(fc);
Miklos Szeredice1d5a42006-04-10 22:54:58 -07001782 if (IS_ERR(req))
1783 return PTR_ERR(req);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001784
1785 memset(&inarg, 0, sizeof(inarg));
1786 inarg.size = size;
1787 req->in.h.opcode = FUSE_GETXATTR;
1788 req->in.h.nodeid = get_node_id(inode);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001789 req->in.numargs = 2;
1790 req->in.args[0].size = sizeof(inarg);
1791 req->in.args[0].value = &inarg;
1792 req->in.args[1].size = strlen(name) + 1;
1793 req->in.args[1].value = name;
1794 /* This is really two different operations rolled into one */
1795 req->out.numargs = 1;
1796 if (size) {
1797 req->out.argvar = 1;
1798 req->out.args[0].size = size;
1799 req->out.args[0].value = value;
1800 } else {
1801 req->out.args[0].size = sizeof(outarg);
1802 req->out.args[0].value = &outarg;
1803 }
Tejun Heob93f8582008-11-26 12:03:55 +01001804 fuse_request_send(fc, req);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001805 ret = req->out.h.error;
1806 if (!ret)
1807 ret = size ? req->out.args[0].size : outarg.size;
1808 else {
1809 if (ret == -ENOSYS) {
1810 fc->no_getxattr = 1;
1811 ret = -EOPNOTSUPP;
1812 }
1813 }
1814 fuse_put_request(fc, req);
1815 return ret;
1816}
1817
1818static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
1819{
1820 struct inode *inode = entry->d_inode;
1821 struct fuse_conn *fc = get_fuse_conn(inode);
1822 struct fuse_req *req;
1823 struct fuse_getxattr_in inarg;
1824 struct fuse_getxattr_out outarg;
1825 ssize_t ret;
1826
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001827 if (!fuse_allow_current_process(fc))
Miklos Szeredie57ac682007-10-18 03:06:58 -07001828 return -EACCES;
1829
Miklos Szeredi92a87802005-09-09 13:10:31 -07001830 if (fc->no_listxattr)
1831 return -EOPNOTSUPP;
1832
Maxim Patlasovb111c8c2012-10-26 19:48:30 +04001833 req = fuse_get_req_nopages(fc);
Miklos Szeredice1d5a42006-04-10 22:54:58 -07001834 if (IS_ERR(req))
1835 return PTR_ERR(req);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001836
1837 memset(&inarg, 0, sizeof(inarg));
1838 inarg.size = size;
1839 req->in.h.opcode = FUSE_LISTXATTR;
1840 req->in.h.nodeid = get_node_id(inode);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001841 req->in.numargs = 1;
1842 req->in.args[0].size = sizeof(inarg);
1843 req->in.args[0].value = &inarg;
1844 /* This is really two different operations rolled into one */
1845 req->out.numargs = 1;
1846 if (size) {
1847 req->out.argvar = 1;
1848 req->out.args[0].size = size;
1849 req->out.args[0].value = list;
1850 } else {
1851 req->out.args[0].size = sizeof(outarg);
1852 req->out.args[0].value = &outarg;
1853 }
Tejun Heob93f8582008-11-26 12:03:55 +01001854 fuse_request_send(fc, req);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001855 ret = req->out.h.error;
1856 if (!ret)
1857 ret = size ? req->out.args[0].size : outarg.size;
1858 else {
1859 if (ret == -ENOSYS) {
1860 fc->no_listxattr = 1;
1861 ret = -EOPNOTSUPP;
1862 }
1863 }
1864 fuse_put_request(fc, req);
1865 return ret;
1866}
1867
1868static int fuse_removexattr(struct dentry *entry, const char *name)
1869{
1870 struct inode *inode = entry->d_inode;
1871 struct fuse_conn *fc = get_fuse_conn(inode);
1872 struct fuse_req *req;
1873 int err;
1874
1875 if (fc->no_removexattr)
1876 return -EOPNOTSUPP;
1877
Maxim Patlasovb111c8c2012-10-26 19:48:30 +04001878 req = fuse_get_req_nopages(fc);
Miklos Szeredice1d5a42006-04-10 22:54:58 -07001879 if (IS_ERR(req))
1880 return PTR_ERR(req);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001881
1882 req->in.h.opcode = FUSE_REMOVEXATTR;
1883 req->in.h.nodeid = get_node_id(inode);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001884 req->in.numargs = 1;
1885 req->in.args[0].size = strlen(name) + 1;
1886 req->in.args[0].value = name;
Tejun Heob93f8582008-11-26 12:03:55 +01001887 fuse_request_send(fc, req);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001888 err = req->out.h.error;
1889 fuse_put_request(fc, req);
1890 if (err == -ENOSYS) {
1891 fc->no_removexattr = 1;
1892 err = -EOPNOTSUPP;
1893 }
Anand Avatid331a412013-08-20 02:21:07 -04001894 if (!err)
1895 fuse_invalidate_attr(inode);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001896 return err;
1897}
1898
Arjan van de Ven754661f2007-02-12 00:55:38 -08001899static const struct inode_operations fuse_dir_inode_operations = {
Miklos Szeredie5e55582005-09-09 13:10:28 -07001900 .lookup = fuse_lookup,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001901 .mkdir = fuse_mkdir,
1902 .symlink = fuse_symlink,
1903 .unlink = fuse_unlink,
1904 .rmdir = fuse_rmdir,
1905 .rename = fuse_rename,
1906 .link = fuse_link,
1907 .setattr = fuse_setattr,
1908 .create = fuse_create,
Miklos Szeredic8ccbe02012-06-05 15:10:22 +02001909 .atomic_open = fuse_atomic_open,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001910 .mknod = fuse_mknod,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001911 .permission = fuse_permission,
1912 .getattr = fuse_getattr,
Miklos Szeredi92a87802005-09-09 13:10:31 -07001913 .setxattr = fuse_setxattr,
1914 .getxattr = fuse_getxattr,
1915 .listxattr = fuse_listxattr,
1916 .removexattr = fuse_removexattr,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001917};
1918
Arjan van de Ven4b6f5d22006-03-28 01:56:42 -08001919static const struct file_operations fuse_dir_operations = {
Miklos Szeredib6aeade2005-09-09 13:10:30 -07001920 .llseek = generic_file_llseek,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001921 .read = generic_read_dir,
Al Viro8d3af7f2013-05-18 03:03:58 -04001922 .iterate = fuse_readdir,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001923 .open = fuse_dir_open,
1924 .release = fuse_dir_release,
Miklos Szeredi82547982005-09-09 13:10:38 -07001925 .fsync = fuse_dir_fsync,
Miklos Szeredib18da0c2011-12-13 11:58:49 +01001926 .unlocked_ioctl = fuse_dir_ioctl,
1927 .compat_ioctl = fuse_dir_compat_ioctl,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001928};
1929
Arjan van de Ven754661f2007-02-12 00:55:38 -08001930static const struct inode_operations fuse_common_inode_operations = {
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001931 .setattr = fuse_setattr,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001932 .permission = fuse_permission,
1933 .getattr = fuse_getattr,
Miklos Szeredi92a87802005-09-09 13:10:31 -07001934 .setxattr = fuse_setxattr,
1935 .getxattr = fuse_getxattr,
1936 .listxattr = fuse_listxattr,
1937 .removexattr = fuse_removexattr,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001938};
1939
Arjan van de Ven754661f2007-02-12 00:55:38 -08001940static const struct inode_operations fuse_symlink_inode_operations = {
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001941 .setattr = fuse_setattr,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001942 .follow_link = fuse_follow_link,
1943 .put_link = fuse_put_link,
1944 .readlink = generic_readlink,
1945 .getattr = fuse_getattr,
Miklos Szeredi92a87802005-09-09 13:10:31 -07001946 .setxattr = fuse_setxattr,
1947 .getxattr = fuse_getxattr,
1948 .listxattr = fuse_listxattr,
1949 .removexattr = fuse_removexattr,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001950};
1951
1952void fuse_init_common(struct inode *inode)
1953{
1954 inode->i_op = &fuse_common_inode_operations;
1955}
1956
1957void fuse_init_dir(struct inode *inode)
1958{
1959 inode->i_op = &fuse_dir_inode_operations;
1960 inode->i_fop = &fuse_dir_operations;
1961}
1962
1963void fuse_init_symlink(struct inode *inode)
1964{
1965 inode->i_op = &fuse_symlink_inode_operations;
1966}