aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/file.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-08-01 11:27:23 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:06 -0400
commitf87f057b49ee52cf5c627ab27a706e3252767c9f (patch)
tree4f8cc04e91ae836f4dd1b2151f47cbd1bd1b9367 /fs/btrfs/file.c
parent492bb6deee3416ad792dcd8584ebd95c463af1a6 (diff)
Btrfs: Improve and cleanup locking done by walk_down_tree
While dropping snapshots, walk_down_tree does most of the work of checking reference counts and limiting tree traversal to just the blocks that we are freeing. It dropped and held the allocation mutex in strange and confusing ways, this commit changes it to only hold the mutex while actually freeing a block. The rest of the checks around reference counts should be safe without the lock because we only allow one process in btrfs_drop_snapshot at a time. Other processes dropping reference counts should not drop it to 1 because their tree roots already have an extra ref on the block. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/file.c')
-rw-r--r--fs/btrfs/file.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index c78f184ee5cc..8915f2dc1bce 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -338,6 +338,13 @@ static int noinline dirty_and_release_pages(struct btrfs_trans_handle *trans,
338 btrfs_drop_extent_cache(inode, start_pos, aligned_end - 1); 338 btrfs_drop_extent_cache(inode, start_pos, aligned_end - 1);
339 BUG_ON(err); 339 BUG_ON(err);
340 mutex_unlock(&BTRFS_I(inode)->extent_mutex); 340 mutex_unlock(&BTRFS_I(inode)->extent_mutex);
341
342 /*
343 * an ugly way to do all the prop accounting around
344 * the page bits and mapping tags
345 */
346 set_page_writeback(pages[0]);
347 end_page_writeback(pages[0]);
341 did_inline = 1; 348 did_inline = 1;
342 } 349 }
343 if (end_pos > isize) { 350 if (end_pos > isize) {
@@ -833,11 +840,7 @@ again:
833 start_pos, last_pos - 1, GFP_NOFS); 840 start_pos, last_pos - 1, GFP_NOFS);
834 } 841 }
835 for (i = 0; i < num_pages; i++) { 842 for (i = 0; i < num_pages; i++) {
836#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18) 843 clear_page_dirty_for_io(pages[i]);
837 ClearPageDirty(pages[i]);
838#else
839 cancel_dirty_page(pages[i], PAGE_CACHE_SIZE);
840#endif
841 set_page_extent_mapped(pages[i]); 844 set_page_extent_mapped(pages[i]);
842 WARN_ON(!PageLocked(pages[i])); 845 WARN_ON(!PageLocked(pages[i]));
843 } 846 }