super.c 22.3 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
#include <linux/string.h>
#include <linux/backing-dev.h>
Y
Yan 已提交
30
#include <linux/mount.h>
C
Chris Mason 已提交
31
#include <linux/mpage.h>
C
Chris Mason 已提交
32 33
#include <linux/swap.h>
#include <linux/writeback.h>
C
Chris Mason 已提交
34
#include <linux/statfs.h>
C
Chris Mason 已提交
35
#include <linux/compat.h>
36
#include <linux/parser.h>
37
#include <linux/ctype.h>
38
#include <linux/namei.h>
39
#include <linux/miscdevice.h>
40
#include <linux/magic.h>
C
Chris Mason 已提交
41
#include "compat.h"
42
#include "ctree.h"
C
Chris Mason 已提交
43
#include "disk-io.h"
44
#include "transaction.h"
C
Chris Mason 已提交
45
#include "btrfs_inode.h"
C
Chris Mason 已提交
46
#include "ioctl.h"
C
Chris Mason 已提交
47
#include "print-tree.h"
J
Josef Bacik 已提交
48
#include "xattr.h"
49
#include "volumes.h"
50
#include "version.h"
B
Balaji Rao 已提交
51
#include "export.h"
C
Chris Mason 已提交
52
#include "compression.h"
53

54
static const struct super_operations btrfs_super_ops;
C
Chris Mason 已提交
55

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

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

65
enum {
66 67 68 69
	Opt_degraded, Opt_subvol, Opt_subvolid, Opt_device, Opt_nodatasum,
	Opt_nodatacow, Opt_max_extent, Opt_max_inline, Opt_alloc_start,
	Opt_nobarrier, Opt_ssd, Opt_nossd, Opt_ssd_spread, Opt_thread_pool,
	Opt_noacl, Opt_compress, Opt_compress_force, Opt_notreelog, Opt_ratio,
C
Chris Mason 已提交
70
	Opt_flushoncommit,
C
Christoph Hellwig 已提交
71
	Opt_discard, Opt_err,
72 73 74
};

static match_table_t tokens = {
75
	{Opt_degraded, "degraded"},
76
	{Opt_subvol, "subvol=%s"},
77
	{Opt_subvolid, "subvolid=%d"},
78
	{Opt_device, "device=%s"},
79
	{Opt_nodatasum, "nodatasum"},
80
	{Opt_nodatacow, "nodatacow"},
81
	{Opt_nobarrier, "nobarrier"},
82
	{Opt_max_extent, "max_extent=%s"},
83
	{Opt_max_inline, "max_inline=%s"},
84
	{Opt_alloc_start, "alloc_start=%s"},
85
	{Opt_thread_pool, "thread_pool=%d"},
C
Chris Mason 已提交
86
	{Opt_compress, "compress"},
C
Chris Mason 已提交
87
	{Opt_compress_force, "compress-force"},
88
	{Opt_ssd, "ssd"},
89
	{Opt_ssd_spread, "ssd_spread"},
C
Chris Mason 已提交
90
	{Opt_nossd, "nossd"},
J
Josef Bacik 已提交
91
	{Opt_noacl, "noacl"},
S
Sage Weil 已提交
92
	{Opt_notreelog, "notreelog"},
93
	{Opt_flushoncommit, "flushoncommit"},
94
	{Opt_ratio, "metadata_ratio=%d"},
C
Christoph Hellwig 已提交
95
	{Opt_discard, "discard"},
J
Josef Bacik 已提交
96
	{Opt_err, NULL},
97 98
};

99
u64 btrfs_parse_size(char *str)
100
{
101
	u64 res;
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
	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;
}

