blob: 264f07c7754e270b61bed27b0e6296f19bf2f7b3 [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
Andrew Gallagher451418f2013-11-05 03:55:43 -0800115/**
116 * Mark the attributes as stale due to an atime change. Avoid the invalidate if
117 * atime is not used.
118 */
119void fuse_invalidate_atime(struct inode *inode)
120{
121 if (!IS_RDONLY(inode))
122 fuse_invalidate_attr(inode);
123}
124
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800125/*
126 * Just mark the entry as stale, so that a next attempt to look it up
127 * will result in a new lookup call to userspace
128 *
129 * This is called when a dentry is about to become negative and the
130 * timeout is unknown (unlink, rmdir, rename and in some cases
131 * lookup)
132 */
Miklos Szeredidbd561d2008-07-25 01:49:00 -0700133void fuse_invalidate_entry_cache(struct dentry *entry)
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800134{
Miklos Szeredi0a0898c2006-07-30 03:04:10 -0700135 fuse_dentry_settime(entry, 0);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800136}
137
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800138/*
139 * Same as fuse_invalidate_entry_cache(), but also try to remove the
140 * dentry from the hash
141 */
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800142static void fuse_invalidate_entry(struct dentry *entry)
143{
144 d_invalidate(entry);
145 fuse_invalidate_entry_cache(entry);
Miklos Szeredi0aa7c692006-01-06 00:19:34 -0800146}
147
Miklos Szeredi70781872014-12-12 09:49:05 +0100148static void fuse_lookup_init(struct fuse_conn *fc, struct fuse_args *args,
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700149 u64 nodeid, struct qstr *name,
Miklos Szeredie5e55582005-09-09 13:10:28 -0700150 struct fuse_entry_out *outarg)
151{
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700152 memset(outarg, 0, sizeof(struct fuse_entry_out));
Miklos Szeredi70781872014-12-12 09:49:05 +0100153 args->in.h.opcode = FUSE_LOOKUP;
154 args->in.h.nodeid = nodeid;
155 args->in.numargs = 1;
156 args->in.args[0].size = name->len + 1;
157 args->in.args[0].value = name->name;
158 args->out.numargs = 1;
Miklos Szeredi21f62172015-01-06 10:45:35 +0100159 args->out.args[0].size = sizeof(struct fuse_entry_out);
Miklos Szeredi70781872014-12-12 09:49:05 +0100160 args->out.args[0].value = outarg;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700161}
162
Miklos Szeredi5c5c5e52008-04-30 00:54:43 -0700163u64 fuse_get_attr_version(struct fuse_conn *fc)
Miklos Szeredi7dca9fd2007-11-28 16:21:59 -0800164{
165 u64 curr_version;
166
167 /*
168 * The spin lock isn't actually needed on 64bit archs, but we
169 * don't yet care too much about such optimizations.
170 */
171 spin_lock(&fc->lock);
172 curr_version = fc->attr_version;
173 spin_unlock(&fc->lock);
174
175 return curr_version;
176}
177
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800178/*
179 * Check whether the dentry is still valid
180 *
181 * If the entry validity timeout has expired and the dentry is
182 * positive, try to redo the lookup. If the lookup results in a
183 * different inode, then let the VFS invalidate the dentry and redo
184 * the lookup once more. If the lookup results in the same inode,
185 * then refresh the attributes, timeouts and mark the dentry valid.
186 */
Al Viro0b728e12012-06-10 16:03:43 -0400187static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
Miklos Szeredie5e55582005-09-09 13:10:28 -0700188{
Nick Piggin34286d62011-01-07 17:49:57 +1100189 struct inode *inode;
Miklos Szeredi28420da2013-06-03 14:40:22 +0200190 struct dentry *parent;
191 struct fuse_conn *fc;
Miklos Szeredi6314efe2013-10-01 16:41:22 +0200192 struct fuse_inode *fi;
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200193 int ret;
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800194
David Howells2b0143b2015-03-17 22:25:59 +0000195 inode = d_inode_rcu(entry);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800196 if (inode && is_bad_inode(inode))
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200197 goto invalid;
Anand Avati154210c2014-06-26 20:21:57 -0400198 else if (time_before64(fuse_dentry_time(entry), get_jiffies_64()) ||
199 (flags & LOOKUP_REVAL)) {
Miklos Szeredie5e55582005-09-09 13:10:28 -0700200 struct fuse_entry_out outarg;
Miklos Szeredi70781872014-12-12 09:49:05 +0100201 FUSE_ARGS(args);
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100202 struct fuse_forget_link *forget;
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700203 u64 attr_version;
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800204
Miklos Szeredi50322fe2006-02-28 16:59:03 -0800205 /* For negative dentries, always do a fresh lookup */
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800206 if (!inode)
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200207 goto invalid;
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800208
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200209 ret = -ECHILD;
Al Viro0b728e12012-06-10 16:03:43 -0400210 if (flags & LOOKUP_RCU)
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200211 goto out;
Miklos Szeredie7c0a162011-03-21 13:58:06 +0100212
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800213 fc = get_fuse_conn(inode);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700214
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100215 forget = fuse_alloc_forget();
Miklos Szeredi70781872014-12-12 09:49:05 +0100216 ret = -ENOMEM;
217 if (!forget)
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200218 goto out;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800219
Miklos Szeredi7dca9fd2007-11-28 16:21:59 -0800220 attr_version = fuse_get_attr_version(fc);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700221
Miklos Szeredie956edd2006-10-17 00:10:12 -0700222 parent = dget_parent(entry);
David Howells2b0143b2015-03-17 22:25:59 +0000223 fuse_lookup_init(fc, &args, get_node_id(d_inode(parent)),
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700224 &entry->d_name, &outarg);
Miklos Szeredi70781872014-12-12 09:49:05 +0100225 ret = fuse_simple_request(fc, &args);
Miklos Szeredie956edd2006-10-17 00:10:12 -0700226 dput(parent);
Miklos Szeredi50322fe2006-02-28 16:59:03 -0800227 /* Zero nodeid is same as -ENOENT */
Miklos Szeredi70781872014-12-12 09:49:05 +0100228 if (!ret && !outarg.nodeid)
229 ret = -ENOENT;
230 if (!ret) {
Miklos Szeredi6314efe2013-10-01 16:41:22 +0200231 fi = get_fuse_inode(inode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700232 if (outarg.nodeid != get_node_id(inode)) {
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100233 fuse_queue_forget(fc, forget, outarg.nodeid, 1);
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200234 goto invalid;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700235 }
Miklos Szeredi8da5ff22006-10-17 00:10:08 -0700236 spin_lock(&fc->lock);
Miklos Szeredi1729a162008-11-26 12:03:54 +0100237 fi->nlookup++;
Miklos Szeredi8da5ff22006-10-17 00:10:08 -0700238 spin_unlock(&fc->lock);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700239 }
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100240 kfree(forget);
Miklos Szeredi70781872014-12-12 09:49:05 +0100241 if (ret == -ENOMEM)
242 goto out;
243 if (ret || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200244 goto invalid;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700245
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700246 fuse_change_attributes(inode, &outarg.attr,
247 entry_attr_timeout(&outarg),
248 attr_version);
249 fuse_change_entry_timeout(entry, &outarg);
Miklos Szeredi28420da2013-06-03 14:40:22 +0200250 } else if (inode) {
Miklos Szeredi6314efe2013-10-01 16:41:22 +0200251 fi = get_fuse_inode(inode);
252 if (flags & LOOKUP_RCU) {
253 if (test_bit(FUSE_I_INIT_RDPLUS, &fi->state))
254 return -ECHILD;
255 } else if (test_and_clear_bit(FUSE_I_INIT_RDPLUS, &fi->state)) {
Miklos Szeredi28420da2013-06-03 14:40:22 +0200256 parent = dget_parent(entry);
David Howells2b0143b2015-03-17 22:25:59 +0000257 fuse_advise_use_readdirplus(d_inode(parent));
Miklos Szeredi28420da2013-06-03 14:40:22 +0200258 dput(parent);
259 }
Miklos Szeredie5e55582005-09-09 13:10:28 -0700260 }
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200261 ret = 1;
262out:
263 return ret;
264
265invalid:
266 ret = 0;
267 goto out;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700268}
269
Miklos Szeredi8bfc0162006-01-16 22:14:28 -0800270static int invalid_nodeid(u64 nodeid)
Miklos Szeredi2827d0b22005-11-28 13:44:16 -0800271{
272 return !nodeid || nodeid == FUSE_ROOT_ID;
273}
274
Al Viro42695902009-02-20 05:59:13 +0000275const struct dentry_operations fuse_dentry_operations = {
Miklos Szeredie5e55582005-09-09 13:10:28 -0700276 .d_revalidate = fuse_dentry_revalidate,
277};
278
Timo Savolaa5bfffac2007-04-08 16:04:00 -0700279int fuse_valid_type(int m)
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800280{
281 return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) ||
282 S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
283}
284
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700285int fuse_lookup_name(struct super_block *sb, u64 nodeid, struct qstr *name,
286 struct fuse_entry_out *outarg, struct inode **inode)
287{
288 struct fuse_conn *fc = get_fuse_conn_super(sb);
Miklos Szeredi70781872014-12-12 09:49:05 +0100289 FUSE_ARGS(args);
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100290 struct fuse_forget_link *forget;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700291 u64 attr_version;
292 int err;
293
294 *inode = NULL;
295 err = -ENAMETOOLONG;
296 if (name->len > FUSE_NAME_MAX)
297 goto out;
298
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700299
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100300 forget = fuse_alloc_forget();
301 err = -ENOMEM;
Miklos Szeredi70781872014-12-12 09:49:05 +0100302 if (!forget)
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700303 goto out;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700304
305 attr_version = fuse_get_attr_version(fc);
306
Miklos Szeredi70781872014-12-12 09:49:05 +0100307 fuse_lookup_init(fc, &args, nodeid, name, outarg);
308 err = fuse_simple_request(fc, &args);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700309 /* Zero nodeid is same as -ENOENT, but with valid timeout */
310 if (err || !outarg->nodeid)
311 goto out_put_forget;
312
313 err = -EIO;
314 if (!outarg->nodeid)
315 goto out_put_forget;
316 if (!fuse_valid_type(outarg->attr.mode))
317 goto out_put_forget;
318
319 *inode = fuse_iget(sb, outarg->nodeid, outarg->generation,
320 &outarg->attr, entry_attr_timeout(outarg),
321 attr_version);
322 err = -ENOMEM;
323 if (!*inode) {
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100324 fuse_queue_forget(fc, forget, outarg->nodeid, 1);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700325 goto out;
326 }
327 err = 0;
328
329 out_put_forget:
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100330 kfree(forget);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700331 out:
332 return err;
333}
334
Miklos Szeredi0aa7c692006-01-06 00:19:34 -0800335static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
Al Viro00cd8dd2012-06-10 17:13:09 -0400336 unsigned int flags)
Miklos Szeredie5e55582005-09-09 13:10:28 -0700337{
338 int err;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700339 struct fuse_entry_out outarg;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700340 struct inode *inode;
Miklos Szeredi0de62562008-07-25 01:48:59 -0700341 struct dentry *newent;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700342 bool outarg_valid = true;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700343
Miklos Szeredi5c672ab2016-06-30 13:10:49 +0200344 fuse_lock_inode(dir);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700345 err = fuse_lookup_name(dir->i_sb, get_node_id(dir), &entry->d_name,
346 &outarg, &inode);
Miklos Szeredi5c672ab2016-06-30 13:10:49 +0200347 fuse_unlock_inode(dir);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700348 if (err == -ENOENT) {
349 outarg_valid = false;
350 err = 0;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800351 }
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700352 if (err)
353 goto out_err;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800354
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700355 err = -EIO;
356 if (inode && get_node_id(inode) == FUSE_ROOT_ID)
357 goto out_iput;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700358
Al Viro41d28bc2014-10-12 22:24:21 -0400359 newent = d_splice_alias(inode, entry);
Miklos Szeredi5835f332013-09-05 11:44:42 +0200360 err = PTR_ERR(newent);
361 if (IS_ERR(newent))
362 goto out_err;
Miklos Szeredid2a85162006-10-17 00:10:11 -0700363
Miklos Szeredi0de62562008-07-25 01:48:59 -0700364 entry = newent ? newent : entry;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700365 if (outarg_valid)
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700366 fuse_change_entry_timeout(entry, &outarg);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800367 else
368 fuse_invalidate_entry_cache(entry);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700369
Feng Shuo4582a4a2013-01-15 11:23:28 +0800370 fuse_advise_use_readdirplus(dir);
Miklos Szeredi0de62562008-07-25 01:48:59 -0700371 return newent;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700372
373 out_iput:
374 iput(inode);
375 out_err:
376 return ERR_PTR(err);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700377}
378
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800379/*
380 * Atomic create+open operation
381 *
382 * If the filesystem doesn't support this, then fall back to separate
383 * 'mknod' + 'open' requests.
384 */
Al Virod9585272012-06-22 12:39:14 +0400385static int fuse_create_open(struct inode *dir, struct dentry *entry,
Al Viro30d90492012-06-22 12:40:19 +0400386 struct file *file, unsigned flags,
Al Virod9585272012-06-22 12:39:14 +0400387 umode_t mode, int *opened)
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800388{
389 int err;
390 struct inode *inode;
391 struct fuse_conn *fc = get_fuse_conn(dir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100392 FUSE_ARGS(args);
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100393 struct fuse_forget_link *forget;
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200394 struct fuse_create_in inarg;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800395 struct fuse_open_out outopen;
396 struct fuse_entry_out outentry;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800397 struct fuse_file *ff;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800398
Miklos Szerediaf109bc2012-08-15 13:01:24 +0200399 /* Userspace expects S_IFREG in create mode */
400 BUG_ON((mode & S_IFMT) != S_IFREG);
401
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100402 forget = fuse_alloc_forget();
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200403 err = -ENOMEM;
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100404 if (!forget)
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200405 goto out_err;
Miklos Szeredi51eb01e2006-06-25 05:48:50 -0700406
Miklos Szeredice1d5a42006-04-10 22:54:58 -0700407 err = -ENOMEM;
Tejun Heoacf99432008-11-26 12:03:55 +0100408 ff = fuse_file_alloc(fc);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800409 if (!ff)
Miklos Szeredi70781872014-12-12 09:49:05 +0100410 goto out_put_forget_req;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800411
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200412 if (!fc->dont_mask)
413 mode &= ~current_umask();
414
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800415 flags &= ~O_NOCTTY;
416 memset(&inarg, 0, sizeof(inarg));
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700417 memset(&outentry, 0, sizeof(outentry));
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800418 inarg.flags = flags;
419 inarg.mode = mode;
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200420 inarg.umask = current_umask();
Miklos Szeredi70781872014-12-12 09:49:05 +0100421 args.in.h.opcode = FUSE_CREATE;
422 args.in.h.nodeid = get_node_id(dir);
423 args.in.numargs = 2;
Miklos Szeredi21f62172015-01-06 10:45:35 +0100424 args.in.args[0].size = sizeof(inarg);
Miklos Szeredi70781872014-12-12 09:49:05 +0100425 args.in.args[0].value = &inarg;
426 args.in.args[1].size = entry->d_name.len + 1;
427 args.in.args[1].value = entry->d_name.name;
428 args.out.numargs = 2;
Miklos Szeredi21f62172015-01-06 10:45:35 +0100429 args.out.args[0].size = sizeof(outentry);
Miklos Szeredi70781872014-12-12 09:49:05 +0100430 args.out.args[0].value = &outentry;
431 args.out.args[1].size = sizeof(outopen);
432 args.out.args[1].value = &outopen;
433 err = fuse_simple_request(fc, &args);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200434 if (err)
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800435 goto out_free_ff;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800436
437 err = -EIO;
Miklos Szeredi2827d0b22005-11-28 13:44:16 -0800438 if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid))
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800439 goto out_free_ff;
440
Miklos Szeredic7b71432009-04-28 16:56:37 +0200441 ff->fh = outopen.fh;
442 ff->nodeid = outentry.nodeid;
443 ff->open_flags = outopen.open_flags;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800444 inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700445 &outentry.attr, entry_attr_timeout(&outentry), 0);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800446 if (!inode) {
447 flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
Miklos Szeredi8b0797a2009-04-28 16:56:39 +0200448 fuse_sync_release(ff, flags);
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100449 fuse_queue_forget(fc, forget, outentry.nodeid, 1);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200450 err = -ENOMEM;
451 goto out_err;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800452 }
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100453 kfree(forget);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800454 d_instantiate(entry, inode);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700455 fuse_change_entry_timeout(entry, &outentry);
Miklos Szeredi0952b2a2008-02-06 01:38:38 -0800456 fuse_invalidate_attr(dir);
Al Viro30d90492012-06-22 12:40:19 +0400457 err = finish_open(file, entry, generic_file_open, opened);
458 if (err) {
Miklos Szeredi8b0797a2009-04-28 16:56:39 +0200459 fuse_sync_release(ff, flags);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200460 } else {
461 file->private_data = fuse_file_get(ff);
462 fuse_finish_open(inode, file);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800463 }
Al Virod9585272012-06-22 12:39:14 +0400464 return err;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800465
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200466out_free_ff:
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800467 fuse_file_free(ff);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200468out_put_forget_req:
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100469 kfree(forget);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200470out_err:
Al Virod9585272012-06-22 12:39:14 +0400471 return err;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200472}
473
474static int fuse_mknod(struct inode *, struct dentry *, umode_t, dev_t);
Al Virod9585272012-06-22 12:39:14 +0400475static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
Al Viro30d90492012-06-22 12:40:19 +0400476 struct file *file, unsigned flags,
Al Virod9585272012-06-22 12:39:14 +0400477 umode_t mode, int *opened)
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200478{
479 int err;
480 struct fuse_conn *fc = get_fuse_conn(dir);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200481 struct dentry *res = NULL;
482
483 if (d_unhashed(entry)) {
Al Viro00cd8dd2012-06-10 17:13:09 -0400484 res = fuse_lookup(dir, entry, 0);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200485 if (IS_ERR(res))
Al Virod9585272012-06-22 12:39:14 +0400486 return PTR_ERR(res);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200487
488 if (res)
489 entry = res;
490 }
491
David Howells2b0143b2015-03-17 22:25:59 +0000492 if (!(flags & O_CREAT) || d_really_is_positive(entry))
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200493 goto no_open;
494
495 /* Only creates */
Al Viro47237682012-06-10 05:01:45 -0400496 *opened |= FILE_CREATED;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200497
498 if (fc->no_create)
499 goto mknod;
500
Al Viro30d90492012-06-22 12:40:19 +0400501 err = fuse_create_open(dir, entry, file, flags, mode, opened);
Al Virod9585272012-06-22 12:39:14 +0400502 if (err == -ENOSYS) {
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200503 fc->no_create = 1;
504 goto mknod;
505 }
506out_dput:
507 dput(res);
Al Virod9585272012-06-22 12:39:14 +0400508 return err;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200509
510mknod:
511 err = fuse_mknod(dir, entry, mode, 0);
Al Virod9585272012-06-22 12:39:14 +0400512 if (err)
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200513 goto out_dput;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200514no_open:
Al Viroe45198a2012-06-10 06:48:09 -0400515 return finish_no_open(file, res);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800516}
517
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800518/*
519 * Code shared between mknod, mkdir, symlink and link
520 */
Miklos Szeredi70781872014-12-12 09:49:05 +0100521static int create_new_entry(struct fuse_conn *fc, struct fuse_args *args,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700522 struct inode *dir, struct dentry *entry,
Al Viro541af6a2011-07-26 03:17:33 -0400523 umode_t mode)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700524{
525 struct fuse_entry_out outarg;
526 struct inode *inode;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700527 int err;
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100528 struct fuse_forget_link *forget;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800529
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100530 forget = fuse_alloc_forget();
Miklos Szeredi70781872014-12-12 09:49:05 +0100531 if (!forget)
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100532 return -ENOMEM;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700533
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700534 memset(&outarg, 0, sizeof(outarg));
Miklos Szeredi70781872014-12-12 09:49:05 +0100535 args->in.h.nodeid = get_node_id(dir);
536 args->out.numargs = 1;
Miklos Szeredi21f62172015-01-06 10:45:35 +0100537 args->out.args[0].size = sizeof(outarg);
Miklos Szeredi70781872014-12-12 09:49:05 +0100538 args->out.args[0].value = &outarg;
539 err = fuse_simple_request(fc, args);
Miklos Szeredi2d510132006-11-25 11:09:20 -0800540 if (err)
541 goto out_put_forget_req;
542
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800543 err = -EIO;
544 if (invalid_nodeid(outarg.nodeid))
Miklos Szeredi2d510132006-11-25 11:09:20 -0800545 goto out_put_forget_req;
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800546
547 if ((outarg.attr.mode ^ mode) & S_IFMT)
Miklos Szeredi2d510132006-11-25 11:09:20 -0800548 goto out_put_forget_req;
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800549
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700550 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700551 &outarg.attr, entry_attr_timeout(&outarg), 0);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700552 if (!inode) {
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100553 fuse_queue_forget(fc, forget, outarg.nodeid, 1);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700554 return -ENOMEM;
555 }
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100556 kfree(forget);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700557
Miklos Szeredib70a80e2013-10-01 16:44:54 +0200558 err = d_instantiate_no_diralias(entry, inode);
559 if (err)
560 return err;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700561
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700562 fuse_change_entry_timeout(entry, &outarg);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700563 fuse_invalidate_attr(dir);
564 return 0;
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800565
Miklos Szeredi2d510132006-11-25 11:09:20 -0800566 out_put_forget_req:
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100567 kfree(forget);
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800568 return err;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700569}
570
Al Viro1a67aaf2011-07-26 01:52:52 -0400571static int fuse_mknod(struct inode *dir, struct dentry *entry, umode_t mode,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700572 dev_t rdev)
573{
574 struct fuse_mknod_in inarg;
575 struct fuse_conn *fc = get_fuse_conn(dir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100576 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700577
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200578 if (!fc->dont_mask)
579 mode &= ~current_umask();
580
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700581 memset(&inarg, 0, sizeof(inarg));
582 inarg.mode = mode;
583 inarg.rdev = new_encode_dev(rdev);
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200584 inarg.umask = current_umask();
Miklos Szeredi70781872014-12-12 09:49:05 +0100585 args.in.h.opcode = FUSE_MKNOD;
586 args.in.numargs = 2;
Miklos Szeredi21f62172015-01-06 10:45:35 +0100587 args.in.args[0].size = sizeof(inarg);
Miklos Szeredi70781872014-12-12 09:49:05 +0100588 args.in.args[0].value = &inarg;
589 args.in.args[1].size = entry->d_name.len + 1;
590 args.in.args[1].value = entry->d_name.name;
591 return create_new_entry(fc, &args, dir, entry, mode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700592}
593
Al Viro4acdaf22011-07-26 01:42:34 -0400594static int fuse_create(struct inode *dir, struct dentry *entry, umode_t mode,
Al Viroebfc3b42012-06-10 18:05:36 -0400595 bool excl)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700596{
597 return fuse_mknod(dir, entry, mode, 0);
598}
599
Al Viro18bb1db2011-07-26 01:41:39 -0400600static int fuse_mkdir(struct inode *dir, struct dentry *entry, umode_t mode)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700601{
602 struct fuse_mkdir_in inarg;
603 struct fuse_conn *fc = get_fuse_conn(dir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100604 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700605
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200606 if (!fc->dont_mask)
607 mode &= ~current_umask();
608
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700609 memset(&inarg, 0, sizeof(inarg));
610 inarg.mode = mode;
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200611 inarg.umask = current_umask();
Miklos Szeredi70781872014-12-12 09:49:05 +0100612 args.in.h.opcode = FUSE_MKDIR;
613 args.in.numargs = 2;
614 args.in.args[0].size = sizeof(inarg);
615 args.in.args[0].value = &inarg;
616 args.in.args[1].size = entry->d_name.len + 1;
617 args.in.args[1].value = entry->d_name.name;
618 return create_new_entry(fc, &args, dir, entry, S_IFDIR);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700619}
620
621static int fuse_symlink(struct inode *dir, struct dentry *entry,
622 const char *link)
623{
624 struct fuse_conn *fc = get_fuse_conn(dir);
625 unsigned len = strlen(link) + 1;
Miklos Szeredi70781872014-12-12 09:49:05 +0100626 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700627
Miklos Szeredi70781872014-12-12 09:49:05 +0100628 args.in.h.opcode = FUSE_SYMLINK;
629 args.in.numargs = 2;
630 args.in.args[0].size = entry->d_name.len + 1;
631 args.in.args[0].value = entry->d_name.name;
632 args.in.args[1].size = len;
633 args.in.args[1].value = link;
634 return create_new_entry(fc, &args, dir, entry, S_IFLNK);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700635}
636
Maxim Patlasov31f32672014-04-28 14:19:24 +0200637static inline void fuse_update_ctime(struct inode *inode)
638{
639 if (!IS_NOCMTIME(inode)) {
640 inode->i_ctime = current_fs_time(inode->i_sb);
641 mark_inode_dirty_sync(inode);
642 }
643}
644
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700645static int fuse_unlink(struct inode *dir, struct dentry *entry)
646{
647 int err;
648 struct fuse_conn *fc = get_fuse_conn(dir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100649 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700650
Miklos Szeredi70781872014-12-12 09:49:05 +0100651 args.in.h.opcode = FUSE_UNLINK;
652 args.in.h.nodeid = get_node_id(dir);
653 args.in.numargs = 1;
654 args.in.args[0].size = entry->d_name.len + 1;
655 args.in.args[0].value = entry->d_name.name;
656 err = fuse_simple_request(fc, &args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700657 if (!err) {
David Howells2b0143b2015-03-17 22:25:59 +0000658 struct inode *inode = d_inode(entry);
Miklos Szerediac45d612012-03-05 15:48:11 +0100659 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700660
Miklos Szerediac45d612012-03-05 15:48:11 +0100661 spin_lock(&fc->lock);
662 fi->attr_version = ++fc->attr_version;
Miklos Szeredidfca7ce2013-02-04 15:57:42 +0100663 /*
664 * If i_nlink == 0 then unlink doesn't make sense, yet this can
665 * happen if userspace filesystem is careless. It would be
666 * difficult to enforce correct nlink usage so just ignore this
667 * condition here
668 */
669 if (inode->i_nlink > 0)
670 drop_nlink(inode);
Miklos Szerediac45d612012-03-05 15:48:11 +0100671 spin_unlock(&fc->lock);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700672 fuse_invalidate_attr(inode);
673 fuse_invalidate_attr(dir);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800674 fuse_invalidate_entry_cache(entry);
Maxim Patlasov31f32672014-04-28 14:19:24 +0200675 fuse_update_ctime(inode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700676 } else if (err == -EINTR)
677 fuse_invalidate_entry(entry);
678 return err;
679}
680
681static int fuse_rmdir(struct inode *dir, struct dentry *entry)
682{
683 int err;
684 struct fuse_conn *fc = get_fuse_conn(dir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100685 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700686
Miklos Szeredi70781872014-12-12 09:49:05 +0100687 args.in.h.opcode = FUSE_RMDIR;
688 args.in.h.nodeid = get_node_id(dir);
689 args.in.numargs = 1;
690 args.in.args[0].size = entry->d_name.len + 1;
691 args.in.args[0].value = entry->d_name.name;
692 err = fuse_simple_request(fc, &args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700693 if (!err) {
David Howells2b0143b2015-03-17 22:25:59 +0000694 clear_nlink(d_inode(entry));
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700695 fuse_invalidate_attr(dir);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800696 fuse_invalidate_entry_cache(entry);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700697 } else if (err == -EINTR)
698 fuse_invalidate_entry(entry);
699 return err;
700}
701
Miklos Szeredi1560c972014-04-28 16:43:44 +0200702static int fuse_rename_common(struct inode *olddir, struct dentry *oldent,
703 struct inode *newdir, struct dentry *newent,
704 unsigned int flags, int opcode, size_t argsize)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700705{
706 int err;
Miklos Szeredi1560c972014-04-28 16:43:44 +0200707 struct fuse_rename2_in inarg;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700708 struct fuse_conn *fc = get_fuse_conn(olddir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100709 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700710
Miklos Szeredi1560c972014-04-28 16:43:44 +0200711 memset(&inarg, 0, argsize);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700712 inarg.newdir = get_node_id(newdir);
Miklos Szeredi1560c972014-04-28 16:43:44 +0200713 inarg.flags = flags;
Miklos Szeredi70781872014-12-12 09:49:05 +0100714 args.in.h.opcode = opcode;
715 args.in.h.nodeid = get_node_id(olddir);
716 args.in.numargs = 3;
717 args.in.args[0].size = argsize;
718 args.in.args[0].value = &inarg;
719 args.in.args[1].size = oldent->d_name.len + 1;
720 args.in.args[1].value = oldent->d_name.name;
721 args.in.args[2].size = newent->d_name.len + 1;
722 args.in.args[2].value = newent->d_name.name;
723 err = fuse_simple_request(fc, &args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700724 if (!err) {
Miklos Szeredi08b63302007-11-28 16:22:03 -0800725 /* ctime changes */
David Howells2b0143b2015-03-17 22:25:59 +0000726 fuse_invalidate_attr(d_inode(oldent));
727 fuse_update_ctime(d_inode(oldent));
Miklos Szeredi08b63302007-11-28 16:22:03 -0800728
Miklos Szeredi1560c972014-04-28 16:43:44 +0200729 if (flags & RENAME_EXCHANGE) {
David Howells2b0143b2015-03-17 22:25:59 +0000730 fuse_invalidate_attr(d_inode(newent));
731 fuse_update_ctime(d_inode(newent));
Miklos Szeredi1560c972014-04-28 16:43:44 +0200732 }
733
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700734 fuse_invalidate_attr(olddir);
735 if (olddir != newdir)
736 fuse_invalidate_attr(newdir);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800737
738 /* newent will end up negative */
David Howells2b0143b2015-03-17 22:25:59 +0000739 if (!(flags & RENAME_EXCHANGE) && d_really_is_positive(newent)) {
740 fuse_invalidate_attr(d_inode(newent));
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800741 fuse_invalidate_entry_cache(newent);
David Howells2b0143b2015-03-17 22:25:59 +0000742 fuse_update_ctime(d_inode(newent));
Miklos Szeredi5219f342009-11-04 10:24:52 +0100743 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700744 } else if (err == -EINTR) {
745 /* If request was interrupted, DEITY only knows if the
746 rename actually took place. If the invalidation
747 fails (e.g. some process has CWD under the renamed
748 directory), then there can be inconsistency between
749 the dcache and the real filesystem. Tough luck. */
750 fuse_invalidate_entry(oldent);
David Howells2b0143b2015-03-17 22:25:59 +0000751 if (d_really_is_positive(newent))
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700752 fuse_invalidate_entry(newent);
753 }
754
755 return err;
756}
757
Miklos Szeredi1560c972014-04-28 16:43:44 +0200758static int fuse_rename2(struct inode *olddir, struct dentry *oldent,
759 struct inode *newdir, struct dentry *newent,
760 unsigned int flags)
761{
762 struct fuse_conn *fc = get_fuse_conn(olddir);
763 int err;
764
765 if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE))
766 return -EINVAL;
767
Miklos Szeredi4237ba42014-07-10 10:50:19 +0200768 if (flags) {
769 if (fc->no_rename2 || fc->minor < 23)
770 return -EINVAL;
Miklos Szeredi1560c972014-04-28 16:43:44 +0200771
Miklos Szeredi4237ba42014-07-10 10:50:19 +0200772 err = fuse_rename_common(olddir, oldent, newdir, newent, flags,
773 FUSE_RENAME2,
774 sizeof(struct fuse_rename2_in));
775 if (err == -ENOSYS) {
776 fc->no_rename2 = 1;
777 err = -EINVAL;
778 }
779 } else {
780 err = fuse_rename_common(olddir, oldent, newdir, newent, 0,
781 FUSE_RENAME,
782 sizeof(struct fuse_rename_in));
Miklos Szeredi1560c972014-04-28 16:43:44 +0200783 }
Miklos Szeredi1560c972014-04-28 16:43:44 +0200784
Miklos Szeredi4237ba42014-07-10 10:50:19 +0200785 return err;
786}
787
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700788static int fuse_link(struct dentry *entry, struct inode *newdir,
789 struct dentry *newent)
790{
791 int err;
792 struct fuse_link_in inarg;
David Howells2b0143b2015-03-17 22:25:59 +0000793 struct inode *inode = d_inode(entry);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700794 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +0100795 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700796
797 memset(&inarg, 0, sizeof(inarg));
798 inarg.oldnodeid = get_node_id(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +0100799 args.in.h.opcode = FUSE_LINK;
800 args.in.numargs = 2;
801 args.in.args[0].size = sizeof(inarg);
802 args.in.args[0].value = &inarg;
803 args.in.args[1].size = newent->d_name.len + 1;
804 args.in.args[1].value = newent->d_name.name;
805 err = create_new_entry(fc, &args, newdir, newent, inode->i_mode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700806 /* Contrary to "normal" filesystems it can happen that link
807 makes two "logical" inodes point to the same "physical"
808 inode. We invalidate the attributes of the old one, so it
809 will reflect changes in the backing inode (link count,
810 etc.)
811 */
Miklos Szerediac45d612012-03-05 15:48:11 +0100812 if (!err) {
813 struct fuse_inode *fi = get_fuse_inode(inode);
814
815 spin_lock(&fc->lock);
816 fi->attr_version = ++fc->attr_version;
817 inc_nlink(inode);
818 spin_unlock(&fc->lock);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700819 fuse_invalidate_attr(inode);
Maxim Patlasov31f32672014-04-28 14:19:24 +0200820 fuse_update_ctime(inode);
Miklos Szerediac45d612012-03-05 15:48:11 +0100821 } else if (err == -EINTR) {
822 fuse_invalidate_attr(inode);
823 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700824 return err;
825}
826
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700827static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
828 struct kstat *stat)
829{
Miklos Szeredi203627b2012-05-10 19:49:38 +0400830 unsigned int blkbits;
Pavel Emelyanov83732002013-10-10 17:10:46 +0400831 struct fuse_conn *fc = get_fuse_conn(inode);
832
833 /* see the comment in fuse_change_attributes() */
Maxim Patlasovb0aa7602013-12-26 19:51:11 +0400834 if (fc->writeback_cache && S_ISREG(inode->i_mode)) {
Pavel Emelyanov83732002013-10-10 17:10:46 +0400835 attr->size = i_size_read(inode);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +0400836 attr->mtime = inode->i_mtime.tv_sec;
837 attr->mtimensec = inode->i_mtime.tv_nsec;
Maxim Patlasov31f32672014-04-28 14:19:24 +0200838 attr->ctime = inode->i_ctime.tv_sec;
839 attr->ctimensec = inode->i_ctime.tv_nsec;
Maxim Patlasovb0aa7602013-12-26 19:51:11 +0400840 }
Miklos Szeredi203627b2012-05-10 19:49:38 +0400841
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700842 stat->dev = inode->i_sb->s_dev;
843 stat->ino = attr->ino;
844 stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
845 stat->nlink = attr->nlink;
Eric W. Biederman499dcf22012-02-07 16:26:03 -0800846 stat->uid = make_kuid(&init_user_ns, attr->uid);
847 stat->gid = make_kgid(&init_user_ns, attr->gid);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700848 stat->rdev = inode->i_rdev;
849 stat->atime.tv_sec = attr->atime;
850 stat->atime.tv_nsec = attr->atimensec;
851 stat->mtime.tv_sec = attr->mtime;
852 stat->mtime.tv_nsec = attr->mtimensec;
853 stat->ctime.tv_sec = attr->ctime;
854 stat->ctime.tv_nsec = attr->ctimensec;
855 stat->size = attr->size;
856 stat->blocks = attr->blocks;
Miklos Szeredi203627b2012-05-10 19:49:38 +0400857
858 if (attr->blksize != 0)
859 blkbits = ilog2(attr->blksize);
860 else
861 blkbits = inode->i_sb->s_blocksize_bits;
862
863 stat->blksize = 1 << blkbits;
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700864}
865
Miklos Szeredic79e3222007-10-18 03:06:59 -0700866static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
867 struct file *file)
Miklos Szeredie5e55582005-09-09 13:10:28 -0700868{
869 int err;
Miklos Szeredic79e3222007-10-18 03:06:59 -0700870 struct fuse_getattr_in inarg;
871 struct fuse_attr_out outarg;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700872 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +0100873 FUSE_ARGS(args);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700874 u64 attr_version;
875
Miklos Szeredi7dca9fd2007-11-28 16:21:59 -0800876 attr_version = fuse_get_attr_version(fc);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700877
Miklos Szeredic79e3222007-10-18 03:06:59 -0700878 memset(&inarg, 0, sizeof(inarg));
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700879 memset(&outarg, 0, sizeof(outarg));
Miklos Szeredic79e3222007-10-18 03:06:59 -0700880 /* Directories have separate file-handle space */
881 if (file && S_ISREG(inode->i_mode)) {
882 struct fuse_file *ff = file->private_data;
883
884 inarg.getattr_flags |= FUSE_GETATTR_FH;
885 inarg.fh = ff->fh;
886 }
Miklos Szeredi70781872014-12-12 09:49:05 +0100887 args.in.h.opcode = FUSE_GETATTR;
888 args.in.h.nodeid = get_node_id(inode);
889 args.in.numargs = 1;
890 args.in.args[0].size = sizeof(inarg);
891 args.in.args[0].value = &inarg;
892 args.out.numargs = 1;
Miklos Szeredi21f62172015-01-06 10:45:35 +0100893 args.out.args[0].size = sizeof(outarg);
Miklos Szeredi70781872014-12-12 09:49:05 +0100894 args.out.args[0].value = &outarg;
895 err = fuse_simple_request(fc, &args);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700896 if (!err) {
Miklos Szeredic79e3222007-10-18 03:06:59 -0700897 if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
Miklos Szeredie5e55582005-09-09 13:10:28 -0700898 make_bad_inode(inode);
899 err = -EIO;
900 } else {
Miklos Szeredic79e3222007-10-18 03:06:59 -0700901 fuse_change_attributes(inode, &outarg.attr,
902 attr_timeout(&outarg),
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700903 attr_version);
904 if (stat)
Miklos Szeredic79e3222007-10-18 03:06:59 -0700905 fuse_fillattr(inode, &outarg.attr, stat);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700906 }
907 }
908 return err;
909}
910
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800911int fuse_update_attributes(struct inode *inode, struct kstat *stat,
912 struct file *file, bool *refreshed)
913{
914 struct fuse_inode *fi = get_fuse_inode(inode);
915 int err;
916 bool r;
917
Miklos Szeredi126b9d42014-07-07 15:28:50 +0200918 if (time_before64(fi->i_time, get_jiffies_64())) {
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800919 r = true;
920 err = fuse_do_getattr(inode, stat, file);
921 } else {
922 r = false;
923 err = 0;
924 if (stat) {
925 generic_fillattr(inode, stat);
926 stat->mode = fi->orig_i_mode;
Pavel Shilovsky45c72cd2012-05-10 19:49:38 +0400927 stat->ino = fi->orig_ino;
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800928 }
929 }
930
931 if (refreshed != NULL)
932 *refreshed = r;
933
934 return err;
935}
936
John Muir3b463ae2009-05-31 11:13:57 -0400937int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid,
John Muir451d0f52011-12-06 21:50:06 +0100938 u64 child_nodeid, struct qstr *name)
John Muir3b463ae2009-05-31 11:13:57 -0400939{
940 int err = -ENOTDIR;
941 struct inode *parent;
942 struct dentry *dir;
943 struct dentry *entry;
944
945 parent = ilookup5(sb, parent_nodeid, fuse_inode_eq, &parent_nodeid);
946 if (!parent)
947 return -ENOENT;
948
Al Viro59551022016-01-22 15:40:57 -0500949 inode_lock(parent);
John Muir3b463ae2009-05-31 11:13:57 -0400950 if (!S_ISDIR(parent->i_mode))
951 goto unlock;
952
953 err = -ENOENT;
954 dir = d_find_alias(parent);
955 if (!dir)
956 goto unlock;
957
958 entry = d_lookup(dir, name);
959 dput(dir);
960 if (!entry)
961 goto unlock;
962
963 fuse_invalidate_attr(parent);
964 fuse_invalidate_entry(entry);
John Muir451d0f52011-12-06 21:50:06 +0100965
David Howells2b0143b2015-03-17 22:25:59 +0000966 if (child_nodeid != 0 && d_really_is_positive(entry)) {
Al Viro59551022016-01-22 15:40:57 -0500967 inode_lock(d_inode(entry));
David Howells2b0143b2015-03-17 22:25:59 +0000968 if (get_node_id(d_inode(entry)) != child_nodeid) {
John Muir451d0f52011-12-06 21:50:06 +0100969 err = -ENOENT;
970 goto badentry;
971 }
972 if (d_mountpoint(entry)) {
973 err = -EBUSY;
974 goto badentry;
975 }
David Howellse36cb0b2015-01-29 12:02:35 +0000976 if (d_is_dir(entry)) {
John Muir451d0f52011-12-06 21:50:06 +0100977 shrink_dcache_parent(entry);
978 if (!simple_empty(entry)) {
979 err = -ENOTEMPTY;
980 goto badentry;
981 }
David Howells2b0143b2015-03-17 22:25:59 +0000982 d_inode(entry)->i_flags |= S_DEAD;
John Muir451d0f52011-12-06 21:50:06 +0100983 }
984 dont_mount(entry);
David Howells2b0143b2015-03-17 22:25:59 +0000985 clear_nlink(d_inode(entry));
John Muir451d0f52011-12-06 21:50:06 +0100986 err = 0;
987 badentry:
Al Viro59551022016-01-22 15:40:57 -0500988 inode_unlock(d_inode(entry));
John Muir451d0f52011-12-06 21:50:06 +0100989 if (!err)
990 d_delete(entry);
991 } else {
992 err = 0;
993 }
John Muir3b463ae2009-05-31 11:13:57 -0400994 dput(entry);
John Muir3b463ae2009-05-31 11:13:57 -0400995
996 unlock:
Al Viro59551022016-01-22 15:40:57 -0500997 inode_unlock(parent);
John Muir3b463ae2009-05-31 11:13:57 -0400998 iput(parent);
999 return err;
1000}
1001
Miklos Szeredi87729a52005-09-09 13:10:34 -07001002/*
1003 * Calling into a user-controlled filesystem gives the filesystem
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001004 * daemon ptrace-like capabilities over the current process. This
Miklos Szeredi87729a52005-09-09 13:10:34 -07001005 * means, that the filesystem daemon is able to record the exact
1006 * filesystem operations performed, and can also control the behavior
1007 * of the requester process in otherwise impossible ways. For example
1008 * it can delay the operation for arbitrary length of time allowing
1009 * DoS against the requester.
1010 *
1011 * For this reason only those processes can call into the filesystem,
1012 * for which the owner of the mount has ptrace privilege. This
1013 * excludes processes started by other users, suid or sgid processes.
1014 */
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001015int fuse_allow_current_process(struct fuse_conn *fc)
Miklos Szeredi87729a52005-09-09 13:10:34 -07001016{
David Howellsc69e8d92008-11-14 10:39:19 +11001017 const struct cred *cred;
David Howellsc69e8d92008-11-14 10:39:19 +11001018
Miklos Szeredi87729a52005-09-09 13:10:34 -07001019 if (fc->flags & FUSE_ALLOW_OTHER)
1020 return 1;
1021
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001022 cred = current_cred();
Eric W. Biederman499dcf22012-02-07 16:26:03 -08001023 if (uid_eq(cred->euid, fc->user_id) &&
1024 uid_eq(cred->suid, fc->user_id) &&
1025 uid_eq(cred->uid, fc->user_id) &&
1026 gid_eq(cred->egid, fc->group_id) &&
1027 gid_eq(cred->sgid, fc->group_id) &&
1028 gid_eq(cred->gid, fc->group_id))
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001029 return 1;
Miklos Szeredi87729a52005-09-09 13:10:34 -07001030
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001031 return 0;
Miklos Szeredi87729a52005-09-09 13:10:34 -07001032}
1033
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001034static int fuse_access(struct inode *inode, int mask)
1035{
1036 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001037 FUSE_ARGS(args);
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001038 struct fuse_access_in inarg;
1039 int err;
1040
Miklos Szeredi698fa1d2013-10-01 16:41:23 +02001041 BUG_ON(mask & MAY_NOT_BLOCK);
1042
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001043 if (fc->no_access)
1044 return 0;
1045
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001046 memset(&inarg, 0, sizeof(inarg));
Al Viroe6305c42008-07-15 21:03:57 -04001047 inarg.mask = mask & (MAY_READ | MAY_WRITE | MAY_EXEC);
Miklos Szeredi70781872014-12-12 09:49:05 +01001048 args.in.h.opcode = FUSE_ACCESS;
1049 args.in.h.nodeid = get_node_id(inode);
1050 args.in.numargs = 1;
1051 args.in.args[0].size = sizeof(inarg);
1052 args.in.args[0].value = &inarg;
1053 err = fuse_simple_request(fc, &args);
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001054 if (err == -ENOSYS) {
1055 fc->no_access = 1;
1056 err = 0;
1057 }
1058 return err;
1059}
1060
Al Viro10556cb2011-06-20 19:28:19 -04001061static int fuse_perm_getattr(struct inode *inode, int mask)
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001062{
Al Viro10556cb2011-06-20 19:28:19 -04001063 if (mask & MAY_NOT_BLOCK)
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001064 return -ECHILD;
1065
1066 return fuse_do_getattr(inode, NULL, NULL);
1067}
1068
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001069/*
1070 * Check permission. The two basic access models of FUSE are:
1071 *
1072 * 1) Local access checking ('default_permissions' mount option) based
1073 * on file mode. This is the plain old disk filesystem permission
1074 * modell.
1075 *
1076 * 2) "Remote" access checking, where server is responsible for
1077 * checking permission in each inode operation. An exception to this
1078 * is if ->permission() was invoked from sys_access() in which case an
1079 * access request is sent. Execute permission is still checked
1080 * locally based on file mode.
1081 */
Al Viro10556cb2011-06-20 19:28:19 -04001082static int fuse_permission(struct inode *inode, int mask)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001083{
1084 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi244f6382007-10-16 23:31:02 -07001085 bool refreshed = false;
1086 int err = 0;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001087
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001088 if (!fuse_allow_current_process(fc))
Miklos Szeredie5e55582005-09-09 13:10:28 -07001089 return -EACCES;
Miklos Szeredi244f6382007-10-16 23:31:02 -07001090
1091 /*
Miklos Szeredie8e96152007-10-16 23:31:06 -07001092 * If attributes are needed, refresh them before proceeding
Miklos Szeredi244f6382007-10-16 23:31:02 -07001093 */
Miklos Szeredie8e96152007-10-16 23:31:06 -07001094 if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) ||
1095 ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) {
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001096 struct fuse_inode *fi = get_fuse_inode(inode);
1097
Miklos Szeredi126b9d42014-07-07 15:28:50 +02001098 if (time_before64(fi->i_time, get_jiffies_64())) {
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001099 refreshed = true;
1100
Al Viro10556cb2011-06-20 19:28:19 -04001101 err = fuse_perm_getattr(inode, mask);
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001102 if (err)
1103 return err;
1104 }
Miklos Szeredi244f6382007-10-16 23:31:02 -07001105 }
1106
1107 if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
Al Viro2830ba72011-06-20 19:16:29 -04001108 err = generic_permission(inode, mask);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001109
1110 /* If permission is denied, try to refresh file
1111 attributes. This is also needed, because the root
1112 node will at first have no permissions */
Miklos Szeredi244f6382007-10-16 23:31:02 -07001113 if (err == -EACCES && !refreshed) {
Al Viro10556cb2011-06-20 19:28:19 -04001114 err = fuse_perm_getattr(inode, mask);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001115 if (!err)
Al Viro2830ba72011-06-20 19:16:29 -04001116 err = generic_permission(inode, mask);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001117 }
1118
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001119 /* Note: the opposite of the above test does not
1120 exist. So if permissions are revoked this won't be
1121 noticed immediately, only after the attribute
1122 timeout has expired */
Eric Paris9cfcac82010-07-23 11:43:51 -04001123 } else if (mask & (MAY_ACCESS | MAY_CHDIR)) {
Miklos Szeredie8e96152007-10-16 23:31:06 -07001124 err = fuse_access(inode, mask);
1125 } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
1126 if (!(inode->i_mode & S_IXUGO)) {
1127 if (refreshed)
1128 return -EACCES;
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001129
Al Viro10556cb2011-06-20 19:28:19 -04001130 err = fuse_perm_getattr(inode, mask);
Miklos Szeredie8e96152007-10-16 23:31:06 -07001131 if (!err && !(inode->i_mode & S_IXUGO))
1132 return -EACCES;
1133 }
Miklos Szeredie5e55582005-09-09 13:10:28 -07001134 }
Miklos Szeredi244f6382007-10-16 23:31:02 -07001135 return err;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001136}
1137
1138static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
Al Viro8d3af7f2013-05-18 03:03:58 -04001139 struct dir_context *ctx)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001140{
1141 while (nbytes >= FUSE_NAME_OFFSET) {
1142 struct fuse_dirent *dirent = (struct fuse_dirent *) buf;
1143 size_t reclen = FUSE_DIRENT_SIZE(dirent);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001144 if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
1145 return -EIO;
1146 if (reclen > nbytes)
1147 break;
Miklos Szerediefeb9e62013-09-03 14:28:38 +02001148 if (memchr(dirent->name, '/', dirent->namelen) != NULL)
1149 return -EIO;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001150
Al Viro8d3af7f2013-05-18 03:03:58 -04001151 if (!dir_emit(ctx, dirent->name, dirent->namelen,
1152 dirent->ino, dirent->type))
Miklos Szeredie5e55582005-09-09 13:10:28 -07001153 break;
1154
1155 buf += reclen;
1156 nbytes -= reclen;
Al Viro8d3af7f2013-05-18 03:03:58 -04001157 ctx->pos = dirent->off;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001158 }
1159
1160 return 0;
1161}
1162
Anand V. Avati0b05b182012-08-19 08:53:23 -04001163static int fuse_direntplus_link(struct file *file,
1164 struct fuse_direntplus *direntplus,
1165 u64 attr_version)
1166{
Anand V. Avati0b05b182012-08-19 08:53:23 -04001167 struct fuse_entry_out *o = &direntplus->entry_out;
1168 struct fuse_dirent *dirent = &direntplus->dirent;
1169 struct dentry *parent = file->f_path.dentry;
1170 struct qstr name = QSTR_INIT(dirent->name, dirent->namelen);
1171 struct dentry *dentry;
1172 struct dentry *alias;
David Howells2b0143b2015-03-17 22:25:59 +00001173 struct inode *dir = d_inode(parent);
Anand V. Avati0b05b182012-08-19 08:53:23 -04001174 struct fuse_conn *fc;
1175 struct inode *inode;
Al Virod9b3dbd2016-04-20 17:30:32 -04001176 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
Anand V. Avati0b05b182012-08-19 08:53:23 -04001177
1178 if (!o->nodeid) {
1179 /*
1180 * Unlike in the case of fuse_lookup, zero nodeid does not mean
1181 * ENOENT. Instead, it only means the userspace filesystem did
1182 * not want to return attributes/handle for this entry.
1183 *
1184 * So do nothing.
1185 */
1186 return 0;
1187 }
1188
1189 if (name.name[0] == '.') {
1190 /*
1191 * We could potentially refresh the attributes of the directory
1192 * and its parent?
1193 */
1194 if (name.len == 1)
1195 return 0;
1196 if (name.name[1] == '.' && name.len == 2)
1197 return 0;
1198 }
Miklos Szeredia28ef452013-07-17 14:53:53 +02001199
1200 if (invalid_nodeid(o->nodeid))
1201 return -EIO;
1202 if (!fuse_valid_type(o->attr.mode))
1203 return -EIO;
1204
Anand V. Avati0b05b182012-08-19 08:53:23 -04001205 fc = get_fuse_conn(dir);
1206
1207 name.hash = full_name_hash(name.name, name.len);
1208 dentry = d_lookup(parent, &name);
Al Virod9b3dbd2016-04-20 17:30:32 -04001209 if (!dentry) {
1210retry:
1211 dentry = d_alloc_parallel(parent, &name, &wq);
1212 if (IS_ERR(dentry))
1213 return PTR_ERR(dentry);
1214 }
1215 if (!d_in_lookup(dentry)) {
1216 struct fuse_inode *fi;
David Howells2b0143b2015-03-17 22:25:59 +00001217 inode = d_inode(dentry);
Al Virod9b3dbd2016-04-20 17:30:32 -04001218 if (!inode ||
1219 get_node_id(inode) != o->nodeid ||
1220 ((o->attr.mode ^ inode->i_mode) & S_IFMT)) {
Eric W. Biederman5542aa22014-02-13 09:46:25 -08001221 d_invalidate(dentry);
Al Virod9b3dbd2016-04-20 17:30:32 -04001222 dput(dentry);
1223 goto retry;
Anand V. Avati0b05b182012-08-19 08:53:23 -04001224 }
Al Virod9b3dbd2016-04-20 17:30:32 -04001225 if (is_bad_inode(inode)) {
1226 dput(dentry);
1227 return -EIO;
1228 }
1229
1230 fi = get_fuse_inode(inode);
1231 spin_lock(&fc->lock);
1232 fi->nlookup++;
1233 spin_unlock(&fc->lock);
1234
1235 fuse_change_attributes(inode, &o->attr,
1236 entry_attr_timeout(o),
1237 attr_version);
1238 /*
1239 * The other branch comes via fuse_iget()
1240 * which bumps nlookup inside
1241 */
1242 } else {
1243 inode = fuse_iget(dir->i_sb, o->nodeid, o->generation,
1244 &o->attr, entry_attr_timeout(o),
1245 attr_version);
1246 if (!inode)
1247 inode = ERR_PTR(-ENOMEM);
1248
1249 alias = d_splice_alias(inode, dentry);
1250 d_lookup_done(dentry);
1251 if (alias) {
1252 dput(dentry);
1253 dentry = alias;
1254 }
1255 if (IS_ERR(dentry))
1256 return PTR_ERR(dentry);
Anand V. Avati0b05b182012-08-19 08:53:23 -04001257 }
Miklos Szeredi6314efe2013-10-01 16:41:22 +02001258 if (fc->readdirplus_auto)
1259 set_bit(FUSE_I_INIT_RDPLUS, &get_fuse_inode(inode)->state);
Anand V. Avati0b05b182012-08-19 08:53:23 -04001260 fuse_change_entry_timeout(dentry, o);
1261
Miklos Szeredic7263bc2013-07-17 14:53:54 +02001262 dput(dentry);
Al Virod9b3dbd2016-04-20 17:30:32 -04001263 return 0;
Anand V. Avati0b05b182012-08-19 08:53:23 -04001264}
1265
1266static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file,
Al Viro8d3af7f2013-05-18 03:03:58 -04001267 struct dir_context *ctx, u64 attr_version)
Anand V. Avati0b05b182012-08-19 08:53:23 -04001268{
1269 struct fuse_direntplus *direntplus;
1270 struct fuse_dirent *dirent;
1271 size_t reclen;
1272 int over = 0;
1273 int ret;
1274
1275 while (nbytes >= FUSE_NAME_OFFSET_DIRENTPLUS) {
1276 direntplus = (struct fuse_direntplus *) buf;
1277 dirent = &direntplus->dirent;
1278 reclen = FUSE_DIRENTPLUS_SIZE(direntplus);
1279
1280 if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
1281 return -EIO;
1282 if (reclen > nbytes)
1283 break;
Miklos Szerediefeb9e62013-09-03 14:28:38 +02001284 if (memchr(dirent->name, '/', dirent->namelen) != NULL)
1285 return -EIO;
Anand V. Avati0b05b182012-08-19 08:53:23 -04001286
1287 if (!over) {
1288 /* We fill entries into dstbuf only as much as
1289 it can hold. But we still continue iterating
1290 over remaining entries to link them. If not,
1291 we need to send a FORGET for each of those
1292 which we did not link.
1293 */
Al Viro8d3af7f2013-05-18 03:03:58 -04001294 over = !dir_emit(ctx, dirent->name, dirent->namelen,
1295 dirent->ino, dirent->type);
1296 ctx->pos = dirent->off;
Anand V. Avati0b05b182012-08-19 08:53:23 -04001297 }
1298
1299 buf += reclen;
1300 nbytes -= reclen;
1301
1302 ret = fuse_direntplus_link(file, direntplus, attr_version);
1303 if (ret)
1304 fuse_force_forget(file, direntplus->entry_out.nodeid);
1305 }
1306
1307 return 0;
1308}
1309
Al Viro8d3af7f2013-05-18 03:03:58 -04001310static int fuse_readdir(struct file *file, struct dir_context *ctx)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001311{
Feng Shuo4582a4a2013-01-15 11:23:28 +08001312 int plus, err;
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001313 size_t nbytes;
1314 struct page *page;
Al Viro496ad9a2013-01-23 17:07:38 -05001315 struct inode *inode = file_inode(file);
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001316 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi248d86e2006-01-06 00:19:39 -08001317 struct fuse_req *req;
Anand V. Avati0b05b182012-08-19 08:53:23 -04001318 u64 attr_version = 0;
Miklos Szeredi248d86e2006-01-06 00:19:39 -08001319
1320 if (is_bad_inode(inode))
1321 return -EIO;
1322
Maxim Patlasovb111c8c2012-10-26 19:48:30 +04001323 req = fuse_get_req(fc, 1);
Miklos Szeredice1d5a42006-04-10 22:54:58 -07001324 if (IS_ERR(req))
1325 return PTR_ERR(req);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001326
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001327 page = alloc_page(GFP_KERNEL);
1328 if (!page) {
1329 fuse_put_request(fc, req);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001330 return -ENOMEM;
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001331 }
Feng Shuo4582a4a2013-01-15 11:23:28 +08001332
Al Viro8d3af7f2013-05-18 03:03:58 -04001333 plus = fuse_use_readdirplus(inode, ctx);
Miklos Szeredif4975c62009-04-02 14:25:34 +02001334 req->out.argpages = 1;
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001335 req->num_pages = 1;
1336 req->pages[0] = page;
Maxim Patlasov85f40ae2012-10-26 19:49:33 +04001337 req->page_descs[0].length = PAGE_SIZE;
Feng Shuo4582a4a2013-01-15 11:23:28 +08001338 if (plus) {
Anand V. Avati0b05b182012-08-19 08:53:23 -04001339 attr_version = fuse_get_attr_version(fc);
Al Viro8d3af7f2013-05-18 03:03:58 -04001340 fuse_read_fill(req, file, ctx->pos, PAGE_SIZE,
Anand V. Avati0b05b182012-08-19 08:53:23 -04001341 FUSE_READDIRPLUS);
1342 } else {
Al Viro8d3af7f2013-05-18 03:03:58 -04001343 fuse_read_fill(req, file, ctx->pos, PAGE_SIZE,
Anand V. Avati0b05b182012-08-19 08:53:23 -04001344 FUSE_READDIR);
1345 }
Miklos Szeredi5c672ab2016-06-30 13:10:49 +02001346 fuse_lock_inode(inode);
Tejun Heob93f8582008-11-26 12:03:55 +01001347 fuse_request_send(fc, req);
Miklos Szeredi5c672ab2016-06-30 13:10:49 +02001348 fuse_unlock_inode(inode);
Miklos Szeredi361b1eb52006-01-16 22:14:45 -08001349 nbytes = req->out.args[0].size;
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001350 err = req->out.h.error;
1351 fuse_put_request(fc, req);
Anand V. Avati0b05b182012-08-19 08:53:23 -04001352 if (!err) {
Feng Shuo4582a4a2013-01-15 11:23:28 +08001353 if (plus) {
Anand V. Avati0b05b182012-08-19 08:53:23 -04001354 err = parse_dirplusfile(page_address(page), nbytes,
Al Viro8d3af7f2013-05-18 03:03:58 -04001355 file, ctx,
Anand V. Avati0b05b182012-08-19 08:53:23 -04001356 attr_version);
1357 } else {
1358 err = parse_dirfile(page_address(page), nbytes, file,
Al Viro8d3af7f2013-05-18 03:03:58 -04001359 ctx);
Anand V. Avati0b05b182012-08-19 08:53:23 -04001360 }
1361 }
Miklos Szeredie5e55582005-09-09 13:10:28 -07001362
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001363 __free_page(page);
Andrew Gallagher451418f2013-11-05 03:55:43 -08001364 fuse_invalidate_atime(inode);
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001365 return err;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001366}
1367
Al Viro6b255392015-11-17 10:20:54 -05001368static const char *fuse_get_link(struct dentry *dentry,
Al Virofceef392015-12-29 15:58:39 -05001369 struct inode *inode,
1370 struct delayed_call *done)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001371{
Miklos Szeredie5e55582005-09-09 13:10:28 -07001372 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001373 FUSE_ARGS(args);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001374 char *link;
Miklos Szeredi70781872014-12-12 09:49:05 +01001375 ssize_t ret;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001376
Al Viro6b255392015-11-17 10:20:54 -05001377 if (!dentry)
1378 return ERR_PTR(-ECHILD);
1379
Al Virocd3417c2015-12-29 16:03:53 -05001380 link = kmalloc(PAGE_SIZE, GFP_KERNEL);
Miklos Szeredi70781872014-12-12 09:49:05 +01001381 if (!link)
1382 return ERR_PTR(-ENOMEM);
1383
1384 args.in.h.opcode = FUSE_READLINK;
1385 args.in.h.nodeid = get_node_id(inode);
1386 args.out.argvar = 1;
1387 args.out.numargs = 1;
1388 args.out.args[0].size = PAGE_SIZE - 1;
1389 args.out.args[0].value = link;
1390 ret = fuse_simple_request(fc, &args);
1391 if (ret < 0) {
Al Virocd3417c2015-12-29 16:03:53 -05001392 kfree(link);
Miklos Szeredi70781872014-12-12 09:49:05 +01001393 link = ERR_PTR(ret);
1394 } else {
1395 link[ret] = '\0';
Al Virofceef392015-12-29 15:58:39 -05001396 set_delayed_call(done, kfree_link, link);
Miklos Szeredi70781872014-12-12 09:49:05 +01001397 }
Andrew Gallagher451418f2013-11-05 03:55:43 -08001398 fuse_invalidate_atime(inode);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001399 return link;
1400}
1401
Miklos Szeredie5e55582005-09-09 13:10:28 -07001402static int fuse_dir_open(struct inode *inode, struct file *file)
1403{
Miklos Szeredi91fe96b2009-04-28 16:56:37 +02001404 return fuse_open_common(inode, file, true);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001405}
1406
1407static int fuse_dir_release(struct inode *inode, struct file *file)
1408{
Miklos Szeredi8b0797a2009-04-28 16:56:39 +02001409 fuse_release_common(file, FUSE_RELEASEDIR);
1410
1411 return 0;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001412}
1413
Josef Bacik02c24a82011-07-16 20:44:56 -04001414static int fuse_dir_fsync(struct file *file, loff_t start, loff_t end,
1415 int datasync)
Miklos Szeredi82547982005-09-09 13:10:38 -07001416{
Josef Bacik02c24a82011-07-16 20:44:56 -04001417 return fuse_fsync_common(file, start, end, datasync, 1);
Miklos Szeredi82547982005-09-09 13:10:38 -07001418}
1419
Miklos Szeredib18da0c2011-12-13 11:58:49 +01001420static long fuse_dir_ioctl(struct file *file, unsigned int cmd,
1421 unsigned long arg)
1422{
1423 struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1424
1425 /* FUSE_IOCTL_DIR only supported for API version >= 7.18 */
1426 if (fc->minor < 18)
1427 return -ENOTTY;
1428
1429 return fuse_ioctl_common(file, cmd, arg, FUSE_IOCTL_DIR);
1430}
1431
1432static long fuse_dir_compat_ioctl(struct file *file, unsigned int cmd,
1433 unsigned long arg)
1434{
1435 struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1436
1437 if (fc->minor < 18)
1438 return -ENOTTY;
1439
1440 return fuse_ioctl_common(file, cmd, arg,
1441 FUSE_IOCTL_COMPAT | FUSE_IOCTL_DIR);
1442}
1443
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001444static bool update_mtime(unsigned ivalid, bool trust_local_mtime)
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001445{
1446 /* Always update if mtime is explicitly set */
1447 if (ivalid & ATTR_MTIME_SET)
1448 return true;
1449
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001450 /* Or if kernel i_mtime is the official one */
1451 if (trust_local_mtime)
1452 return true;
1453
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001454 /* If it's an open(O_TRUNC) or an ftruncate(), don't update */
1455 if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE)))
1456 return false;
1457
1458 /* In all other cases update */
1459 return true;
1460}
1461
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001462static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg,
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001463 bool trust_local_cmtime)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001464{
1465 unsigned ivalid = iattr->ia_valid;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001466
1467 if (ivalid & ATTR_MODE)
Miklos Szeredibefc6492005-11-07 00:59:52 -08001468 arg->valid |= FATTR_MODE, arg->mode = iattr->ia_mode;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001469 if (ivalid & ATTR_UID)
Eric W. Biederman499dcf22012-02-07 16:26:03 -08001470 arg->valid |= FATTR_UID, arg->uid = from_kuid(&init_user_ns, iattr->ia_uid);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001471 if (ivalid & ATTR_GID)
Eric W. Biederman499dcf22012-02-07 16:26:03 -08001472 arg->valid |= FATTR_GID, arg->gid = from_kgid(&init_user_ns, iattr->ia_gid);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001473 if (ivalid & ATTR_SIZE)
Miklos Szeredibefc6492005-11-07 00:59:52 -08001474 arg->valid |= FATTR_SIZE, arg->size = iattr->ia_size;
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001475 if (ivalid & ATTR_ATIME) {
1476 arg->valid |= FATTR_ATIME;
Miklos Szeredibefc6492005-11-07 00:59:52 -08001477 arg->atime = iattr->ia_atime.tv_sec;
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001478 arg->atimensec = iattr->ia_atime.tv_nsec;
1479 if (!(ivalid & ATTR_ATIME_SET))
1480 arg->valid |= FATTR_ATIME_NOW;
1481 }
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001482 if ((ivalid & ATTR_MTIME) && update_mtime(ivalid, trust_local_cmtime)) {
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001483 arg->valid |= FATTR_MTIME;
Miklos Szeredibefc6492005-11-07 00:59:52 -08001484 arg->mtime = iattr->ia_mtime.tv_sec;
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001485 arg->mtimensec = iattr->ia_mtime.tv_nsec;
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001486 if (!(ivalid & ATTR_MTIME_SET) && !trust_local_cmtime)
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001487 arg->valid |= FATTR_MTIME_NOW;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001488 }
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001489 if ((ivalid & ATTR_CTIME) && trust_local_cmtime) {
1490 arg->valid |= FATTR_CTIME;
1491 arg->ctime = iattr->ia_ctime.tv_sec;
1492 arg->ctimensec = iattr->ia_ctime.tv_nsec;
1493 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001494}
1495
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001496/*
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001497 * Prevent concurrent writepages on inode
1498 *
1499 * This is done by adding a negative bias to the inode write counter
1500 * and waiting for all pending writes to finish.
1501 */
1502void fuse_set_nowrite(struct inode *inode)
1503{
1504 struct fuse_conn *fc = get_fuse_conn(inode);
1505 struct fuse_inode *fi = get_fuse_inode(inode);
1506
Al Viro59551022016-01-22 15:40:57 -05001507 BUG_ON(!inode_is_locked(inode));
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001508
1509 spin_lock(&fc->lock);
1510 BUG_ON(fi->writectr < 0);
1511 fi->writectr += FUSE_NOWRITE;
1512 spin_unlock(&fc->lock);
1513 wait_event(fi->page_waitq, fi->writectr == FUSE_NOWRITE);
1514}
1515
1516/*
1517 * Allow writepages on inode
1518 *
1519 * Remove the bias from the writecounter and send any queued
1520 * writepages.
1521 */
1522static void __fuse_release_nowrite(struct inode *inode)
1523{
1524 struct fuse_inode *fi = get_fuse_inode(inode);
1525
1526 BUG_ON(fi->writectr != FUSE_NOWRITE);
1527 fi->writectr = 0;
1528 fuse_flush_writepages(inode);
1529}
1530
1531void fuse_release_nowrite(struct inode *inode)
1532{
1533 struct fuse_conn *fc = get_fuse_conn(inode);
1534
1535 spin_lock(&fc->lock);
1536 __fuse_release_nowrite(inode);
1537 spin_unlock(&fc->lock);
1538}
1539
Miklos Szeredi70781872014-12-12 09:49:05 +01001540static void fuse_setattr_fill(struct fuse_conn *fc, struct fuse_args *args,
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001541 struct inode *inode,
1542 struct fuse_setattr_in *inarg_p,
1543 struct fuse_attr_out *outarg_p)
1544{
Miklos Szeredi70781872014-12-12 09:49:05 +01001545 args->in.h.opcode = FUSE_SETATTR;
1546 args->in.h.nodeid = get_node_id(inode);
1547 args->in.numargs = 1;
1548 args->in.args[0].size = sizeof(*inarg_p);
1549 args->in.args[0].value = inarg_p;
1550 args->out.numargs = 1;
Miklos Szeredi21f62172015-01-06 10:45:35 +01001551 args->out.args[0].size = sizeof(*outarg_p);
Miklos Szeredi70781872014-12-12 09:49:05 +01001552 args->out.args[0].value = outarg_p;
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001553}
1554
1555/*
1556 * Flush inode->i_mtime to the server
1557 */
Maxim Patlasovab9e13f2014-04-28 14:19:24 +02001558int fuse_flush_times(struct inode *inode, struct fuse_file *ff)
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001559{
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001560 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001561 FUSE_ARGS(args);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001562 struct fuse_setattr_in inarg;
1563 struct fuse_attr_out outarg;
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001564
1565 memset(&inarg, 0, sizeof(inarg));
1566 memset(&outarg, 0, sizeof(outarg));
1567
Maxim Patlasovab9e13f2014-04-28 14:19:24 +02001568 inarg.valid = FATTR_MTIME;
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001569 inarg.mtime = inode->i_mtime.tv_sec;
1570 inarg.mtimensec = inode->i_mtime.tv_nsec;
Maxim Patlasovab9e13f2014-04-28 14:19:24 +02001571 if (fc->minor >= 23) {
1572 inarg.valid |= FATTR_CTIME;
1573 inarg.ctime = inode->i_ctime.tv_sec;
1574 inarg.ctimensec = inode->i_ctime.tv_nsec;
1575 }
Miklos Szeredi1e18bda2014-04-28 14:19:23 +02001576 if (ff) {
1577 inarg.valid |= FATTR_FH;
1578 inarg.fh = ff->fh;
1579 }
Miklos Szeredi70781872014-12-12 09:49:05 +01001580 fuse_setattr_fill(fc, &args, inode, &inarg, &outarg);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001581
Miklos Szeredi70781872014-12-12 09:49:05 +01001582 return fuse_simple_request(fc, &args);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001583}
1584
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001585/*
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001586 * Set attributes, and at the same time refresh them.
1587 *
1588 * Truncation is slightly complicated, because the 'truncate' request
1589 * may fail, in which case we don't want to touch the mapping.
Miklos Szeredi9ffbb912006-10-17 00:10:06 -07001590 * vmtruncate() doesn't allow for this case, so do the rlimit checking
1591 * and the actual truncation by hand.
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001592 */
Maxim Patlasovefb9fa92012-12-18 14:05:08 +04001593int fuse_do_setattr(struct inode *inode, struct iattr *attr,
1594 struct file *file)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001595{
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001596 struct fuse_conn *fc = get_fuse_conn(inode);
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001597 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001598 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001599 struct fuse_setattr_in inarg;
1600 struct fuse_attr_out outarg;
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001601 bool is_truncate = false;
Pavel Emelyanov83732002013-10-10 17:10:46 +04001602 bool is_wb = fc->writeback_cache;
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001603 loff_t oldsize;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001604 int err;
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001605 bool trust_local_cmtime = is_wb && S_ISREG(inode->i_mode);
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 Patlasov06a7c3c2013-08-30 17:06:04 +04001623 if (is_truncate) {
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001624 fuse_set_nowrite(inode);
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001625 set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001626 if (trust_local_cmtime && attr->ia_size != inode->i_size)
1627 attr->ia_valid |= ATTR_MTIME | ATTR_CTIME;
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001628 }
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001629
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001630 memset(&inarg, 0, sizeof(inarg));
Miklos Szeredi0e9663e2007-10-18 03:07:05 -07001631 memset(&outarg, 0, sizeof(outarg));
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001632 iattr_to_fattr(attr, &inarg, trust_local_cmtime);
Miklos Szeredi49d49142007-10-18 03:07:00 -07001633 if (file) {
1634 struct fuse_file *ff = file->private_data;
1635 inarg.valid |= FATTR_FH;
1636 inarg.fh = ff->fh;
1637 }
Miklos Szeredif3332112007-10-18 03:07:04 -07001638 if (attr->ia_valid & ATTR_SIZE) {
1639 /* For mandatory locking in truncate */
1640 inarg.valid |= FATTR_LOCKOWNER;
1641 inarg.lock_owner = fuse_lock_owner_id(fc, current->files);
1642 }
Miklos Szeredi70781872014-12-12 09:49:05 +01001643 fuse_setattr_fill(fc, &args, inode, &inarg, &outarg);
1644 err = fuse_simple_request(fc, &args);
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001645 if (err) {
1646 if (err == -EINTR)
1647 fuse_invalidate_attr(inode);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001648 goto error;
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001649 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001650
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001651 if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
1652 make_bad_inode(inode);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001653 err = -EIO;
1654 goto error;
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001655 }
1656
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001657 spin_lock(&fc->lock);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001658 /* the kernel maintains i_mtime locally */
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001659 if (trust_local_cmtime) {
1660 if (attr->ia_valid & ATTR_MTIME)
1661 inode->i_mtime = attr->ia_mtime;
1662 if (attr->ia_valid & ATTR_CTIME)
1663 inode->i_ctime = attr->ia_ctime;
Miklos Szeredi1e18bda2014-04-28 14:19:23 +02001664 /* FIXME: clear I_DIRTY_SYNC? */
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001665 }
1666
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001667 fuse_change_attributes_common(inode, &outarg.attr,
1668 attr_timeout(&outarg));
1669 oldsize = inode->i_size;
Pavel Emelyanov83732002013-10-10 17:10:46 +04001670 /* see the comment in fuse_change_attributes() */
1671 if (!is_wb || is_truncate || !S_ISREG(inode->i_mode))
1672 i_size_write(inode, outarg.attr.size);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001673
1674 if (is_truncate) {
1675 /* NOTE: this may release/reacquire fc->lock */
1676 __fuse_release_nowrite(inode);
1677 }
1678 spin_unlock(&fc->lock);
1679
1680 /*
1681 * Only call invalidate_inode_pages2() after removing
1682 * FUSE_NOWRITE, otherwise fuse_launder_page() would deadlock.
1683 */
Pavel Emelyanov83732002013-10-10 17:10:46 +04001684 if ((is_truncate || !is_wb) &&
1685 S_ISREG(inode->i_mode) && oldsize != outarg.attr.size) {
Kirill A. Shutemov7caef262013-09-12 15:13:56 -07001686 truncate_pagecache(inode, outarg.attr.size);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001687 invalidate_inode_pages2(inode->i_mapping);
1688 }
1689
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001690 clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001691 return 0;
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001692
1693error:
1694 if (is_truncate)
1695 fuse_release_nowrite(inode);
1696
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001697 clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001698 return err;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001699}
1700
Miklos Szeredi49d49142007-10-18 03:07:00 -07001701static int fuse_setattr(struct dentry *entry, struct iattr *attr)
1702{
David Howells2b0143b2015-03-17 22:25:59 +00001703 struct inode *inode = d_inode(entry);
Maxim Patlasovefb9fa92012-12-18 14:05:08 +04001704
1705 if (!fuse_allow_current_process(get_fuse_conn(inode)))
1706 return -EACCES;
1707
Miklos Szeredi49d49142007-10-18 03:07:00 -07001708 if (attr->ia_valid & ATTR_FILE)
Maxim Patlasovefb9fa92012-12-18 14:05:08 +04001709 return fuse_do_setattr(inode, attr, attr->ia_file);
Miklos Szeredi49d49142007-10-18 03:07:00 -07001710 else
Maxim Patlasovefb9fa92012-12-18 14:05:08 +04001711 return fuse_do_setattr(inode, attr, NULL);
Miklos Szeredi49d49142007-10-18 03:07:00 -07001712}
1713
Miklos Szeredie5e55582005-09-09 13:10:28 -07001714static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
1715 struct kstat *stat)
1716{
David Howells2b0143b2015-03-17 22:25:59 +00001717 struct inode *inode = d_inode(entry);
Miklos Szeredi244f6382007-10-16 23:31:02 -07001718 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi244f6382007-10-16 23:31:02 -07001719
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001720 if (!fuse_allow_current_process(fc))
Miklos Szeredi244f6382007-10-16 23:31:02 -07001721 return -EACCES;
1722
Miklos Szeredibcb4be82007-11-28 16:21:59 -08001723 return fuse_update_attributes(inode, stat, NULL, NULL);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001724}
1725
Al Viro3767e252016-05-27 11:06:05 -04001726static int fuse_setxattr(struct dentry *unused, struct inode *inode,
1727 const char *name, const void *value,
1728 size_t size, int flags)
Miklos Szeredi92a87802005-09-09 13:10:31 -07001729{
Miklos Szeredi92a87802005-09-09 13:10:31 -07001730 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001731 FUSE_ARGS(args);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001732 struct fuse_setxattr_in inarg;
1733 int err;
1734
Miklos Szeredi92a87802005-09-09 13:10:31 -07001735 if (fc->no_setxattr)
1736 return -EOPNOTSUPP;
1737
Miklos Szeredi92a87802005-09-09 13:10:31 -07001738 memset(&inarg, 0, sizeof(inarg));
1739 inarg.size = size;
1740 inarg.flags = flags;
Miklos Szeredi70781872014-12-12 09:49:05 +01001741 args.in.h.opcode = FUSE_SETXATTR;
1742 args.in.h.nodeid = get_node_id(inode);
1743 args.in.numargs = 3;
1744 args.in.args[0].size = sizeof(inarg);
1745 args.in.args[0].value = &inarg;
1746 args.in.args[1].size = strlen(name) + 1;
1747 args.in.args[1].value = name;
1748 args.in.args[2].size = size;
1749 args.in.args[2].value = value;
1750 err = fuse_simple_request(fc, &args);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001751 if (err == -ENOSYS) {
1752 fc->no_setxattr = 1;
1753 err = -EOPNOTSUPP;
1754 }
Maxim Patlasov31f32672014-04-28 14:19:24 +02001755 if (!err) {
Anand Avatid331a412013-08-20 02:21:07 -04001756 fuse_invalidate_attr(inode);
Maxim Patlasov31f32672014-04-28 14:19:24 +02001757 fuse_update_ctime(inode);
1758 }
Miklos Szeredi92a87802005-09-09 13:10:31 -07001759 return err;
1760}
1761
Al Viroce23e642016-04-11 00:48:00 -04001762static ssize_t fuse_getxattr(struct dentry *entry, struct inode *inode,
1763 const char *name, void *value, size_t size)
Miklos Szeredi92a87802005-09-09 13:10:31 -07001764{
Miklos Szeredi92a87802005-09-09 13:10:31 -07001765 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001766 FUSE_ARGS(args);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001767 struct fuse_getxattr_in inarg;
1768 struct fuse_getxattr_out outarg;
1769 ssize_t ret;
1770
1771 if (fc->no_getxattr)
1772 return -EOPNOTSUPP;
1773
Miklos Szeredi92a87802005-09-09 13:10:31 -07001774 memset(&inarg, 0, sizeof(inarg));
1775 inarg.size = size;
Miklos Szeredi70781872014-12-12 09:49:05 +01001776 args.in.h.opcode = FUSE_GETXATTR;
1777 args.in.h.nodeid = get_node_id(inode);
1778 args.in.numargs = 2;
1779 args.in.args[0].size = sizeof(inarg);
1780 args.in.args[0].value = &inarg;
1781 args.in.args[1].size = strlen(name) + 1;
1782 args.in.args[1].value = name;
Miklos Szeredi92a87802005-09-09 13:10:31 -07001783 /* This is really two different operations rolled into one */
Miklos Szeredi70781872014-12-12 09:49:05 +01001784 args.out.numargs = 1;
Miklos Szeredi92a87802005-09-09 13:10:31 -07001785 if (size) {
Miklos Szeredi70781872014-12-12 09:49:05 +01001786 args.out.argvar = 1;
1787 args.out.args[0].size = size;
1788 args.out.args[0].value = value;
Miklos Szeredi92a87802005-09-09 13:10:31 -07001789 } else {
Miklos Szeredi70781872014-12-12 09:49:05 +01001790 args.out.args[0].size = sizeof(outarg);
1791 args.out.args[0].value = &outarg;
Miklos Szeredi92a87802005-09-09 13:10:31 -07001792 }
Miklos Szeredi70781872014-12-12 09:49:05 +01001793 ret = fuse_simple_request(fc, &args);
1794 if (!ret && !size)
1795 ret = outarg.size;
1796 if (ret == -ENOSYS) {
1797 fc->no_getxattr = 1;
1798 ret = -EOPNOTSUPP;
Miklos Szeredi92a87802005-09-09 13:10:31 -07001799 }
Miklos Szeredi92a87802005-09-09 13:10:31 -07001800 return ret;
1801}
1802
1803static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
1804{
David Howells2b0143b2015-03-17 22:25:59 +00001805 struct inode *inode = d_inode(entry);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001806 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001807 FUSE_ARGS(args);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001808 struct fuse_getxattr_in inarg;
1809 struct fuse_getxattr_out outarg;
1810 ssize_t ret;
1811
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001812 if (!fuse_allow_current_process(fc))
Miklos Szeredie57ac682007-10-18 03:06:58 -07001813 return -EACCES;
1814
Miklos Szeredi92a87802005-09-09 13:10:31 -07001815 if (fc->no_listxattr)
1816 return -EOPNOTSUPP;
1817
Miklos Szeredi92a87802005-09-09 13:10:31 -07001818 memset(&inarg, 0, sizeof(inarg));
1819 inarg.size = size;
Miklos Szeredi70781872014-12-12 09:49:05 +01001820 args.in.h.opcode = FUSE_LISTXATTR;
1821 args.in.h.nodeid = get_node_id(inode);
1822 args.in.numargs = 1;
1823 args.in.args[0].size = sizeof(inarg);
1824 args.in.args[0].value = &inarg;
Miklos Szeredi92a87802005-09-09 13:10:31 -07001825 /* This is really two different operations rolled into one */
Miklos Szeredi70781872014-12-12 09:49:05 +01001826 args.out.numargs = 1;
Miklos Szeredi92a87802005-09-09 13:10:31 -07001827 if (size) {
Miklos Szeredi70781872014-12-12 09:49:05 +01001828 args.out.argvar = 1;
1829 args.out.args[0].size = size;
1830 args.out.args[0].value = list;
Miklos Szeredi92a87802005-09-09 13:10:31 -07001831 } else {
Miklos Szeredi70781872014-12-12 09:49:05 +01001832 args.out.args[0].size = sizeof(outarg);
1833 args.out.args[0].value = &outarg;
Miklos Szeredi92a87802005-09-09 13:10:31 -07001834 }
Miklos Szeredi70781872014-12-12 09:49:05 +01001835 ret = fuse_simple_request(fc, &args);
1836 if (!ret && !size)
1837 ret = outarg.size;
1838 if (ret == -ENOSYS) {
1839 fc->no_listxattr = 1;
1840 ret = -EOPNOTSUPP;
Miklos Szeredi92a87802005-09-09 13:10:31 -07001841 }
Miklos Szeredi92a87802005-09-09 13:10:31 -07001842 return ret;
1843}
1844
1845static int fuse_removexattr(struct dentry *entry, const char *name)
1846{
David Howells2b0143b2015-03-17 22:25:59 +00001847 struct inode *inode = d_inode(entry);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001848 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001849 FUSE_ARGS(args);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001850 int err;
1851
1852 if (fc->no_removexattr)
1853 return -EOPNOTSUPP;
1854
Miklos Szeredi70781872014-12-12 09:49:05 +01001855 args.in.h.opcode = FUSE_REMOVEXATTR;
1856 args.in.h.nodeid = get_node_id(inode);
1857 args.in.numargs = 1;
1858 args.in.args[0].size = strlen(name) + 1;
1859 args.in.args[0].value = name;
1860 err = fuse_simple_request(fc, &args);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001861 if (err == -ENOSYS) {
1862 fc->no_removexattr = 1;
1863 err = -EOPNOTSUPP;
1864 }
Maxim Patlasov31f32672014-04-28 14:19:24 +02001865 if (!err) {
Anand Avatid331a412013-08-20 02:21:07 -04001866 fuse_invalidate_attr(inode);
Maxim Patlasov31f32672014-04-28 14:19:24 +02001867 fuse_update_ctime(inode);
1868 }
Miklos Szeredi92a87802005-09-09 13:10:31 -07001869 return err;
1870}
1871
Arjan van de Ven754661f2007-02-12 00:55:38 -08001872static const struct inode_operations fuse_dir_inode_operations = {
Miklos Szeredie5e55582005-09-09 13:10:28 -07001873 .lookup = fuse_lookup,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001874 .mkdir = fuse_mkdir,
1875 .symlink = fuse_symlink,
1876 .unlink = fuse_unlink,
1877 .rmdir = fuse_rmdir,
Miklos Szeredi1560c972014-04-28 16:43:44 +02001878 .rename2 = fuse_rename2,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001879 .link = fuse_link,
1880 .setattr = fuse_setattr,
1881 .create = fuse_create,
Miklos Szeredic8ccbe02012-06-05 15:10:22 +02001882 .atomic_open = fuse_atomic_open,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001883 .mknod = fuse_mknod,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001884 .permission = fuse_permission,
1885 .getattr = fuse_getattr,
Miklos Szeredi92a87802005-09-09 13:10:31 -07001886 .setxattr = fuse_setxattr,
1887 .getxattr = fuse_getxattr,
1888 .listxattr = fuse_listxattr,
1889 .removexattr = fuse_removexattr,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001890};
1891
Arjan van de Ven4b6f5d22006-03-28 01:56:42 -08001892static const struct file_operations fuse_dir_operations = {
Miklos Szeredib6aeade2005-09-09 13:10:30 -07001893 .llseek = generic_file_llseek,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001894 .read = generic_read_dir,
Al Virod9b3dbd2016-04-20 17:30:32 -04001895 .iterate_shared = fuse_readdir,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001896 .open = fuse_dir_open,
1897 .release = fuse_dir_release,
Miklos Szeredi82547982005-09-09 13:10:38 -07001898 .fsync = fuse_dir_fsync,
Miklos Szeredib18da0c2011-12-13 11:58:49 +01001899 .unlocked_ioctl = fuse_dir_ioctl,
1900 .compat_ioctl = fuse_dir_compat_ioctl,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001901};
1902
Arjan van de Ven754661f2007-02-12 00:55:38 -08001903static const struct inode_operations fuse_common_inode_operations = {
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001904 .setattr = fuse_setattr,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001905 .permission = fuse_permission,
1906 .getattr = fuse_getattr,
Miklos Szeredi92a87802005-09-09 13:10:31 -07001907 .setxattr = fuse_setxattr,
1908 .getxattr = fuse_getxattr,
1909 .listxattr = fuse_listxattr,
1910 .removexattr = fuse_removexattr,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001911};
1912
Arjan van de Ven754661f2007-02-12 00:55:38 -08001913static const struct inode_operations fuse_symlink_inode_operations = {
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001914 .setattr = fuse_setattr,
Al Viro6b255392015-11-17 10:20:54 -05001915 .get_link = fuse_get_link,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001916 .readlink = generic_readlink,
1917 .getattr = fuse_getattr,
Miklos Szeredi92a87802005-09-09 13:10:31 -07001918 .setxattr = fuse_setxattr,
1919 .getxattr = fuse_getxattr,
1920 .listxattr = fuse_listxattr,
1921 .removexattr = fuse_removexattr,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001922};
1923
1924void fuse_init_common(struct inode *inode)
1925{
1926 inode->i_op = &fuse_common_inode_operations;
1927}
1928
1929void fuse_init_dir(struct inode *inode)
1930{
1931 inode->i_op = &fuse_dir_inode_operations;
1932 inode->i_fop = &fuse_dir_operations;
1933}
1934
1935void fuse_init_symlink(struct inode *inode)
1936{
1937 inode->i_op = &fuse_symlink_inode_operations;
1938}