https://git.reactos.org/?p=reactos.git;a=commitdiff;h=cb408102cc3e3ed853a00…
commit cb408102cc3e3ed853a009962482251e45861699
Author: Joachim Henze <Joachim.Henze(a)reactos.org>
AuthorDate: Sun Jun 27 16:21:32 2021 +0200
Commit: Joachim Henze <Joachim.Henze(a)reactos.org>
CommitDate: Sun Jun 27 16:21:32 2021 +0200
[EXT2] Fix filesystem corruption regressions CORE-17572 CORE-17195
It regressed when we upgraded Ext2Fsd to version 0.69 from version 0.68
via CORE-13980 in 0.4.8-dev-117-g a1d7e9936d8e58bc07ff2cc73a937ce845c7d542
The fix is a partial revert of that.
Thanks to the patches author Doug Lyons.
VBox
https://reactos.org/testman/compare.php?ids=77904,77908 LGTM
KVM
https://reactos.org/testman/compare.php?ids=77903,77907 LGTM
---
drivers/filesystems/ext2/src/ext3/generic.c | 91 +++++++++++++----------------
1 file changed, 42 insertions(+), 49 deletions(-)
diff --git a/drivers/filesystems/ext2/src/ext3/generic.c
b/drivers/filesystems/ext2/src/ext3/generic.c
index d6dd8c4eb6c..0140e930860 100644
--- a/drivers/filesystems/ext2/src/ext3/generic.c
+++ b/drivers/filesystems/ext2/src/ext3/generic.c
@@ -858,69 +858,62 @@ Ext2ZeroBuffer( IN PEXT2_IRP_CONTEXT IrpContext,
}
+#define SIZE_256K 0x40000
+
BOOLEAN
Ext2SaveBuffer( IN PEXT2_IRP_CONTEXT IrpContext,
IN PEXT2_VCB Vcb,
- IN LONGLONG offset,
- IN ULONG size,
- IN PVOID buf )
+ IN LONGLONG Offset,
+ IN ULONG Size,
+ IN PVOID Buf )
{
- struct buffer_head *bh = NULL;
- BOOLEAN rc = 0;
-
- _SEH2_TRY {
-
- while (size) {
-
- sector_t block;
- ULONG len = 0, delta = 0;
-
- block = (sector_t) (offset >> BLOCK_BITS);
- delta = (ULONG)offset & (BLOCK_SIZE - 1);
- len = BLOCK_SIZE - delta;
- if (size < len)
- len = size;
+ BOOLEAN rc;
- if (delta == 0 && len >= BLOCK_SIZE) {
- bh = sb_getblk_zero(&Vcb->sb, block);
- } else {
- bh = sb_getblk(&Vcb->sb, block);
- }
+ while (Size) {
- if (!bh) {
- DEBUG(DL_ERR, ("Ext2SaveBuffer: can't load block %I64u\n",
block));
- DbgBreak();
- _SEH2_LEAVE;
- }
+ PBCB Bcb;
+ PVOID Buffer;
+ ULONG Length;
- if (!buffer_uptodate(bh)) {
- int err = bh_submit_read(bh);
- if (err < 0) {
- DEBUG(DL_ERR, ("Ext2SaveBuffer: bh_submit_read failed: %d\n",
err));
- _SEH2_LEAVE;
- }
- }
+ Length = (ULONG)Offset & (SIZE_256K - 1);
+ Length = SIZE_256K - Length;
+ if (Size < Length)
+ Length = Size;
- _SEH2_TRY {
- RtlCopyMemory(bh->b_data + delta, buf, len);
- mark_buffer_dirty(bh);
- } _SEH2_FINALLY {
- fini_bh(&bh);
- } _SEH2_END;
+ if ( !CcPreparePinWrite(
+ Vcb->Volume,
+ (PLARGE_INTEGER) (&Offset),
+ Length,
+ FALSE,
+ PIN_WAIT | PIN_EXCLUSIVE,
+ &Bcb,
+ &Buffer )) {
- buf = (PUCHAR)buf + len;
- offset = offset + len;
- size = size - len;
+ DEBUG(DL_ERR, ( "Ext2SaveBuffer: failed to PinLock offset %I64xh
...\n", Offset));
+ return FALSE;
}
- rc = TRUE;
+ _SEH2_TRY {
- } _SEH2_FINALLY {
+ RtlCopyMemory(Buffer, Buf, Length);
+ CcSetDirtyPinnedData(Bcb, NULL );
+ SetFlag(Vcb->Volume->Flags, FO_FILE_MODIFIED);
- if (bh)
- fini_bh(&bh);
+ rc = Ext2AddVcbExtent(Vcb, Offset, (LONGLONG)Length);
+ if (!rc) {
+ DbgBreak();
+ Ext2Sleep(100);
+ rc = Ext2AddVcbExtent(Vcb, Offset, (LONGLONG)Length);
+ }
- } _SEH2_END;
+ } _SEH2_FINALLY {
+ CcUnpinData(Bcb);
+ } _SEH2_END;
+
+ Buf = (PUCHAR)Buf + Length;
+ Offset = Offset + Length;
+ Size = Size - Length;
+ }
return rc;
}