Blame view

fs/btrfs/disk-io.c 96.1 KB
6cbd55707   Chris Mason   Btrfs: add GPLv2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  /*
   * 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.
   */
e20d96d64   Chris Mason   Mountable btrfs, ...
18
  #include <linux/fs.h>
d98237b3e   Chris Mason   Btrfs: use a btre...
19
  #include <linux/blkdev.h>
87cbda5c1   Chris Mason   Btrfs: sha256 csu...
20
  #include <linux/scatterlist.h>
22b0ebda6   Chris Mason   Btrfs: hunting sl...
21
  #include <linux/swap.h>
0f7d52f44   Chris Mason   Btrfs: groundwork...
22
  #include <linux/radix-tree.h>
35b7e4761   Chris Mason   Btrfs: fix page c...
23
  #include <linux/writeback.h>
d397712bc   Chris Mason   Btrfs: Fix checkp...
24
  #include <linux/buffer_head.h>
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
25
  #include <linux/workqueue.h>
a74a4b97b   Chris Mason   Btrfs: Replace th...
26
  #include <linux/kthread.h>
4b4e25f2a   Chris Mason   Btrfs: compat cod...
27
  #include <linux/freezer.h>
163e783e6   David Woodhouse   Btrfs: remove crc...
28
  #include <linux/crc32c.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
29
  #include <linux/slab.h>
784b4e29a   Chris Mason   Btrfs: add migrat...
30
  #include <linux/migrate.h>
7a36ddec1   David Sterba   btrfs: use printk...
31
  #include <linux/ratelimit.h>
7e75bf3ff   David Sterba   btrfs: properly a...
32
  #include <asm/unaligned.h>
4b4e25f2a   Chris Mason   Btrfs: compat cod...
33
  #include "compat.h"
eb60ceac0   Chris Mason   Btrfs: Add backin...
34
35
  #include "ctree.h"
  #include "disk-io.h"
e089f05c1   Chris Mason   Btrfs: transactio...
36
  #include "transaction.h"
0f7d52f44   Chris Mason   Btrfs: groundwork...
37
  #include "btrfs_inode.h"
0b86a832a   Chris Mason   Btrfs: Add suppor...
38
  #include "volumes.h"
db94535db   Chris Mason   Btrfs: Allow tree...
39
  #include "print-tree.h"
8b7128429   Chris Mason   Btrfs: Add async ...
40
  #include "async-thread.h"
925baeddc   Chris Mason   Btrfs: Start btre...
41
  #include "locking.h"
e02119d5a   Chris Mason   Btrfs: Add a writ...
42
  #include "tree-log.h"
fa9c0d795   Chris Mason   Btrfs: rework all...
43
  #include "free-space-cache.h"
581bb0509   Li Zefan   Btrfs: Cache free...
44
  #include "inode-map.h"
eb60ceac0   Chris Mason   Btrfs: Add backin...
45

d1310b2e0   Chris Mason   Btrfs: Split the ...
46
  static struct extent_io_ops btree_extent_io_ops;
8b7128429   Chris Mason   Btrfs: Add async ...
47
  static void end_workqueue_fn(struct btrfs_work *work);
4df27c4d5   Yan, Zheng   Btrfs: change how...
48
  static void free_fs_root(struct btrfs_root *root);
acce952b0   liubo   Btrfs: forced rea...
49
50
51
52
53
54
55
56
57
58
59
60
61
62
  static void btrfs_check_super_valid(struct btrfs_fs_info *fs_info,
  				    int read_only);
  static int btrfs_destroy_ordered_operations(struct btrfs_root *root);
  static int btrfs_destroy_ordered_extents(struct btrfs_root *root);
  static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans,
  				      struct btrfs_root *root);
  static int btrfs_destroy_pending_snapshots(struct btrfs_transaction *t);
  static int btrfs_destroy_delalloc_inodes(struct btrfs_root *root);
  static int btrfs_destroy_marked_extents(struct btrfs_root *root,
  					struct extent_io_tree *dirty_pages,
  					int mark);
  static int btrfs_destroy_pinned_extent(struct btrfs_root *root,
  				       struct extent_io_tree *pinned_extents);
  static int btrfs_cleanup_transaction(struct btrfs_root *root);
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
63

d352ac681   Chris Mason   Btrfs: add and im...
64
65
66
67
68
  /*
   * end_io_wq structs are used to do processing in task context when an IO is
   * complete.  This is used during reads to verify checksums, and it is used
   * by writes to insert metadata for new file extents after IO is complete.
   */
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
69
70
71
72
73
74
  struct end_io_wq {
  	struct bio *bio;
  	bio_end_io_t *end_io;
  	void *private;
  	struct btrfs_fs_info *info;
  	int error;
22c599485   Chris Mason   Btrfs: Handle dat...
75
  	int metadata;
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
76
  	struct list_head list;
8b7128429   Chris Mason   Btrfs: Add async ...
77
  	struct btrfs_work work;
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
78
  };
0da5468f4   Chris Mason   Btrfs: Use writep...
79

d352ac681   Chris Mason   Btrfs: add and im...
80
81
82
83
84
  /*
   * async submit bios are used to offload expensive checksumming
   * onto the worker threads.  They checksum file and metadata bios
   * just before they are sent down the IO stack.
   */
44b8bd7ed   Chris Mason   Btrfs: Create a w...
85
86
87
88
  struct async_submit_bio {
  	struct inode *inode;
  	struct bio *bio;
  	struct list_head list;
4a69a4100   Chris Mason   Btrfs: Add ordere...
89
90
  	extent_submit_bio_hook_t *submit_bio_start;
  	extent_submit_bio_hook_t *submit_bio_done;
44b8bd7ed   Chris Mason   Btrfs: Create a w...
91
92
  	int rw;
  	int mirror_num;
c8b978188   Chris Mason   Btrfs: Add zlib c...
93
  	unsigned long bio_flags;
eaf25d933   Chris Mason   Btrfs: use async ...
94
95
96
97
98
  	/*
  	 * bio_offset is optional, can be used if the pages in the bio
  	 * can't tell us where in the file the bio should go
  	 */
  	u64 bio_offset;
8b7128429   Chris Mason   Btrfs: Add async ...
99
  	struct btrfs_work work;
44b8bd7ed   Chris Mason   Btrfs: Create a w...
100
  };
85d4e4611   Chris Mason   Btrfs: make a loc...
101
102
103
104
105
106
107
108
109
110
  /*
   * Lockdep class keys for extent_buffer->lock's in this root.  For a given
   * eb, the lockdep key is determined by the btrfs_root it belongs to and
   * the level the eb occupies in the tree.
   *
   * Different roots are used for different purposes and may nest inside each
   * other and they require separate keysets.  As lockdep keys should be
   * static, assign keysets according to the purpose of the root as indicated
   * by btrfs_root->objectid.  This ensures that all special purpose roots
   * have separate keysets.
4008c04a0   Chris Mason   Btrfs: make a loc...
111
   *
85d4e4611   Chris Mason   Btrfs: make a loc...
112
113
114
   * Lock-nesting across peer nodes is always done with the immediate parent
   * node locked thus preventing deadlock.  As lockdep doesn't know this, use
   * subclass to avoid triggering lockdep warning in such cases.
4008c04a0   Chris Mason   Btrfs: make a loc...
115
   *
85d4e4611   Chris Mason   Btrfs: make a loc...
116
117
118
   * The key is set by the readpage_end_io_hook after the buffer has passed
   * csum validation but before the pages are unlocked.  It is also set by
   * btrfs_init_new_buffer on freshly allocated blocks.
4008c04a0   Chris Mason   Btrfs: make a loc...
119
   *
85d4e4611   Chris Mason   Btrfs: make a loc...
120
121
122
   * We also add a check to make sure the highest level of the tree is the
   * same as our lockdep setup here.  If BTRFS_MAX_LEVEL changes, this code
   * needs update as well.
4008c04a0   Chris Mason   Btrfs: make a loc...
123
124
125
126
127
   */
  #ifdef CONFIG_DEBUG_LOCK_ALLOC
  # if BTRFS_MAX_LEVEL != 8
  #  error
  # endif
85d4e4611   Chris Mason   Btrfs: make a loc...
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
  
  static struct btrfs_lockdep_keyset {
  	u64			id;		/* root objectid */
  	const char		*name_stem;	/* lock name stem */
  	char			names[BTRFS_MAX_LEVEL + 1][20];
  	struct lock_class_key	keys[BTRFS_MAX_LEVEL + 1];
  } btrfs_lockdep_keysets[] = {
  	{ .id = BTRFS_ROOT_TREE_OBJECTID,	.name_stem = "root"	},
  	{ .id = BTRFS_EXTENT_TREE_OBJECTID,	.name_stem = "extent"	},
  	{ .id = BTRFS_CHUNK_TREE_OBJECTID,	.name_stem = "chunk"	},
  	{ .id = BTRFS_DEV_TREE_OBJECTID,	.name_stem = "dev"	},
  	{ .id = BTRFS_FS_TREE_OBJECTID,		.name_stem = "fs"	},
  	{ .id = BTRFS_CSUM_TREE_OBJECTID,	.name_stem = "csum"	},
  	{ .id = BTRFS_ORPHAN_OBJECTID,		.name_stem = "orphan"	},
  	{ .id = BTRFS_TREE_LOG_OBJECTID,	.name_stem = "log"	},
  	{ .id = BTRFS_TREE_RELOC_OBJECTID,	.name_stem = "treloc"	},
  	{ .id = BTRFS_DATA_RELOC_TREE_OBJECTID,	.name_stem = "dreloc"	},
  	{ .id = 0,				.name_stem = "tree"	},
4008c04a0   Chris Mason   Btrfs: make a loc...
146
  };
85d4e4611   Chris Mason   Btrfs: make a loc...
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
  
  void __init btrfs_init_lockdep(void)
  {
  	int i, j;
  
  	/* initialize lockdep class names */
  	for (i = 0; i < ARRAY_SIZE(btrfs_lockdep_keysets); i++) {
  		struct btrfs_lockdep_keyset *ks = &btrfs_lockdep_keysets[i];
  
  		for (j = 0; j < ARRAY_SIZE(ks->names); j++)
  			snprintf(ks->names[j], sizeof(ks->names[j]),
  				 "btrfs-%s-%02d", ks->name_stem, j);
  	}
  }
  
  void btrfs_set_buffer_lockdep_class(u64 objectid, struct extent_buffer *eb,
  				    int level)
  {
  	struct btrfs_lockdep_keyset *ks;
  
  	BUG_ON(level >= ARRAY_SIZE(ks->keys));
  
  	/* find the matching keyset, id 0 is the default entry */
  	for (ks = btrfs_lockdep_keysets; ks->id; ks++)
  		if (ks->id == objectid)
  			break;
  
  	lockdep_set_class_and_name(&eb->lock,
  				   &ks->keys[level], ks->names[level]);
  }
4008c04a0   Chris Mason   Btrfs: make a loc...
177
  #endif
d352ac681   Chris Mason   Btrfs: add and im...
178
179
180
181
  /*
   * extents on the btree inode are pretty simple, there's one extent
   * that covers the entire device
   */
b2950863c   Christoph Hellwig   Btrfs: make thing...
182
  static struct extent_map *btree_get_extent(struct inode *inode,
306e16ce1   David Sterba   btrfs: rename var...
183
  		struct page *page, size_t pg_offset, u64 start, u64 len,
b2950863c   Christoph Hellwig   Btrfs: make thing...
184
  		int create)
7eccb903a   Chris Mason   Btrfs: create a l...
185
  {
5f39d397d   Chris Mason   Btrfs: Create ext...
186
187
188
  	struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
  	struct extent_map *em;
  	int ret;
890871be8   Chris Mason   Btrfs: switch ext...
189
  	read_lock(&em_tree->lock);
d1310b2e0   Chris Mason   Btrfs: Split the ...
190
  	em = lookup_extent_mapping(em_tree, start, len);
a061fc8da   Chris Mason   Btrfs: Add suppor...
191
192
193
  	if (em) {
  		em->bdev =
  			BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev;
890871be8   Chris Mason   Btrfs: switch ext...
194
  		read_unlock(&em_tree->lock);
5f39d397d   Chris Mason   Btrfs: Create ext...
195
  		goto out;
a061fc8da   Chris Mason   Btrfs: Add suppor...
196
  	}
890871be8   Chris Mason   Btrfs: switch ext...
197
  	read_unlock(&em_tree->lock);
7b13b7b11   Chris Mason   Btrfs: Don't drop...
198

172ddd60a   David Sterba   btrfs: drop gfp p...
199
  	em = alloc_extent_map();
5f39d397d   Chris Mason   Btrfs: Create ext...
200
201
202
203
204
  	if (!em) {
  		em = ERR_PTR(-ENOMEM);
  		goto out;
  	}
  	em->start = 0;
0afbaf8c8   Chris Mason   Btrfs: Set the bt...
205
  	em->len = (u64)-1;
c8b978188   Chris Mason   Btrfs: Add zlib c...
206
  	em->block_len = (u64)-1;
5f39d397d   Chris Mason   Btrfs: Create ext...
207
  	em->block_start = 0;
a061fc8da   Chris Mason   Btrfs: Add suppor...
208
  	em->bdev = BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev;
d1310b2e0   Chris Mason   Btrfs: Split the ...
209

890871be8   Chris Mason   Btrfs: switch ext...
210
  	write_lock(&em_tree->lock);
5f39d397d   Chris Mason   Btrfs: Create ext...
211
212
  	ret = add_extent_mapping(em_tree, em);
  	if (ret == -EEXIST) {
0afbaf8c8   Chris Mason   Btrfs: Set the bt...
213
214
  		u64 failed_start = em->start;
  		u64 failed_len = em->len;
5f39d397d   Chris Mason   Btrfs: Create ext...
215
  		free_extent_map(em);
7b13b7b11   Chris Mason   Btrfs: Don't drop...
216
  		em = lookup_extent_mapping(em_tree, start, len);
0afbaf8c8   Chris Mason   Btrfs: Set the bt...
217
  		if (em) {
7b13b7b11   Chris Mason   Btrfs: Don't drop...
218
  			ret = 0;
0afbaf8c8   Chris Mason   Btrfs: Set the bt...
219
220
221
  		} else {
  			em = lookup_extent_mapping(em_tree, failed_start,
  						   failed_len);
7b13b7b11   Chris Mason   Btrfs: Don't drop...
222
  			ret = -EIO;
0afbaf8c8   Chris Mason   Btrfs: Set the bt...
223
  		}
5f39d397d   Chris Mason   Btrfs: Create ext...
224
  	} else if (ret) {
7b13b7b11   Chris Mason   Btrfs: Don't drop...
225
226
  		free_extent_map(em);
  		em = NULL;
5f39d397d   Chris Mason   Btrfs: Create ext...
227
  	}
890871be8   Chris Mason   Btrfs: switch ext...
228
  	write_unlock(&em_tree->lock);
7b13b7b11   Chris Mason   Btrfs: Don't drop...
229
230
231
  
  	if (ret)
  		em = ERR_PTR(ret);
5f39d397d   Chris Mason   Btrfs: Create ext...
232
233
  out:
  	return em;
7eccb903a   Chris Mason   Btrfs: create a l...
234
  }
19c00ddcc   Chris Mason   Btrfs: Add back m...
235
236
  u32 btrfs_csum_data(struct btrfs_root *root, char *data, u32 seed, size_t len)
  {
163e783e6   David Woodhouse   Btrfs: remove crc...
237
  	return crc32c(seed, data, len);
19c00ddcc   Chris Mason   Btrfs: Add back m...
238
239
240
241
  }
  
  void btrfs_csum_final(u32 crc, char *result)
  {
7e75bf3ff   David Sterba   btrfs: properly a...
242
  	put_unaligned_le32(~crc, result);
19c00ddcc   Chris Mason   Btrfs: Add back m...
243
  }
d352ac681   Chris Mason   Btrfs: add and im...
244
245
246
247
  /*
   * compute the csum for a btree block, and either verify it or write it
   * into the csum field of the block.
   */
19c00ddcc   Chris Mason   Btrfs: Add back m...
248
249
250
  static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf,
  			   int verify)
  {
6c41761fc   David Sterba   btrfs: separate s...
251
  	u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
607d432da   Josef Bacik   Btrfs: add suppor...
252
  	char *result = NULL;
19c00ddcc   Chris Mason   Btrfs: Add back m...
253
254
255
  	unsigned long len;
  	unsigned long cur_len;
  	unsigned long offset = BTRFS_CSUM_SIZE;
19c00ddcc   Chris Mason   Btrfs: Add back m...
256
257
258
259
260
  	char *kaddr;
  	unsigned long map_start;
  	unsigned long map_len;
  	int err;
  	u32 crc = ~(u32)0;
607d432da   Josef Bacik   Btrfs: add suppor...
261
  	unsigned long inline_result;
19c00ddcc   Chris Mason   Btrfs: Add back m...
262
263
  
  	len = buf->len - offset;
d397712bc   Chris Mason   Btrfs: Fix checkp...
264
  	while (len > 0) {
19c00ddcc   Chris Mason   Btrfs: Add back m...
265
  		err = map_private_extent_buffer(buf, offset, 32,
a65917156   Chris Mason   Btrfs: stop using...
266
  					&kaddr, &map_start, &map_len);
d397712bc   Chris Mason   Btrfs: Fix checkp...
267
  		if (err)
19c00ddcc   Chris Mason   Btrfs: Add back m...
268
  			return 1;
19c00ddcc   Chris Mason   Btrfs: Add back m...
269
270
271
272
273
  		cur_len = min(len, map_len - (offset - map_start));
  		crc = btrfs_csum_data(root, kaddr + offset - map_start,
  				      crc, cur_len);
  		len -= cur_len;
  		offset += cur_len;
19c00ddcc   Chris Mason   Btrfs: Add back m...
274
  	}
607d432da   Josef Bacik   Btrfs: add suppor...
275
276
277
278
279
280
281
  	if (csum_size > sizeof(inline_result)) {
  		result = kzalloc(csum_size * sizeof(char), GFP_NOFS);
  		if (!result)
  			return 1;
  	} else {
  		result = (char *)&inline_result;
  	}
19c00ddcc   Chris Mason   Btrfs: Add back m...
282
283
284
  	btrfs_csum_final(crc, result);
  
  	if (verify) {
607d432da   Josef Bacik   Btrfs: add suppor...
285
  		if (memcmp_extent_buffer(buf, result, 0, csum_size)) {
e4204dedb   Chris Mason   Btrfs: Change tre...
286
287
  			u32 val;
  			u32 found = 0;
607d432da   Josef Bacik   Btrfs: add suppor...
288
  			memcpy(&found, result, csum_size);
e4204dedb   Chris Mason   Btrfs: Change tre...
289

607d432da   Josef Bacik   Btrfs: add suppor...
290
  			read_extent_buffer(buf, &val, 0, csum_size);
7a36ddec1   David Sterba   btrfs: use printk...
291
  			printk_ratelimited(KERN_INFO "btrfs: %s checksum verify "
193f284d4   Chris Mason   Btrfs: ratelimit ...
292
293
294
295
296
297
  				       "failed on %llu wanted %X found %X "
  				       "level %d
  ",
  				       root->fs_info->sb->s_id,
  				       (unsigned long long)buf->start, val, found,
  				       btrfs_header_level(buf));
607d432da   Josef Bacik   Btrfs: add suppor...
298
299
  			if (result != (char *)&inline_result)
  				kfree(result);
19c00ddcc   Chris Mason   Btrfs: Add back m...
300
301
302
  			return 1;
  		}
  	} else {
607d432da   Josef Bacik   Btrfs: add suppor...
303
  		write_extent_buffer(buf, result, 0, csum_size);
19c00ddcc   Chris Mason   Btrfs: Add back m...
304
  	}
607d432da   Josef Bacik   Btrfs: add suppor...
305
306
  	if (result != (char *)&inline_result)
  		kfree(result);
19c00ddcc   Chris Mason   Btrfs: Add back m...
307
308
  	return 0;
  }
d352ac681   Chris Mason   Btrfs: add and im...
309
310
311
312
313
314
  /*
   * we can't consider a given block up to date unless the transid of the
   * block matches the transid in the parent node's pointer.  This is how we
   * detect blocks that either didn't get written at all or got written
   * in the wrong place.
   */
1259ab75c   Chris Mason   Btrfs: Handle wri...
315
316
317
  static int verify_parent_transid(struct extent_io_tree *io_tree,
  				 struct extent_buffer *eb, u64 parent_transid)
  {
2ac55d41b   Josef Bacik   Btrfs: cache the ...
318
  	struct extent_state *cached_state = NULL;
1259ab75c   Chris Mason   Btrfs: Handle wri...
319
320
321
322
  	int ret;
  
  	if (!parent_transid || btrfs_header_generation(eb) == parent_transid)
  		return 0;
2ac55d41b   Josef Bacik   Btrfs: cache the ...
323
324
325
  	lock_extent_bits(io_tree, eb->start, eb->start + eb->len - 1,
  			 0, &cached_state, GFP_NOFS);
  	if (extent_buffer_uptodate(io_tree, eb, cached_state) &&
1259ab75c   Chris Mason   Btrfs: Handle wri...
326
327
328
329
  	    btrfs_header_generation(eb) == parent_transid) {
  		ret = 0;
  		goto out;
  	}
7a36ddec1   David Sterba   btrfs: use printk...
330
  	printk_ratelimited("parent transid verify failed on %llu wanted %llu "
193f284d4   Chris Mason   Btrfs: ratelimit ...
331
332
333
334
335
  		       "found %llu
  ",
  		       (unsigned long long)eb->start,
  		       (unsigned long long)parent_transid,
  		       (unsigned long long)btrfs_header_generation(eb));
1259ab75c   Chris Mason   Btrfs: Handle wri...
336
  	ret = 1;
2ac55d41b   Josef Bacik   Btrfs: cache the ...
337
  	clear_extent_buffer_uptodate(io_tree, eb, &cached_state);
33958dc6d   Chris Mason   Btrfs: Fix verify...
338
  out:
2ac55d41b   Josef Bacik   Btrfs: cache the ...
339
340
  	unlock_extent_cached(io_tree, eb->start, eb->start + eb->len - 1,
  			     &cached_state, GFP_NOFS);
1259ab75c   Chris Mason   Btrfs: Handle wri...
341
  	return ret;
1259ab75c   Chris Mason   Btrfs: Handle wri...
342
  }
d352ac681   Chris Mason   Btrfs: add and im...
343
344
345
346
  /*
   * helper to read a given tree block, doing retries as required when
   * the checksums don't match and we have alternate mirrors to try.
   */
f188591e9   Chris Mason   Btrfs: Retry meta...
347
348
  static int btree_read_extent_buffer_pages(struct btrfs_root *root,
  					  struct extent_buffer *eb,
ca7a79ad8   Chris Mason   Btrfs: Pass down ...
349
  					  u64 start, u64 parent_transid)
f188591e9   Chris Mason   Btrfs: Retry meta...
350
351
352
353
354
  {
  	struct extent_io_tree *io_tree;
  	int ret;
  	int num_copies = 0;
  	int mirror_num = 0;
a826d6dcb   Josef Bacik   Btrfs: check item...
355
  	clear_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags);
f188591e9   Chris Mason   Btrfs: Retry meta...
356
357
  	io_tree = &BTRFS_I(root->fs_info->btree_inode)->io_tree;
  	while (1) {
bb82ab88d   Arne Jansen   btrfs: add an ext...
358
359
  		ret = read_extent_buffer_pages(io_tree, eb, start,
  					       WAIT_COMPLETE,
f188591e9   Chris Mason   Btrfs: Retry meta...
360
  					       btree_get_extent, mirror_num);
1259ab75c   Chris Mason   Btrfs: Handle wri...
361
362
  		if (!ret &&
  		    !verify_parent_transid(io_tree, eb, parent_transid))
f188591e9   Chris Mason   Btrfs: Retry meta...
363
  			return ret;
d397712bc   Chris Mason   Btrfs: Fix checkp...
364

a826d6dcb   Josef Bacik   Btrfs: check item...
365
366
367
368
369
370
371
  		/*
  		 * This buffer's crc is fine, but its contents are corrupted, so
  		 * there is no reason to read the other copies, they won't be
  		 * any less wrong.
  		 */
  		if (test_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags))
  			return ret;
f188591e9   Chris Mason   Btrfs: Retry meta...
372
373
  		num_copies = btrfs_num_copies(&root->fs_info->mapping_tree,
  					      eb->start, eb->len);
4235298e4   Chris Mason   Btrfs: Drop some ...
374
  		if (num_copies == 1)
f188591e9   Chris Mason   Btrfs: Retry meta...
375
  			return ret;
4235298e4   Chris Mason   Btrfs: Drop some ...
376

f188591e9   Chris Mason   Btrfs: Retry meta...
377
  		mirror_num++;
4235298e4   Chris Mason   Btrfs: Drop some ...
378
  		if (mirror_num > num_copies)
f188591e9   Chris Mason   Btrfs: Retry meta...
379
  			return ret;
f188591e9   Chris Mason   Btrfs: Retry meta...
380
  	}
f188591e9   Chris Mason   Btrfs: Retry meta...
381
382
  	return -EIO;
  }
19c00ddcc   Chris Mason   Btrfs: Add back m...
383

d352ac681   Chris Mason   Btrfs: add and im...
384
  /*
d397712bc   Chris Mason   Btrfs: Fix checkp...
385
386
   * checksum a dirty tree block before IO.  This has extra checks to make sure
   * we only fill in the checksum field in the first page of a multi-page block
d352ac681   Chris Mason   Btrfs: add and im...
387
   */
d397712bc   Chris Mason   Btrfs: Fix checkp...
388

b2950863c   Christoph Hellwig   Btrfs: make thing...
389
  static int csum_dirty_buffer(struct btrfs_root *root, struct page *page)
19c00ddcc   Chris Mason   Btrfs: Add back m...
390
  {
d1310b2e0   Chris Mason   Btrfs: Split the ...
391
  	struct extent_io_tree *tree;
35ebb934b   Chris Mason   Btrfs: Fix PAGE_C...
392
  	u64 start = (u64)page->index << PAGE_CACHE_SHIFT;
19c00ddcc   Chris Mason   Btrfs: Add back m...
393
  	u64 found_start;
19c00ddcc   Chris Mason   Btrfs: Add back m...
394
395
  	unsigned long len;
  	struct extent_buffer *eb;
f188591e9   Chris Mason   Btrfs: Retry meta...
396
  	int ret;
d1310b2e0   Chris Mason   Btrfs: Split the ...
397
  	tree = &BTRFS_I(page->mapping->host)->io_tree;
19c00ddcc   Chris Mason   Btrfs: Add back m...
398

eb14ab8ed   Chris Mason   Btrfs: fix page->...
399
400
  	if (page->private == EXTENT_PAGE_PRIVATE) {
  		WARN_ON(1);
19c00ddcc   Chris Mason   Btrfs: Add back m...
401
  		goto out;
eb14ab8ed   Chris Mason   Btrfs: fix page->...
402
403
404
  	}
  	if (!page->private) {
  		WARN_ON(1);
19c00ddcc   Chris Mason   Btrfs: Add back m...
405
  		goto out;
eb14ab8ed   Chris Mason   Btrfs: fix page->...
406
  	}
19c00ddcc   Chris Mason   Btrfs: Add back m...
407
  	len = page->private >> 2;
d397712bc   Chris Mason   Btrfs: Fix checkp...
408
  	WARN_ON(len == 0);
ba1441926   David Sterba   btrfs: drop gfp p...
409
  	eb = alloc_extent_buffer(tree, start, len, page);
91ca338d7   Tsutomu Itoh   btrfs: check NULL...
410
411
412
413
  	if (eb == NULL) {
  		WARN_ON(1);
  		goto out;
  	}
ca7a79ad8   Chris Mason   Btrfs: Pass down ...
414
415
  	ret = btree_read_extent_buffer_pages(root, eb, start + PAGE_CACHE_SIZE,
  					     btrfs_header_generation(eb));
f188591e9   Chris Mason   Btrfs: Retry meta...
416
  	BUG_ON(ret);
784b4e29a   Chris Mason   Btrfs: add migrat...
417
  	WARN_ON(!btrfs_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN));
