dir.c 42.4 KB
Newer Older
1
2
/*
  FUSE: Filesystem in Userspace
Miklos Szeredi's avatar
Miklos Szeredi committed
3
  Copyright (C) 2001-2008  Miklos Szeredi <miklos@szeredi.hu>
4
5
6
7
8
9
10
11
12
13
14

  This program can be distributed under the terms of the GNU GPL.
  See the file COPYING.
*/

#include "fuse_i.h"

#include <linux/pagemap.h>
#include <linux/file.h>
#include <linux/sched.h>
#include <linux/namei.h>
15
#include <linux/slab.h>
Seth Forshee's avatar
Seth Forshee committed
16
#include <linux/xattr.h>
17
#include <linux/iversion.h>
Seth Forshee's avatar
Seth Forshee committed
18
#include <linux/posix_acl.h>
19

20
21
22
23
24
25
26
static void fuse_advise_use_readdirplus(struct inode *dir)
{
	struct fuse_inode *fi = get_fuse_inode(dir);

	set_bit(FUSE_I_ADVISE_RDPLUS, &fi->state);
}

Miklos Szeredi's avatar
Miklos Szeredi committed
27
28
29
30
31
union fuse_dentry {
	u64 time;
	struct rcu_head rcu;
};

Miklos Szeredi's avatar
Miklos Szeredi committed
32
33
static inline void fuse_dentry_settime(struct dentry *entry, u64 time)
{
Miklos Szeredi's avatar
Miklos Szeredi committed
34
	((union fuse_dentry *) entry->d_fsdata)->time = time;
Miklos Szeredi's avatar
Miklos Szeredi committed
35
36
37
38
}

static inline u64 fuse_dentry_time(struct dentry *entry)
{
Miklos Szeredi's avatar
Miklos Szeredi committed
39
	return ((union fuse_dentry *) entry->d_fsdata)->time;
Miklos Szeredi's avatar
Miklos Szeredi committed
40
41
}

42
43
44
/*
 * FUSE caches dentries and attributes with separate timeout.  The
 * time in jiffies until the dentry/attributes are valid is stored in
Miklos Szeredi's avatar
Miklos Szeredi committed
45
 * dentry->d_fsdata and fuse_inode->i_time respectively.
46
47
48
49
50
 */

/*
 * Calculate the time in jiffies until a dentry/attributes are valid
 */
Miklos Szeredi's avatar
Miklos Szeredi committed
51
static u64 time_to_jiffies(u64 sec, u32 nsec)
52
{
53
	if (sec || nsec) {
Miklos Szeredi's avatar
Miklos Szeredi committed
54
55
		struct timespec64 ts = {
			sec,
56
			min_t(u32, nsec, NSEC_PER_SEC - 1)
Miklos Szeredi's avatar
Miklos Szeredi committed
57
58
59
		};

		return get_jiffies_64() + timespec64_to_jiffies(&ts);
60
	} else
Miklos Szeredi's avatar
Miklos Szeredi committed
61
		return 0;
62
63
}

64
65
66
67
/*
 * Set dentry and possibly attribute timeouts from the lookup/mk*
 * replies
 */
Miklos Szeredi's avatar
Miklos Szeredi committed
68
void fuse_change_entry_timeout(struct dentry *entry, struct fuse_entry_out *o)
69
{
Miklos Szeredi's avatar
Miklos Szeredi committed
70
71
	fuse_dentry_settime(entry,
		time_to_jiffies(o->entry_valid, o->entry_valid_nsec));
72
73
74
75
76
77
78
}

static u64 attr_timeout(struct fuse_attr_out *o)
{
	return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
}

Miklos Szeredi's avatar
Miklos Szeredi committed
79
u64 entry_attr_timeout(struct fuse_entry_out *o)
80
81
{
	return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
82
83
}

84
85
86
87
88
static void fuse_invalidate_attr_mask(struct inode *inode, u32 mask)
{
	set_mask_bits(&get_fuse_inode(inode)->inval_mask, 0, mask);
}

89
90
91
92
/*
 * Mark the attributes as stale, so that at the next call to
 * ->getattr() they will be fetched from userspace
 */
93
94
void fuse_invalidate_attr(struct inode *inode)
{
95
	fuse_invalidate_attr_mask(inode, STATX_BASIC_STATS);
96
97
}

98
99
100
101
102
103
static void fuse_dir_changed(struct inode *dir)
{
	fuse_invalidate_attr(dir);
	inode_maybe_inc_iversion(dir, false);
}

104
105
106
107
108
109
110
/**
 * Mark the attributes as stale due to an atime change.  Avoid the invalidate if
 * atime is not used.
 */
void fuse_invalidate_atime(struct inode *inode)
{
	if (!IS_RDONLY(inode))
111
		fuse_invalidate_attr_mask(inode, STATX_ATIME);
112
113
}

114
115
116
117
118
119
120
121
/*
 * Just mark the entry as stale, so that a next attempt to look it up
 * will result in a new lookup call to userspace
 *
 * This is called when a dentry is about to become negative and the
 * timeout is unknown (unlink, rmdir, rename and in some cases
 * lookup)
 */
