blob: de1e2fde60bd4cf5cdc7213e4be367650eff3863 [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
Khazhismel Kumykov30c6a232019-09-16 16:56:41 -070027#if BITS_PER_LONG >= 64
28static inline void __fuse_dentry_settime(struct dentry *entry, u64 time)
29{
30 entry->d_fsdata = (void *) time;
31}
32
33static inline u64 fuse_dentry_time(const struct dentry *entry)
34{
35 return (u64)entry->d_fsdata;
36}
37
38#else
Miklos Szeredif75fdf22016-10-01 07:32:32 +020039union fuse_dentry {
40 u64 time;
41 struct rcu_head rcu;
42};
43
Khazhismel Kumykov30c6a232019-09-16 16:56:41 -070044static inline void __fuse_dentry_settime(struct dentry *dentry, u64 time)
45{
46 ((union fuse_dentry *) dentry->d_fsdata)->time = time;
47}
48
49static inline u64 fuse_dentry_time(const struct dentry *entry)
50{
51 return ((union fuse_dentry *) entry->d_fsdata)->time;
52}
53#endif
54
Miklos Szeredi8fab0102018-08-15 17:42:34 +020055static void fuse_dentry_settime(struct dentry *dentry, u64 time)
Miklos Szeredi0a0898c2006-07-30 03:04:10 -070056{
Miklos Szeredi8fab0102018-08-15 17:42:34 +020057 struct fuse_conn *fc = get_fuse_conn_super(dentry->d_sb);
58 bool delete = !time && fc->delete_stale;
59 /*
60 * Mess with DCACHE_OP_DELETE because dput() will be faster without it.
61 * Don't care about races, either way it's just an optimization
62 */
63 if ((!delete && (dentry->d_flags & DCACHE_OP_DELETE)) ||
64 (delete && !(dentry->d_flags & DCACHE_OP_DELETE))) {
65 spin_lock(&dentry->d_lock);
66 if (!delete)
67 dentry->d_flags &= ~DCACHE_OP_DELETE;
68 else
69 dentry->d_flags |= DCACHE_OP_DELETE;
70 spin_unlock(&dentry->d_lock);
71 }
72
Khazhismel Kumykov30c6a232019-09-16 16:56:41 -070073 __fuse_dentry_settime(dentry, time);
Miklos Szeredi0a0898c2006-07-30 03:04:10 -070074}
Miklos Szeredi0a0898c2006-07-30 03:04:10 -070075
Miklos Szeredi6f9f1182006-01-06 00:19:39 -080076/*
77 * FUSE caches dentries and attributes with separate timeout. The
78 * time in jiffies until the dentry/attributes are valid is stored in
Miklos Szeredif75fdf22016-10-01 07:32:32 +020079 * dentry->d_fsdata and fuse_inode->i_time respectively.
Miklos Szeredi6f9f1182006-01-06 00:19:39 -080080 */
81
82/*
83 * Calculate the time in jiffies until a dentry/attributes are valid
84 */
Miklos Szeredibcb6f6d2016-10-01 07:32:32 +020085static u64 time_to_jiffies(u64 sec, u32 nsec)
Miklos Szeredie5e55582005-09-09 13:10:28 -070086{
Miklos Szeredi685d16d2006-07-30 03:04:08 -070087 if (sec || nsec) {
Miklos Szeredibcb6f6d2016-10-01 07:32:32 +020088 struct timespec64 ts = {
89 sec,
David Sheets21067522017-01-13 15:58:30 +000090 min_t(u32, nsec, NSEC_PER_SEC - 1)
Miklos Szeredibcb6f6d2016-10-01 07:32:32 +020091 };
92
93 return get_jiffies_64() + timespec64_to_jiffies(&ts);
Miklos Szeredi685d16d2006-07-30 03:04:08 -070094 } else
Miklos Szeredi0a0898c2006-07-30 03:04:10 -070095 return 0;
Miklos Szeredie5e55582005-09-09 13:10:28 -070096}
97
Miklos Szeredi6f9f1182006-01-06 00:19:39 -080098/*
99 * Set dentry and possibly attribute timeouts from the lookup/mk*
100 * replies
101 */
Miklos Szeredid123d8e2018-09-28 16:43:23 +0200102void fuse_change_entry_timeout(struct dentry *entry, struct fuse_entry_out *o)
Miklos Szeredi0aa7c692006-01-06 00:19:34 -0800103{
Miklos Szeredi0a0898c2006-07-30 03:04:10 -0700104 fuse_dentry_settime(entry,
105 time_to_jiffies(o->entry_valid, o->entry_valid_nsec));
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700106}
107
108static u64 attr_timeout(struct fuse_attr_out *o)
109{
110 return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
111}
112
Miklos Szeredid123d8e2018-09-28 16:43:23 +0200113u64 entry_attr_timeout(struct fuse_entry_out *o)
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700114{
115 return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800116}
117
Miklos Szeredi2f1e8192018-10-15 15:43:06 +0200118static void fuse_invalidate_attr_mask(struct inode *inode, u32 mask)
119{
120 set_mask_bits(&get_fuse_inode(inode)->inval_mask, 0, mask);
121}
122
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800123/*
124 * Mark the attributes as stale, so that at the next call to
125 * ->getattr() they will be fetched from userspace
126 */
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800127void fuse_invalidate_attr(struct inode *inode)
128{
Miklos Szeredi2f1e8192018-10-15 15:43:06 +0200129 fuse_invalidate_attr_mask(inode, STATX_BASIC_STATS);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800130}
131
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200132static void fuse_dir_changed(struct inode *dir)
133{
134 fuse_invalidate_attr(dir);
135 inode_maybe_inc_iversion(dir, false);
136}
137
Andrew Gallagher451418f2013-11-05 03:55:43 -0800138/**
139 * Mark the attributes as stale due to an atime change. Avoid the invalidate if
140 * atime is not used.
141 */
142void fuse_invalidate_atime(struct inode *inode)
143{
144 if (!IS_RDONLY(inode))
Miklos Szeredi2f1e8192018-10-15 15:43:06 +0200145 fuse_invalidate_attr_mask(inode, STATX_ATIME);
Andrew Gallagher451418f2013-11-05 03:55:43 -0800146}
147
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800148/*
149 * Just mark the entry as stale, so that a next attempt to look it up
150 * will result in a new lookup call to userspace
151 *
152 * This is called when a dentry is about to become negative and the
153 * timeout is unknown (unlink, rmdir, rename and in some cases
154 * lookup)
155 */
Miklos Szeredidbd561d2008-07-25 01:49:00 -0700156void fuse_invalidate_entry_cache(struct dentry *entry)
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800157{
Miklos Szeredi0a0898c2006-07-30 03:04:10 -0700158 fuse_dentry_settime(entry, 0);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800159}
160
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800161/*
162 * Same as fuse_invalidate_entry_cache(), but also try to remove the
163 * dentry from the hash
164 */
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800165static void fuse_invalidate_entry(struct dentry *entry)
166{
167 d_invalidate(entry);
168 fuse_invalidate_entry_cache(entry);
Miklos Szeredi0aa7c692006-01-06 00:19:34 -0800169}
170
Miklos Szeredi70781872014-12-12 09:49:05 +0100171static void fuse_lookup_init(struct fuse_conn *fc, struct fuse_args *args,
Al Viro13983d02016-07-20 22:34:44 -0400172 u64 nodeid, const struct qstr *name,
Miklos Szeredie5e55582005-09-09 13:10:28 -0700173 struct fuse_entry_out *outarg)
174{
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700175 memset(outarg, 0, sizeof(struct fuse_entry_out));
Miklos Szeredid5b48542019-09-10 15:04:08 +0200176 args->opcode = FUSE_LOOKUP;
177 args->nodeid = nodeid;
178 args->in_numargs = 1;
179 args->in_args[0].size = name->len + 1;
180 args->in_args[0].value = name->name;
181 args->out_numargs = 1;
182 args->out_args[0].size = sizeof(struct fuse_entry_out);
183 args->out_args[0].value = outarg;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700184}
185
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800186/*
187 * Check whether the dentry is still valid
188 *
189 * If the entry validity timeout has expired and the dentry is
190 * positive, try to redo the lookup. If the lookup results in a
191 * different inode, then let the VFS invalidate the dentry and redo
192 * the lookup once more. If the lookup results in the same inode,
193 * then refresh the attributes, timeouts and mark the dentry valid.
194 */
Al Viro0b728e12012-06-10 16:03:43 -0400195static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
Miklos Szeredie5e55582005-09-09 13:10:28 -0700196{
Nick Piggin34286d62011-01-07 17:49:57 +1100197 struct inode *inode;
Miklos Szeredi28420da2013-06-03 14:40:22 +0200198 struct dentry *parent;
199 struct fuse_conn *fc;
Miklos Szeredi6314efe2013-10-01 16:41:22 +0200200 struct fuse_inode *fi;
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200201 int ret;
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800202
David Howells2b0143b2015-03-17 22:25:59 +0000203 inode = d_inode_rcu(entry);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800204 if (inode && is_bad_inode(inode))
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200205 goto invalid;
Anand Avati154210c2014-06-26 20:21:57 -0400206 else if (time_before64(fuse_dentry_time(entry), get_jiffies_64()) ||
207 (flags & LOOKUP_REVAL)) {
Miklos Szeredie5e55582005-09-09 13:10:28 -0700208 struct fuse_entry_out outarg;
Miklos Szeredi70781872014-12-12 09:49:05 +0100209 FUSE_ARGS(args);
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100210 struct fuse_forget_link *forget;
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700211 u64 attr_version;
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800212
Miklos Szeredi50322fe2006-02-28 16:59:03 -0800213 /* For negative dentries, always do a fresh lookup */
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800214 if (!inode)
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200215 goto invalid;
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800216
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200217 ret = -ECHILD;
Al Viro0b728e12012-06-10 16:03:43 -0400218 if (flags & LOOKUP_RCU)
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200219 goto out;
Miklos Szeredie7c0a162011-03-21 13:58:06 +0100220
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800221 fc = get_fuse_conn(inode);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700222
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100223 forget = fuse_alloc_forget();
Miklos Szeredi70781872014-12-12 09:49:05 +0100224 ret = -ENOMEM;
225 if (!forget)
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200226 goto out;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800227
Miklos Szeredi7dca9fd2007-11-28 16:21:59 -0800228 attr_version = fuse_get_attr_version(fc);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700229
Miklos Szeredie956edd2006-10-17 00:10:12 -0700230 parent = dget_parent(entry);
David Howells2b0143b2015-03-17 22:25:59 +0000231 fuse_lookup_init(fc, &args, get_node_id(d_inode(parent)),
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700232 &entry->d_name, &outarg);
Miklos Szeredi70781872014-12-12 09:49:05 +0100233 ret = fuse_simple_request(fc, &args);
Miklos Szeredie956edd2006-10-17 00:10:12 -0700234 dput(parent);
Miklos Szeredi50322fe2006-02-28 16:59:03 -0800235 /* Zero nodeid is same as -ENOENT */
Miklos Szeredi70781872014-12-12 09:49:05 +0100236 if (!ret && !outarg.nodeid)
237 ret = -ENOENT;
238 if (!ret) {
Miklos Szeredi6314efe2013-10-01 16:41:22 +0200239 fi = get_fuse_inode(inode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700240 if (outarg.nodeid != get_node_id(inode)) {
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100241 fuse_queue_forget(fc, forget, outarg.nodeid, 1);
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200242 goto invalid;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700243 }
Kirill Tkhaic9d8f5f2018-11-09 13:33:27 +0300244 spin_lock(&fi->lock);
Miklos Szeredi1729a162008-11-26 12:03:54 +0100245 fi->nlookup++;
Kirill Tkhaic9d8f5f2018-11-09 13:33:27 +0300246 spin_unlock(&fi->lock);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700247 }
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100248 kfree(forget);
Miklos Szeredi70781872014-12-12 09:49:05 +0100249 if (ret == -ENOMEM)
250 goto out;
Miklos Szeredieb59bd12019-11-12 11:49:04 +0100251 if (ret || fuse_invalid_attr(&outarg.attr) ||
252 (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200253 goto invalid;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700254
Seth Forshee60bcc882016-08-29 08:46:37 -0500255 forget_all_cached_acls(inode);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700256 fuse_change_attributes(inode, &outarg.attr,
257 entry_attr_timeout(&outarg),
258 attr_version);
259 fuse_change_entry_timeout(entry, &outarg);
Miklos Szeredi28420da2013-06-03 14:40:22 +0200260 } else if (inode) {
Miklos Szeredi6314efe2013-10-01 16:41:22 +0200261 fi = get_fuse_inode(inode);
262 if (flags & LOOKUP_RCU) {
263 if (test_bit(FUSE_I_INIT_RDPLUS, &fi->state))
264 return -ECHILD;
265 } else if (test_and_clear_bit(FUSE_I_INIT_RDPLUS, &fi->state)) {
Miklos Szeredi28420da2013-06-03 14:40:22 +0200266 parent = dget_parent(entry);
David Howells2b0143b2015-03-17 22:25:59 +0000267 fuse_advise_use_readdirplus(d_inode(parent));
Miklos Szeredi28420da2013-06-03 14:40:22 +0200268 dput(parent);
269 }
Miklos Szeredie5e55582005-09-09 13:10:28 -0700270 }
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200271 ret = 1;
272out:
273 return ret;
274
275invalid:
276 ret = 0;
277 goto out;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700278}
279
Khazhismel Kumykov30c6a232019-09-16 16:56:41 -0700280#if BITS_PER_LONG < 64
Miklos Szeredif75fdf22016-10-01 07:32:32 +0200281static int fuse_dentry_init(struct dentry *dentry)
282{
Khazhismel Kumykovdc69e982019-09-17 12:35:33 -0700283 dentry->d_fsdata = kzalloc(sizeof(union fuse_dentry),
284 GFP_KERNEL_ACCOUNT | __GFP_RECLAIMABLE);
Miklos Szeredif75fdf22016-10-01 07:32:32 +0200285
286 return dentry->d_fsdata ? 0 : -ENOMEM;
287}
288static void fuse_dentry_release(struct dentry *dentry)
289{
290 union fuse_dentry *fd = dentry->d_fsdata;
291
292 kfree_rcu(fd, rcu);
293}
Khazhismel Kumykov30c6a232019-09-16 16:56:41 -0700294#endif
Miklos Szeredif75fdf22016-10-01 07:32:32 +0200295
Miklos Szeredi8fab0102018-08-15 17:42:34 +0200296static int fuse_dentry_delete(const struct dentry *dentry)
297{
298 return time_before64(fuse_dentry_time(dentry), get_jiffies_64());
299}
300
Al Viro42695902009-02-20 05:59:13 +0000301const struct dentry_operations fuse_dentry_operations = {
Miklos Szeredie5e55582005-09-09 13:10:28 -0700302 .d_revalidate = fuse_dentry_revalidate,
Miklos Szeredi8fab0102018-08-15 17:42:34 +0200303 .d_delete = fuse_dentry_delete,
Khazhismel Kumykov30c6a232019-09-16 16:56:41 -0700304#if BITS_PER_LONG < 64
Miklos Szeredif75fdf22016-10-01 07:32:32 +0200305 .d_init = fuse_dentry_init,
306 .d_release = fuse_dentry_release,
Khazhismel Kumykov30c6a232019-09-16 16:56:41 -0700307#endif
Miklos Szeredie5e55582005-09-09 13:10:28 -0700308};
309
Miklos Szeredi0ce267f2016-10-18 15:36:48 +0200310const struct dentry_operations fuse_root_dentry_operations = {
Khazhismel Kumykov30c6a232019-09-16 16:56:41 -0700311#if BITS_PER_LONG < 64
Miklos Szeredi0ce267f2016-10-18 15:36:48 +0200312 .d_init = fuse_dentry_init,
313 .d_release = fuse_dentry_release,
Khazhismel Kumykov30c6a232019-09-16 16:56:41 -0700314#endif
Miklos Szeredi0ce267f2016-10-18 15:36:48 +0200315};
316
Timo Savolaa5bfffac2007-04-08 16:04:00 -0700317int fuse_valid_type(int m)
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800318{
319 return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) ||
320 S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
321}
322
Miklos Szeredieb59bd12019-11-12 11:49:04 +0100323bool fuse_invalid_attr(struct fuse_attr *attr)
324{
325 return !fuse_valid_type(attr->mode) ||
326 attr->size > LLONG_MAX;
327}
328
Al Viro13983d02016-07-20 22:34:44 -0400329int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name,
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700330 struct fuse_entry_out *outarg, struct inode **inode)
331{
332 struct fuse_conn *fc = get_fuse_conn_super(sb);
Miklos Szeredi70781872014-12-12 09:49:05 +0100333 FUSE_ARGS(args);
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100334 struct fuse_forget_link *forget;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700335 u64 attr_version;
336 int err;
337
338 *inode = NULL;
339 err = -ENAMETOOLONG;
340 if (name->len > FUSE_NAME_MAX)
341 goto out;
342
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700343
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100344 forget = fuse_alloc_forget();
345 err = -ENOMEM;
Miklos Szeredi70781872014-12-12 09:49:05 +0100346 if (!forget)
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700347 goto out;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700348
349 attr_version = fuse_get_attr_version(fc);
350
Miklos Szeredi70781872014-12-12 09:49:05 +0100351 fuse_lookup_init(fc, &args, nodeid, name, outarg);
352 err = fuse_simple_request(fc, &args);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700353 /* Zero nodeid is same as -ENOENT, but with valid timeout */
354 if (err || !outarg->nodeid)
355 goto out_put_forget;
356
357 err = -EIO;
358 if (!outarg->nodeid)
359 goto out_put_forget;
Miklos Szeredieb59bd12019-11-12 11:49:04 +0100360 if (fuse_invalid_attr(&outarg->attr))
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700361 goto out_put_forget;
362
363 *inode = fuse_iget(sb, outarg->nodeid, outarg->generation,
364 &outarg->attr, entry_attr_timeout(outarg),
365 attr_version);
366 err = -ENOMEM;
367 if (!*inode) {
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100368 fuse_queue_forget(fc, forget, outarg->nodeid, 1);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700369 goto out;
370 }
371 err = 0;
372
373 out_put_forget:
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100374 kfree(forget);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700375 out:
376 return err;
377}
378
Miklos Szeredi0aa7c692006-01-06 00:19:34 -0800379static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
Al Viro00cd8dd2012-06-10 17:13:09 -0400380 unsigned int flags)
Miklos Szeredie5e55582005-09-09 13:10:28 -0700381{
382 int err;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700383 struct fuse_entry_out outarg;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700384 struct inode *inode;
Miklos Szeredi0de62562008-07-25 01:48:59 -0700385 struct dentry *newent;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700386 bool outarg_valid = true;
Miklos Szeredi63576c12018-07-26 16:13:11 +0200387 bool locked;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700388
Miklos Szeredi63576c12018-07-26 16:13:11 +0200389 locked = fuse_lock_inode(dir);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700390 err = fuse_lookup_name(dir->i_sb, get_node_id(dir), &entry->d_name,
391 &outarg, &inode);
Miklos Szeredi63576c12018-07-26 16:13:11 +0200392 fuse_unlock_inode(dir, locked);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700393 if (err == -ENOENT) {
394 outarg_valid = false;
395 err = 0;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800396 }
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700397 if (err)
398 goto out_err;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800399
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700400 err = -EIO;
401 if (inode && get_node_id(inode) == FUSE_ROOT_ID)
402 goto out_iput;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700403
Al Viro41d28bc2014-10-12 22:24:21 -0400404 newent = d_splice_alias(inode, entry);
Miklos Szeredi5835f332013-09-05 11:44:42 +0200405 err = PTR_ERR(newent);
406 if (IS_ERR(newent))
407 goto out_err;
Miklos Szeredid2a85162006-10-17 00:10:11 -0700408
Miklos Szeredi0de62562008-07-25 01:48:59 -0700409 entry = newent ? newent : entry;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700410 if (outarg_valid)
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700411 fuse_change_entry_timeout(entry, &outarg);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800412 else
413 fuse_invalidate_entry_cache(entry);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700414
Miklos Szeredi6c26f712019-10-21 15:57:07 +0200415 if (inode)
416 fuse_advise_use_readdirplus(dir);
Miklos Szeredi0de62562008-07-25 01:48:59 -0700417 return newent;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700418
419 out_iput:
420 iput(inode);
421 out_err:
422 return ERR_PTR(err);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700423}
424
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800425/*
426 * Atomic create+open operation
427 *
428 * If the filesystem doesn't support this, then fall back to separate
429 * 'mknod' + 'open' requests.
430 */
Al Virod9585272012-06-22 12:39:14 +0400431static int fuse_create_open(struct inode *dir, struct dentry *entry,
Al Viro30d90492012-06-22 12:40:19 +0400432 struct file *file, unsigned flags,
Al Virob452a452018-06-08 13:06:28 -0400433 umode_t mode)
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800434{
435 int err;
436 struct inode *inode;
437 struct fuse_conn *fc = get_fuse_conn(dir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100438 FUSE_ARGS(args);
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100439 struct fuse_forget_link *forget;
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200440 struct fuse_create_in inarg;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800441 struct fuse_open_out outopen;
442 struct fuse_entry_out outentry;
Kirill Tkhaiebf84d02018-11-09 13:33:11 +0300443 struct fuse_inode *fi;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800444 struct fuse_file *ff;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800445
Miklos Szerediaf109bc2012-08-15 13:01:24 +0200446 /* Userspace expects S_IFREG in create mode */
447 BUG_ON((mode & S_IFMT) != S_IFREG);
448
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100449 forget = fuse_alloc_forget();
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200450 err = -ENOMEM;
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100451 if (!forget)
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200452 goto out_err;
Miklos Szeredi51eb01e2006-06-25 05:48:50 -0700453
Miklos Szeredice1d5a42006-04-10 22:54:58 -0700454 err = -ENOMEM;
Tejun Heoacf99432008-11-26 12:03:55 +0100455 ff = fuse_file_alloc(fc);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800456 if (!ff)
Miklos Szeredi70781872014-12-12 09:49:05 +0100457 goto out_put_forget_req;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800458
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200459 if (!fc->dont_mask)
460 mode &= ~current_umask();
461
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800462 flags &= ~O_NOCTTY;
463 memset(&inarg, 0, sizeof(inarg));
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700464 memset(&outentry, 0, sizeof(outentry));
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800465 inarg.flags = flags;
466 inarg.mode = mode;
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200467 inarg.umask = current_umask();
Miklos Szeredid5b48542019-09-10 15:04:08 +0200468 args.opcode = FUSE_CREATE;
469 args.nodeid = get_node_id(dir);
470 args.in_numargs = 2;
471 args.in_args[0].size = sizeof(inarg);
472 args.in_args[0].value = &inarg;
473 args.in_args[1].size = entry->d_name.len + 1;
474 args.in_args[1].value = entry->d_name.name;
475 args.out_numargs = 2;
476 args.out_args[0].size = sizeof(outentry);
477 args.out_args[0].value = &outentry;
478 args.out_args[1].size = sizeof(outopen);
479 args.out_args[1].value = &outopen;
Miklos Szeredi70781872014-12-12 09:49:05 +0100480 err = fuse_simple_request(fc, &args);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200481 if (err)
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800482 goto out_free_ff;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800483
484 err = -EIO;
Miklos Szeredieb59bd12019-11-12 11:49:04 +0100485 if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid) ||
486 fuse_invalid_attr(&outentry.attr))
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800487 goto out_free_ff;
488
Miklos Szeredic7b71432009-04-28 16:56:37 +0200489 ff->fh = outopen.fh;
490 ff->nodeid = outentry.nodeid;
491 ff->open_flags = outopen.open_flags;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800492 inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700493 &outentry.attr, entry_attr_timeout(&outentry), 0);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800494 if (!inode) {
495 flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
Kirill Tkhaiebf84d02018-11-09 13:33:11 +0300496 fuse_sync_release(NULL, ff, flags);
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100497 fuse_queue_forget(fc, forget, outentry.nodeid, 1);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200498 err = -ENOMEM;
499 goto out_err;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800500 }
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100501 kfree(forget);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800502 d_instantiate(entry, inode);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700503 fuse_change_entry_timeout(entry, &outentry);
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200504 fuse_dir_changed(dir);
Al Virobe12af32018-06-08 11:44:56 -0400505 err = finish_open(file, entry, generic_file_open);
Al Viro30d90492012-06-22 12:40:19 +0400506 if (err) {
Kirill Tkhaiebf84d02018-11-09 13:33:11 +0300507 fi = get_fuse_inode(inode);
508 fuse_sync_release(fi, ff, flags);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200509 } else {
Miklos Szeredi267d8442017-02-22 20:08:25 +0100510 file->private_data = ff;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200511 fuse_finish_open(inode, file);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800512 }
Al Virod9585272012-06-22 12:39:14 +0400513 return err;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800514
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200515out_free_ff:
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800516 fuse_file_free(ff);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200517out_put_forget_req:
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100518 kfree(forget);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200519out_err:
Al Virod9585272012-06-22 12:39:14 +0400520 return err;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200521}
522
523static int fuse_mknod(struct inode *, struct dentry *, umode_t, dev_t);
Al Virod9585272012-06-22 12:39:14 +0400524static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
Al Viro30d90492012-06-22 12:40:19 +0400525 struct file *file, unsigned flags,
Al Viro44907d72018-06-08 13:32:02 -0400526 umode_t mode)
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200527{
528 int err;
529 struct fuse_conn *fc = get_fuse_conn(dir);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200530 struct dentry *res = NULL;
531
Al Viro00699ad2016-07-05 09:44:53 -0400532 if (d_in_lookup(entry)) {
Al Viro00cd8dd2012-06-10 17:13:09 -0400533 res = fuse_lookup(dir, entry, 0);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200534 if (IS_ERR(res))
Al Virod9585272012-06-22 12:39:14 +0400535 return PTR_ERR(res);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200536
537 if (res)
538 entry = res;
539 }
540
David Howells2b0143b2015-03-17 22:25:59 +0000541 if (!(flags & O_CREAT) || d_really_is_positive(entry))
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200542 goto no_open;
543
544 /* Only creates */
Al Viro73a09dd2018-06-08 13:22:02 -0400545 file->f_mode |= FMODE_CREATED;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200546
547 if (fc->no_create)
548 goto mknod;
549
Al Virob452a452018-06-08 13:06:28 -0400550 err = fuse_create_open(dir, entry, file, flags, mode);
Al Virod9585272012-06-22 12:39:14 +0400551 if (err == -ENOSYS) {
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200552 fc->no_create = 1;
553 goto mknod;
554 }
555out_dput:
556 dput(res);
Al Virod9585272012-06-22 12:39:14 +0400557 return err;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200558
559mknod:
560 err = fuse_mknod(dir, entry, mode, 0);
Al Virod9585272012-06-22 12:39:14 +0400561 if (err)
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200562 goto out_dput;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200563no_open:
Al Viroe45198a2012-06-10 06:48:09 -0400564 return finish_no_open(file, res);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800565}
566
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800567/*
568 * Code shared between mknod, mkdir, symlink and link
569 */
Miklos Szeredi70781872014-12-12 09:49:05 +0100570static int create_new_entry(struct fuse_conn *fc, struct fuse_args *args,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700571 struct inode *dir, struct dentry *entry,
Al Viro541af6a2011-07-26 03:17:33 -0400572 umode_t mode)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700573{
574 struct fuse_entry_out outarg;
575 struct inode *inode;
Al Viroc971e6a2018-05-28 18:27:19 -0400576 struct dentry *d;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700577 int err;
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100578 struct fuse_forget_link *forget;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800579
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100580 forget = fuse_alloc_forget();
Miklos Szeredi70781872014-12-12 09:49:05 +0100581 if (!forget)
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100582 return -ENOMEM;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700583
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700584 memset(&outarg, 0, sizeof(outarg));
Miklos Szeredid5b48542019-09-10 15:04:08 +0200585 args->nodeid = get_node_id(dir);
586 args->out_numargs = 1;
587 args->out_args[0].size = sizeof(outarg);
588 args->out_args[0].value = &outarg;
Miklos Szeredi70781872014-12-12 09:49:05 +0100589 err = fuse_simple_request(fc, args);
Miklos Szeredi2d510132006-11-25 11:09:20 -0800590 if (err)
591 goto out_put_forget_req;
592
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800593 err = -EIO;
Miklos Szeredieb59bd12019-11-12 11:49:04 +0100594 if (invalid_nodeid(outarg.nodeid) || fuse_invalid_attr(&outarg.attr))
Miklos Szeredi2d510132006-11-25 11:09:20 -0800595 goto out_put_forget_req;
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800596
597 if ((outarg.attr.mode ^ mode) & S_IFMT)
Miklos Szeredi2d510132006-11-25 11:09:20 -0800598 goto out_put_forget_req;
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800599
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700600 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700601 &outarg.attr, entry_attr_timeout(&outarg), 0);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700602 if (!inode) {
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100603 fuse_queue_forget(fc, forget, outarg.nodeid, 1);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700604 return -ENOMEM;
605 }
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100606 kfree(forget);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700607
Al Viroc971e6a2018-05-28 18:27:19 -0400608 d_drop(entry);
609 d = d_splice_alias(inode, entry);
610 if (IS_ERR(d))
611 return PTR_ERR(d);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700612
Al Viroc971e6a2018-05-28 18:27:19 -0400613 if (d) {
614 fuse_change_entry_timeout(d, &outarg);
615 dput(d);
616 } else {
617 fuse_change_entry_timeout(entry, &outarg);
618 }
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200619 fuse_dir_changed(dir);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700620 return 0;
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800621
Miklos Szeredi2d510132006-11-25 11:09:20 -0800622 out_put_forget_req:
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100623 kfree(forget);
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800624 return err;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700625}
626
Al Viro1a67aaf2011-07-26 01:52:52 -0400627static int fuse_mknod(struct inode *dir, struct dentry *entry, umode_t mode,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700628 dev_t rdev)
629{
630 struct fuse_mknod_in inarg;
631 struct fuse_conn *fc = get_fuse_conn(dir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100632 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700633
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200634 if (!fc->dont_mask)
635 mode &= ~current_umask();
636
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700637 memset(&inarg, 0, sizeof(inarg));
638 inarg.mode = mode;
639 inarg.rdev = new_encode_dev(rdev);
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200640 inarg.umask = current_umask();
Miklos Szeredid5b48542019-09-10 15:04:08 +0200641 args.opcode = FUSE_MKNOD;
642 args.in_numargs = 2;
643 args.in_args[0].size = sizeof(inarg);
644 args.in_args[0].value = &inarg;
645 args.in_args[1].size = entry->d_name.len + 1;
646 args.in_args[1].value = entry->d_name.name;
Miklos Szeredi70781872014-12-12 09:49:05 +0100647 return create_new_entry(fc, &args, dir, entry, mode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700648}
649
Al Viro4acdaf22011-07-26 01:42:34 -0400650static int fuse_create(struct inode *dir, struct dentry *entry, umode_t mode,
Al Viroebfc3b42012-06-10 18:05:36 -0400651 bool excl)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700652{
653 return fuse_mknod(dir, entry, mode, 0);
654}
655
Al Viro18bb1db2011-07-26 01:41:39 -0400656static int fuse_mkdir(struct inode *dir, struct dentry *entry, umode_t mode)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700657{
658 struct fuse_mkdir_in inarg;
659 struct fuse_conn *fc = get_fuse_conn(dir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100660 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700661
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200662 if (!fc->dont_mask)
663 mode &= ~current_umask();
664
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700665 memset(&inarg, 0, sizeof(inarg));
666 inarg.mode = mode;
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200667 inarg.umask = current_umask();
Miklos Szeredid5b48542019-09-10 15:04:08 +0200668 args.opcode = FUSE_MKDIR;
669 args.in_numargs = 2;
670 args.in_args[0].size = sizeof(inarg);
671 args.in_args[0].value = &inarg;
672 args.in_args[1].size = entry->d_name.len + 1;
673 args.in_args[1].value = entry->d_name.name;
Miklos Szeredi70781872014-12-12 09:49:05 +0100674 return create_new_entry(fc, &args, dir, entry, S_IFDIR);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700675}
676
677static int fuse_symlink(struct inode *dir, struct dentry *entry,
678 const char *link)
679{
680 struct fuse_conn *fc = get_fuse_conn(dir);
681 unsigned len = strlen(link) + 1;
Miklos Szeredi70781872014-12-12 09:49:05 +0100682 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700683
Miklos Szeredid5b48542019-09-10 15:04:08 +0200684 args.opcode = FUSE_SYMLINK;
685 args.in_numargs = 2;
686 args.in_args[0].size = entry->d_name.len + 1;
687 args.in_args[0].value = entry->d_name.name;
688 args.in_args[1].size = len;
689 args.in_args[1].value = link;
Miklos Szeredi70781872014-12-12 09:49:05 +0100690 return create_new_entry(fc, &args, dir, entry, S_IFLNK);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700691}
692
Seth Forshee703c7362016-08-29 08:46:36 -0500693void fuse_update_ctime(struct inode *inode)
Maxim Patlasov31f32672014-04-28 14:19:24 +0200694{
695 if (!IS_NOCMTIME(inode)) {
Deepa Dinamanic2050a42016-09-14 07:48:06 -0700696 inode->i_ctime = current_time(inode);
Maxim Patlasov31f32672014-04-28 14:19:24 +0200697 mark_inode_dirty_sync(inode);
698 }
699}
700
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700701static int fuse_unlink(struct inode *dir, struct dentry *entry)
702{
703 int err;
704 struct fuse_conn *fc = get_fuse_conn(dir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100705 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700706
Miklos Szeredid5b48542019-09-10 15:04:08 +0200707 args.opcode = FUSE_UNLINK;
708 args.nodeid = get_node_id(dir);
709 args.in_numargs = 1;
710 args.in_args[0].size = entry->d_name.len + 1;
711 args.in_args[0].value = entry->d_name.name;
Miklos Szeredi70781872014-12-12 09:49:05 +0100712 err = fuse_simple_request(fc, &args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700713 if (!err) {
David Howells2b0143b2015-03-17 22:25:59 +0000714 struct inode *inode = d_inode(entry);
Miklos Szerediac45d612012-03-05 15:48:11 +0100715 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700716
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +0300717 spin_lock(&fi->lock);
Kirill Tkhai4510d862018-11-09 13:33:17 +0300718 fi->attr_version = atomic64_inc_return(&fc->attr_version);
Miklos Szeredidfca7ce2013-02-04 15:57:42 +0100719 /*
720 * If i_nlink == 0 then unlink doesn't make sense, yet this can
721 * happen if userspace filesystem is careless. It would be
722 * difficult to enforce correct nlink usage so just ignore this
723 * condition here
724 */
725 if (inode->i_nlink > 0)
726 drop_nlink(inode);
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +0300727 spin_unlock(&fi->lock);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700728 fuse_invalidate_attr(inode);
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200729 fuse_dir_changed(dir);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800730 fuse_invalidate_entry_cache(entry);
Maxim Patlasov31f32672014-04-28 14:19:24 +0200731 fuse_update_ctime(inode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700732 } else if (err == -EINTR)
733 fuse_invalidate_entry(entry);
734 return err;
735}
736
737static int fuse_rmdir(struct inode *dir, struct dentry *entry)
738{
739 int err;
740 struct fuse_conn *fc = get_fuse_conn(dir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100741 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700742
Miklos Szeredid5b48542019-09-10 15:04:08 +0200743 args.opcode = FUSE_RMDIR;
744 args.nodeid = get_node_id(dir);
745 args.in_numargs = 1;
746 args.in_args[0].size = entry->d_name.len + 1;
747 args.in_args[0].value = entry->d_name.name;
Miklos Szeredi70781872014-12-12 09:49:05 +0100748 err = fuse_simple_request(fc, &args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700749 if (!err) {
David Howells2b0143b2015-03-17 22:25:59 +0000750 clear_nlink(d_inode(entry));
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200751 fuse_dir_changed(dir);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800752 fuse_invalidate_entry_cache(entry);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700753 } else if (err == -EINTR)
754 fuse_invalidate_entry(entry);
755 return err;
756}
757
Miklos Szeredi1560c972014-04-28 16:43:44 +0200758static int fuse_rename_common(struct inode *olddir, struct dentry *oldent,
759 struct inode *newdir, struct dentry *newent,
760 unsigned int flags, int opcode, size_t argsize)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700761{
762 int err;
Miklos Szeredi1560c972014-04-28 16:43:44 +0200763 struct fuse_rename2_in inarg;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700764 struct fuse_conn *fc = get_fuse_conn(olddir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100765 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700766
Miklos Szeredi1560c972014-04-28 16:43:44 +0200767 memset(&inarg, 0, argsize);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700768 inarg.newdir = get_node_id(newdir);
Miklos Szeredi1560c972014-04-28 16:43:44 +0200769 inarg.flags = flags;
Miklos Szeredid5b48542019-09-10 15:04:08 +0200770 args.opcode = opcode;
771 args.nodeid = get_node_id(olddir);
772 args.in_numargs = 3;
773 args.in_args[0].size = argsize;
774 args.in_args[0].value = &inarg;
775 args.in_args[1].size = oldent->d_name.len + 1;
776 args.in_args[1].value = oldent->d_name.name;
777 args.in_args[2].size = newent->d_name.len + 1;
778 args.in_args[2].value = newent->d_name.name;
Miklos Szeredi70781872014-12-12 09:49:05 +0100779 err = fuse_simple_request(fc, &args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700780 if (!err) {
Miklos Szeredi08b63302007-11-28 16:22:03 -0800781 /* ctime changes */
David Howells2b0143b2015-03-17 22:25:59 +0000782 fuse_invalidate_attr(d_inode(oldent));
783 fuse_update_ctime(d_inode(oldent));
Miklos Szeredi08b63302007-11-28 16:22:03 -0800784
Miklos Szeredi1560c972014-04-28 16:43:44 +0200785 if (flags & RENAME_EXCHANGE) {
David Howells2b0143b2015-03-17 22:25:59 +0000786 fuse_invalidate_attr(d_inode(newent));
787 fuse_update_ctime(d_inode(newent));
Miklos Szeredi1560c972014-04-28 16:43:44 +0200788 }
789
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200790 fuse_dir_changed(olddir);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700791 if (olddir != newdir)
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200792 fuse_dir_changed(newdir);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800793
794 /* newent will end up negative */
David Howells2b0143b2015-03-17 22:25:59 +0000795 if (!(flags & RENAME_EXCHANGE) && d_really_is_positive(newent)) {
796 fuse_invalidate_attr(d_inode(newent));
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800797 fuse_invalidate_entry_cache(newent);
David Howells2b0143b2015-03-17 22:25:59 +0000798 fuse_update_ctime(d_inode(newent));
Miklos Szeredi5219f342009-11-04 10:24:52 +0100799 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700800 } else if (err == -EINTR) {
801 /* If request was interrupted, DEITY only knows if the
802 rename actually took place. If the invalidation
803 fails (e.g. some process has CWD under the renamed
804 directory), then there can be inconsistency between
805 the dcache and the real filesystem. Tough luck. */
806 fuse_invalidate_entry(oldent);
David Howells2b0143b2015-03-17 22:25:59 +0000807 if (d_really_is_positive(newent))
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700808 fuse_invalidate_entry(newent);
809 }
810
811 return err;
812}
813
Miklos Szeredi1560c972014-04-28 16:43:44 +0200814static int fuse_rename2(struct inode *olddir, struct dentry *oldent,
815 struct inode *newdir, struct dentry *newent,
816 unsigned int flags)
817{
818 struct fuse_conn *fc = get_fuse_conn(olddir);
819 int err;
820
Vivek Goyal519525f2020-02-05 08:15:46 -0500821 if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT))
Miklos Szeredi1560c972014-04-28 16:43:44 +0200822 return -EINVAL;
823
Miklos Szeredi4237ba42014-07-10 10:50:19 +0200824 if (flags) {
825 if (fc->no_rename2 || fc->minor < 23)
826 return -EINVAL;
Miklos Szeredi1560c972014-04-28 16:43:44 +0200827
Miklos Szeredi4237ba42014-07-10 10:50:19 +0200828 err = fuse_rename_common(olddir, oldent, newdir, newent, flags,
829 FUSE_RENAME2,
830 sizeof(struct fuse_rename2_in));
831 if (err == -ENOSYS) {
832 fc->no_rename2 = 1;
833 err = -EINVAL;
834 }
835 } else {
836 err = fuse_rename_common(olddir, oldent, newdir, newent, 0,
837 FUSE_RENAME,
838 sizeof(struct fuse_rename_in));
Miklos Szeredi1560c972014-04-28 16:43:44 +0200839 }
Miklos Szeredi1560c972014-04-28 16:43:44 +0200840
Miklos Szeredi4237ba42014-07-10 10:50:19 +0200841 return err;
842}
843
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700844static int fuse_link(struct dentry *entry, struct inode *newdir,
845 struct dentry *newent)
846{
847 int err;
848 struct fuse_link_in inarg;
David Howells2b0143b2015-03-17 22:25:59 +0000849 struct inode *inode = d_inode(entry);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700850 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +0100851 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700852
853 memset(&inarg, 0, sizeof(inarg));
854 inarg.oldnodeid = get_node_id(inode);
Miklos Szeredid5b48542019-09-10 15:04:08 +0200855 args.opcode = FUSE_LINK;
856 args.in_numargs = 2;
857 args.in_args[0].size = sizeof(inarg);
858 args.in_args[0].value = &inarg;
859 args.in_args[1].size = newent->d_name.len + 1;
860 args.in_args[1].value = newent->d_name.name;
Miklos Szeredi70781872014-12-12 09:49:05 +0100861 err = create_new_entry(fc, &args, newdir, newent, inode->i_mode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700862 /* Contrary to "normal" filesystems it can happen that link
863 makes two "logical" inodes point to the same "physical"
864 inode. We invalidate the attributes of the old one, so it
865 will reflect changes in the backing inode (link count,
866 etc.)
867 */
Miklos Szerediac45d612012-03-05 15:48:11 +0100868 if (!err) {
869 struct fuse_inode *fi = get_fuse_inode(inode);
870
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +0300871 spin_lock(&fi->lock);
Kirill Tkhai4510d862018-11-09 13:33:17 +0300872 fi->attr_version = atomic64_inc_return(&fc->attr_version);
Miklos Szeredic634da72019-11-12 11:49:04 +0100873 if (likely(inode->i_nlink < UINT_MAX))
874 inc_nlink(inode);
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +0300875 spin_unlock(&fi->lock);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700876 fuse_invalidate_attr(inode);
Maxim Patlasov31f32672014-04-28 14:19:24 +0200877 fuse_update_ctime(inode);
Miklos Szerediac45d612012-03-05 15:48:11 +0100878 } else if (err == -EINTR) {
879 fuse_invalidate_attr(inode);
880 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700881 return err;
882}
883
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700884static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
885 struct kstat *stat)
886{
Miklos Szeredi203627b2012-05-10 19:49:38 +0400887 unsigned int blkbits;
Pavel Emelyanov83732002013-10-10 17:10:46 +0400888 struct fuse_conn *fc = get_fuse_conn(inode);
889
890 /* see the comment in fuse_change_attributes() */
Maxim Patlasovb0aa7602013-12-26 19:51:11 +0400891 if (fc->writeback_cache && S_ISREG(inode->i_mode)) {
Pavel Emelyanov83732002013-10-10 17:10:46 +0400892 attr->size = i_size_read(inode);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +0400893 attr->mtime = inode->i_mtime.tv_sec;
894 attr->mtimensec = inode->i_mtime.tv_nsec;
Maxim Patlasov31f32672014-04-28 14:19:24 +0200895 attr->ctime = inode->i_ctime.tv_sec;
896 attr->ctimensec = inode->i_ctime.tv_nsec;
Maxim Patlasovb0aa7602013-12-26 19:51:11 +0400897 }
Miklos Szeredi203627b2012-05-10 19:49:38 +0400898
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700899 stat->dev = inode->i_sb->s_dev;
900 stat->ino = attr->ino;
901 stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
902 stat->nlink = attr->nlink;
Eric W. Biederman8cb08322018-02-21 11:18:07 -0600903 stat->uid = make_kuid(fc->user_ns, attr->uid);
904 stat->gid = make_kgid(fc->user_ns, attr->gid);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700905 stat->rdev = inode->i_rdev;
906 stat->atime.tv_sec = attr->atime;
907 stat->atime.tv_nsec = attr->atimensec;
908 stat->mtime.tv_sec = attr->mtime;
909 stat->mtime.tv_nsec = attr->mtimensec;
910 stat->ctime.tv_sec = attr->ctime;
911 stat->ctime.tv_nsec = attr->ctimensec;
912 stat->size = attr->size;
913 stat->blocks = attr->blocks;
Miklos Szeredi203627b2012-05-10 19:49:38 +0400914
915 if (attr->blksize != 0)
916 blkbits = ilog2(attr->blksize);
917 else
918 blkbits = inode->i_sb->s_blocksize_bits;
919
920 stat->blksize = 1 << blkbits;
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700921}
922
Miklos Szeredic79e3222007-10-18 03:06:59 -0700923static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
924 struct file *file)
Miklos Szeredie5e55582005-09-09 13:10:28 -0700925{
926 int err;
Miklos Szeredic79e3222007-10-18 03:06:59 -0700927 struct fuse_getattr_in inarg;
928 struct fuse_attr_out outarg;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700929 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +0100930 FUSE_ARGS(args);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700931 u64 attr_version;
932
Miklos Szeredi7dca9fd2007-11-28 16:21:59 -0800933 attr_version = fuse_get_attr_version(fc);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700934
Miklos Szeredic79e3222007-10-18 03:06:59 -0700935 memset(&inarg, 0, sizeof(inarg));
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700936 memset(&outarg, 0, sizeof(outarg));
Miklos Szeredic79e3222007-10-18 03:06:59 -0700937 /* Directories have separate file-handle space */
938 if (file && S_ISREG(inode->i_mode)) {
939 struct fuse_file *ff = file->private_data;
940
941 inarg.getattr_flags |= FUSE_GETATTR_FH;
942 inarg.fh = ff->fh;
943 }
Miklos Szeredid5b48542019-09-10 15:04:08 +0200944 args.opcode = FUSE_GETATTR;
945 args.nodeid = get_node_id(inode);
946 args.in_numargs = 1;
947 args.in_args[0].size = sizeof(inarg);
948 args.in_args[0].value = &inarg;
949 args.out_numargs = 1;
950 args.out_args[0].size = sizeof(outarg);
951 args.out_args[0].value = &outarg;
Miklos Szeredi70781872014-12-12 09:49:05 +0100952 err = fuse_simple_request(fc, &args);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700953 if (!err) {
Miklos Szeredieb59bd12019-11-12 11:49:04 +0100954 if (fuse_invalid_attr(&outarg.attr) ||
955 (inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
Miklos Szeredie5e55582005-09-09 13:10:28 -0700956 make_bad_inode(inode);
957 err = -EIO;
958 } else {
Miklos Szeredic79e3222007-10-18 03:06:59 -0700959 fuse_change_attributes(inode, &outarg.attr,
960 attr_timeout(&outarg),
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700961 attr_version);
962 if (stat)
Miklos Szeredic79e3222007-10-18 03:06:59 -0700963 fuse_fillattr(inode, &outarg.attr, stat);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700964 }
965 }
966 return err;
967}
968
Miklos Szeredi5b97eea2017-09-12 16:57:54 +0200969static int fuse_update_get_attr(struct inode *inode, struct file *file,
Miklos Szeredi2f1e8192018-10-15 15:43:06 +0200970 struct kstat *stat, u32 request_mask,
971 unsigned int flags)
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800972{
973 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredi5b97eea2017-09-12 16:57:54 +0200974 int err = 0;
Miklos Szeredibf5c1892018-03-20 17:11:44 +0100975 bool sync;
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800976
Miklos Szeredibf5c1892018-03-20 17:11:44 +0100977 if (flags & AT_STATX_FORCE_SYNC)
978 sync = true;
979 else if (flags & AT_STATX_DONT_SYNC)
980 sync = false;
Miklos Szeredi2f1e8192018-10-15 15:43:06 +0200981 else if (request_mask & READ_ONCE(fi->inval_mask))
982 sync = true;
Miklos Szeredibf5c1892018-03-20 17:11:44 +0100983 else
984 sync = time_before64(fi->i_time, get_jiffies_64());
985
986 if (sync) {
Seth Forshee60bcc882016-08-29 08:46:37 -0500987 forget_all_cached_acls(inode);
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800988 err = fuse_do_getattr(inode, stat, file);
Miklos Szeredi5b97eea2017-09-12 16:57:54 +0200989 } else if (stat) {
990 generic_fillattr(inode, stat);
991 stat->mode = fi->orig_i_mode;
992 stat->ino = fi->orig_ino;
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800993 }
994
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800995 return err;
996}
997
Miklos Szeredi5b97eea2017-09-12 16:57:54 +0200998int fuse_update_attributes(struct inode *inode, struct file *file)
999{
Miklos Szeredi802dc042018-10-15 15:43:06 +02001000 /* Do *not* need to get atime for internal purposes */
1001 return fuse_update_get_attr(inode, file, NULL,
1002 STATX_BASIC_STATS & ~STATX_ATIME, 0);
Miklos Szeredi5b97eea2017-09-12 16:57:54 +02001003}
1004
John Muir3b463ae2009-05-31 11:13:57 -04001005int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid,
John Muir451d0f52011-12-06 21:50:06 +01001006 u64 child_nodeid, struct qstr *name)
John Muir3b463ae2009-05-31 11:13:57 -04001007{
1008 int err = -ENOTDIR;
1009 struct inode *parent;
1010 struct dentry *dir;
1011 struct dentry *entry;
1012
1013 parent = ilookup5(sb, parent_nodeid, fuse_inode_eq, &parent_nodeid);
1014 if (!parent)
1015 return -ENOENT;
1016
Al Viro59551022016-01-22 15:40:57 -05001017 inode_lock(parent);
John Muir3b463ae2009-05-31 11:13:57 -04001018 if (!S_ISDIR(parent->i_mode))
1019 goto unlock;
1020
1021 err = -ENOENT;
1022 dir = d_find_alias(parent);
1023 if (!dir)
1024 goto unlock;
1025
Linus Torvalds8387ff22016-06-10 07:51:30 -07001026 name->hash = full_name_hash(dir, name->name, name->len);
John Muir3b463ae2009-05-31 11:13:57 -04001027 entry = d_lookup(dir, name);
1028 dput(dir);
1029 if (!entry)
1030 goto unlock;
1031
Miklos Szeredi261aaba72018-10-01 10:07:05 +02001032 fuse_dir_changed(parent);
John Muir3b463ae2009-05-31 11:13:57 -04001033 fuse_invalidate_entry(entry);
John Muir451d0f52011-12-06 21:50:06 +01001034
David Howells2b0143b2015-03-17 22:25:59 +00001035 if (child_nodeid != 0 && d_really_is_positive(entry)) {
Al Viro59551022016-01-22 15:40:57 -05001036 inode_lock(d_inode(entry));
David Howells2b0143b2015-03-17 22:25:59 +00001037 if (get_node_id(d_inode(entry)) != child_nodeid) {
John Muir451d0f52011-12-06 21:50:06 +01001038 err = -ENOENT;
1039 goto badentry;
1040 }
1041 if (d_mountpoint(entry)) {
1042 err = -EBUSY;
1043 goto badentry;
1044 }
David Howellse36cb0b2015-01-29 12:02:35 +00001045 if (d_is_dir(entry)) {
John Muir451d0f52011-12-06 21:50:06 +01001046 shrink_dcache_parent(entry);
1047 if (!simple_empty(entry)) {
1048 err = -ENOTEMPTY;
1049 goto badentry;
1050 }
David Howells2b0143b2015-03-17 22:25:59 +00001051 d_inode(entry)->i_flags |= S_DEAD;
John Muir451d0f52011-12-06 21:50:06 +01001052 }
1053 dont_mount(entry);
David Howells2b0143b2015-03-17 22:25:59 +00001054 clear_nlink(d_inode(entry));
John Muir451d0f52011-12-06 21:50:06 +01001055 err = 0;
1056 badentry:
Al Viro59551022016-01-22 15:40:57 -05001057 inode_unlock(d_inode(entry));
John Muir451d0f52011-12-06 21:50:06 +01001058 if (!err)
1059 d_delete(entry);
1060 } else {
1061 err = 0;
1062 }
John Muir3b463ae2009-05-31 11:13:57 -04001063 dput(entry);
John Muir3b463ae2009-05-31 11:13:57 -04001064
1065 unlock:
Al Viro59551022016-01-22 15:40:57 -05001066 inode_unlock(parent);
John Muir3b463ae2009-05-31 11:13:57 -04001067 iput(parent);
1068 return err;
1069}
1070
Miklos Szeredi87729a52005-09-09 13:10:34 -07001071/*
1072 * Calling into a user-controlled filesystem gives the filesystem
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001073 * daemon ptrace-like capabilities over the current process. This
Miklos Szeredi87729a52005-09-09 13:10:34 -07001074 * means, that the filesystem daemon is able to record the exact
1075 * filesystem operations performed, and can also control the behavior
1076 * of the requester process in otherwise impossible ways. For example
1077 * it can delay the operation for arbitrary length of time allowing
1078 * DoS against the requester.
1079 *
1080 * For this reason only those processes can call into the filesystem,
1081 * for which the owner of the mount has ptrace privilege. This
1082 * excludes processes started by other users, suid or sgid processes.
1083 */
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001084int fuse_allow_current_process(struct fuse_conn *fc)
Miklos Szeredi87729a52005-09-09 13:10:34 -07001085{
David Howellsc69e8d92008-11-14 10:39:19 +11001086 const struct cred *cred;
David Howellsc69e8d92008-11-14 10:39:19 +11001087
Miklos Szeredi29433a22016-10-01 07:32:32 +02001088 if (fc->allow_other)
Seth Forshee73f03c22017-12-22 15:32:33 +01001089 return current_in_userns(fc->user_ns);
Miklos Szeredi87729a52005-09-09 13:10:34 -07001090
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001091 cred = current_cred();
Eric W. Biederman499dcf22012-02-07 16:26:03 -08001092 if (uid_eq(cred->euid, fc->user_id) &&
1093 uid_eq(cred->suid, fc->user_id) &&
1094 uid_eq(cred->uid, fc->user_id) &&
1095 gid_eq(cred->egid, fc->group_id) &&
1096 gid_eq(cred->sgid, fc->group_id) &&
1097 gid_eq(cred->gid, fc->group_id))
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001098 return 1;
Miklos Szeredi87729a52005-09-09 13:10:34 -07001099
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001100 return 0;
Miklos Szeredi87729a52005-09-09 13:10:34 -07001101}
1102
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001103static int fuse_access(struct inode *inode, int mask)
1104{
1105 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001106 FUSE_ARGS(args);
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001107 struct fuse_access_in inarg;
1108 int err;
1109
Miklos Szeredi698fa1d2013-10-01 16:41:23 +02001110 BUG_ON(mask & MAY_NOT_BLOCK);
1111
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001112 if (fc->no_access)
1113 return 0;
1114
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001115 memset(&inarg, 0, sizeof(inarg));
Al Viroe6305c42008-07-15 21:03:57 -04001116 inarg.mask = mask & (MAY_READ | MAY_WRITE | MAY_EXEC);
Miklos Szeredid5b48542019-09-10 15:04:08 +02001117 args.opcode = FUSE_ACCESS;
1118 args.nodeid = get_node_id(inode);
1119 args.in_numargs = 1;
1120 args.in_args[0].size = sizeof(inarg);
1121 args.in_args[0].value = &inarg;
Miklos Szeredi70781872014-12-12 09:49:05 +01001122 err = fuse_simple_request(fc, &args);
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001123 if (err == -ENOSYS) {
1124 fc->no_access = 1;
1125 err = 0;
1126 }
1127 return err;
1128}
1129
Al Viro10556cb22011-06-20 19:28:19 -04001130static int fuse_perm_getattr(struct inode *inode, int mask)
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001131{
Al Viro10556cb22011-06-20 19:28:19 -04001132 if (mask & MAY_NOT_BLOCK)
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001133 return -ECHILD;
1134
Seth Forshee60bcc882016-08-29 08:46:37 -05001135 forget_all_cached_acls(inode);
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001136 return fuse_do_getattr(inode, NULL, NULL);
1137}
1138
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001139/*
1140 * Check permission. The two basic access models of FUSE are:
1141 *
1142 * 1) Local access checking ('default_permissions' mount option) based
1143 * on file mode. This is the plain old disk filesystem permission
1144 * modell.
1145 *
1146 * 2) "Remote" access checking, where server is responsible for
1147 * checking permission in each inode operation. An exception to this
1148 * is if ->permission() was invoked from sys_access() in which case an
1149 * access request is sent. Execute permission is still checked
1150 * locally based on file mode.
1151 */
Al Viro10556cb22011-06-20 19:28:19 -04001152static int fuse_permission(struct inode *inode, int mask)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001153{
1154 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi244f6382007-10-16 23:31:02 -07001155 bool refreshed = false;
1156 int err = 0;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001157
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001158 if (!fuse_allow_current_process(fc))
Miklos Szeredie5e55582005-09-09 13:10:28 -07001159 return -EACCES;
Miklos Szeredi244f6382007-10-16 23:31:02 -07001160
1161 /*
Miklos Szeredie8e96152007-10-16 23:31:06 -07001162 * If attributes are needed, refresh them before proceeding
Miklos Szeredi244f6382007-10-16 23:31:02 -07001163 */
Miklos Szeredi29433a22016-10-01 07:32:32 +02001164 if (fc->default_permissions ||
Miklos Szeredie8e96152007-10-16 23:31:06 -07001165 ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) {
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001166 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredid233c7d2018-12-03 10:14:43 +01001167 u32 perm_mask = STATX_MODE | STATX_UID | STATX_GID;
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001168
Miklos Szeredid233c7d2018-12-03 10:14:43 +01001169 if (perm_mask & READ_ONCE(fi->inval_mask) ||
1170 time_before64(fi->i_time, get_jiffies_64())) {
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001171 refreshed = true;
1172
Al Viro10556cb22011-06-20 19:28:19 -04001173 err = fuse_perm_getattr(inode, mask);
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001174 if (err)
1175 return err;
1176 }
Miklos Szeredi244f6382007-10-16 23:31:02 -07001177 }
1178
Miklos Szeredi29433a22016-10-01 07:32:32 +02001179 if (fc->default_permissions) {
Al Viro2830ba72011-06-20 19:16:29 -04001180 err = generic_permission(inode, mask);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001181
1182 /* If permission is denied, try to refresh file
1183 attributes. This is also needed, because the root
1184 node will at first have no permissions */
Miklos Szeredi244f6382007-10-16 23:31:02 -07001185 if (err == -EACCES && !refreshed) {
Al Viro10556cb22011-06-20 19:28:19 -04001186 err = fuse_perm_getattr(inode, mask);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001187 if (!err)
Al Viro2830ba72011-06-20 19:16:29 -04001188 err = generic_permission(inode, mask);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001189 }
1190
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001191 /* Note: the opposite of the above test does not
1192 exist. So if permissions are revoked this won't be
1193 noticed immediately, only after the attribute
1194 timeout has expired */
Eric Paris9cfcac82010-07-23 11:43:51 -04001195 } else if (mask & (MAY_ACCESS | MAY_CHDIR)) {
Miklos Szeredie8e96152007-10-16 23:31:06 -07001196 err = fuse_access(inode, mask);
1197 } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
1198 if (!(inode->i_mode & S_IXUGO)) {
1199 if (refreshed)
1200 return -EACCES;
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001201
Al Viro10556cb22011-06-20 19:28:19 -04001202 err = fuse_perm_getattr(inode, mask);
Miklos Szeredie8e96152007-10-16 23:31:06 -07001203 if (!err && !(inode->i_mode & S_IXUGO))
1204 return -EACCES;
1205 }
Miklos Szeredie5e55582005-09-09 13:10:28 -07001206 }
Miklos Szeredi244f6382007-10-16 23:31:02 -07001207 return err;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001208}
1209
Dan Schatzberg5571f1e2018-10-11 08:17:00 -07001210static int fuse_readlink_page(struct inode *inode, struct page *page)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001211{
Miklos Szeredie5e55582005-09-09 13:10:28 -07001212 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi4c29afe2019-09-10 15:04:09 +02001213 struct fuse_page_desc desc = { .length = PAGE_SIZE - 1 };
1214 struct fuse_args_pages ap = {
1215 .num_pages = 1,
1216 .pages = &page,
1217 .descs = &desc,
1218 };
1219 char *link;
1220 ssize_t res;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001221
Miklos Szeredi4c29afe2019-09-10 15:04:09 +02001222 ap.args.opcode = FUSE_READLINK;
1223 ap.args.nodeid = get_node_id(inode);
1224 ap.args.out_pages = true;
1225 ap.args.out_argvar = true;
1226 ap.args.page_zeroing = true;
1227 ap.args.out_numargs = 1;
1228 ap.args.out_args[0].size = desc.length;
1229 res = fuse_simple_request(fc, &ap.args);
Al Viro6b255392015-11-17 10:20:54 -05001230
Andrew Gallagher451418f2013-11-05 03:55:43 -08001231 fuse_invalidate_atime(inode);
Dan Schatzberg5571f1e2018-10-11 08:17:00 -07001232
Miklos Szeredi4c29afe2019-09-10 15:04:09 +02001233 if (res < 0)
1234 return res;
1235
1236 if (WARN_ON(res >= PAGE_SIZE))
1237 return -EIO;
1238
1239 link = page_address(page);
1240 link[res] = '\0';
1241
1242 return 0;
Dan Schatzberg5571f1e2018-10-11 08:17:00 -07001243}
1244
1245static const char *fuse_get_link(struct dentry *dentry, struct inode *inode,
1246 struct delayed_call *callback)
1247{
1248 struct fuse_conn *fc = get_fuse_conn(inode);
1249 struct page *page;
1250 int err;
1251
1252 err = -EIO;
1253 if (is_bad_inode(inode))
1254 goto out_err;
1255
1256 if (fc->cache_symlinks)
1257 return page_get_link(dentry, inode, callback);
1258
1259 err = -ECHILD;
1260 if (!dentry)
1261 goto out_err;
1262
1263 page = alloc_page(GFP_KERNEL);
1264 err = -ENOMEM;
1265 if (!page)
1266 goto out_err;
1267
1268 err = fuse_readlink_page(inode, page);
1269 if (err) {
1270 __free_page(page);
1271 goto out_err;
1272 }
1273
1274 set_delayed_call(callback, page_put_link, page);
1275
1276 return page_address(page);
1277
1278out_err:
1279 return ERR_PTR(err);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001280}
1281
Miklos Szeredie5e55582005-09-09 13:10:28 -07001282static int fuse_dir_open(struct inode *inode, struct file *file)
1283{
Miklos Szeredi91fe96b2009-04-28 16:56:37 +02001284 return fuse_open_common(inode, file, true);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001285}
1286
1287static int fuse_dir_release(struct inode *inode, struct file *file)
1288{
Chad Austin2e64ff12018-12-10 10:54:52 -08001289 fuse_release_common(file, true);
Miklos Szeredi8b0797a2009-04-28 16:56:39 +02001290
1291 return 0;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001292}
1293
Josef Bacik02c24a82011-07-16 20:44:56 -04001294static int fuse_dir_fsync(struct file *file, loff_t start, loff_t end,
1295 int datasync)
Miklos Szeredi82547982005-09-09 13:10:38 -07001296{
Miklos Szeredia9c2d1e2018-12-03 10:14:43 +01001297 struct inode *inode = file->f_mapping->host;
1298 struct fuse_conn *fc = get_fuse_conn(inode);
1299 int err;
1300
1301 if (is_bad_inode(inode))
1302 return -EIO;
1303
1304 if (fc->no_fsyncdir)
1305 return 0;
1306
1307 inode_lock(inode);
1308 err = fuse_fsync_common(file, start, end, datasync, FUSE_FSYNCDIR);
1309 if (err == -ENOSYS) {
1310 fc->no_fsyncdir = 1;
1311 err = 0;
1312 }
1313 inode_unlock(inode);
1314
1315 return err;
Miklos Szeredi82547982005-09-09 13:10:38 -07001316}
1317
Miklos Szeredib18da0c2011-12-13 11:58:49 +01001318static long fuse_dir_ioctl(struct file *file, unsigned int cmd,
1319 unsigned long arg)
1320{
1321 struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1322
1323 /* FUSE_IOCTL_DIR only supported for API version >= 7.18 */
1324 if (fc->minor < 18)
1325 return -ENOTTY;
1326
1327 return fuse_ioctl_common(file, cmd, arg, FUSE_IOCTL_DIR);
1328}
1329
1330static long fuse_dir_compat_ioctl(struct file *file, unsigned int cmd,
1331 unsigned long arg)
1332{
1333 struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1334
1335 if (fc->minor < 18)
1336 return -ENOTTY;
1337
1338 return fuse_ioctl_common(file, cmd, arg,
1339 FUSE_IOCTL_COMPAT | FUSE_IOCTL_DIR);
1340}
1341
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001342static bool update_mtime(unsigned ivalid, bool trust_local_mtime)
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001343{
1344 /* Always update if mtime is explicitly set */
1345 if (ivalid & ATTR_MTIME_SET)
1346 return true;
1347
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001348 /* Or if kernel i_mtime is the official one */
1349 if (trust_local_mtime)
1350 return true;
1351
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001352 /* If it's an open(O_TRUNC) or an ftruncate(), don't update */
1353 if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE)))
1354 return false;
1355
1356 /* In all other cases update */
1357 return true;
1358}
1359
Eric W. Biederman8cb08322018-02-21 11:18:07 -06001360static void iattr_to_fattr(struct fuse_conn *fc, struct iattr *iattr,
1361 struct fuse_setattr_in *arg, bool trust_local_cmtime)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001362{
1363 unsigned ivalid = iattr->ia_valid;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001364
1365 if (ivalid & ATTR_MODE)
Miklos Szeredibefc6492005-11-07 00:59:52 -08001366 arg->valid |= FATTR_MODE, arg->mode = iattr->ia_mode;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001367 if (ivalid & ATTR_UID)
Eric W. Biederman8cb08322018-02-21 11:18:07 -06001368 arg->valid |= FATTR_UID, arg->uid = from_kuid(fc->user_ns, iattr->ia_uid);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001369 if (ivalid & ATTR_GID)
Eric W. Biederman8cb08322018-02-21 11:18:07 -06001370 arg->valid |= FATTR_GID, arg->gid = from_kgid(fc->user_ns, iattr->ia_gid);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001371 if (ivalid & ATTR_SIZE)
Miklos Szeredibefc6492005-11-07 00:59:52 -08001372 arg->valid |= FATTR_SIZE, arg->size = iattr->ia_size;
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001373 if (ivalid & ATTR_ATIME) {
1374 arg->valid |= FATTR_ATIME;
Miklos Szeredibefc6492005-11-07 00:59:52 -08001375 arg->atime = iattr->ia_atime.tv_sec;
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001376 arg->atimensec = iattr->ia_atime.tv_nsec;
1377 if (!(ivalid & ATTR_ATIME_SET))
1378 arg->valid |= FATTR_ATIME_NOW;
1379 }
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001380 if ((ivalid & ATTR_MTIME) && update_mtime(ivalid, trust_local_cmtime)) {
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001381 arg->valid |= FATTR_MTIME;
Miklos Szeredibefc6492005-11-07 00:59:52 -08001382 arg->mtime = iattr->ia_mtime.tv_sec;
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001383 arg->mtimensec = iattr->ia_mtime.tv_nsec;
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001384 if (!(ivalid & ATTR_MTIME_SET) && !trust_local_cmtime)
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001385 arg->valid |= FATTR_MTIME_NOW;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001386 }
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001387 if ((ivalid & ATTR_CTIME) && trust_local_cmtime) {
1388 arg->valid |= FATTR_CTIME;
1389 arg->ctime = iattr->ia_ctime.tv_sec;
1390 arg->ctimensec = iattr->ia_ctime.tv_nsec;
1391 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001392}
1393
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001394/*
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001395 * Prevent concurrent writepages on inode
1396 *
1397 * This is done by adding a negative bias to the inode write counter
1398 * and waiting for all pending writes to finish.
1399 */
1400void fuse_set_nowrite(struct inode *inode)
1401{
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001402 struct fuse_inode *fi = get_fuse_inode(inode);
1403
Al Viro59551022016-01-22 15:40:57 -05001404 BUG_ON(!inode_is_locked(inode));
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001405
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001406 spin_lock(&fi->lock);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001407 BUG_ON(fi->writectr < 0);
1408 fi->writectr += FUSE_NOWRITE;
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001409 spin_unlock(&fi->lock);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001410 wait_event(fi->page_waitq, fi->writectr == FUSE_NOWRITE);
1411}
1412
1413/*
1414 * Allow writepages on inode
1415 *
1416 * Remove the bias from the writecounter and send any queued
1417 * writepages.
1418 */
1419static void __fuse_release_nowrite(struct inode *inode)
1420{
1421 struct fuse_inode *fi = get_fuse_inode(inode);
1422
1423 BUG_ON(fi->writectr != FUSE_NOWRITE);
1424 fi->writectr = 0;
1425 fuse_flush_writepages(inode);
1426}
1427
1428void fuse_release_nowrite(struct inode *inode)
1429{
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001430 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001431
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001432 spin_lock(&fi->lock);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001433 __fuse_release_nowrite(inode);
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001434 spin_unlock(&fi->lock);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001435}
1436
Miklos Szeredi70781872014-12-12 09:49:05 +01001437static void fuse_setattr_fill(struct fuse_conn *fc, struct fuse_args *args,
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001438 struct inode *inode,
1439 struct fuse_setattr_in *inarg_p,
1440 struct fuse_attr_out *outarg_p)
1441{
Miklos Szeredid5b48542019-09-10 15:04:08 +02001442 args->opcode = FUSE_SETATTR;
1443 args->nodeid = get_node_id(inode);
1444 args->in_numargs = 1;
1445 args->in_args[0].size = sizeof(*inarg_p);
1446 args->in_args[0].value = inarg_p;
1447 args->out_numargs = 1;
1448 args->out_args[0].size = sizeof(*outarg_p);
1449 args->out_args[0].value = outarg_p;
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001450}
1451
1452/*
1453 * Flush inode->i_mtime to the server
1454 */
Maxim Patlasovab9e13f2014-04-28 14:19:24 +02001455int fuse_flush_times(struct inode *inode, struct fuse_file *ff)
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001456{
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001457 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001458 FUSE_ARGS(args);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001459 struct fuse_setattr_in inarg;
1460 struct fuse_attr_out outarg;
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001461
1462 memset(&inarg, 0, sizeof(inarg));
1463 memset(&outarg, 0, sizeof(outarg));
1464
Maxim Patlasovab9e13f2014-04-28 14:19:24 +02001465 inarg.valid = FATTR_MTIME;
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001466 inarg.mtime = inode->i_mtime.tv_sec;
1467 inarg.mtimensec = inode->i_mtime.tv_nsec;
Maxim Patlasovab9e13f2014-04-28 14:19:24 +02001468 if (fc->minor >= 23) {
1469 inarg.valid |= FATTR_CTIME;
1470 inarg.ctime = inode->i_ctime.tv_sec;
1471 inarg.ctimensec = inode->i_ctime.tv_nsec;
1472 }
Miklos Szeredi1e18bda2014-04-28 14:19:23 +02001473 if (ff) {
1474 inarg.valid |= FATTR_FH;
1475 inarg.fh = ff->fh;
1476 }
Miklos Szeredi70781872014-12-12 09:49:05 +01001477 fuse_setattr_fill(fc, &args, inode, &inarg, &outarg);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001478
Miklos Szeredi70781872014-12-12 09:49:05 +01001479 return fuse_simple_request(fc, &args);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001480}
1481
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001482/*
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001483 * Set attributes, and at the same time refresh them.
1484 *
1485 * Truncation is slightly complicated, because the 'truncate' request
1486 * may fail, in which case we don't want to touch the mapping.
Miklos Szeredi9ffbb912006-10-17 00:10:06 -07001487 * vmtruncate() doesn't allow for this case, so do the rlimit checking
1488 * and the actual truncation by hand.
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001489 */
Jan Kara62490332016-05-26 17:12:41 +02001490int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
Maxim Patlasovefb9fa92012-12-18 14:05:08 +04001491 struct file *file)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001492{
Jan Kara62490332016-05-26 17:12:41 +02001493 struct inode *inode = d_inode(dentry);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001494 struct fuse_conn *fc = get_fuse_conn(inode);
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001495 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001496 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001497 struct fuse_setattr_in inarg;
1498 struct fuse_attr_out outarg;
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001499 bool is_truncate = false;
Pavel Emelyanov83732002013-10-10 17:10:46 +04001500 bool is_wb = fc->writeback_cache;
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001501 loff_t oldsize;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001502 int err;
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001503 bool trust_local_cmtime = is_wb && S_ISREG(inode->i_mode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001504
Miklos Szeredi29433a22016-10-01 07:32:32 +02001505 if (!fc->default_permissions)
Christoph Hellwigdb78b872010-06-04 11:30:03 +02001506 attr->ia_valid |= ATTR_FORCE;
1507
Jan Kara31051c82016-05-26 16:55:18 +02001508 err = setattr_prepare(dentry, attr);
Christoph Hellwigdb78b872010-06-04 11:30:03 +02001509 if (err)
1510 return err;
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001511
Miklos Szeredi8d56add2011-02-25 14:44:58 +01001512 if (attr->ia_valid & ATTR_OPEN) {
Miklos Szeredidf0e91d2018-02-08 15:17:38 +01001513 /* This is coming from open(..., ... | O_TRUNC); */
1514 WARN_ON(!(attr->ia_valid & ATTR_SIZE));
1515 WARN_ON(attr->ia_size != 0);
1516 if (fc->atomic_o_trunc) {
1517 /*
1518 * No need to send request to userspace, since actual
1519 * truncation has already been done by OPEN. But still
1520 * need to truncate page cache.
1521 */
1522 i_size_write(inode, 0);
1523 truncate_pagecache(inode, 0);
Miklos Szeredi8d56add2011-02-25 14:44:58 +01001524 return 0;
Miklos Szeredidf0e91d2018-02-08 15:17:38 +01001525 }
Miklos Szeredi8d56add2011-02-25 14:44:58 +01001526 file = NULL;
1527 }
Miklos Szeredi6ff958e2007-10-18 03:07:02 -07001528
Miklos Szerediab2257e2018-10-01 10:07:05 +02001529 if (attr->ia_valid & ATTR_SIZE) {
1530 if (WARN_ON(!S_ISREG(inode->i_mode)))
1531 return -EIO;
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001532 is_truncate = true;
Miklos Szerediab2257e2018-10-01 10:07:05 +02001533 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001534
Miklos Szeredib24e7592019-10-23 14:26:37 +02001535 /* Flush dirty data/metadata before non-truncate SETATTR */
1536 if (is_wb && S_ISREG(inode->i_mode) &&
1537 attr->ia_valid &
1538 (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_MTIME_SET |
1539 ATTR_TIMES_SET)) {
1540 err = write_inode_now(inode, true);
1541 if (err)
1542 return err;
1543
1544 fuse_set_nowrite(inode);
1545 fuse_release_nowrite(inode);
1546 }
1547
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001548 if (is_truncate) {
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001549 fuse_set_nowrite(inode);
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001550 set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001551 if (trust_local_cmtime && attr->ia_size != inode->i_size)
1552 attr->ia_valid |= ATTR_MTIME | ATTR_CTIME;
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001553 }
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001554
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001555 memset(&inarg, 0, sizeof(inarg));
Miklos Szeredi0e9663e2007-10-18 03:07:05 -07001556 memset(&outarg, 0, sizeof(outarg));
Eric W. Biederman8cb08322018-02-21 11:18:07 -06001557 iattr_to_fattr(fc, attr, &inarg, trust_local_cmtime);
Miklos Szeredi49d49142007-10-18 03:07:00 -07001558 if (file) {
1559 struct fuse_file *ff = file->private_data;
1560 inarg.valid |= FATTR_FH;
1561 inarg.fh = ff->fh;
1562 }
Miklos Szeredif3332112007-10-18 03:07:04 -07001563 if (attr->ia_valid & ATTR_SIZE) {
1564 /* For mandatory locking in truncate */
1565 inarg.valid |= FATTR_LOCKOWNER;
1566 inarg.lock_owner = fuse_lock_owner_id(fc, current->files);
1567 }
Miklos Szeredi70781872014-12-12 09:49:05 +01001568 fuse_setattr_fill(fc, &args, inode, &inarg, &outarg);
1569 err = fuse_simple_request(fc, &args);
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001570 if (err) {
1571 if (err == -EINTR)
1572 fuse_invalidate_attr(inode);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001573 goto error;
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001574 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001575
Miklos Szeredieb59bd12019-11-12 11:49:04 +01001576 if (fuse_invalid_attr(&outarg.attr) ||
1577 (inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001578 make_bad_inode(inode);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001579 err = -EIO;
1580 goto error;
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001581 }
1582
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001583 spin_lock(&fi->lock);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001584 /* the kernel maintains i_mtime locally */
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001585 if (trust_local_cmtime) {
1586 if (attr->ia_valid & ATTR_MTIME)
1587 inode->i_mtime = attr->ia_mtime;
1588 if (attr->ia_valid & ATTR_CTIME)
1589 inode->i_ctime = attr->ia_ctime;
Miklos Szeredi1e18bda2014-04-28 14:19:23 +02001590 /* FIXME: clear I_DIRTY_SYNC? */
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001591 }
1592
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001593 fuse_change_attributes_common(inode, &outarg.attr,
1594 attr_timeout(&outarg));
1595 oldsize = inode->i_size;
Pavel Emelyanov83732002013-10-10 17:10:46 +04001596 /* see the comment in fuse_change_attributes() */
1597 if (!is_wb || is_truncate || !S_ISREG(inode->i_mode))
1598 i_size_write(inode, outarg.attr.size);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001599
1600 if (is_truncate) {
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001601 /* NOTE: this may release/reacquire fi->lock */
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001602 __fuse_release_nowrite(inode);
1603 }
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001604 spin_unlock(&fi->lock);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001605
1606 /*
1607 * Only call invalidate_inode_pages2() after removing
1608 * FUSE_NOWRITE, otherwise fuse_launder_page() would deadlock.
1609 */
Pavel Emelyanov83732002013-10-10 17:10:46 +04001610 if ((is_truncate || !is_wb) &&
1611 S_ISREG(inode->i_mode) && oldsize != outarg.attr.size) {
Kirill A. Shutemov7caef262013-09-12 15:13:56 -07001612 truncate_pagecache(inode, outarg.attr.size);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001613 invalidate_inode_pages2(inode->i_mapping);
1614 }
1615
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001616 clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001617 return 0;
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001618
1619error:
1620 if (is_truncate)
1621 fuse_release_nowrite(inode);
1622
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001623 clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001624 return err;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001625}
1626
Miklos Szeredi49d49142007-10-18 03:07:00 -07001627static int fuse_setattr(struct dentry *entry, struct iattr *attr)
1628{
David Howells2b0143b2015-03-17 22:25:59 +00001629 struct inode *inode = d_inode(entry);
Miklos Szeredi5e940c12016-10-01 07:32:32 +02001630 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredia09f99e2016-10-01 07:32:32 +02001631 struct file *file = (attr->ia_valid & ATTR_FILE) ? attr->ia_file : NULL;
Miklos Szeredi5e2b8822016-10-01 07:32:32 +02001632 int ret;
Maxim Patlasovefb9fa92012-12-18 14:05:08 +04001633
1634 if (!fuse_allow_current_process(get_fuse_conn(inode)))
1635 return -EACCES;
1636
Miklos Szeredia09f99e2016-10-01 07:32:32 +02001637 if (attr->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) {
Miklos Szeredia09f99e2016-10-01 07:32:32 +02001638 attr->ia_valid &= ~(ATTR_KILL_SUID | ATTR_KILL_SGID |
1639 ATTR_MODE);
Miklos Szeredia09f99e2016-10-01 07:32:32 +02001640
Miklos Szeredi5e940c12016-10-01 07:32:32 +02001641 /*
1642 * The only sane way to reliably kill suid/sgid is to do it in
1643 * the userspace filesystem
1644 *
1645 * This should be done on write(), truncate() and chown().
1646 */
1647 if (!fc->handle_killpriv) {
Miklos Szeredi5e940c12016-10-01 07:32:32 +02001648 /*
1649 * ia_mode calculation may have used stale i_mode.
1650 * Refresh and recalculate.
1651 */
1652 ret = fuse_do_getattr(inode, NULL, file);
1653 if (ret)
1654 return ret;
1655
1656 attr->ia_mode = inode->i_mode;
Miklos Szeredic01638f2016-12-06 16:18:45 +01001657 if (inode->i_mode & S_ISUID) {
Miklos Szeredi5e940c12016-10-01 07:32:32 +02001658 attr->ia_valid |= ATTR_MODE;
1659 attr->ia_mode &= ~S_ISUID;
1660 }
Miklos Szeredic01638f2016-12-06 16:18:45 +01001661 if ((inode->i_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
Miklos Szeredi5e940c12016-10-01 07:32:32 +02001662 attr->ia_valid |= ATTR_MODE;
1663 attr->ia_mode &= ~S_ISGID;
1664 }
Miklos Szeredia09f99e2016-10-01 07:32:32 +02001665 }
1666 }
1667 if (!attr->ia_valid)
1668 return 0;
1669
Linus Torvaldsabb5a142016-10-10 13:04:49 -07001670 ret = fuse_do_setattr(entry, attr, file);
Miklos Szeredi5e2b8822016-10-01 07:32:32 +02001671 if (!ret) {
Seth Forshee60bcc882016-08-29 08:46:37 -05001672 /*
1673 * If filesystem supports acls it may have updated acl xattrs in
1674 * the filesystem, so forget cached acls for the inode.
1675 */
1676 if (fc->posix_acl)
1677 forget_all_cached_acls(inode);
1678
Miklos Szeredi5e2b8822016-10-01 07:32:32 +02001679 /* Directory mode changed, may need to revalidate access */
1680 if (d_is_dir(entry) && (attr->ia_valid & ATTR_MODE))
1681 fuse_invalidate_entry_cache(entry);
1682 }
1683 return ret;
Miklos Szeredi49d49142007-10-18 03:07:00 -07001684}
1685
David Howellsa528d352017-01-31 16:46:22 +00001686static int fuse_getattr(const struct path *path, struct kstat *stat,
1687 u32 request_mask, unsigned int flags)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001688{
David Howellsa528d352017-01-31 16:46:22 +00001689 struct inode *inode = d_inode(path->dentry);
Miklos Szeredi244f6382007-10-16 23:31:02 -07001690 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi244f6382007-10-16 23:31:02 -07001691
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001692 if (!fuse_allow_current_process(fc))
Miklos Szeredi244f6382007-10-16 23:31:02 -07001693 return -EACCES;
1694
Miklos Szeredi2f1e8192018-10-15 15:43:06 +02001695 return fuse_update_get_attr(inode, NULL, stat, request_mask, flags);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001696}
1697
Arjan van de Ven754661f2007-02-12 00:55:38 -08001698static const struct inode_operations fuse_dir_inode_operations = {
Miklos Szeredie5e55582005-09-09 13:10:28 -07001699 .lookup = fuse_lookup,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001700 .mkdir = fuse_mkdir,
1701 .symlink = fuse_symlink,
1702 .unlink = fuse_unlink,
1703 .rmdir = fuse_rmdir,
Miklos Szeredi2773bf02016-09-27 11:03:58 +02001704 .rename = fuse_rename2,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001705 .link = fuse_link,
1706 .setattr = fuse_setattr,
1707 .create = fuse_create,
Miklos Szeredic8ccbe02012-06-05 15:10:22 +02001708 .atomic_open = fuse_atomic_open,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001709 .mknod = fuse_mknod,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001710 .permission = fuse_permission,
1711 .getattr = fuse_getattr,
Miklos Szeredi92a87802005-09-09 13:10:31 -07001712 .listxattr = fuse_listxattr,
Seth Forshee60bcc882016-08-29 08:46:37 -05001713 .get_acl = fuse_get_acl,
1714 .set_acl = fuse_set_acl,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001715};
1716
Arjan van de Ven4b6f5d22006-03-28 01:56:42 -08001717static const struct file_operations fuse_dir_operations = {
Miklos Szeredib6aeade2005-09-09 13:10:30 -07001718 .llseek = generic_file_llseek,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001719 .read = generic_read_dir,
Al Virod9b3dbd2016-04-20 17:30:32 -04001720 .iterate_shared = fuse_readdir,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001721 .open = fuse_dir_open,
1722 .release = fuse_dir_release,
Miklos Szeredi82547982005-09-09 13:10:38 -07001723 .fsync = fuse_dir_fsync,
Miklos Szeredib18da0c2011-12-13 11:58:49 +01001724 .unlocked_ioctl = fuse_dir_ioctl,
1725 .compat_ioctl = fuse_dir_compat_ioctl,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001726};
1727
Arjan van de Ven754661f2007-02-12 00:55:38 -08001728static const struct inode_operations fuse_common_inode_operations = {
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001729 .setattr = fuse_setattr,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001730 .permission = fuse_permission,
1731 .getattr = fuse_getattr,
Miklos Szeredi92a87802005-09-09 13:10:31 -07001732 .listxattr = fuse_listxattr,
Seth Forshee60bcc882016-08-29 08:46:37 -05001733 .get_acl = fuse_get_acl,
1734 .set_acl = fuse_set_acl,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001735};
1736
Arjan van de Ven754661f2007-02-12 00:55:38 -08001737static const struct inode_operations fuse_symlink_inode_operations = {
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001738 .setattr = fuse_setattr,
Al Viro6b255392015-11-17 10:20:54 -05001739 .get_link = fuse_get_link,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001740 .getattr = fuse_getattr,
Miklos Szeredi92a87802005-09-09 13:10:31 -07001741 .listxattr = fuse_listxattr,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001742};
1743
1744void fuse_init_common(struct inode *inode)
1745{
1746 inode->i_op = &fuse_common_inode_operations;
1747}
1748
1749void fuse_init_dir(struct inode *inode)
1750{
Miklos Szerediab2257e2018-10-01 10:07:05 +02001751 struct fuse_inode *fi = get_fuse_inode(inode);
1752
Miklos Szeredie5e55582005-09-09 13:10:28 -07001753 inode->i_op = &fuse_dir_inode_operations;
1754 inode->i_fop = &fuse_dir_operations;
Miklos Szerediab2257e2018-10-01 10:07:05 +02001755
1756 spin_lock_init(&fi->rdc.lock);
1757 fi->rdc.cached = false;
1758 fi->rdc.size = 0;
1759 fi->rdc.pos = 0;
1760 fi->rdc.version = 0;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001761}
1762
Dan Schatzberg5571f1e2018-10-11 08:17:00 -07001763static int fuse_symlink_readpage(struct file *null, struct page *page)
1764{
1765 int err = fuse_readlink_page(page->mapping->host, page);
1766
1767 if (!err)
1768 SetPageUptodate(page);
1769
1770 unlock_page(page);
1771
1772 return err;
1773}
1774
1775static const struct address_space_operations fuse_symlink_aops = {
1776 .readpage = fuse_symlink_readpage,
1777};
1778
Miklos Szeredie5e55582005-09-09 13:10:28 -07001779void fuse_init_symlink(struct inode *inode)
1780{
1781 inode->i_op = &fuse_symlink_inode_operations;
Dan Schatzberg5571f1e2018-10-11 08:17:00 -07001782 inode->i_data.a_ops = &fuse_symlink_aops;
1783 inode_nohighmem(inode);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001784}