super.c 17.8 KB
Newer Older
C
Chris Mason 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*
 * Copyright (C) 2007 Oracle.  All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License v2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 021110-1307, USA.
 */

Y
Yan 已提交
19
#include <linux/blkdev.h>
20
#include <linux/module.h>
C
Chris Mason 已提交
21
#include <linux/buffer_head.h>
22 23 24 25 26
#include <linux/fs.h>
#include <linux/pagemap.h>
#include <linux/highmem.h>
#include <linux/time.h>
#include <linux/init.h>
E
Eric Paris 已提交
27
#include <linux/seq_file.h>
28 29 30
#include <linux/string.h>
#include <linux/smp_lock.h>
#include <linux/backing-dev.h>
Y
Yan 已提交
31
#include <linux/mount.h>
C
Chris Mason 已提交
32
#include <linux/mpage.h>
C
Chris Mason 已提交
33 34
#include <linux/swap.h>
#include <linux/writeback.h>
C
Chris Mason 已提交
35
#include <linux/statfs.h>
C
Chris Mason 已提交
36
#include <linux/compat.h>
37
#include <linux/parser.h>
38
#include <linux/ctype.h>
39
#include <linux/namei.h>
40
#include <linux/miscdevice.h>
41
#include <linux/magic.h>
C
Chris Mason 已提交
42
#include "compat.h"
43
#include "ctree.h"
C
Chris Mason 已提交
44
#include "disk-io.h"
45
#include "transaction.h"
C
Chris Mason 已提交
46
#include "btrfs_inode.h"
C
Chris Mason 已提交
47
#include "ioctl.h"
C
Chris Mason 已提交
48
#include "print-tree.h"
J
Josef Bacik 已提交
49
#include "xattr.h"
50
#include "volumes.h"
51
#include "version.h"
B
Balaji Rao 已提交
52
#include "export.h"
C
Chris Mason 已提交
53
#include "compression.h"
54

C
Chris Mason 已提交
55

C
Chris Mason 已提交
56
static struct super_operations btrfs_super_ops;
C
Chris Mason 已提交
57

C
Chris Mason 已提交
58
static void btrfs_put_super(struct super_block *sb)
C
Chris Mason 已提交
59
{
C
Chris Mason 已提交
60
	struct btrfs_root *root = btrfs_sb(sb);
C
Chris Mason 已提交
61 62
	int ret;

C
Chris Mason 已提交
63 64
	ret = close_ctree(root);
	sb->s_fs_info = NULL;
C
Chris Mason 已提交
65 66
}

67
enum {
68
	Opt_degraded, Opt_subvol, Opt_device, Opt_nodatasum, Opt_nodatacow,
69
	Opt_max_extent, Opt_max_inline, Opt_alloc_start, Opt_nobarrier,
S
Sage Weil 已提交
70 71
	Opt_ssd, Opt_thread_pool, Opt_noacl,  Opt_compress, Opt_notreelog,
	Opt_err,
72 73 74
};

static match_table_t tokens = {
75
	{Opt_degraded, "degraded"},
76
	{Opt_subvol, "subvol=%s"},
77
	{Opt_device, "device=%s"},
78
	{Opt_nodatasum, "nodatasum"},
79
	{Opt_nodatacow, "nodatacow"},
80
	{Opt_nobarrier, "nobarrier"},
81
	{Opt_max_extent, "max_extent=%s"},
82
	{Opt_max_inline, "max_inline=%s"},
83
	{Opt_alloc_start, "alloc_start=%s"},
84
	{Opt_thread_pool, "thread_pool=%d"},
C
Chris Mason 已提交
85
	{Opt_compress, "compress"},
86
	{Opt_ssd, "ssd"},
J
Josef Bacik 已提交
87
	{Opt_noacl, "noacl"},
S
Sage Weil 已提交
88
	{Opt_notreelog, "notreelog"},
J
Josef Bacik 已提交
89
	{Opt_err, NULL},
90 91
};

92
u64 btrfs_parse_size(char *str)
93
{
94
	u64 res;
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
	int mult = 1;
	char *end;
	char last;

	res = simple_strtoul(str, &end, 10);

	last = end[0];
	if (isalpha(last)) {
		last = tolower(last);
		switch (last) {
		case 'g':
			mult *= 1024;
		case 'm':
			mult *= 1024;
		case 'k':
			mult *= 1024;
		}
		res = res * mult;
	}
	return res;
}

