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 | */ |