linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/5] fix bugs of sub transid
@ 2011-11-21 10:10 Liu Bo
  2011-11-21 10:10 ` [PATCH 1/5] Btrfs: fix btrfs_copy_root warning Liu Bo
                   ` (5 more replies)
  0 siblings, 6 replies; 11+ messages in thread
From: Liu Bo @ 2011-11-21 10:10 UTC (permalink / raw)
  To: linux-btrfs; +Cc: chris.mason, sensille

NOTE:
This patchset is based on "danger" branch.

We've been sufferring two big bugs with sub transid:
one is a bug related to root's last_snapshot, the other is a bug related to
disk extent refs' generation.

1) The first patch fixes a warning,
2) the second one fixes the last_snapshot bug,
3) the third one has already been in for-linus branch, but not in "danger"
   branch, so I add it here for the integrity,
4) the fourth one fixes a transid mismatch bug,
5) the fifth one fixes the disk extent refs' generation bug.

Any advices and tests are welcome!


Liu Bo (5):
  Btrfs: fix btrfs_copy_root warning
  Btrfs: fix bug with heavy snapshot and heavy fsync
  Btrfs: fix inconsistent tree
  Btrfs: filter shared blocks in should_cow_block
  Btrfs: update disk extent ref generation

 fs/btrfs/ctree.c       |   69 +++++++++++++++++++++++++++++++++------------
 fs/btrfs/ctree.h       |    8 ++++-
 fs/btrfs/delayed-ref.c |    7 ++++-
 fs/btrfs/delayed-ref.h |    2 +
 fs/btrfs/disk-io.c     |    3 +-
 fs/btrfs/extent-tree.c |   72 ++++++++++++++++++++++++++++++++++++++++--------
 fs/btrfs/ioctl.c       |    2 +-
 fs/btrfs/transaction.c |   10 ++++++-
 8 files changed, 137 insertions(+), 36 deletions(-)


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/5] Btrfs: fix btrfs_copy_root warning
  2011-11-21 10:10 [PATCH 0/5] fix bugs of sub transid Liu Bo
@ 2011-11-21 10:10 ` Liu Bo
  2011-11-21 10:10 ` [PATCH 2/5] Btrfs: fix bug with heavy snapshot and heavy fsync Liu Bo
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Liu Bo @ 2011-11-21 10:10 UTC (permalink / raw)
  To: linux-btrfs; +Cc: chris.mason, sensille

Should check for sub transid instead.

Signed-off-by: Liu Bo <liubo2009@cn.fujitsu.com>
---
 fs/btrfs/ctree.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index fa34b74..4a96337 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -259,7 +259,7 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans,
 			    (unsigned long)btrfs_header_fsid(cow),
 			    BTRFS_FSID_SIZE);
 
-	WARN_ON(btrfs_header_generation(buf) > trans->transid);
+	WARN_ON(btrfs_header_generation(buf) > trans->transaction->sub_transid);
 	if (new_root_objectid == BTRFS_TREE_RELOC_OBJECTID)
 		ret = btrfs_inc_ref(trans, root, cow, 1);
 	else
-- 
1.6.5.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/5] Btrfs: fix bug with heavy snapshot and heavy fsync
  2011-11-21 10:10 [PATCH 0/5] fix bugs of sub transid Liu Bo
  2011-11-21 10:10 ` [PATCH 1/5] Btrfs: fix btrfs_copy_root warning Liu Bo
@ 2011-11-21 10:10 ` Liu Bo
  2011-11-21 10:10 ` [PATCH 3/5] Btrfs: fix inconsistent tree Liu Bo
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Liu Bo @ 2011-11-21 10:10 UTC (permalink / raw)
  To: linux-btrfs; +Cc: chris.mason, sensille

We've forgotten to update root's last_snapshot gen to the latest sub transid,
so that we will free some extent buffers unexpectedly.  And this will cause
a inconsistent tree crash.

Signed-off-by: Liu Bo <liubo2009@cn.fujitsu.com>
---
 fs/btrfs/transaction.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index e3d2970..e31cdef 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -927,7 +927,8 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
 	BUG_ON(ret);
 
 	record_root_in_trans(trans, root);
-	btrfs_set_root_last_snapshot(&root->root_item, trans->transid);
+	btrfs_set_root_last_snapshot(&root->root_item,
+				     trans->transaction->sub_transid);
 	memcpy(new_root_item, &root->root_item, sizeof(*new_root_item));
 	btrfs_check_and_init_root_item(new_root_item);
 
-- 
1.6.5.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/5] Btrfs: fix inconsistent tree
  2011-11-21 10:10 [PATCH 0/5] fix bugs of sub transid Liu Bo
  2011-11-21 10:10 ` [PATCH 1/5] Btrfs: fix btrfs_copy_root warning Liu Bo
  2011-11-21 10:10 ` [PATCH 2/5] Btrfs: fix bug with heavy snapshot and heavy fsync Liu Bo
@ 2011-11-21 10:10 ` Liu Bo
  2011-11-21 10:10 ` [PATCH 4/5] Btrfs: filter shared blocks in should_cow_block Liu Bo
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: Liu Bo @ 2011-11-21 10:10 UTC (permalink / raw)
  To: linux-btrfs; +Cc: chris.mason, sensille

Signed-off-by: Liu Bo <liubo2009@cn.fujitsu.com>
---
 fs/btrfs/ctree.c       |   17 ++++++++++++++++-
 fs/btrfs/ctree.h       |    2 ++
 fs/btrfs/transaction.c |    8 ++++++++
 3 files changed, 26 insertions(+), 1 deletions(-)

diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 4a96337..2b38acd 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -571,10 +571,25 @@ static inline int should_cow_block(struct btrfs_trans_handle *trans,
 				   struct btrfs_root *root,
 				   struct extent_buffer *buf)
 {
+	/* ensure we can see the force_cow */
+	smp_rmb();
+
+	/*
+	 * We do not need to cow a block if
+	 * 1) this block is not created or changed in this transaction;
+	 * 2) this block does not belong to TREE_RELOC tree;
+	 * 3) the root is not forced COW.
+	 *
+	 * What is forced COW:
+	 *    when we create snapshot during commiting the transaction,
+	 *    after we've finished coping src root, we must COW the shared
+	 *    block to ensure the metadata consistency.
+	 */
 	if (btrfs_header_generation(buf) >= trans->transaction->transid &&
 	    !btrfs_header_flag(buf, BTRFS_HEADER_FLAG_WRITTEN) &&
 	    !(root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID &&
-	      btrfs_header_flag(buf, BTRFS_HEADER_FLAG_RELOC)))
+	      btrfs_header_flag(buf, BTRFS_HEADER_FLAG_RELOC)) &&
+	    !root->force_cow)
 		return 0;
 	return 1;
 }
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 346ad08..a635f1c 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -1271,6 +1271,8 @@ struct btrfs_root {
 	 * for stat.  It may be used for more later
 	 */
 	dev_t anon_dev;
+
+	int force_cow;
 };
 
 struct btrfs_ioctl_defrag_range_args {
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index e31cdef..ee3db16 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -784,6 +784,10 @@ static noinline int commit_fs_roots(struct btrfs_trans_handle *trans,
 
 			btrfs_save_ino_cache(root, trans);
 
+			/* see comments in should_cow_block() */
+			root->force_cow = 0;
+			smp_wmb();
+
 			if (root->commit_root != root->node) {
 				mutex_lock(&root->fs_commit_mutex);
 				switch_commit_root(root);
@@ -947,6 +951,10 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
 	btrfs_tree_unlock(old);
 	free_extent_buffer(old);
 
+	/* see comments in should_cow_block() */
+	root->force_cow = 1;
+	smp_wmb();
+
 	btrfs_set_root_node(new_root_item, tmp);
 	/* record when the snapshot was created in key.offset */
 	key.offset = trans->transid;
-- 
1.6.5.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 4/5] Btrfs: filter shared blocks in should_cow_block
  2011-11-21 10:10 [PATCH 0/5] fix bugs of sub transid Liu Bo
                   ` (2 preceding siblings ...)
  2011-11-21 10:10 ` [PATCH 3/5] Btrfs: fix inconsistent tree Liu Bo
@ 2011-11-21 10:10 ` Liu Bo
  2011-11-21 10:10 ` [PATCH 5/5] Btrfs: update disk extent ref generation Liu Bo
  2011-11-28 15:10 ` [PATCH 0/5] fix bugs of sub transid David Sterba
  5 siblings, 0 replies; 11+ messages in thread
