mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
[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 a1d7e9936d
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
This commit is contained in:
parent
16e988d108
commit
cb408102cc
1 changed files with 42 additions and 49 deletions
|
@ -858,70 +858,63 @@ Ext2ZeroBuffer( IN PEXT2_IRP_CONTEXT IrpContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define SIZE_256K 0x40000
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
Ext2SaveBuffer( IN PEXT2_IRP_CONTEXT IrpContext,
|
Ext2SaveBuffer( IN PEXT2_IRP_CONTEXT IrpContext,
|
||||||
IN PEXT2_VCB Vcb,
|
IN PEXT2_VCB Vcb,
|
||||||
IN LONGLONG offset,
|
IN LONGLONG Offset,
|
||||||
IN ULONG size,
|
IN ULONG Size,
|
||||||
IN PVOID buf )
|
IN PVOID Buf )
|
||||||
{
|
{
|
||||||
struct buffer_head *bh = NULL;
|
BOOLEAN rc;
|
||||||
BOOLEAN rc = 0;
|
|
||||||
|
while (Size) {
|
||||||
|
|
||||||
|
PBCB Bcb;
|
||||||
|
PVOID Buffer;
|
||||||
|
ULONG Length;
|
||||||
|
|
||||||
|
Length = (ULONG)Offset & (SIZE_256K - 1);
|
||||||
|
Length = SIZE_256K - Length;
|
||||||
|
if (Size < Length)
|
||||||
|
Length = Size;
|
||||||
|
|
||||||
|
if ( !CcPreparePinWrite(
|
||||||
|
Vcb->Volume,
|
||||||
|
(PLARGE_INTEGER) (&Offset),
|
||||||
|
Length,
|
||||||
|
FALSE,
|
||||||
|
PIN_WAIT | PIN_EXCLUSIVE,
|
||||||
|
&Bcb,
|
||||||
|
&Buffer )) {
|
||||||
|
|
||||||
|
DEBUG(DL_ERR, ( "Ext2SaveBuffer: failed to PinLock offset %I64xh ...\n", Offset));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
_SEH2_TRY {
|
_SEH2_TRY {
|
||||||
|
|
||||||
while (size) {
|
RtlCopyMemory(Buffer, Buf, Length);
|
||||||
|
CcSetDirtyPinnedData(Bcb, NULL );
|
||||||
|
SetFlag(Vcb->Volume->Flags, FO_FILE_MODIFIED);
|
||||||
|
|
||||||
sector_t block;
|
rc = Ext2AddVcbExtent(Vcb, Offset, (LONGLONG)Length);
|
||||||
ULONG len = 0, delta = 0;
|
if (!rc) {
|
||||||
|
|
||||||
block = (sector_t) (offset >> BLOCK_BITS);
|
|
||||||
delta = (ULONG)offset & (BLOCK_SIZE - 1);
|
|
||||||
len = BLOCK_SIZE - delta;
|
|
||||||
if (size < len)
|
|
||||||
len = size;
|
|
||||||
|
|
||||||
if (delta == 0 && len >= BLOCK_SIZE) {
|
|
||||||
bh = sb_getblk_zero(&Vcb->sb, block);
|
|
||||||
} else {
|
|
||||||
bh = sb_getblk(&Vcb->sb, block);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!bh) {
|
|
||||||
DEBUG(DL_ERR, ("Ext2SaveBuffer: can't load block %I64u\n", block));
|
|
||||||
DbgBreak();
|
DbgBreak();
|
||||||
_SEH2_LEAVE;
|
Ext2Sleep(100);
|
||||||
|
rc = Ext2AddVcbExtent(Vcb, Offset, (LONGLONG)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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_SEH2_TRY {
|
|
||||||
RtlCopyMemory(bh->b_data + delta, buf, len);
|
|
||||||
mark_buffer_dirty(bh);
|
|
||||||
} _SEH2_FINALLY {
|
|
||||||
fini_bh(&bh);
|
|
||||||
} _SEH2_END;
|
|
||||||
|
|
||||||
buf = (PUCHAR)buf + len;
|
|
||||||
offset = offset + len;
|
|
||||||
size = size - len;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = TRUE;
|
|
||||||
|
|
||||||
} _SEH2_FINALLY {
|
} _SEH2_FINALLY {
|
||||||
|
CcUnpinData(Bcb);
|
||||||
if (bh)
|
|
||||||
fini_bh(&bh);
|
|
||||||
|
|
||||||
} _SEH2_END;
|
} _SEH2_END;
|
||||||
|
|
||||||
|
Buf = (PUCHAR)Buf + Length;
|
||||||
|
Offset = Offset + Length;
|
||||||
|
Size = Size - Length;
|
||||||
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue