super.c 22.2 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
	Opt_degraded, Opt_subvol, Opt_subvolid, Opt_device, Opt_nodatasum,
67 68 69
	Opt_nodatacow, 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, Opt_flushoncommit,
C
Christoph Hellwig 已提交
70
	Opt_discard, Opt_err,
71 72 73
};

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

97 98 99 100 101
/*
 * 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)
102
{
103
	struct btrfs_fs_info *info = root->fs_info;
104
	substring_t args[MAX_OPT_ARGS];
105
	char *p, *num, *orig;
106
	int intarg;
S
Sage Weil 已提交
107
	int ret = 0;
108

109
	if (!options)
110
		return 0;
111

112 113 114 115 116 117 118 119
	/*
	 * strsep changes the string, duplicate it because parse_options
	 * gets called twice
	 */
	options = kstrdup(options, GFP_NOFS);
	if (!options)
		return -ENOMEM;

120
	orig = options;
121

122
	while ((p = strsep(&options, ",")) != NULL) {
123 124 125 126 127 128
		int token;
		if (!*p)
			continue;

		token = match_token(p, tokens, args);
		switch (token) {
129
		case Opt_degraded:
130 131
			printk(KERN_INFO "btrfs: allowing degraded mounts\n");
			btrfs_set_opt(info->mount_opt, DEGRADED);
132
			break;
133
		case Opt_subvol:
134
		case Opt_subvolid:
135
		case Opt_device:
136
			/*
137
			 * These are parsed by btrfs_parse_early_options
138 139
			 * and can be happily ignored here.
			 */
140 141
			break;
		case Opt_nodatasum:
142
			printk(KERN_INFO "btrfs: setting nodatasum\n");
143
			btrfs_set_opt(info->mount_opt, NODATASUM);
144 145
			break;
		case Opt_nodatacow:
146 147 148
			printk(KERN_INFO "btrfs: setting nodatacow\n");
			btrfs_set_opt(info->mount_opt, NODATACOW);
			btrfs_set_opt(info->mount_opt, NODATASUM);
149
			break;
C
Chris Mason 已提交
150 151 152 153
		case Opt_compress:
			printk(KERN_INFO "btrfs: use compression\n");
			btrfs_set_opt(info->mount_opt, COMPRESS);
			break;
C
Chris Mason 已提交
154 155 156 157 158
		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;
159
		case Opt_ssd:
160 161
			printk(KERN_INFO "btrfs: use ssd allocation scheme\n");
			btrfs_set_opt(info->mount_opt, SSD);
162
			break;
163 164 165 166 167 168
		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 已提交
169
		case Opt_nossd:
170 171
			printk(KERN_INFO "btrfs: not using ssd allocation "
			       "scheme\n");
C
Chris Mason 已提交
172
			btrfs_set_opt(info->mount_opt, NOSSD);
C
Chris Mason 已提交
173
			btrfs_clear_opt(info->mount_opt, SSD);
174
			btrfs_clear_opt(info->mount_opt, SSD_SPREAD);
C
Chris Mason 已提交
175
			break;
176
		case Opt_nobarrier:
177 178
			printk(KERN_INFO "btrfs: turning off barriers\n");
			btrfs_set_opt(info->mount_opt, NOBARRIER);
179
			break;
180 181 182 183 184 185 186 187 188
		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;
189
		case Opt_max_inline:
190 191
			num = match_strdup(&args[0]);
			if (num) {
A
Akinobu Mita 已提交
192
				info->max_inline = memparse(num, NULL);
193 194
				kfree(num);

C
Chris Mason 已提交
195 196 197 198 199
				if (info->max_inline) {
					info->max_inline = max_t(u64,
						info->max_inline,
						root->sectorsize);
				}
200
				printk(KERN_INFO "btrfs: max_inline at %llu\n",
201
					(unsigned long long)info->max_inline);
202 203
			}
			break;
204
		case Opt_alloc_start:
205 206
			num = match_strdup(&args[0]);
			if (num) {
A
Akinobu Mita 已提交
207
				info->alloc_start = memparse(num, NULL);
208 209 210
				kfree(num);
				printk(KERN_INFO
					"btrfs: allocations start at %llu\n",
211
					(unsigned long long)info->alloc_start);
212 213
			}
			break;
J
Josef Bacik 已提交
214 215 216
		case Opt_noacl:
			root->fs_info->sb->s_flags &= ~MS_POSIXACL;
			break;
S
Sage Weil 已提交
217 218 219 220
		case Opt_notreelog:
			printk(KERN_INFO "btrfs: disabling tree log\n");
			btrfs_set_opt(info->mount_opt, NOTREELOG);
			break;
221 222 223 224
		case Opt_flushoncommit:
			printk(KERN_INFO "btrfs: turning on flush-on-commit\n");
			btrfs_set_opt(info->mount_opt, FLUSHONCOMMIT);
			break;
225 226 227 228 229 230 231 232 233
		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 已提交
234 235 236
		case Opt_discard:
			btrfs_set_opt(info->mount_opt, DISCARD);
			break;
S
Sage Weil 已提交
237 238 239 240 241
		case Opt_err:
			printk(KERN_INFO "btrfs: unrecognized mount option "
			       "'%s'\n", p);
			ret = -EINVAL;
			goto out;
242
		default:
243
			break;
244 245
		}
	}
S
Sage Weil 已提交
246
out:
247
	kfree(orig);
S
Sage Weil 已提交
248
	return ret;
249 250 251 252 253 254 255 256
}

/*
 * 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.
 */
257
static int btrfs_parse_early_options(const char *options, fmode_t flags,
258
		void *holder, char **subvol_name, u64 *subvol_objectid,
259
		struct btrfs_fs_devices **fs_devices)
260 261 262 263
{
	substring_t args[MAX_OPT_ARGS];
	char *opts, *p;
	int error = 0;
264
	int intarg;
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286

	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;
287 288
		case Opt_subvolid:
			intarg = 0;
289 290 291 292 293 294 295 296 297
			error = match_int(&args[0], &intarg);
			if (!error) {
				/* we want the original fs_tree */
				if (!intarg)
					*subvol_objectid =
						BTRFS_FS_TREE_OBJECTID;
				else
					*subvol_objectid = intarg;
			}
298
			break;
299 300 301 302 303 304
		case Opt_device:
			error = btrfs_scan_one_device(match_strdup(&args[0]),
					flags, holder, fs_devices);
			if (error)
				goto out_free_opts;
			break;
305 306 307 308 309
		default:
			break;
		}
	}

310
 out_free_opts:
311 312 313 314
	kfree(opts);
 out:
	/*
	 * If no subvolume name is specified we use the default one.  Allocate
315
	 * a copy of the string "." here so that code later in the
316 317 318
	 * mount path doesn't care if it's the default volume or another one.
	 */
	if (!*subvol_name) {
319
		*subvol_name = kstrdup(".", GFP_KERNEL);
320 321 322 323
		if (!*subvol_name)
			return -ENOMEM;
	}
	return error;
324 325
}

326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 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
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 已提交
430
static int btrfs_fill_super(struct super_block *sb,
431
			    struct btrfs_fs_devices *fs_devices,
C
Chris Mason 已提交
432
			    void *data, int silent)
