Commit b36d9490 authored by Vincent's avatar Vincent

Revert "fs: Remove exfat file system"

This reverts commit 6fef7af7.

Change-Id: Ife05ec62a289aad60ab630a16b641f2a9b8b9d95
parent e9ce9f4f
......@@ -602,6 +602,7 @@ CONFIG_SDCARD_FS_FADV_NOACTIVE=y
CONFIG_CONFIGFS_FS=y
CONFIG_FUSE_FS=y
CONFIG_VFAT_FS=y
CONFIG_EXFAT_FS=y
CONFIG_F2FS_FS=y
CONFIG_F2FS_STAT_FS=y
CONFIG_F2FS_FS_XATTR=y
......
......@@ -95,6 +95,7 @@ if BLOCK
menu "DOS/FAT/NT Filesystems"
source "fs/fat/Kconfig"
source "fs/exfat/Kconfig"
source "fs/ntfs/Kconfig"
endmenu
......
......@@ -79,6 +79,7 @@ obj-$(CONFIG_HUGETLBFS) += hugetlbfs/
obj-$(CONFIG_CODA_FS) += coda/
obj-$(CONFIG_MINIX_FS) += minix/
obj-$(CONFIG_FAT_FS) += fat/
obj-$(CONFIG_EXFAT_FS) += exfat/
obj-$(CONFIG_BFS_FS) += bfs/
obj-$(CONFIG_ISO9660_FS) += isofs/
obj-$(CONFIG_HFSPLUS_FS) += hfsplus/ # Before hfs to find wrapped HFS+
......
config EXFAT_FS
tristate
default y
select NLS
select NLS_UTF8
help
If you want to use the exFAT file systems, then you must say Y or M here
to inlucde exFAT support.
config EXFAT_VIRTUAL_XATTR
bool "Virtual xattr support for exFAT filesystem"
default y
depends on EXFAT_FS
help
Modification of exFAT filesystem for virtual xattr
config EXFAT_VIRTUAL_XATTR_SELINUX_LABEL
string "Default string for SELinux label"
depends on EXFAT_FS && EXFAT_VIRTUAL_XATTR
default "u:object_r:sdcard_external:s0"
help
Set this to the default string for SELinux label.
config EXFAT_SUPPORT_STLOG
bool "Enable storage log"
default y
depends on EXFAT_FS && PROC_STLOG
obj-y += exfat_core.o exfat_fs.o
exfat_fs-y := exfat_super.o
exfat_core-y := exfat.o exfat_api.o exfat_blkdev.o exfat_cache.o \
exfat_data.o exfat_global.o exfat_nls.o \
exfat_oal.o exfat_upcase.o exfat_xattr.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
This diff is collapsed.
This diff is collapsed.
/*
* 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.
*/
#include <linux/version.h>
#include <linux/module.h>
#include <linux/init.h>
#include "exfat_version.h"
#include "exfat_config.h"
#include "exfat_global.h"
#include "exfat_data.h"
#include "exfat_oal.h"
#include "exfat_part.h"
#include "exfat_nls.h"
#include "exfat_api.h"
#include "exfat_super.h"
#include "exfat.h"
extern FS_STRUCT_T fs_struct[];
extern struct semaphore z_sem;
INT32 FsInit(void)
{
INT32 i;
for (i = 0; i < MAX_DRIVE; i++) {
fs_struct[i].mounted = FALSE;
fs_struct[i].sb = NULL;
sm_init(&(fs_struct[i].v_sem));
}
return(ffsInit());
}
INT32 FsShutdown(void)
{
INT32 i;
for (i = 0; i < MAX_DRIVE; i++) {
if (!fs_struct[i].mounted) continue;
ffsUmountVol(fs_struct[i].sb);
}
return(ffsShutdown());
}
INT32 FsMountVol(struct super_block *sb)
{
INT32 err, drv;
sm_P(&z_sem);
for (drv = 0; drv < MAX_DRIVE; drv++) {
if (!fs_struct[drv].mounted) break;
}
if (drv >= MAX_DRIVE) {
err = FFS_ERROR;
goto ret_unlock;
}
sm_P(&(fs_struct[drv].v_sem));
err = buf_init(sb);
if (!err) {
err = ffsMountVol(sb, drv);
}
sm_V(&(fs_struct[drv].v_sem));
if (!err) {
fs_struct[drv].mounted = TRUE;
fs_struct[drv].sb = sb;
} else {
buf_shutdown(sb);
}
ret_unlock:
sm_V(&z_sem);
return(err);
}
INT32 FsUmountVol(struct super_block *sb)
{
INT32 err;
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
sm_P(&z_sem);
sm_P(&(fs_struct[p_fs->drv].v_sem));
err = ffsUmountVol(sb);
buf_shutdown(sb);
sm_V(&(fs_struct[p_fs->drv].v_sem));
fs_struct[p_fs->drv].mounted = FALSE;
fs_struct[p_fs->drv].sb = NULL;
sm_V(&z_sem);
return(err);
}
INT32 FsGetVolInfo(struct super_block *sb, VOL_INFO_T *info)
{
INT32 err;
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
if (info == NULL) return(FFS_ERROR);
sm_P(&(fs_struct[p_fs->drv].v_sem));
err = ffsGetVolInfo(sb, info);
sm_V(&(fs_struct[p_fs->drv].v_sem));
return(err);
}
INT32 FsSyncVol(struct super_block *sb, INT32 do_sync)
{
INT32 err;
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
sm_P(&(fs_struct[p_fs->drv].v_sem));
err = ffsSyncVol(sb, do_sync);
sm_V(&(fs_struct[p_fs->drv].v_sem));
return(err);
}
INT32 FsLookupFile(struct inode *inode, UINT8 *path, FILE_ID_T *fid)
{
INT32 err;
struct super_block *sb = inode->i_sb;
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
if ((fid == NULL) || (path == NULL) || (STRLEN(path) == 0))
return(FFS_ERROR);
sm_P(&(fs_struct[p_fs->drv].v_sem));
err = ffsLookupFile(inode, path, fid);
sm_V(&(fs_struct[p_fs->drv].v_sem));
return(err);
}
INT32 FsCreateFile(struct inode *inode, UINT8 *path, UINT8 mode, FILE_ID_T *fid)
{
INT32 err;
struct super_block *sb = inode->i_sb;
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
if ((fid == NULL) || (path == NULL) || (STRLEN(path) == 0))
return(FFS_ERROR);
sm_P(&(fs_struct[p_fs->drv].v_sem));
err = ffsCreateFile(inode, path, mode, fid);
sm_V(&(fs_struct[p_fs->drv].v_sem));
return(err);
}
INT32 FsReadFile(struct inode *inode, FILE_ID_T *fid, void *buffer, UINT64 count, UINT64 *rcount)
{
INT32 err;
struct super_block *sb = inode->i_sb;
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
if (fid == NULL) return(FFS_INVALIDFID);
if (buffer == NULL) return(FFS_ERROR);
sm_P(&(fs_struct[p_fs->drv].v_sem));
err = ffsReadFile(inode, fid, buffer, count, rcount);
sm_V(&(fs_struct[p_fs->drv].v_sem));
return(err);
}
INT32 FsWriteFile(struct inode *inode, FILE_ID_T *fid, void *buffer, UINT64 count, UINT64 *wcount)
{
INT32 err;
struct super_block *sb = inode->i_sb;
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
if (fid == NULL) return(FFS_INVALIDFID);
if (buffer == NULL) return(FFS_ERROR);
sm_P(&(fs_struct[p_fs->drv].v_sem));
err = ffsWriteFile(inode, fid, buffer, count, wcount);
sm_V(&(fs_struct[p_fs->drv].v_sem));
return(err);
}
INT32 FsTruncateFile(struct inode *inode, UINT64 old_size, UINT64 new_size)
{
INT32 err;
struct super_block *sb = inode->i_sb;
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
sm_P(&(fs_struct[p_fs->drv].v_sem));
PRINTK("FsTruncateFile entered (inode %p size %llu)\n", inode, new_size);
err = ffsTruncateFile(inode, old_size, new_size);
PRINTK("FsTruncateFile exitted (%d)\n", err);
sm_V(&(fs_struct[p_fs->drv].v_sem));
return(err);
}
INT32 FsMoveFile(struct inode *old_parent_inode, FILE_ID_T *fid, struct inode *new_parent_inode, struct dentry *new_dentry)
{
INT32 err;
struct super_block *sb = old_parent_inode->i_sb;
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
if (fid == NULL) return(FFS_INVALIDFID);
sm_P(&(fs_struct[p_fs->drv].v_sem));
err = ffsMoveFile(old_parent_inode, fid, new_parent_inode, new_dentry);
sm_V(&(fs_struct[p_fs->drv].v_sem));
return(err);
}
INT32 FsRemoveFile(struct inode *inode, FILE_ID_T *fid)
{
INT32 err;
struct super_block *sb = inode->i_sb;
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
if (fid == NULL) return(FFS_INVALIDFID);
sm_P(&(fs_struct[p_fs->drv].v_sem));
err = ffsRemoveFile(inode, fid);
sm_V(&(fs_struct[p_fs->drv].v_sem));
return(err);
}
INT32 FsSetAttr(struct inode *inode, UINT32 attr)
{
INT32 err;
struct super_block *sb = inode->i_sb;
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
sm_P(&(fs_struct[p_fs->drv].v_sem));
err = ffsSetAttr(inode, attr);
sm_V(&(fs_struct[p_fs->drv].v_sem));
return(err);
}
INT32 FsReadStat(struct inode *inode, DIR_ENTRY_T *info)
{
INT32 err;
struct super_block *sb = inode->i_sb;
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
sm_P(&(fs_struct[p_fs->drv].v_sem));
err = ffsGetStat(inode, info);
sm_V(&(fs_struct[p_fs->drv].v_sem));
return(err);
}
INT32 FsWriteStat(struct inode *inode, DIR_ENTRY_T *info)
{
INT32 err;
struct super_block *sb = inode->i_sb;
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
sm_P(&(fs_struct[p_fs->drv].v_sem));
PRINTK("FsWriteStat entered (inode %p info %p\n", inode, info);
err = ffsSetStat(inode, info);
sm_V(&(fs_struct[p_fs->drv].v_sem));
PRINTK("FsWriteStat exited (%d)\n", err);
return(err);
}
INT32 FsMapCluster(struct inode *inode, INT32 clu_offset, UINT32 *clu)
{
INT32 err;
struct super_block *sb = inode->i_sb;
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
if (clu == NULL) return(FFS_ERROR);
sm_P(&(fs_struct[p_fs->drv].v_sem));
err = ffsMapCluster(inode, clu_offset, clu);
sm_V(&(fs_struct[p_fs->drv].v_sem));
return(err);
}
INT32 FsCreateDir(struct inode *inode, UINT8 *path, FILE_ID_T *fid)
{
INT32 err;
struct super_block *sb = inode->i_sb;
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
if ((fid == NULL) || (path == NULL) || (STRLEN(path) == 0))
return(FFS_ERROR);
sm_P(&(fs_struct[p_fs->drv].v_sem));
err = ffsCreateDir(inode, path, fid);
sm_V(&(fs_struct[p_fs->drv].v_sem));
return(err);
}
INT32 FsReadDir(struct inode *inode, DIR_ENTRY_T *dir_entry)
{
INT32 err;
struct super_block *sb = inode->i_sb;
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
if (dir_entry == NULL) return(FFS_ERROR);
sm_P(&(fs_struct[p_fs->drv].v_sem));
err = ffsReadDir(inode, dir_entry);
sm_V(&(fs_struct[p_fs->drv].v_sem));
return(err);
}
INT32 FsRemoveDir(struct inode *inode, FILE_ID_T *fid)
{
INT32 err;
struct super_block *sb = inode->i_sb;
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
if (fid == NULL) return(FFS_INVALIDFID);
sm_P(&(fs_struct[p_fs->drv].v_sem));
err = ffsRemoveDir(inode, fid);
sm_V(&(fs_struct[p_fs->drv].v_sem));
return(err);
}
INT32 FsRemoveEntry(struct inode *inode, FILE_ID_T *fid)
{
INT32 err;
struct super_block *sb = inode->i_sb;
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
if (fid == NULL) return(FFS_INVALIDFID);
sm_P(&(fs_struct[p_fs->drv].v_sem));
err = ffsRemoveEntry(inode, fid);
sm_V(&(fs_struct[p_fs->drv].v_sem));
return(err);
}
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);
EXPORT_SYMBOL(FsRemoveEntry);
#if EXFAT_CONFIG_KERNEL_DEBUG
INT32 FsReleaseCache(struct super_block *sb)
{
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
sm_P(&(fs_struct[p_fs->drv].v_sem));
FAT_release_all(sb);
buf_release_all(sb);
sm_V(&(fs_struct[p_fs->drv].v_sem));
return 0;
}
EXPORT_SYMBOL(FsReleaseCache);
#endif
static int __init init_exfat_core(void)
{
int err;
printk(KERN_INFO "exFAT: Core Version %s\n", EXFAT_VERSION);
err = FsInit();
if (err) {
if (err == FFS_MEMORYERR)
return -ENOMEM;
else
return -EIO;
}
return 0;
}
static void __exit exit_exfat_core(void)
{
FsShutdown();
}
module_init(init_exfat_core);
module_exit(exit_exfat_core);
MODULE_LICENSE("GPL");
/*
* 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.
*/
#ifndef _EXFAT_API_H
#define _EXFAT_API_H
#include "exfat_config.h"
#include "exfat_global.h"
#ifdef __cplusplus
extern "C" {
#endif
#define EXFAT_SUPER_MAGIC (0x2011BAB0L)
#define EXFAT_ROOT_INO 1
#define FAT12 0x01
#define FAT16 0x0E
#define FAT32 0x0C
#define EXFAT 0x07
#define MAX_CHARSET_SIZE 3
#define MAX_PATH_DEPTH 15
#define MAX_NAME_LENGTH 256
#define MAX_PATH_LENGTH 260
#define DOS_NAME_LENGTH 11
#define DOS_PATH_LENGTH 80
#define ATTR_NORMAL 0x0000
#define ATTR_READONLY 0x0001
#define ATTR_HIDDEN 0x0002
#define ATTR_SYSTEM 0x0004
#define ATTR_VOLUME 0x0008
#define ATTR_SUBDIR 0x0010
#define ATTR_ARCHIVE 0x0020
#define ATTR_SYMLINK 0x0040
#define ATTR_EXTEND 0x000F
#define ATTR_RWMASK 0x007E
#define FM_REGULAR 0x00
#define FM_SYMLINK 0x40
#define FFS_SUCCESS 0
#define FFS_MEDIAERR 1
#define FFS_FORMATERR 2
#define FFS_MOUNTED 3
#define FFS_NOTMOUNTED 4
#define FFS_ALIGNMENTERR 5
#define FFS_SEMAPHOREERR 6
#define FFS_INVALIDPATH 7
#define FFS_INVALIDFID 8
#define FFS_NOTFOUND 9
#define FFS_FILEEXIST 10
#define FFS_PERMISSIONERR 11
#define FFS_NOTOPENED 12
#define FFS_MAXOPENED 13
#define FFS_FULL 14
#define FFS_EOF 15
#define FFS_DIRBUSY 16
#define FFS_MEMORYERR 17
#define FFS_NAMETOOLONG 18
#define FFS_ERROR 19
typedef struct {
UINT16 Year;
UINT16 Month;
UINT16 Day;
UINT16 Hour;
UINT16 Minute;
UINT16 Second;
UINT16 MilliSecond;
} DATE_TIME_T;
typedef struct {
UINT32 Offset;
UINT32 Size;
} PART_INFO_T;
typedef struct {
UINT32 SecSize;
UINT32 DevSize;
} DEV_INFO_T;
typedef struct {
UINT32 FatType;
UINT32 ClusterSize;
UINT32 NumClusters;
UINT32 FreeClusters;
UINT32 UsedClusters;
} VOL_INFO_T;
typedef struct {
UINT32 dir;
INT32 size;
UINT8 flags;
} CHAIN_T;
typedef struct {
CHAIN_T dir;
INT32 entry;
UINT32 type;
UINT32 attr;
UINT32 start_clu;
UINT64 size;
UINT8 flags;
INT64 rwoffset;
INT32 hint_last_off;
UINT32 hint_last_clu;
} FILE_ID_T;
typedef struct {
INT8 Name[MAX_NAME_LENGTH *MAX_CHARSET_SIZE];
INT8 ShortName[DOS_NAME_LENGTH + 2];
UINT32 Attr;
UINT64 Size;
UINT32 NumSubdirs;
DATE_TIME_T CreateTimestamp;
DATE_TIME_T ModifyTimestamp;
DATE_TIME_T AccessTimestamp;
} DIR_ENTRY_T;
INT32 FsInit(void);
INT32 FsShutdown(void);
INT32 FsMountVol(struct super_block *sb);
INT32 FsUmountVol(struct super_block *sb);
INT32 FsGetVolInfo(struct super_block *sb, VOL_INFO_T *info);
INT32 FsSyncVol(struct super_block *sb, INT32 do_sync);
INT32 FsLookupFile(struct inode *inode, UINT8 *path, FILE_ID_T *fid);
INT32 FsCreateFile(struct inode *inode, UINT8 *path, UINT8 mode, FILE_ID_T *fid);
INT32 FsReadFile(struct inode *inode, FILE_ID_T *fid, void *buffer, UINT64 count, UINT64 *rcount);
INT32 FsWriteFile(struct inode *inode, FILE_ID_T *fid, void *buffer, UINT64 count, UINT64 *wcount);
INT32 FsTruncateFile(struct inode *inode, UINT64 old_size, UINT64 new_size);
INT32 FsMoveFile(struct inode *old_parent_inode, FILE_ID_T *fid, struct inode *new_parent_inode, struct dentry *new_dentry);
INT32 FsRemoveFile(struct inode *inode, FILE_ID_T *fid);
INT32 FsSetAttr(struct inode *inode, UINT32 attr);
INT32 FsReadStat(struct inode *inode, DIR_ENTRY_T *info);
INT32 FsWriteStat(struct inode *inode, DIR_ENTRY_T *info);
INT32 FsMapCluster(struct inode *inode, INT32 clu_offset, UINT32 *clu);
INT32 FsCreateDir(struct inode *inode, UINT8 *path, FILE_ID_T *fid);
INT32 FsReadDir(struct inode *inode, DIR_ENTRY_T *dir_entry);
INT32 FsRemoveDir(struct inode *inode, FILE_ID_T *fid);
INT32 FsRemoveEntry(struct inode *inode, FILE_ID_T *fid);
INT32 FsReleaseCache(struct super_block *sb);
#ifdef __cplusplus
}
#endif
#endif
/*
* 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.