blob: ff7dbeb16f88dae260f280aada6d589cccf1f162 [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>
Max Reitzbf109c62020-04-21 14:47:15 +020013#include <linux/fs_context.h>
Miklos Szeredie5e55582005-09-09 13:10:28 -070014#include <linux/sched.h>
15#include <linux/namei.h>
Miklos Szeredi07e77dc2010-12-07 20:16:56 +010016#include <linux/slab.h>
Seth Forshee703c7362016-08-29 08:46:36 -050017#include <linux/xattr.h>
Miklos Szeredi261aaba72018-10-01 10:07:05 +020018#include <linux/iversion.h>
Seth Forshee60bcc882016-08-29 08:46:37 -050019#include <linux/posix_acl.h>
Miklos Szeredie5e55582005-09-09 13:10:28 -070020
Feng Shuo4582a4a2013-01-15 11:23:28 +080021static void fuse_advise_use_readdirplus(struct inode *dir)
22{
23 struct fuse_inode *fi = get_fuse_inode(dir);
24
25 set_bit(FUSE_I_ADVISE_RDPLUS, &fi->state);
26}
27
Khazhismel Kumykov30c6a232019-09-16 16:56:41 -070028#if BITS_PER_LONG >= 64
29static inline void __fuse_dentry_settime(struct dentry *entry, u64 time)
30{
31 entry->d_fsdata = (void *) time;
32}
33
34static inline u64 fuse_dentry_time(const struct dentry *entry)
35{
36 return (u64)entry->d_fsdata;
37}
38
39#else
Miklos Szeredif75fdf22016-10-01 07:32:32 +020040union fuse_dentry {
41 u64 time;
42 struct rcu_head rcu;
43};
44
Khazhismel Kumykov30c6a232019-09-16 16:56:41 -070045static inline void __fuse_dentry_settime(struct dentry *dentry, u64 time)
46{
47 ((union fuse_dentry *) dentry->d_fsdata)->time = time;
48}
49
50static inline u64 fuse_dentry_time(const struct dentry *entry)
51{
52 return ((union fuse_dentry *) entry->d_fsdata)->time;
53}
54#endif
55
Miklos Szeredi8fab0102018-08-15 17:42:34 +020056static void fuse_dentry_settime(struct dentry *dentry, u64 time)
Miklos Szeredi0a0898c2006-07-30 03:04:10 -070057{
Miklos Szeredi8fab0102018-08-15 17:42:34 +020058 struct fuse_conn *fc = get_fuse_conn_super(dentry->d_sb);
59 bool delete = !time && fc->delete_stale;
60 /*
61 * Mess with DCACHE_OP_DELETE because dput() will be faster without it.
62 * Don't care about races, either way it's just an optimization
63 */
64 if ((!delete && (dentry->d_flags & DCACHE_OP_DELETE)) ||
65 (delete && !(dentry->d_flags & DCACHE_OP_DELETE))) {
66 spin_lock(&dentry->d_lock);
67 if (!delete)
68 dentry->d_flags &= ~DCACHE_OP_DELETE;
69 else
70 dentry->d_flags |= DCACHE_OP_DELETE;
71 spin_unlock(&dentry->d_lock);
72 }
73
Khazhismel Kumykov30c6a232019-09-16 16:56:41 -070074 __fuse_dentry_settime(dentry, time);
Miklos Szeredi0a0898c2006-07-30 03:04:10 -070075}
Miklos Szeredi0a0898c2006-07-30 03:04:10 -070076
Miklos Szeredi6f9f1182006-01-06 00:19:39 -080077/*
78 * FUSE caches dentries and attributes with separate timeout. The
79 * time in jiffies until the dentry/attributes are valid is stored in
Miklos Szeredif75fdf22016-10-01 07:32:32 +020080 * dentry->d_fsdata and fuse_inode->i_time respectively.
Miklos Szeredi6f9f1182006-01-06 00:19:39 -080081 */
82
83/*
84 * Calculate the time in jiffies until a dentry/attributes are valid
85 */
Miklos Szeredibcb6f6d2016-10-01 07:32:32 +020086static u64 time_to_jiffies(u64 sec, u32 nsec)
Miklos Szeredie5e55582005-09-09 13:10:28 -070087{
Miklos Szeredi685d16d2006-07-30 03:04:08 -070088 if (sec || nsec) {
Miklos Szeredibcb6f6d2016-10-01 07:32:32 +020089 struct timespec64 ts = {
90 sec,
David Sheets21067522017-01-13 15:58:30 +000091 min_t(u32, nsec, NSEC_PER_SEC - 1)
Miklos Szeredibcb6f6d2016-10-01 07:32:32 +020092 };
93
94 return get_jiffies_64() + timespec64_to_jiffies(&ts);
Miklos Szeredi685d16d2006-07-30 03:04:08 -070095 } else
Miklos Szeredi0a0898c2006-07-30 03:04:10 -070096 return 0;
Miklos Szeredie5e55582005-09-09 13:10:28 -070097}
98
Miklos Szeredi6f9f1182006-01-06 00:19:39 -080099/*
100 * Set dentry and possibly attribute timeouts from the lookup/mk*
101 * replies
102 */
Miklos Szeredid123d8e2018-09-28 16:43:23 +0200103void fuse_change_entry_timeout(struct dentry *entry, struct fuse_entry_out *o)
Miklos Szeredi0aa7c692006-01-06 00:19:34 -0800104{
Miklos Szeredi0a0898c2006-07-30 03:04:10 -0700105 fuse_dentry_settime(entry,
106 time_to_jiffies(o->entry_valid, o->entry_valid_nsec));
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700107}
108
109static u64 attr_timeout(struct fuse_attr_out *o)
110{
111 return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
112}
113
Miklos Szeredid123d8e2018-09-28 16:43:23 +0200114u64 entry_attr_timeout(struct fuse_entry_out *o)
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700115{
116 return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800117}
118
Miklos Szeredi2f1e8192018-10-15 15:43:06 +0200119static void fuse_invalidate_attr_mask(struct inode *inode, u32 mask)
120{
121 set_mask_bits(&get_fuse_inode(inode)->inval_mask, 0, mask);
122}
123
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800124/*
125 * Mark the attributes as stale, so that at the next call to
126 * ->getattr() they will be fetched from userspace
127 */
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800128void fuse_invalidate_attr(struct inode *inode)
129{
Miklos Szeredi2f1e8192018-10-15 15:43:06 +0200130 fuse_invalidate_attr_mask(inode, STATX_BASIC_STATS);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800131}
132
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200133static void fuse_dir_changed(struct inode *dir)
134{
135 fuse_invalidate_attr(dir);
136 inode_maybe_inc_iversion(dir, false);
137}
138
Andrew Gallagher451418f2013-11-05 03:55:43 -0800139/**
140 * Mark the attributes as stale due to an atime change. Avoid the invalidate if
141 * atime is not used.
142 */
143void fuse_invalidate_atime(struct inode *inode)
144{
145 if (!IS_RDONLY(inode))
Miklos Szeredi2f1e8192018-10-15 15:43:06 +0200146 fuse_invalidate_attr_mask(inode, STATX_ATIME);
Andrew Gallagher451418f2013-11-05 03:55:43 -0800147}
148
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800149/*
150 * Just mark the entry as stale, so that a next attempt to look it up
151 * will result in a new lookup call to userspace
152 *
153 * This is called when a dentry is about to become negative and the
154 * timeout is unknown (unlink, rmdir, rename and in some cases
155 * lookup)
156 */
Miklos Szeredidbd561d2008-07-25 01:49:00 -0700157void fuse_invalidate_entry_cache(struct dentry *entry)
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800158{
Miklos Szeredi0a0898c2006-07-30 03:04:10 -0700159 fuse_dentry_settime(entry, 0);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800160}
161
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800162/*
163 * Same as fuse_invalidate_entry_cache(), but also try to remove the
164 * dentry from the hash
165 */
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800166static void fuse_invalidate_entry(struct dentry *entry)
167{
168 d_invalidate(entry);
169 fuse_invalidate_entry_cache(entry);
Miklos Szeredi0aa7c692006-01-06 00:19:34 -0800170}
171
Miklos Szeredi70781872014-12-12 09:49:05 +0100172static void fuse_lookup_init(struct fuse_conn *fc, struct fuse_args *args,
Al Viro13983d02016-07-20 22:34:44 -0400173 u64 nodeid, const struct qstr *name,
Miklos Szeredie5e55582005-09-09 13:10:28 -0700174 struct fuse_entry_out *outarg)
175{
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700176 memset(outarg, 0, sizeof(struct fuse_entry_out));
Miklos Szeredid5b48542019-09-10 15:04:08 +0200177 args->opcode = FUSE_LOOKUP;
178 args->nodeid = nodeid;
179 args->in_numargs = 1;
180 args->in_args[0].size = name->len + 1;
181 args->in_args[0].value = name->name;
182 args->out_numargs = 1;
183 args->out_args[0].size = sizeof(struct fuse_entry_out);
184 args->out_args[0].value = outarg;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700185}
186
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800187/*
188 * Check whether the dentry is still valid
189 *
190 * If the entry validity timeout has expired and the dentry is
191 * positive, try to redo the lookup. If the lookup results in a
192 * different inode, then let the VFS invalidate the dentry and redo
193 * the lookup once more. If the lookup results in the same inode,
194 * then refresh the attributes, timeouts and mark the dentry valid.
195 */
Al Viro0b728e12012-06-10 16:03:43 -0400196static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
Miklos Szeredie5e55582005-09-09 13:10:28 -0700197{
Nick Piggin34286d62011-01-07 17:49:57 +1100198 struct inode *inode;
Miklos Szeredi28420da2013-06-03 14:40:22 +0200199 struct dentry *parent;
Max Reitzfcee2162020-05-06 17:44:12 +0200200 struct fuse_mount *fm;
Miklos Szeredi6314efe2013-10-01 16:41:22 +0200201 struct fuse_inode *fi;
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200202 int ret;
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800203
David Howells2b0143b2015-03-17 22:25:59 +0000204 inode = d_inode_rcu(entry);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800205 if (inode && is_bad_inode(inode))
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200206 goto invalid;
Anand Avati154210c2014-06-26 20:21:57 -0400207 else if (time_before64(fuse_dentry_time(entry), get_jiffies_64()) ||
208 (flags & LOOKUP_REVAL)) {
Miklos Szeredie5e55582005-09-09 13:10:28 -0700209 struct fuse_entry_out outarg;
Miklos Szeredi70781872014-12-12 09:49:05 +0100210 FUSE_ARGS(args);
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100211 struct fuse_forget_link *forget;
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700212 u64 attr_version;
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800213
Miklos Szeredi50322fe2006-02-28 16:59:03 -0800214 /* For negative dentries, always do a fresh lookup */
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800215 if (!inode)
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200216 goto invalid;
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800217
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200218 ret = -ECHILD;
Al Viro0b728e12012-06-10 16:03:43 -0400219 if (flags & LOOKUP_RCU)
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200220 goto out;
Miklos Szeredie7c0a162011-03-21 13:58:06 +0100221
Max Reitzfcee2162020-05-06 17:44:12 +0200222 fm = get_fuse_mount(inode);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700223
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100224 forget = fuse_alloc_forget();
Miklos Szeredi70781872014-12-12 09:49:05 +0100225 ret = -ENOMEM;
226 if (!forget)
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200227 goto out;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800228
Max Reitzfcee2162020-05-06 17:44:12 +0200229 attr_version = fuse_get_attr_version(fm->fc);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700230
Miklos Szeredie956edd2006-10-17 00:10:12 -0700231 parent = dget_parent(entry);
Max Reitzfcee2162020-05-06 17:44:12 +0200232 fuse_lookup_init(fm->fc, &args, get_node_id(d_inode(parent)),
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700233 &entry->d_name, &outarg);
Max Reitzfcee2162020-05-06 17:44:12 +0200234 ret = fuse_simple_request(fm, &args);
Miklos Szeredie956edd2006-10-17 00:10:12 -0700235 dput(parent);
Miklos Szeredi50322fe2006-02-28 16:59:03 -0800236 /* Zero nodeid is same as -ENOENT */
Miklos Szeredi70781872014-12-12 09:49:05 +0100237 if (!ret && !outarg.nodeid)
238 ret = -ENOENT;
239 if (!ret) {
Miklos Szeredi6314efe2013-10-01 16:41:22 +0200240 fi = get_fuse_inode(inode);
Max Reitzbf109c62020-04-21 14:47:15 +0200241 if (outarg.nodeid != get_node_id(inode) ||
242 (bool) IS_AUTOMOUNT(inode) != (bool) (outarg.attr.flags & FUSE_ATTR_SUBMOUNT)) {
Max Reitzfcee2162020-05-06 17:44:12 +0200243 fuse_queue_forget(fm->fc, forget,
244 outarg.nodeid, 1);
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200245 goto invalid;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700246 }
Kirill Tkhaic9d8f5f2018-11-09 13:33:27 +0300247 spin_lock(&fi->lock);
Miklos Szeredi1729a162008-11-26 12:03:54 +0100248 fi->nlookup++;
Kirill Tkhaic9d8f5f2018-11-09 13:33:27 +0300249 spin_unlock(&fi->lock);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700250 }
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100251 kfree(forget);
Miklos Szeredi70781872014-12-12 09:49:05 +0100252 if (ret == -ENOMEM)
253 goto out;
Miklos Szeredieb59bd12019-11-12 11:49:04 +0100254 if (ret || fuse_invalid_attr(&outarg.attr) ||
255 (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200256 goto invalid;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700257
Seth Forshee60bcc882016-08-29 08:46:37 -0500258 forget_all_cached_acls(inode);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700259 fuse_change_attributes(inode, &outarg.attr,
260 entry_attr_timeout(&outarg),
261 attr_version);
262 fuse_change_entry_timeout(entry, &outarg);
Miklos Szeredi28420da2013-06-03 14:40:22 +0200263 } else if (inode) {
Miklos Szeredi6314efe2013-10-01 16:41:22 +0200264 fi = get_fuse_inode(inode);
265 if (flags & LOOKUP_RCU) {
266 if (test_bit(FUSE_I_INIT_RDPLUS, &fi->state))
267 return -ECHILD;
268 } else if (test_and_clear_bit(FUSE_I_INIT_RDPLUS, &fi->state)) {
Miklos Szeredi28420da2013-06-03 14:40:22 +0200269 parent = dget_parent(entry);
David Howells2b0143b2015-03-17 22:25:59 +0000270 fuse_advise_use_readdirplus(d_inode(parent));
Miklos Szeredi28420da2013-06-03 14:40:22 +0200271 dput(parent);
272 }
Miklos Szeredie5e55582005-09-09 13:10:28 -0700273 }
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200274 ret = 1;
275out:
276 return ret;
277
278invalid:
279 ret = 0;
280 goto out;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700281}
282
Khazhismel Kumykov30c6a232019-09-16 16:56:41 -0700283#if BITS_PER_LONG < 64
Miklos Szeredif75fdf22016-10-01 07:32:32 +0200284static int fuse_dentry_init(struct dentry *dentry)
285{
Khazhismel Kumykovdc69e982019-09-17 12:35:33 -0700286 dentry->d_fsdata = kzalloc(sizeof(union fuse_dentry),
287 GFP_KERNEL_ACCOUNT | __GFP_RECLAIMABLE);
Miklos Szeredif75fdf22016-10-01 07:32:32 +0200288
289 return dentry->d_fsdata ? 0 : -ENOMEM;
290}
291static void fuse_dentry_release(struct dentry *dentry)
292{
293 union fuse_dentry *fd = dentry->d_fsdata;
294
295 kfree_rcu(fd, rcu);
296}
Khazhismel Kumykov30c6a232019-09-16 16:56:41 -0700297#endif
Miklos Szeredif75fdf22016-10-01 07:32:32 +0200298
Miklos Szeredi8fab0102018-08-15 17:42:34 +0200299static int fuse_dentry_delete(const struct dentry *dentry)
300{
301 return time_before64(fuse_dentry_time(dentry), get_jiffies_64());
302}
303
Max Reitzbf109c62020-04-21 14:47:15 +0200304/*
305 * Create a fuse_mount object with a new superblock (with path->dentry
306 * as the root), and return that mount so it can be auto-mounted on
307 * @path.
308 */
309static struct vfsmount *fuse_dentry_automount(struct path *path)
310{
311 struct fs_context *fsc;
312 struct fuse_mount *parent_fm = get_fuse_mount_super(path->mnt->mnt_sb);
313 struct fuse_conn *fc = parent_fm->fc;
314 struct fuse_mount *fm;
315 struct vfsmount *mnt;
316 struct fuse_inode *mp_fi = get_fuse_inode(d_inode(path->dentry));
317 struct super_block *sb;
318 int err;
319
320 fsc = fs_context_for_submount(path->mnt->mnt_sb->s_type, path->dentry);
321 if (IS_ERR(fsc)) {
322 err = PTR_ERR(fsc);
323 goto out;
324 }
325
326 err = -ENOMEM;
327 fm = kzalloc(sizeof(struct fuse_mount), GFP_KERNEL);
328 if (!fm)
329 goto out_put_fsc;
330
331 refcount_set(&fm->count, 1);
332 fsc->s_fs_info = fm;
333 sb = sget_fc(fsc, NULL, set_anon_super_fc);
334 if (IS_ERR(sb)) {
335 err = PTR_ERR(sb);
336 fuse_mount_put(fm);
337 goto out_put_fsc;
338 }
339 fm->fc = fuse_conn_get(fc);
340
341 /* Initialize superblock, making @mp_fi its root */
342 err = fuse_fill_super_submount(sb, mp_fi);
343 if (err)
344 goto out_put_sb;
345
346 sb->s_flags |= SB_ACTIVE;
347 fsc->root = dget(sb->s_root);
348 /* We are done configuring the superblock, so unlock it */
349 up_write(&sb->s_umount);
350
351 down_write(&fc->killsb);
352 list_add_tail(&fm->fc_entry, &fc->mounts);
353 up_write(&fc->killsb);
354
355 /* Create the submount */
356 mnt = vfs_create_mount(fsc);
357 if (IS_ERR(mnt)) {
358 err = PTR_ERR(mnt);
359 goto out_put_fsc;
360 }
361 mntget(mnt);
362 put_fs_context(fsc);
363 return mnt;
364
365out_put_sb:
366 /*
367 * Only jump here when fsc->root is NULL and sb is still locked
368 * (otherwise put_fs_context() will put the superblock)
369 */
370 deactivate_locked_super(sb);
371out_put_fsc:
372 put_fs_context(fsc);
373out:
374 return ERR_PTR(err);
375}
376
Al Viro42695902009-02-20 05:59:13 +0000377const struct dentry_operations fuse_dentry_operations = {
Miklos Szeredie5e55582005-09-09 13:10:28 -0700378 .d_revalidate = fuse_dentry_revalidate,
Miklos Szeredi8fab0102018-08-15 17:42:34 +0200379 .d_delete = fuse_dentry_delete,
Khazhismel Kumykov30c6a232019-09-16 16:56:41 -0700380#if BITS_PER_LONG < 64
Miklos Szeredif75fdf22016-10-01 07:32:32 +0200381 .d_init = fuse_dentry_init,
382 .d_release = fuse_dentry_release,
Khazhismel Kumykov30c6a232019-09-16 16:56:41 -0700383#endif
Max Reitzbf109c62020-04-21 14:47:15 +0200384 .d_automount = fuse_dentry_automount,
Miklos Szeredie5e55582005-09-09 13:10:28 -0700385};
386
Miklos Szeredi0ce267f2016-10-18 15:36:48 +0200387const struct dentry_operations fuse_root_dentry_operations = {
Khazhismel Kumykov30c6a232019-09-16 16:56:41 -0700388#if BITS_PER_LONG < 64
Miklos Szeredi0ce267f2016-10-18 15:36:48 +0200389 .d_init = fuse_dentry_init,
390 .d_release = fuse_dentry_release,
Khazhismel Kumykov30c6a232019-09-16 16:56:41 -0700391#endif
Miklos Szeredi0ce267f2016-10-18 15:36:48 +0200392};
393
Timo Savolaa5bfffac2007-04-08 16:04:00 -0700394int fuse_valid_type(int m)
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800395{
396 return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) ||
397 S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
398}
399
Miklos Szeredieb59bd12019-11-12 11:49:04 +0100400bool fuse_invalid_attr(struct fuse_attr *attr)
401{
402 return !fuse_valid_type(attr->mode) ||
403 attr->size > LLONG_MAX;
404}
405
Al Viro13983d02016-07-20 22:34:44 -0400406int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name,
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700407 struct fuse_entry_out *outarg, struct inode **inode)
408{
Max Reitzfcee2162020-05-06 17:44:12 +0200409 struct fuse_mount *fm = get_fuse_mount_super(sb);
Miklos Szeredi70781872014-12-12 09:49:05 +0100410 FUSE_ARGS(args);
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100411 struct fuse_forget_link *forget;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700412 u64 attr_version;
413 int err;
414
415 *inode = NULL;
416 err = -ENAMETOOLONG;
417 if (name->len > FUSE_NAME_MAX)
418 goto out;
419
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700420
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100421 forget = fuse_alloc_forget();
422 err = -ENOMEM;
Miklos Szeredi70781872014-12-12 09:49:05 +0100423 if (!forget)
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700424 goto out;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700425
Max Reitzfcee2162020-05-06 17:44:12 +0200426 attr_version = fuse_get_attr_version(fm->fc);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700427
Max Reitzfcee2162020-05-06 17:44:12 +0200428 fuse_lookup_init(fm->fc, &args, nodeid, name, outarg);
429 err = fuse_simple_request(fm, &args);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700430 /* Zero nodeid is same as -ENOENT, but with valid timeout */
431 if (err || !outarg->nodeid)
432 goto out_put_forget;
433
434 err = -EIO;
435 if (!outarg->nodeid)
436 goto out_put_forget;
Miklos Szeredieb59bd12019-11-12 11:49:04 +0100437 if (fuse_invalid_attr(&outarg->attr))
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700438 goto out_put_forget;
439
440 *inode = fuse_iget(sb, outarg->nodeid, outarg->generation,
441 &outarg->attr, entry_attr_timeout(outarg),
442 attr_version);
443 err = -ENOMEM;
444 if (!*inode) {
Max Reitzfcee2162020-05-06 17:44:12 +0200445 fuse_queue_forget(fm->fc, forget, outarg->nodeid, 1);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700446 goto out;
447 }
448 err = 0;
449
450 out_put_forget:
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100451 kfree(forget);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700452 out:
453 return err;
454}
455
Miklos Szeredi0aa7c692006-01-06 00:19:34 -0800456static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
Al Viro00cd8dd2012-06-10 17:13:09 -0400457 unsigned int flags)
Miklos Szeredie5e55582005-09-09 13:10:28 -0700458{
459 int err;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700460 struct fuse_entry_out outarg;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700461 struct inode *inode;
Miklos Szeredi0de62562008-07-25 01:48:59 -0700462 struct dentry *newent;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700463 bool outarg_valid = true;
Miklos Szeredi63576c12018-07-26 16:13:11 +0200464 bool locked;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700465
Miklos Szeredi63576c12018-07-26 16:13:11 +0200466 locked = fuse_lock_inode(dir);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700467 err = fuse_lookup_name(dir->i_sb, get_node_id(dir), &entry->d_name,
468 &outarg, &inode);
Miklos Szeredi63576c12018-07-26 16:13:11 +0200469 fuse_unlock_inode(dir, locked);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700470 if (err == -ENOENT) {
471 outarg_valid = false;
472 err = 0;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800473 }
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700474 if (err)
475 goto out_err;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800476
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700477 err = -EIO;
478 if (inode && get_node_id(inode) == FUSE_ROOT_ID)
479 goto out_iput;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700480
Al Viro41d28bc2014-10-12 22:24:21 -0400481 newent = d_splice_alias(inode, entry);
Miklos Szeredi5835f332013-09-05 11:44:42 +0200482 err = PTR_ERR(newent);
483 if (IS_ERR(newent))
484 goto out_err;
Miklos Szeredid2a85162006-10-17 00:10:11 -0700485
Miklos Szeredi0de62562008-07-25 01:48:59 -0700486 entry = newent ? newent : entry;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700487 if (outarg_valid)
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700488 fuse_change_entry_timeout(entry, &outarg);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800489 else
490 fuse_invalidate_entry_cache(entry);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700491
Miklos Szeredi6c26f712019-10-21 15:57:07 +0200492 if (inode)
493 fuse_advise_use_readdirplus(dir);
Miklos Szeredi0de62562008-07-25 01:48:59 -0700494 return newent;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700495
496 out_iput:
497 iput(inode);
498 out_err:
499 return ERR_PTR(err);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700500}
501
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800502/*
503 * Atomic create+open operation
504 *
505 * If the filesystem doesn't support this, then fall back to separate
506 * 'mknod' + 'open' requests.
507 */
Al Virod9585272012-06-22 12:39:14 +0400508static int fuse_create_open(struct inode *dir, struct dentry *entry,
Al Viro30d90492012-06-22 12:40:19 +0400509 struct file *file, unsigned flags,
Al Virob452a452018-06-08 13:06:28 -0400510 umode_t mode)
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800511{
512 int err;
513 struct inode *inode;
Max Reitzfcee2162020-05-06 17:44:12 +0200514 struct fuse_mount *fm = get_fuse_mount(dir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100515 FUSE_ARGS(args);
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100516 struct fuse_forget_link *forget;
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200517 struct fuse_create_in inarg;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800518 struct fuse_open_out outopen;
519 struct fuse_entry_out outentry;
Kirill Tkhaiebf84d02018-11-09 13:33:11 +0300520 struct fuse_inode *fi;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800521 struct fuse_file *ff;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800522
Miklos Szerediaf109bc2012-08-15 13:01:24 +0200523 /* Userspace expects S_IFREG in create mode */
524 BUG_ON((mode & S_IFMT) != S_IFREG);
525
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100526 forget = fuse_alloc_forget();
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200527 err = -ENOMEM;
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100528 if (!forget)
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200529 goto out_err;
Miklos Szeredi51eb01e2006-06-25 05:48:50 -0700530
Miklos Szeredice1d5a42006-04-10 22:54:58 -0700531 err = -ENOMEM;
Max Reitzfcee2162020-05-06 17:44:12 +0200532 ff = fuse_file_alloc(fm);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800533 if (!ff)
Miklos Szeredi70781872014-12-12 09:49:05 +0100534 goto out_put_forget_req;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800535
Max Reitzfcee2162020-05-06 17:44:12 +0200536 if (!fm->fc->dont_mask)
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200537 mode &= ~current_umask();
538
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800539 flags &= ~O_NOCTTY;
540 memset(&inarg, 0, sizeof(inarg));
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700541 memset(&outentry, 0, sizeof(outentry));
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800542 inarg.flags = flags;
543 inarg.mode = mode;
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200544 inarg.umask = current_umask();
Miklos Szeredid5b48542019-09-10 15:04:08 +0200545 args.opcode = FUSE_CREATE;
546 args.nodeid = get_node_id(dir);
547 args.in_numargs = 2;
548 args.in_args[0].size = sizeof(inarg);
549 args.in_args[0].value = &inarg;
550 args.in_args[1].size = entry->d_name.len + 1;
551 args.in_args[1].value = entry->d_name.name;
552 args.out_numargs = 2;
553 args.out_args[0].size = sizeof(outentry);
554 args.out_args[0].value = &outentry;
555 args.out_args[1].size = sizeof(outopen);
556 args.out_args[1].value = &outopen;
Max Reitzfcee2162020-05-06 17:44:12 +0200557 err = fuse_simple_request(fm, &args);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200558 if (err)
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800559 goto out_free_ff;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800560
561 err = -EIO;
Miklos Szeredieb59bd12019-11-12 11:49:04 +0100562 if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid) ||
563 fuse_invalid_attr(&outentry.attr))
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800564 goto out_free_ff;
565
Miklos Szeredic7b71432009-04-28 16:56:37 +0200566 ff->fh = outopen.fh;
567 ff->nodeid = outentry.nodeid;
568 ff->open_flags = outopen.open_flags;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800569 inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700570 &outentry.attr, entry_attr_timeout(&outentry), 0);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800571 if (!inode) {
572 flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
Kirill Tkhaiebf84d02018-11-09 13:33:11 +0300573 fuse_sync_release(NULL, ff, flags);
Max Reitzfcee2162020-05-06 17:44:12 +0200574 fuse_queue_forget(fm->fc, forget, outentry.nodeid, 1);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200575 err = -ENOMEM;
576 goto out_err;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800577 }
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100578 kfree(forget);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800579 d_instantiate(entry, inode);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700580 fuse_change_entry_timeout(entry, &outentry);
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200581 fuse_dir_changed(dir);
Al Virobe12af32018-06-08 11:44:56 -0400582 err = finish_open(file, entry, generic_file_open);
Al Viro30d90492012-06-22 12:40:19 +0400583 if (err) {
Kirill Tkhaiebf84d02018-11-09 13:33:11 +0300584 fi = get_fuse_inode(inode);
585 fuse_sync_release(fi, ff, flags);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200586 } else {
Miklos Szeredi267d8442017-02-22 20:08:25 +0100587 file->private_data = ff;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200588 fuse_finish_open(inode, file);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800589 }
Al Virod9585272012-06-22 12:39:14 +0400590 return err;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800591
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200592out_free_ff:
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800593 fuse_file_free(ff);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200594out_put_forget_req:
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100595 kfree(forget);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200596out_err:
Al Virod9585272012-06-22 12:39:14 +0400597 return err;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200598}
599
600static int fuse_mknod(struct inode *, struct dentry *, umode_t, dev_t);
Al Virod9585272012-06-22 12:39:14 +0400601static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
Al Viro30d90492012-06-22 12:40:19 +0400602 struct file *file, unsigned flags,
Al Viro44907d72018-06-08 13:32:02 -0400603 umode_t mode)
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200604{
605 int err;
606 struct fuse_conn *fc = get_fuse_conn(dir);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200607 struct dentry *res = NULL;
608
Al Viro00699ad2016-07-05 09:44:53 -0400609 if (d_in_lookup(entry)) {
Al Viro00cd8dd2012-06-10 17:13:09 -0400610 res = fuse_lookup(dir, entry, 0);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200611 if (IS_ERR(res))
Al Virod9585272012-06-22 12:39:14 +0400612 return PTR_ERR(res);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200613
614 if (res)
615 entry = res;
616 }
617
David Howells2b0143b2015-03-17 22:25:59 +0000618 if (!(flags & O_CREAT) || d_really_is_positive(entry))
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200619 goto no_open;
620
621 /* Only creates */
Al Viro73a09dd2018-06-08 13:22:02 -0400622 file->f_mode |= FMODE_CREATED;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200623
624 if (fc->no_create)
625 goto mknod;
626
Al Virob452a452018-06-08 13:06:28 -0400627 err = fuse_create_open(dir, entry, file, flags, mode);
Al Virod9585272012-06-22 12:39:14 +0400628 if (err == -ENOSYS) {
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200629 fc->no_create = 1;
630 goto mknod;
631 }
632out_dput:
633 dput(res);
Al Virod9585272012-06-22 12:39:14 +0400634 return err;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200635
636mknod:
637 err = fuse_mknod(dir, entry, mode, 0);
Al Virod9585272012-06-22 12:39:14 +0400638 if (err)
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200639 goto out_dput;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200640no_open:
Al Viroe45198a2012-06-10 06:48:09 -0400641 return finish_no_open(file, res);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800642}
643
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800644/*
645 * Code shared between mknod, mkdir, symlink and link
646 */
Max Reitzfcee2162020-05-06 17:44:12 +0200647static int create_new_entry(struct fuse_mount *fm, struct fuse_args *args,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700648 struct inode *dir, struct dentry *entry,
Al Viro541af6a2011-07-26 03:17:33 -0400649 umode_t mode)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700650{
651 struct fuse_entry_out outarg;
652 struct inode *inode;
Al Viroc971e6a2018-05-28 18:27:19 -0400653 struct dentry *d;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700654 int err;
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100655 struct fuse_forget_link *forget;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800656
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100657 forget = fuse_alloc_forget();
Miklos Szeredi70781872014-12-12 09:49:05 +0100658 if (!forget)
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100659 return -ENOMEM;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700660
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700661 memset(&outarg, 0, sizeof(outarg));
Miklos Szeredid5b48542019-09-10 15:04:08 +0200662 args->nodeid = get_node_id(dir);
663 args->out_numargs = 1;
664 args->out_args[0].size = sizeof(outarg);
665 args->out_args[0].value = &outarg;
Max Reitzfcee2162020-05-06 17:44:12 +0200666 err = fuse_simple_request(fm, args);
Miklos Szeredi2d510132006-11-25 11:09:20 -0800667 if (err)
668 goto out_put_forget_req;
669
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800670 err = -EIO;
Miklos Szeredieb59bd12019-11-12 11:49:04 +0100671 if (invalid_nodeid(outarg.nodeid) || fuse_invalid_attr(&outarg.attr))
Miklos Szeredi2d510132006-11-25 11:09:20 -0800672 goto out_put_forget_req;
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800673
674 if ((outarg.attr.mode ^ mode) & S_IFMT)
Miklos Szeredi2d510132006-11-25 11:09:20 -0800675 goto out_put_forget_req;
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800676
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700677 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700678 &outarg.attr, entry_attr_timeout(&outarg), 0);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700679 if (!inode) {
Max Reitzfcee2162020-05-06 17:44:12 +0200680 fuse_queue_forget(fm->fc, forget, outarg.nodeid, 1);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700681 return -ENOMEM;
682 }
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100683 kfree(forget);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700684
Al Viroc971e6a2018-05-28 18:27:19 -0400685 d_drop(entry);
686 d = d_splice_alias(inode, entry);
687 if (IS_ERR(d))
688 return PTR_ERR(d);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700689
Al Viroc971e6a2018-05-28 18:27:19 -0400690 if (d) {
691 fuse_change_entry_timeout(d, &outarg);
692 dput(d);
693 } else {
694 fuse_change_entry_timeout(entry, &outarg);
695 }
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200696 fuse_dir_changed(dir);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700697 return 0;
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800698
Miklos Szeredi2d510132006-11-25 11:09:20 -0800699 out_put_forget_req:
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100700 kfree(forget);
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800701 return err;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700702}
703
Al Viro1a67aaf2011-07-26 01:52:52 -0400704static int fuse_mknod(struct inode *dir, struct dentry *entry, umode_t mode,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700705 dev_t rdev)
706{
707 struct fuse_mknod_in inarg;
Max Reitzfcee2162020-05-06 17:44:12 +0200708 struct fuse_mount *fm = get_fuse_mount(dir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100709 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700710
Max Reitzfcee2162020-05-06 17:44:12 +0200711 if (!fm->fc->dont_mask)
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200712 mode &= ~current_umask();
713
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700714 memset(&inarg, 0, sizeof(inarg));
715 inarg.mode = mode;
716 inarg.rdev = new_encode_dev(rdev);
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200717 inarg.umask = current_umask();
Miklos Szeredid5b48542019-09-10 15:04:08 +0200718 args.opcode = FUSE_MKNOD;
719 args.in_numargs = 2;
720 args.in_args[0].size = sizeof(inarg);
721 args.in_args[0].value = &inarg;
722 args.in_args[1].size = entry->d_name.len + 1;
723 args.in_args[1].value = entry->d_name.name;
Max Reitzfcee2162020-05-06 17:44:12 +0200724 return create_new_entry(fm, &args, dir, entry, mode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700725}
726
Al Viro4acdaf22011-07-26 01:42:34 -0400727static int fuse_create(struct inode *dir, struct dentry *entry, umode_t mode,
Al Viroebfc3b42012-06-10 18:05:36 -0400728 bool excl)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700729{
730 return fuse_mknod(dir, entry, mode, 0);
731}
732
Al Viro18bb1db2011-07-26 01:41:39 -0400733static int fuse_mkdir(struct inode *dir, struct dentry *entry, umode_t mode)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700734{
735 struct fuse_mkdir_in inarg;
Max Reitzfcee2162020-05-06 17:44:12 +0200736 struct fuse_mount *fm = get_fuse_mount(dir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100737 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700738
Max Reitzfcee2162020-05-06 17:44:12 +0200739 if (!fm->fc->dont_mask)
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200740 mode &= ~current_umask();
741
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700742 memset(&inarg, 0, sizeof(inarg));
743 inarg.mode = mode;
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200744 inarg.umask = current_umask();
Miklos Szeredid5b48542019-09-10 15:04:08 +0200745 args.opcode = FUSE_MKDIR;
746 args.in_numargs = 2;
747 args.in_args[0].size = sizeof(inarg);
748 args.in_args[0].value = &inarg;
749 args.in_args[1].size = entry->d_name.len + 1;
750 args.in_args[1].value = entry->d_name.name;
Max Reitzfcee2162020-05-06 17:44:12 +0200751 return create_new_entry(fm, &args, dir, entry, S_IFDIR);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700752}
753
754static int fuse_symlink(struct inode *dir, struct dentry *entry,
755 const char *link)
756{
Max Reitzfcee2162020-05-06 17:44:12 +0200757 struct fuse_mount *fm = get_fuse_mount(dir);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700758 unsigned len = strlen(link) + 1;
Miklos Szeredi70781872014-12-12 09:49:05 +0100759 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700760
Miklos Szeredid5b48542019-09-10 15:04:08 +0200761 args.opcode = FUSE_SYMLINK;
762 args.in_numargs = 2;
763 args.in_args[0].size = entry->d_name.len + 1;
764 args.in_args[0].value = entry->d_name.name;
765 args.in_args[1].size = len;
766 args.in_args[1].value = link;
Max Reitzfcee2162020-05-06 17:44:12 +0200767 return create_new_entry(fm, &args, dir, entry, S_IFLNK);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700768}
769
Seth Forshee703c7362016-08-29 08:46:36 -0500770void fuse_update_ctime(struct inode *inode)
Maxim Patlasov31f32672014-04-28 14:19:24 +0200771{
772 if (!IS_NOCMTIME(inode)) {
Deepa Dinamanic2050a42016-09-14 07:48:06 -0700773 inode->i_ctime = current_time(inode);
Maxim Patlasov31f32672014-04-28 14:19:24 +0200774 mark_inode_dirty_sync(inode);
775 }
776}
777
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700778static int fuse_unlink(struct inode *dir, struct dentry *entry)
779{
780 int err;
Max Reitzfcee2162020-05-06 17:44:12 +0200781 struct fuse_mount *fm = get_fuse_mount(dir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100782 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700783
Miklos Szeredid5b48542019-09-10 15:04:08 +0200784 args.opcode = FUSE_UNLINK;
785 args.nodeid = get_node_id(dir);
786 args.in_numargs = 1;
787 args.in_args[0].size = entry->d_name.len + 1;
788 args.in_args[0].value = entry->d_name.name;
Max Reitzfcee2162020-05-06 17:44:12 +0200789 err = fuse_simple_request(fm, &args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700790 if (!err) {
David Howells2b0143b2015-03-17 22:25:59 +0000791 struct inode *inode = d_inode(entry);
Miklos Szerediac45d612012-03-05 15:48:11 +0100792 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700793
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +0300794 spin_lock(&fi->lock);
Max Reitzfcee2162020-05-06 17:44:12 +0200795 fi->attr_version = atomic64_inc_return(&fm->fc->attr_version);
Miklos Szeredidfca7ce2013-02-04 15:57:42 +0100796 /*
797 * If i_nlink == 0 then unlink doesn't make sense, yet this can
798 * happen if userspace filesystem is careless. It would be
799 * difficult to enforce correct nlink usage so just ignore this
800 * condition here
801 */
802 if (inode->i_nlink > 0)
803 drop_nlink(inode);
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +0300804 spin_unlock(&fi->lock);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700805 fuse_invalidate_attr(inode);
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200806 fuse_dir_changed(dir);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800807 fuse_invalidate_entry_cache(entry);
Maxim Patlasov31f32672014-04-28 14:19:24 +0200808 fuse_update_ctime(inode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700809 } else if (err == -EINTR)
810 fuse_invalidate_entry(entry);
811 return err;
812}
813
814static int fuse_rmdir(struct inode *dir, struct dentry *entry)
815{
816 int err;
Max Reitzfcee2162020-05-06 17:44:12 +0200817 struct fuse_mount *fm = get_fuse_mount(dir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100818 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700819
Miklos Szeredid5b48542019-09-10 15:04:08 +0200820 args.opcode = FUSE_RMDIR;
821 args.nodeid = get_node_id(dir);
822 args.in_numargs = 1;
823 args.in_args[0].size = entry->d_name.len + 1;
824 args.in_args[0].value = entry->d_name.name;
Max Reitzfcee2162020-05-06 17:44:12 +0200825 err = fuse_simple_request(fm, &args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700826 if (!err) {
David Howells2b0143b2015-03-17 22:25:59 +0000827 clear_nlink(d_inode(entry));
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200828 fuse_dir_changed(dir);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800829 fuse_invalidate_entry_cache(entry);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700830 } else if (err == -EINTR)
831 fuse_invalidate_entry(entry);
832 return err;
833}
834
Miklos Szeredi1560c972014-04-28 16:43:44 +0200835static int fuse_rename_common(struct inode *olddir, struct dentry *oldent,
836 struct inode *newdir, struct dentry *newent,
837 unsigned int flags, int opcode, size_t argsize)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700838{
839 int err;
Miklos Szeredi1560c972014-04-28 16:43:44 +0200840 struct fuse_rename2_in inarg;
Max Reitzfcee2162020-05-06 17:44:12 +0200841 struct fuse_mount *fm = get_fuse_mount(olddir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100842 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700843
Miklos Szeredi1560c972014-04-28 16:43:44 +0200844 memset(&inarg, 0, argsize);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700845 inarg.newdir = get_node_id(newdir);
Miklos Szeredi1560c972014-04-28 16:43:44 +0200846 inarg.flags = flags;
Miklos Szeredid5b48542019-09-10 15:04:08 +0200847 args.opcode = opcode;
848 args.nodeid = get_node_id(olddir);
849 args.in_numargs = 3;
850 args.in_args[0].size = argsize;
851 args.in_args[0].value = &inarg;
852 args.in_args[1].size = oldent->d_name.len + 1;
853 args.in_args[1].value = oldent->d_name.name;
854 args.in_args[2].size = newent->d_name.len + 1;
855 args.in_args[2].value = newent->d_name.name;
Max Reitzfcee2162020-05-06 17:44:12 +0200856 err = fuse_simple_request(fm, &args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700857 if (!err) {
Miklos Szeredi08b63302007-11-28 16:22:03 -0800858 /* ctime changes */
David Howells2b0143b2015-03-17 22:25:59 +0000859 fuse_invalidate_attr(d_inode(oldent));
860 fuse_update_ctime(d_inode(oldent));
Miklos Szeredi08b63302007-11-28 16:22:03 -0800861
Miklos Szeredi1560c972014-04-28 16:43:44 +0200862 if (flags & RENAME_EXCHANGE) {
David Howells2b0143b2015-03-17 22:25:59 +0000863 fuse_invalidate_attr(d_inode(newent));
864 fuse_update_ctime(d_inode(newent));
Miklos Szeredi1560c972014-04-28 16:43:44 +0200865 }
866
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200867 fuse_dir_changed(olddir);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700868 if (olddir != newdir)
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200869 fuse_dir_changed(newdir);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800870
871 /* newent will end up negative */
David Howells2b0143b2015-03-17 22:25:59 +0000872 if (!(flags & RENAME_EXCHANGE) && d_really_is_positive(newent)) {
873 fuse_invalidate_attr(d_inode(newent));
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800874 fuse_invalidate_entry_cache(newent);
David Howells2b0143b2015-03-17 22:25:59 +0000875 fuse_update_ctime(d_inode(newent));
Miklos Szeredi5219f342009-11-04 10:24:52 +0100876 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700877 } else if (err == -EINTR) {
878 /* If request was interrupted, DEITY only knows if the
879 rename actually took place. If the invalidation
880 fails (e.g. some process has CWD under the renamed
881 directory), then there can be inconsistency between
882 the dcache and the real filesystem. Tough luck. */
883 fuse_invalidate_entry(oldent);
David Howells2b0143b2015-03-17 22:25:59 +0000884 if (d_really_is_positive(newent))
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700885 fuse_invalidate_entry(newent);
886 }
887
888 return err;
889}
890
Miklos Szeredi1560c972014-04-28 16:43:44 +0200891static int fuse_rename2(struct inode *olddir, struct dentry *oldent,
892 struct inode *newdir, struct dentry *newent,
893 unsigned int flags)
894{
895 struct fuse_conn *fc = get_fuse_conn(olddir);
896 int err;
897
Vivek Goyal519525f2020-02-05 08:15:46 -0500898 if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT))
Miklos Szeredi1560c972014-04-28 16:43:44 +0200899 return -EINVAL;
900
Miklos Szeredi4237ba42014-07-10 10:50:19 +0200901 if (flags) {
902 if (fc->no_rename2 || fc->minor < 23)
903 return -EINVAL;
Miklos Szeredi1560c972014-04-28 16:43:44 +0200904
Miklos Szeredi4237ba42014-07-10 10:50:19 +0200905 err = fuse_rename_common(olddir, oldent, newdir, newent, flags,
906 FUSE_RENAME2,
907 sizeof(struct fuse_rename2_in));
908 if (err == -ENOSYS) {
909 fc->no_rename2 = 1;
910 err = -EINVAL;
911 }
912 } else {
913 err = fuse_rename_common(olddir, oldent, newdir, newent, 0,
914 FUSE_RENAME,
915 sizeof(struct fuse_rename_in));
Miklos Szeredi1560c972014-04-28 16:43:44 +0200916 }
Miklos Szeredi1560c972014-04-28 16:43:44 +0200917
Miklos Szeredi4237ba42014-07-10 10:50:19 +0200918 return err;
919}
920
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700921static int fuse_link(struct dentry *entry, struct inode *newdir,
922 struct dentry *newent)
923{
924 int err;
925 struct fuse_link_in inarg;
David Howells2b0143b2015-03-17 22:25:59 +0000926 struct inode *inode = d_inode(entry);
Max Reitzfcee2162020-05-06 17:44:12 +0200927 struct fuse_mount *fm = get_fuse_mount(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +0100928 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700929
930 memset(&inarg, 0, sizeof(inarg));
931 inarg.oldnodeid = get_node_id(inode);
Miklos Szeredid5b48542019-09-10 15:04:08 +0200932 args.opcode = FUSE_LINK;
933 args.in_numargs = 2;
934 args.in_args[0].size = sizeof(inarg);
935 args.in_args[0].value = &inarg;
936 args.in_args[1].size = newent->d_name.len + 1;
937 args.in_args[1].value = newent->d_name.name;
Max Reitzfcee2162020-05-06 17:44:12 +0200938 err = create_new_entry(fm, &args, newdir, newent, inode->i_mode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700939 /* Contrary to "normal" filesystems it can happen that link
940 makes two "logical" inodes point to the same "physical"
941 inode. We invalidate the attributes of the old one, so it
942 will reflect changes in the backing inode (link count,
943 etc.)
944 */
Miklos Szerediac45d612012-03-05 15:48:11 +0100945 if (!err) {
946 struct fuse_inode *fi = get_fuse_inode(inode);
947
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +0300948 spin_lock(&fi->lock);
Max Reitzfcee2162020-05-06 17:44:12 +0200949 fi->attr_version = atomic64_inc_return(&fm->fc->attr_version);
Miklos Szeredic634da72019-11-12 11:49:04 +0100950 if (likely(inode->i_nlink < UINT_MAX))
951 inc_nlink(inode);
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +0300952 spin_unlock(&fi->lock);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700953 fuse_invalidate_attr(inode);
Maxim Patlasov31f32672014-04-28 14:19:24 +0200954 fuse_update_ctime(inode);
Miklos Szerediac45d612012-03-05 15:48:11 +0100955 } else if (err == -EINTR) {
956 fuse_invalidate_attr(inode);
957 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700958 return err;
959}
960
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700961static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
962 struct kstat *stat)
963{
Miklos Szeredi203627b2012-05-10 19:49:38 +0400964 unsigned int blkbits;
Pavel Emelyanov83732002013-10-10 17:10:46 +0400965 struct fuse_conn *fc = get_fuse_conn(inode);
966
967 /* see the comment in fuse_change_attributes() */
Maxim Patlasovb0aa7602013-12-26 19:51:11 +0400968 if (fc->writeback_cache && S_ISREG(inode->i_mode)) {
Pavel Emelyanov83732002013-10-10 17:10:46 +0400969 attr->size = i_size_read(inode);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +0400970 attr->mtime = inode->i_mtime.tv_sec;
971 attr->mtimensec = inode->i_mtime.tv_nsec;
Maxim Patlasov31f32672014-04-28 14:19:24 +0200972 attr->ctime = inode->i_ctime.tv_sec;
973 attr->ctimensec = inode->i_ctime.tv_nsec;
Maxim Patlasovb0aa7602013-12-26 19:51:11 +0400974 }
Miklos Szeredi203627b2012-05-10 19:49:38 +0400975
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700976 stat->dev = inode->i_sb->s_dev;
977 stat->ino = attr->ino;
978 stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
979 stat->nlink = attr->nlink;
Eric W. Biederman8cb08322018-02-21 11:18:07 -0600980 stat->uid = make_kuid(fc->user_ns, attr->uid);
981 stat->gid = make_kgid(fc->user_ns, attr->gid);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700982 stat->rdev = inode->i_rdev;
983 stat->atime.tv_sec = attr->atime;
984 stat->atime.tv_nsec = attr->atimensec;
985 stat->mtime.tv_sec = attr->mtime;
986 stat->mtime.tv_nsec = attr->mtimensec;
987 stat->ctime.tv_sec = attr->ctime;
988 stat->ctime.tv_nsec = attr->ctimensec;
989 stat->size = attr->size;
990 stat->blocks = attr->blocks;
Miklos Szeredi203627b2012-05-10 19:49:38 +0400991
992 if (attr->blksize != 0)
993 blkbits = ilog2(attr->blksize);
994 else
995 blkbits = inode->i_sb->s_blocksize_bits;
996
997 stat->blksize = 1 << blkbits;
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700998}
999
Miklos Szeredic79e3222007-10-18 03:06:59 -07001000static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
1001 struct file *file)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001002{
1003 int err;
Miklos Szeredic79e3222007-10-18 03:06:59 -07001004 struct fuse_getattr_in inarg;
1005 struct fuse_attr_out outarg;
Max Reitzfcee2162020-05-06 17:44:12 +02001006 struct fuse_mount *fm = get_fuse_mount(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001007 FUSE_ARGS(args);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -07001008 u64 attr_version;
1009
Max Reitzfcee2162020-05-06 17:44:12 +02001010 attr_version = fuse_get_attr_version(fm->fc);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -07001011
Miklos Szeredic79e3222007-10-18 03:06:59 -07001012 memset(&inarg, 0, sizeof(inarg));
Miklos Szeredi0e9663e2007-10-18 03:07:05 -07001013 memset(&outarg, 0, sizeof(outarg));
Miklos Szeredic79e3222007-10-18 03:06:59 -07001014 /* Directories have separate file-handle space */
1015 if (file && S_ISREG(inode->i_mode)) {
1016 struct fuse_file *ff = file->private_data;
1017
1018 inarg.getattr_flags |= FUSE_GETATTR_FH;
1019 inarg.fh = ff->fh;
1020 }
Miklos Szeredid5b48542019-09-10 15:04:08 +02001021 args.opcode = FUSE_GETATTR;
1022 args.nodeid = get_node_id(inode);
1023 args.in_numargs = 1;
1024 args.in_args[0].size = sizeof(inarg);
1025 args.in_args[0].value = &inarg;
1026 args.out_numargs = 1;
1027 args.out_args[0].size = sizeof(outarg);
1028 args.out_args[0].value = &outarg;
Max Reitzfcee2162020-05-06 17:44:12 +02001029 err = fuse_simple_request(fm, &args);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001030 if (!err) {
Miklos Szeredieb59bd12019-11-12 11:49:04 +01001031 if (fuse_invalid_attr(&outarg.attr) ||
1032 (inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
Miklos Szeredie5e55582005-09-09 13:10:28 -07001033 make_bad_inode(inode);
1034 err = -EIO;
1035 } else {
Miklos Szeredic79e3222007-10-18 03:06:59 -07001036 fuse_change_attributes(inode, &outarg.attr,
1037 attr_timeout(&outarg),
Miklos Szeredi1fb69e72007-10-18 03:06:58 -07001038 attr_version);
1039 if (stat)
Miklos Szeredic79e3222007-10-18 03:06:59 -07001040 fuse_fillattr(inode, &outarg.attr, stat);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001041 }
1042 }
1043 return err;
1044}
1045
Miklos Szeredi5b97eea2017-09-12 16:57:54 +02001046static int fuse_update_get_attr(struct inode *inode, struct file *file,
Miklos Szeredi2f1e8192018-10-15 15:43:06 +02001047 struct kstat *stat, u32 request_mask,
1048 unsigned int flags)
Miklos Szeredibcb4be82007-11-28 16:21:59 -08001049{
1050 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredi5b97eea2017-09-12 16:57:54 +02001051 int err = 0;
Miklos Szeredibf5c1892018-03-20 17:11:44 +01001052 bool sync;
Miklos Szeredibcb4be82007-11-28 16:21:59 -08001053
Miklos Szeredibf5c1892018-03-20 17:11:44 +01001054 if (flags & AT_STATX_FORCE_SYNC)
1055 sync = true;
1056 else if (flags & AT_STATX_DONT_SYNC)
1057 sync = false;
Miklos Szeredi2f1e8192018-10-15 15:43:06 +02001058 else if (request_mask & READ_ONCE(fi->inval_mask))
1059 sync = true;
Miklos Szeredibf5c1892018-03-20 17:11:44 +01001060 else
1061 sync = time_before64(fi->i_time, get_jiffies_64());
1062
1063 if (sync) {
Seth Forshee60bcc882016-08-29 08:46:37 -05001064 forget_all_cached_acls(inode);
Miklos Szeredibcb4be82007-11-28 16:21:59 -08001065 err = fuse_do_getattr(inode, stat, file);
Miklos Szeredi5b97eea2017-09-12 16:57:54 +02001066 } else if (stat) {
1067 generic_fillattr(inode, stat);
1068 stat->mode = fi->orig_i_mode;
1069 stat->ino = fi->orig_ino;
Miklos Szeredibcb4be82007-11-28 16:21:59 -08001070 }
1071
Miklos Szeredibcb4be82007-11-28 16:21:59 -08001072 return err;
1073}
1074
Miklos Szeredi5b97eea2017-09-12 16:57:54 +02001075int fuse_update_attributes(struct inode *inode, struct file *file)
1076{
Miklos Szeredi802dc042018-10-15 15:43:06 +02001077 /* Do *not* need to get atime for internal purposes */
1078 return fuse_update_get_attr(inode, file, NULL,
1079 STATX_BASIC_STATS & ~STATX_ATIME, 0);
Miklos Szeredi5b97eea2017-09-12 16:57:54 +02001080}
1081
Max Reitzfcee2162020-05-06 17:44:12 +02001082int fuse_reverse_inval_entry(struct fuse_conn *fc, u64 parent_nodeid,
John Muir451d0f52011-12-06 21:50:06 +01001083 u64 child_nodeid, struct qstr *name)
John Muir3b463ae2009-05-31 11:13:57 -04001084{
1085 int err = -ENOTDIR;
1086 struct inode *parent;
1087 struct dentry *dir;
1088 struct dentry *entry;
1089
Max Reitzfcee2162020-05-06 17:44:12 +02001090 parent = fuse_ilookup(fc, parent_nodeid, NULL);
John Muir3b463ae2009-05-31 11:13:57 -04001091 if (!parent)
1092 return -ENOENT;
1093
Al Viro59551022016-01-22 15:40:57 -05001094 inode_lock(parent);
John Muir3b463ae2009-05-31 11:13:57 -04001095 if (!S_ISDIR(parent->i_mode))
1096 goto unlock;
1097
1098 err = -ENOENT;
1099 dir = d_find_alias(parent);
1100 if (!dir)
1101 goto unlock;
1102
Linus Torvalds8387ff22016-06-10 07:51:30 -07001103 name->hash = full_name_hash(dir, name->name, name->len);
John Muir3b463ae2009-05-31 11:13:57 -04001104 entry = d_lookup(dir, name);
1105 dput(dir);
1106 if (!entry)
1107 goto unlock;
1108
Miklos Szeredi261aaba72018-10-01 10:07:05 +02001109 fuse_dir_changed(parent);
John Muir3b463ae2009-05-31 11:13:57 -04001110 fuse_invalidate_entry(entry);
John Muir451d0f52011-12-06 21:50:06 +01001111
David Howells2b0143b2015-03-17 22:25:59 +00001112 if (child_nodeid != 0 && d_really_is_positive(entry)) {
Al Viro59551022016-01-22 15:40:57 -05001113 inode_lock(d_inode(entry));
David Howells2b0143b2015-03-17 22:25:59 +00001114 if (get_node_id(d_inode(entry)) != child_nodeid) {
John Muir451d0f52011-12-06 21:50:06 +01001115 err = -ENOENT;
1116 goto badentry;
1117 }
1118 if (d_mountpoint(entry)) {
1119 err = -EBUSY;
1120 goto badentry;
1121 }
David Howellse36cb0b2015-01-29 12:02:35 +00001122 if (d_is_dir(entry)) {
John Muir451d0f52011-12-06 21:50:06 +01001123 shrink_dcache_parent(entry);
1124 if (!simple_empty(entry)) {
1125 err = -ENOTEMPTY;
1126 goto badentry;
1127 }
David Howells2b0143b2015-03-17 22:25:59 +00001128 d_inode(entry)->i_flags |= S_DEAD;
John Muir451d0f52011-12-06 21:50:06 +01001129 }
1130 dont_mount(entry);
David Howells2b0143b2015-03-17 22:25:59 +00001131 clear_nlink(d_inode(entry));
John Muir451d0f52011-12-06 21:50:06 +01001132 err = 0;
1133 badentry:
Al Viro59551022016-01-22 15:40:57 -05001134 inode_unlock(d_inode(entry));
John Muir451d0f52011-12-06 21:50:06 +01001135 if (!err)
1136 d_delete(entry);
1137 } else {
1138 err = 0;
1139 }
John Muir3b463ae2009-05-31 11:13:57 -04001140 dput(entry);
John Muir3b463ae2009-05-31 11:13:57 -04001141
1142 unlock:
Al Viro59551022016-01-22 15:40:57 -05001143 inode_unlock(parent);
John Muir3b463ae2009-05-31 11:13:57 -04001144 iput(parent);
1145 return err;
1146}
1147
Miklos Szeredi87729a52005-09-09 13:10:34 -07001148/*
1149 * Calling into a user-controlled filesystem gives the filesystem
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001150 * daemon ptrace-like capabilities over the current process. This
Miklos Szeredi87729a52005-09-09 13:10:34 -07001151 * means, that the filesystem daemon is able to record the exact
1152 * filesystem operations performed, and can also control the behavior
1153 * of the requester process in otherwise impossible ways. For example
1154 * it can delay the operation for arbitrary length of time allowing
1155 * DoS against the requester.
1156 *
1157 * For this reason only those processes can call into the filesystem,
1158 * for which the owner of the mount has ptrace privilege. This
1159 * excludes processes started by other users, suid or sgid processes.
1160 */
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001161int fuse_allow_current_process(struct fuse_conn *fc)
Miklos Szeredi87729a52005-09-09 13:10:34 -07001162{
David Howellsc69e8d92008-11-14 10:39:19 +11001163 const struct cred *cred;
David Howellsc69e8d92008-11-14 10:39:19 +11001164
Miklos Szeredi29433a22016-10-01 07:32:32 +02001165 if (fc->allow_other)
Seth Forshee73f03c22017-12-22 15:32:33 +01001166 return current_in_userns(fc->user_ns);
Miklos Szeredi87729a52005-09-09 13:10:34 -07001167
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001168 cred = current_cred();
Eric W. Biederman499dcf22012-02-07 16:26:03 -08001169 if (uid_eq(cred->euid, fc->user_id) &&
1170 uid_eq(cred->suid, fc->user_id) &&
1171 uid_eq(cred->uid, fc->user_id) &&
1172 gid_eq(cred->egid, fc->group_id) &&
1173 gid_eq(cred->sgid, fc->group_id) &&
1174 gid_eq(cred->gid, fc->group_id))
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001175 return 1;
Miklos Szeredi87729a52005-09-09 13:10:34 -07001176
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001177 return 0;
Miklos Szeredi87729a52005-09-09 13:10:34 -07001178}
1179
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001180static int fuse_access(struct inode *inode, int mask)
1181{
Max Reitzfcee2162020-05-06 17:44:12 +02001182 struct fuse_mount *fm = get_fuse_mount(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001183 FUSE_ARGS(args);
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001184 struct fuse_access_in inarg;
1185 int err;
1186
Miklos Szeredi698fa1d2013-10-01 16:41:23 +02001187 BUG_ON(mask & MAY_NOT_BLOCK);
1188
Max Reitzfcee2162020-05-06 17:44:12 +02001189 if (fm->fc->no_access)
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001190 return 0;
1191
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001192 memset(&inarg, 0, sizeof(inarg));
Al Viroe6305c42008-07-15 21:03:57 -04001193 inarg.mask = mask & (MAY_READ | MAY_WRITE | MAY_EXEC);
Miklos Szeredid5b48542019-09-10 15:04:08 +02001194 args.opcode = FUSE_ACCESS;
1195 args.nodeid = get_node_id(inode);
1196 args.in_numargs = 1;
1197 args.in_args[0].size = sizeof(inarg);
1198 args.in_args[0].value = &inarg;
Max Reitzfcee2162020-05-06 17:44:12 +02001199 err = fuse_simple_request(fm, &args);
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001200 if (err == -ENOSYS) {
Max Reitzfcee2162020-05-06 17:44:12 +02001201 fm->fc->no_access = 1;
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001202 err = 0;
1203 }
1204 return err;
1205}
1206
Al Viro10556cb2011-06-20 19:28:19 -04001207static int fuse_perm_getattr(struct inode *inode, int mask)
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001208{
Al Viro10556cb2011-06-20 19:28:19 -04001209 if (mask & MAY_NOT_BLOCK)
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001210 return -ECHILD;
1211
Seth Forshee60bcc882016-08-29 08:46:37 -05001212 forget_all_cached_acls(inode);
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001213 return fuse_do_getattr(inode, NULL, NULL);
1214}
1215
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001216/*
1217 * Check permission. The two basic access models of FUSE are:
1218 *
1219 * 1) Local access checking ('default_permissions' mount option) based
1220 * on file mode. This is the plain old disk filesystem permission
1221 * modell.
1222 *
1223 * 2) "Remote" access checking, where server is responsible for
1224 * checking permission in each inode operation. An exception to this
1225 * is if ->permission() was invoked from sys_access() in which case an
1226 * access request is sent. Execute permission is still checked
1227 * locally based on file mode.
1228 */
Al Viro10556cb2011-06-20 19:28:19 -04001229static int fuse_permission(struct inode *inode, int mask)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001230{
1231 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi244f6382007-10-16 23:31:02 -07001232 bool refreshed = false;
1233 int err = 0;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001234
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001235 if (!fuse_allow_current_process(fc))
Miklos Szeredie5e55582005-09-09 13:10:28 -07001236 return -EACCES;
Miklos Szeredi244f6382007-10-16 23:31:02 -07001237
1238 /*
Miklos Szeredie8e96152007-10-16 23:31:06 -07001239 * If attributes are needed, refresh them before proceeding
Miklos Szeredi244f6382007-10-16 23:31:02 -07001240 */
Miklos Szeredi29433a22016-10-01 07:32:32 +02001241 if (fc->default_permissions ||
Miklos Szeredie8e96152007-10-16 23:31:06 -07001242 ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) {
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001243 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredid233c7d2018-12-03 10:14:43 +01001244 u32 perm_mask = STATX_MODE | STATX_UID | STATX_GID;
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001245
Miklos Szeredid233c7d2018-12-03 10:14:43 +01001246 if (perm_mask & READ_ONCE(fi->inval_mask) ||
1247 time_before64(fi->i_time, get_jiffies_64())) {
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001248 refreshed = true;
1249
Al Viro10556cb2011-06-20 19:28:19 -04001250 err = fuse_perm_getattr(inode, mask);
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001251 if (err)
1252 return err;
1253 }
Miklos Szeredi244f6382007-10-16 23:31:02 -07001254 }
1255
Miklos Szeredi29433a22016-10-01 07:32:32 +02001256 if (fc->default_permissions) {
Al Viro2830ba72011-06-20 19:16:29 -04001257 err = generic_permission(inode, mask);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001258
1259 /* If permission is denied, try to refresh file
1260 attributes. This is also needed, because the root
1261 node will at first have no permissions */
Miklos Szeredi244f6382007-10-16 23:31:02 -07001262 if (err == -EACCES && !refreshed) {
Al Viro10556cb2011-06-20 19:28:19 -04001263 err = fuse_perm_getattr(inode, mask);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001264 if (!err)
Al Viro2830ba72011-06-20 19:16:29 -04001265 err = generic_permission(inode, mask);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001266 }
1267
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001268 /* Note: the opposite of the above test does not
1269 exist. So if permissions are revoked this won't be
1270 noticed immediately, only after the attribute
1271 timeout has expired */
Eric Paris9cfcac82010-07-23 11:43:51 -04001272 } else if (mask & (MAY_ACCESS | MAY_CHDIR)) {
Miklos Szeredie8e96152007-10-16 23:31:06 -07001273 err = fuse_access(inode, mask);
1274 } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
1275 if (!(inode->i_mode & S_IXUGO)) {
1276 if (refreshed)
1277 return -EACCES;
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001278
Al Viro10556cb2011-06-20 19:28:19 -04001279 err = fuse_perm_getattr(inode, mask);
Miklos Szeredie8e96152007-10-16 23:31:06 -07001280 if (!err && !(inode->i_mode & S_IXUGO))
1281 return -EACCES;
1282 }
Miklos Szeredie5e55582005-09-09 13:10:28 -07001283 }
Miklos Szeredi244f6382007-10-16 23:31:02 -07001284 return err;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001285}
1286
Dan Schatzberg5571f1e2018-10-11 08:17:00 -07001287static int fuse_readlink_page(struct inode *inode, struct page *page)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001288{
Max Reitzfcee2162020-05-06 17:44:12 +02001289 struct fuse_mount *fm = get_fuse_mount(inode);
Miklos Szeredi4c29afe2019-09-10 15:04:09 +02001290 struct fuse_page_desc desc = { .length = PAGE_SIZE - 1 };
1291 struct fuse_args_pages ap = {
1292 .num_pages = 1,
1293 .pages = &page,
1294 .descs = &desc,
1295 };
1296 char *link;
1297 ssize_t res;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001298
Miklos Szeredi4c29afe2019-09-10 15:04:09 +02001299 ap.args.opcode = FUSE_READLINK;
1300 ap.args.nodeid = get_node_id(inode);
1301 ap.args.out_pages = true;
1302 ap.args.out_argvar = true;
1303 ap.args.page_zeroing = true;
1304 ap.args.out_numargs = 1;
1305 ap.args.out_args[0].size = desc.length;
Max Reitzfcee2162020-05-06 17:44:12 +02001306 res = fuse_simple_request(fm, &ap.args);
Al Viro6b255392015-11-17 10:20:54 -05001307
Andrew Gallagher451418f2013-11-05 03:55:43 -08001308 fuse_invalidate_atime(inode);
Dan Schatzberg5571f1e2018-10-11 08:17:00 -07001309
Miklos Szeredi4c29afe2019-09-10 15:04:09 +02001310 if (res < 0)
1311 return res;
1312
1313 if (WARN_ON(res >= PAGE_SIZE))
1314 return -EIO;
1315
1316 link = page_address(page);
1317 link[res] = '\0';
1318
1319 return 0;
Dan Schatzberg5571f1e2018-10-11 08:17:00 -07001320}
1321
1322static const char *fuse_get_link(struct dentry *dentry, struct inode *inode,
1323 struct delayed_call *callback)
1324{
1325 struct fuse_conn *fc = get_fuse_conn(inode);
1326 struct page *page;
1327 int err;
1328
1329 err = -EIO;
1330 if (is_bad_inode(inode))
1331 goto out_err;
1332
1333 if (fc->cache_symlinks)
1334 return page_get_link(dentry, inode, callback);
1335
1336 err = -ECHILD;
1337 if (!dentry)
1338 goto out_err;
1339
1340 page = alloc_page(GFP_KERNEL);
1341 err = -ENOMEM;
1342 if (!page)
1343 goto out_err;
1344
1345 err = fuse_readlink_page(inode, page);
1346 if (err) {
1347 __free_page(page);
1348 goto out_err;
1349 }
1350
1351 set_delayed_call(callback, page_put_link, page);
1352
1353 return page_address(page);
1354
1355out_err:
1356 return ERR_PTR(err);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001357}
1358
Miklos Szeredie5e55582005-09-09 13:10:28 -07001359static int fuse_dir_open(struct inode *inode, struct file *file)
1360{
Miklos Szeredi91fe96b2009-04-28 16:56:37 +02001361 return fuse_open_common(inode, file, true);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001362}
1363
1364static int fuse_dir_release(struct inode *inode, struct file *file)
1365{
Chad Austin2e64ff12018-12-10 10:54:52 -08001366 fuse_release_common(file, true);
Miklos Szeredi8b0797a2009-04-28 16:56:39 +02001367
1368 return 0;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001369}
1370
Josef Bacik02c24a82011-07-16 20:44:56 -04001371static int fuse_dir_fsync(struct file *file, loff_t start, loff_t end,
1372 int datasync)
Miklos Szeredi82547982005-09-09 13:10:38 -07001373{
Miklos Szeredia9c2d1e2018-12-03 10:14:43 +01001374 struct inode *inode = file->f_mapping->host;
1375 struct fuse_conn *fc = get_fuse_conn(inode);
1376 int err;
1377
1378 if (is_bad_inode(inode))
1379 return -EIO;
1380
1381 if (fc->no_fsyncdir)
1382 return 0;
1383
1384 inode_lock(inode);
1385 err = fuse_fsync_common(file, start, end, datasync, FUSE_FSYNCDIR);
1386 if (err == -ENOSYS) {
1387 fc->no_fsyncdir = 1;
1388 err = 0;
1389 }
1390 inode_unlock(inode);
1391
1392 return err;
Miklos Szeredi82547982005-09-09 13:10:38 -07001393}
1394
Miklos Szeredib18da0c2011-12-13 11:58:49 +01001395static long fuse_dir_ioctl(struct file *file, unsigned int cmd,
1396 unsigned long arg)
1397{
1398 struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1399
1400 /* FUSE_IOCTL_DIR only supported for API version >= 7.18 */
1401 if (fc->minor < 18)
1402 return -ENOTTY;
1403
1404 return fuse_ioctl_common(file, cmd, arg, FUSE_IOCTL_DIR);
1405}
1406
1407static long fuse_dir_compat_ioctl(struct file *file, unsigned int cmd,
1408 unsigned long arg)
1409{
1410 struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1411
1412 if (fc->minor < 18)
1413 return -ENOTTY;
1414
1415 return fuse_ioctl_common(file, cmd, arg,
1416 FUSE_IOCTL_COMPAT | FUSE_IOCTL_DIR);
1417}
1418
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001419static bool update_mtime(unsigned ivalid, bool trust_local_mtime)
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001420{
1421 /* Always update if mtime is explicitly set */
1422 if (ivalid & ATTR_MTIME_SET)
1423 return true;
1424
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001425 /* Or if kernel i_mtime is the official one */
1426 if (trust_local_mtime)
1427 return true;
1428
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001429 /* If it's an open(O_TRUNC) or an ftruncate(), don't update */
1430 if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE)))
1431 return false;
1432
1433 /* In all other cases update */
1434 return true;
1435}
1436
Eric W. Biederman8cb08322018-02-21 11:18:07 -06001437static void iattr_to_fattr(struct fuse_conn *fc, struct iattr *iattr,
1438 struct fuse_setattr_in *arg, bool trust_local_cmtime)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001439{
1440 unsigned ivalid = iattr->ia_valid;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001441
1442 if (ivalid & ATTR_MODE)
Miklos Szeredibefc6492005-11-07 00:59:52 -08001443 arg->valid |= FATTR_MODE, arg->mode = iattr->ia_mode;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001444 if (ivalid & ATTR_UID)
Eric W. Biederman8cb08322018-02-21 11:18:07 -06001445 arg->valid |= FATTR_UID, arg->uid = from_kuid(fc->user_ns, iattr->ia_uid);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001446 if (ivalid & ATTR_GID)
Eric W. Biederman8cb08322018-02-21 11:18:07 -06001447 arg->valid |= FATTR_GID, arg->gid = from_kgid(fc->user_ns, iattr->ia_gid);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001448 if (ivalid & ATTR_SIZE)
Miklos Szeredibefc6492005-11-07 00:59:52 -08001449 arg->valid |= FATTR_SIZE, arg->size = iattr->ia_size;
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001450 if (ivalid & ATTR_ATIME) {
1451 arg->valid |= FATTR_ATIME;
Miklos Szeredibefc6492005-11-07 00:59:52 -08001452 arg->atime = iattr->ia_atime.tv_sec;
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001453 arg->atimensec = iattr->ia_atime.tv_nsec;
1454 if (!(ivalid & ATTR_ATIME_SET))
1455 arg->valid |= FATTR_ATIME_NOW;
1456 }
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001457 if ((ivalid & ATTR_MTIME) && update_mtime(ivalid, trust_local_cmtime)) {
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001458 arg->valid |= FATTR_MTIME;
Miklos Szeredibefc6492005-11-07 00:59:52 -08001459 arg->mtime = iattr->ia_mtime.tv_sec;
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001460 arg->mtimensec = iattr->ia_mtime.tv_nsec;
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001461 if (!(ivalid & ATTR_MTIME_SET) && !trust_local_cmtime)
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001462 arg->valid |= FATTR_MTIME_NOW;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001463 }
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001464 if ((ivalid & ATTR_CTIME) && trust_local_cmtime) {
1465 arg->valid |= FATTR_CTIME;
1466 arg->ctime = iattr->ia_ctime.tv_sec;
1467 arg->ctimensec = iattr->ia_ctime.tv_nsec;
1468 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001469}
1470
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001471/*
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001472 * Prevent concurrent writepages on inode
1473 *
1474 * This is done by adding a negative bias to the inode write counter
1475 * and waiting for all pending writes to finish.
1476 */
1477void fuse_set_nowrite(struct inode *inode)
1478{
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001479 struct fuse_inode *fi = get_fuse_inode(inode);
1480
Al Viro59551022016-01-22 15:40:57 -05001481 BUG_ON(!inode_is_locked(inode));
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001482
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001483 spin_lock(&fi->lock);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001484 BUG_ON(fi->writectr < 0);
1485 fi->writectr += FUSE_NOWRITE;
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001486 spin_unlock(&fi->lock);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001487 wait_event(fi->page_waitq, fi->writectr == FUSE_NOWRITE);
1488}
1489
1490/*
1491 * Allow writepages on inode
1492 *
1493 * Remove the bias from the writecounter and send any queued
1494 * writepages.
1495 */
1496static void __fuse_release_nowrite(struct inode *inode)
1497{
1498 struct fuse_inode *fi = get_fuse_inode(inode);
1499
1500 BUG_ON(fi->writectr != FUSE_NOWRITE);
1501 fi->writectr = 0;
1502 fuse_flush_writepages(inode);
1503}
1504
1505void fuse_release_nowrite(struct inode *inode)
1506{
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001507 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001508
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001509 spin_lock(&fi->lock);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001510 __fuse_release_nowrite(inode);
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001511 spin_unlock(&fi->lock);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001512}
1513
Miklos Szeredi70781872014-12-12 09:49:05 +01001514static void fuse_setattr_fill(struct fuse_conn *fc, struct fuse_args *args,
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001515 struct inode *inode,
1516 struct fuse_setattr_in *inarg_p,
1517 struct fuse_attr_out *outarg_p)
1518{
Miklos Szeredid5b48542019-09-10 15:04:08 +02001519 args->opcode = FUSE_SETATTR;
1520 args->nodeid = get_node_id(inode);
1521 args->in_numargs = 1;
1522 args->in_args[0].size = sizeof(*inarg_p);
1523 args->in_args[0].value = inarg_p;
1524 args->out_numargs = 1;
1525 args->out_args[0].size = sizeof(*outarg_p);
1526 args->out_args[0].value = outarg_p;
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001527}
1528
1529/*
1530 * Flush inode->i_mtime to the server
1531 */
Maxim Patlasovab9e13f2014-04-28 14:19:24 +02001532int fuse_flush_times(struct inode *inode, struct fuse_file *ff)
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001533{
Max Reitzfcee2162020-05-06 17:44:12 +02001534 struct fuse_mount *fm = get_fuse_mount(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001535 FUSE_ARGS(args);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001536 struct fuse_setattr_in inarg;
1537 struct fuse_attr_out outarg;
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001538
1539 memset(&inarg, 0, sizeof(inarg));
1540 memset(&outarg, 0, sizeof(outarg));
1541
Maxim Patlasovab9e13f2014-04-28 14:19:24 +02001542 inarg.valid = FATTR_MTIME;
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001543 inarg.mtime = inode->i_mtime.tv_sec;
1544 inarg.mtimensec = inode->i_mtime.tv_nsec;
Max Reitzfcee2162020-05-06 17:44:12 +02001545 if (fm->fc->minor >= 23) {
Maxim Patlasovab9e13f2014-04-28 14:19:24 +02001546 inarg.valid |= FATTR_CTIME;
1547 inarg.ctime = inode->i_ctime.tv_sec;
1548 inarg.ctimensec = inode->i_ctime.tv_nsec;
1549 }
Miklos Szeredi1e18bda2014-04-28 14:19:23 +02001550 if (ff) {
1551 inarg.valid |= FATTR_FH;
1552 inarg.fh = ff->fh;
1553 }
Max Reitzfcee2162020-05-06 17:44:12 +02001554 fuse_setattr_fill(fm->fc, &args, inode, &inarg, &outarg);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001555
Max Reitzfcee2162020-05-06 17:44:12 +02001556 return fuse_simple_request(fm, &args);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001557}
1558
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001559/*
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001560 * Set attributes, and at the same time refresh them.
1561 *
1562 * Truncation is slightly complicated, because the 'truncate' request
1563 * may fail, in which case we don't want to touch the mapping.
Miklos Szeredi9ffbb912006-10-17 00:10:06 -07001564 * vmtruncate() doesn't allow for this case, so do the rlimit checking
1565 * and the actual truncation by hand.
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001566 */
Jan Kara62490332016-05-26 17:12:41 +02001567int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
Maxim Patlasovefb9fa92012-12-18 14:05:08 +04001568 struct file *file)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001569{
Jan Kara62490332016-05-26 17:12:41 +02001570 struct inode *inode = d_inode(dentry);
Max Reitzfcee2162020-05-06 17:44:12 +02001571 struct fuse_mount *fm = get_fuse_mount(inode);
1572 struct fuse_conn *fc = fm->fc;
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001573 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001574 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001575 struct fuse_setattr_in inarg;
1576 struct fuse_attr_out outarg;
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001577 bool is_truncate = false;
Pavel Emelyanov83732002013-10-10 17:10:46 +04001578 bool is_wb = fc->writeback_cache;
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001579 loff_t oldsize;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001580 int err;
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001581 bool trust_local_cmtime = is_wb && S_ISREG(inode->i_mode);
Vivek Goyal6ae330c2020-08-19 18:19:54 -04001582 bool fault_blocked = false;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001583
Miklos Szeredi29433a22016-10-01 07:32:32 +02001584 if (!fc->default_permissions)
Christoph Hellwigdb78b872010-06-04 11:30:03 +02001585 attr->ia_valid |= ATTR_FORCE;
1586
Jan Kara31051c82016-05-26 16:55:18 +02001587 err = setattr_prepare(dentry, attr);
Christoph Hellwigdb78b872010-06-04 11:30:03 +02001588 if (err)
1589 return err;
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001590
Vivek Goyal6ae330c2020-08-19 18:19:54 -04001591 if (attr->ia_valid & ATTR_SIZE) {
1592 if (WARN_ON(!S_ISREG(inode->i_mode)))
1593 return -EIO;
1594 is_truncate = true;
1595 }
1596
1597 if (FUSE_IS_DAX(inode) && is_truncate) {
1598 down_write(&fi->i_mmap_sem);
1599 fault_blocked = true;
1600 err = fuse_dax_break_layouts(inode, 0, 0);
1601 if (err) {
1602 up_write(&fi->i_mmap_sem);
1603 return err;
1604 }
1605 }
1606
Miklos Szeredi8d56add2011-02-25 14:44:58 +01001607 if (attr->ia_valid & ATTR_OPEN) {
Miklos Szeredidf0e91d2018-02-08 15:17:38 +01001608 /* This is coming from open(..., ... | O_TRUNC); */
1609 WARN_ON(!(attr->ia_valid & ATTR_SIZE));
1610 WARN_ON(attr->ia_size != 0);
1611 if (fc->atomic_o_trunc) {
1612 /*
1613 * No need to send request to userspace, since actual
1614 * truncation has already been done by OPEN. But still
1615 * need to truncate page cache.
1616 */
1617 i_size_write(inode, 0);
1618 truncate_pagecache(inode, 0);
Vivek Goyal6ae330c2020-08-19 18:19:54 -04001619 goto out;
Miklos Szeredidf0e91d2018-02-08 15:17:38 +01001620 }
Miklos Szeredi8d56add2011-02-25 14:44:58 +01001621 file = NULL;
1622 }
Miklos Szeredi6ff958e2007-10-18 03:07:02 -07001623
Miklos Szeredib24e7592019-10-23 14:26:37 +02001624 /* Flush dirty data/metadata before non-truncate SETATTR */
1625 if (is_wb && S_ISREG(inode->i_mode) &&
1626 attr->ia_valid &
1627 (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_MTIME_SET |
1628 ATTR_TIMES_SET)) {
1629 err = write_inode_now(inode, true);
1630 if (err)
1631 return err;
1632
1633 fuse_set_nowrite(inode);
1634 fuse_release_nowrite(inode);
1635 }
1636
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001637 if (is_truncate) {
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001638 fuse_set_nowrite(inode);
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001639 set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001640 if (trust_local_cmtime && attr->ia_size != inode->i_size)
1641 attr->ia_valid |= ATTR_MTIME | ATTR_CTIME;
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001642 }
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001643
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001644 memset(&inarg, 0, sizeof(inarg));
Miklos Szeredi0e9663e2007-10-18 03:07:05 -07001645 memset(&outarg, 0, sizeof(outarg));
Eric W. Biederman8cb08322018-02-21 11:18:07 -06001646 iattr_to_fattr(fc, attr, &inarg, trust_local_cmtime);
Miklos Szeredi49d49142007-10-18 03:07:00 -07001647 if (file) {
1648 struct fuse_file *ff = file->private_data;
1649 inarg.valid |= FATTR_FH;
1650 inarg.fh = ff->fh;
1651 }
Miklos Szeredif3332112007-10-18 03:07:04 -07001652 if (attr->ia_valid & ATTR_SIZE) {
1653 /* For mandatory locking in truncate */
1654 inarg.valid |= FATTR_LOCKOWNER;
1655 inarg.lock_owner = fuse_lock_owner_id(fc, current->files);
1656 }
Miklos Szeredi70781872014-12-12 09:49:05 +01001657 fuse_setattr_fill(fc, &args, inode, &inarg, &outarg);
Max Reitzfcee2162020-05-06 17:44:12 +02001658 err = fuse_simple_request(fm, &args);
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001659 if (err) {
1660 if (err == -EINTR)
1661 fuse_invalidate_attr(inode);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001662 goto error;
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001663 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001664
Miklos Szeredieb59bd12019-11-12 11:49:04 +01001665 if (fuse_invalid_attr(&outarg.attr) ||
1666 (inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001667 make_bad_inode(inode);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001668 err = -EIO;
1669 goto error;
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001670 }
1671
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001672 spin_lock(&fi->lock);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001673 /* the kernel maintains i_mtime locally */
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001674 if (trust_local_cmtime) {
1675 if (attr->ia_valid & ATTR_MTIME)
1676 inode->i_mtime = attr->ia_mtime;
1677 if (attr->ia_valid & ATTR_CTIME)
1678 inode->i_ctime = attr->ia_ctime;
Miklos Szeredi1e18bda2014-04-28 14:19:23 +02001679 /* FIXME: clear I_DIRTY_SYNC? */
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001680 }
1681
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001682 fuse_change_attributes_common(inode, &outarg.attr,
1683 attr_timeout(&outarg));
1684 oldsize = inode->i_size;
Pavel Emelyanov83732002013-10-10 17:10:46 +04001685 /* see the comment in fuse_change_attributes() */
1686 if (!is_wb || is_truncate || !S_ISREG(inode->i_mode))
1687 i_size_write(inode, outarg.attr.size);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001688
1689 if (is_truncate) {
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001690 /* NOTE: this may release/reacquire fi->lock */
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001691 __fuse_release_nowrite(inode);
1692 }
Kirill Tkhaif15ecfe2018-11-09 13:33:22 +03001693 spin_unlock(&fi->lock);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001694
1695 /*
1696 * Only call invalidate_inode_pages2() after removing
1697 * FUSE_NOWRITE, otherwise fuse_launder_page() would deadlock.
1698 */
Pavel Emelyanov83732002013-10-10 17:10:46 +04001699 if ((is_truncate || !is_wb) &&
1700 S_ISREG(inode->i_mode) && oldsize != outarg.attr.size) {
Kirill A. Shutemov7caef262013-09-12 15:13:56 -07001701 truncate_pagecache(inode, outarg.attr.size);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001702 invalidate_inode_pages2(inode->i_mapping);
1703 }
1704
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001705 clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
Vivek Goyal6ae330c2020-08-19 18:19:54 -04001706out:
1707 if (fault_blocked)
1708 up_write(&fi->i_mmap_sem);
1709
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001710 return 0;
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001711
1712error:
1713 if (is_truncate)
1714 fuse_release_nowrite(inode);
1715
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001716 clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
Vivek Goyal6ae330c2020-08-19 18:19:54 -04001717
1718 if (fault_blocked)
1719 up_write(&fi->i_mmap_sem);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001720 return err;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001721}
1722
Miklos Szeredi49d49142007-10-18 03:07:00 -07001723static int fuse_setattr(struct dentry *entry, struct iattr *attr)
1724{
David Howells2b0143b2015-03-17 22:25:59 +00001725 struct inode *inode = d_inode(entry);
Miklos Szeredi5e940c12016-10-01 07:32:32 +02001726 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredia09f99e2016-10-01 07:32:32 +02001727 struct file *file = (attr->ia_valid & ATTR_FILE) ? attr->ia_file : NULL;
Miklos Szeredi5e2b8822016-10-01 07:32:32 +02001728 int ret;
Maxim Patlasovefb9fa92012-12-18 14:05:08 +04001729
1730 if (!fuse_allow_current_process(get_fuse_conn(inode)))
1731 return -EACCES;
1732
Miklos Szeredia09f99e2016-10-01 07:32:32 +02001733 if (attr->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) {
Miklos Szeredia09f99e2016-10-01 07:32:32 +02001734 attr->ia_valid &= ~(ATTR_KILL_SUID | ATTR_KILL_SGID |
1735 ATTR_MODE);
Miklos Szeredia09f99e2016-10-01 07:32:32 +02001736
Miklos Szeredi5e940c12016-10-01 07:32:32 +02001737 /*
1738 * The only sane way to reliably kill suid/sgid is to do it in
1739 * the userspace filesystem
1740 *
1741 * This should be done on write(), truncate() and chown().
1742 */
1743 if (!fc->handle_killpriv) {
Miklos Szeredi5e940c12016-10-01 07:32:32 +02001744 /*
1745 * ia_mode calculation may have used stale i_mode.
1746 * Refresh and recalculate.
1747 */
1748 ret = fuse_do_getattr(inode, NULL, file);
1749 if (ret)
1750 return ret;
1751
1752 attr->ia_mode = inode->i_mode;
Miklos Szeredic01638f2016-12-06 16:18:45 +01001753 if (inode->i_mode & S_ISUID) {
Miklos Szeredi5e940c12016-10-01 07:32:32 +02001754 attr->ia_valid |= ATTR_MODE;
1755 attr->ia_mode &= ~S_ISUID;
1756 }
Miklos Szeredic01638f2016-12-06 16:18:45 +01001757 if ((inode->i_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
Miklos Szeredi5e940c12016-10-01 07:32:32 +02001758 attr->ia_valid |= ATTR_MODE;
1759 attr->ia_mode &= ~S_ISGID;
1760 }
Miklos Szeredia09f99e2016-10-01 07:32:32 +02001761 }
1762 }
1763 if (!attr->ia_valid)
1764 return 0;
1765
Linus Torvaldsabb5a142016-10-10 13:04:49 -07001766 ret = fuse_do_setattr(entry, attr, file);
Miklos Szeredi5e2b8822016-10-01 07:32:32 +02001767 if (!ret) {
Seth Forshee60bcc882016-08-29 08:46:37 -05001768 /*
1769 * If filesystem supports acls it may have updated acl xattrs in
1770 * the filesystem, so forget cached acls for the inode.
1771 */
1772 if (fc->posix_acl)
1773 forget_all_cached_acls(inode);
1774
Miklos Szeredi5e2b8822016-10-01 07:32:32 +02001775 /* Directory mode changed, may need to revalidate access */
1776 if (d_is_dir(entry) && (attr->ia_valid & ATTR_MODE))
1777 fuse_invalidate_entry_cache(entry);
1778 }
1779 return ret;
Miklos Szeredi49d49142007-10-18 03:07:00 -07001780}
1781
David Howellsa528d352017-01-31 16:46:22 +00001782static int fuse_getattr(const struct path *path, struct kstat *stat,
1783 u32 request_mask, unsigned int flags)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001784{
David Howellsa528d352017-01-31 16:46:22 +00001785 struct inode *inode = d_inode(path->dentry);
Miklos Szeredi244f6382007-10-16 23:31:02 -07001786 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi244f6382007-10-16 23:31:02 -07001787
Miklos Szeredi5157da22020-05-19 14:50:37 +02001788 if (!fuse_allow_current_process(fc)) {
1789 if (!request_mask) {
1790 /*
1791 * If user explicitly requested *nothing* then don't
1792 * error out, but return st_dev only.
1793 */
1794 stat->result_mask = 0;
1795 stat->dev = inode->i_sb->s_dev;
1796 return 0;
1797 }
Miklos Szeredi244f6382007-10-16 23:31:02 -07001798 return -EACCES;
Miklos Szeredi5157da22020-05-19 14:50:37 +02001799 }
Miklos Szeredi244f6382007-10-16 23:31:02 -07001800
Miklos Szeredi2f1e8192018-10-15 15:43:06 +02001801 return fuse_update_get_attr(inode, NULL, stat, request_mask, flags);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001802}
1803
Arjan van de Ven754661f2007-02-12 00:55:38 -08001804static const struct inode_operations fuse_dir_inode_operations = {
Miklos Szeredie5e55582005-09-09 13:10:28 -07001805 .lookup = fuse_lookup,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001806 .mkdir = fuse_mkdir,
1807 .symlink = fuse_symlink,
1808 .unlink = fuse_unlink,
1809 .rmdir = fuse_rmdir,
Miklos Szeredi2773bf02016-09-27 11:03:58 +02001810 .rename = fuse_rename2,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001811 .link = fuse_link,
1812 .setattr = fuse_setattr,
1813 .create = fuse_create,
Miklos Szeredic8ccbe02012-06-05 15:10:22 +02001814 .atomic_open = fuse_atomic_open,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001815 .mknod = fuse_mknod,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001816 .permission = fuse_permission,
1817 .getattr = fuse_getattr,
Miklos Szeredi92a87802005-09-09 13:10:31 -07001818 .listxattr = fuse_listxattr,
Seth Forshee60bcc882016-08-29 08:46:37 -05001819 .get_acl = fuse_get_acl,
1820 .set_acl = fuse_set_acl,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001821};
1822
Arjan van de Ven4b6f5d22006-03-28 01:56:42 -08001823static const struct file_operations fuse_dir_operations = {
Miklos Szeredib6aeade2005-09-09 13:10:30 -07001824 .llseek = generic_file_llseek,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001825 .read = generic_read_dir,
Al Virod9b3dbd2016-04-20 17:30:32 -04001826 .iterate_shared = fuse_readdir,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001827 .open = fuse_dir_open,
1828 .release = fuse_dir_release,
Miklos Szeredi82547982005-09-09 13:10:38 -07001829 .fsync = fuse_dir_fsync,
Miklos Szeredib18da0c2011-12-13 11:58:49 +01001830 .unlocked_ioctl = fuse_dir_ioctl,
1831 .compat_ioctl = fuse_dir_compat_ioctl,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001832};
1833
Arjan van de Ven754661f2007-02-12 00:55:38 -08001834static const struct inode_operations fuse_common_inode_operations = {
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001835 .setattr = fuse_setattr,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001836 .permission = fuse_permission,
1837 .getattr = fuse_getattr,
Miklos Szeredi92a87802005-09-09 13:10:31 -07001838 .listxattr = fuse_listxattr,
Seth Forshee60bcc882016-08-29 08:46:37 -05001839 .get_acl = fuse_get_acl,
1840 .set_acl = fuse_set_acl,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001841};
1842
Arjan van de Ven754661f2007-02-12 00:55:38 -08001843static const struct inode_operations fuse_symlink_inode_operations = {
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001844 .setattr = fuse_setattr,
Al Viro6b255392015-11-17 10:20:54 -05001845 .get_link = fuse_get_link,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001846 .getattr = fuse_getattr,
Miklos Szeredi92a87802005-09-09 13:10:31 -07001847 .listxattr = fuse_listxattr,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001848};
1849
1850void fuse_init_common(struct inode *inode)
1851{
1852 inode->i_op = &fuse_common_inode_operations;
1853}
1854
1855void fuse_init_dir(struct inode *inode)
1856{
Miklos Szerediab2257e2018-10-01 10:07:05 +02001857 struct fuse_inode *fi = get_fuse_inode(inode);
1858
Miklos Szeredie5e55582005-09-09 13:10:28 -07001859 inode->i_op = &fuse_dir_inode_operations;
1860 inode->i_fop = &fuse_dir_operations;
Miklos Szerediab2257e2018-10-01 10:07:05 +02001861
1862 spin_lock_init(&fi->rdc.lock);
1863 fi->rdc.cached = false;
1864 fi->rdc.size = 0;
1865 fi->rdc.pos = 0;
1866 fi->rdc.version = 0;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001867}
1868
Dan Schatzberg5571f1e2018-10-11 08:17:00 -07001869static int fuse_symlink_readpage(struct file *null, struct page *page)
1870{
1871 int err = fuse_readlink_page(page->mapping->host, page);
1872
1873 if (!err)
1874 SetPageUptodate(page);
1875
1876 unlock_page(page);
1877
1878 return err;
1879}
1880
1881static const struct address_space_operations fuse_symlink_aops = {
1882 .readpage = fuse_symlink_readpage,
1883};
1884
Miklos Szeredie5e55582005-09-09 13:10:28 -07001885void fuse_init_symlink(struct inode *inode)
1886{
1887 inode->i_op = &fuse_symlink_inode_operations;
Dan Schatzberg5571f1e2018-10-11 08:17:00 -07001888 inode->i_data.a_ops = &fuse_symlink_aops;
1889 inode_nohighmem(inode);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001890}