124 125 126 127 128
/*
 * 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)
129
{
130
	struct btrfs_fs_info *info = root->fs_info;
131
	substring_t args[MAX_OPT_ARGS];
132
	char *p, *num, *orig;
133
	int intarg;
S
Sage Weil 已提交
134
	int ret = 0;
135

136
	if (!options)
137
		return 0;
138

139 140 141 142 143 144 145 146
	/*
	 * strsep changes the string, duplicate it because parse_options
	 * gets called twice
	 */
	options = kstrdup(options, GFP_NOFS);
	if (!options)
		return -ENOMEM;

147
	orig = options;
148

149
	while ((p = strsep(&options, ",")) != NULL) {
150 151 152 153 154 155
		int token;
		if (!*p)
			continue;

		token = match_token(p, tokens, args);
		switch (token) {
156
		case Opt_degraded:
157 158
			printk(KERN_INFO "btrfs: allowing degraded mounts\n");
			btrfs_set_opt(info->mount_opt, DEGRADED);
159
			break;
160
		case Opt_subvol:
161
		case Opt_subvolid:
162
		case Opt_device:
163
			/*
164
			 * These are parsed by btrfs_parse_early_options
165 166
			 * and can be happily ignored here.
			 */
167 168
			break;
		case Opt_nodatasum:
169
			printk(KERN_INFO "btrfs: setting nodatasum\n");
170
			btrfs_set_opt(info->mount_opt, NODATASUM);
171 172
			break;
		case Opt_nodatacow:
173 174 175
			printk(KERN_INFO "btrfs: setting nodatacow\n");
			btrfs_set_opt(info->mount_opt, NODATACOW);
			btrfs_set_opt(info->mount_opt, NODATASUM);
176
			break;
C
Chris Mason 已提交
177 178 179 180
		case Opt_compress:
			printk(KERN_INFO "btrfs: use compression\n");
			btrfs_set_opt(info->mount_opt, COMPRESS);
			break;
C
Chris Mason 已提交
181 182 183 184 185
		case Opt_compress_force:
			printk(KERN_INFO "btrfs: forcing compression\n");
			btrfs_set_opt(info->mount_opt, FORCE_COMPRESS);
			btrfs_set_opt(info->mount_opt, COMPRESS);
			break;
186
		case Opt_ssd:
187 188
			printk(KERN_INFO "btrfs: use ssd allocation scheme\n");
			btrfs_set_opt(info->mount_opt, SSD);
189
			break;
190 191 192 193 194 195
		case Opt_ssd_spread:
			printk(KERN_INFO "btrfs: use spread ssd "
			       "allocation scheme\n");
			btrfs_set_opt(info->mount_opt, SSD);
			btrfs_set_opt(info->mount_opt, SSD_SPREAD);
			break;
C
Chris Mason 已提交
196
		case Opt_nossd:
197 198
			printk(KERN_INFO "btrfs: not using ssd allocation "
			       "scheme\n");
C
Chris Mason 已提交
199
			btrfs_set_opt(info->mount_opt, NOSSD);
C
Chris Mason 已提交
200
			btrfs_clear_opt(info->mount_opt, SSD);
201
			btrfs_clear_opt(info->mount_opt, SSD_SPREAD);
C
Chris Mason 已提交
202
			break;
203
		case Opt_nobarrier:
204 205
			printk(KERN_INFO "btrfs: turning off barriers\n");
			btrfs_set_opt(info->mount_opt, NOBARRIER);
206
			break;
207 208 209 210 211 212 213 214 215
		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;
216
		case Opt_max_extent:
217 218 219 220 221 222 223 224
			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",
225
				       (unsigned long long)info->max_extent);
226 227
			}
			break;
228
		case Opt_max_inline:
229 230 231 232 233
			num = match_strdup(&args[0]);
			if (num) {
				info->max_inline = btrfs_parse_size(num);
				kfree(num);

C
Chris Mason 已提交
234 235 236 237 238
				if (info->max_inline) {
					info->max_inline = max_t(u64,
						info->max_inline,
						root->sectorsize);
				}
239
				printk(KERN_INFO "btrfs: max_inline at %llu\n",
240
					(unsigned long long)info->max_inline);
241 242
			}
			break;