Miklos Szeredi's avatar
Miklos Szeredi committed
122
void fuse_invalidate_entry_cache(struct dentry *entry)
123
{
Miklos Szeredi's avatar
Miklos Szeredi committed
124
	fuse_dentry_settime(entry, 0);
125
126
}

127
128
129
130
/*
 * Same as fuse_invalidate_entry_cache(), but also try to remove the
 * dentry from the hash
 */
131
132
133
134
static void fuse_invalidate_entry(struct dentry *entry)
{
	d_invalidate(entry);
	fuse_invalidate_entry_cache(entry);
135
136
}

137
static void fuse_lookup_init(struct fuse_conn *fc, struct fuse_args *args,
Al Viro's avatar
Al Viro committed
138
			     u64 nodeid, const struct qstr *name,
139
140
			     struct fuse_entry_out *outarg)
{
141
	memset(outarg, 0, sizeof(struct fuse_entry_out));
142
143
144
145
146
147
	args->in.h.opcode = FUSE_LOOKUP;
	args->in.h.nodeid = nodeid;
	args->in.numargs = 1;
	args->in.args[0].size = name->len + 1;
	args->in.args[0].value = name->name;
	args->out.numargs = 1;
148
	args->out.args[0].size = sizeof(struct fuse_entry_out);
149
	args->out.args[0].value = outarg;
150
151
}

152
u64 fuse_get_attr_version(struct fuse_conn *fc)
153
154
155
156
157
158
159
160
161
162
163
164
165
166
{
	u64 curr_version;

	/*
	 * The spin lock isn't actually needed on 64bit archs, but we
	 * don't yet care too much about such optimizations.
	 */
	spin_lock(&fc->lock);
	curr_version = fc->attr_version;
	spin_unlock(&fc->lock);

	return curr_version;
}

167
168
169
170
171
172
173
174
175
/*
 * Check whether the dentry is still valid
 *
 * If the entry validity timeout has expired and the dentry is
 * positive, try to redo the lookup.  If the lookup results in a
 * different inode, then let the VFS invalidate the dentry and redo
 * the lookup once more.  If the lookup results in the same inode,
 * then refresh the attributes, timeouts and mark the dentry valid.
 */
176
static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
177
{
178
	struct inode *inode;
179
180
	struct dentry *parent;
	struct fuse_conn *fc;
181
	struct fuse_inode *fi;
182
	int ret;
183

184
	inode = d_inode_rcu(entry);
185
	if (inode && is_bad_inode(inode))
186
		goto invalid;
187
188
	else if (time_before64(fuse_dentry_time(entry), get_jiffies_64()) ||
		 (flags & LOOKUP_REVAL)) {
189
		struct fuse_entry_out outarg;
190
		FUSE_ARGS(args);
191
		struct fuse_forget_link *forget;
192
		u64 attr_version;
193

194
		/* For negative dentries, always do a fresh lookup */
195
		if (!inode)
196
			goto invalid;
197

198
		ret = -ECHILD;
199
		if (flags & LOOKUP_RCU)
200
			goto out;
201

202
		fc = get_fuse_conn(inode);
203

204
		forget = fuse_alloc_forget();
205
206
		ret = -ENOMEM;
		if (!forget)
207
			goto out;
208

209
		attr_version = fuse_get_attr_version(fc);
210

211
		parent = dget_parent(entry);
212
		fuse_lookup_init(fc, &args, get_node_id(d_inode(parent)),
213
				 &entry->d_name, &outarg);
214
		ret = fuse_simple_request(fc, &args);
215
		dput(parent);
216
		/* Zero nodeid is same as -ENOENT */
217
218
219
		if (!ret && !outarg.nodeid)
			ret = -ENOENT;
		if (!ret) {
220
			fi = get_fuse_inode(inode);
221
			if (outarg.nodeid != get_node_id(inode)) {
222
				fuse_queue_forget(fc, forget, outarg.nodeid, 1);
223
				goto invalid;
224
			}
225
			spin_lock(&fc->lock);
Miklos Szeredi's avatar
Miklos Szeredi committed
226
			fi->nlookup++;
227
			spin_unlock(&fc->lock);
228
		}
229
		kfree(forget);
230
231
232
		if (ret == -ENOMEM)
			goto out;
		if (ret || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
233
			goto invalid;
234

Seth Forshee's avatar
Seth Forshee committed
235
		forget_all_cached_acls(inode);
236
237
238
239
		fuse_change_attributes(inode, &outarg.attr,
				       entry_attr_timeout(&outarg),
				       attr_version);
		fuse_change_entry_timeout(entry, &outarg);
240
	} else if (inode) {
241
242
243
244
245
		fi = get_fuse_inode(inode);
		if (flags & LOOKUP_RCU) {
			if (test_bit(FUSE_I_INIT_RDPLUS, &fi->state))
				return -ECHILD;
		} else if (test_and_clear_bit(FUSE_I_INIT_RDPLUS, &fi->state)) {
246
			parent = dget_parent(entry);
247
			fuse_advise_use_readdirplus(d_inode(parent));
248
249
			dput(parent);
		}
250
	}
251
252
253
254
255
256
257
	ret = 1;
out:
	return ret;

invalid:
	ret = 0;
	goto out;
258
259
}

Miklos Szeredi's avatar
Miklos Szeredi committed
260
261
262
263
264
265
266
267
268
269
270
271
272
static int fuse_dentry_init(struct dentry *dentry)
{
	dentry->d_fsdata = kzalloc(sizeof(union fuse_dentry), GFP_KERNEL);

	return dentry->d_fsdata ? 0 : -ENOMEM;
}
static void fuse_dentry_release(struct dentry *dentry)
{
	union fuse_dentry *fd = dentry->d_fsdata;

	kfree_rcu(fd, rcu);
}

Al Viro's avatar
Al Viro committed
273
const struct dentry_operations fuse_dentry_operations = {
274
	.d_revalidate	= fuse_dentry_revalidate,
Miklos Szeredi's avatar
Miklos Szeredi committed
275
276
	.d_init		= fuse_dentry_init,
	.d_release	= fuse_dentry_release,
277
278
};

279
280
281
282
283
const struct dentry_operations fuse_root_dentry_operations = {
	.d_init		= fuse_dentry_init,
	.d_release	= fuse_dentry_release,
};

284
int fuse_valid_type(int m)
285
286
287
288
289
{
	return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) ||
		S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
}

