forked from cryptomilk/kernel-sdfat
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapi.h
409 lines (348 loc) · 14.2 KB
/
api.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
/*
* 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 */