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
/*
 * 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
123
void fuse_invalidate_entry_cache(struct dentry *entry)
124
{
Miklos Szeredi's avatar
Miklos Szeredi committed
125
	fuse_dentry_settime(entry, 0);
126
127
}

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

138
139
static void fuse_lookup_init(struct fuse_conn *fc, struct fuse_req *req,
			     u64 nodeid, struct qstr *name,
140
141
			     struct fuse_entry_out *outarg)
{
142
	memset(outarg, 0, sizeof(struct fuse_entry_out));
143
	req->in.h.opcode = FUSE_LOOKUP;
144
	req->in.h.nodeid = nodeid;
145
	req->in.numargs = 1;
146
147
	req->in.args[0].size = name->len + 1;
	req->in.args[0].value = name->name;
148
	req->out.numargs = 1;
149
150
151
152
	if (fc->minor < 9)
		req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
	else
		req->out.args[0].size = sizeof(struct fuse_entry_out);
153
154
155
	req->out.args[0].value = outarg;
}

156
u64 fuse_get_attr_version(struct fuse_conn *fc)
157
158
159
160
161
162
163
164
165
166
167
168
169
170
{
	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;
}

171
172
173
174
175
176
177
178
179
/*
 * 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.
 */
180
static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
181
{
182
	struct inode *inode;
183
184
	struct dentry *parent;
	struct fuse_conn *fc;
185

186
	inode = ACCESS_ONCE(entry->d_inode);
187
	if (inode && is_bad_inode(inode))
188
		return 0;
Miklos Szeredi's avatar
Miklos Szeredi committed
189
	else if (fuse_dentry_time(entry) < get_jiffies_64()) {
190
191
		int err;
		struct fuse_entry_out outarg;
192
		struct fuse_req *req;
193
		struct fuse_forget_link *forget;
194
		u64 attr_version;
195

196
		/* For negative dentries, always do a fresh lookup */
197
198
199
		if (!inode)
			return 0;

200
		if (flags & LOOKUP_RCU)
201
202
			return -ECHILD;

203
		fc = get_fuse_conn(inode);
204
		req = fuse_get_req_nopages(fc);
205
		if (IS_ERR(req))
206
207
			return 0;

208
209
		forget = fuse_alloc_forget();
		if (!forget) {
210
211
212
213
			fuse_put_request(fc, req);
			return 0;
		}

214
		attr_version = fuse_get_attr_version(fc);
215

216
		parent = dget_parent(entry);
217
218
		fuse_lookup_init(fc, req, get_node_id(parent->d_inode),
				 &entry->d_name, &outarg);
219
		fuse_request_send(fc, req);
220
		dput(parent);
221
		err = req->out.h.error;
222
		fuse_put_request(fc, req);
223
224
225
		/* Zero nodeid is same as -ENOENT */
		if (!err && !outarg.nodeid)
			err = -ENOENT;
226
		if (!err) {
227
			struct fuse_inode *fi = get_fuse_inode(inode);
228
			if (outarg.nodeid != get_node_id(inode)) {
229
				fuse_queue_forget(fc, forget, outarg.nodeid, 1);
230
231
				return 0;
			}
232
			spin_lock(&fc->lock);
Miklos Szeredi's avatar
Miklos Szeredi committed
233
			fi->nlookup++;
234
			spin_unlock(&fc->lock);
235
		}
236
		kfree(forget);
237
		if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
238
239
			return 0;

240
241
242
243
		fuse_change_attributes(inode, &outarg.attr,
				       entry_attr_timeout(&outarg),
				       attr_version);
		fuse_change_entry_timeout(entry, &outarg);
244
245
246
247
248
249
250
	} else if (inode) {
		fc = get_fuse_conn(inode);
		if (fc->readdirplus_auto) {
			parent = dget_parent(entry);
			fuse_advise_use_readdirplus(parent->d_inode);
			dput(parent);
		}
251
252
253
254
	}
	return 1;
}

255
static int invalid_nodeid(u64 nodeid)
256
257
258
259
{
	return !nodeid || nodeid == FUSE_ROOT_ID;
}

Al Viro's avatar
Al Viro committed
260
const struct dentry_operations fuse_dentry_operations = {
261
262
263
	.d_revalidate	= fuse_dentry_revalidate,
};

