summaryrefslogtreecommitdiff
path: root/fs/xfs/xfs_log_recover.c
diff options
context:
space:
mode:
authorDavid Chinner <dgc@sgi.com>2008-04-10 06:21:53 +0400
committerLachlan McIlroy <lachlan@redback.melbourne.sgi.com>2008-04-18 05:59:23 +0400
commitfc6149d8d9634814cdcd9283b8f2efd3359181df (patch)
tree601c3ad274aae19a264009a385b8eb95977ada9a /fs/xfs/xfs_log_recover.c
parentd87dd6360dce86cad9099aed74f14b4dd0143301 (diff)
downloadlinux-fc6149d8d9634814cdcd9283b8f2efd3359181df.tar.xz
[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.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 418582b709eb..3a8fe7bfa2af 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;
}
/*