Al Viro's avatar
Al Viro committed
290
int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name,
291
		     struct fuse_entry_out *outarg, struct inode **inode)
292
{
293
	struct fuse_conn *fc = get_fuse_conn_super(sb);
294
	FUSE_ARGS(args);
295
	struct fuse_forget_link *forget;
296
	u64 attr_version;
297
	int err;
298

299
300
301
302
	*inode = NULL;
	err = -ENAMETOOLONG;
	if (name->len > FUSE_NAME_MAX)
		goto out;
303
304


305
306
	forget = fuse_alloc_forget();
	err = -ENOMEM;
307
	if (!forget)
308
		goto out;
309

310
	attr_version = fuse_get_attr_version(fc);
311

312
313
	fuse_lookup_init(fc, &args, nodeid, name, outarg);
	err = fuse_simple_request(fc, &args);
314
	/* Zero nodeid is same as -ENOENT, but with valid timeout */
315
316
317
318
319
320
321
322
323
324
325
326
327
328
	if (err || !outarg->nodeid)
		goto out_put_forget;

	err = -EIO;
	if (!outarg->nodeid)
		goto out_put_forget;
	if (!fuse_valid_type(outarg->attr.mode))
		goto out_put_forget;

	*inode = fuse_iget(sb, outarg->nodeid, outarg->generation,
			   &outarg->attr, entry_attr_timeout(outarg),
			   attr_version);
	err = -ENOMEM;
	if (!*inode) {
329
		fuse_queue_forget(fc, forget, outarg->nodeid, 1);
330
		goto out;
331
	}
332
333
334
	err = 0;

 out_put_forget:
335
	kfree(forget);
336
337
338
339
340
 out:
	return err;
}

static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
Al Viro's avatar
Al Viro committed
341
				  unsigned int flags)
342
343
344
345
346
347
{
	int err;
	struct fuse_entry_out outarg;
	struct inode *inode;
	struct dentry *newent;
	bool outarg_valid = true;
348
	bool locked;
349

350
	locked = fuse_lock_inode(dir);
351
352
	err = fuse_lookup_name(dir->i_sb, get_node_id(dir), &entry->d_name,
			       &outarg, &inode);
353
	fuse_unlock_inode(dir, locked);
354
355
356
357
358
359
360
361
362
363
	if (err == -ENOENT) {
		outarg_valid = false;
		err = 0;
	}
	if (err)
		goto out_err;

	err = -EIO;
	if (inode && get_node_id(inode) == FUSE_ROOT_ID)
		goto out_iput;
364

365
	newent = d_splice_alias(inode, entry);
366
367
368
	err = PTR_ERR(newent);
	if (IS_ERR(newent))
		goto out_err;
369

370
	entry = newent ? newent : entry;
371
	if (outarg_valid)
372
		fuse_change_entry_timeout(entry, &outarg);
373
374
	else
		fuse_invalidate_entry_cache(entry);
375

376
	fuse_advise_use_readdirplus(dir);
377
	return newent;
378
379
380
381
382

 out_iput:
	iput(inode);
 out_err:
	return ERR_PTR(err);
383
384
}

385
386
387
388
389
390
/*
 * Atomic create+open operation
 *
 * If the filesystem doesn't support this, then fall back to separate
 * 'mknod' + 'open' requests.
 */
Al Viro's avatar
Al Viro committed
391
static int fuse_create_open(struct inode *dir, struct dentry *entry,
Al Viro's avatar
Al Viro committed
392
			    struct file *file, unsigned flags,
393
			    umode_t mode)