C
Chris Mason 已提交
433
{
C
Chris Mason 已提交
434 435
	struct inode *inode;
	struct dentry *root_dentry;
C
Chris Mason 已提交
436 437
	struct btrfs_super_block *disk_super;
	struct btrfs_root *tree_root;
438
	struct btrfs_key key;
C
Chris Mason 已提交
439
	int err;
440

C
Chris Mason 已提交
441 442 443
	sb->s_maxbytes = MAX_LFS_FILESIZE;
	sb->s_magic = BTRFS_SUPER_MAGIC;
	sb->s_op = &btrfs_super_ops;
B
Balaji Rao 已提交
444
	sb->s_export_op = &btrfs_export_ops;
J
Josef Bacik 已提交
445
	sb->s_xattr = btrfs_xattr_handlers;
C
Chris Mason 已提交
446
	sb->s_time_gran = 1;
C
Chris Mason 已提交
447
#ifdef CONFIG_BTRFS_FS_POSIX_ACL
J
Josef Bacik 已提交
448
	sb->s_flags |= MS_POSIXACL;
449
#endif
450

451
	tree_root = open_ctree(sb, fs_devices, (char *)data);
452

453
	if (IS_ERR(tree_root)) {
C
Chris Mason 已提交
454
		printk("btrfs: open_ctree failed\n");
455
		return PTR_ERR(tree_root);
456
	}
C
Chris Mason 已提交
457
	sb->s_fs_info = tree_root;
458
	disk_super = &tree_root->fs_info->super_copy;
459

460 461 462
	key.objectid = BTRFS_FIRST_FREE_OBJECTID;
	key.type = BTRFS_INODE_ITEM_KEY;
	key.offset = 0;
463
	inode = btrfs_iget(sb, &key, tree_root->fs_info->fs_root, NULL);
464 465
	if (IS_ERR(inode)) {
		err = PTR_ERR(inode);
C
Chris Mason 已提交
466
		goto fail_close;
C
Chris Mason 已提交
467 468
	}

C
Chris Mason 已提交
469 470 471 472 473
	root_dentry = d_alloc_root(inode);
	if (!root_dentry) {
		iput(inode);
		err = -ENOMEM;
		goto fail_close;
C
Chris Mason 已提交
474
	}
475

C
Chris Mason 已提交
476
	sb->s_root = root_dentry;
C
Chris Mason 已提交
477 478

	save_mount_options(sb, data);
C
Chris Mason 已提交
479
	return 0;
C
Chris Mason 已提交
480 481 482 483

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

S
Sage Weil 已提交
486
int btrfs_sync_fs(struct super_block *sb, int wait)
C
Chris Mason 已提交
487 488
{
	struct btrfs_trans_handle *trans;
489
	struct btrfs_root *root = btrfs_sb(sb);
C
Chris Mason 已提交
490
	int ret;
C
Chris Mason 已提交
491

C
Chris Mason 已提交
492 493 494 495
	if (!wait) {
		filemap_flush(root->fs_info->btree_inode->i_mapping);
		return 0;
	}
496

Y
Yan, Zheng 已提交
497 498
	btrfs_start_delalloc_inodes(root, 0);
	btrfs_wait_ordered_extents(root, 0, 0);
499

C
Chris Mason 已提交
500 501
	trans = btrfs_start_transaction(root, 1);
	ret = btrfs_commit_transaction(trans, root);
502
	return ret;
C
Chris Mason 已提交
503 504
}

E
Eric Paris 已提交
505 506 507 508 509 510 511 512 513 514 515 516 517 518
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_inline != 8192 * 1024)
519 520
		seq_printf(seq, ",max_inline=%llu",
			   (unsigned long long)info->max_inline);
E
Eric Paris 已提交
521
	if (info->alloc_start != 0)
522 523
		seq_printf(seq, ",alloc_start=%llu",
			   (unsigned long long)info->alloc_start);
E
Eric Paris 已提交
524 525 526 527 528
	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 已提交
529 530
	if (btrfs_test_opt(root, NOSSD))
		seq_puts(seq, ",nossd");
531 532 533
	if (btrfs_test_opt(root, SSD_SPREAD))
		seq_puts(seq, ",ssd_spread");
	else if (btrfs_test_opt(root, SSD))
E
Eric Paris 已提交
534
		seq_puts(seq, ",ssd");
S
Sage Weil 已提交
535
	if (btrfs_test_opt(root, NOTREELOG))
536
		seq_puts(seq, ",notreelog");
537
	if (btrfs_test_opt(root, FLUSHONCOMMIT))
538
		seq_puts(seq, ",flushoncommit");
539 540
	if (btrfs_test_opt(root, DISCARD))
		seq_puts(seq, ",discard");
E
Eric Paris 已提交
541 542 543 544 545
	if (!(root->fs_info->sb->s_flags & MS_POSIXACL))
		seq_puts(seq, ",noacl");
	return 0;
}

