summaryrefslogtreecommitdiff
path: root/fs/exfat/exfat_api.c
diff options
context:
space:
mode:
authorAndré Fabian Silva Delgado <emulatorman@parabola.nu>2015-12-26 16:00:37 -0300
committerAndré Fabian Silva Delgado <emulatorman@parabola.nu>2015-12-26 16:00:37 -0300
commit35acfa0fc609f2a2cd95cef4a6a9c3a5c38f1778 (patch)
tree281fc9db2a40c54ee94dc88fc2bf8c119cfafc15 /fs/exfat/exfat_api.c
parentf3a16ba6a1152b8966dcadc668af4cf00623c7b1 (diff)
Add support for the exFAT file system, fix hangs on older intel hardware and update AUFSpck-4.3.3-gnu
Diffstat (limited to 'fs/exfat/exfat_api.c')
-rw-r--r--fs/exfat/exfat_api.c528
1 files changed, 528 insertions, 0 deletions
diff --git a/fs/exfat/exfat_api.c b/fs/exfat/exfat_api.c
new file mode 100644
index 000000000..32b29f0dd
--- /dev/null
+++ b/fs/exfat/exfat_api.c
@@ -0,0 +1,528 @@
+/*
+ * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/************************************************************************/
+/* */
+/* PROJECT : exFAT & FAT12/16/32 File System */
+/* FILE : exfat_api.c */
+/* PURPOSE : exFAT API Glue Layer */
+/* */
+/*----------------------------------------------------------------------*/
+/* NOTES */
+/* */
+/*----------------------------------------------------------------------*/
+/* REVISION HISTORY (Ver 0.9) */
+/* */
+/* - 2010.11.15 [Joosun Hahn] : first writing */
+/* */
+/************************************************************************/
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include "exfat_version.h"
+#include "exfat_config.h"
+#include "exfat_data.h"
+#include "exfat_oal.h"
+
+#include "exfat_nls.h"
+#include "exfat_api.h"
+#include "exfat_super.h"
+#include "exfat_core.h"
+
+/*----------------------------------------------------------------------*/
+/* Constant & Macro Definitions */
+/*----------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------*/
+/* Global Variable Definitions */
+/*----------------------------------------------------------------------*/
+
+extern struct semaphore z_sem;
+
+/*----------------------------------------------------------------------*/
+/* Local Variable Definitions */
+/*----------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------*/
+/* Local Function Declarations */
+/*----------------------------------------------------------------------*/
+
+/*======================================================================*/
+/* Global Function Definitions */
+/* - All functions for global use have same return value format, */
+/* that is, FFS_SUCCESS on success and several FS error code on */
+/* various error condition. */
+/*======================================================================*/
+
+/*----------------------------------------------------------------------*/
+/* exFAT Filesystem Init & Exit Functions */
+/*----------------------------------------------------------------------*/
+
+int FsInit(void)
+{
+ return ffsInit();
+}
+
+int FsShutdown(void)
+{
+ return ffsShutdown();
+}
+
+/*----------------------------------------------------------------------*/
+/* Volume Management Functions */
+/*----------------------------------------------------------------------*/
+
+/* FsMountVol : mount the file system volume */
+int FsMountVol(struct super_block *sb)
+{
+ int err;
+
+ sm_P(&z_sem);
+
+ err = buf_init(sb);
+ if (!err)
+ err = ffsMountVol(sb);
+ else
+ buf_shutdown(sb);
+
+ sm_V(&z_sem);
+
+ return err;
+} /* end of FsMountVol */
+
+/* FsUmountVol : unmount the file system volume */
+int FsUmountVol(struct super_block *sb)
+{
+ int err;
+ FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
+
+ sm_P(&z_sem);
+
+ /* acquire the lock for file system critical section */
+ sm_P(&p_fs->v_sem);
+
+ err = ffsUmountVol(sb);
+ buf_shutdown(sb);
+
+ /* release the lock for file system critical section */
+ sm_V(&p_fs->v_sem);
+
+ sm_V(&z_sem);
+
+ return err;
+} /* end of FsUmountVol */
+
+/* FsGetVolInfo : get the information of a file system volume */
+int FsGetVolInfo(struct super_block *sb, VOL_INFO_T *info)
+{
+ int err;
+ FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
+
+ /* check the validity of pointer parameters */
+ if (info == NULL)
+ return FFS_ERROR;
+
+ /* acquire the lock for file system critical section */
+ sm_P(&p_fs->v_sem);
+
+ err = ffsGetVolInfo(sb, info);
+
+ /* release the lock for file system critical section */
+ sm_V(&p_fs->v_sem);
+
+ return err;
+} /* end of FsGetVolInfo */
+
+/* FsSyncVol : synchronize a file system volume */
+int FsSyncVol(struct super_block *sb, int do_sync)
+{
+ int err;
+ FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
+
+ /* acquire the lock for file system critical section */
+ sm_P(&p_fs->v_sem);
+
+ err = ffsSyncVol(sb, do_sync);
+
+ /* release the lock for file system critical section */
+ sm_V(&p_fs->v_sem);
+
+ return err;
+} /* end of FsSyncVol */
+
+
+/*----------------------------------------------------------------------*/
+/* File Operation Functions */
+/*----------------------------------------------------------------------*/
+
+/* FsCreateFile : create a file */
+int FsLookupFile(struct inode *inode, char *path, FILE_ID_T *fid)
+{
+ int err;
+ struct super_block *sb = inode->i_sb;
+ FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
+
+ /* check the validity of pointer parameters */
+ if ((fid == NULL) || (path == NULL) || (*path == '\0'))
+ return FFS_ERROR;
+
+ /* acquire the lock for file system critical section */
+ sm_P(&p_fs->v_sem);
+
+ err = ffsLookupFile(inode, path, fid);
+
+ /* release the lock for file system critical section */
+ sm_V(&p_fs->v_sem);
+
+ return err;
+} /* end of FsLookupFile */
+
+/* FsCreateFile : create a file */
+int FsCreateFile(struct inode *inode, char *path, u8 mode, FILE_ID_T *fid)
+{
+ int err;
+ struct super_block *sb = inode->i_sb;
+ FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
+
+ /* check the validity of pointer parameters */
+ if ((fid == NULL) || (path == NULL) || (*path == '\0'))
+ return FFS_ERROR;
+
+ /* acquire the lock for file system critical section */
+ sm_P(&p_fs->v_sem);
+
+ err = ffsCreateFile(inode, path, mode, fid);
+
+ /* release the lock for file system critical section */
+ sm_V(&p_fs->v_sem);
+
+ return err;
+} /* end of FsCreateFile */
+
+int FsReadFile(struct inode *inode, FILE_ID_T *fid, void *buffer, u64 count, u64 *rcount)
+{
+ int err;
+ struct super_block *sb = inode->i_sb;
+ FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
+
+ /* check the validity of the given file id */
+ if (fid == NULL)
+ return FFS_INVALIDFID;
+
+ /* check the validity of pointer parameters */
+ if (buffer == NULL)
+ return FFS_ERROR;
+
+ /* acquire the lock for file system critical section */
+ sm_P(&p_fs->v_sem);
+
+ err = ffsReadFile(inode, fid, buffer, count, rcount);
+
+ /* release the lock for file system critical section */
+ sm_V(&p_fs->v_sem);
+
+ return err;
+} /* end of FsReadFile */
+
+int FsWriteFile(struct inode *inode, FILE_ID_T *fid, void *buffer, u64 count, u64 *wcount)
+{
+ int err;
+ struct super_block *sb = inode->i_sb;
+ FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
+
+ /* check the validity of the given file id */
+ if (fid == NULL)
+ return FFS_INVALIDFID;
+
+ /* check the validity of pointer parameters */
+ if (buffer == NULL)
+ return FFS_ERROR;
+
+ /* acquire the lock for file system critical section */
+ sm_P(&p_fs->v_sem);
+
+ err = ffsWriteFile(inode, fid, buffer, count, wcount);
+
+ /* release the lock for file system critical section */
+ sm_V(&p_fs->v_sem);
+
+ return err;
+} /* end of FsWriteFile */
+
+/* FsTruncateFile : resize the file length */
+int FsTruncateFile(struct inode *inode, u64 old_size, u64 new_size)
+{
+ int err;
+ struct super_block *sb = inode->i_sb;
+ FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
+
+ /* acquire the lock for file system critical section */
+ sm_P(&p_fs->v_sem);
+
+ DPRINTK("FsTruncateFile entered (inode %p size %llu)\n", inode, new_size);
+
+ err = ffsTruncateFile(inode, old_size, new_size);
+
+ DPRINTK("FsTruncateFile exitted (%d)\n", err);
+
+ /* release the lock for file system critical section */
+ sm_V(&p_fs->v_sem);
+
+ return err;
+} /* end of FsTruncateFile */
+
+/* FsMoveFile : move(rename) a old file into a new file */
+int FsMoveFile(struct inode *old_parent_inode, FILE_ID_T *fid, struct inode *new_parent_inode, struct dentry *new_dentry)
+{
+ int err;
+ struct super_block *sb = old_parent_inode->i_sb;
+ FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
+
+ /* check the validity of the given file id */
+ if (fid == NULL)
+ return FFS_INVALIDFID;
+
+ /* acquire the lock for file system critical section */
+ sm_P(&p_fs->v_sem);
+
+ err = ffsMoveFile(old_parent_inode, fid, new_parent_inode, new_dentry);
+
+ /* release the lock for file system critical section */
+ sm_V(&p_fs->v_sem);
+
+ return err;
+} /* end of FsMoveFile */
+
+/* FsRemoveFile : remove a file */
+int FsRemoveFile(struct inode *inode, FILE_ID_T *fid)
+{
+ int err;
+ struct super_block *sb = inode->i_sb;
+ FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
+
+ /* check the validity of the given file id */
+ if (fid == NULL)
+ return FFS_INVALIDFID;
+
+ /* acquire the lock for file system critical section */
+ sm_P(&p_fs->v_sem);
+
+ err = ffsRemoveFile(inode, fid);
+
+ /* release the lock for file system critical section */
+ sm_V(&p_fs->v_sem);
+
+ return err;
+} /* end of FsRemoveFile */
+
+/* FsSetAttr : set the attribute of a given file */
+int FsSetAttr(struct inode *inode, u32 attr)
+{
+ int err;
+ struct super_block *sb = inode->i_sb;
+ FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
+
+ /* acquire the lock for file system critical section */
+ sm_P(&p_fs->v_sem);
+
+ err = ffsSetAttr(inode, attr);
+
+ /* release the lock for file system critical section */
+ sm_V(&p_fs->v_sem);
+
+ return err;
+} /* end of FsSetAttr */
+
+/* FsReadStat : get the information of a given file */
+int FsReadStat(struct inode *inode, DIR_ENTRY_T *info)
+{
+ int err;
+ struct super_block *sb = inode->i_sb;
+ FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
+
+ /* acquire the lock for file system critical section */
+ sm_P(&p_fs->v_sem);
+
+ err = ffsGetStat(inode, info);
+
+ /* release the lock for file system critical section */
+ sm_V(&p_fs->v_sem);
+
+ return err;
+} /* end of FsReadStat */
+
+/* FsWriteStat : set the information of a given file */
+int FsWriteStat(struct inode *inode, DIR_ENTRY_T *info)
+{
+ int err;
+ struct super_block *sb = inode->i_sb;
+ FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
+
+ /* acquire the lock for file system critical section */
+ sm_P(&p_fs->v_sem);
+
+ DPRINTK("FsWriteStat entered (inode %p info %p\n", inode, info);
+
+ err = ffsSetStat(inode, info);
+
+ /* release the lock for file system critical section */
+ sm_V(&p_fs->v_sem);
+
+ DPRINTK("FsWriteStat exited (%d)\n", err);
+
+ return err;
+} /* end of FsWriteStat */
+
+/* FsMapCluster : return the cluster number in the given cluster offset */
+int FsMapCluster(struct inode *inode, s32 clu_offset, u32 *clu)
+{
+ int err;
+ struct super_block *sb = inode->i_sb;
+ FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
+
+ /* check the validity of pointer parameters */
+ if (clu == NULL)
+ return FFS_ERROR;
+
+ /* acquire the lock for file system critical section */
+ sm_P(&p_fs->v_sem);
+
+ err = ffsMapCluster(inode, clu_offset, clu);
+
+ /* release the lock for file system critical section */
+ sm_V(&p_fs->v_sem);
+
+ return err;
+} /* end of FsMapCluster */
+
+/*----------------------------------------------------------------------*/
+/* Directory Operation Functions */
+/*----------------------------------------------------------------------*/
+
+/* FsCreateDir : create(make) a directory */
+int FsCreateDir(struct inode *inode, char *path, FILE_ID_T *fid)
+{
+ int err;
+ struct super_block *sb = inode->i_sb;
+ FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
+
+ /* check the validity of pointer parameters */
+ if ((fid == NULL) || (path == NULL) || (*path == '\0'))
+ return FFS_ERROR;
+
+ /* acquire the lock for file system critical section */
+ sm_P(&p_fs->v_sem);
+
+ err = ffsCreateDir(inode, path, fid);
+
+ /* release the lock for file system critical section */
+ sm_V(&p_fs->v_sem);
+
+ return err;
+} /* end of FsCreateDir */
+
+/* FsReadDir : read a directory entry from the opened directory */
+int FsReadDir(struct inode *inode, DIR_ENTRY_T *dir_entry)
+{
+ int err;
+ struct super_block *sb = inode->i_sb;
+ FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
+
+ /* check the validity of pointer parameters */
+ if (dir_entry == NULL)
+ return FFS_ERROR;
+
+ /* acquire the lock for file system critical section */
+ sm_P(&p_fs->v_sem);
+
+ err = ffsReadDir(inode, dir_entry);
+
+ /* release the lock for file system critical section */
+ sm_V(&p_fs->v_sem);
+
+ return err;
+} /* end of FsReadDir */
+
+/* FsRemoveDir : remove a directory */
+int FsRemoveDir(struct inode *inode, FILE_ID_T *fid)
+{
+ int err;
+ struct super_block *sb = inode->i_sb;
+ FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
+
+ /* check the validity of the given file id */
+ if (fid == NULL)
+ return FFS_INVALIDFID;
+
+ /* acquire the lock for file system critical section */
+ sm_P(&p_fs->v_sem);
+
+ err = ffsRemoveDir(inode, fid);
+
+ /* release the lock for file system critical section */
+ sm_V(&p_fs->v_sem);
+
+ return err;
+} /* end of FsRemoveDir */
+
+EXPORT_SYMBOL(FsMountVol);
+EXPORT_SYMBOL(FsUmountVol);
+EXPORT_SYMBOL(FsGetVolInfo);
+EXPORT_SYMBOL(FsSyncVol);
+EXPORT_SYMBOL(FsLookupFile);
+EXPORT_SYMBOL(FsCreateFile);
+EXPORT_SYMBOL(FsReadFile);
+EXPORT_SYMBOL(FsWriteFile);
+EXPORT_SYMBOL(FsTruncateFile);
+EXPORT_SYMBOL(FsMoveFile);
+EXPORT_SYMBOL(FsRemoveFile);
+EXPORT_SYMBOL(FsSetAttr);
+EXPORT_SYMBOL(FsReadStat);
+EXPORT_SYMBOL(FsWriteStat);
+EXPORT_SYMBOL(FsMapCluster);
+EXPORT_SYMBOL(FsCreateDir);
+EXPORT_SYMBOL(FsReadDir);
+EXPORT_SYMBOL(FsRemoveDir);
+
+#ifdef CONFIG_EXFAT_KERNEL_DEBUG
+/* FsReleaseCache: Release FAT & buf cache */
+int FsReleaseCache(struct super_block *sb)
+{
+ FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
+
+ /* acquire the lock for file system critical section */
+ sm_P(&p_fs->v_sem);
+
+ FAT_release_all(sb);
+ buf_release_all(sb);
+
+ /* release the lock for file system critical section */
+ sm_V(&p_fs->v_sem);
+
+ return 0;
+}
+/* FsReleaseCache */
+
+EXPORT_SYMBOL(FsReleaseCache);
+#endif /* CONFIG_EXFAT_KERNEL_DEBUG */
+
+/*======================================================================*/
+/* Local Function Definitions */
+/*======================================================================*/