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 /************************************************************************/
21 /* PROJECT : exFAT & FAT12/16/32 File System */
22 /* FILE : exfat_api.c */
23 /* PURPOSE : exFAT API Glue Layer */
25 /*----------------------------------------------------------------------*/
28 /*----------------------------------------------------------------------*/
29 /* REVISION HISTORY (Ver 0.9) */
31 /* - 2010.11.15 [Joosun Hahn] : first writing */
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"
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 /*----------------------------------------------------------------------*/
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
));
96 INT32
FsShutdown(void)
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
)
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
));
132 err
= ffsMountVol(sb
, drv
);
135 /* release the lock for file system critical section */
136 sm_V(&(fs_struct
[drv
].v_sem
));
139 fs_struct
[drv
].mounted
= TRUE
;
140 fs_struct
[drv
].sb
= sb
;
148 } /* end of FsMountVol */
150 /* FsUmountVol : unmount the file system volume */
151 INT32
FsUmountVol(struct super_block
*sb
)
154 FS_INFO_T
*p_fs
= &(EXFAT_SB(sb
)->fs_info
);
158 /* acquire the lock for file system critical section */
159 sm_P(&(fs_struct
[p_fs
->drv
].v_sem
));
161 err
= ffsUmountVol(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
;
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
)
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
));
193 } /* end of FsGetVolInfo */
195 /* FsSyncVol : synchronize a file system volume */
196 INT32
FsSyncVol(struct super_block
*sb
, INT32 do_sync
)
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
));
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
)
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'))
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
));
237 } /* end of FsLookupFile */
239 /* FsCreateFile : create a file */
240 INT32
FsCreateFile(struct inode
*inode
, UINT8
*path
, UINT8 mode
, FILE_ID_T
*fid
)
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'))
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
));
259 } /* end of FsCreateFile */
261 INT32
FsReadFile(struct inode
*inode
, FILE_ID_T
*fid
, void *buffer
, UINT64 count
, UINT64
*rcount
)
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
));
282 } /* end of FsReadFile */
284 INT32
FsWriteFile(struct inode
*inode
, FILE_ID_T
*fid
, void *buffer
, UINT64 count
, UINT64
*wcount
)
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
));
305 } /* end of FsWriteFile */
307 /* FsTruncateFile : resize the file length */
308 INT32
FsTruncateFile(struct inode
*inode
, UINT64 old_size
, UINT64 new_size
)
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
));
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
)
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
));
348 } /* end of FsMoveFile */
350 /* FsRemoveFile : remove a file */
351 INT32
FsRemoveFile(struct inode
*inode
, FILE_ID_T
*fid
)
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
));
369 } /* end of FsRemoveFile */
371 /* FsSetAttr : set the attribute of a given file */
372 INT32
FsSetAttr(struct inode
*inode
, UINT32 attr
)
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
));
387 } /* end of FsSetAttr */
389 /* FsReadStat : get the information of a given file */
390 INT32
FsReadStat(struct inode
*inode
, DIR_ENTRY_T
*info
)
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
));
405 } /* end of FsReadStat */
407 /* FsWriteStat : set the information of a given file */
408 INT32
FsWriteStat(struct inode
*inode
, DIR_ENTRY_T
*info
)
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
);
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
)
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
));
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
)
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'))
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
));
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
)
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
));
495 } /* end of FsReadDir */
497 /* FsRemoveDir : remove a directory */
498 INT32
FsRemoveDir(struct inode
*inode
, FILE_ID_T
*fid
)
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
));
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
));
549 /* release the lock for file system critical section */
550 sm_V(&(fs_struct
[p_fs
->drv
].v_sem
));
556 EXPORT_SYMBOL(FsReleaseCache
);
557 #endif /* EXFAT_CONFIG_KERNEL_DEBUG */
559 /*======================================================================*/
560 /* Local Function Definitions */
561 /*======================================================================*/
563 /* end of exfat_api.c */