dir.c 47.5 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>
16

Al Viro's avatar
Al Viro committed
17
static bool fuse_use_readdirplus(struct inode *dir, struct dir_context *ctx)
18
19
20
21
22
23
{
	struct fuse_conn *fc = get_fuse_conn(dir);
	struct fuse_inode *fi = get_fuse_inode(dir);

	if (!fc->do_readdirplus)
		return false;
24
25
	if (!fc->readdirplus_auto)
		return true;
26
27
	if (test_and_clear_bit(FUSE_I_ADVISE_RDPLUS, &fi->state))
		return true;
Al Viro's avatar
Al Viro committed
28
	if (ctx->pos == 0)
29
30
31
32
33
34
35
36
37
38
39
		return true;
	return false;
}

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#if BITS_PER_LONG >= 64
static inline void fuse_dentry_settime(struct dentry *entry, u64 time)
{
	entry->d_time = time;
}

static inline u64 fuse_dentry_time(struct dentry *entry)
{
	return entry->d_time;
}
#else
/*
 * On 32 bit archs store the high 32 bits of time in d_fsdata
 */
static void fuse_dentry_settime(struct dentry *entry, u64 time)
{
	entry->d_time = time;
	entry->d_fsdata = (void *) (unsigned long) (time >> 32);
}

static u64 fuse_dentry_time(struct dentry *entry)
{
	return (u64) entry->d_time +
		((u64) (unsigned long) entry->d_fsdata << 32);
}
#endif

67
68
69
70
71
72
73
74
75
/*
 * FUSE caches dentries and attributes with separate timeout.  The
 * time in jiffies until the dentry/attributes are valid is stored in
 * dentry->d_time and fuse_inode->i_time respectively.
 */

/*
 * Calculate the time in jiffies until a dentry/attributes are valid
 */
Miklos Szeredi's avatar
Miklos Szeredi committed
76
static u64 time_to_jiffies(unsigned long sec, unsigned long nsec)
77
{
78
79
	if (sec || nsec) {
		struct timespec ts = {sec, nsec};
Miklos Szeredi's avatar
Miklos Szeredi committed
80
		return get_jiffies_64() + timespec_to_jiffies(&ts);
81
	} else
Miklos Szeredi's avatar
Miklos Szeredi committed
82
		return 0;
83
84
}

85
86
87
88
/*
 * Set dentry and possibly attribute timeouts from the lookup/mk*
 * replies
 */
89
90
static void fuse_change_entry_timeout(struct dentry *entry,
				      struct fuse_entry_out *o)
91
{
Miklos Szeredi's avatar
Miklos Szeredi committed
92
93
	fuse_dentry_settime(entry,
		time_to_jiffies(o->entry_valid, o->entry_valid_nsec));
94
95
96
97
98
99
100
101
102
103
}

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

static u64 entry_attr_timeout(struct fuse_entry_out *o)
{
	return time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
104
105
}

106
107
108
109
/*
 * Mark the attributes as stale, so that at the next call to
 * ->getattr() they will be fetched from userspace
 */
110
111
void fuse_invalidate_attr(struct inode *inode)
{
Miklos Szeredi's avatar
Miklos Szeredi committed
112
	get_fuse_inode(inode)->i_time = 0;
113
114
}

115
116
117
118
119
120
121
122
123
124
/**
 * 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))
		fuse_invalidate_attr(inode);
}

125
126
127
128
129
130
131
132
/*
 * 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
133
void fuse_invalidate_entry_cache(struct dentry *entry)
134
{
Miklos Szeredi's avatar
Miklos Szeredi committed
135
	fuse_dentry_settime(entry, 0);
136
137
}

138
139
140
141
/*
 * Same as fuse_invalidate_entry_cache(), but also try to remove the
 * dentry from the hash
 */
142
143
144
145
static void fuse_invalidate_entry(struct dentry *entry)
{
	d_invalidate(entry);
	fuse_invalidate_entry_cache(entry);
146
147
}

148
static void fuse_lookup_init(struct fuse_conn *fc, struct fuse_args *args,
Al Viro's avatar
Al Viro committed
149
			     u64 nodeid, const struct qstr *name,
150
151
			     struct fuse_entry_out *outarg)
{
152
	memset(outarg, 0, sizeof(struct fuse_entry_out));
153
154
155
156
157
158
	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;
159
	args->out.args[0].size = sizeof(struct fuse_entry_out);
160
	args->out.args[0].value = outarg;
161
162
}

