dfs_lfs.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951
  1. #include <rtdevice.h>
  2. #include <rtthread.h>
  3. #include <dfs_file.h>
  4. #include <dfs_fs.h>
  5. #include "lfs.h"
  6. #include <stdio.h>
  7. #include <string.h>
  8. #ifndef RT_DEF_LFS_DRIVERS
  9. #define RT_DEF_LFS_DRIVERS 1
  10. #endif
  11. #if (RT_DEF_LFS_DRIVERS < 1)
  12. #error "#define RT_DEF_LFS_DRIVERS must > 0"
  13. #endif
  14. #ifndef LFS_READ_SIZE
  15. #define LFS_READ_SIZE 256
  16. #endif
  17. #ifndef LFS_PROG_SIZE
  18. #define LFS_PROG_SIZE 256
  19. #endif
  20. #ifndef LFS_BLOCK_SIZE
  21. #define LFS_BLOCK_SIZE 4096
  22. #endif
  23. #ifndef LFS_CACHE_SIZE
  24. #define LFS_CACHE_SIZE LFS_PROG_SIZE
  25. #endif
  26. #ifndef LFS_BLOCK_CYCLES
  27. #define LFS_BLOCK_CYCLES (-1)
  28. #endif
  29. #ifndef LFS_LOOKAHEAD_MAX
  30. #define LFS_LOOKAHEAD_MAX 128
  31. #endif
  32. #define ATTR_TIMESTAMP 0x74
  33. typedef struct _dfs_lfs_s
  34. {
  35. struct lfs lfs;
  36. struct lfs_config cfg;
  37. struct rt_mutex lock;
  38. } dfs_lfs_t;
  39. typedef struct _dfs_lfs_fd_s
  40. {
  41. struct lfs* lfs;
  42. union
  43. {
  44. struct lfs_file file;
  45. struct lfs_dir dir;
  46. } u;
  47. } dfs_lfs_fd_t;
  48. static struct _dfs_lfs_s* _lfs_mount_tbl[RT_DEF_LFS_DRIVERS] = {0};
  49. #ifdef LFS_THREADSAFE
  50. // Lock the underlying block device. Negative error codes
  51. // are propogated to the user.
  52. int _lfs_lock(const struct lfs_config *c)
  53. {
  54. dfs_lfs_t *dfs_lfs = rt_container_of(c, dfs_lfs_t, cfg);
  55. if (rt_mutex_take(&dfs_lfs->lock, RT_WAITING_FOREVER) != RT_EOK)
  56. {
  57. return -1;
  58. }
  59. return 0;
  60. }
  61. // Unlock the underlying block device. Negative error codes
  62. // are propogated to the user.
  63. int _lfs_unlock(const struct lfs_config *c)
  64. {
  65. dfs_lfs_t *dfs_lfs = rt_container_of(c, dfs_lfs_t, cfg);
  66. if (rt_mutex_release(&dfs_lfs->lock) != RT_EOK)
  67. {
  68. return -1;
  69. }
  70. return 0;
  71. }
  72. #endif
  73. // Read a region in a block. Negative error codes are propogated
  74. // to the user.
  75. static int _lfs_flash_read(const struct lfs_config* c, lfs_block_t block, lfs_off_t off, void* buffer, lfs_size_t size)
  76. {
  77. struct rt_mtd_nor_device* mtd_nor;
  78. RT_ASSERT(c != RT_NULL);
  79. RT_ASSERT(c->context != RT_NULL);
  80. mtd_nor = (struct rt_mtd_nor_device*)c->context;
  81. if (rt_mtd_nor_read(mtd_nor, block * c->block_size + off, buffer, size) != size)
  82. {
  83. return LFS_ERR_IO;
  84. }
  85. return LFS_ERR_OK;
  86. }
  87. // Program a region in a block. The block must have previously
  88. // been erased. Negative error codes are propogated to the user.
  89. // May return LFS_ERR_CORRUPT if the block should be considered bad.
  90. static int _lfs_flash_prog(const struct lfs_config* c, lfs_block_t block, lfs_off_t off, const void* buffer, lfs_size_t size)
  91. {
  92. struct rt_mtd_nor_device* mtd_nor;
  93. RT_ASSERT(c != RT_NULL);
  94. RT_ASSERT(c->context != RT_NULL);
  95. mtd_nor = (struct rt_mtd_nor_device*)c->context;
  96. if (rt_mtd_nor_write(mtd_nor, block * c->block_size + off, buffer, size) != size)
  97. {
  98. return LFS_ERR_IO;
  99. }
  100. return LFS_ERR_OK;
  101. }
  102. // Erase a block. A block must be erased before being programmed.
  103. // The state of an erased block is undefined. Negative error codes
  104. // are propogated to the user.
  105. // May return LFS_ERR_CORRUPT if the block should be considered bad.
  106. static int _lfs_flash_erase(const struct lfs_config* c, lfs_block_t block)
  107. {
  108. struct rt_mtd_nor_device* mtd_nor;
  109. RT_ASSERT(c != RT_NULL);
  110. RT_ASSERT(c->context != RT_NULL);
  111. mtd_nor = (struct rt_mtd_nor_device*)c->context;
  112. if (rt_mtd_nor_erase_block(mtd_nor, block * c->block_size, c->block_size) != RT_EOK)
  113. {
  114. return LFS_ERR_IO;
  115. }
  116. return LFS_ERR_OK;
  117. }
  118. // Sync the state of the underlying block device. Negative error codes
  119. // are propogated to the user.
  120. static int _lfs_flash_sync(const struct lfs_config* c)
  121. {
  122. return LFS_ERR_OK;
  123. }
  124. /* results:
  125. * -1, no space to install fatfs driver
  126. * >= 0, there is an space to install littlefs driver
  127. */
  128. static int _get_disk(rt_device_t dev_id)
  129. {
  130. int index;
  131. if (dev_id == RT_NULL)
  132. {
  133. for (index = 0; index < RT_DEF_LFS_DRIVERS; index ++)
  134. {
  135. if(_lfs_mount_tbl[index] == RT_NULL)
  136. {
  137. return index;
  138. }
  139. }
  140. }
  141. else
  142. {
  143. for (index = 0; index < RT_DEF_LFS_DRIVERS; index ++)
  144. {
  145. if ((_lfs_mount_tbl[index] != RT_NULL) && (_lfs_mount_tbl[index]->cfg.context == (void *)dev_id))
  146. {
  147. return index;
  148. }
  149. }
  150. }
  151. return -1;
  152. }
  153. static int _lfs_result_to_dfs(int result)
  154. {
  155. int status = 0;
  156. switch (result)
  157. {
  158. case LFS_ERR_OK:
  159. break;
  160. case LFS_ERR_IO:
  161. status = -EIO;
  162. break; // Error during device operation
  163. case LFS_ERR_NOENT:
  164. status = -ENOENT;
  165. break; // No directory entry
  166. case LFS_ERR_EXIST:
  167. status = -EEXIST;
  168. break; // Entry already exists
  169. case LFS_ERR_NOTDIR:
  170. status = -ENOTDIR;
  171. break; // Entry is not a dir
  172. case LFS_ERR_ISDIR:
  173. status = -EISDIR;
  174. break; // Entry is a dir
  175. case LFS_ERR_NOTEMPTY:
  176. status = -ENOTEMPTY;
  177. break; // Dir is not empty
  178. case LFS_ERR_BADF:
  179. status = -EBADF;
  180. break; // Bad file number
  181. case LFS_ERR_INVAL:
  182. status = -EINVAL;
  183. break; // Invalid parameter
  184. case LFS_ERR_NOSPC:
  185. status = -ENOSPC;
  186. break; // No space left on device
  187. case LFS_ERR_NOMEM:
  188. status = -ENOMEM;
  189. break; // No more memory available
  190. case LFS_ERR_CORRUPT:
  191. status = -52;
  192. break; // Corrupted
  193. default:
  194. status = -EIO;
  195. break;
  196. }
  197. return status;
  198. }
  199. static void _lfs_load_config(struct lfs_config* lfs_cfg, struct rt_mtd_nor_device* mtd_nor)
  200. {
  201. uint64_t mtd_size;
  202. lfs_cfg->context = (void*)mtd_nor;
  203. lfs_cfg->read_size = LFS_READ_SIZE;
  204. lfs_cfg->prog_size = LFS_PROG_SIZE;
  205. lfs_cfg->block_size = mtd_nor->block_size;
  206. if (lfs_cfg->block_size < LFS_BLOCK_SIZE)
  207. {
  208. lfs_cfg->block_size = LFS_BLOCK_SIZE;
  209. }
  210. lfs_cfg->cache_size = LFS_CACHE_SIZE;
  211. lfs_cfg->block_cycles = LFS_BLOCK_CYCLES;
  212. mtd_size = mtd_nor->block_end - mtd_nor->block_start;
  213. mtd_size *= mtd_nor->block_size;
  214. lfs_cfg->block_count = mtd_size / lfs_cfg->block_size;
  215. lfs_cfg->lookahead_size = 32 * ((lfs_cfg->block_count + 31) / 32);
  216. if (lfs_cfg->lookahead_size > LFS_LOOKAHEAD_MAX)
  217. {
  218. lfs_cfg->lookahead_size = LFS_LOOKAHEAD_MAX;
  219. }
  220. #ifdef LFS_THREADSAFE
  221. lfs_cfg->lock = _lfs_lock;
  222. lfs_cfg->unlock = _lfs_unlock;
  223. #endif
  224. lfs_cfg->read = _lfs_flash_read;
  225. lfs_cfg->prog = _lfs_flash_prog;
  226. lfs_cfg->erase = _lfs_flash_erase;
  227. lfs_cfg->sync = _lfs_flash_sync;
  228. }
  229. static int _dfs_lfs_mount(struct dfs_filesystem* dfs, unsigned long rwflag, const void* data)
  230. {
  231. int result;
  232. int index;
  233. dfs_lfs_t* dfs_lfs;
  234. /* Check Device Type */
  235. if (dfs->dev_id->type != RT_Device_Class_MTD)
  236. {
  237. rt_kprintf("The flash device type must be MTD!\n");
  238. return -EINVAL;
  239. }
  240. /* get an empty position */
  241. index = _get_disk(RT_NULL);
  242. if (index == -1)
  243. {
  244. return -EIO;
  245. }
  246. /*create lfs handle */
  247. dfs_lfs = (dfs_lfs_t*)rt_malloc(sizeof(dfs_lfs_t));
  248. if (dfs_lfs == RT_NULL)
  249. {
  250. rt_kprintf("ERROR:no memory!\n");
  251. return -ENOMEM;
  252. }
  253. rt_memset(dfs_lfs, 0, sizeof(dfs_lfs_t));
  254. rt_mutex_init(&dfs_lfs->lock, "lfslock", RT_IPC_FLAG_PRIO);
  255. _lfs_load_config(&dfs_lfs->cfg, (struct rt_mtd_nor_device*)dfs->dev_id);
  256. /* mount lfs*/
  257. result = lfs_mount(&dfs_lfs->lfs, &dfs_lfs->cfg);
  258. if (result != LFS_ERR_OK)
  259. {
  260. rt_mutex_detach(&dfs_lfs->lock);
  261. /* release memory */
  262. rt_free(dfs_lfs);
  263. return -EIO;
  264. }
  265. /* mount succeed! */
  266. dfs->data = (void*)dfs_lfs;
  267. _lfs_mount_tbl[index] = dfs_lfs;
  268. return RT_EOK;
  269. }
  270. static int _dfs_lfs_unmount(struct dfs_filesystem* dfs)
  271. {
  272. int result;
  273. int index;
  274. dfs_lfs_t* dfs_lfs;
  275. RT_ASSERT(dfs != RT_NULL);
  276. RT_ASSERT(dfs->data != RT_NULL);
  277. /* find the device index and then umount it */
  278. index = _get_disk(dfs->dev_id);
  279. if (index == -1)
  280. {
  281. return -ENOENT;
  282. }
  283. _lfs_mount_tbl[index] = RT_NULL;
  284. dfs_lfs = (dfs_lfs_t*)dfs->data;
  285. dfs->data = RT_NULL;
  286. result = lfs_unmount(&dfs_lfs->lfs);
  287. rt_mutex_detach(&dfs_lfs->lock);
  288. rt_free(dfs_lfs);
  289. return _lfs_result_to_dfs(result);
  290. }
  291. #ifndef LFS_READONLY
  292. static int _dfs_lfs_mkfs(rt_device_t dev_id)
  293. {
  294. int result;
  295. int index;
  296. dfs_lfs_t* dfs_lfs;
  297. if (dev_id == RT_NULL)
  298. {
  299. return -EINVAL;
  300. }
  301. /* Check Device Type */
  302. if (dev_id->type != RT_Device_Class_MTD)
  303. {
  304. rt_kprintf("The flash device type must be MTD!\n");
  305. return -EINVAL;
  306. }
  307. index = _get_disk(dev_id);
  308. if (index == -1)
  309. {
  310. /* create lfs handle */
  311. dfs_lfs = rt_malloc(sizeof(dfs_lfs_t));
  312. if (dfs_lfs == RT_NULL)
  313. {
  314. rt_kprintf("ERROR:no memory!\n");
  315. return -ENOMEM;
  316. }
  317. rt_memset(dfs_lfs, 0, sizeof(dfs_lfs_t));
  318. rt_mutex_init(&dfs_lfs->lock, "lfslock", RT_IPC_FLAG_PRIO);
  319. _lfs_load_config(&dfs_lfs->cfg, (struct rt_mtd_nor_device*)dev_id);
  320. /* format flash device */
  321. result = lfs_format(&dfs_lfs->lfs, &dfs_lfs->cfg);
  322. rt_mutex_detach(&dfs_lfs->lock);
  323. rt_free(dfs_lfs);
  324. return _lfs_result_to_dfs(result);
  325. }
  326. dfs_lfs = _lfs_mount_tbl[index];
  327. /* unmount it */
  328. result = lfs_unmount(&dfs_lfs->lfs);
  329. if (result != LFS_ERR_OK)
  330. {
  331. return _lfs_result_to_dfs(result);
  332. }
  333. _lfs_mount_tbl[index] = RT_NULL;
  334. /* format flash device */
  335. result = lfs_format(&dfs_lfs->lfs, &dfs_lfs->cfg);
  336. if (result != LFS_ERR_OK)
  337. {
  338. return _lfs_result_to_dfs(result);
  339. }
  340. _lfs_load_config(&dfs_lfs->cfg, (struct rt_mtd_nor_device*)dev_id);
  341. /* mount lfs*/
  342. result = lfs_mount(&dfs_lfs->lfs, &dfs_lfs->cfg);
  343. if (result == LFS_ERR_OK)
  344. {
  345. _lfs_mount_tbl[index] = dfs_lfs;
  346. }
  347. return _lfs_result_to_dfs(result);
  348. }
  349. #endif
  350. static int _dfs_lfs_statfs_count(void* p, lfs_block_t b)
  351. {
  352. *(lfs_size_t*)p += 1;
  353. return 0;
  354. }
  355. static int _dfs_lfs_statfs(struct dfs_filesystem* dfs, struct statfs* buf)
  356. {
  357. dfs_lfs_t* dfs_lfs;
  358. int result;
  359. lfs_size_t in_use = 0;
  360. RT_ASSERT(buf != RT_NULL);
  361. RT_ASSERT(dfs != RT_NULL);
  362. RT_ASSERT(dfs->data != RT_NULL);
  363. dfs_lfs = (dfs_lfs_t*)dfs->data;
  364. /* Get total sectors and free sectors */
  365. result = lfs_fs_traverse(&dfs_lfs->lfs, _dfs_lfs_statfs_count, &in_use);
  366. if (result != LFS_ERR_OK)
  367. {
  368. return _lfs_result_to_dfs(result);
  369. }
  370. buf->f_bsize = dfs_lfs->cfg.block_size;
  371. buf->f_blocks = dfs_lfs->cfg.block_count;
  372. buf->f_bfree = dfs_lfs->cfg.block_count - in_use;
  373. return RT_EOK;
  374. }
  375. #ifndef LFS_READONLY
  376. static int _dfs_lfs_unlink(struct dfs_filesystem* dfs, const char* path)
  377. {
  378. dfs_lfs_t* dfs_lfs;
  379. int result;
  380. RT_ASSERT(dfs != RT_NULL);
  381. RT_ASSERT(dfs->data != RT_NULL);
  382. dfs_lfs = (dfs_lfs_t*)dfs->data;
  383. result = lfs_remove(&dfs_lfs->lfs, path);
  384. return _lfs_result_to_dfs(result);
  385. }
  386. #endif
  387. static void _dfs_lfs_tostat(struct stat* st, struct lfs_info* info, time_t mtime)
  388. {
  389. memset(st, 0, sizeof(struct stat));
  390. /* convert to dfs stat structure */
  391. st->st_dev = 0;
  392. st->st_size = info->size;
  393. st->st_mode = S_IRWXU | S_IRWXG | S_IRWXO;
  394. switch (info->type)
  395. {
  396. case LFS_TYPE_DIR:
  397. st->st_mode |= S_IFDIR;
  398. break;
  399. case LFS_TYPE_REG:
  400. st->st_mode |= S_IFREG;
  401. break;
  402. }
  403. st->st_mtime = mtime;
  404. }
  405. static int _dfs_lfs_stat(struct dfs_filesystem* dfs, const char* path, struct stat* st)
  406. {
  407. dfs_lfs_t* dfs_lfs;
  408. int result;
  409. struct lfs_info info;
  410. RT_ASSERT(dfs != RT_NULL);
  411. RT_ASSERT(dfs->data != RT_NULL);
  412. dfs_lfs = (dfs_lfs_t*)dfs->data;
  413. result = lfs_stat(&dfs_lfs->lfs, path, &info);
  414. if (result != LFS_ERR_OK)
  415. {
  416. return _lfs_result_to_dfs(result);
  417. }
  418. time_t mtime;
  419. lfs_getattr(&dfs_lfs->lfs, path, ATTR_TIMESTAMP, &mtime, sizeof(time_t));
  420. _dfs_lfs_tostat(st, &info, mtime);
  421. return 0;
  422. }
  423. #ifndef LFS_READONLY
  424. static int _dfs_lfs_rename(struct dfs_filesystem* dfs, const char* from, const char* to)
  425. {
  426. dfs_lfs_t* dfs_lfs;
  427. int result;
  428. RT_ASSERT(dfs != RT_NULL);
  429. RT_ASSERT(dfs->data != RT_NULL);
  430. dfs_lfs = (dfs_lfs_t*)dfs->data;
  431. result = lfs_rename(&dfs_lfs->lfs, from, to);
  432. return _lfs_result_to_dfs(result);
  433. }
  434. #endif
  435. /******************************************************************************
  436. * file operations
  437. ******************************************************************************/
  438. static int _dfs_lfs_open(struct dfs_file* file)
  439. {
  440. struct dfs_filesystem* dfs;
  441. dfs_lfs_t* dfs_lfs;
  442. int result;
  443. int flags = 0;
  444. RT_ASSERT(file != RT_NULL);
  445. dfs = (struct dfs_filesystem*)file->vnode->fs;
  446. RT_ASSERT(file->vnode->ref_count > 0);
  447. if (file->vnode->ref_count > 1)
  448. {
  449. if (file->vnode->type == FT_DIRECTORY
  450. && !(file->flags & O_DIRECTORY))
  451. {
  452. return -ENOENT;
  453. }
  454. file->pos = 0;
  455. return 0;
  456. }
  457. dfs_lfs = (dfs_lfs_t*)dfs->data;
  458. if (file->flags & O_DIRECTORY)
  459. {
  460. dfs_lfs_fd_t* dfs_lfs_fd = rt_malloc(sizeof(dfs_lfs_fd_t));
  461. if (dfs_lfs_fd == RT_NULL)
  462. {
  463. rt_kprintf("ERROR:no memory!\n");
  464. result = -ENOMEM;
  465. goto _error_dir;
  466. }
  467. rt_memset(dfs_lfs_fd, 0, sizeof(dfs_lfs_fd_t));
  468. dfs_lfs_fd->lfs = &dfs_lfs->lfs;
  469. if (file->flags & O_CREAT)
  470. {
  471. #ifndef LFS_READONLY
  472. result = lfs_mkdir(dfs_lfs_fd->lfs, file->vnode->path);
  473. #else
  474. result = -EINVAL;
  475. #endif
  476. if (result != LFS_ERR_OK)
  477. {
  478. goto _error_dir;
  479. }
  480. }
  481. result = lfs_dir_open(dfs_lfs_fd->lfs, &dfs_lfs_fd->u.dir, file->vnode->path);
  482. if (result != LFS_ERR_OK)
  483. {
  484. goto _error_dir;
  485. }
  486. else
  487. {
  488. file->data = (void*)dfs_lfs_fd;
  489. return RT_EOK;
  490. }
  491. _error_dir:
  492. if (dfs_lfs_fd != RT_NULL)
  493. {
  494. rt_free(dfs_lfs_fd);
  495. }
  496. return _lfs_result_to_dfs(result);
  497. }
  498. else
  499. {
  500. dfs_lfs_fd_t* dfs_lfs_fd = rt_malloc(sizeof(dfs_lfs_fd_t));
  501. if (dfs_lfs_fd == RT_NULL)
  502. {
  503. rt_kprintf("ERROR:no memory!\n");
  504. result = -ENOMEM;
  505. goto _error_file;
  506. }
  507. rt_memset(dfs_lfs_fd, 0, sizeof(dfs_lfs_fd_t));
  508. dfs_lfs_fd->lfs = &dfs_lfs->lfs;
  509. if ((file->flags & 3) == O_RDONLY)
  510. flags |= LFS_O_RDONLY;
  511. if ((file->flags & 3) == O_WRONLY)
  512. flags |= LFS_O_WRONLY;
  513. if ((file->flags & 3) == O_RDWR)
  514. flags |= LFS_O_RDWR;
  515. if (file->flags & O_CREAT)
  516. flags |= LFS_O_CREAT;
  517. if (file->flags & O_EXCL)
  518. flags |= LFS_O_EXCL;
  519. if (file->flags & O_TRUNC)
  520. flags |= LFS_O_TRUNC;
  521. if (file->flags & O_APPEND)
  522. flags |= LFS_O_APPEND;
  523. result = lfs_file_open(dfs_lfs_fd->lfs, &dfs_lfs_fd->u.file, file->vnode->path, flags);
  524. if (result != LFS_ERR_OK)
  525. {
  526. goto _error_file;
  527. }
  528. else
  529. {
  530. file->data = (void*)dfs_lfs_fd;
  531. file->pos = dfs_lfs_fd->u.file.pos;
  532. file->vnode->size = dfs_lfs_fd->u.file.ctz.size;
  533. return RT_EOK;
  534. }
  535. _error_file:
  536. if (dfs_lfs_fd != RT_NULL)
  537. {
  538. rt_free(dfs_lfs_fd);
  539. }
  540. return _lfs_result_to_dfs(result);
  541. }
  542. }
  543. static int _dfs_lfs_close(struct dfs_file* file)
  544. {
  545. int result;
  546. dfs_lfs_fd_t* dfs_lfs_fd;
  547. RT_ASSERT(file != RT_NULL);
  548. RT_ASSERT(file->data != RT_NULL);
  549. RT_ASSERT(file->vnode->ref_count > 0);
  550. if (file->vnode->ref_count > 1)
  551. {
  552. return 0;
  553. }
  554. dfs_lfs_fd = (dfs_lfs_fd_t*)file->data;
  555. if (file->vnode->type == FT_DIRECTORY)
  556. {
  557. result = lfs_dir_close(dfs_lfs_fd->lfs, &dfs_lfs_fd->u.dir);
  558. }
  559. else
  560. {
  561. result = lfs_file_close(dfs_lfs_fd->lfs, &dfs_lfs_fd->u.file);
  562. }
  563. time_t now = time(RT_NULL);
  564. lfs_setattr(dfs_lfs_fd->lfs, file->vnode->path, ATTR_TIMESTAMP, &now, sizeof(time_t));
  565. rt_free(dfs_lfs_fd);
  566. return _lfs_result_to_dfs(result);
  567. }
  568. static int _dfs_lfs_ioctl(struct dfs_file* file, int cmd, void* args)
  569. {
  570. return -ENOSYS;
  571. }
  572. static int _dfs_lfs_read(struct dfs_file* file, void* buf, size_t len)
  573. {
  574. lfs_ssize_t ssize;
  575. dfs_lfs_fd_t* dfs_lfs_fd;
  576. RT_ASSERT(file != RT_NULL);
  577. RT_ASSERT(file->data != RT_NULL);
  578. if (file->vnode->type == FT_DIRECTORY)
  579. {
  580. return -EISDIR;
  581. }
  582. dfs_lfs_fd = (dfs_lfs_fd_t*)file->data;
  583. #if 0
  584. if (lfs_file_tell(dfs_lfs_fd->lfs, &dfs_lfs_fd->u.file) != file->pos)
  585. {
  586. lfs_soff_t soff = lfs_file_seek(dfs_lfs_fd->lfs, &dfs_lfs_fd->u.file, file->pos, LFS_SEEK_SET);
  587. if (soff < 0)
  588. {
  589. return _lfs_result_to_dfs(soff);
  590. }
  591. }
  592. #endif
  593. ssize = lfs_file_read(dfs_lfs_fd->lfs, &dfs_lfs_fd->u.file, buf, len);
  594. if (ssize < 0)
  595. {
  596. return _lfs_result_to_dfs(ssize);
  597. }
  598. /* update position */
  599. file->pos = dfs_lfs_fd->u.file.pos;
  600. return ssize;
  601. }
  602. #ifndef LFS_READONLY
  603. static int _dfs_lfs_write(struct dfs_file* file, const void* buf, size_t len)
  604. {
  605. lfs_ssize_t ssize;
  606. dfs_lfs_fd_t* dfs_lfs_fd;
  607. RT_ASSERT(file != RT_NULL);
  608. RT_ASSERT(file->data != RT_NULL);
  609. if (file->vnode->type == FT_DIRECTORY)
  610. {
  611. return -EISDIR;
  612. }
  613. dfs_lfs_fd = (dfs_lfs_fd_t*)file->data;
  614. #if 0
  615. if (lfs_file_tell(dfs_lfs_fd->lfs, &dfs_lfs_fd->u.file) != file->pos)
  616. {
  617. lfs_soff_t soff = lfs_file_seek(dfs_lfs_fd->lfs, &dfs_lfs_fd->u.file, file->pos, LFS_SEEK_SET);
  618. if (soff < 0)
  619. {
  620. return _lfs_result_to_dfs(soff);
  621. }
  622. }
  623. #endif
  624. ssize = lfs_file_write(dfs_lfs_fd->lfs, &dfs_lfs_fd->u.file, buf, len);
  625. if (ssize < 0)
  626. {
  627. return _lfs_result_to_dfs(ssize);
  628. }
  629. /* update position and file size */
  630. file->pos = dfs_lfs_fd->u.file.pos;
  631. file->vnode->size = dfs_lfs_fd->u.file.ctz.size;
  632. return ssize;
  633. }
  634. #endif
  635. static int _dfs_lfs_flush(struct dfs_file* file)
  636. {
  637. int result;
  638. dfs_lfs_fd_t* dfs_lfs_fd;
  639. RT_ASSERT(file != RT_NULL);
  640. RT_ASSERT(file->data != RT_NULL);
  641. dfs_lfs_fd = (dfs_lfs_fd_t*)file->data;
  642. result = lfs_file_sync(dfs_lfs_fd->lfs, &dfs_lfs_fd->u.file);
  643. return _lfs_result_to_dfs(result);
  644. }
  645. static int _dfs_lfs_lseek(struct dfs_file* file, rt_off_t offset)
  646. {
  647. dfs_lfs_fd_t* dfs_lfs_fd;
  648. RT_ASSERT(file != RT_NULL);
  649. RT_ASSERT(file->data != RT_NULL);
  650. dfs_lfs_fd = (dfs_lfs_fd_t*)file->data;
  651. if (file->vnode->type == FT_REGULAR)
  652. {
  653. lfs_soff_t soff = lfs_file_seek(dfs_lfs_fd->lfs, &dfs_lfs_fd->u.file, offset, LFS_SEEK_SET);
  654. if (soff < 0)
  655. {
  656. return _lfs_result_to_dfs(soff);
  657. }
  658. file->pos = dfs_lfs_fd->u.file.pos;
  659. }
  660. else if (file->vnode->type == FT_DIRECTORY)
  661. {
  662. lfs_soff_t soff = lfs_dir_seek(dfs_lfs_fd->lfs, &dfs_lfs_fd->u.dir, offset);
  663. if (soff < 0)
  664. {
  665. return _lfs_result_to_dfs(soff);
  666. }
  667. file->pos = dfs_lfs_fd->u.dir.pos;
  668. }
  669. return (file->pos);
  670. }
  671. static int _dfs_lfs_getdents(struct dfs_file* file, struct dirent* dirp, uint32_t count)
  672. {
  673. dfs_lfs_fd_t* dfs_lfs_fd;
  674. int result;
  675. int index;
  676. struct dirent* d;
  677. struct lfs_info info;
  678. RT_ASSERT(file->data != RT_NULL);
  679. dfs_lfs_fd = (dfs_lfs_fd_t*)(file->data);
  680. /* make integer count */
  681. count = (count / sizeof(struct dirent)) * sizeof(struct dirent);
  682. if (count == 0)
  683. {
  684. return -EINVAL;
  685. }
  686. index = 0;
  687. while (1)
  688. {
  689. d = dirp + index;
  690. result = lfs_dir_read(dfs_lfs_fd->lfs, &dfs_lfs_fd->u.dir, &info);
  691. if ((result != 1) || (info.name[0] == 0))
  692. {
  693. break;
  694. }
  695. if (rt_strcmp(info.name, ".") == 0)
  696. {
  697. continue;
  698. }
  699. else if (rt_strcmp(info.name, "..") == 0)
  700. {
  701. continue;
  702. }
  703. d->d_type = DT_UNKNOWN;
  704. switch (info.type)
  705. {
  706. case LFS_TYPE_DIR:
  707. d->d_type |= DT_DIR;
  708. break;
  709. case LFS_TYPE_REG:
  710. d->d_type |= DT_REG;
  711. break;
  712. }
  713. d->d_namlen = (rt_uint8_t)rt_strlen(info.name);
  714. d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
  715. rt_strncpy(d->d_name, info.name, DFS_PATH_MAX);
  716. index++;
  717. if (index * sizeof(struct dirent) >= count)
  718. {
  719. break;
  720. }
  721. }
  722. if (index == 0)
  723. {
  724. return _lfs_result_to_dfs(result);
  725. }
  726. file->pos += index * sizeof(struct dirent);
  727. return index * sizeof(struct dirent);
  728. }
  729. static const struct dfs_file_ops _dfs_lfs_fops = {
  730. _dfs_lfs_open,
  731. _dfs_lfs_close,
  732. _dfs_lfs_ioctl,
  733. _dfs_lfs_read,
  734. #ifndef LFS_READONLY
  735. _dfs_lfs_write,
  736. #else
  737. NULL,
  738. #endif
  739. _dfs_lfs_flush,
  740. _dfs_lfs_lseek,
  741. _dfs_lfs_getdents,
  742. // RT_NULL, /* poll interface */
  743. };
  744. static const struct dfs_filesystem_ops _dfs_lfs_ops = {
  745. "lfs",
  746. DFS_FS_FLAG_DEFAULT,
  747. &_dfs_lfs_fops,
  748. _dfs_lfs_mount,
  749. _dfs_lfs_unmount,
  750. #ifndef LFS_READONLY
  751. _dfs_lfs_mkfs,
  752. #else
  753. NULL,
  754. #endif
  755. _dfs_lfs_statfs,
  756. #ifndef LFS_READONLY
  757. _dfs_lfs_unlink,
  758. #else
  759. NULL,
  760. #endif
  761. _dfs_lfs_stat,
  762. #ifndef LFS_READONLY
  763. _dfs_lfs_rename,
  764. #else
  765. NULL,
  766. #endif
  767. };
  768. int dfs_lfs_init(void)
  769. {
  770. /* register ram file system */
  771. return dfs_register(&_dfs_lfs_ops);
  772. }
  773. INIT_COMPONENT_EXPORT(dfs_lfs_init);