mirror of
https://github.com/reactos/reactos.git
synced 2024-11-23 11:33:31 +08: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
@ -858,70 +858,63 @@ 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;
|
||||
BOOLEAN rc;
|
||||
|
||||
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 {
|
||||
|
||||
while (size) {
|
||||
RtlCopyMemory(Buffer, Buf, Length);
|
||||
CcSetDirtyPinnedData(Bcb, NULL );
|
||||
SetFlag(Vcb->Volume->Flags, FO_FILE_MODIFIED);
|
||||
|
||||
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;
|
||||
|
||||
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));
|
||||
rc = Ext2AddVcbExtent(Vcb, Offset, (LONGLONG)Length);
|
||||
if (!rc) {
|
||||
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 {
|
||||
|
||||
if (bh)
|
||||
fini_bh(&bh);
|
||||
|
||||
CcUnpinData(Bcb);
|
||||
} _SEH2_END;
|
||||
|
||||
Buf = (PUCHAR)Buf + Length;
|
||||
Offset = Offset + Length;
|
||||
Size = Size - Length;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user