Reiser4xp

Development

I implemented the project together with my fellow students Josias Hosang and Oliver Kadlcek as our first semester project at HSR during the autumn semester 2005.

Detailed Description

Reiser4xp is a file system driver developed for Windows XP. It implements Reiser4 file system read functionality. Thus it enables Windows to read files and directories written by Linux to such a partition, making the work with a dual-boot-system easier. Reiser4 was expected to continue the success of ReiserFS (the Reiser file system version 3). Unfortunately this did not happen until today and does not seem to change in the future. Nevertheless Reiser4xp has been completed and provided enough performance and stability to use it in every-day situations (e.g. watching high resolution movies).

Technical Details

Feature List

Challenges

The main challenge with Reiser4xp was the lack of documentation. Namesys, the creator of Reiser4 did not provide much documentation. The only information about the file system structure was on one HTML page. In addition Hans Reiser refused to give us any more information. Therefore we had to collect all information by hand from analyzing existing Reiser4 partitions and of course the source code.

The Installable File System Kit for Windows on the other contained some example implementations. We also had a book about file system development on Windows NT which is similar to Windows XP. But even with that much information we had to fight a lot of the times with unexpected behaviour of Windows.

Code Sample

The code snippet presented here is the code that is used to mount a Reiser4 partition on Windows XP.

//------------------------------------------------------------------------------ /*! \brief Volume (Partition) mounten. \param target_device_obj Zu mountende Partition. \param vpb Volume Parameter Block der Partition. \param io_stack_location Stack-Position des aktuellen IRPs. \return Ergebnis des mount-Vorgangs. */ NTSTATUS rfsS_init_volume( PDEVICE_OBJECT target_device_obj, PVPB vpb, PIO_STACK_LOCATION io_stack_location, VolumeControlBlock* vcb ) { NTSTATUS status; VolumeDeviceObject* vol_device_obj = NULL; ULONG i; UNICODE_STRING vol_label; WCHAR vol_label_buffer[sizeof(WCHAR)*16]; rfsD_enter_func( DBG_TRACE_FSCTRL ); if( io_stack_location->DeviceObject != global_data.device_obj ) return STATUS_INVALID_DEVICE_REQUEST; // Volume erstellen (wird durch vcb repräsentiert) status = IoCreateDevice( global_data.driver_obj, sizeof( VolumeDeviceObject ) - sizeof( DEVICE_OBJECT ), NULL, FILE_DEVICE_DISK_FILE_SYSTEM, 0, FALSE, (PDEVICE_OBJECT*) &vol_device_obj ); if( !NT_SUCCESS( status ) ) { rfsD_leave_func( DBG_TRACE_FSCTRL ); return status; } // VCB initialisieren ExInitializeResourceLite( &vcb->nt_required_fcb.resource ); ExAcquireResourceExclusiveLite( &vcb->nt_required_fcb.resource, TRUE ); // ? if (target_device_obj->AlignmentRequirement > vol_device_obj->device_obj.AlignmentRequirement) vol_device_obj->device_obj.AlignmentRequirement = target_device_obj->AlignmentRequirement; vcb->nid = NODE_TYPE_VOLUME_CONTROL_BLOCK; vcb->target_device_obj = target_device_obj; vcb->volume_device_obj = (PDEVICE_OBJECT) vol_device_obj; vcb->vpb = vpb; vcb->dismounted = FALSE; ccb_hash_init( &vcb->open_ccbs, 2048 ); InitializeListHead( &vcb->notify_list ); vcb->win_part_initialized = FALSE; FsRtlNotifyInitializeSync(&vcb->notify_sync); vol_device_obj->vcb = vcb; // VPB initialisieren vpb->DeviceObject = (PDEVICE_OBJECT) vol_device_obj; vpb->SerialNumber = vcb->sid->mkfs_id; // VolumeLabel auslesen vol_label.Buffer = vol_label_buffer; vol_label.MaximumLength = sizeof(WCHAR) * 16; vol_label.Length = 0; status = rfsS_read_reiser4_vol_label( target_device_obj, &vol_label ); if( !NT_SUCCESS( status ) ) { rfsD_leave_func( DBG_TRACE_FSCTRL ); return status; } vpb->VolumeLabelLength = vol_label.Length; RtlCopyMemory( vpb->VolumeLabel, vol_label.Buffer, vol_label.Length ); // Volume ist jetzt fertig initialisiert ClearFlag( vol_device_obj->device_obj.Flags, DO_DEVICE_INITIALIZING ); ExReleaseResourceForThreadLite( &vcb->nt_required_fcb.resource, ExGetCurrentResourceThread() ); // Now send mount notification. Note that since this is outside of any // synchronization since the synchronous delivery of this may go to // folks that provoke re-entrance to the FS. // /* if (MountNewVolume) { FsRtlNotifyVolumeEvent( Vcb->RootDcb->Specific.Dcb.DirectoryFile, FSRTL_VOLUME_MOUNT ); ObDereferenceObject( Vcb->RootDcb->Specific.Dcb.DirectoryFile ); } */ rfsD_leave_func( DBG_TRACE_FSCTRL ); return STATUS_SUCCESS; }

Additional Material / Downloads

Related Links