394
395
396
397
{
	int err;
	struct inode *inode;
	struct fuse_conn *fc = get_fuse_conn(dir);
398
	FUSE_ARGS(args);
399
	struct fuse_forget_link *forget;
400
	struct fuse_create_in inarg;
401
402
403
404
	struct fuse_open_out outopen;
	struct fuse_entry_out outentry;
	struct fuse_file *ff;

405
406
407
	/* Userspace expects S_IFREG in create mode */
	BUG_ON((mode & S_IFMT) != S_IFREG);

408
	forget = fuse_alloc_forget();
409
	err = -ENOMEM;
410
	if (!forget)
411
		goto out_err;
412

413
	err = -ENOMEM;
Tejun Heo's avatar
Tejun Heo committed
414
	ff = fuse_file_alloc(fc);
415
	if (!ff)
416
		goto out_put_forget_req;
417

418
419
420
	if (!fc->dont_mask)
		mode &= ~current_umask();

421
422
	flags &= ~O_NOCTTY;
	memset(&inarg, 0, sizeof(inarg));
423
	memset(&outentry, 0, sizeof(outentry));
424
425
	inarg.flags = flags;
	inarg.mode = mode;
426
	inarg.umask = current_umask();
427
428
429
	args.in.h.opcode = FUSE_CREATE;
	args.in.h.nodeid = get_node_id(dir);
	args.in.numargs = 2;
430
	args.in.args[0].size = sizeof(inarg);
431
432
433
434
	args.in.args[0].value = &inarg;
	args.in.args[1].size = entry->d_name.len + 1;
	args.in.args[1].value = entry->d_name.name;
	args.out.numargs = 2;
435
	args.out.args[0].size = sizeof(outentry);
436
437
438
439
	args.out.args[0].value = &outentry;
	args.out.args[1].size = sizeof(outopen);
	args.out.args[1].value = &outopen;
	err = fuse_simple_request(fc, &args);
440
	if (err)
441
442
443
		goto out_free_ff;

	err = -EIO;
444
	if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid))
445
446
		goto out_free_ff;

447
448
449
	ff->fh = outopen.fh;
	ff->nodeid = outentry.nodeid;
	ff->open_flags = outopen.open_flags;
450
	inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
451
			  &outentry.attr, entry_attr_timeout(&outentry), 0);
452
453
	if (!inode) {
		flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
454
		fuse_sync_release(ff, flags);
455
		fuse_queue_forget(fc, forget, outentry.nodeid, 1);
456
457
		err = -ENOMEM;
		goto out_err;
458
	}
459
	kfree(forget);
460
	d_instantiate(entry, inode);
461
	fuse_change_entry_timeout(entry, &outentry);
462
	fuse_dir_changed(dir);
463
	err = finish_open(file, entry, generic_file_open);
Al Viro's avatar
Al Viro committed
464
	if (err) {
465
		fuse_sync_release(ff, flags);
466
	} else {
467
		file->private_data = ff;
468
		fuse_finish_open(inode, file);
469
	}
Al Viro's avatar
Al Viro committed
470
	return err;
471

472
out_free_ff:
473
	fuse_file_free(ff);
474
out_put_forget_req:
475
	kfree(forget);
476
out_err:
Al Viro's avatar
Al Viro committed
477
	return err;
478
479
480
}

static int fuse_mknod(struct inode *, struct dentry *, umode_t, dev_t);
Al Viro's avatar
Al Viro committed
481
static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
Al Viro's avatar
Al Viro committed
482
			    struct file *file, unsigned flags,
483
			    umode_t mode)
484
485
486
487
488
{
	int err;
	struct fuse_conn *fc = get_fuse_conn(dir);
	struct dentry *res = NULL;

489
	if (d_in_lookup(entry)) {
Al Viro's avatar
Al Viro committed
490
		res = fuse_lookup(dir, entry, 0);
491
		if (IS_ERR(res))
Al Viro's avatar
Al Viro committed
492
			return PTR_ERR(res);
493
494
495
496
497

		if (res)
			entry = res;
	}

498
	if (!(flags & O_CREAT) || d_really_is_positive(entry))
499
500
501
		goto no_open;

	/* Only creates */
502
	file->f_mode |= FMODE_CREATED;
503
504
505
506

	if (fc->no_create)
		goto mknod;

507
	err = fuse_create_open(dir, entry, file, flags, mode);
Al Viro's avatar
Al Viro committed
508
	if (err == -ENOSYS) {
509
510
511
512
513
		fc->no_create = 1;
		goto mknod;
	}
out_dput:
	dput(res);
Al Viro's avatar
Al Viro committed
514
	return err;
515
516
517

mknod:
	err = fuse_mknod(dir, entry, mode, 0);
Al Viro's avatar
Al Viro committed
518
	if (err)
519
520
		goto out_dput;
no_open:
Al Viro's avatar
Al Viro committed
521
	return finish_no_open(file, res);
522
523
}

524
525
526
/*
 * Code shared between mknod, mkdir, symlink and link
 */