243
		case Opt_alloc_start:
244 245 246 247 248 249
			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",
250
					(unsigned long long)info->alloc_start);
251 252
			}
			break;
J
Josef Bacik 已提交
253 254 255
		case Opt_noacl:
			root->fs_info->sb->s_flags &= ~MS_POSIXACL;
			break;
S
Sage Weil 已提交
256 257 258 259
		case Opt_notreelog:
			printk(KERN_INFO "btrfs: disabling tree log\n");
			btrfs_set_opt(info->mount_opt, NOTREELOG);
			break;
260 261 262 263
		case Opt_flushoncommit:
			printk(KERN_INFO "btrfs: turning on flush-on-commit\n");
			btrfs_set_opt(info->mount_opt, FLUSHONCOMMIT);
			break;
264 265 266 267 268 269 270 271 272
		case Opt_ratio:
			intarg = 0;
			match_int(&args[0], &intarg);
			if (intarg) {
				info->metadata_ratio = intarg;
				printk(KERN_INFO "btrfs: metadata ratio %d\n",
				       info->metadata_ratio);
			}
			break;
C
Christoph Hellwig 已提交
273 274 275
		case Opt_discard:
			btrfs_set_opt(info->mount_opt, DISCARD);
			break;
S
Sage Weil 已提交
276 277 278 279 280
		case Opt_err:
			printk(KERN_INFO "btrfs: unrecognized mount option "
			       "'%s'\n", p);
			ret = -EINVAL;
			goto out;
281
		default:
282
			break;
283 284
		}
	}
S
Sage Weil 已提交
285
out:
286
	kfree(orig);
S
Sage Weil 已提交
287
	return ret;
288 289 290 291 292 293 294 295
}

/*
 * 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.
 */
296
static int btrfs_parse_early_options(const char *options, fmode_t flags,
297
		void *holder, char **subvol_name, u64 *subvol_objectid,
298
		struct btrfs_fs_devices **fs_devices)
299 300 301 302
{
	substring_t args[MAX_OPT_ARGS];
	char *opts, *p;
	int error = 0;
303
	int intarg;
304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325

	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;
326 327 328 329 330 331
		case Opt_subvolid:
			intarg = 0;
			match_int(&args[0], &intarg);
			if (intarg)
				*subvol_objectid = intarg;
			break;
332 333 334 335 336 337
		case Opt_device:
			error = btrfs_scan_one_device(match_strdup(&args[0]),
					flags, holder, fs_devices);
			if (error)
				goto out_free_opts;
			break;
338 339 340 341 342
		default:
			break;
		}
	}

343
 out_free_opts:
344 345 346 347
	kfree(opts);
 out:
	/*
	 * If no subvolume name is specified we use the default one.  Allocate
348
	 * a copy of the string "." here so that code later in the
349 350 351
	 * mount path doesn't care if it's the default volume or another one.
	 */
	if (!*subvol_name) {
352
		*subvol_name = kstrdup(".", GFP_KERNEL);
353 354 355 356
		if (!*subvol_name)
			return -ENOMEM;
	}
	return error;
357 358
}

