Nicolas Borla
/
BBR_1Ebene
BBR 1 Ebene
mbed-os/features/filesystem/littlefs/LittleFileSystem.cpp@0:fbdae7e6d805, 2018-05-14 (annotated)
- Committer:
- borlanic
- Date:
- Mon May 14 11:29:06 2018 +0000
- Revision:
- 0:fbdae7e6d805
BBR
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
borlanic | 0:fbdae7e6d805 | 1 | /* mbed Microcontroller Library |
borlanic | 0:fbdae7e6d805 | 2 | * Copyright (c) 2017 ARM Limited |
borlanic | 0:fbdae7e6d805 | 3 | * |
borlanic | 0:fbdae7e6d805 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
borlanic | 0:fbdae7e6d805 | 5 | * you may not use this file except in compliance with the License. |
borlanic | 0:fbdae7e6d805 | 6 | * You may obtain a copy of the License at |
borlanic | 0:fbdae7e6d805 | 7 | * |
borlanic | 0:fbdae7e6d805 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
borlanic | 0:fbdae7e6d805 | 9 | * |
borlanic | 0:fbdae7e6d805 | 10 | * Unless required by applicable law or agreed to in writing, software |
borlanic | 0:fbdae7e6d805 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
borlanic | 0:fbdae7e6d805 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
borlanic | 0:fbdae7e6d805 | 13 | * See the License for the specific language governing permissions and |
borlanic | 0:fbdae7e6d805 | 14 | * limitations under the License. |
borlanic | 0:fbdae7e6d805 | 15 | */ |
borlanic | 0:fbdae7e6d805 | 16 | #include "mbed.h" |
borlanic | 0:fbdae7e6d805 | 17 | #include "LittleFileSystem.h" |
borlanic | 0:fbdae7e6d805 | 18 | #include "errno.h" |
borlanic | 0:fbdae7e6d805 | 19 | extern "C" { |
borlanic | 0:fbdae7e6d805 | 20 | #include "lfs.h" |
borlanic | 0:fbdae7e6d805 | 21 | #include "lfs_util.h" |
borlanic | 0:fbdae7e6d805 | 22 | } |
borlanic | 0:fbdae7e6d805 | 23 | |
borlanic | 0:fbdae7e6d805 | 24 | |
borlanic | 0:fbdae7e6d805 | 25 | ////// Conversion functions ////// |
borlanic | 0:fbdae7e6d805 | 26 | static int lfs_toerror(int err) |
borlanic | 0:fbdae7e6d805 | 27 | { |
borlanic | 0:fbdae7e6d805 | 28 | switch (err) { |
borlanic | 0:fbdae7e6d805 | 29 | case LFS_ERR_OK: return 0; |
borlanic | 0:fbdae7e6d805 | 30 | case LFS_ERR_IO: return -EIO; |
borlanic | 0:fbdae7e6d805 | 31 | case LFS_ERR_NOENT: return -ENOENT; |
borlanic | 0:fbdae7e6d805 | 32 | case LFS_ERR_EXIST: return -EEXIST; |
borlanic | 0:fbdae7e6d805 | 33 | case LFS_ERR_NOTDIR: return -ENOTDIR; |
borlanic | 0:fbdae7e6d805 | 34 | case LFS_ERR_ISDIR: return -EISDIR; |
borlanic | 0:fbdae7e6d805 | 35 | case LFS_ERR_INVAL: return -EINVAL; |
borlanic | 0:fbdae7e6d805 | 36 | case LFS_ERR_NOSPC: return -ENOSPC; |
borlanic | 0:fbdae7e6d805 | 37 | case LFS_ERR_NOMEM: return -ENOMEM; |
borlanic | 0:fbdae7e6d805 | 38 | default: return err; |
borlanic | 0:fbdae7e6d805 | 39 | } |
borlanic | 0:fbdae7e6d805 | 40 | } |
borlanic | 0:fbdae7e6d805 | 41 | |
borlanic | 0:fbdae7e6d805 | 42 | static int lfs_fromflags(int flags) |
borlanic | 0:fbdae7e6d805 | 43 | { |
borlanic | 0:fbdae7e6d805 | 44 | return ( |
borlanic | 0:fbdae7e6d805 | 45 | (((flags & 3) == O_RDONLY) ? LFS_O_RDONLY : 0) | |
borlanic | 0:fbdae7e6d805 | 46 | (((flags & 3) == O_WRONLY) ? LFS_O_WRONLY : 0) | |
borlanic | 0:fbdae7e6d805 | 47 | (((flags & 3) == O_RDWR) ? LFS_O_RDWR : 0) | |
borlanic | 0:fbdae7e6d805 | 48 | ((flags & O_CREAT) ? LFS_O_CREAT : 0) | |
borlanic | 0:fbdae7e6d805 | 49 | ((flags & O_EXCL) ? LFS_O_EXCL : 0) | |
borlanic | 0:fbdae7e6d805 | 50 | ((flags & O_TRUNC) ? LFS_O_TRUNC : 0) | |
borlanic | 0:fbdae7e6d805 | 51 | ((flags & O_APPEND) ? LFS_O_APPEND : 0)); |
borlanic | 0:fbdae7e6d805 | 52 | } |
borlanic | 0:fbdae7e6d805 | 53 | |
borlanic | 0:fbdae7e6d805 | 54 | static int lfs_fromwhence(int whence) |
borlanic | 0:fbdae7e6d805 | 55 | { |
borlanic | 0:fbdae7e6d805 | 56 | switch (whence) { |
borlanic | 0:fbdae7e6d805 | 57 | case SEEK_SET: return LFS_SEEK_SET; |
borlanic | 0:fbdae7e6d805 | 58 | case SEEK_CUR: return LFS_SEEK_CUR; |
borlanic | 0:fbdae7e6d805 | 59 | case SEEK_END: return LFS_SEEK_END; |
borlanic | 0:fbdae7e6d805 | 60 | default: return whence; |
borlanic | 0:fbdae7e6d805 | 61 | } |
borlanic | 0:fbdae7e6d805 | 62 | } |
borlanic | 0:fbdae7e6d805 | 63 | |
borlanic | 0:fbdae7e6d805 | 64 | static int lfs_tomode(int type) |
borlanic | 0:fbdae7e6d805 | 65 | { |
borlanic | 0:fbdae7e6d805 | 66 | int mode = S_IRWXU | S_IRWXG | S_IRWXO; |
borlanic | 0:fbdae7e6d805 | 67 | switch (type) { |
borlanic | 0:fbdae7e6d805 | 68 | case LFS_TYPE_DIR: return mode | S_IFDIR; |
borlanic | 0:fbdae7e6d805 | 69 | case LFS_TYPE_REG: return mode | S_IFREG; |
borlanic | 0:fbdae7e6d805 | 70 | default: return 0; |
borlanic | 0:fbdae7e6d805 | 71 | } |
borlanic | 0:fbdae7e6d805 | 72 | } |
borlanic | 0:fbdae7e6d805 | 73 | |
borlanic | 0:fbdae7e6d805 | 74 | static int lfs_totype(int type) |
borlanic | 0:fbdae7e6d805 | 75 | { |
borlanic | 0:fbdae7e6d805 | 76 | switch (type) { |
borlanic | 0:fbdae7e6d805 | 77 | case LFS_TYPE_DIR: return DT_DIR; |
borlanic | 0:fbdae7e6d805 | 78 | case LFS_TYPE_REG: return DT_REG; |
borlanic | 0:fbdae7e6d805 | 79 | default: return DT_UNKNOWN; |
borlanic | 0:fbdae7e6d805 | 80 | } |
borlanic | 0:fbdae7e6d805 | 81 | } |
borlanic | 0:fbdae7e6d805 | 82 | |
borlanic | 0:fbdae7e6d805 | 83 | |
borlanic | 0:fbdae7e6d805 | 84 | ////// Block device operations ////// |
borlanic | 0:fbdae7e6d805 | 85 | static int lfs_bd_read(const struct lfs_config *c, lfs_block_t block, |
borlanic | 0:fbdae7e6d805 | 86 | lfs_off_t off, void *buffer, lfs_size_t size) { |
borlanic | 0:fbdae7e6d805 | 87 | BlockDevice *bd = (BlockDevice *)c->context; |
borlanic | 0:fbdae7e6d805 | 88 | return bd->read(buffer, (bd_addr_t)block*c->block_size + off, size); |
borlanic | 0:fbdae7e6d805 | 89 | } |
borlanic | 0:fbdae7e6d805 | 90 | |
borlanic | 0:fbdae7e6d805 | 91 | static int lfs_bd_prog(const struct lfs_config *c, lfs_block_t block, |
borlanic | 0:fbdae7e6d805 | 92 | lfs_off_t off, const void *buffer, lfs_size_t size) { |
borlanic | 0:fbdae7e6d805 | 93 | BlockDevice *bd = (BlockDevice *)c->context; |
borlanic | 0:fbdae7e6d805 | 94 | return bd->program(buffer, (bd_addr_t)block*c->block_size + off, size); |
borlanic | 0:fbdae7e6d805 | 95 | } |
borlanic | 0:fbdae7e6d805 | 96 | |
borlanic | 0:fbdae7e6d805 | 97 | static int lfs_bd_erase(const struct lfs_config *c, lfs_block_t block) |
borlanic | 0:fbdae7e6d805 | 98 | { |
borlanic | 0:fbdae7e6d805 | 99 | BlockDevice *bd = (BlockDevice *)c->context; |
borlanic | 0:fbdae7e6d805 | 100 | return bd->erase((bd_addr_t)block*c->block_size, c->block_size); |
borlanic | 0:fbdae7e6d805 | 101 | } |
borlanic | 0:fbdae7e6d805 | 102 | |
borlanic | 0:fbdae7e6d805 | 103 | static int lfs_bd_sync(const struct lfs_config *c) |
borlanic | 0:fbdae7e6d805 | 104 | { |
borlanic | 0:fbdae7e6d805 | 105 | BlockDevice *bd = (BlockDevice *)c->context; |
borlanic | 0:fbdae7e6d805 | 106 | return bd->sync(); |
borlanic | 0:fbdae7e6d805 | 107 | } |
borlanic | 0:fbdae7e6d805 | 108 | |
borlanic | 0:fbdae7e6d805 | 109 | |
borlanic | 0:fbdae7e6d805 | 110 | ////// Generic filesystem operations ////// |
borlanic | 0:fbdae7e6d805 | 111 | |
borlanic | 0:fbdae7e6d805 | 112 | // Filesystem implementation (See LittleFileSystem.h) |
borlanic | 0:fbdae7e6d805 | 113 | LittleFileSystem::LittleFileSystem(const char *name, BlockDevice *bd, |
borlanic | 0:fbdae7e6d805 | 114 | lfs_size_t read_size, lfs_size_t prog_size, |
borlanic | 0:fbdae7e6d805 | 115 | lfs_size_t block_size, lfs_size_t lookahead) |
borlanic | 0:fbdae7e6d805 | 116 | : FileSystem(name) |
borlanic | 0:fbdae7e6d805 | 117 | , _read_size(read_size) |
borlanic | 0:fbdae7e6d805 | 118 | , _prog_size(prog_size) |
borlanic | 0:fbdae7e6d805 | 119 | , _block_size(block_size) |
borlanic | 0:fbdae7e6d805 | 120 | , _lookahead(lookahead) { |
borlanic | 0:fbdae7e6d805 | 121 | if (bd) { |
borlanic | 0:fbdae7e6d805 | 122 | mount(bd); |
borlanic | 0:fbdae7e6d805 | 123 | } |
borlanic | 0:fbdae7e6d805 | 124 | } |
borlanic | 0:fbdae7e6d805 | 125 | |
borlanic | 0:fbdae7e6d805 | 126 | LittleFileSystem::~LittleFileSystem() { |
borlanic | 0:fbdae7e6d805 | 127 | // nop if unmounted |
borlanic | 0:fbdae7e6d805 | 128 | unmount(); |
borlanic | 0:fbdae7e6d805 | 129 | } |
borlanic | 0:fbdae7e6d805 | 130 | |
borlanic | 0:fbdae7e6d805 | 131 | int LittleFileSystem::mount(BlockDevice *bd) |
borlanic | 0:fbdae7e6d805 | 132 | { |
borlanic | 0:fbdae7e6d805 | 133 | _mutex.lock(); |
borlanic | 0:fbdae7e6d805 | 134 | LFS_INFO("mount(%p)", bd); |
borlanic | 0:fbdae7e6d805 | 135 | _bd = bd; |
borlanic | 0:fbdae7e6d805 | 136 | int err = _bd->init(); |
borlanic | 0:fbdae7e6d805 | 137 | if (err) { |
borlanic | 0:fbdae7e6d805 | 138 | LFS_INFO("mount -> %d", err); |
borlanic | 0:fbdae7e6d805 | 139 | _mutex.unlock(); |
borlanic | 0:fbdae7e6d805 | 140 | return err; |
borlanic | 0:fbdae7e6d805 | 141 | } |
borlanic | 0:fbdae7e6d805 | 142 | |
borlanic | 0:fbdae7e6d805 | 143 | memset(&_config, 0, sizeof(_config)); |
borlanic | 0:fbdae7e6d805 | 144 | _config.context = bd; |
borlanic | 0:fbdae7e6d805 | 145 | _config.read = lfs_bd_read; |
borlanic | 0:fbdae7e6d805 | 146 | _config.prog = lfs_bd_prog; |
borlanic | 0:fbdae7e6d805 | 147 | _config.erase = lfs_bd_erase; |
borlanic | 0:fbdae7e6d805 | 148 | _config.sync = lfs_bd_sync; |
borlanic | 0:fbdae7e6d805 | 149 | _config.read_size = bd->get_read_size(); |
borlanic | 0:fbdae7e6d805 | 150 | if (_config.read_size < _read_size) { |
borlanic | 0:fbdae7e6d805 | 151 | _config.read_size = _read_size; |
borlanic | 0:fbdae7e6d805 | 152 | } |
borlanic | 0:fbdae7e6d805 | 153 | _config.prog_size = bd->get_program_size(); |
borlanic | 0:fbdae7e6d805 | 154 | if (_config.prog_size < _prog_size) { |
borlanic | 0:fbdae7e6d805 | 155 | _config.prog_size = _prog_size; |
borlanic | 0:fbdae7e6d805 | 156 | } |
borlanic | 0:fbdae7e6d805 | 157 | _config.block_size = bd->get_erase_size(); |
borlanic | 0:fbdae7e6d805 | 158 | if (_config.block_size < _block_size) { |
borlanic | 0:fbdae7e6d805 | 159 | _config.block_size = _block_size; |
borlanic | 0:fbdae7e6d805 | 160 | } |
borlanic | 0:fbdae7e6d805 | 161 | _config.block_count = bd->size() / _config.block_size; |
borlanic | 0:fbdae7e6d805 | 162 | _config.lookahead = 32 * ((_config.block_count+31)/32); |
borlanic | 0:fbdae7e6d805 | 163 | if (_config.lookahead > _lookahead) { |
borlanic | 0:fbdae7e6d805 | 164 | _config.lookahead = _lookahead; |
borlanic | 0:fbdae7e6d805 | 165 | } |
borlanic | 0:fbdae7e6d805 | 166 | |
borlanic | 0:fbdae7e6d805 | 167 | err = lfs_mount(&_lfs, &_config); |
borlanic | 0:fbdae7e6d805 | 168 | LFS_INFO("mount -> %d", lfs_toerror(err)); |
borlanic | 0:fbdae7e6d805 | 169 | _mutex.unlock(); |
borlanic | 0:fbdae7e6d805 | 170 | return lfs_toerror(err); |
borlanic | 0:fbdae7e6d805 | 171 | } |
borlanic | 0:fbdae7e6d805 | 172 | |
borlanic | 0:fbdae7e6d805 | 173 | int LittleFileSystem::unmount() |
borlanic | 0:fbdae7e6d805 | 174 | { |
borlanic | 0:fbdae7e6d805 | 175 | _mutex.lock(); |
borlanic | 0:fbdae7e6d805 | 176 | LFS_INFO("unmount(%s)", ""); |
borlanic | 0:fbdae7e6d805 | 177 | if (_bd) { |
borlanic | 0:fbdae7e6d805 | 178 | int err = lfs_unmount(&_lfs); |
borlanic | 0:fbdae7e6d805 | 179 | if (err) { |
borlanic | 0:fbdae7e6d805 | 180 | LFS_INFO("unmount -> %d", lfs_toerror(err)); |
borlanic | 0:fbdae7e6d805 | 181 | _mutex.unlock(); |
borlanic | 0:fbdae7e6d805 | 182 | return lfs_toerror(err); |
borlanic | 0:fbdae7e6d805 | 183 | } |
borlanic | 0:fbdae7e6d805 | 184 | |
borlanic | 0:fbdae7e6d805 | 185 | err = _bd->deinit(); |
borlanic | 0:fbdae7e6d805 | 186 | if (err) { |
borlanic | 0:fbdae7e6d805 | 187 | LFS_INFO("unmount -> %d", err); |
borlanic | 0:fbdae7e6d805 | 188 | _mutex.unlock(); |
borlanic | 0:fbdae7e6d805 | 189 | return err; |
borlanic | 0:fbdae7e6d805 | 190 | } |
borlanic | 0:fbdae7e6d805 | 191 | |
borlanic | 0:fbdae7e6d805 | 192 | _bd = NULL; |
borlanic | 0:fbdae7e6d805 | 193 | } |
borlanic | 0:fbdae7e6d805 | 194 | |
borlanic | 0:fbdae7e6d805 | 195 | LFS_INFO("unmount -> %d", 0); |
borlanic | 0:fbdae7e6d805 | 196 | _mutex.unlock(); |
borlanic | 0:fbdae7e6d805 | 197 | return 0; |
borlanic | 0:fbdae7e6d805 | 198 | } |
borlanic | 0:fbdae7e6d805 | 199 | |
borlanic | 0:fbdae7e6d805 | 200 | int LittleFileSystem::format(BlockDevice *bd, |
borlanic | 0:fbdae7e6d805 | 201 | lfs_size_t read_size, lfs_size_t prog_size, |
borlanic | 0:fbdae7e6d805 | 202 | lfs_size_t block_size, lfs_size_t lookahead) { |
borlanic | 0:fbdae7e6d805 | 203 | LFS_INFO("format(%p, %ld, %ld, %ld, %ld)", |
borlanic | 0:fbdae7e6d805 | 204 | bd, read_size, prog_size, block_size, lookahead); |
borlanic | 0:fbdae7e6d805 | 205 | int err = bd->init(); |
borlanic | 0:fbdae7e6d805 | 206 | if (err) { |
borlanic | 0:fbdae7e6d805 | 207 | LFS_INFO("format -> %d", err); |
borlanic | 0:fbdae7e6d805 | 208 | return err; |
borlanic | 0:fbdae7e6d805 | 209 | } |
borlanic | 0:fbdae7e6d805 | 210 | |
borlanic | 0:fbdae7e6d805 | 211 | lfs_t _lfs; |
borlanic | 0:fbdae7e6d805 | 212 | struct lfs_config _config; |
borlanic | 0:fbdae7e6d805 | 213 | |
borlanic | 0:fbdae7e6d805 | 214 | memset(&_config, 0, sizeof(_config)); |
borlanic | 0:fbdae7e6d805 | 215 | _config.context = bd; |
borlanic | 0:fbdae7e6d805 | 216 | _config.read = lfs_bd_read; |
borlanic | 0:fbdae7e6d805 | 217 | _config.prog = lfs_bd_prog; |
borlanic | 0:fbdae7e6d805 | 218 | _config.erase = lfs_bd_erase; |
borlanic | 0:fbdae7e6d805 | 219 | _config.sync = lfs_bd_sync; |
borlanic | 0:fbdae7e6d805 | 220 | _config.read_size = bd->get_read_size(); |
borlanic | 0:fbdae7e6d805 | 221 | if (_config.read_size < read_size) { |
borlanic | 0:fbdae7e6d805 | 222 | _config.read_size = read_size; |
borlanic | 0:fbdae7e6d805 | 223 | } |
borlanic | 0:fbdae7e6d805 | 224 | _config.prog_size = bd->get_program_size(); |
borlanic | 0:fbdae7e6d805 | 225 | if (_config.prog_size < prog_size) { |
borlanic | 0:fbdae7e6d805 | 226 | _config.prog_size = prog_size; |
borlanic | 0:fbdae7e6d805 | 227 | } |
borlanic | 0:fbdae7e6d805 | 228 | _config.block_size = bd->get_erase_size(); |
borlanic | 0:fbdae7e6d805 | 229 | if (_config.block_size < block_size) { |
borlanic | 0:fbdae7e6d805 | 230 | _config.block_size = block_size; |
borlanic | 0:fbdae7e6d805 | 231 | } |
borlanic | 0:fbdae7e6d805 | 232 | _config.block_count = bd->size() / _config.block_size; |
borlanic | 0:fbdae7e6d805 | 233 | _config.lookahead = 32 * ((_config.block_count+31)/32); |
borlanic | 0:fbdae7e6d805 | 234 | if (_config.lookahead > lookahead) { |
borlanic | 0:fbdae7e6d805 | 235 | _config.lookahead = lookahead; |
borlanic | 0:fbdae7e6d805 | 236 | } |
borlanic | 0:fbdae7e6d805 | 237 | |
borlanic | 0:fbdae7e6d805 | 238 | err = lfs_format(&_lfs, &_config); |
borlanic | 0:fbdae7e6d805 | 239 | if (err) { |
borlanic | 0:fbdae7e6d805 | 240 | LFS_INFO("format -> %d", lfs_toerror(err)); |
borlanic | 0:fbdae7e6d805 | 241 | return lfs_toerror(err); |
borlanic | 0:fbdae7e6d805 | 242 | } |
borlanic | 0:fbdae7e6d805 | 243 | |
borlanic | 0:fbdae7e6d805 | 244 | err = bd->deinit(); |
borlanic | 0:fbdae7e6d805 | 245 | if (err) { |
borlanic | 0:fbdae7e6d805 | 246 | LFS_INFO("format -> %d", err); |
borlanic | 0:fbdae7e6d805 | 247 | return err; |
borlanic | 0:fbdae7e6d805 | 248 | } |
borlanic | 0:fbdae7e6d805 | 249 | |
borlanic | 0:fbdae7e6d805 | 250 | LFS_INFO("format -> %d", 0); |
borlanic | 0:fbdae7e6d805 | 251 | return 0; |
borlanic | 0:fbdae7e6d805 | 252 | } |
borlanic | 0:fbdae7e6d805 | 253 | |
borlanic | 0:fbdae7e6d805 | 254 | int LittleFileSystem::reformat(BlockDevice *bd) |
borlanic | 0:fbdae7e6d805 | 255 | { |
borlanic | 0:fbdae7e6d805 | 256 | _mutex.lock(); |
borlanic | 0:fbdae7e6d805 | 257 | LFS_INFO("reformat(%p)", bd); |
borlanic | 0:fbdae7e6d805 | 258 | if (_bd) { |
borlanic | 0:fbdae7e6d805 | 259 | if (!bd) { |
borlanic | 0:fbdae7e6d805 | 260 | bd = _bd; |
borlanic | 0:fbdae7e6d805 | 261 | } |
borlanic | 0:fbdae7e6d805 | 262 | |
borlanic | 0:fbdae7e6d805 | 263 | int err = unmount(); |
borlanic | 0:fbdae7e6d805 | 264 | if (err) { |
borlanic | 0:fbdae7e6d805 | 265 | LFS_INFO("reformat -> %d", err); |
borlanic | 0:fbdae7e6d805 | 266 | _mutex.unlock(); |
borlanic | 0:fbdae7e6d805 | 267 | return err; |
borlanic | 0:fbdae7e6d805 | 268 | } |
borlanic | 0:fbdae7e6d805 | 269 | } |
borlanic | 0:fbdae7e6d805 | 270 | |
borlanic | 0:fbdae7e6d805 | 271 | if (!bd) { |
borlanic | 0:fbdae7e6d805 | 272 | LFS_INFO("reformat -> %d", -ENODEV); |
borlanic | 0:fbdae7e6d805 | 273 | _mutex.unlock(); |
borlanic | 0:fbdae7e6d805 | 274 | return -ENODEV; |
borlanic | 0:fbdae7e6d805 | 275 | } |
borlanic | 0:fbdae7e6d805 | 276 | |
borlanic | 0:fbdae7e6d805 | 277 | int err = LittleFileSystem::format(bd, |
borlanic | 0:fbdae7e6d805 | 278 | _read_size, _prog_size, _block_size, _lookahead); |
borlanic | 0:fbdae7e6d805 | 279 | if (err) { |
borlanic | 0:fbdae7e6d805 | 280 | LFS_INFO("reformat -> %d", err); |
borlanic | 0:fbdae7e6d805 | 281 | _mutex.unlock(); |
borlanic | 0:fbdae7e6d805 | 282 | return err; |
borlanic | 0:fbdae7e6d805 | 283 | } |
borlanic | 0:fbdae7e6d805 | 284 | |
borlanic | 0:fbdae7e6d805 | 285 | err = mount(bd); |
borlanic | 0:fbdae7e6d805 | 286 | if (err) { |
borlanic | 0:fbdae7e6d805 | 287 | LFS_INFO("reformat -> %d", err); |
borlanic | 0:fbdae7e6d805 | 288 | _mutex.unlock(); |
borlanic | 0:fbdae7e6d805 | 289 | return err; |
borlanic | 0:fbdae7e6d805 | 290 | } |
borlanic | 0:fbdae7e6d805 | 291 | |
borlanic | 0:fbdae7e6d805 | 292 | LFS_INFO("reformat -> %d", 0); |
borlanic | 0:fbdae7e6d805 | 293 | _mutex.unlock(); |
borlanic | 0:fbdae7e6d805 | 294 | return 0; |
borlanic | 0:fbdae7e6d805 | 295 | } |
borlanic | 0:fbdae7e6d805 | 296 | |
borlanic | 0:fbdae7e6d805 | 297 | int LittleFileSystem::remove(const char *filename) |
borlanic | 0:fbdae7e6d805 | 298 | { |
borlanic | 0:fbdae7e6d805 | 299 | _mutex.lock(); |
borlanic | 0:fbdae7e6d805 | 300 | LFS_INFO("remove(\"%s\")", filename); |
borlanic | 0:fbdae7e6d805 | 301 | int err = lfs_remove(&_lfs, filename); |
borlanic | 0:fbdae7e6d805 | 302 | LFS_INFO("remove -> %d", lfs_toerror(err)); |
borlanic | 0:fbdae7e6d805 | 303 | _mutex.unlock(); |
borlanic | 0:fbdae7e6d805 | 304 | return lfs_toerror(err); |
borlanic | 0:fbdae7e6d805 | 305 | } |
borlanic | 0:fbdae7e6d805 | 306 | |
borlanic | 0:fbdae7e6d805 | 307 | int LittleFileSystem::rename(const char *oldname, const char *newname) |
borlanic | 0:fbdae7e6d805 | 308 | { |
borlanic | 0:fbdae7e6d805 | 309 | _mutex.lock(); |
borlanic | 0:fbdae7e6d805 | 310 | LFS_INFO("rename(\"%s\", \"%s\")", oldname, newname); |
borlanic | 0:fbdae7e6d805 | 311 | int err = lfs_rename(&_lfs, oldname, newname); |
borlanic | 0:fbdae7e6d805 | 312 | LFS_INFO("rename -> %d", lfs_toerror(err)); |
borlanic | 0:fbdae7e6d805 | 313 | _mutex.unlock(); |
borlanic | 0:fbdae7e6d805 | 314 | return lfs_toerror(err); |
borlanic | 0:fbdae7e6d805 | 315 | } |
borlanic | 0:fbdae7e6d805 | 316 | |
borlanic | 0:fbdae7e6d805 | 317 | int LittleFileSystem::mkdir(const char *name, mode_t mode) |
borlanic | 0:fbdae7e6d805 | 318 | { |
borlanic | 0:fbdae7e6d805 | 319 | _mutex.lock(); |
borlanic | 0:fbdae7e6d805 | 320 | LFS_INFO("mkdir(\"%s\", 0x%lx)", name, mode); |
borlanic | 0:fbdae7e6d805 | 321 | int err = lfs_mkdir(&_lfs, name); |
borlanic | 0:fbdae7e6d805 | 322 | LFS_INFO("mkdir -> %d", lfs_toerror(err)); |
borlanic | 0:fbdae7e6d805 | 323 | _mutex.unlock(); |
borlanic | 0:fbdae7e6d805 | 324 | return lfs_toerror(err); |
borlanic | 0:fbdae7e6d805 | 325 | } |
borlanic | 0:fbdae7e6d805 | 326 | |
borlanic | 0:fbdae7e6d805 | 327 | int LittleFileSystem::stat(const char *name, struct stat *st) |
borlanic | 0:fbdae7e6d805 | 328 | { |
borlanic | 0:fbdae7e6d805 | 329 | struct lfs_info info; |
borlanic | 0:fbdae7e6d805 | 330 | _mutex.lock(); |
borlanic | 0:fbdae7e6d805 | 331 | LFS_INFO("stat(\"%s\", %p)", name, st); |
borlanic | 0:fbdae7e6d805 | 332 | int err = lfs_stat(&_lfs, name, &info); |
borlanic | 0:fbdae7e6d805 | 333 | LFS_INFO("stat -> %d", lfs_toerror(err)); |
borlanic | 0:fbdae7e6d805 | 334 | _mutex.unlock(); |
borlanic | 0:fbdae7e6d805 | 335 | st->st_size = info.size; |
borlanic | 0:fbdae7e6d805 | 336 | st->st_mode = lfs_tomode(info.type); |
borlanic | 0:fbdae7e6d805 | 337 | return lfs_toerror(err); |
borlanic | 0:fbdae7e6d805 | 338 | } |
borlanic | 0:fbdae7e6d805 | 339 | |
borlanic | 0:fbdae7e6d805 | 340 | static int lfs_statvfs_count(void *p, lfs_block_t b) |
borlanic | 0:fbdae7e6d805 | 341 | { |
borlanic | 0:fbdae7e6d805 | 342 | *(lfs_size_t *)p += 1; |
borlanic | 0:fbdae7e6d805 | 343 | return 0; |
borlanic | 0:fbdae7e6d805 | 344 | } |
borlanic | 0:fbdae7e6d805 | 345 | |
borlanic | 0:fbdae7e6d805 | 346 | int LittleFileSystem::statvfs(const char *name, struct statvfs *st) |
borlanic | 0:fbdae7e6d805 | 347 | { |
borlanic | 0:fbdae7e6d805 | 348 | memset(st, 0, sizeof(struct statvfs)); |
borlanic | 0:fbdae7e6d805 | 349 | |
borlanic | 0:fbdae7e6d805 | 350 | lfs_size_t in_use = 0; |
borlanic | 0:fbdae7e6d805 | 351 | _mutex.lock(); |
borlanic | 0:fbdae7e6d805 | 352 | LFS_INFO("statvfs(\"%s\", %p)", name, st); |
borlanic | 0:fbdae7e6d805 | 353 | int err = lfs_traverse(&_lfs, lfs_statvfs_count, &in_use); |
borlanic | 0:fbdae7e6d805 | 354 | LFS_INFO("statvfs -> %d", lfs_toerror(err)); |
borlanic | 0:fbdae7e6d805 | 355 | _mutex.unlock(); |
borlanic | 0:fbdae7e6d805 | 356 | if (err) { |
borlanic | 0:fbdae7e6d805 | 357 | return err; |
borlanic | 0:fbdae7e6d805 | 358 | } |
borlanic | 0:fbdae7e6d805 | 359 | |
borlanic | 0:fbdae7e6d805 | 360 | st->f_bsize = _config.block_size; |
borlanic | 0:fbdae7e6d805 | 361 | st->f_frsize = _config.block_size; |
borlanic | 0:fbdae7e6d805 | 362 | st->f_blocks = _config.block_count; |
borlanic | 0:fbdae7e6d805 | 363 | st->f_bfree = _config.block_count - in_use; |
borlanic | 0:fbdae7e6d805 | 364 | st->f_bavail = _config.block_count - in_use; |
borlanic | 0:fbdae7e6d805 | 365 | st->f_namemax = LFS_NAME_MAX; |
borlanic | 0:fbdae7e6d805 | 366 | return 0; |
borlanic | 0:fbdae7e6d805 | 367 | } |
borlanic | 0:fbdae7e6d805 | 368 | |
borlanic | 0:fbdae7e6d805 | 369 | ////// File operations ////// |
borlanic | 0:fbdae7e6d805 | 370 | int LittleFileSystem::file_open(fs_file_t *file, const char *path, int flags) |
borlanic | 0:fbdae7e6d805 | 371 | { |
borlanic | 0:fbdae7e6d805 | 372 | lfs_file_t *f = new lfs_file_t; |
borlanic | 0:fbdae7e6d805 | 373 | _mutex.lock(); |
borlanic | 0:fbdae7e6d805 | 374 | LFS_INFO("file_open(%p, \"%s\", 0x%x)", *file, path, flags); |
borlanic | 0:fbdae7e6d805 | 375 | int err = lfs_file_open(&_lfs, f, path, lfs_fromflags(flags)); |
borlanic | 0:fbdae7e6d805 | 376 | LFS_INFO("file_open -> %d", lfs_toerror(err)); |
borlanic | 0:fbdae7e6d805 | 377 | _mutex.unlock(); |
borlanic | 0:fbdae7e6d805 | 378 | if (!err) { |
borlanic | 0:fbdae7e6d805 | 379 | *file = f; |
borlanic | 0:fbdae7e6d805 | 380 | } else { |
borlanic | 0:fbdae7e6d805 | 381 | delete f; |
borlanic | 0:fbdae7e6d805 | 382 | } |
borlanic | 0:fbdae7e6d805 | 383 | return lfs_toerror(err); |
borlanic | 0:fbdae7e6d805 | 384 | } |
borlanic | 0:fbdae7e6d805 | 385 | |
borlanic | 0:fbdae7e6d805 | 386 | int LittleFileSystem::file_close(fs_file_t file) |
borlanic | 0:fbdae7e6d805 | 387 | { |
borlanic | 0:fbdae7e6d805 | 388 | lfs_file_t *f = (lfs_file_t *)file; |
borlanic | 0:fbdae7e6d805 | 389 | _mutex.lock(); |
borlanic | 0:fbdae7e6d805 | 390 | LFS_INFO("file_close(%p)", file); |
borlanic | 0:fbdae7e6d805 | 391 | int err = lfs_file_close(&_lfs, f); |
borlanic | 0:fbdae7e6d805 | 392 | LFS_INFO("file_close -> %d", lfs_toerror(err)); |
borlanic | 0:fbdae7e6d805 | 393 | _mutex.unlock(); |
borlanic | 0:fbdae7e6d805 | 394 | delete f; |
borlanic | 0:fbdae7e6d805 | 395 | return lfs_toerror(err); |
borlanic | 0:fbdae7e6d805 | 396 | } |
borlanic | 0:fbdae7e6d805 | 397 | |
borlanic | 0:fbdae7e6d805 | 398 | ssize_t LittleFileSystem::file_read(fs_file_t file, void *buffer, size_t len) |
borlanic | 0:fbdae7e6d805 | 399 | { |
borlanic | 0:fbdae7e6d805 | 400 | lfs_file_t *f = (lfs_file_t *)file; |
borlanic | 0:fbdae7e6d805 | 401 | _mutex.lock(); |
borlanic | 0:fbdae7e6d805 | 402 | LFS_INFO("file_read(%p, %p, %d)", file, buffer, len); |
borlanic | 0:fbdae7e6d805 | 403 | lfs_ssize_t res = lfs_file_read(&_lfs, f, buffer, len); |
borlanic | 0:fbdae7e6d805 | 404 | LFS_INFO("file_read -> %d", lfs_toerror(res)); |
borlanic | 0:fbdae7e6d805 | 405 | _mutex.unlock(); |
borlanic | 0:fbdae7e6d805 | 406 | return lfs_toerror(res); |
borlanic | 0:fbdae7e6d805 | 407 | } |
borlanic | 0:fbdae7e6d805 | 408 | |
borlanic | 0:fbdae7e6d805 | 409 | ssize_t LittleFileSystem::file_write(fs_file_t file, const void *buffer, size_t len) |
borlanic | 0:fbdae7e6d805 | 410 | { |
borlanic | 0:fbdae7e6d805 | 411 | lfs_file_t *f = (lfs_file_t *)file; |
borlanic | 0:fbdae7e6d805 | 412 | _mutex.lock(); |
borlanic | 0:fbdae7e6d805 | 413 | LFS_INFO("file_write(%p, %p, %d)", file, buffer, len); |
borlanic | 0:fbdae7e6d805 | 414 | lfs_ssize_t res = lfs_file_write(&_lfs, f, buffer, len); |
borlanic | 0:fbdae7e6d805 | 415 | LFS_INFO("file_write -> %d", lfs_toerror(res)); |
borlanic | 0:fbdae7e6d805 | 416 | _mutex.unlock(); |
borlanic | 0:fbdae7e6d805 | 417 | return lfs_toerror(res); |
borlanic | 0:fbdae7e6d805 | 418 | } |
borlanic | 0:fbdae7e6d805 | 419 | |
borlanic | 0:fbdae7e6d805 | 420 | int LittleFileSystem::file_sync(fs_file_t file) |
borlanic | 0:fbdae7e6d805 | 421 | { |
borlanic | 0:fbdae7e6d805 | 422 | lfs_file_t *f = (lfs_file_t *)file; |
borlanic | 0:fbdae7e6d805 | 423 | _mutex.lock(); |
borlanic | 0:fbdae7e6d805 | 424 | LFS_INFO("file_sync(%p)", file); |
borlanic | 0:fbdae7e6d805 | 425 | int err = lfs_file_sync(&_lfs, f); |
borlanic | 0:fbdae7e6d805 | 426 | LFS_INFO("file_sync -> %d", lfs_toerror(err)); |
borlanic | 0:fbdae7e6d805 | 427 | _mutex.unlock(); |
borlanic | 0:fbdae7e6d805 | 428 | return lfs_toerror(err); |
borlanic | 0:fbdae7e6d805 | 429 | } |
borlanic | 0:fbdae7e6d805 | 430 | |
borlanic | 0:fbdae7e6d805 | 431 | off_t LittleFileSystem::file_seek(fs_file_t file, off_t offset, int whence) |
borlanic | 0:fbdae7e6d805 | 432 | { |
borlanic | 0:fbdae7e6d805 | 433 | lfs_file_t *f = (lfs_file_t *)file; |
borlanic | 0:fbdae7e6d805 | 434 | _mutex.lock(); |
borlanic | 0:fbdae7e6d805 | 435 | LFS_INFO("file_seek(%p, %ld, %d)", file, offset, whence); |
borlanic | 0:fbdae7e6d805 | 436 | off_t res = lfs_file_seek(&_lfs, f, offset, lfs_fromwhence(whence)); |
borlanic | 0:fbdae7e6d805 | 437 | LFS_INFO("file_seek -> %d", lfs_toerror(res)); |
borlanic | 0:fbdae7e6d805 | 438 | _mutex.unlock(); |
borlanic | 0:fbdae7e6d805 | 439 | return lfs_toerror(res); |
borlanic | 0:fbdae7e6d805 | 440 | } |
borlanic | 0:fbdae7e6d805 | 441 | |
borlanic | 0:fbdae7e6d805 | 442 | off_t LittleFileSystem::file_tell(fs_file_t file) |
borlanic | 0:fbdae7e6d805 | 443 | { |
borlanic | 0:fbdae7e6d805 | 444 | lfs_file_t *f = (lfs_file_t *)file; |
borlanic | 0:fbdae7e6d805 | 445 | _mutex.lock(); |
borlanic | 0:fbdae7e6d805 | 446 | LFS_INFO("file_tell(%p)", file); |
borlanic | 0:fbdae7e6d805 | 447 | off_t res = lfs_file_tell(&_lfs, f); |
borlanic | 0:fbdae7e6d805 | 448 | LFS_INFO("file_tell -> %d", lfs_toerror(res)); |
borlanic | 0:fbdae7e6d805 | 449 | _mutex.unlock(); |
borlanic | 0:fbdae7e6d805 | 450 | return lfs_toerror(res); |
borlanic | 0:fbdae7e6d805 | 451 | } |
borlanic | 0:fbdae7e6d805 | 452 | |
borlanic | 0:fbdae7e6d805 | 453 | off_t LittleFileSystem::file_size(fs_file_t file) |
borlanic | 0:fbdae7e6d805 | 454 | { |
borlanic | 0:fbdae7e6d805 | 455 | lfs_file_t *f = (lfs_file_t *)file; |
borlanic | 0:fbdae7e6d805 | 456 | _mutex.lock(); |
borlanic | 0:fbdae7e6d805 | 457 | LFS_INFO("file_size(%p)", file); |
borlanic | 0:fbdae7e6d805 | 458 | off_t res = lfs_file_size(&_lfs, f); |
borlanic | 0:fbdae7e6d805 | 459 | LFS_INFO("file_size -> %d", lfs_toerror(res)); |
borlanic | 0:fbdae7e6d805 | 460 | _mutex.unlock(); |
borlanic | 0:fbdae7e6d805 | 461 | return lfs_toerror(res); |
borlanic | 0:fbdae7e6d805 | 462 | } |
borlanic | 0:fbdae7e6d805 | 463 | |
borlanic | 0:fbdae7e6d805 | 464 | |
borlanic | 0:fbdae7e6d805 | 465 | ////// Dir operations ////// |
borlanic | 0:fbdae7e6d805 | 466 | int LittleFileSystem::dir_open(fs_dir_t *dir, const char *path) |
borlanic | 0:fbdae7e6d805 | 467 | { |
borlanic | 0:fbdae7e6d805 | 468 | lfs_dir_t *d = new lfs_dir_t; |
borlanic | 0:fbdae7e6d805 | 469 | _mutex.lock(); |
borlanic | 0:fbdae7e6d805 | 470 | LFS_INFO("dir_open(%p, \"%s\")", *dir, path); |
borlanic | 0:fbdae7e6d805 | 471 | int err = lfs_dir_open(&_lfs, d, path); |
borlanic | 0:fbdae7e6d805 | 472 | LFS_INFO("dir_open -> %d", lfs_toerror(err)); |
borlanic | 0:fbdae7e6d805 | 473 | _mutex.unlock(); |
borlanic | 0:fbdae7e6d805 | 474 | if (!err) { |
borlanic | 0:fbdae7e6d805 | 475 | *dir = d; |
borlanic | 0:fbdae7e6d805 | 476 | } else { |
borlanic | 0:fbdae7e6d805 | 477 | delete d; |
borlanic | 0:fbdae7e6d805 | 478 | } |
borlanic | 0:fbdae7e6d805 | 479 | return lfs_toerror(err); |
borlanic | 0:fbdae7e6d805 | 480 | } |
borlanic | 0:fbdae7e6d805 | 481 | |
borlanic | 0:fbdae7e6d805 | 482 | int LittleFileSystem::dir_close(fs_dir_t dir) |
borlanic | 0:fbdae7e6d805 | 483 | { |
borlanic | 0:fbdae7e6d805 | 484 | lfs_dir_t *d = (lfs_dir_t *)dir; |
borlanic | 0:fbdae7e6d805 | 485 | _mutex.lock(); |
borlanic | 0:fbdae7e6d805 | 486 | LFS_INFO("dir_close(%p)", dir); |
borlanic | 0:fbdae7e6d805 | 487 | int err = lfs_dir_close(&_lfs, d); |
borlanic | 0:fbdae7e6d805 | 488 | LFS_INFO("dir_close -> %d", lfs_toerror(err)); |
borlanic | 0:fbdae7e6d805 | 489 | _mutex.unlock(); |
borlanic | 0:fbdae7e6d805 | 490 | delete d; |
borlanic | 0:fbdae7e6d805 | 491 | return lfs_toerror(err); |
borlanic | 0:fbdae7e6d805 | 492 | } |
borlanic | 0:fbdae7e6d805 | 493 | |
borlanic | 0:fbdae7e6d805 | 494 | ssize_t LittleFileSystem::dir_read(fs_dir_t dir, struct dirent *ent) |
borlanic | 0:fbdae7e6d805 | 495 | { |
borlanic | 0:fbdae7e6d805 | 496 | lfs_dir_t *d = (lfs_dir_t *)dir; |
borlanic | 0:fbdae7e6d805 | 497 | struct lfs_info info; |
borlanic | 0:fbdae7e6d805 | 498 | _mutex.lock(); |
borlanic | 0:fbdae7e6d805 | 499 | LFS_INFO("dir_read(%p, %p)", dir, ent); |
borlanic | 0:fbdae7e6d805 | 500 | int res = lfs_dir_read(&_lfs, d, &info); |
borlanic | 0:fbdae7e6d805 | 501 | LFS_INFO("dir_read -> %d", lfs_toerror(res)); |
borlanic | 0:fbdae7e6d805 | 502 | _mutex.unlock(); |
borlanic | 0:fbdae7e6d805 | 503 | if (res == 1) { |
borlanic | 0:fbdae7e6d805 | 504 | ent->d_type = lfs_totype(info.type); |
borlanic | 0:fbdae7e6d805 | 505 | strcpy(ent->d_name, info.name); |
borlanic | 0:fbdae7e6d805 | 506 | } |
borlanic | 0:fbdae7e6d805 | 507 | return lfs_toerror(res); |
borlanic | 0:fbdae7e6d805 | 508 | } |
borlanic | 0:fbdae7e6d805 | 509 | |
borlanic | 0:fbdae7e6d805 | 510 | void LittleFileSystem::dir_seek(fs_dir_t dir, off_t offset) |
borlanic | 0:fbdae7e6d805 | 511 | { |
borlanic | 0:fbdae7e6d805 | 512 | lfs_dir_t *d = (lfs_dir_t *)dir; |
borlanic | 0:fbdae7e6d805 | 513 | _mutex.lock(); |
borlanic | 0:fbdae7e6d805 | 514 | LFS_INFO("dir_seek(%p, %ld)", dir, offset); |
borlanic | 0:fbdae7e6d805 | 515 | lfs_dir_seek(&_lfs, d, offset); |
borlanic | 0:fbdae7e6d805 | 516 | LFS_INFO("dir_seek -> %s", "void"); |
borlanic | 0:fbdae7e6d805 | 517 | _mutex.unlock(); |
borlanic | 0:fbdae7e6d805 | 518 | } |
borlanic | 0:fbdae7e6d805 | 519 | |
borlanic | 0:fbdae7e6d805 | 520 | off_t LittleFileSystem::dir_tell(fs_dir_t dir) |
borlanic | 0:fbdae7e6d805 | 521 | { |
borlanic | 0:fbdae7e6d805 | 522 | lfs_dir_t *d = (lfs_dir_t *)dir; |
borlanic | 0:fbdae7e6d805 | 523 | _mutex.lock(); |
borlanic | 0:fbdae7e6d805 | 524 | LFS_INFO("dir_tell(%p)", dir); |
borlanic | 0:fbdae7e6d805 | 525 | lfs_soff_t res = lfs_dir_tell(&_lfs, d); |
borlanic | 0:fbdae7e6d805 | 526 | LFS_INFO("dir_tell -> %d", lfs_toerror(res)); |
borlanic | 0:fbdae7e6d805 | 527 | _mutex.unlock(); |
borlanic | 0:fbdae7e6d805 | 528 | return lfs_toerror(res); |
borlanic | 0:fbdae7e6d805 | 529 | } |
borlanic | 0:fbdae7e6d805 | 530 | |
borlanic | 0:fbdae7e6d805 | 531 | void LittleFileSystem::dir_rewind(fs_dir_t dir) |
borlanic | 0:fbdae7e6d805 | 532 | { |
borlanic | 0:fbdae7e6d805 | 533 | lfs_dir_t *d = (lfs_dir_t *)dir; |
borlanic | 0:fbdae7e6d805 | 534 | _mutex.lock(); |
borlanic | 0:fbdae7e6d805 | 535 | LFS_INFO("dir_rewind(%p)", dir); |
borlanic | 0:fbdae7e6d805 | 536 | lfs_dir_rewind(&_lfs, d); |
borlanic | 0:fbdae7e6d805 | 537 | LFS_INFO("dir_rewind -> %s", "void"); |
borlanic | 0:fbdae7e6d805 | 538 | _mutex.unlock(); |
borlanic | 0:fbdae7e6d805 | 539 | } |
borlanic | 0:fbdae7e6d805 | 540 |