546
static int btrfs_test_super(struct super_block *s, void *data)
Y
Yan 已提交
547
{
548 549
	struct btrfs_fs_devices *test_fs_devices = data;
	struct btrfs_root *root = btrfs_sb(s);
Y
Yan 已提交
550

551
	return root->fs_info->fs_devices == test_fs_devices;
Y
Yan 已提交
552 553
}

554 555 556 557 558 559 560 561
/*
 * 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 已提交
562 563 564 565
{
	struct block_device *bdev = NULL;
	struct super_block *s;
	struct dentry *root;
566
	struct btrfs_fs_devices *fs_devices = NULL;
567
	fmode_t mode = FMODE_READ;
568 569
	char *subvol_name = NULL;
	u64 subvol_objectid = 0;
Y
Yan 已提交
570
	int error = 0;
571
	int found = 0;
Y
Yan 已提交
572

573 574 575 576
	if (!(flags & MS_RDONLY))
		mode |= FMODE_WRITE;

	error = btrfs_parse_early_options(data, mode, fs_type,
577 578
					  &subvol_name, &subvol_objectid,
					  &fs_devices);
579
	if (error)
580
		return error;
581

582
	error = btrfs_scan_one_device(dev_name, mode, fs_type, &fs_devices);
583
	if (error)
584
		goto error_free_subvol_name;
Y
Yan 已提交
585

586
	error = btrfs_open_devices(fs_devices, mode, fs_type);
587
	if (error)
588
		goto error_free_subvol_name;
589

Y
Yan Zheng 已提交
590 591 592 593 594
	if (!(flags & MS_RDONLY) && fs_devices->rw_devices == 0) {
		error = -EACCES;
		goto error_close_devices;
	}

595
	bdev = fs_devices->latest_bdev;
596
	s = sget(fs_type, btrfs_test_super, set_anon_super, fs_devices);
Y
Yan 已提交
597 598 599 600 601
	if (IS_ERR(s))
		goto error_s;

	if (s->s_root) {
		if ((flags ^ s->s_flags) & MS_RDONLY) {
602
			deactivate_locked_super(s);
Y
Yan 已提交
603
			error = -EBUSY;
Y
Yan Zheng 已提交
604
			goto error_close_devices;
Y
Yan 已提交
605 606
		}

607
		found = 1;
Y
Yan Zheng 已提交
608
		btrfs_close_devices(fs_devices);
Y
Yan 已提交
609 610 611 612 613
	} else {
		char b[BDEVNAME_SIZE];

		s->s_flags = flags;
		strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
614 615
		error = btrfs_fill_super(s, fs_devices, data,
					 flags & MS_SILENT ? 1 : 0);
Y
Yan 已提交
616
		if (error) {
617
			deactivate_locked_super(s);
618
			goto error_free_subvol_name;
Y
Yan 已提交
619 620
		}

621
		btrfs_sb(s)->fs_info->bdev_holder = fs_type;
Y
Yan 已提交
622 623 624
		s->s_flags |= MS_ACTIVE;
	}

625 626 627 628 629 630 631 632 633 634 635
	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 已提交
636
				      strlen(subvol_name));
637
		mutex_unlock(&root->d_inode->i_mutex);
C
Chris Mason 已提交
638

639
		if (IS_ERR(new_root)) {
640
			deactivate_locked_super(s);
641 642 643
			error = PTR_ERR(new_root);
			dput(root);
			goto error_close_devices;
644
		}
645
		if (!new_root->d_inode) {
646
			dput(root);
647
			dput(new_root);
648
			deactivate_locked_super(s);
649
			error = -ENXIO;
650
			goto error_close_devices;
651
		}
652 653
		dput(root);
		root = new_root;
Y
Yan 已提交
654 655 656 657
	}

	mnt->mnt_sb = s;
	mnt->mnt_root = root;
658 659

	kfree(subvol_name);
Y
Yan 已提交
660 661 662 663
	return 0;

error_s:
	error = PTR_ERR(s);
Y
Yan Zheng 已提交
664
error_close_devices:
665
	btrfs_close_devices(fs_devices);
666 667
error_free_subvol_name:
	kfree(subvol_name);
668
error:
Y
Yan 已提交
669 670
	return error;
}
671

Y
Yan Zheng 已提交
672 673 674 675 676
static int btrfs_remount(struct super_block *sb, int *flags, char *data)
{
	struct btrfs_root *root = btrfs_sb(sb);
	int ret;

677 678 679 680
	ret = btrfs_parse_options(root, data);
	if (ret)
		return -EINVAL;

Y
Yan Zheng 已提交
681 682 683 684 685 686 687 688 689
	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 已提交
690 691 692
		if (root->fs_info->fs_devices->rw_devices == 0)
			return -EACCES;

Y
Yan Zheng 已提交
693 694 695
		if (btrfs_super_log_root(&root->fs_info->super_copy) != 0)
			return -EINVAL;

696 697
		/* recover relocation */
		ret = btrfs_recover_relocation(root);