359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 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 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462
static struct dentry *get_default_root(struct super_block *sb,
				       u64 subvol_objectid)
{
	struct btrfs_root *root = sb->s_fs_info;
	struct btrfs_root *new_root;
	struct btrfs_dir_item *di;
	struct btrfs_path *path;
	struct btrfs_key location;
	struct inode *inode;
	struct dentry *dentry;
	u64 dir_id;
	int new = 0;

	/*
	 * We have a specific subvol we want to mount, just setup location and
	 * go look up the root.
	 */
	if (subvol_objectid) {
		location.objectid = subvol_objectid;
		location.type = BTRFS_ROOT_ITEM_KEY;
		location.offset = (u64)-1;
		goto find_root;
	}

	path = btrfs_alloc_path();
	if (!path)
		return ERR_PTR(-ENOMEM);
	path->leave_spinning = 1;

	/*
	 * Find the "default" dir item which points to the root item that we
	 * will mount by default if we haven't been given a specific subvolume
	 * to mount.
	 */
	dir_id = btrfs_super_root_dir(&root->fs_info->super_copy);
	di = btrfs_lookup_dir_item(NULL, root, path, dir_id, "default", 7, 0);
	if (!di) {
		/*
		 * Ok the default dir item isn't there.  This is weird since
		 * it's always been there, but don't freak out, just try and
		 * mount to root most subvolume.
		 */
		btrfs_free_path(path);
		dir_id = BTRFS_FIRST_FREE_OBJECTID;
		new_root = root->fs_info->fs_root;
		goto setup_root;
	}

	btrfs_dir_item_key_to_cpu(path->nodes[0], di, &location);
	btrfs_free_path(path);

find_root:
	new_root = btrfs_read_fs_root_no_name(root->fs_info, &location);
	if (IS_ERR(new_root))
		return ERR_PTR(PTR_ERR(new_root));

	if (btrfs_root_refs(&new_root->root_item) == 0)
		return ERR_PTR(-ENOENT);

	dir_id = btrfs_root_dirid(&new_root->root_item);
setup_root:
	location.objectid = dir_id;
	location.type = BTRFS_INODE_ITEM_KEY;
	location.offset = 0;

	inode = btrfs_iget(sb, &location, new_root, &new);
	if (!inode)
		return ERR_PTR(-ENOMEM);

	/*
	 * If we're just mounting the root most subvol put the inode and return
	 * a reference to the dentry.  We will have already gotten a reference
	 * to the inode in btrfs_fill_super so we're good to go.
	 */
	if (!new && sb->s_root->d_inode == inode) {
		iput(inode);
		return dget(sb->s_root);
	}

	if (new) {
		const struct qstr name = { .name = "/", .len = 1 };

		/*
		 * New inode, we need to make the dentry a sibling of s_root so
		 * everything gets cleaned up properly on unmount.
		 */
		dentry = d_alloc(sb->s_root, &name);
		if (!dentry) {
			iput(inode);
			return ERR_PTR(-ENOMEM);
		}
		d_splice_alias(inode, dentry);
	} else {
		/*
		 * We found the inode in cache, just find a dentry for it and
		 * put the reference to the inode we just got.
		 */
		dentry = d_find_alias(inode);
		iput(inode);
	}

	return dentry;
}

C
Chris Mason 已提交
463
static int btrfs_fill_super(struct super_block *sb,
464
			    struct btrfs_fs_devices *fs_devices,
C
Chris Mason 已提交
465
			    void *data, int silent)
