CD exfat support for Tomato. https://github.com/dorimanx/exfat-nofuse.
[tomato.git] / release / src-rt / linux / linux-2.6 / fs / exfat / exfat_api.c
blob5423181260b75cc7ae3377d48c691e5a2a4e01d7
1 /*
2 * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
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.
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.
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.
19 /************************************************************************/
20 /* */
21 /* PROJECT : exFAT & FAT12/16/32 File System */
22 /* FILE : exfat_api.c */
23 /* PURPOSE : exFAT API Glue Layer */
24 /* */
25 /*----------------------------------------------------------------------*/
26 /* NOTES */
27 /* */
28 /*----------------------------------------------------------------------*/
29 /* REVISION HISTORY (Ver 0.9) */
30 /* */
31 /* - 2010.11.15 [Joosun Hahn] : first writing */
32 /* */
33 /************************************************************************/
35 #include <linux/version.h>
36 #include <linux/module.h>
37 #include <linux/init.h>
39 #include "exfat_version.h"
40 #include "exfat_config.h"
41 #include "exfat_global.h"
42 #include "exfat_data.h"
43 #include "exfat_oal.h"
45 #include "exfat_part.h"
46 #include "exfat_nls.h"
47 #include "exfat_api.h"
48 #include "exfat_super.h"
49 #include "exfat.h"
51 /*----------------------------------------------------------------------*/
52 /* Constant & Macro Definitions */
53 /*----------------------------------------------------------------------*/
55 /*----------------------------------------------------------------------*/
56 /* Global Variable Definitions */
57 /*----------------------------------------------------------------------*/
59 extern FS_STRUCT_T fs_struct[];
61 extern struct semaphore z_sem;
63 /*----------------------------------------------------------------------*/
64 /* Local Variable Definitions */
65 /*----------------------------------------------------------------------*/
67 /*----------------------------------------------------------------------*/
68 /* Local Function Declarations */
69 /*----------------------------------------------------------------------*/
71 /*======================================================================*/
72 /* Global Function Definitions */
73 /* - All functions for global use have same return value format, */
74 /* that is, FFS_SUCCESS on success and several FS error code on */
75 /* various error condition. */
76 /*======================================================================*/
78 /*----------------------------------------------------------------------*/
79 /* exFAT Filesystem Init & Exit Functions */
80 /*----------------------------------------------------------------------*/
82 INT32 FsInit(void)
84 INT32 i;
86 /* initialize all volumes as un-mounted */
87 for (i = 0; i < MAX_DRIVE; i++) {
88 fs_struct[i].mounted = FALSE;
89 fs_struct[i].sb = NULL;
90 sm_init(&(fs_struct[i].v_sem));
93 return(ffsInit());
96 INT32 FsShutdown(void)
98 INT32 i;
100 /* unmount all volumes */
101 for (i = 0; i < MAX_DRIVE; i++) {
102 if (!fs_struct[i].mounted) continue;
104 ffsUmountVol(fs_struct[i].sb);
107 return(ffsShutdown());
110 /*----------------------------------------------------------------------*/
111 /* Volume Management Functions */
112 /*----------------------------------------------------------------------*/
114 /* FsMountVol : mount the file system volume */
115 INT32 FsMountVol(struct super_block *sb)
117 INT32 err, drv;
119 sm_P(&z_sem);
121 for (drv = 0; drv < MAX_DRIVE; drv++) {
122 if (!fs_struct[drv].mounted) break;
125 if (drv >= MAX_DRIVE) return(FFS_ERROR);
127 /* acquire the lock for file system critical section */
128 sm_P(&(fs_struct[drv].v_sem));
130 err = buf_init(sb);
131 if (!err) {
132 err = ffsMountVol(sb, drv);
135 /* release the lock for file system critical section */
136 sm_V(&(fs_struct[drv].v_sem));
138 if (!err) {
139 fs_struct[drv].mounted = TRUE;
140 fs_struct[drv].sb = sb;
141 } else {
142 buf_shutdown(sb);
145 sm_V(&z_sem);
147 return(err);
148 } /* end of FsMountVol */
150 /* FsUmountVol : unmount the file system volume */
151 INT32 FsUmountVol(struct super_block *sb)
153 INT32 err;
154 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
156 sm_P(&z_sem);
158 /* acquire the lock for file system critical section */
159 sm_P(&(fs_struct[p_fs->drv].v_sem));
161 err = ffsUmountVol(sb);
162 buf_shutdown(sb);
164 /* release the lock for file system critical section */
165 sm_V(&(fs_struct[p_fs->drv].v_sem));
167 fs_struct[p_fs->drv].mounted = FALSE;
168 fs_struct[p_fs->drv].sb = NULL;
170 sm_V(&z_sem);
172 return(err);
173 } /* end of FsUmountVol */
175 /* FsGetVolInfo : get the information of a file system volume */
176 INT32 FsGetVolInfo(struct super_block *sb, VOL_INFO_T *info)
178 INT32 err;
179 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
181 /* check the validity of pointer parameters */
182 if (info == NULL) return(FFS_ERROR);
184 /* acquire the lock for file system critical section */
185 sm_P(&(fs_struct[p_fs->drv].v_sem));
187 err = ffsGetVolInfo(sb, info);
189 /* release the lock for file system critical section */
190 sm_V(&(fs_struct[p_fs->drv].v_sem));
192 return(err);
193 } /* end of FsGetVolInfo */
195 /* FsSyncVol : synchronize a file system volume */
196 INT32 FsSyncVol(struct super_block *sb, INT32 do_sync)
198 INT32 err;
199 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
201 /* acquire the lock for file system critical section */
202 sm_P(&(fs_struct[p_fs->drv].v_sem));
204 err = ffsSyncVol(sb, do_sync);
206 /* release the lock for file system critical section */
207 sm_V(&(fs_struct[p_fs->drv].v_sem));
209 return(err);
210 } /* end of FsSyncVol */
213 /*----------------------------------------------------------------------*/
214 /* File Operation Functions */
215 /*----------------------------------------------------------------------*/
217 /* FsCreateFile : create a file */
218 INT32 FsLookupFile(struct inode *inode, UINT8 *path, FILE_ID_T *fid)
220 INT32 err;
221 struct super_block *sb = inode->i_sb;
222 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
224 /* check the validity of pointer parameters */
225 if ((fid == NULL) || (path == NULL) || (*path == '\0'))
226 return(FFS_ERROR);
228 /* acquire the lock for file system critical section */
229 sm_P(&(fs_struct[p_fs->drv].v_sem));
231 err = ffsLookupFile(inode, path, fid);
233 /* release the lock for file system critical section */
234 sm_V(&(fs_struct[p_fs->drv].v_sem));
236 return(err);
237 } /* end of FsLookupFile */
239 /* FsCreateFile : create a file */
240 INT32 FsCreateFile(struct inode *inode, UINT8 *path, UINT8 mode, FILE_ID_T *fid)
242 INT32 err;
243 struct super_block *sb = inode->i_sb;
244 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
246 /* check the validity of pointer parameters */
247 if ((fid == NULL) || (path == NULL) || (*path == '\0'))
248 return(FFS_ERROR);
250 /* acquire the lock for file system critical section */
251 sm_P(&(fs_struct[p_fs->drv].v_sem));
253 err = ffsCreateFile(inode, path, mode, fid);
255 /* release the lock for file system critical section */
256 sm_V(&(fs_struct[p_fs->drv].v_sem));
258 return(err);
259 } /* end of FsCreateFile */
261 INT32 FsReadFile(struct inode *inode, FILE_ID_T *fid, void *buffer, UINT64 count, UINT64 *rcount)
263 INT32 err;
264 struct super_block *sb = inode->i_sb;
265 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
267 /* check the validity of the given file id */
268 if (fid == NULL) return(FFS_INVALIDFID);
270 /* check the validity of pointer parameters */
271 if (buffer == NULL) return(FFS_ERROR);
273 /* acquire the lock for file system critical section */
274 sm_P(&(fs_struct[p_fs->drv].v_sem));
276 err = ffsReadFile(inode, fid, buffer, count, rcount);
278 /* release the lock for file system critical section */
279 sm_V(&(fs_struct[p_fs->drv].v_sem));
281 return(err);
282 } /* end of FsReadFile */
284 INT32 FsWriteFile(struct inode *inode, FILE_ID_T *fid, void *buffer, UINT64 count, UINT64 *wcount)
286 INT32 err;
287 struct super_block *sb = inode->i_sb;
288 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
290 /* check the validity of the given file id */
291 if (fid == NULL) return(FFS_INVALIDFID);
293 /* check the validity of pointer parameters */
294 if (buffer == NULL) return(FFS_ERROR);
296 /* acquire the lock for file system critical section */
297 sm_P(&(fs_struct[p_fs->drv].v_sem));
299 err = ffsWriteFile(inode, fid, buffer, count, wcount);
301 /* release the lock for file system critical section */
302 sm_V(&(fs_struct[p_fs->drv].v_sem));
304 return(err);
305 } /* end of FsWriteFile */
307 /* FsTruncateFile : resize the file length */
308 INT32 FsTruncateFile(struct inode *inode, UINT64 old_size, UINT64 new_size)
310 INT32 err;
311 struct super_block *sb = inode->i_sb;
312 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
314 /* acquire the lock for file system critical section */
315 sm_P(&(fs_struct[p_fs->drv].v_sem));
317 PRINTK("FsTruncateFile entered (inode %p size %llu)\n", inode, new_size);
319 err = ffsTruncateFile(inode, old_size, new_size);
321 PRINTK("FsTruncateFile exitted (%d)\n", err);
323 /* release the lock for file system critical section */
324 sm_V(&(fs_struct[p_fs->drv].v_sem));
326 return(err);
327 } /* end of FsTruncateFile */
329 /* FsMoveFile : move(rename) a old file into a new file */
330 INT32 FsMoveFile(struct inode *old_parent_inode, FILE_ID_T *fid, struct inode *new_parent_inode, struct dentry *new_dentry)
332 INT32 err;
333 struct super_block *sb = old_parent_inode->i_sb;
334 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
336 /* check the validity of the given file id */
337 if (fid == NULL) return(FFS_INVALIDFID);
339 /* acquire the lock for file system critical section */
340 sm_P(&(fs_struct[p_fs->drv].v_sem));
342 err = ffsMoveFile(old_parent_inode, fid, new_parent_inode, new_dentry);
344 /* release the lock for file system critical section */
345 sm_V(&(fs_struct[p_fs->drv].v_sem));
347 return(err);
348 } /* end of FsMoveFile */
350 /* FsRemoveFile : remove a file */
351 INT32 FsRemoveFile(struct inode *inode, FILE_ID_T *fid)
353 INT32 err;
354 struct super_block *sb = inode->i_sb;
355 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
357 /* check the validity of the given file id */
358 if (fid == NULL) return(FFS_INVALIDFID);
360 /* acquire the lock for file system critical section */
361 sm_P(&(fs_struct[p_fs->drv].v_sem));
363 err = ffsRemoveFile(inode, fid);
365 /* release the lock for file system critical section */
366 sm_V(&(fs_struct[p_fs->drv].v_sem));
368 return(err);
369 } /* end of FsRemoveFile */
371 /* FsSetAttr : set the attribute of a given file */
372 INT32 FsSetAttr(struct inode *inode, UINT32 attr)
374 INT32 err;
375 struct super_block *sb = inode->i_sb;
376 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
378 /* acquire the lock for file system critical section */
379 sm_P(&(fs_struct[p_fs->drv].v_sem));
381 err = ffsSetAttr(inode, attr);
383 /* release the lock for file system critical section */
384 sm_V(&(fs_struct[p_fs->drv].v_sem));
386 return(err);
387 } /* end of FsSetAttr */
389 /* FsReadStat : get the information of a given file */
390 INT32 FsReadStat(struct inode *inode, DIR_ENTRY_T *info)
392 INT32 err;
393 struct super_block *sb = inode->i_sb;
394 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
396 /* acquire the lock for file system critical section */
397 sm_P(&(fs_struct[p_fs->drv].v_sem));
399 err = ffsGetStat(inode, info);
401 /* release the lock for file system critical section */
402 sm_V(&(fs_struct[p_fs->drv].v_sem));
404 return(err);
405 } /* end of FsReadStat */
407 /* FsWriteStat : set the information of a given file */
408 INT32 FsWriteStat(struct inode *inode, DIR_ENTRY_T *info)
410 INT32 err;
411 struct super_block *sb = inode->i_sb;
412 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
414 /* acquire the lock for file system critical section */
415 sm_P(&(fs_struct[p_fs->drv].v_sem));
417 PRINTK("FsWriteStat entered (inode %p info %p\n", inode, info);
419 err = ffsSetStat(inode, info);
421 /* release the lock for file system critical section */
422 sm_V(&(fs_struct[p_fs->drv].v_sem));
424 PRINTK("FsWriteStat exited (%d)\n", err);
426 return(err);
427 } /* end of FsWriteStat */
429 /* FsMapCluster : return the cluster number in the given cluster offset */
430 INT32 FsMapCluster(struct inode *inode, INT32 clu_offset, UINT32 *clu)
432 INT32 err;
433 struct super_block *sb = inode->i_sb;
434 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
436 /* check the validity of pointer parameters */
437 if (clu == NULL) return(FFS_ERROR);
439 /* acquire the lock for file system critical section */
440 sm_P(&(fs_struct[p_fs->drv].v_sem));
442 err = ffsMapCluster(inode, clu_offset, clu);
444 /* release the lock for file system critical section */
445 sm_V(&(fs_struct[p_fs->drv].v_sem));
447 return(err);
448 } /* end of FsMapCluster */
450 /*----------------------------------------------------------------------*/
451 /* Directory Operation Functions */
452 /*----------------------------------------------------------------------*/
454 /* FsCreateDir : create(make) a directory */
455 INT32 FsCreateDir(struct inode *inode, UINT8 *path, FILE_ID_T *fid)
457 INT32 err;
458 struct super_block *sb = inode->i_sb;
459 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
461 /* check the validity of pointer parameters */
462 if ((fid == NULL) || (path == NULL) || (*path == '\0'))
463 return(FFS_ERROR);
465 /* acquire the lock for file system critical section */
466 sm_P(&(fs_struct[p_fs->drv].v_sem));
468 err = ffsCreateDir(inode, path, fid);
470 /* release the lock for file system critical section */
471 sm_V(&(fs_struct[p_fs->drv].v_sem));
473 return(err);
474 } /* end of FsCreateDir */
476 /* FsReadDir : read a directory entry from the opened directory */
477 INT32 FsReadDir(struct inode *inode, DIR_ENTRY_T *dir_entry)
479 INT32 err;
480 struct super_block *sb = inode->i_sb;
481 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
483 /* check the validity of pointer parameters */
484 if (dir_entry == NULL) return(FFS_ERROR);
486 /* acquire the lock for file system critical section */
487 sm_P(&(fs_struct[p_fs->drv].v_sem));
489 err = ffsReadDir(inode, dir_entry);
491 /* release the lock for file system critical section */
492 sm_V(&(fs_struct[p_fs->drv].v_sem));
494 return(err);
495 } /* end of FsReadDir */
497 /* FsRemoveDir : remove a directory */
498 INT32 FsRemoveDir(struct inode *inode, FILE_ID_T *fid)
500 INT32 err;
501 struct super_block *sb = inode->i_sb;
502 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
504 /* check the validity of the given file id */
505 if (fid == NULL) return(FFS_INVALIDFID);
507 /* acquire the lock for file system critical section */
508 sm_P(&(fs_struct[p_fs->drv].v_sem));
510 err = ffsRemoveDir(inode, fid);
512 /* release the lock for file system critical section */
513 sm_V(&(fs_struct[p_fs->drv].v_sem));
515 return(err);
516 } /* end of FsRemoveDir */
518 EXPORT_SYMBOL(FsMountVol);
519 EXPORT_SYMBOL(FsUmountVol);
520 EXPORT_SYMBOL(FsGetVolInfo);
521 EXPORT_SYMBOL(FsSyncVol);
522 EXPORT_SYMBOL(FsLookupFile);
523 EXPORT_SYMBOL(FsCreateFile);
524 EXPORT_SYMBOL(FsReadFile);
525 EXPORT_SYMBOL(FsWriteFile);
526 EXPORT_SYMBOL(FsTruncateFile);
527 EXPORT_SYMBOL(FsMoveFile);
528 EXPORT_SYMBOL(FsRemoveFile);
529 EXPORT_SYMBOL(FsSetAttr);
530 EXPORT_SYMBOL(FsReadStat);
531 EXPORT_SYMBOL(FsWriteStat);
532 EXPORT_SYMBOL(FsMapCluster);
533 EXPORT_SYMBOL(FsCreateDir);
534 EXPORT_SYMBOL(FsReadDir);
535 EXPORT_SYMBOL(FsRemoveDir);
537 #if EXFAT_CONFIG_KERNEL_DEBUG
538 /* FsReleaseCache: Release FAT & buf cache */
539 INT32 FsReleaseCache(struct super_block *sb)
541 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
543 /* acquire the lock for file system critical section */
544 sm_P(&(fs_struct[p_fs->drv].v_sem));
546 FAT_release_all(sb);
547 buf_release_all(sb);
549 /* release the lock for file system critical section */
550 sm_V(&(fs_struct[p_fs->drv].v_sem));
552 return 0;
554 /* FsReleaseCache */
556 EXPORT_SYMBOL(FsReleaseCache);
557 #endif /* EXFAT_CONFIG_KERNEL_DEBUG */
559 /*======================================================================*/
560 /* Local Function Definitions */
561 /*======================================================================*/
563 /* end of exfat_api.c */