117 118 119 120 121
/*
 * Regular mount options parser.  Everything that is needed only when
 * reading in a new superblock is parsed here.
 */
int btrfs_parse_options(struct btrfs_root *root, char *options)
122
{
123
	struct btrfs_fs_info *info = root->fs_info;
124
	substring_t args[MAX_OPT_ARGS];
125
	char *p, *num;
126
	int intarg;
127

128
	if (!options)
129
		return 0;
130

131 132 133 134 135 136 137 138 139
	/*
	 * strsep changes the string, duplicate it because parse_options
	 * gets called twice
	 */
	options = kstrdup(options, GFP_NOFS);
	if (!options)
		return -ENOMEM;


140
	while ((p = strsep(&options, ",")) != NULL) {
141 142 143 144 145 146
		int token;
		if (!*p)
			continue;

		token = match_token(p, tokens, args);
		switch (token) {
147
		case Opt_degraded:
148 149
			printk(KERN_INFO "btrfs: allowing degraded mounts\n");
			btrfs_set_opt(info->mount_opt, DEGRADED);
150
			break;
151
		case Opt_subvol:
152
		case Opt_device:
153
			/*
154
			 * These are parsed by btrfs_parse_early_options
155 156
			 * and can be happily ignored here.
			 */
157 158
			break;
		case Opt_nodatasum:
159 160
			printk(KERN_INFO "btrfs: setting nodatacsum\n");
			btrfs_set_opt(info->mount_opt, NODATASUM);
161 162
			break;
		case Opt_nodatacow:
163 164 165
			printk(KERN_INFO "btrfs: setting nodatacow\n");
			btrfs_set_opt(info->mount_opt, NODATACOW);
			btrfs_set_opt(info->mount_opt, NODATASUM);
166
			break;
C
Chris Mason 已提交
167 168 169 170
		case Opt_compress:
			printk(KERN_INFO "btrfs: use compression\n");
			btrfs_set_opt(info->mount_opt, COMPRESS);
			break;
171
		case Opt_ssd:
172 173
			printk(KERN_INFO "btrfs: use ssd allocation scheme\n");
			btrfs_set_opt(info->mount_opt, SSD);
174
			break;
175
		case Opt_nobarrier:
176 177
			printk(KERN_INFO "btrfs: turning off barriers\n");
			btrfs_set_opt(info->mount_opt, NOBARRIER);
178
			break;
179 180 181 182 183 184 185 186 187
		case Opt_thread_pool:
			intarg = 0;
			match_int(&args[0], &intarg);
			if (intarg) {
				info->thread_pool_size = intarg;
				printk(KERN_INFO "btrfs: thread pool %d\n",
				       info->thread_pool_size);
			}
			break;
188
		case Opt_max_extent:
189 190 191 192 193 194 195 196 197
			num = match_strdup(&args[0]);
			if (num) {
				info->max_extent = btrfs_parse_size(num);
				kfree(num);

				info->max_extent = max_t(u64,
					info->max_extent, root->sectorsize);
				printk(KERN_INFO "btrfs: max_extent at %llu\n",
				       info->max_extent);
198 199
			}
			break;
200
		case Opt_max_inline:
201 202 203 204 205
			num = match_strdup(&args[0]);
			if (num) {
				info->max_inline = btrfs_parse_size(num);
				kfree(num);

C
Chris Mason 已提交
206 207 208 209 210
				if (info->max_inline) {
					info->max_inline = max_t(u64,
						info->max_inline,
						root->sectorsize);
				}
211 212
				printk(KERN_INFO "btrfs: max_inline at %llu\n",
					info->max_inline);
213 214
			}
			break;
215
		case Opt_alloc_start:
216 217 218 219 220 221 222
			num = match_strdup(&args[0]);
			if (num) {
				info->alloc_start = btrfs_parse_size(num);
				kfree(num);
				printk(KERN_INFO
					"btrfs: allocations start at %llu\n",
					info->alloc_start);
223 224
			}
			break;
J
Josef Bacik 已提交
225 226 227
		case Opt_noacl:
			root->fs_info->sb->s_flags &= ~MS_POSIXACL;
			break;
S
Sage Weil 已提交
228 229 230 231
		case Opt_notreelog:
			printk(KERN_INFO "btrfs: disabling tree log\n");
			btrfs_set_opt(info->mount_opt, NOTREELOG);
			break;
232
		default:
233
			break;
234 235
		}
	}
236
	kfree(options);
237 238 239 240 241 242 243 244 245
	return 0;
}

