blob: 2b6fc2b35649a153305ac7939b54472778ff2e3f [file] [log] [blame]
Miklos Szeredie5e55582005-09-09 13:10:28 -07001/*
2 FUSE: Filesystem in Userspace
Miklos Szeredi1729a162008-11-26 12:03:54 +01003 Copyright (C) 2001-2008 Miklos Szeredi <miklos@szeredi.hu>
Miklos Szeredie5e55582005-09-09 13:10:28 -07004
5 This program can be distributed under the terms of the GNU GPL.
6 See the file COPYING.
7*/
8
9#include "fuse_i.h"
10
11#include <linux/pagemap.h>
12#include <linux/file.h>
Miklos Szeredie5e55582005-09-09 13:10:28 -070013#include <linux/sched.h>
14#include <linux/namei.h>
Miklos Szeredi07e77dc2010-12-07 20:16:56 +010015#include <linux/slab.h>
Seth Forshee703c7362016-08-29 08:46:36 -050016#include <linux/xattr.h>
Miklos Szeredi261aaba72018-10-01 10:07:05 +020017#include <linux/iversion.h>
Seth Forshee60bcc882016-08-29 08:46:37 -050018#include <linux/posix_acl.h>
Miklos Szeredie5e55582005-09-09 13:10:28 -070019
Feng Shuo4582a4a2013-01-15 11:23:28 +080020static void fuse_advise_use_readdirplus(struct inode *dir)
21{
22 struct fuse_inode *fi = get_fuse_inode(dir);
23
24 set_bit(FUSE_I_ADVISE_RDPLUS, &fi->state);
25}
26
Miklos Szeredif75fdf22016-10-01 07:32:32 +020027union fuse_dentry {
28 u64 time;
29 struct rcu_head rcu;
30};
31
Miklos Szeredi0a0898c2006-07-30 03:04:10 -070032static inline void fuse_dentry_settime(struct dentry *entry, u64 time)
33{
Miklos Szeredif75fdf22016-10-01 07:32:32 +020034 ((union fuse_dentry *) entry->d_fsdata)->time = time;
Miklos Szeredi0a0898c2006-07-30 03:04:10 -070035}
36
37static inline u64 fuse_dentry_time(struct dentry *entry)
38{
Miklos Szeredif75fdf22016-10-01 07:32:32 +020039 return ((union fuse_dentry *) entry->d_fsdata)->time;
Miklos Szeredi0a0898c2006-07-30 03:04:10 -070040}
Miklos Szeredi0a0898c2006-07-30 03:04:10 -070041
Miklos Szeredi6f9f1182006-01-06 00:19:39 -080042/*
43 * FUSE caches dentries and attributes with separate timeout. The
44 * time in jiffies until the dentry/attributes are valid is stored in
Miklos Szeredif75fdf22016-10-01 07:32:32 +020045 * dentry->d_fsdata and fuse_inode->i_time respectively.
Miklos Szeredi6f9f1182006-01-06 00:19:39 -080046 */
47
48/*
49 * Calculate the time in jiffies until a dentry/attributes are valid
50 */
Miklos Szeredibcb6f6d2016-10-01 07:32:32 +020051static u64 time_to_jiffies(u64 sec, u32 nsec)
Miklos Szeredie5e55582005-09-09 13:10:28 -070052{
Miklos Szeredi685d16d2006-07-30 03:04:08 -070053 if (sec || nsec) {
Miklos Szeredibcb6f6d2016-10-01 07:32:32 +020054 struct timespec64 ts = {
55 sec,
David Sheets21067522017-01-13 15:58:30 +000056 min_t(u32, nsec, NSEC_PER_SEC - 1)
Miklos Szeredibcb6f6d2016-10-01 07:32:32 +020057 };
58
59 return get_jiffies_64() + timespec64_to_jiffies(&ts);
Miklos Szeredi685d16d2006-07-30 03:04:08 -070060 } else
Miklos Szeredi0a0898c2006-07-30 03:04:10 -070061 return 0;
Miklos Szeredie5e55582005-09-09 13:10:28 -070062}
63
Miklos Szeredi6f9f1182006-01-06 00:19:39 -080064/*
65 * Set dentry and possibly attribute timeouts from the lookup/mk*
66 * replies
67 */
Miklos Szeredid123d8e2018-09-28 16:43:23 +020068void fuse_change_entry_timeout(struct dentry *entry, struct fuse_entry_out *o)
Miklos Szeredi0aa7c692006-01-06 00:19:34 -080069{
Miklos Szeredi0a0898c2006-07-30 03:04:10 -070070 fuse_dentry_settime(entry,
71 time_to_jiffies(o->entry_valid, o->entry_valid_nsec));
Miklos Szeredi1fb69e72007-10-18 03:06:58 -070072}
73
74static u64 attr_timeout(struct fuse_attr_out *o)
75{
76 return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
77}
78
Miklos Szeredid123d8e2018-09-28 16:43:23 +020079u64 entry_attr_timeout(struct fuse_entry_out *o)
Miklos Szeredi1fb69e72007-10-18 03:06:58 -070080{
81 return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -080082}
83
Miklos Szeredi2f1e8192018-10-15 15:43:06 +020084static void fuse_invalidate_attr_mask(struct inode *inode, u32 mask)
85{
86 set_mask_bits(&get_fuse_inode(inode)->inval_mask, 0, mask);
87}
88
Miklos Szeredi6f9f1182006-01-06 00:19:39 -080089/*
90 * Mark the attributes as stale, so that at the next call to
91 * ->getattr() they will be fetched from userspace
92 */
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -080093void fuse_invalidate_attr(struct inode *inode)
94{
Miklos Szeredi2f1e8192018-10-15 15:43:06 +020095 fuse_invalidate_attr_mask(inode, STATX_BASIC_STATS);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -080096}
97
Miklos Szeredi261aaba72018-10-01 10:07:05 +020098static void fuse_dir_changed(struct inode *dir)
99{
100 fuse_invalidate_attr(dir);
101 inode_maybe_inc_iversion(dir, false);
102}
103
Andrew Gallagher451418f2013-11-05 03:55:43 -0800104/**
105 * Mark the attributes as stale due to an atime change. Avoid the invalidate if
106 * atime is not used.
107 */
108void fuse_invalidate_atime(struct inode *inode)
109{
110 if (!IS_RDONLY(inode))
Miklos Szeredi2f1e8192018-10-15 15:43:06 +0200111 fuse_invalidate_attr_mask(inode, STATX_ATIME);
Andrew Gallagher451418f2013-11-05 03:55:43 -0800112}
113
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800114/*
115 * Just mark the entry as stale, so that a next attempt to look it up
116 * will result in a new lookup call to userspace
117 *
118 * This is called when a dentry is about to become negative and the
119 * timeout is unknown (unlink, rmdir, rename and in some cases
120 * lookup)
121 */
Miklos Szeredidbd561d2008-07-25 01:49:00 -0700122void fuse_invalidate_entry_cache(struct dentry *entry)
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800123{
Miklos Szeredi0a0898c2006-07-30 03:04:10 -0700124 fuse_dentry_settime(entry, 0);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800125}
126
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800127/*
128 * Same as fuse_invalidate_entry_cache(), but also try to remove the
129 * dentry from the hash
130 */
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800131static void fuse_invalidate_entry(struct dentry *entry)
132{
133 d_invalidate(entry);
134 fuse_invalidate_entry_cache(entry);
Miklos Szeredi0aa7c692006-01-06 00:19:34 -0800135}
136
Miklos Szeredi70781872014-12-12 09:49:05 +0100137static void fuse_lookup_init(struct fuse_conn *fc, struct fuse_args *args,
Al Viro13983d02016-07-20 22:34:44 -0400138 u64 nodeid, const struct qstr *name,
Miklos Szeredie5e55582005-09-09 13:10:28 -0700139 struct fuse_entry_out *outarg)
140{
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700141 memset(outarg, 0, sizeof(struct fuse_entry_out));
Miklos Szeredi70781872014-12-12 09:49:05 +0100142 args->in.h.opcode = FUSE_LOOKUP;
143 args->in.h.nodeid = nodeid;
144 args->in.numargs = 1;
145 args->in.args[0].size = name->len + 1;
146 args->in.args[0].value = name->name;
147 args->out.numargs = 1;
Miklos Szeredi21f62172015-01-06 10:45:35 +0100148 args->out.args[0].size = sizeof(struct fuse_entry_out);
Miklos Szeredi70781872014-12-12 09:49:05 +0100149 args->out.args[0].value = outarg;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700150}
151
Miklos Szeredi5c5c5e52008-04-30 00:54:43 -0700152u64 fuse_get_attr_version(struct fuse_conn *fc)
Miklos Szeredi7dca9fd2007-11-28 16:21:59 -0800153{
154 u64 curr_version;
155
156 /*
157 * The spin lock isn't actually needed on 64bit archs, but we
158 * don't yet care too much about such optimizations.
159 */
160 spin_lock(&fc->lock);
161 curr_version = fc->attr_version;
162 spin_unlock(&fc->lock);
163
164 return curr_version;
165}
166
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800167/*
168 * Check whether the dentry is still valid
169 *
170 * If the entry validity timeout has expired and the dentry is
171 * positive, try to redo the lookup. If the lookup results in a
172 * different inode, then let the VFS invalidate the dentry and redo
173 * the lookup once more. If the lookup results in the same inode,
174 * then refresh the attributes, timeouts and mark the dentry valid.
175 */
Al Viro0b728e12012-06-10 16:03:43 -0400176static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
Miklos Szeredie5e55582005-09-09 13:10:28 -0700177{
Nick Piggin34286d62011-01-07 17:49:57 +1100178 struct inode *inode;
Miklos Szeredi28420da2013-06-03 14:40:22 +0200179 struct dentry *parent;
180 struct fuse_conn *fc;
Miklos Szeredi6314efe2013-10-01 16:41:22 +0200181 struct fuse_inode *fi;
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200182 int ret;
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800183
David Howells2b0143b2015-03-17 22:25:59 +0000184 inode = d_inode_rcu(entry);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800185 if (inode && is_bad_inode(inode))
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200186 goto invalid;
Anand Avati154210c2014-06-26 20:21:57 -0400187 else if (time_before64(fuse_dentry_time(entry), get_jiffies_64()) ||
188 (flags & LOOKUP_REVAL)) {
Miklos Szeredie5e55582005-09-09 13:10:28 -0700189 struct fuse_entry_out outarg;
Miklos Szeredi70781872014-12-12 09:49:05 +0100190 FUSE_ARGS(args);
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100191 struct fuse_forget_link *forget;
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700192 u64 attr_version;
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800193
Miklos Szeredi50322fe2006-02-28 16:59:03 -0800194 /* For negative dentries, always do a fresh lookup */
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800195 if (!inode)
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200196 goto invalid;
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800197
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200198 ret = -ECHILD;
Al Viro0b728e12012-06-10 16:03:43 -0400199 if (flags & LOOKUP_RCU)
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200200 goto out;
Miklos Szeredie7c0a162011-03-21 13:58:06 +0100201
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800202 fc = get_fuse_conn(inode);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700203
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100204 forget = fuse_alloc_forget();
Miklos Szeredi70781872014-12-12 09:49:05 +0100205 ret = -ENOMEM;
206 if (!forget)
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200207 goto out;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800208
Miklos Szeredi7dca9fd2007-11-28 16:21:59 -0800209 attr_version = fuse_get_attr_version(fc);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700210
Miklos Szeredie956edd2006-10-17 00:10:12 -0700211 parent = dget_parent(entry);
David Howells2b0143b2015-03-17 22:25:59 +0000212 fuse_lookup_init(fc, &args, get_node_id(d_inode(parent)),
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700213 &entry->d_name, &outarg);
Miklos Szeredi70781872014-12-12 09:49:05 +0100214 ret = fuse_simple_request(fc, &args);
Miklos Szeredie956edd2006-10-17 00:10:12 -0700215 dput(parent);
Miklos Szeredi50322fe2006-02-28 16:59:03 -0800216 /* Zero nodeid is same as -ENOENT */
Miklos Szeredi70781872014-12-12 09:49:05 +0100217 if (!ret && !outarg.nodeid)
218 ret = -ENOENT;
219 if (!ret) {
Miklos Szeredi6314efe2013-10-01 16:41:22 +0200220 fi = get_fuse_inode(inode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700221 if (outarg.nodeid != get_node_id(inode)) {
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100222 fuse_queue_forget(fc, forget, outarg.nodeid, 1);
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200223 goto invalid;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700224 }
Miklos Szeredi8da5ff22006-10-17 00:10:08 -0700225 spin_lock(&fc->lock);
Miklos Szeredi1729a162008-11-26 12:03:54 +0100226 fi->nlookup++;
Miklos Szeredi8da5ff22006-10-17 00:10:08 -0700227 spin_unlock(&fc->lock);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700228 }
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100229 kfree(forget);
Miklos Szeredi70781872014-12-12 09:49:05 +0100230 if (ret == -ENOMEM)
231 goto out;
232 if (ret || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200233 goto invalid;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700234
Seth Forshee60bcc882016-08-29 08:46:37 -0500235 forget_all_cached_acls(inode);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700236 fuse_change_attributes(inode, &outarg.attr,
237 entry_attr_timeout(&outarg),
238 attr_version);
239 fuse_change_entry_timeout(entry, &outarg);
Miklos Szeredi28420da2013-06-03 14:40:22 +0200240 } else if (inode) {
Miklos Szeredi6314efe2013-10-01 16:41:22 +0200241 fi = get_fuse_inode(inode);
242 if (flags & LOOKUP_RCU) {
243 if (test_bit(FUSE_I_INIT_RDPLUS, &fi->state))
244 return -ECHILD;
245 } else if (test_and_clear_bit(FUSE_I_INIT_RDPLUS, &fi->state)) {
Miklos Szeredi28420da2013-06-03 14:40:22 +0200246 parent = dget_parent(entry);
David Howells2b0143b2015-03-17 22:25:59 +0000247 fuse_advise_use_readdirplus(d_inode(parent));
Miklos Szeredi28420da2013-06-03 14:40:22 +0200248 dput(parent);
249 }
Miklos Szeredie5e55582005-09-09 13:10:28 -0700250 }
Miklos Szeredie2a6b952013-09-05 11:44:43 +0200251 ret = 1;
252out:
253 return ret;
254
255invalid:
256 ret = 0;
257 goto out;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700258}
259
Miklos Szeredif75fdf22016-10-01 07:32:32 +0200260static int fuse_dentry_init(struct dentry *dentry)
261{
262 dentry->d_fsdata = kzalloc(sizeof(union fuse_dentry), GFP_KERNEL);
263
264 return dentry->d_fsdata ? 0 : -ENOMEM;
265}
266static void fuse_dentry_release(struct dentry *dentry)
267{
268 union fuse_dentry *fd = dentry->d_fsdata;
269
270 kfree_rcu(fd, rcu);
271}
272
Al Viro42695902009-02-20 05:59:13 +0000273const struct dentry_operations fuse_dentry_operations = {
Miklos Szeredie5e55582005-09-09 13:10:28 -0700274 .d_revalidate = fuse_dentry_revalidate,
Miklos Szeredif75fdf22016-10-01 07:32:32 +0200275 .d_init = fuse_dentry_init,
276 .d_release = fuse_dentry_release,
Miklos Szeredie5e55582005-09-09 13:10:28 -0700277};
278
Miklos Szeredi0ce267f2016-10-18 15:36:48 +0200279const struct dentry_operations fuse_root_dentry_operations = {
280 .d_init = fuse_dentry_init,
281 .d_release = fuse_dentry_release,
282};
283
Timo Savolaa5bfffac2007-04-08 16:04:00 -0700284int fuse_valid_type(int m)
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800285{
286 return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) ||
287 S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
288}
289
Al Viro13983d02016-07-20 22:34:44 -0400290int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name,
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700291 struct fuse_entry_out *outarg, struct inode **inode)
292{
293 struct fuse_conn *fc = get_fuse_conn_super(sb);
Miklos Szeredi70781872014-12-12 09:49:05 +0100294 FUSE_ARGS(args);
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100295 struct fuse_forget_link *forget;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700296 u64 attr_version;
297 int err;
298
299 *inode = NULL;
300 err = -ENAMETOOLONG;
301 if (name->len > FUSE_NAME_MAX)
302 goto out;
303
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700304
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100305 forget = fuse_alloc_forget();
306 err = -ENOMEM;
Miklos Szeredi70781872014-12-12 09:49:05 +0100307 if (!forget)
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700308 goto out;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700309
310 attr_version = fuse_get_attr_version(fc);
311
Miklos Szeredi70781872014-12-12 09:49:05 +0100312 fuse_lookup_init(fc, &args, nodeid, name, outarg);
313 err = fuse_simple_request(fc, &args);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700314 /* Zero nodeid is same as -ENOENT, but with valid timeout */
315 if (err || !outarg->nodeid)
316 goto out_put_forget;
317
318 err = -EIO;
319 if (!outarg->nodeid)
320 goto out_put_forget;
321 if (!fuse_valid_type(outarg->attr.mode))
322 goto out_put_forget;
323
324 *inode = fuse_iget(sb, outarg->nodeid, outarg->generation,
325 &outarg->attr, entry_attr_timeout(outarg),
326 attr_version);
327 err = -ENOMEM;
328 if (!*inode) {
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100329 fuse_queue_forget(fc, forget, outarg->nodeid, 1);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700330 goto out;
331 }
332 err = 0;
333
334 out_put_forget:
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100335 kfree(forget);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700336 out:
337 return err;
338}
339
Miklos Szeredi0aa7c692006-01-06 00:19:34 -0800340static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
Al Viro00cd8dd2012-06-10 17:13:09 -0400341 unsigned int flags)
Miklos Szeredie5e55582005-09-09 13:10:28 -0700342{
343 int err;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700344 struct fuse_entry_out outarg;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700345 struct inode *inode;
Miklos Szeredi0de62562008-07-25 01:48:59 -0700346 struct dentry *newent;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700347 bool outarg_valid = true;
Miklos Szeredi63576c12018-07-26 16:13:11 +0200348 bool locked;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700349
Miklos Szeredi63576c12018-07-26 16:13:11 +0200350 locked = fuse_lock_inode(dir);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700351 err = fuse_lookup_name(dir->i_sb, get_node_id(dir), &entry->d_name,
352 &outarg, &inode);
Miklos Szeredi63576c12018-07-26 16:13:11 +0200353 fuse_unlock_inode(dir, locked);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700354 if (err == -ENOENT) {
355 outarg_valid = false;
356 err = 0;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800357 }
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700358 if (err)
359 goto out_err;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800360
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700361 err = -EIO;
362 if (inode && get_node_id(inode) == FUSE_ROOT_ID)
363 goto out_iput;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700364
Al Viro41d28bc2014-10-12 22:24:21 -0400365 newent = d_splice_alias(inode, entry);
Miklos Szeredi5835f332013-09-05 11:44:42 +0200366 err = PTR_ERR(newent);
367 if (IS_ERR(newent))
368 goto out_err;
Miklos Szeredid2a85162006-10-17 00:10:11 -0700369
Miklos Szeredi0de62562008-07-25 01:48:59 -0700370 entry = newent ? newent : entry;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700371 if (outarg_valid)
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700372 fuse_change_entry_timeout(entry, &outarg);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800373 else
374 fuse_invalidate_entry_cache(entry);
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700375
Feng Shuo4582a4a2013-01-15 11:23:28 +0800376 fuse_advise_use_readdirplus(dir);
Miklos Szeredi0de62562008-07-25 01:48:59 -0700377 return newent;
Miklos Szeredic180eeb2008-07-25 01:49:01 -0700378
379 out_iput:
380 iput(inode);
381 out_err:
382 return ERR_PTR(err);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700383}
384
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800385/*
386 * Atomic create+open operation
387 *
388 * If the filesystem doesn't support this, then fall back to separate
389 * 'mknod' + 'open' requests.
390 */
Al Virod9585272012-06-22 12:39:14 +0400391static int fuse_create_open(struct inode *dir, struct dentry *entry,
Al Viro30d90492012-06-22 12:40:19 +0400392 struct file *file, unsigned flags,
Al Virob452a452018-06-08 13:06:28 -0400393 umode_t mode)
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800394{
395 int err;
396 struct inode *inode;
397 struct fuse_conn *fc = get_fuse_conn(dir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100398 FUSE_ARGS(args);
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100399 struct fuse_forget_link *forget;
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200400 struct fuse_create_in inarg;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800401 struct fuse_open_out outopen;
402 struct fuse_entry_out outentry;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800403 struct fuse_file *ff;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800404
Miklos Szerediaf109bc2012-08-15 13:01:24 +0200405 /* Userspace expects S_IFREG in create mode */
406 BUG_ON((mode & S_IFMT) != S_IFREG);
407
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100408 forget = fuse_alloc_forget();
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200409 err = -ENOMEM;
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100410 if (!forget)
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200411 goto out_err;
Miklos Szeredi51eb01e2006-06-25 05:48:50 -0700412
Miklos Szeredice1d5a42006-04-10 22:54:58 -0700413 err = -ENOMEM;
Tejun Heoacf99432008-11-26 12:03:55 +0100414 ff = fuse_file_alloc(fc);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800415 if (!ff)
Miklos Szeredi70781872014-12-12 09:49:05 +0100416 goto out_put_forget_req;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800417
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200418 if (!fc->dont_mask)
419 mode &= ~current_umask();
420
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800421 flags &= ~O_NOCTTY;
422 memset(&inarg, 0, sizeof(inarg));
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700423 memset(&outentry, 0, sizeof(outentry));
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800424 inarg.flags = flags;
425 inarg.mode = mode;
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200426 inarg.umask = current_umask();
Miklos Szeredi70781872014-12-12 09:49:05 +0100427 args.in.h.opcode = FUSE_CREATE;
428 args.in.h.nodeid = get_node_id(dir);
429 args.in.numargs = 2;
Miklos Szeredi21f62172015-01-06 10:45:35 +0100430 args.in.args[0].size = sizeof(inarg);
Miklos Szeredi70781872014-12-12 09:49:05 +0100431 args.in.args[0].value = &inarg;
432 args.in.args[1].size = entry->d_name.len + 1;
433 args.in.args[1].value = entry->d_name.name;
434 args.out.numargs = 2;
Miklos Szeredi21f62172015-01-06 10:45:35 +0100435 args.out.args[0].size = sizeof(outentry);
Miklos Szeredi70781872014-12-12 09:49:05 +0100436 args.out.args[0].value = &outentry;
437 args.out.args[1].size = sizeof(outopen);
438 args.out.args[1].value = &outopen;
439 err = fuse_simple_request(fc, &args);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200440 if (err)
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800441 goto out_free_ff;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800442
443 err = -EIO;
Miklos Szeredi2827d0b22005-11-28 13:44:16 -0800444 if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid))
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800445 goto out_free_ff;
446
Miklos Szeredic7b71432009-04-28 16:56:37 +0200447 ff->fh = outopen.fh;
448 ff->nodeid = outentry.nodeid;
449 ff->open_flags = outopen.open_flags;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800450 inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700451 &outentry.attr, entry_attr_timeout(&outentry), 0);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800452 if (!inode) {
453 flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
Miklos Szeredi8b0797a2009-04-28 16:56:39 +0200454 fuse_sync_release(ff, flags);
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100455 fuse_queue_forget(fc, forget, outentry.nodeid, 1);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200456 err = -ENOMEM;
457 goto out_err;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800458 }
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100459 kfree(forget);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800460 d_instantiate(entry, inode);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700461 fuse_change_entry_timeout(entry, &outentry);
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200462 fuse_dir_changed(dir);
Al Virobe12af32018-06-08 11:44:56 -0400463 err = finish_open(file, entry, generic_file_open);
Al Viro30d90492012-06-22 12:40:19 +0400464 if (err) {
Miklos Szeredi8b0797a2009-04-28 16:56:39 +0200465 fuse_sync_release(ff, flags);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200466 } else {
Miklos Szeredi267d8442017-02-22 20:08:25 +0100467 file->private_data = ff;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200468 fuse_finish_open(inode, file);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800469 }
Al Virod9585272012-06-22 12:39:14 +0400470 return err;
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800471
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200472out_free_ff:
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800473 fuse_file_free(ff);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200474out_put_forget_req:
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100475 kfree(forget);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200476out_err:
Al Virod9585272012-06-22 12:39:14 +0400477 return err;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200478}
479
480static int fuse_mknod(struct inode *, struct dentry *, umode_t, dev_t);
Al Virod9585272012-06-22 12:39:14 +0400481static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
Al Viro30d90492012-06-22 12:40:19 +0400482 struct file *file, unsigned flags,
Al Viro44907d72018-06-08 13:32:02 -0400483 umode_t mode)
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200484{
485 int err;
486 struct fuse_conn *fc = get_fuse_conn(dir);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200487 struct dentry *res = NULL;
488
Al Viro00699ad2016-07-05 09:44:53 -0400489 if (d_in_lookup(entry)) {
Al Viro00cd8dd2012-06-10 17:13:09 -0400490 res = fuse_lookup(dir, entry, 0);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200491 if (IS_ERR(res))
Al Virod9585272012-06-22 12:39:14 +0400492 return PTR_ERR(res);
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200493
494 if (res)
495 entry = res;
496 }
497
David Howells2b0143b2015-03-17 22:25:59 +0000498 if (!(flags & O_CREAT) || d_really_is_positive(entry))
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200499 goto no_open;
500
501 /* Only creates */
Al Viro73a09dd2018-06-08 13:22:02 -0400502 file->f_mode |= FMODE_CREATED;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200503
504 if (fc->no_create)
505 goto mknod;
506
Al Virob452a452018-06-08 13:06:28 -0400507 err = fuse_create_open(dir, entry, file, flags, mode);
Al Virod9585272012-06-22 12:39:14 +0400508 if (err == -ENOSYS) {
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200509 fc->no_create = 1;
510 goto mknod;
511 }
512out_dput:
513 dput(res);
Al Virod9585272012-06-22 12:39:14 +0400514 return err;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200515
516mknod:
517 err = fuse_mknod(dir, entry, mode, 0);
Al Virod9585272012-06-22 12:39:14 +0400518 if (err)
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200519 goto out_dput;
Miklos Szeredic8ccbe02012-06-05 15:10:22 +0200520no_open:
Al Viroe45198a2012-06-10 06:48:09 -0400521 return finish_no_open(file, res);
Miklos Szeredifd72faa2005-11-07 00:59:51 -0800522}
523
Miklos Szeredi6f9f1182006-01-06 00:19:39 -0800524/*
525 * Code shared between mknod, mkdir, symlink and link
526 */
Miklos Szeredi70781872014-12-12 09:49:05 +0100527static int create_new_entry(struct fuse_conn *fc, struct fuse_args *args,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700528 struct inode *dir, struct dentry *entry,
Al Viro541af6a2011-07-26 03:17:33 -0400529 umode_t mode)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700530{
531 struct fuse_entry_out outarg;
532 struct inode *inode;
Al Viroc971e6a2018-05-28 18:27:19 -0400533 struct dentry *d;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700534 int err;
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100535 struct fuse_forget_link *forget;
Miklos Szeredi2d510132006-11-25 11:09:20 -0800536
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100537 forget = fuse_alloc_forget();
Miklos Szeredi70781872014-12-12 09:49:05 +0100538 if (!forget)
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100539 return -ENOMEM;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700540
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700541 memset(&outarg, 0, sizeof(outarg));
Miklos Szeredi70781872014-12-12 09:49:05 +0100542 args->in.h.nodeid = get_node_id(dir);
543 args->out.numargs = 1;
Miklos Szeredi21f62172015-01-06 10:45:35 +0100544 args->out.args[0].size = sizeof(outarg);
Miklos Szeredi70781872014-12-12 09:49:05 +0100545 args->out.args[0].value = &outarg;
546 err = fuse_simple_request(fc, args);
Miklos Szeredi2d510132006-11-25 11:09:20 -0800547 if (err)
548 goto out_put_forget_req;
549
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800550 err = -EIO;
551 if (invalid_nodeid(outarg.nodeid))
Miklos Szeredi2d510132006-11-25 11:09:20 -0800552 goto out_put_forget_req;
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800553
554 if ((outarg.attr.mode ^ mode) & S_IFMT)
Miklos Szeredi2d510132006-11-25 11:09:20 -0800555 goto out_put_forget_req;
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800556
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700557 inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700558 &outarg.attr, entry_attr_timeout(&outarg), 0);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700559 if (!inode) {
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100560 fuse_queue_forget(fc, forget, outarg.nodeid, 1);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700561 return -ENOMEM;
562 }
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100563 kfree(forget);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700564
Al Viroc971e6a2018-05-28 18:27:19 -0400565 d_drop(entry);
566 d = d_splice_alias(inode, entry);
567 if (IS_ERR(d))
568 return PTR_ERR(d);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700569
Al Viroc971e6a2018-05-28 18:27:19 -0400570 if (d) {
571 fuse_change_entry_timeout(d, &outarg);
572 dput(d);
573 } else {
574 fuse_change_entry_timeout(entry, &outarg);
575 }
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200576 fuse_dir_changed(dir);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700577 return 0;
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800578
Miklos Szeredi2d510132006-11-25 11:09:20 -0800579 out_put_forget_req:
Miklos Szeredi07e77dc2010-12-07 20:16:56 +0100580 kfree(forget);
Miklos Szeredi39ee0592006-01-06 00:19:43 -0800581 return err;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700582}
583
Al Viro1a67aaf2011-07-26 01:52:52 -0400584static int fuse_mknod(struct inode *dir, struct dentry *entry, umode_t mode,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700585 dev_t rdev)
586{
587 struct fuse_mknod_in inarg;
588 struct fuse_conn *fc = get_fuse_conn(dir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100589 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700590
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200591 if (!fc->dont_mask)
592 mode &= ~current_umask();
593
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700594 memset(&inarg, 0, sizeof(inarg));
595 inarg.mode = mode;
596 inarg.rdev = new_encode_dev(rdev);
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200597 inarg.umask = current_umask();
Miklos Szeredi70781872014-12-12 09:49:05 +0100598 args.in.h.opcode = FUSE_MKNOD;
599 args.in.numargs = 2;
Miklos Szeredi21f62172015-01-06 10:45:35 +0100600 args.in.args[0].size = sizeof(inarg);
Miklos Szeredi70781872014-12-12 09:49:05 +0100601 args.in.args[0].value = &inarg;
602 args.in.args[1].size = entry->d_name.len + 1;
603 args.in.args[1].value = entry->d_name.name;
604 return create_new_entry(fc, &args, dir, entry, mode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700605}
606
Al Viro4acdaf22011-07-26 01:42:34 -0400607static int fuse_create(struct inode *dir, struct dentry *entry, umode_t mode,
Al Viroebfc3b42012-06-10 18:05:36 -0400608 bool excl)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700609{
610 return fuse_mknod(dir, entry, mode, 0);
611}
612
Al Viro18bb1db2011-07-26 01:41:39 -0400613static int fuse_mkdir(struct inode *dir, struct dentry *entry, umode_t mode)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700614{
615 struct fuse_mkdir_in inarg;
616 struct fuse_conn *fc = get_fuse_conn(dir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100617 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700618
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200619 if (!fc->dont_mask)
620 mode &= ~current_umask();
621
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700622 memset(&inarg, 0, sizeof(inarg));
623 inarg.mode = mode;
Miklos Szeredie0a43dd2009-06-30 20:12:23 +0200624 inarg.umask = current_umask();
Miklos Szeredi70781872014-12-12 09:49:05 +0100625 args.in.h.opcode = FUSE_MKDIR;
626 args.in.numargs = 2;
627 args.in.args[0].size = sizeof(inarg);
628 args.in.args[0].value = &inarg;
629 args.in.args[1].size = entry->d_name.len + 1;
630 args.in.args[1].value = entry->d_name.name;
631 return create_new_entry(fc, &args, dir, entry, S_IFDIR);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700632}
633
634static int fuse_symlink(struct inode *dir, struct dentry *entry,
635 const char *link)
636{
637 struct fuse_conn *fc = get_fuse_conn(dir);
638 unsigned len = strlen(link) + 1;
Miklos Szeredi70781872014-12-12 09:49:05 +0100639 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700640
Miklos Szeredi70781872014-12-12 09:49:05 +0100641 args.in.h.opcode = FUSE_SYMLINK;
642 args.in.numargs = 2;
643 args.in.args[0].size = entry->d_name.len + 1;
644 args.in.args[0].value = entry->d_name.name;
645 args.in.args[1].size = len;
646 args.in.args[1].value = link;
647 return create_new_entry(fc, &args, dir, entry, S_IFLNK);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700648}
649
Seth Forshee703c7362016-08-29 08:46:36 -0500650void fuse_update_ctime(struct inode *inode)
Maxim Patlasov31f32672014-04-28 14:19:24 +0200651{
652 if (!IS_NOCMTIME(inode)) {
Deepa Dinamanic2050a42016-09-14 07:48:06 -0700653 inode->i_ctime = current_time(inode);
Maxim Patlasov31f32672014-04-28 14:19:24 +0200654 mark_inode_dirty_sync(inode);
655 }
656}
657
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700658static int fuse_unlink(struct inode *dir, struct dentry *entry)
659{
660 int err;
661 struct fuse_conn *fc = get_fuse_conn(dir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100662 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700663
Miklos Szeredi70781872014-12-12 09:49:05 +0100664 args.in.h.opcode = FUSE_UNLINK;
665 args.in.h.nodeid = get_node_id(dir);
666 args.in.numargs = 1;
667 args.in.args[0].size = entry->d_name.len + 1;
668 args.in.args[0].value = entry->d_name.name;
669 err = fuse_simple_request(fc, &args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700670 if (!err) {
David Howells2b0143b2015-03-17 22:25:59 +0000671 struct inode *inode = d_inode(entry);
Miklos Szerediac45d612012-03-05 15:48:11 +0100672 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700673
Miklos Szerediac45d612012-03-05 15:48:11 +0100674 spin_lock(&fc->lock);
675 fi->attr_version = ++fc->attr_version;
Miklos Szeredidfca7ce2013-02-04 15:57:42 +0100676 /*
677 * If i_nlink == 0 then unlink doesn't make sense, yet this can
678 * happen if userspace filesystem is careless. It would be
679 * difficult to enforce correct nlink usage so just ignore this
680 * condition here
681 */
682 if (inode->i_nlink > 0)
683 drop_nlink(inode);
Miklos Szerediac45d612012-03-05 15:48:11 +0100684 spin_unlock(&fc->lock);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700685 fuse_invalidate_attr(inode);
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200686 fuse_dir_changed(dir);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800687 fuse_invalidate_entry_cache(entry);
Maxim Patlasov31f32672014-04-28 14:19:24 +0200688 fuse_update_ctime(inode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700689 } else if (err == -EINTR)
690 fuse_invalidate_entry(entry);
691 return err;
692}
693
694static int fuse_rmdir(struct inode *dir, struct dentry *entry)
695{
696 int err;
697 struct fuse_conn *fc = get_fuse_conn(dir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100698 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700699
Miklos Szeredi70781872014-12-12 09:49:05 +0100700 args.in.h.opcode = FUSE_RMDIR;
701 args.in.h.nodeid = get_node_id(dir);
702 args.in.numargs = 1;
703 args.in.args[0].size = entry->d_name.len + 1;
704 args.in.args[0].value = entry->d_name.name;
705 err = fuse_simple_request(fc, &args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700706 if (!err) {
David Howells2b0143b2015-03-17 22:25:59 +0000707 clear_nlink(d_inode(entry));
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200708 fuse_dir_changed(dir);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800709 fuse_invalidate_entry_cache(entry);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700710 } else if (err == -EINTR)
711 fuse_invalidate_entry(entry);
712 return err;
713}
714
Miklos Szeredi1560c972014-04-28 16:43:44 +0200715static int fuse_rename_common(struct inode *olddir, struct dentry *oldent,
716 struct inode *newdir, struct dentry *newent,
717 unsigned int flags, int opcode, size_t argsize)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700718{
719 int err;
Miklos Szeredi1560c972014-04-28 16:43:44 +0200720 struct fuse_rename2_in inarg;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700721 struct fuse_conn *fc = get_fuse_conn(olddir);
Miklos Szeredi70781872014-12-12 09:49:05 +0100722 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700723
Miklos Szeredi1560c972014-04-28 16:43:44 +0200724 memset(&inarg, 0, argsize);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700725 inarg.newdir = get_node_id(newdir);
Miklos Szeredi1560c972014-04-28 16:43:44 +0200726 inarg.flags = flags;
Miklos Szeredi70781872014-12-12 09:49:05 +0100727 args.in.h.opcode = opcode;
728 args.in.h.nodeid = get_node_id(olddir);
729 args.in.numargs = 3;
730 args.in.args[0].size = argsize;
731 args.in.args[0].value = &inarg;
732 args.in.args[1].size = oldent->d_name.len + 1;
733 args.in.args[1].value = oldent->d_name.name;
734 args.in.args[2].size = newent->d_name.len + 1;
735 args.in.args[2].value = newent->d_name.name;
736 err = fuse_simple_request(fc, &args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700737 if (!err) {
Miklos Szeredi08b63302007-11-28 16:22:03 -0800738 /* ctime changes */
David Howells2b0143b2015-03-17 22:25:59 +0000739 fuse_invalidate_attr(d_inode(oldent));
740 fuse_update_ctime(d_inode(oldent));
Miklos Szeredi08b63302007-11-28 16:22:03 -0800741
Miklos Szeredi1560c972014-04-28 16:43:44 +0200742 if (flags & RENAME_EXCHANGE) {
David Howells2b0143b2015-03-17 22:25:59 +0000743 fuse_invalidate_attr(d_inode(newent));
744 fuse_update_ctime(d_inode(newent));
Miklos Szeredi1560c972014-04-28 16:43:44 +0200745 }
746
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200747 fuse_dir_changed(olddir);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700748 if (olddir != newdir)
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200749 fuse_dir_changed(newdir);
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800750
751 /* newent will end up negative */
David Howells2b0143b2015-03-17 22:25:59 +0000752 if (!(flags & RENAME_EXCHANGE) && d_really_is_positive(newent)) {
753 fuse_invalidate_attr(d_inode(newent));
Miklos Szeredi8cbdf1e2006-01-06 00:19:38 -0800754 fuse_invalidate_entry_cache(newent);
David Howells2b0143b2015-03-17 22:25:59 +0000755 fuse_update_ctime(d_inode(newent));
Miklos Szeredi5219f342009-11-04 10:24:52 +0100756 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700757 } else if (err == -EINTR) {
758 /* If request was interrupted, DEITY only knows if the
759 rename actually took place. If the invalidation
760 fails (e.g. some process has CWD under the renamed
761 directory), then there can be inconsistency between
762 the dcache and the real filesystem. Tough luck. */
763 fuse_invalidate_entry(oldent);
David Howells2b0143b2015-03-17 22:25:59 +0000764 if (d_really_is_positive(newent))
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700765 fuse_invalidate_entry(newent);
766 }
767
768 return err;
769}
770
Miklos Szeredi1560c972014-04-28 16:43:44 +0200771static int fuse_rename2(struct inode *olddir, struct dentry *oldent,
772 struct inode *newdir, struct dentry *newent,
773 unsigned int flags)
774{
775 struct fuse_conn *fc = get_fuse_conn(olddir);
776 int err;
777
778 if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE))
779 return -EINVAL;
780
Miklos Szeredi4237ba42014-07-10 10:50:19 +0200781 if (flags) {
782 if (fc->no_rename2 || fc->minor < 23)
783 return -EINVAL;
Miklos Szeredi1560c972014-04-28 16:43:44 +0200784
Miklos Szeredi4237ba42014-07-10 10:50:19 +0200785 err = fuse_rename_common(olddir, oldent, newdir, newent, flags,
786 FUSE_RENAME2,
787 sizeof(struct fuse_rename2_in));
788 if (err == -ENOSYS) {
789 fc->no_rename2 = 1;
790 err = -EINVAL;
791 }
792 } else {
793 err = fuse_rename_common(olddir, oldent, newdir, newent, 0,
794 FUSE_RENAME,
795 sizeof(struct fuse_rename_in));
Miklos Szeredi1560c972014-04-28 16:43:44 +0200796 }
Miklos Szeredi1560c972014-04-28 16:43:44 +0200797
Miklos Szeredi4237ba42014-07-10 10:50:19 +0200798 return err;
799}
800
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700801static int fuse_link(struct dentry *entry, struct inode *newdir,
802 struct dentry *newent)
803{
804 int err;
805 struct fuse_link_in inarg;
David Howells2b0143b2015-03-17 22:25:59 +0000806 struct inode *inode = d_inode(entry);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700807 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +0100808 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700809
810 memset(&inarg, 0, sizeof(inarg));
811 inarg.oldnodeid = get_node_id(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +0100812 args.in.h.opcode = FUSE_LINK;
813 args.in.numargs = 2;
814 args.in.args[0].size = sizeof(inarg);
815 args.in.args[0].value = &inarg;
816 args.in.args[1].size = newent->d_name.len + 1;
817 args.in.args[1].value = newent->d_name.name;
818 err = create_new_entry(fc, &args, newdir, newent, inode->i_mode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700819 /* Contrary to "normal" filesystems it can happen that link
820 makes two "logical" inodes point to the same "physical"
821 inode. We invalidate the attributes of the old one, so it
822 will reflect changes in the backing inode (link count,
823 etc.)
824 */
Miklos Szerediac45d612012-03-05 15:48:11 +0100825 if (!err) {
826 struct fuse_inode *fi = get_fuse_inode(inode);
827
828 spin_lock(&fc->lock);
829 fi->attr_version = ++fc->attr_version;
830 inc_nlink(inode);
831 spin_unlock(&fc->lock);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700832 fuse_invalidate_attr(inode);
Maxim Patlasov31f32672014-04-28 14:19:24 +0200833 fuse_update_ctime(inode);
Miklos Szerediac45d612012-03-05 15:48:11 +0100834 } else if (err == -EINTR) {
835 fuse_invalidate_attr(inode);
836 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -0700837 return err;
838}
839
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700840static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
841 struct kstat *stat)
842{
Miklos Szeredi203627b2012-05-10 19:49:38 +0400843 unsigned int blkbits;
Pavel Emelyanov83732002013-10-10 17:10:46 +0400844 struct fuse_conn *fc = get_fuse_conn(inode);
845
846 /* see the comment in fuse_change_attributes() */
Maxim Patlasovb0aa7602013-12-26 19:51:11 +0400847 if (fc->writeback_cache && S_ISREG(inode->i_mode)) {
Pavel Emelyanov83732002013-10-10 17:10:46 +0400848 attr->size = i_size_read(inode);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +0400849 attr->mtime = inode->i_mtime.tv_sec;
850 attr->mtimensec = inode->i_mtime.tv_nsec;
Maxim Patlasov31f32672014-04-28 14:19:24 +0200851 attr->ctime = inode->i_ctime.tv_sec;
852 attr->ctimensec = inode->i_ctime.tv_nsec;
Maxim Patlasovb0aa7602013-12-26 19:51:11 +0400853 }
Miklos Szeredi203627b2012-05-10 19:49:38 +0400854
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700855 stat->dev = inode->i_sb->s_dev;
856 stat->ino = attr->ino;
857 stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
858 stat->nlink = attr->nlink;
Eric W. Biederman8cb08322018-02-21 11:18:07 -0600859 stat->uid = make_kuid(fc->user_ns, attr->uid);
860 stat->gid = make_kgid(fc->user_ns, attr->gid);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700861 stat->rdev = inode->i_rdev;
862 stat->atime.tv_sec = attr->atime;
863 stat->atime.tv_nsec = attr->atimensec;
864 stat->mtime.tv_sec = attr->mtime;
865 stat->mtime.tv_nsec = attr->mtimensec;
866 stat->ctime.tv_sec = attr->ctime;
867 stat->ctime.tv_nsec = attr->ctimensec;
868 stat->size = attr->size;
869 stat->blocks = attr->blocks;
Miklos Szeredi203627b2012-05-10 19:49:38 +0400870
871 if (attr->blksize != 0)
872 blkbits = ilog2(attr->blksize);
873 else
874 blkbits = inode->i_sb->s_blocksize_bits;
875
876 stat->blksize = 1 << blkbits;
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700877}
878
Miklos Szeredic79e3222007-10-18 03:06:59 -0700879static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
880 struct file *file)
Miklos Szeredie5e55582005-09-09 13:10:28 -0700881{
882 int err;
Miklos Szeredic79e3222007-10-18 03:06:59 -0700883 struct fuse_getattr_in inarg;
884 struct fuse_attr_out outarg;
Miklos Szeredie5e55582005-09-09 13:10:28 -0700885 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +0100886 FUSE_ARGS(args);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700887 u64 attr_version;
888
Miklos Szeredi7dca9fd2007-11-28 16:21:59 -0800889 attr_version = fuse_get_attr_version(fc);
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700890
Miklos Szeredic79e3222007-10-18 03:06:59 -0700891 memset(&inarg, 0, sizeof(inarg));
Miklos Szeredi0e9663e2007-10-18 03:07:05 -0700892 memset(&outarg, 0, sizeof(outarg));
Miklos Szeredic79e3222007-10-18 03:06:59 -0700893 /* Directories have separate file-handle space */
894 if (file && S_ISREG(inode->i_mode)) {
895 struct fuse_file *ff = file->private_data;
896
897 inarg.getattr_flags |= FUSE_GETATTR_FH;
898 inarg.fh = ff->fh;
899 }
Miklos Szeredi70781872014-12-12 09:49:05 +0100900 args.in.h.opcode = FUSE_GETATTR;
901 args.in.h.nodeid = get_node_id(inode);
902 args.in.numargs = 1;
903 args.in.args[0].size = sizeof(inarg);
904 args.in.args[0].value = &inarg;
905 args.out.numargs = 1;
Miklos Szeredi21f62172015-01-06 10:45:35 +0100906 args.out.args[0].size = sizeof(outarg);
Miklos Szeredi70781872014-12-12 09:49:05 +0100907 args.out.args[0].value = &outarg;
908 err = fuse_simple_request(fc, &args);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700909 if (!err) {
Miklos Szeredic79e3222007-10-18 03:06:59 -0700910 if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
Miklos Szeredie5e55582005-09-09 13:10:28 -0700911 make_bad_inode(inode);
912 err = -EIO;
913 } else {
Miklos Szeredic79e3222007-10-18 03:06:59 -0700914 fuse_change_attributes(inode, &outarg.attr,
915 attr_timeout(&outarg),
Miklos Szeredi1fb69e72007-10-18 03:06:58 -0700916 attr_version);
917 if (stat)
Miklos Szeredic79e3222007-10-18 03:06:59 -0700918 fuse_fillattr(inode, &outarg.attr, stat);
Miklos Szeredie5e55582005-09-09 13:10:28 -0700919 }
920 }
921 return err;
922}
923
Miklos Szeredi5b97eea2017-09-12 16:57:54 +0200924static int fuse_update_get_attr(struct inode *inode, struct file *file,
Miklos Szeredi2f1e8192018-10-15 15:43:06 +0200925 struct kstat *stat, u32 request_mask,
926 unsigned int flags)
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800927{
928 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredi5b97eea2017-09-12 16:57:54 +0200929 int err = 0;
Miklos Szeredibf5c1892018-03-20 17:11:44 +0100930 bool sync;
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800931
Miklos Szeredibf5c1892018-03-20 17:11:44 +0100932 if (flags & AT_STATX_FORCE_SYNC)
933 sync = true;
934 else if (flags & AT_STATX_DONT_SYNC)
935 sync = false;
Miklos Szeredi2f1e8192018-10-15 15:43:06 +0200936 else if (request_mask & READ_ONCE(fi->inval_mask))
937 sync = true;
Miklos Szeredibf5c1892018-03-20 17:11:44 +0100938 else
939 sync = time_before64(fi->i_time, get_jiffies_64());
940
941 if (sync) {
Seth Forshee60bcc882016-08-29 08:46:37 -0500942 forget_all_cached_acls(inode);
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800943 err = fuse_do_getattr(inode, stat, file);
Miklos Szeredi5b97eea2017-09-12 16:57:54 +0200944 } else if (stat) {
945 generic_fillattr(inode, stat);
946 stat->mode = fi->orig_i_mode;
947 stat->ino = fi->orig_ino;
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800948 }
949
Miklos Szeredibcb4be82007-11-28 16:21:59 -0800950 return err;
951}
952
Miklos Szeredi5b97eea2017-09-12 16:57:54 +0200953int fuse_update_attributes(struct inode *inode, struct file *file)
954{
Miklos Szeredi2f1e8192018-10-15 15:43:06 +0200955 return fuse_update_get_attr(inode, file, NULL, STATX_BASIC_STATS, 0);
Miklos Szeredi5b97eea2017-09-12 16:57:54 +0200956}
957
John Muir3b463ae2009-05-31 11:13:57 -0400958int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid,
John Muir451d0f52011-12-06 21:50:06 +0100959 u64 child_nodeid, struct qstr *name)
John Muir3b463ae2009-05-31 11:13:57 -0400960{
961 int err = -ENOTDIR;
962 struct inode *parent;
963 struct dentry *dir;
964 struct dentry *entry;
965
966 parent = ilookup5(sb, parent_nodeid, fuse_inode_eq, &parent_nodeid);
967 if (!parent)
968 return -ENOENT;
969
Al Viro59551022016-01-22 15:40:57 -0500970 inode_lock(parent);
John Muir3b463ae2009-05-31 11:13:57 -0400971 if (!S_ISDIR(parent->i_mode))
972 goto unlock;
973
974 err = -ENOENT;
975 dir = d_find_alias(parent);
976 if (!dir)
977 goto unlock;
978
Linus Torvalds8387ff22016-06-10 07:51:30 -0700979 name->hash = full_name_hash(dir, name->name, name->len);
John Muir3b463ae2009-05-31 11:13:57 -0400980 entry = d_lookup(dir, name);
981 dput(dir);
982 if (!entry)
983 goto unlock;
984
Miklos Szeredi261aaba72018-10-01 10:07:05 +0200985 fuse_dir_changed(parent);
John Muir3b463ae2009-05-31 11:13:57 -0400986 fuse_invalidate_entry(entry);
John Muir451d0f52011-12-06 21:50:06 +0100987
David Howells2b0143b2015-03-17 22:25:59 +0000988 if (child_nodeid != 0 && d_really_is_positive(entry)) {
Al Viro59551022016-01-22 15:40:57 -0500989 inode_lock(d_inode(entry));
David Howells2b0143b2015-03-17 22:25:59 +0000990 if (get_node_id(d_inode(entry)) != child_nodeid) {
John Muir451d0f52011-12-06 21:50:06 +0100991 err = -ENOENT;
992 goto badentry;
993 }
994 if (d_mountpoint(entry)) {
995 err = -EBUSY;
996 goto badentry;
997 }
David Howellse36cb0b2015-01-29 12:02:35 +0000998 if (d_is_dir(entry)) {
John Muir451d0f52011-12-06 21:50:06 +0100999 shrink_dcache_parent(entry);
1000 if (!simple_empty(entry)) {
1001 err = -ENOTEMPTY;
1002 goto badentry;
1003 }
David Howells2b0143b2015-03-17 22:25:59 +00001004 d_inode(entry)->i_flags |= S_DEAD;
John Muir451d0f52011-12-06 21:50:06 +01001005 }
1006 dont_mount(entry);
David Howells2b0143b2015-03-17 22:25:59 +00001007 clear_nlink(d_inode(entry));
John Muir451d0f52011-12-06 21:50:06 +01001008 err = 0;
1009 badentry:
Al Viro59551022016-01-22 15:40:57 -05001010 inode_unlock(d_inode(entry));
John Muir451d0f52011-12-06 21:50:06 +01001011 if (!err)
1012 d_delete(entry);
1013 } else {
1014 err = 0;
1015 }
John Muir3b463ae2009-05-31 11:13:57 -04001016 dput(entry);
John Muir3b463ae2009-05-31 11:13:57 -04001017
1018 unlock:
Al Viro59551022016-01-22 15:40:57 -05001019 inode_unlock(parent);
John Muir3b463ae2009-05-31 11:13:57 -04001020 iput(parent);
1021 return err;
1022}
1023
Miklos Szeredi87729a52005-09-09 13:10:34 -07001024/*
1025 * Calling into a user-controlled filesystem gives the filesystem
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001026 * daemon ptrace-like capabilities over the current process. This
Miklos Szeredi87729a52005-09-09 13:10:34 -07001027 * means, that the filesystem daemon is able to record the exact
1028 * filesystem operations performed, and can also control the behavior
1029 * of the requester process in otherwise impossible ways. For example
1030 * it can delay the operation for arbitrary length of time allowing
1031 * DoS against the requester.
1032 *
1033 * For this reason only those processes can call into the filesystem,
1034 * for which the owner of the mount has ptrace privilege. This
1035 * excludes processes started by other users, suid or sgid processes.
1036 */
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001037int fuse_allow_current_process(struct fuse_conn *fc)
Miklos Szeredi87729a52005-09-09 13:10:34 -07001038{
David Howellsc69e8d92008-11-14 10:39:19 +11001039 const struct cred *cred;
David Howellsc69e8d92008-11-14 10:39:19 +11001040
Miklos Szeredi29433a22016-10-01 07:32:32 +02001041 if (fc->allow_other)
Seth Forshee73f03c22017-12-22 15:32:33 +01001042 return current_in_userns(fc->user_ns);
Miklos Szeredi87729a52005-09-09 13:10:34 -07001043
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001044 cred = current_cred();
Eric W. Biederman499dcf22012-02-07 16:26:03 -08001045 if (uid_eq(cred->euid, fc->user_id) &&
1046 uid_eq(cred->suid, fc->user_id) &&
1047 uid_eq(cred->uid, fc->user_id) &&
1048 gid_eq(cred->egid, fc->group_id) &&
1049 gid_eq(cred->sgid, fc->group_id) &&
1050 gid_eq(cred->gid, fc->group_id))
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001051 return 1;
Miklos Szeredi87729a52005-09-09 13:10:34 -07001052
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001053 return 0;
Miklos Szeredi87729a52005-09-09 13:10:34 -07001054}
1055
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001056static int fuse_access(struct inode *inode, int mask)
1057{
1058 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001059 FUSE_ARGS(args);
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001060 struct fuse_access_in inarg;
1061 int err;
1062
Miklos Szeredi698fa1d2013-10-01 16:41:23 +02001063 BUG_ON(mask & MAY_NOT_BLOCK);
1064
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001065 if (fc->no_access)
1066 return 0;
1067
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001068 memset(&inarg, 0, sizeof(inarg));
Al Viroe6305c42008-07-15 21:03:57 -04001069 inarg.mask = mask & (MAY_READ | MAY_WRITE | MAY_EXEC);
Miklos Szeredi70781872014-12-12 09:49:05 +01001070 args.in.h.opcode = FUSE_ACCESS;
1071 args.in.h.nodeid = get_node_id(inode);
1072 args.in.numargs = 1;
1073 args.in.args[0].size = sizeof(inarg);
1074 args.in.args[0].value = &inarg;
1075 err = fuse_simple_request(fc, &args);
Miklos Szeredi31d40d72005-11-07 00:59:50 -08001076 if (err == -ENOSYS) {
1077 fc->no_access = 1;
1078 err = 0;
1079 }
1080 return err;
1081}
1082
Al Viro10556cb22011-06-20 19:28:19 -04001083static int fuse_perm_getattr(struct inode *inode, int mask)
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001084{
Al Viro10556cb22011-06-20 19:28:19 -04001085 if (mask & MAY_NOT_BLOCK)
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001086 return -ECHILD;
1087
Seth Forshee60bcc882016-08-29 08:46:37 -05001088 forget_all_cached_acls(inode);
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001089 return fuse_do_getattr(inode, NULL, NULL);
1090}
1091
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001092/*
1093 * Check permission. The two basic access models of FUSE are:
1094 *
1095 * 1) Local access checking ('default_permissions' mount option) based
1096 * on file mode. This is the plain old disk filesystem permission
1097 * modell.
1098 *
1099 * 2) "Remote" access checking, where server is responsible for
1100 * checking permission in each inode operation. An exception to this
1101 * is if ->permission() was invoked from sys_access() in which case an
1102 * access request is sent. Execute permission is still checked
1103 * locally based on file mode.
1104 */
Al Viro10556cb22011-06-20 19:28:19 -04001105static int fuse_permission(struct inode *inode, int mask)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001106{
1107 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi244f6382007-10-16 23:31:02 -07001108 bool refreshed = false;
1109 int err = 0;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001110
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001111 if (!fuse_allow_current_process(fc))
Miklos Szeredie5e55582005-09-09 13:10:28 -07001112 return -EACCES;
Miklos Szeredi244f6382007-10-16 23:31:02 -07001113
1114 /*
Miklos Szeredie8e96152007-10-16 23:31:06 -07001115 * If attributes are needed, refresh them before proceeding
Miklos Szeredi244f6382007-10-16 23:31:02 -07001116 */
Miklos Szeredi29433a22016-10-01 07:32:32 +02001117 if (fc->default_permissions ||
Miklos Szeredie8e96152007-10-16 23:31:06 -07001118 ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) {
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001119 struct fuse_inode *fi = get_fuse_inode(inode);
1120
Miklos Szeredi126b9d42014-07-07 15:28:50 +02001121 if (time_before64(fi->i_time, get_jiffies_64())) {
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001122 refreshed = true;
1123
Al Viro10556cb22011-06-20 19:28:19 -04001124 err = fuse_perm_getattr(inode, mask);
Miklos Szeredi19690dd2011-03-21 13:58:06 +01001125 if (err)
1126 return err;
1127 }
Miklos Szeredi244f6382007-10-16 23:31:02 -07001128 }
1129
Miklos Szeredi29433a22016-10-01 07:32:32 +02001130 if (fc->default_permissions) {
Al Viro2830ba72011-06-20 19:16:29 -04001131 err = generic_permission(inode, mask);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001132
1133 /* If permission is denied, try to refresh file
1134 attributes. This is also needed, because the root
1135 node will at first have no permissions */
Miklos Szeredi244f6382007-10-16 23:31:02 -07001136 if (err == -EACCES && !refreshed) {
Al Viro10556cb22011-06-20 19:28:19 -04001137 err = fuse_perm_getattr(inode, mask);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001138 if (!err)
Al Viro2830ba72011-06-20 19:16:29 -04001139 err = generic_permission(inode, mask);
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001140 }
1141
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001142 /* Note: the opposite of the above test does not
1143 exist. So if permissions are revoked this won't be
1144 noticed immediately, only after the attribute
1145 timeout has expired */
Eric Paris9cfcac82010-07-23 11:43:51 -04001146 } else if (mask & (MAY_ACCESS | MAY_CHDIR)) {
Miklos Szeredie8e96152007-10-16 23:31:06 -07001147 err = fuse_access(inode, mask);
1148 } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
1149 if (!(inode->i_mode & S_IXUGO)) {
1150 if (refreshed)
1151 return -EACCES;
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001152
Al Viro10556cb22011-06-20 19:28:19 -04001153 err = fuse_perm_getattr(inode, mask);
Miklos Szeredie8e96152007-10-16 23:31:06 -07001154 if (!err && !(inode->i_mode & S_IXUGO))
1155 return -EACCES;
1156 }
Miklos Szeredie5e55582005-09-09 13:10:28 -07001157 }
Miklos Szeredi244f6382007-10-16 23:31:02 -07001158 return err;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001159}
1160
Al Viro6b255392015-11-17 10:20:54 -05001161static const char *fuse_get_link(struct dentry *dentry,
Al Virofceef392015-12-29 15:58:39 -05001162 struct inode *inode,
1163 struct delayed_call *done)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001164{
Miklos Szeredie5e55582005-09-09 13:10:28 -07001165 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001166 FUSE_ARGS(args);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001167 char *link;
Miklos Szeredi70781872014-12-12 09:49:05 +01001168 ssize_t ret;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001169
Al Viro6b255392015-11-17 10:20:54 -05001170 if (!dentry)
1171 return ERR_PTR(-ECHILD);
1172
Al Virocd3417c2015-12-29 16:03:53 -05001173 link = kmalloc(PAGE_SIZE, GFP_KERNEL);
Miklos Szeredi70781872014-12-12 09:49:05 +01001174 if (!link)
1175 return ERR_PTR(-ENOMEM);
1176
1177 args.in.h.opcode = FUSE_READLINK;
1178 args.in.h.nodeid = get_node_id(inode);
1179 args.out.argvar = 1;
1180 args.out.numargs = 1;
1181 args.out.args[0].size = PAGE_SIZE - 1;
1182 args.out.args[0].value = link;
1183 ret = fuse_simple_request(fc, &args);
1184 if (ret < 0) {
Al Virocd3417c2015-12-29 16:03:53 -05001185 kfree(link);
Miklos Szeredi70781872014-12-12 09:49:05 +01001186 link = ERR_PTR(ret);
1187 } else {
1188 link[ret] = '\0';
Al Virofceef392015-12-29 15:58:39 -05001189 set_delayed_call(done, kfree_link, link);
Miklos Szeredi70781872014-12-12 09:49:05 +01001190 }
Andrew Gallagher451418f2013-11-05 03:55:43 -08001191 fuse_invalidate_atime(inode);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001192 return link;
1193}
1194
Miklos Szeredie5e55582005-09-09 13:10:28 -07001195static int fuse_dir_open(struct inode *inode, struct file *file)
1196{
Miklos Szeredi91fe96b2009-04-28 16:56:37 +02001197 return fuse_open_common(inode, file, true);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001198}
1199
1200static int fuse_dir_release(struct inode *inode, struct file *file)
1201{
Miklos Szeredi8b0797a2009-04-28 16:56:39 +02001202 fuse_release_common(file, FUSE_RELEASEDIR);
1203
1204 return 0;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001205}
1206
Josef Bacik02c24a82011-07-16 20:44:56 -04001207static int fuse_dir_fsync(struct file *file, loff_t start, loff_t end,
1208 int datasync)
Miklos Szeredi82547982005-09-09 13:10:38 -07001209{
Josef Bacik02c24a82011-07-16 20:44:56 -04001210 return fuse_fsync_common(file, start, end, datasync, 1);
Miklos Szeredi82547982005-09-09 13:10:38 -07001211}
1212
Miklos Szeredib18da0c2011-12-13 11:58:49 +01001213static long fuse_dir_ioctl(struct file *file, unsigned int cmd,
1214 unsigned long arg)
1215{
1216 struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1217
1218 /* FUSE_IOCTL_DIR only supported for API version >= 7.18 */
1219 if (fc->minor < 18)
1220 return -ENOTTY;
1221
1222 return fuse_ioctl_common(file, cmd, arg, FUSE_IOCTL_DIR);
1223}
1224
1225static long fuse_dir_compat_ioctl(struct file *file, unsigned int cmd,
1226 unsigned long arg)
1227{
1228 struct fuse_conn *fc = get_fuse_conn(file->f_mapping->host);
1229
1230 if (fc->minor < 18)
1231 return -ENOTTY;
1232
1233 return fuse_ioctl_common(file, cmd, arg,
1234 FUSE_IOCTL_COMPAT | FUSE_IOCTL_DIR);
1235}
1236
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001237static bool update_mtime(unsigned ivalid, bool trust_local_mtime)
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001238{
1239 /* Always update if mtime is explicitly set */
1240 if (ivalid & ATTR_MTIME_SET)
1241 return true;
1242
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001243 /* Or if kernel i_mtime is the official one */
1244 if (trust_local_mtime)
1245 return true;
1246
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001247 /* If it's an open(O_TRUNC) or an ftruncate(), don't update */
1248 if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE)))
1249 return false;
1250
1251 /* In all other cases update */
1252 return true;
1253}
1254
Eric W. Biederman8cb08322018-02-21 11:18:07 -06001255static void iattr_to_fattr(struct fuse_conn *fc, struct iattr *iattr,
1256 struct fuse_setattr_in *arg, bool trust_local_cmtime)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001257{
1258 unsigned ivalid = iattr->ia_valid;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001259
1260 if (ivalid & ATTR_MODE)
Miklos Szeredibefc6492005-11-07 00:59:52 -08001261 arg->valid |= FATTR_MODE, arg->mode = iattr->ia_mode;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001262 if (ivalid & ATTR_UID)
Eric W. Biederman8cb08322018-02-21 11:18:07 -06001263 arg->valid |= FATTR_UID, arg->uid = from_kuid(fc->user_ns, iattr->ia_uid);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001264 if (ivalid & ATTR_GID)
Eric W. Biederman8cb08322018-02-21 11:18:07 -06001265 arg->valid |= FATTR_GID, arg->gid = from_kgid(fc->user_ns, iattr->ia_gid);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001266 if (ivalid & ATTR_SIZE)
Miklos Szeredibefc6492005-11-07 00:59:52 -08001267 arg->valid |= FATTR_SIZE, arg->size = iattr->ia_size;
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001268 if (ivalid & ATTR_ATIME) {
1269 arg->valid |= FATTR_ATIME;
Miklos Szeredibefc6492005-11-07 00:59:52 -08001270 arg->atime = iattr->ia_atime.tv_sec;
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001271 arg->atimensec = iattr->ia_atime.tv_nsec;
1272 if (!(ivalid & ATTR_ATIME_SET))
1273 arg->valid |= FATTR_ATIME_NOW;
1274 }
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001275 if ((ivalid & ATTR_MTIME) && update_mtime(ivalid, trust_local_cmtime)) {
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001276 arg->valid |= FATTR_MTIME;
Miklos Szeredibefc6492005-11-07 00:59:52 -08001277 arg->mtime = iattr->ia_mtime.tv_sec;
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001278 arg->mtimensec = iattr->ia_mtime.tv_nsec;
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001279 if (!(ivalid & ATTR_MTIME_SET) && !trust_local_cmtime)
Miklos Szeredi17637cb2007-10-18 03:07:01 -07001280 arg->valid |= FATTR_MTIME_NOW;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001281 }
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001282 if ((ivalid & ATTR_CTIME) && trust_local_cmtime) {
1283 arg->valid |= FATTR_CTIME;
1284 arg->ctime = iattr->ia_ctime.tv_sec;
1285 arg->ctimensec = iattr->ia_ctime.tv_nsec;
1286 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001287}
1288
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001289/*
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001290 * Prevent concurrent writepages on inode
1291 *
1292 * This is done by adding a negative bias to the inode write counter
1293 * and waiting for all pending writes to finish.
1294 */
1295void fuse_set_nowrite(struct inode *inode)
1296{
1297 struct fuse_conn *fc = get_fuse_conn(inode);
1298 struct fuse_inode *fi = get_fuse_inode(inode);
1299
Al Viro59551022016-01-22 15:40:57 -05001300 BUG_ON(!inode_is_locked(inode));
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001301
1302 spin_lock(&fc->lock);
1303 BUG_ON(fi->writectr < 0);
1304 fi->writectr += FUSE_NOWRITE;
1305 spin_unlock(&fc->lock);
1306 wait_event(fi->page_waitq, fi->writectr == FUSE_NOWRITE);
1307}
1308
1309/*
1310 * Allow writepages on inode
1311 *
1312 * Remove the bias from the writecounter and send any queued
1313 * writepages.
1314 */
1315static void __fuse_release_nowrite(struct inode *inode)
1316{
1317 struct fuse_inode *fi = get_fuse_inode(inode);
1318
1319 BUG_ON(fi->writectr != FUSE_NOWRITE);
1320 fi->writectr = 0;
1321 fuse_flush_writepages(inode);
1322}
1323
1324void fuse_release_nowrite(struct inode *inode)
1325{
1326 struct fuse_conn *fc = get_fuse_conn(inode);
1327
1328 spin_lock(&fc->lock);
1329 __fuse_release_nowrite(inode);
1330 spin_unlock(&fc->lock);
1331}
1332
Miklos Szeredi70781872014-12-12 09:49:05 +01001333static void fuse_setattr_fill(struct fuse_conn *fc, struct fuse_args *args,
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001334 struct inode *inode,
1335 struct fuse_setattr_in *inarg_p,
1336 struct fuse_attr_out *outarg_p)
1337{
Miklos Szeredi70781872014-12-12 09:49:05 +01001338 args->in.h.opcode = FUSE_SETATTR;
1339 args->in.h.nodeid = get_node_id(inode);
1340 args->in.numargs = 1;
1341 args->in.args[0].size = sizeof(*inarg_p);
1342 args->in.args[0].value = inarg_p;
1343 args->out.numargs = 1;
Miklos Szeredi21f62172015-01-06 10:45:35 +01001344 args->out.args[0].size = sizeof(*outarg_p);
Miklos Szeredi70781872014-12-12 09:49:05 +01001345 args->out.args[0].value = outarg_p;
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001346}
1347
1348/*
1349 * Flush inode->i_mtime to the server
1350 */
Maxim Patlasovab9e13f2014-04-28 14:19:24 +02001351int fuse_flush_times(struct inode *inode, struct fuse_file *ff)
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001352{
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001353 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001354 FUSE_ARGS(args);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001355 struct fuse_setattr_in inarg;
1356 struct fuse_attr_out outarg;
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001357
1358 memset(&inarg, 0, sizeof(inarg));
1359 memset(&outarg, 0, sizeof(outarg));
1360
Maxim Patlasovab9e13f2014-04-28 14:19:24 +02001361 inarg.valid = FATTR_MTIME;
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001362 inarg.mtime = inode->i_mtime.tv_sec;
1363 inarg.mtimensec = inode->i_mtime.tv_nsec;
Maxim Patlasovab9e13f2014-04-28 14:19:24 +02001364 if (fc->minor >= 23) {
1365 inarg.valid |= FATTR_CTIME;
1366 inarg.ctime = inode->i_ctime.tv_sec;
1367 inarg.ctimensec = inode->i_ctime.tv_nsec;
1368 }
Miklos Szeredi1e18bda2014-04-28 14:19:23 +02001369 if (ff) {
1370 inarg.valid |= FATTR_FH;
1371 inarg.fh = ff->fh;
1372 }
Miklos Szeredi70781872014-12-12 09:49:05 +01001373 fuse_setattr_fill(fc, &args, inode, &inarg, &outarg);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001374
Miklos Szeredi70781872014-12-12 09:49:05 +01001375 return fuse_simple_request(fc, &args);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001376}
1377
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001378/*
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001379 * Set attributes, and at the same time refresh them.
1380 *
1381 * Truncation is slightly complicated, because the 'truncate' request
1382 * may fail, in which case we don't want to touch the mapping.
Miklos Szeredi9ffbb912006-10-17 00:10:06 -07001383 * vmtruncate() doesn't allow for this case, so do the rlimit checking
1384 * and the actual truncation by hand.
Miklos Szeredi6f9f1182006-01-06 00:19:39 -08001385 */
Jan Kara62490332016-05-26 17:12:41 +02001386int fuse_do_setattr(struct dentry *dentry, struct iattr *attr,
Maxim Patlasovefb9fa92012-12-18 14:05:08 +04001387 struct file *file)
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001388{
Jan Kara62490332016-05-26 17:12:41 +02001389 struct inode *inode = d_inode(dentry);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001390 struct fuse_conn *fc = get_fuse_conn(inode);
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001391 struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredi70781872014-12-12 09:49:05 +01001392 FUSE_ARGS(args);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001393 struct fuse_setattr_in inarg;
1394 struct fuse_attr_out outarg;
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001395 bool is_truncate = false;
Pavel Emelyanov83732002013-10-10 17:10:46 +04001396 bool is_wb = fc->writeback_cache;
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001397 loff_t oldsize;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001398 int err;
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001399 bool trust_local_cmtime = is_wb && S_ISREG(inode->i_mode);
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001400
Miklos Szeredi29433a22016-10-01 07:32:32 +02001401 if (!fc->default_permissions)
Christoph Hellwigdb78b872010-06-04 11:30:03 +02001402 attr->ia_valid |= ATTR_FORCE;
1403
Jan Kara31051c82016-05-26 16:55:18 +02001404 err = setattr_prepare(dentry, attr);
Christoph Hellwigdb78b872010-06-04 11:30:03 +02001405 if (err)
1406 return err;
Miklos Szeredi1e9a4ed2005-09-09 13:10:31 -07001407
Miklos Szeredi8d56add2011-02-25 14:44:58 +01001408 if (attr->ia_valid & ATTR_OPEN) {
Miklos Szeredidf0e91d2018-02-08 15:17:38 +01001409 /* This is coming from open(..., ... | O_TRUNC); */
1410 WARN_ON(!(attr->ia_valid & ATTR_SIZE));
1411 WARN_ON(attr->ia_size != 0);
1412 if (fc->atomic_o_trunc) {
1413 /*
1414 * No need to send request to userspace, since actual
1415 * truncation has already been done by OPEN. But still
1416 * need to truncate page cache.
1417 */
1418 i_size_write(inode, 0);
1419 truncate_pagecache(inode, 0);
Miklos Szeredi8d56add2011-02-25 14:44:58 +01001420 return 0;
Miklos Szeredidf0e91d2018-02-08 15:17:38 +01001421 }
Miklos Szeredi8d56add2011-02-25 14:44:58 +01001422 file = NULL;
1423 }
Miklos Szeredi6ff958e2007-10-18 03:07:02 -07001424
Miklos Szerediab2257e2018-10-01 10:07:05 +02001425 if (attr->ia_valid & ATTR_SIZE) {
1426 if (WARN_ON(!S_ISREG(inode->i_mode)))
1427 return -EIO;
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001428 is_truncate = true;
Miklos Szerediab2257e2018-10-01 10:07:05 +02001429 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001430
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001431 if (is_truncate) {
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001432 fuse_set_nowrite(inode);
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001433 set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001434 if (trust_local_cmtime && attr->ia_size != inode->i_size)
1435 attr->ia_valid |= ATTR_MTIME | ATTR_CTIME;
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001436 }
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001437
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001438 memset(&inarg, 0, sizeof(inarg));
Miklos Szeredi0e9663e2007-10-18 03:07:05 -07001439 memset(&outarg, 0, sizeof(outarg));
Eric W. Biederman8cb08322018-02-21 11:18:07 -06001440 iattr_to_fattr(fc, attr, &inarg, trust_local_cmtime);
Miklos Szeredi49d49142007-10-18 03:07:00 -07001441 if (file) {
1442 struct fuse_file *ff = file->private_data;
1443 inarg.valid |= FATTR_FH;
1444 inarg.fh = ff->fh;
1445 }
Miklos Szeredif3332112007-10-18 03:07:04 -07001446 if (attr->ia_valid & ATTR_SIZE) {
1447 /* For mandatory locking in truncate */
1448 inarg.valid |= FATTR_LOCKOWNER;
1449 inarg.lock_owner = fuse_lock_owner_id(fc, current->files);
1450 }
Miklos Szeredi70781872014-12-12 09:49:05 +01001451 fuse_setattr_fill(fc, &args, inode, &inarg, &outarg);
1452 err = fuse_simple_request(fc, &args);
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001453 if (err) {
1454 if (err == -EINTR)
1455 fuse_invalidate_attr(inode);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001456 goto error;
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001457 }
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001458
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001459 if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
1460 make_bad_inode(inode);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001461 err = -EIO;
1462 goto error;
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001463 }
1464
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001465 spin_lock(&fc->lock);
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001466 /* the kernel maintains i_mtime locally */
Maxim Patlasov3ad22c62014-04-28 14:19:25 +02001467 if (trust_local_cmtime) {
1468 if (attr->ia_valid & ATTR_MTIME)
1469 inode->i_mtime = attr->ia_mtime;
1470 if (attr->ia_valid & ATTR_CTIME)
1471 inode->i_ctime = attr->ia_ctime;
Miklos Szeredi1e18bda2014-04-28 14:19:23 +02001472 /* FIXME: clear I_DIRTY_SYNC? */
Maxim Patlasovb0aa7602013-12-26 19:51:11 +04001473 }
1474
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001475 fuse_change_attributes_common(inode, &outarg.attr,
1476 attr_timeout(&outarg));
1477 oldsize = inode->i_size;
Pavel Emelyanov83732002013-10-10 17:10:46 +04001478 /* see the comment in fuse_change_attributes() */
1479 if (!is_wb || is_truncate || !S_ISREG(inode->i_mode))
1480 i_size_write(inode, outarg.attr.size);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001481
1482 if (is_truncate) {
1483 /* NOTE: this may release/reacquire fc->lock */
1484 __fuse_release_nowrite(inode);
1485 }
1486 spin_unlock(&fc->lock);
1487
1488 /*
1489 * Only call invalidate_inode_pages2() after removing
1490 * FUSE_NOWRITE, otherwise fuse_launder_page() would deadlock.
1491 */
Pavel Emelyanov83732002013-10-10 17:10:46 +04001492 if ((is_truncate || !is_wb) &&
1493 S_ISREG(inode->i_mode) && oldsize != outarg.attr.size) {
Kirill A. Shutemov7caef262013-09-12 15:13:56 -07001494 truncate_pagecache(inode, outarg.attr.size);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001495 invalidate_inode_pages2(inode->i_mapping);
1496 }
1497
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001498 clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
Miklos Szeredie00d2c22007-10-16 23:31:01 -07001499 return 0;
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001500
1501error:
1502 if (is_truncate)
1503 fuse_release_nowrite(inode);
1504
Maxim Patlasov06a7c3c2013-08-30 17:06:04 +04001505 clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
Miklos Szeredi3be5a522008-04-30 00:54:41 -07001506 return err;
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001507}
1508
Miklos Szeredi49d49142007-10-18 03:07:00 -07001509static int fuse_setattr(struct dentry *entry, struct iattr *attr)
1510{
David Howells2b0143b2015-03-17 22:25:59 +00001511 struct inode *inode = d_inode(entry);
Miklos Szeredi5e940c12016-10-01 07:32:32 +02001512 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredia09f99e2016-10-01 07:32:32 +02001513 struct file *file = (attr->ia_valid & ATTR_FILE) ? attr->ia_file : NULL;
Miklos Szeredi5e2b8822016-10-01 07:32:32 +02001514 int ret;
Maxim Patlasovefb9fa92012-12-18 14:05:08 +04001515
1516 if (!fuse_allow_current_process(get_fuse_conn(inode)))
1517 return -EACCES;
1518
Miklos Szeredia09f99e2016-10-01 07:32:32 +02001519 if (attr->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) {
Miklos Szeredia09f99e2016-10-01 07:32:32 +02001520 attr->ia_valid &= ~(ATTR_KILL_SUID | ATTR_KILL_SGID |
1521 ATTR_MODE);
Miklos Szeredia09f99e2016-10-01 07:32:32 +02001522
Miklos Szeredi5e940c12016-10-01 07:32:32 +02001523 /*
1524 * The only sane way to reliably kill suid/sgid is to do it in
1525 * the userspace filesystem
1526 *
1527 * This should be done on write(), truncate() and chown().
1528 */
1529 if (!fc->handle_killpriv) {
Miklos Szeredi5e940c12016-10-01 07:32:32 +02001530 /*
1531 * ia_mode calculation may have used stale i_mode.
1532 * Refresh and recalculate.
1533 */
1534 ret = fuse_do_getattr(inode, NULL, file);
1535 if (ret)
1536 return ret;
1537
1538 attr->ia_mode = inode->i_mode;
Miklos Szeredic01638f2016-12-06 16:18:45 +01001539 if (inode->i_mode & S_ISUID) {
Miklos Szeredi5e940c12016-10-01 07:32:32 +02001540 attr->ia_valid |= ATTR_MODE;
1541 attr->ia_mode &= ~S_ISUID;
1542 }
Miklos Szeredic01638f2016-12-06 16:18:45 +01001543 if ((inode->i_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
Miklos Szeredi5e940c12016-10-01 07:32:32 +02001544 attr->ia_valid |= ATTR_MODE;
1545 attr->ia_mode &= ~S_ISGID;
1546 }
Miklos Szeredia09f99e2016-10-01 07:32:32 +02001547 }
1548 }
1549 if (!attr->ia_valid)
1550 return 0;
1551
Linus Torvaldsabb5a142016-10-10 13:04:49 -07001552 ret = fuse_do_setattr(entry, attr, file);
Miklos Szeredi5e2b8822016-10-01 07:32:32 +02001553 if (!ret) {
Seth Forshee60bcc882016-08-29 08:46:37 -05001554 /*
1555 * If filesystem supports acls it may have updated acl xattrs in
1556 * the filesystem, so forget cached acls for the inode.
1557 */
1558 if (fc->posix_acl)
1559 forget_all_cached_acls(inode);
1560
Miklos Szeredi5e2b8822016-10-01 07:32:32 +02001561 /* Directory mode changed, may need to revalidate access */
1562 if (d_is_dir(entry) && (attr->ia_valid & ATTR_MODE))
1563 fuse_invalidate_entry_cache(entry);
1564 }
1565 return ret;
Miklos Szeredi49d49142007-10-18 03:07:00 -07001566}
1567
David Howellsa528d352017-01-31 16:46:22 +00001568static int fuse_getattr(const struct path *path, struct kstat *stat,
1569 u32 request_mask, unsigned int flags)
Miklos Szeredie5e55582005-09-09 13:10:28 -07001570{
David Howellsa528d352017-01-31 16:46:22 +00001571 struct inode *inode = d_inode(path->dentry);
Miklos Szeredi244f6382007-10-16 23:31:02 -07001572 struct fuse_conn *fc = get_fuse_conn(inode);
Miklos Szeredi244f6382007-10-16 23:31:02 -07001573
Anatol Pomozovc2132c12013-01-14 22:30:00 -08001574 if (!fuse_allow_current_process(fc))
Miklos Szeredi244f6382007-10-16 23:31:02 -07001575 return -EACCES;
1576
Miklos Szeredi2f1e8192018-10-15 15:43:06 +02001577 return fuse_update_get_attr(inode, NULL, stat, request_mask, flags);
Miklos Szeredie5e55582005-09-09 13:10:28 -07001578}
1579
Arjan van de Ven754661f2007-02-12 00:55:38 -08001580static const struct inode_operations fuse_dir_inode_operations = {
Miklos Szeredie5e55582005-09-09 13:10:28 -07001581 .lookup = fuse_lookup,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001582 .mkdir = fuse_mkdir,
1583 .symlink = fuse_symlink,
1584 .unlink = fuse_unlink,
1585 .rmdir = fuse_rmdir,
Miklos Szeredi2773bf02016-09-27 11:03:58 +02001586 .rename = fuse_rename2,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001587 .link = fuse_link,
1588 .setattr = fuse_setattr,
1589 .create = fuse_create,
Miklos Szeredic8ccbe02012-06-05 15:10:22 +02001590 .atomic_open = fuse_atomic_open,
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001591 .mknod = fuse_mknod,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001592 .permission = fuse_permission,
1593 .getattr = fuse_getattr,
Miklos Szeredi92a87802005-09-09 13:10:31 -07001594 .listxattr = fuse_listxattr,
Seth Forshee60bcc882016-08-29 08:46:37 -05001595 .get_acl = fuse_get_acl,
1596 .set_acl = fuse_set_acl,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001597};
1598
Arjan van de Ven4b6f5d22006-03-28 01:56:42 -08001599static const struct file_operations fuse_dir_operations = {
Miklos Szeredib6aeade2005-09-09 13:10:30 -07001600 .llseek = generic_file_llseek,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001601 .read = generic_read_dir,
Al Virod9b3dbd2016-04-20 17:30:32 -04001602 .iterate_shared = fuse_readdir,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001603 .open = fuse_dir_open,
1604 .release = fuse_dir_release,
Miklos Szeredi82547982005-09-09 13:10:38 -07001605 .fsync = fuse_dir_fsync,
Miklos Szeredib18da0c2011-12-13 11:58:49 +01001606 .unlocked_ioctl = fuse_dir_ioctl,
1607 .compat_ioctl = fuse_dir_compat_ioctl,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001608};
1609
Arjan van de Ven754661f2007-02-12 00:55:38 -08001610static const struct inode_operations fuse_common_inode_operations = {
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001611 .setattr = fuse_setattr,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001612 .permission = fuse_permission,
1613 .getattr = fuse_getattr,
Miklos Szeredi92a87802005-09-09 13:10:31 -07001614 .listxattr = fuse_listxattr,
Seth Forshee60bcc882016-08-29 08:46:37 -05001615 .get_acl = fuse_get_acl,
1616 .set_acl = fuse_set_acl,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001617};
1618
Arjan van de Ven754661f2007-02-12 00:55:38 -08001619static const struct inode_operations fuse_symlink_inode_operations = {
Miklos Szeredi9e6268d2005-09-09 13:10:29 -07001620 .setattr = fuse_setattr,
Al Viro6b255392015-11-17 10:20:54 -05001621 .get_link = fuse_get_link,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001622 .getattr = fuse_getattr,
Miklos Szeredi92a87802005-09-09 13:10:31 -07001623 .listxattr = fuse_listxattr,
Miklos Szeredie5e55582005-09-09 13:10:28 -07001624};
1625
1626void fuse_init_common(struct inode *inode)
1627{
1628 inode->i_op = &fuse_common_inode_operations;
1629}
1630
1631void fuse_init_dir(struct inode *inode)
1632{
Miklos Szerediab2257e2018-10-01 10:07:05 +02001633 struct fuse_inode *fi = get_fuse_inode(inode);
1634
Miklos Szeredie5e55582005-09-09 13:10:28 -07001635 inode->i_op = &fuse_dir_inode_operations;
1636 inode->i_fop = &fuse_dir_operations;
Miklos Szerediab2257e2018-10-01 10:07:05 +02001637
1638 spin_lock_init(&fi->rdc.lock);
1639 fi->rdc.cached = false;
1640 fi->rdc.size = 0;
1641 fi->rdc.pos = 0;
1642 fi->rdc.version = 0;
Miklos Szeredie5e55582005-09-09 13:10:28 -07001643}
1644
1645void fuse_init_symlink(struct inode *inode)
1646{
1647 inode->i_op = &fuse_symlink_inode_operations;
1648}