diff --git a/headers/os/drivers/fs_interface.h b/headers/os/drivers/fs_interface.h index 421972567a..6912b41b83 100644 --- a/headers/os/drivers/fs_interface.h +++ b/headers/os/drivers/fs_interface.h @@ -245,10 +245,8 @@ typedef struct file_system_module_info { const char *name, disk_job_id job); status_t (*set_content_parameters)(int fd, partition_id partition, const char *parameters, disk_job_id job); - status_t (*initialize)(const char *partition, const char *name, + status_t (*initialize)(int fd, partition_id partition, const char *name, const char *parameters, disk_job_id job); - // This is pretty close to how the hook in R5 looked. Save the job ID, - // of course and that the parameters were given as (void*, size_t) pair. } file_system_module_info; diff --git a/headers/private/fs_shell/fssh_fs_interface.h b/headers/private/fs_shell/fssh_fs_interface.h index 80a56f49c4..27ae245dfa 100644 --- a/headers/private/fs_shell/fssh_fs_interface.h +++ b/headers/private/fs_shell/fssh_fs_interface.h @@ -279,10 +279,8 @@ typedef struct fssh_file_system_module_info { const char *name, fssh_disk_job_id job); fssh_status_t (*set_content_parameters)(int fd, fssh_partition_id partition, const char *parameters, fssh_disk_job_id job); - fssh_status_t (*initialize)(const char *partition, const char *name, - const char *parameters, fssh_disk_job_id job); - // This is pretty close to how the hook in R5 looked. Save the job ID, - // of course and that the parameters were given as (void*, size_t) pair. + fssh_status_t (*initialize)(int fd, fssh_partition_id partition, + const char *name, const char *parameters, fssh_disk_job_id job); } fssh_file_system_module_info; diff --git a/src/add-ons/kernel/file_systems/bfs/Volume.cpp b/src/add-ons/kernel/file_systems/bfs/Volume.cpp index fbd185af10..b181d80348 100644 --- a/src/add-ons/kernel/file_systems/bfs/Volume.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Volume.cpp @@ -27,10 +27,12 @@ static const int32 kDesiredAllocationGroups = 56; class DeviceOpener { public: + DeviceOpener(int fd, int mode); DeviceOpener(const char *device, int mode); ~DeviceOpener(); int Open(const char *device, int mode); + int Open(int fd, int mode); void *InitCache(off_t numBlocks, uint32 blockSize); void RemoveCache(bool allowWrites); @@ -56,6 +58,14 @@ DeviceOpener::DeviceOpener(const char *device, int mode) } +DeviceOpener::DeviceOpener(int fd, int mode) + : + fBlockCache(NULL) +{ + Open(fd, mode); +} + + DeviceOpener::~DeviceOpener() { if (fDevice >= B_OK) { @@ -97,6 +107,19 @@ DeviceOpener::Open(const char *device, int mode) } +int +DeviceOpener::Open(int fd, int mode) +{ + fDevice = dup(fd); + if (fDevice < 0) + return errno; + + fMode = mode; + + return fDevice; +} + + void * DeviceOpener::InitCache(off_t numBlocks, uint32 blockSize) { @@ -563,7 +586,7 @@ Volume::Identify(int fd, disk_super_block *superBlock) status_t -Volume::Initialize(const char *device, const char *name, uint32 blockSize, +Volume::Initialize(int fd, const char *name, uint32 blockSize, uint32 flags) { // although there is no really good reason for it, we won't @@ -576,7 +599,7 @@ Volume::Initialize(const char *device, const char *name, uint32 blockSize, && blockSize != 8192) return B_BAD_VALUE; - DeviceOpener opener(device, O_RDWR); + DeviceOpener opener(fd, O_RDWR); if (opener.Device() < B_OK) return B_BAD_VALUE; diff --git a/src/add-ons/kernel/file_systems/bfs/Volume.h b/src/add-ons/kernel/file_systems/bfs/Volume.h index fd233b51af..50a20566f9 100644 --- a/src/add-ons/kernel/file_systems/bfs/Volume.h +++ b/src/add-ons/kernel/file_systems/bfs/Volume.h @@ -31,7 +31,7 @@ class Volume { status_t Mount(const char *device, uint32 flags); status_t Unmount(); - status_t Initialize(const char *device, const char *name, + status_t Initialize(int fd, const char *name, uint32 blockSize, uint32 flags); bool IsValidSuperBlock(); diff --git a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp index 945ae85414..b970f2f59e 100644 --- a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp @@ -2038,12 +2038,9 @@ bfs_validate_initialize(partition_data *partition, char *name, status_t -bfs_initialize(const char *partition, const char *name, const char *parameters, - disk_job_id job) +bfs_initialize(int fd, partition_id partition, const char *name, + const char *parameters, disk_job_id job) { - if (partition == NULL) - return B_BAD_VALUE; - uint32 blockSize = 1024; uint32 flags = 0; bool verbose = false; @@ -2070,7 +2067,7 @@ bfs_initialize(const char *partition, const char *name, const char *parameters, } Volume volume(-1); - status_t status = volume.Initialize(partition, name, blockSize, flags); + status_t status = volume.Initialize(fd, name, blockSize, flags); if (status < B_OK) { INFORM(("Initializing volume failed: %s\n", strerror(status))); return status; diff --git a/src/kits/storage/DiskDevice.cpp b/src/kits/storage/DiskDevice.cpp index 76638e0831..c084db4218 100644 --- a/src/kits/storage/DiskDevice.cpp +++ b/src/kits/storage/DiskDevice.cpp @@ -228,6 +228,7 @@ BDiskDevice::CommitModifications(bool synchronously, if (!_IsShadow()) return B_BAD_VALUE; // TODO: Get port and token from the progressMessenger + // TODO: Respect "synchronously"! port_id port = -1; int32 token = -1; error = _kern_commit_disk_device_modifications(ID(), port, token, diff --git a/src/system/kernel/disk_device_manager/KFileSystem.cpp b/src/system/kernel/disk_device_manager/KFileSystem.cpp index 66a6fbe71c..905d244eca 100644 --- a/src/system/kernel/disk_device_manager/KFileSystem.cpp +++ b/src/system/kernel/disk_device_manager/KFileSystem.cpp @@ -7,6 +7,7 @@ #include #include "ddm_modules.h" +#include "KDiskDeviceJob.h" #include "KDiskDeviceUtils.h" #include "KFileSystem.h" #include "KPartition.h" @@ -308,8 +309,31 @@ status_t KFileSystem::Initialize(KPartition *partition, const char *name, const char *parameters, KDiskDeviceJob *job) { - // to be implemented - return B_ERROR; + // check parameters + if (!partition || !job || !fModule) + return B_BAD_VALUE; + if (!fModule->initialize) + return B_NOT_SUPPORTED; + + // open partition device (we need a temporary read-lock) + KDiskDeviceManager *manager = KDiskDeviceManager::Default(); + if (!manager->ReadLockPartition(partition->ID())) + return B_ERROR; + DeviceReadLocker locker(partition->Device(), true); + + int fd = -1; + status_t result = partition->Open(O_RDWR, &fd); + if (result != B_OK) + return result; + + locker.Unlock(); + + // call the module hook + result = fModule->initialize(fd, partition->ID(), name, parameters, + job->ID()); + + close(fd); + return result; } diff --git a/src/system/kernel/disk_device_manager/KPartitioningSystem.cpp b/src/system/kernel/disk_device_manager/KPartitioningSystem.cpp index bcb2ffef94..6bb109196a 100644 --- a/src/system/kernel/disk_device_manager/KPartitioningSystem.cpp +++ b/src/system/kernel/disk_device_manager/KPartitioningSystem.cpp @@ -901,6 +901,7 @@ KPartitioningSystem::Initialize(KPartition *partition, const char *name, } // let the module do its job +// TODO: The partition must not be locked at this point! status_t result = fModule->initialize(fd, partition->ID(), name, parameters, job->ID()); diff --git a/src/tools/fs_shell/unistd.cpp b/src/tools/fs_shell/unistd.cpp index c4b4ac9207..2559a19bde 100644 --- a/src/tools/fs_shell/unistd.cpp +++ b/src/tools/fs_shell/unistd.cpp @@ -34,7 +34,8 @@ #ifndef __BEOS__ - // The _kern_close() defined in libroot_build.so. + // Defined in libroot_build.so. + extern "C" int _kern_dup(int fd); extern "C" status_t _kern_close(int fd); #endif @@ -76,6 +77,24 @@ get_partition_size(int fd, off_t maxSize) #endif // HAIKU_HOST_PLATFORM_LINUX +int +fssh_dup(int fd) +{ + // Use the _kern_dup() defined in libroot on BeOS incompatible systems. + // Required for proper attribute emulation support. + #if __BEOS__ + return dup(fd); + #else + int result = _kern_dup(fd); + if (result < 0) { + fssh_set_errno(result); + return -1; + } + return result; + #endif +} + + int fssh_close(int fd) { diff --git a/src/tools/fs_shell/vfs.cpp b/src/tools/fs_shell/vfs.cpp index 0d66918db0..2e3d7c4b15 100644 --- a/src/tools/fs_shell/vfs.cpp +++ b/src/tools/fs_shell/vfs.cpp @@ -16,6 +16,7 @@ #include "fssh_atomic.h" #include "fssh_defs.h" #include "fssh_dirent.h" +#include "fssh_errno.h" #include "fssh_fcntl.h" #include "fssh_fs_info.h" #include "fssh_fs_volume.h" @@ -5184,30 +5185,30 @@ _kern_initialize_volume(const char* fsName, const char *partition, // The partition argument should point to a real file/device. - // normalize the device path - KPath normalizedDevice; -// status = normalizedDevice.SetTo(device, true); -// NOTE: normalizing works only in our namespace. - fssh_status_t status = normalizedDevice.SetTo(partition, false); - if (status != FSSH_B_OK) - return status; - - partition = normalizedDevice.Path(); - // correct path to file device + // open partition + int fd = fssh_open(partition, FSSH_O_RDWR); + if (fd < 0) + return fssh_errno; // get the file system module fssh_file_system_module_info* fsModule = get_file_system(fsName); - if (fsModule == NULL) + if (fsModule == NULL) { + fssh_close(fd); return FSSH_ENODEV; + } // initialize - if (fsModule->initialize) - status = (*fsModule->initialize)(partition, name, parameters, -1); - else + fssh_status_t status; + if (fsModule->initialize) { + status = (*fsModule->initialize)(fd, -1, name, parameters, -1); + // We've got no partition or job IDs -- the FS will hopefully + // ignore that. + } else status = FSSH_B_NOT_SUPPORTED; - // put the file system module + // put the file system module, close partition put_file_system(fsModule); + fssh_close(fd); return status; }