https://git.reactos.org/?p=reactos.git;a=commitdiff;h=cb408102cc3e3ed853a009...
commit cb408102cc3e3ed853a009962482251e45861699 Author: Joachim Henze Joachim.Henze@reactos.org AuthorDate: Sun Jun 27 16:21:32 2021 +0200 Commit: Joachim Henze Joachim.Henze@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; }