From 3b7496b8600a25c6ea2907197a85056861768cd0 Mon Sep 17 00:00:00 2001 From: xieyangrun Date: Thu, 7 Jan 2021 15:31:32 +0800 Subject: [PATCH] update lfs v2.3.0 --- dfs_lfs.c | 164 +++++++++++++++++++++++++----------------------------- 1 file changed, 77 insertions(+), 87 deletions(-) diff --git a/dfs_lfs.c b/dfs_lfs.c index e121065d..5d446131 100644 --- a/dfs_lfs.c +++ b/dfs_lfs.c @@ -45,6 +45,7 @@ typedef struct _dfs_lfs_s { struct lfs lfs; struct lfs_config cfg; + struct rt_mutex lock; } dfs_lfs_t; typedef struct _dfs_lfs_fd_s @@ -58,10 +59,36 @@ typedef struct _dfs_lfs_fd_s } dfs_lfs_fd_t; static struct _dfs_lfs_s* _lfs_mount_tbl[RT_DEF_LFS_DRIVERS] = {0}; -static struct rt_mutex _lfs_lock; -#define lfs_dfs_lock() rt_mutex_take(&_lfs_lock, RT_WAITING_FOREVER); -#define lfs_dfs_unlock() rt_mutex_release(&_lfs_lock); +#ifdef LFS_THREADSAFE +// Lock the underlying block device. Negative error codes +// are propogated to the user. +int _lfs_lock(const struct lfs_config *c) +{ + dfs_lfs_t *dfs_lfs = rt_container_of(c, dfs_lfs_t, cfg); + + if (rt_mutex_take(&dfs_lfs->lock, RT_WAITING_FOREVER) != RT_EOK) + { + return -1; + } + + return 0; +} + +// Unlock the underlying block device. Negative error codes +// are propogated to the user. +int _lfs_unlock(const struct lfs_config *c) +{ + dfs_lfs_t *dfs_lfs = rt_container_of(c, dfs_lfs_t, cfg); + + if (rt_mutex_release(&dfs_lfs->lock) != RT_EOK) + { + return -1; + } + + return 0; +} +#endif // Read a region in a block. Negative error codes are propogated // to the user. @@ -222,6 +249,8 @@ static int _lfs_result_to_dfs(int result) static void _lfs_load_config(struct lfs_config* lfs_cfg, struct rt_mtd_nor_device* mtd_nor) { + uint64_t mtd_size; + lfs_cfg->context = (void*)mtd_nor; lfs_cfg->read_size = LFS_READ_SIZE; @@ -236,18 +265,23 @@ static void _lfs_load_config(struct lfs_config* lfs_cfg, struct rt_mtd_nor_devic lfs_cfg->cache_size = LFS_CACHE_SIZE; lfs_cfg->block_cycles = LFS_BLOCK_CYCLES; - lfs_cfg->block_count = (mtd_nor->block_end - mtd_nor->block_start) * mtd_nor->block_size / lfs_cfg->block_size; + mtd_size = mtd_nor->block_end - mtd_nor->block_start; + mtd_size *= mtd_nor->block_size; + lfs_cfg->block_count = mtd_size / lfs_cfg->block_size; lfs_cfg->lookahead_size = 32 * ((lfs_cfg->block_count + 31) / 32); if (lfs_cfg->lookahead_size > LFS_LOOKAHEAD_MAX) { lfs_cfg->lookahead_size = LFS_LOOKAHEAD_MAX; } - - lfs_cfg->read = &_lfs_flash_read; - lfs_cfg->prog = &_lfs_flash_prog; - lfs_cfg->erase = &_lfs_flash_erase; - lfs_cfg->sync = &_lfs_flash_sync; +#ifdef LFS_THREADSAFE + lfs_cfg->lock = _lfs_lock; + lfs_cfg->unlock = _lfs_unlock; +#endif + lfs_cfg->read = _lfs_flash_read; + lfs_cfg->prog = _lfs_flash_prog; + lfs_cfg->erase = _lfs_flash_erase; + lfs_cfg->sync = _lfs_flash_sync; } static int _dfs_lfs_mount(struct dfs_filesystem* dfs, unsigned long rwflag, const void* data) @@ -263,13 +297,10 @@ static int _dfs_lfs_mount(struct dfs_filesystem* dfs, unsigned long rwflag, cons return -EINVAL; } - lfs_dfs_lock(); - /* get an empty position */ index = _get_disk(RT_NULL); if (index == -1) { - lfs_dfs_unlock(); return -EIO; } @@ -277,19 +308,18 @@ static int _dfs_lfs_mount(struct dfs_filesystem* dfs, unsigned long rwflag, cons dfs_lfs = (dfs_lfs_t*)rt_malloc(sizeof(dfs_lfs_t)); if (dfs_lfs == RT_NULL) { - lfs_dfs_unlock(); rt_kprintf("ERROR:no memory!\n"); return -ENOMEM; } rt_memset(dfs_lfs, 0, sizeof(dfs_lfs_t)); - + rt_mutex_init(&dfs_lfs->lock, "lfslock", RT_IPC_FLAG_PRIO); _lfs_load_config(&dfs_lfs->cfg, (struct rt_mtd_nor_device*)dfs->dev_id); /* mount lfs*/ result = lfs_mount(&dfs_lfs->lfs, &dfs_lfs->cfg); if (result != LFS_ERR_OK) { - lfs_dfs_unlock(); + rt_mutex_detach(&dfs_lfs->lock); /* release memory */ rt_free(dfs_lfs); @@ -299,7 +329,6 @@ static int _dfs_lfs_mount(struct dfs_filesystem* dfs, unsigned long rwflag, cons /* mount succeed! */ dfs->data = (void*)dfs_lfs; _lfs_mount_tbl[index] = dfs_lfs; - lfs_dfs_unlock(); return RT_EOK; } @@ -312,12 +341,10 @@ static int _dfs_lfs_unmount(struct dfs_filesystem* dfs) RT_ASSERT(dfs != RT_NULL); RT_ASSERT(dfs->data != RT_NULL); - lfs_dfs_lock(); /* find the device index and then umount it */ index = _get_disk(dfs->dev_id); if (index == -1) { - lfs_dfs_unlock(); return -ENOENT; } _lfs_mount_tbl[index] = RT_NULL; @@ -326,12 +353,13 @@ static int _dfs_lfs_unmount(struct dfs_filesystem* dfs) dfs->data = RT_NULL; result = lfs_unmount(&dfs_lfs->lfs); - lfs_dfs_unlock(); + rt_mutex_detach(&dfs_lfs->lock); rt_free(dfs_lfs); return _lfs_result_to_dfs(result); } +#ifndef LFS_READONLY static int _dfs_lfs_mkfs(rt_device_t dev_id) { int result; @@ -343,11 +371,9 @@ static int _dfs_lfs_mkfs(rt_device_t dev_id) return -EINVAL; } - lfs_dfs_lock(); /* Check Device Type */ if (dev_id->type != RT_Device_Class_MTD) { - lfs_dfs_unlock(); rt_kprintf("The flash device type must be MTD!\n"); return -EINVAL; } @@ -355,35 +381,21 @@ static int _dfs_lfs_mkfs(rt_device_t dev_id) index = _get_disk(dev_id); if (index == -1) { - /* not found the device id */ - index = _get_disk(RT_NULL); - if (index == -1) - { - lfs_dfs_unlock(); - /* no space to store an temp driver */ - rt_kprintf("sorry, there is no space to do mkfs!\n"); - - return -ENOSPC; - } - /* create lfs handle */ dfs_lfs = rt_malloc(sizeof(dfs_lfs_t)); - if (dfs_lfs == RT_NULL) { - _lfs_mount_tbl[index] = RT_NULL; - lfs_dfs_unlock(); rt_kprintf("ERROR:no memory!\n"); - return -ENOMEM; } rt_memset(dfs_lfs, 0, sizeof(dfs_lfs_t)); - + rt_mutex_init(&dfs_lfs->lock, "lfslock", RT_IPC_FLAG_PRIO); _lfs_load_config(&dfs_lfs->cfg, (struct rt_mtd_nor_device*)dev_id); /* format flash device */ result = lfs_format(&dfs_lfs->lfs, &dfs_lfs->cfg); - lfs_dfs_unlock(); + rt_mutex_detach(&dfs_lfs->lock); + rt_free(dfs_lfs); return _lfs_result_to_dfs(result); } @@ -393,7 +405,6 @@ static int _dfs_lfs_mkfs(rt_device_t dev_id) result = lfs_unmount(&dfs_lfs->lfs); if (result != LFS_ERR_OK) { - lfs_dfs_unlock(); return _lfs_result_to_dfs(result); } @@ -403,7 +414,6 @@ static int _dfs_lfs_mkfs(rt_device_t dev_id) result = lfs_format(&dfs_lfs->lfs, &dfs_lfs->cfg); if (result != LFS_ERR_OK) { - lfs_dfs_unlock(); return _lfs_result_to_dfs(result); } @@ -416,9 +426,9 @@ static int _dfs_lfs_mkfs(rt_device_t dev_id) _lfs_mount_tbl[index] = dfs_lfs; } - lfs_dfs_unlock(); return _lfs_result_to_dfs(result); } +#endif static int _dfs_lfs_statfs_count(void* p, lfs_block_t b) { @@ -436,14 +446,12 @@ static int _dfs_lfs_statfs(struct dfs_filesystem* dfs, struct statfs* buf) RT_ASSERT(dfs != RT_NULL); RT_ASSERT(dfs->data != RT_NULL); - lfs_dfs_lock(); dfs_lfs = (dfs_lfs_t*)dfs->data; /* Get total sectors and free sectors */ result = lfs_fs_traverse(&dfs_lfs->lfs, _dfs_lfs_statfs_count, &in_use); if (result != LFS_ERR_OK) { - lfs_dfs_unlock(); return _lfs_result_to_dfs(result); } @@ -451,10 +459,10 @@ static int _dfs_lfs_statfs(struct dfs_filesystem* dfs, struct statfs* buf) buf->f_blocks = dfs_lfs->cfg.block_count; buf->f_bfree = dfs_lfs->cfg.block_count - in_use; - lfs_dfs_unlock(); return RT_EOK; } +#ifndef LFS_READONLY static int _dfs_lfs_unlink(struct dfs_filesystem* dfs, const char* path) { dfs_lfs_t* dfs_lfs; @@ -463,14 +471,12 @@ static int _dfs_lfs_unlink(struct dfs_filesystem* dfs, const char* path) RT_ASSERT(dfs != RT_NULL); RT_ASSERT(dfs->data != RT_NULL); - lfs_dfs_lock(); dfs_lfs = (dfs_lfs_t*)dfs->data; - result = lfs_remove(&dfs_lfs->lfs, path); - lfs_dfs_unlock(); return _lfs_result_to_dfs(result); } +#endif static void _dfs_lfs_tostat(struct stat* st, struct lfs_info* info) { @@ -502,11 +508,8 @@ static int _dfs_lfs_stat(struct dfs_filesystem* dfs, const char* path, struct st RT_ASSERT(dfs != RT_NULL); RT_ASSERT(dfs->data != RT_NULL); - lfs_dfs_lock(); dfs_lfs = (dfs_lfs_t*)dfs->data; - result = lfs_stat(&dfs_lfs->lfs, path, &info); - lfs_dfs_unlock(); if (result != LFS_ERR_OK) { @@ -517,6 +520,7 @@ static int _dfs_lfs_stat(struct dfs_filesystem* dfs, const char* path, struct st return 0; } +#ifndef LFS_READONLY static int _dfs_lfs_rename(struct dfs_filesystem* dfs, const char* from, const char* to) { dfs_lfs_t* dfs_lfs; @@ -525,14 +529,12 @@ static int _dfs_lfs_rename(struct dfs_filesystem* dfs, const char* from, const c RT_ASSERT(dfs != RT_NULL); RT_ASSERT(dfs->data != RT_NULL); - lfs_dfs_lock(); dfs_lfs = (dfs_lfs_t*)dfs->data; - result = lfs_rename(&dfs_lfs->lfs, from, to); - lfs_dfs_unlock(); return _lfs_result_to_dfs(result); } +#endif /****************************************************************************** * file operations @@ -547,7 +549,6 @@ static int _dfs_lfs_open(struct dfs_fd* file) RT_ASSERT(file != RT_NULL); RT_ASSERT(file->data != RT_NULL); - lfs_dfs_lock(); dfs = (struct dfs_filesystem*)file->data; dfs_lfs = (dfs_lfs_t*)dfs->data; @@ -566,7 +567,11 @@ static int _dfs_lfs_open(struct dfs_fd* file) if (file->flags & O_CREAT) { +#ifndef LFS_READONLY result = lfs_mkdir(dfs_lfs_fd->lfs, file->path); +#else + result = -EINVAL; +#endif if (result != LFS_ERR_OK) { goto _error_dir; @@ -581,7 +586,6 @@ static int _dfs_lfs_open(struct dfs_fd* file) else { file->data = (void*)dfs_lfs_fd; - lfs_dfs_unlock(); return RT_EOK; } @@ -591,7 +595,6 @@ static int _dfs_lfs_open(struct dfs_fd* file) rt_free(dfs_lfs_fd); } - lfs_dfs_unlock(); return _lfs_result_to_dfs(result); } else @@ -632,7 +635,6 @@ static int _dfs_lfs_open(struct dfs_fd* file) file->data = (void*)dfs_lfs_fd; file->pos = dfs_lfs_fd->u.file.pos; file->size = dfs_lfs_fd->u.file.ctz.size; - lfs_dfs_unlock(); return RT_EOK; } @@ -642,7 +644,6 @@ static int _dfs_lfs_open(struct dfs_fd* file) rt_free(dfs_lfs_fd); } - lfs_dfs_unlock(); return _lfs_result_to_dfs(result); } } @@ -654,7 +655,6 @@ static int _dfs_lfs_close(struct dfs_fd* file) RT_ASSERT(file != RT_NULL); RT_ASSERT(file->data != RT_NULL); - lfs_dfs_lock(); dfs_lfs_fd = (dfs_lfs_fd_t*)file->data; if (file->type == FT_DIRECTORY) @@ -667,7 +667,6 @@ static int _dfs_lfs_close(struct dfs_fd* file) } rt_free(dfs_lfs_fd); - lfs_dfs_unlock(); return _lfs_result_to_dfs(result); } @@ -685,11 +684,8 @@ static int _dfs_lfs_read(struct dfs_fd* file, void* buf, size_t len) RT_ASSERT(file != RT_NULL); RT_ASSERT(file->data != RT_NULL); - lfs_dfs_lock(); - if (file->type == FT_DIRECTORY) { - lfs_dfs_unlock(); return -EISDIR; } @@ -701,7 +697,6 @@ static int _dfs_lfs_read(struct dfs_fd* file, void* buf, size_t len) lfs_soff_t soff = lfs_file_seek(dfs_lfs_fd->lfs, &dfs_lfs_fd->u.file, file->pos, LFS_SEEK_SET); if (soff < 0) { - lfs_dfs_unlock(); return _lfs_result_to_dfs(soff); } } @@ -710,17 +705,16 @@ static int _dfs_lfs_read(struct dfs_fd* file, void* buf, size_t len) ssize = lfs_file_read(dfs_lfs_fd->lfs, &dfs_lfs_fd->u.file, buf, len); if (ssize < 0) { - lfs_dfs_unlock(); return _lfs_result_to_dfs(ssize); } /* update position */ file->pos = dfs_lfs_fd->u.file.pos; - lfs_dfs_unlock(); return ssize; } +#ifndef LFS_READONLY static int _dfs_lfs_write(struct dfs_fd* file, const void* buf, size_t len) { lfs_ssize_t ssize; @@ -728,11 +722,8 @@ static int _dfs_lfs_write(struct dfs_fd* file, const void* buf, size_t len) RT_ASSERT(file != RT_NULL); RT_ASSERT(file->data != RT_NULL); - lfs_dfs_lock(); - if (file->type == FT_DIRECTORY) { - lfs_dfs_unlock(); return -EISDIR; } @@ -744,7 +735,6 @@ static int _dfs_lfs_write(struct dfs_fd* file, const void* buf, size_t len) lfs_soff_t soff = lfs_file_seek(dfs_lfs_fd->lfs, &dfs_lfs_fd->u.file, file->pos, LFS_SEEK_SET); if (soff < 0) { - lfs_dfs_unlock(); return _lfs_result_to_dfs(soff); } } @@ -753,7 +743,6 @@ static int _dfs_lfs_write(struct dfs_fd* file, const void* buf, size_t len) ssize = lfs_file_write(dfs_lfs_fd->lfs, &dfs_lfs_fd->u.file, buf, len); if (ssize < 0) { - lfs_dfs_unlock(); return _lfs_result_to_dfs(ssize); } @@ -761,9 +750,9 @@ static int _dfs_lfs_write(struct dfs_fd* file, const void* buf, size_t len) file->pos = dfs_lfs_fd->u.file.pos; file->size = dfs_lfs_fd->u.file.ctz.size; - lfs_dfs_unlock(); return ssize; } +#endif static int _dfs_lfs_flush(struct dfs_fd* file) { @@ -773,11 +762,8 @@ static int _dfs_lfs_flush(struct dfs_fd* file) RT_ASSERT(file != RT_NULL); RT_ASSERT(file->data != RT_NULL); - lfs_dfs_lock(); dfs_lfs_fd = (dfs_lfs_fd_t*)file->data; - result = lfs_file_sync(dfs_lfs_fd->lfs, &dfs_lfs_fd->u.file); - lfs_dfs_unlock(); return _lfs_result_to_dfs(result); } @@ -789,7 +775,6 @@ static int _dfs_lfs_lseek(struct dfs_fd* file, rt_off_t offset) RT_ASSERT(file != RT_NULL); RT_ASSERT(file->data != RT_NULL); - lfs_dfs_lock(); dfs_lfs_fd = (dfs_lfs_fd_t*)file->data; if (file->type == FT_REGULAR) @@ -797,7 +782,6 @@ static int _dfs_lfs_lseek(struct dfs_fd* file, rt_off_t offset) lfs_soff_t soff = lfs_file_seek(dfs_lfs_fd->lfs, &dfs_lfs_fd->u.file, offset, LFS_SEEK_SET); if (soff < 0) { - lfs_dfs_unlock(); return _lfs_result_to_dfs(soff); } @@ -808,14 +792,12 @@ static int _dfs_lfs_lseek(struct dfs_fd* file, rt_off_t offset) lfs_soff_t soff = lfs_dir_seek(dfs_lfs_fd->lfs, &dfs_lfs_fd->u.dir, offset); if (soff < 0) { - lfs_dfs_unlock(); return _lfs_result_to_dfs(soff); } file->pos = dfs_lfs_fd->u.dir.pos; } - lfs_dfs_unlock(); return (file->pos); } @@ -829,14 +811,12 @@ static int _dfs_lfs_getdents(struct dfs_fd* file, struct dirent* dirp, uint32_t RT_ASSERT(file->data != RT_NULL); - lfs_dfs_lock(); dfs_lfs_fd = (dfs_lfs_fd_t*)(file->data); /* make integer count */ count = (count / sizeof(struct dirent)) * sizeof(struct dirent); if (count == 0) { - lfs_dfs_unlock(); return -EINVAL; } @@ -886,13 +866,11 @@ static int _dfs_lfs_getdents(struct dfs_fd* file, struct dirent* dirp, uint32_t if (index == 0) { - lfs_dfs_unlock(); return _lfs_result_to_dfs(result); } file->pos += index * sizeof(struct dirent); - lfs_dfs_unlock(); return index * sizeof(struct dirent); } @@ -901,7 +879,11 @@ static const struct dfs_file_ops _dfs_lfs_fops = { _dfs_lfs_close, _dfs_lfs_ioctl, _dfs_lfs_read, +#ifndef LFS_READONLY _dfs_lfs_write, +#else + NULL, +#endif _dfs_lfs_flush, _dfs_lfs_lseek, _dfs_lfs_getdents, @@ -912,21 +894,29 @@ static const struct dfs_filesystem_ops _dfs_lfs_ops = { "lfs", DFS_FS_FLAG_DEFAULT, &_dfs_lfs_fops, - _dfs_lfs_mount, _dfs_lfs_unmount, - +#ifndef LFS_READONLY _dfs_lfs_mkfs, +#else + NULL, +#endif _dfs_lfs_statfs, +#ifndef LFS_READONLY _dfs_lfs_unlink, +#else + NULL, +#endif _dfs_lfs_stat, +#ifndef LFS_READONLY _dfs_lfs_rename, +#else + NULL, +#endif }; int dfs_lfs_init(void) { - /* init file system lock */ - rt_mutex_init(&_lfs_lock, "lfsmtx", RT_IPC_FLAG_FIFO); /* register ram file system */ return dfs_register(&_dfs_lfs_ops); }