dfs_romfs.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  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, rt_size_t *size)
  22. {
  23. rt_size_t index, found;
  24. const char *subpath, *subpath_end;
  25. struct romfs_dirent* dirent;
  26. rt_size_t dirent_size;
  27. if (path[0] == '/' && path[1] == '\0')
  28. {
  29. *size = root_dirent->size;
  30. return root_dirent;
  31. }
  32. /* goto root directy entries */
  33. dirent = (struct romfs_dirent*)root_dirent->data;
  34. dirent_size = root_dirent->size;
  35. /* get the end position of this subpath */
  36. subpath_end = path;
  37. /* skip /// */
  38. while (*subpath_end && *subpath_end == '/') subpath_end ++;
  39. subpath = subpath_end;
  40. while ((*subpath_end != '/') && *subpath_end) subpath_end ++;
  41. while (dirent != RT_NULL)
  42. {
  43. found = 0;
  44. /* search in folder */
  45. for (index = 0; index < dirent_size; index ++)
  46. {
  47. if (rt_strncmp(dirent[index].name, subpath, (subpath_end - subpath)) == 0)
  48. {
  49. dirent_size = dirent[index].size;
  50. /* skip /// */
  51. while (*subpath_end && *subpath_end == '/') subpath_end ++;
  52. subpath = subpath_end;
  53. while ((*subpath_end != '/') && *subpath_end) subpath_end ++;
  54. if (!(*subpath))
  55. {
  56. *size = dirent_size;
  57. return &dirent[index];
  58. }
  59. if (dirent[index].type == ROMFS_DIRENT_DIR)
  60. {
  61. /* enter directory */
  62. dirent = (struct romfs_dirent*)dirent[index].data;
  63. found = 1;
  64. break;
  65. }
  66. else
  67. {
  68. /* return file dirent */
  69. return &dirent[index];
  70. }
  71. }
  72. }
  73. if (!found) break; /* not found */
  74. }
  75. /* not found */
  76. return RT_NULL;
  77. }
  78. int dfs_romfs_read(struct dfs_fd* file, void *buf, rt_size_t count)
  79. {
  80. rt_size_t length;
  81. struct romfs_dirent* dirent;
  82. dirent = (struct romfs_dirent *)file->data;
  83. RT_ASSERT(dirent != RT_NULL);
  84. if (count < file->size - file->pos)
  85. length = count;
  86. else
  87. length = file->size - file->pos;
  88. if (length > 0)
  89. memcpy(buf, &(dirent->data[file->pos]), length);
  90. /* update file current position */
  91. file->pos += length;
  92. return length;
  93. }
  94. int dfs_romfs_lseek(struct dfs_fd* file, rt_off_t offset)
  95. {
  96. if (offset < file->size)
  97. {
  98. file->pos = offset;
  99. return file->pos;
  100. }
  101. return -DFS_STATUS_EIO;
  102. }
  103. int dfs_romfs_close(struct dfs_fd* file)
  104. {
  105. file->data = RT_NULL;
  106. return DFS_STATUS_OK;
  107. }
  108. int dfs_romfs_open(struct dfs_fd* file)
  109. {
  110. rt_size_t size;
  111. struct romfs_dirent* dirent;
  112. struct romfs_dirent* root_dirent;
  113. root_dirent = (struct romfs_dirent*)file->fs->data;
  114. if (file->flags & (DFS_O_CREAT | DFS_O_WRONLY | DFS_O_APPEND | DFS_O_TRUNC | DFS_O_RDWR))
  115. return -DFS_STATUS_EINVAL;
  116. dirent = dfs_romfs_lookup(root_dirent, file->path, &size);
  117. if (dirent == RT_NULL) return -DFS_STATUS_ENOENT;
  118. /* is a directory but not with O_DIRECTORY flag */
  119. if ((dirent->type == ROMFS_DIRENT_DIR) && !(file->flags & DFS_O_DIRECTORY))
  120. return -DFS_STATUS_ENOENT;
  121. file->data = dirent;
  122. file->size = size;
  123. file->pos = 0;
  124. return DFS_STATUS_OK;
  125. }
  126. int dfs_romfs_stat(struct dfs_filesystem* fs, const char *path, struct stat *st)
  127. {
  128. rt_size_t size;
  129. struct romfs_dirent* dirent;
  130. struct romfs_dirent* root_dirent;
  131. root_dirent = (struct romfs_dirent*)fs->data;
  132. dirent = dfs_romfs_lookup(root_dirent, path, &size);
  133. if (dirent == RT_NULL) return -DFS_STATUS_ENOENT;
  134. st->st_dev = 0;
  135. st->st_mode = DFS_S_IFREG | DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
  136. DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
  137. if (dirent->type == ROMFS_DIRENT_DIR)
  138. {
  139. st->st_mode &= ~DFS_S_IFREG;
  140. st->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH;
  141. }
  142. st->st_size = dirent->size;
  143. st->st_mtime = 0;
  144. st->st_blksize = 512;
  145. return DFS_STATUS_OK;
  146. }
  147. int dfs_romfs_getdents(struct dfs_fd* file, struct dirent* dirp, rt_uint32_t count)
  148. {
  149. rt_size_t index;
  150. const char *name;
  151. struct dirent* d;
  152. struct romfs_dirent *dirent, *sub_dirent;
  153. dirent = (struct romfs_dirent*) file->data;
  154. RT_ASSERT(dirent->type == ROMFS_DIRENT_DIR);
  155. /* enter directory */
  156. dirent = (struct romfs_dirent*) dirent->data;
  157. /* make integer count */
  158. count = (count / sizeof(struct dirent));
  159. if ( count == 0 ) return -DFS_STATUS_EINVAL;
  160. index = 0;
  161. for (index = 0; index < count && file->pos < file->size; index ++)
  162. {
  163. d = dirp + index;
  164. sub_dirent = &dirent[file->pos];
  165. name = sub_dirent->name;
  166. /* fill dirent */
  167. if (sub_dirent->type == ROMFS_DIRENT_DIR)
  168. d->d_type = DFS_DT_DIR;
  169. else
  170. d->d_type = DFS_DT_REG;
  171. d->d_namlen = rt_strlen(name);
  172. d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
  173. rt_strncpy(d->d_name, name, rt_strlen(name) + 1);
  174. /* move to next position */
  175. ++ file->pos;
  176. }
  177. return index * sizeof(struct dirent);
  178. }
  179. static const struct dfs_filesystem_operation _romfs =
  180. {
  181. "rom",
  182. dfs_romfs_mount,
  183. dfs_romfs_unmount,
  184. RT_NULL,
  185. RT_NULL,
  186. dfs_romfs_open,
  187. dfs_romfs_close,
  188. dfs_romfs_ioctl,
  189. dfs_romfs_read,
  190. RT_NULL,
  191. RT_NULL,
  192. dfs_romfs_lseek,
  193. dfs_romfs_getdents,
  194. RT_NULL,
  195. dfs_romfs_stat,
  196. RT_NULL,
  197. };
  198. int dfs_romfs_init(void)
  199. {
  200. /* register rom file system */
  201. dfs_register(&_romfs);
  202. return 0;
  203. }