C
Chris Mason 已提交
466
{
C
Chris Mason 已提交
467 468
	struct inode *inode;
	struct dentry *root_dentry;
C
Chris Mason 已提交
469 470
	struct btrfs_super_block *disk_super;
	struct btrfs_root *tree_root;
471
	struct btrfs_key key;
C
Chris Mason 已提交
472
	int err;
473

C
Chris Mason 已提交
474 475 476
	sb->s_maxbytes = MAX_LFS_FILESIZE;
	sb->s_magic = BTRFS_SUPER_MAGIC;
	sb->s_op = &btrfs_super_ops;
B
Balaji Rao 已提交
477
	sb->s_export_op = &btrfs_export_ops;
J
Josef Bacik 已提交
478
	sb->s_xattr = btrfs_xattr_handlers;
C
Chris Mason 已提交
479
	sb->s_time_gran = 1;
C
Chris Mason 已提交
480
#ifdef CONFIG_BTRFS_FS_POSIX_ACL
J
Josef Bacik 已提交
481
	sb->s_flags |= MS_POSIXACL;
482
#endif
483

484
	tree_root = open_ctree(sb, fs_devices, (char *)data);
485

486
	if (IS_ERR(tree_root)) {
C
Chris Mason 已提交
487
		printk("btrfs: open_ctree failed\n");
488
		return PTR_ERR(tree_root);
489
	}
C
Chris Mason 已提交
490
	sb->s_fs_info = tree_root;
491
	disk_super = &tree_root->fs_info->super_copy;
492

493 494 495
	key.objectid = BTRFS_FIRST_FREE_OBJECTID;
	key.type = BTRFS_INODE_ITEM_KEY;
	key.offset = 0;
496
	inode = btrfs_iget(sb, &key, tree_root->fs_info->fs_root, NULL);
497 498
	if (IS_ERR(inode)) {
		err = PTR_ERR(inode);
C
Chris Mason 已提交
499
		goto fail_close;
C
Chris Mason 已提交
500 501
	}

C
Chris Mason 已提交
502 503 504 505 506
	root_dentry = d_alloc_root(inode);
	if (!root_dentry) {
		iput(inode);
		err = -ENOMEM;
		goto fail_close;
C
Chris Mason 已提交
507
	}
508

C
Chris Mason 已提交
509
	sb->s_root = root_dentry;
C
Chris Mason 已提交
510 511

	save_mount_options(sb, data);
C
Chris Mason 已提交
512
	return 0;
C
Chris Mason 已提交
513 514 515 516

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

S
Sage Weil 已提交
519
int btrfs_sync_fs(struct super_block *sb, int wait)
C
Chris Mason 已提交
520 521
{
	struct btrfs_trans_handle *trans;
522
	struct btrfs_root *root = btrfs_sb(sb);
C
Chris Mason 已提交
523
	int ret;
C
Chris Mason 已提交
524

C
Chris Mason 已提交
525 526 527 528
	if (!wait) {
		filemap_flush(root->fs_info->btree_inode->i_mapping);
		return 0;
	}
529

Y
Yan, Zheng 已提交
530 531
	btrfs_start_delalloc_inodes(root, 0);
	btrfs_wait_ordered_extents(root, 0, 0);
532

C
Chris Mason 已提交
533 534
	trans = btrfs_start_transaction(root, 1);
	ret = btrfs_commit_transaction(trans, root);
535
	return ret;
C
Chris Mason 已提交
536 537
}

E
Eric Paris 已提交
538 539 540 541 542 543 544 545 546 547 548 549 550 551
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)
552 553
		seq_printf(seq, ",max_extent=%llu",
			   (unsigned long long)info->max_extent);
E
Eric Paris 已提交
554
	if (info->max_inline != 8192 * 1024)
555 556
		seq_printf(seq, ",max_inline=%llu",
			   (unsigned long long)info->max_inline);
E
Eric Paris 已提交
557
	if (info->alloc_start != 0)
558 559
		seq_printf(seq, ",alloc_start=%llu",
			   (unsigned long long)info->alloc_start);
E
Eric Paris 已提交
560 561 562 563 564
	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");
C
Chris Mason 已提交
565 566
	if (btrfs_test_opt(root, NOSSD))
		seq_puts(seq, ",nossd");
567 568 569
	if (btrfs_test_opt(root, SSD_SPREAD))
		seq_puts(seq, ",ssd_spread");
	else if (btrfs_test_opt(root, SSD))
E
Eric Paris 已提交
570
		seq_puts(seq, ",ssd");
S
Sage Weil 已提交
571
	if (btrfs_test_opt(root, NOTREELOG))
572
		seq_puts(seq, ",notreelog");
573
	if (btrfs_test_opt(root, FLUSHONCOMMIT))
574
		seq_puts(seq, ",flushoncommit");
575 576
	if (btrfs_test_opt(root, DISCARD))
		seq_puts(seq, ",discard");
E
Eric Paris 已提交
577 578 579 580 581
	if (!(root->fs_info->sb->s_flags & MS_POSIXACL))
		seq_puts(seq, ",noacl");
	return 0;
}