264
int fuse_valid_type(int m)
265
266
267
268
269
{
	return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) ||
		S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m);
}

270
271
272
273
/*
 * Add a directory inode to a dentry, ensuring that no other dentry
 * refers to this inode.  Called with fc->inst_mutex.
 */
274
275
static struct dentry *fuse_d_add_directory(struct dentry *entry,
					   struct inode *inode)
276
277
{
	struct dentry *alias = d_find_alias(inode);
278
	if (alias && !(alias->d_flags & DCACHE_DISCONNECTED)) {
279
280
281
		/* This tries to shrink the subtree below alias */
		fuse_invalidate_entry(alias);
		dput(alias);
282
		if (!hlist_empty(&inode->i_dentry))
283
284
285
			return ERR_PTR(-EBUSY);
	} else {
		dput(alias);
286
	}
287
	return d_splice_alias(inode, entry);
288
289
}

290
291
int fuse_lookup_name(struct super_block *sb, u64 nodeid, struct qstr *name,
		     struct fuse_entry_out *outarg, struct inode **inode)
292
{
293
	struct fuse_conn *fc = get_fuse_conn_super(sb);
294
	struct fuse_req *req;
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
	req = fuse_get_req_nopages(fc);
305
	err = PTR_ERR(req);
306
	if (IS_ERR(req))
307
		goto out;
308

309
310
311
	forget = fuse_alloc_forget();
	err = -ENOMEM;
	if (!forget) {
312
		fuse_put_request(fc, req);
313
		goto out;
314
315
	}

316
	attr_version = fuse_get_attr_version(fc);
317

318
	fuse_lookup_init(fc, req, nodeid, name, outarg);
319
	fuse_request_send(fc, req);
320
	err = req->out.h.error;
321
	fuse_put_request(fc, req);
322
	/* Zero nodeid is same as -ENOENT, but with valid timeout */
323
324
325
326
327
328
329
330
331
332
333
334
335
336
	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) {
337
		fuse_queue_forget(fc, forget, outarg->nodeid, 1);
338
		goto out;
339
	}
340
341
342
	err = 0;

 out_put_forget:
343
	kfree(forget);
344
345
346
347
348
 out:
	return err;
}

static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
Al Viro's avatar
Al Viro committed
349
				  unsigned int flags)
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
{
	int err;
	struct fuse_entry_out outarg;
	struct inode *inode;
	struct dentry *newent;
	struct fuse_conn *fc = get_fuse_conn(dir);
	bool outarg_valid = true;

	err = fuse_lookup_name(dir->i_sb, get_node_id(dir), &entry->d_name,
			       &outarg, &inode);
	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;
370

371
372
	if (inode && S_ISDIR(inode->i_mode)) {
		mutex_lock(&fc->inst_mutex);
373
		newent = fuse_d_add_directory(entry, inode);
374
		mutex_unlock(&fc->inst_mutex);
375
376
377
378
		err = PTR_ERR(newent);
		if (IS_ERR(newent))
			goto out_iput;
	} else {
379
		newent = d_splice_alias(inode, entry);
380
	}
381

382
	entry = newent ? newent : entry;
383
	if (outarg_valid)
384
		fuse_change_entry_timeout(entry, &outarg);
385
386
	else
		fuse_invalidate_entry_cache(entry);
387

388
	fuse_advise_use_readdirplus(dir);
389
	return newent;
390
391
392
393
394

 out_iput:
	iput(inode);
 out_err:
	return ERR_PTR(err);
395
396
}

397
398
399
400
401
402
/*
 * 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
403
static int fuse_create_open(struct inode *dir, struct dentry *entry,
Al Viro's avatar
Al Viro committed
404
			    struct file *file, unsigned flags,
Al Viro's avatar
Al Viro committed
405
			    umode_t mode, int *opened)
406
407
408
409
410
{
	int err;
	struct inode *inode;
	struct fuse_conn *fc = get_fuse_conn(dir);
	struct fuse_req *req;
411
	struct fuse_forget_link *forget;
412
	struct fuse_create_in inarg;
413
414
415
416
	struct fuse_open_out outopen;
	struct fuse_entry_out outentry;
	struct fuse_file *ff;

417
418
419
	/* Userspace expects S_IFREG in create mode */
	BUG_ON((mode & S_IFMT) != S_IFREG);

420
	forget = fuse_alloc_forget();
421
	err = -ENOMEM;
422
	if (!forget)
423
		goto out_err;
424

425
	req = fuse_get_req_nopages(fc);
426
	err = PTR_ERR(req);
427
	if (IS_ERR(req))
428
		goto out_put_forget_req;
429

430
	err = -ENOMEM;
Tejun Heo's avatar
Tejun Heo committed
431
	ff = fuse_file_alloc(fc);
432
433
434
	if (!ff)
		goto out_put_request;

435
436
437
	if (!fc->dont_mask)
		mode &= ~current_umask();

438
439
	flags &= ~O_NOCTTY;
	memset(&inarg, 0, sizeof(inarg));
440
	memset(&outentry, 0, sizeof(outentry));
441
442
	inarg.flags = flags;
	inarg.mode = mode;
443
	inarg.umask = current_umask();
444
445
446
	req->in.h.opcode = FUSE_CREATE;
	req->in.h.nodeid = get_node_id(dir);
	req->in.numargs = 2;
447
448
	req->in.args[0].size = fc->minor < 12 ? sizeof(struct fuse_open_in) :
						sizeof(inarg);
449
450
451
452
	req->in.args[0].value = &inarg;
	req->in.args[1].size = entry->d_name.len + 1;
	req->in.args[1].value = entry->d_name.name;
	req->out.numargs = 2;
453
454
455
456
	if (fc->minor < 9)
		req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
	else
		req->out.args[0].size = sizeof(outentry);
457
458
459
	req->out.args[0].value = &outentry;
	req->out.args[1].size = sizeof(outopen);
	req->out.args[1].value = &outopen;
460
	fuse_request_send(fc, req);
461
	err = req->out.h.error;
462
	if (err)
463
464
465
		goto out_free_ff;

	err = -EIO;
466
	if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid))
467
468
		goto out_free_ff;

469
	fuse_put_request(fc, req);
470
471
472
	ff->fh = outopen.fh;
	ff->nodeid = outentry.nodeid;
	ff->open_flags = outopen.open_flags;
473
	inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
474
			  &outentry.attr, entry_attr_timeout(&outentry), 0);
475
476
	if (!inode) {
		flags &= ~(O_CREAT | O_EXCL | O_TRUNC);
477
		fuse_sync_release(ff, flags);
478
		fuse_queue_forget(fc, forget, outentry.nodeid, 1);
479
480
		err = -ENOMEM;
		goto out_err;
481
	}
482
	kfree(forget);
483
	d_instantiate(entry, inode);
484
	fuse_change_entry_timeout(entry, &outentry);
485
	fuse_invalidate_attr(dir);
Al Viro's avatar
Al Viro committed
486
487
	err = finish_open(file, entry, generic_file_open, opened);
	if (err) {
488
		fuse_sync_release(ff, flags);
489
490
491
	} else {
		file->private_data = fuse_file_get(ff);
		fuse_finish_open(inode, file);
492
	}
Al Viro's avatar
Al Viro committed
493
	return err;
494

495
out_free_ff:
496
	fuse_file_free(ff);
497
out_put_request:
498
	fuse_put_request(fc, req);
499
out_put_forget_req:
500
	kfree(forget);
501
out_err:
Al Viro's avatar
Al Viro committed
502
	return err;
503
504
505
}

static int fuse_mknod(struct inode *, struct dentry *, umode_t, dev_t);
Al Viro's avatar
Al Viro committed
506
static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
Al Viro's avatar
Al Viro committed
507
			    struct file *file, unsigned flags,
Al Viro's avatar
Al Viro committed
508
			    umode_t mode, int *opened)
