summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/transaction.h
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fusionio.com>2013-09-30 11:36:38 -0400
committerChris Mason <chris.mason@fusionio.com>2013-11-11 21:54:03 -0500
commit724e2315db3d59a8201d4a87c7c7a873e60e1ce0 (patch)
tree0a1af5a08bfd4312ad169ed4c1ac9a8e804b3419 /fs/btrfs/transaction.h
parentc16ce1901431629fbe5b9387cc966d62a089e4df (diff)
downloadlinux-724e2315db3d59a8201d4a87c7c7a873e60e1ce0.tar.bz2
Btrfs: fix two use-after-free bugs with transaction cleanup
I was noticing the slab redzone stuff going off every once and a while during transaction aborts. This was caused by two things 1) We would walk the pending snapshots and set their error to -ECANCELED. We don't need to do this, the snapshot stuff waits for a transaction commit and if there is a problem we just free our pending snapshot object and exit. Doing this was causing us to touch the pending snapshot object after the thing had already been freed. 2) We were freeing the transaction manually with wanton disregard for it's use_count reference counter. To fix this I cleaned up the transaction freeing loop to either wait for the transaction commit to finish if it was in the middle of that (since it will be cleaned and freed up there) or to do the cleanup oursevles. I also moved the global "kill all things dirty everywhere" stuff outside of the transaction cleanup loop since that only needs to be done once. With this patch I'm no longer seeing slab corruption because of use after frees. Thanks, Signed-off-by: Josef Bacik <jbacik@fusionio.com> Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'fs/btrfs/transaction.h')
-rw-r--r--fs/btrfs/transaction.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h
index 5c2af8491621..306f88ae1de3 100644
--- a/fs/btrfs/transaction.h
+++ b/fs/btrfs/transaction.h
@@ -166,4 +166,5 @@ int btrfs_wait_marked_extents(struct btrfs_root *root,
struct extent_io_tree *dirty_pages, int mark);
int btrfs_transaction_blocked(struct btrfs_fs_info *info);
int btrfs_transaction_in_commit(struct btrfs_fs_info *info);
+void btrfs_put_transaction(struct btrfs_transaction *transaction);
#endif