diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-12-05 23:20:17 +0000 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-12-05 23:20:17 +0000 |
commit | 742eaa6a6e356a16788ce6530271de89bc4f8fb5 (patch) | |
tree | 12fc040daab06ac796c61c1d92bfad9bb054d1c1 /fs/btrfs/ctree.c | |
parent | ba8bb18a03f8c7508565c385576a5431a4ad804a (diff) | |
parent | ae72fd588a2b302222769b44775912b83f0785eb (diff) | |
download | linux-742eaa6a6e356a16788ce6530271de89bc4f8fb5.tar.bz2 |
Merge branch 'for-rmk' of git://git.kernel.org/pub/scm/linux/kernel/git/will/linux into devel-stable
Conflicts:
arch/arm/common/gic.c
arch/arm/plat-omap/include/plat/common.h
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r-- | fs/btrfs/ctree.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 0fe615e4ea38..dede441bdeee 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -514,10 +514,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->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; } |