19c00ddcc   Chris Mason   Btrfs: Add back m...
418
419
  	found_start = btrfs_header_bytenr(eb);
  	if (found_start != start) {
55c69072d   Chris Mason   Btrfs: Fix extent...
420
421
422
423
  		WARN_ON(1);
  		goto err;
  	}
  	if (eb->first_page != page) {
55c69072d   Chris Mason   Btrfs: Fix extent...
424
425
426
427
  		WARN_ON(1);
  		goto err;
  	}
  	if (!PageUptodate(page)) {
55c69072d   Chris Mason   Btrfs: Fix extent...
428
429
  		WARN_ON(1);
  		goto err;
19c00ddcc   Chris Mason   Btrfs: Add back m...
430
  	}
19c00ddcc   Chris Mason   Btrfs: Add back m...
431
  	csum_tree_block(root, eb, 0);
55c69072d   Chris Mason   Btrfs: Fix extent...
432
  err:
19c00ddcc   Chris Mason   Btrfs: Add back m...
433
434
435
436
  	free_extent_buffer(eb);
  out:
  	return 0;
  }
2b82032c3   Yan Zheng   Btrfs: Seed devic...
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
  static int check_tree_block_fsid(struct btrfs_root *root,
  				 struct extent_buffer *eb)
  {
  	struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices;
  	u8 fsid[BTRFS_UUID_SIZE];
  	int ret = 1;
  
  	read_extent_buffer(eb, fsid, (unsigned long)btrfs_header_fsid(eb),
  			   BTRFS_FSID_SIZE);
  	while (fs_devices) {
  		if (!memcmp(fsid, fs_devices->fsid, BTRFS_FSID_SIZE)) {
  			ret = 0;
  			break;
  		}
  		fs_devices = fs_devices->seed;
  	}
  	return ret;
  }
a826d6dcb   Josef Bacik   Btrfs: check item...
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
  #define CORRUPT(reason, eb, root, slot)				\
  	printk(KERN_CRIT "btrfs: corrupt leaf, %s: block=%llu,"	\
  	       "root=%llu, slot=%d
  ", reason,			\
  	       (unsigned long long)btrfs_header_bytenr(eb),	\
  	       (unsigned long long)root->objectid, slot)
  
  static noinline int check_leaf(struct btrfs_root *root,
  			       struct extent_buffer *leaf)
  {
  	struct btrfs_key key;
  	struct btrfs_key leaf_key;
  	u32 nritems = btrfs_header_nritems(leaf);
  	int slot;
  
  	if (nritems == 0)
  		return 0;
  
  	/* Check the 0 item */
  	if (btrfs_item_offset_nr(leaf, 0) + btrfs_item_size_nr(leaf, 0) !=
  	    BTRFS_LEAF_DATA_SIZE(root)) {
  		CORRUPT("invalid item offset size pair", leaf, root, 0);
  		return -EIO;
  	}
  
  	/*
  	 * Check to make sure each items keys are in the correct order and their
  	 * offsets make sense.  We only have to loop through nritems-1 because
  	 * we check the current slot against the next slot, which verifies the
  	 * next slot's offset+size makes sense and that the current's slot
  	 * offset is correct.
  	 */
  	for (slot = 0; slot < nritems - 1; slot++) {
  		btrfs_item_key_to_cpu(leaf, &leaf_key, slot);
  		btrfs_item_key_to_cpu(leaf, &key, slot + 1);
  
  		/* Make sure the keys are in the right order */
  		if (btrfs_comp_cpu_keys(&leaf_key, &key) >= 0) {
  			CORRUPT("bad key order", leaf, root, slot);
  			return -EIO;
  		}
  
  		/*
  		 * Make sure the offset and ends are right, remember that the
  		 * item data starts at the end of the leaf and grows towards the
  		 * front.
  		 */
  		if (btrfs_item_offset_nr(leaf, slot) !=
  			btrfs_item_end_nr(leaf, slot + 1)) {
  			CORRUPT("slot offset bad", leaf, root, slot);
  			return -EIO;
  		}
  
  		/*
  		 * Check to make sure that we don't point outside of the leaf,
  		 * just incase all the items are consistent to eachother, but
  		 * all point outside of the leaf.
  		 */
  		if (btrfs_item_end_nr(leaf, slot) >
  		    BTRFS_LEAF_DATA_SIZE(root)) {
  			CORRUPT("slot end outside of leaf", leaf, root, slot);
  			return -EIO;
  		}
  	}
  
  	return 0;
  }
b2950863c   Christoph Hellwig   Btrfs: make thing...
522
  static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end,
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
523
524
525
526
527
528
529
530
  			       struct extent_state *state)
  {
  	struct extent_io_tree *tree;
  	u64 found_start;
  	int found_level;
  	unsigned long len;
  	struct extent_buffer *eb;
  	struct btrfs_root *root = BTRFS_I(page->mapping->host)->root;
f188591e9   Chris Mason   Btrfs: Retry meta...
531
  	int ret = 0;
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
532
533
534
535
536
537
  
  	tree = &BTRFS_I(page->mapping->host)->io_tree;
  	if (page->private == EXTENT_PAGE_PRIVATE)
  		goto out;
  	if (!page->private)
  		goto out;
d397712bc   Chris Mason   Btrfs: Fix checkp...
538

ce9adaa5a   Chris Mason   Btrfs: Do metadat...
539
  	len = page->private >> 2;
d397712bc   Chris Mason   Btrfs: Fix checkp...
540
  	WARN_ON(len == 0);
ba1441926   David Sterba   btrfs: drop gfp p...
541
  	eb = alloc_extent_buffer(tree, start, len, page);
91ca338d7   Tsutomu Itoh   btrfs: check NULL...
542
543
544
545
  	if (eb == NULL) {
  		ret = -EIO;
  		goto out;
  	}
f188591e9   Chris Mason   Btrfs: Retry meta...
546

ce9adaa5a   Chris Mason   Btrfs: Do metadat...
547
  	found_start = btrfs_header_bytenr(eb);
23a07867b   Chris Mason   Btrfs: Fix mismer...
548
  	if (found_start != start) {
7a36ddec1   David Sterba   btrfs: use printk...
549
  		printk_ratelimited(KERN_INFO "btrfs bad tree block start "
193f284d4   Chris Mason   Btrfs: ratelimit ...
550
551
552
553
  			       "%llu %llu
  ",
  			       (unsigned long long)found_start,
  			       (unsigned long long)eb->start);
f188591e9   Chris Mason   Btrfs: Retry meta...
554
  		ret = -EIO;
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
555
556
557
  		goto err;
  	}
  	if (eb->first_page != page) {
d397712bc   Chris Mason   Btrfs: Fix checkp...
558
559
560
  		printk(KERN_INFO "btrfs bad first page %lu %lu
  ",
  		       eb->first_page->index, page->index);
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
561
  		WARN_ON(1);
f188591e9   Chris Mason   Btrfs: Retry meta...
562
  		ret = -EIO;
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
563
564
  		goto err;
  	}
2b82032c3   Yan Zheng   Btrfs: Seed devic...
565
  	if (check_tree_block_fsid(root, eb)) {
7a36ddec1   David Sterba   btrfs: use printk...
566
567
  		printk_ratelimited(KERN_INFO "btrfs bad fsid on block %llu
  ",
193f284d4   Chris Mason   Btrfs: ratelimit ...
568
  			       (unsigned long long)eb->start);
1259ab75c   Chris Mason   Btrfs: Handle wri...
569
570
571
  		ret = -EIO;
  		goto err;
  	}
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
572
  	found_level = btrfs_header_level(eb);
85d4e4611   Chris Mason   Btrfs: make a loc...
573
574
  	btrfs_set_buffer_lockdep_class(btrfs_header_owner(eb),
  				       eb, found_level);
4008c04a0   Chris Mason   Btrfs: make a loc...
575

ce9adaa5a   Chris Mason   Btrfs: Do metadat...
576
  	ret = csum_tree_block(root, eb, 1);
a826d6dcb   Josef Bacik   Btrfs: check item...
577
  	if (ret) {
f188591e9   Chris Mason   Btrfs: Retry meta...
578
  		ret = -EIO;
a826d6dcb   Josef Bacik   Btrfs: check item...
579
580
581
582
583
584
585
586
587
588
589
590
  		goto err;
  	}
  
  	/*
  	 * If this is a leaf block and it is corrupt, set the corrupt bit so
  	 * that we don't try and read the other copies of this block, just
  	 * return -EIO.
  	 */
  	if (found_level == 0 && check_leaf(root, eb)) {
  		set_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags);
  		ret = -EIO;
  	}
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
591
592
593
  
  	end = min_t(u64, eb->len, PAGE_CACHE_SIZE);
  	end = eb->start + end - 1;
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
594
  err:
4bb31e928   Arne Jansen   btrfs: hooks for ...
595
596
597
598
  	if (test_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags)) {
  		clear_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags);
  		btree_readahead_hook(root, eb, eb->start, ret);
  	}
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
599
600
  	free_extent_buffer(eb);
  out:
f188591e9   Chris Mason   Btrfs: Retry meta...
601
  	return ret;
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
602
  }
4bb31e928   Arne Jansen   btrfs: hooks for ...
603
604
  static int btree_io_failed_hook(struct bio *failed_bio,
  			 struct page *page, u64 start, u64 end,
32240a913   Jan Schmidt   btrfs: mirror_num...
605
  			 int mirror_num, struct extent_state *state)
4bb31e928   Arne Jansen   btrfs: hooks for ...
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
  {
  	struct extent_io_tree *tree;
  	unsigned long len;
  	struct extent_buffer *eb;
  	struct btrfs_root *root = BTRFS_I(page->mapping->host)->root;
  
  	tree = &BTRFS_I(page->mapping->host)->io_tree;
  	if (page->private == EXTENT_PAGE_PRIVATE)
  		goto out;
  	if (!page->private)
  		goto out;
  
  	len = page->private >> 2;
  	WARN_ON(len == 0);
  
  	eb = alloc_extent_buffer(tree, start, len, page);
  	if (eb == NULL)
  		goto out;
  
  	if (test_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags)) {
  		clear_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags);
  		btree_readahead_hook(root, eb, eb->start, -EIO);
  	}
c674e04e1   Chris Mason   Btrfs: fix extent...
629
  	free_extent_buffer(eb);
4bb31e928   Arne Jansen   btrfs: hooks for ...
630
631
632
633
  
  out:
  	return -EIO;	/* we fixed nothing */
  }
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
634
  static void end_workqueue_bio(struct bio *bio, int err)
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
635
636
637
  {
  	struct end_io_wq *end_io_wq = bio->bi_private;
  	struct btrfs_fs_info *fs_info;
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
638

ce9adaa5a   Chris Mason   Btrfs: Do metadat...
639
  	fs_info = end_io_wq->info;
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
640
  	end_io_wq->error = err;
8b7128429   Chris Mason   Btrfs: Add async ...
641
642
  	end_io_wq->work.func = end_workqueue_fn;
  	end_io_wq->work.flags = 0;
d20f7043f   Chris Mason   Btrfs: move data ...
643

7b6d91dae   Christoph Hellwig   block: unify flag...
644
  	if (bio->bi_rw & REQ_WRITE) {
0cb59c995   Josef Bacik   Btrfs: write out ...
645
  		if (end_io_wq->metadata == 1)
cad321ad5   Chris Mason   Btrfs: shift all ...
646
647
  			btrfs_queue_worker(&fs_info->endio_meta_write_workers,
  					   &end_io_wq->work);
0cb59c995   Josef Bacik   Btrfs: write out ...
648
649
650
  		else if (end_io_wq->metadata == 2)
  			btrfs_queue_worker(&fs_info->endio_freespace_worker,
  					   &end_io_wq->work);
cad321ad5   Chris Mason   Btrfs: shift all ...
651
652
653
  		else
  			btrfs_queue_worker(&fs_info->endio_write_workers,
  					   &end_io_wq->work);
d20f7043f   Chris Mason   Btrfs: move data ...
654
655
656
657
658
659
660
661
  	} else {
  		if (end_io_wq->metadata)
  			btrfs_queue_worker(&fs_info->endio_meta_workers,
  					   &end_io_wq->work);
  		else
  			btrfs_queue_worker(&fs_info->endio_workers,
  					   &end_io_wq->work);
  	}
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
662
  }
0cb59c995   Josef Bacik   Btrfs: write out ...
663
664
665
666
667
668
669
  /*
   * For the metadata arg you want
   *
   * 0 - if data
   * 1 - if normal metadta
   * 2 - if writing to the free space cache area
   */
22c599485   Chris Mason   Btrfs: Handle dat...
670
671
  int btrfs_bio_wq_end_io(struct btrfs_fs_info *info, struct bio *bio,
  			int metadata)
0b86a832a   Chris Mason   Btrfs: Add suppor...
672
  {
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
673
  	struct end_io_wq *end_io_wq;
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
674
675
676
677
678
679
  	end_io_wq = kmalloc(sizeof(*end_io_wq), GFP_NOFS);
  	if (!end_io_wq)
  		return -ENOMEM;
  
  	end_io_wq->private = bio->bi_private;
  	end_io_wq->end_io = bio->bi_end_io;
22c599485   Chris Mason   Btrfs: Handle dat...
680
  	end_io_wq->info = info;
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
681
682
  	end_io_wq->error = 0;
  	end_io_wq->bio = bio;
22c599485   Chris Mason   Btrfs: Handle dat...
683
  	end_io_wq->metadata = metadata;
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
684
685
686
  
  	bio->bi_private = end_io_wq;
  	bio->bi_end_io = end_workqueue_bio;
22c599485   Chris Mason   Btrfs: Handle dat...
687
688
  	return 0;
  }
b64a2851b   Chris Mason   Btrfs: Wait for a...
689
  unsigned long btrfs_async_submit_limit(struct btrfs_fs_info *info)
0986fe9ea   Chris Mason   Btrfs: Count asyn...
690
  {
4854ddd0e   Chris Mason   Btrfs: Wait for k...
691
692
693
694
695
  	unsigned long limit = min_t(unsigned long,
  				    info->workers.max_workers,
  				    info->fs_devices->open_devices);
  	return 256 * limit;
  }
0986fe9ea   Chris Mason   Btrfs: Count asyn...
696

4a69a4100   Chris Mason   Btrfs: Add ordere...
697
698
  static void run_one_async_start(struct btrfs_work *work)
  {
4a69a4100   Chris Mason   Btrfs: Add ordere...
699
700
701
  	struct async_submit_bio *async;
  
  	async = container_of(work, struct  async_submit_bio, work);
4a69a4100   Chris Mason   Btrfs: Add ordere...
702
  	async->submit_bio_start(async->inode, async->rw, async->bio,
eaf25d933   Chris Mason   Btrfs: use async ...
703
704
  			       async->mirror_num, async->bio_flags,
  			       async->bio_offset);
4a69a4100   Chris Mason   Btrfs: Add ordere...
705
706
707
  }
  
  static void run_one_async_done(struct btrfs_work *work)
8b7128429   Chris Mason   Btrfs: Add async ...
708
709
710
  {
  	struct btrfs_fs_info *fs_info;
  	struct async_submit_bio *async;
4854ddd0e   Chris Mason   Btrfs: Wait for k...
711
  	int limit;
8b7128429   Chris Mason   Btrfs: Add async ...
712
713
714
  
  	async = container_of(work, struct  async_submit_bio, work);
  	fs_info = BTRFS_I(async->inode)->root->fs_info;
4854ddd0e   Chris Mason   Btrfs: Wait for k...
715

b64a2851b   Chris Mason   Btrfs: Wait for a...
716
  	limit = btrfs_async_submit_limit(fs_info);
4854ddd0e   Chris Mason   Btrfs: Wait for k...
717
  	limit = limit * 2 / 3;
8b7128429   Chris Mason   Btrfs: Add async ...
718
  	atomic_dec(&fs_info->nr_async_submits);
0986fe9ea   Chris Mason   Btrfs: Count asyn...
719

b64a2851b   Chris Mason   Btrfs: Wait for a...
720
721
  	if (atomic_read(&fs_info->nr_async_submits) < limit &&
  	    waitqueue_active(&fs_info->async_submit_wait))
4854ddd0e   Chris Mason   Btrfs: Wait for k...
722
  		wake_up(&fs_info->async_submit_wait);
4a69a4100   Chris Mason   Btrfs: Add ordere...
723
  	async->submit_bio_done(async->inode, async->rw, async->bio,
eaf25d933   Chris Mason   Btrfs: use async ...
724
725
  			       async->mirror_num, async->bio_flags,
  			       async->bio_offset);
4a69a4100   Chris Mason   Btrfs: Add ordere...
726
727
728
729
730
731
732
  }
  
  static void run_one_async_free(struct btrfs_work *work)
  {
  	struct async_submit_bio *async;
  
  	async = container_of(work, struct  async_submit_bio, work);
8b7128429   Chris Mason   Btrfs: Add async ...
733
734
  	kfree(async);
  }
44b8bd7ed   Chris Mason   Btrfs: Create a w...
735
736
  int btrfs_wq_submit_bio(struct btrfs_fs_info *fs_info, struct inode *inode,
  			int rw, struct bio *bio, int mirror_num,
c8b978188   Chris Mason   Btrfs: Add zlib c...
737
  			unsigned long bio_flags,
eaf25d933   Chris Mason   Btrfs: use async ...
738
  			u64 bio_offset,
4a69a4100   Chris Mason   Btrfs: Add ordere...
739
740
  			extent_submit_bio_hook_t *submit_bio_start,
  			extent_submit_bio_hook_t *submit_bio_done)
44b8bd7ed   Chris Mason   Btrfs: Create a w...
741
742
743
744
745
746
747
748
749
750
751
  {
  	struct async_submit_bio *async;
  
  	async = kmalloc(sizeof(*async), GFP_NOFS);
  	if (!async)
  		return -ENOMEM;
  
  	async->inode = inode;
  	async->rw = rw;
  	async->bio = bio;
  	async->mirror_num = mirror_num;
4a69a4100   Chris Mason   Btrfs: Add ordere...
752
753
754
755
756
757
  	async->submit_bio_start = submit_bio_start;
  	async->submit_bio_done = submit_bio_done;
  
  	async->work.func = run_one_async_start;
  	async->work.ordered_func = run_one_async_done;
  	async->work.ordered_free = run_one_async_free;
8b7128429   Chris Mason   Btrfs: Add async ...
758
  	async->work.flags = 0;
c8b978188   Chris Mason   Btrfs: Add zlib c...
759
  	async->bio_flags = bio_flags;
eaf25d933   Chris Mason   Btrfs: use async ...
760
  	async->bio_offset = bio_offset;
8c8bee1d7   Chris Mason   Btrfs: Wait for I...
761

cb03c743c   Chris Mason   Btrfs: Change the...
762
  	atomic_inc(&fs_info->nr_async_submits);
d313d7a31   Chris Mason   Btrfs: add a prio...
763

7b6d91dae   Christoph Hellwig   block: unify flag...
764
  	if (rw & REQ_SYNC)
d313d7a31   Chris Mason   Btrfs: add a prio...
765
  		btrfs_set_work_high_prio(&async->work);
8b7128429   Chris Mason   Btrfs: Add async ...
766
  	btrfs_queue_worker(&fs_info->workers, &async->work);
9473f16c7   Chris Mason   Btrfs: Throttle f...
767

d397712bc   Chris Mason   Btrfs: Fix checkp...
768
  	while (atomic_read(&fs_info->async_submit_draining) &&
771ed689d   Chris Mason   Btrfs: Optimize c...
769
770
771
772
  	      atomic_read(&fs_info->nr_async_submits)) {
  		wait_event(fs_info->async_submit_wait,
  			   (atomic_read(&fs_info->nr_async_submits) == 0));
  	}
44b8bd7ed   Chris Mason   Btrfs: Create a w...
773
774
  	return 0;
  }
ce3ed71a5   Chris Mason   Btrfs: Checksum t...
775
776
777
778
779
780
781
  static int btree_csum_one_bio(struct bio *bio)
  {
  	struct bio_vec *bvec = bio->bi_io_vec;
  	int bio_index = 0;
  	struct btrfs_root *root;
  
  	WARN_ON(bio->bi_vcnt <= 0);
d397712bc   Chris Mason   Btrfs: Fix checkp...
782
  	while (bio_index < bio->bi_vcnt) {
ce3ed71a5   Chris Mason   Btrfs: Checksum t...
783
784
785
786
787
788
789
  		root = BTRFS_I(bvec->bv_page->mapping->host)->root;
  		csum_dirty_buffer(root, bvec->bv_page);
  		bio_index++;
  		bvec++;
  	}
  	return 0;
  }
4a69a4100   Chris Mason   Btrfs: Add ordere...
790
791
  static int __btree_submit_bio_start(struct inode *inode, int rw,
  				    struct bio *bio, int mirror_num,
eaf25d933   Chris Mason   Btrfs: use async ...
792
793
  				    unsigned long bio_flags,
  				    u64 bio_offset)
22c599485   Chris Mason   Btrfs: Handle dat...
794
  {
8b7128429   Chris Mason   Btrfs: Add async ...
795
796
  	/*
  	 * when we're called for a write, we're already in the async
5443be45f   Chris Mason   Btrfs: Give all t...
797
  	 * submission context.  Just jump into btrfs_map_bio
8b7128429   Chris Mason   Btrfs: Add async ...
798
  	 */
4a69a4100   Chris Mason   Btrfs: Add ordere...
799
800
801
  	btree_csum_one_bio(bio);
  	return 0;
  }
22c599485   Chris Mason   Btrfs: Handle dat...
802

4a69a4100   Chris Mason   Btrfs: Add ordere...
803
  static int __btree_submit_bio_done(struct inode *inode, int rw, struct bio *bio,
eaf25d933   Chris Mason   Btrfs: use async ...
804
805
  				 int mirror_num, unsigned long bio_flags,
  				 u64 bio_offset)
4a69a4100   Chris Mason   Btrfs: Add ordere...
806
  {
8b7128429   Chris Mason   Btrfs: Add async ...
807
  	/*
4a69a4100   Chris Mason   Btrfs: Add ordere...
808
809
  	 * when we're called for a write, we're already in the async
  	 * submission context.  Just jump into btrfs_map_bio
8b7128429   Chris Mason   Btrfs: Add async ...
810
  	 */
8b7128429   Chris Mason   Btrfs: Add async ...
811
  	return btrfs_map_bio(BTRFS_I(inode)->root, rw, bio, mirror_num, 1);
0b86a832a   Chris Mason   Btrfs: Add suppor...
812
  }
44b8bd7ed   Chris Mason   Btrfs: Create a w...
813
  static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
eaf25d933   Chris Mason   Btrfs: use async ...
814
815
  				 int mirror_num, unsigned long bio_flags,
  				 u64 bio_offset)
44b8bd7ed   Chris Mason   Btrfs: Create a w...
816
  {
cad321ad5   Chris Mason   Btrfs: shift all ...
817
818
819
820
821
  	int ret;
  
  	ret = btrfs_bio_wq_end_io(BTRFS_I(inode)->root->fs_info,
  					  bio, 1);
  	BUG_ON(ret);
7b6d91dae   Christoph Hellwig   block: unify flag...
822
  	if (!(rw & REQ_WRITE)) {
4a69a4100   Chris Mason   Btrfs: Add ordere...
823
824
825
826
  		/*
  		 * called for a read, do the setup so that checksum validation
  		 * can happen in the async kernel threads
  		 */
4a69a4100   Chris Mason   Btrfs: Add ordere...
827
  		return btrfs_map_bio(BTRFS_I(inode)->root, rw, bio,
6f3577bdc   Chris Mason   Btrfs: Improve me...
828
  				     mirror_num, 0);
44b8bd7ed   Chris Mason   Btrfs: Create a w...
829
  	}
d313d7a31   Chris Mason   Btrfs: add a prio...
830

cad321ad5   Chris Mason   Btrfs: shift all ...
831
832
833
834
  	/*
  	 * kthread helpers are used to submit writes so that checksumming
  	 * can happen in parallel across all CPUs
  	 */
44b8bd7ed   Chris Mason   Btrfs: Create a w...
835
  	return btrfs_wq_submit_bio(BTRFS_I(inode)->root->fs_info,
c8b978188   Chris Mason   Btrfs: Add zlib c...
836
  				   inode, rw, bio, mirror_num, 0,
eaf25d933   Chris Mason   Btrfs: use async ...
837
  				   bio_offset,
4a69a4100   Chris Mason   Btrfs: Add ordere...
838
839
  				   __btree_submit_bio_start,
  				   __btree_submit_bio_done);
44b8bd7ed   Chris Mason   Btrfs: Create a w...
840
  }
3dd1462e8   Jan Beulich   Btrfs: fix compil...
841
  #ifdef CONFIG_MIGRATION
784b4e29a   Chris Mason   Btrfs: add migrat...
842
  static int btree_migratepage(struct address_space *mapping,
a6bc32b89   Mel Gorman   mm: compaction: i...
843
844
  			struct page *newpage, struct page *page,
  			enum migrate_mode mode)
784b4e29a   Chris Mason   Btrfs: add migrat...
845
846
847
848
849
850
851
852
853
854
855
856
857
858
  {
  	/*
  	 * we can't safely write a btree page from here,
  	 * we haven't done the locking hook
  	 */
  	if (PageDirty(page))
  		return -EAGAIN;
  	/*
  	 * Buffers may be managed in a filesystem specific way.
  	 * We must have no buffers or drop them.
  	 */
  	if (page_has_private(page) &&
  	    !try_to_release_page(page, GFP_KERNEL))
  		return -EAGAIN;
a6bc32b89   Mel Gorman   mm: compaction: i...
859
  	return migrate_page(mapping, newpage, page, mode);
784b4e29a   Chris Mason   Btrfs: add migrat...
860
  }
3dd1462e8   Jan Beulich   Btrfs: fix compil...
861
  #endif
784b4e29a   Chris Mason   Btrfs: add migrat...
862

0da5468f4   Chris Mason   Btrfs: Use writep...
863
864
  static int btree_writepage(struct page *page, struct writeback_control *wbc)
  {
d1310b2e0   Chris Mason   Btrfs: Split the ...
865
  	struct extent_io_tree *tree;
b9473439d   Chris Mason   Btrfs: leave btre...
866
867
868
  	struct btrfs_root *root = BTRFS_I(page->mapping->host)->root;
  	struct extent_buffer *eb;
  	int was_dirty;
d1310b2e0   Chris Mason   Btrfs: Split the ...
869
  	tree = &BTRFS_I(page->mapping->host)->io_tree;
b9473439d   Chris Mason   Btrfs: leave btre...
870
871
872
873
  	if (!(current->flags & PF_MEMALLOC)) {
  		return extent_write_full_page(tree, page,
  					      btree_get_extent, wbc);
  	}
5443be45f   Chris Mason   Btrfs: Give all t...
874

b9473439d   Chris Mason   Btrfs: leave btre...
875
  	redirty_page_for_writepage(wbc, page);
784b4e29a   Chris Mason   Btrfs: add migrat...
876
  	eb = btrfs_find_tree_block(root, page_offset(page), PAGE_CACHE_SIZE);
b9473439d   Chris Mason   Btrfs: leave btre...
877
878
879
880
881
882
883
  	WARN_ON(!eb);
  
  	was_dirty = test_and_set_bit(EXTENT_BUFFER_DIRTY, &eb->bflags);
  	if (!was_dirty) {
  		spin_lock(&root->fs_info->delalloc_lock);
  		root->fs_info->dirty_metadata_bytes += PAGE_CACHE_SIZE;
  		spin_unlock(&root->fs_info->delalloc_lock);
5443be45f   Chris Mason   Btrfs: Give all t...
884
  	}
b9473439d   Chris Mason   Btrfs: leave btre...
885
886
887
888
  	free_extent_buffer(eb);
  
  	unlock_page(page);
  	return 0;
5f39d397d   Chris Mason   Btrfs: Create ext...
889
  }
