blob: 56231b31f806b10a15d86006b0686312b5be2cb2 [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>
Seth Forshee703c7362016-08-29 08:46:36 -050016#include <linux/xattr.h>
Seth Forshee60bcc882016-08-29 08:46:37 -050017#include <linux/posix_acl.h>
Miklos Szeredie5e55582005-09-09 13:10:28 -070018
Al Viro8d3af7f2013-05-18 03:03:58 -040019static bool fuse_use_readdirplus(struct inode *dir, struct dir_context *ctx)
Feng Shuo4582a4a2013-01-15 11:23:28 +080020{
21 struct fuse_conn *fc = get_fuse_conn(dir);
22 struct fuse_inode *fi = get_fuse_inode(dir);
23
24 if (!fc->do_readdirplus)
25 return false;
Eric Wong634734b2013-02-06 22:29:01 +000026 if (!fc->readdirplus_auto)
27 return true;
Feng Shuo4582a4a2013-01-15 11:23:28 +080028 if (test_and_clear_bit(FUSE_I_ADVISE_RDPLUS, &fi->state))
29 return true;
Al Viro8d3af7f2013-05-18 03:03:58 -040030 if (ctx->pos == 0)
Feng Shuo4582a4a2013-01-15 11:23:28 +080031 return true;
32 return false;
33}
34
35static void fuse_advise_use_readdirplus(struct inode *dir)
36{
37 struct fuse_inode *fi = get_fuse_inode(dir);
38
39 set_bit(FUSE_I_ADVISE_RDPLUS, &fi->state);
40}
41
Miklos Szeredif75fdf22016-10-01 07:32:32 +020042union fuse_dentry {
43 u64 time;
44 struct rcu_head rcu;
45};
46
Miklos Szeredi0a0898c2006-07-30 03:04:10 -070047static inline void fuse_dentry_settime(struct dentry *entry, u64 time)
48{
Miklos Szeredif75fdf22016-10-01 07:32:32 +020049 ((union fuse_dentry *) entry->d_fsdata)->time = time;
Miklos Szeredi0a0898c2006-07-30 03:04:10 -070050}
51
52static inline u64 fuse_dentry_time(struct dentry *entry)
53{
Miklos Szeredif75fdf22016-10-01 07:32:32 +020054 return ((union fuse_dentry *) entry->d_fsdata)->time;
Miklos Szeredi0a0898c2006-07-30 03:04:10 -070055}
Miklos Szeredi0a0898c2006-07-30 03:04:10 -070056
Miklos Szeredi6f9f1182006-01-06 00:19:39 -080057/*
58 * FUSE caches dentries and attributes with separate timeout. The
59 * time in jiffies until the dentry/attributes are valid is stored in
Miklos Szeredif75fdf22016-10-01 07:32:32 +020060 * dentry->d_fsdata and fuse_inode->i_time respectively.
Miklos Szeredi6f9f1182006-01-06 00:19:39 -080061 */
62
63/*
64 * Calculate the time in jiffies until a dentry/attributes are valid
65 */
Miklos Szeredibcb6f6d2016-10-01 07:32:32 +020066static u64 time_to_jiffies(u64 sec, u32 nsec)
Miklos Szeredie5e55582005-09-09 13:10:28 -070067{
Miklos Szeredi685d16d2006-07-30 03:04:08 -070068 if (sec || nsec) {
Miklos Szeredibcb6f6d2016-10-01 07:32:32 +020069 struct timespec64 ts = {
70 sec,
David Sheets21067522017-01-13 15:58:30 +000071 min_t(u32, nsec, NSEC_PER_SEC - 1)
Miklos Szeredibcb6f6d2016-10-01 07:32:32 +020072 };
73
74 return get_jiffies_64() + timespec64_to_jiffies(&ts);
Miklos Szeredi685d16d2006-07-30 03:04:08 -070075 } else
Miklos Szeredi0a0898c2006-07-30 03:04:10 -070076 return 0;
Miklos Szeredie5e55582005-09-09 13:10:28 -070077}
78
Miklos Szeredi6f9f1182006-01-06 00:19:39 -080079/*
80 * Set dentry and possibly attribute timeouts from the lookup/mk*
81 * replies
82 */
Miklos Szeredi1fb69e72007-10-18 03:06:58 -070083static void fuse_change_entry_timeout(struct dentry *entry,
84 struct fuse_entry_out *o)
Miklos Szeredi0aa7c692006-01-06 00:19:34 -080085{
Miklos Szeredi0a0898c2006-07-30 03:04:10 -070086 fuse_dentry_settime(entry,
87 time_to_jiffies(o->entry_valid, o->entry_valid_nsec));
Miklos Szeredi1fb69e72007-10-18 03:06:58 -070088}
89
90static u64 attr_timeout(struct fuse_attr_out *o)
91{
92 return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
93}
94
95static u64 entry_attr_timeout(struct fuse_entry_out *o)
96{
97 return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -080098}
99
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800100/*
101 * Mark the attributes as stale, so that at the next call to
102 * ->getattr() they will be fetched from userspace
103 */
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800104void fuse_invalidate_attr(struct inode *inode)
105{
Miklos Szeredi0a0898c2006-07-30 03:04:10 -0700106 get_fuse_inode(inode)->i_time = 0;
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800107}
108
Andrew Gallagher451418f2013-11-05 03:55:43 -0800109/**
110 * Mark the attributes as stale due to an atime change. Avoid the invalidate if
111 * atime is not used.
112 */
113void fuse_invalidate_atime(struct inode *inode)
114{
115 if (!IS_RDONLY(inode))
116 fuse_invalidate_attr(inode);
117}
118
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800119/*
120 * Just mark the entry as stale, so that a next attempt to look it up
121 * will result in a new lookup call to userspace
122 *
123 * This is called when a dentry is about to become negative and the
124 * timeout is unknown (unlink, rmdir, rename and in some cases
125 * lookup)
126 */
Miklos Szeredidbd561d2008-07-25 01:49:00 -0700127void fuse_invalidate_entry_cache(struct dentry *entry)
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800128{
Miklos Szeredi0a0898c2006-07-30 03:04:10 -0700129 fuse_dentry_settime(entry, 0);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800130}
131
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800132/*
133 * Same as fuse_invalidate_entry_cache(), but also try to remove the
134 * dentry from the hash
135 */
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800136static void fuse_invalidate_entry(struct dentry *entry)
137{
138 d_invalidate(entry);
139 fuse_invalidate_entry_cache(entry);
Miklos Szeredi0aa7c692006-01-06 00:19:34 -0800140}
141
Miklos Szeredi70781872014-12-12 09:49:05 +0100142static void fuse_lookup_init(struct fuse_conn *fc, struct fuse_args *args,
Al Viro13983d02016-07-20 22:34:44 -0400143 u64 nodeid, const struct qstr *name,
Miklos Szeredie5e55582005-09-09 13:10:28 -0700144 struct fuse_entry_out *outarg)
145{
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700146 memset(outarg, 0, sizeof(struct fuse_entry_out));
Miklos Szeredi70781872014-12-12 09:49:05 +0100147 args->in.h.opcode = FUSE_LOOKUP;
148 args->in.h.nodeid = nodeid;
149 args->in.numargs = 1;
150 args->in.args[0].size = name->len + 1;
151 args->in.args[0].value = name->name;
152 args->out.numargs = 1;
Miklos Szeredi21f62172015-01-06 10:45:35 +0100153 args->out.args[0].size = sizeof(struct fuse_entry_out);
Miklos Szeredi70781872014-12-12 09:49:05 +0100154 args->out.args[0].value = outarg;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700155}
156
Miklos Szeredi5c5c5e52008-04-30 00:54:43 -0700157u64 fuse_get_attr_version(struct fuse_conn *fc)
Miklos Szeredi7dca9fd2007-11-28 16:21:59 -0800158{
159 u64 curr_version;
160
161 /*
162 * The spin lock isn't actually needed on 64bit archs, but we
163 * don't yet care too much about such optimizations.
164 */
165 spin_lock(&fc->lock);
166 curr_version = fc->attr_version;
167 spin_unlock(&fc->lock);
168
169 return curr_version;
170}
171
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800172/*
173 * Check whether the dentry is still valid
174 *
175 * If the entry validity timeout has expired and the dentry is
176 * positive, try to redo the lookup. If the lookup results in a
177 * different inode, then let the VFS invalidate the dentry and redo
178 * the lookup once more. If the lookup results in the same inode,
179 * then refresh the attributes, timeouts and mark the dentry valid.
180 */
Al Viro0b728e12012-06-10 16:03:43 -0400181static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
Miklos Szeredie5e55582005-09-09 13:10:28 -0700182{
Nick Piggin34286d62011-01-07 17:49:57 +1100183 struct inode *inode;
Miklos Szeredi28420da2013-06-03 14:40:22 +0200184 struct dentry *parent;
185 struct fuse_conn *fc;
Miklos Szeredi6314efe2013-10-01 16:41:22 +0200186 struct fuse_inode *fi;
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200187 int ret;
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800188
David Howells2b0143b2015-03-17 22:25:59 +0000189 inode = d_inode_rcu(entry);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800190 if (inode && is_bad_inode(inode))
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200191 goto invalid;
Anand Avati154210c2014-06-26 20:21:57 -0400192 else if (time_before64(fuse_dentry_time(entry), get_jiffies_64()) ||
193 (flags & LOOKUP_REVAL)) {
Miklos Szeredie5e55582005-09-09 13:10:28 -0700194 struct fuse_entry_out outarg;
Miklos Szeredi70781872014-12-12 09:49:05 +0100195 FUSE_ARGS(args);
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100196 struct fuse_forget_link *forget;
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700197 u64 attr_version;
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800198
Miklos Szeredi50322fe2006-02-28 16:59:03 -0800199 /* For negative dentries, always do a fresh lookup */
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800200 if (!inode)
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200201 goto invalid;
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800202
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200203 ret = -ECHILD;
Al Viro0b728e12012-06-10 16:03:43 -0400204 if (flags & LOOKUP_RCU)
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200205 goto out;
Miklos Szeredie7c0a162011-03-21 13:58:06 +0100206
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800207 fc = get_fuse_conn(inode);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700208
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100209 forget = fuse_alloc_forget();
Miklos Szeredi70781872014-12-12 09:49:05 +0100210 ret = -ENOMEM;
211 if (!forget)
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200212 goto out;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800213
Miklos Szeredi7dca9fd2007-11-28 16:21:59 -0800214 attr_version = fuse_get_attr_version(fc);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700215
Miklos Szeredie956edd2006-10-17 00:10:12 -0700216 parent = dget_parent(entry);
David Howells2b0143b2015-03-17 22:25:59 +0000217 fuse_lookup_init(fc, &args, get_node_id(d_inode(parent)),
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700218 &entry->d_name, &outarg);
Miklos Szeredi70781872014-12-12 09:49:05 +0100219 ret = fuse_simple_request(fc, &args);
Miklos Szeredie956edd2006-10-17 00:10:12 -0700220 dput(parent);
Miklos Szeredi50322fe2006-02-28 16:59:03 -0800221 /* Zero nodeid is same as -ENOENT */
Miklos Szeredi70781872014-12-12 09:49:05 +0100222 if (!ret && !outarg.nodeid)
223 ret = -ENOENT;
224 if (!ret) {
Miklos Szeredi6314efe2013-10-01 16:41:22 +0200225 fi = get_fuse_inode(inode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700226 if (outarg.nodeid != get_node_id(inode)) {
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100227 fuse_queue_forget(fc, forget, outarg.nodeid, 1);
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200228 goto invalid;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700229 }
Miklos Szeredi8da5ff22006-10-17 00:10:08 -0700230 spin_lock(&fc->lock);
Miklos Szeredi1729a162008-11-26 12:03:54 +0100231 fi->nlookup++;
Miklos Szeredi8da5ff22006-10-17 00:10:08 -0700232 spin_unlock(&fc->lock);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700233 }
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100234 kfree(forget);
Miklos Szeredi70781872014-12-12 09:49:05 +0100235 if (ret == -ENOMEM)
236 goto out;
237 if (ret || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200238 goto invalid;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700239
Seth Forshee60bcc882016-08-29 08:46:37 -0500240 forget_all_cached_acls(inode);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700241 fuse_change_attributes(inode, &outarg.attr,
242 entry_attr_timeout(&outarg),
243 attr_version);
244 fuse_change_entry_timeout(entry, &outarg);
Miklos Szeredi28420da2013-06-03 14:40:22 +0200245 } else if (inode) {
Miklos Szeredi6314efe2013-10-01 16:41:22 +0200246 fi = get_fuse_inode(inode);
247 if (flags & LOOKUP_RCU) {
248 if (test_bit(FUSE_I_INIT_RDPLUS, &fi->state))
249 return -ECHILD;
250 } else if (test_and_clear_bit(FUSE_I_INIT_RDPLUS, &fi->state)) {
Miklos Szeredi28420da2013-06-03 14:40:22 +0200251 parent = dget_parent(entry);
David Howells2b0143b2015-03-17 22:25:59 +0000252 fuse_advise_use_readdirplus(d_inode(parent));
Miklos Szeredi28420da2013-06-03 14:40:22 +0200253 dput(parent);
254 }
Miklos Szeredie5e55582005-09-09 13:10:28 -0700255 }
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200256 ret = 1;
257out:
258 return ret;
259
260invalid:
261 ret = 0;
262 goto out;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700263}
264
Miklos Szeredi8bfc0162006-01-16 22:14:28 -0800265static int invalid_nodeid(u64 nodeid)
Miklos Szeredi2827d0b22005-11-28 13:44:16 -0800266{
267 return !nodeid || nodeid == FUSE_ROOT_ID;
268}
269
Miklos Szeredif75fdf22016-10-01 07:32:32 +0200270static int fuse_dentry_init(struct dentry *dentry)
271{
272 dentry->d_fsdata = kzalloc(sizeof(union fuse_dentry), GFP_KERNEL);
273
274 return dentry->d_fsdata ? 0 : -ENOMEM;
275}
276static void fuse_dentry_release(struct dentry *dentry)
277{
278 union fuse_dentry *fd = dentry->d_fsdata;
279
280 kfree_rcu(fd, rcu);
281}
282
Al Viro42695902009-02-20 05:59:13 +0000283const struct dentry_operations fuse_dentry_operations = {
Miklos Szeredie5e55582005-09-09 13:10:28 -0700284 .d_revalidate = fuse_dentry_revalidate,
Miklos Szeredif75fdf22016-10-01 07:32:32 +0200285 .d_init = fuse_dentry_init,
286 .d_release = fuse_dentry_release,
Miklos Szeredie5e55582005-09-09 13:10:28 -0700287};
288
Miklos Szeredi0ce267f2016-10-18 15:36:48 +0200289const struct dentry_operations fuse_root_dentry_operations = {
290 .d_init = fuse_dentry_init,
291 .d_release = fuse_dentry_release,
292};
293
Timo Savolaa5bfffac2007-04-08 16:04:00 -0700294int fuse_valid_type(int m)
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800295{
296 return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) ||
297 S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
298}
299
Al Viro13983d02016-07-20 22:34:44 -0400300int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name,
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700301 struct fuse_entry_out *outarg, struct inode **inode)
302{
303 struct fuse_conn *fc = get_fuse_conn_super(sb);
Miklos Szeredi70781872014-12-12 09:49:05 +0100304 FUSE_ARGS(args);
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100305 struct fuse_forget_link *forget;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700306 u64 attr_version;
307 int err;
308
309 *inode = NULL;
310 err = -ENAMETOOLONG;
311 if (name->len > FUSE_NAME_MAX)
312 goto out;
313
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700314
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100315 forget = fuse_alloc_forget();
316 err = -ENOMEM;
Miklos Szeredi70781872014-12-12 09:49:05 +0100317 if (!forget)
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700318 goto out;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700319
320 attr_version = fuse_get_attr_version(fc);
321
Miklos Szeredi70781872014-12-12 09:49:05 +0100322 fuse_lookup_init(fc, &args, nodeid, name, outarg);
323 err = fuse_simple_request(fc, &args);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700324 /* Zero nodeid is same as -ENOENT, but with valid timeout */
325 if (err || !outarg->nodeid)
326 goto out_put_forget;
327
328 err = -EIO;
329 if (!outarg->nodeid)
330 goto out_put_forget;
331 if (!fuse_valid_type(outarg->attr.mode))
332 goto out_put_forget;
333
334 *inode = fuse_iget(sb, outarg->nodeid, outarg->generation,
335 &outarg->attr, entry_attr_timeout(outarg),
336 attr_version);
337 err = -ENOMEM;
338 if (!*inode) {
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100339 fuse_queue_forget(fc, forget, outarg->nodeid, 1);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700340 goto out;
341 }
342 err = 0;
343
344 out_put_forget:
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100345 kfree(forget);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700346 out:
347 return err;
348}
349
Miklos Szeredi0aa7c692006-01-06 00:19:34 -0800350static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
Al Viro00cd8dd2012-06-10 17:13:09 -0400351 unsigned int flags)
Miklos Szeredie5e55582005-09-09 13:10:28 -0700352{
353 int err;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700354 struct fuse_entry_out outarg;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700355 struct inode *inode;
Miklos Szeredi0de62562008-07-25 01:48:59 -0700356 struct dentry *newent;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700357 bool outarg_valid = true;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700358
Miklos Szeredi5c672ab2016-06-30 13:10:49 +0200359 fuse_lock_inode(dir);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700360 err = fuse_lookup_name(dir->i_sb, get_node_id(dir), &entry->d_name,
361 &outarg, &inode);
Miklos Szeredi5c672ab2016-06-30 13:10:49 +0200362 fuse_unlock_inode(dir);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700363 if (err == -ENOENT) {
364 outarg_valid = false;
365 err = 0;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800366 }
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700367 if (err)
368 goto out_err;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800369
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700370 err = -EIO;
371 if (inode && get_node_id(inode) == FUSE_ROOT_ID)
372 goto out_iput;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700373
Al Viro41d28bc2014-10-12 22:24:21 -0400374 newent = d_splice_alias(inode, entry);
Miklos Szeredi5835f332013-09-05 11:44:42 +0200375 err = PTR_ERR(newent);
376 if (IS_ERR(newent))
377 goto out_err;
Miklos Szeredid2a85162006-10-17 00:10:11 -0700378
Miklos Szeredi0de62562008-07-25 01:48:59 -0700379 entry = newent ? newent : entry;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700380 if (outarg_valid)
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700381 fuse_change_entry_timeout(entry, &outarg);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800382 else
383 fuse_invalidate_entry_cache(entry);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700384
Feng Shuo4582a4a2013-01-15 11:23:28 +0800385 fuse_advise_use_readdirplus(dir);
Miklos Szeredi0de62562008-07-25 01:48:59 -0700386 return newent;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700387
388 out_iput:
389 iput(inode);
390 out_err:
391 return ERR_PTR(err);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700392}
393
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800394/*
395 * Atomic create+open operation
396 *
397 * If the filesystem doesn't support this, then fall back to separate
398 * 'mknod' + 'open' requests.
399 */
Al Virod9585272012-06-22 12:39:14 +0400400static int fuse_create_open(struct inode *dir, struct dentry *entry,
Al Viro30d90492012-06-22 12:40:19 +0400401 struct file *file, unsigned flags,
Al Virod9585272012-06-22 12:39:14 +0400402 umode_t mode, int *opened)
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800403{
404 int err;
405 struct inode *inode;
406 struct fuse_conn *fc = get_fuse_conn(dir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100407 FUSE_ARGS(args);
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100408 struct fuse_forget_link *forget;
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200409 struct fuse_create_in inarg;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800410 struct fuse_open_out outopen;
411 struct fuse_entry_out outentry;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800412 struct fuse_file *ff;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800413
Miklos Szerediaf109bc2012-08-15 13:01:24 +0200414 /* Userspace expects S_IFREG in create mode */
415 BUG_ON((mode & S_IFMT) != S_IFREG);
416
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100417 forget = fuse_alloc_forget();
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200418 err = -ENOMEM;
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100419 if (!forget)
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200420 goto out_err;
Miklos Szeredi51eb01e2006-06-25 05:48:50 -0700421
Miklos Szeredice1d5a42006-04-10 22:54:58 -0700422 err = -ENOMEM;
Tejun Heoacf99432008-11-26 12:03:55 +0100423 ff = fuse_file_alloc(fc);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800424 if (!ff)
Miklos Szeredi70781872014-12-12 09:49:05 +0100425 goto out_put_forget_req;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800426
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200427 if (!fc->dont_mask)
428 mode &= ~current_umask();
429
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800430 flags &= ~O_NOCTTY;
431 memset(&inarg, 0, sizeof(inarg));
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700432 memset(&outentry, 0, sizeof(outentry));
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800433 inarg.flags = flags;
434 inarg.mode = mode;
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200435 inarg.umask = current_umask();
Miklos Szeredi70781872014-12-12 09:49:05 +0100436 args.in.h.opcode = FUSE_CREATE;
437 args.in.h.nodeid = get_node_id(dir);
438 args.in.numargs = 2;
Miklos Szeredi21f62172015-01-06 10:45:35 +0100439 args.in.args[0].size = sizeof(inarg);
Miklos Szeredi70781872014-12-12 09:49:05 +0100440 args.in.args[0].value = &inarg;
441 args.in.args[1].size = entry->d_name.len + 1;
442 args.in.args[1].value = entry->d_name.name;
443 args.out.numargs = 2;
Miklos Szeredi21f62172015-01-06 10:45:35 +0100444 args.out.args[0].size = sizeof(outentry);
Miklos Szeredi70781872014-12-12 09:49:05 +0100445 args.out.args[0].value = &outentry;
446 args.out.args[1].size = sizeof(outopen);
447 args.out.args[1].value = &outopen;
448 err = fuse_simple_request(fc, &args);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200449 if (err)
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800450 goto out_free_ff;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800451
452 err = -EIO;
Miklos Szeredi2827d0b22005-11-28 13:44:16 -0800453 if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid))
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800454 goto out_free_ff;
455
Miklos Szeredic7b71432009-04-28 16:56:37 +0200456 ff->fh = outopen.fh;
457 ff->nodeid = outentry.nodeid;
458 ff->open_flags = outopen.open_flags;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800459 inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700460 &outentry.attr, entry_attr_timeout(&outentry), 0);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800461 if (!inode) {
462 flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
Miklos Szeredi8b0797a2009-04-28 16:56:39 +0200463 fuse_sync_release(ff, flags);
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100464 fuse_queue_forget(fc, forget, outentry.nodeid, 1);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200465 err = -ENOMEM;
466 goto out_err;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800467 }
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100468 kfree(forget);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800469 d_instantiate(entry, inode);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700470 fuse_change_entry_timeout(entry, &outentry);
Miklos Szeredi0952b2a2008-02-06 01:38:38 -0800471 fuse_invalidate_attr(dir);
Al Viro30d90492012-06-22 12:40:19 +0400472 err = finish_open(file, entry, generic_file_open, opened);
473 if (err) {
Miklos Szeredi8b0797a2009-04-28 16:56:39 +0200474 fuse_sync_release(ff, flags);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200475 } else {
Miklos Szeredi267d8442017-02-22 20:08:25 +0100476 file->private_data = ff;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200477 fuse_finish_open(inode, file);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800478 }
Al Virod9585272012-06-22 12:39:14 +0400479 return err;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800480
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200481out_free_ff:
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800482 fuse_file_free(ff);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200483out_put_forget_req:
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100484 kfree(forget);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200485out_err:
Al Virod9585272012-06-22 12:39:14 +0400486 return err;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200487}
488
489static int fuse_mknod(struct inode *, struct dentry *, umode_t, dev_t);
Al Virod9585272012-06-22 12:39:14 +0400490static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
Al Viro30d90492012-06-22 12:40:19 +0400491 struct file *file, unsigned flags,
Al Virod9585272012-06-22 12:39:14 +0400492 umode_t mode, int *opened)
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200493{
494 int err;
495 struct fuse_conn *fc = get_fuse_conn(dir);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200496 struct dentry *res = NULL;
497
Al Viro00699ad2016-07-05 09:44:53 -0400498 if (d_in_lookup(entry)) {
Al Viro00cd8dd2012-06-10 17:13:09 -0400499 res = fuse_lookup(dir, entry, 0);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200500 if (IS_ERR(res))
Al Virod9585272012-06-22 12:39:14 +0400501 return PTR_ERR(res);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200502
503 if (res)
504 entry = res;
505 }
506
David Howells2b0143b2015-03-17 22:25:59 +0000507 if (!(flags & O_CREAT) || d_really_is_positive(entry))
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200508 goto no_open;
509
510 /* Only creates */
Al Viro47237682012-06-10 05:01:45 -0400511 *opened |= FILE_CREATED;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200512
513 if (fc->no_create)
514 goto mknod;
515
Al Viro30d90492012-06-22 12:40:19 +0400516 err = fuse_create_open(dir, entry, file, flags, mode, opened);
Al Virod9585272012-06-22 12:39:14 +0400517 if (err == -ENOSYS) {
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200518 fc->no_create = 1;
519 goto mknod;
520 }
521out_dput:
522 dput(res);
Al Virod9585272012-06-22 12:39:14 +0400523 return err;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200524
525mknod:
526 err = fuse_mknod(dir, entry, mode, 0);
Al Virod9585272012-06-22 12:39:14 +0400527 if (err)
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200528 goto out_dput;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200529no_open:
Al Viroe45198a2012-06-10 06:48:09 -0400530 return finish_no_open(file, res);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800531}
532
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800533/*
534 * Code shared between mknod, mkdir, symlink and link
535 */
Miklos Szeredi70781872014-12-12 09:49:05 +0100536static int create_new_entry(struct fuse_conn *fc, struct fuse_args *args,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700537 struct inode *dir, struct dentry *entry,
Al Viro541af6a2011-07-26 03:17:33 -0400538 umode_t mode)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700539{
540 struct fuse_entry_out outarg;
541 struct inode *inode;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700542 int err;
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100543 struct fuse_forget_link *forget;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800544
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100545 forget = fuse_alloc_forget();
Miklos Szeredi70781872014-12-12 09:49:05 +0100546 if (!forget)
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100547 return -ENOMEM;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700548
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700549 memset(&outarg, 0, sizeof(outarg));
Miklos Szeredi70781872014-12-12 09:49:05 +0100550 args->in.h.nodeid = get_node_id(dir);
551 args->out.numargs = 1;
Miklos Szeredi21f62172015-01-06 10:45:35 +0100552 args->out.args[0].size = sizeof(outarg);
Miklos Szeredi70781872014-12-12 09:49:05 +0100553 args->out.args[0].value = &outarg;
554 err = fuse_simple_request(fc, args);
Miklos Szeredi2d510132006-11-25 11:09:20 -0800555 if (err)
556 goto out_put_forget_req;
557
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800558 err = -EIO;
559 if (invalid_nodeid(outarg.nodeid))
Miklos Szeredi2d510132006-11-25 11:09:20 -0800560 goto out_put_forget_req;
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800561
562 if ((outarg.attr.mode ^ mode) & S_IFMT)
Miklos Szeredi2d510132006-11-25 11:09:20 -0800563 goto out_put_forget_req;
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800564
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700565 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700566 &outarg.attr, entry_attr_timeout(&outarg), 0);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700567 if (!inode) {
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100568 fuse_queue_forget(fc, forget, outarg.nodeid, 1);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700569 return -ENOMEM;
570 }
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100571 kfree(forget);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700572
Miklos Szeredib70a80e2013-10-01 16:44:54 +0200573 err = d_instantiate_no_diralias(entry, inode);
574 if (err)
575 return err;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700576
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700577 fuse_change_entry_timeout(entry, &outarg);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700578 fuse_invalidate_attr(dir);
579 return 0;
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800580
Miklos Szeredi2d510132006-11-25 11:09:20 -0800581 out_put_forget_req:
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100582 kfree(forget);
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800583 return err;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700584}
585
Al Viro1a67aaf2011-07-26 01:52:52 -0400586static int fuse_mknod(struct inode *dir, struct dentry *entry, umode_t mode,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700587 dev_t rdev)
588{
589 struct fuse_mknod_in inarg;
590 struct fuse_conn *fc = get_fuse_conn(dir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100591 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700592
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200593 if (!fc->dont_mask)
594 mode &= ~current_umask();
595
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700596 memset(&inarg, 0, sizeof(inarg));
597 inarg.mode = mode;
598 inarg.rdev = new_encode_dev(rdev);
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200599 inarg.umask = current_umask();
Miklos Szeredi70781872014-12-12 09:49:05 +0100600 args.in.h.opcode = FUSE_MKNOD;
601 args.in.numargs = 2;
Miklos Szeredi21f62172015-01-06 10:45:35 +0100602 args.in.args[0].size = sizeof(inarg);
Miklos Szeredi70781872014-12-12 09:49:05 +0100603 args.in.args[0].value = &inarg;
604 args.in.args[1].size = entry->d_name.len + 1;
605 args.in.args[1].value = entry->d_name.name;
606 return create_new_entry(fc, &args, dir, entry, mode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700607}
608
Al Viro4acdaf22011-07-26 01:42:34 -0400609static int fuse_create(struct inode *dir, struct dentry *entry, umode_t mode,
Al Viroebfc3b42012-06-10 18:05:36 -0400610 bool excl)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700611{
612 return fuse_mknod(dir, entry, mode, 0);
613}
614
Al Viro18bb1db2011-07-26 01:41:39 -0400615static int fuse_mkdir(struct inode *dir, struct dentry *entry, umode_t mode)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700616{
617 struct fuse_mkdir_in inarg;
618 struct fuse_conn *fc = get_fuse_conn(dir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100619 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700620
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200621 if (!fc->dont_mask)
622 mode &= ~current_umask();
623
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700624 memset(&inarg, 0, sizeof(inarg));
625 inarg.mode = mode;
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200626 inarg.umask = current_umask();
Miklos Szeredi70781872014-12-12 09:49:05 +0100627 args.in.h.opcode = FUSE_MKDIR;
628 args.in.numargs = 2;
629 args.in.args[0].size = sizeof(inarg);
630 args.in.args[0].value = &inarg;
631 args.in.args[1].size = entry->d_name.len + 1;
632 args.in.args[1].value = entry->d_name.name;
633 return create_new_entry(fc, &args, dir, entry, S_IFDIR);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700634}
635
636static int fuse_symlink(struct inode *dir, struct dentry *entry,
637 const char *link)
638{
639 struct fuse_conn *fc = get_fuse_conn(dir);
640 unsigned len = strlen(link) + 1;
Miklos Szeredi70781872014-12-12 09:49:05 +0100641 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700642
Miklos Szeredi70781872014-12-12 09:49:05 +0100643 args.in.h.opcode = FUSE_SYMLINK;
644 args.in.numargs = 2;
645 args.in.args[0].size = entry->d_name.len + 1;
646 args.in.args[0].value = entry->d_name.name;
647 args.in.args[1].size = len;
648 args.in.args[1].value = link;
649 return create_new_entry(fc, &args, dir, entry, S_IFLNK);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700650}
651
Seth Forshee703c7362016-08-29 08:46:36 -0500652void fuse_update_ctime(struct inode *inode)
Maxim Patlasov31f32672014-04-28 14:19:24 +0200653{
654 if (!IS_NOCMTIME(inode)) {
Deepa Dinamanic2050a42016-09-14 07:48:06 -0700655 inode->i_ctime = current_time(inode);
Maxim Patlasov31f32672014-04-28 14:19:24 +0200656 mark_inode_dirty_sync(inode);
657 }
658}
659
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700660static int fuse_unlink(struct inode *dir, struct dentry *entry)
661{
662 int err;
663 struct fuse_conn *fc = get_fuse_conn(dir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100664 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700665
Miklos Szeredi70781872014-12-12 09:49:05 +0100666 args.in.h.opcode = FUSE_UNLINK;
667 args.in.h.nodeid = get_node_id(dir);
668 args.in.numargs = 1;
669 args.in.args[0].size = entry->d_name.len + 1;
670 args.in.args[0].value = entry->d_name.name;
671 err = fuse_simple_request(fc, &args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700672 if (!err) {
David Howells2b0143b2015-03-17 22:25:59 +0000673 struct inode *inode = d_inode(entry);
Miklos Szerediac45d612012-03-05 15:48:11 +0100674 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700675
Miklos Szerediac45d612012-03-05 15:48:11 +0100676 spin_lock(&fc->lock);
677 fi->attr_version = ++fc->attr_version;
Miklos Szeredidfca7ce2013-02-04 15:57:42 +0100678 /*
679 * If i_nlink == 0 then unlink doesn't make sense, yet this can
680 * happen if userspace filesystem is careless. It would be
681 * difficult to enforce correct nlink usage so just ignore this
682 * condition here
683 */
684 if (inode->i_nlink > 0)
685 drop_nlink(inode);
Miklos Szerediac45d612012-03-05 15:48:11 +0100686 spin_unlock(&fc->lock);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700687 fuse_invalidate_attr(inode);
688 fuse_invalidate_attr(dir);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800689 fuse_invalidate_entry_cache(entry);
Maxim Patlasov31f32672014-04-28 14:19:24 +0200690 fuse_update_ctime(inode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700691 } else if (err == -EINTR)
692 fuse_invalidate_entry(entry);
693 return err;
694}
695
696static int fuse_rmdir(struct inode *dir, struct dentry *entry)
697{
698 int err;
699 struct fuse_conn *fc = get_fuse_conn(dir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100700 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700701
Miklos Szeredi70781872014-12-12 09:49:05 +0100702 args.in.h.opcode = FUSE_RMDIR;
703 args.in.h.nodeid = get_node_id(dir);
704 args.in.numargs = 1;
705 args.in.args[0].size = entry->d_name.len + 1;
706 args.in.args[0].value = entry->d_name.name;
707 err = fuse_simple_request(fc, &args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700708 if (!err) {
David Howells2b0143b2015-03-17 22:25:59 +0000709 clear_nlink(d_inode(entry));
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700710 fuse_invalidate_attr(dir);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800711 fuse_invalidate_entry_cache(entry);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700712 } else if (err == -EINTR)
713 fuse_invalidate_entry(entry);
714 return err;
715}
716
Miklos Szeredi1560c972014-04-28 16:43:44 +0200717static int fuse_rename_common(struct inode *olddir, struct dentry *oldent,
718 struct inode *newdir, struct dentry *newent,
719 unsigned int flags, int opcode, size_t argsize)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700720{
721 int err;
Miklos Szeredi1560c972014-04-28 16:43:44 +0200722 struct fuse_rename2_in inarg;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700723 struct fuse_conn *fc = get_fuse_conn(olddir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100724 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700725
Miklos Szeredi1560c972014-04-28 16:43:44 +0200726 memset(&inarg, 0, argsize);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700727 inarg.newdir = get_node_id(newdir);
Miklos Szeredi1560c972014-04-28 16:43:44 +0200728 inarg.flags = flags;
Miklos Szeredi70781872014-12-12 09:49:05 +0100729 args.in.h.opcode = opcode;
730 args.in.h.nodeid = get_node_id(olddir);
731 args.in.numargs = 3;
732 args.in.args[0].size = argsize;
733 args.in.args[0].value = &inarg;
734 args.in.args[1].size = oldent->d_name.len + 1;
735 args.in.args[1].value = oldent->d_name.name;
736 args.in.args[2].size = newent->d_name.len + 1;
737 args.in.args[2].value = newent->d_name.name;
738 err = fuse_simple_request(fc, &args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700739 if (!err) {
Miklos Szeredi08b63302007-11-28 16:22:03 -0800740 /* ctime changes */
David Howells2b0143b2015-03-17 22:25:59 +0000741 fuse_invalidate_attr(d_inode(oldent));
742 fuse_update_ctime(d_inode(oldent));
Miklos Szeredi08b63302007-11-28 16:22:03 -0800743
Miklos Szeredi1560c972014-04-28 16:43:44 +0200744 if (flags & RENAME_EXCHANGE) {
David Howells2b0143b2015-03-17 22:25:59 +0000745 fuse_invalidate_attr(d_inode(newent));
746 fuse_update_ctime(d_inode(newent));
Miklos Szeredi1560c972014-04-28 16:43:44 +0200747 }
748
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700749 fuse_invalidate_attr(olddir);
750 if (olddir != newdir)
751 fuse_invalidate_attr(newdir);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800752
753 /* newent will end up negative */
David Howells2b0143b2015-03-17 22:25:59 +0000754 if (!(flags & RENAME_EXCHANGE) && d_really_is_positive(newent)) {
755 fuse_invalidate_attr(d_inode(newent));
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800756 fuse_invalidate_entry_cache(newent);
David Howells2b0143b2015-03-17 22:25:59 +0000757 fuse_update_ctime(d_inode(newent));
Miklos Szeredi5219f342009-11-04 10:24:52 +0100758 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700759 } else if (err == -EINTR) {
760 /* If request was interrupted, DEITY only knows if the
761 rename actually took place. If the invalidation
762 fails (e.g. some process has CWD under the renamed
763 directory), then there can be inconsistency between
764 the dcache and the real filesystem. Tough luck. */
765 fuse_invalidate_entry(oldent);
David Howells2b0143b2015-03-17 22:25:59 +0000766 if (d_really_is_positive(newent))
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700767 fuse_invalidate_entry(newent);
768 }
769
770 return err;
771}
772
Miklos Szeredi1560c972014-04-28 16:43:44 +0200773static int fuse_rename2(struct inode *olddir, struct dentry *oldent,
774 struct inode *newdir, struct dentry *newent,
775 unsigned int flags)
776{
777 struct fuse_conn *fc = get_fuse_conn(olddir);
778 int err;
779
780 if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE))
781 return -EINVAL;
782
Miklos Szeredi4237ba42014-07-10 10:50:19 +0200783 if (flags) {
784 if (fc->no_rename2 || fc->minor < 23)
785 return -EINVAL;
Miklos Szeredi1560c972014-04-28 16:43:44 +0200786
Miklos Szeredi4237ba42014-07-10 10:50:19 +0200787 err = fuse_rename_common(olddir, oldent, newdir, newent, flags,
788 FUSE_RENAME2,
789 sizeof(struct fuse_rename2_in));
790 if (err == -ENOSYS) {
791 fc->no_rename2 = 1;
792 err = -EINVAL;
793 }
794 } else {
795 err = fuse_rename_common(olddir, oldent, newdir, newent, 0,
796 FUSE_RENAME,
797 sizeof(struct fuse_rename_in));
Miklos Szeredi1560c972014-04-28 16:43:44 +0200798 }
Miklos Szeredi1560c972014-04-28 16:43:44 +0200799
Miklos Szeredi4237ba42014-07-10 10:50:19 +0200800 return err;
801}
802
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700803static int fuse_link(struct dentry *entry, struct inode *newdir,
804 struct dentry *newent)
805{
806 int err;
807 struct fuse_link_in inarg;
David Howells2b0143b2015-03-17 22:25:59 +0000808 struct inode *inode = d_inode(entry);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700809 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +0100810 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700811
812 memset(&inarg, 0, sizeof(inarg));
813 inarg.oldnodeid = get_node_id(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +0100814 args.in.h.opcode = FUSE_LINK;
815 args.in.numargs = 2;
816 args.in.args[0].size = sizeof(inarg);
817 args.in.args[0].value = &inarg;
818 args.in.args[1].size = newent->d_name.len + 1;
819 args.in.args[1].value = newent->d_name.name;
820 err = create_new_entry(fc, &args, newdir, newent, inode->i_mode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700821 /* Contrary to "normal" filesystems it can happen that link
822 makes two "logical" inodes point to the same "physical"
823 inode. We invalidate the attributes of the old one, so it
824 will reflect changes in the backing inode (link count,
825 etc.)
826 */
Miklos Szerediac45d612012-03-05 15:48:11 +0100827 if (!err) {
828 struct fuse_inode *fi = get_fuse_inode(inode);
829
830 spin_lock(&fc->lock);
831 fi->attr_version = ++fc->attr_version;
832 inc_nlink(inode);
833 spin_unlock(&fc->lock);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700834 fuse_invalidate_attr(inode);
Maxim Patlasov31f32672014-04-28 14:19:24 +0200835 fuse_update_ctime(inode);
Miklos Szerediac45d612012-03-05 15:48:11 +0100836 } else if (err == -EINTR) {
837 fuse_invalidate_attr(inode);
838 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700839 return err;
840}
841
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700842static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
843 struct kstat *stat)
844{
Miklos Szeredi203627b2012-05-10 19:49:38 +0400845 unsigned int blkbits;
Pavel Emelyanov83732002013-10-10 17:10:46 +0400846 struct fuse_conn *fc = get_fuse_conn(inode);
847
848 /* see the comment in fuse_change_attributes() */
Maxim Patlasovb0aa7602013-12-26 19:51:11 +0400849 if (fc->writeback_cache && S_ISREG(inode->i_mode)) {
Pavel Emelyanov83732002013-10-10 17:10:46 +0400850 attr->size = i_size_read(inode);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +0400851 attr->mtime = inode->i_mtime.tv_sec;
852 attr->mtimensec = inode->i_mtime.tv_nsec;
Maxim Patlasov31f32672014-04-28 14:19:24 +0200853 attr->ctime = inode->i_ctime.tv_sec;
854 attr->ctimensec = inode->i_ctime.tv_nsec;
Maxim Patlasovb0aa7602013-12-26 19:51:11 +0400855 }
Miklos Szeredi203627b2012-05-10 19:49:38 +0400856
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700857 stat->dev = inode->i_sb->s_dev;
858 stat->ino = attr->ino;
859 stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
860 stat->nlink = attr->nlink;
Eric W. Biederman8cb08322018-02-21 11:18:07 -0600861 stat->uid = make_kuid(fc->user_ns, attr->uid);
862 stat->gid = make_kgid(fc->user_ns, attr->gid);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700863 stat->rdev = inode->i_rdev;
864 stat->atime.tv_sec = attr->atime;
865 stat->atime.tv_nsec = attr->atimensec;
866 stat->mtime.tv_sec = attr->mtime;
867 stat->mtime.tv_nsec = attr->mtimensec;
868 stat->ctime.tv_sec = attr->ctime;
869 stat->ctime.tv_nsec = attr->ctimensec;
870 stat->size = attr->size;
871 stat->blocks = attr->blocks;
Miklos Szeredi203627b2012-05-10 19:49:38 +0400872
873 if (attr->blksize != 0)
874 blkbits = ilog2(attr->blksize);
875 else
876 blkbits = inode->i_sb->s_blocksize_bits;
877
878 stat->blksize = 1 << blkbits;
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700879}
880
Miklos Szeredic79e3222007-10-18 03:06:59 -0700881static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
882 struct file *file)
Miklos Szeredie5e55582005-09-09 13:10:28 -0700883{
884 int err;
Miklos Szeredic79e3222007-10-18 03:06:59 -0700885 struct fuse_getattr_in inarg;
886 struct fuse_attr_out outarg;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700887 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +0100888 FUSE_ARGS(args);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700889 u64 attr_version;
890
Miklos Szeredi7dca9fd2007-11-28 16:21:59 -0800891 attr_version = fuse_get_attr_version(fc);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700892
Miklos Szeredic79e3222007-10-18 03:06:59 -0700893 memset(&inarg, 0, sizeof(inarg));
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700894 memset(&outarg, 0, sizeof(outarg));
Miklos Szeredic79e3222007-10-18 03:06:59 -0700895 /* Directories have separate file-handle space */
896 if (file && S_ISREG(inode->i_mode)) {
897 struct fuse_file *ff = file->private_data;
898
899 inarg.getattr_flags |= FUSE_GETATTR_FH;
900 inarg.fh = ff->fh;
901 }
Miklos Szeredi70781872014-12-12 09:49:05 +0100902 args.in.h.opcode = FUSE_GETATTR;
903 args.in.h.nodeid = get_node_id(inode);
904 args.in.numargs = 1;
905 args.in.args[0].size = sizeof(inarg);
906 args.in.args[0].value = &inarg;
907 args.out.numargs = 1;
Miklos Szeredi21f62172015-01-06 10:45:35 +0100908 args.out.args[0].size = sizeof(outarg);
Miklos Szeredi70781872014-12-12 09:49:05 +0100909 args.out.args[0].value = &outarg;
910 err = fuse_simple_request(fc, &args);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700911 if (!err) {
Miklos Szeredic79e3222007-10-18 03:06:59 -0700912 if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
Miklos Szeredie5e55582005-09-09 13:10:28 -0700913 make_bad_inode(inode);
914 err = -EIO;
915 } else {
Miklos Szeredic79e3222007-10-18 03:06:59 -0700916 fuse_change_attributes(inode, &outarg.attr,
917 attr_timeout(&outarg),
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700918 attr_version);
919 if (stat)
Miklos Szeredic79e3222007-10-18 03:06:59 -0700920 fuse_fillattr(inode, &outarg.attr, stat);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700921 }
922 }
923 return err;
924}
925
Miklos Szeredi5b97eea2017-09-12 16:57:54 +0200926static int fuse_update_get_attr(struct inode *inode, struct file *file,
Miklos Szerediff1b89f2018-03-20 17:11:44 +0100927 struct kstat *stat, unsigned int flags)
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800928{
929 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredi5b97eea2017-09-12 16:57:54 +0200930 int err = 0;
Miklos Szeredibf5c1892018-03-20 17:11:44 +0100931 bool sync;
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800932
Miklos Szeredibf5c1892018-03-20 17:11:44 +0100933 if (flags & AT_STATX_FORCE_SYNC)
934 sync = true;
935 else if (flags & AT_STATX_DONT_SYNC)
936 sync = false;
937 else
938 sync = time_before64(fi->i_time, get_jiffies_64());
939
940 if (sync) {
Seth Forshee60bcc882016-08-29 08:46:37 -0500941 forget_all_cached_acls(inode);
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800942 err = fuse_do_getattr(inode, stat, file);
Miklos Szeredi5b97eea2017-09-12 16:57:54 +0200943 } else if (stat) {
944 generic_fillattr(inode, stat);
945 stat->mode = fi->orig_i_mode;
946 stat->ino = fi->orig_ino;
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800947 }
948
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800949 return err;
950}
951
Miklos Szeredi5b97eea2017-09-12 16:57:54 +0200952int fuse_update_attributes(struct inode *inode, struct file *file)
953{
Miklos Szerediff1b89f2018-03-20 17:11:44 +0100954 return fuse_update_get_attr(inode, file, NULL, 0);
Miklos Szeredi5b97eea2017-09-12 16:57:54 +0200955}
956
John Muir3b463ae2009-05-31 11:13:57 -0400957int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid,
John Muir451d0f52011-12-06 21:50:06 +0100958 u64 child_nodeid, struct qstr *name)
John Muir3b463ae2009-05-31 11:13:57 -0400959{
960 int err = -ENOTDIR;
961 struct inode *parent;
962 struct dentry *dir;
963 struct dentry *entry;
964
965 parent = ilookup5(sb, parent_nodeid, fuse_inode_eq, &parent_nodeid);
966 if (!parent)
967 return -ENOENT;
968
Al Viro59551022016-01-22 15:40:57 -0500969 inode_lock(parent);
John Muir3b463ae2009-05-31 11:13:57 -0400970 if (!S_ISDIR(parent->i_mode))
971 goto unlock;
972
973 err = -ENOENT;
974 dir = d_find_alias(parent);
975 if (!dir)
976 goto unlock;
977
Linus Torvalds8387ff22016-06-10 07:51:30 -0700978 name->hash = full_name_hash(dir, name->name, name->len);
John Muir3b463ae2009-05-31 11:13:57 -0400979 entry = d_lookup(dir, name);
980 dput(dir);
981 if (!entry)
982 goto unlock;
983
984 fuse_invalidate_attr(parent);
985 fuse_invalidate_entry(entry);
John Muir451d0f52011-12-06 21:50:06 +0100986
David Howells2b0143b2015-03-17 22:25:59 +0000987 if (child_nodeid != 0 && d_really_is_positive(entry)) {
Al Viro59551022016-01-22 15:40:57 -0500988 inode_lock(d_inode(entry));
David Howells2b0143b2015-03-17 22:25:59 +0000989 if (get_node_id(d_inode(entry)) != child_nodeid) {
John Muir451d0f52011-12-06 21:50:06 +0100990 err = -ENOENT;
991 goto badentry;
992 }
993 if (d_mountpoint(entry)) {
994 err = -EBUSY;
995 goto badentry;
996 }
David Howellse36cb0b2015-01-29 12:02:35 +0000997 if (d_is_dir(entry)) {
John Muir451d0f52011-12-06 21:50:06 +0100998 shrink_dcache_parent(entry);
999 if (!simple_empty(entry)) {
1000 err = -ENOTEMPTY;
1001 goto badentry;
1002 }
David Howells2b0143b2015-03-17 22:25:59 +00001003 d_inode(entry)->i_flags |= S_DEAD;
John Muir451d0f52011-12-06 21:50:06 +01001004 }
1005 dont_mount(entry);
David Howells2b0143b2015-03-17 22:25:59 +00001006 clear_nlink(d_inode(entry));
John Muir451d0f52011-12-06 21:50:06 +01001007 err = 0;
1008 badentry:
Al Viro59551022016-01-22 15:40:57 -05001009 inode_unlock(d_inode(entry));
John Muir451d0f52011-12-06 21:50:06 +01001010 if (!err)
1011 d_delete(entry);
1012 } else {
1013 err = 0;
1014 }
John Muir3b463ae2009-05-31 11:13:57 -04001015 dput(entry);
John Muir3b463ae2009-05-31 11:13:57 -04001016
1017 unlock:
Al Viro59551022016-01-22 15:40:57 -05001018 inode_unlock(parent);
John Muir3b463ae2009-05-31 11:13:57 -04001019 iput(parent);
1020 return err;
1021}
1022
Miklos Szeredi87729a52005-09-09 13:10:34 -07001023/*
1024 * Calling into a user-controlled filesystem gives the filesystem
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001025 * daemon ptrace-like capabilities over the current process. This
Miklos Szeredi87729a52005-09-09 13:10:34 -07001026 * means, that the filesystem daemon is able to record the exact
1027 * filesystem operations performed, and can also control the behavior
1028 * of the requester process in otherwise impossible ways. For example
1029 * it can delay the operation for arbitrary length of time allowing
1030 * DoS against the requester.
1031 *
1032 * For this reason only those processes can call into the filesystem,
1033 * for which the owner of the mount has ptrace privilege. This
1034 * excludes processes started by other users, suid or sgid processes.
1035 */
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001036int fuse_allow_current_process(struct fuse_conn *fc)
Miklos Szeredi87729a52005-09-09 13:10:34 -07001037{
David Howellsc69e8d92008-11-14 10:39:19 +11001038 const struct cred *cred;
David Howellsc69e8d92008-11-14 10:39:19 +11001039
Miklos Szeredi29433a22016-10-01 07:32:32 +02001040 if (fc->allow_other)
Seth Forshee73f03c22017-12-22 15:32:33 +01001041 return current_in_userns(fc->user_ns);
Miklos Szeredi87729a52005-09-09 13:10:34 -07001042
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001043 cred = current_cred();
Eric W. Biederman499dcf22012-02-07 16:26:03 -08001044 if (uid_eq(cred->euid, fc->user_id) &&
1045 uid_eq(cred->suid, fc->user_id) &&
1046 uid_eq(cred->uid, fc->user_id) &&
1047 gid_eq(cred->egid, fc->group_id) &&
1048 gid_eq(cred->sgid, fc->group_id) &&
1049 gid_eq(cred->gid, fc->group_id))
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001050 return 1;
Miklos Szeredi87729a52005-09-09 13:10:34 -07001051
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001052 return 0;
Miklos Szeredi87729a52005-09-09 13:10:34 -07001053}
1054
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001055static int fuse_access(struct inode *inode, int mask)
1056{
1057 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001058 FUSE_ARGS(args);
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001059 struct fuse_access_in inarg;
1060 int err;
1061
Miklos Szeredi698fa1d2013-10-01 16:41:23 +02001062 BUG_ON(mask & MAY_NOT_BLOCK);
1063
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001064 if (fc->no_access)
1065 return 0;
1066
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001067 memset(&inarg, 0, sizeof(inarg));
Al Viroe6305c42008-07-15 21:03:57 -04001068 inarg.mask = mask & (MAY_READ | MAY_WRITE | MAY_EXEC);
Miklos Szeredi70781872014-12-12 09:49:05 +01001069 args.in.h.opcode = FUSE_ACCESS;
1070 args.in.h.nodeid = get_node_id(inode);
1071 args.in.numargs = 1;
1072 args.in.args[0].size = sizeof(inarg);
1073 args.in.args[0].value = &inarg;
1074 err = fuse_simple_request(fc, &args);
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001075 if (err == -ENOSYS) {
1076 fc->no_access = 1;
1077 err = 0;
1078 }
1079 return err;
1080}
1081
Al Viro10556cb2011-06-20 19:28:19 -04001082static int fuse_perm_getattr(struct inode *inode, int mask)
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001083{
Al Viro10556cb2011-06-20 19:28:19 -04001084 if (mask & MAY_NOT_BLOCK)
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001085 return -ECHILD;
1086
Seth Forshee60bcc882016-08-29 08:46:37 -05001087 forget_all_cached_acls(inode);
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001088 return fuse_do_getattr(inode, NULL, NULL);
1089}
1090
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001091/*
1092 * Check permission. The two basic access models of FUSE are:
1093 *
1094 * 1) Local access checking ('default_permissions' mount option) based
1095 * on file mode. This is the plain old disk filesystem permission
1096 * modell.
1097 *
1098 * 2) "Remote" access checking, where server is responsible for
1099 * checking permission in each inode operation. An exception to this
1100 * is if ->permission() was invoked from sys_access() in which case an
1101 * access request is sent. Execute permission is still checked
1102 * locally based on file mode.
1103 */
Al Viro10556cb2011-06-20 19:28:19 -04001104static int fuse_permission(struct inode *inode, int mask)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001105{
1106 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi244f6382007-10-16 23:31:02 -07001107 bool refreshed = false;
1108 int err = 0;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001109
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001110 if (!fuse_allow_current_process(fc))
Miklos Szeredie5e55582005-09-09 13:10:28 -07001111 return -EACCES;
Miklos Szeredi244f6382007-10-16 23:31:02 -07001112
1113 /*
Miklos Szeredie8e96152007-10-16 23:31:06 -07001114 * If attributes are needed, refresh them before proceeding
Miklos Szeredi244f6382007-10-16 23:31:02 -07001115 */
Miklos Szeredi29433a22016-10-01 07:32:32 +02001116 if (fc->default_permissions ||
Miklos Szeredie8e96152007-10-16 23:31:06 -07001117 ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) {
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001118 struct fuse_inode *fi = get_fuse_inode(inode);
1119
Miklos Szeredi126b9d42014-07-07 15:28:50 +02001120 if (time_before64(fi->i_time, get_jiffies_64())) {
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001121 refreshed = true;
1122
Al Viro10556cb2011-06-20 19:28:19 -04001123 err = fuse_perm_getattr(inode, mask);
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001124 if (err)
1125 return err;
1126 }
Miklos Szeredi244f6382007-10-16 23:31:02 -07001127 }
1128
Miklos Szeredi29433a22016-10-01 07:32:32 +02001129 if (fc->default_permissions) {
Al Viro2830ba72011-06-20 19:16:29 -04001130 err = generic_permission(inode, mask);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001131
1132 /* If permission is denied, try to refresh file
1133 attributes. This is also needed, because the root
1134 node will at first have no permissions */
Miklos Szeredi244f6382007-10-16 23:31:02 -07001135 if (err == -EACCES && !refreshed) {
Al Viro10556cb2011-06-20 19:28:19 -04001136 err = fuse_perm_getattr(inode, mask);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001137 if (!err)
Al Viro2830ba72011-06-20 19:16:29 -04001138 err = generic_permission(inode, mask);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001139 }
1140
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001141 /* Note: the opposite of the above test does not
1142 exist. So if permissions are revoked this won't be
1143 noticed immediately, only after the attribute
1144 timeout has expired */
Eric Paris9cfcac82010-07-23 11:43:51 -04001145 } else if (mask & (MAY_ACCESS | MAY_CHDIR)) {
Miklos Szeredie8e96152007-10-16 23:31:06 -07001146 err = fuse_access(inode, mask);
1147 } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
1148 if (!(inode->i_mode & S_IXUGO)) {
1149 if (refreshed)
1150 return -EACCES;
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001151
Al Viro10556cb2011-06-20 19:28:19 -04001152 err = fuse_perm_getattr(inode, mask);
Miklos Szeredie8e96152007-10-16 23:31:06 -07001153 if (!err && !(inode->i_mode & S_IXUGO))
1154 return -EACCES;
1155 }
Miklos Szeredie5e55582005-09-09 13:10:28 -07001156 }
Miklos Szeredi244f6382007-10-16 23:31:02 -07001157 return err;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001158}
1159
1160static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
Al Viro8d3af7f2013-05-18 03:03:58 -04001161 struct dir_context *ctx)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001162{
1163 while (nbytes >= FUSE_NAME_OFFSET) {
1164 struct fuse_dirent *dirent = (struct fuse_dirent *) buf;
1165 size_t reclen = FUSE_DIRENT_SIZE(dirent);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001166 if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
1167 return -EIO;
1168 if (reclen > nbytes)
1169 break;
Miklos Szerediefeb9e62013-09-03 14:28:38 +02001170 if (memchr(dirent->name, '/', dirent->namelen) != NULL)
1171 return -EIO;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001172
Al Viro8d3af7f2013-05-18 03:03:58 -04001173 if (!dir_emit(ctx, dirent->name, dirent->namelen,
1174 dirent->ino, dirent->type))
Miklos Szeredie5e55582005-09-09 13:10:28 -07001175 break;
1176
1177 buf += reclen;
1178 nbytes -= reclen;
Al Viro8d3af7f2013-05-18 03:03:58 -04001179 ctx->pos = dirent->off;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001180 }
1181
1182 return 0;
1183}
1184
Anand V. Avati0b05b182012-08-19 08:53:23 -04001185static int fuse_direntplus_link(struct file *file,
1186 struct fuse_direntplus *direntplus,
1187 u64 attr_version)
1188{
Anand V. Avati0b05b182012-08-19 08:53:23 -04001189 struct fuse_entry_out *o = &direntplus->entry_out;
1190 struct fuse_dirent *dirent = &direntplus->dirent;
1191 struct dentry *parent = file->f_path.dentry;
1192 struct qstr name = QSTR_INIT(dirent->name, dirent->namelen);
1193 struct dentry *dentry;
1194 struct dentry *alias;
David Howells2b0143b2015-03-17 22:25:59 +00001195 struct inode *dir = d_inode(parent);
Anand V. Avati0b05b182012-08-19 08:53:23 -04001196 struct fuse_conn *fc;
1197 struct inode *inode;
Al Virod9b3dbd2016-04-20 17:30:32 -04001198 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
Anand V. Avati0b05b182012-08-19 08:53:23 -04001199
1200 if (!o->nodeid) {
1201 /*
1202 * Unlike in the case of fuse_lookup, zero nodeid does not mean
1203 * ENOENT. Instead, it only means the userspace filesystem did
1204 * not want to return attributes/handle for this entry.
1205 *
1206 * So do nothing.
1207 */
1208 return 0;
1209 }
1210
1211 if (name.name[0] == '.') {
1212 /*
1213 * We could potentially refresh the attributes of the directory
1214 * and its parent?
1215 */
1216 if (name.len == 1)
1217 return 0;
1218 if (name.name[1] == '.' && name.len == 2)
1219 return 0;
1220 }
Miklos Szeredia28ef452013-07-17 14:53:53 +02001221
1222 if (invalid_nodeid(o->nodeid))
1223 return -EIO;
1224 if (!fuse_valid_type(o->attr.mode))
1225 return -EIO;
1226
Anand V. Avati0b05b182012-08-19 08:53:23 -04001227 fc = get_fuse_conn(dir);
1228
Linus Torvalds8387ff22016-06-10 07:51:30 -07001229 name.hash = full_name_hash(parent, name.name, name.len);
Anand V. Avati0b05b182012-08-19 08:53:23 -04001230 dentry = d_lookup(parent, &name);
Al Virod9b3dbd2016-04-20 17:30:32 -04001231 if (!dentry) {
1232retry:
1233 dentry = d_alloc_parallel(parent, &name, &wq);
1234 if (IS_ERR(dentry))
1235 return PTR_ERR(dentry);
1236 }
1237 if (!d_in_lookup(dentry)) {
1238 struct fuse_inode *fi;
David Howells2b0143b2015-03-17 22:25:59 +00001239 inode = d_inode(dentry);
Al Virod9b3dbd2016-04-20 17:30:32 -04001240 if (!inode ||
1241 get_node_id(inode) != o->nodeid ||
1242 ((o->attr.mode ^ inode->i_mode) & S_IFMT)) {
Eric W. Biederman5542aa22014-02-13 09:46:25 -08001243 d_invalidate(dentry);
Al Virod9b3dbd2016-04-20 17:30:32 -04001244 dput(dentry);
1245 goto retry;
Anand V. Avati0b05b182012-08-19 08:53:23 -04001246 }
Al Virod9b3dbd2016-04-20 17:30:32 -04001247 if (is_bad_inode(inode)) {
1248 dput(dentry);
1249 return -EIO;
1250 }
1251
1252 fi = get_fuse_inode(inode);
1253 spin_lock(&fc->lock);
1254 fi->nlookup++;
1255 spin_unlock(&fc->lock);
1256
Seth Forshee60bcc882016-08-29 08:46:37 -05001257 forget_all_cached_acls(inode);
Al Virod9b3dbd2016-04-20 17:30:32 -04001258 fuse_change_attributes(inode, &o->attr,
1259 entry_attr_timeout(o),
1260 attr_version);
1261 /*
1262 * The other branch comes via fuse_iget()
1263 * which bumps nlookup inside
1264 */
1265 } else {
1266 inode = fuse_iget(dir->i_sb, o->nodeid, o->generation,
1267 &o->attr, entry_attr_timeout(o),
1268 attr_version);
1269 if (!inode)
1270 inode = ERR_PTR(-ENOMEM);
1271
1272 alias = d_splice_alias(inode, dentry);
1273 d_lookup_done(dentry);
1274 if (alias) {
1275 dput(dentry);
1276 dentry = alias;
1277 }
1278 if (IS_ERR(dentry))
1279 return PTR_ERR(dentry);
Anand V. Avati0b05b182012-08-19 08:53:23 -04001280 }
Miklos Szeredi6314efe2013-10-01 16:41:22 +02001281 if (fc->readdirplus_auto)
1282 set_bit(FUSE_I_INIT_RDPLUS, &get_fuse_inode(inode)->state);
Anand V. Avati0b05b182012-08-19 08:53:23 -04001283 fuse_change_entry_timeout(dentry, o);
1284
Miklos Szeredic7263bc2013-07-17 14:53:54 +02001285 dput(dentry);
Al Virod9b3dbd2016-04-20 17:30:32 -04001286 return 0;
Anand V. Avati0b05b182012-08-19 08:53:23 -04001287}
1288
1289static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file,
Al Viro8d3af7f2013-05-18 03:03:58 -04001290 struct dir_context *ctx, u64 attr_version)
Anand V. Avati0b05b182012-08-19 08:53:23 -04001291{
1292 struct fuse_direntplus *direntplus;
1293 struct fuse_dirent *dirent;
1294 size_t reclen;
1295 int over = 0;
1296 int ret;
1297
1298 while (nbytes >= FUSE_NAME_OFFSET_DIRENTPLUS) {
1299 direntplus = (struct fuse_direntplus *) buf;
1300 dirent = &direntplus->dirent;
1301 reclen = FUSE_DIRENTPLUS_SIZE(direntplus);
1302
1303 if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
1304 return -EIO;
1305 if (reclen > nbytes)
1306 break;
Miklos Szerediefeb9e62013-09-03 14:28:38 +02001307 if (memchr(dirent->name, '/', dirent->namelen) != NULL)
1308 return -EIO;
Anand V. Avati0b05b182012-08-19 08:53:23 -04001309
1310 if (!over) {
1311 /* We fill entries into dstbuf only as much as
1312 it can hold. But we still continue iterating
1313 over remaining entries to link them. If not,
1314 we need to send a FORGET for each of those
1315 which we did not link.
1316 */
Al Viro8d3af7f2013-05-18 03:03:58 -04001317 over = !dir_emit(ctx, dirent->name, dirent->namelen,
1318 dirent->ino, dirent->type);
Miklos Szeredic6cdd512017-10-25 16:34:27 +02001319 if (!over)
1320 ctx->pos = dirent->off;
Anand V. Avati0b05b182012-08-19 08:53:23 -04001321 }
1322
1323 buf += reclen;
1324 nbytes -= reclen;
1325
1326 ret = fuse_direntplus_link(file, direntplus, attr_version);
1327 if (ret)
1328 fuse_force_forget(file, direntplus->entry_out.nodeid);
1329 }
1330
1331 return 0;
1332}
1333
Al Viro8d3af7f2013-05-18 03:03:58 -04001334static int fuse_readdir(struct file *file, struct dir_context *ctx)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001335{
Feng Shuo4582a4a2013-01-15 11:23:28 +08001336 int plus, err;
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001337 size_t nbytes;
1338 struct page *page;
Al Viro496ad9a2013-01-23 17:07:38 -05001339 struct inode *inode = file_inode(file);
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001340 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi248d86e2006-01-06 00:19:39 -08001341 struct fuse_req *req;
Anand V. Avati0b05b182012-08-19 08:53:23 -04001342 u64 attr_version = 0;
Miklos Szeredi248d86e2006-01-06 00:19:39 -08001343
1344 if (is_bad_inode(inode))
1345 return -EIO;
1346
Maxim Patlasovb111c8c2012-10-26 19:48:30 +04001347 req = fuse_get_req(fc, 1);
Miklos Szeredice1d5a42006-04-10 22:54:58 -07001348 if (IS_ERR(req))
1349 return PTR_ERR(req);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001350
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001351 page = alloc_page(GFP_KERNEL);
1352 if (!page) {
1353 fuse_put_request(fc, req);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001354 return -ENOMEM;
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001355 }
Feng Shuo4582a4a2013-01-15 11:23:28 +08001356
Al Viro8d3af7f2013-05-18 03:03:58 -04001357 plus = fuse_use_readdirplus(inode, ctx);
Miklos Szeredif4975c62009-04-02 14:25:34 +02001358 req->out.argpages = 1;
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001359 req->num_pages = 1;
1360 req->pages[0] = page;
Maxim Patlasov85f40ae2012-10-26 19:49:33 +04001361 req->page_descs[0].length = PAGE_SIZE;
Feng Shuo4582a4a2013-01-15 11:23:28 +08001362 if (plus) {
Anand V. Avati0b05b182012-08-19 08:53:23 -04001363 attr_version = fuse_get_attr_version(fc);
Al Viro8d3af7f2013-05-18 03:03:58 -04001364 fuse_read_fill(req, file, ctx->pos, PAGE_SIZE,
Anand V. Avati0b05b182012-08-19 08:53:23 -04001365 FUSE_READDIRPLUS);
1366 } else {
Al Viro8d3af7f2013-05-18 03:03:58 -04001367 fuse_read_fill(req, file, ctx->pos, PAGE_SIZE,
Anand V. Avati0b05b182012-08-19 08:53:23 -04001368 FUSE_READDIR);
1369 }
Miklos Szeredi5c672ab2016-06-30 13:10:49 +02001370 fuse_lock_inode(inode);
Tejun Heob93f8582008-11-26 12:03:55 +01001371 fuse_request_send(fc, req);
Miklos Szeredi5c672ab2016-06-30 13:10:49 +02001372 fuse_unlock_inode(inode);
Miklos Szeredi361b1eb52006-01-16 22:14:45 -08001373 nbytes = req->out.args[0].size;
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001374 err = req->out.h.error;
1375 fuse_put_request(fc, req);
Anand V. Avati0b05b182012-08-19 08:53:23 -04001376 if (!err) {
Feng Shuo4582a4a2013-01-15 11:23:28 +08001377 if (plus) {
Anand V. Avati0b05b182012-08-19 08:53:23 -04001378 err = parse_dirplusfile(page_address(page), nbytes,
Al Viro8d3af7f2013-05-18 03:03:58 -04001379 file, ctx,
Anand V. Avati0b05b182012-08-19 08:53:23 -04001380 attr_version);
1381 } else {
1382 err = parse_dirfile(page_address(page), nbytes, file,
Al Viro8d3af7f2013-05-18 03:03:58 -04001383 ctx);
Anand V. Avati0b05b182012-08-19 08:53:23 -04001384 }
1385 }
Miklos Szeredie5e55582005-09-09 13:10:28 -07001386
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001387 __free_page(page);
Andrew Gallagher451418f2013-11-05 03:55:43 -08001388 fuse_invalidate_atime(inode);
Miklos Szeredi04730fe2005-09-09 13:10:36 -07001389 return err;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001390}
1391
Al Viro6b255392015-11-17 10:20:54 -05001392static const char *fuse_get_link(struct dentry *dentry,
Al Virofceef392015-12-29 15:58:39 -05001393 struct inode *inode,
1394 struct delayed_call *done)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001395{
Miklos Szeredie5e55582005-09-09 13:10:28 -07001396 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001397 FUSE_ARGS(args);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001398 char *link;
Miklos Szeredi70781872014-12-12 09:49:05 +01001399 ssize_t ret;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001400
Al Viro6b255392015-11-17 10:20:54 -05001401 if (!dentry)
1402 return ERR_PTR(-ECHILD);
1403
Al Virocd3417c2015-12-29 16:03:53 -05001404 link = kmalloc(PAGE_SIZE, GFP_KERNEL);
Miklos Szeredi70781872014-12-12 09:49:05 +01001405 if (!link)
1406 return ERR_PTR(-ENOMEM);
1407
1408 args.in.h.opcode = FUSE_READLINK;
1409 args.in.h.nodeid = get_node_id(inode);
1410 args.out.argvar = 1;
1411 args.out.numargs = 1;
1412 args.out.args[0].size = PAGE_SIZE - 1;
1413 args.out.args[0].value = link;
1414 ret = fuse_simple_request(fc, &args);
1415 if (ret < 0) {
Al Virocd3417c2015-12-29 16:03:53 -05001416 kfree(link);
Miklos Szeredi70781872014-12-12 09:49:05 +01001417 link = ERR_PTR(ret);
1418 } else {
1419 link[ret] = '\0';
Al Virofceef392015-12-29 15:58:39 -05001420 set_delayed_call(done, kfree_link, link);
Miklos Szeredi70781872014-12-12 09:49:05 +01001421 }
Andrew Gallagher451418f2013-11-05 03:55:43 -08001422 fuse_invalidate_atime(inode);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001423 return link;
1424}
1425
Miklos Szeredie5e55582005-09-09 13:10:28 -07001426static int fuse_dir_open(struct inode *inode, struct file *file)
1427{
Miklos Szeredi91fe96b2009-04-28 16:56:37 +02001428 return fuse_open_common(inode, file, true);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001429}
1430
1431static int fuse_dir_release(struct inode *inode, struct file *file)
1432{
Miklos Szeredi8b0797a2009-04-28 16:56:39 +02001433 fuse_release_common(file, FUSE_RELEASEDIR);
1434
1435 return 0;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001436}
1437
Josef Bacik02c24a82011-07-16 20:44:56 -04001438static int fuse_dir_fsync(struct file *file, loff_t start, loff_t end,
1439 int datasync)
Miklos Szeredi82547982005-09-09 13:10:38 -07001440{
Josef Bacik02c24a82011-07-16 20:44:56 -04001441 return fuse_fsync_common(file, start, end, datasync, 1);
Miklos Szeredi82547982005-09-09 13:10:38 -07001442}
1443
Miklos Szeredib18da0c2011-12-13 11:58:49 +01001444static long fuse_dir_ioctl(struct file *file, unsigned int cmd,
1445 unsigned long arg)
1446{
1447 struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1448
1449 /* FUSE_IOCTL_DIR only supported for API version >= 7.18 */
1450 if (fc->minor < 18)
1451 return -ENOTTY;
1452
1453 return fuse_ioctl_common(file, cmd, arg, FUSE_IOCTL_DIR);
1454}
1455
1456static long fuse_dir_compat_ioctl(struct file *file, unsigned int cmd,
1457 unsigned long arg)
1458{
1459 struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1460
1461 if (fc->minor < 18)
1462 return -ENOTTY;
1463
1464 return fuse_ioctl_common(file, cmd, arg,
1465 FUSE_IOCTL_COMPAT | FUSE_IOCTL_DIR);
1466}
1467
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001468static bool update_mtime(unsigned ivalid, bool trust_local_mtime)
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001469{
1470 /* Always update if mtime is explicitly set */
1471 if (ivalid & ATTR_MTIME_SET)
1472 return true;
1473
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001474 /* Or if kernel i_mtime is the official one */
1475 if (trust_local_mtime)
1476 return true;
1477
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001478 /* If it's an open(O_TRUNC) or an ftruncate(), don't update */
1479 if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE)))
1480 return false;
1481
1482 /* In all other cases update */
1483 return true;
1484}
1485
Eric W. Biederman8cb08322018-02-21 11:18:07 -06001486static void iattr_to_fattr(struct fuse_conn *fc, struct iattr *iattr,
1487 struct fuse_setattr_in *arg, bool trust_local_cmtime)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001488{
1489 unsigned ivalid = iattr->ia_valid;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001490
1491 if (ivalid & ATTR_MODE)
Miklos Szeredibefc6492005-11-07 00:59:52 -08001492 arg->valid |= FATTR_MODE, arg->mode = iattr->ia_mode;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001493 if (ivalid & ATTR_UID)
Eric W. Biederman8cb08322018-02-21 11:18:07 -06001494 arg->valid |= FATTR_UID, arg->uid = from_kuid(fc->user_ns, iattr->ia_uid);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001495 if (ivalid & ATTR_GID)
Eric W. Biederman8cb08322018-02-21 11:18:07 -06001496 arg->valid |= FATTR_GID, arg->gid = from_kgid(fc->user_ns, iattr->ia_gid);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001497 if (ivalid & ATTR_SIZE)
Miklos Szeredibefc6492005-11-07 00:59:52 -08001498 arg->valid |= FATTR_SIZE, arg->size = iattr->ia_size;
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001499 if (ivalid & ATTR_ATIME) {
1500 arg->valid |= FATTR_ATIME;
Miklos Szeredibefc6492005-11-07 00:59:52 -08001501 arg->atime = iattr->ia_atime.tv_sec;
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001502 arg->atimensec = iattr->ia_atime.tv_nsec;
1503 if (!(ivalid & ATTR_ATIME_SET))
1504 arg->valid |= FATTR_ATIME_NOW;
1505 }
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001506 if ((ivalid & ATTR_MTIME) && update_mtime(ivalid, trust_local_cmtime)) {
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001507 arg->valid |= FATTR_MTIME;
Miklos Szeredibefc6492005-11-07 00:59:52 -08001508 arg->mtime = iattr->ia_mtime.tv_sec;
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001509 arg->mtimensec = iattr->ia_mtime.tv_nsec;
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001510 if (!(ivalid & ATTR_MTIME_SET) && !trust_local_cmtime)
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001511 arg->valid |= FATTR_MTIME_NOW;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001512 }
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001513 if ((ivalid & ATTR_CTIME) && trust_local_cmtime) {
1514 arg->valid |= FATTR_CTIME;
1515 arg->ctime = iattr->ia_ctime.tv_sec;
1516 arg->ctimensec = iattr->ia_ctime.tv_nsec;
1517 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001518}
1519
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001520/*
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001521 * Prevent concurrent writepages on inode
1522 *
1523 * This is done by adding a negative bias to the inode write counter
1524 * and waiting for all pending writes to finish.
1525 */
1526void fuse_set_nowrite(struct inode *inode)
1527{
1528 struct fuse_conn *fc = get_fuse_conn(inode);
1529 struct fuse_inode *fi = get_fuse_inode(inode);
1530
Al Viro59551022016-01-22 15:40:57 -05001531 BUG_ON(!inode_is_locked(inode));
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001532
1533 spin_lock(&fc->lock);
1534 BUG_ON(fi->writectr < 0);
1535 fi->writectr += FUSE_NOWRITE;
1536 spin_unlock(&fc->lock);
1537 wait_event(fi->page_waitq, fi->writectr == FUSE_NOWRITE);
1538}
1539
1540/*
1541 * Allow writepages on inode
1542 *
1543 * Remove the bias from the writecounter and send any queued
1544 * writepages.
1545 */
1546static void __fuse_release_nowrite(struct inode *inode)
1547{
1548 struct fuse_inode *fi = get_fuse_inode(inode);
1549
1550 BUG_ON(fi->writectr != FUSE_NOWRITE);
1551 fi->writectr = 0;
1552 fuse_flush_writepages(inode);
1553}
1554
1555void fuse_release_nowrite(struct inode *inode)
1556{
1557 struct fuse_conn *fc = get_fuse_conn(inode);
1558
1559 spin_lock(&fc->lock);
1560 __fuse_release_nowrite(inode);
1561 spin_unlock(&fc->lock);
1562}
1563
Miklos Szeredi70781872014-12-12 09:49:05 +01001564static void fuse_setattr_fill(struct fuse_conn *fc, struct fuse_args *args,
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001565 struct inode *inode,
1566 struct fuse_setattr_in *inarg_p,
1567 struct fuse_attr_out *outarg_p)
1568{
Miklos Szeredi70781872014-12-12 09:49:05 +01001569 args->in.h.opcode = FUSE_SETATTR;
1570 args->in.h.nodeid = get_node_id(inode);
1571 args->in.numargs = 1;
1572 args->in.args[0].size = sizeof(*inarg_p);
1573 args->in.args[0].value = inarg_p;
1574 args->out.numargs = 1;
Miklos Szeredi21f62172015-01-06 10:45:35 +01001575 args->out.args[0].size = sizeof(*outarg_p);
Miklos Szeredi70781872014-12-12 09:49:05 +01001576 args->out.args[0].value = outarg_p;
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001577}
1578
1579/*
1580 * Flush inode->i_mtime to the server
1581 */
Maxim Patlasovab9e13f2014-04-28 14:19:24 +02001582int fuse_flush_times(struct inode *inode, struct fuse_file *ff)
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001583{
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001584 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001585 FUSE_ARGS(args);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001586 struct fuse_setattr_in inarg;
1587 struct fuse_attr_out outarg;
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001588
1589 memset(&inarg, 0, sizeof(inarg));
1590 memset(&outarg, 0, sizeof(outarg));
1591
Maxim Patlasovab9e13f2014-04-28 14:19:24 +02001592 inarg.valid = FATTR_MTIME;
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001593 inarg.mtime = inode->i_mtime.tv_sec;
1594 inarg.mtimensec = inode->i_mtime.tv_nsec;
Maxim Patlasovab9e13f2014-04-28 14:19:24 +02001595 if (fc->minor >= 23) {
1596 inarg.valid |= FATTR_CTIME;
1597 inarg.ctime = inode->i_ctime.tv_sec;
1598 inarg.ctimensec = inode->i_ctime.tv_nsec;
1599 }
Miklos Szeredi1e18bda2014-04-28 14:19:23 +02001600 if (ff) {
1601 inarg.valid |= FATTR_FH;
1602 inarg.fh = ff->fh;
1603 }
Miklos Szeredi70781872014-12-12 09:49:05 +01001604 fuse_setattr_fill(fc, &args, inode, &inarg, &outarg);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001605
Miklos Szeredi70781872014-12-12 09:49:05 +01001606 return fuse_simple_request(fc, &args);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001607}
1608
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001609/*
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001610 * Set attributes, and at the same time refresh them.
1611 *
1612 * Truncation is slightly complicated, because the 'truncate' request
1613 * may fail, in which case we don't want to touch the mapping.
Miklos Szeredi9ffbb912006-10-17 00:10:06 -07001614 * vmtruncate() doesn't allow for this case, so do the rlimit checking
1615 * and the actual truncation by hand.
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001616 */
Jan Kara62490332016-05-26 17:12:41 +02001617int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
Maxim Patlasovefb9fa92012-12-18 14:05:08 +04001618 struct file *file)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001619{
Jan Kara62490332016-05-26 17:12:41 +02001620 struct inode *inode = d_inode(dentry);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001621 struct fuse_conn *fc = get_fuse_conn(inode);
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001622 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001623 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001624 struct fuse_setattr_in inarg;
1625 struct fuse_attr_out outarg;
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001626 bool is_truncate = false;
Pavel Emelyanov83732002013-10-10 17:10:46 +04001627 bool is_wb = fc->writeback_cache;
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001628 loff_t oldsize;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001629 int err;
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001630 bool trust_local_cmtime = is_wb && S_ISREG(inode->i_mode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001631
Miklos Szeredi29433a22016-10-01 07:32:32 +02001632 if (!fc->default_permissions)
Christoph Hellwigdb78b872010-06-04 11:30:03 +02001633 attr->ia_valid |= ATTR_FORCE;
1634
Jan Kara31051c82016-05-26 16:55:18 +02001635 err = setattr_prepare(dentry, attr);
Christoph Hellwigdb78b872010-06-04 11:30:03 +02001636 if (err)
1637 return err;
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001638
Miklos Szeredi8d56add2011-02-25 14:44:58 +01001639 if (attr->ia_valid & ATTR_OPEN) {
Miklos Szeredidf0e91d2018-02-08 15:17:38 +01001640 /* This is coming from open(..., ... | O_TRUNC); */
1641 WARN_ON(!(attr->ia_valid & ATTR_SIZE));
1642 WARN_ON(attr->ia_size != 0);
1643 if (fc->atomic_o_trunc) {
1644 /*
1645 * No need to send request to userspace, since actual
1646 * truncation has already been done by OPEN. But still
1647 * need to truncate page cache.
1648 */
1649 i_size_write(inode, 0);
1650 truncate_pagecache(inode, 0);
Miklos Szeredi8d56add2011-02-25 14:44:58 +01001651 return 0;
Miklos Szeredidf0e91d2018-02-08 15:17:38 +01001652 }
Miklos Szeredi8d56add2011-02-25 14:44:58 +01001653 file = NULL;
1654 }
Miklos Szeredi6ff958e2007-10-18 03:07:02 -07001655
Christoph Hellwig2c27c652010-06-04 11:30:04 +02001656 if (attr->ia_valid & ATTR_SIZE)
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001657 is_truncate = true;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001658
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001659 if (is_truncate) {
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001660 fuse_set_nowrite(inode);
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001661 set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001662 if (trust_local_cmtime && attr->ia_size != inode->i_size)
1663 attr->ia_valid |= ATTR_MTIME | ATTR_CTIME;
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001664 }
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001665
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001666 memset(&inarg, 0, sizeof(inarg));
Miklos Szeredi0e9663e2007-10-18 03:07:05 -07001667 memset(&outarg, 0, sizeof(outarg));
Eric W. Biederman8cb08322018-02-21 11:18:07 -06001668 iattr_to_fattr(fc, attr, &inarg, trust_local_cmtime);
Miklos Szeredi49d49142007-10-18 03:07:00 -07001669 if (file) {
1670 struct fuse_file *ff = file->private_data;
1671 inarg.valid |= FATTR_FH;
1672 inarg.fh = ff->fh;
1673 }
Miklos Szeredif3332112007-10-18 03:07:04 -07001674 if (attr->ia_valid & ATTR_SIZE) {
1675 /* For mandatory locking in truncate */
1676 inarg.valid |= FATTR_LOCKOWNER;
1677 inarg.lock_owner = fuse_lock_owner_id(fc, current->files);
1678 }
Miklos Szeredi70781872014-12-12 09:49:05 +01001679 fuse_setattr_fill(fc, &args, inode, &inarg, &outarg);
1680 err = fuse_simple_request(fc, &args);
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001681 if (err) {
1682 if (err == -EINTR)
1683 fuse_invalidate_attr(inode);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001684 goto error;
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001685 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001686
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001687 if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
1688 make_bad_inode(inode);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001689 err = -EIO;
1690 goto error;
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001691 }
1692
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001693 spin_lock(&fc->lock);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001694 /* the kernel maintains i_mtime locally */
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001695 if (trust_local_cmtime) {
1696 if (attr->ia_valid & ATTR_MTIME)
1697 inode->i_mtime = attr->ia_mtime;
1698 if (attr->ia_valid & ATTR_CTIME)
1699 inode->i_ctime = attr->ia_ctime;
Miklos Szeredi1e18bda2014-04-28 14:19:23 +02001700 /* FIXME: clear I_DIRTY_SYNC? */
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001701 }
1702
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001703 fuse_change_attributes_common(inode, &outarg.attr,
1704 attr_timeout(&outarg));
1705 oldsize = inode->i_size;
Pavel Emelyanov83732002013-10-10 17:10:46 +04001706 /* see the comment in fuse_change_attributes() */
1707 if (!is_wb || is_truncate || !S_ISREG(inode->i_mode))
1708 i_size_write(inode, outarg.attr.size);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001709
1710 if (is_truncate) {
1711 /* NOTE: this may release/reacquire fc->lock */
1712 __fuse_release_nowrite(inode);
1713 }
1714 spin_unlock(&fc->lock);
1715
1716 /*
1717 * Only call invalidate_inode_pages2() after removing
1718 * FUSE_NOWRITE, otherwise fuse_launder_page() would deadlock.
1719 */
Pavel Emelyanov83732002013-10-10 17:10:46 +04001720 if ((is_truncate || !is_wb) &&
1721 S_ISREG(inode->i_mode) && oldsize != outarg.attr.size) {
Kirill A. Shutemov7caef262013-09-12 15:13:56 -07001722 truncate_pagecache(inode, outarg.attr.size);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001723 invalidate_inode_pages2(inode->i_mapping);
1724 }
1725
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001726 clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001727 return 0;
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001728
1729error:
1730 if (is_truncate)
1731 fuse_release_nowrite(inode);
1732
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001733 clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001734 return err;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001735}
1736
Miklos Szeredi49d49142007-10-18 03:07:00 -07001737static int fuse_setattr(struct dentry *entry, struct iattr *attr)
1738{
David Howells2b0143b2015-03-17 22:25:59 +00001739 struct inode *inode = d_inode(entry);
Miklos Szeredi5e940c12016-10-01 07:32:32 +02001740 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredia09f99e2016-10-01 07:32:32 +02001741 struct file *file = (attr->ia_valid & ATTR_FILE) ? attr->ia_file : NULL;
Miklos Szeredi5e2b8822016-10-01 07:32:32 +02001742 int ret;
Maxim Patlasovefb9fa92012-12-18 14:05:08 +04001743
1744 if (!fuse_allow_current_process(get_fuse_conn(inode)))
1745 return -EACCES;
1746
Miklos Szeredia09f99e2016-10-01 07:32:32 +02001747 if (attr->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) {
Miklos Szeredia09f99e2016-10-01 07:32:32 +02001748 attr->ia_valid &= ~(ATTR_KILL_SUID | ATTR_KILL_SGID |
1749 ATTR_MODE);
Miklos Szeredia09f99e2016-10-01 07:32:32 +02001750
Miklos Szeredi5e940c12016-10-01 07:32:32 +02001751 /*
1752 * The only sane way to reliably kill suid/sgid is to do it in
1753 * the userspace filesystem
1754 *
1755 * This should be done on write(), truncate() and chown().
1756 */
1757 if (!fc->handle_killpriv) {
Miklos Szeredi5e940c12016-10-01 07:32:32 +02001758 /*
1759 * ia_mode calculation may have used stale i_mode.
1760 * Refresh and recalculate.
1761 */
1762 ret = fuse_do_getattr(inode, NULL, file);
1763 if (ret)
1764 return ret;
1765
1766 attr->ia_mode = inode->i_mode;
Miklos Szeredic01638f2016-12-06 16:18:45 +01001767 if (inode->i_mode & S_ISUID) {
Miklos Szeredi5e940c12016-10-01 07:32:32 +02001768 attr->ia_valid |= ATTR_MODE;
1769 attr->ia_mode &= ~S_ISUID;
1770 }
Miklos Szeredic01638f2016-12-06 16:18:45 +01001771 if ((inode->i_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
Miklos Szeredi5e940c12016-10-01 07:32:32 +02001772 attr->ia_valid |= ATTR_MODE;
1773 attr->ia_mode &= ~S_ISGID;
1774 }
Miklos Szeredia09f99e2016-10-01 07:32:32 +02001775 }
1776 }
1777 if (!attr->ia_valid)
1778 return 0;
1779
Linus Torvaldsabb5a142016-10-10 13:04:49 -07001780 ret = fuse_do_setattr(entry, attr, file);
Miklos Szeredi5e2b8822016-10-01 07:32:32 +02001781 if (!ret) {
Seth Forshee60bcc882016-08-29 08:46:37 -05001782 /*
1783 * If filesystem supports acls it may have updated acl xattrs in
1784 * the filesystem, so forget cached acls for the inode.
1785 */
1786 if (fc->posix_acl)
1787 forget_all_cached_acls(inode);
1788
Miklos Szeredi5e2b8822016-10-01 07:32:32 +02001789 /* Directory mode changed, may need to revalidate access */
1790 if (d_is_dir(entry) && (attr->ia_valid & ATTR_MODE))
1791 fuse_invalidate_entry_cache(entry);
1792 }
1793 return ret;
Miklos Szeredi49d49142007-10-18 03:07:00 -07001794}
1795
David Howellsa528d352017-01-31 16:46:22 +00001796static int fuse_getattr(const struct path *path, struct kstat *stat,
1797 u32 request_mask, unsigned int flags)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001798{
David Howellsa528d352017-01-31 16:46:22 +00001799 struct inode *inode = d_inode(path->dentry);
Miklos Szeredi244f6382007-10-16 23:31:02 -07001800 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi244f6382007-10-16 23:31:02 -07001801
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001802 if (!fuse_allow_current_process(fc))
Miklos Szeredi244f6382007-10-16 23:31:02 -07001803 return -EACCES;
1804
Miklos Szerediff1b89f2018-03-20 17:11:44 +01001805 return fuse_update_get_attr(inode, NULL, stat, flags);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001806}
1807
Arjan van de Ven754661f2007-02-12 00:55:38 -08001808static const struct inode_operations fuse_dir_inode_operations = {
Miklos Szeredie5e55582005-09-09 13:10:28 -07001809 .lookup = fuse_lookup,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001810 .mkdir = fuse_mkdir,
1811 .symlink = fuse_symlink,
1812 .unlink = fuse_unlink,
1813 .rmdir = fuse_rmdir,
Miklos Szeredi2773bf02016-09-27 11:03:58 +02001814 .rename = fuse_rename2,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001815 .link = fuse_link,
1816 .setattr = fuse_setattr,
1817 .create = fuse_create,
Miklos Szeredic8ccbe02012-06-05 15:10:22 +02001818 .atomic_open = fuse_atomic_open,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001819 .mknod = fuse_mknod,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001820 .permission = fuse_permission,
1821 .getattr = fuse_getattr,
Miklos Szeredi92a87802005-09-09 13:10:31 -07001822 .listxattr = fuse_listxattr,
Seth Forshee60bcc882016-08-29 08:46:37 -05001823 .get_acl = fuse_get_acl,
1824 .set_acl = fuse_set_acl,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001825};
1826
Arjan van de Ven4b6f5d22006-03-28 01:56:42 -08001827static const struct file_operations fuse_dir_operations = {
Miklos Szeredib6aeade2005-09-09 13:10:30 -07001828 .llseek = generic_file_llseek,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001829 .read = generic_read_dir,
Al Virod9b3dbd2016-04-20 17:30:32 -04001830 .iterate_shared = fuse_readdir,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001831 .open = fuse_dir_open,
1832 .release = fuse_dir_release,
Miklos Szeredi82547982005-09-09 13:10:38 -07001833 .fsync = fuse_dir_fsync,
Miklos Szeredib18da0c2011-12-13 11:58:49 +01001834 .unlocked_ioctl = fuse_dir_ioctl,
1835 .compat_ioctl = fuse_dir_compat_ioctl,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001836};
1837
Arjan van de Ven754661f2007-02-12 00:55:38 -08001838static const struct inode_operations fuse_common_inode_operations = {
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001839 .setattr = fuse_setattr,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001840 .permission = fuse_permission,
1841 .getattr = fuse_getattr,
Miklos Szeredi92a87802005-09-09 13:10:31 -07001842 .listxattr = fuse_listxattr,
Seth Forshee60bcc882016-08-29 08:46:37 -05001843 .get_acl = fuse_get_acl,
1844 .set_acl = fuse_set_acl,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001845};
1846
Arjan van de Ven754661f2007-02-12 00:55:38 -08001847static const struct inode_operations fuse_symlink_inode_operations = {
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001848 .setattr = fuse_setattr,
Al Viro6b255392015-11-17 10:20:54 -05001849 .get_link = fuse_get_link,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001850 .getattr = fuse_getattr,
Miklos Szeredi92a87802005-09-09 13:10:31 -07001851 .listxattr = fuse_listxattr,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001852};
1853
1854void fuse_init_common(struct inode *inode)
1855{
1856 inode->i_op = &fuse_common_inode_operations;
1857}
1858
1859void fuse_init_dir(struct inode *inode)
1860{
1861 inode->i_op = &fuse_dir_inode_operations;
1862 inode->i_fop = &fuse_dir_operations;
1863}
1864
1865void fuse_init_symlink(struct inode *inode)
1866{
1867 inode->i_op = &fuse_symlink_inode_operations;
1868}