163
u64 fuse_get_attr_version(struct fuse_conn *fc)
164
165
166
167
168
169
170
171
172
173
174
175
176
177
{
	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;
}

178
179
180
181
182
183
184
185
186
/*
 * 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.
 */
187
static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
188
{
189
	struct inode *inode;
190
191
	struct dentry *parent;
	struct fuse_conn *fc;
192
	struct fuse_inode *fi;
193
	int ret;
194

195
	inode = d_inode_rcu(entry);
196
	if (inode && is_bad_inode(inode))
197
		goto invalid;
198
199
	else if (time_before64(fuse_dentry_time(entry), get_jiffies_64()) ||
		 (flags & LOOKUP_REVAL)) {
200
		struct fuse_entry_out outarg;
201
		FUSE_ARGS(args);
202
		struct fuse_forget_link *forget;
203
		u64 attr_version;
204

205
		/* For negative dentries, always do a fresh lookup */
206
		if (!inode)
207
			goto invalid;
208

209
		ret = -ECHILD;
210
		if (flags & LOOKUP_RCU)
211
			goto out;
212

213
		fc = get_fuse_conn(inode);
214

215
		forget = fuse_alloc_forget();
216
217
		ret = -ENOMEM;
		if (!forget)
218
			goto out;
219

220
		attr_version = fuse_get_attr_version(fc);
221

222
		parent = dget_parent(entry);
223
		fuse_lookup_init(fc, &args, get_node_id(d_inode(parent)),
224
				 &entry->d_name, &outarg);
225
		ret = fuse_simple_request(fc, &args);
226
		dput(parent);
227
		/* Zero nodeid is same as -ENOENT */
228
229
230
		if (!ret && !outarg.nodeid)
			ret = -ENOENT;
		if (!ret) {
231
			fi = get_fuse_inode(inode);
232
			if (outarg.nodeid != get_node_id(inode)) {
233
				fuse_queue_forget(fc, forget, outarg.nodeid, 1);
234
				goto invalid;
235
			}
236
			spin_lock(&fc->lock);
Miklos Szeredi's avatar
Miklos Szeredi committed
237
			fi->nlookup++;
238
			spin_unlock(&fc->lock);
239
		}
240
		kfree(forget);
241
242
243
		if (ret == -ENOMEM)
			goto out;
		if (ret || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
244
			goto invalid;
245

246
247
248
249
		fuse_change_attributes(inode, &outarg.attr,
				       entry_attr_timeout(&outarg),
				       attr_version);
		fuse_change_entry_timeout(entry, &outarg);
250
	} else if (inode) {
251
252
253
254
255
		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)) {
256
			parent = dget_parent(entry);
257
			fuse_advise_use_readdirplus(d_inode(parent));
258
259
			dput(parent);
		}
260
	}
261
262
263
264
265
266
267
	ret = 1;
out:
	return ret;

invalid:
	ret = 0;
	goto out;
268
269
}

270
static int invalid_nodeid(u64 nodeid)
271
272
273
274
{
	return !nodeid || nodeid == FUSE_ROOT_ID;
}

Al Viro's avatar
Al Viro committed
275
const struct dentry_operations fuse_dentry_operations = {
276
277
278
	.d_revalidate	= fuse_dentry_revalidate,
};

279
int fuse_valid_type(int m)
280
281
282
283
284
{
	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
285
int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name,
286
		     struct fuse_entry_out *outarg, struct inode **inode)
287
{
288
	struct fuse_conn *fc = get_fuse_conn_super(sb);
289
	FUSE_ARGS(args);
290
	struct fuse_forget_link *forget;
291
	u64 attr_version;
292
	int err;
293

294
295
296
297
	*inode = NULL;
	err = -ENAMETOOLONG;
	if (name->len > FUSE_NAME_MAX)
		goto out;
298
299


300
301
	forget = fuse_alloc_forget();
	err = -ENOMEM;
302
	if (!forget)
303
		goto out;
304

305
	attr_version = fuse_get_attr_version(fc);
306

307
308
	fuse_lookup_init(fc, &args, nodeid, name, outarg);
	err = fuse_simple_request(fc, &args);
309
	/* Zero nodeid is same as -ENOENT, but with valid timeout */
310
311
312
313
314
315
316
317
318
319
320
321
322
323
	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) {
324
		fuse_queue_forget(fc, forget, outarg->nodeid, 1);
325
		goto out;
326
	}