0da5468f4   Chris Mason   Btrfs: Use writep...
890
891
892
893
  
  static int btree_writepages(struct address_space *mapping,
  			    struct writeback_control *wbc)
  {
d1310b2e0   Chris Mason   Btrfs: Split the ...
894
895
  	struct extent_io_tree *tree;
  	tree = &BTRFS_I(mapping->host)->io_tree;
d8d5f3e16   Chris Mason   Btrfs: Add lowest...
896
  	if (wbc->sync_mode == WB_SYNC_NONE) {
b9473439d   Chris Mason   Btrfs: leave btre...
897
  		struct btrfs_root *root = BTRFS_I(mapping->host)->root;
793955bca   Chris Mason   Btrfs: Limit btre...
898
  		u64 num_dirty;
24ab9cd85   Chris Mason   Btrfs: Raise thre...
899
  		unsigned long thresh = 32 * 1024 * 1024;
448d640b6   Chris Mason   Btrfs: Fine tune ...
900
901
902
  
  		if (wbc->for_kupdate)
  			return 0;
b9473439d   Chris Mason   Btrfs: leave btre...
903
904
  		/* this is a bit racy, but that's ok */
  		num_dirty = root->fs_info->dirty_metadata_bytes;
d397712bc   Chris Mason   Btrfs: Fix checkp...
905
  		if (num_dirty < thresh)
793955bca   Chris Mason   Btrfs: Limit btre...
906
  			return 0;
793955bca   Chris Mason   Btrfs: Limit btre...
907
  	}
0da5468f4   Chris Mason   Btrfs: Use writep...
908
909
  	return extent_writepages(tree, mapping, btree_get_extent, wbc);
  }
b2950863c   Christoph Hellwig   Btrfs: make thing...
910
  static int btree_readpage(struct file *file, struct page *page)
5f39d397d   Chris Mason   Btrfs: Create ext...
911
  {
d1310b2e0   Chris Mason   Btrfs: Split the ...
912
913
  	struct extent_io_tree *tree;
  	tree = &BTRFS_I(page->mapping->host)->io_tree;
8ddc7d9cd   Jan Schmidt   btrfs: add mirror...
914
  	return extent_read_full_page(tree, page, btree_get_extent, 0);
5f39d397d   Chris Mason   Btrfs: Create ext...
915
  }
22b0ebda6   Chris Mason   Btrfs: hunting sl...
916

70dec8079   Chris Mason   Btrfs: extent_io ...
917
  static int btree_releasepage(struct page *page, gfp_t gfp_flags)
5f39d397d   Chris Mason   Btrfs: Create ext...
918
  {
d1310b2e0   Chris Mason   Btrfs: Split the ...
919
920
  	struct extent_io_tree *tree;
  	struct extent_map_tree *map;
5f39d397d   Chris Mason   Btrfs: Create ext...
921
  	int ret;
d98237b3e   Chris Mason   Btrfs: use a btre...
922

98509cfc5   Chris Mason   Btrfs: Fix releas...
923
  	if (PageWriteback(page) || PageDirty(page))
d397712bc   Chris Mason   Btrfs: Fix checkp...
924
  		return 0;
98509cfc5   Chris Mason   Btrfs: Fix releas...
925

d1310b2e0   Chris Mason   Btrfs: Split the ...
926
927
  	tree = &BTRFS_I(page->mapping->host)->io_tree;
  	map = &BTRFS_I(page->mapping->host)->extent_tree;
6af118ce5   Chris Mason   Btrfs: Index exte...
928

7b13b7b11   Chris Mason   Btrfs: Don't drop...
929
  	ret = try_release_extent_state(map, tree, page, gfp_flags);
d397712bc   Chris Mason   Btrfs: Fix checkp...
930
  	if (!ret)
6af118ce5   Chris Mason   Btrfs: Index exte...
931
  		return 0;
6af118ce5   Chris Mason   Btrfs: Index exte...
932
933
  
  	ret = try_release_extent_buffer(tree, page);
5f39d397d   Chris Mason   Btrfs: Create ext...
934
935
936
937
938
  	if (ret == 1) {
  		ClearPagePrivate(page);
  		set_page_private(page, 0);
  		page_cache_release(page);
  	}
6af118ce5   Chris Mason   Btrfs: Index exte...
939

d98237b3e   Chris Mason   Btrfs: use a btre...
940
941
  	return ret;
  }
5f39d397d   Chris Mason   Btrfs: Create ext...
942
  static void btree_invalidatepage(struct page *page, unsigned long offset)
d98237b3e   Chris Mason   Btrfs: use a btre...
943
  {
d1310b2e0   Chris Mason   Btrfs: Split the ...
944
945
  	struct extent_io_tree *tree;
  	tree = &BTRFS_I(page->mapping->host)->io_tree;
5f39d397d   Chris Mason   Btrfs: Create ext...
946
947
  	extent_invalidatepage(tree, page, offset);
  	btree_releasepage(page, GFP_NOFS);
9ad6b7bc2   Chris Mason   Force page->priva...
948
  	if (PagePrivate(page)) {
d397712bc   Chris Mason   Btrfs: Fix checkp...
949
950
951
  		printk(KERN_WARNING "btrfs warning page private not zero "
  		       "on page %llu
  ", (unsigned long long)page_offset(page));
9ad6b7bc2   Chris Mason   Force page->priva...
952
953
954
955
  		ClearPagePrivate(page);
  		set_page_private(page, 0);
  		page_cache_release(page);
  	}
d98237b3e   Chris Mason   Btrfs: use a btre...
956
  }
7f09410bb   Alexey Dobriyan   const: mark remai...
957
  static const struct address_space_operations btree_aops = {
d98237b3e   Chris Mason   Btrfs: use a btre...
958
959
  	.readpage	= btree_readpage,
  	.writepage	= btree_writepage,
0da5468f4   Chris Mason   Btrfs: Use writep...
960
  	.writepages	= btree_writepages,
5f39d397d   Chris Mason   Btrfs: Create ext...
961
962
  	.releasepage	= btree_releasepage,
  	.invalidatepage = btree_invalidatepage,
5a92bc88c   Chris Mason   Btrfs: don't use ...
963
  #ifdef CONFIG_MIGRATION
784b4e29a   Chris Mason   Btrfs: add migrat...
964
  	.migratepage	= btree_migratepage,
5a92bc88c   Chris Mason   Btrfs: don't use ...
965
  #endif
d98237b3e   Chris Mason   Btrfs: use a btre...
966
  };
ca7a79ad8   Chris Mason   Btrfs: Pass down ...
967
968
  int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize,
  			 u64 parent_transid)
090d18753   Chris Mason   Btrfs: directory ...
969
  {
5f39d397d   Chris Mason   Btrfs: Create ext...
970
971
  	struct extent_buffer *buf = NULL;
  	struct inode *btree_inode = root->fs_info->btree_inode;
de428b63b   Chris Mason   Btrfs: allocator ...
972
  	int ret = 0;
090d18753   Chris Mason   Btrfs: directory ...
973

db94535db   Chris Mason   Btrfs: Allow tree...
974
  	buf = btrfs_find_create_tree_block(root, bytenr, blocksize);
5f39d397d   Chris Mason   Btrfs: Create ext...
975
  	if (!buf)
090d18753   Chris Mason   Btrfs: directory ...
976
  		return 0;
d1310b2e0   Chris Mason   Btrfs: Split the ...
977
  	read_extent_buffer_pages(&BTRFS_I(btree_inode)->io_tree,
bb82ab88d   Arne Jansen   btrfs: add an ext...
978
  				 buf, 0, WAIT_NONE, btree_get_extent, 0);
5f39d397d   Chris Mason   Btrfs: Create ext...
979
  	free_extent_buffer(buf);
de428b63b   Chris Mason   Btrfs: allocator ...
980
  	return ret;
090d18753   Chris Mason   Btrfs: directory ...
981
  }
ab0fff030   Arne Jansen   btrfs: add READAH...
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
  int reada_tree_block_flagged(struct btrfs_root *root, u64 bytenr, u32 blocksize,
  			 int mirror_num, struct extent_buffer **eb)
  {
  	struct extent_buffer *buf = NULL;
  	struct inode *btree_inode = root->fs_info->btree_inode;
  	struct extent_io_tree *io_tree = &BTRFS_I(btree_inode)->io_tree;
  	int ret;
  
  	buf = btrfs_find_create_tree_block(root, bytenr, blocksize);
  	if (!buf)
  		return 0;
  
  	set_bit(EXTENT_BUFFER_READAHEAD, &buf->bflags);
  
  	ret = read_extent_buffer_pages(io_tree, buf, 0, WAIT_PAGE_LOCK,
  				       btree_get_extent, mirror_num);
  	if (ret) {
  		free_extent_buffer(buf);
  		return ret;
  	}
  
  	if (test_bit(EXTENT_BUFFER_CORRUPT, &buf->bflags)) {
  		free_extent_buffer(buf);
  		return -EIO;
  	} else if (extent_buffer_uptodate(io_tree, buf, NULL)) {
  		*eb = buf;
  	} else {
  		free_extent_buffer(buf);
  	}
  	return 0;
  }
0999df54f   Chris Mason   Btrfs: Verify che...
1013
1014
1015
1016
1017
1018
  struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root,
  					    u64 bytenr, u32 blocksize)
  {
  	struct inode *btree_inode = root->fs_info->btree_inode;
  	struct extent_buffer *eb;
  	eb = find_extent_buffer(&BTRFS_I(btree_inode)->io_tree,
f09d1f60e   David Sterba   btrfs: drop gfp p...
1019
  				bytenr, blocksize);
0999df54f   Chris Mason   Btrfs: Verify che...
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
  	return eb;
  }
  
  struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root,
  						 u64 bytenr, u32 blocksize)
  {
  	struct inode *btree_inode = root->fs_info->btree_inode;
  	struct extent_buffer *eb;
  
  	eb = alloc_extent_buffer(&BTRFS_I(btree_inode)->io_tree,
ba1441926   David Sterba   btrfs: drop gfp p...
1030
  				 bytenr, blocksize, NULL);
0999df54f   Chris Mason   Btrfs: Verify che...
1031
1032
  	return eb;
  }
e02119d5a   Chris Mason   Btrfs: Add a writ...
1033
1034
  int btrfs_write_tree_block(struct extent_buffer *buf)
  {
8aa38c31b   Christoph Hellwig   Btrfs: remove dup...
1035
1036
  	return filemap_fdatawrite_range(buf->first_page->mapping, buf->start,
  					buf->start + buf->len - 1);
e02119d5a   Chris Mason   Btrfs: Add a writ...
1037
1038
1039
1040
  }
  
  int btrfs_wait_tree_block_writeback(struct extent_buffer *buf)
  {
8aa38c31b   Christoph Hellwig   Btrfs: remove dup...
1041
1042
  	return filemap_fdatawait_range(buf->first_page->mapping,
  				       buf->start, buf->start + buf->len - 1);
e02119d5a   Chris Mason   Btrfs: Add a writ...
1043
  }
0999df54f   Chris Mason   Btrfs: Verify che...
1044
  struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr,
ca7a79ad8   Chris Mason   Btrfs: Pass down ...
1045
  				      u32 blocksize, u64 parent_transid)
0999df54f   Chris Mason   Btrfs: Verify che...
1046
1047
  {
  	struct extent_buffer *buf = NULL;
0999df54f   Chris Mason   Btrfs: Verify che...
1048
  	int ret;
0999df54f   Chris Mason   Btrfs: Verify che...
1049
1050
1051
  	buf = btrfs_find_create_tree_block(root, bytenr, blocksize);
  	if (!buf)
  		return NULL;
0999df54f   Chris Mason   Btrfs: Verify che...
1052

ca7a79ad8   Chris Mason   Btrfs: Pass down ...
1053
  	ret = btree_read_extent_buffer_pages(root, buf, 0, parent_transid);
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
1054

d397712bc   Chris Mason   Btrfs: Fix checkp...
1055
  	if (ret == 0)
b4ce94de9   Chris Mason   Btrfs: Change btr...
1056
  		set_bit(EXTENT_BUFFER_UPTODATE, &buf->bflags);
5f39d397d   Chris Mason   Btrfs: Create ext...
1057
  	return buf;
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
1058

eb60ceac0   Chris Mason   Btrfs: Add backin...
1059
  }
e089f05c1   Chris Mason   Btrfs: transactio...
1060
  int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
5f39d397d   Chris Mason   Btrfs: Create ext...
1061
  		     struct extent_buffer *buf)
ed2ff2cba   Chris Mason   Btrfs: pretend pa...
1062
  {
5f39d397d   Chris Mason   Btrfs: Create ext...
1063
  	struct inode *btree_inode = root->fs_info->btree_inode;
55c69072d   Chris Mason   Btrfs: Fix extent...
1064
  	if (btrfs_header_generation(buf) ==
925baeddc   Chris Mason   Btrfs: Start btre...
1065
  	    root->fs_info->running_transaction->transid) {
b9447ef80   Chris Mason   Btrfs: fix spinlo...
1066
  		btrfs_assert_tree_locked(buf);
b4ce94de9   Chris Mason   Btrfs: Change btr...
1067

b9473439d   Chris Mason   Btrfs: leave btre...
1068
1069
1070
1071
1072
1073
1074
1075
  		if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &buf->bflags)) {
  			spin_lock(&root->fs_info->delalloc_lock);
  			if (root->fs_info->dirty_metadata_bytes >= buf->len)
  				root->fs_info->dirty_metadata_bytes -= buf->len;
  			else
  				WARN_ON(1);
  			spin_unlock(&root->fs_info->delalloc_lock);
  		}
b4ce94de9   Chris Mason   Btrfs: Change btr...
1076

b9473439d   Chris Mason   Btrfs: leave btre...
1077
1078
  		/* ugh, clear_extent_buffer_dirty needs to lock the page */
  		btrfs_set_lock_blocking(buf);
d1310b2e0   Chris Mason   Btrfs: Split the ...
1079
  		clear_extent_buffer_dirty(&BTRFS_I(btree_inode)->io_tree,
55c69072d   Chris Mason   Btrfs: Fix extent...
1080
  					  buf);
925baeddc   Chris Mason   Btrfs: Start btre...
1081
  	}
5f39d397d   Chris Mason   Btrfs: Create ext...
1082
1083
  	return 0;
  }
db94535db   Chris Mason   Btrfs: Allow tree...
1084
  static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
87ee04eb0   Chris Mason   Btrfs: Add simple...
1085
  			u32 stripesize, struct btrfs_root *root,
9f5fae2fe   Chris Mason   Btrfs: Add inode ...
1086
  			struct btrfs_fs_info *fs_info,
e20d96d64   Chris Mason   Mountable btrfs, ...
1087
  			u64 objectid)
d97e63b69   Chris Mason   Btrfs: early exte...
1088
  {
cfaa72952   Chris Mason   Btrfs: extent fixes
1089
  	root->node = NULL;
a28ec1977   Chris Mason   Btrfs: Fixup refe...
1090
  	root->commit_root = NULL;
db94535db   Chris Mason   Btrfs: Allow tree...
1091
1092
1093
  	root->sectorsize = sectorsize;
  	root->nodesize = nodesize;
  	root->leafsize = leafsize;
87ee04eb0   Chris Mason   Btrfs: Add simple...
1094
  	root->stripesize = stripesize;
123abc88c   Chris Mason   Btrfs: variable b...
1095
  	root->ref_cows = 0;
0b86a832a   Chris Mason   Btrfs: Add suppor...
1096
  	root->track_dirty = 0;
c71bf099a   Yan, Zheng   Btrfs: Avoid orph...
1097
  	root->in_radix = 0;
d68fc57b7   Yan, Zheng   Btrfs: Metadata r...
1098
1099
  	root->orphan_item_inserted = 0;
  	root->orphan_cleanup_state = 0;
0b86a832a   Chris Mason   Btrfs: Add suppor...
1100

9f5fae2fe   Chris Mason   Btrfs: Add inode ...
1101
  	root->fs_info = fs_info;
0f7d52f44   Chris Mason   Btrfs: groundwork...
1102
1103
  	root->objectid = objectid;
  	root->last_trans = 0;
13a8a7c8c   Yan, Zheng   Btrfs: do not reu...
1104
  	root->highest_objectid = 0;
58176a960   Josef Bacik   Btrfs: Add per-ro...
1105
  	root->name = NULL;
6bef4d317   Eric Paris   Btrfs: use RB_ROO...
1106
  	root->inode_tree = RB_ROOT;
16cdcec73   Miao Xie   btrfs: implement ...
1107
  	INIT_RADIX_TREE(&root->delayed_nodes_tree, GFP_ATOMIC);
f0486c68e   Yan, Zheng   Btrfs: Introduce ...
1108
  	root->block_rsv = NULL;
d68fc57b7   Yan, Zheng   Btrfs: Metadata r...
1109
  	root->orphan_block_rsv = NULL;
0b86a832a   Chris Mason   Btrfs: Add suppor...
1110
1111
  
  	INIT_LIST_HEAD(&root->dirty_list);
7b1287662   Josef Bacik   Btrfs: Create orp...
1112
  	INIT_LIST_HEAD(&root->orphan_list);
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
1113
  	INIT_LIST_HEAD(&root->root_list);
d68fc57b7   Yan, Zheng   Btrfs: Metadata r...
1114
  	spin_lock_init(&root->orphan_lock);
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
1115
  	spin_lock_init(&root->inode_lock);
f0486c68e   Yan, Zheng   Btrfs: Introduce ...
1116
  	spin_lock_init(&root->accounting_lock);
a21350115   Chris Mason   Btrfs: Replace th...
1117
  	mutex_init(&root->objectid_mutex);
e02119d5a   Chris Mason   Btrfs: Add a writ...
1118
  	mutex_init(&root->log_mutex);
7237f1833   Yan Zheng   Btrfs: fix tree l...
1119
1120
1121
1122
1123
1124
1125
1126
  	init_waitqueue_head(&root->log_writer_wait);
  	init_waitqueue_head(&root->log_commit_wait[0]);
  	init_waitqueue_head(&root->log_commit_wait[1]);
  	atomic_set(&root->log_commit[0], 0);
  	atomic_set(&root->log_commit[1], 0);
  	atomic_set(&root->log_writers, 0);
  	root->log_batch = 0;
  	root->log_transid = 0;
257c62e1b   Chris Mason   Btrfs: avoid tree...
1127
  	root->last_log_commit = 0;
d0c803c40   Chris Mason   Btrfs: Record dir...
1128
  	extent_io_tree_init(&root->dirty_log_pages,
f993c883a   David Sterba   btrfs: drop unuse...
1129
  			     fs_info->btree_inode->i_mapping);
017e5369e   Chris Mason   Btrfs: Leaf refer...
1130

3768f3689   Chris Mason   Btrfs: Change the...
1131
1132
  	memset(&root->root_key, 0, sizeof(root->root_key));
  	memset(&root->root_item, 0, sizeof(root->root_item));
6702ed490   Chris Mason   Btrfs: Add run ti...
1133
  	memset(&root->defrag_progress, 0, sizeof(root->defrag_progress));
58176a960   Josef Bacik   Btrfs: Add per-ro...
1134
  	memset(&root->root_kobj, 0, sizeof(root->root_kobj));
3f157a2fd   Chris Mason   Btrfs: Online btr...
1135
  	root->defrag_trans_start = fs_info->generation;
58176a960   Josef Bacik   Btrfs: Add per-ro...
1136
  	init_completion(&root->kobj_unregister);
6702ed490   Chris Mason   Btrfs: Add run ti...
1137
  	root->defrag_running = 0;
4d7756730   Chris Mason   Btrfs: add owner ...
1138
  	root->root_key.objectid = objectid;
0ee5dc676   Al Viro   btrfs: kill magic...
1139
  	root->anon_dev = 0;
3768f3689   Chris Mason   Btrfs: Change the...
1140
1141
  	return 0;
  }
db94535db   Chris Mason   Btrfs: Allow tree...
1142
  static int find_and_setup_root(struct btrfs_root *tree_root,
9f5fae2fe   Chris Mason   Btrfs: Add inode ...
1143
1144
  			       struct btrfs_fs_info *fs_info,
  			       u64 objectid,
e20d96d64   Chris Mason   Mountable btrfs, ...
1145
  			       struct btrfs_root *root)
3768f3689   Chris Mason   Btrfs: Change the...
1146
1147
  {
  	int ret;
db94535db   Chris Mason   Btrfs: Allow tree...
1148
  	u32 blocksize;
84234f3a1   Yan Zheng   Btrfs: Add root t...
1149
  	u64 generation;
3768f3689   Chris Mason   Btrfs: Change the...
1150

db94535db   Chris Mason   Btrfs: Allow tree...
1151
  	__setup_root(tree_root->nodesize, tree_root->leafsize,
87ee04eb0   Chris Mason   Btrfs: Add simple...
1152
1153
  		     tree_root->sectorsize, tree_root->stripesize,
  		     root, fs_info, objectid);
3768f3689   Chris Mason   Btrfs: Change the...
1154
1155
  	ret = btrfs_find_last_root(tree_root, objectid,
  				   &root->root_item, &root->root_key);
4df27c4d5   Yan, Zheng   Btrfs: change how...
1156
1157
  	if (ret > 0)
  		return -ENOENT;
3768f3689   Chris Mason   Btrfs: Change the...
1158
  	BUG_ON(ret);
84234f3a1   Yan Zheng   Btrfs: Add root t...
1159
  	generation = btrfs_root_generation(&root->root_item);
db94535db   Chris Mason   Btrfs: Allow tree...
1160
  	blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item));
af31f5e5b   Chris Mason   Btrfs: add a log ...
1161
  	root->commit_root = NULL;
db94535db   Chris Mason   Btrfs: Allow tree...
1162
  	root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item),
84234f3a1   Yan Zheng   Btrfs: Add root t...
1163
  				     blocksize, generation);
68433b73b   Chris Mason   Btrfs: EIO when w...
1164
1165
  	if (!root->node || !btrfs_buffer_uptodate(root->node, generation)) {
  		free_extent_buffer(root->node);
af31f5e5b   Chris Mason   Btrfs: add a log ...
1166
  		root->node = NULL;
68433b73b   Chris Mason   Btrfs: EIO when w...
1167
1168
  		return -EIO;
  	}
4df27c4d5   Yan, Zheng   Btrfs: change how...
1169
  	root->commit_root = btrfs_root_node(root);
d97e63b69   Chris Mason   Btrfs: early exte...
1170
1171
  	return 0;
  }
7237f1833   Yan Zheng   Btrfs: fix tree l...
1172
1173
  static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans,
  					 struct btrfs_fs_info *fs_info)
0f7d52f44   Chris Mason   Btrfs: groundwork...
1174
1175
1176
  {
  	struct btrfs_root *root;
  	struct btrfs_root *tree_root = fs_info->tree_root;
7237f1833   Yan Zheng   Btrfs: fix tree l...
1177
  	struct extent_buffer *leaf;
e02119d5a   Chris Mason   Btrfs: Add a writ...
1178
1179
1180
  
  	root = kzalloc(sizeof(*root), GFP_NOFS);
  	if (!root)
7237f1833   Yan Zheng   Btrfs: fix tree l...
1181
  		return ERR_PTR(-ENOMEM);
e02119d5a   Chris Mason   Btrfs: Add a writ...
1182
1183
1184
1185
1186
1187
1188
1189
  
  	__setup_root(tree_root->nodesize, tree_root->leafsize,
  		     tree_root->sectorsize, tree_root->stripesize,
  		     root, fs_info, BTRFS_TREE_LOG_OBJECTID);
  
  	root->root_key.objectid = BTRFS_TREE_LOG_OBJECTID;
  	root->root_key.type = BTRFS_ROOT_ITEM_KEY;
  	root->root_key.offset = BTRFS_TREE_LOG_OBJECTID;
7237f1833   Yan Zheng   Btrfs: fix tree l...
1190
1191
1192
1193
1194
1195
  	/*
  	 * log trees do not get reference counted because they go away
  	 * before a real commit is actually done.  They do store pointers
  	 * to file data extents, and those reference counts still get
  	 * updated (along with back refs to the log tree).
  	 */
e02119d5a   Chris Mason   Btrfs: Add a writ...
1196
  	root->ref_cows = 0;
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
1197
1198
  	leaf = btrfs_alloc_free_block(trans, root, root->leafsize, 0,
  				      BTRFS_TREE_LOG_OBJECTID, NULL, 0, 0, 0);
7237f1833   Yan Zheng   Btrfs: fix tree l...
1199
1200
1201
1202
  	if (IS_ERR(leaf)) {
  		kfree(root);
  		return ERR_CAST(leaf);
  	}
e02119d5a   Chris Mason   Btrfs: Add a writ...
1203

5d4f98a28   Yan Zheng   Btrfs: Mixed back...
1204
1205
1206
1207
1208
  	memset_extent_buffer(leaf, 0, 0, sizeof(struct btrfs_header));
  	btrfs_set_header_bytenr(leaf, leaf->start);
  	btrfs_set_header_generation(leaf, trans->transid);
  	btrfs_set_header_backref_rev(leaf, BTRFS_MIXED_BACKREF_REV);
  	btrfs_set_header_owner(leaf, BTRFS_TREE_LOG_OBJECTID);
7237f1833   Yan Zheng   Btrfs: fix tree l...
1209
  	root->node = leaf;
e02119d5a   Chris Mason   Btrfs: Add a writ...
1210
1211
1212
1213
1214
1215
  
  	write_extent_buffer(root->node, root->fs_info->fsid,
  			    (unsigned long)btrfs_header_fsid(root->node),
  			    BTRFS_FSID_SIZE);
  	btrfs_mark_buffer_dirty(root->node);
  	btrfs_tree_unlock(root->node);
7237f1833   Yan Zheng   Btrfs: fix tree l...
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
  	return root;
  }
  
  int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans,
  			     struct btrfs_fs_info *fs_info)
  {
  	struct btrfs_root *log_root;
  
  	log_root = alloc_log_tree(trans, fs_info);
  	if (IS_ERR(log_root))
  		return PTR_ERR(log_root);
  	WARN_ON(fs_info->log_root_tree);
  	fs_info->log_root_tree = log_root;
  	return 0;
  }
  
  int btrfs_add_log_tree(struct btrfs_trans_handle *trans,
  		       struct btrfs_root *root)
  {
  	struct btrfs_root *log_root;
  	struct btrfs_inode_item *inode_item;
  
  	log_root = alloc_log_tree(trans, root->fs_info);
  	if (IS_ERR(log_root))
  		return PTR_ERR(log_root);
  
  	log_root->last_trans = trans->transid;
  	log_root->root_key.offset = root->root_key.objectid;
  
  	inode_item = &log_root->root_item.inode;
  	inode_item->generation = cpu_to_le64(1);
  	inode_item->size = cpu_to_le64(3);
  	inode_item->nlink = cpu_to_le32(1);
  	inode_item->nbytes = cpu_to_le64(root->leafsize);
  	inode_item->mode = cpu_to_le32(S_IFDIR | 0755);
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
1251
  	btrfs_set_root_node(&log_root->root_item, log_root->node);
7237f1833   Yan Zheng   Btrfs: fix tree l...
1252
1253
1254
1255
  
  	WARN_ON(root->log_root);
  	root->log_root = log_root;
  	root->log_transid = 0;
257c62e1b   Chris Mason   Btrfs: avoid tree...
1256
  	root->last_log_commit = 0;
e02119d5a   Chris Mason   Btrfs: Add a writ...
1257
1258
1259
1260
1261
1262
1263
1264
  	return 0;
  }
  
  struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root,
  					       struct btrfs_key *location)
  {
  	struct btrfs_root *root;
  	struct btrfs_fs_info *fs_info = tree_root->fs_info;
0f7d52f44   Chris Mason   Btrfs: groundwork...
1265
  	struct btrfs_path *path;
5f39d397d   Chris Mason   Btrfs: Create ext...
1266
  	struct extent_buffer *l;
84234f3a1   Yan Zheng   Btrfs: Add root t...
1267
  	u64 generation;
db94535db   Chris Mason   Btrfs: Allow tree...
1268
  	u32 blocksize;
0f7d52f44   Chris Mason   Btrfs: groundwork...
1269
  	int ret = 0;
5eda7b5e9   Chris Mason   Btrfs: Add the ab...
1270
  	root = kzalloc(sizeof(*root), GFP_NOFS);
0cf6c6201   Chris Mason   Btrfs: remove dev...
1271
  	if (!root)
0f7d52f44   Chris Mason   Btrfs: groundwork...
1272
  		return ERR_PTR(-ENOMEM);
0f7d52f44   Chris Mason   Btrfs: groundwork...
1273
  	if (location->offset == (u64)-1) {
db94535db   Chris Mason   Btrfs: Allow tree...
1274
  		ret = find_and_setup_root(tree_root, fs_info,
0f7d52f44   Chris Mason   Btrfs: groundwork...
1275
1276
  					  location->objectid, root);
  		if (ret) {
0f7d52f44   Chris Mason   Btrfs: groundwork...
1277
1278
1279
  			kfree(root);
  			return ERR_PTR(ret);
  		}
13a8a7c8c   Yan, Zheng   Btrfs: do not reu...
1280
  		goto out;
0f7d52f44   Chris Mason   Btrfs: groundwork...
1281
  	}
db94535db   Chris Mason   Btrfs: Allow tree...
1282
  	__setup_root(tree_root->nodesize, tree_root->leafsize,
87ee04eb0   Chris Mason   Btrfs: Add simple...
1283
1284
  		     tree_root->sectorsize, tree_root->stripesize,
  		     root, fs_info, location->objectid);
0f7d52f44   Chris Mason   Btrfs: groundwork...
1285
1286
  
  	path = btrfs_alloc_path();
db5b493ac   Tsutomu Itoh   Btrfs: cleanup so...
1287
1288
1289
1290
  	if (!path) {
  		kfree(root);
  		return ERR_PTR(-ENOMEM);
  	}
0f7d52f44   Chris Mason   Btrfs: groundwork...
1291
  	ret = btrfs_search_slot(NULL, tree_root, location, path, 0, 0);
13a8a7c8c   Yan, Zheng   Btrfs: do not reu...
1292
1293
1294
1295
1296
1297
  	if (ret == 0) {
  		l = path->nodes[0];
  		read_extent_buffer(l, &root->root_item,
  				btrfs_item_ptr_offset(l, path->slots[0]),
  				sizeof(root->root_item));
  		memcpy(&root->root_key, location, sizeof(*location));
0f7d52f44   Chris Mason   Btrfs: groundwork...
1298
  	}
0f7d52f44   Chris Mason   Btrfs: groundwork...
1299
1300
  	btrfs_free_path(path);
  	if (ret) {
5e540f771   Tsutomu Itoh   btrfs: Fix memory...
1301
  		kfree(root);
13a8a7c8c   Yan, Zheng   Btrfs: do not reu...
1302
1303
  		if (ret > 0)
  			ret = -ENOENT;
0f7d52f44   Chris Mason   Btrfs: groundwork...
1304
1305
  		return ERR_PTR(ret);
  	}
13a8a7c8c   Yan, Zheng   Btrfs: do not reu...
1306

84234f3a1   Yan Zheng   Btrfs: Add root t...
1307
  	generation = btrfs_root_generation(&root->root_item);
db94535db   Chris Mason   Btrfs: Allow tree...
1308
1309
  	blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item));
  	root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item),
