exfat_api.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. /*
  2. * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation; either version 2
  7. * of the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  17. */
  18. #include <linux/version.h>
  19. #include <linux/module.h>
  20. #include <linux/init.h>
  21. #include "exfat_version.h"
  22. #include "exfat_config.h"
  23. #include "exfat_global.h"
  24. #include "exfat_data.h"
  25. #include "exfat_oal.h"
  26. #include "exfat_part.h"
  27. #include "exfat_nls.h"
  28. #include "exfat_api.h"
  29. #include "exfat_super.h"
  30. #include "exfat.h"
  31. extern FS_STRUCT_T fs_struct[];
  32. extern struct semaphore z_sem;
  33. INT32 FsInit(void)
  34. {
  35. INT32 i;
  36. for (i = 0; i < MAX_DRIVE; i++) {
  37. fs_struct[i].mounted = FALSE;
  38. fs_struct[i].sb = NULL;
  39. sm_init(&(fs_struct[i].v_sem));
  40. }
  41. return(ffsInit());
  42. }
  43. INT32 FsShutdown(void)
  44. {
  45. INT32 i;
  46. for (i = 0; i < MAX_DRIVE; i++) {
  47. if (!fs_struct[i].mounted) continue;
  48. ffsUmountVol(fs_struct[i].sb);
  49. }
  50. return(ffsShutdown());
  51. }
  52. INT32 FsMountVol(struct super_block *sb)
  53. {
  54. INT32 err, drv;
  55. sm_P(&z_sem);
  56. for (drv = 0; drv < MAX_DRIVE; drv++) {
  57. if (!fs_struct[drv].mounted) break;
  58. }
  59. if (drv >= MAX_DRIVE) {
  60. err = FFS_ERROR;
  61. goto ret_unlock;
  62. }
  63. sm_P(&(fs_struct[drv].v_sem));
  64. err = buf_init(sb);
  65. if (!err) {
  66. err = ffsMountVol(sb, drv);
  67. }
  68. sm_V(&(fs_struct[drv].v_sem));
  69. if (!err) {
  70. fs_struct[drv].mounted = TRUE;
  71. fs_struct[drv].sb = sb;
  72. } else {
  73. buf_shutdown(sb);
  74. }
  75. ret_unlock:
  76. sm_V(&z_sem);
  77. return(err);
  78. }
  79. INT32 FsUmountVol(struct super_block *sb)
  80. {
  81. INT32 err;
  82. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  83. sm_P(&z_sem);
  84. sm_P(&(fs_struct[p_fs->drv].v_sem));
  85. err = ffsUmountVol(sb);
  86. buf_shutdown(sb);
  87. sm_V(&(fs_struct[p_fs->drv].v_sem));
  88. fs_struct[p_fs->drv].mounted = FALSE;
  89. fs_struct[p_fs->drv].sb = NULL;
  90. sm_V(&z_sem);
  91. return(err);
  92. }
  93. INT32 FsGetVolInfo(struct super_block *sb, VOL_INFO_T *info)
  94. {
  95. INT32 err;
  96. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  97. if (info == NULL) return(FFS_ERROR);
  98. sm_P(&(fs_struct[p_fs->drv].v_sem));
  99. err = ffsGetVolInfo(sb, info);
  100. sm_V(&(fs_struct[p_fs->drv].v_sem));
  101. return(err);
  102. }
  103. INT32 FsSyncVol(struct super_block *sb, INT32 do_sync)
  104. {
  105. INT32 err;
  106. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  107. sm_P(&(fs_struct[p_fs->drv].v_sem));
  108. err = ffsSyncVol(sb, do_sync);
  109. sm_V(&(fs_struct[p_fs->drv].v_sem));
  110. return(err);
  111. }
  112. INT32 FsLookupFile(struct inode *inode, UINT8 *path, FILE_ID_T *fid)
  113. {
  114. INT32 err;
  115. struct super_block *sb = inode->i_sb;
  116. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  117. if ((fid == NULL) || (path == NULL) || (STRLEN(path) == 0))
  118. return(FFS_ERROR);
  119. sm_P(&(fs_struct[p_fs->drv].v_sem));
  120. err = ffsLookupFile(inode, path, fid);
  121. sm_V(&(fs_struct[p_fs->drv].v_sem));
  122. return(err);
  123. }
  124. INT32 FsCreateFile(struct inode *inode, UINT8 *path, UINT8 mode, FILE_ID_T *fid)
  125. {
  126. INT32 err;
  127. struct super_block *sb = inode->i_sb;
  128. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  129. if ((fid == NULL) || (path == NULL) || (STRLEN(path) == 0))
  130. return(FFS_ERROR);
  131. sm_P(&(fs_struct[p_fs->drv].v_sem));
  132. err = ffsCreateFile(inode, path, mode, fid);
  133. sm_V(&(fs_struct[p_fs->drv].v_sem));
  134. return(err);
  135. }
  136. INT32 FsReadFile(struct inode *inode, FILE_ID_T *fid, void *buffer, UINT64 count, UINT64 *rcount)
  137. {
  138. INT32 err;
  139. struct super_block *sb = inode->i_sb;
  140. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  141. if (fid == NULL) return(FFS_INVALIDFID);
  142. if (buffer == NULL) return(FFS_ERROR);
  143. sm_P(&(fs_struct[p_fs->drv].v_sem));
  144. err = ffsReadFile(inode, fid, buffer, count, rcount);
  145. sm_V(&(fs_struct[p_fs->drv].v_sem));
  146. return(err);
  147. }
  148. INT32 FsWriteFile(struct inode *inode, FILE_ID_T *fid, void *buffer, UINT64 count, UINT64 *wcount)
  149. {
  150. INT32 err;
  151. struct super_block *sb = inode->i_sb;
  152. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  153. if (fid == NULL) return(FFS_INVALIDFID);
  154. if (buffer == NULL) return(FFS_ERROR);
  155. sm_P(&(fs_struct[p_fs->drv].v_sem));
  156. err = ffsWriteFile(inode, fid, buffer, count, wcount);
  157. sm_V(&(fs_struct[p_fs->drv].v_sem));
  158. return(err);
  159. }
  160. INT32 FsTruncateFile(struct inode *inode, UINT64 old_size, UINT64 new_size)
  161. {
  162. INT32 err;
  163. struct super_block *sb = inode->i_sb;
  164. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  165. sm_P(&(fs_struct[p_fs->drv].v_sem));
  166. PRINTK("FsTruncateFile entered (inode %p size %llu)\n", inode, new_size);
  167. err = ffsTruncateFile(inode, old_size, new_size);
  168. PRINTK("FsTruncateFile exitted (%d)\n", err);
  169. sm_V(&(fs_struct[p_fs->drv].v_sem));
  170. return(err);
  171. }
  172. INT32 FsMoveFile(struct inode *old_parent_inode, FILE_ID_T *fid, struct inode *new_parent_inode, struct dentry *new_dentry)
  173. {
  174. INT32 err;
  175. struct super_block *sb = old_parent_inode->i_sb;
  176. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  177. if (fid == NULL) return(FFS_INVALIDFID);
  178. sm_P(&(fs_struct[p_fs->drv].v_sem));
  179. err = ffsMoveFile(old_parent_inode, fid, new_parent_inode, new_dentry);
  180. sm_V(&(fs_struct[p_fs->drv].v_sem));
  181. return(err);
  182. }
  183. INT32 FsRemoveFile(struct inode *inode, FILE_ID_T *fid)
  184. {
  185. INT32 err;
  186. struct super_block *sb = inode->i_sb;
  187. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  188. if (fid == NULL) return(FFS_INVALIDFID);
  189. sm_P(&(fs_struct[p_fs->drv].v_sem));
  190. err = ffsRemoveFile(inode, fid);
  191. sm_V(&(fs_struct[p_fs->drv].v_sem));
  192. return(err);
  193. }
  194. INT32 FsSetAttr(struct inode *inode, UINT32 attr)
  195. {
  196. INT32 err;
  197. struct super_block *sb = inode->i_sb;
  198. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  199. sm_P(&(fs_struct[p_fs->drv].v_sem));
  200. err = ffsSetAttr(inode, attr);
  201. sm_V(&(fs_struct[p_fs->drv].v_sem));
  202. return(err);
  203. }
  204. INT32 FsReadStat(struct inode *inode, DIR_ENTRY_T *info)
  205. {
  206. INT32 err;
  207. struct super_block *sb = inode->i_sb;
  208. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  209. sm_P(&(fs_struct[p_fs->drv].v_sem));
  210. err = ffsGetStat(inode, info);
  211. sm_V(&(fs_struct[p_fs->drv].v_sem));
  212. return(err);
  213. }
  214. INT32 FsWriteStat(struct inode *inode, DIR_ENTRY_T *info)
  215. {
  216. INT32 err;
  217. struct super_block *sb = inode->i_sb;
  218. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  219. sm_P(&(fs_struct[p_fs->drv].v_sem));
  220. PRINTK("FsWriteStat entered (inode %p info %p\n", inode, info);
  221. err = ffsSetStat(inode, info);
  222. sm_V(&(fs_struct[p_fs->drv].v_sem));
  223. PRINTK("FsWriteStat exited (%d)\n", err);
  224. return(err);
  225. }
  226. INT32 FsMapCluster(struct inode *inode, INT32 clu_offset, UINT32 *clu)
  227. {
  228. INT32 err;
  229. struct super_block *sb = inode->i_sb;
  230. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  231. if (clu == NULL) return(FFS_ERROR);
  232. sm_P(&(fs_struct[p_fs->drv].v_sem));
  233. err = ffsMapCluster(inode, clu_offset, clu);
  234. sm_V(&(fs_struct[p_fs->drv].v_sem));
  235. return(err);
  236. }
  237. INT32 FsCreateDir(struct inode *inode, UINT8 *path, FILE_ID_T *fid)
  238. {
  239. INT32 err;
  240. struct super_block *sb = inode->i_sb;
  241. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  242. if ((fid == NULL) || (path == NULL) || (STRLEN(path) == 0))
  243. return(FFS_ERROR);
  244. sm_P(&(fs_struct[p_fs->drv].v_sem));
  245. err = ffsCreateDir(inode, path, fid);
  246. sm_V(&(fs_struct[p_fs->drv].v_sem));
  247. return(err);
  248. }
  249. INT32 FsReadDir(struct inode *inode, DIR_ENTRY_T *dir_entry)
  250. {
  251. INT32 err;
  252. struct super_block *sb = inode->i_sb;
  253. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  254. if (dir_entry == NULL) return(FFS_ERROR);
  255. sm_P(&(fs_struct[p_fs->drv].v_sem));
  256. err = ffsReadDir(inode, dir_entry);
  257. sm_V(&(fs_struct[p_fs->drv].v_sem));
  258. return(err);
  259. }
  260. INT32 FsRemoveDir(struct inode *inode, FILE_ID_T *fid)
  261. {
  262. INT32 err;
  263. struct super_block *sb = inode->i_sb;
  264. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  265. if (fid == NULL) return(FFS_INVALIDFID);
  266. sm_P(&(fs_struct[p_fs->drv].v_sem));
  267. err = ffsRemoveDir(inode, fid);
  268. sm_V(&(fs_struct[p_fs->drv].v_sem));
  269. return(err);
  270. }
  271. INT32 FsRemoveEntry(struct inode *inode, FILE_ID_T *fid)
  272. {
  273. INT32 err;
  274. struct super_block *sb = inode->i_sb;
  275. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  276. if (fid == NULL) return(FFS_INVALIDFID);
  277. sm_P(&(fs_struct[p_fs->drv].v_sem));
  278. err = ffsRemoveEntry(inode, fid);
  279. sm_V(&(fs_struct[p_fs->drv].v_sem));
  280. return(err);
  281. }
  282. EXPORT_SYMBOL(FsMountVol);
  283. EXPORT_SYMBOL(FsUmountVol);
  284. EXPORT_SYMBOL(FsGetVolInfo);
  285. EXPORT_SYMBOL(FsSyncVol);
  286. EXPORT_SYMBOL(FsLookupFile);
  287. EXPORT_SYMBOL(FsCreateFile);
  288. EXPORT_SYMBOL(FsReadFile);
  289. EXPORT_SYMBOL(FsWriteFile);
  290. EXPORT_SYMBOL(FsTruncateFile);
  291. EXPORT_SYMBOL(FsMoveFile);
  292. EXPORT_SYMBOL(FsRemoveFile);
  293. EXPORT_SYMBOL(FsSetAttr);
  294. EXPORT_SYMBOL(FsReadStat);
  295. EXPORT_SYMBOL(FsWriteStat);
  296. EXPORT_SYMBOL(FsMapCluster);
  297. EXPORT_SYMBOL(FsCreateDir);
  298. EXPORT_SYMBOL(FsReadDir);
  299. EXPORT_SYMBOL(FsRemoveDir);
  300. EXPORT_SYMBOL(FsRemoveEntry);
  301. #if EXFAT_CONFIG_KERNEL_DEBUG
  302. INT32 FsReleaseCache(struct super_block *sb)
  303. {
  304. FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
  305. sm_P(&(fs_struct[p_fs->drv].v_sem));
  306. FAT_release_all(sb);
  307. buf_release_all(sb);
  308. sm_V(&(fs_struct[p_fs->drv].v_sem));
  309. return 0;
  310. }
  311. EXPORT_SYMBOL(FsReleaseCache);
  312. #endif
  313. static int __init init_exfat_core(void)
  314. {
  315. int err;
  316. printk(KERN_INFO "exFAT: Core Version %s\n", EXFAT_VERSION);
  317. err = FsInit();
  318. if (err) {
  319. if (err == FFS_MEMORYERR)
  320. return -ENOMEM;
  321. else
  322. return -EIO;
  323. }
  324. return 0;
  325. }
  326. static void __exit exit_exfat_core(void)
  327. {
  328. FsShutdown();
  329. }
  330. module_init(init_exfat_core);
  331. module_exit(exit_exfat_core);
  332. MODULE_LICENSE("GPL");