/*
 * Parse mount options that are required early in the mount process.
 *
 * All other options will be parsed on much later in the mount process and
 * only when we need to allocate a new super block.
 */
246
static int btrfs_parse_early_options(const char *options, fmode_t flags,
247 248
		void *holder, char **subvol_name,
		struct btrfs_fs_devices **fs_devices)
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
{
	substring_t args[MAX_OPT_ARGS];
	char *opts, *p;
	int error = 0;

	if (!options)
		goto out;

	/*
	 * strsep changes the string, duplicate it because parse_options
	 * gets called twice
	 */
	opts = kstrdup(options, GFP_KERNEL);
	if (!opts)
		return -ENOMEM;

	while ((p = strsep(&opts, ",")) != NULL) {
		int token;
		if (!*p)
			continue;

		token = match_token(p, tokens, args);
		switch (token) {
		case Opt_subvol:
			*subvol_name = match_strdup(&args[0]);
			break;
275 276 277 278 279 280
		case Opt_device:
			error = btrfs_scan_one_device(match_strdup(&args[0]),
					flags, holder, fs_devices);
			if (error)
				goto out_free_opts;
			break;
281 282 283 284 285
		default:
			break;
		}
	}

286
 out_free_opts:
287 288 289 290
	kfree(opts);
 out:
	/*
	 * If no subvolume name is specified we use the default one.  Allocate
291
	 * a copy of the string "." here so that code later in the
292 293 294
	 * mount path doesn't care if it's the default volume or another one.
	 */
	if (!*subvol_name) {
295
		*subvol_name = kstrdup(".", GFP_KERNEL);
296 297 298 299
		if (!*subvol_name)
			return -ENOMEM;
	}
	return error;
300 301
}

C
Chris Mason 已提交
302
static int btrfs_fill_super(struct super_block *sb,
303
			    struct btrfs_fs_devices *fs_devices,
C
Chris Mason 已提交
304
			    void *data, int silent)
C
Chris Mason 已提交
305
{
C
Chris Mason 已提交
306 307
	struct inode *inode;
	struct dentry *root_dentry;
C
Chris Mason 已提交
308 309 310 311
	struct btrfs_super_block *disk_super;
	struct btrfs_root *tree_root;
	struct btrfs_inode *bi;
	int err;
312

C
Chris Mason 已提交
313 314 315
	sb->s_maxbytes = MAX_LFS_FILESIZE;
	sb->s_magic = BTRFS_SUPER_MAGIC;
	sb->s_op = &btrfs_super_ops;
B
Balaji Rao 已提交
316
	sb->s_export_op = &btrfs_export_ops;
J
Josef Bacik 已提交
317
	sb->s_xattr = btrfs_xattr_handlers;
C
Chris Mason 已提交
318
	sb->s_time_gran = 1;
J
Josef Bacik 已提交
319
	sb->s_flags |= MS_POSIXACL;
320

321
	tree_root = open_ctree(sb, fs_devices, (char *)data);
322

323
	if (IS_ERR(tree_root)) {
C
Chris Mason 已提交
324
		printk("btrfs: open_ctree failed\n");
325
		return PTR_ERR(tree_root);
326
	}
C
Chris Mason 已提交
327
	sb->s_fs_info = tree_root;
328
	disk_super = &tree_root->fs_info->super_copy;
329 330
	inode = btrfs_iget_locked(sb, BTRFS_FIRST_FREE_OBJECTID,
				  tree_root->fs_info->fs_root);
C
Chris Mason 已提交
331 332 333
	bi = BTRFS_I(inode);
	bi->location.objectid = inode->i_ino;
	bi->location.offset = 0;
334
	bi->root = tree_root->fs_info->fs_root;
335

C
Chris Mason 已提交
336
	btrfs_set_key_type(&bi->location, BTRFS_INODE_ITEM_KEY);
337

C
Chris Mason 已提交
338
	if (!inode) {
339
		err = -ENOMEM;
C
Chris Mason 已提交
340
		goto fail_close;
C
Chris Mason 已提交
341
	}
C
Chris Mason 已提交
342 343 344
	if (inode->i_state & I_NEW) {
		btrfs_read_locked_inode(inode);
		unlock_new_inode(inode);
C
Chris Mason 已提交
345 346
	}

C
Chris Mason 已提交
347 348 349 350 351
	root_dentry = d_alloc_root(inode);
	if (!root_dentry) {
		iput(inode);
		err = -ENOMEM;
		goto fail_close;
C
Chris Mason 已提交
352
	}
Y
Yan Zheng 已提交
353
#if 0
354 355 356 357
	/* this does the super kobj at the same time */
	err = btrfs_sysfs_add_super(tree_root->fs_info);
	if (err)
		goto fail_close;
Y
Yan Zheng 已提交
358
#endif
359

C
Chris Mason 已提交
360
	sb->s_root = root_dentry;
C
Chris Mason 已提交
361 362

	save_mount_options(sb, data);
C
Chris Mason 已提交
363
	return 0;
C
Chris Mason 已提交
364 365 366 367

fail_close:
	close_ctree(tree_root);
	return err;
C
Chris Mason 已提交
368 369
}