From: Liu Bo @ 2011-11-21 10:10 UTC (permalink / raw)
  To: linux-btrfs; +Cc: chris.mason, sensille

We've suffered some transid mismatches by using sub transid,
here is a case:

before:
   parent A (gen = x)     parent B(gen = x)
           \                    /
            \                  /
             \                /
              block C (gen = x)

After We can update block C via parent A:
   parent A (gen = x + 1)     parent B(gen = x)
           \                    /
            \                  /
             \                /
              block C (gen = x + 1)

We'll get a mismatch between parent B and block C.

Fix it by:
COW the block if it can be shared and its gen is not same with sub transid.

Signed-off-by: Liu Bo <liubo2009@cn.fujitsu.com>
---
 fs/btrfs/ctree.c |   32 +++++++++++++++++++++-----------
 1 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 2b38acd..6cc9529 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -575,23 +575,33 @@ static inline int should_cow_block(struct btrfs_trans_handle *trans,
 	smp_rmb();
 
 	/*
-	 * We do not need to cow a block if
-	 * 1) this block is not created or changed in this transaction;
-	 * 2) this block does not belong to TREE_RELOC tree;
-	 * 3) the root is not forced COW.
+	 * We should cow a block if
+	 * 1) the root is forced COW,
+	 * 2) this block has not been updated in the current transaction,
+	 * 3) this block has been writeback on disk in the current transactoin,
+	 * 4) this block belongs to TREE_RELOC tree.
+	 * 5) this block may be shared, and its generation is not transid
+	 *    (we need to ensure every parents has a proper node_ptr_gen)
 	 *
 	 * What is forced COW:
 	 *    when we create snapshot during commiting the transaction,
 	 *    after we've finished coping src root, we must COW the shared
 	 *    block to ensure the metadata consistency.
 	 */
-	if (btrfs_header_generation(buf) >= trans->transaction->transid &&
-	    !btrfs_header_flag(buf, BTRFS_HEADER_FLAG_WRITTEN) &&
-	    !(root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID &&
-	      btrfs_header_flag(buf, BTRFS_HEADER_FLAG_RELOC)) &&
-	    !root->force_cow)
-		return 0;
-	return 1;
+	if (root->force_cow)
+		return 1;
+	if (btrfs_header_generation(buf) < trans->transaction->transid)
+		return 1;
+	if (btrfs_header_flag(buf, BTRFS_HEADER_FLAG_WRITTEN))
+		return 1;
+	if (root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID &&
+	    btrfs_header_flag(buf, BTRFS_HEADER_FLAG_RELOC))
+		return 1;
+	if (btrfs_block_can_be_shared(root, buf) &&
+	    must_update_generation(trans, root, buf))
+		return 1;
+
+	return 0;
 }
 
 /*
-- 
1.6.5.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 5/5] Btrfs: update disk extent ref generation
  2011-11-21 10:10 [PATCH 0/5] fix bugs of sub transid Liu Bo
                   ` (3 preceding siblings ...)
  2011-11-21 10:10 ` [PATCH 4/5] Btrfs: filter shared blocks in should_cow_block Liu Bo
@ 2011-11-21 10:10 ` Liu Bo
  2011-11-28 15:10 ` [PATCH 0/5] fix bugs of sub transid David Sterba
  5 siblings, 0 replies; 11+ messages in thread
From: Liu Bo @ 2011-11-21 10:10 UTC (permalink / raw)
  To: linux-btrfs; +Cc: chris.mason, sensille

We used to set disk extent refs' generation with transid,
but now with sub transid, it will cause a generation mismatch between
a tree block and its corresponding disk extent ref, and this will lead
to balance and scrub's crash.

Since these disk extent refs are delayed and stored in a rbtree,
the udpate will be easy.  When we update a block's generation, we
also update the related ref's generation in the rbtree.

Signed-off-by: Liu Bo <liubo2009@cn.fujitsu.com>
---
 fs/btrfs/ctree.c       |   32 ++++++++++++--------
 fs/btrfs/ctree.h       |    6 +++-
 fs/btrfs/delayed-ref.c |    7 ++++-
 fs/btrfs/delayed-ref.h |    2 +
 fs/btrfs/disk-io.c     |    3 +-
 fs/btrfs/extent-tree.c |   72 ++++++++++++++++++++++++++++++++++++++++--------
 fs/btrfs/ioctl.c       |    2 +-
 7 files changed, 95 insertions(+), 29 deletions(-)

diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 6cc9529..4ec35d9 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -227,6 +227,7 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans,
 	int ret = 0;
 	int level;
 	struct btrfs_disk_key disk_key;
+	u64 transid;
 
 	WARN_ON(root->ref_cows && trans->transaction->transid !=
 		root->fs_info->running_transaction->transid);
@@ -240,13 +241,13 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans,
 
 	cow = btrfs_alloc_free_block(trans, root, buf->len, 0,
 				     new_root_objectid, &disk_key, level,
-				     buf->start, 0);
+				     buf->start, 0, &transid);
 	if (IS_ERR(cow))
 		return PTR_ERR(cow);
 
 	copy_extent_buffer(cow, buf, 0, 0, cow->len);
 	btrfs_set_header_bytenr(cow, cow->start);
-	btrfs_set_header_generation(cow, trans->transaction->sub_transid);
+	btrfs_set_header_generation(cow, transid);
 	btrfs_set_header_backref_rev(cow, BTRFS_MIXED_BACKREF_REV);
 	btrfs_clear_header_flag(cow, BTRFS_HEADER_FLAG_WRITTEN |
 				     BTRFS_HEADER_FLAG_RELOC);
@@ -419,6 +420,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
 	int last_ref = 0;
 	int unlock_orig = 0;
 	u64 parent_start;
+	u64 transid;
 
 	if (*cow_ret == buf)
 		unlock_orig = 1;
@@ -446,7 +448,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
 
 	cow = btrfs_alloc_free_block(trans, root, buf->len, parent_start,
 				     root->root_key.objectid, &disk_key,
-				     level, search_start, empty_size);
+				     level, search_start, empty_size, &transid);
 	if (IS_ERR(cow))
 		return PTR_ERR(cow);
 
@@ -459,8 +461,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
 	    buf == root->node) {
 		btrfs_set_header_generation(cow, trans->transaction->transid);
 	} else {
-		btrfs_set_header_generation(cow,
-					    trans->transaction->sub_transid);
+		btrfs_set_header_generation(cow, transid);
 	}
 
 	btrfs_set_header_backref_rev(cow, BTRFS_MIXED_BACKREF_REV);
@@ -556,6 +557,9 @@ static inline void update_block_generation(struct btrfs_trans_handle *trans,
 		return;
 
 	btrfs_set_header_generation(buf, transid);
+	if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID)
+		btrfs_set_disk_extent_gen(trans, root, buf->start, buf->len,
+					  transid, 0);
 
 	if (buf == root->node) {
 		btrfs_mark_buffer_dirty(buf);
@@ -2154,6 +2158,7 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans,
 	struct extent_buffer *c;
 	struct extent_buffer *old;
 	struct btrfs_disk_key lower_key;
+	u64 transid;
 
 	BUG_ON(path->nodes[level]);
 	BUG_ON(path->nodes[level-1] != root->node);
@@ -2166,7 +2171,7 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans,
 
 	c = btrfs_alloc_free_block(trans, root, root->nodesize, 0,
 				   root->root_key.objectid, &lower_key,
-				   level, root->node->start, 0);
+				   level, root->node->start, 0, &transid);
 	if (IS_ERR(c))
 		return PTR_ERR(c);
 
@@ -2188,8 +2193,7 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans,
 					    trans->transaction->sub_transid);
 		btrfs_mark_buffer_dirty(lower);
 	} else {
-		btrfs_set_header_generation(c,
-					    trans->transaction->sub_transid);
+		btrfs_set_header_generation(c, transid);
 	}
 
 	btrfs_set_header_backref_rev(c, BTRFS_MIXED_BACKREF_REV);
@@ -2284,6 +2288,7 @@ static noinline int split_node(struct btrfs_trans_handle *trans,
 	int ret;
 	int wret;
 	u32 c_nritems;
+	u64 transid;
 
 	c = path->nodes[level];
 	WARN_ON(btrfs_header_generation(c) < trans->transaction->transid);
@@ -2307,8 +2312,8 @@ static noinline int split_node(struct btrfs_trans_handle *trans,
 	btrfs_node_key(c, &disk_key, mid);
 
 	split = btrfs_alloc_free_block(trans, root, root->nodesize, 0,
-					root->root_key.objectid,
-					&disk_key, level, c->start, 0);
+					root->root_key.objectid, &disk_key,
+					level, c->start, 0, &transid);
 	if (IS_ERR(split))
 		return PTR_ERR(split);
 
@@ -2317,7 +2322,7 @@ static noinline int split_node(struct btrfs_trans_handle *trans,
 	memset_extent_buffer(split, 0, 0, sizeof(struct btrfs_header));
 	btrfs_set_header_level(split, btrfs_header_level(c));
 	btrfs_set_header_bytenr(split, split->start);
-	btrfs_set_header_generation(split, trans->transaction->sub_transid);
+	btrfs_set_header_generation(split, transid);
 	btrfs_set_header_backref_rev(split, BTRFS_MIXED_BACKREF_REV);
 	btrfs_set_header_owner(split, root->root_key.objectid);
 	write_extent_buffer(split, root->fs_info->fsid,
@@ -2981,6 +2986,7 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans,
 	int split;
 	int num_doubles = 0;
 	int tried_avoid_double = 0;
+	u64 transid;
 
 	l = path->nodes[0];
 	slot = path->slots[0];
@@ -3063,7 +3069,7 @@ again:
 
 	right = btrfs_alloc_free_block(trans, root, root->leafsize, 0,
 					root->root_key.objectid,
-					&disk_key, 0, l->start, 0);
+					&disk_key, 0, l->start, 0, &transid);
 	if (IS_ERR(right))
 		return PTR_ERR(right);
 
@@ -3071,7 +3077,7 @@ again:
 
 	memset_extent_buffer(right, 0, 0, sizeof(struct btrfs_header));
 	btrfs_set_header_bytenr(right, right->start);
-	btrfs_set_header_generation(right, trans->transaction->sub_transid);
+	btrfs_set_header_generation(right, transid);
 	btrfs_set_header_backref_rev(right, BTRFS_MIXED_BACKREF_REV);
 	btrfs_set_header_owner(right, root->root_key.objectid);
 	btrfs_set_header_level(right, 0);
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index a635f1c..7fd10eb 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -2276,7 +2276,7 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
 					struct btrfs_root *root, u32 blocksize,
 					u64 parent, u64 root_objectid,
 					struct btrfs_disk_key *key, int level,
-					u64 hint, u64 empty_size);
+					u64 hint, u64 empty_size, u64 *gen_ret);
 void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
 			   struct btrfs_root *root,
 			   struct extent_buffer *buf,
@@ -2307,6 +2307,10 @@ int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans,
 				struct btrfs_root *root,
 				u64 bytenr, u64 num_bytes, u64 flags,
 				int is_data);
+int btrfs_set_disk_extent_gen(struct btrfs_trans_handle *trans,
+			      struct btrfs_root *root,
+			      u64 bytenr, u64 num_bytes, u64 gen,
+			      int is_data);
 int btrfs_free_extent(struct btrfs_trans_handle *trans,
 		      struct btrfs_root *root,
 		      u64 bytenr, u64 num_bytes, u64 parent,
diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c
index 125cf76..c5fb298 100644
--- a/fs/btrfs/delayed-ref.c
+++ b/fs/btrfs/delayed-ref.c
@@ -376,6 +376,11 @@ update_existing_head_ref(struct btrfs_delayed_ref_node *existing,
 					ref->extent_op->flags_to_set;
 				existing_ref->extent_op->update_flags = 1;
 			}
+			if (ref->extent_op->update_gen) {
+				existing_ref->extent_op->generation =
+					ref->extent_op->generation;
+				existing_ref->extent_op->update_gen = 1;
+			}
 			kfree(ref->extent_op);
 		}
 	}
@@ -674,7 +679,7 @@ int btrfs_add_delayed_extent_op(struct btrfs_trans_handle *trans,
 	struct btrfs_delayed_ref_root *delayed_refs;
 	int ret;
 
-	head_ref = kmalloc(sizeof(*head_ref), GFP_NOFS);
+	head_ref = kmalloc(sizeof(*head_ref), GFP_ATOMIC);
 	if (!head_ref)
 		return -ENOMEM;
 
diff --git a/fs/btrfs/delayed-ref.h b/fs/btrfs/delayed-ref.h
index e287e3b..098e4c2 100644
--- a/fs/btrfs/delayed-ref.h
+++ b/fs/btrfs/delayed-ref.h
@@ -57,8 +57,10 @@ struct btrfs_delayed_ref_node {
 struct btrfs_delayed_extent_op {
 	struct btrfs_disk_key key;
 	u64 flags_to_set;
+	u64 generation;
 	unsigned int update_key:1;
 	unsigned int update_flags:1;
+	unsigned int update_gen:1;
 	unsigned int is_data:1;
 };
 
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 6e1a660..8a72f0d 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -1243,7 +1243,8 @@ static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans,
 	root->ref_cows = 0;
 
 	leaf = btrfs_alloc_free_block(trans, root, root->leafsize, 0,
-				      BTRFS_TREE_LOG_OBJECTID, NULL, 0, 0, 0);
+				      BTRFS_TREE_LOG_OBJECTID, NULL, 0, 0, 0,
+				      NULL);
 	if (IS_ERR(leaf)) {
 		kfree(root);
 		return ERR_CAST(leaf);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 1311beb..2279386 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -89,7 +89,7 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans,
 				     struct btrfs_root *root,
 				     u64 parent, u64 root_objectid,
 				     u64 flags, struct btrfs_disk_key *key,
-				     int level, struct btrfs_key *ins);
+				     u64 gen, int level, struct btrfs_key *ins);
 static int do_chunk_alloc(struct btrfs_trans_handle *trans,
 			  struct btrfs_root *extent_root, u64 alloc_bytes,
 			  u64 flags, int force);
@@ -1971,6 +1971,8 @@ static void __run_delayed_extent_op(struct btrfs_delayed_extent_op *extent_op,
 		bi = (struct btrfs_tree_block_info *)(ei + 1);
 		btrfs_set_tree_block_key(leaf, bi, &extent_op->key);
 	}
+	if (extent_op->update_gen)
+		btrfs_set_extent_generation(leaf, ei, extent_op->generation);
 }
 
 static int run_delayed_extent_op(struct btrfs_trans_handle *trans,
@@ -2056,11 +2058,12 @@ static int run_delayed_tree_ref(struct btrfs_trans_handle *trans,
 	BUG_ON(node->ref_mod != 1);
 	if (node->action == BTRFS_ADD_DELAYED_REF && insert_reserved) {
 		BUG_ON(!extent_op || !extent_op->update_flags ||
-		       !extent_op->update_key);
+		       !extent_op->update_key || !extent_op->update_gen);
 		ret = alloc_reserved_tree_block(trans, root,
 						parent, ref_root,
 						extent_op->flags_to_set,
 						&extent_op->key,
+						extent_op->generation,
 						ref->level, &ins);
 	} else if (node->action == BTRFS_ADD_DELAYED_REF) {
 		ret = __btrfs_inc_extent_ref(trans, root, node->bytenr,
@@ -2347,29 +2350,67 @@ out:
 	return 0;
 }
 
-int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans,
-				struct btrfs_root *root,
-				u64 bytenr, u64 num_bytes, u64 flags,
-				int is_data)
+static int __btrfs_update_disk_extent_attr(struct btrfs_trans_handle *trans,
+					   struct btrfs_root *root,
+					   u64 bytenr, u64 num_bytes,
+					   u64 flags, u64 gen,
+					   int update_flags, int update_gen,
+					   int is_data)
 {
 	struct btrfs_delayed_extent_op *extent_op;
 	int ret;
 
-	extent_op = kmalloc(sizeof(*extent_op), GFP_NOFS);
+	extent_op = kmalloc(sizeof(*extent_op), GFP_ATOMIC);
 	if (!extent_op)
 		return -ENOMEM;
 
-	extent_op->flags_to_set = flags;
-	extent_op->update_flags = 1;
+	extent_op->update_flags = 0;
 	extent_op->update_key = 0;
+	extent_op->update_gen = 0;
 	extent_op->is_data = is_data ? 1 : 0;
 
+	if (update_flags) {
+		extent_op->flags_to_set = flags;
+		extent_op->update_flags = 1;
+	}
+
+	if (update_gen) {
+		extent_op->generation = gen;
+		extent_op->update_gen = 1;
+	}
+
 	ret = btrfs_add_delayed_extent_op(trans, bytenr, num_bytes, extent_op);
 	if (ret)
 		kfree(extent_op);
 	return ret;
 }
 
+int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans,
+				struct btrfs_root *root,
+				u64 bytenr, u64 num_bytes, u64 flags,
+				int is_data)
+{
+	int ret;
+
+	ret = __btrfs_update_disk_extent_attr(trans, root, bytenr, num_bytes,
+					      flags, 0, 1, 0, is_data);
+	BUG_ON(ret);
+	return ret;
+}
+
+int btrfs_set_disk_extent_gen(struct btrfs_trans_handle *trans,
+			      struct btrfs_root *root,
+			      u64 bytenr, u64 num_bytes, u64 gen,
+			      int is_data)
+{
+	int ret;
+
+	ret = __btrfs_update_disk_extent_attr(trans, root, bytenr, num_bytes,
+					      0, gen, 0, 1, is_data);
+	BUG_ON(ret);
+	return ret;
+}
+
 static noinline int check_delayed_ref(struct btrfs_trans_handle *trans,
 				      struct btrfs_root *root,
 				      struct btrfs_path *path,
@@ -5697,7 +5738,7 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans,
 				     struct btrfs_root *root,
 				     u64 parent, u64 root_objectid,
 				     u64 flags, struct btrfs_disk_key *key,
-				     int level, struct btrfs_key *ins)
+				     u64 gen, int level, struct btrfs_key *ins)
 {
 	int ret;
 	struct btrfs_fs_info *fs_info = root->fs_info;
@@ -5721,7 +5762,7 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans,
 	extent_item = btrfs_item_ptr(leaf, path->slots[0],
 				     struct btrfs_extent_item);
 	btrfs_set_extent_refs(leaf, extent_item, 1);
-	btrfs_set_extent_generation(leaf, extent_item, trans->transid);
+	btrfs_set_extent_generation(leaf, extent_item, gen);
 	btrfs_set_extent_flags(leaf, extent_item,
 			       flags | BTRFS_EXTENT_FLAG_TREE_BLOCK);
 	block_info = (struct btrfs_tree_block_info *)(extent_item + 1);
@@ -5935,12 +5976,13 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
 					struct btrfs_root *root, u32 blocksize,
 					u64 parent, u64 root_objectid,
 					struct btrfs_disk_key *key, int level,
-					u64 hint, u64 empty_size)
+					u64 hint, u64 empty_size, u64 *gen_ret)
 {
 	struct btrfs_key ins;
 	struct btrfs_block_rsv *block_rsv;
 	struct extent_buffer *buf;
 	u64 flags = 0;
+	u64 gen;
 	int ret;
 
 
@@ -5966,6 +6008,7 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
 	} else
 		BUG_ON(parent > 0);
 
+	gen = trans->transaction->sub_transid;
 	if (root_objectid != BTRFS_TREE_LOG_OBJECTID) {
 		struct btrfs_delayed_extent_op *extent_op;
 		extent_op = kmalloc(sizeof(*extent_op), GFP_NOFS);
@@ -5975,8 +6018,10 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
 		else
 			memset(&extent_op->key, 0, sizeof(extent_op->key));
 		extent_op->flags_to_set = flags;
+		extent_op->generation = gen;
 		extent_op->update_key = 1;
 		extent_op->update_flags = 1;
+		extent_op->update_gen = 1;
 		extent_op->is_data = 0;
 
 		ret = btrfs_add_delayed_tree_ref(trans, ins.objectid,
@@ -5985,6 +6030,9 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
 					extent_op);
 		BUG_ON(ret);
 	}
+
+	if (gen_ret)
+		*gen_ret = gen;
 	return buf;
 }
 
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index c7c81e6..fe8876c 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -358,7 +358,7 @@ static noinline int create_subvol(struct btrfs_root *root,
 		return PTR_ERR(trans);
 
 	leaf = btrfs_alloc_free_block(trans, root, root->leafsize,
-				      0, objectid, NULL, 0, 0, 0);
+				      0, objectid, NULL, 0, 0, 0, NULL);
 	if (IS_ERR(leaf)) {
 		ret = PTR_ERR(leaf);
 		goto fail;
-- 
1.6.5.2


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 0/5] fix bugs of sub transid
  2011-11-21 10:10 [PATCH 0/5] fix bugs of sub transid Liu Bo
                   ` (4 preceding siblings ...)
  2011-11-21 10:10 ` [PATCH 5/5] Btrfs: update disk extent ref generation Liu Bo
@ 2011-11-28 15:10 ` David Sterba
  2011-11-29  1:18   ` Liu Bo
  5 siblings, 1 reply; 11+ messages in thread
From: David Sterba @ 2011-11-28 15:10 UTC (permalink / raw)
  To: Liu Bo; +Cc: linux-btrfs, chris.mason, sensille

On Mon, Nov 21, 2011 at 06:10:19PM +0800, Liu Bo wrote:
> We've been sufferring two big bugs with sub transid:
> one is a bug related to root's last_snapshot, the other is a bug related to
> disk extent refs' generation.

Do you have a testcase to trigger and check these bugs?

> 1) The first patch fixes a warning,
> 2) the second one fixes the last_snapshot bug,
> 3) the third one has already been in for-linus branch, but not in "danger"
>    branch, so I add it here for the integrity,
> 4) the fourth one fixes a transid mismatch bug,
> 5) the fifth one fixes the disk extent refs' generation bug.
> 
> Any advices and tests are welcome!

I have rebased this series on top of current cmason/for-linus (24a70313969),
should anybody want to test.

(repo address: http://repo.or.cz/w/linux-2.6/btrfs-unstable.git )


david

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 0/5] fix bugs of sub transid
  2011-11-28 15:10 ` [PATCH 0/5] fix bugs of sub transid David Sterba
@ 2011-11-29  1:18   ` Liu Bo
  2011-11-29 16:17     ` [PATCH 0/5] fix bugs of sub transid -- WARNING: at fs/btrfs/ctree.c:432 David Sterba
  0 siblings, 1 reply; 11+ messages in thread
From: Liu Bo @ 2011-11-29  1:18 UTC (permalink / raw)
  To: David Sterba; +Cc: linux-btrfs, chris.mason, sensille

On 11/28/2011 11:10 PM, David Sterba wrote:
> On Mon, Nov 21, 2011 at 06:10:19PM +0800, Liu Bo wrote:
>> We've been sufferring two big bugs with sub transid:
>> one is a bug related to root's last_snapshot, the other is a bug related to
>> disk extent refs' generation.
> 
> Do you have a testcase to trigger and check these bugs?
> 

Hi, David, 

a) For the first one (last_snapshot bug),

The test involves three processes (derived from Chris):

mkfs.btrfs /dev/xxx
mount /dev/xxx /mnt

1) run compilebench -i 30 --makej -D /mnt

Let compilebench run until it starts the create phase.

2) run synctest -f -u -n 200 -t 3 /mnt
3) for x in `seq 1 200` ; do btrfs subvol snap /mnt /mnt/snap$x ; sleep 0.5 ; done


b) For the second one, 

1) build a btrfs partition, and

2) fill something, and then

3) run balance on it.


>> 1) The first patch fixes a warning,
>> 2) the second one fixes the last_snapshot bug,
>> 3) the third one has already been in for-linus branch, but not in "danger"
>>    branch, so I add it here for the integrity,
>> 4) the fourth one fixes a transid mismatch bug,
>> 5) the fifth one fixes the disk extent refs' generation bug.
>>
>> Any advices and tests are welcome!
> 
> I have rebased this series on top of current cmason/for-linus (24a70313969),
> should anybody want to test.
> 
> (repo address: http://repo.or.cz/w/linux-2.6/btrfs-unstable.git )
> 


Great!  Thanks for what you've done!

thanks,
liubo


> 
> david
> --
> To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 0/5] fix bugs of sub transid -- WARNING: at fs/btrfs/ctree.c:432
  2011-11-29  1:18   ` Liu Bo
@ 2011-11-29 16:17     ` David Sterba
  2011-12-01  1:32       ` Liu Bo
  0 siblings, 1 reply; 11+ messages in thread
From: David Sterba @ 2011-11-29 16:17 UTC (permalink / raw)
  To: Liu Bo; +Cc: David Sterba, linux-btrfs, chris.mason, sensille

On Tue, Nov 29, 2011 at 09:18:35AM +0800, Liu Bo wrote:
> a) For the first one (last_snapshot bug),
> 
> The test involves three processes (derived from Chris):
> 
> mkfs.btrfs /dev/xxx
> mount /dev/xxx /mnt
> 
> 1) run compilebench -i 30 --makej -D /mnt
> 
> Let compilebench run until it starts the create phase.
> 
> 2) run synctest -f -u -n 200 -t 3 /mnt
> 3) for x in `seq 1 200` ; do btrfs subvol snap /mnt /mnt/snap$x ; sleep 0.5 ; done

I have hit following 2 warnings during this test. Phase 1 was at compile
stage, 2 and 3 were running. I did not see them during first run and other
activity at the filestystem was 'du -sh /mnt'.

mount options: compress-force=lzo,discard,space_cache,autodefrag,inode_cache

Label: none  uuid: 79f4160b-81f8-46ed-968c-968cb17a2e87
        Total devices 4 FS bytes used 7.76GB
        devid    4 size 13.96GB used 2.26GB path /dev/sdb4
        devid    3 size 13.96GB used 2.26GB path /dev/sdb3
        devid    2 size 13.96GB used 3.00GB path /dev/sdb2
        devid    1 size 13.96GB used 3.02GB path /dev/sdb1

fresh and default mkfs

 430         WARN_ON(root->ref_cows && trans->transaction->transid !=
 431                 root->fs_info->running_transaction->transid);
 432         WARN_ON(root->ref_cows && trans->transid < root->last_trans);


20433.473713] ------------[ cut here ]------------
[20433.478825] WARNING: at fs/btrfs/ctree.c:432 __btrfs_cow_block+0x429/0x5e0 [btrfs]()
[20433.487148] Hardware name: Santa Rosa platform
[20433.487150] Modules linked in: btrfs aoe sr_mod ide_cd_mod cdrom loop [last unloaded: btrfs]
[20433.487162] Pid: 12099, comm: btrfs Tainted: G        W   3.1.0-default+ #80
[20433.487165] Call Trace:
[20433.487174]  [<ffffffff81051c0f>] warn_slowpath_common+0x7f/0xc0
[20433.487179]  [<ffffffff81051c6a>] warn_slowpath_null+0x1a/0x20
[20433.487190]  [<ffffffffa00d6909>] __btrfs_cow_block+0x429/0x5e0 [btrfs]
[20433.487196]  [<ffffffff8108a429>] ? trace_hardirqs_off_caller+0x29/0xc0
[20433.487201]  [<ffffffff8108a7ed>] ? lock_release_holdtime+0x3d/0x1c0
[20433.487218]  [<ffffffffa0129cc0>] ? btrfs_set_lock_blocking_rw+0x50/0xb0 [btrfs]
[20433.487230]  [<ffffffffa00d6c66>] btrfs_cow_block+0x1a6/0x3d0 [btrfs]
[20433.487236]  [<ffffffff818b90cb>] ? _raw_write_unlock+0x2b/0x50
[20433.487247]  [<ffffffffa00dae70>] btrfs_search_slot+0x300/0xd20 [btrfs]
[20433.487262]  [<ffffffffa00eedcf>] btrfs_lookup_inode+0x2f/0xa0 [btrfs]
[20433.487279]  [<ffffffffa00fd186>] btrfs_update_inode_item+0x66/0x120 [btrfs]
[20433.487296]  [<ffffffffa00fe63b>] btrfs_update_inode+0xab/0xc0 [btrfs]
[20433.487313]  [<ffffffffa0134e61>] ? lookup_free_ino_inode+0x51/0xe0 [btrfs]
[20433.487327]  [<ffffffffa00ef515>] btrfs_save_ino_cache+0x145/0x2f0 [btrfs]
[20433.487342]  [<ffffffffa00f7464>] ? commit_fs_roots+0xa4/0x1c0 [btrfs]
[20433.487357]  [<ffffffffa00f7494>] commit_fs_roots+0xd4/0x1c0 [btrfs]
[20433.487373]  [<ffffffffa00f86a4>] btrfs_commit_transaction+0x454/0x900 [btrfs]
[20433.487378]  [<ffffffff8108a7ed>] ? lock_release_holdtime+0x3d/0x1c0
[20433.487395]  [<ffffffffa0126e08>] ? btrfs_mksubvol+0x298/0x360 [btrfs]
[20433.487400]  [<ffffffff81076550>] ? wake_up_bit+0x40/0x40
[20433.487405]  [<ffffffff8134738e>] ? do_raw_spin_unlock+0x5e/0xb0
[20433.487421]  [<ffffffffa0126ec8>] btrfs_mksubvol+0x358/0x360 [btrfs]
[20433.487427]  [<ffffffff8110ece3>] ? might_fault+0x53/0xb0
[20433.487443]  [<ffffffffa0126fd0>] btrfs_ioctl_snap_create_transid+0x100/0x160 [btrfs]
[20433.487448]  [<ffffffff8110ece3>] ? might_fault+0x53/0xb0
[20433.487464]  [<ffffffffa01271ad>] btrfs_ioctl_snap_create_v2.clone.0+0xfd/0x110 [btrfs]
[20433.487482]  [<ffffffffa0128a78>] btrfs_ioctl+0x588/0x1080 [btrfs]
[20433.487487]  [<ffffffff818bd9c0>] ? do_page_fault+0x2d0/0x580
[20433.487492]  [<ffffffff8107d6cf>] ? local_clock+0x6f/0x80
[20433.487498]  [<ffffffff811473e8>] do_vfs_ioctl+0x98/0x560
[20433.487502]  [<ffffffff818b9fd9>] ? retint_swapgs+0x13/0x1b
[20433.487507]  [<ffffffff811478ff>] sys_ioctl+0x4f/0x80
[20433.487512]  [<ffffffff818c21c2>] system_call_fastpath+0x16/0x1b
[20433.487515] ---[ end trace d93007cf8d0a8eac ]---
[20433.487576] ------------[ cut here ]------------
[20433.487587] WARNING: at fs/btrfs/ctree.c:432 __btrfs_cow_block+0x429/0x5e0 [btrfs]()
[20433.487590] Hardware name: Santa Rosa platform
[20433.487592] Modules linked in: btrfs aoe sr_mod ide_cd_mod cdrom loop [last unloaded: btrfs]
[20433.487601] Pid: 12099, comm: btrfs Tainted: G        W   3.1.0-default+ #80
[20433.487603] Call Trace:
[20433.487608]  [<ffffffff81051c0f>] warn_slowpath_common+0x7f/0xc0
[20433.487613]  [<ffffffff81051c6a>] warn_slowpath_null+0x1a/0x20
[20433.487623]  [<ffffffffa00d6909>] __btrfs_cow_block+0x429/0x5e0 [btrfs]
[20433.487628]  [<ffffffff8108a429>] ? trace_hardirqs_off_caller+0x29/0xc0
[20433.487633]  [<ffffffff8108a7ed>] ? lock_release_holdtime+0x3d/0x1c0
[20433.487649]  [<ffffffffa0129cc0>] ? btrfs_set_lock_blocking_rw+0x50/0xb0 [btrfs]
[20433.487660]  [<ffffffffa00d6c66>] btrfs_cow_block+0x1a6/0x3d0 [btrfs]
[20433.487665]  [<ffffffff818b90cb>] ? _raw_write_unlock+0x2b/0x50
[20433.487676]  [<ffffffffa00dae70>] btrfs_search_slot+0x300/0xd20 [btrfs]
[20433.487691]  [<ffffffffa00eedcf>] btrfs_lookup_inode+0x2f/0xa0 [btrfs]
[20433.487707]  [<ffffffffa00fd186>] btrfs_update_inode_item+0x66/0x120 [btrfs]
[20433.487723]  [<ffffffffa00fe63b>] btrfs_update_inode+0xab/0xc0 [btrfs]
[20433.487739]  [<ffffffffa0134e61>] ? lookup_free_ino_inode+0x51/0xe0 [btrfs]
[20433.487753]  [<ffffffffa00ef515>] btrfs_save_ino_cache+0x145/0x2f0 [btrfs]
[20433.487769]  [<ffffffffa00f7464>] ? commit_fs_roots+0xa4/0x1c0 [btrfs]
[20433.487784]  [<ffffffffa00f7494>] commit_fs_roots+0xd4/0x1c0 [btrfs]
[20433.487800]  [<ffffffffa00f86a4>] btrfs_commit_transaction+0x454/0x900 [btrfs]
[20433.487805]  [<ffffffff8108a7ed>] ? lock_release_holdtime+0x3d/0x1c0
[20433.487821]  [<ffffffffa0126e08>] ? btrfs_mksubvol+0x298/0x360 [btrfs]
[20433.487826]  [<ffffffff81076550>] ? wake_up_bit+0x40/0x40
[20433.487830]  [<ffffffff8134738e>] ? do_raw_spin_unlock+0x5e/0xb0
[20433.487846]  [<ffffffffa0126ec8>] btrfs_mksubvol+0x358/0x360 [btrfs]
[20433.487851]  [<ffffffff8110ece3>] ? might_fault+0x53/0xb0
[20433.487867]  [<ffffffffa0126fd0>] btrfs_ioctl_snap_create_transid+0x100/0x160 [btrfs]
[20433.487872]  [<ffffffff8110ece3>] ? might_fault+0x53/0xb0
[20433.487888]  [<ffffffffa01271ad>] btrfs_ioctl_snap_create_v2.clone.0+0xfd/0x110 [btrfs]
[20433.487905]  [<ffffffffa0128a78>] btrfs_ioctl+0x588/0x1080 [btrfs]
[20433.487909]  [<ffffffff818bd9c0>] ? do_page_fault+0x2d0/0x580
[20433.487913]  [<ffffffff8107d6cf>] ? local_clock+0x6f/0x80
[20433.487918]  [<ffffffff811473e8>] do_vfs_ioctl+0x98/0x560
[20433.487922]  [<ffffffff818b9fd9>] ? retint_swapgs+0x13/0x1b
[20433.487926]  [<ffffffff811478ff>] sys_ioctl+0x4f/0x80
[20433.487931]  [<ffffffff818c21c2>] system_call_fastpath+0x16/0x1b
[20433.487934] ---[ end trace d93007cf8d0a8ead ]---


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 0/5] fix bugs of sub transid -- WARNING: at fs/btrfs/ctree.c:432
  2011-11-29 16:17     ` [PATCH 0/5] fix bugs of sub transid -- WARNING: at fs/btrfs/ctree.c:432 David Sterba
@ 2011-12-01  1:32       ` Liu Bo
  2011-12-02 16:30         ` David Sterba
  0 siblings, 1 reply; 11+ messages in thread
From: Liu Bo @ 2011-12-01  1:32 UTC (permalink / raw)
  To: David Sterba, linux-btrfs, chris.mason, sensille

On 11/30/2011 12:17 AM, David Sterba wrote:
> On Tue, Nov 29, 2011 at 09:18:35AM +0800, Liu Bo wrote:
>> a) For the first one (last_snapshot bug),
>>
>> The test involves three processes (derived from Chris):
>>
>> mkfs.btrfs /dev/xxx
>> mount /dev/xxx /mnt
>>
>> 1) run compilebench -i 30 --makej -D /mnt
>>
>> Let compilebench run until it starts the create phase.
>>
>> 2) run synctest -f -u -n 200 -t 3 /mnt
>> 3) for x in `seq 1 200` ; do btrfs subvol snap /mnt /mnt/snap$x ; sleep 0.5 ; done
> 
> I have hit following 2 warnings during this test. Phase 1 was at compile
> stage, 2 and 3 were running. I did not see them during first run and other
> activity at the filestystem was 'du -sh /mnt'.
> 
> mount options: compress-force=lzo,discard,space_cache,autodefrag,inode_cache
> 
> Label: none  uuid: 79f4160b-81f8-46ed-968c-968cb17a2e87
>         Total devices 4 FS bytes used 7.76GB
>         devid    4 size 13.96GB used 2.26GB path /dev/sdb4
>         devid    3 size 13.96GB used 2.26GB path /dev/sdb3
>         devid    2 size 13.96GB used 3.00GB path /dev/sdb2
>         devid    1 size 13.96GB used 3.02GB path /dev/sdb1
> 
> fresh and default mkfs
> 
>  430         WARN_ON(root->ref_cows && trans->transaction->transid !=
>  431                 root->fs_info->running_transaction->transid);
>  432         WARN_ON(root->ref_cows && trans->transid < root->last_trans);
> 

Hi, David,

This should be a miss from me.

The warning is aimed to check whether this ref_cow root is in this transaction, so we can change it
to WARN_ON(root->ref_cows && trans->transaction->transid > root->last_trans);

BTW, did you catch any "parent transid mismatch" during the test? :)

thanks,
liubo

> 
> 20433.473713] ------------[ cut here ]------------
> [20433.478825] WARNING: at fs/btrfs/ctree.c:432 __btrfs_cow_block+0x429/0x5e0 [btrfs]()
> [20433.487148] Hardware name: Santa Rosa platform
> [20433.487150] Modules linked in: btrfs aoe sr_mod ide_cd_mod cdrom loop [last unloaded: btrfs]
> [20433.487162] Pid: 12099, comm: btrfs Tainted: G        W   3.1.0-default+ #80
> [20433.487165] Call Trace:
> [20433.487174]  [<ffffffff81051c0f>] warn_slowpath_common+0x7f/0xc0
> [20433.487179]  [<ffffffff81051c6a>] warn_slowpath_null+0x1a/0x20
> [20433.487190]  [<ffffffffa00d6909>] __btrfs_cow_block+0x429/0x5e0 [btrfs]
> [20433.487196]  [<ffffffff8108a429>] ? trace_hardirqs_off_caller+0x29/0xc0
> [20433.487201]  [<ffffffff8108a7ed>] ? lock_release_holdtime+0x3d/0x1c0
> [20433.487218]  [<ffffffffa0129cc0>] ? btrfs_set_lock_blocking_rw+0x50/0xb0 [btrfs]
> [20433.487230]  [<ffffffffa00d6c66>] btrfs_cow_block+0x1a6/0x3d0 [btrfs]
> [20433.487236]  [<ffffffff818b90cb>] ? _raw_write_unlock+0x2b/0x50
> [20433.487247]  [<ffffffffa00dae70>] btrfs_search_slot+0x300/0xd20 [btrfs]
> [20433.487262]  [<ffffffffa00eedcf>] btrfs_lookup_inode+0x2f/0xa0 [btrfs]
> [20433.487279]  [<ffffffffa00fd186>] btrfs_update_inode_item+0x66/0x120 [btrfs]
> [20433.487296]  [<ffffffffa00fe63b>] btrfs_update_inode+0xab/0xc0 [btrfs]
> [20433.487313]  [<ffffffffa0134e61>] ? lookup_free_ino_inode+0x51/0xe0 [btrfs]
> [20433.487327]  [<ffffffffa00ef515>] btrfs_save_ino_cache+0x145/0x2f0 [btrfs]
> [20433.487342]  [<ffffffffa00f7464>] ? commit_fs_roots+0xa4/0x1c0 [btrfs]
> [20433.487357]  [<ffffffffa00f7494>] commit_fs_roots+0xd4/0x1c0 [btrfs]
> [20433.487373]  [<ffffffffa00f86a4>] btrfs_commit_transaction+0x454/0x900 [btrfs]
> [20433.487378]  [<ffffffff8108a7ed>] ? lock_release_holdtime+0x3d/0x1c0
> [20433.487395]  [<ffffffffa0126e08>] ? btrfs_mksubvol+0x298/0x360 [btrfs]
> [20433.487400]  [<ffffffff81076550>] ? wake_up_bit+0x40/0x40
> [20433.487405]  [<ffffffff8134738e>] ? do_raw_spin_unlock+0x5e/0xb0
> [20433.487421]  [<ffffffffa0126ec8>] btrfs_mksubvol+0x358/0x360 [btrfs]
> [20433.487427]  [<ffffffff8110ece3>] ? might_fault+0x53/0xb0
> [20433.487443]  [<ffffffffa0126fd0>] btrfs_ioctl_snap_create_transid+0x100/0x160 [btrfs]
> [20433.487448]  [<ffffffff8110ece3>] ? might_fault+0x53/0xb0
> [20433.487464]  [<ffffffffa01271ad>] btrfs_ioctl_snap_create_v2.clone.0+0xfd/0x110 [btrfs]
> [20433.487482]  [<ffffffffa0128a78>] btrfs_ioctl+0x588/0x1080 [btrfs]
> [20433.487487]  [<ffffffff818bd9c0>] ? do_page_fault+0x2d0/0x580
> [20433.487492]  [<ffffffff8107d6cf>] ? local_clock+0x6f/0x80
> [20433.487498]  [<ffffffff811473e8>] do_vfs_ioctl+0x98/0x560
> [20433.487502]  [<ffffffff818b9fd9>] ? retint_swapgs+0x13/0x1b
> [20433.487507]  [<ffffffff811478ff>] sys_ioctl+0x4f/0x80
> [20433.487512]  [<ffffffff818c21c2>] system_call_fastpath+0x16/0x1b
> [20433.487515] ---[ end trace d93007cf8d0a8eac ]---
> [20433.487576] ------------[ cut here ]------------
> [20433.487587] WARNING: at fs/btrfs/ctree.c:432 __btrfs_cow_block+0x429/0x5e0 [btrfs]()
> [20433.487590] Hardware name: Santa Rosa platform
> [20433.487592] Modules linked in: btrfs aoe sr_mod ide_cd_mod cdrom loop [last unloaded: btrfs]
> [20433.487601] Pid: 12099, comm: btrfs Tainted: G        W   3.1.0-default+ #80
> [20433.487603] Call Trace:
> [20433.487608]  [<ffffffff81051c0f>] warn_slowpath_common+0x7f/0xc0
> [20433.487613]  [<ffffffff81051c6a>] warn_slowpath_null+0x1a/0x20
> [20433.487623]  [<ffffffffa00d6909>] __btrfs_cow_block+0x429/0x5e0 [btrfs]
> [20433.487628]  [<ffffffff8108a429>] ? trace_hardirqs_off_caller+0x29/0xc0
> [20433.487633]  [<ffffffff8108a7ed>] ? lock_release_holdtime+0x3d/0x1c0
> [20433.487649]  [<ffffffffa0129cc0>] ? btrfs_set_lock_blocking_rw+0x50/0xb0 [btrfs]
> [20433.487660]  [<ffffffffa00d6c66>] btrfs_cow_block+0x1a6/0x3d0 [btrfs]
> [20433.487665]  [<ffffffff818b90cb>] ? _raw_write_unlock+0x2b/0x50
> [20433.487676]  [<ffffffffa00dae70>] btrfs_search_slot+0x300/0xd20 [btrfs]
> [20433.487691]  [<ffffffffa00eedcf>] btrfs_lookup_inode+0x2f/0xa0 [btrfs]
> [20433.487707]  [<ffffffffa00fd186>] btrfs_update_inode_item+0x66/0x120 [btrfs]
> [20433.487723]  [<ffffffffa00fe63b>] btrfs_update_inode+0xab/0xc0 [btrfs]
> [20433.487739]  [<ffffffffa0134e61>] ? lookup_free_ino_inode+0x51/0xe0 [btrfs]
> [20433.487753]  [<ffffffffa00ef515>] btrfs_save_ino_cache+0x145/0x2f0 [btrfs]
> [20433.487769]  [<ffffffffa00f7464>] ? commit_fs_roots+0xa4/0x1c0 [btrfs]
> [20433.487784]  [<ffffffffa00f7494>] commit_fs_roots+0xd4/0x1c0 [btrfs]
> [20433.487800]  [<ffffffffa00f86a4>] btrfs_commit_transaction+0x454/0x900 [btrfs]
> [20433.487805]  [<ffffffff8108a7ed>] ? lock_release_holdtime+0x3d/0x1c0
> [20433.487821]  [<ffffffffa0126e08>] ? btrfs_mksubvol+0x298/0x360 [btrfs]
> [20433.487826]  [<ffffffff81076550>] ? wake_up_bit+0x40/0x40
> [20433.487830]  [<ffffffff8134738e>] ? do_raw_spin_unlock+0x5e/0xb0
> [20433.487846]  [<ffffffffa0126ec8>] btrfs_mksubvol+0x358/0x360 [btrfs]
> [20433.487851]  [<ffffffff8110ece3>] ? might_fault+0x53/0xb0
> [20433.487867]  [<ffffffffa0126fd0>] btrfs_ioctl_snap_create_transid+0x100/0x160 [btrfs]
> [20433.487872]  [<ffffffff8110ece3>] ? might_fault+0x53/0xb0
> [20433.487888]  [<ffffffffa01271ad>] btrfs_ioctl_snap_create_v2.clone.0+0xfd/0x110 [btrfs]
> [20433.487905]  [<ffffffffa0128a78>] btrfs_ioctl+0x588/0x1080 [btrfs]
> [20433.487909]  [<ffffffff818bd9c0>] ? do_page_fault+0x2d0/0x580
> [20433.487913]  [<ffffffff8107d6cf>] ? local_clock+0x6f/0x80
> [20433.487918]  [<ffffffff811473e8>] do_vfs_ioctl+0x98/0x560
> [20433.487922]  [<ffffffff818b9fd9>] ? retint_swapgs+0x13/0x1b
> [20433.487926]  [<ffffffff811478ff>] sys_ioctl+0x4f/0x80
> [20433.487931]  [<ffffffff818c21c2>] system_call_fastpath+0x16/0x1b
> [20433.487934] ---[ end trace d93007cf8d0a8ead ]---
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 0/5] fix bugs of sub transid -- WARNING: at fs/btrfs/ctree.c:432
  2011-12-01  1:32       ` Liu Bo
@ 2011-12-02 16:30         ` David Sterba
  0 siblings, 0 replies; 11+ messages in thread
From: David Sterba @ 2011-12-02 16:30 UTC (permalink / raw)
  To: Liu Bo; +Cc: David Sterba, linux-btrfs, chris.mason, sensille

On Thu, Dec 01, 2011 at 09:32:19AM +0800, Liu Bo wrote:
> The warning is aimed to check whether this ref_cow root is in this transaction, so we can change it
> to WARN_ON(root->ref_cows && trans->transaction->transid > root->last_trans);

Ok, I'll add this change to next testing round.

> BTW, did you catch any "parent transid mismatch" during the test? :)

No such message appeared in the syslog.


david

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2011-12-02 16:30 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-21 10:10 [PATCH 0/5] fix bugs of sub transid Liu Bo
2011-11-21 10:10 ` [PATCH 1/5] Btrfs: fix btrfs_copy_root warning Liu Bo
2011-11-21 10:10 ` [PATCH 2/5] Btrfs: fix bug with heavy snapshot and heavy fsync Liu Bo
2011-11-21 10:10 ` [PATCH 3/5] Btrfs: fix inconsistent tree Liu Bo
2011-11-21 10:10 ` [PATCH 4/5] Btrfs: filter shared blocks in should_cow_block Liu Bo
2011-11-21 10:10 ` [PATCH 5/5] Btrfs: update disk extent ref generation Liu Bo
2011-11-28 15:10 ` [PATCH 0/5] fix bugs of sub transid David Sterba
2011-11-29  1:18   ` Liu Bo
2011-11-29 16:17     ` [PATCH 0/5] fix bugs of sub transid -- WARNING: at fs/btrfs/ctree.c:432 David Sterba
2011-12-01  1:32       ` Liu Bo
2011-12-02 16:30         ` David Sterba

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).