509
510
511
512
513
514
{
	int err;
	struct fuse_conn *fc = get_fuse_conn(dir);
	struct dentry *res = NULL;

	if (d_unhashed(entry)) {
Al Viro's avatar
Al Viro committed
515
		res = fuse_lookup(dir, entry, 0);
516
		if (IS_ERR(res))
Al Viro's avatar
Al Viro committed
517
			return PTR_ERR(res);
518
519
520
521
522
523
524
525
526

		if (res)
			entry = res;
	}

	if (!(flags & O_CREAT) || entry->d_inode)
		goto no_open;

	/* Only creates */
527
	*opened |= FILE_CREATED;
528
529
530
531

	if (fc->no_create)
		goto mknod;

Al Viro's avatar
Al Viro committed
532
	err = fuse_create_open(dir, entry, file, flags, mode, opened);
Al Viro's avatar
Al Viro committed
533
	if (err == -ENOSYS) {
534
535
536
537
538
		fc->no_create = 1;
		goto mknod;
	}
out_dput:
	dput(res);
Al Viro's avatar
Al Viro committed
539
	return err;
540
541
542

mknod:
	err = fuse_mknod(dir, entry, mode, 0);
Al Viro's avatar
Al Viro committed
543
	if (err)
544
545
		goto out_dput;
no_open:
Al Viro's avatar
Al Viro committed
546
	return finish_no_open(file, res);
547
548
}

549
550
551
/*
 * Code shared between mknod, mkdir, symlink and link
 */
552
553
static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
			    struct inode *dir, struct dentry *entry,
Al Viro's avatar
Al Viro committed
554
			    umode_t mode)
555
556
557
558
{
	struct fuse_entry_out outarg;
	struct inode *inode;
	int err;
559
	struct fuse_forget_link *forget;
560

561
562
	forget = fuse_alloc_forget();
	if (!forget) {
563
		fuse_put_request(fc, req);
564
		return -ENOMEM;
565
	}
566

567
	memset(&outarg, 0, sizeof(outarg));
568
569
	req->in.h.nodeid = get_node_id(dir);
	req->out.numargs = 1;
570
571
572
573
	if (fc->minor < 9)
		req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
	else
		req->out.args[0].size = sizeof(outarg);
574
	req->out.args[0].value = &outarg;
575
	fuse_request_send(fc, req);
576
	err = req->out.h.error;
577
578
579
580
	fuse_put_request(fc, req);
	if (err)
		goto out_put_forget_req;

581
582
	err = -EIO;
	if (invalid_nodeid(outarg.nodeid))
583
		goto out_put_forget_req;
584
585

	if ((outarg.attr.mode ^ mode) & S_IFMT)
586
		goto out_put_forget_req;
587

588
	inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
589
			  &outarg.attr, entry_attr_timeout(&outarg), 0);
590
	if (!inode) {
591
		fuse_queue_forget(fc, forget, outarg.nodeid, 1);
592
593
		return -ENOMEM;
	}
594
	kfree(forget);
595

596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
	if (S_ISDIR(inode->i_mode)) {
		struct dentry *alias;
		mutex_lock(&fc->inst_mutex);
		alias = d_find_alias(inode);
		if (alias) {
			/* New directory must have moved since mkdir */
			mutex_unlock(&fc->inst_mutex);
			dput(alias);
			iput(inode);
			return -EBUSY;
		}
		d_instantiate(entry, inode);
		mutex_unlock(&fc->inst_mutex);
	} else
		d_instantiate(entry, inode);
611

612
	fuse_change_entry_timeout(entry, &outarg);
613
614
	fuse_invalidate_attr(dir);
	return 0;
615

616
 out_put_forget_req:
617
	kfree(forget);
618
	return err;
619
620
}

Al Viro's avatar
Al Viro committed
621
static int fuse_mknod(struct inode *dir, struct dentry *entry, umode_t mode,
622
623
624
625
		      dev_t rdev)
{
	struct fuse_mknod_in inarg;
	struct fuse_conn *fc = get_fuse_conn(dir);
626
	struct fuse_req *req = fuse_get_req_nopages(fc);
627
628
	if (IS_ERR(req))
		return PTR_ERR(req);
629

630
631
632
	if (!fc->dont_mask)
		mode &= ~current_umask();

633
634
635
	memset(&inarg, 0, sizeof(inarg));
	inarg.mode = mode;
	inarg.rdev = new_encode_dev(rdev);
636
	inarg.umask = current_umask();
637
638
	req->in.h.opcode = FUSE_MKNOD;
	req->in.numargs = 2;
639
640
	req->in.args[0].size = fc->minor < 12 ? FUSE_COMPAT_MKNOD_IN_SIZE :
						sizeof(inarg);
641
642
643
644
645
646
	req->in.args[0].value = &inarg;
	req->in.args[1].size = entry->d_name.len + 1;
	req->in.args[1].value = entry->d_name.name;
	return create_new_entry(fc, req, dir, entry, mode);
}