S
Sage Weil 已提交
370
int btrfs_sync_fs(struct super_block *sb, int wait)
C
Chris Mason 已提交
371 372
{
	struct btrfs_trans_handle *trans;
C
Chris Mason 已提交
373
	struct btrfs_root *root;
C
Chris Mason 已提交
374
	int ret;
C
Chris Mason 已提交
375
	root = btrfs_sb(sb);
C
Chris Mason 已提交
376

Y
Yan Zheng 已提交
377 378 379
	if (sb->s_flags & MS_RDONLY)
		return 0;

C
Chris Mason 已提交
380 381 382 383 384
	sb->s_dirt = 0;
	if (!wait) {
		filemap_flush(root->fs_info->btree_inode->i_mapping);
		return 0;
	}
385 386 387 388

	btrfs_start_delalloc_inodes(root);
	btrfs_wait_ordered_extents(root, 0);

C
Chris Mason 已提交
389 390
	trans = btrfs_start_transaction(root, 1);
	ret = btrfs_commit_transaction(trans, root);
C
Chris Mason 已提交
391
	sb->s_dirt = 0;
392
	return ret;
C
Chris Mason 已提交
393 394
}

E
Eric Paris 已提交
395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420
static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
{
	struct btrfs_root *root = btrfs_sb(vfs->mnt_sb);
	struct btrfs_fs_info *info = root->fs_info;

	if (btrfs_test_opt(root, DEGRADED))
		seq_puts(seq, ",degraded");
	if (btrfs_test_opt(root, NODATASUM))
		seq_puts(seq, ",nodatasum");
	if (btrfs_test_opt(root, NODATACOW))
		seq_puts(seq, ",nodatacow");
	if (btrfs_test_opt(root, NOBARRIER))
		seq_puts(seq, ",nobarrier");
	if (info->max_extent != (u64)-1)
		seq_printf(seq, ",max_extent=%llu", info->max_extent);
	if (info->max_inline != 8192 * 1024)
		seq_printf(seq, ",max_inline=%llu", info->max_inline);
	if (info->alloc_start != 0)
		seq_printf(seq, ",alloc_start=%llu", info->alloc_start);
	if (info->thread_pool_size !=  min_t(unsigned long,
					     num_online_cpus() + 2, 8))
		seq_printf(seq, ",thread_pool=%d", info->thread_pool_size);
	if (btrfs_test_opt(root, COMPRESS))
		seq_puts(seq, ",compress");
	if (btrfs_test_opt(root, SSD))
		seq_puts(seq, ",ssd");
S
Sage Weil 已提交
421 422
	if (btrfs_test_opt(root, NOTREELOG))
		seq_puts(seq, ",notreelog");
E
Eric Paris 已提交
423 424 425 426 427
	if (!(root->fs_info->sb->s_flags & MS_POSIXACL))
		seq_puts(seq, ",noacl");
	return 0;
}

C
Chris Mason 已提交
428
static void btrfs_write_super(struct super_block *sb)
C
Chris Mason 已提交
429
{
C
Chris Mason 已提交
430
	sb->s_dirt = 0;
C
Chris Mason 已提交
431 432
}

433
static int btrfs_test_super(struct super_block *s, void *data)
Y
Yan 已提交
434
{
435 436
	struct btrfs_fs_devices *test_fs_devices = data;
	struct btrfs_root *root = btrfs_sb(s);
Y
Yan 已提交
437

438
	return root->fs_info->fs_devices == test_fs_devices;
Y
Yan 已提交
439 440
}

