Commit | Line | Data |
---|---|---|
45e430a1 PK |
1 | /* |
2 | * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or | |
5 | * modify it under the terms of the GNU General Public License | |
6 | * as published by the Free Software Foundation; either version 2 | |
7 | * of the License, or (at your option) any later version. | |
8 | * | |
9 | * This program is distributed in the hope that it will be useful, | |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | * GNU General Public License for more details. | |
13 | * | |
14 | * You should have received a copy of the GNU General Public License | |
15 | * along with this program; if not, see <http://www.gnu.org/licenses/>. | |
16 | */ | |
17 | ||
18 | #ifndef _SDFAT_FS_H | |
19 | #define _SDFAT_FS_H | |
20 | ||
21 | #include <linux/types.h> | |
22 | #include <linux/magic.h> | |
23 | #include <asm/byteorder.h> | |
24 | ||
25 | /*----------------------------------------------------------------------*/ | |
26 | /* Constant & Macro Definitions */ | |
27 | /*----------------------------------------------------------------------*/ | |
28 | #ifndef MSDOS_SUPER_MAGIC | |
29 | #define MSDOS_SUPER_MAGIC 0x4d44 /* MD */ | |
30 | #endif | |
31 | ||
32 | #ifndef EXFAT_SUPER_MAGIC | |
33 | #define EXFAT_SUPER_MAGIC (0x2011BAB0UL) | |
34 | #endif /* EXFAT_SUPER_MAGIC */ | |
35 | ||
36 | #define SDFAT_SUPER_MAGIC (0x5EC5DFA4UL) | |
37 | #define SDFAT_ROOT_INO 1 | |
38 | ||
39 | /* FAT types */ | |
40 | #define FAT12 0x01 // FAT12 | |
41 | #define FAT16 0x0E // Win95 FAT16 (LBA) | |
42 | #define FAT32 0x0C // Win95 FAT32 (LBA) | |
43 | #define EXFAT 0x07 // exFAT | |
44 | ||
45 | /* directory file name */ | |
46 | #define DOS_CUR_DIR_NAME ". " | |
47 | #define DOS_PAR_DIR_NAME ".. " | |
48 | ||
49 | #ifdef __LITTLE_ENDIAN | |
50 | #define UNI_CUR_DIR_NAME ".\0" | |
51 | #define UNI_PAR_DIR_NAME ".\0.\0" | |
52 | #else | |
53 | #define UNI_CUR_DIR_NAME "\0." | |
54 | #define UNI_PAR_DIR_NAME "\0.\0." | |
55 | #endif | |
56 | ||
57 | /* file name lengths */ | |
58 | /* NOTE : | |
59 | * The maximum length of input or output is limited to 256 including NULL, | |
60 | * But we allocate 4 extra bytes for utf8 translation reside in last position, | |
61 | * because utf8 can uses memory upto 6 bytes per one character. | |
62 | * Therefore, MAX_CHARSET_SIZE supports upto 6 bytes for utf8 | |
63 | */ | |
64 | #define MAX_UNINAME_BUF_SIZE (((MAX_NAME_LENGTH+1)*2)+4) | |
65 | #define MAX_DOSNAME_BUF_SIZE ((DOS_NAME_LENGTH+2)+6) | |
66 | #define MAX_VFSNAME_BUF_SIZE ((MAX_NAME_LENGTH+1)*MAX_CHARSET_SIZE) | |
67 | #define MAX_CHARSET_SIZE 6 // max size of multi-byte character | |
68 | #define MAX_NAME_LENGTH 255 // max len of file name excluding NULL | |
69 | #define DOS_NAME_LENGTH 11 // DOS file name length excluding NULL | |
70 | ||
71 | #define DENTRY_SIZE 32 /* directory entry size */ | |
72 | #define DENTRY_SIZE_BITS 5 | |
73 | ||
74 | #define MAX_FAT_DENTRIES 65536 /* FAT allows 65536 directory entries */ | |
75 | #define MAX_EXFAT_DENTRIES 8388608 /* exFAT allows 8388608(256MB) directory entries */ | |
76 | ||
77 | /* PBR entries */ | |
78 | #define PBR_SIGNATURE 0xAA55 | |
79 | #define EXT_SIGNATURE 0xAA550000 | |
80 | #define VOL_LABEL "NO NAME " /* size should be 11 */ | |
81 | #define OEM_NAME "MSWIN4.1" /* size should be 8 */ | |
82 | #define STR_FAT12 "FAT12 " /* size should be 8 */ | |
83 | #define STR_FAT16 "FAT16 " /* size should be 8 */ | |
84 | #define STR_FAT32 "FAT32 " /* size should be 8 */ | |
85 | #define STR_EXFAT "EXFAT " /* size should be 8 */ | |
86 | ||
87 | #define VOL_CLEAN 0x0000 | |
88 | #define VOL_DIRTY 0x0002 | |
89 | ||
90 | #define FAT_VOL_DIRTY 0x01 | |
91 | ||
92 | /* max number of clusters */ | |
93 | #define FAT12_THRESHOLD 4087 // 2^12 - 1 + 2 (clu 0 & 1) | |
94 | #define FAT16_THRESHOLD 65527 // 2^16 - 1 + 2 | |
95 | #define FAT32_THRESHOLD 268435457 // 2^28 - 1 + 2 | |
96 | #define EXFAT_THRESHOLD 268435457 // 2^28 - 1 + 2 | |
97 | ||
98 | /* dentry types */ | |
99 | #define MSDOS_DELETED 0xE5 /* deleted mark */ | |
100 | #define MSDOS_UNUSED 0x00 /* end of directory */ | |
101 | ||
102 | #define EXFAT_UNUSED 0x00 /* end of directory */ | |
103 | #define IS_EXFAT_DELETED(x) ((x) < 0x80) /* deleted file (0x01~0x7F) */ | |
104 | #define EXFAT_INVAL 0x80 /* invalid value */ | |
105 | #define EXFAT_BITMAP 0x81 /* allocation bitmap */ | |
106 | #define EXFAT_UPCASE 0x82 /* upcase table */ | |
107 | #define EXFAT_VOLUME 0x83 /* volume label */ | |
108 | #define EXFAT_FILE 0x85 /* file or dir */ | |
109 | #define EXFAT_STREAM 0xC0 /* stream entry */ | |
110 | #define EXFAT_NAME 0xC1 /* file name entry */ | |
111 | #define EXFAT_ACL 0xC2 /* stream entry */ | |
112 | ||
113 | /* specific flag */ | |
114 | #define MSDOS_LAST_LFN 0x40 | |
115 | ||
116 | /* file attributes */ | |
117 | #define ATTR_NORMAL 0x0000 | |
118 | #define ATTR_READONLY 0x0001 | |
119 | #define ATTR_HIDDEN 0x0002 | |
120 | #define ATTR_SYSTEM 0x0004 | |
121 | #define ATTR_VOLUME 0x0008 | |
122 | #define ATTR_SUBDIR 0x0010 | |
123 | #define ATTR_ARCHIVE 0x0020 | |
124 | #define ATTR_SYMLINK 0x0040 | |
125 | #define ATTR_EXTEND (ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | \ | |
126 | ATTR_VOLUME) /* 0x000F */ | |
127 | ||
128 | #define ATTR_EXTEND_MASK (ATTR_EXTEND | ATTR_SUBDIR | ATTR_ARCHIVE) | |
129 | #define ATTR_RWMASK (ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME | \ | |
130 | ATTR_SUBDIR | ATTR_ARCHIVE | ATTR_SYMLINK)/* 0x007E */ | |
131 | ||
132 | /* file creation modes */ | |
133 | #define FM_REGULAR 0x00 | |
134 | #define FM_SYMLINK 0x40 | |
135 | ||
136 | /* time modes */ | |
137 | #define TM_CREATE 0 | |
138 | #define TM_MODIFY 1 | |
139 | #define TM_ACCESS 2 | |
140 | ||
141 | /* checksum types */ | |
142 | #define CS_DIR_ENTRY 0 | |
143 | #define CS_PBR_SECTOR 1 | |
144 | #define CS_DEFAULT 2 | |
145 | ||
146 | /* | |
147 | * ioctl command | |
148 | */ | |
149 | #define SDFAT_IOCTL_GET_VOLUME_ID _IOR('r', 0x12, __u32) | |
150 | #define SDFAT_IOCTL_DFR_INFO _IOC(_IOC_NONE, 'E', 0x13, sizeof(u32)) | |
151 | #define SDFAT_IOCTL_DFR_TRAV _IOC(_IOC_NONE, 'E', 0x14, sizeof(u32)) | |
152 | #define SDFAT_IOCTL_DFR_REQ _IOC(_IOC_NONE, 'E', 0x15, sizeof(u32)) | |
153 | #define SDFAT_IOCTL_DFR_SPO_FLAG _IOC(_IOC_NONE, 'E', 0x16, sizeof(u32)) | |
154 | #define SDFAT_IOCTL_PANIC _IOC(_IOC_NONE, 'E', 0x17, sizeof(u32)) | |
155 | ||
156 | /* | |
157 | * ioctl command for debugging | |
158 | */ | |
159 | ||
160 | /* | |
161 | * IOCTL code 'f' used by | |
162 | * - file systems typically #0~0x1F | |
163 | * - embedded terminal devices #128~ | |
164 | * - exts for debugging purpose #99 | |
165 | * number 100 and 101 is available now but has possible conflicts | |
166 | * | |
167 | * NOTE : This is available only If CONFIG_SDFAT_DVBG_IOCTL is enabled. | |
168 | * | |
169 | */ | |
170 | #define SDFAT_IOC_GET_DEBUGFLAGS _IOR('f', 100, long) | |
171 | #define SDFAT_IOC_SET_DEBUGFLAGS _IOW('f', 101, long) | |
172 | ||
173 | #define SDFAT_DEBUGFLAGS_INVALID_UMOUNT 0x01 | |
174 | #define SDFAT_DEBUGFLAGS_ERROR_RW 0x02 | |
175 | ||
176 | /*----------------------------------------------------------------------*/ | |
177 | /* On-Disk Type Definitions */ | |
178 | /*----------------------------------------------------------------------*/ | |
179 | ||
180 | /* FAT12/16 BIOS parameter block (64 bytes) */ | |
181 | typedef struct { | |
182 | __u8 jmp_boot[3]; | |
183 | __u8 oem_name[8]; | |
184 | ||
185 | __u8 sect_size[2]; /* unaligned */ | |
186 | __u8 sect_per_clus; | |
187 | __le16 num_reserved; /* . */ | |
188 | __u8 num_fats; | |
189 | __u8 num_root_entries[2]; /* unaligned */ | |
190 | __u8 num_sectors[2]; /* unaligned */ | |
191 | __u8 media_type; | |
192 | __le16 num_fat_sectors; | |
193 | __le16 sectors_in_track; | |
194 | __le16 num_heads; | |
195 | __le32 num_hid_sectors; /* . */ | |
196 | __le32 num_huge_sectors; | |
197 | ||
198 | __u8 phy_drv_no; | |
199 | __u8 state; /* used by WindowsNT for mount state */ | |
200 | __u8 ext_signature; | |
201 | __u8 vol_serial[4]; | |
202 | __u8 vol_label[11]; | |
203 | __u8 vol_type[8]; | |
204 | __le16 dummy; | |
205 | } bpb16_t; | |
206 | ||
207 | /* FAT32 BIOS parameter block (64 bytes) */ | |
208 | typedef struct { | |
209 | __u8 jmp_boot[3]; | |
210 | __u8 oem_name[8]; | |
211 | ||
212 | __u8 sect_size[2]; /* unaligned */ | |
213 | __u8 sect_per_clus; | |
214 | __le16 num_reserved; | |
215 | __u8 num_fats; | |
216 | __u8 num_root_entries[2]; /* unaligned */ | |
217 | __u8 num_sectors[2]; /* unaligned */ | |
218 | __u8 media_type; | |
219 | __le16 num_fat_sectors; /* zero */ | |
220 | __le16 sectors_in_track; | |
221 | __le16 num_heads; | |
222 | __le32 num_hid_sectors; /* . */ | |
223 | __le32 num_huge_sectors; | |
224 | ||
225 | __le32 num_fat32_sectors; | |
226 | __le16 ext_flags; | |
227 | __u8 fs_version[2]; | |
228 | __le32 root_cluster; /* . */ | |
229 | __le16 fsinfo_sector; | |
230 | __le16 backup_sector; | |
231 | __le16 reserved[6]; /* . */ | |
232 | } bpb32_t; | |
233 | ||
234 | /* FAT32 EXTEND BIOS parameter block (32 bytes) */ | |
235 | typedef struct { | |
236 | __u8 phy_drv_no; | |
237 | __u8 state; /* used by WindowsNT for mount state */ | |
238 | __u8 ext_signature; | |
239 | __u8 vol_serial[4]; | |
240 | __u8 vol_label[11]; | |
241 | __u8 vol_type[8]; | |
242 | __le16 dummy[3]; | |
243 | } bsx32_t; | |
244 | ||
245 | /* EXFAT BIOS parameter block (64 bytes) */ | |
246 | typedef struct { | |
247 | __u8 jmp_boot[3]; | |
248 | __u8 oem_name[8]; | |
249 | __u8 res_zero[53]; | |
250 | } bpb64_t; | |
251 | ||
252 | /* EXFAT EXTEND BIOS parameter block (56 bytes) */ | |
253 | typedef struct { | |
254 | __le64 vol_offset; | |
255 | __le64 vol_length; | |
256 | __le32 fat_offset; | |
257 | __le32 fat_length; | |
258 | __le32 clu_offset; | |
259 | __le32 clu_count; | |
260 | __le32 root_cluster; | |
261 | __le32 vol_serial; | |
262 | __u8 fs_version[2]; | |
263 | __le16 vol_flags; | |
264 | __u8 sect_size_bits; | |
265 | __u8 sect_per_clus_bits; | |
266 | __u8 num_fats; | |
267 | __u8 phy_drv_no; | |
268 | __u8 perc_in_use; | |
269 | __u8 reserved2[7]; | |
270 | } bsx64_t; | |
271 | ||
272 | /* FAT32 PBR (64 bytes) */ | |
273 | typedef struct { | |
274 | bpb16_t bpb; | |
275 | } pbr16_t; | |
276 | ||
277 | /* FAT32 PBR[BPB+BSX] (96 bytes) */ | |
278 | typedef struct { | |
279 | bpb32_t bpb; | |
280 | bsx32_t bsx; | |
281 | } pbr32_t; | |
282 | ||
283 | /* EXFAT PBR[BPB+BSX] (120 bytes) */ | |
284 | typedef struct { | |
285 | bpb64_t bpb; | |
286 | bsx64_t bsx; | |
287 | } pbr64_t; | |
288 | ||
289 | /* Common PBR[Partition Boot Record] (512 bytes) */ | |
290 | typedef struct { | |
291 | union { | |
292 | __u8 raw[64]; | |
293 | bpb16_t f16; | |
294 | bpb32_t f32; | |
295 | bpb64_t f64; | |
296 | } bpb; | |
297 | union { | |
298 | __u8 raw[56]; | |
299 | bsx32_t f32; | |
300 | bsx64_t f64; | |
301 | } bsx; | |
302 | __u8 boot_code[390]; | |
303 | __le16 signature; | |
304 | } pbr_t; | |
305 | ||
306 | /* FAT32 filesystem information sector (512 bytes) */ | |
307 | typedef struct { | |
308 | __le32 signature1; // aligned | |
309 | __u8 reserved1[480]; | |
310 | __le32 signature2; // aligned | |
311 | __le32 free_cluster; // aligned | |
312 | __le32 next_cluster; // aligned | |
313 | __u8 reserved2[14]; | |
314 | __le16 signature3[2]; | |
315 | } fat32_fsi_t; | |
316 | ||
317 | /* FAT directory entry (32 bytes) */ | |
318 | typedef struct { | |
319 | __u8 dummy[32]; | |
320 | } DENTRY_T; | |
321 | ||
322 | typedef struct { | |
323 | __u8 name[DOS_NAME_LENGTH]; /* 11 chars */ | |
324 | __u8 attr; | |
325 | __u8 lcase; | |
326 | __u8 create_time_ms; | |
327 | __le16 create_time; // aligned | |
328 | __le16 create_date; // aligned | |
329 | __le16 access_date; // aligned | |
330 | __le16 start_clu_hi; // aligned | |
331 | __le16 modify_time; // aligned | |
332 | __le16 modify_date; // aligned | |
333 | __le16 start_clu_lo; // aligned | |
334 | __le32 size; // aligned | |
335 | } DOS_DENTRY_T; | |
336 | ||
337 | /* FAT extended directory entry (32 bytes) */ | |
338 | typedef struct { | |
339 | __u8 order; | |
340 | __u8 unicode_0_4[10]; | |
341 | __u8 attr; | |
342 | __u8 sysid; | |
343 | __u8 checksum; | |
344 | __le16 unicode_5_10[6]; // aligned | |
345 | __le16 start_clu; // aligned | |
346 | __le16 unicode_11_12[2]; // aligned | |
347 | } EXT_DENTRY_T; | |
348 | ||
349 | /* EXFAT file directory entry (32 bytes) */ | |
350 | typedef struct { | |
351 | __u8 type; | |
352 | __u8 num_ext; | |
353 | __le16 checksum; // aligned | |
354 | __le16 attr; // aligned | |
355 | __le16 reserved1; | |
356 | __le16 create_time; // aligned | |
357 | __le16 create_date; // aligned | |
358 | __le16 modify_time; // aligned | |
359 | __le16 modify_date; // aligned | |
360 | __le16 access_time; // aligned | |
361 | __le16 access_date; // aligned | |
362 | __u8 create_time_ms; | |
363 | __u8 modify_time_ms; | |
364 | __u8 access_time_ms; | |
365 | __u8 reserved2[9]; | |
366 | } FILE_DENTRY_T; | |
367 | ||
368 | /* EXFAT stream extension directory entry (32 bytes) */ | |
369 | typedef struct { | |
370 | __u8 type; | |
371 | __u8 flags; | |
372 | __u8 reserved1; | |
373 | __u8 name_len; | |
374 | __le16 name_hash; // aligned | |
375 | __le16 reserved2; | |
376 | __le64 valid_size; // aligned | |
377 | __le32 reserved3; // aligned | |
378 | __le32 start_clu; // aligned | |
379 | __le64 size; // aligned | |
380 | } STRM_DENTRY_T; | |
381 | ||
382 | /* EXFAT file name directory entry (32 bytes) */ | |
383 | typedef struct { | |
384 | __u8 type; | |
385 | __u8 flags; | |
386 | __le16 unicode_0_14[15]; // aligned | |
387 | } NAME_DENTRY_T; | |
388 | ||
389 | /* EXFAT allocation bitmap directory entry (32 bytes) */ | |
390 | typedef struct { | |
391 | __u8 type; | |
392 | __u8 flags; | |
393 | __u8 reserved[18]; | |
394 | __le32 start_clu; // aligned | |
395 | __le64 size; // aligned | |
396 | } BMAP_DENTRY_T; | |
397 | ||
398 | /* EXFAT up-case table directory entry (32 bytes) */ | |
399 | typedef struct { | |
400 | __u8 type; | |
401 | __u8 reserved1[3]; | |
402 | __le32 checksum; // aligned | |
403 | __u8 reserved2[12]; | |
404 | __le32 start_clu; // aligned | |
405 | __le64 size; // aligned | |
406 | } CASE_DENTRY_T; | |
407 | ||
408 | /* EXFAT volume label directory entry (32 bytes) */ | |
409 | typedef struct { | |
410 | __u8 type; | |
411 | __u8 label_len; | |
412 | __le16 unicode_0_10[11]; // aligned | |
413 | __u8 reserved[8]; | |
414 | } VOLM_DENTRY_T; | |
415 | ||
416 | #endif /* _SDFAT_FS_H */ |