Al Viro's avatar
Al Viro committed
647
static int fuse_create(struct inode *dir, struct dentry *entry, umode_t mode,
Al Viro's avatar
Al Viro committed
648
		       bool excl)
649
650
651
652
{
	return fuse_mknod(dir, entry, mode, 0);
}

653
static int fuse_mkdir(struct inode *dir, struct dentry *entry, umode_t mode)
654
655
656
{
	struct fuse_mkdir_in inarg;
	struct fuse_conn *fc = get_fuse_conn(dir);
657
	struct fuse_req *req = fuse_get_req_nopages(fc);
658
659
	if (IS_ERR(req))
		return PTR_ERR(req);
660

661
662
663
	if (!fc->dont_mask)
		mode &= ~current_umask();

664
665
	memset(&inarg, 0, sizeof(inarg));
	inarg.mode = mode;
666
	inarg.umask = current_umask();
667
668
669
670
671
672
673
674
675
676
677
678
679
680
	req->in.h.opcode = FUSE_MKDIR;
	req->in.numargs = 2;
	req->in.args[0].size = sizeof(inarg);
	req->in.args[0].value = &inarg;
	req->in.args[1].size = entry->d_name.len + 1;
	req->in.args[1].value = entry->d_name.name;
	return create_new_entry(fc, req, dir, entry, S_IFDIR);
}

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;
681
	struct fuse_req *req = fuse_get_req_nopages(fc);
682
683
	if (IS_ERR(req))
		return PTR_ERR(req);
684
685
686
687
688
689
690
691
692
693
694
695
696
697

	req->in.h.opcode = FUSE_SYMLINK;
	req->in.numargs = 2;
	req->in.args[0].size = entry->d_name.len + 1;
	req->in.args[0].value = entry->d_name.name;
	req->in.args[1].size = len;
	req->in.args[1].value = link;
	return create_new_entry(fc, req, dir, entry, S_IFLNK);
}

static int fuse_unlink(struct inode *dir, struct dentry *entry)
{
	int err;
	struct fuse_conn *fc = get_fuse_conn(dir);
698
	struct fuse_req *req = fuse_get_req_nopages(fc);
699
700
	if (IS_ERR(req))
		return PTR_ERR(req);
701
702
703
704
705
706

	req->in.h.opcode = FUSE_UNLINK;
	req->in.h.nodeid = get_node_id(dir);
	req->in.numargs = 1;
	req->in.args[0].size = entry->d_name.len + 1;
	req->in.args[0].value = entry->d_name.name;
707
	fuse_request_send(fc, req);
708
709
710
711
	err = req->out.h.error;
	fuse_put_request(fc, req);
	if (!err) {
		struct inode *inode = entry->d_inode;
Miklos Szeredi's avatar
Miklos Szeredi committed
712
		struct fuse_inode *fi = get_fuse_inode(inode);
713

Miklos Szeredi's avatar
Miklos Szeredi committed
714
715
		spin_lock(&fc->lock);
		fi->attr_version = ++fc->attr_version;
716
717
718
719
720
721
722
723
		/*
		 * 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
724
		spin_unlock(&fc->lock);
725
726
		fuse_invalidate_attr(inode);
		fuse_invalidate_attr(dir);
727
		fuse_invalidate_entry_cache(entry);
728
729
730
731
732
733
734
735
736
	} 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);
737
	struct fuse_req *req = fuse_get_req_nopages(fc);
738
739
	if (IS_ERR(req))
		return PTR_ERR(req);
740
741
742
743
744
745

	req->in.h.opcode = FUSE_RMDIR;
	req->in.h.nodeid = get_node_id(dir);
	req->in.numargs = 1;
	req->in.args[0].size = entry->d_name.len + 1;
	req->in.args[0].value = entry->d_name.name;
746
	fuse_request_send(fc, req);
747
748
749
	err = req->out.h.error;
	fuse_put_request(fc, req);
	if (!err) {
750
		clear_nlink(entry->d_inode);
751
		fuse_invalidate_attr(dir);
752
		fuse_invalidate_entry_cache(entry);
753
754
755
756
757
758
759
760
761
762
763
	} else if (err == -EINTR)
		fuse_invalidate_entry(entry);
	return err;
}

static int fuse_rename(struct inode *olddir, struct dentry *oldent,
		       struct inode *newdir, struct dentry *newent)
{
	int err;
	struct fuse_rename_in inarg;
	struct fuse_conn *fc = get_fuse_conn(olddir);
764
	struct fuse_req *req = fuse_get_req_nopages(fc);
765

766
767
	if (IS_ERR(req))
		return PTR_ERR(req);
768
769
770
771
772
773
774
775
776
777
778
779

	memset(&inarg, 0, sizeof(inarg));
	inarg.newdir = get_node_id(newdir);
	req->in.h.opcode = FUSE_RENAME;
	req->in.h.nodeid = get_node_id(olddir);
	req->in.numargs = 3;
	req->in.args[0].size = sizeof(inarg);
	req->in.args[0].value = &inarg;
	req->in.args[1].size = oldent->d_name.len + 1;
	req->in.args[1].value = oldent->d_name.name;
	req->in.args[2].size = newent->d_name.len + 1;
	req->in.args[2].value = newent->d_name.name;
780
	fuse_request_send(fc, req);
781
782
783
	err = req->out.h.error;
	fuse_put_request(fc, req);
	if (!err) {
784
785
786
		/* ctime changes */
		fuse_invalidate_attr(oldent->d_inode);

787
788
789
		fuse_invalidate_attr(olddir);
		if (olddir != newdir)
			fuse_invalidate_attr(newdir);
790
791

		/* newent will end up negative */
792
793
		if (newent->d_inode) {
			fuse_invalidate_attr(newent->d_inode);
794
			fuse_invalidate_entry_cache(newent);
795
		}
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
	} 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);
		if (newent->d_inode)
			fuse_invalidate_entry(newent);
	}

	return err;
}

