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 #include <linux/version.h>
20 #include <linux/module.h>
21 #include <linux/init.h>
23 #include "exfat_version.h"
24 #include "exfat_config.h"
25 #include "exfat_global.h"
26 #include "exfat_data.h"
27 #include "exfat_oal.h"
29 #include "exfat_part.h"
30 #include "exfat_nls.h"
31 #include "exfat_api.h"
32 #include "exfat_super.h"
35 extern FS_STRUCT_T fs_struct[];
37 extern struct semaphore z_sem;
43 for (i = 0; i < MAX_DRIVE; i++) {
44 fs_struct[i].mounted = FALSE;
45 fs_struct[i].sb = NULL;
46 sm_init(&(fs_struct[i].v_sem));
52 INT32 FsShutdown(void)
56 for (i = 0; i < MAX_DRIVE; i++) {
57 if (!fs_struct[i].mounted) continue;
59 ffsUmountVol(fs_struct[i].sb);
62 return(ffsShutdown());
65 INT32 FsMountVol(struct super_block *sb)
71 for (drv = 0; drv < MAX_DRIVE; drv++) {
72 if (!fs_struct[drv].mounted) break;
75 if (drv >= MAX_DRIVE) return(FFS_ERROR);
77 sm_P(&(fs_struct[drv].v_sem));
81 err = ffsMountVol(sb, drv);
84 sm_V(&(fs_struct[drv].v_sem));
87 fs_struct[drv].mounted = TRUE;
88 fs_struct[drv].sb = sb;
98 INT32 FsUmountVol(struct super_block *sb)
101 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
105 sm_P(&(fs_struct[p_fs->drv].v_sem));
107 err = ffsUmountVol(sb);
110 sm_V(&(fs_struct[p_fs->drv].v_sem));
112 fs_struct[p_fs->drv].mounted = FALSE;
113 fs_struct[p_fs->drv].sb = NULL;
120 INT32 FsGetVolInfo(struct super_block *sb, VOL_INFO_T *info)
123 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
125 if (info == NULL) return(FFS_ERROR);
127 sm_P(&(fs_struct[p_fs->drv].v_sem));
129 err = ffsGetVolInfo(sb, info);
131 sm_V(&(fs_struct[p_fs->drv].v_sem));
136 INT32 FsSyncVol(struct super_block *sb, INT32 do_sync)
139 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
141 sm_P(&(fs_struct[p_fs->drv].v_sem));
143 err = ffsSyncVol(sb, do_sync);
145 sm_V(&(fs_struct[p_fs->drv].v_sem));
150 INT32 FsLookupFile(struct inode *inode, UINT8 *path, FILE_ID_T *fid)
153 struct super_block *sb = inode->i_sb;
154 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
156 if ((fid == NULL) || (path == NULL) || (STRLEN(path) == 0))
159 sm_P(&(fs_struct[p_fs->drv].v_sem));
161 err = ffsLookupFile(inode, path, fid);
163 sm_V(&(fs_struct[p_fs->drv].v_sem));
168 INT32 FsCreateFile(struct inode *inode, UINT8 *path, UINT8 mode, FILE_ID_T *fid)
171 struct super_block *sb = inode->i_sb;
172 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
174 if ((fid == NULL) || (path == NULL) || (STRLEN(path) == 0))
177 sm_P(&(fs_struct[p_fs->drv].v_sem));
179 err = ffsCreateFile(inode, path, mode, fid);
181 sm_V(&(fs_struct[p_fs->drv].v_sem));
186 INT32 FsReadFile(struct inode *inode, FILE_ID_T *fid, void *buffer, UINT64 count, UINT64 *rcount)
189 struct super_block *sb = inode->i_sb;
190 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
192 if (fid == NULL) return(FFS_INVALIDFID);
194 if (buffer == NULL) return(FFS_ERROR);
196 sm_P(&(fs_struct[p_fs->drv].v_sem));
198 err = ffsReadFile(inode, fid, buffer, count, rcount);
200 sm_V(&(fs_struct[p_fs->drv].v_sem));
205 INT32 FsWriteFile(struct inode *inode, FILE_ID_T *fid, void *buffer, UINT64 count, UINT64 *wcount)
208 struct super_block *sb = inode->i_sb;
209 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
211 if (fid == NULL) return(FFS_INVALIDFID);
213 if (buffer == NULL) return(FFS_ERROR);
215 sm_P(&(fs_struct[p_fs->drv].v_sem));
217 err = ffsWriteFile(inode, fid, buffer, count, wcount);
219 sm_V(&(fs_struct[p_fs->drv].v_sem));
224 INT32 FsTruncateFile(struct inode *inode, UINT64 old_size, UINT64 new_size)
227 struct super_block *sb = inode->i_sb;
228 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
230 sm_P(&(fs_struct[p_fs->drv].v_sem));
232 PRINTK("FsTruncateFile entered (inode %p size %llu)\n", inode, new_size);
234 err = ffsTruncateFile(inode, old_size, new_size);
236 PRINTK("FsTruncateFile exitted (%d)\n", err);
238 sm_V(&(fs_struct[p_fs->drv].v_sem));
243 INT32 FsMoveFile(struct inode *old_parent_inode, FILE_ID_T *fid, struct inode *new_parent_inode, struct dentry *new_dentry)
246 struct super_block *sb = old_parent_inode->i_sb;
247 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
249 if (fid == NULL) return(FFS_INVALIDFID);
251 sm_P(&(fs_struct[p_fs->drv].v_sem));
253 err = ffsMoveFile(old_parent_inode, fid, new_parent_inode, new_dentry);
255 sm_V(&(fs_struct[p_fs->drv].v_sem));
260 INT32 FsRemoveFile(struct inode *inode, FILE_ID_T *fid)
263 struct super_block *sb = inode->i_sb;
264 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
266 if (fid == NULL) return(FFS_INVALIDFID);
268 sm_P(&(fs_struct[p_fs->drv].v_sem));
270 err = ffsRemoveFile(inode, fid);
272 sm_V(&(fs_struct[p_fs->drv].v_sem));
277 INT32 FsSetAttr(struct inode *inode, UINT32 attr)
280 struct super_block *sb = inode->i_sb;
281 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
283 sm_P(&(fs_struct[p_fs->drv].v_sem));
285 err = ffsSetAttr(inode, attr);
287 sm_V(&(fs_struct[p_fs->drv].v_sem));
292 INT32 FsReadStat(struct inode *inode, DIR_ENTRY_T *info)
295 struct super_block *sb = inode->i_sb;
296 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
298 sm_P(&(fs_struct[p_fs->drv].v_sem));
300 err = ffsGetStat(inode, info);
302 sm_V(&(fs_struct[p_fs->drv].v_sem));
307 INT32 FsWriteStat(struct inode *inode, DIR_ENTRY_T *info)
310 struct super_block *sb = inode->i_sb;
311 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
313 sm_P(&(fs_struct[p_fs->drv].v_sem));
315 PRINTK("FsWriteStat entered (inode %p info %p\n", inode, info);
317 err = ffsSetStat(inode, info);
319 sm_V(&(fs_struct[p_fs->drv].v_sem));
321 PRINTK("FsWriteStat exited (%d)\n", err);
326 INT32 FsMapCluster(struct inode *inode, INT32 clu_offset, UINT32 *clu)
329 struct super_block *sb = inode->i_sb;
330 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
332 if (clu == NULL) return(FFS_ERROR);
334 sm_P(&(fs_struct[p_fs->drv].v_sem));
336 err = ffsMapCluster(inode, clu_offset, clu);
338 sm_V(&(fs_struct[p_fs->drv].v_sem));
343 INT32 FsCreateDir(struct inode *inode, UINT8 *path, FILE_ID_T *fid)
346 struct super_block *sb = inode->i_sb;
347 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
349 if ((fid == NULL) || (path == NULL) || (STRLEN(path) == 0))
352 sm_P(&(fs_struct[p_fs->drv].v_sem));
354 err = ffsCreateDir(inode, path, fid);
356 sm_V(&(fs_struct[p_fs->drv].v_sem));
361 INT32 FsReadDir(struct inode *inode, DIR_ENTRY_T *dir_entry)
364 struct super_block *sb = inode->i_sb;
365 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
367 if (dir_entry == NULL) return(FFS_ERROR);
369 sm_P(&(fs_struct[p_fs->drv].v_sem));
371 err = ffsReadDir(inode, dir_entry);
373 sm_V(&(fs_struct[p_fs->drv].v_sem));
378 INT32 FsRemoveDir(struct inode *inode, FILE_ID_T *fid)
381 struct super_block *sb = inode->i_sb;
382 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
384 if (fid == NULL) return(FFS_INVALIDFID);
386 sm_P(&(fs_struct[p_fs->drv].v_sem));
388 err = ffsRemoveDir(inode, fid);
390 sm_V(&(fs_struct[p_fs->drv].v_sem));
395 INT32 FsRemoveEntry(struct inode *inode, FILE_ID_T *fid)
398 struct super_block *sb = inode->i_sb;
399 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
401 if (fid == NULL) return(FFS_INVALIDFID);
403 sm_P(&(fs_struct[p_fs->drv].v_sem));
405 err = ffsRemoveEntry(inode, fid);
407 sm_V(&(fs_struct[p_fs->drv].v_sem));
414 EXPORT_SYMBOL(FsMountVol);
415 EXPORT_SYMBOL(FsUmountVol);
416 EXPORT_SYMBOL(FsGetVolInfo);
417 EXPORT_SYMBOL(FsSyncVol);
418 EXPORT_SYMBOL(FsLookupFile);
419 EXPORT_SYMBOL(FsCreateFile);
420 EXPORT_SYMBOL(FsReadFile);
421 EXPORT_SYMBOL(FsWriteFile);
422 EXPORT_SYMBOL(FsTruncateFile);
423 EXPORT_SYMBOL(FsMoveFile);
424 EXPORT_SYMBOL(FsRemoveFile);
425 EXPORT_SYMBOL(FsSetAttr);
426 EXPORT_SYMBOL(FsReadStat);
427 EXPORT_SYMBOL(FsWriteStat);
428 EXPORT_SYMBOL(FsMapCluster);
429 EXPORT_SYMBOL(FsCreateDir);
430 EXPORT_SYMBOL(FsReadDir);
431 EXPORT_SYMBOL(FsRemoveDir);
432 EXPORT_SYMBOL(FsRemoveEntry);
434 #if EXFAT_CONFIG_KERNEL_DEBUG
435 INT32 FsReleaseCache(struct super_block *sb)
437 FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
439 sm_P(&(fs_struct[p_fs->drv].v_sem));
444 sm_V(&(fs_struct[p_fs->drv].v_sem));
449 EXPORT_SYMBOL(FsReleaseCache);
452 static int __init init_exfat_core(void)
456 printk(KERN_INFO "exFAT: Core Version %s\n", EXFAT_VERSION);
460 if (err == FFS_MEMORYERR)
469 static void __exit exit_exfat_core(void)
474 module_init(init_exfat_core);
475 module_exit(exit_exfat_core);
477 MODULE_LICENSE("GPL");