84234f3a1   Yan Zheng   Btrfs: Add root t...
1310
  				     blocksize, generation);
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
1311
  	root->commit_root = btrfs_root_node(root);
0f7d52f44   Chris Mason   Btrfs: groundwork...
1312
  	BUG_ON(!root->node);
13a8a7c8c   Yan, Zheng   Btrfs: do not reu...
1313
  out:
08fe4db17   Li Zefan   Btrfs: Fix uninit...
1314
  	if (location->objectid != BTRFS_TREE_LOG_OBJECTID) {
e02119d5a   Chris Mason   Btrfs: Add a writ...
1315
  		root->ref_cows = 1;
08fe4db17   Li Zefan   Btrfs: Fix uninit...
1316
1317
  		btrfs_check_and_init_root_item(&root->root_item);
  	}
13a8a7c8c   Yan, Zheng   Btrfs: do not reu...
1318

5eda7b5e9   Chris Mason   Btrfs: Add the ab...
1319
1320
  	return root;
  }
edbd8d4ef   Chris Mason   Btrfs: Support fo...
1321
1322
  struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info,
  					      struct btrfs_key *location)
5eda7b5e9   Chris Mason   Btrfs: Add the ab...
1323
1324
1325
  {
  	struct btrfs_root *root;
  	int ret;
edbd8d4ef   Chris Mason   Btrfs: Support fo...
1326
1327
1328
1329
  	if (location->objectid == BTRFS_ROOT_TREE_OBJECTID)
  		return fs_info->tree_root;
  	if (location->objectid == BTRFS_EXTENT_TREE_OBJECTID)
  		return fs_info->extent_root;
8f18cf133   Chris Mason   Btrfs: Make the r...
1330
1331
1332
1333
  	if (location->objectid == BTRFS_CHUNK_TREE_OBJECTID)
  		return fs_info->chunk_root;
  	if (location->objectid == BTRFS_DEV_TREE_OBJECTID)
  		return fs_info->dev_root;
0403e47ee   Yan Zheng   Btrfs: Add checki...
1334
1335
  	if (location->objectid == BTRFS_CSUM_TREE_OBJECTID)
  		return fs_info->csum_root;
4df27c4d5   Yan, Zheng   Btrfs: change how...
1336
1337
  again:
  	spin_lock(&fs_info->fs_roots_radix_lock);
5eda7b5e9   Chris Mason   Btrfs: Add the ab...
1338
1339
  	root = radix_tree_lookup(&fs_info->fs_roots_radix,
  				 (unsigned long)location->objectid);
4df27c4d5   Yan, Zheng   Btrfs: change how...
1340
  	spin_unlock(&fs_info->fs_roots_radix_lock);
5eda7b5e9   Chris Mason   Btrfs: Add the ab...
1341
1342
  	if (root)
  		return root;
e02119d5a   Chris Mason   Btrfs: Add a writ...
1343
  	root = btrfs_read_fs_root_no_radix(fs_info->tree_root, location);
5eda7b5e9   Chris Mason   Btrfs: Add the ab...
1344
1345
  	if (IS_ERR(root))
  		return root;
3394e1607   Chris Mason   Btrfs: Give each ...
1346

581bb0509   Li Zefan   Btrfs: Cache free...
1347
  	root->free_ino_ctl = kzalloc(sizeof(*root->free_ino_ctl), GFP_NOFS);
581bb0509   Li Zefan   Btrfs: Cache free...
1348
1349
  	root->free_ino_pinned = kzalloc(sizeof(*root->free_ino_pinned),
  					GFP_NOFS);
35a30d7ce   David Sterba   btrfs: fix uninit...
1350
1351
  	if (!root->free_ino_pinned || !root->free_ino_ctl) {
  		ret = -ENOMEM;
581bb0509   Li Zefan   Btrfs: Cache free...
1352
  		goto fail;
35a30d7ce   David Sterba   btrfs: fix uninit...
1353
  	}
581bb0509   Li Zefan   Btrfs: Cache free...
1354
1355
1356
1357
1358
  
  	btrfs_init_free_ino_ctl(root);
  	mutex_init(&root->fs_commit_mutex);
  	spin_lock_init(&root->cache_lock);
  	init_waitqueue_head(&root->cache_wait);
0ee5dc676   Al Viro   btrfs: kill magic...
1359
  	ret = get_anon_bdev(&root->anon_dev);
ac08aedfa   Chris Mason   Btrfs: check the ...
1360
1361
  	if (ret)
  		goto fail;
3394e1607   Chris Mason   Btrfs: Give each ...
1362

d68fc57b7   Yan, Zheng   Btrfs: Metadata r...
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
  	if (btrfs_root_refs(&root->root_item) == 0) {
  		ret = -ENOENT;
  		goto fail;
  	}
  
  	ret = btrfs_find_orphan_item(fs_info->tree_root, location->objectid);
  	if (ret < 0)
  		goto fail;
  	if (ret == 0)
  		root->orphan_item_inserted = 1;
4df27c4d5   Yan, Zheng   Btrfs: change how...
1373
1374
1375
1376
1377
  	ret = radix_tree_preload(GFP_NOFS & ~__GFP_HIGHMEM);
  	if (ret)
  		goto fail;
  
  	spin_lock(&fs_info->fs_roots_radix_lock);
2619ba1f0   Chris Mason   Btrfs: subvolumes
1378
1379
  	ret = radix_tree_insert(&fs_info->fs_roots_radix,
  				(unsigned long)root->root_key.objectid,
0f7d52f44   Chris Mason   Btrfs: groundwork...
1380
  				root);
d68fc57b7   Yan, Zheng   Btrfs: Metadata r...
1381
  	if (ret == 0)
4df27c4d5   Yan, Zheng   Btrfs: change how...
1382
  		root->in_radix = 1;
d68fc57b7   Yan, Zheng   Btrfs: Metadata r...
1383

4df27c4d5   Yan, Zheng   Btrfs: change how...
1384
1385
  	spin_unlock(&fs_info->fs_roots_radix_lock);
  	radix_tree_preload_end();
0f7d52f44   Chris Mason   Btrfs: groundwork...
1386
  	if (ret) {
4df27c4d5   Yan, Zheng   Btrfs: change how...
1387
1388
1389
1390
1391
  		if (ret == -EEXIST) {
  			free_fs_root(root);
  			goto again;
  		}
  		goto fail;
0f7d52f44   Chris Mason   Btrfs: groundwork...
1392
  	}
4df27c4d5   Yan, Zheng   Btrfs: change how...
1393
1394
1395
1396
  
  	ret = btrfs_find_dead_roots(fs_info->tree_root,
  				    root->root_key.objectid);
  	WARN_ON(ret);
edbd8d4ef   Chris Mason   Btrfs: Support fo...
1397
  	return root;
4df27c4d5   Yan, Zheng   Btrfs: change how...
1398
1399
1400
  fail:
  	free_fs_root(root);
  	return ERR_PTR(ret);
edbd8d4ef   Chris Mason   Btrfs: Support fo...
1401
  }
041600881   Chris Mason   Create a btrfs ba...
1402
1403
1404
1405
  static int btrfs_congested_fn(void *congested_data, int bdi_bits)
  {
  	struct btrfs_fs_info *info = (struct btrfs_fs_info *)congested_data;
  	int ret = 0;
041600881   Chris Mason   Create a btrfs ba...
1406
1407
  	struct btrfs_device *device;
  	struct backing_dev_info *bdi;
b7967db75   Chris Mason   Btrfs: remove #if...
1408

1f78160ce   Xiao Guangrong   Btrfs: using rcu ...
1409
1410
  	rcu_read_lock();
  	list_for_each_entry_rcu(device, &info->fs_devices->devices, dev_list) {
dfe250206   Chris Mason   Btrfs: Add mount ...
1411
1412
  		if (!device->bdev)
  			continue;
041600881   Chris Mason   Create a btrfs ba...
1413
1414
1415
1416
1417
1418
  		bdi = blk_get_backing_dev_info(device->bdev);
  		if (bdi && bdi_congested(bdi, bdi_bits)) {
  			ret = 1;
  			break;
  		}
  	}
1f78160ce   Xiao Guangrong   Btrfs: using rcu ...
1419
  	rcu_read_unlock();
041600881   Chris Mason   Create a btrfs ba...
1420
1421
  	return ret;
  }
38b669880   Chris Mason   Deal with page ==...
1422
  /*
ad081f143   Jens Axboe   btrfs: properly r...
1423
1424
1425
   * If this fails, caller must call bdi_destroy() to get rid of the
   * bdi again.
   */
041600881   Chris Mason   Create a btrfs ba...
1426
1427
  static int setup_bdi(struct btrfs_fs_info *info, struct backing_dev_info *bdi)
  {
ad081f143   Jens Axboe   btrfs: properly r...
1428
1429
1430
  	int err;
  
  	bdi->capabilities = BDI_CAP_MAP_COPY;
e6d086d83   Jens Axboe   btrfs: convert to...
1431
  	err = bdi_setup_and_register(bdi, "btrfs", BDI_CAP_MAP_COPY);
ad081f143   Jens Axboe   btrfs: properly r...
1432
1433
  	if (err)
  		return err;
4575c9cce   Chris Mason   Btrfs: Scale the ...
1434
  	bdi->ra_pages	= default_backing_dev_info.ra_pages;
041600881   Chris Mason   Create a btrfs ba...
1435
1436
1437
1438
  	bdi->congested_fn	= btrfs_congested_fn;
  	bdi->congested_data	= info;
  	return 0;
  }
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
1439
1440
1441
1442
1443
1444
1445
  static int bio_ready_for_csum(struct bio *bio)
  {
  	u64 length = 0;
  	u64 buf_len = 0;
  	u64 start = 0;
  	struct page *page;
  	struct extent_io_tree *io_tree = NULL;
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
  	struct bio_vec *bvec;
  	int i;
  	int ret;
  
  	bio_for_each_segment(bvec, bio, i) {
  		page = bvec->bv_page;
  		if (page->private == EXTENT_PAGE_PRIVATE) {
  			length += bvec->bv_len;
  			continue;
  		}
  		if (!page->private) {
  			length += bvec->bv_len;
  			continue;
  		}
  		length = bvec->bv_len;
  		buf_len = page->private >> 2;
  		start = page_offset(page) + bvec->bv_offset;
  		io_tree = &BTRFS_I(page->mapping->host)->io_tree;
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
1464
1465
1466
1467
1468
1469
1470
  	}
  	/* are we fully contained in this bio? */
  	if (buf_len <= length)
  		return 1;
  
  	ret = extent_range_uptodate(io_tree, start + length,
  				    start + buf_len - 1);
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
1471
1472
  	return ret;
  }
8b7128429   Chris Mason   Btrfs: Add async ...
1473
1474
1475
1476
1477
  /*
   * called by the kthread helper functions to finally call the bio end_io
   * functions.  This is where read checksum verification actually happens
   */
  static void end_workqueue_fn(struct btrfs_work *work)
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
1478
  {
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
1479
  	struct bio *bio;
8b7128429   Chris Mason   Btrfs: Add async ...
1480
1481
  	struct end_io_wq *end_io_wq;
  	struct btrfs_fs_info *fs_info;
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
1482
  	int error;
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
1483

8b7128429   Chris Mason   Btrfs: Add async ...
1484
1485
1486
  	end_io_wq = container_of(work, struct end_io_wq, work);
  	bio = end_io_wq->bio;
  	fs_info = end_io_wq->info;
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
1487

cad321ad5   Chris Mason   Btrfs: shift all ...
1488
  	/* metadata bio reads are special because the whole tree block must
8b7128429   Chris Mason   Btrfs: Add async ...
1489
1490
1491
1492
  	 * be checksummed at once.  This makes sure the entire block is in
  	 * ram and up to date before trying to verify things.  For
  	 * blocksize <= pagesize, it is basically a noop
  	 */
7b6d91dae   Christoph Hellwig   block: unify flag...
1493
  	if (!(bio->bi_rw & REQ_WRITE) && end_io_wq->metadata &&
cad321ad5   Chris Mason   Btrfs: shift all ...
1494
  	    !bio_ready_for_csum(bio)) {
d20f7043f   Chris Mason   Btrfs: move data ...
1495
  		btrfs_queue_worker(&fs_info->endio_meta_workers,
8b7128429   Chris Mason   Btrfs: Add async ...
1496
1497
1498
1499
1500
1501
1502
  				   &end_io_wq->work);
  		return;
  	}
  	error = end_io_wq->error;
  	bio->bi_private = end_io_wq->private;
  	bio->bi_end_io = end_io_wq->end_io;
  	kfree(end_io_wq);
8b7128429   Chris Mason   Btrfs: Add async ...
1503
  	bio_endio(bio, error);
44b8bd7ed   Chris Mason   Btrfs: Create a w...
1504
  }
a74a4b97b   Chris Mason   Btrfs: Replace th...
1505
1506
1507
1508
1509
  static int cleaner_kthread(void *arg)
  {
  	struct btrfs_root *root = arg;
  
  	do {
a74a4b97b   Chris Mason   Btrfs: Replace th...
1510
  		vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE);
76dda93c6   Yan, Zheng   Btrfs: add snapsh...
1511
1512
1513
  
  		if (!(root->fs_info->sb->s_flags & MS_RDONLY) &&
  		    mutex_trylock(&root->fs_info->cleaner_mutex)) {
24bbcf044   Yan, Zheng   Btrfs: Add delaye...
1514
  			btrfs_run_delayed_iputs(root);
76dda93c6   Yan, Zheng   Btrfs: add snapsh...
1515
1516
  			btrfs_clean_old_snapshots(root);
  			mutex_unlock(&root->fs_info->cleaner_mutex);
4cb5300bc   Chris Mason   Btrfs: add mount ...
1517
  			btrfs_run_defrag_inodes(root->fs_info);
76dda93c6   Yan, Zheng   Btrfs: add snapsh...
1518
  		}
a74a4b97b   Chris Mason   Btrfs: Replace th...
1519

a0acae0e8   Tejun Heo   freezer: unexport...
1520
  		if (!try_to_freeze()) {
a74a4b97b   Chris Mason   Btrfs: Replace th...
1521
  			set_current_state(TASK_INTERRUPTIBLE);
8929ecfa5   Yan, Zheng   Btrfs: Introduce ...
1522
1523
  			if (!kthread_should_stop())
  				schedule();
a74a4b97b   Chris Mason   Btrfs: Replace th...
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
  			__set_current_state(TASK_RUNNING);
  		}
  	} while (!kthread_should_stop());
  	return 0;
  }
  
  static int transaction_kthread(void *arg)
  {
  	struct btrfs_root *root = arg;
  	struct btrfs_trans_handle *trans;
  	struct btrfs_transaction *cur;
8929ecfa5   Yan, Zheng   Btrfs: Introduce ...
1535
  	u64 transid;
a74a4b97b   Chris Mason   Btrfs: Replace th...
1536
1537
1538
1539
1540
  	unsigned long now;
  	unsigned long delay;
  	int ret;
  
  	do {
a74a4b97b   Chris Mason   Btrfs: Replace th...
1541
1542
1543
  		delay = HZ * 30;
  		vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE);
  		mutex_lock(&root->fs_info->transaction_kthread_mutex);
a4abeea41   Josef Bacik   Btrfs: kill trans...
1544
  		spin_lock(&root->fs_info->trans_lock);
a74a4b97b   Chris Mason   Btrfs: Replace th...
1545
1546
  		cur = root->fs_info->running_transaction;
  		if (!cur) {
a4abeea41   Josef Bacik   Btrfs: kill trans...
1547
  			spin_unlock(&root->fs_info->trans_lock);
a74a4b97b   Chris Mason   Btrfs: Replace th...
1548
1549
  			goto sleep;
  		}
31153d812   Yan Zheng   Btrfs: Add a leaf...
1550

a74a4b97b   Chris Mason   Btrfs: Replace th...
1551
  		now = get_seconds();
8929ecfa5   Yan, Zheng   Btrfs: Introduce ...
1552
1553
  		if (!cur->blocked &&
  		    (now < cur->start_time || now - cur->start_time < 30)) {
a4abeea41   Josef Bacik   Btrfs: kill trans...
1554
  			spin_unlock(&root->fs_info->trans_lock);
a74a4b97b   Chris Mason   Btrfs: Replace th...
1555
1556
1557
  			delay = HZ * 5;
  			goto sleep;
  		}
8929ecfa5   Yan, Zheng   Btrfs: Introduce ...
1558
  		transid = cur->transid;
a4abeea41   Josef Bacik   Btrfs: kill trans...
1559
  		spin_unlock(&root->fs_info->trans_lock);
56bec294d   Chris Mason   Btrfs: do extent ...
1560

7a7eaa40a   Josef Bacik   Btrfs: take away ...
1561
  		trans = btrfs_join_transaction(root);
3612b4959   Tsutomu Itoh   btrfs: fix return...
1562
  		BUG_ON(IS_ERR(trans));
8929ecfa5   Yan, Zheng   Btrfs: Introduce ...
1563
1564
1565
1566
1567
1568
  		if (transid == trans->transid) {
  			ret = btrfs_commit_transaction(trans, root);
  			BUG_ON(ret);
  		} else {
  			btrfs_end_transaction(trans, root);
  		}
a74a4b97b   Chris Mason   Btrfs: Replace th...
1569
1570
1571
  sleep:
  		wake_up_process(root->fs_info->cleaner_kthread);
  		mutex_unlock(&root->fs_info->transaction_kthread_mutex);
a0acae0e8   Tejun Heo   freezer: unexport...
1572
  		if (!try_to_freeze()) {
a74a4b97b   Chris Mason   Btrfs: Replace th...
1573
  			set_current_state(TASK_INTERRUPTIBLE);
8929ecfa5   Yan, Zheng   Btrfs: Introduce ...
1574
1575
1576
  			if (!kthread_should_stop() &&
  			    !btrfs_transaction_blocked(root->fs_info))
  				schedule_timeout(delay);
a74a4b97b   Chris Mason   Btrfs: Replace th...
1577
1578
1579
1580
1581
  			__set_current_state(TASK_RUNNING);
  		}
  	} while (!kthread_should_stop());
  	return 0;
  }
af31f5e5b   Chris Mason   Btrfs: add a log ...
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
  /*
   * this will find the highest generation in the array of
   * root backups.  The index of the highest array is returned,
   * or -1 if we can't find anything.
   *
   * We check to make sure the array is valid by comparing the
   * generation of the latest  root in the array with the generation
   * in the super block.  If they don't match we pitch it.
   */
  static int find_newest_super_backup(struct btrfs_fs_info *info, u64 newest_gen)
  {
  	u64 cur;
  	int newest_index = -1;
  	struct btrfs_root_backup *root_backup;
  	int i;
  
  	for (i = 0; i < BTRFS_NUM_BACKUP_ROOTS; i++) {
  		root_backup = info->super_copy->super_roots + i;
  		cur = btrfs_backup_tree_root_gen(root_backup);
  		if (cur == newest_gen)
  			newest_index = i;
  	}
  
  	/* check to see if we actually wrapped around */
  	if (newest_index == BTRFS_NUM_BACKUP_ROOTS - 1) {
  		root_backup = info->super_copy->super_roots;
  		cur = btrfs_backup_tree_root_gen(root_backup);
  		if (cur == newest_gen)
  			newest_index = 0;
  	}
  	return newest_index;
  }
  
  
  /*
   * find the oldest backup so we know where to store new entries
   * in the backup array.  This will set the backup_root_index
   * field in the fs_info struct
   */
  static void find_oldest_super_backup(struct btrfs_fs_info *info,
  				     u64 newest_gen)
  {
  	int newest_index = -1;
  
  	newest_index = find_newest_super_backup(info, newest_gen);
  	/* if there was garbage in there, just move along */
  	if (newest_index == -1) {
  		info->backup_root_index = 0;
  	} else {
  		info->backup_root_index = (newest_index + 1) % BTRFS_NUM_BACKUP_ROOTS;
  	}
  }
  
  /*
   * copy all the root pointers into the super backup array.
   * this will bump the backup pointer by one when it is
   * done
   */
  static void backup_super_roots(struct btrfs_fs_info *info)
  {
  	int next_backup;
  	struct btrfs_root_backup *root_backup;
  	int last_backup;
  
  	next_backup = info->backup_root_index;
  	last_backup = (next_backup + BTRFS_NUM_BACKUP_ROOTS - 1) %
  		BTRFS_NUM_BACKUP_ROOTS;
  
  	/*
  	 * just overwrite the last backup if we're at the same generation
  	 * this happens only at umount
  	 */
  	root_backup = info->super_for_commit->super_roots + last_backup;
  	if (btrfs_backup_tree_root_gen(root_backup) ==
  	    btrfs_header_generation(info->tree_root->node))
  		next_backup = last_backup;
  
  	root_backup = info->super_for_commit->super_roots + next_backup;
  
  	/*
  	 * make sure all of our padding and empty slots get zero filled
  	 * regardless of which ones we use today
  	 */
  	memset(root_backup, 0, sizeof(*root_backup));
  
  	info->backup_root_index = (next_backup + 1) % BTRFS_NUM_BACKUP_ROOTS;
  
  	btrfs_set_backup_tree_root(root_backup, info->tree_root->node->start);
  	btrfs_set_backup_tree_root_gen(root_backup,
  			       btrfs_header_generation(info->tree_root->node));
  
  	btrfs_set_backup_tree_root_level(root_backup,
  			       btrfs_header_level(info->tree_root->node));
  
  	btrfs_set_backup_chunk_root(root_backup, info->chunk_root->node->start);
  	btrfs_set_backup_chunk_root_gen(root_backup,
  			       btrfs_header_generation(info->chunk_root->node));
  	btrfs_set_backup_chunk_root_level(root_backup,
  			       btrfs_header_level(info->chunk_root->node));
  
  	btrfs_set_backup_extent_root(root_backup, info->extent_root->node->start);
  	btrfs_set_backup_extent_root_gen(root_backup,
  			       btrfs_header_generation(info->extent_root->node));
  	btrfs_set_backup_extent_root_level(root_backup,
  			       btrfs_header_level(info->extent_root->node));
7c7e82a77   Chris Mason   Btrfs: check for ...
1687
1688
1689
1690
1691
1692
1693
1694
  	/*
  	 * we might commit during log recovery, which happens before we set
  	 * the fs_root.  Make sure it is valid before we fill it in.
  	 */
  	if (info->fs_root && info->fs_root->node) {
  		btrfs_set_backup_fs_root(root_backup,
  					 info->fs_root->node->start);
  		btrfs_set_backup_fs_root_gen(root_backup,
af31f5e5b   Chris Mason   Btrfs: add a log ...
1695
  			       btrfs_header_generation(info->fs_root->node));
7c7e82a77   Chris Mason   Btrfs: check for ...
1696
  		btrfs_set_backup_fs_root_level(root_backup,
af31f5e5b   Chris Mason   Btrfs: add a log ...
1697
  			       btrfs_header_level(info->fs_root->node));
7c7e82a77   Chris Mason   Btrfs: check for ...
1698
  	}
af31f5e5b   Chris Mason   Btrfs: add a log ...
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
  
  	btrfs_set_backup_dev_root(root_backup, info->dev_root->node->start);
  	btrfs_set_backup_dev_root_gen(root_backup,
  			       btrfs_header_generation(info->dev_root->node));
  	btrfs_set_backup_dev_root_level(root_backup,
  				       btrfs_header_level(info->dev_root->node));
  
  	btrfs_set_backup_csum_root(root_backup, info->csum_root->node->start);
  	btrfs_set_backup_csum_root_gen(root_backup,
  			       btrfs_header_generation(info->csum_root->node));
  	btrfs_set_backup_csum_root_level(root_backup,
  			       btrfs_header_level(info->csum_root->node));
  
  	btrfs_set_backup_total_bytes(root_backup,
  			     btrfs_super_total_bytes(info->super_copy));
  	btrfs_set_backup_bytes_used(root_backup,
  			     btrfs_super_bytes_used(info->super_copy));
  	btrfs_set_backup_num_devices(root_backup,
  			     btrfs_super_num_devices(info->super_copy));
  
  	/*
  	 * if we don't copy this out to the super_copy, it won't get remembered
  	 * for the next commit
  	 */
  	memcpy(&info->super_copy->super_roots,
  	       &info->super_for_commit->super_roots,
  	       sizeof(*root_backup) * BTRFS_NUM_BACKUP_ROOTS);
  }
  
  /*
   * this copies info out of the root backup array and back into
   * the in-memory super block.  It is meant to help iterate through
   * the array, so you send it the number of backups you've already
   * tried and the last backup index you used.
   *
   * this returns -1 when it has tried all the backups
   */
  static noinline int next_root_backup(struct btrfs_fs_info *info,
  				     struct btrfs_super_block *super,
  				     int *num_backups_tried, int *backup_index)
  {
  	struct btrfs_root_backup *root_backup;
  	int newest = *backup_index;
  
  	if (*num_backups_tried == 0) {
  		u64 gen = btrfs_super_generation(super);
  
  		newest = find_newest_super_backup(info, gen);
  		if (newest == -1)
  			return -1;
  
  		*backup_index = newest;
  		*num_backups_tried = 1;
  	} else if (*num_backups_tried == BTRFS_NUM_BACKUP_ROOTS) {
  		/* we've tried all the backups, all done */
  		return -1;
  	} else {
  		/* jump to the next oldest backup */
  		newest = (*backup_index + BTRFS_NUM_BACKUP_ROOTS - 1) %
  			BTRFS_NUM_BACKUP_ROOTS;
  		*backup_index = newest;
  		*num_backups_tried += 1;
  	}
  	root_backup = super->super_roots + newest;
  
  	btrfs_set_super_generation(super,
  				   btrfs_backup_tree_root_gen(root_backup));
  	btrfs_set_super_root(super, btrfs_backup_tree_root(root_backup));
  	btrfs_set_super_root_level(super,
  				   btrfs_backup_tree_root_level(root_backup));
  	btrfs_set_super_bytes_used(super, btrfs_backup_bytes_used(root_backup));
  
  	/*
  	 * fixme: the total bytes and num_devices need to match or we should
  	 * need a fsck
  	 */
  	btrfs_set_super_total_bytes(super, btrfs_backup_total_bytes(root_backup));
  	btrfs_set_super_num_devices(super, btrfs_backup_num_devices(root_backup));
  	return 0;
  }
  
  /* helper to cleanup tree roots */
  static void free_root_pointers(struct btrfs_fs_info *info, int chunk_root)
  {
  	free_extent_buffer(info->tree_root->node);
  	free_extent_buffer(info->tree_root->commit_root);
  	free_extent_buffer(info->dev_root->node);
  	free_extent_buffer(info->dev_root->commit_root);
  	free_extent_buffer(info->extent_root->node);
  	free_extent_buffer(info->extent_root->commit_root);
  	free_extent_buffer(info->csum_root->node);
  	free_extent_buffer(info->csum_root->commit_root);
  
  	info->tree_root->node = NULL;
  	info->tree_root->commit_root = NULL;
  	info->dev_root->node = NULL;
  	info->dev_root->commit_root = NULL;
  	info->extent_root->node = NULL;
  	info->extent_root->commit_root = NULL;
  	info->csum_root->node = NULL;
  	info->csum_root->commit_root = NULL;
  
  	if (chunk_root) {
  		free_extent_buffer(info->chunk_root->node);
  		free_extent_buffer(info->chunk_root->commit_root);
  		info->chunk_root->node = NULL;
  		info->chunk_root->commit_root = NULL;
  	}
  }
8a4b83cc8   Chris Mason   Btrfs: Add suppor...
1808
  struct btrfs_root *open_ctree(struct super_block *sb,
dfe250206   Chris Mason   Btrfs: Add mount ...
1809
1810
  			      struct btrfs_fs_devices *fs_devices,
  			      char *options)
eb60ceac0   Chris Mason   Btrfs: Add backin...
1811
  {
db94535db   Chris Mason   Btrfs: Allow tree...
1812
1813
1814
1815
  	u32 sectorsize;
  	u32 nodesize;
  	u32 leafsize;
  	u32 blocksize;
87ee04eb0   Chris Mason   Btrfs: Add simple...
1816
  	u32 stripesize;
84234f3a1   Yan Zheng   Btrfs: Add root t...
1817
  	u64 generation;
f2b636e80   Josef Bacik   Btrfs: add suppor...
1818
  	u64 features;
3de4586c5   Chris Mason   Btrfs: Allow subv...
1819
  	struct btrfs_key location;
a061fc8da   Chris Mason   Btrfs: Add suppor...
1820
  	struct buffer_head *bh;
4d34b2789   Ilya Dryomov   Btrfs: avoid null...
1821
  	struct btrfs_super_block *disk_super;
450ba0ea0   Josef Bacik   Btrfs: setup blan...
1822
  	struct btrfs_root *tree_root = btrfs_sb(sb);
4d34b2789   Ilya Dryomov   Btrfs: avoid null...
1823
1824
1825
1826
1827
  	struct btrfs_fs_info *fs_info = tree_root->fs_info;
  	struct btrfs_root *extent_root;
  	struct btrfs_root *csum_root;
  	struct btrfs_root *chunk_root;
  	struct btrfs_root *dev_root;
e02119d5a   Chris Mason   Btrfs: Add a writ...
1828
  	struct btrfs_root *log_tree_root;
eb60ceac0   Chris Mason   Btrfs: Add backin...
1829
  	int ret;
e58ca0203   Yan   Fix btrfs_fill_su...
1830
  	int err = -EINVAL;
af31f5e5b   Chris Mason   Btrfs: add a log ...
1831
1832
  	int num_backups_tried = 0;
  	int backup_index = 0;
4543df7ec   Chris Mason   Btrfs: Add a moun...
1833

4d34b2789   Ilya Dryomov   Btrfs: avoid null...
1834
1835
1836
1837
1838
1839
1840
1841
  	extent_root = fs_info->extent_root =
  		kzalloc(sizeof(struct btrfs_root), GFP_NOFS);
  	csum_root = fs_info->csum_root =
  		kzalloc(sizeof(struct btrfs_root), GFP_NOFS);
  	chunk_root = fs_info->chunk_root =
  		kzalloc(sizeof(struct btrfs_root), GFP_NOFS);
  	dev_root = fs_info->dev_root =
  		kzalloc(sizeof(struct btrfs_root), GFP_NOFS);
8790d502e   Chris Mason   Btrfs: Add suppor...
1842

4d34b2789   Ilya Dryomov   Btrfs: avoid null...
1843
  	if (!extent_root || !csum_root || !chunk_root || !dev_root) {
39279cc3d   Chris Mason   Btrfs: split up s...
1844
1845
1846
  		err = -ENOMEM;
  		goto fail;
  	}
76dda93c6   Yan, Zheng   Btrfs: add snapsh...
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
  
  	ret = init_srcu_struct(&fs_info->subvol_srcu);
  	if (ret) {
  		err = ret;
  		goto fail;
  	}
  
  	ret = setup_bdi(fs_info, &fs_info->bdi);
  	if (ret) {
  		err = ret;
  		goto fail_srcu;
  	}
  
  	fs_info->btree_inode = new_inode(sb);
  	if (!fs_info->btree_inode) {
  		err = -ENOMEM;
  		goto fail_bdi;
  	}
a65917156   Chris Mason   Btrfs: stop using...
1865
  	mapping_set_gfp_mask(fs_info->btree_inode->i_mapping, GFP_NOFS);
1561deda6   Miao Xie   btrfs: fix possib...
1866

76dda93c6   Yan, Zheng   Btrfs: add snapsh...
1867
  	INIT_RADIX_TREE(&fs_info->fs_roots_radix, GFP_ATOMIC);
8fd17795b   Chris Mason   Btrfs: early fsyn...
1868
  	INIT_LIST_HEAD(&fs_info->trans_list);
facda1e78   Chris Mason   Btrfs: get forced...
1869
  	INIT_LIST_HEAD(&fs_info->dead_roots);
24bbcf044   Yan, Zheng   Btrfs: Add delaye...
1870
  	INIT_LIST_HEAD(&fs_info->delayed_iputs);
19c00ddcc   Chris Mason   Btrfs: Add back m...
1871
  	INIT_LIST_HEAD(&fs_info->hashers);
ea8c28194   Chris Mason   Btrfs: Maintain a...
1872
  	INIT_LIST_HEAD(&fs_info->delalloc_inodes);
5a3f23d51   Chris Mason   Btrfs: add extra ...
1873
  	INIT_LIST_HEAD(&fs_info->ordered_operations);
11833d66b   Yan Zheng   Btrfs: improve as...
1874
  	INIT_LIST_HEAD(&fs_info->caching_block_groups);
1832a6d5e   Chris Mason   Btrfs: Implement ...
1875
  	spin_lock_init(&fs_info->delalloc_lock);
a4abeea41   Josef Bacik   Btrfs: kill trans...
1876
  	spin_lock_init(&fs_info->trans_lock);
31153d812   Yan Zheng   Btrfs: Add a leaf...
1877
  	spin_lock_init(&fs_info->ref_cache_lock);
76dda93c6   Yan, Zheng   Btrfs: add snapsh...
1878
  	spin_lock_init(&fs_info->fs_roots_radix_lock);
24bbcf044   Yan, Zheng   Btrfs: Add delaye...
1879
  	spin_lock_init(&fs_info->delayed_iput_lock);
4cb5300bc   Chris Mason   Btrfs: add mount ...
1880
  	spin_lock_init(&fs_info->defrag_inodes_lock);
2bf64758f   Josef Bacik   Btrfs: allow us t...
1881
  	spin_lock_init(&fs_info->free_chunk_lock);
7585717f3   Chris Mason   Btrfs: fix reloca...
1882
  	mutex_init(&fs_info->reloc_mutex);
19c00ddcc   Chris Mason   Btrfs: Add back m...
1883

58176a960   Josef Bacik   Btrfs: Add per-ro...
1884
  	init_completion(&fs_info->kobj_unregister);
0b86a832a   Chris Mason   Btrfs: Add suppor...
1885
  	INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots);
6324fbf33   Chris Mason   Btrfs: Dynamic ch...
1886
  	INIT_LIST_HEAD(&fs_info->space_info);
0b86a832a   Chris Mason   Btrfs: Add suppor...
1887
  	btrfs_mapping_init(&fs_info->mapping_tree);
f0486c68e   Yan, Zheng   Btrfs: Introduce ...
1888
1889
1890
1891
1892
  	btrfs_init_block_rsv(&fs_info->global_block_rsv);
  	btrfs_init_block_rsv(&fs_info->delalloc_block_rsv);
  	btrfs_init_block_rsv(&fs_info->trans_block_rsv);
  	btrfs_init_block_rsv(&fs_info->chunk_block_rsv);
  	btrfs_init_block_rsv(&fs_info->empty_block_rsv);
6d668dda0   Josef Bacik   Btrfs: make a del...
1893
  	btrfs_init_block_rsv(&fs_info->delayed_block_rsv);
cb03c743c   Chris Mason   Btrfs: Change the...
1894
  	atomic_set(&fs_info->nr_async_submits, 0);
771ed689d   Chris Mason   Btrfs: Optimize c...
1895
  	atomic_set(&fs_info->async_delalloc_pages, 0);
8c8bee1d7   Chris Mason   Btrfs: Wait for I...
1896
  	atomic_set(&fs_info->async_submit_draining, 0);
0986fe9ea   Chris Mason   Btrfs: Count asyn...
1897
  	atomic_set(&fs_info->nr_async_bios, 0);
4cb5300bc   Chris Mason   Btrfs: add mount ...
1898
  	atomic_set(&fs_info->defrag_running, 0);
e20d96d64   Chris Mason   Mountable btrfs, ...
1899
  	fs_info->sb = sb;
6f568d35a   Chris Mason   Btrfs: mount -o m...
1900
  	fs_info->max_inline = 8192 * 1024;
9ed74f2db   Josef Bacik   Btrfs: proper -EN...
1901
  	fs_info->metadata_ratio = 0;
4cb5300bc   Chris Mason   Btrfs: add mount ...
1902
  	fs_info->defrag_inodes = RB_ROOT;
a4abeea41   Josef Bacik   Btrfs: kill trans...
1903
  	fs_info->trans_no_join = 0;
2bf64758f   Josef Bacik   Btrfs: allow us t...
1904
  	fs_info->free_chunk_space = 0;
c8b978188   Chris Mason   Btrfs: Add zlib c...
1905

90519d66a   Arne Jansen   btrfs: state info...
1906
1907
1908
  	/* readahead state */
  	INIT_RADIX_TREE(&fs_info->reada_tree, GFP_NOFS & ~__GFP_WAIT);
  	spin_lock_init(&fs_info->reada_lock);
c8b978188   Chris Mason   Btrfs: Add zlib c...
1909

b34b086c1   Chris Mason   Btrfs: Fix compil...
1910
1911
  	fs_info->thread_pool_size = min_t(unsigned long,
  					  num_online_cpus() + 2, 8);
0afbaf8c8   Chris Mason   Btrfs: Set the bt...
1912

3eaa28852   Chris Mason   Btrfs: Fix the de...
1913
1914
  	INIT_LIST_HEAD(&fs_info->ordered_extents);
  	spin_lock_init(&fs_info->ordered_extent_lock);
16cdcec73   Miao Xie   btrfs: implement ...
1915
1916
1917
1918
1919
1920
1921
  	fs_info->delayed_root = kmalloc(sizeof(struct btrfs_delayed_root),
  					GFP_NOFS);
  	if (!fs_info->delayed_root) {
  		err = -ENOMEM;
  		goto fail_iput;
  	}
  	btrfs_init_delayed_root(fs_info->delayed_root);
3eaa28852   Chris Mason   Btrfs: Fix the de...
1922

a2de733c7   Arne Jansen   btrfs: scrub
1923
1924
1925
1926
1927
1928
1929
1930
  	mutex_init(&fs_info->scrub_lock);
  	atomic_set(&fs_info->scrubs_running, 0);
  	atomic_set(&fs_info->scrub_pause_req, 0);
  	atomic_set(&fs_info->scrubs_paused, 0);
  	atomic_set(&fs_info->scrub_cancel_req, 0);
  	init_waitqueue_head(&fs_info->scrub_pause_wait);
  	init_rwsem(&fs_info->scrub_super_lock);
  	fs_info->scrub_workers_refcnt = 0;
a2de733c7   Arne Jansen   btrfs: scrub
1931

a061fc8da   Chris Mason   Btrfs: Add suppor...
1932
1933
  	sb->s_blocksize = 4096;
  	sb->s_blocksize_bits = blksize_bits(4096);
32a88aa1b   Jens Axboe   fs: Assign bdi in...
1934
  	sb->s_bdi = &fs_info->bdi;
a061fc8da   Chris Mason   Btrfs: Add suppor...
1935

76dda93c6   Yan, Zheng   Btrfs: add snapsh...
1936
  	fs_info->btree_inode->i_ino = BTRFS_BTREE_INODE_OBJECTID;
bfe868486   Miklos Szeredi   filesystems: add ...
1937
  	set_nlink(fs_info->btree_inode, 1);
0afbaf8c8   Chris Mason   Btrfs: Set the bt...
1938
1939
1940
1941
1942
1943
  	/*
  	 * we set the i_size on the btree inode to the max possible int.
  	 * the real end of the address space is determined by all of
  	 * the devices in the system
  	 */
  	fs_info->btree_inode->i_size = OFFSET_MAX;
d98237b3e   Chris Mason   Btrfs: use a btre...
1944
  	fs_info->btree_inode->i_mapping->a_ops = &btree_aops;
041600881   Chris Mason   Create a btrfs ba...
1945
  	fs_info->btree_inode->i_mapping->backing_dev_info = &fs_info->bdi;
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
1946
  	RB_CLEAR_NODE(&BTRFS_I(fs_info->btree_inode)->rb_node);
d1310b2e0   Chris Mason   Btrfs: Split the ...
1947
  	extent_io_tree_init(&BTRFS_I(fs_info->btree_inode)->io_tree,
f993c883a   David Sterba   btrfs: drop unuse...
1948
  			     fs_info->btree_inode->i_mapping);
a8067e022   David Sterba   btrfs: drop unuse...
1949
  	extent_map_tree_init(&BTRFS_I(fs_info->btree_inode)->extent_tree);
d1310b2e0   Chris Mason   Btrfs: Split the ...
1950
1951
  
  	BTRFS_I(fs_info->btree_inode)->io_tree.ops = &btree_extent_io_ops;
0da5468f4   Chris Mason   Btrfs: Use writep...
1952

76dda93c6   Yan, Zheng   Btrfs: add snapsh...
1953
1954
1955
1956
  	BTRFS_I(fs_info->btree_inode)->root = tree_root;
  	memset(&BTRFS_I(fs_info->btree_inode)->location, 0,
  	       sizeof(struct btrfs_key));
  	BTRFS_I(fs_info->btree_inode)->dummy_inode = 1;
c65ddb52d   Yan Zheng   Btrfs: hash the b...
1957
  	insert_inode_hash(fs_info->btree_inode);
76dda93c6   Yan, Zheng   Btrfs: add snapsh...
1958

0f9dd46cd   Josef Bacik   Btrfs: free space...
1959
  	spin_lock_init(&fs_info->block_group_cache_lock);
6bef4d317   Eric Paris   Btrfs: use RB_ROO...
1960
  	fs_info->block_group_cache_tree = RB_ROOT;
0f9dd46cd   Josef Bacik   Btrfs: free space...
1961

11833d66b   Yan Zheng   Btrfs: improve as...
1962
  	extent_io_tree_init(&fs_info->freed_extents[0],
f993c883a   David Sterba   btrfs: drop unuse...
1963
  			     fs_info->btree_inode->i_mapping);
11833d66b   Yan Zheng   Btrfs: improve as...
1964
  	extent_io_tree_init(&fs_info->freed_extents[1],
f993c883a   David Sterba   btrfs: drop unuse...
1965
  			     fs_info->btree_inode->i_mapping);
11833d66b   Yan Zheng   Btrfs: improve as...
1966
  	fs_info->pinned_extents = &fs_info->freed_extents[0];
e66f709b1   Chris Mason   Btrfs: write barr...
1967
  	fs_info->do_barriers = 1;
e18e4809b   Chris Mason   Btrfs: Add mount ...
1968

39279cc3d   Chris Mason   Btrfs: split up s...
1969

5a3f23d51   Chris Mason   Btrfs: add extra ...
1970
  	mutex_init(&fs_info->ordered_operations_mutex);
e02119d5a   Chris Mason   Btrfs: Add a writ...
1971
  	mutex_init(&fs_info->tree_log_mutex);
925baeddc   Chris Mason   Btrfs: Start btre...
1972
  	mutex_init(&fs_info->chunk_mutex);
a74a4b97b   Chris Mason   Btrfs: Replace th...
1973
1974
  	mutex_init(&fs_info->transaction_kthread_mutex);
  	mutex_init(&fs_info->cleaner_mutex);
7d9eb12c8   Chris Mason   Btrfs: Add lockin...
1975
  	mutex_init(&fs_info->volume_mutex);
276e680d1   Yan Zheng   Btrfs: preserve c...
1976
  	init_rwsem(&fs_info->extent_commit_sem);
c71bf099a   Yan, Zheng   Btrfs: Avoid orph...
1977
  	init_rwsem(&fs_info->cleanup_work_sem);
76dda93c6   Yan, Zheng   Btrfs: add snapsh...
1978
  	init_rwsem(&fs_info->subvol_sem);
fa9c0d795   Chris Mason   Btrfs: rework all...
1979
1980
1981
  
  	btrfs_init_free_cluster(&fs_info->meta_alloc_cluster);
  	btrfs_init_free_cluster(&fs_info->data_alloc_cluster);
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
1982
  	init_waitqueue_head(&fs_info->transaction_throttle);
f92957493   Chris Mason   btrfs_start_trans...
1983
  	init_waitqueue_head(&fs_info->transaction_wait);
bb9c12c94   Sage Weil   Btrfs: async tran...
1984
  	init_waitqueue_head(&fs_info->transaction_blocked_wait);
4854ddd0e   Chris Mason   Btrfs: Wait for k...
1985
  	init_waitqueue_head(&fs_info->async_submit_wait);
3768f3689   Chris Mason   Btrfs: Change the...
1986

0b86a832a   Chris Mason   Btrfs: Add suppor...
1987
  	__setup_root(4096, 4096, 4096, 4096, tree_root,
2c90e5d65   Chris Mason   Btrfs: still corr...
1988
  		     fs_info, BTRFS_ROOT_TREE_OBJECTID);
7eccb903a   Chris Mason   Btrfs: create a l...
1989

a512bbf85   Yan Zheng   Btrfs: superblock...
1990
  	bh = btrfs_read_dev_super(fs_devices->latest_bdev);
20b450773   Dave Young   btrfs: mount fail...
1991
1992
  	if (!bh) {
  		err = -EINVAL;
16cdcec73   Miao Xie   btrfs: implement ...
1993
  		goto fail_alloc;
20b450773   Dave Young   btrfs: mount fail...
1994
  	}
39279cc3d   Chris Mason   Btrfs: split up s...
1995

6c41761fc   David Sterba   btrfs: separate s...
1996
1997
1998
  	memcpy(fs_info->super_copy, bh->b_data, sizeof(*fs_info->super_copy));
  	memcpy(fs_info->super_for_commit, fs_info->super_copy,
  	       sizeof(*fs_info->super_for_commit));
a061fc8da   Chris Mason   Btrfs: Add suppor...
1999
  	brelse(bh);
5f39d397d   Chris Mason   Btrfs: Create ext...
2000

6c41761fc   David Sterba   btrfs: separate s...
2001
  	memcpy(fs_info->fsid, fs_info->super_copy->fsid, BTRFS_FSID_SIZE);
0b86a832a   Chris Mason   Btrfs: Add suppor...
2002

6c41761fc   David Sterba   btrfs: separate s...
2003
  	disk_super = fs_info->super_copy;
0f7d52f44   Chris Mason   Btrfs: groundwork...
2004
  	if (!btrfs_super_root(disk_super))
16cdcec73   Miao Xie   btrfs: implement ...
2005
  		goto fail_alloc;
0f7d52f44   Chris Mason   Btrfs: groundwork...
2006

acce952b0   liubo   Btrfs: forced rea...
2007
2008
2009
2010
  	/* check FS state, whether FS is broken. */
  	fs_info->fs_state |= btrfs_super_flags(disk_super);
  
  	btrfs_check_super_valid(fs_info, sb->s_flags & MS_RDONLY);
75e7cb7fe   Liu Bo   Btrfs: Per file/d...
2011
  	/*
af31f5e5b   Chris Mason   Btrfs: add a log ...
2012
2013
2014
2015
2016
2017
2018
  	 * run through our array of backup supers and setup
  	 * our ring pointer to the oldest one
  	 */
  	generation = btrfs_super_generation(disk_super);
  	find_oldest_super_backup(fs_info, generation);
  
  	/*
75e7cb7fe   Liu Bo   Btrfs: Per file/d...
2019
2020
2021
2022
  	 * In the long term, we'll store the compression type in the super
  	 * block, and it'll be used for per file compression control.
  	 */
  	fs_info->compress_type = BTRFS_COMPRESS_ZLIB;
2b82032c3   Yan Zheng   Btrfs: Seed devic...
2023
2024
2025
  	ret = btrfs_parse_options(tree_root, options);
  	if (ret) {
  		err = ret;
16cdcec73   Miao Xie   btrfs: implement ...
2026
  		goto fail_alloc;
2b82032c3   Yan Zheng   Btrfs: Seed devic...
2027
  	}
dfe250206   Chris Mason   Btrfs: Add mount ...
2028

f2b636e80   Josef Bacik   Btrfs: add suppor...
2029
2030
2031
2032
2033
2034
  	features = btrfs_super_incompat_flags(disk_super) &
  		~BTRFS_FEATURE_INCOMPAT_SUPP;
  	if (features) {
  		printk(KERN_ERR "BTRFS: couldn't mount because of "
  		       "unsupported optional features (%Lx).
  ",
21380931e   Joel Becker   Btrfs: Fix a bunc...
2035
  		       (unsigned long long)features);
f2b636e80   Josef Bacik   Btrfs: add suppor...
2036
  		err = -EINVAL;
16cdcec73   Miao Xie   btrfs: implement ...
2037
  		goto fail_alloc;
f2b636e80   Josef Bacik   Btrfs: add suppor...
2038
  	}
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
2039
  	features = btrfs_super_incompat_flags(disk_super);
a6fa6fae4   Li Zefan   btrfs: Add lzo co...
2040
2041
2042
2043
  	features |= BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF;
  	if (tree_root->fs_info->compress_type & BTRFS_COMPRESS_LZO)
  		features |= BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO;
  	btrfs_set_super_incompat_flags(disk_super, features);
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
2044

f2b636e80   Josef Bacik   Btrfs: add suppor...
2045
2046
2047
2048
2049
2050
  	features = btrfs_super_compat_ro_flags(disk_super) &
  		~BTRFS_FEATURE_COMPAT_RO_SUPP;
  	if (!(sb->s_flags & MS_RDONLY) && features) {
  		printk(KERN_ERR "BTRFS: couldn't mount RDWR because of "
  		       "unsupported option features (%Lx).
  ",
21380931e   Joel Becker   Btrfs: Fix a bunc...
2051
  		       (unsigned long long)features);
f2b636e80   Josef Bacik   Btrfs: add suppor...
2052
  		err = -EINVAL;
16cdcec73   Miao Xie   btrfs: implement ...
2053
  		goto fail_alloc;
f2b636e80   Josef Bacik   Btrfs: add suppor...
2054
  	}
61d92c328   Chris Mason   Btrfs: fix deadlo...
2055
2056
2057
  
  	btrfs_init_workers(&fs_info->generic_worker,
  			   "genwork", 1, NULL);
5443be45f   Chris Mason   Btrfs: Give all t...
2058
  	btrfs_init_workers(&fs_info->workers, "worker",
61d92c328   Chris Mason   Btrfs: fix deadlo...
2059
2060
  			   fs_info->thread_pool_size,
  			   &fs_info->generic_worker);
c8b978188   Chris Mason   Btrfs: Add zlib c...
2061

771ed689d   Chris Mason   Btrfs: Optimize c...
2062
  	btrfs_init_workers(&fs_info->delalloc_workers, "delalloc",
61d92c328   Chris Mason   Btrfs: fix deadlo...
2063
2064
  			   fs_info->thread_pool_size,
  			   &fs_info->generic_worker);
771ed689d   Chris Mason   Btrfs: Optimize c...
2065

5443be45f   Chris Mason   Btrfs: Give all t...
2066
  	btrfs_init_workers(&fs_info->submit_workers, "submit",
b720d2095   Chris Mason   Btrfs: Limit the ...
2067
  			   min_t(u64, fs_devices->num_devices,
61d92c328   Chris Mason   Btrfs: fix deadlo...
2068
2069
  			   fs_info->thread_pool_size),
  			   &fs_info->generic_worker);
61b494401   Chris Mason   Btrfs: Fix stream...
2070

bab39bf99   Josef Bacik   Btrfs: use a work...
2071
2072
  	btrfs_init_workers(&fs_info->caching_workers, "cache",
  			   2, &fs_info->generic_worker);
61b494401   Chris Mason   Btrfs: Fix stream...
2073
2074
2075
2076
2077
  	/* a higher idle thresh on the submit workers makes it much more
  	 * likely that bios will be send down in a sane order to the
  	 * devices
  	 */
  	fs_info->submit_workers.idle_thresh = 64;
53863232e   Chris Mason   Btrfs: Lower cont...
2078

771ed689d   Chris Mason   Btrfs: Optimize c...
2079
  	fs_info->workers.idle_thresh = 16;
4a69a4100   Chris Mason   Btrfs: Add ordere...
2080
  	fs_info->workers.ordered = 1;
61b494401   Chris Mason   Btrfs: Fix stream...
2081

771ed689d   Chris Mason   Btrfs: Optimize c...
2082
2083
  	fs_info->delalloc_workers.idle_thresh = 2;
  	fs_info->delalloc_workers.ordered = 1;
61d92c328   Chris Mason   Btrfs: fix deadlo...
2084
2085
  	btrfs_init_workers(&fs_info->fixup_workers, "fixup", 1,
  			   &fs_info->generic_worker);
5443be45f   Chris Mason   Btrfs: Give all t...
2086
  	btrfs_init_workers(&fs_info->endio_workers, "endio",
61d92c328   Chris Mason   Btrfs: fix deadlo...
2087
2088
  			   fs_info->thread_pool_size,
  			   &fs_info->generic_worker);
d20f7043f   Chris Mason   Btrfs: move data ...
2089
  	btrfs_init_workers(&fs_info->endio_meta_workers, "endio-meta",
61d92c328   Chris Mason   Btrfs: fix deadlo...
2090
2091
  			   fs_info->thread_pool_size,
  			   &fs_info->generic_worker);
cad321ad5   Chris Mason   Btrfs: shift all ...
2092
  	btrfs_init_workers(&fs_info->endio_meta_write_workers,
61d92c328   Chris Mason   Btrfs: fix deadlo...
2093
2094
  			   "endio-meta-write", fs_info->thread_pool_size,
  			   &fs_info->generic_worker);
5443be45f   Chris Mason   Btrfs: Give all t...
2095
  	btrfs_init_workers(&fs_info->endio_write_workers, "endio-write",
61d92c328   Chris Mason   Btrfs: fix deadlo...
2096
2097
  			   fs_info->thread_pool_size,
  			   &fs_info->generic_worker);
0cb59c995   Josef Bacik   Btrfs: write out ...
2098
2099
  	btrfs_init_workers(&fs_info->endio_freespace_worker, "freespace-write",
  			   1, &fs_info->generic_worker);
16cdcec73   Miao Xie   btrfs: implement ...
2100
2101
2102
  	btrfs_init_workers(&fs_info->delayed_workers, "delayed-meta",
  			   fs_info->thread_pool_size,
  			   &fs_info->generic_worker);
90519d66a   Arne Jansen   btrfs: state info...
2103
2104
2105
  	btrfs_init_workers(&fs_info->readahead_workers, "readahead",
  			   fs_info->thread_pool_size,
  			   &fs_info->generic_worker);
61b494401   Chris Mason   Btrfs: Fix stream...
2106
2107
2108
2109
2110
2111
  
  	/*
  	 * endios are largely parallel and should have a very
  	 * low idle thresh
  	 */
  	fs_info->endio_workers.idle_thresh = 4;
b51912c91   Chris Mason   Btrfs: async thre...
2112
  	fs_info->endio_meta_workers.idle_thresh = 4;
9042846bc   Chris Mason   Btrfs: Allow work...
2113
2114
  	fs_info->endio_write_workers.idle_thresh = 2;
  	fs_info->endio_meta_write_workers.idle_thresh = 2;
90519d66a   Arne Jansen   btrfs: state info...
2115
  	fs_info->readahead_workers.idle_thresh = 2;
9042846bc   Chris Mason   Btrfs: Allow work...
2116

0dc3b84a7   Josef Bacik   Btrfs: fix num_wo...
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
  	/*
  	 * btrfs_start_workers can really only fail because of ENOMEM so just
  	 * return -ENOMEM if any of these fail.
  	 */
  	ret = btrfs_start_workers(&fs_info->workers);
  	ret |= btrfs_start_workers(&fs_info->generic_worker);
  	ret |= btrfs_start_workers(&fs_info->submit_workers);
  	ret |= btrfs_start_workers(&fs_info->delalloc_workers);
  	ret |= btrfs_start_workers(&fs_info->fixup_workers);
  	ret |= btrfs_start_workers(&fs_info->endio_workers);
  	ret |= btrfs_start_workers(&fs_info->endio_meta_workers);
  	ret |= btrfs_start_workers(&fs_info->endio_meta_write_workers);
  	ret |= btrfs_start_workers(&fs_info->endio_write_workers);
  	ret |= btrfs_start_workers(&fs_info->endio_freespace_worker);
  	ret |= btrfs_start_workers(&fs_info->delayed_workers);
  	ret |= btrfs_start_workers(&fs_info->caching_workers);
  	ret |= btrfs_start_workers(&fs_info->readahead_workers);
  	if (ret) {
  		ret = -ENOMEM;
  		goto fail_sb_buffer;
  	}
4543df7ec   Chris Mason   Btrfs: Add a moun...
2138

4575c9cce   Chris Mason   Btrfs: Scale the ...
2139
  	fs_info->bdi.ra_pages *= btrfs_super_num_devices(disk_super);
c8b978188   Chris Mason   Btrfs: Add zlib c...
2140
2141
  	fs_info->bdi.ra_pages = max(fs_info->bdi.ra_pages,
  				    4 * 1024 * 1024 / PAGE_CACHE_SIZE);
4575c9cce   Chris Mason   Btrfs: Scale the ...
2142

db94535db   Chris Mason   Btrfs: Allow tree...
2143
2144
2145
  	nodesize = btrfs_super_nodesize(disk_super);
  	leafsize = btrfs_super_leafsize(disk_super);
  	sectorsize = btrfs_super_sectorsize(disk_super);
87ee04eb0   Chris Mason   Btrfs: Add simple...
2146
  	stripesize = btrfs_super_stripesize(disk_super);
db94535db   Chris Mason   Btrfs: Allow tree...
2147
2148
2149
  	tree_root->nodesize = nodesize;
  	tree_root->leafsize = leafsize;
  	tree_root->sectorsize = sectorsize;
87ee04eb0   Chris Mason   Btrfs: Add simple...
2150
  	tree_root->stripesize = stripesize;
a061fc8da   Chris Mason   Btrfs: Add suppor...
2151
2152
2153
  
  	sb->s_blocksize = sectorsize;
  	sb->s_blocksize_bits = blksize_bits(sectorsize);
db94535db   Chris Mason   Btrfs: Allow tree...
2154

