aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorZheng Yan <zheng.yan@oracle.com>2008-09-26 10:05:38 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-26 10:05:38 -0400
commit5b21f2ed3f2947b5195b65c9fdbdd9e52904cc03 (patch)
tree9af8f539ac487c163f3207bc065767c3c8b37ae7 /fs
parente465768938f95388723b0fd3c50a0ae48173edb9 (diff)
Btrfs: extent_map and data=ordered fixes for space balancing
* Add an EXTENT_BOUNDARY state bit to keep the writepage code from merging data extents that are in the process of being relocated. This allows us to do accounting for them properly. * The balancing code relocates data extents indepdent of the underlying inode. The extent_map code was modified to properly account for things moving around (invalidating extent_map caches in the inode). * Don't take the drop_mutex in the create_subvol ioctl. It isn't required. * Fix walking of the ordered extent list to avoid races with sys_unlink * Change the lock ordering rules. Transaction start goes outside the drop_mutex. This allows btrfs_commit_transaction to directly drop the relocation trees. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/ctree.c9
-rw-r--r--fs/btrfs/ctree.h11
-rw-r--r--fs/btrfs/extent_io.c13
-rw-r--r--fs/btrfs/extent_io.h1
-rw-r--r--fs/btrfs/file.c31
-rw-r--r--fs/btrfs/inode-map.c4
-rw-r--r--fs/btrfs/inode.c52
-rw-r--r--fs/btrfs/ioctl.c2
-rw-r--r--fs/btrfs/ordered-data.c26
-rw-r--r--fs/btrfs/transaction.c8
10 files changed, 108 insertions, 49 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 50aea8cb653a..f9cd40967d04 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -290,7 +290,6 @@ int noinline btrfs_cow_block(struct btrfs_trans_handle *trans,
290 struct extent_buffer **cow_ret, u64 prealloc_dest) 290 struct extent_buffer **cow_ret, u64 prealloc_dest)
291{ 291{
292 u64 search_start; 292 u64 search_start;
293 u64 header_trans;
294 int ret; 293 int ret;
295 294
296 if (trans->transaction != root->fs_info->running_transaction) { 295 if (trans->transaction != root->fs_info->running_transaction) {
@@ -304,9 +303,9 @@ int noinline btrfs_cow_block(struct btrfs_trans_handle *trans,
304 WARN_ON(1); 303 WARN_ON(1);
305 } 304 }
306 305
307 header_trans = btrfs_header_generation(buf);
308 spin_lock(&root->fs_info->hash_lock); 306 spin_lock(&root->fs_info->hash_lock);
309 if (header_trans == trans->transid && 307 if (btrfs_header_generation(buf) == trans->transid &&
308 btrfs_header_owner(buf) == root->root_key.objectid &&
310 !btrfs_header_flag(buf, BTRFS_HEADER_FLAG_WRITTEN)) { 309 !btrfs_header_flag(buf, BTRFS_HEADER_FLAG_WRITTEN)) {
311 *cow_ret = buf; 310 *cow_ret = buf;
312 spin_unlock(&root->fs_info->hash_lock); 311 spin_unlock(&root->fs_info->hash_lock);
@@ -1300,6 +1299,7 @@ again:
1300 /* is a cow on this block not required */ 1299 /* is a cow on this block not required */
1301 spin_lock(&root->fs_info->hash_lock); 1300 spin_lock(&root->fs_info->hash_lock);
1302 if (btrfs_header_generation(b) == trans->transid && 1301 if (btrfs_header_generation(b) == trans->transid &&
1302 btrfs_header_owner(b) == root->root_key.objectid &&
1303 !btrfs_header_flag(b, BTRFS_HEADER_FLAG_WRITTEN)) { 1303 !btrfs_header_flag(b, BTRFS_HEADER_FLAG_WRITTEN)) {
1304 spin_unlock(&root->fs_info->hash_lock); 1304 spin_unlock(&root->fs_info->hash_lock);
1305 goto cow_done; 1305 goto cow_done;
@@ -1396,7 +1396,8 @@ cow_done:
1396 1396
1397 /* this is only true while dropping a snapshot */ 1397 /* this is only true while dropping a snapshot */
1398 if (level == lowest_level) { 1398 if (level == lowest_level) {
1399 break; 1399 ret = 0;
1400 goto done;
1400 } 1401 }
1401 1402
1402 blocknr = btrfs_node_blockptr(b, slot); 1403 blocknr = btrfs_node_blockptr(b, slot);
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index b9f9f815ed09..3e62a1b0a1f7 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -1486,6 +1486,9 @@ static inline struct dentry *fdentry(struct file *file)
1486 1486
1487/* extent-tree.c */ 1487/* extent-tree.c */
1488int btrfs_lookup_extent(struct btrfs_root *root, u64 start, u64 len); 1488int btrfs_lookup_extent(struct btrfs_root *root, u64 start, u64 len);
1489int btrfs_lookup_extent_ref(struct btrfs_trans_handle *trans,
1490 struct btrfs_root *root, u64 bytenr,
1491 u64 num_bytes, u32 *refs);
1489int btrfs_update_pinned_extents(struct btrfs_root *root, 1492int btrfs_update_pinned_extents(struct btrfs_root *root,
1490 u64 bytenr, u64 num, int pin); 1493 u64 bytenr, u64 num, int pin);
1491int btrfs_drop_leaf_ref(struct btrfs_trans_handle *trans, 1494int btrfs_drop_leaf_ref(struct btrfs_trans_handle *trans,
@@ -1812,6 +1815,8 @@ void btrfs_destroy_inode(struct inode *inode);
1812int btrfs_init_cachep(void); 1815int btrfs_init_cachep(void);
1813void btrfs_destroy_cachep(void); 1816void btrfs_destroy_cachep(void);
1814long btrfs_ioctl_trans_end(struct file *file); 1817long btrfs_ioctl_trans_end(struct file *file);
1818struct inode *btrfs_ilookup(struct super_block *s, u64 objectid,
1819 struct btrfs_root *root, int wait);
1815struct inode *btrfs_iget_locked(struct super_block *s, u64 objectid, 1820struct inode *btrfs_iget_locked(struct super_block *s, u64 objectid,
1816 struct btrfs_root *root); 1821 struct btrfs_root *root);
1817struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, 1822struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
@@ -1824,13 +1829,17 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page,
1824int btrfs_update_inode(struct btrfs_trans_handle *trans, 1829int btrfs_update_inode(struct btrfs_trans_handle *trans,
1825 struct btrfs_root *root, 1830 struct btrfs_root *root,
1826 struct inode *inode); 1831 struct inode *inode);
1832int btrfs_orphan_add(struct btrfs_trans_handle *trans, struct inode *inode);
1833int btrfs_orphan_del(struct btrfs_trans_handle *trans, struct inode *inode);
1834void btrfs_orphan_cleanup(struct btrfs_root *root);
1827 1835
1828/* ioctl.c */ 1836/* ioctl.c */
1829long btrfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg); 1837long btrfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
1830 1838
1831/* file.c */ 1839/* file.c */
1832int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync); 1840int btrfs_sync_file(struct file *file, struct dentry *dentry, int datasync);
1833int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end); 1841int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
1842 int skip_pinned);
1834int btrfs_check_file(struct btrfs_root *root, struct inode *inode); 1843int btrfs_check_file(struct btrfs_root *root, struct inode *inode);
1835extern struct file_operations btrfs_file_operations; 1844extern struct file_operations btrfs_file_operations;
1836int btrfs_drop_extents(struct btrfs_trans_handle *trans, 1845int btrfs_drop_extents(struct btrfs_trans_handle *trans,
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index e3a25be5c663..8bd1b402f3fd 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -292,7 +292,7 @@ static int merge_state(struct extent_io_tree *tree,
292 struct extent_state *other; 292 struct extent_state *other;
293 struct rb_node *other_node; 293 struct rb_node *other_node;
294 294
295 if (state->state & EXTENT_IOBITS) 295 if (state->state & (EXTENT_IOBITS | EXTENT_BOUNDARY))
296 return 0; 296 return 0;
297 297
298 other_node = rb_prev(&state->rb_node); 298 other_node = rb_prev(&state->rb_node);
@@ -1070,7 +1070,8 @@ search_again:
1070 1070
1071 while(1) { 1071 while(1) {
1072 state = rb_entry(node, struct extent_state, rb_node); 1072 state = rb_entry(node, struct extent_state, rb_node);
1073 if (found && state->start != cur_start) { 1073 if (found && (state->start != cur_start ||
1074 (state->state & EXTENT_BOUNDARY))) {
1074 goto out; 1075 goto out;
1075 } 1076 }
1076 if (!(state->state & EXTENT_DELALLOC)) { 1077 if (!(state->state & EXTENT_DELALLOC)) {
@@ -1078,7 +1079,7 @@ search_again:
1078 *end = state->end; 1079 *end = state->end;
1079 goto out; 1080 goto out;
1080 } 1081 }
1081 if (!found) { 1082 if (!found && !(state->state & EXTENT_BOUNDARY)) {
1082 struct extent_state *prev_state; 1083 struct extent_state *prev_state;
1083 struct rb_node *prev_node = node; 1084 struct rb_node *prev_node = node;
1084 while(1) { 1085 while(1) {
@@ -1088,7 +1089,11 @@ search_again:
1088 prev_state = rb_entry(prev_node, 1089 prev_state = rb_entry(prev_node,
1089 struct extent_state, 1090 struct extent_state,
1090 rb_node); 1091 rb_node);
1091 if (!(prev_state->state & EXTENT_DELALLOC)) 1092 if ((prev_state->end + 1 != state->start) ||
1093 !(prev_state->state & EXTENT_DELALLOC))
1094 break;
1095 if ((cur_start - prev_state->start) * 2 >
1096 max_bytes)
1092 break; 1097 break;
1093 state = prev_state; 1098 state = prev_state;
1094 node = prev_node; 1099 node = prev_node;
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
index 3cb411a5f4d3..c9d1908a1ae3 100644
--- a/fs/btrfs/extent_io.h
+++ b/fs/btrfs/extent_io.h
@@ -15,6 +15,7 @@
15#define EXTENT_BUFFER_FILLED (1 << 8) 15#define EXTENT_BUFFER_FILLED (1 << 8)
16#define EXTENT_ORDERED (1 << 9) 16#define EXTENT_ORDERED (1 << 9)
17#define EXTENT_ORDERED_METADATA (1 << 10) 17#define EXTENT_ORDERED_METADATA (1 << 10)
18#define EXTENT_BOUNDARY (1 << 11)
18#define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK) 19#define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK)
19 20
20/* 21/*
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 8856570a0ebd..1b7e51a9db0f 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -294,7 +294,7 @@ static int noinline dirty_and_release_pages(struct btrfs_trans_handle *trans,
294 last_pos_in_file, 294 last_pos_in_file,
295 0, 0, hole_size, 0); 295 0, 0, hole_size, 0);
296 btrfs_drop_extent_cache(inode, last_pos_in_file, 296 btrfs_drop_extent_cache(inode, last_pos_in_file,
297 last_pos_in_file + hole_size -1); 297 last_pos_in_file + hole_size - 1, 0);
298 mutex_unlock(&BTRFS_I(inode)->extent_mutex); 298 mutex_unlock(&BTRFS_I(inode)->extent_mutex);
299 btrfs_check_file(root, inode); 299 btrfs_check_file(root, inode);
300 } 300 }
@@ -337,7 +337,7 @@ static int noinline dirty_and_release_pages(struct btrfs_trans_handle *trans,
337 inline_size -= start_pos; 337 inline_size -= start_pos;
338 err = insert_inline_extent(trans, root, inode, start_pos, 338 err = insert_inline_extent(trans, root, inode, start_pos,
339 inline_size, pages, 0, num_pages); 339 inline_size, pages, 0, num_pages);
340 btrfs_drop_extent_cache(inode, start_pos, aligned_end - 1); 340 btrfs_drop_extent_cache(inode, start_pos, aligned_end - 1, 0);
341 BUG_ON(err); 341 BUG_ON(err);
342 mutex_unlock(&BTRFS_I(inode)->extent_mutex); 342 mutex_unlock(&BTRFS_I(inode)->extent_mutex);
343 343
@@ -362,7 +362,8 @@ out_unlock:
362 return err; 362 return err;
363} 363}
364 364
365int noinline btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end) 365int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
366 int skip_pinned)
366{ 367{
367 struct extent_map *em; 368 struct extent_map *em;
368 struct extent_map *split = NULL; 369 struct extent_map *split = NULL;
@@ -371,6 +372,7 @@ int noinline btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end)
371 u64 len = end - start + 1; 372 u64 len = end - start + 1;
372 int ret; 373 int ret;
373 int testend = 1; 374 int testend = 1;
375 unsigned long flags;
374 376
375 WARN_ON(end < start); 377 WARN_ON(end < start);
376 if (end == (u64)-1) { 378 if (end == (u64)-1) {
@@ -389,6 +391,23 @@ int noinline btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end)
389 spin_unlock(&em_tree->lock); 391 spin_unlock(&em_tree->lock);
390 break; 392 break;
391 } 393 }
394 flags = em->flags;
395 if (skip_pinned && test_bit(EXTENT_FLAG_PINNED, &em->flags)) {
396 spin_unlock(&em_tree->lock);
397 if (em->start <= start &&
398 (!testend || em->start + em->len >= start + len)) {
399 free_extent_map(em);
400 break;
401 }
402 if (start < em->start) {
403 len = em->start - start;
404 } else {
405 len = start + len - (em->start + em->len);
406 start = em->start + em->len;
407 }
408 free_extent_map(em);
409 continue;
410 }
392 clear_bit(EXTENT_FLAG_PINNED, &em->flags); 411 clear_bit(EXTENT_FLAG_PINNED, &em->flags);
393 remove_extent_mapping(em_tree, em); 412 remove_extent_mapping(em_tree, em);
394 413
@@ -398,7 +417,7 @@ int noinline btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end)
398 split->len = start - em->start; 417 split->len = start - em->start;
399 split->block_start = em->block_start; 418 split->block_start = em->block_start;
400 split->bdev = em->bdev; 419 split->bdev = em->bdev;
401 split->flags = em->flags; 420 split->flags = flags;
402 ret = add_extent_mapping(em_tree, split); 421 ret = add_extent_mapping(em_tree, split);
403 BUG_ON(ret); 422 BUG_ON(ret);
404 free_extent_map(split); 423 free_extent_map(split);
@@ -412,7 +431,7 @@ int noinline btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end)
412 split->start = start + len; 431 split->start = start + len;
413 split->len = em->start + em->len - (start + len); 432 split->len = em->start + em->len - (start + len);
414 split->bdev = em->bdev; 433 split->bdev = em->bdev;
415 split->flags = em->flags; 434 split->flags = flags;
416 435
417 split->block_start = em->block_start + diff; 436 split->block_start = em->block_start + diff;
418 437
@@ -541,7 +560,7 @@ int noinline btrfs_drop_extents(struct btrfs_trans_handle *trans,
541 int recow; 560 int recow;
542 int ret; 561 int ret;
543 562
544 btrfs_drop_extent_cache(inode, start, end - 1); 563 btrfs_drop_extent_cache(inode, start, end - 1, 0);
545 564
546 path = btrfs_alloc_path(); 565 path = btrfs_alloc_path();
547 if (!path) 566 if (!path)
diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c
index cd6171c2da42..80038c5ef7cf 100644
--- a/fs/btrfs/inode-map.c
+++ b/fs/btrfs/inode-map.c
@@ -117,10 +117,14 @@ int btrfs_find_free_objectid(struct btrfs_trans_handle *trans,
117 *objectid = last_ino; 117 *objectid = last_ino;
118 goto found; 118 goto found;
119 } 119 }
120 } else if (key.objectid > search_start) {
121 *objectid = search_start;
122 goto found;
120 } 123 }
121 } 124 }
122 if (key.objectid >= BTRFS_LAST_FREE_OBJECTID) 125 if (key.objectid >= BTRFS_LAST_FREE_OBJECTID)
123 break; 126 break;
127
124 start_found = 1; 128 start_found = 1;
125 last_ino = key.objectid + 1; 129 last_ino = key.objectid + 1;
126 path->slots[0]++; 130 path->slots[0]++;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 48a3dc030807..4516fbf01671 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -135,7 +135,7 @@ static int cow_file_range(struct inode *inode, u64 start, u64 end)
135 135
136 BUG_ON(num_bytes > btrfs_super_total_bytes(&root->fs_info->super_copy)); 136 BUG_ON(num_bytes > btrfs_super_total_bytes(&root->fs_info->super_copy));
137 mutex_lock(&BTRFS_I(inode)->extent_mutex); 137 mutex_lock(&BTRFS_I(inode)->extent_mutex);
138 btrfs_drop_extent_cache(inode, start, start + num_bytes - 1); 138 btrfs_drop_extent_cache(inode, start, start + num_bytes - 1, 0);
139 mutex_unlock(&BTRFS_I(inode)->extent_mutex); 139 mutex_unlock(&BTRFS_I(inode)->extent_mutex);
140 140
141 while(num_bytes > 0) { 141 while(num_bytes > 0) {
@@ -163,7 +163,7 @@ static int cow_file_range(struct inode *inode, u64 start, u64 end)
163 break; 163 break;
164 } 164 }
165 btrfs_drop_extent_cache(inode, start, 165 btrfs_drop_extent_cache(inode, start,
166 start + ins.offset - 1); 166 start + ins.offset - 1, 0);
167 } 167 }
168 mutex_unlock(&BTRFS_I(inode)->extent_mutex); 168 mutex_unlock(&BTRFS_I(inode)->extent_mutex);
169 169
@@ -587,7 +587,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end)
587 587
588 btrfs_drop_extent_cache(inode, ordered_extent->file_offset, 588 btrfs_drop_extent_cache(inode, ordered_extent->file_offset,
589 ordered_extent->file_offset + 589 ordered_extent->file_offset +
590 ordered_extent->len - 1); 590 ordered_extent->len - 1, 0);
591 mutex_unlock(&BTRFS_I(inode)->extent_mutex); 591 mutex_unlock(&BTRFS_I(inode)->extent_mutex);
592 592
593 ins.objectid = ordered_extent->start; 593 ins.objectid = ordered_extent->start;
@@ -880,7 +880,7 @@ void btrfs_orphan_cleanup(struct btrfs_root *root)
880 int ret = 0, nr_unlink = 0, nr_truncate = 0; 880 int ret = 0, nr_unlink = 0, nr_truncate = 0;
881 881
882 /* don't do orphan cleanup if the fs is readonly. */ 882 /* don't do orphan cleanup if the fs is readonly. */
883 if (root->inode->i_sb->s_flags & MS_RDONLY) 883 if (root->fs_info->sb->s_flags & MS_RDONLY)
884 return; 884 return;
885 885
886 path = btrfs_alloc_path(); 886 path = btrfs_alloc_path();
@@ -892,8 +892,6 @@ void btrfs_orphan_cleanup(struct btrfs_root *root)
892 btrfs_set_key_type(&key, BTRFS_ORPHAN_ITEM_KEY); 892 btrfs_set_key_type(&key, BTRFS_ORPHAN_ITEM_KEY);
893 key.offset = (u64)-1; 893 key.offset = (u64)-1;
894 894
895 trans = btrfs_start_transaction(root, 1);
896 btrfs_set_trans_block_group(trans, root->inode);
897 895
898 while (1) { 896 while (1) {
899 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); 897 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
@@ -933,7 +931,7 @@ void btrfs_orphan_cleanup(struct btrfs_root *root)
933 * crossing root thing. we store the inode number in the 931 * crossing root thing. we store the inode number in the
934 * offset of the orphan item. 932 * offset of the orphan item.
935 */ 933 */
936 inode = btrfs_iget_locked(root->inode->i_sb, 934 inode = btrfs_iget_locked(root->fs_info->sb,
937 found_key.offset, root); 935 found_key.offset, root);
938 if (!inode) 936 if (!inode)
939 break; 937 break;
@@ -965,7 +963,9 @@ void btrfs_orphan_cleanup(struct btrfs_root *root)
965 * do a destroy_inode 963 * do a destroy_inode
966 */ 964 */
967 if (is_bad_inode(inode)) { 965 if (is_bad_inode(inode)) {
966 trans = btrfs_start_transaction(root, 1);
968 btrfs_orphan_del(trans, inode); 967 btrfs_orphan_del(trans, inode);
968 btrfs_end_transaction(trans, root);
969 iput(inode); 969 iput(inode);
970 continue; 970 continue;
971 } 971 }
@@ -988,7 +988,6 @@ void btrfs_orphan_cleanup(struct btrfs_root *root)
988 printk(KERN_INFO "btrfs: truncated %d orphans\n", nr_truncate); 988 printk(KERN_INFO "btrfs: truncated %d orphans\n", nr_truncate);
989 989
990 btrfs_free_path(path); 990 btrfs_free_path(path);
991 btrfs_end_transaction(trans, root);
992} 991}
993 992
994void btrfs_read_locked_inode(struct inode *inode) 993void btrfs_read_locked_inode(struct inode *inode)
@@ -1343,8 +1342,7 @@ noinline int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
1343 u64 mask = root->sectorsize - 1; 1342 u64 mask = root->sectorsize - 1;
1344 1343
1345 if (root->ref_cows) 1344 if (root->ref_cows)
1346 btrfs_drop_extent_cache(inode, 1345 btrfs_drop_extent_cache(inode, new_size & (~mask), (u64)-1, 0);
1347 new_size & (~mask), (u64)-1);
1348 path = btrfs_alloc_path(); 1346 path = btrfs_alloc_path();
1349 path->reada = -1; 1347 path->reada = -1;
1350 BUG_ON(!path); 1348 BUG_ON(!path);
@@ -1677,7 +1675,7 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr)
1677 hole_start, 0, 0, 1675 hole_start, 0, 0,
1678 hole_size, 0); 1676 hole_size, 0);
1679 btrfs_drop_extent_cache(inode, hole_start, 1677 btrfs_drop_extent_cache(inode, hole_start,
1680 (u64)-1); 1678 (u64)-1, 0);
1681 btrfs_check_file(root, inode); 1679 btrfs_check_file(root, inode);
1682 } 1680 }
1683 mutex_unlock(&BTRFS_I(inode)->extent_mutex); 1681 mutex_unlock(&BTRFS_I(inode)->extent_mutex);
@@ -1843,6 +1841,24 @@ static int btrfs_find_actor(struct inode *inode, void *opaque)
1843 args->root == BTRFS_I(inode)->root); 1841 args->root == BTRFS_I(inode)->root);
1844} 1842}
1845 1843
1844struct inode *btrfs_ilookup(struct super_block *s, u64 objectid,
1845 struct btrfs_root *root, int wait)
1846{
1847 struct inode *inode;
1848 struct btrfs_iget_args args;
1849 args.ino = objectid;
1850 args.root = root;
1851
1852 if (wait) {
1853 inode = ilookup5(s, objectid, btrfs_find_actor,
1854 (void *)&args);
1855 } else {
1856 inode = ilookup5_nowait(s, objectid, btrfs_find_actor,
1857 (void *)&args);
1858 }
1859 return inode;
1860}
1861
1846struct inode *btrfs_iget_locked(struct super_block *s, u64 objectid, 1862struct inode *btrfs_iget_locked(struct super_block *s, u64 objectid,
1847 struct btrfs_root *root) 1863 struct btrfs_root *root)
1848{ 1864{
@@ -3266,7 +3282,7 @@ void btrfs_destroy_inode(struct inode *inode)
3266 btrfs_put_ordered_extent(ordered); 3282 btrfs_put_ordered_extent(ordered);
3267 } 3283 }
3268 } 3284 }
3269 btrfs_drop_extent_cache(inode, 0, (u64)-1); 3285 btrfs_drop_extent_cache(inode, 0, (u64)-1, 0);
3270 kmem_cache_free(btrfs_inode_cachep, BTRFS_I(inode)); 3286 kmem_cache_free(btrfs_inode_cachep, BTRFS_I(inode));
3271} 3287}
3272 3288
@@ -3412,16 +3428,22 @@ int btrfs_start_delalloc_inodes(struct btrfs_root *root)
3412{ 3428{
3413 struct list_head *head = &root->fs_info->delalloc_inodes; 3429 struct list_head *head = &root->fs_info->delalloc_inodes;
3414 struct btrfs_inode *binode; 3430 struct btrfs_inode *binode;
3431 struct inode *inode;
3415 unsigned long flags; 3432 unsigned long flags;
3416 3433
3417 spin_lock_irqsave(&root->fs_info->delalloc_lock, flags); 3434 spin_lock_irqsave(&root->fs_info->delalloc_lock, flags);
3418 while(!list_empty(head)) { 3435 while(!list_empty(head)) {
3419 binode = list_entry(head->next, struct btrfs_inode, 3436 binode = list_entry(head->next, struct btrfs_inode,
3420 delalloc_inodes); 3437 delalloc_inodes);
3421 atomic_inc(&binode->vfs_inode.i_count); 3438 inode = igrab(&binode->vfs_inode);
3439 if (!inode)
3440 list_del_init(&binode->delalloc_inodes);
3422 spin_unlock_irqrestore(&root->fs_info->delalloc_lock, flags); 3441 spin_unlock_irqrestore(&root->fs_info->delalloc_lock, flags);
3423 filemap_write_and_wait(binode->vfs_inode.i_mapping); 3442 if (inode) {
3424 iput(&binode->vfs_inode); 3443 filemap_write_and_wait(inode->i_mapping);
3444 iput(inode);
3445 }
3446 cond_resched();
3425 spin_lock_irqsave(&root->fs_info->delalloc_lock, flags); 3447 spin_lock_irqsave(&root->fs_info->delalloc_lock, flags);
3426 } 3448 }
3427 spin_unlock_irqrestore(&root->fs_info->delalloc_lock, flags); 3449 spin_unlock_irqrestore(&root->fs_info->delalloc_lock, flags);
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 4c6e0c15754d..04de767a8db2 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -444,12 +444,10 @@ static noinline int btrfs_ioctl_snap_create(struct btrfs_root *root,
444 goto out; 444 goto out;
445 } 445 }
446 446
447 mutex_lock(&root->fs_info->drop_mutex);
448 if (root == root->fs_info->tree_root) 447 if (root == root->fs_info->tree_root)
449 ret = create_subvol(root, vol_args->name, namelen); 448 ret = create_subvol(root, vol_args->name, namelen);
450 else 449 else
451 ret = create_snapshot(root, vol_args->name, namelen); 450 ret = create_snapshot(root, vol_args->name, namelen);
452 mutex_unlock(&root->fs_info->drop_mutex);
453out: 451out:
454 kfree(vol_args); 452 kfree(vol_args);
455 return ret; 453 return ret;
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index da6d43eb41db..951eacff2420 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -309,7 +309,6 @@ int btrfs_wait_ordered_extents(struct btrfs_root *root, int nocow_only)
309{ 309{
310 struct list_head splice; 310 struct list_head splice;
311 struct list_head *cur; 311 struct list_head *cur;
312 struct list_head *tmp;
313 struct btrfs_ordered_extent *ordered; 312 struct btrfs_ordered_extent *ordered;
314 struct inode *inode; 313 struct inode *inode;
315 314
@@ -317,37 +316,38 @@ int btrfs_wait_ordered_extents(struct btrfs_root *root, int nocow_only)
317 316
318 spin_lock(&root->fs_info->ordered_extent_lock); 317 spin_lock(&root->fs_info->ordered_extent_lock);
319 list_splice_init(&root->fs_info->ordered_extents, &splice); 318 list_splice_init(&root->fs_info->ordered_extents, &splice);
320 list_for_each_safe(cur, tmp, &splice) { 319 while (!list_empty(&splice)) {
321 cur = splice.next; 320 cur = splice.next;
322 ordered = list_entry(cur, struct btrfs_ordered_extent, 321 ordered = list_entry(cur, struct btrfs_ordered_extent,
323 root_extent_list); 322 root_extent_list);
324 if (nocow_only && 323 if (nocow_only &&
325 !test_bit(BTRFS_ORDERED_NOCOW, &ordered->flags)) { 324 !test_bit(BTRFS_ORDERED_NOCOW, &ordered->flags)) {
325 list_move(&ordered->root_extent_list,
326 &root->fs_info->ordered_extents);
326 cond_resched_lock(&root->fs_info->ordered_extent_lock); 327 cond_resched_lock(&root->fs_info->ordered_extent_lock);
327 continue; 328 continue;
328 } 329 }
329 330
330 list_del_init(&ordered->root_extent_list); 331 list_del_init(&ordered->root_extent_list);
331 atomic_inc(&ordered->refs); 332 atomic_inc(&ordered->refs);
332 inode = ordered->inode;
333 333
334 /* 334 /*
335 * the inode can't go away until all the pages are gone 335 * the inode may be getting freed (in sys_unlink path).
336 * and the pages won't go away while there is still
337 * an ordered extent and the ordered extent won't go
338 * away until it is off this list. So, we can safely
339 * increment i_count here and call iput later
340 */ 336 */
341 atomic_inc(&inode->i_count); 337 inode = igrab(ordered->inode);
338
342 spin_unlock(&root->fs_info->ordered_extent_lock); 339 spin_unlock(&root->fs_info->ordered_extent_lock);
343 340
344 btrfs_start_ordered_extent(inode, ordered, 1); 341 if (inode) {
345 btrfs_put_ordered_extent(ordered); 342 btrfs_start_ordered_extent(inode, ordered, 1);
346 iput(inode); 343 btrfs_put_ordered_extent(ordered);
344 iput(inode);
345 } else {
346 btrfs_put_ordered_extent(ordered);
347 }
347 348
348 spin_lock(&root->fs_info->ordered_extent_lock); 349 spin_lock(&root->fs_info->ordered_extent_lock);
349 } 350 }
350 list_splice_init(&splice, &root->fs_info->ordered_extents);
351 spin_unlock(&root->fs_info->ordered_extent_lock); 351 spin_unlock(&root->fs_info->ordered_extent_lock);
352 return 0; 352 return 0;
353} 353}
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 656baefa5255..8c83cf464c83 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -109,6 +109,7 @@ noinline int btrfs_record_root_in_trans(struct btrfs_root *root)
109 spin_lock_init(&dirty->root->node_lock); 109 spin_lock_init(&dirty->root->node_lock);
110 spin_lock_init(&dirty->root->list_lock); 110 spin_lock_init(&dirty->root->list_lock);
111 mutex_init(&dirty->root->objectid_mutex); 111 mutex_init(&dirty->root->objectid_mutex);
112 mutex_init(&dirty->root->log_mutex);
112 INIT_LIST_HEAD(&dirty->root->dead_list); 113 INIT_LIST_HEAD(&dirty->root->dead_list);
113 dirty->root->node = root->commit_root; 114 dirty->root->node = root->commit_root;
114 dirty->root->commit_root = NULL; 115 dirty->root->commit_root = NULL;
@@ -590,13 +591,14 @@ static noinline int drop_dirty_roots(struct btrfs_root *tree_root,
590 root = dirty->latest_root; 591 root = dirty->latest_root;
591 atomic_inc(&root->fs_info->throttles); 592 atomic_inc(&root->fs_info->throttles);
592 593
593 mutex_lock(&root->fs_info->drop_mutex);
594 while(1) { 594 while(1) {
595 trans = btrfs_start_transaction(tree_root, 1); 595 trans = btrfs_start_transaction(tree_root, 1);
596 mutex_lock(&root->fs_info->drop_mutex);
596 ret = btrfs_drop_snapshot(trans, dirty->root); 597 ret = btrfs_drop_snapshot(trans, dirty->root);
597 if (ret != -EAGAIN) { 598 if (ret != -EAGAIN) {
598 break; 599 break;
599 } 600 }
601 mutex_unlock(&root->fs_info->drop_mutex);
600 602
601 err = btrfs_update_root(trans, 603 err = btrfs_update_root(trans,
602 tree_root, 604 tree_root,
@@ -608,10 +610,8 @@ static noinline int drop_dirty_roots(struct btrfs_root *tree_root,
608 ret = btrfs_end_transaction(trans, tree_root); 610 ret = btrfs_end_transaction(trans, tree_root);
609 BUG_ON(ret); 611 BUG_ON(ret);
610 612
611 mutex_unlock(&root->fs_info->drop_mutex);
612 btrfs_btree_balance_dirty(tree_root, nr); 613 btrfs_btree_balance_dirty(tree_root, nr);
613 cond_resched(); 614 cond_resched();
614 mutex_lock(&root->fs_info->drop_mutex);
615 } 615 }
616 BUG_ON(ret); 616 BUG_ON(ret);
617 atomic_dec(&root->fs_info->throttles); 617 atomic_dec(&root->fs_info->throttles);
@@ -689,7 +689,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
689 memcpy(new_root_item, &root->root_item, sizeof(*new_root_item)); 689 memcpy(new_root_item, &root->root_item, sizeof(*new_root_item));
690 690
691 key.objectid = objectid; 691 key.objectid = objectid;
692 key.offset = 1; 692 key.offset = trans->transid;
693 btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); 693 btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY);
694 694
695 old = btrfs_lock_root_node(root); 695 old = btrfs_lock_root_node(root);