blob: 4bfeaa70815f6c76cfa8ea06eadbe856d4c91d43 [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,
Al Viro13983d02016-07-20 22:34:44 -0400149 u64 nodeid, const 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
Al Viro13983d02016-07-20 22:34:44 -0400285int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name,
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700286 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
Al Viro00699ad2016-07-05 09:44:53 -0400483 if (d_in_lookup(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
Linus Torvalds8387ff22016-06-10 07:51:30 -0700958 name->hash = full_name_hash(dir, name->name, name->len);
John Muir3b463ae2009-05-31 11:13:57 -0400959 entry = d_lookup(dir, name);
960 dput(dir);
961 if (!entry)
962 goto unlock;
963
964 fuse_invalidate_attr(parent);
965 fuse_invalidate_entry(entry);
John Muir451d0f52011-12-06 21:50:06 +0100966
David Howells2b0143b2015-03-17 22:25:59 +0000967 if (child_nodeid != 0 && d_really_is_positive(entry)) {
Al Viro59551022016-01-22 15:40:57 -0500968 inode_lock(d_inode(entry));
David Howells2b0143b2015-03-17 22:25:59 +0000969 if (get_node_id(d_inode(entry)) != child_nodeid) {
John Muir451d0f52011-12-06 21:50:06 +0100970 err = -ENOENT;
971 goto badentry;
972 }
973 if (d_mountpoint(entry)) {
974 err = -EBUSY;
975 goto badentry;
976 }
David Howellse36cb0b2015-01-29 12:02:35 +0000977 if (d_is_dir(entry)) {
John Muir451d0f52011-12-06 21:50:06 +0100978 shrink_dcache_parent(entry);
979 if (!simple_empty(entry)) {
980 err = -ENOTEMPTY;
981 goto badentry;
982 }
David Howells2b0143b2015-03-17 22:25:59 +0000983 d_inode(entry)->i_flags |= S_DEAD;
John Muir451d0f52011-12-06 21:50:06 +0100984 }
985 dont_mount(entry);
David Howells2b0143b2015-03-17 22:25:59 +0000986 clear_nlink(d_inode(entry));
John Muir451d0f52011-12-06 21:50:06 +0100987 err = 0;
988 badentry:
Al Viro59551022016-01-22 15:40:57 -0500989 inode_unlock(d_inode(entry));
John Muir451d0f52011-12-06 21:50:06 +0100990 if (!err)
991 d_delete(entry);
992 } else {
993 err = 0;
994 }
John Muir3b463ae2009-05-31 11:13:57 -0400995 dput(entry);
John Muir3b463ae2009-05-31 11:13:57 -0400996
997 unlock:
Al Viro59551022016-01-22 15:40:57 -0500998 inode_unlock(parent);
John Muir3b463ae2009-05-31 11:13:57 -0400999 iput(parent);
1000 return err;
1001}
1002
Miklos Szeredi87729a52005-09-09 13:10:34 -07001003/*
1004 * Calling into a user-controlled filesystem gives the filesystem
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001005 * daemon ptrace-like capabilities over the current process. This
Miklos Szeredi87729a52005-09-09 13:10:34 -07001006 * means, that the filesystem daemon is able to record the exact
1007 * filesystem operations performed, and can also control the behavior
1008 * of the requester process in otherwise impossible ways. For example
1009 * it can delay the operation for arbitrary length of time allowing
1010 * DoS against the requester.
1011 *
1012 * For this reason only those processes can call into the filesystem,
1013 * for which the owner of the mount has ptrace privilege. This
1014 * excludes processes started by other users, suid or sgid processes.
1015 */
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001016int fuse_allow_current_process(struct fuse_conn *fc)
Miklos Szeredi87729a52005-09-09 13:10:34 -07001017{
David Howellsc69e8d92008-11-14 10:39:19 +11001018 const struct cred *cred;
David Howellsc69e8d92008-11-14 10:39:19 +11001019
Miklos Szeredi87729a52005-09-09 13:10:34 -07001020 if (fc->flags & FUSE_ALLOW_OTHER)
1021 return 1;
1022
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001023 cred = current_cred();
Eric W. Biederman499dcf22012-02-07 16:26:03 -08001024 if (uid_eq(cred->euid, fc->user_id) &&
1025 uid_eq(cred->suid, fc->user_id) &&
1026 uid_eq(cred->uid, fc->user_id) &&
1027 gid_eq(cred->egid, fc->group_id) &&
1028 gid_eq(cred->sgid, fc->group_id) &&
1029 gid_eq(cred->gid, fc->group_id))
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001030 return 1;
Miklos Szeredi87729a52005-09-09 13:10:34 -07001031
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001032 return 0;
Miklos Szeredi87729a52005-09-09 13:10:34 -07001033}
1034
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001035static int fuse_access(struct inode *inode, int mask)
1036{
1037 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001038 FUSE_ARGS(args);
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001039 struct fuse_access_in inarg;
1040 int err;
1041
Miklos Szeredi698fa1d2013-10-01 16:41:23 +02001042 BUG_ON(mask & MAY_NOT_BLOCK);
1043
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001044 if (fc->no_access)
1045 return 0;
1046
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001047 memset(&inarg, 0, sizeof(inarg));
Al Viroe6305c42008-07-15 21:03:57 -04001048 inarg.mask = mask & (MAY_READ | MAY_WRITE | MAY_EXEC);
Miklos Szeredi70781872014-12-12 09:49:05 +01001049 args.in.h.opcode = FUSE_ACCESS;
1050 args.in.h.nodeid = get_node_id(inode);
1051 args.in.numargs = 1;
1052 args.in.args[0].size = sizeof(inarg);
1053 args.in.args[0].value = &inarg;
1054 err = fuse_simple_request(fc, &args);
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001055 if (err == -ENOSYS) {
1056 fc->no_access = 1;
1057 err = 0;
1058 }
1059 return err;
1060}
1061
Al Viro10556cb2011-06-20 19:28:19 -04001062static int fuse_perm_getattr(struct inode *inode, int mask)
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001063{
Al Viro10556cb2011-06-20 19:28:19 -04001064 if (mask & MAY_NOT_BLOCK)
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001065 return -ECHILD;
1066
1067 return fuse_do_getattr(inode, NULL, NULL);
1068}
1069
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001070/*
1071 * Check permission. The two basic access models of FUSE are:
1072 *
1073 * 1) Local access checking ('default_permissions' mount option) based
1074 * on file mode. This is the plain old disk filesystem permission
1075 * modell.
1076 *
1077 * 2) "Remote" access checking, where server is responsible for
1078 * checking permission in each inode operation. An exception to this
1079 * is if ->permission() was invoked from sys_access() in which case an
1080 * access request is sent. Execute permission is still checked
1081 * locally based on file mode.
1082 */
Al Viro10556cb2011-06-20 19:28:19 -04001083static int fuse_permission(struct inode *inode, int mask)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001084{
1085 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi244f6382007-10-16 23:31:02 -07001086 bool refreshed = false;
1087 int err = 0;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001088
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001089 if (!fuse_allow_current_process(fc))
Miklos Szeredie5e55582005-09-09 13:10:28 -07001090 return -EACCES;
Miklos Szeredi244f6382007-10-16 23:31:02 -07001091
1092 /*
Miklos Szeredie8e96152007-10-16 23:31:06 -07001093 * If attributes are needed, refresh them before proceeding
Miklos Szeredi244f6382007-10-16 23:31:02 -07001094 */
Miklos Szeredie8e96152007-10-16 23:31:06 -07001095 if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) ||
1096 ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) {
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001097 struct fuse_inode *fi = get_fuse_inode(inode);
1098
Miklos Szeredi126b9d42014-07-07 15:28:50 +02001099 if (time_before64(fi->i_time, get_jiffies_64())) {
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001100 refreshed = true;
1101
Al Viro10556cb2011-06-20 19:28:19 -04001102 err = fuse_perm_getattr(inode, mask);
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001103 if (err)
1104 return err;
1105 }
Miklos Szeredi244f6382007-10-16 23:31:02 -07001106 }
1107
1108 if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
Al Viro2830ba72011-06-20 19:16:29 -04001109 err = generic_permission(inode, mask);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001110
1111 /* If permission is denied, try to refresh file
1112 attributes. This is also needed, because the root
1113 node will at first have no permissions */
Miklos Szeredi244f6382007-10-16 23:31:02 -07001114 if (err == -EACCES && !refreshed) {
Al Viro10556cb2011-06-20 19:28:19 -04001115 err = fuse_perm_getattr(inode, mask);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001116 if (!err)
Al Viro2830ba72011-06-20 19:16:29 -04001117 err = generic_permission(inode, mask);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001118 }
1119
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001120 /* Note: the opposite of the above test does not
1121 exist. So if permissions are revoked this won't be
1122 noticed immediately, only after the attribute
1123 timeout has expired */
Eric Paris9cfcac82010-07-23 11:43:51 -04001124 } else if (mask & (MAY_ACCESS | MAY_CHDIR)) {
Miklos Szeredie8e96152007-10-16 23:31:06 -07001125 err = fuse_access(inode, mask);
1126 } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
1127 if (!(inode->i_mode & S_IXUGO)) {
1128 if (refreshed)
1129 return -EACCES;
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001130
Al Viro10556cb2011-06-20 19:28:19 -04001131 err = fuse_perm_getattr(inode, mask);
Miklos Szeredie8e96152007-10-16 23:31:06 -07001132 if (!err && !(inode->i_mode & S_IXUGO))
1133 return -EACCES;
1134 }
Miklos Szeredie5e55582005-09-09 13:10:28 -07001135 }
Miklos Szeredi244f6382007-10-16 23:31:02 -07001136 return err;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001137}
1138
1139static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
Al Viro8d3af7f2013-05-18 03:03:58 -04001140 struct dir_context *ctx)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001141{
1142 while (nbytes >= FUSE_NAME_OFFSET) {
1143 struct fuse_dirent *dirent = (struct fuse_dirent *) buf;
1144 size_t reclen = FUSE_DIRENT_SIZE(dirent);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001145 if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
1146 return -EIO;
1147 if (reclen > nbytes)
1148 break;
Miklos Szerediefeb9e62013-09-03 14:28:38 +02001149 if (memchr(dirent->name, '/', dirent->namelen) != NULL)
1150 return -EIO;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001151
Al Viro8d3af7f2013-05-18 03:03:58 -04001152 if (!dir_emit(ctx, dirent->name, dirent->namelen,
1153 dirent->ino, dirent->type))
Miklos Szeredie5e55582005-09-09 13:10:28 -07001154 break;
1155
1156 buf += reclen;
1157 nbytes -= reclen;
Al Viro8d3af7f2013-05-18 03:03:58 -04001158 ctx->pos = dirent->off;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001159 }
1160
1161 return 0;
1162}
1163
Anand V. Avati0b05b182012-08-19 08:53:23 -04001164static int fuse_direntplus_link(struct file *file,
1165 struct fuse_direntplus *direntplus,
1166 u64 attr_version)
1167{
Anand V. Avati0b05b182012-08-19 08:53:23 -04001168 struct fuse_entry_out *o = &direntplus->entry_out;
1169 struct fuse_dirent *dirent = &direntplus->dirent;
1170 struct dentry *parent = file->f_path.dentry;
1171 struct qstr name = QSTR_INIT(dirent->name, dirent->namelen);
1172 struct dentry *dentry;
1173 struct dentry *alias;
David Howells2b0143b2015-03-17 22:25:59 +00001174 struct inode *dir = d_inode(parent);
Anand V. Avati0b05b182012-08-19 08:53:23 -04001175 struct fuse_conn *fc;
1176 struct inode *inode;
Al Virod9b3dbd2016-04-20 17:30:32 -04001177 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
Anand V. Avati0b05b182012-08-19 08:53:23 -04001178
1179 if (!o->nodeid) {
1180 /*
1181 * Unlike in the case of fuse_lookup, zero nodeid does not mean
1182 * ENOENT. Instead, it only means the userspace filesystem did
1183 * not want to return attributes/handle for this entry.
1184 *
1185 * So do nothing.
1186 */
1187 return 0;
1188 }
1189
1190 if (name.name[0] == '.') {
1191 /*
1192 * We could potentially refresh the attributes of the directory
1193 * and its parent?
1194 */
1195 if (name.len == 1)
1196 return 0;
1197 if (name.name[1] == '.' && name.len == 2)
1198 return 0;
1199 }
Miklos Szeredia28ef452013-07-17 14:53:53 +02001200
1201 if (invalid_nodeid(o->nodeid))
1202 return -EIO;
1203 if (!fuse_valid_type(o->attr.mode))
1204 return -EIO;
1205
Anand V. Avati0b05b182012-08-19 08:53:23 -04001206 fc = get_fuse_conn(dir);
1207
Linus Torvalds8387ff22016-06-10 07:51:30 -07001208 name.hash = full_name_hash(parent, name.name, name.len);
Anand V. Avati0b05b182012-08-19 08:53:23 -04001209 dentry = d_lookup(parent, &name);
Al Virod9b3dbd2016-04-20 17:30:32 -04001210 if (!dentry) {
1211retry:
1212 dentry = d_alloc_parallel(parent, &name, &wq);
1213 if (IS_ERR(dentry))
1214 return PTR_ERR(dentry);
1215 }
1216 if (!d_in_lookup(dentry)) {
1217 struct fuse_inode *fi;
David Howells2b0143b2015-03-17 22:25:59 +00001218 inode = d_inode(dentry);
Al Virod9b3dbd2016-04-20 17:30:32 -04001219 if (!inode ||
1220 get_node_id(inode) != o->nodeid ||
1221 ((o->attr.mode ^ inode->i_mode) & S_IFMT)) {
Eric W. Biederman5542aa22014-02-13 09:46:25 -08001222 d_invalidate(dentry);
Al Virod9b3dbd2016-04-20 17:30:32 -04001223 dput(dentry);
1224 goto retry;
Anand V. Avati0b05b182012-08-19 08:53:23 -04001225 }
Al Virod9b3dbd2016-04-20 17:30:32 -04001226 if (is_bad_inode(inode)) {
1227 dput(dentry);
1228 return -EIO;
1229 }
1230
1231 fi = get_fuse_inode(inode);
1232 spin_lock(&fc->lock);
1233 fi->nlookup++;
1234 spin_unlock(&fc->lock);
1235
1236 fuse_change_attributes(inode, &o->attr,
1237 entry_attr_timeout(o),
1238 attr_version);
1239 /*
1240 * The other branch comes via fuse_iget()
1241 * which bumps nlookup inside
1242 */
1243 } else {
1244 inode = fuse_iget(dir->i_sb, o->nodeid, o->generation,
1245 &o->attr, entry_attr_timeout(o),
1246 attr_version);
1247 if (!inode)
1248 inode = ERR_PTR(-ENOMEM);
1249
1250 alias = d_splice_alias(inode, dentry);
1251 d_lookup_done(dentry);
1252 if (alias) {
1253 dput(dentry);
1254 dentry = alias;
1255 }
1256 if (IS_ERR(dentry))
1257 return PTR_ERR(dentry);
Anand V. Avati0b05b182012-08-19 08:53:23 -04001258 }
Miklos Szeredi6314efe2013-10-01 16:41:22 +02001259 if (fc->readdirplus_auto)
1260 set_bit(FUSE_I_INIT_RDPLUS, &get_fuse_inode(inode)->state);
Anand V. Avati0b05b182012-08-19 08:53:23 -04001261 fuse_change_entry_timeout(dentry, o);
1262
Miklos Szeredic7263bc2013-07-17 14:53:54 +02001263 dput(dentry);
Al Virod9b3dbd2016-04-20 17:30:32 -04001264 return 0;
Anand V. Avati0b05b182012-08-19 08:53:23 -04001265}
1266
1267static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file,
Al Viro8d3af7f2013-05-18 03:03:58 -04001268 struct dir_context *ctx, u64 attr_version)
Anand V. Avati0b05b182012-08-19 08:53:23 -04001269{
1270 struct fuse_direntplus *direntplus;
1271 struct fuse_dirent *dirent;
1272 size_t reclen;
1273 int over = 0;
1274 int ret;
1275
1276 while (nbytes >= FUSE_NAME_OFFSET_DIRENTPLUS) {
1277 direntplus = (struct fuse_direntplus *) buf;
1278 dirent = &direntplus->dirent;
1279 reclen = FUSE_DIRENTPLUS_SIZE(direntplus);
1280
1281 if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
1282 return -EIO;
1283 if (reclen > nbytes)
1284 break;
Miklos Szerediefeb9e62013-09-03 14:28:38 +02001285 if (memchr(dirent->name, '/', dirent->namelen) != NULL)
1286 return -EIO;
Anand V. Avati0b05b182012-08-19 08:53:23 -04001287
1288 if (!over) {
1289 /* We fill entries into dstbuf only as much as
1290 it can hold. But we still continue iterating
1291 over remaining entries to link them. If not,
1292 we need to send a FORGET for each of those
1293 which we did not link.
1294 */
Al Viro8d3af7f2013-05-18 03:03:58 -04001295 over = !dir_emit(ctx, dirent->name, dirent->namelen,
1296 dirent->ino, dirent->type);
1297 ctx->pos = dirent->off;
Anand V. Avati0b05b182012-08-19 08:53:23 -04001298 }
1299
1300 buf += reclen;
1301 nbytes -= reclen;
1302
1303 ret = fuse_direntplus_link(file, direntplus, attr_version);
1304 if (ret)
1305 fuse_force_forget(file, direntplus->entry_out.nodeid);
1306 }
1307
1308 return 0;
1309}
1310
Al Viro8d3af7f2013-05-18 03:03:58 -04001311static int fuse_readdir(struct file *file, struct dir_context *ctx)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001312{
Feng Shuo4582a4a2013-01-15 11:23:28 +08001313 int plus, err;
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001314 size_t nbytes;
1315 struct page *page;
Al Viro496ad9a2013-01-23 17:07:38 -05001316 struct inode *inode = file_inode(file);
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001317 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi248d86e2006-01-06 00:19:39 -08001318 struct fuse_req *req;
Anand V. Avati0b05b182012-08-19 08:53:23 -04001319 u64 attr_version = 0;
Miklos Szeredi248d86e2006-01-06 00:19:39 -08001320
1321 if (is_bad_inode(inode))
1322 return -EIO;
1323
Maxim Patlasovb111c8c2012-10-26 19:48:30 +04001324 req = fuse_get_req(fc, 1);
Miklos Szeredice1d5a42006-04-10 22:54:58 -07001325 if (IS_ERR(req))
1326 return PTR_ERR(req);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001327
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001328 page = alloc_page(GFP_KERNEL);
1329 if (!page) {
1330 fuse_put_request(fc, req);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001331 return -ENOMEM;
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001332 }
Feng Shuo4582a4a2013-01-15 11:23:28 +08001333
Al Viro8d3af7f2013-05-18 03:03:58 -04001334 plus = fuse_use_readdirplus(inode, ctx);
Miklos Szeredif4975c62009-04-02 14:25:34 +02001335 req->out.argpages = 1;
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001336 req->num_pages = 1;
1337 req->pages[0] = page;
Maxim Patlasov85f40ae2012-10-26 19:49:33 +04001338 req->page_descs[0].length = PAGE_SIZE;
Feng Shuo4582a4a2013-01-15 11:23:28 +08001339 if (plus) {
Anand V. Avati0b05b182012-08-19 08:53:23 -04001340 attr_version = fuse_get_attr_version(fc);
Al Viro8d3af7f2013-05-18 03:03:58 -04001341 fuse_read_fill(req, file, ctx->pos, PAGE_SIZE,
Anand V. Avati0b05b182012-08-19 08:53:23 -04001342 FUSE_READDIRPLUS);
1343 } else {
Al Viro8d3af7f2013-05-18 03:03:58 -04001344 fuse_read_fill(req, file, ctx->pos, PAGE_SIZE,
Anand V. Avati0b05b182012-08-19 08:53:23 -04001345 FUSE_READDIR);
1346 }
Miklos Szeredi5c672ab2016-06-30 13:10:49 +02001347 fuse_lock_inode(inode);
Tejun Heob93f8582008-11-26 12:03:55 +01001348 fuse_request_send(fc, req);
Miklos Szeredi5c672ab2016-06-30 13:10:49 +02001349 fuse_unlock_inode(inode);
Miklos Szeredi361b1eb52006-01-16 22:14:45 -08001350 nbytes = req->out.args[0].size;
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001351 err = req->out.h.error;
1352 fuse_put_request(fc, req);
Anand V. Avati0b05b182012-08-19 08:53:23 -04001353 if (!err) {
Feng Shuo4582a4a2013-01-15 11:23:28 +08001354 if (plus) {
Anand V. Avati0b05b182012-08-19 08:53:23 -04001355 err = parse_dirplusfile(page_address(page), nbytes,
Al Viro8d3af7f2013-05-18 03:03:58 -04001356 file, ctx,
Anand V. Avati0b05b182012-08-19 08:53:23 -04001357 attr_version);
1358 } else {
1359 err = parse_dirfile(page_address(page), nbytes, file,
Al Viro8d3af7f2013-05-18 03:03:58 -04001360 ctx);
Anand V. Avati0b05b182012-08-19 08:53:23 -04001361 }
1362 }
Miklos Szeredie5e55582005-09-09 13:10:28 -07001363
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001364 __free_page(page);
Andrew Gallagher451418f2013-11-05 03:55:43 -08001365 fuse_invalidate_atime(inode);
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001366 return err;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001367}
1368
Al Viro6b255392015-11-17 10:20:54 -05001369static const char *fuse_get_link(struct dentry *dentry,
Al Virofceef392015-12-29 15:58:39 -05001370 struct inode *inode,
1371 struct delayed_call *done)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001372{
Miklos Szeredie5e55582005-09-09 13:10:28 -07001373 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001374 FUSE_ARGS(args);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001375 char *link;
Miklos Szeredi70781872014-12-12 09:49:05 +01001376 ssize_t ret;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001377
Al Viro6b255392015-11-17 10:20:54 -05001378 if (!dentry)
1379 return ERR_PTR(-ECHILD);
1380
Al Virocd3417c2015-12-29 16:03:53 -05001381 link = kmalloc(PAGE_SIZE, GFP_KERNEL);
Miklos Szeredi70781872014-12-12 09:49:05 +01001382 if (!link)
1383 return ERR_PTR(-ENOMEM);
1384
1385 args.in.h.opcode = FUSE_READLINK;
1386 args.in.h.nodeid = get_node_id(inode);
1387 args.out.argvar = 1;
1388 args.out.numargs = 1;
1389 args.out.args[0].size = PAGE_SIZE - 1;
1390 args.out.args[0].value = link;
1391 ret = fuse_simple_request(fc, &args);
1392 if (ret < 0) {
Al Virocd3417c2015-12-29 16:03:53 -05001393 kfree(link);
Miklos Szeredi70781872014-12-12 09:49:05 +01001394 link = ERR_PTR(ret);
1395 } else {
1396 link[ret] = '\0';
Al Virofceef392015-12-29 15:58:39 -05001397 set_delayed_call(done, kfree_link, link);
Miklos Szeredi70781872014-12-12 09:49:05 +01001398 }
Andrew Gallagher451418f2013-11-05 03:55:43 -08001399 fuse_invalidate_atime(inode);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001400 return link;
1401}
1402
Miklos Szeredie5e55582005-09-09 13:10:28 -07001403static int fuse_dir_open(struct inode *inode, struct file *file)
1404{
Miklos Szeredi91fe96b2009-04-28 16:56:37 +02001405 return fuse_open_common(inode, file, true);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001406}
1407
1408static int fuse_dir_release(struct inode *inode, struct file *file)
1409{
Miklos Szeredi8b0797a2009-04-28 16:56:39 +02001410 fuse_release_common(file, FUSE_RELEASEDIR);
1411
1412 return 0;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001413}
1414
Josef Bacik02c24a82011-07-16 20:44:56 -04001415static int fuse_dir_fsync(struct file *file, loff_t start, loff_t end,
1416 int datasync)
Miklos Szeredi82547982005-09-09 13:10:38 -07001417{
Josef Bacik02c24a82011-07-16 20:44:56 -04001418 return fuse_fsync_common(file, start, end, datasync, 1);
Miklos Szeredi82547982005-09-09 13:10:38 -07001419}
1420
Miklos Szeredib18da0c2011-12-13 11:58:49 +01001421static long fuse_dir_ioctl(struct file *file, unsigned int cmd,
1422 unsigned long arg)
1423{
1424 struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1425
1426 /* FUSE_IOCTL_DIR only supported for API version >= 7.18 */
1427 if (fc->minor < 18)
1428 return -ENOTTY;
1429
1430 return fuse_ioctl_common(file, cmd, arg, FUSE_IOCTL_DIR);
1431}
1432
1433static long fuse_dir_compat_ioctl(struct file *file, unsigned int cmd,
1434 unsigned long arg)
1435{
1436 struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1437
1438 if (fc->minor < 18)
1439 return -ENOTTY;
1440
1441 return fuse_ioctl_common(file, cmd, arg,
1442 FUSE_IOCTL_COMPAT | FUSE_IOCTL_DIR);
1443}
1444
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001445static bool update_mtime(unsigned ivalid, bool trust_local_mtime)
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001446{
1447 /* Always update if mtime is explicitly set */
1448 if (ivalid & ATTR_MTIME_SET)
1449 return true;
1450
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001451 /* Or if kernel i_mtime is the official one */
1452 if (trust_local_mtime)
1453 return true;
1454
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001455 /* If it's an open(O_TRUNC) or an ftruncate(), don't update */
1456 if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE)))
1457 return false;
1458
1459 /* In all other cases update */
1460 return true;
1461}
1462
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001463static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg,
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001464 bool trust_local_cmtime)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001465{
1466 unsigned ivalid = iattr->ia_valid;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001467
1468 if (ivalid & ATTR_MODE)
Miklos Szeredibefc6492005-11-07 00:59:52 -08001469 arg->valid |= FATTR_MODE, arg->mode = iattr->ia_mode;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001470 if (ivalid & ATTR_UID)
Eric W. Biederman499dcf22012-02-07 16:26:03 -08001471 arg->valid |= FATTR_UID, arg->uid = from_kuid(&init_user_ns, iattr->ia_uid);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001472 if (ivalid & ATTR_GID)
Eric W. Biederman499dcf22012-02-07 16:26:03 -08001473 arg->valid |= FATTR_GID, arg->gid = from_kgid(&init_user_ns, iattr->ia_gid);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001474 if (ivalid & ATTR_SIZE)
Miklos Szeredibefc6492005-11-07 00:59:52 -08001475 arg->valid |= FATTR_SIZE, arg->size = iattr->ia_size;
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001476 if (ivalid & ATTR_ATIME) {
1477 arg->valid |= FATTR_ATIME;
Miklos Szeredibefc6492005-11-07 00:59:52 -08001478 arg->atime = iattr->ia_atime.tv_sec;
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001479 arg->atimensec = iattr->ia_atime.tv_nsec;
1480 if (!(ivalid & ATTR_ATIME_SET))
1481 arg->valid |= FATTR_ATIME_NOW;
1482 }
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001483 if ((ivalid & ATTR_MTIME) && update_mtime(ivalid, trust_local_cmtime)) {
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001484 arg->valid |= FATTR_MTIME;
Miklos Szeredibefc6492005-11-07 00:59:52 -08001485 arg->mtime = iattr->ia_mtime.tv_sec;
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001486 arg->mtimensec = iattr->ia_mtime.tv_nsec;
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001487 if (!(ivalid & ATTR_MTIME_SET) && !trust_local_cmtime)
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001488 arg->valid |= FATTR_MTIME_NOW;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001489 }
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001490 if ((ivalid & ATTR_CTIME) && trust_local_cmtime) {
1491 arg->valid |= FATTR_CTIME;
1492 arg->ctime = iattr->ia_ctime.tv_sec;
1493 arg->ctimensec = iattr->ia_ctime.tv_nsec;
1494 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001495}
1496
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001497/*
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001498 * Prevent concurrent writepages on inode
1499 *
1500 * This is done by adding a negative bias to the inode write counter
1501 * and waiting for all pending writes to finish.
1502 */
1503void fuse_set_nowrite(struct inode *inode)
1504{
1505 struct fuse_conn *fc = get_fuse_conn(inode);
1506 struct fuse_inode *fi = get_fuse_inode(inode);
1507
Al Viro59551022016-01-22 15:40:57 -05001508 BUG_ON(!inode_is_locked(inode));
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001509
1510 spin_lock(&fc->lock);
1511 BUG_ON(fi->writectr < 0);
1512 fi->writectr += FUSE_NOWRITE;
1513 spin_unlock(&fc->lock);
1514 wait_event(fi->page_waitq, fi->writectr == FUSE_NOWRITE);
1515}
1516
1517/*
1518 * Allow writepages on inode
1519 *
1520 * Remove the bias from the writecounter and send any queued
1521 * writepages.
1522 */
1523static void __fuse_release_nowrite(struct inode *inode)
1524{
1525 struct fuse_inode *fi = get_fuse_inode(inode);
1526
1527 BUG_ON(fi->writectr != FUSE_NOWRITE);
1528 fi->writectr = 0;
1529 fuse_flush_writepages(inode);
1530}
1531
1532void fuse_release_nowrite(struct inode *inode)
1533{
1534 struct fuse_conn *fc = get_fuse_conn(inode);
1535
1536 spin_lock(&fc->lock);
1537 __fuse_release_nowrite(inode);
1538 spin_unlock(&fc->lock);
1539}
1540
Miklos Szeredi70781872014-12-12 09:49:05 +01001541static void fuse_setattr_fill(struct fuse_conn *fc, struct fuse_args *args,
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001542 struct inode *inode,
1543 struct fuse_setattr_in *inarg_p,
1544 struct fuse_attr_out *outarg_p)
1545{
Miklos Szeredi70781872014-12-12 09:49:05 +01001546 args->in.h.opcode = FUSE_SETATTR;
1547 args->in.h.nodeid = get_node_id(inode);
1548 args->in.numargs = 1;
1549 args->in.args[0].size = sizeof(*inarg_p);
1550 args->in.args[0].value = inarg_p;
1551 args->out.numargs = 1;
Miklos Szeredi21f62172015-01-06 10:45:35 +01001552 args->out.args[0].size = sizeof(*outarg_p);
Miklos Szeredi70781872014-12-12 09:49:05 +01001553 args->out.args[0].value = outarg_p;
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001554}
1555
1556/*
1557 * Flush inode->i_mtime to the server
1558 */
Maxim Patlasovab9e13f2014-04-28 14:19:24 +02001559int fuse_flush_times(struct inode *inode, struct fuse_file *ff)
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001560{
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001561 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001562 FUSE_ARGS(args);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001563 struct fuse_setattr_in inarg;
1564 struct fuse_attr_out outarg;
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001565
1566 memset(&inarg, 0, sizeof(inarg));
1567 memset(&outarg, 0, sizeof(outarg));
1568
Maxim Patlasovab9e13f2014-04-28 14:19:24 +02001569 inarg.valid = FATTR_MTIME;
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001570 inarg.mtime = inode->i_mtime.tv_sec;
1571 inarg.mtimensec = inode->i_mtime.tv_nsec;
Maxim Patlasovab9e13f2014-04-28 14:19:24 +02001572 if (fc->minor >= 23) {
1573 inarg.valid |= FATTR_CTIME;
1574 inarg.ctime = inode->i_ctime.tv_sec;
1575 inarg.ctimensec = inode->i_ctime.tv_nsec;
1576 }
Miklos Szeredi1e18bda2014-04-28 14:19:23 +02001577 if (ff) {
1578 inarg.valid |= FATTR_FH;
1579 inarg.fh = ff->fh;
1580 }
Miklos Szeredi70781872014-12-12 09:49:05 +01001581 fuse_setattr_fill(fc, &args, inode, &inarg, &outarg);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001582
Miklos Szeredi70781872014-12-12 09:49:05 +01001583 return fuse_simple_request(fc, &args);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001584}
1585
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001586/*
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001587 * Set attributes, and at the same time refresh them.
1588 *
1589 * Truncation is slightly complicated, because the 'truncate' request
1590 * may fail, in which case we don't want to touch the mapping.
Miklos Szeredi9ffbb912006-10-17 00:10:06 -07001591 * vmtruncate() doesn't allow for this case, so do the rlimit checking
1592 * and the actual truncation by hand.
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001593 */
Maxim Patlasovefb9fa92012-12-18 14:05:08 +04001594int fuse_do_setattr(struct inode *inode, struct iattr *attr,
1595 struct file *file)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001596{
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001597 struct fuse_conn *fc = get_fuse_conn(inode);
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001598 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001599 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001600 struct fuse_setattr_in inarg;
1601 struct fuse_attr_out outarg;
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001602 bool is_truncate = false;
Pavel Emelyanov83732002013-10-10 17:10:46 +04001603 bool is_wb = fc->writeback_cache;
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001604 loff_t oldsize;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001605 int err;
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001606 bool trust_local_cmtime = is_wb && S_ISREG(inode->i_mode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001607
Christoph Hellwigdb78b872010-06-04 11:30:03 +02001608 if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS))
1609 attr->ia_valid |= ATTR_FORCE;
1610
1611 err = inode_change_ok(inode, attr);
1612 if (err)
1613 return err;
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001614
Miklos Szeredi8d56add2011-02-25 14:44:58 +01001615 if (attr->ia_valid & ATTR_OPEN) {
1616 if (fc->atomic_o_trunc)
1617 return 0;
1618 file = NULL;
1619 }
Miklos Szeredi6ff958e2007-10-18 03:07:02 -07001620
Christoph Hellwig2c27c652010-06-04 11:30:04 +02001621 if (attr->ia_valid & ATTR_SIZE)
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001622 is_truncate = true;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001623
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001624 if (is_truncate) {
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001625 fuse_set_nowrite(inode);
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001626 set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001627 if (trust_local_cmtime && attr->ia_size != inode->i_size)
1628 attr->ia_valid |= ATTR_MTIME | ATTR_CTIME;
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001629 }
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001630
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001631 memset(&inarg, 0, sizeof(inarg));
Miklos Szeredi0e9663e2007-10-18 03:07:05 -07001632 memset(&outarg, 0, sizeof(outarg));
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001633 iattr_to_fattr(attr, &inarg, trust_local_cmtime);
Miklos Szeredi49d49142007-10-18 03:07:00 -07001634 if (file) {
1635 struct fuse_file *ff = file->private_data;
1636 inarg.valid |= FATTR_FH;
1637 inarg.fh = ff->fh;
1638 }
Miklos Szeredif3332112007-10-18 03:07:04 -07001639 if (attr->ia_valid & ATTR_SIZE) {
1640 /* For mandatory locking in truncate */
1641 inarg.valid |= FATTR_LOCKOWNER;
1642 inarg.lock_owner = fuse_lock_owner_id(fc, current->files);
1643 }
Miklos Szeredi70781872014-12-12 09:49:05 +01001644 fuse_setattr_fill(fc, &args, inode, &inarg, &outarg);
1645 err = fuse_simple_request(fc, &args);
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001646 if (err) {
1647 if (err == -EINTR)
1648 fuse_invalidate_attr(inode);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001649 goto error;
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001650 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001651
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001652 if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
1653 make_bad_inode(inode);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001654 err = -EIO;
1655 goto error;
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001656 }
1657
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001658 spin_lock(&fc->lock);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001659 /* the kernel maintains i_mtime locally */
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001660 if (trust_local_cmtime) {
1661 if (attr->ia_valid & ATTR_MTIME)
1662 inode->i_mtime = attr->ia_mtime;
1663 if (attr->ia_valid & ATTR_CTIME)
1664 inode->i_ctime = attr->ia_ctime;
Miklos Szeredi1e18bda2014-04-28 14:19:23 +02001665 /* FIXME: clear I_DIRTY_SYNC? */
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001666 }
1667
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001668 fuse_change_attributes_common(inode, &outarg.attr,
1669 attr_timeout(&outarg));
1670 oldsize = inode->i_size;
Pavel Emelyanov83732002013-10-10 17:10:46 +04001671 /* see the comment in fuse_change_attributes() */
1672 if (!is_wb || is_truncate || !S_ISREG(inode->i_mode))
1673 i_size_write(inode, outarg.attr.size);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001674
1675 if (is_truncate) {
1676 /* NOTE: this may release/reacquire fc->lock */
1677 __fuse_release_nowrite(inode);
1678 }
1679 spin_unlock(&fc->lock);
1680
1681 /*
1682 * Only call invalidate_inode_pages2() after removing
1683 * FUSE_NOWRITE, otherwise fuse_launder_page() would deadlock.
1684 */
Pavel Emelyanov83732002013-10-10 17:10:46 +04001685 if ((is_truncate || !is_wb) &&
1686 S_ISREG(inode->i_mode) && oldsize != outarg.attr.size) {
Kirill A. Shutemov7caef262013-09-12 15:13:56 -07001687 truncate_pagecache(inode, outarg.attr.size);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001688 invalidate_inode_pages2(inode->i_mapping);
1689 }
1690
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001691 clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001692 return 0;
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001693
1694error:
1695 if (is_truncate)
1696 fuse_release_nowrite(inode);
1697
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001698 clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001699 return err;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001700}
1701
Miklos Szeredi49d49142007-10-18 03:07:00 -07001702static int fuse_setattr(struct dentry *entry, struct iattr *attr)
1703{
David Howells2b0143b2015-03-17 22:25:59 +00001704 struct inode *inode = d_inode(entry);
Maxim Patlasovefb9fa92012-12-18 14:05:08 +04001705
1706 if (!fuse_allow_current_process(get_fuse_conn(inode)))
1707 return -EACCES;
1708
Miklos Szeredi49d49142007-10-18 03:07:00 -07001709 if (attr->ia_valid & ATTR_FILE)
Maxim Patlasovefb9fa92012-12-18 14:05:08 +04001710 return fuse_do_setattr(inode, attr, attr->ia_file);
Miklos Szeredi49d49142007-10-18 03:07:00 -07001711 else
Maxim Patlasovefb9fa92012-12-18 14:05:08 +04001712 return fuse_do_setattr(inode, attr, NULL);
Miklos Szeredi49d49142007-10-18 03:07:00 -07001713}
1714
Miklos Szeredie5e55582005-09-09 13:10:28 -07001715static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
1716 struct kstat *stat)
1717{
David Howells2b0143b2015-03-17 22:25:59 +00001718 struct inode *inode = d_inode(entry);
Miklos Szeredi244f6382007-10-16 23:31:02 -07001719 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi244f6382007-10-16 23:31:02 -07001720
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001721 if (!fuse_allow_current_process(fc))
Miklos Szeredi244f6382007-10-16 23:31:02 -07001722 return -EACCES;
1723
Miklos Szeredibcb4be82007-11-28 16:21:59 -08001724 return fuse_update_attributes(inode, stat, NULL, NULL);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001725}
1726
Al Viro3767e252016-05-27 11:06:05 -04001727static int fuse_setxattr(struct dentry *unused, struct inode *inode,
1728 const char *name, const void *value,
1729 size_t size, int flags)
Miklos Szeredi92a87802005-09-09 13:10:31 -07001730{
Miklos Szeredi92a87802005-09-09 13:10:31 -07001731 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001732 FUSE_ARGS(args);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001733 struct fuse_setxattr_in inarg;
1734 int err;
1735
Miklos Szeredi92a87802005-09-09 13:10:31 -07001736 if (fc->no_setxattr)
1737 return -EOPNOTSUPP;
1738
Miklos Szeredi92a87802005-09-09 13:10:31 -07001739 memset(&inarg, 0, sizeof(inarg));
1740 inarg.size = size;
1741 inarg.flags = flags;
Miklos Szeredi70781872014-12-12 09:49:05 +01001742 args.in.h.opcode = FUSE_SETXATTR;
1743 args.in.h.nodeid = get_node_id(inode);
1744 args.in.numargs = 3;
1745 args.in.args[0].size = sizeof(inarg);
1746 args.in.args[0].value = &inarg;
1747 args.in.args[1].size = strlen(name) + 1;
1748 args.in.args[1].value = name;
1749 args.in.args[2].size = size;
1750 args.in.args[2].value = value;
1751 err = fuse_simple_request(fc, &args);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001752 if (err == -ENOSYS) {
1753 fc->no_setxattr = 1;
1754 err = -EOPNOTSUPP;
1755 }
Maxim Patlasov31f32672014-04-28 14:19:24 +02001756 if (!err) {
Anand Avatid331a412013-08-20 02:21:07 -04001757 fuse_invalidate_attr(inode);
Maxim Patlasov31f32672014-04-28 14:19:24 +02001758 fuse_update_ctime(inode);
1759 }
Miklos Szeredi92a87802005-09-09 13:10:31 -07001760 return err;
1761}
1762
Al Viroce23e642016-04-11 00:48:00 -04001763static ssize_t fuse_getxattr(struct dentry *entry, struct inode *inode,
1764 const char *name, void *value, size_t size)
Miklos Szeredi92a87802005-09-09 13:10:31 -07001765{
Miklos Szeredi92a87802005-09-09 13:10:31 -07001766 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001767 FUSE_ARGS(args);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001768 struct fuse_getxattr_in inarg;
1769 struct fuse_getxattr_out outarg;
1770 ssize_t ret;
1771
1772 if (fc->no_getxattr)
1773 return -EOPNOTSUPP;
1774
Miklos Szeredi92a87802005-09-09 13:10:31 -07001775 memset(&inarg, 0, sizeof(inarg));
1776 inarg.size = size;
Miklos Szeredi70781872014-12-12 09:49:05 +01001777 args.in.h.opcode = FUSE_GETXATTR;
1778 args.in.h.nodeid = get_node_id(inode);
1779 args.in.numargs = 2;
1780 args.in.args[0].size = sizeof(inarg);
1781 args.in.args[0].value = &inarg;
1782 args.in.args[1].size = strlen(name) + 1;
1783 args.in.args[1].value = name;
Miklos Szeredi92a87802005-09-09 13:10:31 -07001784 /* This is really two different operations rolled into one */
Miklos Szeredi70781872014-12-12 09:49:05 +01001785 args.out.numargs = 1;
Miklos Szeredi92a87802005-09-09 13:10:31 -07001786 if (size) {
Miklos Szeredi70781872014-12-12 09:49:05 +01001787 args.out.argvar = 1;
1788 args.out.args[0].size = size;
1789 args.out.args[0].value = value;
Miklos Szeredi92a87802005-09-09 13:10:31 -07001790 } else {
Miklos Szeredi70781872014-12-12 09:49:05 +01001791 args.out.args[0].size = sizeof(outarg);
1792 args.out.args[0].value = &outarg;
Miklos Szeredi92a87802005-09-09 13:10:31 -07001793 }
Miklos Szeredi70781872014-12-12 09:49:05 +01001794 ret = fuse_simple_request(fc, &args);
1795 if (!ret && !size)
1796 ret = outarg.size;
1797 if (ret == -ENOSYS) {
1798 fc->no_getxattr = 1;
1799 ret = -EOPNOTSUPP;
Miklos Szeredi92a87802005-09-09 13:10:31 -07001800 }
Miklos Szeredi92a87802005-09-09 13:10:31 -07001801 return ret;
1802}
1803
1804static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
1805{
David Howells2b0143b2015-03-17 22:25:59 +00001806 struct inode *inode = d_inode(entry);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001807 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001808 FUSE_ARGS(args);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001809 struct fuse_getxattr_in inarg;
1810 struct fuse_getxattr_out outarg;
1811 ssize_t ret;
1812
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001813 if (!fuse_allow_current_process(fc))
Miklos Szeredie57ac682007-10-18 03:06:58 -07001814 return -EACCES;
1815
Miklos Szeredi92a87802005-09-09 13:10:31 -07001816 if (fc->no_listxattr)
1817 return -EOPNOTSUPP;
1818
Miklos Szeredi92a87802005-09-09 13:10:31 -07001819 memset(&inarg, 0, sizeof(inarg));
1820 inarg.size = size;
Miklos Szeredi70781872014-12-12 09:49:05 +01001821 args.in.h.opcode = FUSE_LISTXATTR;
1822 args.in.h.nodeid = get_node_id(inode);
1823 args.in.numargs = 1;
1824 args.in.args[0].size = sizeof(inarg);
1825 args.in.args[0].value = &inarg;
Miklos Szeredi92a87802005-09-09 13:10:31 -07001826 /* This is really two different operations rolled into one */
Miklos Szeredi70781872014-12-12 09:49:05 +01001827 args.out.numargs = 1;
Miklos Szeredi92a87802005-09-09 13:10:31 -07001828 if (size) {
Miklos Szeredi70781872014-12-12 09:49:05 +01001829 args.out.argvar = 1;
1830 args.out.args[0].size = size;
1831 args.out.args[0].value = list;
Miklos Szeredi92a87802005-09-09 13:10:31 -07001832 } else {
Miklos Szeredi70781872014-12-12 09:49:05 +01001833 args.out.args[0].size = sizeof(outarg);
1834 args.out.args[0].value = &outarg;
Miklos Szeredi92a87802005-09-09 13:10:31 -07001835 }
Miklos Szeredi70781872014-12-12 09:49:05 +01001836 ret = fuse_simple_request(fc, &args);
1837 if (!ret && !size)
1838 ret = outarg.size;
1839 if (ret == -ENOSYS) {
1840 fc->no_listxattr = 1;
1841 ret = -EOPNOTSUPP;
Miklos Szeredi92a87802005-09-09 13:10:31 -07001842 }
Miklos Szeredi92a87802005-09-09 13:10:31 -07001843 return ret;
1844}
1845
1846static int fuse_removexattr(struct dentry *entry, const char *name)
1847{
David Howells2b0143b2015-03-17 22:25:59 +00001848 struct inode *inode = d_inode(entry);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001849 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001850 FUSE_ARGS(args);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001851 int err;
1852
1853 if (fc->no_removexattr)
1854 return -EOPNOTSUPP;
1855
Miklos Szeredi70781872014-12-12 09:49:05 +01001856 args.in.h.opcode = FUSE_REMOVEXATTR;
1857 args.in.h.nodeid = get_node_id(inode);
1858 args.in.numargs = 1;
1859 args.in.args[0].size = strlen(name) + 1;
1860 args.in.args[0].value = name;
1861 err = fuse_simple_request(fc, &args);
Miklos Szeredi92a87802005-09-09 13:10:31 -07001862 if (err == -ENOSYS) {
1863 fc->no_removexattr = 1;
1864 err = -EOPNOTSUPP;
1865 }
Maxim Patlasov31f32672014-04-28 14:19:24 +02001866 if (!err) {
Anand Avatid331a412013-08-20 02:21:07 -04001867 fuse_invalidate_attr(inode);
Maxim Patlasov31f32672014-04-28 14:19:24 +02001868 fuse_update_ctime(inode);
1869 }
Miklos Szeredi92a87802005-09-09 13:10:31 -07001870 return err;
1871}
1872
Arjan van de Ven754661f2007-02-12 00:55:38 -08001873static const struct inode_operations fuse_dir_inode_operations = {
Miklos Szeredie5e55582005-09-09 13:10:28 -07001874 .lookup = fuse_lookup,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001875 .mkdir = fuse_mkdir,
1876 .symlink = fuse_symlink,
1877 .unlink = fuse_unlink,
1878 .rmdir = fuse_rmdir,
Miklos Szeredi2773bf02016-09-27 11:03:58 +02001879 .rename = fuse_rename2,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001880 .link = fuse_link,
1881 .setattr = fuse_setattr,
1882 .create = fuse_create,
Miklos Szeredic8ccbe02012-06-05 15:10:22 +02001883 .atomic_open = fuse_atomic_open,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001884 .mknod = fuse_mknod,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001885 .permission = fuse_permission,
1886 .getattr = fuse_getattr,
Miklos Szeredi92a87802005-09-09 13:10:31 -07001887 .setxattr = fuse_setxattr,
1888 .getxattr = fuse_getxattr,
1889 .listxattr = fuse_listxattr,
1890 .removexattr = fuse_removexattr,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001891};
1892
Arjan van de Ven4b6f5d22006-03-28 01:56:42 -08001893static const struct file_operations fuse_dir_operations = {
Miklos Szeredib6aeade2005-09-09 13:10:30 -07001894 .llseek = generic_file_llseek,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001895 .read = generic_read_dir,
Al Virod9b3dbd2016-04-20 17:30:32 -04001896 .iterate_shared = fuse_readdir,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001897 .open = fuse_dir_open,
1898 .release = fuse_dir_release,
Miklos Szeredi82547982005-09-09 13:10:38 -07001899 .fsync = fuse_dir_fsync,
Miklos Szeredib18da0c2011-12-13 11:58:49 +01001900 .unlocked_ioctl = fuse_dir_ioctl,
1901 .compat_ioctl = fuse_dir_compat_ioctl,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001902};
1903
Arjan van de Ven754661f2007-02-12 00:55:38 -08001904static const struct inode_operations fuse_common_inode_operations = {
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001905 .setattr = fuse_setattr,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001906 .permission = fuse_permission,
1907 .getattr = fuse_getattr,
Miklos Szeredi92a87802005-09-09 13:10:31 -07001908 .setxattr = fuse_setxattr,
1909 .getxattr = fuse_getxattr,
1910 .listxattr = fuse_listxattr,
1911 .removexattr = fuse_removexattr,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001912};
1913
Arjan van de Ven754661f2007-02-12 00:55:38 -08001914static const struct inode_operations fuse_symlink_inode_operations = {
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001915 .setattr = fuse_setattr,
Al Viro6b255392015-11-17 10:20:54 -05001916 .get_link = fuse_get_link,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001917 .readlink = generic_readlink,
1918 .getattr = fuse_getattr,
Miklos Szeredi92a87802005-09-09 13:10:31 -07001919 .setxattr = fuse_setxattr,
1920 .getxattr = fuse_getxattr,
1921 .listxattr = fuse_listxattr,
1922 .removexattr = fuse_removexattr,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001923};
1924
1925void fuse_init_common(struct inode *inode)
1926{
1927 inode->i_op = &fuse_common_inode_operations;
1928}
1929
1930void fuse_init_dir(struct inode *inode)
1931{
1932 inode->i_op = &fuse_dir_inode_operations;
1933 inode->i_fop = &fuse_dir_operations;
1934}
1935
1936void fuse_init_symlink(struct inode *inode)
1937{
1938 inode->i_op = &fuse_symlink_inode_operations;
1939}