dfs_fs.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. /*
  2. +------------------------------------------------------------------------------
  3. | Project : Device Filesystem
  4. +------------------------------------------------------------------------------
  5. | Copyright 2004, 2005 www.fayfayspace.org.
  6. | All rights reserved.
  7. |------------------------------------------------------------------------------
  8. | File : dfs_fs.c, the filesystem related implementations of Device FileSystem
  9. |------------------------------------------------------------------------------
  10. | Chang Logs:
  11. | Date Author Notes
  12. | 2005-02-22 ffxz The first version.
  13. +------------------------------------------------------------------------------
  14. */
  15. #include <dfs_fs.h>
  16. #include <dfs_raw.h>
  17. #include <dfs_util.h>
  18. #include <string.h>
  19. /*
  20. +------------------------------------------------------------------------------
  21. | Function : dfs_register
  22. +------------------------------------------------------------------------------
  23. | Description : registers a filesystem
  24. |
  25. | Parameters : ops, the implementation of filesystem
  26. | Returns : the status of register
  27. | 0 , successful
  28. | -1, failed
  29. +------------------------------------------------------------------------------
  30. */
  31. int dfs_register(struct dfs_filesystem_operation* ops)
  32. {
  33. int index, result;
  34. result = 0;
  35. /* lock filesystem */
  36. dfs_lock();
  37. /* check if this filesystem was already registered */
  38. for (index = 0; index < DFS_FILESYSTEM_TYPES_MAX; index++)
  39. {
  40. if (filesystem_operation_table[index] != RT_NULL &&
  41. strcmp(filesystem_operation_table[index]->name, ops->name) == 0)
  42. {
  43. result = -1;
  44. goto err;
  45. }
  46. }
  47. /* find out an empty filesystem type entry */
  48. for (index = 0; index < DFS_FILESYSTEM_TYPES_MAX && filesystem_operation_table[index] != RT_NULL;
  49. index++) ;
  50. /* filesystem type table full */
  51. if (index == DFS_FILESYSTEM_TYPES_MAX)
  52. {
  53. result = -1;
  54. goto err;
  55. }
  56. /* save the filesystem's operations */
  57. filesystem_operation_table[index] = ops;
  58. err:
  59. dfs_unlock();
  60. return result;
  61. }
  62. /*
  63. +------------------------------------------------------------------------------
  64. | Function : dfs_filesystem_lookup
  65. +------------------------------------------------------------------------------
  66. | Description : lookup the mounted filesystem on the specified path
  67. |
  68. | Parameters : path, the specified path string
  69. | Returns : the found filesystem
  70. +------------------------------------------------------------------------------
  71. */
  72. struct dfs_filesystem* dfs_filesystem_lookup(const char *path)
  73. {
  74. struct dfs_filesystem* fs;
  75. rt_uint32_t index, fspath, prefixlen;
  76. fs = RT_NULL;
  77. prefixlen = 0;
  78. /* lock filesystem */
  79. dfs_lock();
  80. /* lookup it in the filesystem table */
  81. for (index = 0; index < DFS_FILESYSTEMS_MAX + 1; index++)
  82. {
  83. fspath = strlen(filesystem_table[index].path);
  84. if (fspath < prefixlen) continue;
  85. if ((filesystem_table[index].ops != RT_NULL) &&
  86. str_is_prefix(filesystem_table[index].path, path) == 0)
  87. {
  88. fs = &filesystem_table[index];
  89. prefixlen = fspath;
  90. }
  91. }
  92. dfs_unlock();
  93. return fs;
  94. }
  95. rt_err_t dfs_filesystem_get_partition(struct dfs_partition* part, rt_uint8_t* buf, rt_uint32_t pindex)
  96. {
  97. #define DPT_ADDRESS 0x1be /* device partition offset in Boot Sector */
  98. #define DPT_ITEM_SIZE 16 /* partition item size */
  99. rt_uint8_t* dpt;
  100. rt_uint8_t type;
  101. rt_err_t result;
  102. RT_ASSERT(part != RT_NULL);
  103. RT_ASSERT(buf != RT_NULL);
  104. result = RT_EOK;
  105. dpt = buf + DPT_ADDRESS + pindex * DPT_ITEM_SIZE;
  106. if ((*dpt != 0x80) && (*dpt != 0x00))
  107. {
  108. /* which is not a partition table */
  109. result = -RT_ERROR;
  110. return result;
  111. }
  112. /* get partition type */
  113. type = *(dpt+4);
  114. if (type != 0)
  115. {
  116. /* set partition type */
  117. part->type = type;
  118. /* get partition offset and size */
  119. part->offset = *(dpt+ 8) | *(dpt+ 9) << 8 |
  120. *(dpt+10) << 16 | *(dpt+11) << 24;
  121. part->size = *(dpt+12) | *(dpt+13) << 8 |
  122. *(dpt+14) << 16 | *(dpt+15) << 24;
  123. #ifdef RT_USING_FINSH
  124. rt_kprintf("part[%d], begin: %d, size: ",
  125. pindex, part->offset * 512);
  126. if ( (part->size>>11) > 0 ) /* MB */
  127. {
  128. unsigned int part_size;
  129. part_size = part->size>>11;/* MB */
  130. if ( (part_size>>10) > 0) /* GB */
  131. {
  132. rt_kprintf("%d.%d%s",part_size>>10,part_size&0x3FF,"GB\r\n");/* GB */
  133. }
  134. else
  135. {
  136. rt_kprintf("%d.%d%s",part_size,(part->size>>1)&0x3FF,"MB\r\n");/* MB */
  137. }
  138. }
  139. else
  140. {
  141. rt_kprintf("%d%s",part->size>>1,"KB\r\n");/* KB */
  142. }
  143. #endif
  144. }
  145. else
  146. {
  147. result = -RT_ERROR;
  148. }
  149. return result;
  150. }
  151. /*
  152. +------------------------------------------------------------------------------
  153. | Function : dfs_mount
  154. +------------------------------------------------------------------------------
  155. | Description : mount a filesystem to specified path
  156. |
  157. | Parameters : device_name, the implementation of filesystem
  158. | path,
  159. | filesystemtype,
  160. | rwflag,
  161. | data,
  162. | Returns : the status of register
  163. | 0 , successful
  164. | -1, failed
  165. +------------------------------------------------------------------------------
  166. */
  167. int dfs_mount(const char* device_name, const char* path,
  168. const char* filesystemtype, unsigned long rwflag, const
  169. void* data)
  170. {
  171. struct dfs_filesystem_operation* ops;
  172. struct dfs_filesystem* fs;
  173. char *fullpath=RT_NULL;
  174. #ifdef DFS_USING_WORKDIR
  175. char full_path[DFS_PATH_MAX + 1];
  176. #endif
  177. rt_device_t dev_id;
  178. int index;
  179. /* open specific device */
  180. dev_id = rt_device_find(device_name);
  181. if (dev_id == RT_NULL)
  182. {
  183. /* no this device */
  184. rt_set_errno(-DFS_STATUS_ENODEV);
  185. return -1;
  186. }
  187. /* find out specific filesystem */
  188. dfs_lock();
  189. for ( index = 0; index < DFS_FILESYSTEM_TYPES_MAX; index++ )
  190. {
  191. if (strcmp(filesystem_operation_table[index]->name, filesystemtype) == 0)break;
  192. }
  193. /* can't find filesystem */
  194. if ( index == DFS_FILESYSTEM_TYPES_MAX )
  195. {
  196. rt_set_errno(-DFS_STATUS_ENODEV);
  197. dfs_unlock();
  198. return -1;
  199. }
  200. ops = filesystem_operation_table[index];
  201. dfs_unlock();
  202. /* make full path for special file */
  203. fullpath = (char*)path;
  204. if ( fullpath[0] != '/') /* not an abstract path */
  205. {
  206. #ifdef DFS_USING_WORKDIR
  207. /* build full path */
  208. fullpath = full_path;
  209. dfs_lock();
  210. build_fullpath(working_directory, path, fullpath);
  211. dfs_unlock();
  212. #else
  213. rt_set_errno(-DFS_STATUS_ENOTDIR);
  214. return -1;
  215. #endif
  216. }
  217. /* Check if the path exists or not, raw APIs call, fixme */
  218. if ( (strcmp(fullpath, "/") != 0) && (strcmp(fullpath, "/dev") != 0) )
  219. {
  220. struct dfs_fd fd;
  221. if ( dfile_raw_open(&fd, fullpath, DFS_O_RDONLY | DFS_O_DIRECTORY) < 0 )
  222. {
  223. rt_set_errno(-DFS_STATUS_ENOTDIR);
  224. return -1;
  225. }
  226. dfile_raw_close(&fd);
  227. }
  228. /* check whether the file system mounted or not */
  229. dfs_lock();
  230. for (index =0; index < DFS_FILESYSTEMS_MAX; index++)
  231. {
  232. if ( filesystem_table[index].ops != RT_NULL &&
  233. strcmp(filesystem_table[index].path, path) == 0 )
  234. {
  235. rt_set_errno(-DFS_STATUS_EINVAL);
  236. goto err1;
  237. }
  238. }
  239. /* find out en empty filesystem table entry */
  240. for (index = 0; index < DFS_FILESYSTEMS_MAX && filesystem_table[index].ops != RT_NULL;
  241. index++) ;
  242. if ( index == DFS_FILESYSTEMS_MAX ) /* can't find en empty filesystem table entry */
  243. {
  244. rt_set_errno(-DFS_STATUS_EMMOUNT);
  245. goto err1;
  246. }
  247. /* register file system */
  248. fs = &(filesystem_table[index]);
  249. strncpy(fs->path, fullpath, strlen(fullpath));
  250. fs->ops = ops;
  251. fs->dev_id = dev_id;
  252. /* release filesystem_table lock */
  253. dfs_unlock();
  254. /* open device, but do not check the status of device */
  255. rt_device_open(fs->dev_id, RT_DEVICE_OFLAG_RDWR);
  256. if ( ops->mount == RT_NULL ) /* there is no mount implementation */
  257. {
  258. dfs_lock();
  259. /* clear filesystem table entry */
  260. rt_memset(fs, 0, sizeof(struct dfs_filesystem));
  261. dfs_unlock();
  262. rt_set_errno(-DFS_STATUS_ENOSYS);
  263. return -1;
  264. }
  265. /* call mount of this filesystem */
  266. else if ( ops->mount(fs) < 0 )
  267. {
  268. /* mount failed */
  269. dfs_lock();
  270. /* close device */
  271. rt_device_close(fs->dev_id);
  272. /* clear filesystem table entry */
  273. rt_memset(fs, 0, sizeof(struct dfs_filesystem));
  274. dfs_unlock();
  275. return -1;
  276. }
  277. return 0;
  278. err1:
  279. dfs_unlock();
  280. return -1;
  281. }
  282. /*
  283. +------------------------------------------------------------------------------
  284. | Function : dfs_unmount
  285. +------------------------------------------------------------------------------
  286. | Description : unmount a filesystem
  287. |
  288. | Parameters :
  289. | Returns : the status of register
  290. | 0 , successful
  291. | -1, failed
  292. +------------------------------------------------------------------------------
  293. */
  294. int dfs_unmount(const char *specialfile)
  295. {
  296. char *fullpath;
  297. #ifdef DFS_USING_WORKDIR
  298. char full_path[DFS_PATH_MAX + 1];
  299. #endif
  300. struct dfs_filesystem* fs = RT_NULL;
  301. fullpath = (char*)specialfile;
  302. if ( fullpath[0] != '/')
  303. {
  304. #ifdef DFS_USING_WORKDIR
  305. /* build full path */
  306. fullpath = full_path;
  307. dfs_lock();
  308. build_fullpath(working_directory, specialfile, fullpath);
  309. dfs_unlock();
  310. #else
  311. rt_set_errno(-DFS_STATUS_ENOTDIR);
  312. return -1;
  313. #endif
  314. }
  315. /* lock filesystem */
  316. dfs_lock();
  317. fs = dfs_filesystem_lookup(fullpath);
  318. if (fs != RT_NULL && fs->ops->unmount != RT_NULL && fs->ops->unmount(fs) < 0)
  319. {
  320. goto err1;
  321. }
  322. /* close device, but do not check the status of device */
  323. rt_device_close(fs->dev_id);
  324. /* clear this filesystem table entry */
  325. rt_memset(fs, 0, sizeof(struct dfs_filesystem));
  326. dfs_unlock();
  327. return 0;
  328. err1:
  329. dfs_unlock();
  330. return -1;
  331. }