diff --git a/fs/disk/include/disk/disk.h b/fs/disk/include/disk/disk.h index cf2849629d..544d22c95e 100644 --- a/fs/disk/include/disk/disk.h +++ b/fs/disk/include/disk/disk.h @@ -22,7 +22,8 @@ #include #include -#include "os/mynewt.h" +#include +#include #ifdef __cplusplus extern "C" { @@ -35,19 +36,194 @@ extern "C" { #define DISK_EOS 4 /* OS error */ #define DISK_EUNINIT 5 /* File system not initialized */ -struct disk_ops { - int (*read)(uint8_t, uint32_t, void *, uint32_t); - int (*write)(uint8_t, uint32_t, const void *, uint32_t); - int (*ioctl)(uint8_t, uint32_t, void *); +typedef struct disk disk_t; +typedef struct disk_info disk_info_t; +typedef struct disk_listener disk_listener_t; - SLIST_ENTRY(disk_ops) sc_next; +/** + * Disk information + */ +struct disk_info { + /* Disk name (information only) */ + const char *name; + /* Disk block (sector) count */ + uint32_t block_count; + /* Block size (usually 512) */ + uint16_t block_size; + /* Set to 1 if disk is present */ + uint16_t present : 1; +}; + +typedef struct disk_ops { + /** Get basic information about disk + * + * @param disk - disk to query + * @param info - disk information to fill + * @return 0 on success, SYS_EINVAL if arguments are incorrect + */ + int (*get_info)(const struct disk *disk, struct disk_info *info); + + /** + * Inform driver that disk was just removed + * @param disk - disk that was ejected + * @return 0 on success, SYS_EINVAL if arguments are incorrect + */ + int (*eject)(struct disk *disk); + /** + * Read disk block + * @param disk - dist to read from + * @param lba - block to read + * @param buf - buffer for data + * @param block_count - number for blocks to read + * @return 0 on success + */ + int (*read)(struct disk *disk, uint32_t lba, void *buf, uint32_t block_count); + /** + * Write disk block + * @param disk - dist to write to + * @param lba - block to write to + * @param buf - data buffer + * @param block_count - number of blocks to write + * @return 0 on success + */ + int (*write)(struct disk *disk, uint32_t lba, const void *buf, uint32_t block_count); +} disk_ops_t; + +/* Disk listener operations */ +typedef struct disk_listener_ops { + /* New disk was inserted to driver and could be mounter */ + int (*disk_added)(struct disk_listener *listener, struct disk *disk); + /* Disk was ejected and should be unmounted */ + int (*disk_removed)(struct disk_listener *listener, struct disk *disk); +} disk_listener_ops_t; + +/* Disk listener */ +struct disk_listener { + const disk_listener_ops_t *ops; }; -int disk_register(const char *disk_name, const char *fs_name, struct disk_ops *dops); -struct disk_ops *disk_ops_for(const char *disk_name); -char *disk_fs_for(const char *disk_name); -char *disk_name_from_path(const char *path); -char *disk_filepath_from_path(const char *path); +/* Base for disks */ +struct disk { + const disk_ops_t *ops; +}; + +/** + * Function called when disk was inserted into a driver + * and system could mount it or otherwise be aware that new + * disk could be used + * + * @param disk - disk that was inserted + * + * @return 0 - for success + */ +int mn_disk_inserted(disk_t *disk); + +/** + * Function called when disk was removed, if disk was + * mounted it file system can be unmounted. If disk + * was present to MSC it can no longer be advertised + * as present. + * + * @param disk - disk that was remove from driver + * + * @return 0 -for success + */ +int mn_disk_ejected(disk_t *disk); + +/** + * Function return 1 if disk is present + * + * @param disk - disk to check for presence + * @return 1 - disk is present, 0 - disk is not present + */ +static inline int disk_present(disk_t *disk) +{ + disk_info_t di; + disk->ops->get_info(disk, &di); + + return di.present; +} + +/** + * Get disk information + * Disk information consist of size information + * + * @param disk - disk to get information from + * @param di - pointer to data to received disk information + * + * @return 0 - for success + */ +static inline int mn_disk_info_get(disk_t *disk, disk_info_t *di) +{ + return disk->ops->get_info(disk, di); +} + +/** + * Read sector(s) from disk + * + * @param disk - disk to read data from + * @param lba - sector number + * @param buf - buffer to be filled with data from disk + * @param block_count - number of sectors to read + * @return 0 - for success + */ +static inline int mn_disk_read(disk_t *disk, uint32_t lba, void *buf, uint32_t block_count) +{ + return disk->ops->read(disk, lba, buf, block_count); +} + +/** + * Write sector(s) to disk + * + * @param disk - disk to write to + * @param lba - first sector to write to + * @param buf - buffer with data + * @param block_count - number of sectors to write + * @return 0 - for success + */ +static inline int mn_disk_write(disk_t *disk, uint32_t lba, const void *buf, uint32_t block_count) +{ + return disk->ops->write(disk, lba, buf, block_count); +} + +/** + * Eject disk + * + * Calling this function will result in calling disk listeners about + * disk being removed via disk_removed(). This may result in file + * system being unmounted. + * + * @param disk - disk to eject + * @return 0 - for success + */ +static inline int mn_disk_eject(disk_t *disk) +{ + return disk->ops->eject(disk); +} + +/** + * Link time table to hold all available disk listeners + * that will be informed when disk is available and + * can be mounted or used in other ways. + */ +LINK_TABLE(disk_listener_t *, disk_listeners) + +/** + * @brief Macros to put disk_listener in link table + * + * i.e. + * // Define disk_listener_t structure + * disk_listener_t mounter = { + * .opt = &mounter_ops, + * }; + * + * DISK_LISTENER(mounter_entry, mounter) + * + * @param listener_entry - new pointer variable name that will be put in disk_listeners table + * @param listener - object of type disk_listener_t + */ +#define DISK_LISTENER(listener_entry, listener) \ + LINK_TABLE_ELEMENT(disk_listeners, listener_entry) = &listener; #ifdef __cplusplus } diff --git a/fs/disk/pkg.yml b/fs/disk/pkg.yml index 52a0f7f112..1157f15e92 100644 --- a/fs/disk/pkg.yml +++ b/fs/disk/pkg.yml @@ -18,10 +18,13 @@ # pkg.name: fs/disk -pkg.description: Disk management layer to glue filesystems to disk devices. +pkg.description: Disk management layer to disk devices. pkg.author: "Apache Mynewt " pkg.homepage: "http://mynewt.apache.org/" pkg.keywords: pkg.deps: - "@apache-mynewt-core/kernel/os" + +pkg.link_tables: + - disk_listeners diff --git a/fs/disk/src/disk.c b/fs/disk/src/disk.c index 93a2741fd2..910985375f 100644 --- a/fs/disk/src/disk.c +++ b/fs/disk/src/disk.c @@ -17,135 +17,38 @@ * under the License. */ -#include -#include -#include "os/mynewt.h" +#include +#include +#include #include -struct disk_info { - const char *disk_name; - const char *fs_name; - struct disk_ops *dops; +#define DISK_EOK 0 /* Success */ +#define DISK_EHW 1 /* Error accessing storage medium */ +#define DISK_ENOMEM 2 /* Insufficient memory */ +#define DISK_ENOENT 3 /* No such file or directory */ +#define DISK_EOS 4 /* OS error */ +#define DISK_EUNINIT 5 /* File system not initialized */ - SLIST_ENTRY(disk_info) sc_next; -}; - -static SLIST_HEAD(, disk_info) disks = SLIST_HEAD_INITIALIZER(); - -/** - * - */ -int disk_register(const char *disk_name, const char *fs_name, struct disk_ops *dops) +int +mn_disk_inserted(disk_t *disk) { - struct disk_info *info = NULL; - struct disk_info *sc; - - SLIST_FOREACH(sc, &disks, sc_next) { - if (strcmp(sc->disk_name, disk_name) == 0) { - return DISK_ENOENT; - } - } + int count = LINK_TABLE_SIZE(disk_listeners); - info = malloc(sizeof(struct disk_info)); - if (!info) { - return DISK_ENOMEM; + for (int i = 0; i < count; ++i) { + disk_listener_t *listener = disk_listeners[i]; + listener->ops->disk_added(listener, disk); } - - info->disk_name = disk_name; - info->fs_name = fs_name; - info->dops = dops; - - SLIST_INSERT_HEAD(&disks, info, sc_next); - return 0; } -struct disk_ops * -disk_ops_for(const char *disk_name) +int +mn_disk_ejected(disk_t *disk) { - struct disk_info *sc; + int count = LINK_TABLE_SIZE(disk_listeners); - if (disk_name) { - SLIST_FOREACH(sc, &disks, sc_next) { - if (strcmp(sc->disk_name, disk_name) == 0) { - return sc->dops; - } - } + for (int i = 0; i < count; ++i) { + disk_listener_t *listener = disk_listeners[i]; + listener->ops->disk_removed(listener, disk); } - - return NULL; -} - -char * -disk_fs_for(const char *disk_name) -{ - struct disk_info *sc; - - if (disk_name) { - SLIST_FOREACH(sc, &disks, sc_next) { - if (strcmp(sc->disk_name, disk_name) == 0) { - return ((char *) sc->fs_name); - } - } - } - - return NULL; -} - -char * -disk_name_from_path(const char *path) -{ - char *colon; - uint8_t len; - char *disk; - - colon = (char *) path; - while (*colon && *colon != ':') { - colon++; - } - - if (*colon != ':') { - return NULL; - } - - len = colon - path; - disk = malloc(len + 1); - if (!disk) { - return NULL; - } - memcpy(disk, path, len); - disk[len] = '\0'; - - return disk; -} - -/** - * @brief Returns the path with the disk prefix removed (if found) - * - * Paths should be given in the form disk:/path. This routine - * will parse and return only the path, removing the disk information. - */ -char * -disk_filepath_from_path(const char *path) -{ - char *colon; - char *filepath; - size_t len; - - colon = (char *) path; - while (*colon && *colon != ':') { - colon++; - } - - if (*colon != ':') { - filepath = strdup(path); - } else { - colon++; - len = strlen(colon); - filepath = malloc(len + 1); - memcpy(filepath, colon, len); - filepath[len] = '\0'; - } - - return filepath; + return 0; } diff --git a/fs/fatfs/pkg.yml b/fs/fatfs/pkg.yml index 01cef770df..6b389f60f2 100644 --- a/fs/fatfs/pkg.yml +++ b/fs/fatfs/pkg.yml @@ -30,11 +30,11 @@ pkg.deps: - "@apache-mynewt-core/util/crc" - "@apache-mynewt-core/hw/hal" - "@apache-mynewt-core/kernel/os" - - "@apache-mynewt-core/test/testutil" - - "@apache-mynewt-core/sys/flash_map" pkg.req_apis: - log - stats -pkg.init: - fatfs_pkg_init: 'MYNEWT_VAL(FATFS_SYSINIT_STAGE)' +pkg.whole_archive: true + +pkg.cflags: + - -Wno-unused-variable diff --git a/fs/fatfs/src/mynewt_glue.c b/fs/fatfs/src/mynewt_glue.c index 0fbefeb47c..36ef72cacf 100644 --- a/fs/fatfs/src/mynewt_glue.c +++ b/fs/fatfs/src/mynewt_glue.c @@ -22,11 +22,9 @@ #include #include #include -#include "os/mynewt.h" +#include #include -#include #include -#include #include #include @@ -53,17 +51,12 @@ static int fatfs_closedir(struct fs_dir *dir); static int fatfs_dirent_name(const struct fs_dirent *fs_dirent, size_t max_len, char *out_name, uint8_t *out_name_len); static int fatfs_dirent_is_dir(const struct fs_dirent *fs_dirent); - -#define DRIVE_LEN 4 +static int fatfs_mount(const file_system_t *fs); +static int fatfs_umount(const file_system_t *fs); struct fatfs_file { struct fs_ops *fops; - FIL *file; -}; - -struct fatfs_dir { - struct fs_ops *fops; - FATFS_DIR *dir; + FIL fil; }; struct fatfs_dirent { @@ -71,11 +64,10 @@ struct fatfs_dirent { FILINFO filinfo; }; -/* NOTE: to ease memory management of dirent structs, this single static - * variable holds the latest entry found by readdir. This limits FAT to - * working on a single thread, single opendir -> closedir cycle. - */ -static struct fatfs_dirent dirent; +struct fatfs_dir { + struct fatfs_dirent dirent; + FATFS_DIR dir; +}; static struct fs_ops fatfs_ops = { .f_open = fatfs_open, @@ -99,9 +91,19 @@ static struct fs_ops fatfs_ops = { .f_dirent_name = fatfs_dirent_name, .f_dirent_is_dir = fatfs_dirent_is_dir, - .f_name = "fatfs" + .f_mount = fatfs_mount, + .f_umount = fatfs_umount, }; +typedef struct fat_disk { + file_system_t fs; + char vol[4]; + FATFS fatfs; + disk_t *disk; +} fat_disk_t; + +static fat_disk_t *fat_vol[_VOLUMES]; + int fatfs_to_vfs_error(FRESULT res) { int rc = FS_EOS; @@ -171,112 +173,22 @@ int fatfs_to_vfs_error(FRESULT res) return rc; } -struct mounted_disk { - char *disk_name; - int disk_number; - struct disk_ops *dops; - - SLIST_ENTRY(mounted_disk) sc_next; -}; - -static SLIST_HEAD(, mounted_disk) mounted_disks = SLIST_HEAD_INITIALIZER(); - -static int -drivenumber_from_disk(char *disk_name) -{ - struct mounted_disk *sc; - struct mounted_disk *new_disk; - int disk_number; - FATFS *fs; - char path[6]; - - disk_number = 0; - if (disk_name) { - SLIST_FOREACH(sc, &mounted_disks, sc_next) { - if (strcmp(sc->disk_name, disk_name) == 0) { - return sc->disk_number; - } - disk_number++; - } - } - - /* XXX: check for errors? */ - fs = malloc(sizeof(FATFS)); - sprintf(path, "%d:", (uint8_t)disk_number); - f_mount(fs, path, 1); - - /* FIXME */ - new_disk = malloc(sizeof(struct mounted_disk)); - new_disk->disk_name = strdup(disk_name); - new_disk->disk_number = disk_number; - new_disk->dops = disk_ops_for(disk_name); - SLIST_INSERT_HEAD(&mounted_disks, new_disk, sc_next); - - return disk_number; -} - -/** - * Converts fs path to fatfs path - * - * Function changes mmc0:/dir/file.ext to 0:/dir/file.ext - * - * @param fs_path - * @return pointer to allocated memory with fatfs path - */ -static char * -fatfs_path_from_fs_path(const char *fs_path) -{ - char *disk; - int drive_number; - char *file_path = NULL; - char *fatfs_path = NULL; - - disk = disk_name_from_path(fs_path); - if (disk == NULL) { - goto err; - } - drive_number = drivenumber_from_disk(disk); - free(disk); - file_path = disk_filepath_from_path(fs_path); - - if (file_path == NULL) { - goto err; - } - - fatfs_path = malloc(strlen(file_path) + 3); - if (fatfs_path == NULL) { - goto err; - } - sprintf(fatfs_path, "%d:%s", drive_number, file_path); -err: - free(file_path); - return fatfs_path; -} - static int fatfs_open(const char *path, uint8_t access_flags, struct fs_file **out_fs_file) { FRESULT res; - FIL *out_file = NULL; BYTE mode; struct fatfs_file *file = NULL; - char *fatfs_path = NULL; int rc; FATFS_LOG_DEBUG("Open file %s", path); - file = malloc(sizeof(struct fatfs_file)); + file = os_malloc(sizeof(struct fatfs_file)); if (!file) { rc = FS_ENOMEM; goto out; } - out_file = malloc(sizeof(FIL)); - if (!out_file) { - rc = FS_ENOMEM; - goto out; - } - mode = FA_OPEN_EXISTING; if (access_flags & FS_ACCESS_READ) { mode |= FA_READ; @@ -292,29 +204,21 @@ fatfs_open(const char *path, uint8_t access_flags, struct fs_file **out_fs_file) mode |= FA_CREATE_ALWAYS; } - fatfs_path = fatfs_path_from_fs_path(path); - if (fatfs_path == NULL) { - rc = FS_ENOMEM; - goto out; - } - res = f_open(out_file, fatfs_path, mode); + res = f_open(&file->fil, path, mode); if (res != FR_OK) { rc = fatfs_to_vfs_error(res); goto out; } - file->file = out_file; file->fops = &fatfs_ops; *out_fs_file = (struct fs_file *) file; rc = FS_EOK; out: - free(fatfs_path); if (rc != FS_EOK) { FATFS_LOG_ERROR("File %s open failed %d", path, rc); if (file) free(file); - if (out_file) free(out_file); } else { FATFS_LOG_DEBUG("File %s opened %p", path, *out_fs_file); } @@ -324,15 +228,12 @@ fatfs_open(const char *path, uint8_t access_flags, struct fs_file **out_fs_file) static int fatfs_close(struct fs_file *fs_file) { - FRESULT res = FR_OK; - FIL *file = ((struct fatfs_file *) fs_file)->file; + struct fatfs_file *fat_file = (struct fatfs_file *)fs_file; + FRESULT res; - FATFS_LOG_DEBUG("Open file %p", fs_file); + FATFS_LOG_DEBUG("Close file %p", fs_file); - if (file != NULL) { - res = f_close(file); - free(file); - } + res = f_close(&fat_file->fil); free(fs_file); return fatfs_to_vfs_error(res); @@ -342,7 +243,7 @@ static int fatfs_seek(struct fs_file *fs_file, uint32_t offset) { FRESULT res; - FIL *file = ((struct fatfs_file *) fs_file)->file; + FIL *file = &((struct fatfs_file *)fs_file)->fil; FATFS_LOG_DEBUG("File %p seek %u", fs_file, offset); @@ -354,7 +255,7 @@ static uint32_t fatfs_getpos(const struct fs_file *fs_file) { uint32_t offset; - FIL *file = ((struct fatfs_file *) fs_file)->file; + FIL *file = &((struct fatfs_file *)fs_file)->fil; offset = (uint32_t) f_tell(file); return offset; @@ -363,7 +264,7 @@ fatfs_getpos(const struct fs_file *fs_file) static int fatfs_file_len(const struct fs_file *fs_file, uint32_t *out_len) { - FIL *file = ((struct fatfs_file *) fs_file)->file; + FIL *file = &((struct fatfs_file *) fs_file)->fil; *out_len = (uint32_t) f_size(file); @@ -377,7 +278,7 @@ fatfs_read(struct fs_file *fs_file, uint32_t len, void *out_data, uint32_t *out_len) { FRESULT res; - FIL *file = ((struct fatfs_file *) fs_file)->file; + FIL *file = &((struct fatfs_file *)fs_file)->fil; UINT uint_len; FATFS_LOG_DEBUG("File %p read %u", fs_file, len); @@ -392,7 +293,7 @@ fatfs_write(struct fs_file *fs_file, const void *data, int len) { FRESULT res; UINT out_len; - FIL *file = ((struct fatfs_file *) fs_file)->file; + FIL *file = &((struct fatfs_file *)fs_file)->fil; FATFS_LOG_DEBUG("File %p write %u", fs_file, len); @@ -407,7 +308,7 @@ static int fatfs_flush(struct fs_file *fs_file) { FRESULT res; - FIL *file = ((struct fatfs_file *)fs_file)->file; + FIL *file = &((struct fatfs_file *)fs_file)->fil; FATFS_LOG_DEBUG("Flush %p", fs_file); @@ -420,17 +321,10 @@ static int fatfs_unlink(const char *path) { FRESULT res; - char *fatfs_path; FATFS_LOG_INFO("Unlink %s", path); - fatfs_path = fatfs_path_from_fs_path(path); - - if (fatfs_path == NULL) { - return FS_ENOMEM; - } - res = f_unlink(fatfs_path); - free(fatfs_path); + res = f_unlink(path); return fatfs_to_vfs_error(res); } @@ -439,23 +333,10 @@ static int fatfs_rename(const char *from, const char *to) { FRESULT res; - char *fatfs_src_path; - char *fatfs_dst_path; FATFS_LOG_INFO("Rename %s to %s", from, to); - fatfs_src_path = fatfs_path_from_fs_path(from); - fatfs_dst_path = fatfs_path_from_fs_path(to); - - if (fatfs_src_path == NULL || fatfs_dst_path == NULL) { - free(fatfs_src_path); - free(fatfs_dst_path); - return FS_ENOMEM; - } - - res = f_rename(fatfs_src_path, fatfs_dst_path); - free(fatfs_src_path); - free(fatfs_dst_path); + res = f_rename(from, to); return fatfs_to_vfs_error(res); } @@ -464,17 +345,10 @@ static int fatfs_mkdir(const char *path) { FRESULT res; - char *fatfs_path; FATFS_LOG_INFO("Mkdir %s", path); - fatfs_path = fatfs_path_from_fs_path(path); - - if (fatfs_path == NULL) { - return FS_ENOMEM; - } - - res = f_mkdir(fatfs_path); + res = f_mkdir(path); return fatfs_to_vfs_error(res); } @@ -482,45 +356,34 @@ static int fatfs_opendir(const char *path, struct fs_dir **out_fs_dir) { FRESULT res; - FATFS_DIR *out_dir = NULL; struct fatfs_dir *dir = NULL; - char *fatfs_path = NULL; int rc; - dir = malloc(sizeof(struct fatfs_dir)); + dir = os_malloc(sizeof(struct fatfs_dir)); if (!dir) { rc = FS_ENOMEM; goto out; } + dir->dirent.fops = &fatfs_ops; - out_dir = malloc(sizeof(FATFS_DIR)); - if (!out_dir) { - rc = FS_ENOMEM; - goto out; - } - - fatfs_path = fatfs_path_from_fs_path(path); - - res = f_opendir(out_dir, fatfs_path); + res = f_opendir(&dir->dir, path); if (res != FR_OK) { rc = fatfs_to_vfs_error(res); goto out; } - dir->dir = out_dir; - dir->fops = &fatfs_ops; *out_fs_dir = (struct fs_dir *)dir; rc = FS_EOK; FATFS_LOG_INFO("Open dir %s -> %p", path, *out_fs_dir); out: - free(fatfs_path); if (rc != FS_EOK) { FATFS_LOG_ERROR("Open dir %s failed %d", path, rc); - if (dir) free(dir); - if (out_dir) free(out_dir); + if (dir) { + os_free(dir); + } } return rc; } @@ -529,18 +392,18 @@ static int fatfs_readdir(struct fs_dir *fs_dir, struct fs_dirent **out_fs_dirent) { FRESULT res; - FATFS_DIR *dir = ((struct fatfs_dir *) fs_dir)->dir; + struct fatfs_dir *fat_dir = ((struct fatfs_dir *)fs_dir); + FATFS_DIR *dir = &fat_dir->dir; FATFS_LOG_DEBUG("Read dir %p", fs_dir); - dirent.fops = &fatfs_ops; - res = f_readdir(dir, &dirent.filinfo); + res = f_readdir(dir, &fat_dir->dirent.filinfo); if (res != FR_OK) { return fatfs_to_vfs_error(res); } - *out_fs_dirent = (struct fs_dirent *) &dirent; - if (!dirent.filinfo.fname[0]) { + *out_fs_dirent = (struct fs_dirent *)&fat_dir->dirent; + if (!fat_dir->dirent.filinfo.fname[0]) { return FS_ENOENT; } return FS_EOK; @@ -550,13 +413,13 @@ static int fatfs_closedir(struct fs_dir *fs_dir) { FRESULT res; - FATFS_DIR *dir = ((struct fatfs_dir *) fs_dir)->dir; + FATFS_DIR *dir = &((struct fatfs_dir *) fs_dir)->dir; FATFS_LOG_INFO("Close dir %p", fs_dir); res = f_closedir(dir); - free(dir); - free(fs_dir); + + os_free(fs_dir); return fatfs_to_vfs_error(res); } @@ -585,6 +448,30 @@ fatfs_dirent_is_dir(const struct fs_dirent *fs_dirent) return filinfo->fattrib & AM_DIR; } +static int +fatfs_mount(const file_system_t *fs) +{ + int rc; + fat_disk_t *fat_disk = (fat_disk_t *)fs; + + /* Pass to FAT driver */ + rc = f_mount(&fat_disk->fatfs, fat_disk->vol, 0); + + return rc; +} + +static int +fatfs_umount(const file_system_t *fs) +{ + int rc; + fat_disk_t *fat_disk = (fat_disk_t *)fs; + + /* Pass to FAT driver */ + rc = f_mount(NULL, fat_disk->vol, 0); + + return rc; +} + DSTATUS disk_initialize(BYTE pdrv) { @@ -599,67 +486,40 @@ disk_status(BYTE pdrv) return RES_OK; } -static struct disk_ops *dops_from_handle(BYTE pdrv) -{ - struct mounted_disk *sc; - - SLIST_FOREACH(sc, &mounted_disks, sc_next) { - if (sc->disk_number == pdrv) { - return sc->dops; - } - } - - return NULL; -} - DRESULT disk_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) { int rc; - uint32_t address; - uint32_t num_bytes; - struct disk_ops *dops; - - /* NOTE: safe to assume sector size as 512 for now, see ffconf.h */ - address = (uint32_t) sector * 512; - num_bytes = (uint32_t) count * 512; - - dops = dops_from_handle(pdrv); - if (dops == NULL) { - return STA_NOINIT; - } + struct fat_disk *fat_disk = fat_vol[pdrv]; - rc = dops->read(pdrv, address, (void *) buff, num_bytes); - if (rc < 0) { - return STA_NOINIT; + if (fat_disk != NULL) { + rc = mn_disk_read(fat_disk->disk, sector, buff, count); + if (rc != 0) { + rc = FR_NOT_READY; + } + } else { + rc = FR_NOT_READY; } - return RES_OK; + return rc; } DRESULT disk_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) { int rc; - uint32_t address; - uint32_t num_bytes; - struct disk_ops *dops; - - /* NOTE: safe to assume sector size as 512 for now, see ffconf.h */ - address = (uint32_t) sector * 512; - num_bytes = (uint32_t) count * 512; - - dops = dops_from_handle(pdrv); - if (dops == NULL) { - return STA_NOINIT; - } + struct fat_disk *fat_disk = fat_vol[pdrv]; - rc = dops->write(pdrv, address, (const void *) buff, num_bytes); - if (rc < 0) { - return STA_NOINIT; + if (fat_disk != NULL) { + rc = mn_disk_write(fat_disk->disk, sector, buff, count); + if (rc != 0) { + rc = FR_NOT_READY; + } + } else { + rc = FR_NOT_READY; } - return RES_OK; + return rc; } DRESULT @@ -742,11 +602,93 @@ ff_wtoupper(WCHAR chr) return toupper(chr); } -void -fatfs_pkg_init(void) +#if MYNEWT_VAL_FATFS_AUTO_MOUNT_DISKS +int fatfs_disk_added(struct disk_listener *listener, struct disk *disk) +{ + fat_disk_t *fat_disk; + int i; + int rc; + + for (i = 0; i < _VOLUMES; ++i) { + if (fat_vol[i] == NULL) { + break; + } + } + if (i >= _VOLUMES) { + fat_disk = NULL; + FATFS_LOG_ERROR("Can mount additional volumes"); + goto end; + } + fat_disk = os_malloc(sizeof(*fat_disk)); + + if (fat_disk == NULL) { + FATFS_LOG_ERROR("No enough heap for FAT file system"); + goto end; + } + + if (mn_disk_read(disk, 0, fat_disk->fatfs.win, 1) == 0) { + disk_info_t di; + uint8_t fs_type = fat_disk->fatfs.win[450]; + mn_disk_info_get(disk, &di); + + /* Check if first partition is FAT */ + if (fs_type == 0x0C || fs_type == 0x0B || (_FS_EXFAT && fs_type == 0x07)) { + fat_disk->disk = disk; + fat_disk->fs.ops = &fatfs_ops; + fat_disk->fs.name = "fatfs"; + fat_disk->vol[0] = '0' + i; + fat_disk->vol[1] = ':'; + fat_disk->vol[2] = '\0'; + + /* Associate in mynewt */ + rc = fs_mount(&fat_disk->fs, fat_disk->vol); + if (rc != 0) { + FATFS_LOG_ERROR("Can't mount FAT file system"); + } else { + fat_vol[i] = fat_disk; + /* Disk successfully mounted, prevent from being freed */ + FATFS_LOG_INFO("Mounted FAT partition from %s at %s", di.name, fat_disk->vol); + fat_disk = NULL; + } + } else { + FATFS_LOG_INFO("Disk %s not with FAT file system", di.name); + } + } +end: + if (fat_disk) { + os_free(fat_disk); + } + return 0; +} + +int fatfs_disk_removed(struct disk_listener *listener, struct disk *disk) { - /* Ensure this function only gets called by sysinit. */ - SYSINIT_ASSERT_ACTIVE(); + int i; + int rc = FS_EINVAL; + struct fat_disk *fat_disk; - fs_register(&fatfs_ops); + for (i = 0; i < _VOLUMES; ++i) { + fat_disk = fat_vol[i]; + if (fat_disk->disk == disk) { + fs_unmount_file_system(&fat_disk->fs); + fat_vol[i] = NULL; + os_free(fat_disk); + rc = 0; + break; + } + } + return rc; } + +const disk_listener_ops_t fatfs_disk_listener_ops = { + .disk_added = fatfs_disk_added, + .disk_removed = fatfs_disk_removed, +}; + +disk_listener_t fatfs_disk_listener = { + .ops = &fatfs_disk_listener_ops, +}; + +DISK_LISTENER(fatfs_disk_listener_ptr, fatfs_disk_listener) + +#endif diff --git a/fs/fatfs/syscfg.yml b/fs/fatfs/syscfg.yml index 66035279b4..93c85f9476 100644 --- a/fs/fatfs/syscfg.yml +++ b/fs/fatfs/syscfg.yml @@ -48,6 +48,12 @@ syscfg.defs: Timout for locking file system object. value: 1000 + FATFS_AUTO_MOUNT_DISKS: + description: > + If 1 package tries to read every disks that is inserted + and if it's FAT disk, mounts it automatically. + value: 1 + FATFS_LOG_MODULE: description: 'Numeric module ID to use for FATFS log messages.' value: 253 diff --git a/fs/fs/include/fs/fs_if.h b/fs/fs/include/fs/fs_if.h index 567561f21a..120c386ac5 100644 --- a/fs/fs/include/fs/fs_if.h +++ b/fs/fs/include/fs/fs_if.h @@ -26,6 +26,16 @@ extern "C" { #include "os/mynewt.h" +typedef struct file_system { + const struct fs_ops *ops; + const char *name; +} file_system_t; + +struct mount_point { + const char *mount_point; + const file_system_t *fs; +}; + /* * Common interface filesystem(s) provide. */ @@ -53,10 +63,8 @@ struct fs_ops { int (*f_dirent_name)(const struct fs_dirent *dirent, size_t max_len, char *out_name, uint8_t *out_name_len); int (*f_dirent_is_dir)(const struct fs_dirent *dirent); - - const char *f_name; - - SLIST_ENTRY(fs_ops) sc_next; + int (*f_mount)(const file_system_t *fs); + int (*f_umount)(const file_system_t *fs); }; struct fops_container { @@ -78,18 +86,67 @@ int fs_register(struct fs_ops *fops); * * @return fops if there's only one registered filesystem, NULL otherwise. */ -struct fs_ops *fs_ops_try_unique(void); +const struct fs_ops *fs_ops_try_unique(void); + +const struct fs_ops *fs_ops_from_container(struct fops_container *container); + +/** + * Mount file system + * + * @param fs - file system to mount + * @param path - path to mount i.e. 0:, nffs: + * @return 0 on success + */ +int fs_mount(const file_system_t *fs, const char *path); + +/** + * Unmount file system by mount point + * + * @param mount_point - mount point to unmount i.e. 0:, nffs: + * @return 0 on success + */ +const file_system_t *fs_unmount_mount_point(const char *mount_point); + +/** + * Unmount file system + * + * @param fs - mounted file system to unmount + * @return 0 on success + */ +int fs_unmount_file_system(const file_system_t *fs); /** - * Retrieve a filesystem's operations table + * Get file system mount point path + * + * For given path it will return mount point and file system + * i.e.: + * For 0:/DIREC/FIL.TXT function will return "0:" and fs + * will be filled with pointer to valid file_system_t structure. * - * @param name Name of the filesystem to retrieve fs_ops for + * @param path - file or directory name + * @param fs - on success file system + * @return file system mount point string + */ +const char *file_system_path(const char *path, const file_system_t **fs); + +/** + * Return the only file system mounted * - * @return valid pointer on success, NULL on failure + * It there is only one file system mounted it will be returned by this + * function. If two file system were mounted funciton will return NULL. + * @return non-NULL if exactly one file system is mounted, otherwise NULL */ -struct fs_ops *fs_ops_for(const char *name); +const file_system_t *get_only_file_system(void); -struct fs_ops *fs_ops_from_container(struct fops_container *container); +/** + * Get file system and file system mount point + * + * Usually + * @param path - file system path + * @param fs - file system for path + * @param fs_path - mount point (usually prefix of file path) + */ +void get_file_system_path(const char *path, const file_system_t **fs, const char **fs_path); #ifdef __cplusplus } diff --git a/fs/fs/pkg.yml b/fs/fs/pkg.yml index d08fd18dea..fc3e1eeaae 100644 --- a/fs/fs/pkg.yml +++ b/fs/fs/pkg.yml @@ -26,11 +26,10 @@ pkg.keywords: - filesystem - ffs -pkg.deps: - - "@apache-mynewt-core/fs/disk" - pkg.deps.FS_CLI: - "@apache-mynewt-core/sys/shell" pkg.deps.FS_MGMT: - "@apache-mynewt-mcumgr/cmd/fs_mgmt/port/mynewt" + +pkg.whole_archive: true diff --git a/fs/fs/src/fs_cli.c b/fs/fs/src/fs_cli.c index 257586093e..cddfe54d0c 100644 --- a/fs/fs/src/fs_cli.c +++ b/fs/fs/src/fs_cli.c @@ -28,33 +28,7 @@ #include #include "fs/fs.h" - -static int fs_ls_cmd(int argc, char **argv); -static int fs_rm_cmd(int argc, char **argv); -static int fs_mkdir_cmd(int argc, char **argv); -static int fs_mv_cmd(int argc, char **argv); -static int fs_cat_cmd(int argc, char **argv); - -static struct shell_cmd fs_ls_struct = { - .sc_cmd = "ls", - .sc_cmd_func = fs_ls_cmd -}; -static struct shell_cmd fs_rm_struct = { - .sc_cmd = "rm", - .sc_cmd_func = fs_rm_cmd -}; -static struct shell_cmd fs_mkdir_struct = { - .sc_cmd = "mkdir", - .sc_cmd_func = fs_mkdir_cmd -}; -static struct shell_cmd fs_mv_struct = { - .sc_cmd = "mv", - .sc_cmd_func = fs_mv_cmd -}; -static struct shell_cmd fs_cat_struct = { - .sc_cmd = "cat", - .sc_cmd_func = fs_cat_cmd -}; +#include "fs/fs_if.h" static void fs_ls_file(const char *name, struct fs_file *file) @@ -187,6 +161,21 @@ fs_mv_cmd(int argc, char **argv) return 0; } +extern struct mount_point mount_points[]; + +static int +fs_mount_cmd(int argc, char **argv) +{ + console_printf("mount points:\n"); + for (int i = 0; i < MYNEWT_VAL_FS_MAX_MOUNT_POINTS; ++i) { + if (mount_points[i].fs) { + console_printf("%s %s\n", mount_points[i].mount_point, mount_points[i].fs->name); + } + } + + return 0; +} + static int fs_cat_cmd(int argc, char **argv) { @@ -220,13 +209,11 @@ fs_cat_cmd(int argc, char **argv) return 0; } -void -fs_cli_init(void) -{ - shell_cmd_register(&fs_ls_struct); - shell_cmd_register(&fs_rm_struct); - shell_cmd_register(&fs_mkdir_struct); - shell_cmd_register(&fs_mv_struct); - shell_cmd_register(&fs_cat_struct); -} +MAKE_SHELL_CMD(ls, fs_ls_cmd, NULL) +MAKE_SHELL_CMD(rm, fs_rm_cmd, NULL) +MAKE_SHELL_CMD(mkdir, fs_mkdir_cmd, NULL) +MAKE_SHELL_CMD(mv, fs_mv_cmd, NULL) +MAKE_SHELL_CMD(cat, fs_cat_cmd, NULL) +MAKE_SHELL_CMD(mount, fs_mount_cmd, NULL) + #endif /* MYNEWT_VAL(FS_CLI) */ diff --git a/fs/fs/src/fs_dirent.c b/fs/fs/src/fs_dirent.c index c9e46369b6..306a82258a 100644 --- a/fs/fs/src/fs_dirent.c +++ b/fs/fs/src/fs_dirent.c @@ -22,13 +22,13 @@ struct fs_ops *fops_from_filename(const char *); -static struct fs_ops * +static const struct fs_ops * fops_from_dir(const struct fs_dir *dir) { return fs_ops_from_container((struct fops_container *) dir); } -static inline struct fs_ops * +static inline const struct fs_ops * fops_from_dirent(const struct fs_dirent *dirent) { return fs_ops_from_container((struct fops_container *) dirent); @@ -37,21 +37,24 @@ fops_from_dirent(const struct fs_dirent *dirent) int fs_opendir(const char *path, struct fs_dir **out_dir) { - struct fs_ops *fops = fops_from_filename(path); - return fops->f_opendir(path, out_dir); + const file_system_t *fs; + const char *fs_path; + get_file_system_path(path, &fs, &fs_path); + + return fs->ops->f_opendir(fs_path, out_dir); } int fs_readdir(struct fs_dir *dir, struct fs_dirent **out_dirent) { - struct fs_ops *fops = fops_from_dir(dir); + const struct fs_ops *fops = fops_from_dir(dir); return fops->f_readdir(dir, out_dirent); } int fs_closedir(struct fs_dir *dir) { - struct fs_ops *fops = fops_from_dir(dir); + const struct fs_ops *fops = fops_from_dir(dir); return fops->f_closedir(dir); } @@ -59,13 +62,13 @@ int fs_dirent_name(const struct fs_dirent *dirent, size_t max_len, char *out_name, uint8_t *out_name_len) { - struct fs_ops *fops = fops_from_dirent(dirent); + const struct fs_ops *fops = fops_from_dirent(dirent); return fops->f_dirent_name(dirent, max_len, out_name, out_name_len); } int fs_dirent_is_dir(const struct fs_dirent *dirent) { - struct fs_ops *fops = fops_from_dirent(dirent); + const struct fs_ops *fops = fops_from_dirent(dirent); return fops->f_dirent_is_dir(dirent); } diff --git a/fs/fs/src/fs_file.c b/fs/fs/src/fs_file.c index 320a4eacc0..33fee7df40 100644 --- a/fs/fs/src/fs_file.c +++ b/fs/fs/src/fs_file.c @@ -19,7 +19,6 @@ #include #include -#include #include #include @@ -123,7 +122,7 @@ fake_dirent_is_dir(const struct fs_dirent *dirent) return FS_EUNINIT; } -struct fs_ops not_initialized_ops = { +const struct fs_ops not_initialized_ops = { .f_open = &fake_open, .f_close = &fake_close, .f_read = &fake_read, @@ -140,13 +139,17 @@ struct fs_ops not_initialized_ops = { .f_closedir = &fake_closedir, .f_dirent_name = &fake_dirent_name, .f_dirent_is_dir = &fake_dirent_is_dir, - .f_name = "fakefs", }; -struct fs_ops * +const file_system_t fake_fs = { + .ops = ¬_initialized_ops, + .name = "fakefs", +}; + +const struct fs_ops * safe_fs_ops_for(const char *fs_name) { - struct fs_ops *fops; + const struct fs_ops *fops; fops = fs_ops_for(fs_name); if (fops == NULL) { @@ -156,31 +159,20 @@ safe_fs_ops_for(const char *fs_name) return fops; } -struct fs_ops * -fops_from_filename(const char *filename) -{ - char *disk; - char *fs_name = NULL; - struct fs_ops *unique; - - disk = disk_name_from_path(filename); - if (disk) { - fs_name = disk_fs_for(disk); - free(disk); - } else { - /** - * special case: if only one fs was ever registered, - * return that fs' ops. - */ - if ((unique = fs_ops_try_unique()) != NULL) { - return unique; +void +get_file_system_path(const char *path, const file_system_t **fs, const char **fs_path) +{ + *fs_path = file_system_path(path, fs); + if (*fs_path == NULL) { + *fs = get_only_file_system(); + if (*fs == NULL) { + *fs = &fake_fs; } + *fs_path = path; } - - return safe_fs_ops_for(fs_name); } -static inline struct fs_ops * +static inline const struct fs_ops * fops_from_file(const struct fs_file *file) { return fs_ops_from_container((struct fops_container *) file); @@ -189,62 +181,68 @@ fops_from_file(const struct fs_file *file) int fs_open(const char *filename, uint8_t access_flags, struct fs_file **out_file) { - struct fs_ops *fops = fops_from_filename(filename); - return fops->f_open(filename, access_flags, out_file); + const file_system_t *fs; + const char *fs_filename; + + get_file_system_path(filename, &fs, &fs_filename); + return fs->ops->f_open(fs_filename, access_flags, out_file); } int fs_close(struct fs_file *file) { - struct fs_ops *fops = fops_from_file(file); + const struct fs_ops *fops = fops_from_file(file); return fops->f_close(file); } int fs_read(struct fs_file *file, uint32_t len, void *out_data, uint32_t *out_len) { - struct fs_ops *fops = fops_from_file(file); + const struct fs_ops *fops = fops_from_file(file); return fops->f_read(file, len, out_data, out_len); } int fs_write(struct fs_file *file, const void *data, int len) { - struct fs_ops *fops = fops_from_file(file); + const struct fs_ops *fops = fops_from_file(file); return fops->f_write(file, data, len); } int fs_seek(struct fs_file *file, uint32_t offset) { - struct fs_ops *fops = fops_from_file(file); + const struct fs_ops *fops = fops_from_file(file); return fops->f_seek(file, offset); } uint32_t fs_getpos(const struct fs_file *file) { - struct fs_ops *fops = fops_from_file(file); + const struct fs_ops *fops = fops_from_file(file); return fops->f_getpos(file); } int fs_filelen(const struct fs_file *file, uint32_t *out_len) { - struct fs_ops *fops = fops_from_file(file); + const struct fs_ops *fops = fops_from_file(file); return fops->f_filelen(file, out_len); } int fs_unlink(const char *filename) { - struct fs_ops *fops = fops_from_filename(filename); - return fops->f_unlink(filename); + const file_system_t *fs; + const char *fs_filename; + + get_file_system_path(filename, &fs, &fs_filename); + return fs->ops->f_unlink(fs_filename); } int fs_flush(struct fs_file *file) { - struct fs_ops *fops = fops_from_file(file); + const struct fs_ops *fops = fops_from_file(file); return fops->f_flush(file); } diff --git a/fs/fs/src/fs_mkdir.c b/fs/fs/src/fs_mkdir.c index aca27f59f1..223b5527b9 100644 --- a/fs/fs/src/fs_mkdir.c +++ b/fs/fs/src/fs_mkdir.c @@ -21,18 +21,31 @@ #include "fs_priv.h" -struct fs_ops *fops_from_filename(const char *); - int fs_rename(const char *from, const char *to) { - struct fs_ops *fops = fops_from_filename(from); - return fops->f_rename(from, to); + const file_system_t *fs1; + const file_system_t *fs2; + const char *fs_from; + const char *fs_to; + + get_file_system_path(from, &fs1, &fs_from); + get_file_system_path(to, &fs2, &fs_to); + + if (fs1 == fs2) { + return fs1->ops->f_rename(fs_from, fs_to); + } + + return FS_EINVAL; } int fs_mkdir(const char *path) { - struct fs_ops *fops = fops_from_filename(path); - return fops->f_mkdir(path); + const file_system_t *fs; + const char *fs_path; + + get_file_system_path(path, &fs, &fs_path); + + return fs->ops->f_mkdir(fs_path); } diff --git a/fs/fs/src/fs_mount.c b/fs/fs/src/fs_mount.c index 5319aed7bc..567c1f469a 100644 --- a/fs/fs/src/fs_mount.c +++ b/fs/fs/src/fs_mount.c @@ -26,79 +26,134 @@ #include #endif -static SLIST_HEAD(, fs_ops) root_fops = SLIST_HEAD_INITIALIZER(); +#define MAX_MOUNT_POINTS MYNEWT_VAL_FS_MAX_MOUNT_POINTS -#if MYNEWT_VAL(FS_CLI) -static uint8_t g_cli_initialized; -#endif - -#if MYNEWT_VAL(FS_MGMT) -static uint8_t g_mgmt_initialized; -#endif +struct mount_point mount_points[MAX_MOUNT_POINTS]; int -fs_register(struct fs_ops *fops) +fs_mount(const file_system_t *fs, const char *mount_point) { - struct fs_ops *sc; + int free_slot = -1; + int rc = FS_EOK; + + for (int i = 0; i < ARRAY_SIZE(mount_points); ++i) { + if (mount_points[i].mount_point == NULL) { + if (free_slot < 0) { + free_slot = i; + } + } else if (strcmp(mount_point, mount_points[i].mount_point) == 0) { + rc = FS_EEXIST; + goto end; + } + } + if (free_slot >= 0) { + mount_points[free_slot].mount_point = mount_point; + mount_points[free_slot].fs = fs; + rc = fs->ops->f_mount ? fs->ops->f_mount(fs) : 0; + if (rc) { + mount_points[free_slot].mount_point = NULL; + mount_points[free_slot].fs = NULL; + } + } else { + rc = FS_ENOMEM; + } +end: + return rc; +} - SLIST_FOREACH(sc, &root_fops, sc_next) { - if (strcmp(sc->f_name, fops->f_name) == 0) { - return FS_EEXIST; +const file_system_t * +fs_unmount_mount_point(const char *mount_point) +{ + const file_system_t *fs = NULL; + + for (int i = 0; i < ARRAY_SIZE(mount_points); ++i) { + if (strcmp(mount_point, mount_points[i].mount_point) == 0) { + fs = mount_points[i].fs; + mount_points[i].mount_point = NULL; + mount_points[i].fs = NULL; + break; } } - SLIST_INSERT_HEAD(&root_fops, fops, sc_next); + return fs; +} -#if MYNEWT_VAL(FS_CLI) - if (!g_cli_initialized) { - fs_cli_init(); - g_cli_initialized = 1; +int +fs_unmount_file_system(const file_system_t *fs) +{ + int rc = FS_EINVAL; + + for (int i = 0; i < ARRAY_SIZE(mount_points); ++i) { + if (mount_points[i].fs == fs) { + mount_points[i].mount_point = NULL; + mount_points[i].fs = NULL; + rc = 0; + break; + } } -#endif + + return rc; +} #if MYNEWT_VAL(FS_MGMT) - if (!g_mgmt_initialized) { - fs_mgmt_register_group(); - g_mgmt_initialized = 1; - } +static uint8_t g_mgmt_initialized; #endif - return FS_EOK; +int +fs_register(struct fs_ops *fops) +{ + return FS_EINVAL; } -struct fs_ops * -fs_ops_try_unique(void) +const file_system_t * +get_only_file_system(void) { - struct fs_ops *fops = SLIST_FIRST(&root_fops); + const file_system_t *fs = NULL; - if (fops && !SLIST_NEXT(fops, sc_next)) { - return fops; + for (int i = 0; i < ARRAY_SIZE(mount_points); ++i) { + if (mount_points[i].mount_point == NULL) { + continue; + } + if (fs != NULL) { + fs = NULL; + break; + } + fs = mount_points[i].fs; } - return NULL; + return fs; } -struct fs_ops * -fs_ops_for(const char *fs_name) +const char * +file_system_path(const char *uri, const file_system_t **fs) { - struct fs_ops *fops = NULL; - struct fs_ops *sc; - - if (fs_name) { - SLIST_FOREACH(sc, &root_fops, sc_next) { - if (strcmp(sc->f_name, fs_name) == 0) { - fops = sc; + const char *fs_path = NULL; + const char *m; + + for (int i = 0; i < ARRAY_SIZE(mount_points); ++i) { + if (mount_points[i].mount_point != NULL) { + fs_path = uri; + m = mount_points[i].mount_point; + while (*fs_path == *m) { + ++fs_path; + ++m; + } + /* Reached end of mount point path ? */ + if (*m == '\0') { + if (fs) { + *fs = mount_points[i].fs; + } break; } + fs_path = NULL; } } - - return fops; + return fs_path; } -extern struct fs_ops not_initialized_ops; +extern const struct fs_ops not_initialized_ops; -struct fs_ops * +const struct fs_ops * fs_ops_from_container(struct fops_container *container) { if (!container) { diff --git a/fs/fs/src/fs_priv.h b/fs/fs/src/fs_priv.h index 0e6345db57..a2a3da15ee 100644 --- a/fs/fs/src/fs_priv.h +++ b/fs/fs/src/fs_priv.h @@ -26,12 +26,9 @@ extern "C" { #endif struct fs_ops; -struct fs_ops *fs_ops_for(const char *fs_name); -struct fs_ops *safe_fs_ops_for(const char *fs_name); +const struct fs_ops *fs_ops_for(const char *fs_name); +const struct fs_ops *safe_fs_ops_for(const char *fs_name); -#if MYNEWT_VAL(FS_CLI) -void fs_cli_init(void); -#endif #ifdef __cplusplus } diff --git a/fs/fs/syscfg.yml b/fs/fs/syscfg.yml index cc676340c1..4cf97388fa 100644 --- a/fs/fs/syscfg.yml +++ b/fs/fs/syscfg.yml @@ -27,6 +27,13 @@ syscfg.defs: description: 'Enables file system mgmt commands.' value: 0 + FS_MAX_MOUNT_POINTS: + description: > + Number of mount point tha can be used. + There should be one mount point for each file system that + could be mounted. + value: 2 + FS_UPLOAD_MAX_CHUNK_SIZE: description: > The maximum amount of file data that can fit in a diff --git a/fs/littlefs/src/mynewt_glue.c b/fs/littlefs/src/mynewt_glue.c index 9f269d8521..1a72da38d2 100644 --- a/fs/littlefs/src/mynewt_glue.c +++ b/fs/littlefs/src/mynewt_glue.c @@ -23,7 +23,6 @@ #include #include "os/mynewt.h" #include -#include #include #include "lfs.h" @@ -91,8 +90,6 @@ static struct fs_ops littlefs_ops = { .f_dirent_name = littlefs_dirent_name, .f_dirent_is_dir = littlefs_dirent_is_dir, - - .f_name = "littlefs" }; static int @@ -785,6 +782,11 @@ littlefs_reformat(void) return lfs_format(g_lfs, &g_lfs_cfg); } +static const file_system_t littlefs_fs0 = { + .ops = &littlefs_ops, + .name = "littlefs" +}; + int littlefs_init(void) { @@ -816,7 +818,7 @@ littlefs_init(void) } if (!rc) { - fs_register(&littlefs_ops); + fs_mount(&littlefs_fs0, "lfs0:"); } return rc; diff --git a/fs/nffs/src/nffs.c b/fs/nffs/src/nffs.c index 1dc9c778f7..5315f9354f 100644 --- a/fs/nffs/src/nffs.c +++ b/fs/nffs/src/nffs.c @@ -30,7 +30,6 @@ #include "nffs_priv.h" #include "nffs/nffs.h" #include "fs/fs_if.h" -#include "disk/disk.h" struct nffs_area *nffs_areas; uint8_t nffs_num_areas; @@ -98,8 +97,11 @@ struct fs_ops nffs_ops = { .f_dirent_name = nffs_dirent_name, .f_dirent_is_dir = nffs_dirent_is_dir, +}; - .f_name = "nffs" +const file_system_t nffs_fs0 = { + .ops = &nffs_ops, + .name = "nffs", }; STATS_SECT_DECL(nffs_stats) nffs_stats; @@ -190,7 +192,6 @@ nffs_open(const char *path, uint8_t access_flags, struct fs_file **out_fs_file) { int rc; struct nffs_file *out_file; - char *filepath = NULL; nffs_lock(); @@ -199,17 +200,12 @@ nffs_open(const char *path, uint8_t access_flags, struct fs_file **out_fs_file) goto done; } - filepath = disk_filepath_from_path(path); - - rc = nffs_file_open(&out_file, filepath, access_flags); + rc = nffs_file_open(&out_file, path, access_flags); if (rc != 0) { goto done; } *out_fs_file = (struct fs_file *)out_file; done: - if (filepath) { - free(filepath); - } nffs_unlock(); if (rc != 0) { *out_fs_file = NULL; @@ -512,7 +508,6 @@ nffs_opendir(const char *path, struct fs_dir **out_fs_dir) { int rc; struct nffs_dir **out_dir = (struct nffs_dir **)out_fs_dir; - char *filepath = NULL; nffs_lock(); @@ -521,14 +516,9 @@ nffs_opendir(const char *path, struct fs_dir **out_fs_dir) goto done; } - filepath = disk_filepath_from_path(path); - - rc = nffs_dir_open(filepath, out_dir); + rc = nffs_dir_open(path, out_dir); done: - if (filepath) { - free(filepath); - } nffs_unlock(); if (rc != 0) { *out_dir = NULL; @@ -764,7 +754,8 @@ nffs_init(void) return rc; } - fs_register(&nffs_ops); + fs_mount(&nffs_fs0, "nffs:"); + return 0; }