diff options
author | Josef Bacik <josef@redhat.com> | 2010-10-26 20:52:53 +0400 |
---|---|---|
committer | Josef Bacik <josef@redhat.com> | 2010-10-26 20:52:53 +0400 |
commit | 382279336f428c80f344edfc30d53797e3e76146 (patch) | |
tree | 91b1acbc1f60430742ace0b9155c4a014b7dbbaf /fs | |
parent | 0e78340f3c1fc603e8016c8ac304766bcc65506e (diff) | |
download | linux-382279336f428c80f344edfc30d53797e3e76146.tar.xz |
Btrfs: set trans to null in reserve_metadata_bytes if we commit the transaction
btrfs_commit_transaction will free our trans, but because we pass trans to
shrink_delalloc we could possibly have a use after free situation. So instead
if we commit the transaction, set trans to null and set committed to true so we
don't keep trying to commit a transaction. This fixes a panic I could reproduce
at will. Thanks,
Signed-off-by: Josef Bacik <josef@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/extent-tree.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 180a50146ddf..e2dfd4ab3b9b 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -3157,6 +3157,7 @@ static int reserve_metadata_bytes(struct btrfs_trans_handle *trans, int retries = 0; int ret = 0; bool reserved = false; + bool committed = false; again: ret = -ENOSPC; @@ -3249,17 +3250,19 @@ again: goto out; ret = -EAGAIN; - if (trans) + if (trans || committed) goto out; - ret = -ENOSPC; trans = btrfs_join_transaction(root, 1); if (IS_ERR(trans)) goto out; ret = btrfs_commit_transaction(trans, root); - if (!ret) + if (!ret) { + trans = NULL; + committed = true; goto again; + } out: if (reserved) { |