dfs_romfs.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. #include <rtthread.h>
  2. #include <dfs.h>
  3. #include <dfs_fs.h>
  4. #include "dfs_romfs.h"
  5. int dfs_romfs_mount(struct dfs_filesystem* fs, unsigned long rwflag, const void* data)
  6. {
  7. struct romfs_dirent* root_dirent;
  8. if (data == RT_NULL) return -DFS_STATUS_EIO;
  9. root_dirent = (struct romfs_dirent*)data;
  10. fs->data = root_dirent;
  11. return DFS_STATUS_OK;
  12. }
  13. int dfs_romfs_unmount(struct dfs_filesystem* fs)
  14. {
  15. return DFS_STATUS_OK;
  16. }
  17. int dfs_romfs_ioctl(struct dfs_fd* file, int cmd, void* args)
  18. {
  19. return -DFS_STATUS_EIO;
  20. }
  21. struct romfs_dirent* dfs_romfs_lookup(struct romfs_dirent* root_dirent, const char* path)
  22. {
  23. rt_size_t index;
  24. const char *subpath, *subpath_end;
  25. struct romfs_dirent* dirent;
  26. dirent = root_dirent;
  27. if (path[0] == '/' && path[1] == '\0') return dirent;
  28. /* get the end position of this subpath */
  29. subpath_end = path;
  30. /* skip /// */
  31. while (*subpath_end && *subpath_end == '/') subpath_end ++;
  32. subpath = subpath_end;
  33. while ((*subpath_end != '/') && *subpath_end) subpath_end ++;
  34. while (dirent != RT_NULL)
  35. {
  36. /* search in folder */
  37. for (index = 0; index < dirent->size; index ++)
  38. {
  39. if (rt_strncmp(dirent[index].name, subpath, (subpath_end - subpath)) == 0)
  40. {
  41. /* skip /// */
  42. while (*subpath_end && *subpath_end == '/') subpath_end ++;
  43. subpath = subpath_end;
  44. while ((*subpath_end != '/') && *subpath_end) subpath_end ++;
  45. if (!(*subpath)) return dirent;
  46. if (dirent[index].type == ROMFS_DIRENT_DIR)
  47. {
  48. dirent = (struct romfs_dirent*)dirent[index].data;
  49. break;
  50. }
  51. else return dirent;
  52. }
  53. }
  54. }
  55. /* not found */
  56. return RT_NULL;
  57. }
  58. int dfs_romfs_read(struct dfs_fd* file, void *buf, rt_size_t count)
  59. {
  60. rt_size_t length;
  61. struct romfs_dirent* dirent;
  62. dirent = (struct romfs_dirent *)file->data;
  63. RT_ASSERT(dirent != RT_NULL);
  64. if (count < file->size - file->pos)
  65. length = count;
  66. else
  67. length = file->size - file->pos;
  68. if (length > 0)
  69. memcpy(buf, &(dirent->data[file->pos]), length);
  70. return length;
  71. }
  72. int dfs_romfs_lseek(struct dfs_fd* file, rt_off_t offset)
  73. {
  74. if (offset < file->size)
  75. {
  76. file->pos = offset;
  77. return file->pos;
  78. }
  79. return -DFS_STATUS_EIO;
  80. }
  81. int dfs_romfs_close(struct dfs_fd* file)
  82. {
  83. file->data = RT_NULL;
  84. return DFS_STATUS_OK;
  85. }
  86. int dfs_romfs_open(struct dfs_fd* file)
  87. {
  88. struct romfs_dirent* root_dirent;
  89. struct romfs_dirent* dirent;
  90. root_dirent = (struct romfs_dirent*)file->fs->data;
  91. if (file->flags & (DFS_O_CREAT | DFS_O_WRONLY | DFS_O_APPEND | DFS_O_TRUNC | DFS_O_RDWR))
  92. return -DFS_STATUS_EINVAL;
  93. dirent = dfs_romfs_lookup(root_dirent, file->path);
  94. if (dirent == RT_NULL) return -DFS_STATUS_ENOENT;
  95. if (file->flags & DFS_O_DIRECTORY)
  96. file->data = dirent;
  97. file->size = dirent->size;
  98. file->pos = 0;
  99. return DFS_STATUS_OK;
  100. }
  101. int dfs_romfs_stat(struct dfs_filesystem* fs, const char *path, struct _stat *st)
  102. {
  103. struct romfs_dirent* root_dirent;
  104. struct romfs_dirent* dirent;
  105. root_dirent = (struct romfs_dirent*)fs->data;
  106. dirent = dfs_romfs_lookup(root_dirent, path);
  107. if (dirent == RT_NULL) return -DFS_STATUS_ENOENT;
  108. st->st_dev = 0;
  109. st->st_mode = DFS_S_IFREG | DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
  110. DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
  111. if (dirent->type == ROMFS_DIRENT_DIR)
  112. {
  113. st->st_mode &= ~DFS_S_IFREG;
  114. st->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH;
  115. }
  116. st->st_size = dirent->size;
  117. st->st_mtime = 0;
  118. st->st_blksize = 512;
  119. return DFS_STATUS_OK;
  120. }
  121. int dfs_romfs_getdents(struct dfs_fd* file, struct _dirent* dirp, rt_uint32_t count)
  122. {
  123. rt_size_t index;
  124. const char *name;
  125. struct _dirent* d;
  126. struct romfs_dirent *dirent, *sub_dirent;
  127. dirent = (struct romfs_dirent*) file->data;
  128. /* make integer count */
  129. count = (count / sizeof(struct _dirent)) * sizeof(struct _dirent);
  130. if ( count == 0 ) return -DFS_STATUS_EINVAL;
  131. index = 0;
  132. sub_dirent = &dirent[file->pos];
  133. for (index = 0; index < count; index ++)
  134. {
  135. d = dirp + index;
  136. sub_dirent = &dirent[file->pos];
  137. name = sub_dirent->name;
  138. /* fill dirent */
  139. d->d_type &= DFS_DT_REG;
  140. d->d_namlen = rt_strlen(name);
  141. d->d_reclen = (rt_uint16_t)sizeof(struct _dirent);
  142. rt_strncpy(d->d_name, name, rt_strlen(name) + 1);
  143. /* move to next position */
  144. ++ file->pos;
  145. if (file->pos > file->size) break;
  146. }
  147. return index * sizeof(struct _dirent);
  148. }
  149. static const struct dfs_filesystem_operation _romfs =
  150. {
  151. "rom",
  152. dfs_romfs_mount,
  153. dfs_romfs_unmount,
  154. RT_NULL,
  155. RT_NULL,
  156. dfs_romfs_open,
  157. dfs_romfs_close,
  158. dfs_romfs_ioctl,
  159. dfs_romfs_read,
  160. RT_NULL,
  161. RT_NULL,
  162. dfs_romfs_lseek,
  163. dfs_romfs_getdents,
  164. RT_NULL,
  165. dfs_romfs_stat,
  166. RT_NULL,
  167. };
  168. int dfs_romfs_init(void)
  169. {
  170. /* register rom file system */
  171. dfs_register(&_romfs);
  172. return 0;
  173. }