582
static int btrfs_test_super(struct super_block *s, void *data)
Y
Yan 已提交
583
{
584 585
	struct btrfs_fs_devices *test_fs_devices = data;
	struct btrfs_root *root = btrfs_sb(s);
Y
Yan 已提交
586

587
	return root->fs_info->fs_devices == test_fs_devices;
Y
Yan 已提交
588 589
}

590 591 592 593 594 595 596 597
/*
 * 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 已提交
598 599 600 601
{
	struct block_device *bdev = NULL;
	struct super_block *s;
	struct dentry *root;
602
	struct btrfs_fs_devices *fs_devices = NULL;
603
	fmode_t mode = FMODE_READ;
604 605
	char *subvol_name = NULL;
	u64 subvol_objectid = 0;
Y
Yan 已提交
606
	int error = 0;
607
	int found = 0;
Y
Yan 已提交
608

609 610 611 612
	if (!(flags & MS_RDONLY))
		mode |= FMODE_WRITE;

	error = btrfs_parse_early_options(data, mode, fs_type,
613 614
					  &subvol_name, &subvol_objectid,
					  &fs_devices);
615
	if (error)
616
		return error;
617

618
	error = btrfs_scan_one_device(dev_name, mode, fs_type, &fs_devices);
619
	if (error)
620
		goto error_free_subvol_name;
Y
Yan 已提交
621

622
	error = btrfs_open_devices(fs_devices, mode, fs_type);
623
	if (error)
624
		goto error_free_subvol_name;
625

Y
Yan Zheng 已提交
626 627 628 629 630
	if (!(flags & MS_RDONLY) && fs_devices->rw_devices == 0) {
		error = -EACCES;
		goto error_close_devices;
	}

631
	bdev = fs_devices->latest_bdev;
632
	s = sget(fs_type, btrfs_test_super, set_anon_super, fs_devices);
Y
Yan 已提交
633 634 635 636 637
	if (IS_ERR(s))
		goto error_s;

	if (s->s_root) {
		if ((flags ^ s->s_flags) & MS_RDONLY) {
638
			deactivate_locked_super(s);
Y
Yan 已提交
639
			error = -EBUSY;
Y
Yan Zheng 已提交
640
			goto error_close_devices;
Y
Yan 已提交
641 642
		}

643
		found = 1;
Y
Yan Zheng 已提交
644
		btrfs_close_devices(fs_devices);
Y
Yan 已提交
645 646 647 648 649
	} else {
		char b[BDEVNAME_SIZE];

		s->s_flags = flags;
		strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
650 651
		error = btrfs_fill_super(s, fs_devices, data,
					 flags & MS_SILENT ? 1 : 0);
Y
Yan 已提交
652
		if (error) {
653
			deactivate_locked_super(s);
654
			goto error_free_subvol_name;
Y
Yan 已提交
655 656
		}

657
		btrfs_sb(s)->fs_info->bdev_holder = fs_type;
Y
Yan 已提交
658 659 660
		s->s_flags |= MS_ACTIVE;
	}

661 662 663 664 665 666 667 668 669 670 671
	root = get_default_root(s, subvol_objectid);
	if (IS_ERR(root)) {
		error = PTR_ERR(root);
		deactivate_locked_super(s);
		goto error;
	}
	/* if they gave us a subvolume name bind mount into that */
	if (strcmp(subvol_name, ".")) {
		struct dentry *new_root;
		mutex_lock(&root->d_inode->i_mutex);
		new_root = lookup_one_len(subvol_name, root,
C
Chris Mason 已提交
672
				      strlen(subvol_name));
673
		mutex_unlock(&root->d_inode->i_mutex);
C
Chris Mason 已提交
674

675
		if (IS_ERR(new_root)) {
676
			deactivate_locked_super(s);
677 678 679
			error = PTR_ERR(new_root);
			dput(root);
			goto error_close_devices;
680
		}
681
		if (!new_root->d_inode) {
682
			dput(root);
683
			dput(new_root);
684
			deactivate_locked_super(s);
685
			error = -ENXIO;
686
			goto error_close_devices;
687
		}
688 689
		dput(root);
		root = new_root;
Y
Yan 已提交
690 691 692 693
	}

	mnt->mnt_sb = s;
	mnt->mnt_root = root;
