blob: dd0f64f7bc060d85158aaacd85036f2679898e78 [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>
Miklos Szeredi261aaba72018-10-01 10:07:05 +020017#include <linux/iversion.h>
Seth Forshee60bcc882016-08-29 08:46:37 -050018#include <linux/posix_acl.h>
Miklos Szeredie5e55582005-09-09 13:10:28 -070019
Feng Shuo4582a4a2013-01-15 11:23:28 +080020static void fuse_advise_use_readdirplus(struct inode *dir)
21{
22 struct fuse_inode *fi = get_fuse_inode(dir);
23
24 set_bit(FUSE_I_ADVISE_RDPLUS, &fi->state);
25}
26
Miklos Szeredif75fdf22016-10-01 07:32:32 +020027union fuse_dentry {
28 u64 time;
29 struct rcu_head rcu;
30};
31
Miklos Szeredi0a0898c2006-07-30 03:04:10 -070032static inline void fuse_dentry_settime(struct dentry *entry, u64 time)
33{
Miklos Szeredif75fdf22016-10-01 07:32:32 +020034 ((union fuse_dentry *) entry->d_fsdata)->time = time;
Miklos Szeredi0a0898c2006-07-30 03:04:10 -070035}
36
37static inline u64 fuse_dentry_time(struct dentry *entry)
38{
Miklos Szeredif75fdf22016-10-01 07:32:32 +020039 return ((union fuse_dentry *) entry->d_fsdata)->time;
Miklos Szeredi0a0898c2006-07-30 03:04:10 -070040}
Miklos Szeredi0a0898c2006-07-30 03:04:10 -070041
Miklos Szeredi6f9f1182006-01-06 00:19:39 -080042/*
43 * FUSE caches dentries and attributes with separate timeout. The
44 * time in jiffies until the dentry/attributes are valid is stored in
Miklos Szeredif75fdf22016-10-01 07:32:32 +020045 * dentry->d_fsdata and fuse_inode->i_time respectively.
Miklos Szeredi6f9f1182006-01-06 00:19:39 -080046 */
47
48/*
49 * Calculate the time in jiffies until a dentry/attributes are valid
50 */
Miklos Szeredibcb6f6d2016-10-01 07:32:32 +020051static u64 time_to_jiffies(u64 sec, u32 nsec)
Miklos Szeredie5e55582005-09-09 13:10:28 -070052{
Miklos Szeredi685d16d2006-07-30 03:04:08 -070053 if (sec || nsec) {
Miklos Szeredibcb6f6d2016-10-01 07:32:32 +020054 struct timespec64 ts = {
55 sec,
David Sheets21067522017-01-13 15:58:30 +000056 min_t(u32, nsec, NSEC_PER_SEC - 1)
Miklos Szeredibcb6f6d2016-10-01 07:32:32 +020057 };
58
59 return get_jiffies_64() + timespec64_to_jiffies(&ts);
Miklos Szeredi685d16d2006-07-30 03:04:08 -070060 } else
Miklos Szeredi0a0898c2006-07-30 03:04:10 -070061 return 0;
Miklos Szeredie5e55582005-09-09 13:10:28 -070062}
63
Miklos Szeredi6f9f1182006-01-06 00:19:39 -080064/*
65 * Set dentry and possibly attribute timeouts from the lookup/mk*
66 * replies
67 */
Miklos Szeredid123d8e2018-09-28 16:43:23 +020068void fuse_change_entry_timeout(struct dentry *entry, struct fuse_entry_out *o)
Miklos Szeredi0aa7c692006-01-06 00:19:34 -080069{
Miklos Szeredi0a0898c2006-07-30 03:04:10 -070070 fuse_dentry_settime(entry,
71 time_to_jiffies(o->entry_valid, o->entry_valid_nsec));
Miklos Szeredi1fb69e72007-10-18 03:06:58 -070072}
73
74static u64 attr_timeout(struct fuse_attr_out *o)
75{
76 return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
77}
78
Miklos Szeredid123d8e2018-09-28 16:43:23 +020079u64 entry_attr_timeout(struct fuse_entry_out *o)
Miklos Szeredi1fb69e72007-10-18 03:06:58 -070080{
81 return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -080082}
83
Miklos Szeredi2f1e8192018-10-15 15:43:06 +020084static void fuse_invalidate_attr_mask(struct inode *inode, u32 mask)
85{
86 set_mask_bits(&get_fuse_inode(inode)->inval_mask, 0, mask);
87}
88
Miklos Szeredi6f9f1182006-01-06 00:19:39 -080089/*
90 * Mark the attributes as stale, so that at the next call to
91 * ->getattr() they will be fetched from userspace
92 */
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -080093void fuse_invalidate_attr(struct inode *inode)
94{
Miklos Szeredi2f1e8192018-10-15 15:43:06 +020095 fuse_invalidate_attr_mask(inode, STATX_BASIC_STATS);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -080096}
97
Miklos Szeredi261aaba72018-10-01 10:07:05 +020098static void fuse_dir_changed(struct inode *dir)
99{
100 fuse_invalidate_attr(dir);
101 inode_maybe_inc_iversion(dir, false);
102}
103
Andrew Gallagher451418f2013-11-05 03:55:43 -0800104/**
105 * Mark the attributes as stale due to an atime change. Avoid the invalidate if
106 * atime is not used.
107 */
108void fuse_invalidate_atime(struct inode *inode)
109{
110 if (!IS_RDONLY(inode))
Miklos Szeredi2f1e8192018-10-15 15:43:06 +0200111 fuse_invalidate_attr_mask(inode, STATX_ATIME);
Andrew Gallagher451418f2013-11-05 03:55:43 -0800112}
113
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800114/*
115 * Just mark the entry as stale, so that a next attempt to look it up
116 * will result in a new lookup call to userspace
117 *
118 * This is called when a dentry is about to become negative and the
119 * timeout is unknown (unlink, rmdir, rename and in some cases
120 * lookup)
121 */
Miklos Szeredidbd561d2008-07-25 01:49:00 -0700122void fuse_invalidate_entry_cache(struct dentry *entry)
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800123{
Miklos Szeredi0a0898c2006-07-30 03:04:10 -0700124 fuse_dentry_settime(entry, 0);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800125}
126
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800127/*
128 * Same as fuse_invalidate_entry_cache(), but also try to remove the
129 * dentry from the hash
130 */
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800131static void fuse_invalidate_entry(struct dentry *entry)
132{
133 d_invalidate(entry);
134 fuse_invalidate_entry_cache(entry);
Miklos Szeredi0aa7c692006-01-06 00:19:34 -0800135}
136
Miklos Szeredi70781872014-12-12 09:49:05 +0100137static void fuse_lookup_init(struct fuse_conn *fc, struct fuse_args *args,
Al Viro13983d02016-07-20 22:34:44 -0400138 u64 nodeid, const struct qstr *name,
Miklos Szeredie5e55582005-09-09 13:10:28 -0700139 struct fuse_entry_out *outarg)
140{
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700141 memset(outarg, 0, sizeof(struct fuse_entry_out));
Miklos Szeredi70781872014-12-12 09:49:05 +0100142 args->in.h.opcode = FUSE_LOOKUP;
143 args->in.h.nodeid = nodeid;
144 args->in.numargs = 1;
145 args->in.args[0].size = name->len + 1;
146 args->in.args[0].value = name->name;
147 args->out.numargs = 1;
Miklos Szeredi21f62172015-01-06 10:45:35 +0100148 args->out.args[0].size = sizeof(struct fuse_entry_out);
Miklos Szeredi70781872014-12-12 09:49:05 +0100149 args->out.args[0].value = outarg;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700150}
151
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800152/*
153 * Check whether the dentry is still valid
154 *
155 * If the entry validity timeout has expired and the dentry is
156 * positive, try to redo the lookup. If the lookup results in a
157 * different inode, then let the VFS invalidate the dentry and redo
158 * the lookup once more. If the lookup results in the same inode,
159 * then refresh the attributes, timeouts and mark the dentry valid.
160 */
Al Viro0b728e12012-06-10 16:03:43 -0400161static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
Miklos Szeredie5e55582005-09-09 13:10:28 -0700162{
Nick Piggin34286d62011-01-07 17:49:57 +1100163 struct inode *inode;
Miklos Szeredi28420da2013-06-03 14:40:22 +0200164 struct dentry *parent;
165 struct fuse_conn *fc;
Miklos Szeredi6314efe2013-10-01 16:41:22 +0200166 struct fuse_inode *fi;
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200167 int ret;
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800168
David Howells2b0143b2015-03-17 22:25:59 +0000169 inode = d_inode_rcu(entry);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800170 if (inode && is_bad_inode(inode))
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200171 goto invalid;
Anand Avati154210c2014-06-26 20:21:57 -0400172 else if (time_before64(fuse_dentry_time(entry), get_jiffies_64()) ||
173 (flags & LOOKUP_REVAL)) {
Miklos Szeredie5e55582005-09-09 13:10:28 -0700174 struct fuse_entry_out outarg;
Miklos Szeredi70781872014-12-12 09:49:05 +0100175 FUSE_ARGS(args);
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100176 struct fuse_forget_link *forget;
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700177 u64 attr_version;
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800178
Miklos Szeredi50322fe2006-02-28 16:59:03 -0800179 /* For negative dentries, always do a fresh lookup */
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800180 if (!inode)
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200181 goto invalid;
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800182
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200183 ret = -ECHILD;
Al Viro0b728e12012-06-10 16:03:43 -0400184 if (flags & LOOKUP_RCU)
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200185 goto out;
Miklos Szeredie7c0a162011-03-21 13:58:06 +0100186
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800187 fc = get_fuse_conn(inode);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700188
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100189 forget = fuse_alloc_forget();
Miklos Szeredi70781872014-12-12 09:49:05 +0100190 ret = -ENOMEM;
191 if (!forget)
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200192 goto out;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800193
Miklos Szeredi7dca9fd2007-11-28 16:21:59 -0800194 attr_version = fuse_get_attr_version(fc);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700195
Miklos Szeredie956edd2006-10-17 00:10:12 -0700196 parent = dget_parent(entry);
David Howells2b0143b2015-03-17 22:25:59 +0000197 fuse_lookup_init(fc, &args, get_node_id(d_inode(parent)),
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700198 &entry->d_name, &outarg);
Miklos Szeredi70781872014-12-12 09:49:05 +0100199 ret = fuse_simple_request(fc, &args);
Miklos Szeredie956edd2006-10-17 00:10:12 -0700200 dput(parent);
Miklos Szeredi50322fe2006-02-28 16:59:03 -0800201 /* Zero nodeid is same as -ENOENT */
Miklos Szeredi70781872014-12-12 09:49:05 +0100202 if (!ret && !outarg.nodeid)
203 ret = -ENOENT;
204 if (!ret) {
Miklos Szeredi6314efe2013-10-01 16:41:22 +0200205 fi = get_fuse_inode(inode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700206 if (outarg.nodeid != get_node_id(inode)) {
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100207 fuse_queue_forget(fc, forget, outarg.nodeid, 1);
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200208 goto invalid;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700209 }
Kirill Tkhaic9d8f5f2018-11-09 13:33:27 +0300210 spin_lock(&fi->lock);
Miklos Szeredi1729a162008-11-26 12:03:54 +0100211 fi->nlookup++;
Kirill Tkhaic9d8f5f2018-11-09 13:33:27 +0300212 spin_unlock(&fi->lock);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700213 }
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100214 kfree(forget);
Miklos Szeredi70781872014-12-12 09:49:05 +0100215 if (ret == -ENOMEM)
216 goto out;
217 if (ret || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200218 goto invalid;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700219
Seth Forshee60bcc882016-08-29 08:46:37 -0500220 forget_all_cached_acls(inode);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700221 fuse_change_attributes(inode, &outarg.attr,
222 entry_attr_timeout(&outarg),
223 attr_version);
224 fuse_change_entry_timeout(entry, &outarg);
Miklos Szeredi28420da2013-06-03 14:40:22 +0200225 } else if (inode) {
Miklos Szeredi6314efe2013-10-01 16:41:22 +0200226 fi = get_fuse_inode(inode);
227 if (flags & LOOKUP_RCU) {
228 if (test_bit(FUSE_I_INIT_RDPLUS, &fi->state))
229 return -ECHILD;
230 } else if (test_and_clear_bit(FUSE_I_INIT_RDPLUS, &fi->state)) {
Miklos Szeredi28420da2013-06-03 14:40:22 +0200231 parent = dget_parent(entry);
David Howells2b0143b2015-03-17 22:25:59 +0000232 fuse_advise_use_readdirplus(d_inode(parent));
Miklos Szeredi28420da2013-06-03 14:40:22 +0200233 dput(parent);
234 }
Miklos Szeredie5e55582005-09-09 13:10:28 -0700235 }
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200236 ret = 1;
237out:
238 return ret;
239
240invalid:
241 ret = 0;
242 goto out;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700243}
244
Miklos Szeredif75fdf22016-10-01 07:32:32 +0200245static int fuse_dentry_init(struct dentry *dentry)
246{
247 dentry->d_fsdata = kzalloc(sizeof(union fuse_dentry), GFP_KERNEL);
248
249 return dentry->d_fsdata ? 0 : -ENOMEM;
250}
251static void fuse_dentry_release(struct dentry *dentry)
252{
253 union fuse_dentry *fd = dentry->d_fsdata;
254
255 kfree_rcu(fd, rcu);
256}
257
Al Viro42695902009-02-20 05:59:13 +0000258const struct dentry_operations fuse_dentry_operations = {
Miklos Szeredie5e55582005-09-09 13:10:28 -0700259 .d_revalidate = fuse_dentry_revalidate,
Miklos Szeredif75fdf22016-10-01 07:32:32 +0200260 .d_init = fuse_dentry_init,
261 .d_release = fuse_dentry_release,
Miklos Szeredie5e55582005-09-09 13:10:28 -0700262};
263
Miklos Szeredi0ce267f2016-10-18 15:36:48 +0200264const struct dentry_operations fuse_root_dentry_operations = {
265 .d_init = fuse_dentry_init,
266 .d_release = fuse_dentry_release,
267};
268
Timo Savolaa5bfffac2007-04-08 16:04:00 -0700269int fuse_valid_type(int m)
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800270{
271 return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) ||
272 S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
273}
274
Al Viro13983d02016-07-20 22:34:44 -0400275int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name,
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700276 struct fuse_entry_out *outarg, struct inode **inode)
277{
278 struct fuse_conn *fc = get_fuse_conn_super(sb);
Miklos Szeredi70781872014-12-12 09:49:05 +0100279 FUSE_ARGS(args);
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100280 struct fuse_forget_link *forget;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700281 u64 attr_version;
282 int err;
283
284 *inode = NULL;
285 err = -ENAMETOOLONG;
286 if (name->len > FUSE_NAME_MAX)
287 goto out;
288
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700289
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100290 forget = fuse_alloc_forget();
291 err = -ENOMEM;
Miklos Szeredi70781872014-12-12 09:49:05 +0100292 if (!forget)
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700293 goto out;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700294
295 attr_version = fuse_get_attr_version(fc);
296
Miklos Szeredi70781872014-12-12 09:49:05 +0100297 fuse_lookup_init(fc, &args, nodeid, name, outarg);
298 err = fuse_simple_request(fc, &args);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700299 /* Zero nodeid is same as -ENOENT, but with valid timeout */
300 if (err || !outarg->nodeid)
301 goto out_put_forget;
302
303 err = -EIO;
304 if (!outarg->nodeid)
305 goto out_put_forget;
306 if (!fuse_valid_type(outarg->attr.mode))
307 goto out_put_forget;
308
309 *inode = fuse_iget(sb, outarg->nodeid, outarg->generation,
310 &outarg->attr, entry_attr_timeout(outarg),
311 attr_version);
312 err = -ENOMEM;
313 if (!*inode) {
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100314 fuse_queue_forget(fc, forget, outarg->nodeid, 1);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700315 goto out;
316 }
317 err = 0;
318
319 out_put_forget:
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100320 kfree(forget);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700321 out:
322 return err;
323}
324
Miklos Szeredi0aa7c692006-01-06 00:19:34 -0800325static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
Al Viro00cd8dd2012-06-10 17:13:09 -0400326 unsigned int flags)
Miklos Szeredie5e55582005-09-09 13:10:28 -0700327{
328 int err;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700329 struct fuse_entry_out outarg;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700330 struct inode *inode;
Miklos Szeredi0de62562008-07-25 01:48:59 -0700331 struct dentry *newent;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700332 bool outarg_valid = true;
Miklos Szeredi63576c12018-07-26 16:13:11 +0200333 bool locked;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700334
Miklos Szeredi63576c12018-07-26 16:13:11 +0200335 locked = fuse_lock_inode(dir);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700336 err = fuse_lookup_name(dir->i_sb, get_node_id(dir), &entry->d_name,
337 &outarg, &inode);
Miklos Szeredi63576c12018-07-26 16:13:11 +0200338 fuse_unlock_inode(dir, locked);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700339 if (err == -ENOENT) {
340 outarg_valid = false;
341 err = 0;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800342 }
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700343 if (err)
344 goto out_err;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800345
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700346 err = -EIO;
347 if (inode && get_node_id(inode) == FUSE_ROOT_ID)
348 goto out_iput;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700349
Al Viro41d28bc2014-10-12 22:24:21 -0400350 newent = d_splice_alias(inode, entry);
Miklos Szeredi5835f332013-09-05 11:44:42 +0200351 err = PTR_ERR(newent);
352 if (IS_ERR(newent))
353 goto out_err;
Miklos Szeredid2a85162006-10-17 00:10:11 -0700354
Miklos Szeredi0de62562008-07-25 01:48:59 -0700355 entry = newent ? newent : entry;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700356 if (outarg_valid)
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700357 fuse_change_entry_timeout(entry, &outarg);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800358 else
359 fuse_invalidate_entry_cache(entry);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700360
Feng Shuo4582a4a2013-01-15 11:23:28 +0800361 fuse_advise_use_readdirplus(dir);
Miklos Szeredi0de62562008-07-25 01:48:59 -0700362 return newent;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700363
364 out_iput:
365 iput(inode);
366 out_err:
367 return ERR_PTR(err);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700368}
369
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800370/*
371 * Atomic create+open operation
372 *
373 * If the filesystem doesn't support this, then fall back to separate
374 * 'mknod' + 'open' requests.
375 */
Al Virod9585272012-06-22 12:39:14 +0400376static int fuse_create_open(struct inode *dir, struct dentry *entry,
Al Viro30d90492012-06-22 12:40:19 +0400377 struct file *file, unsigned flags,
Al Virob452a452018-06-08 13:06:28 -0400378 umode_t mode)
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800379{
380 int err;
381 struct inode *inode;
382 struct fuse_conn *fc = get_fuse_conn(dir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100383 FUSE_ARGS(args);
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100384 struct fuse_forget_link *forget;
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200385 struct fuse_create_in inarg;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800386 struct fuse_open_out outopen;
387 struct fuse_entry_out outentry;
Kirill Tkhaiebf84d02018-11-09 13:33:11 +0300388 struct fuse_inode *fi;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800389 struct fuse_file *ff;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800390
Miklos Szerediaf109bc2012-08-15 13:01:24 +0200391 /* Userspace expects S_IFREG in create mode */
392 BUG_ON((mode & S_IFMT) != S_IFREG);
393
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100394 forget = fuse_alloc_forget();
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200395 err = -ENOMEM;
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100396 if (!forget)
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200397 goto out_err;
Miklos Szeredi51eb01e2006-06-25 05:48:50 -0700398
Miklos Szeredice1d5a42006-04-10 22:54:58 -0700399 err = -ENOMEM;
Tejun Heoacf99432008-11-26 12:03:55 +0100400 ff = fuse_file_alloc(fc);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800401 if (!ff)
Miklos Szeredi70781872014-12-12 09:49:05 +0100402 goto out_put_forget_req;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800403
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200404 if (!fc->dont_mask)
405 mode &= ~current_umask();
406
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800407 flags &= ~O_NOCTTY;
408 memset(&inarg, 0, sizeof(inarg));
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700409 memset(&outentry, 0, sizeof(outentry));
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800410 inarg.flags = flags;
411 inarg.mode = mode;
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200412 inarg.umask = current_umask();
Miklos Szeredi70781872014-12-12 09:49:05 +0100413 args.in.h.opcode = FUSE_CREATE;
414 args.in.h.nodeid = get_node_id(dir);
415 args.in.numargs = 2;
Miklos Szeredi21f62172015-01-06 10:45:35 +0100416 args.in.args[0].size = sizeof(inarg);
Miklos Szeredi70781872014-12-12 09:49:05 +0100417 args.in.args[0].value = &inarg;
418 args.in.args[1].size = entry->d_name.len + 1;
419 args.in.args[1].value = entry->d_name.name;
420 args.out.numargs = 2;
Miklos Szeredi21f62172015-01-06 10:45:35 +0100421 args.out.args[0].size = sizeof(outentry);
Miklos Szeredi70781872014-12-12 09:49:05 +0100422 args.out.args[0].value = &outentry;
423 args.out.args[1].size = sizeof(outopen);
424 args.out.args[1].value = &outopen;
425 err = fuse_simple_request(fc, &args);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200426 if (err)
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800427 goto out_free_ff;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800428
429 err = -EIO;
Miklos Szeredi2827d0b22005-11-28 13:44:16 -0800430 if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid))
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800431 goto out_free_ff;
432
Miklos Szeredic7b71432009-04-28 16:56:37 +0200433 ff->fh = outopen.fh;
434 ff->nodeid = outentry.nodeid;
435 ff->open_flags = outopen.open_flags;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800436 inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700437 &outentry.attr, entry_attr_timeout(&outentry), 0);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800438 if (!inode) {
439 flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
Kirill Tkhaiebf84d02018-11-09 13:33:11 +0300440 fuse_sync_release(NULL, ff, flags);
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100441 fuse_queue_forget(fc, forget, outentry.nodeid, 1);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200442 err = -ENOMEM;
443 goto out_err;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800444 }
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100445 kfree(forget);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800446 d_instantiate(entry, inode);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700447 fuse_change_entry_timeout(entry, &outentry);
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200448 fuse_dir_changed(dir);
Al Virobe12af32018-06-08 11:44:56 -0400449 err = finish_open(file, entry, generic_file_open);
Al Viro30d90492012-06-22 12:40:19 +0400450 if (err) {
Kirill Tkhaiebf84d02018-11-09 13:33:11 +0300451 fi = get_fuse_inode(inode);
452 fuse_sync_release(fi, ff, flags);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200453 } else {
Miklos Szeredi267d8442017-02-22 20:08:25 +0100454 file->private_data = ff;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200455 fuse_finish_open(inode, file);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800456 }
Al Virod9585272012-06-22 12:39:14 +0400457 return err;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800458
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200459out_free_ff:
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800460 fuse_file_free(ff);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200461out_put_forget_req:
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100462 kfree(forget);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200463out_err:
Al Virod9585272012-06-22 12:39:14 +0400464 return err;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200465}
466
467static int fuse_mknod(struct inode *, struct dentry *, umode_t, dev_t);
Al Virod9585272012-06-22 12:39:14 +0400468static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
Al Viro30d90492012-06-22 12:40:19 +0400469 struct file *file, unsigned flags,
Al Viro44907d72018-06-08 13:32:02 -0400470 umode_t mode)
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200471{
472 int err;
473 struct fuse_conn *fc = get_fuse_conn(dir);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200474 struct dentry *res = NULL;
475
Al Viro00699ad2016-07-05 09:44:53 -0400476 if (d_in_lookup(entry)) {
Al Viro00cd8dd2012-06-10 17:13:09 -0400477 res = fuse_lookup(dir, entry, 0);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200478 if (IS_ERR(res))
Al Virod9585272012-06-22 12:39:14 +0400479 return PTR_ERR(res);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200480
481 if (res)
482 entry = res;
483 }
484
David Howells2b0143b2015-03-17 22:25:59 +0000485 if (!(flags & O_CREAT) || d_really_is_positive(entry))
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200486 goto no_open;
487
488 /* Only creates */
Al Viro73a09dd2018-06-08 13:22:02 -0400489 file->f_mode |= FMODE_CREATED;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200490
491 if (fc->no_create)
492 goto mknod;
493
Al Virob452a452018-06-08 13:06:28 -0400494 err = fuse_create_open(dir, entry, file, flags, mode);
Al Virod9585272012-06-22 12:39:14 +0400495 if (err == -ENOSYS) {
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200496 fc->no_create = 1;
497 goto mknod;
498 }
499out_dput:
500 dput(res);
Al Virod9585272012-06-22 12:39:14 +0400501 return err;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200502
503mknod:
504 err = fuse_mknod(dir, entry, mode, 0);
Al Virod9585272012-06-22 12:39:14 +0400505 if (err)
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200506 goto out_dput;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200507no_open:
Al Viroe45198a2012-06-10 06:48:09 -0400508 return finish_no_open(file, res);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800509}
510
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800511/*
512 * Code shared between mknod, mkdir, symlink and link
513 */
Miklos Szeredi70781872014-12-12 09:49:05 +0100514static int create_new_entry(struct fuse_conn *fc, struct fuse_args *args,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700515 struct inode *dir, struct dentry *entry,
Al Viro541af6a2011-07-26 03:17:33 -0400516 umode_t mode)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700517{
518 struct fuse_entry_out outarg;
519 struct inode *inode;
Al Viroc971e6a2018-05-28 18:27:19 -0400520 struct dentry *d;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700521 int err;
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100522 struct fuse_forget_link *forget;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800523
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100524 forget = fuse_alloc_forget();
Miklos Szeredi70781872014-12-12 09:49:05 +0100525 if (!forget)
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100526 return -ENOMEM;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700527
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700528 memset(&outarg, 0, sizeof(outarg));
Miklos Szeredi70781872014-12-12 09:49:05 +0100529 args->in.h.nodeid = get_node_id(dir);
530 args->out.numargs = 1;
Miklos Szeredi21f62172015-01-06 10:45:35 +0100531 args->out.args[0].size = sizeof(outarg);
Miklos Szeredi70781872014-12-12 09:49:05 +0100532 args->out.args[0].value = &outarg;
533 err = fuse_simple_request(fc, args);
Miklos Szeredi2d510132006-11-25 11:09:20 -0800534 if (err)
535 goto out_put_forget_req;
536
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800537 err = -EIO;
538 if (invalid_nodeid(outarg.nodeid))
Miklos Szeredi2d510132006-11-25 11:09:20 -0800539 goto out_put_forget_req;
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800540
541 if ((outarg.attr.mode ^ mode) & S_IFMT)
Miklos Szeredi2d510132006-11-25 11:09:20 -0800542 goto out_put_forget_req;
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800543
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700544 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700545 &outarg.attr, entry_attr_timeout(&outarg), 0);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700546 if (!inode) {
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100547 fuse_queue_forget(fc, forget, outarg.nodeid, 1);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700548 return -ENOMEM;
549 }
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100550 kfree(forget);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700551
Al Viroc971e6a2018-05-28 18:27:19 -0400552 d_drop(entry);
553 d = d_splice_alias(inode, entry);
554 if (IS_ERR(d))
555 return PTR_ERR(d);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700556
Al Viroc971e6a2018-05-28 18:27:19 -0400557 if (d) {
558 fuse_change_entry_timeout(d, &outarg);
559 dput(d);
560 } else {
561 fuse_change_entry_timeout(entry, &outarg);
562 }
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200563 fuse_dir_changed(dir);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700564 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
Seth Forshee703c7362016-08-29 08:46:36 -0500637void fuse_update_ctime(struct inode *inode)
Maxim Patlasov31f32672014-04-28 14:19:24 +0200638{
639 if (!IS_NOCMTIME(inode)) {
Deepa Dinamanic2050a42016-09-14 07:48:06 -0700640 inode->i_ctime = current_time(inode);
Maxim Patlasov31f32672014-04-28 14:19:24 +0200641 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
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +0300661 spin_lock(&fi->lock);
Kirill Tkhai4510d862018-11-09 13:33:17 +0300662 fi->attr_version = atomic64_inc_return(&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);
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +0300671 spin_unlock(&fi->lock);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700672 fuse_invalidate_attr(inode);
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200673 fuse_dir_changed(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 Szeredi261aaba72018-10-01 10:07:05 +0200695 fuse_dir_changed(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 Szeredi261aaba72018-10-01 10:07:05 +0200734 fuse_dir_changed(olddir);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700735 if (olddir != newdir)
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200736 fuse_dir_changed(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
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +0300815 spin_lock(&fi->lock);
Kirill Tkhai4510d862018-11-09 13:33:17 +0300816 fi->attr_version = atomic64_inc_return(&fc->attr_version);
Miklos Szerediac45d612012-03-05 15:48:11 +0100817 inc_nlink(inode);
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +0300818 spin_unlock(&fi->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. Biederman8cb08322018-02-21 11:18:07 -0600846 stat->uid = make_kuid(fc->user_ns, attr->uid);
847 stat->gid = make_kgid(fc->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 Szeredi5b97eea2017-09-12 16:57:54 +0200911static int fuse_update_get_attr(struct inode *inode, struct file *file,
Miklos Szeredi2f1e8192018-10-15 15:43:06 +0200912 struct kstat *stat, u32 request_mask,
913 unsigned int flags)
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800914{
915 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredi5b97eea2017-09-12 16:57:54 +0200916 int err = 0;
Miklos Szeredibf5c1892018-03-20 17:11:44 +0100917 bool sync;
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800918
Miklos Szeredibf5c1892018-03-20 17:11:44 +0100919 if (flags & AT_STATX_FORCE_SYNC)
920 sync = true;
921 else if (flags & AT_STATX_DONT_SYNC)
922 sync = false;
Miklos Szeredi2f1e8192018-10-15 15:43:06 +0200923 else if (request_mask & READ_ONCE(fi->inval_mask))
924 sync = true;
Miklos Szeredibf5c1892018-03-20 17:11:44 +0100925 else
926 sync = time_before64(fi->i_time, get_jiffies_64());
927
928 if (sync) {
Seth Forshee60bcc882016-08-29 08:46:37 -0500929 forget_all_cached_acls(inode);
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800930 err = fuse_do_getattr(inode, stat, file);
Miklos Szeredi5b97eea2017-09-12 16:57:54 +0200931 } else if (stat) {
932 generic_fillattr(inode, stat);
933 stat->mode = fi->orig_i_mode;
934 stat->ino = fi->orig_ino;
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800935 }
936
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800937 return err;
938}
939
Miklos Szeredi5b97eea2017-09-12 16:57:54 +0200940int fuse_update_attributes(struct inode *inode, struct file *file)
941{
Miklos Szeredi802dc042018-10-15 15:43:06 +0200942 /* Do *not* need to get atime for internal purposes */
943 return fuse_update_get_attr(inode, file, NULL,
944 STATX_BASIC_STATS & ~STATX_ATIME, 0);
Miklos Szeredi5b97eea2017-09-12 16:57:54 +0200945}
946
John Muir3b463ae2009-05-31 11:13:57 -0400947int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid,
John Muir451d0f52011-12-06 21:50:06 +0100948 u64 child_nodeid, struct qstr *name)
John Muir3b463ae2009-05-31 11:13:57 -0400949{
950 int err = -ENOTDIR;
951 struct inode *parent;
952 struct dentry *dir;
953 struct dentry *entry;
954
955 parent = ilookup5(sb, parent_nodeid, fuse_inode_eq, &parent_nodeid);
956 if (!parent)
957 return -ENOENT;
958
Al Viro59551022016-01-22 15:40:57 -0500959 inode_lock(parent);
John Muir3b463ae2009-05-31 11:13:57 -0400960 if (!S_ISDIR(parent->i_mode))
961 goto unlock;
962
963 err = -ENOENT;
964 dir = d_find_alias(parent);
965 if (!dir)
966 goto unlock;
967
Linus Torvalds8387ff22016-06-10 07:51:30 -0700968 name->hash = full_name_hash(dir, name->name, name->len);
John Muir3b463ae2009-05-31 11:13:57 -0400969 entry = d_lookup(dir, name);
970 dput(dir);
971 if (!entry)
972 goto unlock;
973
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200974 fuse_dir_changed(parent);
John Muir3b463ae2009-05-31 11:13:57 -0400975 fuse_invalidate_entry(entry);
John Muir451d0f52011-12-06 21:50:06 +0100976
David Howells2b0143b2015-03-17 22:25:59 +0000977 if (child_nodeid != 0 && d_really_is_positive(entry)) {
Al Viro59551022016-01-22 15:40:57 -0500978 inode_lock(d_inode(entry));
David Howells2b0143b2015-03-17 22:25:59 +0000979 if (get_node_id(d_inode(entry)) != child_nodeid) {
John Muir451d0f52011-12-06 21:50:06 +0100980 err = -ENOENT;
981 goto badentry;
982 }
983 if (d_mountpoint(entry)) {
984 err = -EBUSY;
985 goto badentry;
986 }
David Howellse36cb0b2015-01-29 12:02:35 +0000987 if (d_is_dir(entry)) {
John Muir451d0f52011-12-06 21:50:06 +0100988 shrink_dcache_parent(entry);
989 if (!simple_empty(entry)) {
990 err = -ENOTEMPTY;
991 goto badentry;
992 }
David Howells2b0143b2015-03-17 22:25:59 +0000993 d_inode(entry)->i_flags |= S_DEAD;
John Muir451d0f52011-12-06 21:50:06 +0100994 }
995 dont_mount(entry);
David Howells2b0143b2015-03-17 22:25:59 +0000996 clear_nlink(d_inode(entry));
John Muir451d0f52011-12-06 21:50:06 +0100997 err = 0;
998 badentry:
Al Viro59551022016-01-22 15:40:57 -0500999 inode_unlock(d_inode(entry));
John Muir451d0f52011-12-06 21:50:06 +01001000 if (!err)
1001 d_delete(entry);
1002 } else {
1003 err = 0;
1004 }
John Muir3b463ae2009-05-31 11:13:57 -04001005 dput(entry);
John Muir3b463ae2009-05-31 11:13:57 -04001006
1007 unlock:
Al Viro59551022016-01-22 15:40:57 -05001008 inode_unlock(parent);
John Muir3b463ae2009-05-31 11:13:57 -04001009 iput(parent);
1010 return err;
1011}
1012
Miklos Szeredi87729a52005-09-09 13:10:34 -07001013/*
1014 * Calling into a user-controlled filesystem gives the filesystem
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001015 * daemon ptrace-like capabilities over the current process. This
Miklos Szeredi87729a52005-09-09 13:10:34 -07001016 * means, that the filesystem daemon is able to record the exact
1017 * filesystem operations performed, and can also control the behavior
1018 * of the requester process in otherwise impossible ways. For example
1019 * it can delay the operation for arbitrary length of time allowing
1020 * DoS against the requester.
1021 *
1022 * For this reason only those processes can call into the filesystem,
1023 * for which the owner of the mount has ptrace privilege. This
1024 * excludes processes started by other users, suid or sgid processes.
1025 */
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001026int fuse_allow_current_process(struct fuse_conn *fc)
Miklos Szeredi87729a52005-09-09 13:10:34 -07001027{
David Howellsc69e8d92008-11-14 10:39:19 +11001028 const struct cred *cred;
David Howellsc69e8d92008-11-14 10:39:19 +11001029
Miklos Szeredi29433a22016-10-01 07:32:32 +02001030 if (fc->allow_other)
Seth Forshee73f03c22017-12-22 15:32:33 +01001031 return current_in_userns(fc->user_ns);
Miklos Szeredi87729a52005-09-09 13:10:34 -07001032
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001033 cred = current_cred();
Eric W. Biederman499dcf22012-02-07 16:26:03 -08001034 if (uid_eq(cred->euid, fc->user_id) &&
1035 uid_eq(cred->suid, fc->user_id) &&
1036 uid_eq(cred->uid, fc->user_id) &&
1037 gid_eq(cred->egid, fc->group_id) &&
1038 gid_eq(cred->sgid, fc->group_id) &&
1039 gid_eq(cred->gid, fc->group_id))
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001040 return 1;
Miklos Szeredi87729a52005-09-09 13:10:34 -07001041
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001042 return 0;
Miklos Szeredi87729a52005-09-09 13:10:34 -07001043}
1044
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001045static int fuse_access(struct inode *inode, int mask)
1046{
1047 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001048 FUSE_ARGS(args);
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001049 struct fuse_access_in inarg;
1050 int err;
1051
Miklos Szeredi698fa1d2013-10-01 16:41:23 +02001052 BUG_ON(mask & MAY_NOT_BLOCK);
1053
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001054 if (fc->no_access)
1055 return 0;
1056
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001057 memset(&inarg, 0, sizeof(inarg));
Al Viroe6305c42008-07-15 21:03:57 -04001058 inarg.mask = mask & (MAY_READ | MAY_WRITE | MAY_EXEC);
Miklos Szeredi70781872014-12-12 09:49:05 +01001059 args.in.h.opcode = FUSE_ACCESS;
1060 args.in.h.nodeid = get_node_id(inode);
1061 args.in.numargs = 1;
1062 args.in.args[0].size = sizeof(inarg);
1063 args.in.args[0].value = &inarg;
1064 err = fuse_simple_request(fc, &args);
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001065 if (err == -ENOSYS) {
1066 fc->no_access = 1;
1067 err = 0;
1068 }
1069 return err;
1070}
1071
Al Viro10556cb2011-06-20 19:28:19 -04001072static int fuse_perm_getattr(struct inode *inode, int mask)
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001073{
Al Viro10556cb2011-06-20 19:28:19 -04001074 if (mask & MAY_NOT_BLOCK)
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001075 return -ECHILD;
1076
Seth Forshee60bcc882016-08-29 08:46:37 -05001077 forget_all_cached_acls(inode);
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001078 return fuse_do_getattr(inode, NULL, NULL);
1079}
1080
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001081/*
1082 * Check permission. The two basic access models of FUSE are:
1083 *
1084 * 1) Local access checking ('default_permissions' mount option) based
1085 * on file mode. This is the plain old disk filesystem permission
1086 * modell.
1087 *
1088 * 2) "Remote" access checking, where server is responsible for
1089 * checking permission in each inode operation. An exception to this
1090 * is if ->permission() was invoked from sys_access() in which case an
1091 * access request is sent. Execute permission is still checked
1092 * locally based on file mode.
1093 */
Al Viro10556cb2011-06-20 19:28:19 -04001094static int fuse_permission(struct inode *inode, int mask)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001095{
1096 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi244f6382007-10-16 23:31:02 -07001097 bool refreshed = false;
1098 int err = 0;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001099
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001100 if (!fuse_allow_current_process(fc))
Miklos Szeredie5e55582005-09-09 13:10:28 -07001101 return -EACCES;
Miklos Szeredi244f6382007-10-16 23:31:02 -07001102
1103 /*
Miklos Szeredie8e96152007-10-16 23:31:06 -07001104 * If attributes are needed, refresh them before proceeding
Miklos Szeredi244f6382007-10-16 23:31:02 -07001105 */
Miklos Szeredi29433a22016-10-01 07:32:32 +02001106 if (fc->default_permissions ||
Miklos Szeredie8e96152007-10-16 23:31:06 -07001107 ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) {
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001108 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredid233c7d2018-12-03 10:14:43 +01001109 u32 perm_mask = STATX_MODE | STATX_UID | STATX_GID;
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001110
Miklos Szeredid233c7d2018-12-03 10:14:43 +01001111 if (perm_mask & READ_ONCE(fi->inval_mask) ||
1112 time_before64(fi->i_time, get_jiffies_64())) {
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001113 refreshed = true;
1114
Al Viro10556cb2011-06-20 19:28:19 -04001115 err = fuse_perm_getattr(inode, mask);
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001116 if (err)
1117 return err;
1118 }
Miklos Szeredi244f6382007-10-16 23:31:02 -07001119 }
1120
Miklos Szeredi29433a22016-10-01 07:32:32 +02001121 if (fc->default_permissions) {
Al Viro2830ba72011-06-20 19:16:29 -04001122 err = generic_permission(inode, mask);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001123
1124 /* If permission is denied, try to refresh file
1125 attributes. This is also needed, because the root
1126 node will at first have no permissions */
Miklos Szeredi244f6382007-10-16 23:31:02 -07001127 if (err == -EACCES && !refreshed) {
Al Viro10556cb2011-06-20 19:28:19 -04001128 err = fuse_perm_getattr(inode, mask);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001129 if (!err)
Al Viro2830ba72011-06-20 19:16:29 -04001130 err = generic_permission(inode, mask);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001131 }
1132
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001133 /* Note: the opposite of the above test does not
1134 exist. So if permissions are revoked this won't be
1135 noticed immediately, only after the attribute
1136 timeout has expired */
Eric Paris9cfcac82010-07-23 11:43:51 -04001137 } else if (mask & (MAY_ACCESS | MAY_CHDIR)) {
Miklos Szeredie8e96152007-10-16 23:31:06 -07001138 err = fuse_access(inode, mask);
1139 } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
1140 if (!(inode->i_mode & S_IXUGO)) {
1141 if (refreshed)
1142 return -EACCES;
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001143
Al Viro10556cb2011-06-20 19:28:19 -04001144 err = fuse_perm_getattr(inode, mask);
Miklos Szeredie8e96152007-10-16 23:31:06 -07001145 if (!err && !(inode->i_mode & S_IXUGO))
1146 return -EACCES;
1147 }
Miklos Szeredie5e55582005-09-09 13:10:28 -07001148 }
Miklos Szeredi244f6382007-10-16 23:31:02 -07001149 return err;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001150}
1151
Dan Schatzberg5571f1e2018-10-11 08:17:00 -07001152static int fuse_readlink_page(struct inode *inode, struct page *page)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001153{
Miklos Szeredie5e55582005-09-09 13:10:28 -07001154 struct fuse_conn *fc = get_fuse_conn(inode);
Dan Schatzberg5571f1e2018-10-11 08:17:00 -07001155 struct fuse_req *req;
1156 int err;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001157
Dan Schatzberg5571f1e2018-10-11 08:17:00 -07001158 req = fuse_get_req(fc, 1);
1159 if (IS_ERR(req))
1160 return PTR_ERR(req);
Al Viro6b255392015-11-17 10:20:54 -05001161
Dan Schatzberg5571f1e2018-10-11 08:17:00 -07001162 req->out.page_zeroing = 1;
1163 req->out.argpages = 1;
1164 req->num_pages = 1;
1165 req->pages[0] = page;
1166 req->page_descs[0].length = PAGE_SIZE - 1;
1167 req->in.h.opcode = FUSE_READLINK;
1168 req->in.h.nodeid = get_node_id(inode);
1169 req->out.argvar = 1;
1170 req->out.numargs = 1;
1171 req->out.args[0].size = PAGE_SIZE - 1;
1172 fuse_request_send(fc, req);
1173 err = req->out.h.error;
Miklos Szeredi70781872014-12-12 09:49:05 +01001174
Dan Schatzberg5571f1e2018-10-11 08:17:00 -07001175 if (!err) {
1176 char *link = page_address(page);
1177 size_t len = req->out.args[0].size;
1178
1179 BUG_ON(len >= PAGE_SIZE);
1180 link[len] = '\0';
Miklos Szeredi70781872014-12-12 09:49:05 +01001181 }
Dan Schatzberg5571f1e2018-10-11 08:17:00 -07001182
1183 fuse_put_request(fc, req);
Andrew Gallagher451418f2013-11-05 03:55:43 -08001184 fuse_invalidate_atime(inode);
Dan Schatzberg5571f1e2018-10-11 08:17:00 -07001185
1186 return err;
1187}
1188
1189static const char *fuse_get_link(struct dentry *dentry, struct inode *inode,
1190 struct delayed_call *callback)
1191{
1192 struct fuse_conn *fc = get_fuse_conn(inode);
1193 struct page *page;
1194 int err;
1195
1196 err = -EIO;
1197 if (is_bad_inode(inode))
1198 goto out_err;
1199
1200 if (fc->cache_symlinks)
1201 return page_get_link(dentry, inode, callback);
1202
1203 err = -ECHILD;
1204 if (!dentry)
1205 goto out_err;
1206
1207 page = alloc_page(GFP_KERNEL);
1208 err = -ENOMEM;
1209 if (!page)
1210 goto out_err;
1211
1212 err = fuse_readlink_page(inode, page);
1213 if (err) {
1214 __free_page(page);
1215 goto out_err;
1216 }
1217
1218 set_delayed_call(callback, page_put_link, page);
1219
1220 return page_address(page);
1221
1222out_err:
1223 return ERR_PTR(err);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001224}
1225
Miklos Szeredie5e55582005-09-09 13:10:28 -07001226static int fuse_dir_open(struct inode *inode, struct file *file)
1227{
Miklos Szeredi91fe96b2009-04-28 16:56:37 +02001228 return fuse_open_common(inode, file, true);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001229}
1230
1231static int fuse_dir_release(struct inode *inode, struct file *file)
1232{
Chad Austin2e64ff12018-12-10 10:54:52 -08001233 fuse_release_common(file, true);
Miklos Szeredi8b0797a2009-04-28 16:56:39 +02001234
1235 return 0;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001236}
1237
Josef Bacik02c24a82011-07-16 20:44:56 -04001238static int fuse_dir_fsync(struct file *file, loff_t start, loff_t end,
1239 int datasync)
Miklos Szeredi82547982005-09-09 13:10:38 -07001240{
Miklos Szeredia9c2d1e2018-12-03 10:14:43 +01001241 struct inode *inode = file->f_mapping->host;
1242 struct fuse_conn *fc = get_fuse_conn(inode);
1243 int err;
1244
1245 if (is_bad_inode(inode))
1246 return -EIO;
1247
1248 if (fc->no_fsyncdir)
1249 return 0;
1250
1251 inode_lock(inode);
1252 err = fuse_fsync_common(file, start, end, datasync, FUSE_FSYNCDIR);
1253 if (err == -ENOSYS) {
1254 fc->no_fsyncdir = 1;
1255 err = 0;
1256 }
1257 inode_unlock(inode);
1258
1259 return err;
Miklos Szeredi82547982005-09-09 13:10:38 -07001260}
1261
Miklos Szeredib18da0c2011-12-13 11:58:49 +01001262static long fuse_dir_ioctl(struct file *file, unsigned int cmd,
1263 unsigned long arg)
1264{
1265 struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1266
1267 /* FUSE_IOCTL_DIR only supported for API version >= 7.18 */
1268 if (fc->minor < 18)
1269 return -ENOTTY;
1270
1271 return fuse_ioctl_common(file, cmd, arg, FUSE_IOCTL_DIR);
1272}
1273
1274static long fuse_dir_compat_ioctl(struct file *file, unsigned int cmd,
1275 unsigned long arg)
1276{
1277 struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1278
1279 if (fc->minor < 18)
1280 return -ENOTTY;
1281
1282 return fuse_ioctl_common(file, cmd, arg,
1283 FUSE_IOCTL_COMPAT | FUSE_IOCTL_DIR);
1284}
1285
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001286static bool update_mtime(unsigned ivalid, bool trust_local_mtime)
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001287{
1288 /* Always update if mtime is explicitly set */
1289 if (ivalid & ATTR_MTIME_SET)
1290 return true;
1291
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001292 /* Or if kernel i_mtime is the official one */
1293 if (trust_local_mtime)
1294 return true;
1295
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001296 /* If it's an open(O_TRUNC) or an ftruncate(), don't update */
1297 if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE)))
1298 return false;
1299
1300 /* In all other cases update */
1301 return true;
1302}
1303
Eric W. Biederman8cb08322018-02-21 11:18:07 -06001304static void iattr_to_fattr(struct fuse_conn *fc, struct iattr *iattr,
1305 struct fuse_setattr_in *arg, bool trust_local_cmtime)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001306{
1307 unsigned ivalid = iattr->ia_valid;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001308
1309 if (ivalid & ATTR_MODE)
Miklos Szeredibefc6492005-11-07 00:59:52 -08001310 arg->valid |= FATTR_MODE, arg->mode = iattr->ia_mode;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001311 if (ivalid & ATTR_UID)
Eric W. Biederman8cb08322018-02-21 11:18:07 -06001312 arg->valid |= FATTR_UID, arg->uid = from_kuid(fc->user_ns, iattr->ia_uid);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001313 if (ivalid & ATTR_GID)
Eric W. Biederman8cb08322018-02-21 11:18:07 -06001314 arg->valid |= FATTR_GID, arg->gid = from_kgid(fc->user_ns, iattr->ia_gid);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001315 if (ivalid & ATTR_SIZE)
Miklos Szeredibefc6492005-11-07 00:59:52 -08001316 arg->valid |= FATTR_SIZE, arg->size = iattr->ia_size;
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001317 if (ivalid & ATTR_ATIME) {
1318 arg->valid |= FATTR_ATIME;
Miklos Szeredibefc6492005-11-07 00:59:52 -08001319 arg->atime = iattr->ia_atime.tv_sec;
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001320 arg->atimensec = iattr->ia_atime.tv_nsec;
1321 if (!(ivalid & ATTR_ATIME_SET))
1322 arg->valid |= FATTR_ATIME_NOW;
1323 }
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001324 if ((ivalid & ATTR_MTIME) && update_mtime(ivalid, trust_local_cmtime)) {
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001325 arg->valid |= FATTR_MTIME;
Miklos Szeredibefc6492005-11-07 00:59:52 -08001326 arg->mtime = iattr->ia_mtime.tv_sec;
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001327 arg->mtimensec = iattr->ia_mtime.tv_nsec;
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001328 if (!(ivalid & ATTR_MTIME_SET) && !trust_local_cmtime)
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001329 arg->valid |= FATTR_MTIME_NOW;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001330 }
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001331 if ((ivalid & ATTR_CTIME) && trust_local_cmtime) {
1332 arg->valid |= FATTR_CTIME;
1333 arg->ctime = iattr->ia_ctime.tv_sec;
1334 arg->ctimensec = iattr->ia_ctime.tv_nsec;
1335 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001336}
1337
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001338/*
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001339 * Prevent concurrent writepages on inode
1340 *
1341 * This is done by adding a negative bias to the inode write counter
1342 * and waiting for all pending writes to finish.
1343 */
1344void fuse_set_nowrite(struct inode *inode)
1345{
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001346 struct fuse_inode *fi = get_fuse_inode(inode);
1347
Al Viro59551022016-01-22 15:40:57 -05001348 BUG_ON(!inode_is_locked(inode));
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001349
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001350 spin_lock(&fi->lock);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001351 BUG_ON(fi->writectr < 0);
1352 fi->writectr += FUSE_NOWRITE;
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001353 spin_unlock(&fi->lock);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001354 wait_event(fi->page_waitq, fi->writectr == FUSE_NOWRITE);
1355}
1356
1357/*
1358 * Allow writepages on inode
1359 *
1360 * Remove the bias from the writecounter and send any queued
1361 * writepages.
1362 */
1363static void __fuse_release_nowrite(struct inode *inode)
1364{
1365 struct fuse_inode *fi = get_fuse_inode(inode);
1366
1367 BUG_ON(fi->writectr != FUSE_NOWRITE);
1368 fi->writectr = 0;
1369 fuse_flush_writepages(inode);
1370}
1371
1372void fuse_release_nowrite(struct inode *inode)
1373{
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001374 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001375
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001376 spin_lock(&fi->lock);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001377 __fuse_release_nowrite(inode);
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001378 spin_unlock(&fi->lock);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001379}
1380
Miklos Szeredi70781872014-12-12 09:49:05 +01001381static void fuse_setattr_fill(struct fuse_conn *fc, struct fuse_args *args,
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001382 struct inode *inode,
1383 struct fuse_setattr_in *inarg_p,
1384 struct fuse_attr_out *outarg_p)
1385{
Miklos Szeredi70781872014-12-12 09:49:05 +01001386 args->in.h.opcode = FUSE_SETATTR;
1387 args->in.h.nodeid = get_node_id(inode);
1388 args->in.numargs = 1;
1389 args->in.args[0].size = sizeof(*inarg_p);
1390 args->in.args[0].value = inarg_p;
1391 args->out.numargs = 1;
Miklos Szeredi21f62172015-01-06 10:45:35 +01001392 args->out.args[0].size = sizeof(*outarg_p);
Miklos Szeredi70781872014-12-12 09:49:05 +01001393 args->out.args[0].value = outarg_p;
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001394}
1395
1396/*
1397 * Flush inode->i_mtime to the server
1398 */
Maxim Patlasovab9e13f2014-04-28 14:19:24 +02001399int fuse_flush_times(struct inode *inode, struct fuse_file *ff)
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001400{
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001401 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001402 FUSE_ARGS(args);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001403 struct fuse_setattr_in inarg;
1404 struct fuse_attr_out outarg;
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001405
1406 memset(&inarg, 0, sizeof(inarg));
1407 memset(&outarg, 0, sizeof(outarg));
1408
Maxim Patlasovab9e13f2014-04-28 14:19:24 +02001409 inarg.valid = FATTR_MTIME;
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001410 inarg.mtime = inode->i_mtime.tv_sec;
1411 inarg.mtimensec = inode->i_mtime.tv_nsec;
Maxim Patlasovab9e13f2014-04-28 14:19:24 +02001412 if (fc->minor >= 23) {
1413 inarg.valid |= FATTR_CTIME;
1414 inarg.ctime = inode->i_ctime.tv_sec;
1415 inarg.ctimensec = inode->i_ctime.tv_nsec;
1416 }
Miklos Szeredi1e18bda2014-04-28 14:19:23 +02001417 if (ff) {
1418 inarg.valid |= FATTR_FH;
1419 inarg.fh = ff->fh;
1420 }
Miklos Szeredi70781872014-12-12 09:49:05 +01001421 fuse_setattr_fill(fc, &args, inode, &inarg, &outarg);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001422
Miklos Szeredi70781872014-12-12 09:49:05 +01001423 return fuse_simple_request(fc, &args);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001424}
1425
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001426/*
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001427 * Set attributes, and at the same time refresh them.
1428 *
1429 * Truncation is slightly complicated, because the 'truncate' request
1430 * may fail, in which case we don't want to touch the mapping.
Miklos Szeredi9ffbb912006-10-17 00:10:06 -07001431 * vmtruncate() doesn't allow for this case, so do the rlimit checking
1432 * and the actual truncation by hand.
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001433 */
Jan Kara62490332016-05-26 17:12:41 +02001434int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
Maxim Patlasovefb9fa92012-12-18 14:05:08 +04001435 struct file *file)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001436{
Jan Kara62490332016-05-26 17:12:41 +02001437 struct inode *inode = d_inode(dentry);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001438 struct fuse_conn *fc = get_fuse_conn(inode);
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001439 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001440 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001441 struct fuse_setattr_in inarg;
1442 struct fuse_attr_out outarg;
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001443 bool is_truncate = false;
Pavel Emelyanov83732002013-10-10 17:10:46 +04001444 bool is_wb = fc->writeback_cache;
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001445 loff_t oldsize;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001446 int err;
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001447 bool trust_local_cmtime = is_wb && S_ISREG(inode->i_mode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001448
Miklos Szeredi29433a22016-10-01 07:32:32 +02001449 if (!fc->default_permissions)
Christoph Hellwigdb78b872010-06-04 11:30:03 +02001450 attr->ia_valid |= ATTR_FORCE;
1451
Jan Kara31051c82016-05-26 16:55:18 +02001452 err = setattr_prepare(dentry, attr);
Christoph Hellwigdb78b872010-06-04 11:30:03 +02001453 if (err)
1454 return err;
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001455
Miklos Szeredi8d56add2011-02-25 14:44:58 +01001456 if (attr->ia_valid & ATTR_OPEN) {
Miklos Szeredidf0e91d2018-02-08 15:17:38 +01001457 /* This is coming from open(..., ... | O_TRUNC); */
1458 WARN_ON(!(attr->ia_valid & ATTR_SIZE));
1459 WARN_ON(attr->ia_size != 0);
1460 if (fc->atomic_o_trunc) {
1461 /*
1462 * No need to send request to userspace, since actual
1463 * truncation has already been done by OPEN. But still
1464 * need to truncate page cache.
1465 */
1466 i_size_write(inode, 0);
1467 truncate_pagecache(inode, 0);
Miklos Szeredi8d56add2011-02-25 14:44:58 +01001468 return 0;
Miklos Szeredidf0e91d2018-02-08 15:17:38 +01001469 }
Miklos Szeredi8d56add2011-02-25 14:44:58 +01001470 file = NULL;
1471 }
Miklos Szeredi6ff958e2007-10-18 03:07:02 -07001472
Miklos Szerediab2257e2018-10-01 10:07:05 +02001473 if (attr->ia_valid & ATTR_SIZE) {
1474 if (WARN_ON(!S_ISREG(inode->i_mode)))
1475 return -EIO;
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001476 is_truncate = true;
Miklos Szerediab2257e2018-10-01 10:07:05 +02001477 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001478
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001479 if (is_truncate) {
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001480 fuse_set_nowrite(inode);
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001481 set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001482 if (trust_local_cmtime && attr->ia_size != inode->i_size)
1483 attr->ia_valid |= ATTR_MTIME | ATTR_CTIME;
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001484 }
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001485
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001486 memset(&inarg, 0, sizeof(inarg));
Miklos Szeredi0e9663e2007-10-18 03:07:05 -07001487 memset(&outarg, 0, sizeof(outarg));
Eric W. Biederman8cb08322018-02-21 11:18:07 -06001488 iattr_to_fattr(fc, attr, &inarg, trust_local_cmtime);
Miklos Szeredi49d49142007-10-18 03:07:00 -07001489 if (file) {
1490 struct fuse_file *ff = file->private_data;
1491 inarg.valid |= FATTR_FH;
1492 inarg.fh = ff->fh;
1493 }
Miklos Szeredif3332112007-10-18 03:07:04 -07001494 if (attr->ia_valid & ATTR_SIZE) {
1495 /* For mandatory locking in truncate */
1496 inarg.valid |= FATTR_LOCKOWNER;
1497 inarg.lock_owner = fuse_lock_owner_id(fc, current->files);
1498 }
Miklos Szeredi70781872014-12-12 09:49:05 +01001499 fuse_setattr_fill(fc, &args, inode, &inarg, &outarg);
1500 err = fuse_simple_request(fc, &args);
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001501 if (err) {
1502 if (err == -EINTR)
1503 fuse_invalidate_attr(inode);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001504 goto error;
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001505 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001506
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001507 if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
1508 make_bad_inode(inode);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001509 err = -EIO;
1510 goto error;
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001511 }
1512
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001513 spin_lock(&fi->lock);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001514 /* the kernel maintains i_mtime locally */
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001515 if (trust_local_cmtime) {
1516 if (attr->ia_valid & ATTR_MTIME)
1517 inode->i_mtime = attr->ia_mtime;
1518 if (attr->ia_valid & ATTR_CTIME)
1519 inode->i_ctime = attr->ia_ctime;
Miklos Szeredi1e18bda2014-04-28 14:19:23 +02001520 /* FIXME: clear I_DIRTY_SYNC? */
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001521 }
1522
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001523 fuse_change_attributes_common(inode, &outarg.attr,
1524 attr_timeout(&outarg));
1525 oldsize = inode->i_size;
Pavel Emelyanov83732002013-10-10 17:10:46 +04001526 /* see the comment in fuse_change_attributes() */
1527 if (!is_wb || is_truncate || !S_ISREG(inode->i_mode))
1528 i_size_write(inode, outarg.attr.size);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001529
1530 if (is_truncate) {
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001531 /* NOTE: this may release/reacquire fi->lock */
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001532 __fuse_release_nowrite(inode);
1533 }
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001534 spin_unlock(&fi->lock);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001535
1536 /*
1537 * Only call invalidate_inode_pages2() after removing
1538 * FUSE_NOWRITE, otherwise fuse_launder_page() would deadlock.
1539 */
Pavel Emelyanov83732002013-10-10 17:10:46 +04001540 if ((is_truncate || !is_wb) &&
1541 S_ISREG(inode->i_mode) && oldsize != outarg.attr.size) {
Kirill A. Shutemov7caef262013-09-12 15:13:56 -07001542 truncate_pagecache(inode, outarg.attr.size);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001543 invalidate_inode_pages2(inode->i_mapping);
1544 }
1545
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001546 clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001547 return 0;
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001548
1549error:
1550 if (is_truncate)
1551 fuse_release_nowrite(inode);
1552
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001553 clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001554 return err;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001555}
1556
Miklos Szeredi49d49142007-10-18 03:07:00 -07001557static int fuse_setattr(struct dentry *entry, struct iattr *attr)
1558{
David Howells2b0143b2015-03-17 22:25:59 +00001559 struct inode *inode = d_inode(entry);
Miklos Szeredi5e940c12016-10-01 07:32:32 +02001560 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredia09f99e2016-10-01 07:32:32 +02001561 struct file *file = (attr->ia_valid & ATTR_FILE) ? attr->ia_file : NULL;
Miklos Szeredi5e2b8822016-10-01 07:32:32 +02001562 int ret;
Maxim Patlasovefb9fa92012-12-18 14:05:08 +04001563
1564 if (!fuse_allow_current_process(get_fuse_conn(inode)))
1565 return -EACCES;
1566
Miklos Szeredia09f99e2016-10-01 07:32:32 +02001567 if (attr->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) {
Miklos Szeredia09f99e2016-10-01 07:32:32 +02001568 attr->ia_valid &= ~(ATTR_KILL_SUID | ATTR_KILL_SGID |
1569 ATTR_MODE);
Miklos Szeredia09f99e2016-10-01 07:32:32 +02001570
Miklos Szeredi5e940c12016-10-01 07:32:32 +02001571 /*
1572 * The only sane way to reliably kill suid/sgid is to do it in
1573 * the userspace filesystem
1574 *
1575 * This should be done on write(), truncate() and chown().
1576 */
1577 if (!fc->handle_killpriv) {
Miklos Szeredi5e940c12016-10-01 07:32:32 +02001578 /*
1579 * ia_mode calculation may have used stale i_mode.
1580 * Refresh and recalculate.
1581 */
1582 ret = fuse_do_getattr(inode, NULL, file);
1583 if (ret)
1584 return ret;
1585
1586 attr->ia_mode = inode->i_mode;
Miklos Szeredic01638f2016-12-06 16:18:45 +01001587 if (inode->i_mode & S_ISUID) {
Miklos Szeredi5e940c12016-10-01 07:32:32 +02001588 attr->ia_valid |= ATTR_MODE;
1589 attr->ia_mode &= ~S_ISUID;
1590 }
Miklos Szeredic01638f2016-12-06 16:18:45 +01001591 if ((inode->i_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
Miklos Szeredi5e940c12016-10-01 07:32:32 +02001592 attr->ia_valid |= ATTR_MODE;
1593 attr->ia_mode &= ~S_ISGID;
1594 }
Miklos Szeredia09f99e2016-10-01 07:32:32 +02001595 }
1596 }
1597 if (!attr->ia_valid)
1598 return 0;
1599
Linus Torvaldsabb5a142016-10-10 13:04:49 -07001600 ret = fuse_do_setattr(entry, attr, file);
Miklos Szeredi5e2b8822016-10-01 07:32:32 +02001601 if (!ret) {
Seth Forshee60bcc882016-08-29 08:46:37 -05001602 /*
1603 * If filesystem supports acls it may have updated acl xattrs in
1604 * the filesystem, so forget cached acls for the inode.
1605 */
1606 if (fc->posix_acl)
1607 forget_all_cached_acls(inode);
1608
Miklos Szeredi5e2b8822016-10-01 07:32:32 +02001609 /* Directory mode changed, may need to revalidate access */
1610 if (d_is_dir(entry) && (attr->ia_valid & ATTR_MODE))
1611 fuse_invalidate_entry_cache(entry);
1612 }
1613 return ret;
Miklos Szeredi49d49142007-10-18 03:07:00 -07001614}
1615
David Howellsa528d352017-01-31 16:46:22 +00001616static int fuse_getattr(const struct path *path, struct kstat *stat,
1617 u32 request_mask, unsigned int flags)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001618{
David Howellsa528d352017-01-31 16:46:22 +00001619 struct inode *inode = d_inode(path->dentry);
Miklos Szeredi244f6382007-10-16 23:31:02 -07001620 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi244f6382007-10-16 23:31:02 -07001621
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001622 if (!fuse_allow_current_process(fc))
Miklos Szeredi244f6382007-10-16 23:31:02 -07001623 return -EACCES;
1624
Miklos Szeredi2f1e8192018-10-15 15:43:06 +02001625 return fuse_update_get_attr(inode, NULL, stat, request_mask, flags);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001626}
1627
Arjan van de Ven754661f2007-02-12 00:55:38 -08001628static const struct inode_operations fuse_dir_inode_operations = {
Miklos Szeredie5e55582005-09-09 13:10:28 -07001629 .lookup = fuse_lookup,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001630 .mkdir = fuse_mkdir,
1631 .symlink = fuse_symlink,
1632 .unlink = fuse_unlink,
1633 .rmdir = fuse_rmdir,
Miklos Szeredi2773bf02016-09-27 11:03:58 +02001634 .rename = fuse_rename2,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001635 .link = fuse_link,
1636 .setattr = fuse_setattr,
1637 .create = fuse_create,
Miklos Szeredic8ccbe02012-06-05 15:10:22 +02001638 .atomic_open = fuse_atomic_open,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001639 .mknod = fuse_mknod,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001640 .permission = fuse_permission,
1641 .getattr = fuse_getattr,
Miklos Szeredi92a87802005-09-09 13:10:31 -07001642 .listxattr = fuse_listxattr,
Seth Forshee60bcc882016-08-29 08:46:37 -05001643 .get_acl = fuse_get_acl,
1644 .set_acl = fuse_set_acl,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001645};
1646
Arjan van de Ven4b6f5d22006-03-28 01:56:42 -08001647static const struct file_operations fuse_dir_operations = {
Miklos Szeredib6aeade2005-09-09 13:10:30 -07001648 .llseek = generic_file_llseek,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001649 .read = generic_read_dir,
Al Virod9b3dbd2016-04-20 17:30:32 -04001650 .iterate_shared = fuse_readdir,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001651 .open = fuse_dir_open,
1652 .release = fuse_dir_release,
Miklos Szeredi82547982005-09-09 13:10:38 -07001653 .fsync = fuse_dir_fsync,
Miklos Szeredib18da0c2011-12-13 11:58:49 +01001654 .unlocked_ioctl = fuse_dir_ioctl,
1655 .compat_ioctl = fuse_dir_compat_ioctl,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001656};
1657
Arjan van de Ven754661f2007-02-12 00:55:38 -08001658static const struct inode_operations fuse_common_inode_operations = {
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001659 .setattr = fuse_setattr,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001660 .permission = fuse_permission,
1661 .getattr = fuse_getattr,
Miklos Szeredi92a87802005-09-09 13:10:31 -07001662 .listxattr = fuse_listxattr,
Seth Forshee60bcc882016-08-29 08:46:37 -05001663 .get_acl = fuse_get_acl,
1664 .set_acl = fuse_set_acl,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001665};
1666
Arjan van de Ven754661f2007-02-12 00:55:38 -08001667static const struct inode_operations fuse_symlink_inode_operations = {
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001668 .setattr = fuse_setattr,
Al Viro6b255392015-11-17 10:20:54 -05001669 .get_link = fuse_get_link,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001670 .getattr = fuse_getattr,
Miklos Szeredi92a87802005-09-09 13:10:31 -07001671 .listxattr = fuse_listxattr,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001672};
1673
1674void fuse_init_common(struct inode *inode)
1675{
1676 inode->i_op = &fuse_common_inode_operations;
1677}
1678
1679void fuse_init_dir(struct inode *inode)
1680{
Miklos Szerediab2257e2018-10-01 10:07:05 +02001681 struct fuse_inode *fi = get_fuse_inode(inode);
1682
Miklos Szeredie5e55582005-09-09 13:10:28 -07001683 inode->i_op = &fuse_dir_inode_operations;
1684 inode->i_fop = &fuse_dir_operations;
Miklos Szerediab2257e2018-10-01 10:07:05 +02001685
1686 spin_lock_init(&fi->rdc.lock);
1687 fi->rdc.cached = false;
1688 fi->rdc.size = 0;
1689 fi->rdc.pos = 0;
1690 fi->rdc.version = 0;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001691}
1692
Dan Schatzberg5571f1e2018-10-11 08:17:00 -07001693static int fuse_symlink_readpage(struct file *null, struct page *page)
1694{
1695 int err = fuse_readlink_page(page->mapping->host, page);
1696
1697 if (!err)
1698 SetPageUptodate(page);
1699
1700 unlock_page(page);
1701
1702 return err;
1703}
1704
1705static const struct address_space_operations fuse_symlink_aops = {
1706 .readpage = fuse_symlink_readpage,
1707};
1708
Miklos Szeredie5e55582005-09-09 13:10:28 -07001709void fuse_init_symlink(struct inode *inode)
1710{
1711 inode->i_op = &fuse_symlink_inode_operations;
Dan Schatzberg5571f1e2018-10-11 08:17:00 -07001712 inode->i_data.a_ops = &fuse_symlink_aops;
1713 inode_nohighmem(inode);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001714}