diff options
| author | Jan Schmidt <list.btrfs@jan-o-sch.net> | 2012-05-29 11:06:54 -0400 |
|---|---|---|
| committer | Jan Schmidt <list.btrfs@jan-o-sch.net> | 2012-05-30 12:18:21 -0400 |
| commit | 95a06077f7edbd00d32612562be4d857a5b7df54 (patch) | |
| tree | 664ff2a92a2de3ba96be5a49ac36531d933ee5eb | |
| parent | 20b297d620cd1bb94127942bbb3702fb7b1030b2 (diff) | |
Btrfs: use delayed ref sequence numbers for all fs-tree updates
The sequence number for delayed refs is needed to postpone certain delayed
refs for a very short period while walking backrefs. Before the tree
modification log, we thought we'd only have to hold back those references
that don't have a counter operation.
While now we've the tree mod log, we're rewinding fs tree blocks to a
defined consistent state. We cannot know in advance for which tree block
we'll be doing rewind operations later. Therefore, we must postpone all the
delayed refs for fs-tree blocks, even those having a counter operation.
Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net>
| -rw-r--r-- | fs/btrfs/ctree.h | 7 | ||||
| -rw-r--r-- | fs/btrfs/delayed-ref.c | 10 | ||||
| -rw-r--r-- | fs/btrfs/delayed-ref.h | 19 |
3 files changed, 13 insertions, 23 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 6ba21b12cec4..f5f11a6c5e92 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
| @@ -3121,4 +3121,11 @@ void btrfs_get_tree_mod_seq(struct btrfs_fs_info *fs_info, | |||
| 3121 | void btrfs_put_tree_mod_seq(struct btrfs_fs_info *fs_info, | 3121 | void btrfs_put_tree_mod_seq(struct btrfs_fs_info *fs_info, |
| 3122 | struct seq_list *elem); | 3122 | struct seq_list *elem); |
| 3123 | 3123 | ||
| 3124 | static inline int is_fstree(u64 rootid) | ||
| 3125 | { | ||
| 3126 | if (rootid == BTRFS_FS_TREE_OBJECTID || | ||
| 3127 | (s64)rootid >= (s64)BTRFS_FIRST_FREE_OBJECTID) | ||
| 3128 | return 1; | ||
| 3129 | return 0; | ||
| 3130 | } | ||
| 3124 | #endif | 3131 | #endif |
diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c index 69f22e3ab3bc..13ae7b04790e 100644 --- a/fs/btrfs/delayed-ref.c +++ b/fs/btrfs/delayed-ref.c | |||
| @@ -525,7 +525,7 @@ static noinline void add_delayed_tree_ref(struct btrfs_fs_info *fs_info, | |||
| 525 | ref->is_head = 0; | 525 | ref->is_head = 0; |
| 526 | ref->in_tree = 1; | 526 | ref->in_tree = 1; |
| 527 | 527 | ||
| 528 | if (need_ref_seq(for_cow, ref_root)) | 528 | if (is_fstree(ref_root)) |
| 529 | seq = inc_delayed_seq(delayed_refs); | 529 | seq = inc_delayed_seq(delayed_refs); |
| 530 | ref->seq = seq; | 530 | ref->seq = seq; |
| 531 | 531 | ||
| @@ -584,7 +584,7 @@ static noinline void add_delayed_data_ref(struct btrfs_fs_info *fs_info, | |||
| 584 | ref->is_head = 0; | 584 | ref->is_head = 0; |
| 585 | ref->in_tree = 1; | 585 | ref->in_tree = 1; |
| 586 | 586 | ||
| 587 | if (need_ref_seq(for_cow, ref_root)) | 587 | if (is_fstree(ref_root)) |
| 588 | seq = inc_delayed_seq(delayed_refs); | 588 | seq = inc_delayed_seq(delayed_refs); |
| 589 | ref->seq = seq; | 589 | ref->seq = seq; |
| 590 | 590 | ||
| @@ -658,10 +658,11 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info, | |||
| 658 | add_delayed_tree_ref(fs_info, trans, &ref->node, bytenr, | 658 | add_delayed_tree_ref(fs_info, trans, &ref->node, bytenr, |
| 659 | num_bytes, parent, ref_root, level, action, | 659 | num_bytes, parent, ref_root, level, action, |
| 660 | for_cow); | 660 | for_cow); |
| 661 | if (!need_ref_seq(for_cow, ref_root) && | 661 | if (!is_fstree(ref_root) && |
| 662 | waitqueue_active(&delayed_refs->seq_wait)) | 662 | waitqueue_active(&delayed_refs->seq_wait)) |
| 663 | wake_up(&delayed_refs->seq_wait); | 663 | wake_up(&delayed_refs->seq_wait); |
| 664 | spin_unlock(&delayed_refs->lock); | 664 | spin_unlock(&delayed_refs->lock); |
| 665 | |||
| 665 | return 0; | 666 | return 0; |
| 666 | } | 667 | } |
| 667 | 668 | ||
| @@ -706,10 +707,11 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info, | |||
| 706 | add_delayed_data_ref(fs_info, trans, &ref->node, bytenr, | 707 | add_delayed_data_ref(fs_info, trans, &ref->node, bytenr, |
| 707 | num_bytes, parent, ref_root, owner, offset, | 708 | num_bytes, parent, ref_root, owner, offset, |
| 708 | action, for_cow); | 709 | action, for_cow); |
| 709 | if (!need_ref_seq(for_cow, ref_root) && | 710 | if (!is_fstree(ref_root) && |
| 710 | waitqueue_active(&delayed_refs->seq_wait)) | 711 | waitqueue_active(&delayed_refs->seq_wait)) |
| 711 | wake_up(&delayed_refs->seq_wait); | 712 | wake_up(&delayed_refs->seq_wait); |
| 712 | spin_unlock(&delayed_refs->lock); | 713 | spin_unlock(&delayed_refs->lock); |
| 714 | |||
| 713 | return 0; | 715 | return 0; |
| 714 | } | 716 | } |
| 715 | 717 | ||
diff --git a/fs/btrfs/delayed-ref.h b/fs/btrfs/delayed-ref.h index fd8244670212..413927fb9957 100644 --- a/fs/btrfs/delayed-ref.h +++ b/fs/btrfs/delayed-ref.h | |||
| @@ -225,25 +225,6 @@ int btrfs_check_delayed_seq(struct btrfs_delayed_ref_root *delayed_refs, | |||
| 225 | u64 seq); | 225 | u64 seq); |
| 226 | 226 | ||
| 227 | /* | 227 | /* |
| 228 | * delayed refs with a ref_seq > 0 must be held back during backref walking. | ||
| 229 | * this only applies to items in one of the fs-trees. for_cow items never need | ||
| 230 | * to be held back, so they won't get a ref_seq number. | ||
| 231 | */ | ||
| 232 | static inline int need_ref_seq(int for_cow, u64 rootid) | ||
| 233 | { | ||
| 234 | if (for_cow) | ||
| 235 | return 0; | ||
| 236 | |||
| 237 | if (rootid == BTRFS_FS_TREE_OBJECTID) | ||
| 238 | return 1; | ||
| 239 | |||
| 240 | if ((s64)rootid >= (s64)BTRFS_FIRST_FREE_OBJECTID) | ||
| 241 | return 1; | ||
| 242 | |||
| 243 | return 0; | ||
| 244 | } | ||
| 245 | |||
| 246 | /* | ||
| 247 | * a node might live in a head or a regular ref, this lets you | 228 | * a node might live in a head or a regular ref, this lets you |
| 248 | * test for the proper type to use. | 229 | * test for the proper type to use. |
| 249 | */ | 230 | */ |