527
static int create_new_entry(struct fuse_conn *fc, struct fuse_args *args,
528
			    struct inode *dir, struct dentry *entry,
Al Viro's avatar
Al Viro committed
529
			    umode_t mode)
530
531
532
{
	struct fuse_entry_out outarg;
	struct inode *inode;
Al Viro's avatar
Al Viro committed
533
	struct dentry *d;
534
	int err;
535
	struct fuse_forget_link *forget;
536

537
	forget = fuse_alloc_forget();
538
	if (!forget)
539
		return -ENOMEM;
540

541
	memset(&outarg, 0, sizeof(outarg));
542
543
	args->in.h.nodeid = get_node_id(dir);
	args->out.numargs = 1;
544
	args->out.args[0].size = sizeof(outarg);
545
546
	args->out.args[0].value = &outarg;
	err = fuse_simple_request(fc, args);
547
548
549
	if (err)
		goto out_put_forget_req;

550
551
	err = -EIO;
	if (invalid_nodeid(outarg.nodeid))
552
		goto out_put_forget_req;
553
554

	if ((outarg.attr.mode ^ mode) & S_IFMT)
555
		goto out_put_forget_req;
556

557
	inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
558
			  &outarg.attr, entry_attr_timeout(&outarg), 0);
559
	if (!inode) {
560
		fuse_queue_forget(fc, forget, outarg.nodeid, 1);
561
562
		return -ENOMEM;
	}
563
	kfree(forget);
564

Al Viro's avatar
Al Viro committed
565
566
567
568
	d_drop(entry);
	d = d_splice_alias(inode, entry);
	if (IS_ERR(d))
		return PTR_ERR(d);
569

Al Viro's avatar
Al Viro committed
570
571
572
573
574
575
	if (d) {
		fuse_change_entry_timeout(d, &outarg);
		dput(d);
	} else {
		fuse_change_entry_timeout(entry, &outarg);
	}
576
	fuse_dir_changed(dir);
577
	return 0;
578

579
 out_put_forget_req:
580
	kfree(forget);
581
	return err;
582
583
}

Al Viro's avatar
Al Viro committed
584
static int fuse_mknod(struct inode *dir, struct dentry *entry, umode_t mode,
585
586
587
588
		      dev_t rdev)
{
	struct fuse_mknod_in inarg;
	struct fuse_conn *fc = get_fuse_conn(dir);
589
	FUSE_ARGS(args);
590

591
592
593
	if (!fc->dont_mask)
		mode &= ~current_umask();

594
595
596
	memset(&inarg, 0, sizeof(inarg));
	inarg.mode = mode;
	inarg.rdev = new_encode_dev(rdev);
597
	inarg.umask = current_umask();
598
599
	args.in.h.opcode = FUSE_MKNOD;
	args.in.numargs = 2;
600
	args.in.args[0].size = sizeof(inarg);
601
602
603
604
	args.in.args[0].value = &inarg;
	args.in.args[1].size = entry->d_name.len + 1;
	args.in.args[1].value = entry->d_name.name;
	return create_new_entry(fc, &args, dir, entry, mode);
605
606
}

Al Viro's avatar
Al Viro committed
607
static int fuse_create(struct inode *dir, struct dentry *entry, umode_t mode,
Al Viro's avatar
Al Viro committed
608
		       bool excl)
609
610
611
612
{
	return fuse_mknod(dir, entry, mode, 0);
}

613
static int fuse_mkdir(struct inode *dir, struct dentry *entry, umode_t mode)
614
615
616
{
	struct fuse_mkdir_in inarg;
	struct fuse_conn *fc = get_fuse_conn(dir);
617
	FUSE_ARGS(args);
618

619
620
621
	if (!fc->dont_mask)
		mode &= ~current_umask();

622
623
	memset(&inarg, 0, sizeof(inarg));
	inarg.mode = mode;
624
	inarg.umask = current_umask();
625
626
627
628
629
630
631
	args.in.h.opcode = FUSE_MKDIR;
	args.in.numargs = 2;
	args.in.args[0].size = sizeof(inarg);
	args.in.args[0].value = &inarg;
	args.in.args[1].size = entry->d_name.len + 1;
	args.in.args[1].value = entry->d_name.name;
	return create_new_entry(fc, &args, dir, entry, S_IFDIR);
632
633
634
635
636
637
638
}

static int fuse_symlink(struct inode *dir, struct dentry *entry,
			const char *link)
{
	struct fuse_conn *fc = get_fuse_conn(dir);
	unsigned len = strlen(link) + 1;
639
	FUSE_ARGS(args);
640

641
642
643
644
645
646
647
	args.in.h.opcode = FUSE_SYMLINK;
	args.in.numargs = 2;
	args.in.args[0].size = entry->d_name.len + 1;
	args.in.args[0].value = entry->d_name.name;
	args.in.args[1].size = len;
	args.in.args[1].value = link;
	return create_new_entry(fc, &args, dir, entry, S_IFLNK);
648
649
}