441 442 443 444 445 446 447 448
/*
 * Find a superblock for the given device / mount point.
 *
 * Note:  This is based on get_sb_bdev from fs/super.c with a few additions
 *	  for multiple device setup.  Make sure to keep it in sync.
 */
static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
		const char *dev_name, void *data, struct vfsmount *mnt)
Y
Yan 已提交
449
{
450
	char *subvol_name = NULL;
Y
Yan 已提交
451 452 453
	struct block_device *bdev = NULL;
	struct super_block *s;
	struct dentry *root;
454
	struct btrfs_fs_devices *fs_devices = NULL;
455
	fmode_t mode = FMODE_READ;
Y
Yan 已提交
456 457
	int error = 0;

458 459 460 461
	if (!(flags & MS_RDONLY))
		mode |= FMODE_WRITE;

	error = btrfs_parse_early_options(data, mode, fs_type,
462
					  &subvol_name, &fs_devices);
463
	if (error)
464
		return error;
465

466
	error = btrfs_scan_one_device(dev_name, mode, fs_type, &fs_devices);
467
	if (error)
468
		goto error_free_subvol_name;
Y
Yan 已提交
469

470
	error = btrfs_open_devices(fs_devices, mode, fs_type);
471
	if (error)
472
		goto error_free_subvol_name;
473

Y
Yan Zheng 已提交
474 475 476 477 478
	if (!(flags & MS_RDONLY) && fs_devices->rw_devices == 0) {
		error = -EACCES;
		goto error_close_devices;
	}

479
	bdev = fs_devices->latest_bdev;
480
	s = sget(fs_type, btrfs_test_super, set_anon_super, fs_devices);
Y
Yan 已提交
481 482 483 484 485 486 487 488
	if (IS_ERR(s))
		goto error_s;

	if (s->s_root) {
		if ((flags ^ s->s_flags) & MS_RDONLY) {
			up_write(&s->s_umount);
			deactivate_super(s);
			error = -EBUSY;
Y
Yan Zheng 已提交
489
			goto error_close_devices;
Y
Yan 已提交
490 491
		}

Y
Yan Zheng 已提交
492
		btrfs_close_devices(fs_devices);
Y
Yan 已提交
493 494 495 496 497
	} else {
		char b[BDEVNAME_SIZE];

		s->s_flags = flags;
		strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
498 499
		error = btrfs_fill_super(s, fs_devices, data,
					 flags & MS_SILENT ? 1 : 0);
Y
Yan 已提交
500 501 502
		if (error) {
			up_write(&s->s_umount);
			deactivate_super(s);
503
			goto error_free_subvol_name;
Y
Yan 已提交
504 505
		}

506
		btrfs_sb(s)->fs_info->bdev_holder = fs_type;
Y
Yan 已提交
507 508 509
		s->s_flags |= MS_ACTIVE;
	}

510 511 512 513
	if (!strcmp(subvol_name, "."))
		root = dget(s->s_root);
	else {
		mutex_lock(&s->s_root->d_inode->i_mutex);
C
Chris Mason 已提交
514 515
		root = lookup_one_len(subvol_name, s->s_root,
				      strlen(subvol_name));
516
		mutex_unlock(&s->s_root->d_inode->i_mutex);
C
Chris Mason 已提交
517

518 519 520 521
		if (IS_ERR(root)) {
			up_write(&s->s_umount);
			deactivate_super(s);
			error = PTR_ERR(root);
522
			goto error_free_subvol_name;
523 524 525 526 527 528
		}
		if (!root->d_inode) {
			dput(root);
			up_write(&s->s_umount);
			deactivate_super(s);
			error = -ENXIO;
529
			goto error_free_subvol_name;
530
		}
Y
Yan 已提交
531 532 533 534
	}

	mnt->mnt_sb = s;
	mnt->mnt_root = root;
535 536

	kfree(subvol_name);
Y
Yan 已提交
537 538 539 540
	return 0;

error_s:
	error = PTR_ERR(s);
Y
Yan Zheng 已提交
541
error_close_devices:
542
	btrfs_close_devices(fs_devices);
543 544
error_free_subvol_name:
	kfree(subvol_name);
Y
Yan 已提交
545 546
	return error;
}
547