static int fuse_link(struct dentry *entry, struct inode *newdir,
		     struct dentry *newent)
{
	int err;
	struct fuse_link_in inarg;
	struct inode *inode = entry->d_inode;
	struct fuse_conn *fc = get_fuse_conn(inode);
817
	struct fuse_req *req = fuse_get_req_nopages(fc);
818
819
	if (IS_ERR(req))
		return PTR_ERR(req);
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835

	memset(&inarg, 0, sizeof(inarg));
	inarg.oldnodeid = get_node_id(inode);
	req->in.h.opcode = FUSE_LINK;
	req->in.numargs = 2;
	req->in.args[0].size = sizeof(inarg);
	req->in.args[0].value = &inarg;
	req->in.args[1].size = newent->d_name.len + 1;
	req->in.args[1].value = newent->d_name.name;
	err = create_new_entry(fc, req, newdir, newent, inode->i_mode);
	/* 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
836
837
838
839
840
841
842
	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);
843
		fuse_invalidate_attr(inode);
Miklos Szeredi's avatar
Miklos Szeredi committed
844
845
846
	} else if (err == -EINTR) {
		fuse_invalidate_attr(inode);
	}
847
848
849
	return err;
}

850
851
852
static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr,
			  struct kstat *stat)
{
Miklos Szeredi's avatar
Miklos Szeredi committed
853
854
	unsigned int blkbits;

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(&init_user_ns, attr->uid);
	stat->gid = make_kgid(&init_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
887
888
	struct fuse_req *req;
	u64 attr_version;

889
	req = fuse_get_req_nopages(fc);
890
891
	if (IS_ERR(req))
		return PTR_ERR(req);
892

893
	attr_version = fuse_get_attr_version(fc);
894

895
	memset(&inarg, 0, sizeof(inarg));
896
	memset(&outarg, 0, sizeof(outarg));
897
898
899
900
901
902
903
	/* 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;
	}
904
905
	req->in.h.opcode = FUSE_GETATTR;
	req->in.h.nodeid = get_node_id(inode);
906
907
908
	req->in.numargs = 1;
	req->in.args[0].size = sizeof(inarg);
	req->in.args[0].value = &inarg;
909
	req->out.numargs = 1;
910
911
912
913
	if (fc->minor < 9)
		req->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
	else
		req->out.args[0].size = sizeof(outarg);
914
	req->out.args[0].value = &outarg;
915
	fuse_request_send(fc, req);
916
917
918
	err = req->out.h.error;
	fuse_put_request(fc, req);
	if (!err) {
919
		if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
920
921
922
			make_bad_inode(inode);
			err = -EIO;
		} else {
923
924
			fuse_change_attributes(inode, &outarg.attr,
					       attr_timeout(&outarg),
925
926
					       attr_version);
			if (stat)
927
				fuse_fillattr(inode, &outarg.attr, stat);
928
929
930
931
932
		}
	}
	return err;
}

Miklos Szeredi's avatar
Miklos Szeredi committed
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
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;

	if (fi->i_time < get_jiffies_64()) {
		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;
949
			stat->ino = fi->orig_ino;
Miklos Szeredi's avatar
Miklos Szeredi committed
950
951
952
953
954
955
956
957
958
		}
	}

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

	return err;
}

John Muir's avatar
John Muir committed
959
int fuse_reverse_inval_entry(struct super_block *sb, u64 parent_nodeid,
960
			     u64 child_nodeid, struct qstr *name)
John Muir's avatar
John Muir committed
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
{
	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;

	mutex_lock(&parent->i_mutex);
	if (!S_ISDIR(parent->i_mode))
		goto unlock;

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

	entry = d_lookup(dir, name);
	dput(dir);
	if (!entry)
		goto unlock;

	fuse_invalidate_attr(parent);
	fuse_invalidate_entry(entry);
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015

	if (child_nodeid != 0 && entry->d_inode) {
		mutex_lock(&entry->d_inode->i_mutex);
		if (get_node_id(entry->d_inode) != child_nodeid) {
			err = -ENOENT;
			goto badentry;
		}
		if (d_mountpoint(entry)) {
			err = -EBUSY;
			goto badentry;
		}
		if (S_ISDIR(entry->d_inode->i_mode)) {
			shrink_dcache_parent(entry);
			if (!simple_empty(entry)) {
				err = -ENOTEMPTY;
				goto badentry;
			}
			entry->d_inode->i_flags |= S_DEAD;
		}
		dont_mount(entry);
		clear_nlink(entry->d_inode);
		err = 0;
 badentry:
		mutex_unlock(&entry->d_inode->i_mutex);
		if (!err)
			d_delete(entry);
	} else {
		err = 0;
	}
John Muir's avatar
John Muir committed
1016
1017
1018
1019
1020
1021
1022
1023
	dput(entry);

 unlock:
	mutex_unlock(&parent->i_mutex);
	iput(parent);
	return err;
}

1024
1025
/*
 * Calling into a user-controlled filesystem gives the filesystem
1026
 * daemon ptrace-like capabilities over the current process.  This
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
 * 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.
 */
1037
int fuse_allow_current_process(struct fuse_conn *fc)
1038
{
1039
	const struct cred *cred;
1040

1041
	if (fc->flags & FUSE_ALLOW_OTHER)
1042
1043
		return 1;

1044
	cred = current_cred();
1045
1046
1047
1048
1049
1050
	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))
1051
		return 1;
1052

1053
	return 0;
1054
1055
}

Miklos Szeredi's avatar
Miklos Szeredi committed
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
static int fuse_access(struct inode *inode, int mask)
{
	struct fuse_conn *fc = get_fuse_conn(inode);
	struct fuse_req *req;
	struct fuse_access_in inarg;
	int err;

	if (fc->no_access)
		return 0;

1066
	req = fuse_get_req_nopages(fc);
1067
1068
	if (IS_ERR(req))
		return PTR_ERR(req);
Miklos Szeredi's avatar
Miklos Szeredi committed
1069
1070

	memset(&inarg, 0, sizeof(inarg));
1071
	inarg.mask = mask & (MAY_READ | MAY_WRITE | MAY_EXEC);
Miklos Szeredi's avatar
Miklos Szeredi committed
1072
1073
1074
1075
1076
	req->in.h.opcode = FUSE_ACCESS;
	req->in.h.nodeid = get_node_id(inode);
	req->in.numargs = 1;
	req->in.args[0].size = sizeof(inarg);
	req->in.args[0].value = &inarg;
1077
	fuse_request_send(fc, req);