Seth Forshee's avatar
Seth Forshee committed
650
void fuse_update_ctime(struct inode *inode)
651
652
{
	if (!IS_NOCMTIME(inode)) {
653
		inode->i_ctime = current_time(inode);
654
655
656
657
		mark_inode_dirty_sync(inode);
	}
}

658
659
660
661
static int fuse_unlink(struct inode *dir, struct dentry *entry)
{
	int err;
	struct fuse_conn *fc = get_fuse_conn(dir);
662
663
664
665
666
667
668
669
	FUSE_ARGS(args);

	args.in.h.opcode = FUSE_UNLINK;
	args.in.h.nodeid = get_node_id(dir);
	args.in.numargs = 1;
	args.in.args[0].size = entry->d_name.len + 1;
	args.in.args[0].value = entry->d_name.name;
	err = fuse_simple_request(fc, &args);
670
	if (!err) {
671
		struct inode *inode = d_inode(entry);
Miklos Szeredi's avatar
Miklos Szeredi committed
672
		struct fuse_inode *fi = get_fuse_inode(inode);
673

Miklos Szeredi's avatar
Miklos Szeredi committed
674
675
		spin_lock(&fc->lock);
		fi->attr_version = ++fc->attr_version;
676
677
678
679
680
681
682
683
		/*
		 * If i_nlink == 0 then unlink doesn't make sense, yet this can
		 * happen if userspace filesystem is careless.  It would be
		 * difficult to enforce correct nlink usage so just ignore this
		 * condition here
		 */
		if (inode->i_nlink > 0)
			drop_nlink(inode);
Miklos Szeredi's avatar
Miklos Szeredi committed
684
		spin_unlock(&fc->lock);
685
		fuse_invalidate_attr(inode);
686
		fuse_dir_changed(dir);
687
		fuse_invalidate_entry_cache(entry);
688
		fuse_update_ctime(inode);
689
690
691
692
693
694
695
696
697
	} else if (err == -EINTR)
		fuse_invalidate_entry(entry);
	return err;
}

static int fuse_rmdir(struct inode *dir, struct dentry *entry)
{
	int err;
	struct fuse_conn *fc = get_fuse_conn(dir);
698
699
700
701
702
703
704
705
	FUSE_ARGS(args);

	args.in.h.opcode = FUSE_RMDIR;
	args.in.h.nodeid = get_node_id(dir);
	args.in.numargs = 1;
	args.in.args[0].size = entry->d_name.len + 1;
	args.in.args[0].value = entry->d_name.name;
	err = fuse_simple_request(fc, &args);
706
	if (!err) {
707
		clear_nlink(d_inode(entry));
708
		fuse_dir_changed(dir);
709
		fuse_invalidate_entry_cache(entry);
710
711
712
713
714
	} else if (err == -EINTR)
		fuse_invalidate_entry(entry);
	return err;
}

Miklos Szeredi's avatar
Miklos Szeredi committed
715
716
717
static int fuse_rename_common(struct inode *olddir, struct dentry *oldent,
			      struct inode *newdir, struct dentry *newent,
			      unsigned int flags, int opcode, size_t argsize)
718
719
{
	int err;
Miklos Szeredi's avatar
Miklos Szeredi committed
720
	struct fuse_rename2_in inarg;
721
	struct fuse_conn *fc = get_fuse_conn(olddir);
722
	FUSE_ARGS(args);
723

Miklos Szeredi's avatar
Miklos Szeredi committed
724
	memset(&inarg, 0, argsize);
725
	inarg.newdir = get_node_id(newdir);
Miklos Szeredi's avatar
Miklos Szeredi committed
726
	inarg.flags = flags;
727
728
729
730
731
732
733
734
735
736
	args.in.h.opcode = opcode;
	args.in.h.nodeid = get_node_id(olddir);
	args.in.numargs = 3;
	args.in.args[0].size = argsize;
	args.in.args[0].value = &inarg;
	args.in.args[1].size = oldent->d_name.len + 1;
	args.in.args[1].value = oldent->d_name.name;
	args.in.args[2].size = newent->d_name.len + 1;
	args.in.args[2].value = newent->d_name.name;
	err = fuse_simple_request(fc, &args);
737
	if (!err) {
738
		/* ctime changes */
739
740
		fuse_invalidate_attr(d_inode(oldent));
		fuse_update_ctime(d_inode(oldent));
741

Miklos Szeredi's avatar
Miklos Szeredi committed
742
		if (flags & RENAME_EXCHANGE) {
743
744
			fuse_invalidate_attr(d_inode(newent));
			fuse_update_ctime(d_inode(newent));
Miklos Szeredi's avatar
Miklos Szeredi committed
745
746
		}

747
		fuse_dir_changed(olddir);
748
		if (olddir != newdir)
749
			fuse_dir_changed(newdir);
750
751

		/* newent will end up negative */
752
753
		if (!(flags & RENAME_EXCHANGE) && d_really_is_positive(newent)) {
			fuse_invalidate_attr(d_inode(newent));
754
			fuse_invalidate_entry_cache(newent);
755
			fuse_update_ctime(d_inode(newent));
756
		}
757
758
759
760
761
762
763
	} else if (err == -EINTR) {
		/* If request was interrupted, DEITY only knows if the
		   rename actually took place.  If the invalidation
		   fails (e.g. some process has CWD under the renamed
		   directory), then there can be inconsistency between
		   the dcache and the real filesystem.  Tough luck. */
		fuse_invalidate_entry(oldent);
764
		if (d_really_is_positive(newent))
765
766
767
768
769
770
			fuse_invalidate_entry(newent);
	}

	return err;
}