39279cc3d   Chris Mason   Btrfs: split up s...
2155
2156
  	if (strncmp((char *)(&disk_super->magic), BTRFS_MAGIC,
  		    sizeof(disk_super->magic))) {
d397712bc   Chris Mason   Btrfs: Fix checkp...
2157
2158
  		printk(KERN_INFO "btrfs: valid FS not found on %s
  ", sb->s_id);
39279cc3d   Chris Mason   Btrfs: split up s...
2159
2160
  		goto fail_sb_buffer;
  	}
19c00ddcc   Chris Mason   Btrfs: Add back m...
2161

925baeddc   Chris Mason   Btrfs: Start btre...
2162
  	mutex_lock(&fs_info->chunk_mutex);
e4404d6e8   Yan Zheng   Btrfs: shared see...
2163
  	ret = btrfs_read_sys_array(tree_root);
925baeddc   Chris Mason   Btrfs: Start btre...
2164
  	mutex_unlock(&fs_info->chunk_mutex);
84eed90fa   Chris Mason   Btrfs: Add failur...
2165
  	if (ret) {
d397712bc   Chris Mason   Btrfs: Fix checkp...
2166
2167
2168
  		printk(KERN_WARNING "btrfs: failed to read the system "
  		       "array on %s
  ", sb->s_id);
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
2169
  		goto fail_sb_buffer;
84eed90fa   Chris Mason   Btrfs: Add failur...
2170
  	}
0b86a832a   Chris Mason   Btrfs: Add suppor...
2171
2172
2173
  
  	blocksize = btrfs_level_size(tree_root,
  				     btrfs_super_chunk_root_level(disk_super));
84234f3a1   Yan Zheng   Btrfs: Add root t...
2174
  	generation = btrfs_super_chunk_root_generation(disk_super);
0b86a832a   Chris Mason   Btrfs: Add suppor...
2175
2176
2177
2178
2179
2180
  
  	__setup_root(nodesize, leafsize, sectorsize, stripesize,
  		     chunk_root, fs_info, BTRFS_CHUNK_TREE_OBJECTID);
  
  	chunk_root->node = read_tree_block(chunk_root,
  					   btrfs_super_chunk_root(disk_super),
84234f3a1   Yan Zheng   Btrfs: Add root t...
2181
  					   blocksize, generation);
0b86a832a   Chris Mason   Btrfs: Add suppor...
2182
  	BUG_ON(!chunk_root->node);
83121942b   David Woodhouse   Btrfs: Fix crash ...
2183
2184
2185
2186
  	if (!test_bit(EXTENT_BUFFER_UPTODATE, &chunk_root->node->bflags)) {
  		printk(KERN_WARNING "btrfs: failed to read chunk root on %s
  ",
  		       sb->s_id);
af31f5e5b   Chris Mason   Btrfs: add a log ...
2187
  		goto fail_tree_roots;
83121942b   David Woodhouse   Btrfs: Fix crash ...
2188
  	}
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
2189
2190
  	btrfs_set_root_node(&chunk_root->root_item, chunk_root->node);
  	chunk_root->commit_root = btrfs_root_node(chunk_root);
0b86a832a   Chris Mason   Btrfs: Add suppor...
2191

e17cade25   Chris Mason   Btrfs: Add chunk ...
2192
  	read_extent_buffer(chunk_root->node, fs_info->chunk_tree_uuid,
d397712bc   Chris Mason   Btrfs: Fix checkp...
2193
2194
  	   (unsigned long)btrfs_header_chunk_tree_uuid(chunk_root->node),
  	   BTRFS_UUID_SIZE);
e17cade25   Chris Mason   Btrfs: Add chunk ...
2195

925baeddc   Chris Mason   Btrfs: Start btre...
2196
  	mutex_lock(&fs_info->chunk_mutex);
0b86a832a   Chris Mason   Btrfs: Add suppor...
2197
  	ret = btrfs_read_chunk_tree(chunk_root);
925baeddc   Chris Mason   Btrfs: Start btre...
2198
  	mutex_unlock(&fs_info->chunk_mutex);
2b82032c3   Yan Zheng   Btrfs: Seed devic...
2199
  	if (ret) {
d397712bc   Chris Mason   Btrfs: Fix checkp...
2200
2201
2202
  		printk(KERN_WARNING "btrfs: failed to read chunk tree on %s
  ",
  		       sb->s_id);
af31f5e5b   Chris Mason   Btrfs: add a log ...
2203
  		goto fail_tree_roots;
2b82032c3   Yan Zheng   Btrfs: Seed devic...
2204
  	}
0b86a832a   Chris Mason   Btrfs: Add suppor...
2205

dfe250206   Chris Mason   Btrfs: Add mount ...
2206
  	btrfs_close_extra_devices(fs_devices);
af31f5e5b   Chris Mason   Btrfs: add a log ...
2207
  retry_root_backup:
db94535db   Chris Mason   Btrfs: Allow tree...
2208
2209
  	blocksize = btrfs_level_size(tree_root,
  				     btrfs_super_root_level(disk_super));
84234f3a1   Yan Zheng   Btrfs: Add root t...
2210
  	generation = btrfs_super_generation(disk_super);
0b86a832a   Chris Mason   Btrfs: Add suppor...
2211

e20d96d64   Chris Mason   Mountable btrfs, ...
2212
  	tree_root->node = read_tree_block(tree_root,
db94535db   Chris Mason   Btrfs: Allow tree...
2213
  					  btrfs_super_root(disk_super),
84234f3a1   Yan Zheng   Btrfs: Add root t...
2214
  					  blocksize, generation);
af31f5e5b   Chris Mason   Btrfs: add a log ...
2215
2216
  	if (!tree_root->node ||
  	    !test_bit(EXTENT_BUFFER_UPTODATE, &tree_root->node->bflags)) {
83121942b   David Woodhouse   Btrfs: Fix crash ...
2217
2218
2219
  		printk(KERN_WARNING "btrfs: failed to read tree root on %s
  ",
  		       sb->s_id);
af31f5e5b   Chris Mason   Btrfs: add a log ...
2220
2221
  
  		goto recovery_tree_root;
83121942b   David Woodhouse   Btrfs: Fix crash ...
2222
  	}
af31f5e5b   Chris Mason   Btrfs: add a log ...
2223

5d4f98a28   Yan Zheng   Btrfs: Mixed back...
2224
2225
  	btrfs_set_root_node(&tree_root->root_item, tree_root->node);
  	tree_root->commit_root = btrfs_root_node(tree_root);
db94535db   Chris Mason   Btrfs: Allow tree...
2226
2227
  
  	ret = find_and_setup_root(tree_root, fs_info,
e20d96d64   Chris Mason   Mountable btrfs, ...
2228
  				  BTRFS_EXTENT_TREE_OBJECTID, extent_root);
0b86a832a   Chris Mason   Btrfs: Add suppor...
2229
  	if (ret)
af31f5e5b   Chris Mason   Btrfs: add a log ...
2230
  		goto recovery_tree_root;
0b86a832a   Chris Mason   Btrfs: Add suppor...
2231
2232
2233
2234
  	extent_root->track_dirty = 1;
  
  	ret = find_and_setup_root(tree_root, fs_info,
  				  BTRFS_DEV_TREE_OBJECTID, dev_root);
0b86a832a   Chris Mason   Btrfs: Add suppor...
2235
  	if (ret)
af31f5e5b   Chris Mason   Btrfs: add a log ...
2236
  		goto recovery_tree_root;
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
2237
  	dev_root->track_dirty = 1;
3768f3689   Chris Mason   Btrfs: Change the...
2238

d20f7043f   Chris Mason   Btrfs: move data ...
2239
2240
2241
  	ret = find_and_setup_root(tree_root, fs_info,
  				  BTRFS_CSUM_TREE_OBJECTID, csum_root);
  	if (ret)
af31f5e5b   Chris Mason   Btrfs: add a log ...
2242
  		goto recovery_tree_root;
d20f7043f   Chris Mason   Btrfs: move data ...
2243
2244
  
  	csum_root->track_dirty = 1;
8929ecfa5   Yan, Zheng   Btrfs: Introduce ...
2245
2246
2247
2248
2249
  	fs_info->generation = generation;
  	fs_info->last_trans_committed = generation;
  	fs_info->data_alloc_profile = (u64)-1;
  	fs_info->metadata_alloc_profile = (u64)-1;
  	fs_info->system_alloc_profile = fs_info->metadata_alloc_profile;
c59021f84   liubo   Btrfs: fix OOPS o...
2250
2251
2252
2253
2254
2255
  	ret = btrfs_init_space_info(fs_info);
  	if (ret) {
  		printk(KERN_ERR "Failed to initial space info: %d
  ", ret);
  		goto fail_block_groups;
  	}
1b1d1f662   Josef Bacik   Btrfs: fail to mo...
2256
2257
2258
2259
2260
2261
  	ret = btrfs_read_block_groups(extent_root);
  	if (ret) {
  		printk(KERN_ERR "Failed to read block groups: %d
  ", ret);
  		goto fail_block_groups;
  	}
9078a3e1e   Chris Mason   Btrfs: start of b...
2262

a74a4b97b   Chris Mason   Btrfs: Replace th...
2263
2264
  	fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root,
  					       "btrfs-cleaner");
57506d50e   Qinghuang Feng   Btrfs: check retu...
2265
  	if (IS_ERR(fs_info->cleaner_kthread))
1b1d1f662   Josef Bacik   Btrfs: fail to mo...
2266
  		goto fail_block_groups;
a74a4b97b   Chris Mason   Btrfs: Replace th...
2267
2268
2269
2270
  
  	fs_info->transaction_kthread = kthread_run(transaction_kthread,
  						   tree_root,
  						   "btrfs-transaction");
57506d50e   Qinghuang Feng   Btrfs: check retu...
2271
  	if (IS_ERR(fs_info->transaction_kthread))
3f157a2fd   Chris Mason   Btrfs: Online btr...
2272
  		goto fail_cleaner;
a74a4b97b   Chris Mason   Btrfs: Replace th...
2273

c289811cc   Chris Mason   Btrfs: autodetect...
2274
2275
2276
2277
2278
2279
2280
2281
  	if (!btrfs_test_opt(tree_root, SSD) &&
  	    !btrfs_test_opt(tree_root, NOSSD) &&
  	    !fs_info->fs_devices->rotating) {
  		printk(KERN_INFO "Btrfs detected SSD devices, enabling SSD "
  		       "mode
  ");
  		btrfs_set_opt(fs_info->mount_opt, SSD);
  	}
acce952b0   liubo   Btrfs: forced rea...
2282
2283
2284
  	/* do not make disk changes in broken FS */
  	if (btrfs_super_log_root(disk_super) != 0 &&
  	    !(fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR)) {
e02119d5a   Chris Mason   Btrfs: Add a writ...
2285
  		u64 bytenr = btrfs_super_log_root(disk_super);
7c2ca4682   Chris Mason   Btrfs: Do fsync l...
2286
  		if (fs_devices->rw_devices == 0) {
d397712bc   Chris Mason   Btrfs: Fix checkp...
2287
2288
2289
  			printk(KERN_WARNING "Btrfs log replay required "
  			       "on RO media
  ");
7c2ca4682   Chris Mason   Btrfs: Do fsync l...
2290
2291
2292
  			err = -EIO;
  			goto fail_trans_kthread;
  		}
e02119d5a   Chris Mason   Btrfs: Add a writ...
2293
2294
2295
  		blocksize =
  		     btrfs_level_size(tree_root,
  				      btrfs_super_log_root_level(disk_super));
d18a2c447   Chris Mason   Btrfs: Fix alloca...
2296

676e4c863   Dan Carpenter   Btrfs: handle kza...
2297
2298
2299
2300
2301
  		log_tree_root = kzalloc(sizeof(struct btrfs_root), GFP_NOFS);
  		if (!log_tree_root) {
  			err = -ENOMEM;
  			goto fail_trans_kthread;
  		}
e02119d5a   Chris Mason   Btrfs: Add a writ...
2302
2303
2304
2305
2306
  
  		__setup_root(nodesize, leafsize, sectorsize, stripesize,
  			     log_tree_root, fs_info, BTRFS_TREE_LOG_OBJECTID);
  
  		log_tree_root->node = read_tree_block(tree_root, bytenr,
84234f3a1   Yan Zheng   Btrfs: Add root t...
2307
2308
  						      blocksize,
  						      generation + 1);
e02119d5a   Chris Mason   Btrfs: Add a writ...
2309
2310
  		ret = btrfs_recover_log_trees(log_tree_root);
  		BUG_ON(ret);
e556ce2c9   Yan Zheng   Btrfs: Drop dirty...
2311
2312
2313
2314
2315
  
  		if (sb->s_flags & MS_RDONLY) {
  			ret =  btrfs_commit_super(tree_root);
  			BUG_ON(ret);
  		}
e02119d5a   Chris Mason   Btrfs: Add a writ...
2316
  	}
1a40e23b9   Zheng Yan   Btrfs: update spa...
2317

76dda93c6   Yan, Zheng   Btrfs: add snapsh...
2318
2319
  	ret = btrfs_find_orphan_roots(tree_root);
  	BUG_ON(ret);
7c2ca4682   Chris Mason   Btrfs: Do fsync l...
2320
  	if (!(sb->s_flags & MS_RDONLY)) {
d68fc57b7   Yan, Zheng   Btrfs: Metadata r...
2321
2322
  		ret = btrfs_cleanup_fs_roots(fs_info);
  		BUG_ON(ret);
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
2323
  		ret = btrfs_recover_relocation(tree_root);
d7ce5843b   Miao Xie   Btrfs: remove BUG...
2324
2325
2326
2327
2328
2329
2330
  		if (ret < 0) {
  			printk(KERN_WARNING
  			       "btrfs: failed to recover relocation
  ");
  			err = -EINVAL;
  			goto fail_trans_kthread;
  		}
7c2ca4682   Chris Mason   Btrfs: Do fsync l...
2331
  	}
1a40e23b9   Zheng Yan   Btrfs: update spa...
2332

3de4586c5   Chris Mason   Btrfs: Allow subv...
2333
2334
2335
  	location.objectid = BTRFS_FS_TREE_OBJECTID;
  	location.type = BTRFS_ROOT_ITEM_KEY;
  	location.offset = (u64)-1;
3de4586c5   Chris Mason   Btrfs: Allow subv...
2336
2337
  	fs_info->fs_root = btrfs_read_fs_root_no_name(fs_info, &location);
  	if (!fs_info->fs_root)
7c2ca4682   Chris Mason   Btrfs: Do fsync l...
2338
  		goto fail_trans_kthread;
3140c9a34   Dan Carpenter   Btrfs: btrfs_read...
2339
2340
2341
2342
  	if (IS_ERR(fs_info->fs_root)) {
  		err = PTR_ERR(fs_info->fs_root);
  		goto fail_trans_kthread;
  	}
c289811cc   Chris Mason   Btrfs: autodetect...
2343

e3acc2a68   Josef Bacik   Btrfs: run orphan...
2344
2345
  	if (!(sb->s_flags & MS_RDONLY)) {
  		down_read(&fs_info->cleanup_work_sem);
66b4ffd11   Josef Bacik   Btrfs: handle err...
2346
2347
2348
  		err = btrfs_orphan_cleanup(fs_info->fs_root);
  		if (!err)
  			err = btrfs_orphan_cleanup(fs_info->tree_root);
e3acc2a68   Josef Bacik   Btrfs: run orphan...
2349
  		up_read(&fs_info->cleanup_work_sem);
66b4ffd11   Josef Bacik   Btrfs: handle err...
2350
2351
2352
2353
  		if (err) {
  			close_ctree(tree_root);
  			return ERR_PTR(err);
  		}
e3acc2a68   Josef Bacik   Btrfs: run orphan...
2354
  	}
0f7d52f44   Chris Mason   Btrfs: groundwork...
2355
  	return tree_root;
39279cc3d   Chris Mason   Btrfs: split up s...
2356

7c2ca4682   Chris Mason   Btrfs: Do fsync l...
2357
2358
  fail_trans_kthread:
  	kthread_stop(fs_info->transaction_kthread);
3f157a2fd   Chris Mason   Btrfs: Online btr...
2359
  fail_cleaner:
a74a4b97b   Chris Mason   Btrfs: Replace th...
2360
  	kthread_stop(fs_info->cleaner_kthread);
7c2ca4682   Chris Mason   Btrfs: Do fsync l...
2361
2362
2363
2364
2365
2366
2367
  
  	/*
  	 * make sure we're done with the btree inode before we stop our
  	 * kthreads
  	 */
  	filemap_write_and_wait(fs_info->btree_inode->i_mapping);
  	invalidate_inode_pages2(fs_info->btree_inode->i_mapping);
1b1d1f662   Josef Bacik   Btrfs: fail to mo...
2368
2369
  fail_block_groups:
  	btrfs_free_block_groups(fs_info);
af31f5e5b   Chris Mason   Btrfs: add a log ...
2370
2371
2372
  
  fail_tree_roots:
  	free_root_pointers(fs_info, 1);
39279cc3d   Chris Mason   Btrfs: split up s...
2373
  fail_sb_buffer:
61d92c328   Chris Mason   Btrfs: fix deadlo...
2374
  	btrfs_stop_workers(&fs_info->generic_worker);
306c8b68c   Chris Mason   Btrfs: stop the r...
2375
  	btrfs_stop_workers(&fs_info->readahead_workers);
247e743cb   Chris Mason   Btrfs: Use async ...
2376
  	btrfs_stop_workers(&fs_info->fixup_workers);
771ed689d   Chris Mason   Btrfs: Optimize c...
2377
  	btrfs_stop_workers(&fs_info->delalloc_workers);
8b7128429   Chris Mason   Btrfs: Add async ...
2378
2379
  	btrfs_stop_workers(&fs_info->workers);
  	btrfs_stop_workers(&fs_info->endio_workers);
d20f7043f   Chris Mason   Btrfs: move data ...
2380
  	btrfs_stop_workers(&fs_info->endio_meta_workers);
cad321ad5   Chris Mason   Btrfs: shift all ...
2381
  	btrfs_stop_workers(&fs_info->endio_meta_write_workers);
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
2382
  	btrfs_stop_workers(&fs_info->endio_write_workers);
0cb59c995   Josef Bacik   Btrfs: write out ...
2383
  	btrfs_stop_workers(&fs_info->endio_freespace_worker);
1cc127b5d   Chris Mason   Btrfs: Add a thre...
2384
  	btrfs_stop_workers(&fs_info->submit_workers);
16cdcec73   Miao Xie   btrfs: implement ...
2385
  	btrfs_stop_workers(&fs_info->delayed_workers);
bab39bf99   Josef Bacik   Btrfs: use a work...
2386
  	btrfs_stop_workers(&fs_info->caching_workers);
16cdcec73   Miao Xie   btrfs: implement ...
2387
  fail_alloc:
4543df7ec   Chris Mason   Btrfs: Add a moun...
2388
  fail_iput:
586e46e28   Ilya Dryomov   Btrfs: close devi...
2389
  	btrfs_mapping_tree_free(&fs_info->mapping_tree);
7c2ca4682   Chris Mason   Btrfs: Do fsync l...
2390
  	invalidate_inode_pages2(fs_info->btree_inode->i_mapping);
4543df7ec   Chris Mason   Btrfs: Add a moun...
2391
  	iput(fs_info->btree_inode);
ad081f143   Jens Axboe   btrfs: properly r...
2392
  fail_bdi:
7e6628544   Qinghuang Feng   Btrfs: open_ctree...
2393
  	bdi_destroy(&fs_info->bdi);
76dda93c6   Yan, Zheng   Btrfs: add snapsh...
2394
2395
  fail_srcu:
  	cleanup_srcu_struct(&fs_info->subvol_srcu);
7e6628544   Qinghuang Feng   Btrfs: open_ctree...
2396
  fail:
586e46e28   Ilya Dryomov   Btrfs: close devi...
2397
  	btrfs_close_devices(fs_info->fs_devices);
6c41761fc   David Sterba   btrfs: separate s...
2398
  	free_fs_info(fs_info);
39279cc3d   Chris Mason   Btrfs: split up s...
2399
  	return ERR_PTR(err);
af31f5e5b   Chris Mason   Btrfs: add a log ...
2400
2401
  
  recovery_tree_root:
af31f5e5b   Chris Mason   Btrfs: add a log ...
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
  	if (!btrfs_test_opt(tree_root, RECOVERY))
  		goto fail_tree_roots;
  
  	free_root_pointers(fs_info, 0);
  
  	/* don't use the log in recovery mode, it won't be valid */
  	btrfs_set_super_log_root(disk_super, 0);
  
  	/* we can't trust the free space cache either */
  	btrfs_set_opt(fs_info->mount_opt, CLEAR_CACHE);
  
  	ret = next_root_backup(fs_info, fs_info->super_copy,
  			       &num_backups_tried, &backup_index);
  	if (ret == -1)
  		goto fail_block_groups;
  	goto retry_root_backup;
eb60ceac0   Chris Mason   Btrfs: Add backin...
2418
  }
f29844623   Chris Mason   Btrfs: Write out ...
2419
2420
2421
2422
2423
2424
2425
  static void btrfs_end_buffer_write_sync(struct buffer_head *bh, int uptodate)
  {
  	char b[BDEVNAME_SIZE];
  
  	if (uptodate) {
  		set_buffer_uptodate(bh);
  	} else {
7a36ddec1   David Sterba   btrfs: use printk...
2426
  		printk_ratelimited(KERN_WARNING "lost page write due to "
f29844623   Chris Mason   Btrfs: Write out ...
2427
2428
2429
  					"I/O error on %s
  ",
  				       bdevname(bh->b_bdev, b));
1259ab75c   Chris Mason   Btrfs: Handle wri...
2430
2431
2432
  		/* note, we dont' set_buffer_write_io_error because we have
  		 * our own ways of dealing with the IO errors
  		 */
f29844623   Chris Mason   Btrfs: Write out ...
2433
2434
2435
2436
2437
  		clear_buffer_uptodate(bh);
  	}
  	unlock_buffer(bh);
  	put_bh(bh);
  }
a512bbf85   Yan Zheng   Btrfs: superblock...
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
  struct buffer_head *btrfs_read_dev_super(struct block_device *bdev)
  {
  	struct buffer_head *bh;
  	struct buffer_head *latest = NULL;
  	struct btrfs_super_block *super;
  	int i;
  	u64 transid = 0;
  	u64 bytenr;
  
  	/* we would like to check all the supers, but that would make
  	 * a btrfs mount succeed after a mkfs from a different FS.
  	 * So, we need to add a special mount option to scan for
  	 * later supers, using BTRFS_SUPER_MIRROR_MAX instead
  	 */
  	for (i = 0; i < 1; i++) {
  		bytenr = btrfs_sb_offset(i);
  		if (bytenr + 4096 >= i_size_read(bdev->bd_inode))
  			break;
  		bh = __bread(bdev, bytenr / 4096, 4096);
  		if (!bh)
  			continue;
  
  		super = (struct btrfs_super_block *)bh->b_data;
  		if (btrfs_super_bytenr(super) != bytenr ||
  		    strncmp((char *)(&super->magic), BTRFS_MAGIC,
  			    sizeof(super->magic))) {
  			brelse(bh);
  			continue;
  		}
  
  		if (!latest || btrfs_super_generation(super) > transid) {
  			brelse(latest);
  			latest = bh;
  			transid = btrfs_super_generation(super);
  		} else {
  			brelse(bh);
  		}
  	}
  	return latest;
  }
4eedeb75e   Hisashi Hifumi   Btrfs: pin buffer...
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
  /*
   * this should be called twice, once with wait == 0 and
   * once with wait == 1.  When wait == 0 is done, all the buffer heads
   * we write are pinned.
   *
   * They are released when wait == 1 is done.
   * max_mirrors must be the same for both runs, and it indicates how
   * many supers on this one device should be written.
   *
   * max_mirrors == 0 means to write them all.
   */
a512bbf85   Yan Zheng   Btrfs: superblock...
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
  static int write_dev_supers(struct btrfs_device *device,
  			    struct btrfs_super_block *sb,
  			    int do_barriers, int wait, int max_mirrors)
  {
  	struct buffer_head *bh;
  	int i;
  	int ret;
  	int errors = 0;
  	u32 crc;
  	u64 bytenr;
a512bbf85   Yan Zheng   Btrfs: superblock...
2499
2500
2501
  
  	if (max_mirrors == 0)
  		max_mirrors = BTRFS_SUPER_MIRROR_MAX;
a512bbf85   Yan Zheng   Btrfs: superblock...
2502
2503
2504
2505
2506
2507
2508
2509
2510
  	for (i = 0; i < max_mirrors; i++) {
  		bytenr = btrfs_sb_offset(i);
  		if (bytenr + BTRFS_SUPER_INFO_SIZE >= device->total_bytes)
  			break;
  
  		if (wait) {
  			bh = __find_get_block(device->bdev, bytenr / 4096,
  					      BTRFS_SUPER_INFO_SIZE);
  			BUG_ON(!bh);
a512bbf85   Yan Zheng   Btrfs: superblock...
2511
  			wait_on_buffer(bh);
4eedeb75e   Hisashi Hifumi   Btrfs: pin buffer...
2512
2513
2514
2515
2516
2517
2518
2519
2520
  			if (!buffer_uptodate(bh))
  				errors++;
  
  			/* drop our reference */
  			brelse(bh);
  
  			/* drop the reference from the wait == 0 run */
  			brelse(bh);
  			continue;
a512bbf85   Yan Zheng   Btrfs: superblock...
2521
2522
2523
2524
2525
2526
2527
2528
2529
  		} else {
  			btrfs_set_super_bytenr(sb, bytenr);
  
  			crc = ~(u32)0;
  			crc = btrfs_csum_data(NULL, (char *)sb +
  					      BTRFS_CSUM_SIZE, crc,
  					      BTRFS_SUPER_INFO_SIZE -
  					      BTRFS_CSUM_SIZE);
  			btrfs_csum_final(crc, sb->csum);
4eedeb75e   Hisashi Hifumi   Btrfs: pin buffer...
2530
2531
2532
2533
  			/*
  			 * one reference for us, and we leave it for the
  			 * caller
  			 */
a512bbf85   Yan Zheng   Btrfs: superblock...
2534
2535
2536
  			bh = __getblk(device->bdev, bytenr / 4096,
  				      BTRFS_SUPER_INFO_SIZE);
  			memcpy(bh->b_data, sb, BTRFS_SUPER_INFO_SIZE);
4eedeb75e   Hisashi Hifumi   Btrfs: pin buffer...
2537
  			/* one reference for submit_bh */
a512bbf85   Yan Zheng   Btrfs: superblock...
2538
  			get_bh(bh);
4eedeb75e   Hisashi Hifumi   Btrfs: pin buffer...
2539
2540
  
  			set_buffer_uptodate(bh);
a512bbf85   Yan Zheng   Btrfs: superblock...
2541
2542
2543
  			lock_buffer(bh);
  			bh->b_end_io = btrfs_end_buffer_write_sync;
  		}
387125fc7   Chris Mason   Btrfs: fix barrie...
2544
2545
2546
2547
2548
  		/*
  		 * we fua the first super.  The others we allow
  		 * to go down lazy.
  		 */
  		ret = submit_bh(WRITE_FUA, bh);
4eedeb75e   Hisashi Hifumi   Btrfs: pin buffer...
2549
  		if (ret)
a512bbf85   Yan Zheng   Btrfs: superblock...
2550
  			errors++;
a512bbf85   Yan Zheng   Btrfs: superblock...
2551
2552
2553
  	}
  	return errors < i ? 0 : -1;
  }
387125fc7   Chris Mason   Btrfs: fix barrie...
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
  /*
   * endio for the write_dev_flush, this will wake anyone waiting
   * for the barrier when it is done
   */
  static void btrfs_end_empty_barrier(struct bio *bio, int err)
  {
  	if (err) {
  		if (err == -EOPNOTSUPP)
  			set_bit(BIO_EOPNOTSUPP, &bio->bi_flags);
  		clear_bit(BIO_UPTODATE, &bio->bi_flags);
  	}
  	if (bio->bi_private)
  		complete(bio->bi_private);
  	bio_put(bio);
  }
  
  /*
   * trigger flushes for one the devices.  If you pass wait == 0, the flushes are
   * sent down.  With wait == 1, it waits for the previous flush.
   *
   * any device where the flush fails with eopnotsupp are flagged as not-barrier
   * capable
   */
  static int write_dev_flush(struct btrfs_device *device, int wait)
  {
  	struct bio *bio;
  	int ret = 0;
  
  	if (device->nobarriers)
  		return 0;
  
  	if (wait) {
  		bio = device->flush_bio;
  		if (!bio)
  			return 0;
  
  		wait_for_completion(&device->flush_wait);
  
  		if (bio_flagged(bio, BIO_EOPNOTSUPP)) {
  			printk("btrfs: disabling barriers on dev %s
  ",
  			       device->name);
  			device->nobarriers = 1;
  		}
  		if (!bio_flagged(bio, BIO_UPTODATE)) {
  			ret = -EIO;
  		}
  
  		/* drop the reference from the wait == 0 run */
  		bio_put(bio);
  		device->flush_bio = NULL;
  
  		return ret;
  	}
  
  	/*
  	 * one reference for us, and we leave it for the
  	 * caller
  	 */
  	device->flush_bio = NULL;;
  	bio = bio_alloc(GFP_NOFS, 0);
  	if (!bio)
  		return -ENOMEM;
  
  	bio->bi_end_io = btrfs_end_empty_barrier;
  	bio->bi_bdev = device->bdev;
  	init_completion(&device->flush_wait);
  	bio->bi_private = &device->flush_wait;
  	device->flush_bio = bio;
  
  	bio_get(bio);
  	submit_bio(WRITE_FLUSH, bio);
  
  	return 0;
  }
  
  /*
   * send an empty flush down to each device in parallel,
   * then wait for them
   */
  static int barrier_all_devices(struct btrfs_fs_info *info)
  {
  	struct list_head *head;
  	struct btrfs_device *dev;
  	int errors = 0;
  	int ret;
  
  	/* send down all the barriers */
  	head = &info->fs_devices->devices;
  	list_for_each_entry_rcu(dev, head, dev_list) {
  		if (!dev->bdev) {
  			errors++;
  			continue;
  		}
  		if (!dev->in_fs_metadata || !dev->writeable)
  			continue;
  
  		ret = write_dev_flush(dev, 0);
  		if (ret)
  			errors++;
  	}
  
  	/* wait for all the barriers */
  	list_for_each_entry_rcu(dev, head, dev_list) {
  		if (!dev->bdev) {
  			errors++;
  			continue;
  		}
  		if (!dev->in_fs_metadata || !dev->writeable)
  			continue;
  
  		ret = write_dev_flush(dev, 1);
  		if (ret)
  			errors++;
  	}
  	if (errors)
  		return -EIO;
  	return 0;
  }
a512bbf85   Yan Zheng   Btrfs: superblock...
2673
  int write_all_supers(struct btrfs_root *root, int max_mirrors)
f29844623   Chris Mason   Btrfs: Write out ...
2674
  {
e5e9a5206   Chris Mason   Btrfs: avoid race...
2675
  	struct list_head *head;
f29844623   Chris Mason   Btrfs: Write out ...
2676
  	struct btrfs_device *dev;
a061fc8da   Chris Mason   Btrfs: Add suppor...
2677
  	struct btrfs_super_block *sb;
f29844623   Chris Mason   Btrfs: Write out ...
2678
  	struct btrfs_dev_item *dev_item;
f29844623   Chris Mason   Btrfs: Write out ...
2679
2680
  	int ret;
  	int do_barriers;
a236aed14   Chris Mason   Btrfs: Deal with ...
2681
2682
  	int max_errors;
  	int total_errors = 0;
a061fc8da   Chris Mason   Btrfs: Add suppor...
2683
  	u64 flags;
f29844623   Chris Mason   Btrfs: Write out ...
2684

6c41761fc   David Sterba   btrfs: separate s...
2685
  	max_errors = btrfs_super_num_devices(root->fs_info->super_copy) - 1;
f29844623   Chris Mason   Btrfs: Write out ...
2686
  	do_barriers = !btrfs_test_opt(root, NOBARRIER);
af31f5e5b   Chris Mason   Btrfs: add a log ...
2687
  	backup_super_roots(root->fs_info);
f29844623   Chris Mason   Btrfs: Write out ...
2688

6c41761fc   David Sterba   btrfs: separate s...
2689
  	sb = root->fs_info->super_for_commit;
a061fc8da   Chris Mason   Btrfs: Add suppor...
2690
  	dev_item = &sb->dev_item;
e5e9a5206   Chris Mason   Btrfs: avoid race...
2691

174ba5091   Chris Mason   Btrfs: use the de...
2692
  	mutex_lock(&root->fs_info->fs_devices->device_list_mutex);
e5e9a5206   Chris Mason   Btrfs: avoid race...
2693
  	head = &root->fs_info->fs_devices->devices;
387125fc7   Chris Mason   Btrfs: fix barrie...
2694
2695
2696
  
  	if (do_barriers)
  		barrier_all_devices(root->fs_info);
1f78160ce   Xiao Guangrong   Btrfs: using rcu ...
2697
  	list_for_each_entry_rcu(dev, head, dev_list) {
dfe250206   Chris Mason   Btrfs: Add mount ...
2698
2699
2700
2701
  		if (!dev->bdev) {
  			total_errors++;
  			continue;
  		}
2b82032c3   Yan Zheng   Btrfs: Seed devic...
2702
  		if (!dev->in_fs_metadata || !dev->writeable)
dfe250206   Chris Mason   Btrfs: Add mount ...
2703
  			continue;
2b82032c3   Yan Zheng   Btrfs: Seed devic...
2704
  		btrfs_set_stack_device_generation(dev_item, 0);
a061fc8da   Chris Mason   Btrfs: Add suppor...
2705
2706
2707
2708
2709
2710
2711
2712
  		btrfs_set_stack_device_type(dev_item, dev->type);
  		btrfs_set_stack_device_id(dev_item, dev->devid);
  		btrfs_set_stack_device_total_bytes(dev_item, dev->total_bytes);
  		btrfs_set_stack_device_bytes_used(dev_item, dev->bytes_used);
  		btrfs_set_stack_device_io_align(dev_item, dev->io_align);
  		btrfs_set_stack_device_io_width(dev_item, dev->io_width);
  		btrfs_set_stack_device_sector_size(dev_item, dev->sector_size);
  		memcpy(dev_item->uuid, dev->uuid, BTRFS_UUID_SIZE);
2b82032c3   Yan Zheng   Btrfs: Seed devic...
2713
  		memcpy(dev_item->fsid, dev->fs_devices->fsid, BTRFS_UUID_SIZE);
a512bbf85   Yan Zheng   Btrfs: superblock...
2714

a061fc8da   Chris Mason   Btrfs: Add suppor...
2715
2716
  		flags = btrfs_super_flags(sb);
  		btrfs_set_super_flags(sb, flags | BTRFS_HEADER_FLAG_WRITTEN);
a512bbf85   Yan Zheng   Btrfs: superblock...
2717
  		ret = write_dev_supers(dev, sb, do_barriers, 0, max_mirrors);
a236aed14   Chris Mason   Btrfs: Deal with ...
2718
2719
  		if (ret)
  			total_errors++;
f29844623   Chris Mason   Btrfs: Write out ...
2720
  	}
a236aed14   Chris Mason   Btrfs: Deal with ...
2721
  	if (total_errors > max_errors) {
d397712bc   Chris Mason   Btrfs: Fix checkp...
2722
2723
2724
  		printk(KERN_ERR "btrfs: %d errors while writing supers
  ",
  		       total_errors);
a236aed14   Chris Mason   Btrfs: Deal with ...
2725
2726
  		BUG();
  	}
f29844623   Chris Mason   Btrfs: Write out ...
2727

a512bbf85   Yan Zheng   Btrfs: superblock...
2728
  	total_errors = 0;
1f78160ce   Xiao Guangrong   Btrfs: using rcu ...
2729
  	list_for_each_entry_rcu(dev, head, dev_list) {
dfe250206   Chris Mason   Btrfs: Add mount ...
2730
2731
  		if (!dev->bdev)
  			continue;
2b82032c3   Yan Zheng   Btrfs: Seed devic...
2732
  		if (!dev->in_fs_metadata || !dev->writeable)
dfe250206   Chris Mason   Btrfs: Add mount ...
2733
  			continue;
a512bbf85   Yan Zheng   Btrfs: superblock...
2734
2735
2736
  		ret = write_dev_supers(dev, sb, do_barriers, 1, max_mirrors);
  		if (ret)
  			total_errors++;
f29844623   Chris Mason   Btrfs: Write out ...
2737
  	}
174ba5091   Chris Mason   Btrfs: use the de...
2738
  	mutex_unlock(&root->fs_info->fs_devices->device_list_mutex);
a236aed14   Chris Mason   Btrfs: Deal with ...
2739
  	if (total_errors > max_errors) {
d397712bc   Chris Mason   Btrfs: Fix checkp...
2740
2741
2742
  		printk(KERN_ERR "btrfs: %d errors while writing supers
  ",
  		       total_errors);
a236aed14   Chris Mason   Btrfs: Deal with ...
2743
2744
  		BUG();
  	}
f29844623   Chris Mason   Btrfs: Write out ...
2745
2746
  	return 0;
  }
a512bbf85   Yan Zheng   Btrfs: superblock...
2747
2748
  int write_ctree_super(struct btrfs_trans_handle *trans,
  		      struct btrfs_root *root, int max_mirrors)
eb60ceac0   Chris Mason   Btrfs: Add backin...
2749
  {
e66f709b1   Chris Mason   Btrfs: write barr...
2750
  	int ret;
5f39d397d   Chris Mason   Btrfs: Create ext...
2751

a512bbf85   Yan Zheng   Btrfs: superblock...
2752
  	ret = write_all_supers(root, max_mirrors);
5f39d397d   Chris Mason   Btrfs: Create ext...
2753
  	return ret;
cfaa72952   Chris Mason   Btrfs: extent fixes
2754
  }
5eda7b5e9   Chris Mason   Btrfs: Add the ab...
2755
  int btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root)
2619ba1f0   Chris Mason   Btrfs: subvolumes
2756
  {
4df27c4d5   Yan, Zheng   Btrfs: change how...
2757
  	spin_lock(&fs_info->fs_roots_radix_lock);
2619ba1f0   Chris Mason   Btrfs: subvolumes
2758
2759
  	radix_tree_delete(&fs_info->fs_roots_radix,
  			  (unsigned long)root->root_key.objectid);
4df27c4d5   Yan, Zheng   Btrfs: change how...
2760
  	spin_unlock(&fs_info->fs_roots_radix_lock);
76dda93c6   Yan, Zheng   Btrfs: add snapsh...
2761
2762
2763
  
  	if (btrfs_root_refs(&root->root_item) == 0)
  		synchronize_srcu(&fs_info->subvol_srcu);
581bb0509   Li Zefan   Btrfs: Cache free...
2764
2765
  	__btrfs_remove_free_space_cache(root->free_ino_pinned);
  	__btrfs_remove_free_space_cache(root->free_ino_ctl);
4df27c4d5   Yan, Zheng   Btrfs: change how...
2766
2767
2768
2769
2770
2771
  	free_fs_root(root);
  	return 0;
  }
  
  static void free_fs_root(struct btrfs_root *root)
  {
82d5902d9   Li Zefan   Btrfs: Support re...
2772
  	iput(root->cache_inode);
4df27c4d5   Yan, Zheng   Btrfs: change how...
2773
  	WARN_ON(!RB_EMPTY_ROOT(&root->inode_tree));
0ee5dc676   Al Viro   btrfs: kill magic...
2774
2775
  	if (root->anon_dev)
  		free_anon_bdev(root->anon_dev);
4df27c4d5   Yan, Zheng   Btrfs: change how...
2776
2777
  	free_extent_buffer(root->node);
  	free_extent_buffer(root->commit_root);
581bb0509   Li Zefan   Btrfs: Cache free...
2778
2779
  	kfree(root->free_ino_ctl);
  	kfree(root->free_ino_pinned);
d397712bc   Chris Mason   Btrfs: Fix checkp...
2780
  	kfree(root->name);
2619ba1f0   Chris Mason   Btrfs: subvolumes
2781
  	kfree(root);
2619ba1f0   Chris Mason   Btrfs: subvolumes
2782
  }
35b7e4761   Chris Mason   Btrfs: fix page c...
2783
  static int del_fs_roots(struct btrfs_fs_info *fs_info)
0f7d52f44   Chris Mason   Btrfs: groundwork...
2784
2785
2786
2787
  {
  	int ret;
  	struct btrfs_root *gang[8];
  	int i;
76dda93c6   Yan, Zheng   Btrfs: add snapsh...
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
  	while (!list_empty(&fs_info->dead_roots)) {
  		gang[0] = list_entry(fs_info->dead_roots.next,
  				     struct btrfs_root, root_list);
  		list_del(&gang[0]->root_list);
  
  		if (gang[0]->in_radix) {
  			btrfs_free_fs_root(fs_info, gang[0]);
  		} else {
  			free_extent_buffer(gang[0]->node);
  			free_extent_buffer(gang[0]->commit_root);
  			kfree(gang[0]);
  		}
  	}
d397712bc   Chris Mason   Btrfs: Fix checkp...
2801
  	while (1) {
0f7d52f44   Chris Mason   Btrfs: groundwork...
2802
2803
2804
2805
2806
  		ret = radix_tree_gang_lookup(&fs_info->fs_roots_radix,
  					     (void **)gang, 0,
  					     ARRAY_SIZE(gang));
  		if (!ret)
  			break;
2619ba1f0   Chris Mason   Btrfs: subvolumes
2807
  		for (i = 0; i < ret; i++)
5eda7b5e9   Chris Mason   Btrfs: Add the ab...
2808
  			btrfs_free_fs_root(fs_info, gang[i]);
0f7d52f44   Chris Mason   Btrfs: groundwork...
2809
2810
2811
  	}
  	return 0;
  }
b4100d642   Chris Mason   Btrfs: add a devi...
2812

c146afad2   Yan Zheng   Btrfs: mount ro a...
2813
  int btrfs_cleanup_fs_roots(struct btrfs_fs_info *fs_info)
cfaa72952   Chris Mason   Btrfs: extent fixes
2814
  {
c146afad2   Yan Zheng   Btrfs: mount ro a...
2815
2816
2817
  	u64 root_objectid = 0;
  	struct btrfs_root *gang[8];
  	int i;
3768f3689   Chris Mason   Btrfs: Change the...
2818
  	int ret;
e089f05c1   Chris Mason   Btrfs: transactio...
2819

c146afad2   Yan Zheng   Btrfs: mount ro a...
2820
2821
2822
2823
2824
2825
  	while (1) {
  		ret = radix_tree_gang_lookup(&fs_info->fs_roots_radix,
  					     (void **)gang, root_objectid,
  					     ARRAY_SIZE(gang));
  		if (!ret)
  			break;
5d4f98a28   Yan Zheng   Btrfs: Mixed back...
2826
2827
  
  		root_objectid = gang[ret - 1]->root_key.objectid + 1;
c146afad2   Yan Zheng   Btrfs: mount ro a...
2828
  		for (i = 0; i < ret; i++) {
66b4ffd11   Josef Bacik   Btrfs: handle err...
2829
  			int err;
c146afad2   Yan Zheng   Btrfs: mount ro a...
2830
  			root_objectid = gang[i]->root_key.objectid;
66b4ffd11   Josef Bacik   Btrfs: handle err...
2831
2832
2833
  			err = btrfs_orphan_cleanup(gang[i]);
  			if (err)
  				return err;
c146afad2   Yan Zheng   Btrfs: mount ro a...
2834
2835
2836
2837
2838
  		}
  		root_objectid++;
  	}
  	return 0;
  }
a21350115   Chris Mason   Btrfs: Replace th...
2839

c146afad2   Yan Zheng   Btrfs: mount ro a...
2840
2841
2842
2843
  int btrfs_commit_super(struct btrfs_root *root)
  {
  	struct btrfs_trans_handle *trans;
  	int ret;
a74a4b97b   Chris Mason   Btrfs: Replace th...
2844

c146afad2   Yan Zheng   Btrfs: mount ro a...
2845
  	mutex_lock(&root->fs_info->cleaner_mutex);
24bbcf044   Yan, Zheng   Btrfs: Add delaye...
2846
  	btrfs_run_delayed_iputs(root);
a74a4b97b   Chris Mason   Btrfs: Replace th...
2847
  	btrfs_clean_old_snapshots(root);
c146afad2   Yan Zheng   Btrfs: mount ro a...
2848
  	mutex_unlock(&root->fs_info->cleaner_mutex);
c71bf099a   Yan, Zheng   Btrfs: Avoid orph...
2849
2850
2851
2852
  
  	/* wait until ongoing cleanup work done */
  	down_write(&root->fs_info->cleanup_work_sem);
  	up_write(&root->fs_info->cleanup_work_sem);
7a7eaa40a   Josef Bacik   Btrfs: take away ...
2853
  	trans = btrfs_join_transaction(root);
3612b4959   Tsutomu Itoh   btrfs: fix return...
2854
2855
  	if (IS_ERR(trans))
  		return PTR_ERR(trans);
54aa1f4df   Chris Mason   Btrfs: Audit call...
2856
  	ret = btrfs_commit_transaction(trans, root);
c146afad2   Yan Zheng   Btrfs: mount ro a...
2857
2858
  	BUG_ON(ret);
  	/* run commit again to drop the original snapshot */
7a7eaa40a   Josef Bacik   Btrfs: take away ...
2859
  	trans = btrfs_join_transaction(root);
3612b4959   Tsutomu Itoh   btrfs: fix return...
2860
2861
  	if (IS_ERR(trans))
  		return PTR_ERR(trans);
79154b1b5   Chris Mason   Btrfs: transactio...
2862
2863
  	btrfs_commit_transaction(trans, root);
  	ret = btrfs_write_and_wait_transaction(NULL, root);
3768f3689   Chris Mason   Btrfs: Change the...
2864
  	BUG_ON(ret);
d6bfde876   Chris Mason   Btrfs: Fixes for ...
2865

a512bbf85   Yan Zheng   Btrfs: superblock...
2866
  	ret = write_ctree_super(NULL, root, 0);
c146afad2   Yan Zheng   Btrfs: mount ro a...
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
  	return ret;
  }
  
  int close_ctree(struct btrfs_root *root)
  {
  	struct btrfs_fs_info *fs_info = root->fs_info;
  	int ret;
  
  	fs_info->closing = 1;
  	smp_mb();
a2de733c7   Arne Jansen   btrfs: scrub
2877
  	btrfs_scrub_cancel(root);
4cb5300bc   Chris Mason   Btrfs: add mount ...
2878
2879
2880
2881
2882
2883
2884
  
  	/* wait for any defraggers to finish */
  	wait_event(fs_info->transaction_wait,
  		   (atomic_read(&fs_info->defrag_running) == 0));
  
  	/* clear out the rbtree of defraggable inodes */
  	btrfs_run_defrag_inodes(root->fs_info);
acce952b0   liubo   Btrfs: forced rea...
2885
2886
2887
2888
2889
2890
2891
2892
2893
  	/*
  	 * Here come 2 situations when btrfs is broken to flip readonly:
  	 *
  	 * 1. when btrfs flips readonly somewhere else before
  	 * btrfs_commit_super, sb->s_flags has MS_RDONLY flag,
  	 * and btrfs will skip to write sb directly to keep
  	 * ERROR state on disk.
  	 *
  	 * 2. when btrfs flips readonly just in btrfs_commit_super,
ae0e47f02   Justin P. Mattock   Remove one to man...
2894
  	 * and in such case, btrfs cannot write sb via btrfs_commit_super,
acce952b0   liubo   Btrfs: forced rea...
2895
2896
2897
  	 * and since fs_state has been set BTRFS_SUPER_FLAG_ERROR flag,
  	 * btrfs will cleanup all FS resources first and write sb then.
  	 */
c146afad2   Yan Zheng   Btrfs: mount ro a...
2898
  	if (!(fs_info->sb->s_flags & MS_RDONLY)) {
acce952b0   liubo   Btrfs: forced rea...
2899
2900
2901
2902
2903
2904
2905
2906
  		ret = btrfs_commit_super(root);
  		if (ret)
  			printk(KERN_ERR "btrfs: commit super ret %d
  ", ret);
  	}
  
  	if (fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) {
  		ret = btrfs_error_commit_super(root);
d397712bc   Chris Mason   Btrfs: Fix checkp...
2907
2908
2909
  		if (ret)
  			printk(KERN_ERR "btrfs: commit super ret %d
  ", ret);
c146afad2   Yan Zheng   Btrfs: mount ro a...
2910
  	}
0f7d52f44   Chris Mason   Btrfs: groundwork...
2911

300e4f8a5   Josef Bacik   Btrfs: put the bl...
2912
  	btrfs_put_block_group_cache(fs_info);
8929ecfa5   Yan, Zheng   Btrfs: Introduce ...
2913
2914
  	kthread_stop(root->fs_info->transaction_kthread);
  	kthread_stop(root->fs_info->cleaner_kthread);
f25784b35   Yan Zheng   Btrfs: Fix async ...
2915
2916
  	fs_info->closing = 2;
  	smp_mb();
b0c68f8be   Chris Mason   Btrfs: Enable del...
2917
  	if (fs_info->delalloc_bytes) {
d397712bc   Chris Mason   Btrfs: Fix checkp...
2918
2919
  		printk(KERN_INFO "btrfs: at unmount delalloc count %llu
  ",
21380931e   Joel Becker   Btrfs: Fix a bunc...
2920
  		       (unsigned long long)fs_info->delalloc_bytes);
b0c68f8be   Chris Mason   Btrfs: Enable del...
2921
  	}
31153d812   Yan Zheng   Btrfs: Add a leaf...
2922
  	if (fs_info->total_ref_cache_size) {
d397712bc   Chris Mason   Btrfs: Fix checkp...
2923
2924
2925
  		printk(KERN_INFO "btrfs: at umount reference cache size %llu
  ",
  		       (unsigned long long)fs_info->total_ref_cache_size);
31153d812   Yan Zheng   Btrfs: Add a leaf...
2926
  	}
bcc63abbf   Yan   Btrfs: implement ...
2927

5d4f98a28   Yan Zheng   Btrfs: Mixed back...
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
  	free_extent_buffer(fs_info->extent_root->node);
  	free_extent_buffer(fs_info->extent_root->commit_root);
  	free_extent_buffer(fs_info->tree_root->node);
  	free_extent_buffer(fs_info->tree_root->commit_root);
  	free_extent_buffer(root->fs_info->chunk_root->node);
  	free_extent_buffer(root->fs_info->chunk_root->commit_root);
  	free_extent_buffer(root->fs_info->dev_root->node);
  	free_extent_buffer(root->fs_info->dev_root->commit_root);
  	free_extent_buffer(root->fs_info->csum_root->node);
  	free_extent_buffer(root->fs_info->csum_root->commit_root);
d20f7043f   Chris Mason   Btrfs: move data ...
2938

9078a3e1e   Chris Mason   Btrfs: start of b...
2939
  	btrfs_free_block_groups(root->fs_info);
d10c5f31c   Chris Mason   Btrfs: Fix extent...
2940

c146afad2   Yan Zheng   Btrfs: mount ro a...
2941
  	del_fs_roots(fs_info);
d10c5f31c   Chris Mason   Btrfs: Fix extent...
2942

c146afad2   Yan Zheng   Btrfs: mount ro a...
2943
  	iput(fs_info->btree_inode);
9ad6b7bc2   Chris Mason   Force page->priva...
2944

61d92c328   Chris Mason   Btrfs: fix deadlo...
2945
  	btrfs_stop_workers(&fs_info->generic_worker);
247e743cb   Chris Mason   Btrfs: Use async ...
2946
  	btrfs_stop_workers(&fs_info->fixup_workers);
771ed689d   Chris Mason   Btrfs: Optimize c...
2947
  	btrfs_stop_workers(&fs_info->delalloc_workers);
8b7128429   Chris Mason   Btrfs: Add async ...
2948
2949
  	btrfs_stop_workers(&fs_info->workers);
  	btrfs_stop_workers(&fs_info->endio_workers);
d20f7043f   Chris Mason   Btrfs: move data ...
2950
  	btrfs_stop_workers(&fs_info->endio_meta_workers);
cad321ad5   Chris Mason   Btrfs: shift all ...
2951
  	btrfs_stop_workers(&fs_info->endio_meta_write_workers);
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
2952
  	btrfs_stop_workers(&fs_info->endio_write_workers);
0cb59c995   Josef Bacik   Btrfs: write out ...
2953
  	btrfs_stop_workers(&fs_info->endio_freespace_worker);
1cc127b5d   Chris Mason   Btrfs: Add a thre...
2954
  	btrfs_stop_workers(&fs_info->submit_workers);
16cdcec73   Miao Xie   btrfs: implement ...
2955
  	btrfs_stop_workers(&fs_info->delayed_workers);
bab39bf99   Josef Bacik   Btrfs: use a work...
2956
  	btrfs_stop_workers(&fs_info->caching_workers);
90519d66a   Arne Jansen   btrfs: state info...
2957
  	btrfs_stop_workers(&fs_info->readahead_workers);
d6bfde876   Chris Mason   Btrfs: Fixes for ...
2958

dfe250206   Chris Mason   Btrfs: Add mount ...
2959
  	btrfs_close_devices(fs_info->fs_devices);
0b86a832a   Chris Mason   Btrfs: Add suppor...
2960
  	btrfs_mapping_tree_free(&fs_info->mapping_tree);
b248a4152   Chris Mason   Btrfs: A few upda...
2961

041600881   Chris Mason   Create a btrfs ba...
2962
  	bdi_destroy(&fs_info->bdi);
76dda93c6   Yan, Zheng   Btrfs: add snapsh...
2963
  	cleanup_srcu_struct(&fs_info->subvol_srcu);
0b86a832a   Chris Mason   Btrfs: Add suppor...
2964

6c41761fc   David Sterba   btrfs: separate s...
2965
  	free_fs_info(fs_info);
83a4d5484   Li Zefan   Btrfs: Fix memory...
2966

eb60ceac0   Chris Mason   Btrfs: Add backin...
2967
2968
  	return 0;
  }
1259ab75c   Chris Mason   Btrfs: Handle wri...
2969
  int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid)
5f39d397d   Chris Mason   Btrfs: Create ext...
2970
  {
1259ab75c   Chris Mason   Btrfs: Handle wri...
2971
  	int ret;
810191ff3   Chris Mason   Btrfs: extent_map...
2972
  	struct inode *btree_inode = buf->first_page->mapping->host;
1259ab75c   Chris Mason   Btrfs: Handle wri...
2973

2ac55d41b   Josef Bacik   Btrfs: cache the ...
2974
2975
  	ret = extent_buffer_uptodate(&BTRFS_I(btree_inode)->io_tree, buf,
  				     NULL);
1259ab75c   Chris Mason   Btrfs: Handle wri...
2976
2977
2978
2979
2980
2981
  	if (!ret)
  		return ret;
  
  	ret = verify_parent_transid(&BTRFS_I(btree_inode)->io_tree, buf,
  				    parent_transid);
  	return !ret;
5f39d397d   Chris Mason   Btrfs: Create ext...
2982
2983
2984
  }
  
  int btrfs_set_buffer_uptodate(struct extent_buffer *buf)
ccd467d60   Chris Mason   Btrfs: crash reco...
2985
  {
810191ff3   Chris Mason   Btrfs: extent_map...
2986
  	struct inode *btree_inode = buf->first_page->mapping->host;
d1310b2e0   Chris Mason   Btrfs: Split the ...
2987
  	return set_extent_buffer_uptodate(&BTRFS_I(btree_inode)->io_tree,
5f39d397d   Chris Mason   Btrfs: Create ext...
2988
2989
  					  buf);
  }
6702ed490   Chris Mason   Btrfs: Add run ti...
2990

5f39d397d   Chris Mason   Btrfs: Create ext...
2991
2992
  void btrfs_mark_buffer_dirty(struct extent_buffer *buf)
  {
810191ff3   Chris Mason   Btrfs: extent_map...
2993
  	struct btrfs_root *root = BTRFS_I(buf->first_page->mapping->host)->root;
5f39d397d   Chris Mason   Btrfs: Create ext...
2994
2995
  	u64 transid = btrfs_header_generation(buf);
  	struct inode *btree_inode = root->fs_info->btree_inode;
b9473439d   Chris Mason   Btrfs: leave btre...
2996
  	int was_dirty;
b4ce94de9   Chris Mason   Btrfs: Change btr...
2997

b9447ef80   Chris Mason   Btrfs: fix spinlo...
2998
  	btrfs_assert_tree_locked(buf);
ccd467d60   Chris Mason   Btrfs: crash reco...
2999
  	if (transid != root->fs_info->generation) {
d397712bc   Chris Mason   Btrfs: Fix checkp...
3000
3001
3002
  		printk(KERN_CRIT "btrfs transid mismatch buffer %llu, "
  		       "found %llu running %llu
  ",
db94535db   Chris Mason   Btrfs: Allow tree...
3003
  			(unsigned long long)buf->start,
d397712bc   Chris Mason   Btrfs: Fix checkp...
3004
3005
  			(unsigned long long)transid,
  			(unsigned long long)root->fs_info->generation);
ccd467d60   Chris Mason   Btrfs: crash reco...
3006
3007
  		WARN_ON(1);
  	}
b9473439d   Chris Mason   Btrfs: leave btre...
3008
3009
3010
3011
3012
3013
3014
  	was_dirty = set_extent_buffer_dirty(&BTRFS_I(btree_inode)->io_tree,
  					    buf);
  	if (!was_dirty) {
  		spin_lock(&root->fs_info->delalloc_lock);
  		root->fs_info->dirty_metadata_bytes += buf->len;
  		spin_unlock(&root->fs_info->delalloc_lock);
  	}
eb60ceac0   Chris Mason   Btrfs: Add backin...
3015
  }
d3c2fdcf7   Chris Mason   Btrfs: Use balanc...
3016
  void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr)
35b7e4761   Chris Mason   Btrfs: fix page c...
3017
  {
188de649c   Chris Mason   Btrfs: Don't do b...
3018
3019
  	/*
  	 * looks as though older kernels can get into trouble with
16cdcec73   Miao Xie   btrfs: implement ...
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
  	 * this code, they end up stuck in balance_dirty_pages forever
  	 */
  	u64 num_dirty;
  	unsigned long thresh = 32 * 1024 * 1024;
  
  	if (current->flags & PF_MEMALLOC)
  		return;
  
  	btrfs_balance_delayed_items(root);
  
  	num_dirty = root->fs_info->dirty_metadata_bytes;
  
  	if (num_dirty > thresh) {
  		balance_dirty_pages_ratelimited_nr(
  				   root->fs_info->btree_inode->i_mapping, 1);
  	}
  	return;
  }
  
  void __btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr)
  {
  	/*
  	 * looks as though older kernels can get into trouble with
188de649c   Chris Mason   Btrfs: Don't do b...
3043
3044
  	 * this code, they end up stuck in balance_dirty_pages forever
  	 */
d6bfde876   Chris Mason   Btrfs: Fixes for ...
3045
  	u64 num_dirty;
771ed689d   Chris Mason   Btrfs: Optimize c...
3046
  	unsigned long thresh = 32 * 1024 * 1024;
d6bfde876   Chris Mason   Btrfs: Fixes for ...
3047

6933c02e9   Jens Axboe   btrfs: get rid of...
3048
  	if (current->flags & PF_MEMALLOC)
d6bfde876   Chris Mason   Btrfs: Fixes for ...
3049
  		return;
585ad2c37   Chris Mason   Btrfs: fix metada...
3050
  	num_dirty = root->fs_info->dirty_metadata_bytes;
d6bfde876   Chris Mason   Btrfs: Fixes for ...
3051
3052
  	if (num_dirty > thresh) {
  		balance_dirty_pages_ratelimited_nr(
d7fc640e6   Chris Mason   Btrfs: Allocator ...
3053
  				   root->fs_info->btree_inode->i_mapping, 1);
d6bfde876   Chris Mason   Btrfs: Fixes for ...
3054
  	}
188de649c   Chris Mason   Btrfs: Don't do b...
3055
  	return;
35b7e4761   Chris Mason   Btrfs: fix page c...
3056
  }
6b80053d0   Chris Mason   Btrfs: Add back t...
3057

ca7a79ad8   Chris Mason   Btrfs: Pass down ...
3058
  int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid)
6b80053d0   Chris Mason   Btrfs: Add back t...
3059
  {
810191ff3   Chris Mason   Btrfs: extent_map...
3060
  	struct btrfs_root *root = BTRFS_I(buf->first_page->mapping->host)->root;
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
3061
  	int ret;
ca7a79ad8   Chris Mason   Btrfs: Pass down ...
3062
  	ret = btree_read_extent_buffer_pages(root, buf, 0, parent_transid);
d397712bc   Chris Mason   Btrfs: Fix checkp...
3063
  	if (ret == 0)
b4ce94de9   Chris Mason   Btrfs: Change btr...
3064
  		set_bit(EXTENT_BUFFER_UPTODATE, &buf->bflags);
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
3065
  	return ret;
6b80053d0   Chris Mason   Btrfs: Add back t...
3066
  }
0da5468f4   Chris Mason   Btrfs: Use writep...
3067

01d658f2c   Chris Mason   Btrfs: make sure ...
3068
3069
  static int btree_lock_page_hook(struct page *page, void *data,
  				void (*flush_fn)(void *))
4bef08485   Chris Mason   Btrfs: Tree loggi...
3070
3071
  {
  	struct inode *inode = page->mapping->host;
b9473439d   Chris Mason   Btrfs: leave btre...
3072
  	struct btrfs_root *root = BTRFS_I(inode)->root;
4bef08485   Chris Mason   Btrfs: Tree loggi...
3073
3074
3075
3076
3077
3078
3079
3080
3081
  	struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
  	struct extent_buffer *eb;
  	unsigned long len;
  	u64 bytenr = page_offset(page);
  
  	if (page->private == EXTENT_PAGE_PRIVATE)
  		goto out;
  
  	len = page->private >> 2;
f09d1f60e   David Sterba   btrfs: drop gfp p...
3082
  	eb = find_extent_buffer(io_tree, bytenr, len);
4bef08485   Chris Mason   Btrfs: Tree loggi...
3083
3084
  	if (!eb)
  		goto out;
01d658f2c   Chris Mason   Btrfs: make sure ...
3085
3086
3087
3088
  	if (!btrfs_try_tree_write_lock(eb)) {
  		flush_fn(data);
  		btrfs_tree_lock(eb);
  	}
4bef08485   Chris Mason   Btrfs: Tree loggi...
3089
  	btrfs_set_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN);
b9473439d   Chris Mason   Btrfs: leave btre...
3090
3091
3092
3093
3094
3095
3096
3097
3098
  
  	if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &eb->bflags)) {
  		spin_lock(&root->fs_info->delalloc_lock);
  		if (root->fs_info->dirty_metadata_bytes >= eb->len)
  			root->fs_info->dirty_metadata_bytes -= eb->len;
  		else
  			WARN_ON(1);
  		spin_unlock(&root->fs_info->delalloc_lock);
  	}