327
328
329
	err = 0;

 out_put_forget:
330
	kfree(forget);
331
332
333
334
335
 out:
	return err;
}

static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
Al Viro's avatar
Al Viro committed
336
				  unsigned int flags)
337
338
339
340
341
342
343
{
	int err;
	struct fuse_entry_out outarg;
	struct inode *inode;
	struct dentry *newent;
	bool outarg_valid = true;

344
	fuse_lock_inode(dir);
345
346
	err = fuse_lookup_name(dir->i_sb, get_node_id(dir), &entry->d_name,
			       &outarg, &inode);
347
	fuse_unlock_inode(dir);
348
349
350
351
352
353
354
355
356
357
	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;
358

359
	newent = d_splice_alias(inode, entry);
360
361
362
	err = PTR_ERR(newent);
	if (IS_ERR(newent))
		goto out_err;
363

364
	entry = newent ? newent : entry;
365
	if (outarg_valid)
366
		fuse_change_entry_timeout(entry, &outarg);
367
368
	else
		fuse_invalidate_entry_cache(entry);
369

370
	fuse_advise_use_readdirplus(dir);
371
	return newent;
372
373
374
375
376

 out_iput:
	iput(inode);
 out_err:
	return ERR_PTR(err);
377
378
}

379
380
381
382
383
384
/*
 * 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
385
static int fuse_create_open(struct inode *dir, struct dentry *entry,
Al Viro's avatar
Al Viro committed
386
			    struct file *file, unsigned flags,
Al Viro's avatar
Al Viro committed
387
			    umode_t mode, int *opened)
388
389
390
391
{
	int err;
	struct inode *inode;
	struct fuse_conn *fc = get_fuse_conn(dir);
392
	FUSE_ARGS(args);
393
	struct fuse_forget_link *forget;
394
	struct fuse_create_in inarg;
395
396
397
398
	struct fuse_open_out outopen;
	struct fuse_entry_out outentry;
	struct fuse_file *ff;

399
400
401
	/* Userspace expects S_IFREG in create mode */
	BUG_ON((mode & S_IFMT) != S_IFREG);

402
	forget = fuse_alloc_forget();
403
	err = -ENOMEM;
404
	if (!forget)
405
		goto out_err;
406

407
	err = -ENOMEM;
Tejun Heo's avatar
Tejun Heo committed
408
	ff = fuse_file_alloc(fc);
409
	if (!ff)
410
		goto out_put_forget_req;
411

412
413
414
	if (!fc->dont_mask)
		mode &= ~current_umask();

415
416
	flags &= ~O_NOCTTY;
	memset(&inarg, 0, sizeof(inarg));
417
	memset(&outentry, 0, sizeof(outentry));
418
419
	inarg.flags = flags;
	inarg.mode = mode;
420
	inarg.umask = current_umask();
421
422
423
	args.in.h.opcode = FUSE_CREATE;
	args.in.h.nodeid = get_node_id(dir);
	args.in.numargs = 2;
424
	args.in.args[0].size = sizeof(inarg);
425
426
427
428
	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;
429
	args.out.args[0].size = sizeof(outentry);
430
431
432
433
	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);
434
	if (err)
435
436
437
		goto out_free_ff;

	err = -EIO;
438
	if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid))
439
440
		goto out_free_ff;

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

466
out_free_ff:
467
	fuse_file_free(ff);
468
out_put_forget_req:
469
	kfree(forget);
470
out_err:
Al Viro's avatar
Al Viro committed
471
	return err;
472
473
474
}

static int fuse_mknod(struct inode *, struct dentry *, umode_t, dev_t);
Al Viro's avatar
Al Viro committed
475
static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
Al Viro's avatar
Al Viro committed
476
			    struct file *file, unsigned flags,
