blob: c885d9b602638bf4d5d12c6827b5143478286582 [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;
Max Reitzfcee2162020-05-06 17:44:12 +0200199 struct fuse_mount *fm;
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
Max Reitzfcee2162020-05-06 17:44:12 +0200221 fm = get_fuse_mount(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
Max Reitzfcee2162020-05-06 17:44:12 +0200228 attr_version = fuse_get_attr_version(fm->fc);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700229
Miklos Szeredie956edd2006-10-17 00:10:12 -0700230 parent = dget_parent(entry);
Max Reitzfcee2162020-05-06 17:44:12 +0200231 fuse_lookup_init(fm->fc, &args, get_node_id(d_inode(parent)),
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700232 &entry->d_name, &outarg);
Max Reitzfcee2162020-05-06 17:44:12 +0200233 ret = fuse_simple_request(fm, &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)) {
Max Reitzfcee2162020-05-06 17:44:12 +0200241 fuse_queue_forget(fm->fc, forget,
242 outarg.nodeid, 1);
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200243 goto invalid;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700244 }
Kirill Tkhaic9d8f5f2018-11-09 13:33:27 +0300245 spin_lock(&fi->lock);
Miklos Szeredi1729a162008-11-26 12:03:54 +0100246 fi->nlookup++;
Kirill Tkhaic9d8f5f2018-11-09 13:33:27 +0300247 spin_unlock(&fi->lock);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700248 }
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100249 kfree(forget);
Miklos Szeredi70781872014-12-12 09:49:05 +0100250 if (ret == -ENOMEM)
251 goto out;
Miklos Szeredieb59bd12019-11-12 11:49:04 +0100252 if (ret || fuse_invalid_attr(&outarg.attr) ||
253 (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200254 goto invalid;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700255
Seth Forshee60bcc882016-08-29 08:46:37 -0500256 forget_all_cached_acls(inode);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700257 fuse_change_attributes(inode, &outarg.attr,
258 entry_attr_timeout(&outarg),
259 attr_version);
260 fuse_change_entry_timeout(entry, &outarg);
Miklos Szeredi28420da2013-06-03 14:40:22 +0200261 } else if (inode) {
Miklos Szeredi6314efe2013-10-01 16:41:22 +0200262 fi = get_fuse_inode(inode);
263 if (flags & LOOKUP_RCU) {
264 if (test_bit(FUSE_I_INIT_RDPLUS, &fi->state))
265 return -ECHILD;
266 } else if (test_and_clear_bit(FUSE_I_INIT_RDPLUS, &fi->state)) {
Miklos Szeredi28420da2013-06-03 14:40:22 +0200267 parent = dget_parent(entry);
David Howells2b0143b2015-03-17 22:25:59 +0000268 fuse_advise_use_readdirplus(d_inode(parent));
Miklos Szeredi28420da2013-06-03 14:40:22 +0200269 dput(parent);
270 }
Miklos Szeredie5e55582005-09-09 13:10:28 -0700271 }
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200272 ret = 1;
273out:
274 return ret;
275
276invalid:
277 ret = 0;
278 goto out;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700279}
280
Khazhismel Kumykov30c6a232019-09-16 16:56:41 -0700281#if BITS_PER_LONG < 64
Miklos Szeredif75fdf22016-10-01 07:32:32 +0200282static int fuse_dentry_init(struct dentry *dentry)
283{
Khazhismel Kumykovdc69e982019-09-17 12:35:33 -0700284 dentry->d_fsdata = kzalloc(sizeof(union fuse_dentry),
285 GFP_KERNEL_ACCOUNT | __GFP_RECLAIMABLE);
Miklos Szeredif75fdf22016-10-01 07:32:32 +0200286
287 return dentry->d_fsdata ? 0 : -ENOMEM;
288}
289static void fuse_dentry_release(struct dentry *dentry)
290{
291 union fuse_dentry *fd = dentry->d_fsdata;
292
293 kfree_rcu(fd, rcu);
294}
Khazhismel Kumykov30c6a232019-09-16 16:56:41 -0700295#endif
Miklos Szeredif75fdf22016-10-01 07:32:32 +0200296
Miklos Szeredi8fab0102018-08-15 17:42:34 +0200297static int fuse_dentry_delete(const struct dentry *dentry)
298{
299 return time_before64(fuse_dentry_time(dentry), get_jiffies_64());
300}
301
Al Viro42695902009-02-20 05:59:13 +0000302const struct dentry_operations fuse_dentry_operations = {
Miklos Szeredie5e55582005-09-09 13:10:28 -0700303 .d_revalidate = fuse_dentry_revalidate,
Miklos Szeredi8fab0102018-08-15 17:42:34 +0200304 .d_delete = fuse_dentry_delete,
Khazhismel Kumykov30c6a232019-09-16 16:56:41 -0700305#if BITS_PER_LONG < 64
Miklos Szeredif75fdf22016-10-01 07:32:32 +0200306 .d_init = fuse_dentry_init,
307 .d_release = fuse_dentry_release,
Khazhismel Kumykov30c6a232019-09-16 16:56:41 -0700308#endif
Miklos Szeredie5e55582005-09-09 13:10:28 -0700309};
310
Miklos Szeredi0ce267f2016-10-18 15:36:48 +0200311const struct dentry_operations fuse_root_dentry_operations = {
Khazhismel Kumykov30c6a232019-09-16 16:56:41 -0700312#if BITS_PER_LONG < 64
Miklos Szeredi0ce267f2016-10-18 15:36:48 +0200313 .d_init = fuse_dentry_init,
314 .d_release = fuse_dentry_release,
Khazhismel Kumykov30c6a232019-09-16 16:56:41 -0700315#endif
Miklos Szeredi0ce267f2016-10-18 15:36:48 +0200316};
317
Timo Savolaa5bfffac2007-04-08 16:04:00 -0700318int fuse_valid_type(int m)
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800319{
320 return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) ||
321 S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
322}
323
Miklos Szeredieb59bd12019-11-12 11:49:04 +0100324bool fuse_invalid_attr(struct fuse_attr *attr)
325{
326 return !fuse_valid_type(attr->mode) ||
327 attr->size > LLONG_MAX;
328}
329
Al Viro13983d02016-07-20 22:34:44 -0400330int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name,
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700331 struct fuse_entry_out *outarg, struct inode **inode)
332{
Max Reitzfcee2162020-05-06 17:44:12 +0200333 struct fuse_mount *fm = get_fuse_mount_super(sb);
Miklos Szeredi70781872014-12-12 09:49:05 +0100334 FUSE_ARGS(args);
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100335 struct fuse_forget_link *forget;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700336 u64 attr_version;
337 int err;
338
339 *inode = NULL;
340 err = -ENAMETOOLONG;
341 if (name->len > FUSE_NAME_MAX)
342 goto out;
343
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700344
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100345 forget = fuse_alloc_forget();
346 err = -ENOMEM;
Miklos Szeredi70781872014-12-12 09:49:05 +0100347 if (!forget)
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700348 goto out;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700349
Max Reitzfcee2162020-05-06 17:44:12 +0200350 attr_version = fuse_get_attr_version(fm->fc);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700351
Max Reitzfcee2162020-05-06 17:44:12 +0200352 fuse_lookup_init(fm->fc, &args, nodeid, name, outarg);
353 err = fuse_simple_request(fm, &args);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700354 /* Zero nodeid is same as -ENOENT, but with valid timeout */
355 if (err || !outarg->nodeid)
356 goto out_put_forget;
357
358 err = -EIO;
359 if (!outarg->nodeid)
360 goto out_put_forget;
Miklos Szeredieb59bd12019-11-12 11:49:04 +0100361 if (fuse_invalid_attr(&outarg->attr))
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700362 goto out_put_forget;
363
364 *inode = fuse_iget(sb, outarg->nodeid, outarg->generation,
365 &outarg->attr, entry_attr_timeout(outarg),
366 attr_version);
367 err = -ENOMEM;
368 if (!*inode) {
Max Reitzfcee2162020-05-06 17:44:12 +0200369 fuse_queue_forget(fm->fc, forget, outarg->nodeid, 1);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700370 goto out;
371 }
372 err = 0;
373
374 out_put_forget:
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100375 kfree(forget);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700376 out:
377 return err;
378}
379
Miklos Szeredi0aa7c692006-01-06 00:19:34 -0800380static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
Al Viro00cd8dd2012-06-10 17:13:09 -0400381 unsigned int flags)
Miklos Szeredie5e55582005-09-09 13:10:28 -0700382{
383 int err;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700384 struct fuse_entry_out outarg;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700385 struct inode *inode;
Miklos Szeredi0de62562008-07-25 01:48:59 -0700386 struct dentry *newent;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700387 bool outarg_valid = true;
Miklos Szeredi63576c12018-07-26 16:13:11 +0200388 bool locked;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700389
Miklos Szeredi63576c12018-07-26 16:13:11 +0200390 locked = fuse_lock_inode(dir);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700391 err = fuse_lookup_name(dir->i_sb, get_node_id(dir), &entry->d_name,
392 &outarg, &inode);
Miklos Szeredi63576c12018-07-26 16:13:11 +0200393 fuse_unlock_inode(dir, locked);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700394 if (err == -ENOENT) {
395 outarg_valid = false;
396 err = 0;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800397 }
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700398 if (err)
399 goto out_err;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800400
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700401 err = -EIO;
402 if (inode && get_node_id(inode) == FUSE_ROOT_ID)
403 goto out_iput;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700404
Al Viro41d28bc2014-10-12 22:24:21 -0400405 newent = d_splice_alias(inode, entry);
Miklos Szeredi5835f332013-09-05 11:44:42 +0200406 err = PTR_ERR(newent);
407 if (IS_ERR(newent))
408 goto out_err;
Miklos Szeredid2a85162006-10-17 00:10:11 -0700409
Miklos Szeredi0de62562008-07-25 01:48:59 -0700410 entry = newent ? newent : entry;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700411 if (outarg_valid)
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700412 fuse_change_entry_timeout(entry, &outarg);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800413 else
414 fuse_invalidate_entry_cache(entry);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700415
Miklos Szeredi6c26f712019-10-21 15:57:07 +0200416 if (inode)
417 fuse_advise_use_readdirplus(dir);
Miklos Szeredi0de62562008-07-25 01:48:59 -0700418 return newent;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700419
420 out_iput:
421 iput(inode);
422 out_err:
423 return ERR_PTR(err);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700424}
425
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800426/*
427 * Atomic create+open operation
428 *
429 * If the filesystem doesn't support this, then fall back to separate
430 * 'mknod' + 'open' requests.
431 */
Al Virod9585272012-06-22 12:39:14 +0400432static int fuse_create_open(struct inode *dir, struct dentry *entry,
Al Viro30d90492012-06-22 12:40:19 +0400433 struct file *file, unsigned flags,
Al Virob452a452018-06-08 13:06:28 -0400434 umode_t mode)
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800435{
436 int err;
437 struct inode *inode;
Max Reitzfcee2162020-05-06 17:44:12 +0200438 struct fuse_mount *fm = get_fuse_mount(dir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100439 FUSE_ARGS(args);
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100440 struct fuse_forget_link *forget;
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200441 struct fuse_create_in inarg;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800442 struct fuse_open_out outopen;
443 struct fuse_entry_out outentry;
Kirill Tkhaiebf84d02018-11-09 13:33:11 +0300444 struct fuse_inode *fi;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800445 struct fuse_file *ff;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800446
Miklos Szerediaf109bc2012-08-15 13:01:24 +0200447 /* Userspace expects S_IFREG in create mode */
448 BUG_ON((mode & S_IFMT) != S_IFREG);
449
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100450 forget = fuse_alloc_forget();
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200451 err = -ENOMEM;
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100452 if (!forget)
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200453 goto out_err;
Miklos Szeredi51eb01e2006-06-25 05:48:50 -0700454
Miklos Szeredice1d5a42006-04-10 22:54:58 -0700455 err = -ENOMEM;
Max Reitzfcee2162020-05-06 17:44:12 +0200456 ff = fuse_file_alloc(fm);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800457 if (!ff)
Miklos Szeredi70781872014-12-12 09:49:05 +0100458 goto out_put_forget_req;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800459
Max Reitzfcee2162020-05-06 17:44:12 +0200460 if (!fm->fc->dont_mask)
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200461 mode &= ~current_umask();
462
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800463 flags &= ~O_NOCTTY;
464 memset(&inarg, 0, sizeof(inarg));
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700465 memset(&outentry, 0, sizeof(outentry));
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800466 inarg.flags = flags;
467 inarg.mode = mode;
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200468 inarg.umask = current_umask();
Miklos Szeredid5b48542019-09-10 15:04:08 +0200469 args.opcode = FUSE_CREATE;
470 args.nodeid = get_node_id(dir);
471 args.in_numargs = 2;
472 args.in_args[0].size = sizeof(inarg);
473 args.in_args[0].value = &inarg;
474 args.in_args[1].size = entry->d_name.len + 1;
475 args.in_args[1].value = entry->d_name.name;
476 args.out_numargs = 2;
477 args.out_args[0].size = sizeof(outentry);
478 args.out_args[0].value = &outentry;
479 args.out_args[1].size = sizeof(outopen);
480 args.out_args[1].value = &outopen;
Max Reitzfcee2162020-05-06 17:44:12 +0200481 err = fuse_simple_request(fm, &args);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200482 if (err)
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800483 goto out_free_ff;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800484
485 err = -EIO;
Miklos Szeredieb59bd12019-11-12 11:49:04 +0100486 if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid) ||
487 fuse_invalid_attr(&outentry.attr))
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800488 goto out_free_ff;
489
Miklos Szeredic7b71432009-04-28 16:56:37 +0200490 ff->fh = outopen.fh;
491 ff->nodeid = outentry.nodeid;
492 ff->open_flags = outopen.open_flags;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800493 inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700494 &outentry.attr, entry_attr_timeout(&outentry), 0);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800495 if (!inode) {
496 flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
Kirill Tkhaiebf84d02018-11-09 13:33:11 +0300497 fuse_sync_release(NULL, ff, flags);
Max Reitzfcee2162020-05-06 17:44:12 +0200498 fuse_queue_forget(fm->fc, forget, outentry.nodeid, 1);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200499 err = -ENOMEM;
500 goto out_err;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800501 }
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100502 kfree(forget);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800503 d_instantiate(entry, inode);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700504 fuse_change_entry_timeout(entry, &outentry);
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200505 fuse_dir_changed(dir);
Al Virobe12af32018-06-08 11:44:56 -0400506 err = finish_open(file, entry, generic_file_open);
Al Viro30d90492012-06-22 12:40:19 +0400507 if (err) {
Kirill Tkhaiebf84d02018-11-09 13:33:11 +0300508 fi = get_fuse_inode(inode);
509 fuse_sync_release(fi, ff, flags);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200510 } else {
Miklos Szeredi267d8442017-02-22 20:08:25 +0100511 file->private_data = ff;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200512 fuse_finish_open(inode, file);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800513 }
Al Virod9585272012-06-22 12:39:14 +0400514 return err;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800515
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200516out_free_ff:
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800517 fuse_file_free(ff);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200518out_put_forget_req:
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100519 kfree(forget);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200520out_err:
Al Virod9585272012-06-22 12:39:14 +0400521 return err;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200522}
523
524static int fuse_mknod(struct inode *, struct dentry *, umode_t, dev_t);
Al Virod9585272012-06-22 12:39:14 +0400525static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
Al Viro30d90492012-06-22 12:40:19 +0400526 struct file *file, unsigned flags,
Al Viro44907d72018-06-08 13:32:02 -0400527 umode_t mode)
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200528{
529 int err;
530 struct fuse_conn *fc = get_fuse_conn(dir);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200531 struct dentry *res = NULL;
532
Al Viro00699ad2016-07-05 09:44:53 -0400533 if (d_in_lookup(entry)) {
Al Viro00cd8dd2012-06-10 17:13:09 -0400534 res = fuse_lookup(dir, entry, 0);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200535 if (IS_ERR(res))
Al Virod9585272012-06-22 12:39:14 +0400536 return PTR_ERR(res);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200537
538 if (res)
539 entry = res;
540 }
541
David Howells2b0143b2015-03-17 22:25:59 +0000542 if (!(flags & O_CREAT) || d_really_is_positive(entry))
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200543 goto no_open;
544
545 /* Only creates */
Al Viro73a09dd2018-06-08 13:22:02 -0400546 file->f_mode |= FMODE_CREATED;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200547
548 if (fc->no_create)
549 goto mknod;
550
Al Virob452a452018-06-08 13:06:28 -0400551 err = fuse_create_open(dir, entry, file, flags, mode);
Al Virod9585272012-06-22 12:39:14 +0400552 if (err == -ENOSYS) {
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200553 fc->no_create = 1;
554 goto mknod;
555 }
556out_dput:
557 dput(res);
Al Virod9585272012-06-22 12:39:14 +0400558 return err;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200559
560mknod:
561 err = fuse_mknod(dir, entry, mode, 0);
Al Virod9585272012-06-22 12:39:14 +0400562 if (err)
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200563 goto out_dput;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200564no_open:
Al Viroe45198a2012-06-10 06:48:09 -0400565 return finish_no_open(file, res);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800566}
567
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800568/*
569 * Code shared between mknod, mkdir, symlink and link
570 */
Max Reitzfcee2162020-05-06 17:44:12 +0200571static int create_new_entry(struct fuse_mount *fm, struct fuse_args *args,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700572 struct inode *dir, struct dentry *entry,
Al Viro541af6a2011-07-26 03:17:33 -0400573 umode_t mode)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700574{
575 struct fuse_entry_out outarg;
576 struct inode *inode;
Al Viroc971e6a2018-05-28 18:27:19 -0400577 struct dentry *d;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700578 int err;
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100579 struct fuse_forget_link *forget;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800580
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100581 forget = fuse_alloc_forget();
Miklos Szeredi70781872014-12-12 09:49:05 +0100582 if (!forget)
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100583 return -ENOMEM;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700584
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700585 memset(&outarg, 0, sizeof(outarg));
Miklos Szeredid5b48542019-09-10 15:04:08 +0200586 args->nodeid = get_node_id(dir);
587 args->out_numargs = 1;
588 args->out_args[0].size = sizeof(outarg);
589 args->out_args[0].value = &outarg;
Max Reitzfcee2162020-05-06 17:44:12 +0200590 err = fuse_simple_request(fm, args);
Miklos Szeredi2d510132006-11-25 11:09:20 -0800591 if (err)
592 goto out_put_forget_req;
593
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800594 err = -EIO;
Miklos Szeredieb59bd12019-11-12 11:49:04 +0100595 if (invalid_nodeid(outarg.nodeid) || fuse_invalid_attr(&outarg.attr))
Miklos Szeredi2d510132006-11-25 11:09:20 -0800596 goto out_put_forget_req;
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800597
598 if ((outarg.attr.mode ^ mode) & S_IFMT)
Miklos Szeredi2d510132006-11-25 11:09:20 -0800599 goto out_put_forget_req;
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800600
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700601 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700602 &outarg.attr, entry_attr_timeout(&outarg), 0);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700603 if (!inode) {
Max Reitzfcee2162020-05-06 17:44:12 +0200604 fuse_queue_forget(fm->fc, forget, outarg.nodeid, 1);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700605 return -ENOMEM;
606 }
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100607 kfree(forget);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700608
Al Viroc971e6a2018-05-28 18:27:19 -0400609 d_drop(entry);
610 d = d_splice_alias(inode, entry);
611 if (IS_ERR(d))
612 return PTR_ERR(d);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700613
Al Viroc971e6a2018-05-28 18:27:19 -0400614 if (d) {
615 fuse_change_entry_timeout(d, &outarg);
616 dput(d);
617 } else {
618 fuse_change_entry_timeout(entry, &outarg);
619 }
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200620 fuse_dir_changed(dir);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700621 return 0;
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800622
Miklos Szeredi2d510132006-11-25 11:09:20 -0800623 out_put_forget_req:
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100624 kfree(forget);
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800625 return err;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700626}
627
Al Viro1a67aaf2011-07-26 01:52:52 -0400628static int fuse_mknod(struct inode *dir, struct dentry *entry, umode_t mode,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700629 dev_t rdev)
630{
631 struct fuse_mknod_in inarg;
Max Reitzfcee2162020-05-06 17:44:12 +0200632 struct fuse_mount *fm = get_fuse_mount(dir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100633 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700634
Max Reitzfcee2162020-05-06 17:44:12 +0200635 if (!fm->fc->dont_mask)
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200636 mode &= ~current_umask();
637
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700638 memset(&inarg, 0, sizeof(inarg));
639 inarg.mode = mode;
640 inarg.rdev = new_encode_dev(rdev);
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200641 inarg.umask = current_umask();
Miklos Szeredid5b48542019-09-10 15:04:08 +0200642 args.opcode = FUSE_MKNOD;
643 args.in_numargs = 2;
644 args.in_args[0].size = sizeof(inarg);
645 args.in_args[0].value = &inarg;
646 args.in_args[1].size = entry->d_name.len + 1;
647 args.in_args[1].value = entry->d_name.name;
Max Reitzfcee2162020-05-06 17:44:12 +0200648 return create_new_entry(fm, &args, dir, entry, mode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700649}
650
Al Viro4acdaf22011-07-26 01:42:34 -0400651static int fuse_create(struct inode *dir, struct dentry *entry, umode_t mode,
Al Viroebfc3b42012-06-10 18:05:36 -0400652 bool excl)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700653{
654 return fuse_mknod(dir, entry, mode, 0);
655}
656
Al Viro18bb1db2011-07-26 01:41:39 -0400657static int fuse_mkdir(struct inode *dir, struct dentry *entry, umode_t mode)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700658{
659 struct fuse_mkdir_in inarg;
Max Reitzfcee2162020-05-06 17:44:12 +0200660 struct fuse_mount *fm = get_fuse_mount(dir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100661 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700662
Max Reitzfcee2162020-05-06 17:44:12 +0200663 if (!fm->fc->dont_mask)
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200664 mode &= ~current_umask();
665
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700666 memset(&inarg, 0, sizeof(inarg));
667 inarg.mode = mode;
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200668 inarg.umask = current_umask();
Miklos Szeredid5b48542019-09-10 15:04:08 +0200669 args.opcode = FUSE_MKDIR;
670 args.in_numargs = 2;
671 args.in_args[0].size = sizeof(inarg);
672 args.in_args[0].value = &inarg;
673 args.in_args[1].size = entry->d_name.len + 1;
674 args.in_args[1].value = entry->d_name.name;
Max Reitzfcee2162020-05-06 17:44:12 +0200675 return create_new_entry(fm, &args, dir, entry, S_IFDIR);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700676}
677
678static int fuse_symlink(struct inode *dir, struct dentry *entry,
679 const char *link)
680{
Max Reitzfcee2162020-05-06 17:44:12 +0200681 struct fuse_mount *fm = get_fuse_mount(dir);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700682 unsigned len = strlen(link) + 1;
Miklos Szeredi70781872014-12-12 09:49:05 +0100683 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700684
Miklos Szeredid5b48542019-09-10 15:04:08 +0200685 args.opcode = FUSE_SYMLINK;
686 args.in_numargs = 2;
687 args.in_args[0].size = entry->d_name.len + 1;
688 args.in_args[0].value = entry->d_name.name;
689 args.in_args[1].size = len;
690 args.in_args[1].value = link;
Max Reitzfcee2162020-05-06 17:44:12 +0200691 return create_new_entry(fm, &args, dir, entry, S_IFLNK);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700692}
693
Seth Forshee703c7362016-08-29 08:46:36 -0500694void fuse_update_ctime(struct inode *inode)
Maxim Patlasov31f32672014-04-28 14:19:24 +0200695{
696 if (!IS_NOCMTIME(inode)) {
Deepa Dinamanic2050a42016-09-14 07:48:06 -0700697 inode->i_ctime = current_time(inode);
Maxim Patlasov31f32672014-04-28 14:19:24 +0200698 mark_inode_dirty_sync(inode);
699 }
700}
701
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700702static int fuse_unlink(struct inode *dir, struct dentry *entry)
703{
704 int err;
Max Reitzfcee2162020-05-06 17:44:12 +0200705 struct fuse_mount *fm = get_fuse_mount(dir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100706 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700707
Miklos Szeredid5b48542019-09-10 15:04:08 +0200708 args.opcode = FUSE_UNLINK;
709 args.nodeid = get_node_id(dir);
710 args.in_numargs = 1;
711 args.in_args[0].size = entry->d_name.len + 1;
712 args.in_args[0].value = entry->d_name.name;
Max Reitzfcee2162020-05-06 17:44:12 +0200713 err = fuse_simple_request(fm, &args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700714 if (!err) {
David Howells2b0143b2015-03-17 22:25:59 +0000715 struct inode *inode = d_inode(entry);
Miklos Szerediac45d612012-03-05 15:48:11 +0100716 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700717
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +0300718 spin_lock(&fi->lock);
Max Reitzfcee2162020-05-06 17:44:12 +0200719 fi->attr_version = atomic64_inc_return(&fm->fc->attr_version);
Miklos Szeredidfca7ce2013-02-04 15:57:42 +0100720 /*
721 * If i_nlink == 0 then unlink doesn't make sense, yet this can
722 * happen if userspace filesystem is careless. It would be
723 * difficult to enforce correct nlink usage so just ignore this
724 * condition here
725 */
726 if (inode->i_nlink > 0)
727 drop_nlink(inode);
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +0300728 spin_unlock(&fi->lock);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700729 fuse_invalidate_attr(inode);
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200730 fuse_dir_changed(dir);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800731 fuse_invalidate_entry_cache(entry);
Maxim Patlasov31f32672014-04-28 14:19:24 +0200732 fuse_update_ctime(inode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700733 } else if (err == -EINTR)
734 fuse_invalidate_entry(entry);
735 return err;
736}
737
738static int fuse_rmdir(struct inode *dir, struct dentry *entry)
739{
740 int err;
Max Reitzfcee2162020-05-06 17:44:12 +0200741 struct fuse_mount *fm = get_fuse_mount(dir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100742 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700743
Miklos Szeredid5b48542019-09-10 15:04:08 +0200744 args.opcode = FUSE_RMDIR;
745 args.nodeid = get_node_id(dir);
746 args.in_numargs = 1;
747 args.in_args[0].size = entry->d_name.len + 1;
748 args.in_args[0].value = entry->d_name.name;
Max Reitzfcee2162020-05-06 17:44:12 +0200749 err = fuse_simple_request(fm, &args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700750 if (!err) {
David Howells2b0143b2015-03-17 22:25:59 +0000751 clear_nlink(d_inode(entry));
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200752 fuse_dir_changed(dir);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800753 fuse_invalidate_entry_cache(entry);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700754 } else if (err == -EINTR)
755 fuse_invalidate_entry(entry);
756 return err;
757}
758
Miklos Szeredi1560c972014-04-28 16:43:44 +0200759static int fuse_rename_common(struct inode *olddir, struct dentry *oldent,
760 struct inode *newdir, struct dentry *newent,
761 unsigned int flags, int opcode, size_t argsize)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700762{
763 int err;
Miklos Szeredi1560c972014-04-28 16:43:44 +0200764 struct fuse_rename2_in inarg;
Max Reitzfcee2162020-05-06 17:44:12 +0200765 struct fuse_mount *fm = get_fuse_mount(olddir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100766 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700767
Miklos Szeredi1560c972014-04-28 16:43:44 +0200768 memset(&inarg, 0, argsize);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700769 inarg.newdir = get_node_id(newdir);
Miklos Szeredi1560c972014-04-28 16:43:44 +0200770 inarg.flags = flags;
Miklos Szeredid5b48542019-09-10 15:04:08 +0200771 args.opcode = opcode;
772 args.nodeid = get_node_id(olddir);
773 args.in_numargs = 3;
774 args.in_args[0].size = argsize;
775 args.in_args[0].value = &inarg;
776 args.in_args[1].size = oldent->d_name.len + 1;
777 args.in_args[1].value = oldent->d_name.name;
778 args.in_args[2].size = newent->d_name.len + 1;
779 args.in_args[2].value = newent->d_name.name;
Max Reitzfcee2162020-05-06 17:44:12 +0200780 err = fuse_simple_request(fm, &args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700781 if (!err) {
Miklos Szeredi08b63302007-11-28 16:22:03 -0800782 /* ctime changes */
David Howells2b0143b2015-03-17 22:25:59 +0000783 fuse_invalidate_attr(d_inode(oldent));
784 fuse_update_ctime(d_inode(oldent));
Miklos Szeredi08b63302007-11-28 16:22:03 -0800785
Miklos Szeredi1560c972014-04-28 16:43:44 +0200786 if (flags & RENAME_EXCHANGE) {
David Howells2b0143b2015-03-17 22:25:59 +0000787 fuse_invalidate_attr(d_inode(newent));
788 fuse_update_ctime(d_inode(newent));
Miklos Szeredi1560c972014-04-28 16:43:44 +0200789 }
790
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200791 fuse_dir_changed(olddir);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700792 if (olddir != newdir)
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200793 fuse_dir_changed(newdir);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800794
795 /* newent will end up negative */
David Howells2b0143b2015-03-17 22:25:59 +0000796 if (!(flags & RENAME_EXCHANGE) && d_really_is_positive(newent)) {
797 fuse_invalidate_attr(d_inode(newent));
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800798 fuse_invalidate_entry_cache(newent);
David Howells2b0143b2015-03-17 22:25:59 +0000799 fuse_update_ctime(d_inode(newent));
Miklos Szeredi5219f342009-11-04 10:24:52 +0100800 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700801 } else if (err == -EINTR) {
802 /* If request was interrupted, DEITY only knows if the
803 rename actually took place. If the invalidation
804 fails (e.g. some process has CWD under the renamed
805 directory), then there can be inconsistency between
806 the dcache and the real filesystem. Tough luck. */
807 fuse_invalidate_entry(oldent);
David Howells2b0143b2015-03-17 22:25:59 +0000808 if (d_really_is_positive(newent))
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700809 fuse_invalidate_entry(newent);
810 }
811
812 return err;
813}
814
Miklos Szeredi1560c972014-04-28 16:43:44 +0200815static int fuse_rename2(struct inode *olddir, struct dentry *oldent,
816 struct inode *newdir, struct dentry *newent,
817 unsigned int flags)
818{
819 struct fuse_conn *fc = get_fuse_conn(olddir);
820 int err;
821
Vivek Goyal519525f2020-02-05 08:15:46 -0500822 if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT))
Miklos Szeredi1560c972014-04-28 16:43:44 +0200823 return -EINVAL;
824
Miklos Szeredi4237ba42014-07-10 10:50:19 +0200825 if (flags) {
826 if (fc->no_rename2 || fc->minor < 23)
827 return -EINVAL;
Miklos Szeredi1560c972014-04-28 16:43:44 +0200828
Miklos Szeredi4237ba42014-07-10 10:50:19 +0200829 err = fuse_rename_common(olddir, oldent, newdir, newent, flags,
830 FUSE_RENAME2,
831 sizeof(struct fuse_rename2_in));
832 if (err == -ENOSYS) {
833 fc->no_rename2 = 1;
834 err = -EINVAL;
835 }
836 } else {
837 err = fuse_rename_common(olddir, oldent, newdir, newent, 0,
838 FUSE_RENAME,
839 sizeof(struct fuse_rename_in));
Miklos Szeredi1560c972014-04-28 16:43:44 +0200840 }
Miklos Szeredi1560c972014-04-28 16:43:44 +0200841
Miklos Szeredi4237ba42014-07-10 10:50:19 +0200842 return err;
843}
844
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700845static int fuse_link(struct dentry *entry, struct inode *newdir,
846 struct dentry *newent)
847{
848 int err;
849 struct fuse_link_in inarg;
David Howells2b0143b2015-03-17 22:25:59 +0000850 struct inode *inode = d_inode(entry);
Max Reitzfcee2162020-05-06 17:44:12 +0200851 struct fuse_mount *fm = get_fuse_mount(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +0100852 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700853
854 memset(&inarg, 0, sizeof(inarg));
855 inarg.oldnodeid = get_node_id(inode);
Miklos Szeredid5b48542019-09-10 15:04:08 +0200856 args.opcode = FUSE_LINK;
857 args.in_numargs = 2;
858 args.in_args[0].size = sizeof(inarg);
859 args.in_args[0].value = &inarg;
860 args.in_args[1].size = newent->d_name.len + 1;
861 args.in_args[1].value = newent->d_name.name;
Max Reitzfcee2162020-05-06 17:44:12 +0200862 err = create_new_entry(fm, &args, newdir, newent, inode->i_mode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700863 /* Contrary to "normal" filesystems it can happen that link
864 makes two "logical" inodes point to the same "physical"
865 inode. We invalidate the attributes of the old one, so it
866 will reflect changes in the backing inode (link count,
867 etc.)
868 */
Miklos Szerediac45d612012-03-05 15:48:11 +0100869 if (!err) {
870 struct fuse_inode *fi = get_fuse_inode(inode);
871
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +0300872 spin_lock(&fi->lock);
Max Reitzfcee2162020-05-06 17:44:12 +0200873 fi->attr_version = atomic64_inc_return(&fm->fc->attr_version);
Miklos Szeredic634da72019-11-12 11:49:04 +0100874 if (likely(inode->i_nlink < UINT_MAX))
875 inc_nlink(inode);
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +0300876 spin_unlock(&fi->lock);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700877 fuse_invalidate_attr(inode);
Maxim Patlasov31f32672014-04-28 14:19:24 +0200878 fuse_update_ctime(inode);
Miklos Szerediac45d612012-03-05 15:48:11 +0100879 } else if (err == -EINTR) {
880 fuse_invalidate_attr(inode);
881 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700882 return err;
883}
884
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700885static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
886 struct kstat *stat)
887{
Miklos Szeredi203627b2012-05-10 19:49:38 +0400888 unsigned int blkbits;
Pavel Emelyanov83732002013-10-10 17:10:46 +0400889 struct fuse_conn *fc = get_fuse_conn(inode);
890
891 /* see the comment in fuse_change_attributes() */
Maxim Patlasovb0aa7602013-12-26 19:51:11 +0400892 if (fc->writeback_cache && S_ISREG(inode->i_mode)) {
Pavel Emelyanov83732002013-10-10 17:10:46 +0400893 attr->size = i_size_read(inode);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +0400894 attr->mtime = inode->i_mtime.tv_sec;
895 attr->mtimensec = inode->i_mtime.tv_nsec;
Maxim Patlasov31f32672014-04-28 14:19:24 +0200896 attr->ctime = inode->i_ctime.tv_sec;
897 attr->ctimensec = inode->i_ctime.tv_nsec;
Maxim Patlasovb0aa7602013-12-26 19:51:11 +0400898 }
Miklos Szeredi203627b2012-05-10 19:49:38 +0400899
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700900 stat->dev = inode->i_sb->s_dev;
901 stat->ino = attr->ino;
902 stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
903 stat->nlink = attr->nlink;
Eric W. Biederman8cb08322018-02-21 11:18:07 -0600904 stat->uid = make_kuid(fc->user_ns, attr->uid);
905 stat->gid = make_kgid(fc->user_ns, attr->gid);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700906 stat->rdev = inode->i_rdev;
907 stat->atime.tv_sec = attr->atime;
908 stat->atime.tv_nsec = attr->atimensec;
909 stat->mtime.tv_sec = attr->mtime;
910 stat->mtime.tv_nsec = attr->mtimensec;
911 stat->ctime.tv_sec = attr->ctime;
912 stat->ctime.tv_nsec = attr->ctimensec;
913 stat->size = attr->size;
914 stat->blocks = attr->blocks;
Miklos Szeredi203627b2012-05-10 19:49:38 +0400915
916 if (attr->blksize != 0)
917 blkbits = ilog2(attr->blksize);
918 else
919 blkbits = inode->i_sb->s_blocksize_bits;
920
921 stat->blksize = 1 << blkbits;
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700922}
923
Miklos Szeredic79e3222007-10-18 03:06:59 -0700924static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
925 struct file *file)
Miklos Szeredie5e55582005-09-09 13:10:28 -0700926{
927 int err;
Miklos Szeredic79e3222007-10-18 03:06:59 -0700928 struct fuse_getattr_in inarg;
929 struct fuse_attr_out outarg;
Max Reitzfcee2162020-05-06 17:44:12 +0200930 struct fuse_mount *fm = get_fuse_mount(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +0100931 FUSE_ARGS(args);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700932 u64 attr_version;
933
Max Reitzfcee2162020-05-06 17:44:12 +0200934 attr_version = fuse_get_attr_version(fm->fc);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700935
Miklos Szeredic79e3222007-10-18 03:06:59 -0700936 memset(&inarg, 0, sizeof(inarg));
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700937 memset(&outarg, 0, sizeof(outarg));
Miklos Szeredic79e3222007-10-18 03:06:59 -0700938 /* Directories have separate file-handle space */
939 if (file && S_ISREG(inode->i_mode)) {
940 struct fuse_file *ff = file->private_data;
941
942 inarg.getattr_flags |= FUSE_GETATTR_FH;
943 inarg.fh = ff->fh;
944 }
Miklos Szeredid5b48542019-09-10 15:04:08 +0200945 args.opcode = FUSE_GETATTR;
946 args.nodeid = get_node_id(inode);
947 args.in_numargs = 1;
948 args.in_args[0].size = sizeof(inarg);
949 args.in_args[0].value = &inarg;
950 args.out_numargs = 1;
951 args.out_args[0].size = sizeof(outarg);
952 args.out_args[0].value = &outarg;
Max Reitzfcee2162020-05-06 17:44:12 +0200953 err = fuse_simple_request(fm, &args);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700954 if (!err) {
Miklos Szeredieb59bd12019-11-12 11:49:04 +0100955 if (fuse_invalid_attr(&outarg.attr) ||
956 (inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
Miklos Szeredie5e55582005-09-09 13:10:28 -0700957 make_bad_inode(inode);
958 err = -EIO;
959 } else {
Miklos Szeredic79e3222007-10-18 03:06:59 -0700960 fuse_change_attributes(inode, &outarg.attr,
961 attr_timeout(&outarg),
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700962 attr_version);
963 if (stat)
Miklos Szeredic79e3222007-10-18 03:06:59 -0700964 fuse_fillattr(inode, &outarg.attr, stat);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700965 }
966 }
967 return err;
968}
969
Miklos Szeredi5b97eea2017-09-12 16:57:54 +0200970static int fuse_update_get_attr(struct inode *inode, struct file *file,
Miklos Szeredi2f1e8192018-10-15 15:43:06 +0200971 struct kstat *stat, u32 request_mask,
972 unsigned int flags)
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800973{
974 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredi5b97eea2017-09-12 16:57:54 +0200975 int err = 0;
Miklos Szeredibf5c1892018-03-20 17:11:44 +0100976 bool sync;
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800977
Miklos Szeredibf5c1892018-03-20 17:11:44 +0100978 if (flags & AT_STATX_FORCE_SYNC)
979 sync = true;
980 else if (flags & AT_STATX_DONT_SYNC)
981 sync = false;
Miklos Szeredi2f1e8192018-10-15 15:43:06 +0200982 else if (request_mask & READ_ONCE(fi->inval_mask))
983 sync = true;
Miklos Szeredibf5c1892018-03-20 17:11:44 +0100984 else
985 sync = time_before64(fi->i_time, get_jiffies_64());
986
987 if (sync) {
Seth Forshee60bcc882016-08-29 08:46:37 -0500988 forget_all_cached_acls(inode);
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800989 err = fuse_do_getattr(inode, stat, file);
Miklos Szeredi5b97eea2017-09-12 16:57:54 +0200990 } else if (stat) {
991 generic_fillattr(inode, stat);
992 stat->mode = fi->orig_i_mode;
993 stat->ino = fi->orig_ino;
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800994 }
995
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800996 return err;
997}
998
Miklos Szeredi5b97eea2017-09-12 16:57:54 +0200999int fuse_update_attributes(struct inode *inode, struct file *file)
1000{
Miklos Szeredi802dc042018-10-15 15:43:06 +02001001 /* Do *not* need to get atime for internal purposes */
1002 return fuse_update_get_attr(inode, file, NULL,
1003 STATX_BASIC_STATS & ~STATX_ATIME, 0);
Miklos Szeredi5b97eea2017-09-12 16:57:54 +02001004}
1005
Max Reitzfcee2162020-05-06 17:44:12 +02001006int fuse_reverse_inval_entry(struct fuse_conn *fc, u64 parent_nodeid,
John Muir451d0f52011-12-06 21:50:06 +01001007 u64 child_nodeid, struct qstr *name)
John Muir3b463ae2009-05-31 11:13:57 -04001008{
1009 int err = -ENOTDIR;
1010 struct inode *parent;
1011 struct dentry *dir;
1012 struct dentry *entry;
1013
Max Reitzfcee2162020-05-06 17:44:12 +02001014 parent = fuse_ilookup(fc, parent_nodeid, NULL);
John Muir3b463ae2009-05-31 11:13:57 -04001015 if (!parent)
1016 return -ENOENT;
1017
Al Viro59551022016-01-22 15:40:57 -05001018 inode_lock(parent);
John Muir3b463ae2009-05-31 11:13:57 -04001019 if (!S_ISDIR(parent->i_mode))
1020 goto unlock;
1021
1022 err = -ENOENT;
1023 dir = d_find_alias(parent);
1024 if (!dir)
1025 goto unlock;
1026
Linus Torvalds8387ff22016-06-10 07:51:30 -07001027 name->hash = full_name_hash(dir, name->name, name->len);
John Muir3b463ae2009-05-31 11:13:57 -04001028 entry = d_lookup(dir, name);
1029 dput(dir);
1030 if (!entry)
1031 goto unlock;
1032
Miklos Szeredi261aaba72018-10-01 10:07:05 +02001033 fuse_dir_changed(parent);
John Muir3b463ae2009-05-31 11:13:57 -04001034 fuse_invalidate_entry(entry);
John Muir451d0f52011-12-06 21:50:06 +01001035
David Howells2b0143b2015-03-17 22:25:59 +00001036 if (child_nodeid != 0 && d_really_is_positive(entry)) {
Al Viro59551022016-01-22 15:40:57 -05001037 inode_lock(d_inode(entry));
David Howells2b0143b2015-03-17 22:25:59 +00001038 if (get_node_id(d_inode(entry)) != child_nodeid) {
John Muir451d0f52011-12-06 21:50:06 +01001039 err = -ENOENT;
1040 goto badentry;
1041 }
1042 if (d_mountpoint(entry)) {
1043 err = -EBUSY;
1044 goto badentry;
1045 }
David Howellse36cb0b2015-01-29 12:02:35 +00001046 if (d_is_dir(entry)) {
John Muir451d0f52011-12-06 21:50:06 +01001047 shrink_dcache_parent(entry);
1048 if (!simple_empty(entry)) {
1049 err = -ENOTEMPTY;
1050 goto badentry;
1051 }
David Howells2b0143b2015-03-17 22:25:59 +00001052 d_inode(entry)->i_flags |= S_DEAD;
John Muir451d0f52011-12-06 21:50:06 +01001053 }
1054 dont_mount(entry);
David Howells2b0143b2015-03-17 22:25:59 +00001055 clear_nlink(d_inode(entry));
John Muir451d0f52011-12-06 21:50:06 +01001056 err = 0;
1057 badentry:
Al Viro59551022016-01-22 15:40:57 -05001058 inode_unlock(d_inode(entry));
John Muir451d0f52011-12-06 21:50:06 +01001059 if (!err)
1060 d_delete(entry);
1061 } else {
1062 err = 0;
1063 }
John Muir3b463ae2009-05-31 11:13:57 -04001064 dput(entry);
John Muir3b463ae2009-05-31 11:13:57 -04001065
1066 unlock:
Al Viro59551022016-01-22 15:40:57 -05001067 inode_unlock(parent);
John Muir3b463ae2009-05-31 11:13:57 -04001068 iput(parent);
1069 return err;
1070}
1071
Miklos Szeredi87729a52005-09-09 13:10:34 -07001072/*
1073 * Calling into a user-controlled filesystem gives the filesystem
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001074 * daemon ptrace-like capabilities over the current process. This
Miklos Szeredi87729a52005-09-09 13:10:34 -07001075 * means, that the filesystem daemon is able to record the exact
1076 * filesystem operations performed, and can also control the behavior
1077 * of the requester process in otherwise impossible ways. For example
1078 * it can delay the operation for arbitrary length of time allowing
1079 * DoS against the requester.
1080 *
1081 * For this reason only those processes can call into the filesystem,
1082 * for which the owner of the mount has ptrace privilege. This
1083 * excludes processes started by other users, suid or sgid processes.
1084 */
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001085int fuse_allow_current_process(struct fuse_conn *fc)
Miklos Szeredi87729a52005-09-09 13:10:34 -07001086{
David Howellsc69e8d92008-11-14 10:39:19 +11001087 const struct cred *cred;
David Howellsc69e8d92008-11-14 10:39:19 +11001088
Miklos Szeredi29433a22016-10-01 07:32:32 +02001089 if (fc->allow_other)
Seth Forshee73f03c22017-12-22 15:32:33 +01001090 return current_in_userns(fc->user_ns);
Miklos Szeredi87729a52005-09-09 13:10:34 -07001091
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001092 cred = current_cred();
Eric W. Biederman499dcf22012-02-07 16:26:03 -08001093 if (uid_eq(cred->euid, fc->user_id) &&
1094 uid_eq(cred->suid, fc->user_id) &&
1095 uid_eq(cred->uid, fc->user_id) &&
1096 gid_eq(cred->egid, fc->group_id) &&
1097 gid_eq(cred->sgid, fc->group_id) &&
1098 gid_eq(cred->gid, fc->group_id))
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001099 return 1;
Miklos Szeredi87729a52005-09-09 13:10:34 -07001100
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001101 return 0;
Miklos Szeredi87729a52005-09-09 13:10:34 -07001102}
1103
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001104static int fuse_access(struct inode *inode, int mask)
1105{
Max Reitzfcee2162020-05-06 17:44:12 +02001106 struct fuse_mount *fm = get_fuse_mount(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001107 FUSE_ARGS(args);
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001108 struct fuse_access_in inarg;
1109 int err;
1110
Miklos Szeredi698fa1d2013-10-01 16:41:23 +02001111 BUG_ON(mask & MAY_NOT_BLOCK);
1112
Max Reitzfcee2162020-05-06 17:44:12 +02001113 if (fm->fc->no_access)
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001114 return 0;
1115
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001116 memset(&inarg, 0, sizeof(inarg));
Al Viroe6305c42008-07-15 21:03:57 -04001117 inarg.mask = mask & (MAY_READ | MAY_WRITE | MAY_EXEC);
Miklos Szeredid5b48542019-09-10 15:04:08 +02001118 args.opcode = FUSE_ACCESS;
1119 args.nodeid = get_node_id(inode);
1120 args.in_numargs = 1;
1121 args.in_args[0].size = sizeof(inarg);
1122 args.in_args[0].value = &inarg;
Max Reitzfcee2162020-05-06 17:44:12 +02001123 err = fuse_simple_request(fm, &args);
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001124 if (err == -ENOSYS) {
Max Reitzfcee2162020-05-06 17:44:12 +02001125 fm->fc->no_access = 1;
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001126 err = 0;
1127 }
1128 return err;
1129}
1130
Al Viro10556cb2011-06-20 19:28:19 -04001131static int fuse_perm_getattr(struct inode *inode, int mask)
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001132{
Al Viro10556cb2011-06-20 19:28:19 -04001133 if (mask & MAY_NOT_BLOCK)
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001134 return -ECHILD;
1135
Seth Forshee60bcc882016-08-29 08:46:37 -05001136 forget_all_cached_acls(inode);
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001137 return fuse_do_getattr(inode, NULL, NULL);
1138}
1139
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001140/*
1141 * Check permission. The two basic access models of FUSE are:
1142 *
1143 * 1) Local access checking ('default_permissions' mount option) based
1144 * on file mode. This is the plain old disk filesystem permission
1145 * modell.
1146 *
1147 * 2) "Remote" access checking, where server is responsible for
1148 * checking permission in each inode operation. An exception to this
1149 * is if ->permission() was invoked from sys_access() in which case an
1150 * access request is sent. Execute permission is still checked
1151 * locally based on file mode.
1152 */
Al Viro10556cb2011-06-20 19:28:19 -04001153static int fuse_permission(struct inode *inode, int mask)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001154{
1155 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi244f6382007-10-16 23:31:02 -07001156 bool refreshed = false;
1157 int err = 0;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001158
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001159 if (!fuse_allow_current_process(fc))
Miklos Szeredie5e55582005-09-09 13:10:28 -07001160 return -EACCES;
Miklos Szeredi244f6382007-10-16 23:31:02 -07001161
1162 /*
Miklos Szeredie8e96152007-10-16 23:31:06 -07001163 * If attributes are needed, refresh them before proceeding
Miklos Szeredi244f6382007-10-16 23:31:02 -07001164 */
Miklos Szeredi29433a22016-10-01 07:32:32 +02001165 if (fc->default_permissions ||
Miklos Szeredie8e96152007-10-16 23:31:06 -07001166 ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) {
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001167 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredid233c7d2018-12-03 10:14:43 +01001168 u32 perm_mask = STATX_MODE | STATX_UID | STATX_GID;
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001169
Miklos Szeredid233c7d2018-12-03 10:14:43 +01001170 if (perm_mask & READ_ONCE(fi->inval_mask) ||
1171 time_before64(fi->i_time, get_jiffies_64())) {
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001172 refreshed = true;
1173
Al Viro10556cb2011-06-20 19:28:19 -04001174 err = fuse_perm_getattr(inode, mask);
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001175 if (err)
1176 return err;
1177 }
Miklos Szeredi244f6382007-10-16 23:31:02 -07001178 }
1179
Miklos Szeredi29433a22016-10-01 07:32:32 +02001180 if (fc->default_permissions) {
Al Viro2830ba72011-06-20 19:16:29 -04001181 err = generic_permission(inode, mask);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001182
1183 /* If permission is denied, try to refresh file
1184 attributes. This is also needed, because the root
1185 node will at first have no permissions */
Miklos Szeredi244f6382007-10-16 23:31:02 -07001186 if (err == -EACCES && !refreshed) {
Al Viro10556cb2011-06-20 19:28:19 -04001187 err = fuse_perm_getattr(inode, mask);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001188 if (!err)
Al Viro2830ba72011-06-20 19:16:29 -04001189 err = generic_permission(inode, mask);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001190 }
1191
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001192 /* Note: the opposite of the above test does not
1193 exist. So if permissions are revoked this won't be
1194 noticed immediately, only after the attribute
1195 timeout has expired */
Eric Paris9cfcac82010-07-23 11:43:51 -04001196 } else if (mask & (MAY_ACCESS | MAY_CHDIR)) {
Miklos Szeredie8e96152007-10-16 23:31:06 -07001197 err = fuse_access(inode, mask);
1198 } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
1199 if (!(inode->i_mode & S_IXUGO)) {
1200 if (refreshed)
1201 return -EACCES;
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001202
Al Viro10556cb2011-06-20 19:28:19 -04001203 err = fuse_perm_getattr(inode, mask);
Miklos Szeredie8e96152007-10-16 23:31:06 -07001204 if (!err && !(inode->i_mode & S_IXUGO))
1205 return -EACCES;
1206 }
Miklos Szeredie5e55582005-09-09 13:10:28 -07001207 }
Miklos Szeredi244f6382007-10-16 23:31:02 -07001208 return err;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001209}
1210
Dan Schatzberg5571f1e2018-10-11 08:17:00 -07001211static int fuse_readlink_page(struct inode *inode, struct page *page)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001212{
Max Reitzfcee2162020-05-06 17:44:12 +02001213 struct fuse_mount *fm = get_fuse_mount(inode);
Miklos Szeredi4c29afe2019-09-10 15:04:09 +02001214 struct fuse_page_desc desc = { .length = PAGE_SIZE - 1 };
1215 struct fuse_args_pages ap = {
1216 .num_pages = 1,
1217 .pages = &page,
1218 .descs = &desc,
1219 };
1220 char *link;
1221 ssize_t res;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001222
Miklos Szeredi4c29afe2019-09-10 15:04:09 +02001223 ap.args.opcode = FUSE_READLINK;
1224 ap.args.nodeid = get_node_id(inode);
1225 ap.args.out_pages = true;
1226 ap.args.out_argvar = true;
1227 ap.args.page_zeroing = true;
1228 ap.args.out_numargs = 1;
1229 ap.args.out_args[0].size = desc.length;
Max Reitzfcee2162020-05-06 17:44:12 +02001230 res = fuse_simple_request(fm, &ap.args);
Al Viro6b255392015-11-17 10:20:54 -05001231
Andrew Gallagher451418f2013-11-05 03:55:43 -08001232 fuse_invalidate_atime(inode);
Dan Schatzberg5571f1e2018-10-11 08:17:00 -07001233
Miklos Szeredi4c29afe2019-09-10 15:04:09 +02001234 if (res < 0)
1235 return res;
1236
1237 if (WARN_ON(res >= PAGE_SIZE))
1238 return -EIO;
1239
1240 link = page_address(page);
1241 link[res] = '\0';
1242
1243 return 0;
Dan Schatzberg5571f1e2018-10-11 08:17:00 -07001244}
1245
1246static const char *fuse_get_link(struct dentry *dentry, struct inode *inode,
1247 struct delayed_call *callback)
1248{
1249 struct fuse_conn *fc = get_fuse_conn(inode);
1250 struct page *page;
1251 int err;
1252
1253 err = -EIO;
1254 if (is_bad_inode(inode))
1255 goto out_err;
1256
1257 if (fc->cache_symlinks)
1258 return page_get_link(dentry, inode, callback);
1259
1260 err = -ECHILD;
1261 if (!dentry)
1262 goto out_err;
1263
1264 page = alloc_page(GFP_KERNEL);
1265 err = -ENOMEM;
1266 if (!page)
1267 goto out_err;
1268
1269 err = fuse_readlink_page(inode, page);
1270 if (err) {
1271 __free_page(page);
1272 goto out_err;
1273 }
1274
1275 set_delayed_call(callback, page_put_link, page);
1276
1277 return page_address(page);
1278
1279out_err:
1280 return ERR_PTR(err);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001281}
1282
Miklos Szeredie5e55582005-09-09 13:10:28 -07001283static int fuse_dir_open(struct inode *inode, struct file *file)
1284{
Miklos Szeredi91fe96b2009-04-28 16:56:37 +02001285 return fuse_open_common(inode, file, true);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001286}
1287
1288static int fuse_dir_release(struct inode *inode, struct file *file)
1289{
Chad Austin2e64ff12018-12-10 10:54:52 -08001290 fuse_release_common(file, true);
Miklos Szeredi8b0797a2009-04-28 16:56:39 +02001291
1292 return 0;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001293}
1294
Josef Bacik02c24a82011-07-16 20:44:56 -04001295static int fuse_dir_fsync(struct file *file, loff_t start, loff_t end,
1296 int datasync)
Miklos Szeredi82547982005-09-09 13:10:38 -07001297{
Miklos Szeredia9c2d1e2018-12-03 10:14:43 +01001298 struct inode *inode = file->f_mapping->host;
1299 struct fuse_conn *fc = get_fuse_conn(inode);
1300 int err;
1301
1302 if (is_bad_inode(inode))
1303 return -EIO;
1304
1305 if (fc->no_fsyncdir)
1306 return 0;
1307
1308 inode_lock(inode);
1309 err = fuse_fsync_common(file, start, end, datasync, FUSE_FSYNCDIR);
1310 if (err == -ENOSYS) {
1311 fc->no_fsyncdir = 1;
1312 err = 0;
1313 }
1314 inode_unlock(inode);
1315
1316 return err;
Miklos Szeredi82547982005-09-09 13:10:38 -07001317}
1318
Miklos Szeredib18da0c2011-12-13 11:58:49 +01001319static long fuse_dir_ioctl(struct file *file, unsigned int cmd,
1320 unsigned long arg)
1321{
1322 struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1323
1324 /* FUSE_IOCTL_DIR only supported for API version >= 7.18 */
1325 if (fc->minor < 18)
1326 return -ENOTTY;
1327
1328 return fuse_ioctl_common(file, cmd, arg, FUSE_IOCTL_DIR);
1329}
1330
1331static long fuse_dir_compat_ioctl(struct file *file, unsigned int cmd,
1332 unsigned long arg)
1333{
1334 struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1335
1336 if (fc->minor < 18)
1337 return -ENOTTY;
1338
1339 return fuse_ioctl_common(file, cmd, arg,
1340 FUSE_IOCTL_COMPAT | FUSE_IOCTL_DIR);
1341}
1342
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001343static bool update_mtime(unsigned ivalid, bool trust_local_mtime)
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001344{
1345 /* Always update if mtime is explicitly set */
1346 if (ivalid & ATTR_MTIME_SET)
1347 return true;
1348
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001349 /* Or if kernel i_mtime is the official one */
1350 if (trust_local_mtime)
1351 return true;
1352
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001353 /* If it's an open(O_TRUNC) or an ftruncate(), don't update */
1354 if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE)))
1355 return false;
1356
1357 /* In all other cases update */
1358 return true;
1359}
1360
Eric W. Biederman8cb08322018-02-21 11:18:07 -06001361static void iattr_to_fattr(struct fuse_conn *fc, struct iattr *iattr,
1362 struct fuse_setattr_in *arg, bool trust_local_cmtime)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001363{
1364 unsigned ivalid = iattr->ia_valid;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001365
1366 if (ivalid & ATTR_MODE)
Miklos Szeredibefc6492005-11-07 00:59:52 -08001367 arg->valid |= FATTR_MODE, arg->mode = iattr->ia_mode;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001368 if (ivalid & ATTR_UID)
Eric W. Biederman8cb08322018-02-21 11:18:07 -06001369 arg->valid |= FATTR_UID, arg->uid = from_kuid(fc->user_ns, iattr->ia_uid);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001370 if (ivalid & ATTR_GID)
Eric W. Biederman8cb08322018-02-21 11:18:07 -06001371 arg->valid |= FATTR_GID, arg->gid = from_kgid(fc->user_ns, iattr->ia_gid);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001372 if (ivalid & ATTR_SIZE)
Miklos Szeredibefc6492005-11-07 00:59:52 -08001373 arg->valid |= FATTR_SIZE, arg->size = iattr->ia_size;
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001374 if (ivalid & ATTR_ATIME) {
1375 arg->valid |= FATTR_ATIME;
Miklos Szeredibefc6492005-11-07 00:59:52 -08001376 arg->atime = iattr->ia_atime.tv_sec;
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001377 arg->atimensec = iattr->ia_atime.tv_nsec;
1378 if (!(ivalid & ATTR_ATIME_SET))
1379 arg->valid |= FATTR_ATIME_NOW;
1380 }
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001381 if ((ivalid & ATTR_MTIME) && update_mtime(ivalid, trust_local_cmtime)) {
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001382 arg->valid |= FATTR_MTIME;
Miklos Szeredibefc6492005-11-07 00:59:52 -08001383 arg->mtime = iattr->ia_mtime.tv_sec;
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001384 arg->mtimensec = iattr->ia_mtime.tv_nsec;
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001385 if (!(ivalid & ATTR_MTIME_SET) && !trust_local_cmtime)
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001386 arg->valid |= FATTR_MTIME_NOW;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001387 }
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001388 if ((ivalid & ATTR_CTIME) && trust_local_cmtime) {
1389 arg->valid |= FATTR_CTIME;
1390 arg->ctime = iattr->ia_ctime.tv_sec;
1391 arg->ctimensec = iattr->ia_ctime.tv_nsec;
1392 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001393}
1394
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001395/*
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001396 * Prevent concurrent writepages on inode
1397 *
1398 * This is done by adding a negative bias to the inode write counter
1399 * and waiting for all pending writes to finish.
1400 */
1401void fuse_set_nowrite(struct inode *inode)
1402{
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001403 struct fuse_inode *fi = get_fuse_inode(inode);
1404
Al Viro59551022016-01-22 15:40:57 -05001405 BUG_ON(!inode_is_locked(inode));
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001406
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001407 spin_lock(&fi->lock);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001408 BUG_ON(fi->writectr < 0);
1409 fi->writectr += FUSE_NOWRITE;
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001410 spin_unlock(&fi->lock);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001411 wait_event(fi->page_waitq, fi->writectr == FUSE_NOWRITE);
1412}
1413
1414/*
1415 * Allow writepages on inode
1416 *
1417 * Remove the bias from the writecounter and send any queued
1418 * writepages.
1419 */
1420static void __fuse_release_nowrite(struct inode *inode)
1421{
1422 struct fuse_inode *fi = get_fuse_inode(inode);
1423
1424 BUG_ON(fi->writectr != FUSE_NOWRITE);
1425 fi->writectr = 0;
1426 fuse_flush_writepages(inode);
1427}
1428
1429void fuse_release_nowrite(struct inode *inode)
1430{
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001431 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001432
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001433 spin_lock(&fi->lock);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001434 __fuse_release_nowrite(inode);
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001435 spin_unlock(&fi->lock);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001436}
1437
Miklos Szeredi70781872014-12-12 09:49:05 +01001438static void fuse_setattr_fill(struct fuse_conn *fc, struct fuse_args *args,
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001439 struct inode *inode,
1440 struct fuse_setattr_in *inarg_p,
1441 struct fuse_attr_out *outarg_p)
1442{
Miklos Szeredid5b48542019-09-10 15:04:08 +02001443 args->opcode = FUSE_SETATTR;
1444 args->nodeid = get_node_id(inode);
1445 args->in_numargs = 1;
1446 args->in_args[0].size = sizeof(*inarg_p);
1447 args->in_args[0].value = inarg_p;
1448 args->out_numargs = 1;
1449 args->out_args[0].size = sizeof(*outarg_p);
1450 args->out_args[0].value = outarg_p;
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001451}
1452
1453/*
1454 * Flush inode->i_mtime to the server
1455 */
Maxim Patlasovab9e13f2014-04-28 14:19:24 +02001456int fuse_flush_times(struct inode *inode, struct fuse_file *ff)
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001457{
Max Reitzfcee2162020-05-06 17:44:12 +02001458 struct fuse_mount *fm = get_fuse_mount(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001459 FUSE_ARGS(args);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001460 struct fuse_setattr_in inarg;
1461 struct fuse_attr_out outarg;
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001462
1463 memset(&inarg, 0, sizeof(inarg));
1464 memset(&outarg, 0, sizeof(outarg));
1465
Maxim Patlasovab9e13f2014-04-28 14:19:24 +02001466 inarg.valid = FATTR_MTIME;
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001467 inarg.mtime = inode->i_mtime.tv_sec;
1468 inarg.mtimensec = inode->i_mtime.tv_nsec;
Max Reitzfcee2162020-05-06 17:44:12 +02001469 if (fm->fc->minor >= 23) {
Maxim Patlasovab9e13f2014-04-28 14:19:24 +02001470 inarg.valid |= FATTR_CTIME;
1471 inarg.ctime = inode->i_ctime.tv_sec;
1472 inarg.ctimensec = inode->i_ctime.tv_nsec;
1473 }
Miklos Szeredi1e18bda2014-04-28 14:19:23 +02001474 if (ff) {
1475 inarg.valid |= FATTR_FH;
1476 inarg.fh = ff->fh;
1477 }
Max Reitzfcee2162020-05-06 17:44:12 +02001478 fuse_setattr_fill(fm->fc, &args, inode, &inarg, &outarg);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001479
Max Reitzfcee2162020-05-06 17:44:12 +02001480 return fuse_simple_request(fm, &args);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001481}
1482
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001483/*
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001484 * Set attributes, and at the same time refresh them.
1485 *
1486 * Truncation is slightly complicated, because the 'truncate' request
1487 * may fail, in which case we don't want to touch the mapping.
Miklos Szeredi9ffbb912006-10-17 00:10:06 -07001488 * vmtruncate() doesn't allow for this case, so do the rlimit checking
1489 * and the actual truncation by hand.
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001490 */
Jan Kara62490332016-05-26 17:12:41 +02001491int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
Maxim Patlasovefb9fa92012-12-18 14:05:08 +04001492 struct file *file)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001493{
Jan Kara62490332016-05-26 17:12:41 +02001494 struct inode *inode = d_inode(dentry);
Max Reitzfcee2162020-05-06 17:44:12 +02001495 struct fuse_mount *fm = get_fuse_mount(inode);
1496 struct fuse_conn *fc = fm->fc;
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001497 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001498 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001499 struct fuse_setattr_in inarg;
1500 struct fuse_attr_out outarg;
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001501 bool is_truncate = false;
Pavel Emelyanov83732002013-10-10 17:10:46 +04001502 bool is_wb = fc->writeback_cache;
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001503 loff_t oldsize;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001504 int err;
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001505 bool trust_local_cmtime = is_wb && S_ISREG(inode->i_mode);
Vivek Goyal6ae330c2020-08-19 18:19:54 -04001506 bool fault_blocked = false;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001507
Miklos Szeredi29433a22016-10-01 07:32:32 +02001508 if (!fc->default_permissions)
Christoph Hellwigdb78b872010-06-04 11:30:03 +02001509 attr->ia_valid |= ATTR_FORCE;
1510
Jan Kara31051c82016-05-26 16:55:18 +02001511 err = setattr_prepare(dentry, attr);
Christoph Hellwigdb78b872010-06-04 11:30:03 +02001512 if (err)
1513 return err;
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001514
Vivek Goyal6ae330c2020-08-19 18:19:54 -04001515 if (attr->ia_valid & ATTR_SIZE) {
1516 if (WARN_ON(!S_ISREG(inode->i_mode)))
1517 return -EIO;
1518 is_truncate = true;
1519 }
1520
1521 if (FUSE_IS_DAX(inode) && is_truncate) {
1522 down_write(&fi->i_mmap_sem);
1523 fault_blocked = true;
1524 err = fuse_dax_break_layouts(inode, 0, 0);
1525 if (err) {
1526 up_write(&fi->i_mmap_sem);
1527 return err;
1528 }
1529 }
1530
Miklos Szeredi8d56add2011-02-25 14:44:58 +01001531 if (attr->ia_valid & ATTR_OPEN) {
Miklos Szeredidf0e91d2018-02-08 15:17:38 +01001532 /* This is coming from open(..., ... | O_TRUNC); */
1533 WARN_ON(!(attr->ia_valid & ATTR_SIZE));
1534 WARN_ON(attr->ia_size != 0);
1535 if (fc->atomic_o_trunc) {
1536 /*
1537 * No need to send request to userspace, since actual
1538 * truncation has already been done by OPEN. But still
1539 * need to truncate page cache.
1540 */
1541 i_size_write(inode, 0);
1542 truncate_pagecache(inode, 0);
Vivek Goyal6ae330c2020-08-19 18:19:54 -04001543 goto out;
Miklos Szeredidf0e91d2018-02-08 15:17:38 +01001544 }
Miklos Szeredi8d56add2011-02-25 14:44:58 +01001545 file = NULL;
1546 }
Miklos Szeredi6ff958e2007-10-18 03:07:02 -07001547
Miklos Szeredib24e7592019-10-23 14:26:37 +02001548 /* Flush dirty data/metadata before non-truncate SETATTR */
1549 if (is_wb && S_ISREG(inode->i_mode) &&
1550 attr->ia_valid &
1551 (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_MTIME_SET |
1552 ATTR_TIMES_SET)) {
1553 err = write_inode_now(inode, true);
1554 if (err)
1555 return err;
1556
1557 fuse_set_nowrite(inode);
1558 fuse_release_nowrite(inode);
1559 }
1560
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001561 if (is_truncate) {
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001562 fuse_set_nowrite(inode);
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001563 set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001564 if (trust_local_cmtime && attr->ia_size != inode->i_size)
1565 attr->ia_valid |= ATTR_MTIME | ATTR_CTIME;
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001566 }
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001567
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001568 memset(&inarg, 0, sizeof(inarg));
Miklos Szeredi0e9663e2007-10-18 03:07:05 -07001569 memset(&outarg, 0, sizeof(outarg));
Eric W. Biederman8cb08322018-02-21 11:18:07 -06001570 iattr_to_fattr(fc, attr, &inarg, trust_local_cmtime);
Miklos Szeredi49d49142007-10-18 03:07:00 -07001571 if (file) {
1572 struct fuse_file *ff = file->private_data;
1573 inarg.valid |= FATTR_FH;
1574 inarg.fh = ff->fh;
1575 }
Miklos Szeredif3332112007-10-18 03:07:04 -07001576 if (attr->ia_valid & ATTR_SIZE) {
1577 /* For mandatory locking in truncate */
1578 inarg.valid |= FATTR_LOCKOWNER;
1579 inarg.lock_owner = fuse_lock_owner_id(fc, current->files);
1580 }
Miklos Szeredi70781872014-12-12 09:49:05 +01001581 fuse_setattr_fill(fc, &args, inode, &inarg, &outarg);
Max Reitzfcee2162020-05-06 17:44:12 +02001582 err = fuse_simple_request(fm, &args);
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001583 if (err) {
1584 if (err == -EINTR)
1585 fuse_invalidate_attr(inode);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001586 goto error;
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001587 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001588
Miklos Szeredieb59bd12019-11-12 11:49:04 +01001589 if (fuse_invalid_attr(&outarg.attr) ||
1590 (inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001591 make_bad_inode(inode);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001592 err = -EIO;
1593 goto error;
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001594 }
1595
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001596 spin_lock(&fi->lock);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001597 /* the kernel maintains i_mtime locally */
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001598 if (trust_local_cmtime) {
1599 if (attr->ia_valid & ATTR_MTIME)
1600 inode->i_mtime = attr->ia_mtime;
1601 if (attr->ia_valid & ATTR_CTIME)
1602 inode->i_ctime = attr->ia_ctime;
Miklos Szeredi1e18bda2014-04-28 14:19:23 +02001603 /* FIXME: clear I_DIRTY_SYNC? */
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001604 }
1605
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001606 fuse_change_attributes_common(inode, &outarg.attr,
1607 attr_timeout(&outarg));
1608 oldsize = inode->i_size;
Pavel Emelyanov83732002013-10-10 17:10:46 +04001609 /* see the comment in fuse_change_attributes() */
1610 if (!is_wb || is_truncate || !S_ISREG(inode->i_mode))
1611 i_size_write(inode, outarg.attr.size);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001612
1613 if (is_truncate) {
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001614 /* NOTE: this may release/reacquire fi->lock */
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001615 __fuse_release_nowrite(inode);
1616 }
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001617 spin_unlock(&fi->lock);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001618
1619 /*
1620 * Only call invalidate_inode_pages2() after removing
1621 * FUSE_NOWRITE, otherwise fuse_launder_page() would deadlock.
1622 */
Pavel Emelyanov83732002013-10-10 17:10:46 +04001623 if ((is_truncate || !is_wb) &&
1624 S_ISREG(inode->i_mode) && oldsize != outarg.attr.size) {
Kirill A. Shutemov7caef262013-09-12 15:13:56 -07001625 truncate_pagecache(inode, outarg.attr.size);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001626 invalidate_inode_pages2(inode->i_mapping);
1627 }
1628
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001629 clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
Vivek Goyal6ae330c2020-08-19 18:19:54 -04001630out:
1631 if (fault_blocked)
1632 up_write(&fi->i_mmap_sem);
1633
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001634 return 0;
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001635
1636error:
1637 if (is_truncate)
1638 fuse_release_nowrite(inode);
1639
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001640 clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
Vivek Goyal6ae330c2020-08-19 18:19:54 -04001641
1642 if (fault_blocked)
1643 up_write(&fi->i_mmap_sem);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001644 return err;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001645}
1646
Miklos Szeredi49d49142007-10-18 03:07:00 -07001647static int fuse_setattr(struct dentry *entry, struct iattr *attr)
1648{
David Howells2b0143b2015-03-17 22:25:59 +00001649 struct inode *inode = d_inode(entry);
Miklos Szeredi5e940c12016-10-01 07:32:32 +02001650 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredia09f99e2016-10-01 07:32:32 +02001651 struct file *file = (attr->ia_valid & ATTR_FILE) ? attr->ia_file : NULL;
Miklos Szeredi5e2b8822016-10-01 07:32:32 +02001652 int ret;
Maxim Patlasovefb9fa92012-12-18 14:05:08 +04001653
1654 if (!fuse_allow_current_process(get_fuse_conn(inode)))
1655 return -EACCES;
1656
Miklos Szeredia09f99e2016-10-01 07:32:32 +02001657 if (attr->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) {
Miklos Szeredia09f99e2016-10-01 07:32:32 +02001658 attr->ia_valid &= ~(ATTR_KILL_SUID | ATTR_KILL_SGID |
1659 ATTR_MODE);
Miklos Szeredia09f99e2016-10-01 07:32:32 +02001660
Miklos Szeredi5e940c12016-10-01 07:32:32 +02001661 /*
1662 * The only sane way to reliably kill suid/sgid is to do it in
1663 * the userspace filesystem
1664 *
1665 * This should be done on write(), truncate() and chown().
1666 */
1667 if (!fc->handle_killpriv) {
Miklos Szeredi5e940c12016-10-01 07:32:32 +02001668 /*
1669 * ia_mode calculation may have used stale i_mode.
1670 * Refresh and recalculate.
1671 */
1672 ret = fuse_do_getattr(inode, NULL, file);
1673 if (ret)
1674 return ret;
1675
1676 attr->ia_mode = inode->i_mode;
Miklos Szeredic01638f2016-12-06 16:18:45 +01001677 if (inode->i_mode & S_ISUID) {
Miklos Szeredi5e940c12016-10-01 07:32:32 +02001678 attr->ia_valid |= ATTR_MODE;
1679 attr->ia_mode &= ~S_ISUID;
1680 }
Miklos Szeredic01638f2016-12-06 16:18:45 +01001681 if ((inode->i_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
Miklos Szeredi5e940c12016-10-01 07:32:32 +02001682 attr->ia_valid |= ATTR_MODE;
1683 attr->ia_mode &= ~S_ISGID;
1684 }
Miklos Szeredia09f99e2016-10-01 07:32:32 +02001685 }
1686 }
1687 if (!attr->ia_valid)
1688 return 0;
1689
Linus Torvaldsabb5a142016-10-10 13:04:49 -07001690 ret = fuse_do_setattr(entry, attr, file);
Miklos Szeredi5e2b8822016-10-01 07:32:32 +02001691 if (!ret) {
Seth Forshee60bcc882016-08-29 08:46:37 -05001692 /*
1693 * If filesystem supports acls it may have updated acl xattrs in
1694 * the filesystem, so forget cached acls for the inode.
1695 */
1696 if (fc->posix_acl)
1697 forget_all_cached_acls(inode);
1698
Miklos Szeredi5e2b8822016-10-01 07:32:32 +02001699 /* Directory mode changed, may need to revalidate access */
1700 if (d_is_dir(entry) && (attr->ia_valid & ATTR_MODE))
1701 fuse_invalidate_entry_cache(entry);
1702 }
1703 return ret;
Miklos Szeredi49d49142007-10-18 03:07:00 -07001704}
1705
David Howellsa528d352017-01-31 16:46:22 +00001706static int fuse_getattr(const struct path *path, struct kstat *stat,
1707 u32 request_mask, unsigned int flags)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001708{
David Howellsa528d352017-01-31 16:46:22 +00001709 struct inode *inode = d_inode(path->dentry);
Miklos Szeredi244f6382007-10-16 23:31:02 -07001710 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi244f6382007-10-16 23:31:02 -07001711
Miklos Szeredi5157da22020-05-19 14:50:37 +02001712 if (!fuse_allow_current_process(fc)) {
1713 if (!request_mask) {
1714 /*
1715 * If user explicitly requested *nothing* then don't
1716 * error out, but return st_dev only.
1717 */
1718 stat->result_mask = 0;
1719 stat->dev = inode->i_sb->s_dev;
1720 return 0;
1721 }
Miklos Szeredi244f6382007-10-16 23:31:02 -07001722 return -EACCES;
Miklos Szeredi5157da22020-05-19 14:50:37 +02001723 }
Miklos Szeredi244f6382007-10-16 23:31:02 -07001724
Miklos Szeredi2f1e8192018-10-15 15:43:06 +02001725 return fuse_update_get_attr(inode, NULL, stat, request_mask, flags);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001726}
1727
Arjan van de Ven754661f2007-02-12 00:55:38 -08001728static const struct inode_operations fuse_dir_inode_operations = {
Miklos Szeredie5e55582005-09-09 13:10:28 -07001729 .lookup = fuse_lookup,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001730 .mkdir = fuse_mkdir,
1731 .symlink = fuse_symlink,
1732 .unlink = fuse_unlink,
1733 .rmdir = fuse_rmdir,
Miklos Szeredi2773bf02016-09-27 11:03:58 +02001734 .rename = fuse_rename2,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001735 .link = fuse_link,
1736 .setattr = fuse_setattr,
1737 .create = fuse_create,
Miklos Szeredic8ccbe02012-06-05 15:10:22 +02001738 .atomic_open = fuse_atomic_open,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001739 .mknod = fuse_mknod,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001740 .permission = fuse_permission,
1741 .getattr = fuse_getattr,
Miklos Szeredi92a87802005-09-09 13:10:31 -07001742 .listxattr = fuse_listxattr,
Seth Forshee60bcc882016-08-29 08:46:37 -05001743 .get_acl = fuse_get_acl,
1744 .set_acl = fuse_set_acl,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001745};
1746
Arjan van de Ven4b6f5d22006-03-28 01:56:42 -08001747static const struct file_operations fuse_dir_operations = {
Miklos Szeredib6aeade2005-09-09 13:10:30 -07001748 .llseek = generic_file_llseek,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001749 .read = generic_read_dir,
Al Virod9b3dbd2016-04-20 17:30:32 -04001750 .iterate_shared = fuse_readdir,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001751 .open = fuse_dir_open,
1752 .release = fuse_dir_release,
Miklos Szeredi82547982005-09-09 13:10:38 -07001753 .fsync = fuse_dir_fsync,
Miklos Szeredib18da0c2011-12-13 11:58:49 +01001754 .unlocked_ioctl = fuse_dir_ioctl,
1755 .compat_ioctl = fuse_dir_compat_ioctl,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001756};
1757
Arjan van de Ven754661f2007-02-12 00:55:38 -08001758static const struct inode_operations fuse_common_inode_operations = {
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001759 .setattr = fuse_setattr,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001760 .permission = fuse_permission,
1761 .getattr = fuse_getattr,
Miklos Szeredi92a87802005-09-09 13:10:31 -07001762 .listxattr = fuse_listxattr,
Seth Forshee60bcc882016-08-29 08:46:37 -05001763 .get_acl = fuse_get_acl,
1764 .set_acl = fuse_set_acl,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001765};
1766
Arjan van de Ven754661f2007-02-12 00:55:38 -08001767static const struct inode_operations fuse_symlink_inode_operations = {
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001768 .setattr = fuse_setattr,
Al Viro6b255392015-11-17 10:20:54 -05001769 .get_link = fuse_get_link,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001770 .getattr = fuse_getattr,
Miklos Szeredi92a87802005-09-09 13:10:31 -07001771 .listxattr = fuse_listxattr,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001772};
1773
1774void fuse_init_common(struct inode *inode)
1775{
1776 inode->i_op = &fuse_common_inode_operations;
1777}
1778
1779void fuse_init_dir(struct inode *inode)
1780{
Miklos Szerediab2257e2018-10-01 10:07:05 +02001781 struct fuse_inode *fi = get_fuse_inode(inode);
1782
Miklos Szeredie5e55582005-09-09 13:10:28 -07001783 inode->i_op = &fuse_dir_inode_operations;
1784 inode->i_fop = &fuse_dir_operations;
Miklos Szerediab2257e2018-10-01 10:07:05 +02001785
1786 spin_lock_init(&fi->rdc.lock);
1787 fi->rdc.cached = false;
1788 fi->rdc.size = 0;
1789 fi->rdc.pos = 0;
1790 fi->rdc.version = 0;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001791}
1792
Dan Schatzberg5571f1e2018-10-11 08:17:00 -07001793static int fuse_symlink_readpage(struct file *null, struct page *page)
1794{
1795 int err = fuse_readlink_page(page->mapping->host, page);
1796
1797 if (!err)
1798 SetPageUptodate(page);
1799
1800 unlock_page(page);
1801
1802 return err;
1803}
1804
1805static const struct address_space_operations fuse_symlink_aops = {
1806 .readpage = fuse_symlink_readpage,
1807};
1808
Miklos Szeredie5e55582005-09-09 13:10:28 -07001809void fuse_init_symlink(struct inode *inode)
1810{
1811 inode->i_op = &fuse_symlink_inode_operations;
Dan Schatzberg5571f1e2018-10-11 08:17:00 -07001812 inode->i_data.a_ops = &fuse_symlink_aops;
1813 inode_nohighmem(inode);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001814}