浏览代码

[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>
David Chinner 17 年之前
父节点
当前提交
fc6149d8d9
共有 1 个文件被更改,包括 9 次插入5 次删除
  1. 9 5
      fs/xfs/xfs_log_recover.c

+ 9 - 5
fs/xfs/xfs_log_recover.c

@@ -3003,15 +3003,15 @@ xlog_recover_process_efi(
 
 
 	tp = xfs_trans_alloc(mp, 0);
 	tp = xfs_trans_alloc(mp, 0);
 	error = xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0, 0, 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);
 	efdp = xfs_trans_get_efd(tp, efip, efip->efi_format.efi_nextents);
 
 
 	for (i = 0; i < efip->efi_format.efi_nextents; i++) {
 	for (i = 0; i < efip->efi_format.efi_nextents; i++) {
 		extp = &(efip->efi_format.efi_extents[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,
 		xfs_trans_log_efd_extent(tp, efdp, extp->ext_start,
 					 extp->ext_len);
 					 extp->ext_len);
 	}
 	}
@@ -3019,6 +3019,10 @@ xlog_recover_process_efi(
 	efip->efi_flags |= XFS_EFI_RECOVERED;
 	efip->efi_flags |= XFS_EFI_RECOVERED;
 	error = xfs_trans_commit(tp, 0);
 	error = xfs_trans_commit(tp, 0);
 	return error;
 	return error;
+
+abort_error:
+	xfs_trans_cancel(tp, XFS_TRANS_ABORT);
+	return error;
 }
 }
 
 
 /*
 /*