Al Viro's avatar
Al Viro committed
477
			    umode_t mode, int *opened)
478
479
480
481
482
{
	int err;
	struct fuse_conn *fc = get_fuse_conn(dir);
	struct dentry *res = NULL;

483
	if (d_in_lookup(entry)) {
Al Viro's avatar
Al Viro committed
484
		res = fuse_lookup(dir, entry, 0);
485
		if (IS_ERR(res))
Al Viro's avatar
Al Viro committed
486
			return PTR_ERR(res);
487
488
489
490
491

		if (res)
			entry = res;
	}

492
	if (!(flags & O_CREAT) || d_really_is_positive(entry))
493
494
495
		goto no_open;

	/* Only creates */
496
	*opened |= FILE_CREATED;
497
498
499
500

	if (fc->no_create)
		goto mknod;

Al Viro's avatar
Al Viro committed
501
	err = fuse_create_open(dir, entry, file, flags, mode, opened);
Al Viro's avatar
Al Viro committed
502
	if (err == -ENOSYS) {
503
504
505
506
507
		fc->no_create = 1;
		goto mknod;
	}
out_dput:
	dput(res);
Al Viro's avatar
Al Viro committed
508
	return err;
509
510
511

mknod:
	err = fuse_mknod(dir, entry, mode, 0);
Al Viro's avatar
Al Viro committed
512
	if (err)
513
514
		goto out_dput;
no_open:
Al Viro's avatar
Al Viro committed
515
	return finish_no_open(file, res);
516
517
}

518
519
520
/*
 * Code shared between mknod, mkdir, symlink and link
 */
521
static int create_new_entry(struct fuse_conn *fc, struct fuse_args *args,
522
			    struct inode *dir, struct dentry *entry,
Al Viro's avatar
Al Viro committed
523
			    umode_t mode)
524
525
526
527
{
	struct fuse_entry_out outarg;
	struct inode *inode;
	int err;
528
	struct fuse_forget_link *forget;
529

530
	forget = fuse_alloc_forget();
531
	if (!forget)
532
		return -ENOMEM;
533

534
	memset(&outarg, 0, sizeof(outarg));
535
536
	args->in.h.nodeid = get_node_id(dir);
	args->out.numargs = 1;
537
	args->out.args[0].size = sizeof(outarg);
538
539
	args->out.args[0].value = &outarg;
	err = fuse_simple_request(fc, args);
540
541
542
	if (err)
		goto out_put_forget_req;

543
544
	err = -EIO;
	if (invalid_nodeid(outarg.nodeid))
545
		goto out_put_forget_req;
546
547

	if ((outarg.attr.mode ^ mode) & S_IFMT)
548
		goto out_put_forget_req;
549

550
	inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
551
			  &outarg.attr, entry_attr_timeout(&outarg), 0);
552
	if (!inode) {
553
		fuse_queue_forget(fc, forget, outarg.nodeid, 1);
554
555
		return -ENOMEM;
	}
556
	kfree(forget);
557

558
559
560
	err = d_instantiate_no_diralias(entry, inode);
	if (err)
		return err;
561

562
	fuse_change_entry_timeout(entry, &outarg);
563
564
	fuse_invalidate_attr(dir);
	return 0;
565

566
 out_put_forget_req:
567
	kfree(forget);
568
	return err;
569
570
}

Al Viro's avatar
Al Viro committed
571
static int fuse_mknod(struct inode *dir, struct dentry *entry, umode_t mode,
572
573
574
575
		      dev_t rdev)
{
	struct fuse_mknod_in inarg;
	struct fuse_conn *fc = get_fuse_conn(dir);
576
	FUSE_ARGS(args);
577

578
579
580
	if (!fc->dont_mask)
		mode &= ~current_umask();

581
582
583
	memset(&inarg, 0, sizeof(inarg));
	inarg.mode = mode;
	inarg.rdev = new_encode_dev(rdev);
584
	inarg.umask = current_umask();
585
586
	args.in.h.opcode = FUSE_MKNOD;
	args.in.numargs = 2;
587
	args.in.args[0].size = sizeof(inarg);
588
589
590
591
	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);
592
593
}

Al Viro's avatar
Al Viro committed
594
static int fuse_create(struct inode *dir, struct dentry *entry, umode_t mode,
Al Viro's avatar
Al Viro committed
595
		       bool excl)