Miklos Szeredi's avatar
Miklos Szeredi committed
771
772
773
774
775
776
777
778
779
780
static int fuse_rename2(struct inode *olddir, struct dentry *oldent,
			struct inode *newdir, struct dentry *newent,
			unsigned int flags)
{
	struct fuse_conn *fc = get_fuse_conn(olddir);
	int err;

	if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE))
		return -EINVAL;

Miklos Szeredi's avatar
Miklos Szeredi committed
781
782
783
	if (flags) {
		if (fc->no_rename2 || fc->minor < 23)
			return -EINVAL;
Miklos Szeredi's avatar
Miklos Szeredi committed
784

Miklos Szeredi's avatar
Miklos Szeredi committed
785
786
787
788
789
790
791
792
793
794
795
		err = fuse_rename_common(olddir, oldent, newdir, newent, flags,
					 FUSE_RENAME2,
					 sizeof(struct fuse_rename2_in));
		if (err == -ENOSYS) {
			fc->no_rename2 = 1;
			err = -EINVAL;
		}
	} else {
		err = fuse_rename_common(olddir, oldent, newdir, newent, 0,
					 FUSE_RENAME,
					 sizeof(struct fuse_rename_in));
Miklos Szeredi's avatar
Miklos Szeredi committed
796
	}
Miklos Szeredi's avatar
Miklos Szeredi committed
797

Miklos Szeredi's avatar
Miklos Szeredi committed
798
	return err;
Miklos Szeredi's avatar
Miklos Szeredi committed
799
}
Miklos Szeredi's avatar
Miklos Szeredi committed
800

801
802
803
804
805
static int fuse_link(struct dentry *entry, struct inode *newdir,
		     struct dentry *newent)
{
	int err;
	struct fuse_link_in inarg;
806
	struct inode *inode = d_inode(entry);
807
	struct fuse_conn *fc = get_fuse_conn(inode);
808
	FUSE_ARGS(args);
809
810
811

	memset(&inarg, 0, sizeof(inarg));
	inarg.oldnodeid = get_node_id(inode);
812
813
814
815
816
817
818
	args.in.h.opcode = FUSE_LINK;
	args.in.numargs = 2;
	args.in.args[0].size = sizeof(inarg);
	args.in.args[0].value = &inarg;
	args.in.args[1].size = newent->d_name.len + 1;
	args.in.args[1].value = newent->d_name.name;
	err = create_new_entry(fc, &args, newdir, newent, inode->i_mode);
819
820
821
822
823
824
	/* Contrary to "normal" filesystems it can happen that link
	   makes two "logical" inodes point to the same "physical"
	   inode.  We invalidate the attributes of the old one, so it
	   will reflect changes in the backing inode (link count,
	   etc.)
	*/
Miklos Szeredi's avatar
Miklos Szeredi committed
825
826
827
828
829
830
831
	if (!err) {
		struct fuse_inode *fi = get_fuse_inode(inode);

		spin_lock(&fc->lock);
		fi->attr_version = ++fc->attr_version;
		inc_nlink(inode);
		spin_unlock(&fc->lock);
832
		fuse_invalidate_attr(inode);
833
		fuse_update_ctime(inode);
Miklos Szeredi's avatar
Miklos Szeredi committed
834
835
836
	} else if (err == -EINTR) {
		fuse_invalidate_attr(inode);
	}
837
838
839
	return err;
}

840
841
842
static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
			  struct kstat *stat)
{
Miklos Szeredi's avatar
Miklos Szeredi committed
843
	unsigned int blkbits;
844
845
846
	struct fuse_conn *fc = get_fuse_conn(inode);

	/* see the comment in fuse_change_attributes() */
847
	if (fc->writeback_cache && S_ISREG(inode->i_mode)) {
848
		attr->size = i_size_read(inode);
849
850
		attr->mtime = inode->i_mtime.tv_sec;
		attr->mtimensec = inode->i_mtime.tv_nsec;
851
852
		attr->ctime = inode->i_ctime.tv_sec;
		attr->ctimensec = inode->i_ctime.tv_nsec;
853
	}
Miklos Szeredi's avatar
Miklos Szeredi committed
854

855
856
857
858
	stat->dev = inode->i_sb->s_dev;
	stat->ino = attr->ino;
	stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777);
	stat->nlink = attr->nlink;
859
860
	stat->uid = make_kuid(fc->user_ns, attr->uid);
	stat->gid = make_kgid(fc->user_ns, attr->gid);