Y
Yan Zheng 已提交
698 699 700 701 702 703 704 705 706 707 708
		WARN_ON(ret);

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

		sb->s_flags &= ~MS_RDONLY;
	}

	return 0;
}

C
Chris Mason 已提交
709 710 711
static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)
{
	struct btrfs_root *root = btrfs_sb(dentry->d_sb);
712
	struct btrfs_super_block *disk_super = &root->fs_info->super_copy;
713 714 715 716
	struct list_head *head = &root->fs_info->space_info;
	struct btrfs_space_info *found;
	u64 total_used = 0;
	u64 data_used = 0;
717
	int bits = dentry->d_sb->s_blocksize_bits;
718
	__be32 *fsid = (__be32 *)root->fs_info->fsid;
C
Chris Mason 已提交
719

720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739
	rcu_read_lock();
	list_for_each_entry_rcu(found, head, list) {
		if (found->flags & (BTRFS_BLOCK_GROUP_DUP|
				    BTRFS_BLOCK_GROUP_RAID10|
				    BTRFS_BLOCK_GROUP_RAID1)) {
			total_used += found->bytes_used;
			if (found->flags & BTRFS_BLOCK_GROUP_DATA)
				data_used += found->bytes_used;
			else
				data_used += found->total_bytes;
		}

		total_used += found->bytes_used;
		if (found->flags & BTRFS_BLOCK_GROUP_DATA)
			data_used += found->bytes_used;
		else
			data_used += found->total_bytes;
	}
	rcu_read_unlock();

C
Chris Mason 已提交
740
	buf->f_namelen = BTRFS_NAME_LEN;
741
	buf->f_blocks = btrfs_super_total_bytes(disk_super) >> bits;
742 743
	buf->f_bfree = buf->f_blocks - (total_used >> bits);
	buf->f_bavail = buf->f_blocks - (data_used >> bits);
C
Chris Mason 已提交
744 745
	buf->f_bsize = dentry->d_sb->s_blocksize;
	buf->f_type = BTRFS_SUPER_MAGIC;
C
Chris Mason 已提交
746

747
	/* We treat it as constant endianness (it doesn't matter _which_)
C
Chris Mason 已提交
748
	   because we want the fsid to come out the same whether mounted
749 750 751
	   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]);
752 753 754 755
	/* 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 已提交
756 757
	return 0;
}
C
Chris Mason 已提交
758

759 760 761 762
static struct file_system_type btrfs_fs_type = {
	.owner		= THIS_MODULE,
	.name		= "btrfs",
	.get_sb		= btrfs_get_sb,
763
	.kill_sb	= kill_anon_super,
764 765
	.fs_flags	= FS_REQUIRES_DEV,
};
766

C
Chris Mason 已提交
767 768 769
/*
 * used by btrfsctl to scan devices when no FS is mounted
 */
770 771 772 773 774
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;
775
	int ret = -ENOTTY;
776

777 778 779
	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

L
Li Zefan 已提交
780 781 782
	vol = memdup_user((void __user *)arg, sizeof(*vol));
	if (IS_ERR(vol))
		return PTR_ERR(vol);
783

784 785
	switch (cmd) {
	case BTRFS_IOC_SCAN_DEV:
786
		ret = btrfs_scan_one_device(vol->name, FMODE_READ,
787 788 789
					    &btrfs_fs_type, &fs_devices);
		break;
	}
L
Li Zefan 已提交
790

791
	kfree(vol);
L
Linda Knippers 已提交
792
	return ret;
793 794
}

795
static int btrfs_freeze(struct super_block *sb)
Y
Yan 已提交
796 797
{
	struct btrfs_root *root = btrfs_sb(sb);
798 799
	mutex_lock(&root->fs_info->transaction_kthread_mutex);
	mutex_lock(&root->fs_info->cleaner_mutex);
800
	return 0;
Y
Yan 已提交
801 802
}

803
static int btrfs_unfreeze(struct super_block *sb)
Y
Yan 已提交
804 805
{
	struct btrfs_root *root = btrfs_sb(sb);
806 807
	mutex_unlock(&root->fs_info->cleaner_mutex);
	mutex_unlock(&root->fs_info->transaction_kthread_mutex);
808
	return 0;
Y
Yan 已提交
809
}
810

811
static const struct super_operations btrfs_super_ops = {
812
	.drop_inode	= btrfs_drop_inode,
C
Chris Mason 已提交
813
	.delete_inode	= btrfs_delete_inode,
C
Chris Mason 已提交
814
	.put_super	= btrfs_put_super,
815
	.sync_fs	= btrfs_sync_fs,
E
Eric Paris 已提交
816
	.show_options	= btrfs_show_options,
C
Chris Mason 已提交
817
	.write_inode	= btrfs_write_inode,
C
Chris Mason 已提交
818
	.dirty_inode	= btrfs_dirty_inode,
C
Chris Mason 已提交
819 820
	.alloc_inode	= btrfs_alloc_inode,
	.destroy_inode	= btrfs_destroy_inode,
C
Chris Mason 已提交
821
	.statfs		= btrfs_statfs,
Y
Yan Zheng 已提交
822
	.remount_fs	= btrfs_remount,
823 824
	.freeze_fs	= btrfs_freeze,
	.unfreeze_fs	= btrfs_unfreeze,
C
Chris Mason 已提交
825
};
826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843

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

844
static void btrfs_interface_exit(void)
845 846
{
	if (misc_deregister(&btrfs_misc) < 0)
C
Chris Mason 已提交
847
		printk(KERN_INFO "misc_deregister failed for control device");
848 849
}

850 851
static int __init init_btrfs_fs(void)
{
C
Chris Mason 已提交
852
	int err;
853 854 855 856 857

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

C
Chris Mason 已提交
858
	err = btrfs_init_cachep();
C
Chris Mason 已提交
859
	if (err)
860
		goto free_sysfs;
861 862

	err = extent_io_init();
863 864 865
	if (err)
		goto free_cachep;

866 867 868 869
	err = extent_map_init();
	if (err)
		goto free_extent_io;

870
	err = btrfs_interface_init();
871 872
	if (err)
		goto free_extent_map;
C
Chris Mason 已提交
873

874 875 876
	err = register_filesystem(&btrfs_fs_type);
	if (err)
		goto unregister_ioctl;
877 878

	printk(KERN_INFO "%s loaded\n", BTRFS_BUILD_VERSION);
879 880
	return 0;

881 882
unregister_ioctl:
	btrfs_interface_exit();
883 884
free_extent_map:
	extent_map_exit();
885 886
free_extent_io:
	extent_io_exit();
887 888
free_cachep:
	btrfs_destroy_cachep();
889
free_sysfs:
890 891
	btrfs_exit_sysfs();
	return err;
892 893 894 895
}

static void __exit exit_btrfs_fs(void)
{
C
Chris Mason 已提交
896
	btrfs_destroy_cachep();
897
	extent_map_exit();
898
	extent_io_exit();
899
	btrfs_interface_exit();
900
	unregister_filesystem(&btrfs_fs_type);
901
	btrfs_exit_sysfs();
902
	btrfs_cleanup_fs_uuids();
C
Chris Mason 已提交
903
	btrfs_zlib_exit();
904 905 906 907 908 909
}

module_init(init_btrfs_fs)
module_exit(exit_btrfs_fs)

MODULE_LICENSE("GPL");