596
597
598
599
{
	return fuse_mknod(dir, entry, mode, 0);
}

600
static int fuse_mkdir(struct inode *dir, struct dentry *entry, umode_t mode)
601
602
603
{
	struct fuse_mkdir_in inarg;
	struct fuse_conn *fc = get_fuse_conn(dir);
604
	FUSE_ARGS(args);
605

606
607
608
	if (!fc->dont_mask)
		mode &= ~current_umask();

609
610
	memset(&inarg, 0, sizeof(inarg));
	inarg.mode = mode;
611
	inarg.umask = current_umask();
612
613
614
615
616
617
618
	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);
619
620
621
622
623
624
625
}

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;
626
	FUSE_ARGS(args);
627

628
629
630
631
632
633
634
	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);
635
636
}

637
638
639
640
641
642
643
644
static inline void fuse_update_ctime(struct inode *inode)
{
	if (!IS_NOCMTIME(inode)) {
		inode->i_ctime = current_fs_time(inode->i_sb);
		mark_inode_dirty_sync(inode);
	}
}

645
646
647
648
static int fuse_unlink(struct inode *dir, struct dentry *entry)
{
	int err;
	struct fuse_conn *fc = get_fuse_conn(dir);
649
650
651
652
653
654
655
656
	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);
657
	if (!err) {
658
		struct inode *inode = d_inode(entry);
Miklos Szeredi's avatar
Miklos Szeredi committed
659
		struct fuse_inode *fi = get_fuse_inode(inode);
660

Miklos Szeredi's avatar
Miklos Szeredi committed
661
662
		spin_lock(&fc->lock);
		fi->attr_version = ++fc->attr_version;
663
664
665
666
667
668
669
670
		/*
		 * 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
671
		spin_unlock(&fc->lock);
672
673
		fuse_invalidate_attr(inode);
		fuse_invalidate_attr(dir);
674
		fuse_invalidate_entry_cache(entry);
675
		fuse_update_ctime(inode);
676
677
678
679
680
681
682
683
684
	} 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);
685
686
687
688
689
690
691
692
	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);
693
	if (!err) {
694
		clear_nlink(d_inode(entry));
695
		fuse_invalidate_attr(dir);
696
		fuse_invalidate_entry_cache(entry);
697
698
699
700
701
	} else if (err == -EINTR)
		fuse_invalidate_entry(entry);
	return err;
}

Miklos Szeredi's avatar
Miklos Szeredi committed
702
703
704
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)
705
706
{
	int err;
Miklos Szeredi's avatar
Miklos Szeredi committed
707
	struct fuse_rename2_in inarg;
708
	struct fuse_conn *fc = get_fuse_conn(olddir);
709
	FUSE_ARGS(args);
710

Miklos Szeredi's avatar
Miklos Szeredi committed
711
	memset(&inarg, 0, argsize);
712
	inarg.newdir = get_node_id(newdir);
Miklos Szeredi's avatar
Miklos Szeredi committed
713
	inarg.flags = flags;
714
715
716
717
718
719
720
721
722
723
	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);
724
	if (!err) {
725
		/* ctime changes */
726
727
		fuse_invalidate_attr(d_inode(oldent));
		fuse_update_ctime(d_inode(oldent));
728

Miklos Szeredi's avatar
Miklos Szeredi committed
729
		if (flags & RENAME_EXCHANGE) {
730
731
			fuse_invalidate_attr(d_inode(newent));
			fuse_update_ctime(d_inode(newent));
Miklos Szeredi's avatar
Miklos Szeredi committed
732
733
		}

734
735
736
		fuse_invalidate_attr(olddir);
		if (olddir != newdir)
			fuse_invalidate_attr(newdir);
737
738

		/* newent will end up negative */
739
740
		if (!(flags & RENAME_EXCHANGE) && d_really_is_positive(newent)) {
			fuse_invalidate_attr(d_inode(newent));
741
			fuse_invalidate_entry_cache(newent);
742
			fuse_update_ctime(d_inode(newent));
743
		}
744
745
746
747
748
749
750
	} 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);
751
		if (d_really_is_positive(newent))