4bef08485   Chris Mason   Btrfs: Tree loggi...
3099
3100
3101
  	btrfs_tree_unlock(eb);
  	free_extent_buffer(eb);
  out:
01d658f2c   Chris Mason   Btrfs: make sure ...
3102
3103
3104
3105
  	if (!trylock_page(page)) {
  		flush_fn(data);
  		lock_page(page);
  	}
4bef08485   Chris Mason   Btrfs: Tree loggi...
3106
3107
  	return 0;
  }
acce952b0   liubo   Btrfs: forced rea...
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
  static void btrfs_check_super_valid(struct btrfs_fs_info *fs_info,
  			      int read_only)
  {
  	if (read_only)
  		return;
  
  	if (fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR)
  		printk(KERN_WARNING "warning: mount fs with errors, "
  		       "running btrfsck is recommended
  ");
  }
  
  int btrfs_error_commit_super(struct btrfs_root *root)
  {
  	int ret;
  
  	mutex_lock(&root->fs_info->cleaner_mutex);
  	btrfs_run_delayed_iputs(root);
  	mutex_unlock(&root->fs_info->cleaner_mutex);
  
  	down_write(&root->fs_info->cleanup_work_sem);
  	up_write(&root->fs_info->cleanup_work_sem);
  
  	/* cleanup FS via transaction */
  	btrfs_cleanup_transaction(root);
  
  	ret = write_ctree_super(NULL, root, 0);
  
  	return ret;
  }
  
  static int btrfs_destroy_ordered_operations(struct btrfs_root *root)
  {
  	struct btrfs_inode *btrfs_inode;
  	struct list_head splice;
  
  	INIT_LIST_HEAD(&splice);
  
  	mutex_lock(&root->fs_info->ordered_operations_mutex);
  	spin_lock(&root->fs_info->ordered_extent_lock);
  
  	list_splice_init(&root->fs_info->ordered_operations, &splice);
  	while (!list_empty(&splice)) {
  		btrfs_inode = list_entry(splice.next, struct btrfs_inode,
  					 ordered_operations);
  
  		list_del_init(&btrfs_inode->ordered_operations);
  
  		btrfs_invalidate_inodes(btrfs_inode->root);
  	}
  
  	spin_unlock(&root->fs_info->ordered_extent_lock);
  	mutex_unlock(&root->fs_info->ordered_operations_mutex);
  
  	return 0;
  }
  
  static int btrfs_destroy_ordered_extents(struct btrfs_root *root)
  {
  	struct list_head splice;
  	struct btrfs_ordered_extent *ordered;
  	struct inode *inode;
  
  	INIT_LIST_HEAD(&splice);
  
  	spin_lock(&root->fs_info->ordered_extent_lock);
  
  	list_splice_init(&root->fs_info->ordered_extents, &splice);
  	while (!list_empty(&splice)) {
  		ordered = list_entry(splice.next, struct btrfs_ordered_extent,
  				     root_extent_list);
  
  		list_del_init(&ordered->root_extent_list);
  		atomic_inc(&ordered->refs);
  
  		/* the inode may be getting freed (in sys_unlink path). */
  		inode = igrab(ordered->inode);
  
  		spin_unlock(&root->fs_info->ordered_extent_lock);
  		if (inode)
  			iput(inode);
  
  		atomic_set(&ordered->refs, 1);
  		btrfs_put_ordered_extent(ordered);
  
  		spin_lock(&root->fs_info->ordered_extent_lock);
  	}
  
  	spin_unlock(&root->fs_info->ordered_extent_lock);
  
  	return 0;
  }
  
  static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans,
  				      struct btrfs_root *root)
  {
  	struct rb_node *node;
  	struct btrfs_delayed_ref_root *delayed_refs;
  	struct btrfs_delayed_ref_node *ref;
  	int ret = 0;
  
  	delayed_refs = &trans->delayed_refs;
  
  	spin_lock(&delayed_refs->lock);
  	if (delayed_refs->num_entries == 0) {
cfece4db1   David Sterba   btrfs: add missin...
3213
  		spin_unlock(&delayed_refs->lock);
acce952b0   liubo   Btrfs: forced rea...
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
  		printk(KERN_INFO "delayed_refs has NO entry
  ");
  		return ret;
  	}
  
  	node = rb_first(&delayed_refs->root);
  	while (node) {
  		ref = rb_entry(node, struct btrfs_delayed_ref_node, rb_node);
  		node = rb_next(node);
  
  		ref->in_tree = 0;
  		rb_erase(&ref->rb_node, &delayed_refs->root);
  		delayed_refs->num_entries--;
  
  		atomic_set(&ref->refs, 1);
  		if (btrfs_delayed_ref_is_head(ref)) {
  			struct btrfs_delayed_ref_head *head;
  
  			head = btrfs_delayed_node_to_head(ref);
  			mutex_lock(&head->mutex);
  			kfree(head->extent_op);
  			delayed_refs->num_heads--;
  			if (list_empty(&head->cluster))
  				delayed_refs->num_heads_ready--;
  			list_del_init(&head->cluster);
  			mutex_unlock(&head->mutex);
  		}
  
  		spin_unlock(&delayed_refs->lock);
  		btrfs_put_delayed_ref(ref);
  
  		cond_resched();
  		spin_lock(&delayed_refs->lock);
  	}
  
  	spin_unlock(&delayed_refs->lock);
  
  	return ret;
  }
  
  static int btrfs_destroy_pending_snapshots(struct btrfs_transaction *t)
  {
  	struct btrfs_pending_snapshot *snapshot;
  	struct list_head splice;
  
  	INIT_LIST_HEAD(&splice);
  
  	list_splice_init(&t->pending_snapshots, &splice);
  
  	while (!list_empty(&splice)) {
  		snapshot = list_entry(splice.next,
  				      struct btrfs_pending_snapshot,
  				      list);
  
  		list_del_init(&snapshot->list);
  
  		kfree(snapshot);
  	}
  
  	return 0;
  }
  
  static int btrfs_destroy_delalloc_inodes(struct btrfs_root *root)
  {
  	struct btrfs_inode *btrfs_inode;
  	struct list_head splice;
  
  	INIT_LIST_HEAD(&splice);
acce952b0   liubo   Btrfs: forced rea...
3282
  	spin_lock(&root->fs_info->delalloc_lock);
5be76758f   David Sterba   btrfs: fix unlock...
3283
  	list_splice_init(&root->fs_info->delalloc_inodes, &splice);
acce952b0   liubo   Btrfs: forced rea...
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
  
  	while (!list_empty(&splice)) {
  		btrfs_inode = list_entry(splice.next, struct btrfs_inode,
  				    delalloc_inodes);
  
  		list_del_init(&btrfs_inode->delalloc_inodes);
  
  		btrfs_invalidate_inodes(btrfs_inode->root);
  	}
  
  	spin_unlock(&root->fs_info->delalloc_lock);
  
  	return 0;
  }
  
  static int btrfs_destroy_marked_extents(struct btrfs_root *root,
  					struct extent_io_tree *dirty_pages,
  					int mark)
  {
  	int ret;
  	struct page *page;
  	struct inode *btree_inode = root->fs_info->btree_inode;
  	struct extent_buffer *eb;
  	u64 start = 0;
  	u64 end;
  	u64 offset;
  	unsigned long index;
  
  	while (1) {
  		ret = find_first_extent_bit(dirty_pages, start, &start, &end,
  					    mark);
  		if (ret)
  			break;
  
  		clear_extent_bits(dirty_pages, start, end, mark, GFP_NOFS);
  		while (start <= end) {
  			index = start >> PAGE_CACHE_SHIFT;
  			start = (u64)(index + 1) << PAGE_CACHE_SHIFT;
  			page = find_get_page(btree_inode->i_mapping, index);
  			if (!page)
  				continue;
  			offset = page_offset(page);
  
  			spin_lock(&dirty_pages->buffer_lock);
  			eb = radix_tree_lookup(
  			     &(&BTRFS_I(page->mapping->host)->io_tree)->buffer,
  					       offset >> PAGE_CACHE_SHIFT);
  			spin_unlock(&dirty_pages->buffer_lock);
  			if (eb) {
  				ret = test_and_clear_bit(EXTENT_BUFFER_DIRTY,
  							 &eb->bflags);
  				atomic_set(&eb->refs, 1);
  			}
  			if (PageWriteback(page))
  				end_page_writeback(page);
  
  			lock_page(page);
  			if (PageDirty(page)) {
  				clear_page_dirty_for_io(page);
  				spin_lock_irq(&page->mapping->tree_lock);
  				radix_tree_tag_clear(&page->mapping->page_tree,
  							page_index(page),
  							PAGECACHE_TAG_DIRTY);
  				spin_unlock_irq(&page->mapping->tree_lock);
  			}
  
  			page->mapping->a_ops->invalidatepage(page, 0);
  			unlock_page(page);
  		}
  	}
  
  	return ret;
  }
  
  static int btrfs_destroy_pinned_extent(struct btrfs_root *root,
  				       struct extent_io_tree *pinned_extents)
  {
  	struct extent_io_tree *unpin;
  	u64 start;
  	u64 end;
  	int ret;
  
  	unpin = pinned_extents;
  	while (1) {
  		ret = find_first_extent_bit(unpin, 0, &start, &end,
  					    EXTENT_DIRTY);
  		if (ret)
  			break;
  
  		/* opt_discard */
5378e6073   Li Dongyang   Btrfs: adjust btr...
3374
3375
3376
3377
  		if (btrfs_test_opt(root, DISCARD))
  			ret = btrfs_error_discard_extent(root, start,
  							 end + 1 - start,
  							 NULL);
acce952b0   liubo   Btrfs: forced rea...
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
  
  		clear_extent_dirty(unpin, start, end, GFP_NOFS);
  		btrfs_error_unpin_extent_range(root, start, end);
  		cond_resched();
  	}
  
  	return 0;
  }
  
  static int btrfs_cleanup_transaction(struct btrfs_root *root)
  {
  	struct btrfs_transaction *t;
  	LIST_HEAD(list);
  
  	WARN_ON(1);
acce952b0   liubo   Btrfs: forced rea...
3393
  	mutex_lock(&root->fs_info->transaction_kthread_mutex);
a4abeea41   Josef Bacik   Btrfs: kill trans...
3394
  	spin_lock(&root->fs_info->trans_lock);
acce952b0   liubo   Btrfs: forced rea...
3395
  	list_splice_init(&root->fs_info->trans_list, &list);
a4abeea41   Josef Bacik   Btrfs: kill trans...
3396
3397
  	root->fs_info->trans_no_join = 1;
  	spin_unlock(&root->fs_info->trans_lock);
acce952b0   liubo   Btrfs: forced rea...
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
  	while (!list_empty(&list)) {
  		t = list_entry(list.next, struct btrfs_transaction, list);
  		if (!t)
  			break;
  
  		btrfs_destroy_ordered_operations(root);
  
  		btrfs_destroy_ordered_extents(root);
  
  		btrfs_destroy_delayed_refs(t, root);
  
  		btrfs_block_rsv_release(root,
  					&root->fs_info->trans_block_rsv,
  					t->dirty_pages.dirty_bytes);
  
  		/* FIXME: cleanup wait for commit */
  		t->in_commit = 1;
  		t->blocked = 1;
  		if (waitqueue_active(&root->fs_info->transaction_blocked_wait))
  			wake_up(&root->fs_info->transaction_blocked_wait);
  
  		t->blocked = 0;
  		if (waitqueue_active(&root->fs_info->transaction_wait))
  			wake_up(&root->fs_info->transaction_wait);
acce952b0   liubo   Btrfs: forced rea...
3422

acce952b0   liubo   Btrfs: forced rea...
3423
3424
3425
  		t->commit_done = 1;
  		if (waitqueue_active(&t->commit_wait))
  			wake_up(&t->commit_wait);
acce952b0   liubo   Btrfs: forced rea...
3426
3427
3428
3429
  
  		btrfs_destroy_pending_snapshots(t);
  
  		btrfs_destroy_delalloc_inodes(root);
a4abeea41   Josef Bacik   Btrfs: kill trans...
3430
  		spin_lock(&root->fs_info->trans_lock);
acce952b0   liubo   Btrfs: forced rea...
3431
  		root->fs_info->running_transaction = NULL;
a4abeea41   Josef Bacik   Btrfs: kill trans...
3432
  		spin_unlock(&root->fs_info->trans_lock);
acce952b0   liubo   Btrfs: forced rea...
3433
3434
3435
3436
3437
3438
  
  		btrfs_destroy_marked_extents(root, &t->dirty_pages,
  					     EXTENT_DIRTY);
  
  		btrfs_destroy_pinned_extent(root,
  					    root->fs_info->pinned_extents);
13c5a93e7   Josef Bacik   Btrfs: avoid taki...
3439
  		atomic_set(&t->use_count, 0);
acce952b0   liubo   Btrfs: forced rea...
3440
3441
3442
3443
  		list_del_init(&t->list);
  		memset(t, 0, sizeof(*t));
  		kmem_cache_free(btrfs_transaction_cachep, t);
  	}
a4abeea41   Josef Bacik   Btrfs: kill trans...
3444
3445
3446
  	spin_lock(&root->fs_info->trans_lock);
  	root->fs_info->trans_no_join = 0;
  	spin_unlock(&root->fs_info->trans_lock);
acce952b0   liubo   Btrfs: forced rea...
3447
  	mutex_unlock(&root->fs_info->transaction_kthread_mutex);
acce952b0   liubo   Btrfs: forced rea...
3448
3449
3450
  
  	return 0;
  }
d1310b2e0   Chris Mason   Btrfs: Split the ...
3451
  static struct extent_io_ops btree_extent_io_ops = {
4bef08485   Chris Mason   Btrfs: Tree loggi...
3452
  	.write_cache_pages_lock_hook = btree_lock_page_hook,
ce9adaa5a   Chris Mason   Btrfs: Do metadat...
3453
  	.readpage_end_io_hook = btree_readpage_end_io_hook,
4bb31e928   Arne Jansen   btrfs: hooks for ...
3454
  	.readpage_io_failed_hook = btree_io_failed_hook,
0b86a832a   Chris Mason   Btrfs: Add suppor...
3455
  	.submit_bio_hook = btree_submit_bio_hook,
239b14b32   Chris Mason   Btrfs: Bring back...
3456
3457
  	/* note we're sharing with inode.c for the merge bio hook */
  	.merge_bio_hook = btrfs_merge_bio_hook,
0da5468f4   Chris Mason   Btrfs: Use writep...
3458
  };