2 * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
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.
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.
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/>.
18 /************************************************************************/
20 /* PROJECT : exFAT & FAT12/16/32 File System */
21 /* FILE : core_exfat.c */
22 /* PURPOSE : exFAT-fs core code for sdFAT */
24 /*----------------------------------------------------------------------*/
28 /************************************************************************/
30 #include <linux/version.h>
31 #include <linux/blkdev.h>
32 #include <linux/workqueue.h>
33 #include <linux/kernel.h>
34 #include <linux/log2.h>
38 #include <asm/byteorder.h>
39 #include <asm/unaligned.h>
41 /*----------------------------------------------------------------------*/
42 /* Constant & Macro Definitions */
43 /*----------------------------------------------------------------------*/
45 /*----------------------------------------------------------------------*/
46 /* Global Variable Definitions */
47 /*----------------------------------------------------------------------*/
49 /*----------------------------------------------------------------------*/
50 /* Local Variable Definitions */
51 /*----------------------------------------------------------------------*/
52 static u8 free_bit
[] = {
53 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2,/* 0 ~ 19*/
54 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3,/* 20 ~ 39*/
55 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2,/* 40 ~ 59*/
56 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4,/* 60 ~ 79*/
57 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2,/* 80 ~ 99*/
58 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3,/*100 ~ 119*/
59 0, 1, 0, 2, 0, 1, 0, 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2,/*120 ~ 139*/
60 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5,/*140 ~ 159*/
61 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2,/*160 ~ 179*/
62 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3,/*180 ~ 199*/
63 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2,/*200 ~ 219*/
64 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4,/*220 ~ 239*/
65 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 /*240 ~ 254*/
68 static u8 used_bit
[] = {
69 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3,/* 0 ~ 19*/
70 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4,/* 20 ~ 39*/
71 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5,/* 40 ~ 59*/
72 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,/* 60 ~ 79*/
73 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4,/* 80 ~ 99*/
74 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,/*100 ~ 119*/
75 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4,/*120 ~ 139*/
76 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,/*140 ~ 159*/
77 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5,/*160 ~ 179*/
78 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5,/*180 ~ 199*/
79 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6,/*200 ~ 219*/
80 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,/*220 ~ 239*/
81 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 /*240 ~ 255*/
85 /*======================================================================*/
86 /* Local Function Definitions */
87 /*======================================================================*/
89 * Directory Entry Management Functions
91 static u32
exfat_get_entry_type(DENTRY_T
*p_entry
)
93 FILE_DENTRY_T
*ep
= (FILE_DENTRY_T
*) p_entry
;
95 if (ep
->type
== EXFAT_UNUSED
)
101 if (ep
->type
< 0xA0) {
102 if (ep
->type
== 0x81)
104 if (ep
->type
== 0x82)
106 if (ep
->type
== 0x83)
108 if (ep
->type
== 0x85) {
109 if (le16_to_cpu(ep
->attr
) & ATTR_SUBDIR
)
113 return TYPE_CRITICAL_PRI
;
115 if (ep
->type
< 0xC0) {
116 if (ep
->type
== 0xA0)
118 if (ep
->type
== 0xA1)
120 if (ep
->type
== 0xA2)
122 return TYPE_BENIGN_PRI
;
124 if (ep
->type
< 0xE0) {
125 if (ep
->type
== 0xC0)
127 if (ep
->type
== 0xC1)
129 if (ep
->type
== 0xC2)
131 return TYPE_CRITICAL_SEC
;
133 return TYPE_BENIGN_SEC
;
134 } /* end of exfat_get_entry_type */
136 static void exfat_set_entry_type(DENTRY_T
*p_entry
, u32 type
)
138 FILE_DENTRY_T
*ep
= (FILE_DENTRY_T
*) p_entry
;
140 if (type
== TYPE_UNUSED
) {
142 } else if (type
== TYPE_DELETED
) {
144 } else if (type
== TYPE_STREAM
) {
146 } else if (type
== TYPE_EXTEND
) {
148 } else if (type
== TYPE_BITMAP
) {
150 } else if (type
== TYPE_UPCASE
) {
152 } else if (type
== TYPE_VOLUME
) {
154 } else if (type
== TYPE_DIR
) {
156 ep
->attr
= cpu_to_le16(ATTR_SUBDIR
);
157 } else if (type
== TYPE_FILE
) {
159 ep
->attr
= cpu_to_le16(ATTR_ARCHIVE
);
160 } else if (type
== TYPE_SYMLINK
) {
162 ep
->attr
= cpu_to_le16(ATTR_ARCHIVE
| ATTR_SYMLINK
);
164 } /* end of exfat_set_entry_type */
166 static u32
exfat_get_entry_attr(DENTRY_T
*p_entry
)
168 FILE_DENTRY_T
*ep
= (FILE_DENTRY_T
*)p_entry
;
170 return (u32
)le16_to_cpu(ep
->attr
);
171 } /* end of exfat_get_entry_attr */
173 static void exfat_set_entry_attr(DENTRY_T
*p_entry
, u32 attr
)
175 FILE_DENTRY_T
*ep
= (FILE_DENTRY_T
*)p_entry
;
177 ep
->attr
= cpu_to_le16((u16
) attr
);
178 } /* end of exfat_set_entry_attr */
180 static u8
exfat_get_entry_flag(DENTRY_T
*p_entry
)
182 STRM_DENTRY_T
*ep
= (STRM_DENTRY_T
*)p_entry
;
185 } /* end of exfat_get_entry_flag */
187 static void exfat_set_entry_flag(DENTRY_T
*p_entry
, u8 flags
)
189 STRM_DENTRY_T
*ep
= (STRM_DENTRY_T
*)p_entry
;
192 } /* end of exfat_set_entry_flag */
194 static u32
exfat_get_entry_clu0(DENTRY_T
*p_entry
)
196 STRM_DENTRY_T
*ep
= (STRM_DENTRY_T
*)p_entry
;
198 return (u32
)le32_to_cpu(ep
->start_clu
);
199 } /* end of exfat_get_entry_clu0 */
201 static void exfat_set_entry_clu0(DENTRY_T
*p_entry
, u32 start_clu
)
203 STRM_DENTRY_T
*ep
= (STRM_DENTRY_T
*)p_entry
;
205 ep
->start_clu
= cpu_to_le32(start_clu
);
206 } /* end of exfat_set_entry_clu0 */
208 static u64
exfat_get_entry_size(DENTRY_T
*p_entry
)
210 STRM_DENTRY_T
*ep
= (STRM_DENTRY_T
*)p_entry
;
212 return le64_to_cpu(ep
->valid_size
);
213 } /* end of exfat_get_entry_size */
215 static void exfat_set_entry_size(DENTRY_T
*p_entry
, u64 size
)
217 STRM_DENTRY_T
*ep
= (STRM_DENTRY_T
*)p_entry
;
219 ep
->valid_size
= cpu_to_le64(size
);
220 ep
->size
= cpu_to_le64(size
);
221 } /* end of exfat_set_entry_size */
223 static void exfat_get_entry_time(DENTRY_T
*p_entry
, TIMESTAMP_T
*tp
, u8 mode
)
225 u16 t
= 0x00, d
= 0x21;
226 FILE_DENTRY_T
*ep
= (FILE_DENTRY_T
*)p_entry
;
230 t
= le16_to_cpu(ep
->create_time
);
231 d
= le16_to_cpu(ep
->create_date
);
234 t
= le16_to_cpu(ep
->modify_time
);
235 d
= le16_to_cpu(ep
->modify_date
);
238 t
= le16_to_cpu(ep
->access_time
);
239 d
= le16_to_cpu(ep
->access_date
);
243 tp
->sec
= (t
& 0x001F) << 1;
244 tp
->min
= (t
>> 5) & 0x003F;
245 tp
->hour
= (t
>> 11);
246 tp
->day
= (d
& 0x001F);
247 tp
->mon
= (d
>> 5) & 0x000F;
249 } /* end of exfat_get_entry_time */
251 static void exfat_set_entry_time(DENTRY_T
*p_entry
, TIMESTAMP_T
*tp
, u8 mode
)
254 FILE_DENTRY_T
*ep
= (FILE_DENTRY_T
*)p_entry
;
256 t
= (tp
->hour
<< 11) | (tp
->min
<< 5) | (tp
->sec
>> 1);
257 d
= (tp
->year
<< 9) | (tp
->mon
<< 5) | tp
->day
;
261 ep
->create_time
= cpu_to_le16(t
);
262 ep
->create_date
= cpu_to_le16(d
);
265 ep
->modify_time
= cpu_to_le16(t
);
266 ep
->modify_date
= cpu_to_le16(d
);
269 ep
->access_time
= cpu_to_le16(t
);
270 ep
->access_date
= cpu_to_le16(d
);
273 } /* end of exfat_set_entry_time */
276 static void __init_file_entry(struct super_block
*sb
, FILE_DENTRY_T
*ep
, u32 type
)
280 exfat_set_entry_type((DENTRY_T
*) ep
, type
);
282 tp
= tm_now(SDFAT_SB(sb
), &tm
);
283 exfat_set_entry_time((DENTRY_T
*) ep
, tp
, TM_CREATE
);
284 exfat_set_entry_time((DENTRY_T
*) ep
, tp
, TM_MODIFY
);
285 exfat_set_entry_time((DENTRY_T
*) ep
, tp
, TM_ACCESS
);
286 ep
->create_time_ms
= 0;
287 ep
->modify_time_ms
= 0;
288 ep
->access_time_ms
= 0;
289 } /* end of __init_file_entry */
291 static void __init_strm_entry(STRM_DENTRY_T
*ep
, u8 flags
, u32 start_clu
, u64 size
)
293 exfat_set_entry_type((DENTRY_T
*) ep
, TYPE_STREAM
);
295 ep
->start_clu
= cpu_to_le32(start_clu
);
296 ep
->valid_size
= cpu_to_le64(size
);
297 ep
->size
= cpu_to_le64(size
);
298 } /* end of __init_strm_entry */
300 static void __init_name_entry(NAME_DENTRY_T
*ep
, u16
*uniname
)
304 exfat_set_entry_type((DENTRY_T
*) ep
, TYPE_EXTEND
);
307 for (i
= 0; i
< 15; i
++) {
308 ep
->unicode_0_14
[i
] = cpu_to_le16(*uniname
);
313 } /* end of __init_name_entry */
315 static s32
exfat_init_dir_entry(struct super_block
*sb
, CHAIN_T
*p_dir
, s32 entry
, u32 type
, u32 start_clu
, u64 size
)
319 FILE_DENTRY_T
*file_ep
;
320 STRM_DENTRY_T
*strm_ep
;
322 flags
= (type
== TYPE_FILE
) ? 0x01 : 0x03;
324 /* we cannot use get_dentry_set_in_dir here because file ep is not initialized yet */
325 file_ep
= (FILE_DENTRY_T
*)get_dentry_in_dir(sb
, p_dir
, entry
, §or
);
329 strm_ep
= (STRM_DENTRY_T
*)get_dentry_in_dir(sb
, p_dir
, entry
+1, §or
);
333 __init_file_entry(sb
, file_ep
, type
);
334 if (dcache_modify(sb
, sector
))
337 __init_strm_entry(strm_ep
, flags
, start_clu
, size
);
338 if (dcache_modify(sb
, sector
))
342 } /* end of exfat_init_dir_entry */
344 s32
update_dir_chksum(struct super_block
*sb
, CHAIN_T
*p_dir
, s32 entry
)
350 FILE_DENTRY_T
*file_ep
;
353 file_ep
= (FILE_DENTRY_T
*)get_dentry_in_dir(sb
, p_dir
, entry
, §or
);
357 dcache_lock(sb
, sector
);
359 num_entries
= (s32
) file_ep
->num_ext
+ 1;
360 chksum
= calc_chksum_2byte((void *) file_ep
, DENTRY_SIZE
, 0, CS_DIR_ENTRY
);
362 for (i
= 1; i
< num_entries
; i
++) {
363 ep
= get_dentry_in_dir(sb
, p_dir
, entry
+i
, NULL
);
367 chksum
= calc_chksum_2byte((void *) ep
, DENTRY_SIZE
, chksum
, CS_DEFAULT
);
370 file_ep
->checksum
= cpu_to_le16(chksum
);
371 ret
= dcache_modify(sb
, sector
);
373 dcache_unlock(sb
, sector
);
376 } /* end of update_dir_chksum */
379 static s32
exfat_init_ext_entry(struct super_block
*sb
, CHAIN_T
*p_dir
, s32 entry
, s32 num_entries
,
380 UNI_NAME_T
*p_uniname
, DOS_NAME_T
*p_dosname
)
384 u16
*uniname
= p_uniname
->name
;
385 FILE_DENTRY_T
*file_ep
;
386 STRM_DENTRY_T
*strm_ep
;
387 NAME_DENTRY_T
*name_ep
;
389 file_ep
= (FILE_DENTRY_T
*)get_dentry_in_dir(sb
, p_dir
, entry
, §or
);
393 file_ep
->num_ext
= (u8
)(num_entries
- 1);
394 dcache_modify(sb
, sector
);
396 strm_ep
= (STRM_DENTRY_T
*)get_dentry_in_dir(sb
, p_dir
, entry
+1, §or
);
400 strm_ep
->name_len
= p_uniname
->name_len
;
401 strm_ep
->name_hash
= cpu_to_le16(p_uniname
->name_hash
);
402 dcache_modify(sb
, sector
);
404 for (i
= 2; i
< num_entries
; i
++) {
405 name_ep
= (NAME_DENTRY_T
*)get_dentry_in_dir(sb
, p_dir
, entry
+i
, §or
);
409 __init_name_entry(name_ep
, uniname
);
410 dcache_modify(sb
, sector
);
414 update_dir_chksum(sb
, p_dir
, entry
);
417 } /* end of exfat_init_ext_entry */
420 static s32
exfat_delete_dir_entry(struct super_block
*sb
, CHAIN_T
*p_dir
, s32 entry
, s32 order
, s32 num_entries
)
426 for (i
= order
; i
< num_entries
; i
++) {
427 ep
= get_dentry_in_dir(sb
, p_dir
, entry
+i
, §or
);
431 exfat_set_entry_type(ep
, TYPE_DELETED
);
432 if (dcache_modify(sb
, sector
))
439 static s32
__write_partial_entries_in_entry_set(struct super_block
*sb
,
440 ENTRY_SET_CACHE_T
*es
, u32 sec
, s32 off
, u32 count
)
442 s32 num_entries
, buf_off
= (off
- es
->offset
);
443 u32 remaining_byte_in_sector
, copy_entries
;
444 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
446 u8
*buf
, *esbuf
= (u8
*)&(es
->__buf
);
448 TMSG("%s entered\n", __func__
);
449 MMSG("%s: es %p sec %u off %d cnt %d\n", __func__
, es
, sec
, off
, count
);
452 while (num_entries
) {
453 /* write per sector base */
454 remaining_byte_in_sector
= (1 << sb
->s_blocksize_bits
) - off
;
455 copy_entries
= min((s32
)(remaining_byte_in_sector
>> DENTRY_SIZE_BITS
), num_entries
);
456 buf
= dcache_getblk(sb
, sec
);
459 MMSG("es->buf %p buf_off %u\n", esbuf
, buf_off
);
460 MMSG("copying %d entries from %p to sector %u\n", copy_entries
, (esbuf
+ buf_off
), sec
);
461 memcpy(buf
+ off
, esbuf
+ buf_off
, copy_entries
<< DENTRY_SIZE_BITS
);
462 dcache_modify(sb
, sec
);
463 num_entries
-= copy_entries
;
467 if (IS_LAST_SECT_IN_CLUS(fsi
, sec
)) {
468 clu
= SECT_TO_CLUS(fsi
, sec
);
469 if (es
->alloc_flag
== 0x03)
471 else if (get_next_clus_safe(sb
, &clu
))
473 sec
= CLUS_TO_SECT(fsi
, clu
);
478 buf_off
+= copy_entries
<< DENTRY_SIZE_BITS
;
482 TMSG("%s exited successfully\n", __func__
);
485 TMSG("%s failed\n", __func__
);
489 /* write back all entries in entry set */
490 static s32
__write_whole_entry_set(struct super_block
*sb
, ENTRY_SET_CACHE_T
*es
)
492 return __write_partial_entries_in_entry_set(sb
, es
, es
->sector
, es
->offset
, es
->num_entries
);
495 s32
update_dir_chksum_with_entry_set(struct super_block
*sb
, ENTRY_SET_CACHE_T
*es
)
499 s32 chksum_type
= CS_DIR_ENTRY
, i
;
501 ep
= (DENTRY_T
*)&(es
->__buf
);
502 for (i
= 0; i
< es
->num_entries
; i
++) {
503 MMSG("%s %p\n", __func__
, ep
);
504 chksum
= calc_chksum_2byte((void *) ep
, DENTRY_SIZE
, chksum
, chksum_type
);
506 chksum_type
= CS_DEFAULT
;
509 ep
= (DENTRY_T
*)&(es
->__buf
);
510 ((FILE_DENTRY_T
*)ep
)->checksum
= cpu_to_le16(chksum
);
511 return __write_whole_entry_set(sb
, es
);
514 /* returns a set of dentries for a file or dir.
515 * Note that this is a copy (dump) of dentries so that user should call write_entry_set()
516 * to apply changes made in this entry set to the real device.
518 * sb+p_dir+entry: indicates a file/dir
519 * type: specifies how many dentries should be included.
521 * file_ep: will point the first dentry(= file dentry) on success
523 * pointer of entry set on success,
527 #define ES_MODE_STARTED 0
528 #define ES_MODE_GET_FILE_ENTRY 1
529 #define ES_MODE_GET_STRM_ENTRY 2
530 #define ES_MODE_GET_NAME_ENTRY 3
531 #define ES_MODE_GET_CRITICAL_SEC_ENTRY 4
532 ENTRY_SET_CACHE_T
*get_dentry_set_in_dir(struct super_block
*sb
,
533 CHAIN_T
*p_dir
, s32 entry
, u32 type
, DENTRY_T
**file_ep
)
535 s32 off
, ret
, byte_offset
;
538 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
539 ENTRY_SET_CACHE_T
*es
= NULL
;
543 s32 mode
= ES_MODE_STARTED
;
545 /* FIXME : is available in error case? */
546 if (p_dir
->dir
== DIR_DELETED
) {
547 EMSG("%s : access to deleted dentry\n", __func__
);
548 BUG_ON(!fsi
->prev_eio
);
552 TMSG("%s entered\n", __func__
);
553 MMSG("p_dir dir %u flags %x size %d\n", p_dir
->dir
, p_dir
->flags
, p_dir
->size
);
554 MMSG("entry %d type %d\n", entry
, type
);
556 byte_offset
= entry
<< DENTRY_SIZE_BITS
;
557 ret
= walk_fat_chain(sb
, p_dir
, byte_offset
, &clu
);
561 /* byte offset in cluster */
562 byte_offset
&= fsi
->cluster_size
- 1;
564 /* byte offset in sector */
565 off
= byte_offset
& (u32
)(sb
->s_blocksize
- 1);
567 /* sector offset in cluster */
568 sec
= byte_offset
>> (sb
->s_blocksize_bits
);
569 sec
+= CLUS_TO_SECT(fsi
, clu
);
571 buf
= dcache_getblk(sb
, sec
);
575 ep
= (DENTRY_T
*)(buf
+ off
);
576 entry_type
= exfat_get_entry_type(ep
);
578 if ((entry_type
!= TYPE_FILE
)
579 && (entry_type
!= TYPE_DIR
))
582 if (type
== ES_ALL_ENTRIES
)
583 num_entries
= ((FILE_DENTRY_T
*)ep
)->num_ext
+1;
587 MMSG("trying to malloc %lx bytes for %d entries\n",
588 (unsigned long)(offsetof(ENTRY_SET_CACHE_T
, __buf
) + (num_entries
) * sizeof(DENTRY_T
)), num_entries
);
589 es
= kmalloc((offsetof(ENTRY_SET_CACHE_T
, __buf
) + (num_entries
) * sizeof(DENTRY_T
)), GFP_KERNEL
);
591 EMSG("%s: failed to alloc entryset\n", __func__
);
595 es
->num_entries
= num_entries
;
598 es
->alloc_flag
= p_dir
->flags
;
600 pos
= (DENTRY_T
*) &(es
->__buf
);
602 while (num_entries
) {
603 // instead of copying whole sector, we will check every entry.
604 // this will provide minimum stablity and consistency.
605 entry_type
= exfat_get_entry_type(ep
);
607 if ((entry_type
== TYPE_UNUSED
) || (entry_type
== TYPE_DELETED
))
611 case ES_MODE_STARTED
:
612 if ((entry_type
== TYPE_FILE
) || (entry_type
== TYPE_DIR
))
613 mode
= ES_MODE_GET_FILE_ENTRY
;
617 case ES_MODE_GET_FILE_ENTRY
:
618 if (entry_type
== TYPE_STREAM
)
619 mode
= ES_MODE_GET_STRM_ENTRY
;
623 case ES_MODE_GET_STRM_ENTRY
:
624 if (entry_type
== TYPE_EXTEND
)
625 mode
= ES_MODE_GET_NAME_ENTRY
;
629 case ES_MODE_GET_NAME_ENTRY
:
630 if (entry_type
== TYPE_EXTEND
)
632 else if (entry_type
== TYPE_STREAM
)
634 else if (entry_type
& TYPE_CRITICAL_SEC
)
635 mode
= ES_MODE_GET_CRITICAL_SEC_ENTRY
;
639 case ES_MODE_GET_CRITICAL_SEC_ENTRY
:
640 if ((entry_type
== TYPE_EXTEND
) || (entry_type
== TYPE_STREAM
))
642 else if ((entry_type
& TYPE_CRITICAL_SEC
) != TYPE_CRITICAL_SEC
)
648 memcpy(pos
, ep
, sizeof(DENTRY_T
));
650 if (--num_entries
== 0)
653 if (((off
+ DENTRY_SIZE
) & (u32
)(sb
->s_blocksize
- 1)) <
654 (off
& (u32
)(sb
->s_blocksize
- 1))) {
655 // get the next sector
656 if (IS_LAST_SECT_IN_CLUS(fsi
, sec
)) {
657 if (es
->alloc_flag
== 0x03)
659 else if (get_next_clus_safe(sb
, &clu
))
661 sec
= CLUS_TO_SECT(fsi
, clu
);
665 buf
= dcache_getblk(sb
, sec
);
669 ep
= (DENTRY_T
*)(buf
);
678 *file_ep
= (DENTRY_T
*)&(es
->__buf
);
680 MMSG("es sec %u offset %d flags %d, num_entries %u buf ptr %p\n",
681 es
->sector
, es
->offset
, es
->alloc_flag
, es
->num_entries
, &(es
->__buf
));
682 TMSG("%s exited %p\n", __func__
, es
);
685 TMSG("%s exited (return NULL) (es %p)\n", __func__
, es
);
687 /* kfree(NULL) is safe */
693 void release_dentry_set(ENTRY_SET_CACHE_T
*es
)
695 TMSG("%s %p\n", __func__
, es
);
697 /* kfree(NULL) is safe */
702 static s32
__extract_uni_name_from_name_entry(NAME_DENTRY_T
*ep
, u16
*uniname
, s32 order
)
706 for (i
= 0; i
< 15; i
++) {
707 /* FIXME : unaligned? */
708 *uniname
= le16_to_cpu(ep
->unicode_0_14
[i
]);
717 } /* end of __extract_uni_name_from_name_entry */
719 #define DIRENT_STEP_FILE (0)
720 #define DIRENT_STEP_STRM (1)
721 #define DIRENT_STEP_NAME (2)
722 #define DIRENT_STEP_SECD (3)
724 /* return values of exfat_find_dir_entry()
725 * >= 0 : return dir entiry position with the name in dir
726 * -EEXIST : (root dir, ".") it is the root dir itself
727 * -ENOENT : entry with the name does not exist
730 static s32
exfat_find_dir_entry(struct super_block
*sb
, FILE_ID_T
*fid
,
731 CHAIN_T
*p_dir
, UNI_NAME_T
*p_uniname
, s32 num_entries
, DOS_NAME_T
*unused
, u32 type
)
733 s32 i
, rewind
= 0, dentry
= 0, end_eidx
= 0, num_ext
= 0, len
;
734 s32 order
, step
, name_len
;
735 s32 dentries_per_clu
, num_empty
= 0;
737 u16 entry_uniname
[16], *uniname
= NULL
, unichar
;
740 HINT_T
*hint_stat
= &fid
->hint_stat
;
741 HINT_FEMP_T candi_empty
;
742 FILE_DENTRY_T
*file_ep
;
743 STRM_DENTRY_T
*strm_ep
;
744 NAME_DENTRY_T
*name_ep
;
745 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
749 * DOT and DOTDOT are handled by VFS layer
752 if (IS_CLUS_FREE(p_dir
->dir
))
755 dentries_per_clu
= fsi
->dentries_per_clu
;
757 clu
.dir
= p_dir
->dir
;
758 clu
.size
= p_dir
->size
;
759 clu
.flags
= p_dir
->flags
;
761 if (hint_stat
->eidx
) {
762 clu
.dir
= hint_stat
->clu
;
763 dentry
= hint_stat
->eidx
;
767 candi_empty
.eidx
= -1;
770 step
= DIRENT_STEP_FILE
;
771 while (!IS_CLUS_EOF(clu
.dir
)) {
772 i
= dentry
& (dentries_per_clu
- 1);
773 for (; i
< dentries_per_clu
; i
++, dentry
++) {
774 if (rewind
&& (dentry
== end_eidx
))
777 ep
= get_dentry_in_dir(sb
, &clu
, i
, NULL
);
781 entry_type
= exfat_get_entry_type(ep
);
783 if ((entry_type
== TYPE_UNUSED
) || (entry_type
== TYPE_DELETED
)) {
784 step
= DIRENT_STEP_FILE
;
787 if (candi_empty
.eidx
== -1) {
788 if (num_empty
== 1) {
789 candi_empty
.cur
.dir
= clu
.dir
;
790 candi_empty
.cur
.size
= clu
.size
;
791 candi_empty
.cur
.flags
= clu
.flags
;
794 if (num_empty
>= num_entries
) {
795 candi_empty
.eidx
= dentry
- (num_empty
- 1);
796 ASSERT(0 <= candi_empty
.eidx
);
797 candi_empty
.count
= num_empty
;
799 if ((fid
->hint_femp
.eidx
== -1) ||
800 (candi_empty
.eidx
<= fid
->hint_femp
.eidx
)) {
801 memcpy(&fid
->hint_femp
,
803 sizeof(HINT_FEMP_T
));
808 if (entry_type
== TYPE_UNUSED
)
814 candi_empty
.eidx
= -1;
816 if ((entry_type
== TYPE_FILE
) || (entry_type
== TYPE_DIR
)) {
817 step
= DIRENT_STEP_FILE
;
818 if ((type
== TYPE_ALL
) || (type
== entry_type
)) {
819 file_ep
= (FILE_DENTRY_T
*) ep
;
820 num_ext
= file_ep
->num_ext
;
821 step
= DIRENT_STEP_STRM
;
826 if (entry_type
== TYPE_STREAM
) {
827 if (step
!= DIRENT_STEP_STRM
) {
828 step
= DIRENT_STEP_FILE
;
831 step
= DIRENT_STEP_FILE
;
832 strm_ep
= (STRM_DENTRY_T
*) ep
;
833 if ((p_uniname
->name_hash
== le16_to_cpu(strm_ep
->name_hash
)) &&
834 (p_uniname
->name_len
== strm_ep
->name_len
)) {
835 step
= DIRENT_STEP_NAME
;
842 if (entry_type
== TYPE_EXTEND
) {
843 if (step
!= DIRENT_STEP_NAME
) {
844 step
= DIRENT_STEP_FILE
;
847 name_ep
= (NAME_DENTRY_T
*) ep
;
850 uniname
= p_uniname
->name
;
854 len
= __extract_uni_name_from_name_entry(name_ep
, entry_uniname
, order
);
857 unichar
= *(uniname
+len
);
858 *(uniname
+len
) = 0x0;
860 if (nls_cmp_uniname(sb
, uniname
, entry_uniname
)) {
861 step
= DIRENT_STEP_FILE
;
862 } else if (name_len
== p_uniname
->name_len
) {
863 if (order
== num_ext
) {
864 //fid->hint_femp.eidx = -1;
867 step
= DIRENT_STEP_SECD
;
870 *(uniname
+len
) = unichar
;
874 if (entry_type
& (TYPE_CRITICAL_SEC
| TYPE_BENIGN_SEC
)) {
875 if (step
== DIRENT_STEP_SECD
) {
876 if (++order
== num_ext
)
881 step
= DIRENT_STEP_FILE
;
884 if (clu
.flags
== 0x03) {
885 if ((--clu
.size
) > 0)
890 if (get_next_clus_safe(sb
, &clu
.dir
))
896 /* we started at not 0 index,so we should try to find target
897 * from 0 index to the index we started at.
899 if (!rewind
&& end_eidx
) {
902 clu
.dir
= p_dir
->dir
;
903 /* reset empty hint */
905 candi_empty
.eidx
= -1;
909 /* initialized hint_stat */
910 hint_stat
->clu
= p_dir
->dir
;
915 /* next dentry we'll find is out of this cluster */
916 if (!((dentry
+ 1) & (dentries_per_clu
-1))) {
919 if (clu
.flags
== 0x03) {
920 if ((--clu
.size
) > 0)
925 ret
= get_next_clus_safe(sb
, &clu
.dir
);
928 if (ret
|| IS_CLUS_EOF(clu
.dir
)) {
929 /* just initialized hint_stat */
930 hint_stat
->clu
= p_dir
->dir
;
932 return (dentry
- num_ext
);
936 hint_stat
->clu
= clu
.dir
;
937 hint_stat
->eidx
= dentry
+ 1;
938 return (dentry
- num_ext
);
939 } /* end of exfat_find_dir_entry */
941 /* returns -EIO on error */
942 static s32
exfat_count_ext_entries(struct super_block
*sb
, CHAIN_T
*p_dir
, s32 entry
, DENTRY_T
*p_entry
)
946 FILE_DENTRY_T
*file_ep
= (FILE_DENTRY_T
*) p_entry
;
949 for (i
= 0, entry
++; i
< file_ep
->num_ext
; i
++, entry
++) {
950 ext_ep
= get_dentry_in_dir(sb
, p_dir
, entry
, NULL
);
954 type
= exfat_get_entry_type(ext_ep
);
955 if ((type
== TYPE_EXTEND
) || (type
== TYPE_STREAM
))
962 } /* end of exfat_count_ext_entries */
966 * Name Conversion Functions
968 static void exfat_get_uniname_from_ext_entry(struct super_block
*sb
, CHAIN_T
*p_dir
, s32 entry
, u16
*uniname
)
972 ENTRY_SET_CACHE_T
*es
;
974 es
= get_dentry_set_in_dir(sb
, p_dir
, entry
, ES_ALL_ENTRIES
, &ep
);
978 if (es
->num_entries
< 3)
984 * First entry : file entry
985 * Second entry : stream-extension entry
986 * Third entry : first file-name entry
987 * So, the index of first file-name dentry should start from 2.
989 for (i
= 2; i
< es
->num_entries
; i
++, ep
++) {
990 /* end of name entry */
991 if (exfat_get_entry_type(ep
) != TYPE_EXTEND
)
994 __extract_uni_name_from_name_entry((NAME_DENTRY_T
*)ep
, uniname
, i
);
999 release_dentry_set(es
);
1000 } /* end of exfat_get_uniname_from_ext_entry */
1002 static s32
exfat_calc_num_entries(UNI_NAME_T
*p_uniname
)
1006 len
= p_uniname
->name_len
;
1010 /* 1 file entry + 1 stream entry + name entries */
1011 return((len
-1) / 15 + 3);
1013 } /* end of exfat_calc_num_entries */
1015 static s32
exfat_check_max_dentries(FILE_ID_T
*fid
)
1017 if ((fid
->size
>> DENTRY_SIZE_BITS
) >= MAX_EXFAT_DENTRIES
) {
1018 /* exFAT spec allows a dir to grow upto 8388608(256MB) dentries */
1022 } /* end of check_max_dentries */
1026 * Allocation Bitmap Management Functions
1028 s32
load_alloc_bmp(struct super_block
*sb
)
1031 u32 map_size
, need_map_size
;
1035 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
1037 clu
.dir
= fsi
->root_dir
;
1040 while (!IS_CLUS_EOF(clu
.dir
)) {
1041 for (i
= 0; i
< fsi
->dentries_per_clu
; i
++) {
1042 ep
= (BMAP_DENTRY_T
*) get_dentry_in_dir(sb
, &clu
, i
, NULL
);
1046 type
= exfat_get_entry_type((DENTRY_T
*) ep
);
1048 if (type
== TYPE_UNUSED
)
1050 if (type
!= TYPE_BITMAP
)
1053 if (ep
->flags
== 0x0) {
1054 fsi
->map_clu
= le32_to_cpu(ep
->start_clu
);
1055 map_size
= (u32
) le64_to_cpu(ep
->size
);
1057 need_map_size
= (((fsi
->num_clusters
- CLUS_BASE
) - 1) >> 3) + 1;
1058 if (need_map_size
!= map_size
) {
1059 sdfat_log_msg(sb
, KERN_ERR
,
1060 "bogus allocation bitmap size(need : %u, cur : %u)",
1061 need_map_size
, map_size
);
1062 /* Only allowed when bogus allocation bitmap size is large */
1063 if (need_map_size
> map_size
)
1066 fsi
->map_sectors
= ((need_map_size
- 1) >> (sb
->s_blocksize_bits
)) + 1;
1068 kmalloc((sizeof(struct buffer_head
*) * fsi
->map_sectors
), GFP_KERNEL
);
1072 sector
= CLUS_TO_SECT(fsi
, fsi
->map_clu
);
1074 for (j
= 0; j
< fsi
->map_sectors
; j
++) {
1075 fsi
->vol_amap
[j
] = NULL
;
1076 ret
= read_sect(sb
, sector
+j
, &(fsi
->vol_amap
[j
]), 1);
1078 /* release all buffers and free vol_amap */
1081 brelse(fsi
->vol_amap
[i
++]);
1083 /* kfree(NULL) is safe */
1084 kfree(fsi
->vol_amap
);
1085 fsi
->vol_amap
= NULL
;
1095 if (get_next_clus_safe(sb
, &clu
.dir
))
1100 } /* end of load_alloc_bmp */
1102 void free_alloc_bmp(struct super_block
*sb
)
1105 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
1107 brelse(fsi
->pbr_bh
);
1109 for (i
= 0; i
< fsi
->map_sectors
; i
++)
1110 __brelse(fsi
->vol_amap
[i
]);
1112 /* kfree(NULL) is safe */
1113 kfree(fsi
->vol_amap
);
1114 fsi
->vol_amap
= NULL
;
1118 * If the value of "clu" is 0, it means cluster 2 which is
1119 * the first cluster of cluster heap.
1121 static s32
set_alloc_bitmap(struct super_block
*sb
, u32 clu
)
1125 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
1127 i
= clu
>> (sb
->s_blocksize_bits
+ 3);
1128 b
= clu
& (u32
)((sb
->s_blocksize
<< 3) - 1);
1130 sector
= CLUS_TO_SECT(fsi
, fsi
->map_clu
) + i
;
1131 bitmap_set((unsigned long *)(fsi
->vol_amap
[i
]->b_data
), b
, 1);
1133 return write_sect(sb
, sector
, fsi
->vol_amap
[i
], 0);
1134 } /* end of set_alloc_bitmap */
1137 * If the value of "clu" is 0, it means cluster 2 which is
1138 * the first cluster of cluster heap.
1140 static s32
clr_alloc_bitmap(struct super_block
*sb
, u32 clu
)
1145 struct sdfat_sb_info
*sbi
= SDFAT_SB(sb
);
1146 struct sdfat_mount_options
*opts
= &sbi
->options
;
1147 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
1149 i
= clu
>> (sb
->s_blocksize_bits
+ 3);
1150 b
= clu
& (u32
)((sb
->s_blocksize
<< 3) - 1);
1152 sector
= CLUS_TO_SECT(fsi
, fsi
->map_clu
) + i
;
1154 bitmap_clear((unsigned long *)(fsi
->vol_amap
[i
]->b_data
), b
, 1);
1156 ret
= write_sect(sb
, sector
, fsi
->vol_amap
[i
], 0);
1158 if (opts
->discard
) {
1161 TMSG("discard cluster(%08x)\n", clu
+2);
1162 ret_discard
= sb_issue_discard(sb
, CLUS_TO_SECT(fsi
, clu
+2),
1163 (1 << fsi
->sect_per_clus_bits
), GFP_NOFS
, 0);
1165 if (ret_discard
== -EOPNOTSUPP
) {
1166 sdfat_msg(sb
, KERN_ERR
,
1167 "discard not supported by device, disabling");
1173 } /* end of clr_alloc_bitmap */
1176 * If the value of "clu" is 0, it means cluster 2 which is
1177 * the first cluster of cluster heap.
1179 static u32
test_alloc_bitmap(struct super_block
*sb
, u32 clu
)
1181 u32 i
, map_i
, map_b
;
1182 u32 clu_base
, clu_free
;
1184 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
1186 clu_base
= (clu
& ~(0x7)) + 2;
1187 clu_mask
= (1 << (clu
- clu_base
+ 2)) - 1;
1189 map_i
= clu
>> (sb
->s_blocksize_bits
+ 3);
1190 map_b
= (clu
>> 3) & (u32
)(sb
->s_blocksize
- 1);
1192 for (i
= 2; i
< fsi
->num_clusters
; i
+= 8) {
1193 k
= *(((u8
*) fsi
->vol_amap
[map_i
]->b_data
) + map_b
);
1199 clu_free
= clu_base
+ free_bit
[k
];
1200 if (clu_free
< fsi
->num_clusters
)
1205 if (((++map_b
) >= (u32
)sb
->s_blocksize
) ||
1206 (clu_base
>= fsi
->num_clusters
)) {
1207 if ((++map_i
) >= fsi
->map_sectors
) {
1216 } /* end of test_alloc_bitmap */
1218 void sync_alloc_bmp(struct super_block
*sb
)
1221 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
1223 if (fsi
->vol_amap
== NULL
)
1226 for (i
= 0; i
< fsi
->map_sectors
; i
++)
1227 sync_dirty_buffer(fsi
->vol_amap
[i
]);
1230 static s32
exfat_chain_cont_cluster(struct super_block
*sb
, u32 chain
, s32 len
)
1236 if (fat_ent_set(sb
, chain
, chain
+1))
1242 if (fat_ent_set(sb
, chain
, CLUS_EOF
))
1247 s32
chain_cont_cluster(struct super_block
*sb
, u32 chain
, s32 len
)
1249 return exfat_chain_cont_cluster(sb
, chain
, len
);
1252 static s32
exfat_alloc_cluster(struct super_block
*sb
, s32 num_alloc
, CHAIN_T
*p_chain
, int dest
)
1254 s32 num_clusters
= 0;
1255 u32 hint_clu
, new_clu
, last_clu
= CLUS_EOF
;
1256 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
1258 hint_clu
= p_chain
->dir
;
1259 /* find new cluster */
1260 if (IS_CLUS_EOF(hint_clu
)) {
1261 if (fsi
->clu_srch_ptr
< 2) {
1262 EMSG("%s: fsi->clu_srch_ptr is invalid (%u)\n",
1263 __func__
, fsi
->clu_srch_ptr
);
1265 fsi
->clu_srch_ptr
= 2;
1268 hint_clu
= test_alloc_bitmap(sb
, fsi
->clu_srch_ptr
-2);
1269 if (IS_CLUS_EOF(hint_clu
))
1273 /* check cluster validation */
1274 if ((hint_clu
< 2) && (hint_clu
>= fsi
->num_clusters
)) {
1275 EMSG("%s: hint_cluster is invalid (%u)\n", __func__
, hint_clu
);
1278 if (p_chain
->flags
== 0x03) {
1279 if (exfat_chain_cont_cluster(sb
, p_chain
->dir
, num_clusters
))
1281 p_chain
->flags
= 0x01;
1287 p_chain
->dir
= CLUS_EOF
;
1289 while ((new_clu
= test_alloc_bitmap(sb
, hint_clu
-2)) != CLUS_EOF
) {
1290 if ((new_clu
!= hint_clu
) && (p_chain
->flags
== 0x03)) {
1291 if (exfat_chain_cont_cluster(sb
, p_chain
->dir
, num_clusters
))
1293 p_chain
->flags
= 0x01;
1296 /* update allocation bitmap */
1297 if (set_alloc_bitmap(sb
, new_clu
-2))
1302 /* update FAT table */
1303 if (p_chain
->flags
== 0x01)
1304 if (fat_ent_set(sb
, new_clu
, CLUS_EOF
))
1307 if (IS_CLUS_EOF(p_chain
->dir
)) {
1308 p_chain
->dir
= new_clu
;
1309 } else if (p_chain
->flags
== 0x01) {
1310 if (fat_ent_set(sb
, last_clu
, new_clu
))
1315 if ((--num_alloc
) == 0) {
1316 fsi
->clu_srch_ptr
= hint_clu
;
1317 if (fsi
->used_clusters
!= (u32
) ~0)
1318 fsi
->used_clusters
+= num_clusters
;
1320 p_chain
->size
+= num_clusters
;
1321 return num_clusters
;
1324 hint_clu
= new_clu
+ 1;
1325 if (hint_clu
>= fsi
->num_clusters
) {
1328 if (p_chain
->flags
== 0x03) {
1329 if (exfat_chain_cont_cluster(sb
, p_chain
->dir
, num_clusters
))
1331 p_chain
->flags
= 0x01;
1336 fsi
->clu_srch_ptr
= hint_clu
;
1337 if (fsi
->used_clusters
!= (u32
) ~0)
1338 fsi
->used_clusters
+= num_clusters
;
1340 p_chain
->size
+= num_clusters
;
1341 return num_clusters
;
1342 } /* end of exfat_alloc_cluster */
1345 static s32
exfat_free_cluster(struct super_block
*sb
, CHAIN_T
*p_chain
, s32 do_relse
)
1348 s32 num_clusters
= 0;
1350 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
1354 /* invalid cluster number */
1355 if (IS_CLUS_FREE(p_chain
->dir
) || IS_CLUS_EOF(p_chain
->dir
))
1358 /* no cluster to truncate */
1359 if (p_chain
->size
<= 0) {
1360 DMSG("%s: cluster(%u) truncation is not required.",
1361 __func__
, p_chain
->dir
);
1365 /* check cluster validation */
1366 if ((p_chain
->dir
< 2) && (p_chain
->dir
>= fsi
->num_clusters
)) {
1367 EMSG("%s: invalid start cluster (%u)\n", __func__
, p_chain
->dir
);
1368 sdfat_debug_bug_on(1);
1375 if (p_chain
->flags
== 0x03) {
1378 sector
= CLUS_TO_SECT(fsi
, clu
);
1379 for (i
= 0; i
< fsi
->sect_per_clus
; i
++) {
1380 if (dcache_release(sb
, sector
+i
) == -EIO
)
1385 if (clr_alloc_bitmap(sb
, clu
-2))
1390 } while (num_clusters
< p_chain
->size
);
1394 sector
= CLUS_TO_SECT(fsi
, clu
);
1395 for (i
= 0; i
< fsi
->sect_per_clus
; i
++) {
1396 if (dcache_release(sb
, sector
+i
) == -EIO
)
1401 if (clr_alloc_bitmap(sb
, (clu
- CLUS_BASE
)))
1404 if (get_next_clus_safe(sb
, &clu
))
1408 } while (!IS_CLUS_EOF(clu
));
1415 if (fsi
->used_clusters
!= (u32
) ~0)
1416 fsi
->used_clusters
-= num_clusters
;
1418 } /* end of exfat_free_cluster */
1420 static s32
exfat_count_used_clusters(struct super_block
*sb
, u32
*ret_count
)
1423 u32 i
, map_i
, map_b
;
1424 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
1425 u32 total_clus
= fsi
->num_clusters
- 2;
1429 for (i
= 0; i
< total_clus
; i
+= 8) {
1430 u8 k
= *(((u8
*) fsi
->vol_amap
[map_i
]->b_data
) + map_b
);
1432 count
+= used_bit
[k
];
1433 if ((++map_b
) >= (u32
)sb
->s_blocksize
) {
1439 /* FIXME : abnormal bitmap count should be handled as more smart */
1440 if (total_clus
< count
)
1445 } /* end of exfat_count_used_clusters */
1449 * File Operation Functions
1451 static FS_FUNC_T exfat_fs_func
= {
1452 .alloc_cluster
= exfat_alloc_cluster
,
1453 .free_cluster
= exfat_free_cluster
,
1454 .count_used_clusters
= exfat_count_used_clusters
,
1456 .init_dir_entry
= exfat_init_dir_entry
,
1457 .init_ext_entry
= exfat_init_ext_entry
,
1458 .find_dir_entry
= exfat_find_dir_entry
,
1459 .delete_dir_entry
= exfat_delete_dir_entry
,
1460 .get_uniname_from_ext_entry
= exfat_get_uniname_from_ext_entry
,
1461 .count_ext_entries
= exfat_count_ext_entries
,
1462 .calc_num_entries
= exfat_calc_num_entries
,
1463 .check_max_dentries
= exfat_check_max_dentries
,
1465 .get_entry_type
= exfat_get_entry_type
,
1466 .set_entry_type
= exfat_set_entry_type
,
1467 .get_entry_attr
= exfat_get_entry_attr
,
1468 .set_entry_attr
= exfat_set_entry_attr
,
1469 .get_entry_flag
= exfat_get_entry_flag
,
1470 .set_entry_flag
= exfat_set_entry_flag
,
1471 .get_entry_clu0
= exfat_get_entry_clu0
,
1472 .set_entry_clu0
= exfat_set_entry_clu0
,
1473 .get_entry_size
= exfat_get_entry_size
,
1474 .set_entry_size
= exfat_set_entry_size
,
1475 .get_entry_time
= exfat_get_entry_time
,
1476 .set_entry_time
= exfat_set_entry_time
,
1479 s32
mount_exfat(struct super_block
*sb
, pbr_t
*p_pbr
)
1481 pbr64_t
*p_bpb
= (pbr64_t
*)p_pbr
;
1482 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
1484 if (!p_bpb
->bsx
.num_fats
) {
1485 sdfat_msg(sb
, KERN_ERR
, "bogus number of FAT structure");
1489 fsi
->sect_per_clus
= 1 << p_bpb
->bsx
.sect_per_clus_bits
;
1490 fsi
->sect_per_clus_bits
= p_bpb
->bsx
.sect_per_clus_bits
;
1491 fsi
->cluster_size_bits
= fsi
->sect_per_clus_bits
+ sb
->s_blocksize_bits
;
1492 fsi
->cluster_size
= 1 << fsi
->cluster_size_bits
;
1494 fsi
->num_FAT_sectors
= le32_to_cpu(p_bpb
->bsx
.fat_length
);
1496 fsi
->FAT1_start_sector
= le32_to_cpu(p_bpb
->bsx
.fat_offset
);
1497 if (p_bpb
->bsx
.num_fats
== 1)
1498 fsi
->FAT2_start_sector
= fsi
->FAT1_start_sector
;
1500 fsi
->FAT2_start_sector
= fsi
->FAT1_start_sector
+ fsi
->num_FAT_sectors
;
1502 fsi
->root_start_sector
= le32_to_cpu(p_bpb
->bsx
.clu_offset
);
1503 fsi
->data_start_sector
= fsi
->root_start_sector
;
1505 fsi
->num_sectors
= le64_to_cpu(p_bpb
->bsx
.vol_length
);
1506 fsi
->num_clusters
= le32_to_cpu(p_bpb
->bsx
.clu_count
) + 2;
1507 /* because the cluster index starts with 2 */
1509 fsi
->vol_type
= EXFAT
;
1510 fsi
->vol_id
= le32_to_cpu(p_bpb
->bsx
.vol_serial
);
1512 fsi
->root_dir
= le32_to_cpu(p_bpb
->bsx
.root_cluster
);
1513 fsi
->dentries_in_root
= 0;
1514 fsi
->dentries_per_clu
= 1 << (fsi
->cluster_size_bits
- DENTRY_SIZE_BITS
);
1516 fsi
->vol_flag
= (u32
) le16_to_cpu(p_bpb
->bsx
.vol_flags
);
1517 fsi
->clu_srch_ptr
= 2;
1518 fsi
->used_clusters
= (u32
) ~0;
1520 fsi
->fs_func
= &exfat_fs_func
;
1521 fat_ent_ops_init(sb
);
1523 if (p_bpb
->bsx
.vol_flags
& VOL_DIRTY
) {
1524 fsi
->vol_flag
|= VOL_DIRTY
;
1525 sdfat_log_msg(sb
, KERN_WARNING
, "Volume was not properly "
1526 "unmounted. Some data may be corrupt. "
1527 "Please run fsck.");
1531 } /* end of mount_exfat */
1533 /* end of core_exfat.c */