Y
Yan Zheng 已提交
548 549 550 551 552
static int btrfs_remount(struct super_block *sb, int *flags, char *data)
{
	struct btrfs_root *root = btrfs_sb(sb);
	int ret;

553 554 555 556
	ret = btrfs_parse_options(root, data);
	if (ret)
		return -EINVAL;

Y
Yan Zheng 已提交
557 558 559 560 561 562 563 564 565
	if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
		return 0;

	if (*flags & MS_RDONLY) {
		sb->s_flags |= MS_RDONLY;

		ret =  btrfs_commit_super(root);
		WARN_ON(ret);
	} else {
Y
Yan Zheng 已提交
566 567 568
		if (root->fs_info->fs_devices->rw_devices == 0)
			return -EACCES;

Y
Yan Zheng 已提交
569 570 571 572 573 574 575 576 577 578 579 580 581 582 583
		if (btrfs_super_log_root(&root->fs_info->super_copy) != 0)
			return -EINVAL;

		ret = btrfs_cleanup_reloc_trees(root);
		WARN_ON(ret);

		ret = btrfs_cleanup_fs_roots(root->fs_info);
		WARN_ON(ret);

		sb->s_flags &= ~MS_RDONLY;
	}

	return 0;
}

C
Chris Mason 已提交
584 585 586
static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)
{
	struct btrfs_root *root = btrfs_sb(dentry->d_sb);
587
	struct btrfs_super_block *disk_super = &root->fs_info->super_copy;
588
	int bits = dentry->d_sb->s_blocksize_bits;
589
	__be32 *fsid = (__be32 *)root->fs_info->fsid;
C
Chris Mason 已提交
590 591

	buf->f_namelen = BTRFS_NAME_LEN;
592 593 594
	buf->f_blocks = btrfs_super_total_bytes(disk_super) >> bits;
	buf->f_bfree = buf->f_blocks -
		(btrfs_super_bytes_used(disk_super) >> bits);
C
Chris Mason 已提交
595 596 597
	buf->f_bavail = buf->f_bfree;
	buf->f_bsize = dentry->d_sb->s_blocksize;
	buf->f_type = BTRFS_SUPER_MAGIC;
C
Chris Mason 已提交
598

599
	/* We treat it as constant endianness (it doesn't matter _which_)
C
Chris Mason 已提交
600
	   because we want the fsid to come out the same whether mounted
601 602 603
	   on a big-endian or little-endian host */
	buf->f_fsid.val[0] = be32_to_cpu(fsid[0]) ^ be32_to_cpu(fsid[2]);
	buf->f_fsid.val[1] = be32_to_cpu(fsid[1]) ^ be32_to_cpu(fsid[3]);
604 605 606 607
	/* Mask in the root object ID too, to disambiguate subvols */
	buf->f_fsid.val[0] ^= BTRFS_I(dentry->d_inode)->root->objectid >> 32;
	buf->f_fsid.val[1] ^= BTRFS_I(dentry->d_inode)->root->objectid;

C
Chris Mason 已提交
608 609
	return 0;
}
C
Chris Mason 已提交
610

611 612 613 614
static struct file_system_type btrfs_fs_type = {
	.owner		= THIS_MODULE,
	.name		= "btrfs",
	.get_sb		= btrfs_get_sb,
615
	.kill_sb	= kill_anon_super,
616 617
	.fs_flags	= FS_REQUIRES_DEV,
};
618

C
Chris Mason 已提交
619 620 621
/*
 * used by btrfsctl to scan devices when no FS is mounted
 */
622 623 624 625 626
static long btrfs_control_ioctl(struct file *file, unsigned int cmd,
				unsigned long arg)
{
	struct btrfs_ioctl_vol_args *vol;
	struct btrfs_fs_devices *fs_devices;
627
	int ret = -ENOTTY;
628

629 630 631
	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

632
	vol = kmalloc(sizeof(*vol), GFP_KERNEL);
633 634 635
	if (!vol)
		return -ENOMEM;

636 637 638 639
	if (copy_from_user(vol, (void __user *)arg, sizeof(*vol))) {
		ret = -EFAULT;
		goto out;
	}
640

641 642
	switch (cmd) {
	case BTRFS_IOC_SCAN_DEV:
643
		ret = btrfs_scan_one_device(vol->name, FMODE_READ,
644 645 646 647 648
					    &btrfs_fs_type, &fs_devices);
		break;
	}
out:
	kfree(vol);
L
Linda Knippers 已提交
649
	return ret;
650 651
}

