You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
409 lines
14 KiB
409 lines
14 KiB
/*
|
|
* 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, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef _SDFAT_API_H
|
|
#define _SDFAT_API_H
|
|
|
|
#include "config.h"
|
|
#include "sdfat_fs.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif /* __cplusplus */
|
|
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* Configure Constant & Macro Definitions */
|
|
/*----------------------------------------------------------------------*/
|
|
/* cache size (in number of sectors) */
|
|
/* (should be an exponential value of 2) */
|
|
#define FAT_CACHE_SIZE 128
|
|
#define FAT_CACHE_HASH_SIZE 64
|
|
#define BUF_CACHE_SIZE 256
|
|
#define BUF_CACHE_HASH_SIZE 64
|
|
|
|
/* Read-ahead related */
|
|
/* First config vars. should be pow of 2 */
|
|
#define FCACHE_MAX_RA_SIZE (PAGE_SIZE)
|
|
#define DCACHE_MAX_RA_SIZE (128*1024)
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* Constant & Macro Definitions */
|
|
/*----------------------------------------------------------------------*/
|
|
/* type values */
|
|
#define TYPE_UNUSED 0x0000
|
|
#define TYPE_DELETED 0x0001
|
|
#define TYPE_INVALID 0x0002
|
|
#define TYPE_CRITICAL_PRI 0x0100
|
|
#define TYPE_BITMAP 0x0101
|
|
#define TYPE_UPCASE 0x0102
|
|
#define TYPE_VOLUME 0x0103
|
|
#define TYPE_DIR 0x0104
|
|
#define TYPE_FILE 0x011F
|
|
#define TYPE_SYMLINK 0x015F
|
|
#define TYPE_CRITICAL_SEC 0x0200
|
|
#define TYPE_STREAM 0x0201
|
|
#define TYPE_EXTEND 0x0202
|
|
#define TYPE_ACL 0x0203
|
|
#define TYPE_BENIGN_PRI 0x0400
|
|
#define TYPE_GUID 0x0401
|
|
#define TYPE_PADDING 0x0402
|
|
#define TYPE_ACLTAB 0x0403
|
|
#define TYPE_BENIGN_SEC 0x0800
|
|
#define TYPE_ALL 0x0FFF
|
|
|
|
/* eio values */
|
|
#define SDFAT_EIO_NONE (0x00000000)
|
|
#define SDFAT_EIO_READ (0x00000001)
|
|
#define SDFAT_EIO_WRITE (0x00000002)
|
|
#define SDFAT_EIO_BDI (0x00000004)
|
|
|
|
/* modes for volume allocation unit status */
|
|
#define VOL_AU_STAT_TOTAL (0)
|
|
#define VOL_AU_STAT_CLEAN (1)
|
|
#define VOL_AU_STAT_FULL (2)
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* NLS Type Definitions */
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
/* DOS name structure */
|
|
typedef struct {
|
|
u8 name[DOS_NAME_LENGTH];
|
|
u8 name_case;
|
|
} DOS_NAME_T;
|
|
|
|
/* unicode name structure */
|
|
typedef struct {
|
|
u16 name[MAX_NAME_LENGTH+3]; /* +3 for null and for converting */
|
|
u16 name_hash;
|
|
u8 name_len;
|
|
} UNI_NAME_T;
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* Type Definitions */
|
|
/*----------------------------------------------------------------------*/
|
|
/* should be merged it to DATE_TIME_T */
|
|
typedef union {
|
|
struct {
|
|
u8 off : 7;
|
|
u8 valid : 1;
|
|
};
|
|
u8 value;
|
|
} TIMEZONE_T;
|
|
|
|
typedef struct {
|
|
u16 sec; /* 0 ~ 59 */
|
|
u16 min; /* 0 ~ 59 */
|
|
u16 hour; /* 0 ~ 23 */
|
|
u16 day; /* 1 ~ 31 */
|
|
u16 mon; /* 1 ~ 12 */
|
|
u16 year; /* 0 ~ 127 (since 1980) */
|
|
TIMEZONE_T tz;
|
|
} TIMESTAMP_T;
|
|
|
|
typedef struct {
|
|
u16 Year;
|
|
u16 Month;
|
|
u16 Day;
|
|
u16 Hour;
|
|
u16 Minute;
|
|
u16 Second;
|
|
u16 MilliSecond;
|
|
TIMEZONE_T Timezone;
|
|
} DATE_TIME_T;
|
|
|
|
typedef struct {
|
|
u64 Offset; // start sector number of the partition
|
|
u64 Size; // in sectors
|
|
} PART_INFO_T;
|
|
|
|
typedef struct {
|
|
u32 SecSize; // sector size in bytes
|
|
u64 DevSize; // block device size in sectors
|
|
} DEV_INFO_T;
|
|
|
|
typedef struct {
|
|
u32 FatType;
|
|
u32 ClusterSize;
|
|
u32 NumClusters;
|
|
u32 FreeClusters;
|
|
u32 UsedClusters;
|
|
} VOL_INFO_T;
|
|
|
|
/* directory structure */
|
|
typedef struct {
|
|
u32 dir;
|
|
u32 size;
|
|
u8 flags;
|
|
} CHAIN_T;
|
|
|
|
/* hint structure */
|
|
typedef struct {
|
|
u32 clu;
|
|
union {
|
|
u32 off; // cluster offset
|
|
s32 eidx; // entry index
|
|
};
|
|
} HINT_T;
|
|
|
|
typedef struct {
|
|
spinlock_t cache_lru_lock;
|
|
struct list_head cache_lru;
|
|
s32 nr_caches;
|
|
u32 cache_valid_id; // for avoiding the race between alloc and free
|
|
} EXTENT_T;
|
|
|
|
/* first empty entry hint information */
|
|
typedef struct {
|
|
s32 eidx; // entry index of a directory
|
|
s32 count; // count of continuous empty entry
|
|
CHAIN_T cur; // the cluster that first empty slot exists in
|
|
} HINT_FEMP_T;
|
|
|
|
/* file id structure */
|
|
typedef struct {
|
|
CHAIN_T dir;
|
|
s32 entry;
|
|
u32 type;
|
|
u32 attr;
|
|
u32 start_clu;
|
|
u64 size;
|
|
u8 flags;
|
|
u8 reserved[3]; // padding
|
|
u32 version; // the copy of low 32bit of i_version to check the validation of hint_stat
|
|
s64 rwoffset; // file offset or dentry index for readdir
|
|
EXTENT_T extent; // extent cache for a file
|
|
HINT_T hint_bmap; // hint for cluster last accessed
|
|
HINT_T hint_stat; // hint for entry index we try to lookup next time
|
|
HINT_FEMP_T hint_femp; // hint for first empty entry
|
|
} FILE_ID_T;
|
|
|
|
typedef struct {
|
|
s8 *lfn;
|
|
s8 *sfn;
|
|
s32 lfnbuf_len; //usally MAX_UNINAME_BUF_SIZE
|
|
s32 sfnbuf_len; //usally MAX_DOSNAME_BUF_SIZE, used only for vfat, not for exfat
|
|
} DENTRY_NAMEBUF_T;
|
|
|
|
typedef struct {
|
|
u32 Attr;
|
|
u64 Size;
|
|
u32 NumSubdirs;
|
|
DATE_TIME_T CreateTimestamp;
|
|
DATE_TIME_T ModifyTimestamp;
|
|
DATE_TIME_T AccessTimestamp;
|
|
DENTRY_NAMEBUF_T NameBuf;
|
|
} DIR_ENTRY_T;
|
|
|
|
/* cache information */
|
|
typedef struct __cache_entry {
|
|
struct __cache_entry *next;
|
|
struct __cache_entry *prev;
|
|
struct {
|
|
struct __cache_entry *next;
|
|
struct __cache_entry *prev;
|
|
} hash;
|
|
u64 sec;
|
|
u32 flag;
|
|
struct buffer_head *bh;
|
|
} cache_ent_t;
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* Type Definitions : Wrapper & In-Core */
|
|
/*----------------------------------------------------------------------*/
|
|
typedef struct __FATENT_OPS_T {
|
|
s32 (*ent_get)(struct super_block *sb, u32 loc, u32 *content);
|
|
s32 (*ent_set)(struct super_block *sb, u32 loc, u32 content);
|
|
} FATENT_OPS_T;
|
|
|
|
typedef struct {
|
|
s32 (*alloc_cluster)(struct super_block *, u32, CHAIN_T *, s32);
|
|
s32 (*free_cluster)(struct super_block *, CHAIN_T *, s32);
|
|
s32 (*count_used_clusters)(struct super_block *, u32 *);
|
|
s32 (*init_dir_entry)(struct super_block *, CHAIN_T *, s32, u32, u32, u64);
|
|
s32 (*init_ext_entry)(struct super_block *, CHAIN_T *, s32, s32, UNI_NAME_T *, DOS_NAME_T *);
|
|
s32 (*find_dir_entry)(struct super_block *, FILE_ID_T *, CHAIN_T *, UNI_NAME_T *, s32, DOS_NAME_T *, u32);
|
|
s32 (*delete_dir_entry)(struct super_block *, CHAIN_T *, s32, s32, s32);
|
|
void (*get_uniname_from_ext_entry)(struct super_block *, CHAIN_T *, s32, u16 *);
|
|
s32 (*count_ext_entries)(struct super_block *, CHAIN_T *, s32, DENTRY_T *);
|
|
s32 (*calc_num_entries)(UNI_NAME_T *);
|
|
s32 (*check_max_dentries)(FILE_ID_T *);
|
|
u32 (*get_entry_type)(DENTRY_T *);
|
|
void (*set_entry_type)(DENTRY_T *, u32);
|
|
u32 (*get_entry_attr)(DENTRY_T *);
|
|
void (*set_entry_attr)(DENTRY_T *, u32);
|
|
u8 (*get_entry_flag)(DENTRY_T *);
|
|
void (*set_entry_flag)(DENTRY_T *, u8);
|
|
u32 (*get_entry_clu0)(DENTRY_T *);
|
|
void (*set_entry_clu0)(DENTRY_T *, u32);
|
|
u64 (*get_entry_size)(DENTRY_T *);
|
|
void (*set_entry_size)(DENTRY_T *, u64);
|
|
void (*get_entry_time)(DENTRY_T *, TIMESTAMP_T *, u8);
|
|
void (*set_entry_time)(DENTRY_T *, TIMESTAMP_T *, u8);
|
|
u32 (*get_au_stat)(struct super_block *, s32);
|
|
} FS_FUNC_T;
|
|
|
|
typedef struct __FS_INFO_T {
|
|
s32 bd_opened; // opened or not
|
|
u32 vol_type; // volume FAT type
|
|
u32 vol_id; // volume serial number
|
|
u64 num_sectors; // num of sectors in volume
|
|
u32 num_clusters; // num of clusters in volume
|
|
u32 cluster_size; // cluster size in bytes
|
|
u32 cluster_size_bits;
|
|
u32 sect_per_clus; // cluster size in sectors
|
|
u32 sect_per_clus_bits;
|
|
u64 FAT1_start_sector; // FAT1 start sector
|
|
u64 FAT2_start_sector; // FAT2 start sector
|
|
u64 root_start_sector; // root dir start sector
|
|
u64 data_start_sector; // data area start sector
|
|
u32 num_FAT_sectors; // num of FAT sectors
|
|
u32 root_dir; // root dir cluster
|
|
u32 dentries_in_root; // num of dentries in root dir
|
|
u32 dentries_per_clu; // num of dentries per cluster
|
|
u32 vol_flag; // volume dirty flag
|
|
struct buffer_head *pbr_bh; // buffer_head of PBR sector
|
|
|
|
u32 map_clu; // allocation bitmap start cluster
|
|
u32 map_sectors; // num of allocation bitmap sectors
|
|
struct buffer_head **vol_amap; // allocation bitmap
|
|
|
|
u16 **vol_utbl; // upcase table
|
|
|
|
u32 clu_srch_ptr; // cluster search pointer
|
|
u32 used_clusters; // number of used clusters
|
|
|
|
u32 prev_eio; // block device operation error flag
|
|
|
|
FS_FUNC_T *fs_func;
|
|
FATENT_OPS_T *fatent_ops;
|
|
|
|
s32 reserved_clusters; // # of reserved clusters (DA)
|
|
void *amap; // AU Allocation Map
|
|
|
|
/* fat cache */
|
|
struct {
|
|
cache_ent_t pool[FAT_CACHE_SIZE];
|
|
cache_ent_t lru_list;
|
|
cache_ent_t hash_list[FAT_CACHE_HASH_SIZE];
|
|
} fcache;
|
|
|
|
/* meta cache */
|
|
struct {
|
|
cache_ent_t pool[BUF_CACHE_SIZE];
|
|
cache_ent_t lru_list;
|
|
cache_ent_t keep_list; // CACHEs in this list will not be kicked by normal lru operations
|
|
cache_ent_t hash_list[BUF_CACHE_HASH_SIZE];
|
|
} dcache;
|
|
} FS_INFO_T;
|
|
|
|
/*======================================================================*/
|
|
/* */
|
|
/* API FUNCTION DECLARATIONS */
|
|
/* (CHANGE THIS PART IF REQUIRED) */
|
|
/* */
|
|
/*======================================================================*/
|
|
|
|
/*----------------------------------------------------------------------*/
|
|
/* External Function Declarations */
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
/* file system initialization & shutdown functions */
|
|
s32 fsapi_init(void);
|
|
s32 fsapi_shutdown(void);
|
|
|
|
/* volume management functions */
|
|
s32 fsapi_mount(struct super_block *sb);
|
|
s32 fsapi_umount(struct super_block *sb);
|
|
s32 fsapi_statfs(struct super_block *sb, VOL_INFO_T *info);
|
|
s32 fsapi_sync_fs(struct super_block *sb, s32 do_sync);
|
|
s32 fsapi_set_vol_flags(struct super_block *sb, u16 new_flag, s32 always_sync);
|
|
|
|
/* file management functions */
|
|
s32 fsapi_lookup(struct inode *inode, u8 *path, FILE_ID_T *fid);
|
|
s32 fsapi_create(struct inode *inode, u8 *path, u8 mode, FILE_ID_T *fid);
|
|
s32 fsapi_read_link(struct inode *inode, FILE_ID_T *fid, void *buffer, u64 count, u64 *rcount);
|
|
s32 fsapi_write_link(struct inode *inode, FILE_ID_T *fid, void *buffer, u64 count, u64 *wcount);
|
|
s32 fsapi_remove(struct inode *inode, FILE_ID_T *fid); /* unlink and truncate */
|
|
s32 fsapi_truncate(struct inode *inode, u64 old_size, u64 new_size);
|
|
s32 fsapi_rename(struct inode *old_parent_inode, FILE_ID_T *fid,
|
|
struct inode *new_parent_inode, struct dentry *new_dentry);
|
|
s32 fsapi_unlink(struct inode *inode, FILE_ID_T *fid);
|
|
s32 fsapi_read_inode(struct inode *inode, DIR_ENTRY_T *info);
|
|
s32 fsapi_write_inode(struct inode *inode, DIR_ENTRY_T *info, int sync);
|
|
s32 fsapi_map_clus(struct inode *inode, u32 clu_offset, u32 *clu, int dest);
|
|
s32 fsapi_reserve_clus(struct inode *inode);
|
|
|
|
/* directory management functions */
|
|
s32 fsapi_mkdir(struct inode *inode, u8 *path, FILE_ID_T *fid);
|
|
s32 fsapi_readdir(struct inode *inode, DIR_ENTRY_T *dir_entry);
|
|
s32 fsapi_rmdir(struct inode *inode, FILE_ID_T *fid);
|
|
|
|
/* FAT & buf cache functions */
|
|
s32 fsapi_cache_flush(struct super_block *sb, int do_sync);
|
|
s32 fsapi_cache_release(struct super_block *sb);
|
|
|
|
/* extra info functions */
|
|
u32 fsapi_get_au_stat(struct super_block *sb, s32 mode);
|
|
|
|
/* extent cache functions */
|
|
void fsapi_invalidate_extent(struct inode *inode);
|
|
|
|
/* bdev management */
|
|
s32 fsapi_check_bdi_valid(struct super_block *sb);
|
|
|
|
#ifdef CONFIG_SDFAT_DFR
|
|
/*----------------------------------------------------------------------*/
|
|
/* Defragmentation related */
|
|
/*----------------------------------------------------------------------*/
|
|
|
|
s32 fsapi_dfr_get_info(struct super_block *sb, void *arg);
|
|
|
|
s32 fsapi_dfr_scan_dir(struct super_block *sb, void *args);
|
|
|
|
s32 fsapi_dfr_validate_clus(struct inode *inode, void *chunk, int skip_prev);
|
|
s32 fsapi_dfr_reserve_clus(struct super_block *sb, s32 nr_clus);
|
|
s32 fsapi_dfr_mark_ignore(struct super_block *sb, unsigned int clus);
|
|
void fsapi_dfr_unmark_ignore_all(struct super_block *sb);
|
|
|
|
s32 fsapi_dfr_map_clus(struct inode *inode, u32 clu_offset, u32 *clu);
|
|
void fsapi_dfr_writepage_endio(struct page *page);
|
|
|
|
void fsapi_dfr_update_fat_prev(struct super_block *sb, int force);
|
|
void fsapi_dfr_update_fat_next(struct super_block *sb);
|
|
void fsapi_dfr_check_discard(struct super_block *sb);
|
|
void fsapi_dfr_free_clus(struct super_block *sb, u32 clus);
|
|
|
|
s32 fsapi_dfr_check_dfr_required(struct super_block *sb, int *totalau, int *cleanau, int *fullau);
|
|
s32 fsapi_dfr_check_dfr_on(struct inode *inode, loff_t start, loff_t end, s32 cancel, const char *caller);
|
|
|
|
|
|
#ifdef CONFIG_SDFAT_DFR_DEBUG
|
|
void fsapi_dfr_spo_test(struct super_block *sb, int flag, const char *caller);
|
|
#endif /* CONFIG_SDFAT_DFR_DEBUG */
|
|
|
|
#endif /* CONFIG_SDFAT_DFR */
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif /* __cplusplus */
|
|
|
|
#endif /* _SDFAT_API_H */
|
|
|
|
/* end of api.h */
|
|
|