694 695

	kfree(subvol_name);
Y
Yan 已提交
696 697 698 699
	return 0;

error_s:
	error = PTR_ERR(s);
Y
Yan Zheng 已提交
700
error_close_devices:
701
	btrfs_close_devices(fs_devices);
702 703
error_free_subvol_name:
	kfree(subvol_name);
704
error:
Y
Yan 已提交
705 706
	return error;
}
707

Y
Yan Zheng 已提交
708 709 710 711 712
static int btrfs_remount(struct super_block *sb, int *flags, char *data)
{
	struct btrfs_root *root = btrfs_sb(sb);
	int ret;

713 714 715 716
	ret = btrfs_parse_options(root, data);
	if (ret)
		return -EINVAL;

Y
Yan Zheng 已提交
717 718 719 720 721 722 723 724 725
	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 已提交
726 727 728
		if (root->fs_info->fs_devices->rw_devices == 0)
			return -EACCES;

Y
Yan Zheng 已提交
729 730 731
		if (btrfs_super_log_root(&root->fs_info->super_copy) != 0)
			return -EINVAL;

732 733
		/* recover relocation */
		ret = btrfs_recover_relocation(root);
Y
Yan Zheng 已提交
734 735 736 737 738 739 740 741 742 743 744
		WARN_ON(ret);

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

		sb->s_flags &= ~MS_RDONLY;
	}

	return 0;
}

C
Chris Mason 已提交
745 746 747
static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)
{
	struct btrfs_root *root = btrfs_sb(dentry->d_sb);
748
	struct btrfs_super_block *disk_super = &root->fs_info->super_copy;
749
	int bits = dentry->d_sb->s_blocksize_bits;
750
	__be32 *fsid = (__be32 *)root->fs_info->fsid;
C
Chris Mason 已提交
751 752

	buf->f_namelen = BTRFS_NAME_LEN;
753 754 755
	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 已提交
756 757 758
	buf->f_bavail = buf->f_bfree;
	buf->f_bsize = dentry->d_sb->s_blocksize;
	buf->f_type = BTRFS_SUPER_MAGIC;
C
Chris Mason 已提交
759

760
	/* We treat it as constant endianness (it doesn't matter _which_)
C
Chris Mason 已提交
761
	   because we want the fsid to come out the same whether mounted
762 763 764
	   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]);
765 766 767 768
	/* 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 已提交
769 770
	return 0;
}
C
Chris Mason 已提交
771

772 773 774 775
static struct file_system_type btrfs_fs_type = {
	.owner		= THIS_MODULE,
	.name		= "btrfs",
	.get_sb		= btrfs_get_sb,
776
	.kill_sb	= kill_anon_super,
777 778
	.fs_flags	= FS_REQUIRES_DEV,
};
779

C
Chris Mason 已提交
780 781 782
/*
 * used by btrfsctl to scan devices when no FS is mounted
 */
783 784 785 786 787
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;
788
	int ret = -ENOTTY;
789

790 791 792
	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

L
Li Zefan 已提交
793 794 795
	vol = memdup_user((void __user *)arg, sizeof(*vol));
	if (IS_ERR(vol))
		return PTR_ERR(vol);
796

797 798
	switch (cmd) {
	case BTRFS_IOC_SCAN_DEV:
799
		ret = btrfs_scan_one_device(vol->name, FMODE_READ,
800 801 802
					    &btrfs_fs_type, &fs_devices);
		break;
	}
L
Li Zefan 已提交
803

804
	kfree(vol);
L
Linda Knippers 已提交
805
	return ret;
806 807
}

