mirror of
https://github.com/reactos/reactos.git
synced 2024-07-30 16:18:43 +00:00
- Simplify/modularize FS registration by using distinct lists for each type of FS (Tape/Disk/Network/Cdrom).
- Optimize by using directly the device queue instead of allocating a structure for each FS registered. - Hack IopMountVolume to manage this new model. Improved version coming in next patch to deal with some bugs. svn path=/trunk/; revision=22758
This commit is contained in:
parent
23e06403c7
commit
8da2913330
|
@ -16,24 +16,14 @@
|
||||||
|
|
||||||
#if defined (ALLOC_PRAGMA)
|
#if defined (ALLOC_PRAGMA)
|
||||||
#pragma alloc_text(INIT, IoInitFileSystemImplementation)
|
#pragma alloc_text(INIT, IoInitFileSystemImplementation)
|
||||||
#endif
|
|
||||||
|
|
||||||
/* TYPES *******************************************************************/
|
|
||||||
|
|
||||||
typedef struct _FILE_SYSTEM_OBJECT
|
|
||||||
{
|
|
||||||
PDEVICE_OBJECT DeviceObject;
|
|
||||||
LIST_ENTRY Entry;
|
|
||||||
} FILE_SYSTEM_OBJECT, *PFILE_SYSTEM_OBJECT;
|
|
||||||
|
|
||||||
#if defined (ALLOC_PRAGMA)
|
|
||||||
#pragma alloc_text(INIT, IoInitVpbImplementation)
|
#pragma alloc_text(INIT, IoInitVpbImplementation)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* GLOBALS ******************************************************************/
|
/* GLOBALS ******************************************************************/
|
||||||
|
|
||||||
ERESOURCE FileSystemListLock;
|
ERESOURCE FileSystemListLock;
|
||||||
LIST_ENTRY FileSystemListHead;
|
LIST_ENTRY IopDiskFsListHead, IopNetworkFsListHead;
|
||||||
|
LIST_ENTRY IopCdRomFsListHead, IopTapeFsListHead;
|
||||||
KGUARDED_MUTEX FsChangeNotifyListLock;
|
KGUARDED_MUTEX FsChangeNotifyListLock;
|
||||||
LIST_ENTRY FsChangeNotifyListHead;
|
LIST_ENTRY FsChangeNotifyListHead;
|
||||||
KSPIN_LOCK IoVpbLock;
|
KSPIN_LOCK IoVpbLock;
|
||||||
|
@ -53,11 +43,14 @@ INIT_FUNCTION
|
||||||
NTAPI
|
NTAPI
|
||||||
IoInitFileSystemImplementation(VOID)
|
IoInitFileSystemImplementation(VOID)
|
||||||
{
|
{
|
||||||
InitializeListHead(&FileSystemListHead);
|
/* Initialize the FS Lists and Locks */
|
||||||
ExInitializeResourceLite(&FileSystemListLock);
|
InitializeListHead(&IopDiskFsListHead);
|
||||||
|
InitializeListHead(&IopNetworkFsListHead);
|
||||||
InitializeListHead(&FsChangeNotifyListHead);
|
InitializeListHead(&IopCdRomFsListHead);
|
||||||
KeInitializeGuardedMutex(&FsChangeNotifyListLock);
|
InitializeListHead(&IopTapeFsListHead);
|
||||||
|
ExInitializeResourceLite(&FileSystemListLock);
|
||||||
|
InitializeListHead(&FsChangeNotifyListHead);
|
||||||
|
KeInitializeGuardedMutex(&FsChangeNotifyListLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -174,38 +167,57 @@ VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
IoShutdownRegisteredFileSystems(VOID)
|
IoShutdownRegisteredFileSystems(VOID)
|
||||||
{
|
{
|
||||||
FILE_SYSTEM_OBJECT* current;
|
PLIST_ENTRY ListEntry;
|
||||||
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
IO_STATUS_BLOCK StatusBlock;
|
||||||
PIRP Irp;
|
PIRP Irp;
|
||||||
KEVENT Event;
|
KEVENT Event;
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* Lock the FS List and initialize an event to wait on */
|
||||||
KeEnterCriticalRegion();
|
KeEnterCriticalRegion();
|
||||||
ExAcquireResourceSharedLite(&FileSystemListLock,TRUE);
|
ExAcquireResourceSharedLite(&FileSystemListLock,TRUE);
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
|
|
||||||
LIST_FOR_EACH(current, &FileSystemListHead, FILE_SYSTEM_OBJECT,Entry)
|
/* Get the first entry and start looping */
|
||||||
|
ListEntry = IopDiskFsListHead.Flink;
|
||||||
|
while (ListEntry != &IopDiskFsListHead)
|
||||||
{
|
{
|
||||||
/* send IRP_MJ_SHUTDOWN */
|
/* Get the device object */
|
||||||
|
DeviceObject = CONTAINING_RECORD(ListEntry,
|
||||||
|
DEVICE_OBJECT,
|
||||||
|
Queue.ListEntry);
|
||||||
|
|
||||||
|
/* Check if we're attached */
|
||||||
|
if (DeviceObject->AttachedDevice)
|
||||||
|
{
|
||||||
|
/* Get the attached device */
|
||||||
|
DeviceObject = IoGetAttachedDevice(DeviceObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Build the shutdown IRP and call the driver */
|
||||||
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SHUTDOWN,
|
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SHUTDOWN,
|
||||||
current->DeviceObject,
|
DeviceObject,
|
||||||
NULL,
|
NULL,
|
||||||
0,
|
0,
|
||||||
0,
|
NULL,
|
||||||
&Event,
|
&Event,
|
||||||
&IoStatusBlock);
|
&StatusBlock);
|
||||||
|
Status = IoCallDriver(DeviceObject, Irp);
|
||||||
Status = IoCallDriver(current->DeviceObject,Irp);
|
|
||||||
if (Status == STATUS_PENDING)
|
if (Status == STATUS_PENDING)
|
||||||
{
|
{
|
||||||
KeWaitForSingleObject(&Event,
|
/* Wait on the driver */
|
||||||
Executive,
|
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||||
KernelMode,
|
|
||||||
FALSE,
|
|
||||||
NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reset the event */
|
||||||
|
KeClearEvent(&Event);
|
||||||
|
|
||||||
|
/* Go to the next entry */
|
||||||
|
ListEntry = ListEntry->Flink;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Release the lock */
|
||||||
ExReleaseResourceLite(&FileSystemListLock);
|
ExReleaseResourceLite(&FileSystemListLock);
|
||||||
KeLeaveCriticalRegion();
|
KeLeaveCriticalRegion();
|
||||||
}
|
}
|
||||||
|
@ -311,63 +323,58 @@ IopMountVolume(IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN BOOLEAN Alertable,
|
IN BOOLEAN Alertable,
|
||||||
OUT PVPB *Vpb)
|
OUT PVPB *Vpb)
|
||||||
{
|
{
|
||||||
PFILE_SYSTEM_OBJECT current;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
DEVICE_TYPE MatchingDeviceType;
|
PLIST_ENTRY FsList, ListEntry;
|
||||||
PDEVICE_OBJECT DevObject;
|
PDEVICE_OBJECT DevObject;
|
||||||
|
PDEVICE_OBJECT FileSystemDeviceObject;
|
||||||
ASSERT_IRQL(PASSIVE_LEVEL);
|
ASSERT_IRQL(PASSIVE_LEVEL);
|
||||||
|
|
||||||
switch (DeviceObject->DeviceType)
|
|
||||||
{
|
|
||||||
case FILE_DEVICE_DISK:
|
|
||||||
case FILE_DEVICE_VIRTUAL_DISK: /* ?? */
|
|
||||||
MatchingDeviceType = FILE_DEVICE_DISK_FILE_SYSTEM;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FILE_DEVICE_CD_ROM:
|
|
||||||
MatchingDeviceType = FILE_DEVICE_CD_ROM_FILE_SYSTEM;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FILE_DEVICE_NETWORK:
|
|
||||||
MatchingDeviceType = FILE_DEVICE_NETWORK_FILE_SYSTEM;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FILE_DEVICE_TAPE:
|
|
||||||
MatchingDeviceType = FILE_DEVICE_TAPE_FILE_SYSTEM;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
CPRINT("No matching file system type found for device type: %x\n",
|
|
||||||
DeviceObject->DeviceType);
|
|
||||||
return(STATUS_UNRECOGNIZED_VOLUME);
|
|
||||||
}
|
|
||||||
|
|
||||||
KeEnterCriticalRegion();
|
KeEnterCriticalRegion();
|
||||||
ExAcquireResourceSharedLite(&FileSystemListLock,TRUE);
|
ExAcquireResourceSharedLite(&FileSystemListLock,TRUE);
|
||||||
|
|
||||||
restart:
|
restart:
|
||||||
LIST_FOR_EACH(current,&FileSystemListHead, FILE_SYSTEM_OBJECT, Entry)
|
/* For a mount operation, this can only be a Disk, CD-ROM or tape */
|
||||||
|
if ((DeviceObject->DeviceType == FILE_DEVICE_DISK) ||
|
||||||
|
(DeviceObject->DeviceType == FILE_DEVICE_VIRTUAL_DISK))
|
||||||
{
|
{
|
||||||
if (current->DeviceObject->DeviceType != MatchingDeviceType)
|
/* Use the disk list */
|
||||||
{
|
FsList = &IopDiskFsListHead;
|
||||||
continue;
|
}
|
||||||
}
|
else if (DeviceObject->DeviceType == FILE_DEVICE_CD_ROM)
|
||||||
|
{
|
||||||
|
/* Use the CD-ROM list */
|
||||||
|
FsList = &IopCdRomFsListHead;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* It's gotta be a tape... */
|
||||||
|
FsList = &IopTapeFsListHead;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now loop the fs list until one of the file systems accepts us */
|
||||||
|
ListEntry = FsList->Flink;
|
||||||
|
while (ListEntry != FsList)
|
||||||
|
{
|
||||||
|
/* Get the Device Object for this FS */
|
||||||
|
FileSystemDeviceObject = CONTAINING_RECORD(ListEntry,
|
||||||
|
DEVICE_OBJECT,
|
||||||
|
Queue.ListEntry);
|
||||||
|
|
||||||
/* If we are not allowed to mount this volume as a raw filesystem volume
|
/* If we are not allowed to mount this volume as a raw filesystem volume
|
||||||
then don't try this */
|
then don't try this */
|
||||||
if (!AllowRawMount && RawFsIsRawFileSystemDeviceObject(current->DeviceObject))
|
if (!AllowRawMount && RawFsIsRawFileSystemDeviceObject(FileSystemDeviceObject))
|
||||||
{
|
{
|
||||||
Status = STATUS_UNRECOGNIZED_VOLUME;
|
Status = STATUS_UNRECOGNIZED_VOLUME;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Status = IopMountFileSystem(current->DeviceObject, DeviceObject);
|
Status = IopMountFileSystem(FileSystemDeviceObject, DeviceObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (Status)
|
switch (Status)
|
||||||
{
|
{
|
||||||
case STATUS_FS_DRIVER_REQUIRED:
|
case STATUS_FS_DRIVER_REQUIRED:
|
||||||
DevObject = current->DeviceObject;
|
DevObject = FileSystemDeviceObject;
|
||||||
ExReleaseResourceLite(&FileSystemListLock);
|
ExReleaseResourceLite(&FileSystemListLock);
|
||||||
IopLoadFileSystem(DevObject);
|
IopLoadFileSystem(DevObject);
|
||||||
ExAcquireResourceSharedLite(&FileSystemListLock,TRUE);
|
ExAcquireResourceSharedLite(&FileSystemListLock,TRUE);
|
||||||
|
@ -497,27 +504,59 @@ VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
IoRegisterFileSystem(IN PDEVICE_OBJECT DeviceObject)
|
IoRegisterFileSystem(IN PDEVICE_OBJECT DeviceObject)
|
||||||
{
|
{
|
||||||
PFILE_SYSTEM_OBJECT Fs;
|
PLIST_ENTRY FsList = NULL;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
Fs = ExAllocatePoolWithTag(NonPagedPool,
|
/* Acquire the FS lock */
|
||||||
sizeof(FILE_SYSTEM_OBJECT),
|
|
||||||
TAG_FILE_SYSTEM);
|
|
||||||
ASSERT(Fs!=NULL);
|
|
||||||
|
|
||||||
Fs->DeviceObject = DeviceObject;
|
|
||||||
KeEnterCriticalRegion();
|
KeEnterCriticalRegion();
|
||||||
ExAcquireResourceExclusiveLite(&FileSystemListLock, TRUE);
|
ExAcquireResourceExclusiveLite(&FileSystemListLock, TRUE);
|
||||||
|
|
||||||
/* The RAW filesystem device objects must be last in the list so the
|
/* Check what kind of FS this is */
|
||||||
raw filesystem driver is the last filesystem driver asked to mount
|
if (DeviceObject->DeviceType == FILE_DEVICE_DISK_FILE_SYSTEM)
|
||||||
a volume. It is always the first filesystem driver registered so
|
{
|
||||||
we use InsertHeadList() here as opposed to the other alternative
|
/* Use the disk list */
|
||||||
InsertTailList(). */
|
FsList = &IopDiskFsListHead;
|
||||||
InsertHeadList(&FileSystemListHead, &Fs->Entry);
|
}
|
||||||
|
else if (DeviceObject->DeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM)
|
||||||
|
{
|
||||||
|
/* Use the network device list */
|
||||||
|
FsList = &IopNetworkFsListHead;
|
||||||
|
}
|
||||||
|
else if (DeviceObject->DeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM)
|
||||||
|
{
|
||||||
|
/* Use the CD-ROM list */
|
||||||
|
FsList = &IopCdRomFsListHead;
|
||||||
|
}
|
||||||
|
else if (DeviceObject->DeviceType == FILE_DEVICE_TAPE_FILE_SYSTEM)
|
||||||
|
{
|
||||||
|
/* Use the tape list */
|
||||||
|
FsList = &IopTapeFsListHead;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure that we have a valid list */
|
||||||
|
if (FsList)
|
||||||
|
{
|
||||||
|
/* Check if we should insert it at the top or bottom of the list */
|
||||||
|
if (DeviceObject->Flags & DO_LOW_PRIORITY_FILESYSTEM)
|
||||||
|
{
|
||||||
|
/* At the bottom */
|
||||||
|
InsertTailList(FsList->Blink, &DeviceObject->Queue.ListEntry);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* On top */
|
||||||
|
InsertHeadList(FsList, &DeviceObject->Queue.ListEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear the initializing flag */
|
||||||
|
DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||||
|
|
||||||
|
/* Release the FS Lock */
|
||||||
ExReleaseResourceLite(&FileSystemListLock);
|
ExReleaseResourceLite(&FileSystemListLock);
|
||||||
KeLeaveCriticalRegion();
|
KeLeaveCriticalRegion();
|
||||||
|
|
||||||
|
/* Notify file systems of the addition */
|
||||||
IopNotifyFileSystemChange(DeviceObject, TRUE);
|
IopNotifyFileSystemChange(DeviceObject, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -528,24 +567,19 @@ VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
IoUnregisterFileSystem(IN PDEVICE_OBJECT DeviceObject)
|
IoUnregisterFileSystem(IN PDEVICE_OBJECT DeviceObject)
|
||||||
{
|
{
|
||||||
PFILE_SYSTEM_OBJECT current;
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Acquire the FS lock */
|
||||||
KeEnterCriticalRegion();
|
KeEnterCriticalRegion();
|
||||||
ExAcquireResourceExclusiveLite(&FileSystemListLock, TRUE);
|
ExAcquireResourceExclusiveLite(&FileSystemListLock, TRUE);
|
||||||
|
|
||||||
LIST_FOR_EACH(current,&FileSystemListHead, FILE_SYSTEM_OBJECT,Entry)
|
/* Simply remove the entry */
|
||||||
{
|
RemoveEntryList(&DeviceObject->Queue.ListEntry);
|
||||||
if (current->DeviceObject == DeviceObject)
|
|
||||||
{
|
|
||||||
RemoveEntryList(¤t->Entry);
|
|
||||||
ExFreePoolWithTag(current, TAG_FILE_SYSTEM);
|
|
||||||
ExReleaseResourceLite(&FileSystemListLock);
|
|
||||||
KeLeaveCriticalRegion();
|
|
||||||
IopNotifyFileSystemChange(DeviceObject, FALSE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* And notify all registered file systems */
|
||||||
|
IopNotifyFileSystemChange(DeviceObject, FALSE);
|
||||||
|
|
||||||
|
/* Then release the lock */
|
||||||
ExReleaseResourceLite(&FileSystemListLock);
|
ExReleaseResourceLite(&FileSystemListLock);
|
||||||
KeLeaveCriticalRegion();
|
KeLeaveCriticalRegion();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue