diff --git a/headers/private/fs_shell/fssh_fs_interface.h b/headers/private/fs_shell/fssh_fs_interface.h index 9457ab09e4..80a56f49c4 100644 --- a/headers/private/fs_shell/fssh_fs_interface.h +++ b/headers/private/fs_shell/fssh_fs_interface.h @@ -7,6 +7,7 @@ #define _FSSH_FS_INTERFACE_H +#include "fssh_disk_device_defs.h" #include "fssh_module.h" #include "fssh_os.h" @@ -236,6 +237,52 @@ typedef struct fssh_file_system_module_info { struct fssh_dirent *buffer, fssh_size_t bufferSize, uint32_t *_num); fssh_status_t (*rewind_query)(fssh_fs_volume fs, fssh_fs_cookie cookie); + + /* capability querying (the device is read locked) */ + // ToDo: this will probably be combined to a single call + bool (*supports_defragmenting)(fssh_partition_data *partition, + bool *whileMounted); + bool (*supports_repairing)(fssh_partition_data *partition, + bool checkOnly, bool *whileMounted); + bool (*supports_resizing)(fssh_partition_data *partition, + bool *whileMounted); + bool (*supports_moving)(fssh_partition_data *partition, bool *isNoOp); + bool (*supports_setting_content_name)(fssh_partition_data *partition, + bool *whileMounted); + bool (*supports_setting_content_parameters)(fssh_partition_data *partition, + bool *whileMounted); + bool (*supports_initializing)(fssh_partition_data *partition); + + bool (*validate_resize)(fssh_partition_data *partition, fssh_off_t *size); + bool (*validate_move)(fssh_partition_data *partition, fssh_off_t *start); + bool (*validate_set_content_name)(fssh_partition_data *partition, + char *name); + bool (*validate_set_content_parameters)(fssh_partition_data *partition, + const char *parameters); + bool (*validate_initialize)(fssh_partition_data *partition, char *name, + const char *parameters); + + /* shadow partition modification (device is write locked) */ + fssh_status_t (*shadow_changed)(fssh_partition_data *partition, + uint32_t operation); + + /* writing (the device is NOT locked) */ + fssh_status_t (*defragment)(int fd, fssh_partition_id partition, + fssh_disk_job_id job); + fssh_status_t (*repair)(int fd, fssh_partition_id partition, bool checkOnly, + fssh_disk_job_id job); + fssh_status_t (*resize)(int fd, fssh_partition_id partition, + fssh_off_t size, fssh_disk_job_id job); + fssh_status_t (*move)(int fd, fssh_partition_id partition, + fssh_off_t offset, fssh_disk_job_id job); + fssh_status_t (*set_content_name)(int fd, fssh_partition_id partition, + 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_file_system_module_info; diff --git a/src/tools/fs_shell/fssh.cpp b/src/tools/fs_shell/fssh.cpp index 4aaf9e04ea..141488405c 100644 --- a/src/tools/fs_shell/fssh.cpp +++ b/src/tools/fs_shell/fssh.cpp @@ -1114,10 +1114,17 @@ standard_session(const char* device, const char* fsName, bool interactive) static int initialization_session(const char* device, const char* fsName, - const char* initParameters) + const char* volumeName, const char* initParameters) { - fprintf(stderr, "initialization not implemented yet\n"); - return 1; + fssh_status_t error = _kern_initialize_volume(fsName, device, + volumeName, initParameters); + if (error != FSSH_B_OK) { + fprintf(stderr, "Error: Initializing volume failed: %s\n", + fssh_strerror(error)); + return 1; + } + + return 0; } @@ -1126,7 +1133,8 @@ print_usage(bool error) { fprintf((error ? stderr : stdout), "Usage: %s [-n] \n" - " %s --initialize [-n] [ ]\n", + " %s --initialize [-n] " + "[ ]\n", sArgv[0], sArgv[0] ); } @@ -1156,6 +1164,7 @@ main(int argc, const char* const* argv) bool interactive = true; bool initialize = false; const char* device = NULL; + const char* volumeName = NULL; const char* initParameters = NULL; // eat options @@ -1178,11 +1187,19 @@ main(int argc, const char* const* argv) print_usage_and_exit(true); device = argv[argi++]; - // get init parameters - if (initialize && argi < argc) - initParameters = argv[argi++]; + // get volume name and init parameters + if (initialize) { + // volume name + if (argi >= argc) + print_usage_and_exit(true); + volumeName = argv[argi++]; - // if more parameters are excess + // (optional) init paramaters + if (argi < argc) + initParameters = argv[argi++]; + } + + // more parameters are excess if (argi < argc) print_usage_and_exit(true); @@ -1205,9 +1222,10 @@ main(int argc, const char* const* argv) // start the action int result; - if (initialize) - result = initialization_session(device, fsName, initParameters); - else + if (initialize) { + result = initialization_session(device, fsName, volumeName, + initParameters); + } else result = standard_session(device, fsName, interactive); return result; diff --git a/src/tools/fs_shell/syscalls.h b/src/tools/fs_shell/syscalls.h index 18bdee0cce..5f0ad08c0d 100644 --- a/src/tools/fs_shell/syscalls.h +++ b/src/tools/fs_shell/syscalls.h @@ -67,6 +67,10 @@ fssh_status_t _kern_remove_index(fssh_dev_t device, const char *name); fssh_status_t _kern_getcwd(char *buffer, fssh_size_t size); fssh_status_t _kern_setcwd(int fd, const char *path); +fssh_status_t _kern_initialize_volume(const char* fileSystem, + const char *partition, const char *name, + const char *parameters); + // defined in fd.cpp fssh_ssize_t _kern_read(int fd, fssh_off_t pos, void *buffer, fssh_size_t length); diff --git a/src/tools/fs_shell/vfs.cpp b/src/tools/fs_shell/vfs.cpp index 959217671c..cebd01cf9f 100644 --- a/src/tools/fs_shell/vfs.cpp +++ b/src/tools/fs_shell/vfs.cpp @@ -5169,3 +5169,41 @@ _kern_setcwd(int fd, const char *path) return set_cwd(fd, path != NULL ? pathBuffer.LockBuffer() : NULL, true); } + +fssh_status_t +_kern_initialize_volume(const char* fsName, const char *partition, + const char *name, const char *parameters) +{ + if (!fsName || ! partition) + return FSSH_B_BAD_VALUE; + + // 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 + + // get the file system module + fssh_file_system_module_info* fsModule = get_file_system(fsName); + if (fsModule == NULL) + return FSSH_ENODEV; + + // initialize + if (fsModule->initialize) + status = (*fsModule->initialize)(partition, name, parameters, -1); + else + status = FSSH_B_NOT_SUPPORTED; + + // put the file system module + put_file_system(fsModule); + + return status; +} +