xref: /linux/fs/btrfs/super.c (revision f106e82caaa0d943e47cacc184f5b40d538e0044)
16cbd5570SChris Mason /*
26cbd5570SChris Mason  * Copyright (C) 2007 Oracle.  All rights reserved.
36cbd5570SChris Mason  *
46cbd5570SChris Mason  * This program is free software; you can redistribute it and/or
56cbd5570SChris Mason  * modify it under the terms of the GNU General Public
66cbd5570SChris Mason  * License v2 as published by the Free Software Foundation.
76cbd5570SChris Mason  *
86cbd5570SChris Mason  * This program is distributed in the hope that it will be useful,
96cbd5570SChris Mason  * but WITHOUT ANY WARRANTY; without even the implied warranty of
106cbd5570SChris Mason  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
116cbd5570SChris Mason  * General Public License for more details.
126cbd5570SChris Mason  *
136cbd5570SChris Mason  * You should have received a copy of the GNU General Public
146cbd5570SChris Mason  * License along with this program; if not, write to the
156cbd5570SChris Mason  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
166cbd5570SChris Mason  * Boston, MA 021110-1307, USA.
176cbd5570SChris Mason  */
186cbd5570SChris Mason 
194b82d6e4SYan #include <linux/blkdev.h>
202e635a27SChris Mason #include <linux/module.h>
21e20d96d6SChris Mason #include <linux/buffer_head.h>
222e635a27SChris Mason #include <linux/fs.h>
232e635a27SChris Mason #include <linux/pagemap.h>
242e635a27SChris Mason #include <linux/highmem.h>
252e635a27SChris Mason #include <linux/time.h>
262e635a27SChris Mason #include <linux/init.h>
27a9572a15SEric Paris #include <linux/seq_file.h>
282e635a27SChris Mason #include <linux/string.h>
292e635a27SChris Mason #include <linux/backing-dev.h>
304b82d6e4SYan #include <linux/mount.h>
31dee26a9fSChris Mason #include <linux/mpage.h>
3275dfe396SChris Mason #include <linux/swap.h>
3375dfe396SChris Mason #include <linux/writeback.h>
348fd17795SChris Mason #include <linux/statfs.h>
3508607c1bSChris Mason #include <linux/compat.h>
3695e05289SChris Mason #include <linux/parser.h>
37c59f8951SChris Mason #include <linux/ctype.h>
386da6abaeSChris Mason #include <linux/namei.h>
39a9218f6bSChris Mason #include <linux/miscdevice.h>
401bcbf313SQinghuang Feng #include <linux/magic.h>
415a0e3ad6STejun Heo #include <linux/slab.h>
424b4e25f2SChris Mason #include "compat.h"
432e635a27SChris Mason #include "ctree.h"
44e20d96d6SChris Mason #include "disk-io.h"
45d5719762SChris Mason #include "transaction.h"
462c90e5d6SChris Mason #include "btrfs_inode.h"
47c5739bbaSChris Mason #include "ioctl.h"
483a686375SChris Mason #include "print-tree.h"
495103e947SJosef Bacik #include "xattr.h"
508a4b83ccSChris Mason #include "volumes.h"
51b3c3da71SChris Mason #include "version.h"
52be6e8dc0SBalaji Rao #include "export.h"
53c8b97818SChris Mason #include "compression.h"
542e635a27SChris Mason 
55b87221deSAlexey Dobriyan static const struct super_operations btrfs_super_ops;
56e20d96d6SChris Mason 
57e20d96d6SChris Mason static void btrfs_put_super(struct super_block *sb)
58e20d96d6SChris Mason {
59e20d96d6SChris Mason 	struct btrfs_root *root = btrfs_sb(sb);
60e20d96d6SChris Mason 	int ret;
61e20d96d6SChris Mason 
62e20d96d6SChris Mason 	ret = close_ctree(root);
63e20d96d6SChris Mason 	sb->s_fs_info = NULL;
64559af821SAndi Kleen 
65559af821SAndi Kleen 	(void)ret; /* FIXME: need to fix VFS to return error? */
66e20d96d6SChris Mason }
672e635a27SChris Mason 
6895e05289SChris Mason enum {
6973f73415SJosef Bacik 	Opt_degraded, Opt_subvol, Opt_subvolid, Opt_device, Opt_nodatasum,
70287a0ab9SJosef Bacik 	Opt_nodatacow, Opt_max_inline, Opt_alloc_start, Opt_nobarrier, Opt_ssd,
71287a0ab9SJosef Bacik 	Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl, Opt_compress,
72287a0ab9SJosef Bacik 	Opt_compress_force, Opt_notreelog, Opt_ratio, Opt_flushoncommit,
7388c2ba3bSJosef Bacik 	Opt_discard, Opt_space_cache, Opt_clear_cache, Opt_err,
744260f7c7SSage Weil 	Opt_user_subvol_rm_allowed,
7595e05289SChris Mason };
7695e05289SChris Mason 
7795e05289SChris Mason static match_table_t tokens = {
78dfe25020SChris Mason 	{Opt_degraded, "degraded"},
7995e05289SChris Mason 	{Opt_subvol, "subvol=%s"},
8073f73415SJosef Bacik 	{Opt_subvolid, "subvolid=%d"},
8143e570b0SChristoph Hellwig 	{Opt_device, "device=%s"},
82b6cda9bcSChris Mason 	{Opt_nodatasum, "nodatasum"},
83be20aa9dSChris Mason 	{Opt_nodatacow, "nodatacow"},
8421ad10cfSChris Mason 	{Opt_nobarrier, "nobarrier"},
856f568d35SChris Mason 	{Opt_max_inline, "max_inline=%s"},
868f662a76SChris Mason 	{Opt_alloc_start, "alloc_start=%s"},
874543df7eSChris Mason 	{Opt_thread_pool, "thread_pool=%d"},
88c8b97818SChris Mason 	{Opt_compress, "compress"},
89a555f810SChris Mason 	{Opt_compress_force, "compress-force"},
90e18e4809SChris Mason 	{Opt_ssd, "ssd"},
91451d7585SChris Mason 	{Opt_ssd_spread, "ssd_spread"},
923b30c22fSChris Mason 	{Opt_nossd, "nossd"},
9333268eafSJosef Bacik 	{Opt_noacl, "noacl"},
943a5e1404SSage Weil 	{Opt_notreelog, "notreelog"},
95dccae999SSage Weil 	{Opt_flushoncommit, "flushoncommit"},
9697e728d4SJosef Bacik 	{Opt_ratio, "metadata_ratio=%d"},
97e244a0aeSChristoph Hellwig 	{Opt_discard, "discard"},
980af3d00bSJosef Bacik 	{Opt_space_cache, "space_cache"},
9988c2ba3bSJosef Bacik 	{Opt_clear_cache, "clear_cache"},
1004260f7c7SSage Weil 	{Opt_user_subvol_rm_allowed, "user_subvol_rm_allowed"},
10133268eafSJosef Bacik 	{Opt_err, NULL},
10295e05289SChris Mason };
10395e05289SChris Mason 
104edf24abeSChristoph Hellwig /*
105edf24abeSChristoph Hellwig  * Regular mount options parser.  Everything that is needed only when
106edf24abeSChristoph Hellwig  * reading in a new superblock is parsed here.
107edf24abeSChristoph Hellwig  */
108edf24abeSChristoph Hellwig int btrfs_parse_options(struct btrfs_root *root, char *options)
10995e05289SChris Mason {
110edf24abeSChristoph Hellwig 	struct btrfs_fs_info *info = root->fs_info;
11195e05289SChris Mason 	substring_t args[MAX_OPT_ARGS];
112da495eccSJosef Bacik 	char *p, *num, *orig;
1134543df7eSChris Mason 	int intarg;
114a7a3f7caSSage Weil 	int ret = 0;
115b6cda9bcSChris Mason 
11695e05289SChris Mason 	if (!options)
117edf24abeSChristoph Hellwig 		return 0;
11895e05289SChris Mason 
119be20aa9dSChris Mason 	/*
120be20aa9dSChris Mason 	 * strsep changes the string, duplicate it because parse_options
121be20aa9dSChris Mason 	 * gets called twice
122be20aa9dSChris Mason 	 */
123be20aa9dSChris Mason 	options = kstrdup(options, GFP_NOFS);
124be20aa9dSChris Mason 	if (!options)
125be20aa9dSChris Mason 		return -ENOMEM;
126be20aa9dSChris Mason 
127da495eccSJosef Bacik 	orig = options;
128be20aa9dSChris Mason 
12995e05289SChris Mason 	while ((p = strsep(&options, ",")) != NULL) {
13095e05289SChris Mason 		int token;
13195e05289SChris Mason 		if (!*p)
13295e05289SChris Mason 			continue;
13395e05289SChris Mason 
13495e05289SChris Mason 		token = match_token(p, tokens, args);
13595e05289SChris Mason 		switch (token) {
136dfe25020SChris Mason 		case Opt_degraded:
137edf24abeSChristoph Hellwig 			printk(KERN_INFO "btrfs: allowing degraded mounts\n");
138dfe25020SChris Mason 			btrfs_set_opt(info->mount_opt, DEGRADED);
139dfe25020SChris Mason 			break;
14095e05289SChris Mason 		case Opt_subvol:
14173f73415SJosef Bacik 		case Opt_subvolid:
14243e570b0SChristoph Hellwig 		case Opt_device:
143edf24abeSChristoph Hellwig 			/*
14443e570b0SChristoph Hellwig 			 * These are parsed by btrfs_parse_early_options
145edf24abeSChristoph Hellwig 			 * and can be happily ignored here.
146edf24abeSChristoph Hellwig 			 */
14795e05289SChris Mason 			break;
148b6cda9bcSChris Mason 		case Opt_nodatasum:
149067c28adSChris Mason 			printk(KERN_INFO "btrfs: setting nodatasum\n");
150b6cda9bcSChris Mason 			btrfs_set_opt(info->mount_opt, NODATASUM);
151be20aa9dSChris Mason 			break;
152be20aa9dSChris Mason 		case Opt_nodatacow:
153edf24abeSChristoph Hellwig 			printk(KERN_INFO "btrfs: setting nodatacow\n");
154be20aa9dSChris Mason 			btrfs_set_opt(info->mount_opt, NODATACOW);
155be20aa9dSChris Mason 			btrfs_set_opt(info->mount_opt, NODATASUM);
156b6cda9bcSChris Mason 			break;
157c8b97818SChris Mason 		case Opt_compress:
158c8b97818SChris Mason 			printk(KERN_INFO "btrfs: use compression\n");
159c8b97818SChris Mason 			btrfs_set_opt(info->mount_opt, COMPRESS);
160c8b97818SChris Mason 			break;
161a555f810SChris Mason 		case Opt_compress_force:
162a555f810SChris Mason 			printk(KERN_INFO "btrfs: forcing compression\n");
163a555f810SChris Mason 			btrfs_set_opt(info->mount_opt, FORCE_COMPRESS);
164a555f810SChris Mason 			btrfs_set_opt(info->mount_opt, COMPRESS);
165a555f810SChris Mason 			break;
166e18e4809SChris Mason 		case Opt_ssd:
167edf24abeSChristoph Hellwig 			printk(KERN_INFO "btrfs: use ssd allocation scheme\n");
168e18e4809SChris Mason 			btrfs_set_opt(info->mount_opt, SSD);
169e18e4809SChris Mason 			break;
170451d7585SChris Mason 		case Opt_ssd_spread:
171451d7585SChris Mason 			printk(KERN_INFO "btrfs: use spread ssd "
172451d7585SChris Mason 			       "allocation scheme\n");
173451d7585SChris Mason 			btrfs_set_opt(info->mount_opt, SSD);
174451d7585SChris Mason 			btrfs_set_opt(info->mount_opt, SSD_SPREAD);
175451d7585SChris Mason 			break;
1763b30c22fSChris Mason 		case Opt_nossd:
177451d7585SChris Mason 			printk(KERN_INFO "btrfs: not using ssd allocation "
178451d7585SChris Mason 			       "scheme\n");
179c289811cSChris Mason 			btrfs_set_opt(info->mount_opt, NOSSD);
1803b30c22fSChris Mason 			btrfs_clear_opt(info->mount_opt, SSD);
181451d7585SChris Mason 			btrfs_clear_opt(info->mount_opt, SSD_SPREAD);
1823b30c22fSChris Mason 			break;
18321ad10cfSChris Mason 		case Opt_nobarrier:
184edf24abeSChristoph Hellwig 			printk(KERN_INFO "btrfs: turning off barriers\n");
18521ad10cfSChris Mason 			btrfs_set_opt(info->mount_opt, NOBARRIER);
18621ad10cfSChris Mason 			break;
1874543df7eSChris Mason 		case Opt_thread_pool:
1884543df7eSChris Mason 			intarg = 0;
1894543df7eSChris Mason 			match_int(&args[0], &intarg);
1904543df7eSChris Mason 			if (intarg) {
1914543df7eSChris Mason 				info->thread_pool_size = intarg;
1924543df7eSChris Mason 				printk(KERN_INFO "btrfs: thread pool %d\n",
1934543df7eSChris Mason 				       info->thread_pool_size);
1944543df7eSChris Mason 			}
1954543df7eSChris Mason 			break;
1966f568d35SChris Mason 		case Opt_max_inline:
197edf24abeSChristoph Hellwig 			num = match_strdup(&args[0]);
1986f568d35SChris Mason 			if (num) {
19991748467SAkinobu Mita 				info->max_inline = memparse(num, NULL);
2006f568d35SChris Mason 				kfree(num);
2016f568d35SChris Mason 
20215ada040SChris Mason 				if (info->max_inline) {
2036f568d35SChris Mason 					info->max_inline = max_t(u64,
20415ada040SChris Mason 						info->max_inline,
20515ada040SChris Mason 						root->sectorsize);
20615ada040SChris Mason 				}
207edf24abeSChristoph Hellwig 				printk(KERN_INFO "btrfs: max_inline at %llu\n",
20821380931SJoel Becker 					(unsigned long long)info->max_inline);
2096f568d35SChris Mason 			}
2106f568d35SChris Mason 			break;
2118f662a76SChris Mason 		case Opt_alloc_start:
212edf24abeSChristoph Hellwig 			num = match_strdup(&args[0]);
2138f662a76SChris Mason 			if (num) {
21491748467SAkinobu Mita 				info->alloc_start = memparse(num, NULL);
2158f662a76SChris Mason 				kfree(num);
216edf24abeSChristoph Hellwig 				printk(KERN_INFO
217edf24abeSChristoph Hellwig 					"btrfs: allocations start at %llu\n",
21821380931SJoel Becker 					(unsigned long long)info->alloc_start);
2198f662a76SChris Mason 			}
2208f662a76SChris Mason 			break;
22133268eafSJosef Bacik 		case Opt_noacl:
22233268eafSJosef Bacik 			root->fs_info->sb->s_flags &= ~MS_POSIXACL;
22333268eafSJosef Bacik 			break;
2243a5e1404SSage Weil 		case Opt_notreelog:
2253a5e1404SSage Weil 			printk(KERN_INFO "btrfs: disabling tree log\n");
2263a5e1404SSage Weil 			btrfs_set_opt(info->mount_opt, NOTREELOG);
2273a5e1404SSage Weil 			break;
228dccae999SSage Weil 		case Opt_flushoncommit:
229dccae999SSage Weil 			printk(KERN_INFO "btrfs: turning on flush-on-commit\n");
230dccae999SSage Weil 			btrfs_set_opt(info->mount_opt, FLUSHONCOMMIT);
231dccae999SSage Weil 			break;
23297e728d4SJosef Bacik 		case Opt_ratio:
23397e728d4SJosef Bacik 			intarg = 0;
23497e728d4SJosef Bacik 			match_int(&args[0], &intarg);
23597e728d4SJosef Bacik 			if (intarg) {
23697e728d4SJosef Bacik 				info->metadata_ratio = intarg;
23797e728d4SJosef Bacik 				printk(KERN_INFO "btrfs: metadata ratio %d\n",
23897e728d4SJosef Bacik 				       info->metadata_ratio);
23997e728d4SJosef Bacik 			}
24097e728d4SJosef Bacik 			break;
241e244a0aeSChristoph Hellwig 		case Opt_discard:
242e244a0aeSChristoph Hellwig 			btrfs_set_opt(info->mount_opt, DISCARD);
243e244a0aeSChristoph Hellwig 			break;
2440af3d00bSJosef Bacik 		case Opt_space_cache:
2450af3d00bSJosef Bacik 			printk(KERN_INFO "btrfs: enabling disk space caching\n");
2460af3d00bSJosef Bacik 			btrfs_set_opt(info->mount_opt, SPACE_CACHE);
2470de90876SJosef Bacik 			break;
24888c2ba3bSJosef Bacik 		case Opt_clear_cache:
24988c2ba3bSJosef Bacik 			printk(KERN_INFO "btrfs: force clearing of disk cache\n");
25088c2ba3bSJosef Bacik 			btrfs_set_opt(info->mount_opt, CLEAR_CACHE);
2510af3d00bSJosef Bacik 			break;
2524260f7c7SSage Weil 		case Opt_user_subvol_rm_allowed:
2534260f7c7SSage Weil 			btrfs_set_opt(info->mount_opt, USER_SUBVOL_RM_ALLOWED);
2544260f7c7SSage Weil 			break;
255a7a3f7caSSage Weil 		case Opt_err:
256a7a3f7caSSage Weil 			printk(KERN_INFO "btrfs: unrecognized mount option "
257a7a3f7caSSage Weil 			       "'%s'\n", p);
258a7a3f7caSSage Weil 			ret = -EINVAL;
259a7a3f7caSSage Weil 			goto out;
26095e05289SChris Mason 		default:
261be20aa9dSChris Mason 			break;
26295e05289SChris Mason 		}
26395e05289SChris Mason 	}
264a7a3f7caSSage Weil out:
265da495eccSJosef Bacik 	kfree(orig);
266a7a3f7caSSage Weil 	return ret;
267edf24abeSChristoph Hellwig }
268edf24abeSChristoph Hellwig 
269edf24abeSChristoph Hellwig /*
270edf24abeSChristoph Hellwig  * Parse mount options that are required early in the mount process.
271edf24abeSChristoph Hellwig  *
272edf24abeSChristoph Hellwig  * All other options will be parsed on much later in the mount process and
273edf24abeSChristoph Hellwig  * only when we need to allocate a new super block.
274edf24abeSChristoph Hellwig  */
27597288f2cSChristoph Hellwig static int btrfs_parse_early_options(const char *options, fmode_t flags,
27673f73415SJosef Bacik 		void *holder, char **subvol_name, u64 *subvol_objectid,
27743e570b0SChristoph Hellwig 		struct btrfs_fs_devices **fs_devices)
278edf24abeSChristoph Hellwig {
279edf24abeSChristoph Hellwig 	substring_t args[MAX_OPT_ARGS];
280edf24abeSChristoph Hellwig 	char *opts, *p;
281edf24abeSChristoph Hellwig 	int error = 0;
28273f73415SJosef Bacik 	int intarg;
283edf24abeSChristoph Hellwig 
284edf24abeSChristoph Hellwig 	if (!options)
285edf24abeSChristoph Hellwig 		goto out;
286edf24abeSChristoph Hellwig 
287edf24abeSChristoph Hellwig 	/*
288edf24abeSChristoph Hellwig 	 * strsep changes the string, duplicate it because parse_options
289edf24abeSChristoph Hellwig 	 * gets called twice
290edf24abeSChristoph Hellwig 	 */
291edf24abeSChristoph Hellwig 	opts = kstrdup(options, GFP_KERNEL);
292edf24abeSChristoph Hellwig 	if (!opts)
293edf24abeSChristoph Hellwig 		return -ENOMEM;
294edf24abeSChristoph Hellwig 
295edf24abeSChristoph Hellwig 	while ((p = strsep(&opts, ",")) != NULL) {
296edf24abeSChristoph Hellwig 		int token;
297edf24abeSChristoph Hellwig 		if (!*p)
298edf24abeSChristoph Hellwig 			continue;
299edf24abeSChristoph Hellwig 
300edf24abeSChristoph Hellwig 		token = match_token(p, tokens, args);
301edf24abeSChristoph Hellwig 		switch (token) {
302edf24abeSChristoph Hellwig 		case Opt_subvol:
303edf24abeSChristoph Hellwig 			*subvol_name = match_strdup(&args[0]);
304edf24abeSChristoph Hellwig 			break;
30573f73415SJosef Bacik 		case Opt_subvolid:
30673f73415SJosef Bacik 			intarg = 0;
3074849f01dSJosef Bacik 			error = match_int(&args[0], &intarg);
3084849f01dSJosef Bacik 			if (!error) {
3094849f01dSJosef Bacik 				/* we want the original fs_tree */
3104849f01dSJosef Bacik 				if (!intarg)
3114849f01dSJosef Bacik 					*subvol_objectid =
3124849f01dSJosef Bacik 						BTRFS_FS_TREE_OBJECTID;
3134849f01dSJosef Bacik 				else
31473f73415SJosef Bacik 					*subvol_objectid = intarg;
3154849f01dSJosef Bacik 			}
31673f73415SJosef Bacik 			break;
31743e570b0SChristoph Hellwig 		case Opt_device:
31843e570b0SChristoph Hellwig 			error = btrfs_scan_one_device(match_strdup(&args[0]),
31943e570b0SChristoph Hellwig 					flags, holder, fs_devices);
32043e570b0SChristoph Hellwig 			if (error)
32143e570b0SChristoph Hellwig 				goto out_free_opts;
32243e570b0SChristoph Hellwig 			break;
323edf24abeSChristoph Hellwig 		default:
324edf24abeSChristoph Hellwig 			break;
325edf24abeSChristoph Hellwig 		}
326edf24abeSChristoph Hellwig 	}
327edf24abeSChristoph Hellwig 
32843e570b0SChristoph Hellwig  out_free_opts:
329edf24abeSChristoph Hellwig 	kfree(opts);
330edf24abeSChristoph Hellwig  out:
331edf24abeSChristoph Hellwig 	/*
332edf24abeSChristoph Hellwig 	 * If no subvolume name is specified we use the default one.  Allocate
3333de4586cSChris Mason 	 * a copy of the string "." here so that code later in the
334edf24abeSChristoph Hellwig 	 * mount path doesn't care if it's the default volume or another one.
335edf24abeSChristoph Hellwig 	 */
336edf24abeSChristoph Hellwig 	if (!*subvol_name) {
3373de4586cSChris Mason 		*subvol_name = kstrdup(".", GFP_KERNEL);
338edf24abeSChristoph Hellwig 		if (!*subvol_name)
339edf24abeSChristoph Hellwig 			return -ENOMEM;
340edf24abeSChristoph Hellwig 	}
341edf24abeSChristoph Hellwig 	return error;
34295e05289SChris Mason }
34395e05289SChris Mason 
34473f73415SJosef Bacik static struct dentry *get_default_root(struct super_block *sb,
34573f73415SJosef Bacik 				       u64 subvol_objectid)
34673f73415SJosef Bacik {
34773f73415SJosef Bacik 	struct btrfs_root *root = sb->s_fs_info;
34873f73415SJosef Bacik 	struct btrfs_root *new_root;
34973f73415SJosef Bacik 	struct btrfs_dir_item *di;
35073f73415SJosef Bacik 	struct btrfs_path *path;
35173f73415SJosef Bacik 	struct btrfs_key location;
35273f73415SJosef Bacik 	struct inode *inode;
35373f73415SJosef Bacik 	struct dentry *dentry;
35473f73415SJosef Bacik 	u64 dir_id;
35573f73415SJosef Bacik 	int new = 0;
35673f73415SJosef Bacik 
35773f73415SJosef Bacik 	/*
35873f73415SJosef Bacik 	 * We have a specific subvol we want to mount, just setup location and
35973f73415SJosef Bacik 	 * go look up the root.
36073f73415SJosef Bacik 	 */
36173f73415SJosef Bacik 	if (subvol_objectid) {
36273f73415SJosef Bacik 		location.objectid = subvol_objectid;
36373f73415SJosef Bacik 		location.type = BTRFS_ROOT_ITEM_KEY;
36473f73415SJosef Bacik 		location.offset = (u64)-1;
36573f73415SJosef Bacik 		goto find_root;
36673f73415SJosef Bacik 	}
36773f73415SJosef Bacik 
36873f73415SJosef Bacik 	path = btrfs_alloc_path();
36973f73415SJosef Bacik 	if (!path)
37073f73415SJosef Bacik 		return ERR_PTR(-ENOMEM);
37173f73415SJosef Bacik 	path->leave_spinning = 1;
37273f73415SJosef Bacik 
37373f73415SJosef Bacik 	/*
37473f73415SJosef Bacik 	 * Find the "default" dir item which points to the root item that we
37573f73415SJosef Bacik 	 * will mount by default if we haven't been given a specific subvolume
37673f73415SJosef Bacik 	 * to mount.
37773f73415SJosef Bacik 	 */
37873f73415SJosef Bacik 	dir_id = btrfs_super_root_dir(&root->fs_info->super_copy);
37973f73415SJosef Bacik 	di = btrfs_lookup_dir_item(NULL, root, path, dir_id, "default", 7, 0);
380fb4f6f91SDan Carpenter 	if (IS_ERR(di))
381fb4f6f91SDan Carpenter 		return ERR_CAST(di);
38273f73415SJosef Bacik 	if (!di) {
38373f73415SJosef Bacik 		/*
38473f73415SJosef Bacik 		 * Ok the default dir item isn't there.  This is weird since
38573f73415SJosef Bacik 		 * it's always been there, but don't freak out, just try and
38673f73415SJosef Bacik 		 * mount to root most subvolume.
38773f73415SJosef Bacik 		 */
38873f73415SJosef Bacik 		btrfs_free_path(path);
38973f73415SJosef Bacik 		dir_id = BTRFS_FIRST_FREE_OBJECTID;
39073f73415SJosef Bacik 		new_root = root->fs_info->fs_root;
39173f73415SJosef Bacik 		goto setup_root;
39273f73415SJosef Bacik 	}
39373f73415SJosef Bacik 
39473f73415SJosef Bacik 	btrfs_dir_item_key_to_cpu(path->nodes[0], di, &location);
39573f73415SJosef Bacik 	btrfs_free_path(path);
39673f73415SJosef Bacik 
39773f73415SJosef Bacik find_root:
39873f73415SJosef Bacik 	new_root = btrfs_read_fs_root_no_name(root->fs_info, &location);
39973f73415SJosef Bacik 	if (IS_ERR(new_root))
400d0b678cbSJulia Lawall 		return ERR_CAST(new_root);
40173f73415SJosef Bacik 
40273f73415SJosef Bacik 	if (btrfs_root_refs(&new_root->root_item) == 0)
40373f73415SJosef Bacik 		return ERR_PTR(-ENOENT);
40473f73415SJosef Bacik 
40573f73415SJosef Bacik 	dir_id = btrfs_root_dirid(&new_root->root_item);
40673f73415SJosef Bacik setup_root:
40773f73415SJosef Bacik 	location.objectid = dir_id;
40873f73415SJosef Bacik 	location.type = BTRFS_INODE_ITEM_KEY;
40973f73415SJosef Bacik 	location.offset = 0;
41073f73415SJosef Bacik 
41173f73415SJosef Bacik 	inode = btrfs_iget(sb, &location, new_root, &new);
4124cbd1149SDan Carpenter 	if (IS_ERR(inode))
4134cbd1149SDan Carpenter 		return ERR_CAST(inode);
41473f73415SJosef Bacik 
41573f73415SJosef Bacik 	/*
41673f73415SJosef Bacik 	 * If we're just mounting the root most subvol put the inode and return
41773f73415SJosef Bacik 	 * a reference to the dentry.  We will have already gotten a reference
41873f73415SJosef Bacik 	 * to the inode in btrfs_fill_super so we're good to go.
41973f73415SJosef Bacik 	 */
42073f73415SJosef Bacik 	if (!new && sb->s_root->d_inode == inode) {
42173f73415SJosef Bacik 		iput(inode);
42273f73415SJosef Bacik 		return dget(sb->s_root);
42373f73415SJosef Bacik 	}
42473f73415SJosef Bacik 
42573f73415SJosef Bacik 	if (new) {
42673f73415SJosef Bacik 		const struct qstr name = { .name = "/", .len = 1 };
42773f73415SJosef Bacik 
42873f73415SJosef Bacik 		/*
42973f73415SJosef Bacik 		 * New inode, we need to make the dentry a sibling of s_root so
43073f73415SJosef Bacik 		 * everything gets cleaned up properly on unmount.
43173f73415SJosef Bacik 		 */
43273f73415SJosef Bacik 		dentry = d_alloc(sb->s_root, &name);
43373f73415SJosef Bacik 		if (!dentry) {
43473f73415SJosef Bacik 			iput(inode);
43573f73415SJosef Bacik 			return ERR_PTR(-ENOMEM);
43673f73415SJosef Bacik 		}
43773f73415SJosef Bacik 		d_splice_alias(inode, dentry);
43873f73415SJosef Bacik 	} else {
43973f73415SJosef Bacik 		/*
44073f73415SJosef Bacik 		 * We found the inode in cache, just find a dentry for it and
44173f73415SJosef Bacik 		 * put the reference to the inode we just got.
44273f73415SJosef Bacik 		 */
44373f73415SJosef Bacik 		dentry = d_find_alias(inode);
44473f73415SJosef Bacik 		iput(inode);
44573f73415SJosef Bacik 	}
44673f73415SJosef Bacik 
44773f73415SJosef Bacik 	return dentry;
44873f73415SJosef Bacik }
44973f73415SJosef Bacik 
4508a4b83ccSChris Mason static int btrfs_fill_super(struct super_block *sb,
4518a4b83ccSChris Mason 			    struct btrfs_fs_devices *fs_devices,
4528a4b83ccSChris Mason 			    void *data, int silent)
4532e635a27SChris Mason {
4542e635a27SChris Mason 	struct inode *inode;
455e20d96d6SChris Mason 	struct dentry *root_dentry;
4560f7d52f4SChris Mason 	struct btrfs_root *tree_root;
4575d4f98a2SYan Zheng 	struct btrfs_key key;
45839279cc3SChris Mason 	int err;
4592e635a27SChris Mason 
4602e635a27SChris Mason 	sb->s_maxbytes = MAX_LFS_FILESIZE;
4612e635a27SChris Mason 	sb->s_magic = BTRFS_SUPER_MAGIC;
462e20d96d6SChris Mason 	sb->s_op = &btrfs_super_ops;
463be6e8dc0SBalaji Rao 	sb->s_export_op = &btrfs_export_ops;
4645103e947SJosef Bacik 	sb->s_xattr = btrfs_xattr_handlers;
4652e635a27SChris Mason 	sb->s_time_gran = 1;
4660eda294dSChris Mason #ifdef CONFIG_BTRFS_FS_POSIX_ACL
46733268eafSJosef Bacik 	sb->s_flags |= MS_POSIXACL;
46849cf6f45SChris Ball #endif
469e20d96d6SChris Mason 
470dfe25020SChris Mason 	tree_root = open_ctree(sb, fs_devices, (char *)data);
471d98237b3SChris Mason 
472e58ca020SYan 	if (IS_ERR(tree_root)) {
473e20d96d6SChris Mason 		printk("btrfs: open_ctree failed\n");
474e58ca020SYan 		return PTR_ERR(tree_root);
475e20d96d6SChris Mason 	}
4760f7d52f4SChris Mason 	sb->s_fs_info = tree_root;
477b888db2bSChris Mason 
4785d4f98a2SYan Zheng 	key.objectid = BTRFS_FIRST_FREE_OBJECTID;
4795d4f98a2SYan Zheng 	key.type = BTRFS_INODE_ITEM_KEY;
4805d4f98a2SYan Zheng 	key.offset = 0;
48173f73415SJosef Bacik 	inode = btrfs_iget(sb, &key, tree_root->fs_info->fs_root, NULL);
4825d4f98a2SYan Zheng 	if (IS_ERR(inode)) {
4835d4f98a2SYan Zheng 		err = PTR_ERR(inode);
48439279cc3SChris Mason 		goto fail_close;
48539279cc3SChris Mason 	}
4862e635a27SChris Mason 
487e20d96d6SChris Mason 	root_dentry = d_alloc_root(inode);
488e20d96d6SChris Mason 	if (!root_dentry) {
4892e635a27SChris Mason 		iput(inode);
49039279cc3SChris Mason 		err = -ENOMEM;
49139279cc3SChris Mason 		goto fail_close;
4922e635a27SChris Mason 	}
49358176a96SJosef Bacik 
494e20d96d6SChris Mason 	sb->s_root = root_dentry;
4956885f308SChris Mason 
4966885f308SChris Mason 	save_mount_options(sb, data);
4972e635a27SChris Mason 	return 0;
4982e635a27SChris Mason 
49939279cc3SChris Mason fail_close:
50039279cc3SChris Mason 	close_ctree(tree_root);
501d5719762SChris Mason 	return err;
502d5719762SChris Mason }
503d5719762SChris Mason 
5046bf13c0cSSage Weil int btrfs_sync_fs(struct super_block *sb, int wait)
505d5719762SChris Mason {
506d5719762SChris Mason 	struct btrfs_trans_handle *trans;
507dccae999SSage Weil 	struct btrfs_root *root = btrfs_sb(sb);
508d5719762SChris Mason 	int ret;
509df2ce34cSChris Mason 
510d561c025SChris Mason 	if (!wait) {
5117cfcc17eSChris Mason 		filemap_flush(root->fs_info->btree_inode->i_mapping);
512df2ce34cSChris Mason 		return 0;
513d561c025SChris Mason 	}
514771ed689SChris Mason 
51524bbcf04SYan, Zheng 	btrfs_start_delalloc_inodes(root, 0);
51624bbcf04SYan, Zheng 	btrfs_wait_ordered_extents(root, 0, 0);
517771ed689SChris Mason 
518a22285a6SYan, Zheng 	trans = btrfs_start_transaction(root, 0);
519d5719762SChris Mason 	ret = btrfs_commit_transaction(trans, root);
52054aa1f4dSChris Mason 	return ret;
521d5719762SChris Mason }
522d5719762SChris Mason 
523a9572a15SEric Paris static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
524a9572a15SEric Paris {
525a9572a15SEric Paris 	struct btrfs_root *root = btrfs_sb(vfs->mnt_sb);
526a9572a15SEric Paris 	struct btrfs_fs_info *info = root->fs_info;
527a9572a15SEric Paris 
528a9572a15SEric Paris 	if (btrfs_test_opt(root, DEGRADED))
529a9572a15SEric Paris 		seq_puts(seq, ",degraded");
530a9572a15SEric Paris 	if (btrfs_test_opt(root, NODATASUM))
531a9572a15SEric Paris 		seq_puts(seq, ",nodatasum");
532a9572a15SEric Paris 	if (btrfs_test_opt(root, NODATACOW))
533a9572a15SEric Paris 		seq_puts(seq, ",nodatacow");
534a9572a15SEric Paris 	if (btrfs_test_opt(root, NOBARRIER))
535a9572a15SEric Paris 		seq_puts(seq, ",nobarrier");
536a9572a15SEric Paris 	if (info->max_inline != 8192 * 1024)
53721380931SJoel Becker 		seq_printf(seq, ",max_inline=%llu",
53821380931SJoel Becker 			   (unsigned long long)info->max_inline);
539a9572a15SEric Paris 	if (info->alloc_start != 0)
54021380931SJoel Becker 		seq_printf(seq, ",alloc_start=%llu",
54121380931SJoel Becker 			   (unsigned long long)info->alloc_start);
542a9572a15SEric Paris 	if (info->thread_pool_size !=  min_t(unsigned long,
543a9572a15SEric Paris 					     num_online_cpus() + 2, 8))
544a9572a15SEric Paris 		seq_printf(seq, ",thread_pool=%d", info->thread_pool_size);
545a9572a15SEric Paris 	if (btrfs_test_opt(root, COMPRESS))
546a9572a15SEric Paris 		seq_puts(seq, ",compress");
547c289811cSChris Mason 	if (btrfs_test_opt(root, NOSSD))
548c289811cSChris Mason 		seq_puts(seq, ",nossd");
549451d7585SChris Mason 	if (btrfs_test_opt(root, SSD_SPREAD))
550451d7585SChris Mason 		seq_puts(seq, ",ssd_spread");
551451d7585SChris Mason 	else if (btrfs_test_opt(root, SSD))
552a9572a15SEric Paris 		seq_puts(seq, ",ssd");
5533a5e1404SSage Weil 	if (btrfs_test_opt(root, NOTREELOG))
5546b65c5c6SSage Weil 		seq_puts(seq, ",notreelog");
555dccae999SSage Weil 	if (btrfs_test_opt(root, FLUSHONCOMMIT))
5566b65c5c6SSage Weil 		seq_puts(seq, ",flushoncommit");
55720a5239aSMatthew Wilcox 	if (btrfs_test_opt(root, DISCARD))
55820a5239aSMatthew Wilcox 		seq_puts(seq, ",discard");
559a9572a15SEric Paris 	if (!(root->fs_info->sb->s_flags & MS_POSIXACL))
560a9572a15SEric Paris 		seq_puts(seq, ",noacl");
561a9572a15SEric Paris 	return 0;
562a9572a15SEric Paris }
563a9572a15SEric Paris 
564a061fc8dSChris Mason static int btrfs_test_super(struct super_block *s, void *data)
5652e635a27SChris Mason {
566450ba0eaSJosef Bacik 	struct btrfs_root *test_root = data;
567a061fc8dSChris Mason 	struct btrfs_root *root = btrfs_sb(s);
5684b82d6e4SYan 
569619c8c76SIan Kent 	/*
570619c8c76SIan Kent 	 * If this super block is going away, return false as it
571619c8c76SIan Kent 	 * can't match as an existing super block.
572619c8c76SIan Kent 	 */
573619c8c76SIan Kent 	if (!atomic_read(&s->s_active))
574619c8c76SIan Kent 		return 0;
575450ba0eaSJosef Bacik 	return root->fs_info->fs_devices == test_root->fs_info->fs_devices;
5764b82d6e4SYan }
5774b82d6e4SYan 
578450ba0eaSJosef Bacik static int btrfs_set_super(struct super_block *s, void *data)
579450ba0eaSJosef Bacik {
580450ba0eaSJosef Bacik 	s->s_fs_info = data;
581450ba0eaSJosef Bacik 
582450ba0eaSJosef Bacik 	return set_anon_super(s, data);
583450ba0eaSJosef Bacik }
584450ba0eaSJosef Bacik 
585450ba0eaSJosef Bacik 
586edf24abeSChristoph Hellwig /*
587edf24abeSChristoph Hellwig  * Find a superblock for the given device / mount point.
588edf24abeSChristoph Hellwig  *
589edf24abeSChristoph Hellwig  * Note:  This is based on get_sb_bdev from fs/super.c with a few additions
590edf24abeSChristoph Hellwig  *	  for multiple device setup.  Make sure to keep it in sync.
591edf24abeSChristoph Hellwig  */
592edf24abeSChristoph Hellwig static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
593edf24abeSChristoph Hellwig 		const char *dev_name, void *data, struct vfsmount *mnt)
5944b82d6e4SYan {
5954b82d6e4SYan 	struct block_device *bdev = NULL;
5964b82d6e4SYan 	struct super_block *s;
5974b82d6e4SYan 	struct dentry *root;
5988a4b83ccSChris Mason 	struct btrfs_fs_devices *fs_devices = NULL;
599450ba0eaSJosef Bacik 	struct btrfs_root *tree_root = NULL;
600450ba0eaSJosef Bacik 	struct btrfs_fs_info *fs_info = NULL;
60197288f2cSChristoph Hellwig 	fmode_t mode = FMODE_READ;
60273f73415SJosef Bacik 	char *subvol_name = NULL;
60373f73415SJosef Bacik 	u64 subvol_objectid = 0;
6044b82d6e4SYan 	int error = 0;
6054b82d6e4SYan 
60697288f2cSChristoph Hellwig 	if (!(flags & MS_RDONLY))
60797288f2cSChristoph Hellwig 		mode |= FMODE_WRITE;
60897288f2cSChristoph Hellwig 
60997288f2cSChristoph Hellwig 	error = btrfs_parse_early_options(data, mode, fs_type,
61073f73415SJosef Bacik 					  &subvol_name, &subvol_objectid,
61173f73415SJosef Bacik 					  &fs_devices);
612edf24abeSChristoph Hellwig 	if (error)
6131f483660SShen Feng 		return error;
614edf24abeSChristoph Hellwig 
61597288f2cSChristoph Hellwig 	error = btrfs_scan_one_device(dev_name, mode, fs_type, &fs_devices);
6168a4b83ccSChris Mason 	if (error)
617edf24abeSChristoph Hellwig 		goto error_free_subvol_name;
6184b82d6e4SYan 
61997288f2cSChristoph Hellwig 	error = btrfs_open_devices(fs_devices, mode, fs_type);
6208a4b83ccSChris Mason 	if (error)
621edf24abeSChristoph Hellwig 		goto error_free_subvol_name;
6228a4b83ccSChris Mason 
6232b82032cSYan Zheng 	if (!(flags & MS_RDONLY) && fs_devices->rw_devices == 0) {
6242b82032cSYan Zheng 		error = -EACCES;
6252b82032cSYan Zheng 		goto error_close_devices;
6262b82032cSYan Zheng 	}
6272b82032cSYan Zheng 
628450ba0eaSJosef Bacik 	/*
629450ba0eaSJosef Bacik 	 * Setup a dummy root and fs_info for test/set super.  This is because
630450ba0eaSJosef Bacik 	 * we don't actually fill this stuff out until open_ctree, but we need
631450ba0eaSJosef Bacik 	 * it for searching for existing supers, so this lets us do that and
632450ba0eaSJosef Bacik 	 * then open_ctree will properly initialize everything later.
633450ba0eaSJosef Bacik 	 */
634450ba0eaSJosef Bacik 	fs_info = kzalloc(sizeof(struct btrfs_fs_info), GFP_NOFS);
635450ba0eaSJosef Bacik 	tree_root = kzalloc(sizeof(struct btrfs_root), GFP_NOFS);
636450ba0eaSJosef Bacik 	if (!fs_info || !tree_root) {
637450ba0eaSJosef Bacik 		error = -ENOMEM;
638450ba0eaSJosef Bacik 		goto error_close_devices;
639450ba0eaSJosef Bacik 	}
640450ba0eaSJosef Bacik 	fs_info->tree_root = tree_root;
641450ba0eaSJosef Bacik 	fs_info->fs_devices = fs_devices;
642450ba0eaSJosef Bacik 	tree_root->fs_info = fs_info;
643450ba0eaSJosef Bacik 
644dfe25020SChris Mason 	bdev = fs_devices->latest_bdev;
645450ba0eaSJosef Bacik 	s = sget(fs_type, btrfs_test_super, btrfs_set_super, tree_root);
6464b82d6e4SYan 	if (IS_ERR(s))
6474b82d6e4SYan 		goto error_s;
6484b82d6e4SYan 
6494b82d6e4SYan 	if (s->s_root) {
6504b82d6e4SYan 		if ((flags ^ s->s_flags) & MS_RDONLY) {
6516f5bbff9SAl Viro 			deactivate_locked_super(s);
6524b82d6e4SYan 			error = -EBUSY;
653c146afadSYan Zheng 			goto error_close_devices;
6544b82d6e4SYan 		}
6554b82d6e4SYan 
6562b82032cSYan Zheng 		btrfs_close_devices(fs_devices);
6574b82d6e4SYan 	} else {
6584b82d6e4SYan 		char b[BDEVNAME_SIZE];
6594b82d6e4SYan 
6604b82d6e4SYan 		s->s_flags = flags;
6614b82d6e4SYan 		strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
6628a4b83ccSChris Mason 		error = btrfs_fill_super(s, fs_devices, data,
6638a4b83ccSChris Mason 					 flags & MS_SILENT ? 1 : 0);
6644b82d6e4SYan 		if (error) {
6656f5bbff9SAl Viro 			deactivate_locked_super(s);
6661f483660SShen Feng 			goto error_free_subvol_name;
6674b82d6e4SYan 		}
6684b82d6e4SYan 
669788f20ebSChris Mason 		btrfs_sb(s)->fs_info->bdev_holder = fs_type;
6704b82d6e4SYan 		s->s_flags |= MS_ACTIVE;
6714b82d6e4SYan 	}
6724b82d6e4SYan 
67373f73415SJosef Bacik 	root = get_default_root(s, subvol_objectid);
6744b82d6e4SYan 	if (IS_ERR(root)) {
6754b82d6e4SYan 		error = PTR_ERR(root);
67673f73415SJosef Bacik 		deactivate_locked_super(s);
6770e78340fSJosef Bacik 		goto error_free_subvol_name;
6784b82d6e4SYan 	}
67973f73415SJosef Bacik 	/* if they gave us a subvolume name bind mount into that */
68073f73415SJosef Bacik 	if (strcmp(subvol_name, ".")) {
68173f73415SJosef Bacik 		struct dentry *new_root;
68273f73415SJosef Bacik 		mutex_lock(&root->d_inode->i_mutex);
68373f73415SJosef Bacik 		new_root = lookup_one_len(subvol_name, root,
68473f73415SJosef Bacik 				      strlen(subvol_name));
68573f73415SJosef Bacik 		mutex_unlock(&root->d_inode->i_mutex);
68673f73415SJosef Bacik 
68773f73415SJosef Bacik 		if (IS_ERR(new_root)) {
688*f106e82cSLi Zefan 			dput(root);
68973f73415SJosef Bacik 			deactivate_locked_super(s);
69073f73415SJosef Bacik 			error = PTR_ERR(new_root);
6910e78340fSJosef Bacik 			goto error_free_subvol_name;
69273f73415SJosef Bacik 		}
69373f73415SJosef Bacik 		if (!new_root->d_inode) {
69473f73415SJosef Bacik 			dput(root);
69573f73415SJosef Bacik 			dput(new_root);
6966f5bbff9SAl Viro 			deactivate_locked_super(s);
6974b82d6e4SYan 			error = -ENXIO;
6980e78340fSJosef Bacik 			goto error_free_subvol_name;
6994b82d6e4SYan 		}
70073f73415SJosef Bacik 		dput(root);
70173f73415SJosef Bacik 		root = new_root;
70276fcef19SDavid Woodhouse 	}
7034b82d6e4SYan 
7044b82d6e4SYan 	mnt->mnt_sb = s;
7054b82d6e4SYan 	mnt->mnt_root = root;
706edf24abeSChristoph Hellwig 
707edf24abeSChristoph Hellwig 	kfree(subvol_name);
7084b82d6e4SYan 	return 0;
7094b82d6e4SYan 
7104b82d6e4SYan error_s:
7114b82d6e4SYan 	error = PTR_ERR(s);
712c146afadSYan Zheng error_close_devices:
7138a4b83ccSChris Mason 	btrfs_close_devices(fs_devices);
714450ba0eaSJosef Bacik 	kfree(fs_info);
715450ba0eaSJosef Bacik 	kfree(tree_root);
716edf24abeSChristoph Hellwig error_free_subvol_name:
717edf24abeSChristoph Hellwig 	kfree(subvol_name);
7184b82d6e4SYan 	return error;
7194b82d6e4SYan }
7202e635a27SChris Mason 
721c146afadSYan Zheng static int btrfs_remount(struct super_block *sb, int *flags, char *data)
722c146afadSYan Zheng {
723c146afadSYan Zheng 	struct btrfs_root *root = btrfs_sb(sb);
724c146afadSYan Zheng 	int ret;
725c146afadSYan Zheng 
726b288052eSChris Mason 	ret = btrfs_parse_options(root, data);
727b288052eSChris Mason 	if (ret)
728b288052eSChris Mason 		return -EINVAL;
729b288052eSChris Mason 
730c146afadSYan Zheng 	if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
731c146afadSYan Zheng 		return 0;
732c146afadSYan Zheng 
733c146afadSYan Zheng 	if (*flags & MS_RDONLY) {
734c146afadSYan Zheng 		sb->s_flags |= MS_RDONLY;
735c146afadSYan Zheng 
736c146afadSYan Zheng 		ret =  btrfs_commit_super(root);
737c146afadSYan Zheng 		WARN_ON(ret);
738c146afadSYan Zheng 	} else {
7392b82032cSYan Zheng 		if (root->fs_info->fs_devices->rw_devices == 0)
7402b82032cSYan Zheng 			return -EACCES;
7412b82032cSYan Zheng 
742c146afadSYan Zheng 		if (btrfs_super_log_root(&root->fs_info->super_copy) != 0)
743c146afadSYan Zheng 			return -EINVAL;
744c146afadSYan Zheng 
745d68fc57bSYan, Zheng 		ret = btrfs_cleanup_fs_roots(root->fs_info);
746c146afadSYan Zheng 		WARN_ON(ret);
747c146afadSYan Zheng 
748d68fc57bSYan, Zheng 		/* recover relocation */
749d68fc57bSYan, Zheng 		ret = btrfs_recover_relocation(root);
750c146afadSYan Zheng 		WARN_ON(ret);
751c146afadSYan Zheng 
752c146afadSYan Zheng 		sb->s_flags &= ~MS_RDONLY;
753c146afadSYan Zheng 	}
754c146afadSYan Zheng 
755c146afadSYan Zheng 	return 0;
756c146afadSYan Zheng }
757c146afadSYan Zheng 
7588fd17795SChris Mason static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)
7598fd17795SChris Mason {
7608fd17795SChris Mason 	struct btrfs_root *root = btrfs_sb(dentry->d_sb);
7614b52dff6SChris Mason 	struct btrfs_super_block *disk_super = &root->fs_info->super_copy;
762bd4d1088SJosef Bacik 	struct list_head *head = &root->fs_info->space_info;
763bd4d1088SJosef Bacik 	struct btrfs_space_info *found;
764bd4d1088SJosef Bacik 	u64 total_used = 0;
76589a55897SJosef Bacik 	u64 total_used_data = 0;
766db94535dSChris Mason 	int bits = dentry->d_sb->s_blocksize_bits;
7679d03632eSDavid Woodhouse 	__be32 *fsid = (__be32 *)root->fs_info->fsid;
7688fd17795SChris Mason 
769bd4d1088SJosef Bacik 	rcu_read_lock();
77089a55897SJosef Bacik 	list_for_each_entry_rcu(found, head, list) {
77189a55897SJosef Bacik 		if (found->flags & (BTRFS_BLOCK_GROUP_METADATA |
77289a55897SJosef Bacik 				    BTRFS_BLOCK_GROUP_SYSTEM))
77389a55897SJosef Bacik 			total_used_data += found->disk_total;
77489a55897SJosef Bacik 		else
77589a55897SJosef Bacik 			total_used_data += found->disk_used;
776b742bb82SYan, Zheng 		total_used += found->disk_used;
77789a55897SJosef Bacik 	}
778bd4d1088SJosef Bacik 	rcu_read_unlock();
779bd4d1088SJosef Bacik 
7808fd17795SChris Mason 	buf->f_namelen = BTRFS_NAME_LEN;
781db94535dSChris Mason 	buf->f_blocks = btrfs_super_total_bytes(disk_super) >> bits;
782bd4d1088SJosef Bacik 	buf->f_bfree = buf->f_blocks - (total_used >> bits);
78389a55897SJosef Bacik 	buf->f_bavail = buf->f_blocks - (total_used_data >> bits);
7848fd17795SChris Mason 	buf->f_bsize = dentry->d_sb->s_blocksize;
7858fd17795SChris Mason 	buf->f_type = BTRFS_SUPER_MAGIC;
786d397712bSChris Mason 
7879d03632eSDavid Woodhouse 	/* We treat it as constant endianness (it doesn't matter _which_)
7889d03632eSDavid Woodhouse 	   because we want the fsid to come out the same whether mounted
7899d03632eSDavid Woodhouse 	   on a big-endian or little-endian host */
7909d03632eSDavid Woodhouse 	buf->f_fsid.val[0] = be32_to_cpu(fsid[0]) ^ be32_to_cpu(fsid[2]);
7919d03632eSDavid Woodhouse 	buf->f_fsid.val[1] = be32_to_cpu(fsid[1]) ^ be32_to_cpu(fsid[3]);
79232d48fa1SDavid Woodhouse 	/* Mask in the root object ID too, to disambiguate subvols */
79332d48fa1SDavid Woodhouse 	buf->f_fsid.val[0] ^= BTRFS_I(dentry->d_inode)->root->objectid >> 32;
79432d48fa1SDavid Woodhouse 	buf->f_fsid.val[1] ^= BTRFS_I(dentry->d_inode)->root->objectid;
79532d48fa1SDavid Woodhouse 
7968fd17795SChris Mason 	return 0;
7978fd17795SChris Mason }
798b5133862SChris Mason 
7992e635a27SChris Mason static struct file_system_type btrfs_fs_type = {
8002e635a27SChris Mason 	.owner		= THIS_MODULE,
8012e635a27SChris Mason 	.name		= "btrfs",
8022e635a27SChris Mason 	.get_sb		= btrfs_get_sb,
803a061fc8dSChris Mason 	.kill_sb	= kill_anon_super,
8042e635a27SChris Mason 	.fs_flags	= FS_REQUIRES_DEV,
8052e635a27SChris Mason };
806a9218f6bSChris Mason 
807d352ac68SChris Mason /*
808d352ac68SChris Mason  * used by btrfsctl to scan devices when no FS is mounted
809d352ac68SChris Mason  */
8108a4b83ccSChris Mason static long btrfs_control_ioctl(struct file *file, unsigned int cmd,
8118a4b83ccSChris Mason 				unsigned long arg)
8128a4b83ccSChris Mason {
8138a4b83ccSChris Mason 	struct btrfs_ioctl_vol_args *vol;
8148a4b83ccSChris Mason 	struct btrfs_fs_devices *fs_devices;
815c071fcfdSChris Mason 	int ret = -ENOTTY;
8168a4b83ccSChris Mason 
817e441d54dSChris Mason 	if (!capable(CAP_SYS_ADMIN))
818e441d54dSChris Mason 		return -EPERM;
819e441d54dSChris Mason 
820dae7b665SLi Zefan 	vol = memdup_user((void __user *)arg, sizeof(*vol));
821dae7b665SLi Zefan 	if (IS_ERR(vol))
822dae7b665SLi Zefan 		return PTR_ERR(vol);
823c071fcfdSChris Mason 
8248a4b83ccSChris Mason 	switch (cmd) {
8258a4b83ccSChris Mason 	case BTRFS_IOC_SCAN_DEV:
82697288f2cSChristoph Hellwig 		ret = btrfs_scan_one_device(vol->name, FMODE_READ,
8278a4b83ccSChris Mason 					    &btrfs_fs_type, &fs_devices);
8288a4b83ccSChris Mason 		break;
8298a4b83ccSChris Mason 	}
830dae7b665SLi Zefan 
8318a4b83ccSChris Mason 	kfree(vol);
832f819d837SLinda Knippers 	return ret;
8338a4b83ccSChris Mason }
8348a4b83ccSChris Mason 
8350176260fSLinus Torvalds static int btrfs_freeze(struct super_block *sb)
836ed0dab6bSYan {
837ed0dab6bSYan 	struct btrfs_root *root = btrfs_sb(sb);
838a74a4b97SChris Mason 	mutex_lock(&root->fs_info->transaction_kthread_mutex);
839a74a4b97SChris Mason 	mutex_lock(&root->fs_info->cleaner_mutex);
8400176260fSLinus Torvalds 	return 0;
841ed0dab6bSYan }
842ed0dab6bSYan 
8430176260fSLinus Torvalds static int btrfs_unfreeze(struct super_block *sb)
844ed0dab6bSYan {
845ed0dab6bSYan 	struct btrfs_root *root = btrfs_sb(sb);
846a74a4b97SChris Mason 	mutex_unlock(&root->fs_info->cleaner_mutex);
847a74a4b97SChris Mason 	mutex_unlock(&root->fs_info->transaction_kthread_mutex);
8480176260fSLinus Torvalds 	return 0;
849ed0dab6bSYan }
8502e635a27SChris Mason 
851b87221deSAlexey Dobriyan static const struct super_operations btrfs_super_ops = {
85276dda93cSYan, Zheng 	.drop_inode	= btrfs_drop_inode,
853bd555975SAl Viro 	.evict_inode	= btrfs_evict_inode,
854e20d96d6SChris Mason 	.put_super	= btrfs_put_super,
855d5719762SChris Mason 	.sync_fs	= btrfs_sync_fs,
856a9572a15SEric Paris 	.show_options	= btrfs_show_options,
8574730a4bcSChris Mason 	.write_inode	= btrfs_write_inode,
858b5133862SChris Mason 	.dirty_inode	= btrfs_dirty_inode,
8592c90e5d6SChris Mason 	.alloc_inode	= btrfs_alloc_inode,
8602c90e5d6SChris Mason 	.destroy_inode	= btrfs_destroy_inode,
8618fd17795SChris Mason 	.statfs		= btrfs_statfs,
862c146afadSYan Zheng 	.remount_fs	= btrfs_remount,
8630176260fSLinus Torvalds 	.freeze_fs	= btrfs_freeze,
8640176260fSLinus Torvalds 	.unfreeze_fs	= btrfs_unfreeze,
865e20d96d6SChris Mason };
866a9218f6bSChris Mason 
867a9218f6bSChris Mason static const struct file_operations btrfs_ctl_fops = {
868a9218f6bSChris Mason 	.unlocked_ioctl	 = btrfs_control_ioctl,
869a9218f6bSChris Mason 	.compat_ioctl = btrfs_control_ioctl,
870a9218f6bSChris Mason 	.owner	 = THIS_MODULE,
871a9218f6bSChris Mason };
872a9218f6bSChris Mason 
873a9218f6bSChris Mason static struct miscdevice btrfs_misc = {
874578454ffSKay Sievers 	.minor		= BTRFS_MINOR,
875a9218f6bSChris Mason 	.name		= "btrfs-control",
876a9218f6bSChris Mason 	.fops		= &btrfs_ctl_fops
877a9218f6bSChris Mason };
878a9218f6bSChris Mason 
879578454ffSKay Sievers MODULE_ALIAS_MISCDEV(BTRFS_MINOR);
880578454ffSKay Sievers MODULE_ALIAS("devname:btrfs-control");
881578454ffSKay Sievers 
882a9218f6bSChris Mason static int btrfs_interface_init(void)
883a9218f6bSChris Mason {
884a9218f6bSChris Mason 	return misc_register(&btrfs_misc);
885a9218f6bSChris Mason }
886a9218f6bSChris Mason 
887b2950863SChristoph Hellwig static void btrfs_interface_exit(void)
888a9218f6bSChris Mason {
889a9218f6bSChris Mason 	if (misc_deregister(&btrfs_misc) < 0)
890d397712bSChris Mason 		printk(KERN_INFO "misc_deregister failed for control device");
891a9218f6bSChris Mason }
892a9218f6bSChris Mason 
8932e635a27SChris Mason static int __init init_btrfs_fs(void)
8942e635a27SChris Mason {
8952c90e5d6SChris Mason 	int err;
89658176a96SJosef Bacik 
89758176a96SJosef Bacik 	err = btrfs_init_sysfs();
89858176a96SJosef Bacik 	if (err)
89958176a96SJosef Bacik 		return err;
90058176a96SJosef Bacik 
90139279cc3SChris Mason 	err = btrfs_init_cachep();
9022c90e5d6SChris Mason 	if (err)
903a74a4b97SChris Mason 		goto free_sysfs;
904d1310b2eSChris Mason 
905d1310b2eSChris Mason 	err = extent_io_init();
9062f4cbe64SWyatt Banks 	if (err)
9072f4cbe64SWyatt Banks 		goto free_cachep;
9082f4cbe64SWyatt Banks 
909d1310b2eSChris Mason 	err = extent_map_init();
910d1310b2eSChris Mason 	if (err)
911d1310b2eSChris Mason 		goto free_extent_io;
912d1310b2eSChris Mason 
913a9218f6bSChris Mason 	err = btrfs_interface_init();
9142f4cbe64SWyatt Banks 	if (err)
9152f4cbe64SWyatt Banks 		goto free_extent_map;
916c8b97818SChris Mason 
917a9218f6bSChris Mason 	err = register_filesystem(&btrfs_fs_type);
918a9218f6bSChris Mason 	if (err)
919a9218f6bSChris Mason 		goto unregister_ioctl;
920b3c3da71SChris Mason 
921b3c3da71SChris Mason 	printk(KERN_INFO "%s loaded\n", BTRFS_BUILD_VERSION);
9222f4cbe64SWyatt Banks 	return 0;
9232f4cbe64SWyatt Banks 
924a9218f6bSChris Mason unregister_ioctl:
925a9218f6bSChris Mason 	btrfs_interface_exit();
9262f4cbe64SWyatt Banks free_extent_map:
9272f4cbe64SWyatt Banks 	extent_map_exit();
928d1310b2eSChris Mason free_extent_io:
929d1310b2eSChris Mason 	extent_io_exit();
9302f4cbe64SWyatt Banks free_cachep:
9312f4cbe64SWyatt Banks 	btrfs_destroy_cachep();
932a74a4b97SChris Mason free_sysfs:
9332f4cbe64SWyatt Banks 	btrfs_exit_sysfs();
9342c90e5d6SChris Mason 	return err;
9352e635a27SChris Mason }
9362e635a27SChris Mason 
9372e635a27SChris Mason static void __exit exit_btrfs_fs(void)
9382e635a27SChris Mason {
93939279cc3SChris Mason 	btrfs_destroy_cachep();
940a52d9a80SChris Mason 	extent_map_exit();
941d1310b2eSChris Mason 	extent_io_exit();
942a9218f6bSChris Mason 	btrfs_interface_exit();
9432e635a27SChris Mason 	unregister_filesystem(&btrfs_fs_type);
94458176a96SJosef Bacik 	btrfs_exit_sysfs();
9458a4b83ccSChris Mason 	btrfs_cleanup_fs_uuids();
946c8b97818SChris Mason 	btrfs_zlib_exit();
9472e635a27SChris Mason }
9482e635a27SChris Mason 
9492e635a27SChris Mason module_init(init_btrfs_fs)
9502e635a27SChris Mason module_exit(exit_btrfs_fs)
9512e635a27SChris Mason 
9522e635a27SChris Mason MODULE_LICENSE("GPL");
953