752
753
754
755
756
757
			fuse_invalidate_entry(newent);
	}

	return err;
}

Miklos Szeredi's avatar
Miklos Szeredi committed
758
759
760
761
762
763
764
765
766
767
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
768
769
770
	if (flags) {
		if (fc->no_rename2 || fc->minor < 23)
			return -EINVAL;
Miklos Szeredi's avatar
Miklos Szeredi committed
771

Miklos Szeredi's avatar
Miklos Szeredi committed
772
773
774
775
776
777
778
779
780
781
782
		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
783
	}
Miklos Szeredi's avatar
Miklos Szeredi committed
784

Miklos Szeredi's avatar
Miklos Szeredi committed
785
	return err;
Miklos Szeredi's avatar
Miklos Szeredi committed
786
}
Miklos Szeredi's avatar
Miklos Szeredi committed
787

788
789
790
791
792
static int fuse_link(struct dentry *entry, struct inode *newdir,
		     struct dentry *newent)
{
	int err;
	struct fuse_link_in inarg;
793
	struct inode *inode = d_inode(entry);
794
	struct fuse_conn *fc = get_fuse_conn(inode);
795
	FUSE_ARGS(args);
796
797
798

	memset(&inarg, 0, sizeof(inarg));
	inarg.oldnodeid = get_node_id(inode);
799
800
801
802
803
804
805
	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);
806
807
808
809
810
811
	/* 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
812
813
814
815
816
817
818
	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);
819
		fuse_invalidate_attr(inode);
820
		fuse_update_ctime(inode);
Miklos Szeredi's avatar
Miklos Szeredi committed
821
822
823
	} else if (err == -EINTR) {
		fuse_invalidate_attr(inode);
	}
824
825
826
	return err;
}

827
828
829
static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
			  struct kstat *stat)
{
Miklos Szeredi's avatar
Miklos Szeredi committed
830
	unsigned int blkbits;
831
832
833
	struct fuse_conn *fc = get_fuse_conn(inode);

	/* see the comment in fuse_change_attributes() */
834
	if (fc->writeback_cache && S_ISREG(inode->i_mode)) {
835
		attr->size = i_size_read(inode);
836
837
		attr->mtime = inode->i_mtime.tv_sec;
		attr->mtimensec = inode->i_mtime.tv_nsec;
838
839
		attr->ctime = inode->i_ctime.tv_sec;
		attr->ctimensec = inode->i_ctime.tv_nsec;
840
	}
Miklos Szeredi's avatar
Miklos Szeredi committed
841

842
843
844
845
	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;
846
847
	stat->uid = make_kuid(&init_user_ns, attr->uid);
	stat->gid = make_kgid(&init_user_ns, attr->gid);
848
849
850
851
852
853
854
855
856
	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
857
858
859
860
861
862
863

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

	stat->blksize = 1 << blkbits;
864
865
}

866
867
static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
			   struct file *file)
