mirror of
https://github.com/reactos/reactos.git
synced 2024-10-30 11:35:58 +00:00
220 lines
5 KiB
C
220 lines
5 KiB
C
|
/*
|
||
|
* COPYRIGHT: See COPYING in the top level directory
|
||
|
* PROJECT: ReactOS kernel
|
||
|
* FILE: services/fs/ext2/super.c
|
||
|
* PURPOSE: ext2 filesystem
|
||
|
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||
|
* UPDATE HISTORY:
|
||
|
*/
|
||
|
|
||
|
/* INCLUDES *****************************************************************/
|
||
|
|
||
|
#include <ntddk.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
#define NDEBUG
|
||
|
#include <debug.h>
|
||
|
|
||
|
#include "ext2fs.h"
|
||
|
|
||
|
/* FUNCTIONS *****************************************************************/
|
||
|
|
||
|
NTSTATUS Ext2ReadPage(PDEVICE_EXTENSION DeviceExt,
|
||
|
PEXT2_FCB Fcb,
|
||
|
PVOID Buffer,
|
||
|
ULONG Offset)
|
||
|
{
|
||
|
ULONG block, i;
|
||
|
|
||
|
for (i=0; i<4; i++)
|
||
|
{
|
||
|
block = Ext2BlockMap(DeviceExt,
|
||
|
Fcb->i.inode,
|
||
|
Offset + i);
|
||
|
Ext2ReadSectors(DeviceExt->StorageDevice,
|
||
|
block,
|
||
|
1,
|
||
|
Buffer + (i*BLOCKSIZE));
|
||
|
}
|
||
|
return(STATUS_SUCCESS);
|
||
|
}
|
||
|
|
||
|
NTSTATUS Ext2ReadFile(PDEVICE_EXTENSION DeviceExt,
|
||
|
PFILE_OBJECT FileObject,
|
||
|
PVOID Buffer,
|
||
|
ULONG Length,
|
||
|
LARGE_INTEGER OffsetL)
|
||
|
{
|
||
|
PVOID BaseAddress;
|
||
|
BOOLEAN Uptodate = FALSE;
|
||
|
PCACHE_SEGMENT CacheSeg;
|
||
|
ULONG Offset = (ULONG)OffsetL.u.LowPart;
|
||
|
PEXT2_FCB Fcb;
|
||
|
ULONG block, i, Delta;
|
||
|
DPRINT("Ext2ReadFile(DeviceExt %x, FileObject %x, Buffer %x, Length %d, \n"
|
||
|
"OffsetL %d)\n",DeviceExt,FileObject,Buffer,Length,(ULONG)OffsetL);
|
||
|
|
||
|
Fcb = (PEXT2_FCB)FileObject->FsContext;
|
||
|
|
||
|
Ext2LoadInode(DeviceExt,
|
||
|
Fcb->inode,
|
||
|
&Fcb->i);
|
||
|
|
||
|
if (Offset >= Fcb->i.inode->i_size)
|
||
|
{
|
||
|
DPRINT("Returning end of file\n");
|
||
|
return(STATUS_END_OF_FILE);
|
||
|
}
|
||
|
if ((Offset + Length) > Fcb->i.inode->i_size)
|
||
|
{
|
||
|
Length = Fcb->i.inode->i_size - Offset;
|
||
|
}
|
||
|
|
||
|
Ext2ReleaseInode(DeviceExt,
|
||
|
&Fcb->i);
|
||
|
|
||
|
if ((Offset % PAGE_SIZE) != 0)
|
||
|
{
|
||
|
Delta = min(PAGE_SIZE - (Offset % PAGE_SIZE),Length);
|
||
|
CcRequestCachePage(Fcb->Bcb,
|
||
|
Offset,
|
||
|
&BaseAddress,
|
||
|
&Uptodate,
|
||
|
&CacheSeg);
|
||
|
if (Uptodate == FALSE)
|
||
|
{
|
||
|
Ext2ReadPage(DeviceExt,
|
||
|
Fcb,
|
||
|
BaseAddress,
|
||
|
Offset / BLOCKSIZE);
|
||
|
}
|
||
|
memcpy(Buffer, BaseAddress + (Offset % PAGE_SIZE), Delta);
|
||
|
CcReleaseCachePage(Fcb->Bcb,
|
||
|
CacheSeg,
|
||
|
TRUE);
|
||
|
Length = Length - Delta;
|
||
|
Offset = Offset + Delta;
|
||
|
Buffer = Buffer + Delta;
|
||
|
}
|
||
|
CHECKPOINT;
|
||
|
for (i=0; i<(Length/PAGE_SIZE); i++)
|
||
|
{
|
||
|
CcRequestCachePage(Fcb->Bcb,
|
||
|
Offset,
|
||
|
&BaseAddress,
|
||
|
&Uptodate,
|
||
|
&CacheSeg);
|
||
|
if (Uptodate == FALSE)
|
||
|
{
|
||
|
Ext2ReadPage(DeviceExt,
|
||
|
Fcb,
|
||
|
BaseAddress,
|
||
|
(Offset / BLOCKSIZE));
|
||
|
}
|
||
|
memcpy(Buffer, BaseAddress, PAGE_SIZE);
|
||
|
CcReleaseCachePage(Fcb->Bcb,
|
||
|
CacheSeg,
|
||
|
TRUE);
|
||
|
Length = Length - PAGE_SIZE;
|
||
|
Offset = Offset + PAGE_SIZE;
|
||
|
Buffer = Buffer + PAGE_SIZE;
|
||
|
}
|
||
|
CHECKPOINT;
|
||
|
if ((Length % PAGE_SIZE) != 0)
|
||
|
{
|
||
|
CcRequestCachePage(Fcb->Bcb,
|
||
|
Offset,
|
||
|
&BaseAddress,
|
||
|
&Uptodate,
|
||
|
&CacheSeg);
|
||
|
if (Uptodate == FALSE)
|
||
|
{
|
||
|
Ext2ReadPage(DeviceExt,
|
||
|
Fcb,
|
||
|
BaseAddress,
|
||
|
(Offset / BLOCKSIZE));
|
||
|
}
|
||
|
DPRINT("Copying %x to %x Length %d\n",BaseAddress,Buffer,Length);
|
||
|
memcpy(Buffer,BaseAddress,Length);
|
||
|
CcReleaseCachePage(Fcb->Bcb,
|
||
|
CacheSeg,
|
||
|
TRUE);
|
||
|
}
|
||
|
CHECKPOINT;
|
||
|
|
||
|
return(STATUS_SUCCESS);
|
||
|
}
|
||
|
|
||
|
|
||
|
NTSTATUS STDCALL
|
||
|
Ext2Write(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||
|
{
|
||
|
DPRINT("Ext2Write(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
|
||
|
|
||
|
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
||
|
Irp->IoStatus.Information = 0;
|
||
|
return(STATUS_UNSUCCESSFUL);
|
||
|
}
|
||
|
|
||
|
NTSTATUS STDCALL
|
||
|
Ext2FlushBuffers(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||
|
{
|
||
|
DPRINT("Ext2FlushBuffers(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
|
||
|
|
||
|
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
||
|
Irp->IoStatus.Information = 0;
|
||
|
return(STATUS_UNSUCCESSFUL);
|
||
|
}
|
||
|
|
||
|
NTSTATUS STDCALL
|
||
|
Ext2Shutdown(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||
|
{
|
||
|
DPRINT("Ext2Shutdown(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
|
||
|
|
||
|
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
||
|
Irp->IoStatus.Information = 0;
|
||
|
return(STATUS_UNSUCCESSFUL);
|
||
|
}
|
||
|
|
||
|
NTSTATUS STDCALL
|
||
|
Ext2Cleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||
|
{
|
||
|
DbgPrint("Ext2Cleanup(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
|
||
|
|
||
|
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
||
|
Irp->IoStatus.Information = 0;
|
||
|
|
||
|
DbgPrint("Ext2Cleanup() finished\n");
|
||
|
|
||
|
return(STATUS_UNSUCCESSFUL);
|
||
|
}
|
||
|
|
||
|
NTSTATUS STDCALL
|
||
|
Ext2Read(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||
|
{
|
||
|
ULONG Length;
|
||
|
PVOID Buffer;
|
||
|
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||
|
PFILE_OBJECT FileObject = Stack->FileObject;
|
||
|
PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
|
||
|
NTSTATUS Status;
|
||
|
|
||
|
DPRINT("Ext2Read(DeviceObject %x, FileObject %x, Irp %x)\n",
|
||
|
DeviceObject, FileObject, Irp);
|
||
|
|
||
|
Length = Stack->Parameters.Read.Length;
|
||
|
CHECKPOINT;
|
||
|
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||
|
CHECKPOINT;
|
||
|
CHECKPOINT;
|
||
|
|
||
|
Status = Ext2ReadFile(DeviceExt,FileObject,Buffer,Length,
|
||
|
Stack->Parameters.Read.ByteOffset);
|
||
|
|
||
|
Irp->IoStatus.Status = Status;
|
||
|
Irp->IoStatus.Information = Length;
|
||
|
IoCompleteRequest(Irp,IO_NO_INCREMENT);
|
||
|
|
||
|
return(Status);
|
||
|
}
|