aboutsummaryrefslogtreecommitdiff
path: root/fs/exfat/api.h
blob: 5b13c0a1aab1f6956087f08a81b3c7cee34639d9 (plain)
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
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
 */

#ifndef _EXFAT_API_H
#define _EXFAT_API_H

#include "config.h"
#include "exfat_fs.h"

/* 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)

/* 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 EXFAT_EIO_NONE		(0x00000000)
#define EXFAT_EIO_READ		(0x00000001)
#define EXFAT_EIO_WRITE		(0x00000002)
#define EXFAT_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)

/* 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;

/* should be merged it to DATE_TIME_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) */
} TIMESTAMP_T;


typedef struct {
	u16      Year;
	u16      Month;
	u16      Day;
	u16      Hour;
	u16      Minute;
	u16      Second;
	u16      MilliSecond;
} 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      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;

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_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;

	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;

#endif /* _EXFAT_API_H */