868
869
{
	int err;
870
871
	struct fuse_getattr_in inarg;
	struct fuse_attr_out outarg;
872
	struct fuse_conn *fc = get_fuse_conn(inode);
873
	FUSE_ARGS(args);
874
875
	u64 attr_version;

876
	attr_version = fuse_get_attr_version(fc);
877

878
	memset(&inarg, 0, sizeof(inarg));
879
	memset(&outarg, 0, sizeof(outarg));
880
881
882
883
884
885
886
	/* 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;
	}
887
888
889
890
891
892
	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;
893
	args.out.args[0].size = sizeof(outarg);
894
895
	args.out.args[0].value = &outarg;
	err = fuse_simple_request(fc, &args);
896
	if (!err) {
897
		if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
898
899
900
			make_bad_inode(inode);
			err = -EIO;
		} else {
901
902
			fuse_change_attributes(inode, &outarg.attr,
					       attr_timeout(&outarg),
903
904
					       attr_version);
			if (stat)
905
				fuse_fillattr(inode, &outarg.attr, stat);
906
907
908
909
910
		}
	}
	return err;
}

Miklos Szeredi's avatar
Miklos Szeredi committed
911
912
913
914
915
916
917
int fuse_update_attributes(struct inode *inode, struct kstat *stat,
			   struct file *file, bool *refreshed)
{
	struct fuse_inode *fi = get_fuse_inode(inode);
	int err;
	bool r;

Miklos Szeredi's avatar
Miklos Szeredi committed
918
	if (time_before64(fi->i_time, get_jiffies_64())) {
Miklos Szeredi's avatar
Miklos Szeredi committed
919
920
921
922
923
924
925
926
		r = true;
		err = fuse_do_getattr(inode, stat, file);
	} else {
		r = false;
		err = 0;
		if (stat) {
			generic_fillattr(inode, stat);
			stat->mode = fi->orig_i_mode;
927
			stat->ino = fi->orig_ino;
Miklos Szeredi's avatar
Miklos Szeredi committed
928
929
930
931
932
933
934
935
936
		}
	}

	if (refreshed != NULL)
		*refreshed = r;

	return err;
}

John Muir's avatar
John Muir committed
937
int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid,
938
			     u64 child_nodeid, struct qstr *name)
John Muir's avatar
John Muir committed
939
940
941
942
943
944
945
946
947
948
{
	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
949
	inode_lock(parent);
John Muir's avatar
John Muir committed
950
951
952
953
954
955
956
957
	if (!S_ISDIR(parent->i_mode))
		goto unlock;

	err = -ENOENT;
	dir = d_find_alias(parent);
	if (!dir)
		goto unlock;

958
	name->hash = full_name_hash(dir, name->name, name->len);
John Muir's avatar
John Muir committed
959
960
961
962
963
964
965
	entry = d_lookup(dir, name);
	dput(dir);
	if (!entry)
		goto unlock;

	fuse_invalidate_attr(parent);
	fuse_invalidate_entry(entry);
966

967
	if (child_nodeid != 0 && d_really_is_positive(entry)) {
Al Viro's avatar
Al Viro committed
968
		inode_lock(d_inode(entry));
969
		if (get_node_id(d_inode(entry)) != child_nodeid) {
970
971
972
973
974
975
976
			err = -ENOENT;
			goto badentry;
		}
		if (d_mountpoint(entry)) {
			err = -EBUSY;
			goto badentry;
		}
977
		if (d_is_dir(entry)) {
978
979
980
981
982
			shrink_dcache_parent(entry);
			if (!simple_empty(entry)) {
				err = -ENOTEMPTY;
				goto badentry;
			}
983
			d_inode(entry)->i_flags |= S_DEAD;
984
985
		}
		dont_mount(entry);
986
		clear_nlink(d_inode(entry));
987
988
		err = 0;
 badentry:
Al Viro's avatar
Al Viro committed
989
		inode_unlock(d_inode(entry));
990
991
992
993
994
		if (!err)
			d_delete(entry);
	} else {
		err = 0;
	}
John Muir's avatar
John Muir committed
995
996
997
	dput(entry);

 unlock:
Al Viro's avatar
Al Viro committed
998
	inode_unlock(parent);
John Muir's avatar
John Muir committed
999
1000
1001
1002
	iput(parent);
	return err;
}

1003
1004
/*
 * Calling into a user-controlled filesystem gives the filesystem
1005
 * daemon ptrace-like capabilities over the current process.  This
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
 * means, that the filesystem daemon is able to record the exact
 * filesystem operations performed, and can also control the behavior
 * of the requester process in otherwise impossible ways.  For example
 * it can delay the operation for arbitrary length of time allowing
 * DoS against the requester.
 *
 * For this reason only those processes can call into the filesystem,
 * for which the owner of the mount has ptrace privilege.  This
 * excludes processes started by other users, suid or sgid processes.
 */
1016
int fuse_allow_current_process(struct fuse_conn *fc)
1017
{
1018
	const struct cred *cred;
1019

1020
	if (fc->flags & FUSE_ALLOW_OTHER)
1021
1022
		return 1;

1023
	cred = current_cred();
1024
1025
1026
1027
1028
1029
	if (uid_eq(cred->euid, fc->user_id) &&
	    uid_eq(cred->suid, fc->user_id) &&
	    uid_eq(cred->uid,  fc->user_id) &&
	    gid_eq(cred->egid, fc->group_id) &&
	    gid_eq(cred->sgid, fc->group_id) &&
	    gid_eq(cred->gid,  fc->group_id))