861
862
863
864
865
866
867
868
869
	stat->rdev = inode->i_rdev;
	stat->atime.tv_sec = attr->atime;
	stat->atime.tv_nsec = attr->atimensec;
	stat->mtime.tv_sec = attr->mtime;
	stat->mtime.tv_nsec = attr->mtimensec;
	stat->ctime.tv_sec = attr->ctime;
	stat->ctime.tv_nsec = attr->ctimensec;
	stat->size = attr->size;
	stat->blocks = attr->blocks;
Miklos Szeredi's avatar
Miklos Szeredi committed
870
871
872
873
874
875
876

	if (attr->blksize != 0)
		blkbits = ilog2(attr->blksize);
	else
		blkbits = inode->i_sb->s_blocksize_bits;

	stat->blksize = 1 << blkbits;
877
878
}

879
880
static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
			   struct file *file)
881
882
{
	int err;
883
884
	struct fuse_getattr_in inarg;
	struct fuse_attr_out outarg;
885
	struct fuse_conn *fc = get_fuse_conn(inode);
886
	FUSE_ARGS(args);
887
888
	u64 attr_version;

889
	attr_version = fuse_get_attr_version(fc);
890

891
	memset(&inarg, 0, sizeof(inarg));
892
	memset(&outarg, 0, sizeof(outarg));
893
894
895
896
897
898
899
	/* Directories have separate file-handle space */
	if (file && S_ISREG(inode->i_mode)) {
		struct fuse_file *ff = file->private_data;

		inarg.getattr_flags |= FUSE_GETATTR_FH;
		inarg.fh = ff->fh;
	}
900
901
902
903
904
905
	args.in.h.opcode = FUSE_GETATTR;
	args.in.h.nodeid = get_node_id(inode);
	args.in.numargs = 1;
	args.in.args[0].size = sizeof(inarg);
	args.in.args[0].value = &inarg;
	args.out.numargs = 1;
906
	args.out.args[0].size = sizeof(outarg);
907
908
	args.out.args[0].value = &outarg;
	err = fuse_simple_request(fc, &args);
909
	if (!err) {
910
		if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
911
912
913
			make_bad_inode(inode);
			err = -EIO;
		} else {
914
915
			fuse_change_attributes(inode, &outarg.attr,
					       attr_timeout(&outarg),
916
917
					       attr_version);
			if (stat)
918
				fuse_fillattr(inode, &outarg.attr, stat);
919
920
921
922
923
		}
	}
	return err;
}

Miklos Szeredi's avatar
Miklos Szeredi committed
924
static int fuse_update_get_attr(struct inode *inode, struct file *file,
925
926
				struct kstat *stat, u32 request_mask,
				unsigned int flags)
Miklos Szeredi's avatar
Miklos Szeredi committed
927
928
{
	struct fuse_inode *fi = get_fuse_inode(inode);
Miklos Szeredi's avatar
Miklos Szeredi committed
929
	int err = 0;
930
	bool sync;
Miklos Szeredi's avatar
Miklos Szeredi committed
931

932
933
934
935
	if (flags & AT_STATX_FORCE_SYNC)
		sync = true;
	else if (flags & AT_STATX_DONT_SYNC)
		sync = false;
936
937
	else if (request_mask & READ_ONCE(fi->inval_mask))
		sync = true;
938
939
940
941
	else
		sync = time_before64(fi->i_time, get_jiffies_64());

	if (sync) {
Seth Forshee's avatar
Seth Forshee committed
942
		forget_all_cached_acls(inode);
Miklos Szeredi's avatar
Miklos Szeredi committed
943
		err = fuse_do_getattr(inode, stat, file);
Miklos Szeredi's avatar
Miklos Szeredi committed
944
945
946
947
	} else if (stat) {
		generic_fillattr(inode, stat);
		stat->mode = fi->orig_i_mode;
		stat->ino = fi->orig_ino;
Miklos Szeredi's avatar
Miklos Szeredi committed
948
949
950
951
952
	}

	return err;
}

Miklos Szeredi's avatar
Miklos Szeredi committed
953
954
int fuse_update_attributes(struct inode *inode, struct file *file)
{
955
956
957
	/* Do *not* need to get atime for internal purposes */
	return fuse_update_get_attr(inode, file, NULL,
				    STATX_BASIC_STATS & ~STATX_ATIME, 0);
Miklos Szeredi's avatar
Miklos Szeredi committed
958
959
}

John Muir's avatar
John Muir committed
960
int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid,
961
			     u64 child_nodeid, struct qstr *name)
John Muir's avatar
John Muir committed
962
963
964
965
966
967
968
969
970
971
{
	int err = -ENOTDIR;
	struct inode *parent;
	struct dentry *dir;
	struct dentry *entry;

	parent = ilookup5(sb, parent_nodeid, fuse_inode_eq, &parent_nodeid);
	if (!parent)
		return -ENOENT;

Al Viro's avatar
Al Viro committed
972
	inode_lock(parent);
John Muir's avatar
John Muir committed
973
974
975