808
static int btrfs_freeze(struct super_block *sb)
Y
Yan 已提交
809 810
{
	struct btrfs_root *root = btrfs_sb(sb);
811 812
	mutex_lock(&root->fs_info->transaction_kthread_mutex);
	mutex_lock(&root->fs_info->cleaner_mutex);
813
	return 0;
Y
Yan 已提交
814 815
}

816
static int btrfs_unfreeze(struct super_block *sb)
Y
Yan 已提交
817 818
{
	struct btrfs_root *root = btrfs_sb(sb);
819 820
	mutex_unlock(&root->fs_info->cleaner_mutex);
	mutex_unlock(&root->fs_info->transaction_kthread_mutex);
821
	return 0;
Y
Yan 已提交
822
}
823

824
static const struct super_operations btrfs_super_ops = {
825
	.drop_inode	= btrfs_drop_inode,
C
Chris Mason 已提交
826
	.delete_inode	= btrfs_delete_inode,
C
Chris Mason 已提交
827
	.put_super	= btrfs_put_super,
828
	.sync_fs	= btrfs_sync_fs,
E
Eric Paris 已提交
829
	.show_options	= btrfs_show_options,
C
Chris Mason 已提交
830
	.write_inode	= btrfs_write_inode,
C
Chris Mason 已提交
831
	.dirty_inode	= btrfs_dirty_inode,
C
Chris Mason 已提交
832 833
	.alloc_inode	= btrfs_alloc_inode,
	.destroy_inode	= btrfs_destroy_inode,
C
Chris Mason 已提交
834
	.statfs		= btrfs_statfs,
Y
Yan Zheng 已提交
835
	.remount_fs	= btrfs_remount,
836 837
	.freeze_fs	= btrfs_freeze,
	.unfreeze_fs	= btrfs_unfreeze,
C
Chris Mason 已提交
838
};
839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856

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);
}

857
static void btrfs_interface_exit(void)
858 859
{
	if (misc_deregister(&btrfs_misc) < 0)
C
Chris Mason 已提交
860
		printk(KERN_INFO "misc_deregister failed for control device");
861 862
}

863 864
static int __init init_btrfs_fs(void)
{
C
Chris Mason 已提交
865
	int err;
866 867 868 869 870

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

C
Chris Mason 已提交
871
	err = btrfs_init_cachep();
C
Chris Mason 已提交
872
	if (err)
873
		goto free_sysfs;
874 875

	err = extent_io_init();
876 877 878
	if (err)
		goto free_cachep;

879 880 881 882
	err = extent_map_init();
	if (err)
		goto free_extent_io;

883
	err = btrfs_interface_init();
884 885
	if (err)
		goto free_extent_map;
C
Chris Mason 已提交
886

887 888 889
	err = register_filesystem(&btrfs_fs_type);
	if (err)
		goto unregister_ioctl;
890 891

	printk(KERN_INFO "%s loaded\n", BTRFS_BUILD_VERSION);
892 893
	return 0;

894 895
unregister_ioctl:
	btrfs_interface_exit();
896 897
free_extent_map:
	extent_map_exit();
898 899
free_extent_io:
	extent_io_exit();
900 901
free_cachep:
	btrfs_destroy_cachep();
902
free_sysfs:
903 904
	btrfs_exit_sysfs();
	return err;
905 906 907 908
}

static void __exit exit_btrfs_fs(void)
{
C
Chris Mason 已提交
909
	btrfs_destroy_cachep();
910
	extent_map_exit();
911
	extent_io_exit();
912
	btrfs_interface_exit();
913
	unregister_filesystem(&btrfs_fs_type);
914
	btrfs_exit_sysfs();
915
	btrfs_cleanup_fs_uuids();
C
Chris Mason 已提交
916
	btrfs_zlib_exit();
917 918 919 920 921 922
}

module_init(init_btrfs_fs)
module_exit(exit_btrfs_fs)

MODULE_LICENSE("GPL");