diff options
author | Zheng Yan <zheng.yan@oracle.com> | 2008-09-26 10:05:38 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-26 10:05:38 -0400 |
commit | 5b21f2ed3f2947b5195b65c9fdbdd9e52904cc03 (patch) | |
tree | 9af8f539ac487c163f3207bc065767c3c8b37ae7 /fs/btrfs/ordered-data.c | |
parent | e465768938f95388723b0fd3c50a0ae48173edb9 (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/btrfs/ordered-data.c')
-rw-r--r-- | fs/btrfs/ordered-data.c | 26 |
1 files changed, 13 insertions, 13 deletions
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 | } |