652
static int btrfs_freeze(struct super_block *sb)
Y
Yan 已提交
653 654
{
	struct btrfs_root *root = btrfs_sb(sb);
655 656
	mutex_lock(&root->fs_info->transaction_kthread_mutex);
	mutex_lock(&root->fs_info->cleaner_mutex);
657
	return 0;
Y
Yan 已提交
658 659
}

660
static int btrfs_unfreeze(struct super_block *sb)
Y
Yan 已提交
661 662
{
	struct btrfs_root *root = btrfs_sb(sb);
663 664
	mutex_unlock(&root->fs_info->cleaner_mutex);
	mutex_unlock(&root->fs_info->transaction_kthread_mutex);
665
	return 0;
Y
Yan 已提交
666
}
667

C
Chris Mason 已提交
668
static struct super_operations btrfs_super_ops = {
C
Chris Mason 已提交
669
	.delete_inode	= btrfs_delete_inode,
C
Chris Mason 已提交
670
	.put_super	= btrfs_put_super,
671 672
	.write_super	= btrfs_write_super,
	.sync_fs	= btrfs_sync_fs,
E
Eric Paris 已提交
673
	.show_options	= btrfs_show_options,
C
Chris Mason 已提交
674
	.write_inode	= btrfs_write_inode,
C
Chris Mason 已提交
675
	.dirty_inode	= btrfs_dirty_inode,
C
Chris Mason 已提交
676 677
	.alloc_inode	= btrfs_alloc_inode,
	.destroy_inode	= btrfs_destroy_inode,
C
Chris Mason 已提交
678
	.statfs		= btrfs_statfs,
Y
Yan Zheng 已提交
679
	.remount_fs	= btrfs_remount,
680 681
	.freeze_fs	= btrfs_freeze,
	.unfreeze_fs	= btrfs_unfreeze,
C
Chris Mason 已提交
682
};
683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700

static const struct file_operations btrfs_ctl_fops = {
	.unlocked_ioctl	 = btrfs_control_ioctl,
	.compat_ioctl = btrfs_control_ioctl,
	.owner	 = THIS_MODULE,
};

static struct miscdevice btrfs_misc = {
	.minor		= MISC_DYNAMIC_MINOR,
	.name		= "btrfs-control",
	.fops		= &btrfs_ctl_fops
};

static int btrfs_interface_init(void)
{
	return misc_register(&btrfs_misc);
}

701
static void btrfs_interface_exit(void)
702 703
{
	if (misc_deregister(&btrfs_misc) < 0)
C
Chris Mason 已提交
704
		printk(KERN_INFO "misc_deregister failed for control device");
705 706
}

707 708
static int __init init_btrfs_fs(void)
{
C
Chris Mason 已提交
709
	int err;
710 711 712 713 714

	err = btrfs_init_sysfs();
	if (err)
		return err;

C
Chris Mason 已提交
715
	err = btrfs_init_cachep();
C
Chris Mason 已提交
716
	if (err)
717
		goto free_sysfs;
718 719

	err = extent_io_init();
720 721 722
	if (err)
		goto free_cachep;

723 724 725 726
	err = extent_map_init();
	if (err)
		goto free_extent_io;

727
	err = btrfs_interface_init();
728 729
	if (err)
		goto free_extent_map;
C
Chris Mason 已提交
730

731 732 733
	err = register_filesystem(&btrfs_fs_type);
	if (err)
		goto unregister_ioctl;
734 735

	printk(KERN_INFO "%s loaded\n", BTRFS_BUILD_VERSION);
736 737
	return 0;

738 739
unregister_ioctl:
	btrfs_interface_exit();
740 741
free_extent_map:
	extent_map_exit();
742 743
free_extent_io:
	extent_io_exit();
744 745
free_cachep:
	btrfs_destroy_cachep();
746
free_sysfs:
747 748
	btrfs_exit_sysfs();
	return err;
749 750 751 752
}

static void __exit exit_btrfs_fs(void)
{
C
Chris Mason 已提交
753
	btrfs_destroy_cachep();
754
	extent_map_exit();
755
	extent_io_exit();
756
	btrfs_interface_exit();
757
	unregister_filesystem(&btrfs_fs_type);
758
	btrfs_exit_sysfs();
759
	btrfs_cleanup_fs_uuids();
C
Chris Mason 已提交
760
	btrfs_zlib_exit();
761 762 763 764 765 766
}

module_init(init_btrfs_fs)
module_exit(exit_btrfs_fs)

MODULE_LICENSE("GPL");