diff options
author | David Chinner <dgc@sgi.com> | 2008-04-10 12:21:53 +1000 |
---|---|---|
committer | Lachlan McIlroy <lachlan@redback.melbourne.sgi.com> | 2008-04-18 11:59:23 +1000 |
commit | fc6149d8d9634814cdcd9283b8f2efd3359181df (patch) | |
tree | 601c3ad274aae19a264009a385b8eb95977ada9a /fs/xfs/xfs_log_recover.c | |
parent | d87dd6360dce86cad9099aed74f14b4dd0143301 (diff) | |
download | op-kernel-dev-fc6149d8d9634814cdcd9283b8f2efd3359181df.zip op-kernel-dev-fc6149d8d9634814cdcd9283b8f2efd3359181df.tar.gz |
[XFS] Check for xfs_free_extent() failing.
xfs_free_extent() can fail, but log recovery never bothers to check if it
successfully free the extent it was supposed to. This could lead to silent
corruption during log recovery. Abort log recovery if we fail to free an
extent.
SGI-PV: 980084
SGI-Modid: xfs-linux-melb:xfs-kern:30801a
Signed-off-by: David Chinner <dgc@sgi.com>
Signed-off-by: Niv Sardi <xaiki@sgi.com>
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_log_recover.c')
-rw-r--r-- | fs/xfs/xfs_log_recover.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 418582b..3a8fe7b 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -3003,15 +3003,15 @@ xlog_recover_process_efi( tp = xfs_trans_alloc(mp, 0); error = xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0, 0, 0); - if (error) { - xfs_trans_cancel(tp, XFS_TRANS_ABORT); - return error; - } + if (error) + goto abort_error; efdp = xfs_trans_get_efd(tp, efip, efip->efi_format.efi_nextents); for (i = 0; i < efip->efi_format.efi_nextents; i++) { extp = &(efip->efi_format.efi_extents[i]); - xfs_free_extent(tp, extp->ext_start, extp->ext_len); + error = xfs_free_extent(tp, extp->ext_start, extp->ext_len); + if (error) + goto abort_error; xfs_trans_log_efd_extent(tp, efdp, extp->ext_start, extp->ext_len); } @@ -3019,6 +3019,10 @@ xlog_recover_process_efi( efip->efi_flags |= XFS_EFI_RECOVERED; error = xfs_trans_commit(tp, 0); return error; + +abort_error: + xfs_trans_cancel(tp, XFS_TRANS_ABORT); + return error; } /* |