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 */
22 /* PURPOSE : FAT & exFAT common core code for sdFAT */
24 /*----------------------------------------------------------------------*/
28 /************************************************************************/
30 #include <linux/version.h>
31 #include <linux/blkdev.h>
32 #include <linux/workqueue.h>
33 #include <linux/writeback.h>
34 #include <linux/kernel.h>
35 #include <linux/log2.h>
39 #include <asm/byteorder.h>
40 #include <asm/unaligned.h>
42 /*----------------------------------------------------------------------*/
43 /* Constant & Macro Definitions */
44 /*----------------------------------------------------------------------*/
45 static inline void __set_sb_dirty(struct super_block
*sb
)
47 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0)
49 #else /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0) */
50 struct sdfat_sb_info
*sbi
= SDFAT_SB(sb
);
54 spin_lock(&sbi
->work_lock
);
55 if (!sbi
->write_super_queued
) {
58 delay
= msecs_to_jiffies(CONFIG_SDFAT_WRITE_SB_INTERVAL_CSECS
* 10);
59 queue_delayed_work(system_long_wq
, &sbi
->write_super_work
, delay
);
60 sbi
->write_super_queued
= 1;
62 spin_unlock(&sbi
->work_lock
);
66 void set_sb_dirty(struct super_block
*sb
)
69 // XXX: to be removed later, prints too much output
70 //TMSG("%s finished.\n", __func__);
73 /*----------------------------------------------------------------------*/
74 /* Global Variable Definitions */
75 /*----------------------------------------------------------------------*/
77 /*----------------------------------------------------------------------*/
78 /* Local Variable Definitions */
79 /*----------------------------------------------------------------------*/
81 static s8
*reserved_names
[] = {
82 "AUX ", "CON ", "NUL ", "PRN ",
83 "COM1 ", "COM2 ", "COM3 ", "COM4 ",
84 "COM5 ", "COM6 ", "COM7 ", "COM8 ", "COM9 ",
85 "LPT1 ", "LPT2 ", "LPT3 ", "LPT4 ",
86 "LPT5 ", "LPT6 ", "LPT7 ", "LPT8 ", "LPT9 ",
90 /*======================================================================*/
91 /* Local Function Definitions */
92 /*======================================================================*/
95 * File System Management Functions
98 static s32
check_type_size(void)
100 /* critical check for system requirement on size of DENTRY_T structure */
101 if (sizeof(DENTRY_T
) != DENTRY_SIZE
)
104 if (sizeof(DOS_DENTRY_T
) != DENTRY_SIZE
)
107 if (sizeof(EXT_DENTRY_T
) != DENTRY_SIZE
)
110 if (sizeof(FILE_DENTRY_T
) != DENTRY_SIZE
)
113 if (sizeof(STRM_DENTRY_T
) != DENTRY_SIZE
)
116 if (sizeof(NAME_DENTRY_T
) != DENTRY_SIZE
)
119 if (sizeof(BMAP_DENTRY_T
) != DENTRY_SIZE
)
122 if (sizeof(CASE_DENTRY_T
) != DENTRY_SIZE
)
125 if (sizeof(VOLM_DENTRY_T
) != DENTRY_SIZE
)
131 static s32
__fs_set_vol_flags(struct super_block
*sb
, u16 new_flag
, s32 always_sync
)
133 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
137 /* flags are not changed */
138 if (fsi
->vol_flag
== new_flag
)
141 fsi
->vol_flag
= new_flag
;
143 /* skip updating volume dirty flag,
144 * if this volume has been mounted with read-only
146 if (sb
->s_flags
& MS_RDONLY
)
150 err
= read_sect(sb
, 0, &(fsi
->pbr_bh
), 1);
152 EMSG("%s : failed to read boot sector\n", __func__
);
157 if (fsi
->vol_type
== EXFAT
) {
158 pbr64_t
*bpb
= (pbr64_t
*)fsi
->pbr_bh
->b_data
;
159 bpb
->bsx
.vol_flags
= cpu_to_le16(new_flag
);
160 } else if (fsi
->vol_type
== FAT32
) {
161 pbr32_t
*bpb
= (pbr32_t
*)fsi
->pbr_bh
->b_data
;
162 bpb
->bsx
.state
= new_flag
& VOL_DIRTY
? FAT_VOL_DIRTY
: 0x00;
163 } else { /* FAT16/12 */
164 pbr16_t
*bpb
= (pbr16_t
*) fsi
->pbr_bh
->b_data
;
165 bpb
->bpb
.state
= new_flag
& VOL_DIRTY
? FAT_VOL_DIRTY
: 0x00;
170 else if ((new_flag
== VOL_DIRTY
) && (!buffer_dirty(fsi
->pbr_bh
)))
175 err
= write_sect(sb
, 0, fsi
->pbr_bh
, sync
);
177 EMSG("%s : failed to modify volume flag\n", __func__
);
182 static s32
fs_set_vol_flags(struct super_block
*sb
, u16 new_flag
)
184 return __fs_set_vol_flags(sb
, new_flag
, 0);
187 s32
fscore_set_vol_flags(struct super_block
*sb
, u16 new_flag
, s32 always_sync
)
189 return __fs_set_vol_flags(sb
, new_flag
, always_sync
);
192 static inline s32
__fs_meta_sync(struct super_block
*sb
, s32 do_sync
)
194 #ifdef CONFIG_SDFAT_DELAYED_META_DIRTY
195 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
197 if (fsi
->vol_type
!= EXFAT
) {
198 MMSG("meta flush in fs_sync(sync=%d)\n", do_sync
);
208 static s32
fs_sync(struct super_block
*sb
, s32 do_sync
)
215 err
= __fs_meta_sync(sb
, do_sync
);
218 err
= bdev_sync_all(sb
);
221 EMSG("%s : failed to sync. (err:%d)\n", __func__
, err
);
227 * Cluster Management Functions
230 static s32
__clear_cluster(struct inode
*inode
, u32 clu
)
233 struct super_block
*sb
= inode
->i_sb
;
234 u32 sect_size
= (u32
)sb
->s_blocksize
;
236 struct buffer_head
*tmp_bh
= NULL
;
237 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
239 if (IS_CLUS_FREE(clu
)) { /* FAT16 root_dir */
240 s
= fsi
->root_start_sector
;
241 n
= fsi
->data_start_sector
;
243 s
= CLUS_TO_SECT(fsi
, clu
);
244 n
= s
+ fsi
->sect_per_clus
;
247 if (IS_DIRSYNC(inode
)) {
248 ret
= write_msect_zero(sb
, s
, (s32
)fsi
->sect_per_clus
);
253 /* Trying buffered zero writes
254 * if it doesn't have DIRSYNC or write_msect_zero() returned -EAGAIN
256 for ( ; s
< n
; s
++) {
258 dcache_release(sb
, s
);
260 ret
= read_sect(sb
, s
, &tmp_bh
, 0);
264 memset((u8
*)tmp_bh
->b_data
, 0x0, sect_size
);
265 ret
= write_sect(sb
, s
, tmp_bh
, 0);
272 } /* end of __clear_cluster */
274 static s32
__find_last_cluster(struct super_block
*sb
, CHAIN_T
*p_chain
, u32
*ret_clu
)
280 if (p_chain
->flags
== 0x03) {
281 *ret_clu
= next
+ p_chain
->size
- 1;
288 if (fat_ent_get_safe(sb
, clu
, &next
))
290 } while (!IS_CLUS_EOF(next
));
292 if (p_chain
->size
!= count
) {
293 sdfat_fs_error(sb
, "bogus directory size "
294 "(clus : ondisk(%d) != counted(%d))",
295 p_chain
->size
, count
);
296 sdfat_debug_bug_on(1);
305 static s32
__count_num_clusters(struct super_block
*sb
, CHAIN_T
*p_chain
, s32
*ret_count
)
309 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
311 if (!p_chain
->dir
|| IS_CLUS_EOF(p_chain
->dir
)) {
316 if (p_chain
->flags
== 0x03) {
317 *ret_count
= p_chain
->size
;
323 for (i
= CLUS_BASE
; i
< fsi
->num_clusters
; i
++) {
325 if (fat_ent_get_safe(sb
, clu
, &clu
))
327 if (IS_CLUS_EOF(clu
))
336 * Upcase table Management Functions
338 static void free_upcase_table(struct super_block
*sb
)
341 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
344 upcase_table
= fsi
->vol_utbl
;
345 for (i
= 0 ; i
< UTBL_COL_COUNT
; i
++) {
346 /* kfree(NULL) is safe */
347 kfree(upcase_table
[i
]);
348 upcase_table
[i
] = NULL
;
351 /* kfree(NULL) is safe */
352 kfree(fsi
->vol_utbl
);
353 fsi
->vol_utbl
= NULL
;
356 static s32
__load_upcase_table(struct super_block
*sb
, u32 sector
, u32 num_sectors
, u32 utbl_checksum
)
358 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
359 struct buffer_head
*tmp_bh
= NULL
;
360 u32 sect_size
= (u32
)sb
->s_blocksize
;
367 u16
**upcase_table
= kzalloc((UTBL_COL_COUNT
* sizeof(u16
*)), GFP_KERNEL
);
371 /* thanks for kzalloc
372 * memset(upcase_table, 0, UTBL_COL_COUNT * sizeof(u16 *));
375 fsi
->vol_utbl
= upcase_table
;
376 num_sectors
+= sector
;
378 while (sector
< num_sectors
) {
379 ret
= read_sect(sb
, sector
, &tmp_bh
, 1);
381 EMSG("%s: failed to read sector(0x%x)\n",
387 for (i
= 0; i
< sect_size
&& index
<= 0xFFFF; i
+= 2) {
388 /* FIXME : is __le16 ok? */
389 //u16 uni = le16_to_cpu(((__le16*)(tmp_bh->b_data))[i]);
390 u16 uni
= get_unaligned_le16((u8
*)tmp_bh
->b_data
+i
);
392 checksum
= ((checksum
& 1) ? 0x80000000 : 0) +
393 (checksum
>> 1) + *(((u8
*)tmp_bh
->b_data
)+i
);
394 checksum
= ((checksum
& 1) ? 0x80000000 : 0) +
395 (checksum
>> 1) + *(((u8
*)tmp_bh
->b_data
)+(i
+1));
398 MMSG("skip from 0x%X to 0x%X(amount of 0x%X)\n",
399 index
, index
+uni
, uni
);
402 } else if (uni
== index
) {
404 } else if (uni
== 0xFFFF) {
406 } else { /* uni != index , uni != 0xFFFF */
407 u16 col_index
= get_col_index(index
);
409 if (!upcase_table
[col_index
]) {
410 upcase_table
[col_index
] =
411 kmalloc((UTBL_ROW_COUNT
* sizeof(u16
)), GFP_KERNEL
);
412 if (!upcase_table
[col_index
]) {
413 EMSG("failed to allocate memory"
414 " for column 0x%X\n",
420 for (j
= 0; j
< UTBL_ROW_COUNT
; j
++)
421 upcase_table
[col_index
][j
] = (col_index
<< LOW_INDEX_BIT
) | j
;
424 upcase_table
[col_index
][get_row_index(index
)] = uni
;
429 if (index
>= 0xFFFF && utbl_checksum
== checksum
) {
430 DMSG("%s: load upcase table successfully"
431 "(idx:0x%08x, utbl_chksum:0x%08x)\n",
432 __func__
, index
, utbl_checksum
);
438 EMSG("%s: failed to load upcase table"
439 "(idx:0x%08x, chksum:0x%08x, utbl_chksum:0x%08x)\n",
440 __func__
, index
, checksum
, utbl_checksum
);
446 free_upcase_table(sb
);
450 static s32
__load_default_upcase_table(struct super_block
*sb
)
454 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
461 upcase_table
= kmalloc((UTBL_COL_COUNT
* sizeof(u16
*)), GFP_KERNEL
);
465 fsi
->vol_utbl
= upcase_table
;
466 memset(upcase_table
, 0, UTBL_COL_COUNT
* sizeof(u16
*));
468 for (i
= 0; index
<= 0xFFFF && i
< SDFAT_NUM_UPCASE
*2; i
+= 2) {
469 /* FIXME : is __le16 ok? */
470 //uni = le16_to_cpu(((__le16*)uni_def_upcase)[i>>1]);
471 uni
= get_unaligned_le16((u8
*)uni_def_upcase
+i
);
473 MMSG("skip from 0x%x ", index
);
475 MMSG("to 0x%x (amount of 0x%x)\n", index
, uni
);
477 } else if (uni
== index
) {
479 } else if (uni
== 0xFFFF) {
481 } else { /* uni != index , uni != 0xFFFF */
482 u16 col_index
= get_col_index(index
);
484 if (!upcase_table
[col_index
]) {
485 upcase_table
[col_index
] = kmalloc((UTBL_ROW_COUNT
* sizeof(u16
)), GFP_KERNEL
);
486 if (!upcase_table
[col_index
]) {
487 EMSG("failed to allocate memory for "
488 "new column 0x%x\n", col_index
);
493 for (j
= 0; j
< UTBL_ROW_COUNT
; j
++)
494 upcase_table
[col_index
][j
] = (col_index
<< LOW_INDEX_BIT
) | j
;
497 upcase_table
[col_index
][get_row_index(index
)] = uni
;
506 /* FATAL error: default upcase table has error */
507 free_upcase_table(sb
);
511 static s32
load_upcase_table(struct super_block
*sb
)
514 u32 tbl_clu
, tbl_size
;
515 u32 type
, sector
, num_sectors
;
516 u8 blksize_bits
= sb
->s_blocksize_bits
;
519 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
521 clu
.dir
= fsi
->root_dir
;
524 if (fsi
->vol_type
!= EXFAT
)
527 while (!IS_CLUS_EOF(clu
.dir
)) {
528 for (i
= 0; i
< fsi
->dentries_per_clu
; i
++) {
529 ep
= (CASE_DENTRY_T
*) get_dentry_in_dir(sb
, &clu
, i
, NULL
);
533 type
= fsi
->fs_func
->get_entry_type((DENTRY_T
*) ep
);
535 if (type
== TYPE_UNUSED
)
537 if (type
!= TYPE_UPCASE
)
540 tbl_clu
= le32_to_cpu(ep
->start_clu
);
541 tbl_size
= (u32
) le64_to_cpu(ep
->size
);
543 sector
= CLUS_TO_SECT(fsi
, tbl_clu
);
544 num_sectors
= ((tbl_size
-1) >> blksize_bits
) + 1;
545 ret
= __load_upcase_table(sb
, sector
, num_sectors
,
546 le32_to_cpu(ep
->checksum
));
548 if (ret
&& (ret
!= -EIO
))
551 /* load successfully */
555 if (get_next_clus_safe(sb
, &(clu
.dir
)))
560 sdfat_log_msg(sb
, KERN_INFO
, "trying to load default upcase table");
561 /* load default upcase table */
562 return __load_default_upcase_table(sb
);
563 } /* end of load_upcase_table */
567 * Directory Entry Management Functions
569 s32
walk_fat_chain(struct super_block
*sb
, CHAIN_T
*p_dir
, s32 byte_offset
, u32
*clu
)
571 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
575 clu_offset
= byte_offset
>> fsi
->cluster_size_bits
;
576 cur_clu
= p_dir
->dir
;
578 if (p_dir
->flags
== 0x03) {
579 cur_clu
+= clu_offset
;
581 while (clu_offset
> 0) {
582 if (get_next_clus_safe(sb
, &cur_clu
))
584 if (IS_CLUS_EOF(cur_clu
)) {
585 sdfat_fs_error(sb
, "invalid dentry access "
586 "beyond EOF (clu : %u, eidx : %d)",
588 byte_offset
>> DENTRY_SIZE_BITS
);
600 static s32
find_location(struct super_block
*sb
, CHAIN_T
*p_dir
, s32 entry
, u32
*sector
, s32
*offset
)
604 u32 blksize_mask
= (u32
)(sb
->s_blocksize
-1);
605 u8 blksize_bits
= sb
->s_blocksize_bits
;
606 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
608 off
= entry
<< DENTRY_SIZE_BITS
;
611 if (IS_CLUS_FREE(p_dir
->dir
)) {
612 *offset
= off
& blksize_mask
;
613 *sector
= off
>> blksize_bits
;
614 *sector
+= fsi
->root_start_sector
;
618 ret
= walk_fat_chain(sb
, p_dir
, off
, &clu
);
622 /* byte offset in cluster */
623 off
&= (fsi
->cluster_size
- 1);
625 /* byte offset in sector */
626 *offset
= off
& blksize_mask
;
628 /* sector offset in cluster */
629 *sector
= off
>> blksize_bits
;
630 *sector
+= CLUS_TO_SECT(fsi
, clu
);
632 } /* end of find_location */
634 DENTRY_T
*get_dentry_in_dir(struct super_block
*sb
, CHAIN_T
*p_dir
, s32 entry
, u32
*sector
)
636 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
637 u32 dentries_per_page
= PAGE_SIZE
>> DENTRY_SIZE_BITS
;
642 if (p_dir
->dir
== DIR_DELETED
) {
643 EMSG("%s : abnormal access to deleted dentry\n", __func__
);
644 BUG_ON(!fsi
->prev_eio
);
648 if (find_location(sb
, p_dir
, entry
, &sec
, &off
))
651 /* DIRECTORY READAHEAD :
652 * Try to read ahead per a page except root directory of fat12/16
654 if ((!IS_CLUS_FREE(p_dir
->dir
)) &&
655 !(entry
& (dentries_per_page
- 1)))
656 dcache_readahead(sb
, sec
);
658 buf
= dcache_getblk(sb
, sec
);
664 return (DENTRY_T
*)(buf
+ off
);
665 } /* end of get_dentry_in_dir */
667 /* used only in search empty_slot() */
668 #define CNT_UNUSED_NOHIT (-1)
669 #define CNT_UNUSED_HIT (-2)
670 /* search EMPTY CONTINUOUS "num_entries" entries */
671 static s32
search_empty_slot(struct super_block
*sb
, HINT_FEMP_T
*hint_femp
, CHAIN_T
*p_dir
, s32 num_entries
)
673 s32 i
, dentry
, num_empty
= 0;
674 s32 dentries_per_clu
;
678 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
680 if (IS_CLUS_FREE(p_dir
->dir
)) /* FAT16 root_dir */
681 dentries_per_clu
= fsi
->dentries_in_root
;
683 dentries_per_clu
= fsi
->dentries_per_clu
;
685 ASSERT(-1 <= hint_femp
->eidx
);
687 if (hint_femp
->eidx
!= -1) {
688 clu
.dir
= hint_femp
->cur
.dir
;
689 clu
.size
= hint_femp
->cur
.size
;
690 clu
.flags
= hint_femp
->cur
.flags
;
692 dentry
= hint_femp
->eidx
;
694 if (num_entries
<= hint_femp
->count
) {
695 MMSG("%s: empty slot(HIT) - found "
696 "(clu : 0x%08x eidx : %d)\n",
697 __func__
, hint_femp
->cur
.dir
, hint_femp
->eidx
);
698 hint_femp
->eidx
= -1;
700 if (fsi
->vol_type
== EXFAT
)
703 return dentry
+ (num_entries
- 1);
705 MMSG("%s: empty slot(HIT) - search from "
706 "(clu : 0x%08x eidx : %d)\n",
707 __func__
, hint_femp
->cur
.dir
, hint_femp
->eidx
);
709 MMSG("%s: empty slot(MISS) - search from "
710 "(clu:0x%08x eidx : 0)\n",
711 __func__
, p_dir
->dir
);
713 clu
.dir
= p_dir
->dir
;
714 clu
.size
= p_dir
->size
;
715 clu
.flags
= p_dir
->flags
;
720 while (!IS_CLUS_EOF(clu
.dir
)) {
722 if (IS_CLUS_FREE(p_dir
->dir
))
723 i
= dentry
% dentries_per_clu
;
725 i
= dentry
& (dentries_per_clu
-1);
727 for ( ; i
< dentries_per_clu
; i
++, dentry
++) {
728 ep
= get_dentry_in_dir(sb
, &clu
, i
, NULL
);
732 type
= fsi
->fs_func
->get_entry_type(ep
);
734 if ((type
== TYPE_UNUSED
) || (type
== TYPE_DELETED
)) {
736 if (hint_femp
->eidx
== -1) {
737 hint_femp
->eidx
= dentry
;
738 hint_femp
->count
= CNT_UNUSED_NOHIT
;
740 hint_femp
->cur
.dir
= clu
.dir
;
741 hint_femp
->cur
.size
= clu
.size
;
742 hint_femp
->cur
.flags
= clu
.flags
;
745 if ((type
== TYPE_UNUSED
) &&
746 (hint_femp
->count
!= CNT_UNUSED_HIT
)) {
747 hint_femp
->count
= CNT_UNUSED_HIT
;
750 if ((hint_femp
->eidx
!= -1) &&
751 (hint_femp
->count
== CNT_UNUSED_HIT
)) {
752 /* unused empty group means
753 * an empty group which includes
757 "found bogus dentry(%d) "
758 "beyond unused empty group(%d) "
759 "(start_clu : %u, cur_clu : %u)\n",
760 dentry
, hint_femp
->eidx
, p_dir
->dir
,
766 hint_femp
->eidx
= -1;
769 if (num_empty
>= num_entries
) {
770 /* found and invalidate hint_femp */
771 hint_femp
->eidx
= -1;
773 if (fsi
->vol_type
== EXFAT
)
774 return (dentry
- (num_entries
-1));
780 if (IS_CLUS_FREE(p_dir
->dir
))
781 break; /* FAT16 root_dir */
783 if (clu
.flags
== 0x03) {
784 if ((--clu
.size
) > 0)
789 if (get_next_clus_safe(sb
, &(clu
.dir
)))
795 } /* end of search_empty_slot */
797 /* find empty directory entry.
798 * if there isn't any empty slot, expand cluster chain.
800 static s32
find_empty_entry(struct inode
*inode
, CHAIN_T
*p_dir
, s32 num_entries
)
803 u32 last_clu
, sector
;
807 struct super_block
*sb
= inode
->i_sb
;
808 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
809 FILE_ID_T
*fid
= &(SDFAT_I(inode
)->fid
);
810 HINT_FEMP_T hint_femp
;
814 ASSERT(-1 <= fid
->hint_femp
.eidx
);
816 if (fid
->hint_femp
.eidx
!= -1) {
817 memcpy(&hint_femp
, &fid
->hint_femp
, sizeof(HINT_FEMP_T
));
818 fid
->hint_femp
.eidx
= -1;
822 if (IS_CLUS_FREE(p_dir
->dir
))
823 return search_empty_slot(sb
, &hint_femp
, p_dir
, num_entries
);
825 while ((dentry
= search_empty_slot(sb
, &hint_femp
, p_dir
, num_entries
)) < 0) {
829 if (fsi
->fs_func
->check_max_dentries(fid
))
832 /* we trust p_dir->size regardless of FAT type */
833 if (__find_last_cluster(sb
, p_dir
, &last_clu
))
837 * Allocate new cluster to this directory
839 clu
.dir
= last_clu
+ 1;
840 clu
.size
= 0; /* UNUSED */
841 clu
.flags
= p_dir
->flags
;
843 /* (0) check if there are reserved clusters
844 * (create_dir 의 주석 참고)
846 if (!IS_CLUS_EOF(fsi
->used_clusters
) &&
847 ((fsi
->used_clusters
+ fsi
->reserved_clusters
) >= (fsi
->num_clusters
- 2)))
850 /* (1) allocate a cluster */
851 ret
= fsi
->fs_func
->alloc_cluster(sb
, 1, &clu
, ALLOC_HOT
);
857 if (__clear_cluster(inode
, clu
.dir
))
860 /* (2) append to the FAT chain */
861 if (clu
.flags
!= p_dir
->flags
) {
862 /* no-fat-chain bit is disabled,
863 * so fat-chain should be synced with alloc-bmp
865 chain_cont_cluster(sb
, p_dir
->dir
, p_dir
->size
);
867 hint_femp
.cur
.flags
= 0x01;
870 if (clu
.flags
== 0x01)
871 if (fat_ent_set(sb
, last_clu
, clu
.dir
))
874 if (hint_femp
.eidx
== -1) {
875 /* the special case that new dentry
876 * should be allocated from the start of new cluster
878 hint_femp
.eidx
= p_dir
->size
<<
879 (fsi
->cluster_size_bits
- DENTRY_SIZE_BITS
);
880 hint_femp
.count
= fsi
->dentries_per_clu
;
882 hint_femp
.cur
.dir
= clu
.dir
;
883 hint_femp
.cur
.size
= 0;
884 hint_femp
.cur
.flags
= clu
.flags
;
886 hint_femp
.cur
.size
++;
888 size
= (p_dir
->size
<< fsi
->cluster_size_bits
);
890 /* (3) update the directory entry */
891 if ((fsi
->vol_type
== EXFAT
) && (p_dir
->dir
!= fsi
->root_dir
)) {
892 ep
= get_dentry_in_dir(sb
,
893 &(fid
->dir
), fid
->entry
+1, §or
);
896 fsi
->fs_func
->set_entry_size(ep
, size
);
897 fsi
->fs_func
->set_entry_flag(ep
, p_dir
->flags
);
898 if (dcache_modify(sb
, sector
))
901 if (update_dir_chksum(sb
, &(fid
->dir
), fid
->entry
))
905 /* directory inode should be updated in here */
906 i_size_write(inode
, (loff_t
)size
);
907 SDFAT_I(inode
)->i_size_ondisk
+= fsi
->cluster_size
;
908 SDFAT_I(inode
)->i_size_aligned
+= fsi
->cluster_size
;
909 SDFAT_I(inode
)->fid
.size
= size
;
910 SDFAT_I(inode
)->fid
.flags
= p_dir
->flags
;
911 inode
->i_blocks
+= 1 << (fsi
->cluster_size_bits
- sb
->s_blocksize_bits
);
915 } /* end of find_empty_entry */
917 #define SDFAT_MIN_SUBDIR (2)
918 static const char *dot_name
[SDFAT_MIN_SUBDIR
] = { DOS_CUR_DIR_NAME
, DOS_PAR_DIR_NAME
};
920 static s32
__count_dos_name_entries(struct super_block
*sb
, CHAIN_T
*p_dir
, u32 type
, u32
*dotcnt
)
922 s32 i
, count
= 0, check_dot
= 0;
923 s32 dentries_per_clu
;
927 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
929 if (IS_CLUS_FREE(p_dir
->dir
)) /* FAT16 root_dir */
930 dentries_per_clu
= fsi
->dentries_in_root
;
932 dentries_per_clu
= fsi
->dentries_per_clu
;
934 clu
.dir
= p_dir
->dir
;
935 clu
.size
= p_dir
->size
;
936 clu
.flags
= p_dir
->flags
;
940 if (fsi
->vol_type
!= EXFAT
)
944 while (!IS_CLUS_EOF(clu
.dir
)) {
945 for (i
= 0; i
< dentries_per_clu
; i
++) {
946 ep
= get_dentry_in_dir(sb
, &clu
, i
, NULL
);
950 entry_type
= fsi
->fs_func
->get_entry_type(ep
);
952 if (entry_type
== TYPE_UNUSED
)
954 if (!(type
& TYPE_CRITICAL_PRI
) && !(type
& TYPE_BENIGN_PRI
))
957 if ((type
!= TYPE_ALL
) && (type
!= entry_type
))
961 if (check_dot
&& (i
< SDFAT_MIN_SUBDIR
)) {
962 BUG_ON(fsi
->vol_type
== EXFAT
);
963 /* 11 is DOS_NAME_LENGTH */
964 if (!strncmp(ep
->dummy
, dot_name
[i
], 11))
970 if (IS_CLUS_FREE(p_dir
->dir
))
973 if (clu
.flags
== 0x03) {
974 if ((--clu
.size
) > 0)
979 if (get_next_clus_safe(sb
, &(clu
.dir
)))
989 s32
check_dir_empty(struct super_block
*sb
, CHAIN_T
*p_dir
)
992 s32 dentries_per_clu
;
996 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
998 if (IS_CLUS_FREE(p_dir
->dir
)) /* FAT16 root_dir */
999 dentries_per_clu
= fsi
->dentries_in_root
;
1001 dentries_per_clu
= fsi
->dentries_per_clu
;
1003 clu
.dir
= p_dir
->dir
;
1004 clu
.size
= p_dir
->size
;
1005 clu
.flags
= p_dir
->flags
;
1007 while (!IS_CLUS_EOF(clu
.dir
)) {
1008 for (i
= 0; i
< dentries_per_clu
; i
++) {
1009 ep
= get_dentry_in_dir(sb
, &clu
, i
, NULL
);
1013 type
= fsi
->fs_func
->get_entry_type(ep
);
1015 if (type
== TYPE_UNUSED
)
1018 if ((type
!= TYPE_FILE
) && (type
!= TYPE_DIR
))
1021 /* FAT16 root_dir */
1022 if (IS_CLUS_FREE(p_dir
->dir
))
1025 if (fsi
->vol_type
== EXFAT
)
1028 if ((p_dir
->dir
== fsi
->root_dir
) || (++count
> 2))
1032 /* FAT16 root_dir */
1033 if (IS_CLUS_FREE(p_dir
->dir
))
1036 if (clu
.flags
== 0x03) {
1037 if ((--clu
.size
) > 0)
1042 if (get_next_clus_safe(sb
, &(clu
.dir
)))
1051 * Name Conversion Functions
1053 #ifdef CONFIG_SDFAT_ALLOW_LOOKUP_LOSSY_SFN
1054 /* over name length only */
1055 #define NEED_INVALIDATE_SFN(x) ((x) & NLS_NAME_OVERLEN)
1057 /* all lossy case */
1058 #define NEED_INVALIDATE_SFN(x) (x)
1062 * We should keep shortname code compatible with v1.0.15 or lower
1063 * So, we try to check ext-only-name at create-mode only.
1066 * v1.0.15 : ' MTP' with name_case, 0x10
1067 * v1.1.0 : 'MT????~?' with name_case, 0x00 and longname.
1069 static inline void preprocess_ext_only_sfn(s32 lookup
, u16 first_char
, DOS_NAME_T
*p_dosname
, s32
*lossy
)
1071 #ifdef CONFIG_SDFAT_RESTRICT_EXT_ONLY_SFN
1073 /* check ext-only-name at create-mode */
1074 if (*lossy
|| lookup
|| (first_char
!= (u16
)'.'))
1077 p_dosname
->name_case
= 0xFF;
1079 /* move ext-name to base-name */
1080 for (i
= 0; i
< 3; i
++) {
1081 p_dosname
->name
[i
] = p_dosname
->name
[8+i
];
1082 if (p_dosname
->name
[i
] == ' ')
1083 p_dosname
->name
[i
] = '_';
1086 /* fill remained space with '_' */
1087 for (i
= 3; i
< 8; i
++)
1088 p_dosname
->name
[i
] = '_';
1090 /* eliminate ext-name */
1091 for (i
= 8; i
< 11; i
++)
1092 p_dosname
->name
[i
] = ' ';
1094 *lossy
= NLS_NAME_LOSSY
;
1095 #endif /* CONFIG_SDFAT_CAN_CREATE_EXT_ONLY_SFN */
1098 /* input : dir, uni_name
1099 * output : num_of_entry, dos_name(format : aaaaaa~1.bbb)
1101 static s32
get_num_entries_and_dos_name(struct super_block
*sb
, CHAIN_T
*p_dir
,
1102 UNI_NAME_T
*p_uniname
, s32
*entries
,
1103 DOS_NAME_T
*p_dosname
, s32 lookup
)
1105 s32 ret
, num_entries
, lossy
= NLS_NAME_NO_LOSSY
;
1107 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
1109 /* Init null char. */
1110 p_dosname
->name
[0] = '\0';
1112 num_entries
= fsi
->fs_func
->calc_num_entries(p_uniname
);
1113 if (num_entries
== 0)
1116 if (fsi
->vol_type
== EXFAT
)
1119 nls_uni16s_to_sfn(sb
, p_uniname
, p_dosname
, &lossy
);
1121 preprocess_ext_only_sfn(lookup
, p_uniname
->name
[0], p_dosname
, &lossy
);
1124 for (r
= reserved_names
; *r
; r
++) {
1125 if (!strncmp((void *) p_dosname
->name
, *r
, 8))
1129 if (p_dosname
->name_case
!= 0xFF)
1131 } else if (!lookup
) {
1132 /* create new dos name */
1133 ret
= fat_generate_dos_name_new(sb
, p_dir
, p_dosname
,
1138 } else if (NEED_INVALIDATE_SFN(lossy
)) {
1139 /* FIXME : We should check num_entries */
1140 p_dosname
->name
[0] = '\0';
1143 if (num_entries
> 1)
1144 p_dosname
->name_case
= 0x0;
1146 *entries
= num_entries
;
1148 } /* end of get_num_entries_and_dos_name */
1150 void get_uniname_from_dos_entry(struct super_block
*sb
, DOS_DENTRY_T
*ep
, UNI_NAME_T
*p_uniname
, u8 mode
)
1152 DOS_NAME_T dos_name
;
1155 dos_name
.name_case
= 0x0;
1157 dos_name
.name_case
= ep
->lcase
;
1159 memcpy(dos_name
.name
, ep
->name
, DOS_NAME_LENGTH
);
1160 nls_sfn_to_uni16s(sb
, &dos_name
, p_uniname
);
1161 } /* end of get_uniname_from_dos_entry */
1163 /* returns the length of a struct qstr, ignoring trailing dots */
1164 static inline unsigned int __striptail_len(unsigned int len
, const char *name
)
1166 while (len
&& name
[len
- 1] == '.')
1172 * Name Resolution Functions :
1173 * Zero if it was successful; otherwise nonzero.
1175 static s32
__resolve_path(struct inode
*inode
, const u8
*path
, CHAIN_T
*p_dir
, UNI_NAME_T
*p_uniname
, int lookup
)
1178 s32 lossy
= NLS_NAME_NO_LOSSY
;
1179 struct super_block
*sb
= inode
->i_sb
;
1180 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
1181 FILE_ID_T
*fid
= &(SDFAT_I(inode
)->fid
);
1183 /* DOT and DOTDOT are handled by VFS layer */
1185 /* strip all trailing spaces */
1186 /* DO NOTHING : Is needed? */
1188 /* strip all trailing periods */
1189 namelen
= __striptail_len(strlen(path
), path
);
1193 /* the limitation of linux? */
1194 if (strlen(path
) > (MAX_NAME_LENGTH
* MAX_CHARSET_SIZE
))
1195 return -ENAMETOOLONG
;
1198 * strip all leading spaces :
1199 * "MS windows 7" supports leading spaces.
1200 * So we should skip this preprocessing for compatibility.
1203 /* file name conversion :
1204 * If lookup case, we allow bad-name for compatibility.
1206 namelen
= nls_vfsname_to_uni16s(sb
, path
, namelen
, p_uniname
, &lossy
);
1208 return namelen
; /* return error value */
1210 if ((lossy
&& !lookup
) || !namelen
)
1213 sdfat_debug_bug_on(fid
->size
!= i_size_read(inode
));
1214 // fid->size = i_size_read(inode);
1216 p_dir
->dir
= fid
->start_clu
;
1217 p_dir
->size
= (s32
)(fid
->size
>> fsi
->cluster_size_bits
);
1218 p_dir
->flags
= fid
->flags
;
1223 static inline s32
resolve_path(struct inode
*inode
, const u8
*path
, CHAIN_T
*dir
, UNI_NAME_T
*uni
)
1225 return __resolve_path(inode
, path
, dir
, uni
, 0);
1228 static inline s32
resolve_path_for_lookup(struct inode
*inode
, const u8
*path
, CHAIN_T
*dir
, UNI_NAME_T
*uni
)
1230 return __resolve_path(inode
, path
, dir
, uni
, 1);
1233 static s32
create_dir(struct inode
*inode
, CHAIN_T
*p_dir
, UNI_NAME_T
*p_uniname
, FILE_ID_T
*fid
)
1235 s32 ret
, dentry
, num_entries
;
1238 DOS_NAME_T dos_name
, dot_name
;
1239 struct super_block
*sb
= inode
->i_sb
;
1240 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
1242 ret
= get_num_entries_and_dos_name(sb
, p_dir
, p_uniname
, &num_entries
, &dos_name
, 0);
1246 /* find_empty_entry must be called before alloc_cluster */
1247 dentry
= find_empty_entry(inode
, p_dir
, num_entries
);
1249 return dentry
; /* -EIO or -ENOSPC */
1253 clu
.flags
= (fsi
->vol_type
== EXFAT
) ? 0x03 : 0x01;
1255 /* (0) Check if there are reserved clusters up to max. */
1256 if ((fsi
->used_clusters
!= (u32
) ~0) &&
1257 ((fsi
->used_clusters
+ fsi
->reserved_clusters
) >= (fsi
->num_clusters
- 2)))
1260 /* (1) allocate a cluster */
1261 ret
= fsi
->fs_func
->alloc_cluster(sb
, 1, &clu
, ALLOC_HOT
);
1269 ret
= __clear_cluster(inode
, clu
.dir
);
1273 size
= fsi
->cluster_size
;
1274 if (fsi
->vol_type
!= EXFAT
) {
1275 /* initialize the . and .. entry
1276 * Information for . points to itself
1277 * Information for .. points to parent dir
1280 dot_name
.name_case
= 0x0;
1281 memcpy(dot_name
.name
, DOS_CUR_DIR_NAME
, DOS_NAME_LENGTH
);
1283 ret
= fsi
->fs_func
->init_dir_entry(sb
, &clu
, 0, TYPE_DIR
, clu
.dir
, 0);
1287 ret
= fsi
->fs_func
->init_ext_entry(sb
, &clu
, 0, 1, NULL
, &dot_name
);
1291 memcpy(dot_name
.name
, DOS_PAR_DIR_NAME
, DOS_NAME_LENGTH
);
1293 if (p_dir
->dir
== fsi
->root_dir
)
1294 ret
= fsi
->fs_func
->init_dir_entry(sb
, &clu
, 1, TYPE_DIR
, CLUS_FREE
, 0);
1296 ret
= fsi
->fs_func
->init_dir_entry(sb
, &clu
, 1, TYPE_DIR
, p_dir
->dir
, 0);
1301 ret
= fsi
->fs_func
->init_ext_entry(sb
, &clu
, 1, 1, NULL
, &dot_name
);
1306 /* (2) update the directory entry */
1307 /* make sub-dir entry in parent directory */
1308 ret
= fsi
->fs_func
->init_dir_entry(sb
, p_dir
, dentry
, TYPE_DIR
, clu
.dir
, size
);
1312 ret
= fsi
->fs_func
->init_ext_entry(sb
, p_dir
, dentry
, num_entries
, p_uniname
, &dos_name
);
1316 fid
->dir
.dir
= p_dir
->dir
;
1317 fid
->dir
.size
= p_dir
->size
;
1318 fid
->dir
.flags
= p_dir
->flags
;
1319 fid
->entry
= dentry
;
1321 fid
->attr
= ATTR_SUBDIR
;
1322 fid
->flags
= (fsi
->vol_type
== EXFAT
) ? 0x03 : 0x01;
1324 fid
->start_clu
= clu
.dir
;
1326 fid
->type
= TYPE_DIR
;
1328 fid
->hint_bmap
.off
= -1;
1330 /* hint_stat will be used if this is directory. */
1332 fid
->hint_stat
.eidx
= 0;
1333 fid
->hint_stat
.clu
= fid
->start_clu
;
1334 fid
->hint_femp
.eidx
= -1;
1337 } /* end of create_dir */
1339 static s32
create_file(struct inode
*inode
, CHAIN_T
*p_dir
, UNI_NAME_T
*p_uniname
, u8 mode
, FILE_ID_T
*fid
)
1341 s32 ret
, dentry
, num_entries
;
1342 DOS_NAME_T dos_name
;
1343 struct super_block
*sb
= inode
->i_sb
;
1344 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
1346 ret
= get_num_entries_and_dos_name(sb
, p_dir
, p_uniname
, &num_entries
, &dos_name
, 0);
1350 /* find_empty_entry must be called before alloc_cluster() */
1351 dentry
= find_empty_entry(inode
, p_dir
, num_entries
);
1353 return dentry
; /* -EIO or -ENOSPC */
1355 /* (1) update the directory entry */
1356 /* fill the dos name directory entry information of the created file.
1357 * the first cluster is not determined yet. (0)
1359 ret
= fsi
->fs_func
->init_dir_entry(sb
, p_dir
, dentry
, TYPE_FILE
| mode
, CLUS_FREE
, 0);
1363 ret
= fsi
->fs_func
->init_ext_entry(sb
, p_dir
, dentry
, num_entries
, p_uniname
, &dos_name
);
1367 fid
->dir
.dir
= p_dir
->dir
;
1368 fid
->dir
.size
= p_dir
->size
;
1369 fid
->dir
.flags
= p_dir
->flags
;
1370 fid
->entry
= dentry
;
1372 fid
->attr
= ATTR_ARCHIVE
| mode
;
1373 fid
->flags
= (fsi
->vol_type
== EXFAT
) ? 0x03 : 0x01;
1375 fid
->start_clu
= CLUS_EOF
;
1377 fid
->type
= TYPE_FILE
;
1379 fid
->hint_bmap
.off
= -1;
1381 /* hint_stat will be used if this is directory. */
1383 fid
->hint_stat
.eidx
= 0;
1384 fid
->hint_stat
.clu
= fid
->start_clu
;
1385 fid
->hint_femp
.eidx
= -1;
1388 } /* end of create_file */
1390 static s32
remove_file(struct inode
*inode
, CHAIN_T
*p_dir
, s32 entry
)
1395 struct super_block
*sb
= inode
->i_sb
;
1396 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
1398 ep
= get_dentry_in_dir(sb
, p_dir
, entry
, §or
);
1402 dcache_lock(sb
, sector
);
1404 /* dcache_lock() before call count_ext_entries() */
1405 num_entries
= fsi
->fs_func
->count_ext_entries(sb
, p_dir
, entry
, ep
);
1406 if (num_entries
< 0) {
1407 dcache_unlock(sb
, sector
);
1412 dcache_unlock(sb
, sector
);
1414 /* (1) update the directory entry */
1415 return fsi
->fs_func
->delete_dir_entry(sb
, p_dir
, entry
, 0, num_entries
);
1416 } /* end of remove_file */
1418 static s32
rename_file(struct inode
*inode
, CHAIN_T
*p_dir
, s32 oldentry
, UNI_NAME_T
*p_uniname
, FILE_ID_T
*fid
)
1420 s32 ret
, newentry
= -1, num_old_entries
, num_new_entries
;
1421 u32 sector_old
, sector_new
;
1422 DOS_NAME_T dos_name
;
1423 DENTRY_T
*epold
, *epnew
;
1424 struct super_block
*sb
= inode
->i_sb
;
1425 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
1427 epold
= get_dentry_in_dir(sb
, p_dir
, oldentry
, §or_old
);
1431 dcache_lock(sb
, sector_old
);
1433 /* dcache_lock() before call count_ext_entries() */
1434 num_old_entries
= fsi
->fs_func
->count_ext_entries(sb
, p_dir
, oldentry
, epold
);
1435 if (num_old_entries
< 0) {
1436 dcache_unlock(sb
, sector_old
);
1441 ret
= get_num_entries_and_dos_name(sb
, p_dir
, p_uniname
, &num_new_entries
, &dos_name
, 0);
1443 dcache_unlock(sb
, sector_old
);
1447 if (num_old_entries
< num_new_entries
) {
1448 newentry
= find_empty_entry(inode
, p_dir
, num_new_entries
);
1450 dcache_unlock(sb
, sector_old
);
1451 return newentry
; /* -EIO or -ENOSPC */
1454 epnew
= get_dentry_in_dir(sb
, p_dir
, newentry
, §or_new
);
1456 dcache_unlock(sb
, sector_old
);
1460 memcpy((void *) epnew
, (void *) epold
, DENTRY_SIZE
);
1461 if (fsi
->fs_func
->get_entry_type(epnew
) == TYPE_FILE
) {
1462 fsi
->fs_func
->set_entry_attr(epnew
, fsi
->fs_func
->get_entry_attr(epnew
) | ATTR_ARCHIVE
);
1463 fid
->attr
|= ATTR_ARCHIVE
;
1465 dcache_modify(sb
, sector_new
);
1466 dcache_unlock(sb
, sector_old
);
1468 if (fsi
->vol_type
== EXFAT
) {
1469 epold
= get_dentry_in_dir(sb
, p_dir
, oldentry
+1, §or_old
);
1470 dcache_lock(sb
, sector_old
);
1471 epnew
= get_dentry_in_dir(sb
, p_dir
, newentry
+1, §or_new
);
1473 if (!epold
|| !epnew
) {
1474 dcache_unlock(sb
, sector_old
);
1478 memcpy((void *) epnew
, (void *) epold
, DENTRY_SIZE
);
1479 dcache_modify(sb
, sector_new
);
1480 dcache_unlock(sb
, sector_old
);
1483 ret
= fsi
->fs_func
->init_ext_entry(sb
, p_dir
, newentry
, num_new_entries
, p_uniname
, &dos_name
);
1487 fsi
->fs_func
->delete_dir_entry(sb
, p_dir
, oldentry
, 0, num_old_entries
);
1488 fid
->entry
= newentry
;
1490 if (fsi
->fs_func
->get_entry_type(epold
) == TYPE_FILE
) {
1491 fsi
->fs_func
->set_entry_attr(epold
, fsi
->fs_func
->get_entry_attr(epold
) | ATTR_ARCHIVE
);
1492 fid
->attr
|= ATTR_ARCHIVE
;
1494 dcache_modify(sb
, sector_old
);
1495 dcache_unlock(sb
, sector_old
);
1497 ret
= fsi
->fs_func
->init_ext_entry(sb
, p_dir
, oldentry
, num_new_entries
, p_uniname
, &dos_name
);
1501 fsi
->fs_func
->delete_dir_entry(sb
, p_dir
, oldentry
, num_new_entries
, num_old_entries
);
1505 } /* end of rename_file */
1507 static s32
move_file(struct inode
*inode
, CHAIN_T
*p_olddir
, s32 oldentry
,
1508 CHAIN_T
*p_newdir
, UNI_NAME_T
*p_uniname
, FILE_ID_T
*fid
)
1510 s32 ret
, newentry
, num_new_entries
, num_old_entries
;
1511 u32 sector_mov
, sector_new
;
1513 DOS_NAME_T dos_name
;
1514 DENTRY_T
*epmov
, *epnew
;
1515 struct super_block
*sb
= inode
->i_sb
;
1516 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
1518 epmov
= get_dentry_in_dir(sb
, p_olddir
, oldentry
, §or_mov
);
1522 /* check if the source and target directory is the same */
1523 if (fsi
->fs_func
->get_entry_type(epmov
) == TYPE_DIR
&&
1524 fsi
->fs_func
->get_entry_clu0(epmov
) == p_newdir
->dir
)
1527 dcache_lock(sb
, sector_mov
);
1529 /* dcache_lock() before call count_ext_entries() */
1530 num_old_entries
= fsi
->fs_func
->count_ext_entries(sb
, p_olddir
, oldentry
, epmov
);
1531 if (num_old_entries
< 0) {
1532 dcache_unlock(sb
, sector_mov
);
1537 ret
= get_num_entries_and_dos_name(sb
, p_newdir
, p_uniname
, &num_new_entries
, &dos_name
, 0);
1539 dcache_unlock(sb
, sector_mov
);
1543 newentry
= find_empty_entry(inode
, p_newdir
, num_new_entries
);
1545 dcache_unlock(sb
, sector_mov
);
1546 return newentry
; /* -EIO or -ENOSPC */
1549 epnew
= get_dentry_in_dir(sb
, p_newdir
, newentry
, §or_new
);
1551 dcache_unlock(sb
, sector_mov
);
1555 memcpy((void *) epnew
, (void *) epmov
, DENTRY_SIZE
);
1556 if (fsi
->fs_func
->get_entry_type(epnew
) == TYPE_FILE
) {
1557 fsi
->fs_func
->set_entry_attr(epnew
, fsi
->fs_func
->get_entry_attr(epnew
) | ATTR_ARCHIVE
);
1558 fid
->attr
|= ATTR_ARCHIVE
;
1560 dcache_modify(sb
, sector_new
);
1561 dcache_unlock(sb
, sector_mov
);
1563 if (fsi
->vol_type
== EXFAT
) {
1564 epmov
= get_dentry_in_dir(sb
, p_olddir
, oldentry
+1, §or_mov
);
1565 dcache_lock(sb
, sector_mov
);
1566 epnew
= get_dentry_in_dir(sb
, p_newdir
, newentry
+1, §or_new
);
1567 if (!epmov
|| !epnew
) {
1568 dcache_unlock(sb
, sector_mov
);
1572 memcpy((void *) epnew
, (void *) epmov
, DENTRY_SIZE
);
1573 dcache_modify(sb
, sector_new
);
1574 dcache_unlock(sb
, sector_mov
);
1575 } else if (fsi
->fs_func
->get_entry_type(epnew
) == TYPE_DIR
) {
1576 /* change ".." pointer to new parent dir */
1577 clu
.dir
= fsi
->fs_func
->get_entry_clu0(epnew
);
1580 epnew
= get_dentry_in_dir(sb
, &clu
, 1, §or_new
);
1584 if (p_newdir
->dir
== fsi
->root_dir
)
1585 fsi
->fs_func
->set_entry_clu0(epnew
, CLUS_FREE
);
1587 fsi
->fs_func
->set_entry_clu0(epnew
, p_newdir
->dir
);
1588 dcache_modify(sb
, sector_new
);
1591 ret
= fsi
->fs_func
->init_ext_entry(sb
, p_newdir
, newentry
, num_new_entries
, p_uniname
, &dos_name
);
1595 fsi
->fs_func
->delete_dir_entry(sb
, p_olddir
, oldentry
, 0, num_old_entries
);
1597 fid
->dir
.dir
= p_newdir
->dir
;
1598 fid
->dir
.size
= p_newdir
->size
;
1599 fid
->dir
.flags
= p_newdir
->flags
;
1601 fid
->entry
= newentry
;
1604 } /* end of move_file */
1607 /*======================================================================*/
1608 /* Global Function Definitions */
1609 /*======================================================================*/
1610 /* roll back to the initial state of the file system */
1611 s32
fscore_init(void)
1615 ret
= check_type_size();
1619 return extent_cache_init();
1622 /* make free all memory-alloced global buffers */
1623 s32
fscore_shutdown(void)
1625 extent_cache_shutdown();
1629 static bool is_exfat(pbr_t
*pbr
)
1634 if (pbr
->bpb
.f64
.res_zero
[i
-1])
1637 return i
? false : true;
1640 static bool is_fat32(pbr_t
*pbr
)
1642 if (le16_to_cpu(pbr
->bpb
.f16
.num_fat_sectors
))
1647 inline pbr_t
*read_pbr_with_logical_sector(struct super_block
*sb
, struct buffer_head
**prev_bh
)
1649 pbr_t
*p_pbr
= (pbr_t
*) (*prev_bh
)->b_data
;
1650 u16 logical_sect
= 0;
1652 if (is_exfat(p_pbr
))
1653 logical_sect
= 1 << p_pbr
->bsx
.f64
.sect_size_bits
;
1655 logical_sect
= get_unaligned_le16(&p_pbr
->bpb
.f16
.sect_size
);
1657 /* is x a power of 2?
1658 * (x) != 0 && (((x) & ((x) - 1)) == 0)
1660 if (!is_power_of_2(logical_sect
)
1661 || (logical_sect
< 512)
1662 || (logical_sect
> 4096)) {
1663 sdfat_log_msg(sb
, KERN_ERR
, "bogus logical sector size %u",
1668 if (logical_sect
< sb
->s_blocksize
) {
1669 sdfat_log_msg(sb
, KERN_ERR
,
1670 "logical sector size too small for device"
1671 " (logical sector size = %u)", logical_sect
);
1675 if (logical_sect
> sb
->s_blocksize
) {
1676 struct buffer_head
*bh
= NULL
;
1681 if (!sb_set_blocksize(sb
, logical_sect
)) {
1682 sdfat_log_msg(sb
, KERN_ERR
,
1683 "unable to set blocksize %u", logical_sect
);
1686 bh
= sb_bread(sb
, 0);
1688 sdfat_log_msg(sb
, KERN_ERR
,
1689 "unable to read boot sector "
1690 "(logical sector size = %lu)", sb
->s_blocksize
);
1695 p_pbr
= (pbr_t
*) bh
->b_data
;
1698 sdfat_log_msg(sb
, KERN_INFO
,
1699 "set logical sector size : %lu", sb
->s_blocksize
);
1704 /* mount the file system volume */
1705 s32
fscore_mount(struct super_block
*sb
)
1709 struct buffer_head
*tmp_bh
= NULL
;
1710 struct gendisk
*disk
= sb
->s_bdev
->bd_disk
;
1711 struct sdfat_mount_options
*opts
= &(SDFAT_SB(sb
)->options
);
1712 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
1714 /* initialize previous I/O error */
1717 /* open the block device */
1718 if (bdev_open_dev(sb
))
1721 /* set block size to read super block */
1722 sb_min_blocksize(sb
, 512);
1724 /* read boot sector */
1725 ret
= read_sect(sb
, 0, &tmp_bh
, 1);
1727 sdfat_log_msg(sb
, KERN_ERR
, "unable to read boot sector");
1733 p_pbr
= (pbr_t
*) tmp_bh
->b_data
;
1735 /* check the validity of PBR */
1736 if (le16_to_cpu((p_pbr
->signature
)) != PBR_SIGNATURE
) {
1737 sdfat_log_msg(sb
, KERN_ERR
, "invalid boot record signature");
1743 /* check logical sector size */
1744 p_pbr
= read_pbr_with_logical_sector(sb
, &tmp_bh
);
1751 /* fill fs_struct */
1752 if (is_exfat(p_pbr
)) {
1753 if (opts
->fs_type
&& opts
->fs_type
!= FS_TYPE_EXFAT
) {
1754 sdfat_log_msg(sb
, KERN_ERR
,
1755 "not specified filesystem type "
1756 "(media:exfat, opts:%s)",
1757 FS_TYPE_STR
[opts
->fs_type
]);
1761 /* set maximum file size for exFAT */
1762 sb
->s_maxbytes
= 0x7fffffffffffffffLL
;
1763 opts
->improved_allocation
= 0;
1765 ret
= mount_exfat(sb
, p_pbr
);
1766 } else if (is_fat32(p_pbr
)) {
1767 if (opts
->fs_type
&& opts
->fs_type
!= FS_TYPE_VFAT
) {
1768 sdfat_log_msg(sb
, KERN_ERR
,
1769 "not specified filesystem type "
1770 "(media:vfat, opts:%s)",
1771 FS_TYPE_STR
[opts
->fs_type
]);
1775 /* set maximum file size for FAT */
1776 sb
->s_maxbytes
= 0xffffffff;
1777 ret
= mount_fat32(sb
, p_pbr
);
1779 if (opts
->fs_type
&& opts
->fs_type
!= FS_TYPE_VFAT
) {
1780 sdfat_log_msg(sb
, KERN_ERR
,
1781 "not specified filesystem type "
1782 "(media:vfat, opts:%s)",
1783 FS_TYPE_STR
[opts
->fs_type
]);
1787 /* set maximum file size for FAT */
1788 sb
->s_maxbytes
= 0xffffffff;
1789 opts
->improved_allocation
= 0;
1791 ret
= mount_fat16(sb
, p_pbr
);
1796 sdfat_log_msg(sb
, KERN_ERR
, "failed to mount fs-core");
1800 /* warn misaligned data data start sector must be a multiple of clu_size */
1801 sdfat_log_msg(sb
, KERN_INFO
,
1802 "detected volume info : %s "
1803 "(bps : %lu, spc : %u, data start : %u, %s)",
1804 sdfat_get_vol_type_str(fsi
->vol_type
),
1805 sb
->s_blocksize
, fsi
->sect_per_clus
, fsi
->data_start_sector
,
1806 (fsi
->data_start_sector
& (fsi
->sect_per_clus
- 1)) ?
1807 "misaligned" : "aligned");
1809 sdfat_log_msg(sb
, KERN_INFO
,
1810 "detected volume size : %u MB (disk_size : %llu MB)",
1811 fsi
->num_sectors
>> 11,
1812 disk
? (u64
)((disk
->part0
.nr_sects
) >> 11) : 0);
1814 ret
= load_upcase_table(sb
);
1816 sdfat_log_msg(sb
, KERN_ERR
, "failed to load upcase table");
1820 if (fsi
->vol_type
!= EXFAT
)
1823 /* allocate-bitmap is only for exFAT */
1824 ret
= load_alloc_bmp(sb
);
1826 sdfat_log_msg(sb
, KERN_ERR
, "failed to load alloc-bitmap");
1832 free_upcase_table(sb
);
1836 } /* end of fscore_mount */
1838 /* umount the file system volume */
1839 s32
fscore_umount(struct super_block
*sb
)
1842 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
1847 if (fs_set_vol_flags(sb
, VOL_CLEAN
))
1850 free_upcase_table(sb
);
1852 if (fsi
->vol_type
== EXFAT
)
1855 if (fcache_release_all(sb
))
1858 if (dcache_release_all(sb
))
1865 /* close the block device */
1870 /* get the information of a file system volume */
1871 s32
fscore_statfs(struct super_block
*sb
, VOL_INFO_T
*info
)
1873 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
1875 if (fsi
->used_clusters
== (u32
) ~0) {
1876 if (fsi
->fs_func
->count_used_clusters(sb
, &fsi
->used_clusters
))
1880 info
->FatType
= fsi
->vol_type
;
1881 info
->ClusterSize
= fsi
->cluster_size
;
1882 info
->NumClusters
= fsi
->num_clusters
- 2; /* clu 0 & 1 */
1883 info
->UsedClusters
= fsi
->used_clusters
+ fsi
->reserved_clusters
;
1884 info
->FreeClusters
= info
->NumClusters
- info
->UsedClusters
;
1889 /* synchronize all file system volumes */
1890 s32
fscore_sync_fs(struct super_block
*sb
, s32 do_sync
)
1892 /* synchronize the file system */
1893 if (fs_sync(sb
, do_sync
))
1896 if (fs_set_vol_flags(sb
, VOL_CLEAN
))
1902 /* stat allocation unit of a file system volume */
1903 u32
fscore_get_au_stat(struct super_block
*sb
, s32 mode
)
1905 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
1907 if (fsi
->fs_func
->get_au_stat
)
1908 return fsi
->fs_func
->get_au_stat(sb
, mode
);
1910 /* No error, just returns 0 */
1915 /*----------------------------------------------------------------------*/
1916 /* File Operation Functions */
1917 /*----------------------------------------------------------------------*/
1919 s32
fscore_lookup(struct inode
*inode
, u8
*path
, FILE_ID_T
*fid
)
1921 s32 ret
, dentry
, num_entries
;
1923 UNI_NAME_T uni_name
;
1924 DOS_NAME_T dos_name
;
1926 ENTRY_SET_CACHE_T
*es
= NULL
;
1927 struct super_block
*sb
= inode
->i_sb
;
1928 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
1929 FILE_ID_T
*dir_fid
= &(SDFAT_I(inode
)->fid
);
1931 TMSG("%s entered\n", __func__
);
1933 /* check the validity of directory name in the given pathname */
1934 ret
= resolve_path_for_lookup(inode
, path
, &dir
, &uni_name
);
1938 ret
= get_num_entries_and_dos_name(sb
, &dir
, &uni_name
, &num_entries
, &dos_name
, 1);
1942 /* check the validation of hint_stat and initialize it if required */
1943 if (dir_fid
->version
!= (u32
)(inode
->i_version
& 0xffffffff)) {
1944 dir_fid
->hint_stat
.clu
= dir
.dir
;
1945 dir_fid
->hint_stat
.eidx
= 0;
1946 dir_fid
->version
= (u32
)(inode
->i_version
& 0xffffffff);
1947 dir_fid
->hint_femp
.eidx
= -1;
1950 /* search the file name for directories */
1951 dentry
= fsi
->fs_func
->find_dir_entry(sb
, dir_fid
, &dir
, &uni_name
,
1952 num_entries
, &dos_name
, TYPE_ALL
);
1954 if ((dentry
< 0) && (dentry
!= -EEXIST
))
1955 return dentry
; /* -error value */
1957 fid
->dir
.dir
= dir
.dir
;
1958 fid
->dir
.size
= dir
.size
;
1959 fid
->dir
.flags
= dir
.flags
;
1960 fid
->entry
= dentry
;
1962 /* root directory itself */
1963 if (unlikely(dentry
== -EEXIST
)) {
1964 fid
->type
= TYPE_DIR
;
1966 fid
->hint_bmap
.off
= -1;
1968 fid
->attr
= ATTR_SUBDIR
;
1971 fid
->start_clu
= fsi
->root_dir
;
1973 if (fsi
->vol_type
== EXFAT
) {
1974 es
= get_dentry_set_in_dir(sb
, &dir
, dentry
, ES_2_ENTRIES
, &ep
);
1979 ep
= get_dentry_in_dir(sb
, &dir
, dentry
, NULL
);
1985 fid
->type
= fsi
->fs_func
->get_entry_type(ep
);
1987 fid
->hint_bmap
.off
= -1;
1988 fid
->attr
= fsi
->fs_func
->get_entry_attr(ep
);
1990 fid
->size
= fsi
->fs_func
->get_entry_size(ep2
);
1991 if ((fid
->type
== TYPE_FILE
) && (fid
->size
== 0)) {
1992 fid
->flags
= (fsi
->vol_type
== EXFAT
) ? 0x03 : 0x01;
1993 fid
->start_clu
= CLUS_EOF
;
1995 fid
->flags
= fsi
->fs_func
->get_entry_flag(ep2
);
1996 fid
->start_clu
= fsi
->fs_func
->get_entry_clu0(ep2
);
1999 if ((fid
->type
== TYPE_DIR
) && (fsi
->vol_type
!= EXFAT
)) {
2003 tmp_dir
.dir
= fid
->start_clu
;
2004 tmp_dir
.flags
= fid
->flags
;
2005 tmp_dir
.size
= 0; /* UNUSED */
2007 if (__count_num_clusters(sb
, &tmp_dir
, &num_clu
))
2009 fid
->size
= (u64
)num_clu
<< fsi
->cluster_size_bits
;
2012 /* FOR GRACEFUL ERROR HANDLING */
2013 if (IS_CLUS_FREE(fid
->start_clu
)) {
2015 "non-zero size file starts with zero cluster "
2016 "(size : %llu, p_dir : %u, entry : 0x%08x)",
2017 fid
->size
, fid
->dir
.dir
, fid
->entry
);
2018 sdfat_debug_bug_on(1);
2022 if (fsi
->vol_type
== EXFAT
)
2023 release_dentry_set(es
);
2026 /* hint_stat will be used if this is directory. */
2028 fid
->hint_stat
.eidx
= 0;
2029 fid
->hint_stat
.clu
= fid
->start_clu
;
2030 fid
->hint_femp
.eidx
= -1;
2032 TMSG("%s exited successfully\n", __func__
);
2034 } /* end of fscore_lookup */
2037 s32
fscore_create(struct inode
*inode
, u8
*path
, u8 mode
, FILE_ID_T
*fid
)
2039 s32 ret
/*, dentry*/;
2041 UNI_NAME_T uni_name
;
2042 struct super_block
*sb
= inode
->i_sb
;
2044 /* check the validity of directory name in the given pathname */
2045 ret
= resolve_path(inode
, path
, &dir
, &uni_name
);
2049 fs_set_vol_flags(sb
, VOL_DIRTY
);
2051 /* create a new file */
2052 ret
= create_file(inode
, &dir
, &uni_name
, mode
, fid
);
2055 fs_set_vol_flags(sb
, VOL_CLEAN
);
2060 /* read data from a opened file */
2061 s32
fscore_read_link(struct inode
*inode
, FILE_ID_T
*fid
, void *buffer
, u64 count
, u64
*rcount
)
2064 s32 offset
, sec_offset
, clu_offset
;
2066 u64 oneblkread
, read_bytes
;
2067 struct buffer_head
*tmp_bh
= NULL
;
2068 struct super_block
*sb
= inode
->i_sb
;
2069 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
2071 /* check if the given file ID is opened */
2072 if (fid
->type
!= TYPE_FILE
)
2075 if (fid
->rwoffset
> fid
->size
)
2076 fid
->rwoffset
= fid
->size
;
2078 if (count
> (fid
->size
- fid
->rwoffset
))
2079 count
= fid
->size
- fid
->rwoffset
;
2090 clu_offset
= (s32
)(fid
->rwoffset
>> fsi
->cluster_size_bits
);
2091 clu
= fid
->start_clu
;
2093 if (fid
->flags
== 0x03) {
2096 /* hint information */
2097 if ((clu_offset
> 0) && (fid
->hint_bmap
.off
> 0) &&
2098 (clu_offset
>= fid
->hint_bmap
.off
)) {
2099 clu_offset
-= fid
->hint_bmap
.off
;
2100 clu
= fid
->hint_bmap
.clu
;
2103 while (clu_offset
> 0) {
2104 ret
= get_next_clus_safe(sb
, &clu
);
2112 /* hint information */
2113 fid
->hint_bmap
.off
= (s32
)(fid
->rwoffset
>> fsi
->cluster_size_bits
);
2114 fid
->hint_bmap
.clu
= clu
;
2116 offset
= (s32
)(fid
->rwoffset
& (fsi
->cluster_size
- 1)); /* byte offset in cluster */
2117 sec_offset
= offset
>> sb
->s_blocksize_bits
; /* sector offset in cluster */
2118 offset
&= (sb
->s_blocksize
- 1); /* byte offset in sector */
2120 LogSector
= CLUS_TO_SECT(fsi
, clu
) + sec_offset
;
2122 oneblkread
= (u64
)(sb
->s_blocksize
- offset
);
2123 if (oneblkread
> count
)
2126 if ((offset
== 0) && (oneblkread
== sb
->s_blocksize
)) {
2127 ret
= read_sect(sb
, LogSector
, &tmp_bh
, 1);
2130 memcpy(((s8
*) buffer
)+read_bytes
, ((s8
*) tmp_bh
->b_data
), (s32
) oneblkread
);
2132 ret
= read_sect(sb
, LogSector
, &tmp_bh
, 1);
2135 memcpy(((s8
*) buffer
)+read_bytes
, ((s8
*) tmp_bh
->b_data
)+offset
, (s32
) oneblkread
);
2137 count
-= oneblkread
;
2138 read_bytes
+= oneblkread
;
2139 fid
->rwoffset
+= oneblkread
;
2145 /* set the size of read bytes */
2147 *rcount
= read_bytes
;
2150 } /* end of fscore_read_link */
2152 /* write data into a opened file */
2153 s32
fscore_write_link(struct inode
*inode
, FILE_ID_T
*fid
, void *buffer
, u64 count
, u64
*wcount
)
2156 s32 modified
= false, offset
, sec_offset
, clu_offset
;
2157 s32 num_clusters
, num_alloc
, num_alloced
= (s32
) ~0;
2158 u32 clu
, last_clu
, LogSector
, sector
;
2159 u64 oneblkwrite
, write_bytes
;
2163 ENTRY_SET_CACHE_T
*es
= NULL
;
2164 struct buffer_head
*tmp_bh
= NULL
;
2165 struct super_block
*sb
= inode
->i_sb
;
2166 u32 blksize
= (u32
)sb
->s_blocksize
;
2167 u32 blksize_mask
= (u32
)(sb
->s_blocksize
-1);
2168 u8 blksize_bits
= sb
->s_blocksize_bits
;
2169 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
2171 /* check if the given file ID is opened */
2172 if (fid
->type
!= TYPE_FILE
)
2175 if (fid
->rwoffset
> fid
->size
)
2176 fid
->rwoffset
= fid
->size
;
2184 fs_set_vol_flags(sb
, VOL_DIRTY
);
2189 num_clusters
= (s32
)((fid
->size
-1) >> fsi
->cluster_size_bits
) + 1;
2194 clu_offset
= (s32
)(fid
->rwoffset
>> fsi
->cluster_size_bits
);
2195 clu
= last_clu
= fid
->start_clu
;
2197 if (fid
->flags
== 0x03) {
2198 if ((clu_offset
> 0) && (!IS_CLUS_EOF(clu
))) {
2199 last_clu
+= clu_offset
- 1;
2201 if (clu_offset
== num_clusters
)
2207 /* hint information */
2208 if ((clu_offset
> 0) && (fid
->hint_bmap
.off
> 0) &&
2209 (clu_offset
>= fid
->hint_bmap
.off
)) {
2210 clu_offset
-= fid
->hint_bmap
.off
;
2211 clu
= fid
->hint_bmap
.clu
;
2214 while ((clu_offset
> 0) && (!IS_CLUS_EOF(clu
))) {
2216 ret
= get_next_clus_safe(sb
, &clu
);
2224 if (IS_CLUS_EOF(clu
)) {
2225 num_alloc
= (s32
)((count
-1) >> fsi
->cluster_size_bits
) + 1;
2226 new_clu
.dir
= IS_CLUS_EOF(last_clu
) ? CLUS_EOF
: last_clu
+1;
2228 new_clu
.flags
= fid
->flags
;
2230 /* (1) allocate a chain of clusters */
2231 num_alloced
= fsi
->fs_func
->alloc_cluster(sb
, num_alloc
, &new_clu
, ALLOC_COLD
);
2235 if (num_alloced
< 0) {
2240 /* (2) append to the FAT chain */
2241 if (IS_CLUS_EOF(last_clu
)) {
2242 if (new_clu
.flags
== 0x01)
2244 fid
->start_clu
= new_clu
.dir
;
2247 if (new_clu
.flags
!= fid
->flags
) {
2248 /* no-fat-chain bit is disabled,
2249 * so fat-chain should be synced with
2252 chain_cont_cluster(sb
, fid
->start_clu
, num_clusters
);
2256 if (new_clu
.flags
== 0x01) {
2257 ret
= fat_ent_set(sb
, last_clu
, new_clu
.dir
);
2263 num_clusters
+= num_alloced
;
2267 /* hint information */
2268 fid
->hint_bmap
.off
= (s32
)(fid
->rwoffset
>> fsi
->cluster_size_bits
);
2269 fid
->hint_bmap
.clu
= clu
;
2271 /* byte offset in cluster */
2272 offset
= (s32
)(fid
->rwoffset
& (fsi
->cluster_size
-1));
2273 /* sector offset in cluster */
2274 sec_offset
= offset
>> blksize_bits
;
2275 /* byte offset in sector */
2276 offset
&= blksize_mask
;
2277 LogSector
= CLUS_TO_SECT(fsi
, clu
) + sec_offset
;
2279 oneblkwrite
= (u64
)(blksize
- offset
);
2280 if (oneblkwrite
> count
)
2281 oneblkwrite
= count
;
2283 if ((offset
== 0) && (oneblkwrite
== blksize
)) {
2284 ret
= read_sect(sb
, LogSector
, &tmp_bh
, 0);
2288 memcpy(((s8
*)tmp_bh
->b_data
),
2289 ((s8
*)buffer
)+write_bytes
,
2292 ret
= write_sect(sb
, LogSector
, tmp_bh
, 0);
2298 if ((offset
> 0) || ((fid
->rwoffset
+oneblkwrite
) < fid
->size
)) {
2299 ret
= read_sect(sb
, LogSector
, &tmp_bh
, 1);
2303 ret
= read_sect(sb
, LogSector
, &tmp_bh
, 0);
2308 memcpy(((s8
*) tmp_bh
->b_data
)+offset
, ((s8
*) buffer
)+write_bytes
, (s32
) oneblkwrite
);
2309 ret
= write_sect(sb
, LogSector
, tmp_bh
, 0);
2316 count
-= oneblkwrite
;
2317 write_bytes
+= oneblkwrite
;
2318 fid
->rwoffset
+= oneblkwrite
;
2320 fid
->attr
|= ATTR_ARCHIVE
;
2322 if (fid
->size
< fid
->rwoffset
) {
2323 fid
->size
= fid
->rwoffset
;
2330 /* (3) update the direcoty entry */
2331 /* get_entry_(set_)in_dir shoulb be check DIR_DELETED flag. */
2332 if (fsi
->vol_type
== EXFAT
) {
2333 es
= get_dentry_set_in_dir(sb
, &(fid
->dir
), fid
->entry
, ES_ALL_ENTRIES
, &ep
);
2340 ep
= get_dentry_in_dir(sb
, &(fid
->dir
), fid
->entry
, §or
);
2348 fsi
->fs_func
->set_entry_time(ep
, tm_now(SDFAT_SB(sb
), &tm
), TM_MODIFY
);
2349 fsi
->fs_func
->set_entry_attr(ep
, fid
->attr
);
2352 if (fsi
->fs_func
->get_entry_flag(ep2
) != fid
->flags
)
2353 fsi
->fs_func
->set_entry_flag(ep2
, fid
->flags
);
2355 if (fsi
->fs_func
->get_entry_size(ep2
) != fid
->size
)
2356 fsi
->fs_func
->set_entry_size(ep2
, fid
->size
);
2358 if (fsi
->fs_func
->get_entry_clu0(ep2
) != fid
->start_clu
)
2359 fsi
->fs_func
->set_entry_clu0(ep2
, fid
->start_clu
);
2362 if (fsi
->vol_type
== EXFAT
) {
2363 if (update_dir_chksum_with_entry_set(sb
, es
)) {
2367 release_dentry_set(es
);
2369 if (dcache_modify(sb
, sector
)) {
2376 fs_set_vol_flags(sb
, VOL_CLEAN
);
2379 /* set the size of written bytes */
2381 *wcount
= write_bytes
;
2387 } /* end of fscore_write_link */
2389 /* resize the file length */
2390 s32
fscore_truncate(struct inode
*inode
, u64 old_size
, u64 new_size
)
2392 s32 num_clusters_new
, num_clusters_da
, num_clusters_phys
;
2393 u32 last_clu
= CLUS_FREE
, sector
;
2397 struct super_block
*sb
= inode
->i_sb
;
2398 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
2399 FILE_ID_T
*fid
= &(SDFAT_I(inode
)->fid
);
2400 ENTRY_SET_CACHE_T
*es
= NULL
;
2401 s32 evict
= (fid
->dir
.dir
== DIR_DELETED
) ? 1 : 0;
2403 /* check if the given file ID is opened */
2404 if ((fid
->type
!= TYPE_FILE
) && (fid
->type
!= TYPE_DIR
))
2407 /* TO CHECK inode type and size */
2408 MMSG("%s: inode(%p) type(%s) size:%lld->%lld\n", __func__
, inode
,
2409 (fid
->type
== TYPE_FILE
) ? "file" : "dir", old_size
, new_size
);
2411 /* XXX : This is for debugging. */
2413 /* It can be when write failed */
2415 if (fid
->size
!= old_size
) {
2416 DMSG("%s: inode(%p) size-mismatch(old:%lld != fid:%lld)\n",
2417 __func__
, inode
, old_size
, fid
->size
);
2422 * There is no lock to protect fid->size.
2423 * So, we should get old_size and use it.
2425 if (old_size
<= new_size
)
2428 fs_set_vol_flags(sb
, VOL_DIRTY
);
2430 /* Reserved count update */
2431 #define num_clusters(v) ((v) ? (s32)(((v) - 1) >> fsi->cluster_size_bits) + 1 : 0)
2432 num_clusters_da
= num_clusters(SDFAT_I(inode
)->i_size_aligned
);
2433 num_clusters_new
= num_clusters(i_size_read(inode
));
2434 num_clusters_phys
= num_clusters(SDFAT_I(inode
)->i_size_ondisk
);
2436 /* num_clusters(i_size_old) should be equal to num_clusters_da */
2437 BUG_ON((num_clusters(old_size
)) != (num_clusters(SDFAT_I(inode
)->i_size_aligned
)));
2439 /* for debugging (FIXME: is okay on no-da case?) */
2440 BUG_ON(num_clusters_da
< num_clusters_phys
);
2442 if ((num_clusters_da
!= num_clusters_phys
) &&
2443 (num_clusters_new
< num_clusters_da
)) {
2444 /* Decrement reserved clusters
2445 * n_reserved = num_clusters_da - max(new,phys)
2447 int n_reserved
= (num_clusters_new
> num_clusters_phys
) ?
2448 (num_clusters_da
- num_clusters_new
) :
2449 (num_clusters_da
- num_clusters_phys
);
2451 fsi
->reserved_clusters
-= n_reserved
;
2452 BUG_ON(fsi
->reserved_clusters
< 0);
2455 clu
.dir
= fid
->start_clu
;
2456 /* In no-da case, num_clusters_phys is equal to below value
2457 * clu.size = (s32)((old_size-1) >> fsi->cluster_size_bits) + 1;
2459 clu
.size
= num_clusters_phys
;
2460 clu
.flags
= fid
->flags
;
2463 sdfat_statistics_set_trunc(clu
.flags
, &clu
);
2466 /* Truncate FAT chain num_clusters after the first cluster
2467 * num_clusters = min(new, phys);
2469 s32 num_clusters
= (num_clusters_new
< num_clusters_phys
) ?
2470 num_clusters_new
: num_clusters_phys
;
2473 * (defensive coding - works fine even with corrupted FAT table
2475 if (clu
.flags
== 0x03) {
2476 clu
.dir
+= num_clusters
;
2477 clu
.size
-= num_clusters
;
2479 /* extent_get_clus can`t know last_cluster
2480 * when find target cluster in cache.
2482 } else if (fid
->type
== TYPE_FILE
) {
2484 s32 err
= extent_get_clus(inode
, num_clusters
,
2485 &fclus
, &(clu
.dir
), &last_clu
, 0);
2488 ASSERT(fclus
== num_clusters
);
2490 if ((num_clusters
> 1) && (last_clu
== fid
->start_clu
)) {
2494 err
= extent_get_clus(inode
, num_clusters
- 1,
2495 &fclus_tmp
, &last_clu
, &temp
, 0);
2498 ASSERT(fclus_tmp
== (num_clusters
- 1));
2501 num_clusters
-= fclus
;
2505 while (num_clusters
> 0) {
2507 if (get_next_clus_safe(sb
, &(clu
.dir
)))
2515 /* Optimization avialable: */
2517 if (num_clusters_new
< num_clusters
) {
2520 // num_clusters_new >= num_clusters_phys
2521 // FAT truncation is not necessary
2527 } else if (new_size
== 0) {
2528 fid
->flags
= (fsi
->vol_type
== EXFAT
) ? 0x03 : 0x01;
2529 fid
->start_clu
= CLUS_EOF
;
2531 BUG_ON(clu
.size
< 0);
2532 fid
->size
= new_size
;
2534 if (fid
->type
== TYPE_FILE
)
2535 fid
->attr
|= ATTR_ARCHIVE
;
2538 * clu.dir: free from
2539 * clu.size: # of clusters to free (exFAT, 0x03 only), no fat_free if 0
2540 * clu.flags: fid->flags (exFAT only)
2543 /* (1) update the directory entry */
2546 if (fsi
->vol_type
== EXFAT
) {
2547 es
= get_dentry_set_in_dir(sb
, &(fid
->dir
), fid
->entry
, ES_ALL_ENTRIES
, &ep
);
2552 ep
= get_dentry_in_dir(sb
, &(fid
->dir
), fid
->entry
, §or
);
2558 fsi
->fs_func
->set_entry_time(ep
, tm_now(SDFAT_SB(sb
), &tm
), TM_MODIFY
);
2559 fsi
->fs_func
->set_entry_attr(ep
, fid
->attr
);
2562 * if (fsi->vol_type != EXFAT)
2563 * dcache_modify(sb, sector);
2566 /* File size should be zero if there is no cluster allocated */
2567 if (IS_CLUS_EOF(fid
->start_clu
))
2568 fsi
->fs_func
->set_entry_size(ep2
, 0);
2570 fsi
->fs_func
->set_entry_size(ep2
, new_size
);
2572 if (new_size
== 0) {
2573 /* Any directory can not be truncated to zero */
2574 BUG_ON(fid
->type
!= TYPE_FILE
);
2576 fsi
->fs_func
->set_entry_flag(ep2
, 0x01);
2577 fsi
->fs_func
->set_entry_clu0(ep2
, CLUS_FREE
);
2580 if (fsi
->vol_type
== EXFAT
) {
2581 if (update_dir_chksum_with_entry_set(sb
, es
))
2583 release_dentry_set(es
);
2585 if (dcache_modify(sb
, sector
))
2589 } /* end of if(fid->dir.dir != DIR_DELETED) */
2591 /* (2) cut off from the FAT chain */
2592 if ((fid
->flags
== 0x01) &&
2593 (!IS_CLUS_FREE(last_clu
)) && (!IS_CLUS_EOF(last_clu
))) {
2594 if (fat_ent_set(sb
, last_clu
, CLUS_EOF
))
2598 /* (3) invalidate cache and free the clusters */
2599 /* clear extent cache */
2600 extent_cache_inval_inode(inode
);
2602 /* hint information */
2603 fid
->hint_bmap
.off
= -1;
2604 fid
->hint_bmap
.clu
= CLUS_EOF
;
2605 if (fid
->rwoffset
> fid
->size
)
2606 fid
->rwoffset
= fid
->size
;
2608 /* hint_stat will be used if this is directory. */
2609 fid
->hint_stat
.eidx
= 0;
2610 fid
->hint_stat
.clu
= fid
->start_clu
;
2611 fid
->hint_femp
.eidx
= -1;
2613 /* free the clusters */
2614 if (fsi
->fs_func
->free_cluster(sb
, &clu
, evict
))
2618 fs_set_vol_flags(sb
, VOL_CLEAN
);
2621 } /* end of fscore_truncate */
2623 static void update_parent_info(FILE_ID_T
*fid
, struct inode
*parent_inode
)
2625 FS_INFO_T
*fsi
= &(SDFAT_SB(parent_inode
->i_sb
)->fsi
);
2626 FILE_ID_T
*parent_fid
= &(SDFAT_I(parent_inode
)->fid
);
2629 * the problem that FILE_ID_T caches wrong parent info.
2631 * because of flag-mismatch of fid->dir,
2632 * there is abnormal traversing cluster chain.
2634 if (unlikely((parent_fid
->flags
!= fid
->dir
.flags
)
2635 || (parent_fid
->size
!= (fid
->dir
.size
<<fsi
->cluster_size_bits
))
2636 || (parent_fid
->start_clu
!= fid
->dir
.dir
))) {
2638 fid
->dir
.dir
= parent_fid
->start_clu
;
2639 fid
->dir
.flags
= parent_fid
->flags
;
2640 fid
->dir
.size
= ((parent_fid
->size
+ (fsi
->cluster_size
-1))
2641 >> fsi
->cluster_size_bits
);
2645 /* rename or move a old file into a new file */
2646 s32
fscore_rename(struct inode
*old_parent_inode
, FILE_ID_T
*fid
,
2647 struct inode
*new_parent_inode
, struct dentry
*new_dentry
)
2651 CHAIN_T olddir
, newdir
;
2652 CHAIN_T
*p_dir
= NULL
;
2653 UNI_NAME_T uni_name
;
2655 struct super_block
*sb
= old_parent_inode
->i_sb
;
2656 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
2657 u8
*new_path
= (u8
*) new_dentry
->d_name
.name
;
2658 struct inode
*new_inode
= new_dentry
->d_inode
;
2660 FILE_ID_T
*new_fid
= NULL
;
2661 u32 new_entry_type
= TYPE_UNUSED
;
2664 /* check the validity of pointer parameters */
2665 if ((new_path
== NULL
) || (strlen(new_path
) == 0))
2668 if (fid
->dir
.dir
== DIR_DELETED
) {
2669 EMSG("%s : abnormal access to deleted source dentry\n", __func__
);
2673 /* patch 1.2.4 : the problem that FILE_ID_T caches wrong parent info. */
2674 update_parent_info(fid
, old_parent_inode
);
2676 olddir
.dir
= fid
->dir
.dir
;
2677 olddir
.size
= fid
->dir
.size
;
2678 olddir
.flags
= fid
->dir
.flags
;
2680 dentry
= fid
->entry
;
2682 /* check if the old file is "." or ".." */
2683 if (fsi
->vol_type
!= EXFAT
) {
2684 if ((olddir
.dir
!= fsi
->root_dir
) && (dentry
< 2))
2688 ep
= get_dentry_in_dir(sb
, &olddir
, dentry
, NULL
);
2692 #ifdef CONFIG_SDFAT_CHECK_RO_ATTR
2693 if (fsi
->fs_func
->get_entry_attr(ep
) & ATTR_READONLY
)
2697 /* check whether new dir is existing directory and empty */
2700 new_fid
= &SDFAT_I(new_inode
)->fid
;
2702 if (new_fid
->dir
.dir
== DIR_DELETED
) {
2703 EMSG("%s : abnormal access to deleted target dentry\n", __func__
);
2708 * the problem that FILE_ID_T caches wrong parent info.
2710 * FIXME : is needed?
2712 update_parent_info(new_fid
, new_parent_inode
);
2714 p_dir
= &(new_fid
->dir
);
2715 new_entry
= new_fid
->entry
;
2716 ep
= get_dentry_in_dir(sb
, p_dir
, new_entry
, NULL
);
2720 new_entry_type
= fsi
->fs_func
->get_entry_type(ep
);
2722 /* if new_inode exists, update fid */
2723 new_fid
->size
= i_size_read(new_inode
);
2725 if (new_entry_type
== TYPE_DIR
) {
2728 new_clu
.dir
= new_fid
->start_clu
;
2729 new_clu
.size
= (s32
)((new_fid
->size
-1) >> fsi
->cluster_size_bits
) + 1;
2730 new_clu
.flags
= new_fid
->flags
;
2732 ret
= check_dir_empty(sb
, &new_clu
);
2738 /* check the validity of directory name in the given new pathname */
2739 ret
= resolve_path(new_parent_inode
, new_path
, &newdir
, &uni_name
);
2743 fs_set_vol_flags(sb
, VOL_DIRTY
);
2745 if (olddir
.dir
== newdir
.dir
)
2746 ret
= rename_file(new_parent_inode
, &olddir
, dentry
, &uni_name
, fid
);
2748 ret
= move_file(new_parent_inode
, &olddir
, dentry
, &newdir
, &uni_name
, fid
);
2750 if ((!ret
) && new_inode
) {
2751 /* delete entries of new_dir */
2752 ep
= get_dentry_in_dir(sb
, p_dir
, new_entry
, NULL
);
2758 num_entries
= fsi
->fs_func
->count_ext_entries(sb
, p_dir
, new_entry
, ep
);
2759 if (num_entries
< 0) {
2765 if (fsi
->fs_func
->delete_dir_entry(sb
, p_dir
, new_entry
, 0, num_entries
+1)) {
2770 /* Free the clusters if new_inode is a dir(as if fscore_rmdir) */
2771 if (new_entry_type
== TYPE_DIR
) {
2772 /* new_fid, new_clu_to_free */
2773 CHAIN_T new_clu_to_free
;
2775 new_clu_to_free
.dir
= new_fid
->start_clu
;
2776 new_clu_to_free
.size
= (s32
)((new_fid
->size
-1) >> fsi
->cluster_size_bits
) + 1;
2777 new_clu_to_free
.flags
= new_fid
->flags
;
2779 if (fsi
->fs_func
->free_cluster(sb
, &new_clu_to_free
, 1)) {
2780 /* just set I/O error only */
2785 new_fid
->start_clu
= CLUS_EOF
;
2786 new_fid
->flags
= (fsi
->vol_type
== EXFAT
) ? 0x03 : 0x01;
2789 /* Update new_inode fid
2790 * Prevent syncing removed new_inode
2791 * (new_fid is already initialized above code ("if (new_inode)")
2793 new_fid
->dir
.dir
= DIR_DELETED
;
2797 fs_set_vol_flags(sb
, VOL_CLEAN
);
2800 } /* end of fscore_rename */
2803 s32
fscore_remove(struct inode
*inode
, FILE_ID_T
*fid
)
2807 CHAIN_T dir
, clu_to_free
;
2809 struct super_block
*sb
= inode
->i_sb
;
2810 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
2812 dir
.dir
= fid
->dir
.dir
;
2813 dir
.size
= fid
->dir
.size
;
2814 dir
.flags
= fid
->dir
.flags
;
2816 dentry
= fid
->entry
;
2818 if (fid
->dir
.dir
== DIR_DELETED
) {
2819 EMSG("%s : abnormal access to deleted dentry\n", __func__
);
2823 ep
= get_dentry_in_dir(sb
, &dir
, dentry
, NULL
);
2828 #ifdef CONFIG_SDFAT_CHECK_RO_ATTR
2829 if (fsi
->fs_func
->get_entry_attr(ep
) & ATTR_READONLY
)
2833 fs_set_vol_flags(sb
, VOL_DIRTY
);
2835 /* (1) update the directory entry */
2836 ret
= remove_file(inode
, &dir
, dentry
);
2840 clu_to_free
.dir
= fid
->start_clu
;
2841 clu_to_free
.size
= (s32
)((fid
->size
-1) >> fsi
->cluster_size_bits
) + 1;
2842 clu_to_free
.flags
= fid
->flags
;
2844 /* (2) invalidate extent cache and free the clusters
2846 /* clear extent cache */
2847 extent_cache_inval_inode(inode
);
2848 ret
= fsi
->fs_func
->free_cluster(sb
, &clu_to_free
, 0);
2849 /* WARN : DO NOT RETURN ERROR IN HERE */
2851 /* (3) update FILE_ID_T */
2853 fid
->start_clu
= CLUS_EOF
;
2854 fid
->flags
= (fsi
->vol_type
== EXFAT
) ? 0x03 : 0x01;
2855 fid
->dir
.dir
= DIR_DELETED
;
2858 fs_set_vol_flags(sb
, VOL_CLEAN
);
2861 } /* end of fscore_remove */
2865 * Get the information of a given file
2866 * REMARK : This function does not need any file name on linux
2868 * info.Size means the value saved on disk.
2869 * But root directory doesn`t have real dentry,
2870 * so the size of root directory returns calculated one exceptively.
2872 s32
fscore_read_inode(struct inode
*inode
, DIR_ENTRY_T
*info
)
2879 struct super_block
*sb
= inode
->i_sb
;
2880 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
2881 FILE_ID_T
*fid
= &(SDFAT_I(inode
)->fid
);
2882 ENTRY_SET_CACHE_T
*es
= NULL
;
2883 u8 is_dir
= (fid
->type
== TYPE_DIR
) ? 1 : 0;
2885 TMSG("%s entered\n", __func__
);
2887 extent_cache_init_inode(inode
);
2889 /* if root directory */
2890 if (is_dir
&& (fid
->dir
.dir
== fsi
->root_dir
) && (fid
->entry
== -1)) {
2891 info
->Attr
= ATTR_SUBDIR
;
2892 memset((s8
*) &info
->CreateTimestamp
, 0, sizeof(DATE_TIME_T
));
2893 memset((s8
*) &info
->ModifyTimestamp
, 0, sizeof(DATE_TIME_T
));
2894 memset((s8
*) &info
->AccessTimestamp
, 0, sizeof(DATE_TIME_T
));
2895 //strcpy(info->NameBuf.sfn, ".");
2896 //strcpy(info->NameBuf.lfn, ".");
2898 dir
.dir
= fsi
->root_dir
;
2900 dir
.size
= 0; /* UNUSED */
2902 /* FAT16 root_dir */
2903 if (IS_CLUS_FREE(fsi
->root_dir
)) {
2904 info
->Size
= fsi
->dentries_in_root
<< DENTRY_SIZE_BITS
;
2908 if (__count_num_clusters(sb
, &dir
, &num_clu
))
2910 info
->Size
= (u64
)num_clu
<< fsi
->cluster_size_bits
;
2913 count
= __count_dos_name_entries(sb
, &dir
, TYPE_DIR
, NULL
);
2916 info
->NumSubdirs
= count
;
2921 /* get the directory entry of given file or directory */
2922 if (fsi
->vol_type
== EXFAT
) {
2923 /* es should be released */
2924 es
= get_dentry_set_in_dir(sb
, &(fid
->dir
), fid
->entry
, ES_2_ENTRIES
, &ep
);
2929 ep
= get_dentry_in_dir(sb
, &(fid
->dir
), fid
->entry
, §or
);
2933 /* dcache should be unlocked */
2934 dcache_lock(sb
, sector
);
2937 /* set FILE_INFO structure using the acquired DENTRY_T */
2938 info
->Attr
= fsi
->fs_func
->get_entry_attr(ep
);
2940 fsi
->fs_func
->get_entry_time(ep
, &tm
, TM_CREATE
);
2941 info
->CreateTimestamp
.Year
= tm
.year
;
2942 info
->CreateTimestamp
.Month
= tm
.mon
;
2943 info
->CreateTimestamp
.Day
= tm
.day
;
2944 info
->CreateTimestamp
.Hour
= tm
.hour
;
2945 info
->CreateTimestamp
.Minute
= tm
.min
;
2946 info
->CreateTimestamp
.Second
= tm
.sec
;
2947 info
->CreateTimestamp
.MilliSecond
= 0;
2949 fsi
->fs_func
->get_entry_time(ep
, &tm
, TM_MODIFY
);
2950 info
->ModifyTimestamp
.Year
= tm
.year
;
2951 info
->ModifyTimestamp
.Month
= tm
.mon
;
2952 info
->ModifyTimestamp
.Day
= tm
.day
;
2953 info
->ModifyTimestamp
.Hour
= tm
.hour
;
2954 info
->ModifyTimestamp
.Minute
= tm
.min
;
2955 info
->ModifyTimestamp
.Second
= tm
.sec
;
2956 info
->ModifyTimestamp
.MilliSecond
= 0;
2958 memset((s8
*) &info
->AccessTimestamp
, 0, sizeof(DATE_TIME_T
));
2960 info
->NumSubdirs
= 0;
2961 info
->Size
= fsi
->fs_func
->get_entry_size(ep2
);
2963 if (fsi
->vol_type
== EXFAT
)
2964 release_dentry_set(es
);
2966 dcache_unlock(sb
, sector
);
2971 dir
.dir
= fid
->start_clu
;
2972 dir
.flags
= fid
->flags
;
2973 dir
.size
= fid
->size
>> fsi
->cluster_size_bits
;
2976 * If "dir.flags" has 0x01, "dir.size" is meaningless.
2979 if (info
->Size
== 0) {
2982 if (__count_num_clusters(sb
, &dir
, &num_clu
))
2984 info
->Size
= (u64
)num_clu
<< fsi
->cluster_size_bits
;
2987 count
= __count_dos_name_entries(sb
, &dir
, TYPE_DIR
, &dotcnt
);
2991 if (fsi
->vol_type
== EXFAT
) {
2992 count
+= SDFAT_MIN_SUBDIR
;
2995 * if directory has been corrupted,
2996 * we have to adjust subdir count.
2998 BUG_ON(dotcnt
> SDFAT_MIN_SUBDIR
);
2999 if (dotcnt
< SDFAT_MIN_SUBDIR
) {
3000 EMSG("%s: contents of the directory has been "
3001 "corrupted (parent clus : %08x, idx : %d)",
3002 __func__
, fid
->dir
.dir
, fid
->entry
);
3004 count
+= (SDFAT_MIN_SUBDIR
- dotcnt
);
3006 info
->NumSubdirs
= count
;
3009 TMSG("%s exited successfully\n", __func__
);
3011 } /* end of fscore_read_inode */
3013 /* set the information of a given file
3014 * REMARK : This function does not need any file name on linux
3016 s32
fscore_write_inode(struct inode
*inode
, DIR_ENTRY_T
*info
, s32 sync
)
3022 ENTRY_SET_CACHE_T
*es
= NULL
;
3023 struct super_block
*sb
= inode
->i_sb
;
3024 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
3025 FILE_ID_T
*fid
= &(SDFAT_I(inode
)->fid
);
3026 u8 is_dir
= (fid
->type
== TYPE_DIR
) ? 1 : 0;
3029 /* SKIP WRITING INODE :
3030 * if the indoe is already unlinked,
3031 * there is no need for updating inode
3033 if (fid
->dir
.dir
== DIR_DELETED
)
3036 if (is_dir
&& (fid
->dir
.dir
== fsi
->root_dir
) && (fid
->entry
== -1))
3039 fs_set_vol_flags(sb
, VOL_DIRTY
);
3041 /* get the directory entry of given file or directory */
3042 if (fsi
->vol_type
== EXFAT
) {
3043 es
= get_dentry_set_in_dir(sb
, &(fid
->dir
), fid
->entry
, ES_ALL_ENTRIES
, &ep
);
3048 /* for other than exfat */
3049 ep
= get_dentry_in_dir(sb
, &(fid
->dir
), fid
->entry
, §or
);
3056 fsi
->fs_func
->set_entry_attr(ep
, info
->Attr
);
3058 /* set FILE_INFO structure using the acquired DENTRY_T */
3059 tm
.sec
= info
->CreateTimestamp
.Second
;
3060 tm
.min
= info
->CreateTimestamp
.Minute
;
3061 tm
.hour
= info
->CreateTimestamp
.Hour
;
3062 tm
.day
= info
->CreateTimestamp
.Day
;
3063 tm
.mon
= info
->CreateTimestamp
.Month
;
3064 tm
.year
= info
->CreateTimestamp
.Year
;
3065 fsi
->fs_func
->set_entry_time(ep
, &tm
, TM_CREATE
);
3067 tm
.sec
= info
->ModifyTimestamp
.Second
;
3068 tm
.min
= info
->ModifyTimestamp
.Minute
;
3069 tm
.hour
= info
->ModifyTimestamp
.Hour
;
3070 tm
.day
= info
->ModifyTimestamp
.Day
;
3071 tm
.mon
= info
->ModifyTimestamp
.Month
;
3072 tm
.year
= info
->ModifyTimestamp
.Year
;
3073 fsi
->fs_func
->set_entry_time(ep
, &tm
, TM_MODIFY
);
3075 if (is_dir
&& fsi
->vol_type
!= EXFAT
) {
3076 /* overwirte dirsize if FAT32 and dir size != 0 */
3077 if (fsi
->fs_func
->get_entry_size(ep2
))
3078 fsi
->fs_func
->set_entry_size(ep2
, 0);
3080 /* File size should be zero if there is no cluster allocated */
3081 u64 on_disk_size
= info
->Size
;
3083 if (IS_CLUS_EOF(fid
->start_clu
))
3086 fsi
->fs_func
->set_entry_size(ep2
, on_disk_size
);
3089 if (fsi
->vol_type
== EXFAT
) {
3090 ret
= update_dir_chksum_with_entry_set(sb
, es
);
3091 release_dentry_set(es
);
3093 ret
= dcache_modify(sb
, sector
);
3097 /* Comment below code to prevent super block update frequently */
3098 //fs_set_vol_flags(sb, VOL_CLEAN);
3101 } /* end of fscore_write_inode */
3105 * Input: inode, (logical) clu_offset, target allocation area
3106 * Output: errcode, cluster number
3107 * *clu = (~0), if it's unable to allocate a new cluster
3109 s32
fscore_map_clus(struct inode
*inode
, s32 clu_offset
, u32
*clu
, int dest
)
3111 s32 num_clusters
, num_alloced
, num_to_be_allocated
, modified
= false;
3112 u32 last_clu
, sector
;
3115 ENTRY_SET_CACHE_T
*es
= NULL
;
3116 struct super_block
*sb
= inode
->i_sb
;
3117 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
3118 FILE_ID_T
*fid
= &(SDFAT_I(inode
)->fid
);
3119 s32 local_clu_offset
= clu_offset
;
3120 s32 reserved_clusters
= fsi
->reserved_clusters
;
3122 fid
->rwoffset
= (s64
)(clu_offset
) << fsi
->cluster_size_bits
;
3124 if (SDFAT_I(inode
)->i_size_ondisk
== 0)
3127 num_clusters
= (s32
)((SDFAT_I(inode
)->i_size_ondisk
-1) >> fsi
->cluster_size_bits
) + 1;
3129 num_to_be_allocated
= clu_offset
- num_clusters
+ 1;
3130 if ((dest
== ALLOC_NOWHERE
) && (num_to_be_allocated
> 0)) {
3135 sdfat_debug_check_clusters(inode
);
3137 *clu
= last_clu
= fid
->start_clu
;
3139 /* XXX: Defensive code needed.
3140 * what if i_size_ondisk != # of allocated clusters
3142 if (fid
->flags
== 0x03) {
3143 if ((clu_offset
> 0) && (!IS_CLUS_EOF(*clu
))) {
3144 last_clu
+= clu_offset
- 1;
3146 if (clu_offset
== num_clusters
)
3151 } else if (fid
->type
== TYPE_FILE
) {
3153 s32 err
= extent_get_clus(inode
, clu_offset
,
3154 &fclus
, clu
, &last_clu
, 1);
3158 clu_offset
-= fclus
;
3160 /* hint information */
3161 if ((clu_offset
> 0) && (fid
->hint_bmap
.off
> 0) &&
3162 (clu_offset
>= fid
->hint_bmap
.off
)) {
3163 clu_offset
-= fid
->hint_bmap
.off
;
3164 /* hint_bmap.clu should be valid */
3165 ASSERT(fid
->hint_bmap
.clu
>= 2);
3166 *clu
= fid
->hint_bmap
.clu
;
3169 while ((clu_offset
> 0) && (!IS_CLUS_EOF(*clu
))) {
3171 if (get_next_clus_safe(sb
, clu
))
3177 if (IS_CLUS_EOF(*clu
)) {
3178 fs_set_vol_flags(sb
, VOL_DIRTY
);
3180 new_clu
.dir
= (IS_CLUS_EOF(last_clu
)) ? CLUS_EOF
: last_clu
+ 1;
3182 new_clu
.flags
= fid
->flags
;
3184 /* (1) allocate a cluster */
3185 if (num_to_be_allocated
< 1) {
3186 /* Broken FAT (i_sze > allocated FAT) */
3187 EMSG("%s: invalid fat chain : inode(%p) "
3188 "num_to_be_allocated(%d) "
3189 "i_size_ondisk(%lld) fid->flags(%02x) "
3190 "fid->start(%08x) fid->hint_off(%d) "
3191 "fid->hint_clu(%u) fid->rwoffset(%llu) "
3192 "modified_clu_off(%d) last_clu(%08x) "
3193 "new_clu(%08x)", __func__
, inode
,
3194 num_to_be_allocated
,
3195 (SDFAT_I(inode
)->i_size_ondisk
),
3196 fid
->flags
, fid
->start_clu
,
3197 fid
->hint_bmap
.off
, fid
->hint_bmap
.clu
,
3198 fid
->rwoffset
, clu_offset
,
3199 last_clu
, new_clu
.dir
);
3200 sdfat_fs_error(sb
, "broken FAT chain.");
3204 num_alloced
= fsi
->fs_func
->alloc_cluster(sb
, num_to_be_allocated
, &new_clu
, ALLOC_COLD
);
3205 if (num_alloced
< 0) {
3207 } else if (num_alloced
< num_to_be_allocated
) {
3208 if (num_to_be_allocated
== 1) {
3209 ASSERT(!num_alloced
);
3211 DMSG("%s : ENOSPC (requested:%d, alloced:%d)\n",
3212 __func__
, num_alloced
,
3213 num_to_be_allocated
);
3218 if (IS_CLUS_EOF(new_clu
.dir
) || IS_CLUS_FREE(new_clu
.dir
)) {
3219 sdfat_fs_error(sb
, "bogus cluster new allocated"
3220 "(last_clu : %u, new_clu : %u)",
3221 last_clu
, new_clu
.dir
);
3226 /* Reserved cluster dec. */
3227 // XXX: Inode DA flag needed
3228 if (SDFAT_SB(sb
)->options
.improved_allocation
& SDFAT_ALLOC_DELAY
) {
3229 BUG_ON(reserved_clusters
< num_alloced
);
3230 reserved_clusters
-= num_alloced
;
3234 /* (2) append to the FAT chain */
3235 if (IS_CLUS_EOF(last_clu
)) {
3236 if (new_clu
.flags
== 0x01)
3238 fid
->start_clu
= new_clu
.dir
;
3241 if (new_clu
.flags
!= fid
->flags
) {
3242 /* no-fat-chain bit is disabled,
3243 * so fat-chain should be synced with alloc-bmp
3245 chain_cont_cluster(sb
, fid
->start_clu
, num_clusters
);
3249 if (new_clu
.flags
== 0x01)
3250 if (fat_ent_set(sb
, last_clu
, new_clu
.dir
))
3254 num_clusters
+= num_alloced
;
3257 if (fid
->dir
.dir
!= DIR_DELETED
) {
3259 if (fsi
->vol_type
== EXFAT
) {
3260 es
= get_dentry_set_in_dir(sb
, &(fid
->dir
), fid
->entry
, ES_ALL_ENTRIES
, &ep
);
3263 /* get stream entry */
3267 /* (3) update directory entry */
3269 if (fsi
->vol_type
!= EXFAT
) {
3270 ep
= get_dentry_in_dir(sb
, &(fid
->dir
), fid
->entry
, §or
);
3275 if (fsi
->fs_func
->get_entry_flag(ep
) != fid
->flags
)
3276 fsi
->fs_func
->set_entry_flag(ep
, fid
->flags
);
3278 if (fsi
->fs_func
->get_entry_clu0(ep
) != fid
->start_clu
)
3279 fsi
->fs_func
->set_entry_clu0(ep
, fid
->start_clu
);
3281 fsi
->fs_func
->set_entry_size(ep
, fid
->size
);
3283 if (fsi
->vol_type
!= EXFAT
) {
3284 if (dcache_modify(sb
, sector
))
3289 if (fsi
->vol_type
== EXFAT
) {
3290 if (update_dir_chksum_with_entry_set(sb
, es
))
3292 release_dentry_set(es
);
3295 } /* end of if != DIR_DELETED */
3298 /* add number of new blocks to inode (non-DA only) */
3299 if (!(SDFAT_SB(sb
)->options
.improved_allocation
& SDFAT_ALLOC_DELAY
)) {
3300 inode
->i_blocks
+= num_alloced
<< (fsi
->cluster_size_bits
- sb
->s_blocksize_bits
);
3302 // DA의 경우, i_blocks가 이미 증가해있어야 함.
3303 BUG_ON(clu_offset
>= (inode
->i_blocks
>> (fsi
->cluster_size_bits
- sb
->s_blocksize_bits
)));
3307 fs_set_vol_flags(sb
, VOL_CLEAN
);
3309 /* (4) Move *clu pointer along FAT chains (hole care)
3310 * because the caller of this function expect *clu to be the last cluster.
3311 * This only works when num_to_be_allocated >= 2,
3312 * *clu = (the first cluster of the allocated chain) => (the last cluster of ...)
3314 if (fid
->flags
== 0x03) {
3315 *clu
+= num_to_be_allocated
- 1;
3317 while (num_to_be_allocated
> 1) {
3318 if (get_next_clus_safe(sb
, clu
))
3320 num_to_be_allocated
--;
3326 /* update reserved_clusters */
3327 fsi
->reserved_clusters
= reserved_clusters
;
3329 /* hint information */
3330 fid
->hint_bmap
.off
= local_clu_offset
;
3331 fid
->hint_bmap
.clu
= *clu
;
3334 } /* end of fscore_map_clus */
3336 /* allocate reserved cluster */
3337 s32
fscore_reserve_clus(struct inode
*inode
)
3339 struct super_block
*sb
= inode
->i_sb
;
3340 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
3342 /* used cluster check */
3343 if (fsi
->used_clusters
== (u32
) ~0) {
3344 if (fsi
->fs_func
->count_used_clusters(sb
, &fsi
->used_clusters
))
3348 if ((fsi
->used_clusters
+ fsi
->reserved_clusters
) >= (fsi
->num_clusters
- 2))
3351 if (bdev_check_bdi_valid(sb
))
3354 fsi
->reserved_clusters
++;
3356 /* inode->i_blocks update */
3357 inode
->i_blocks
+= 1 << (fsi
->cluster_size_bits
- sb
->s_blocksize_bits
);
3359 sdfat_debug_check_clusters(inode
);
3364 /* remove an entry, BUT don't truncate */
3365 s32
fscore_unlink(struct inode
*inode
, FILE_ID_T
*fid
)
3370 struct super_block
*sb
= inode
->i_sb
;
3372 dir
.dir
= fid
->dir
.dir
;
3373 dir
.size
= fid
->dir
.size
;
3374 dir
.flags
= fid
->dir
.flags
;
3376 dentry
= fid
->entry
;
3378 if (fid
->dir
.dir
== DIR_DELETED
) {
3379 EMSG("%s : abnormal access to deleted dentry\n", __func__
);
3383 ep
= get_dentry_in_dir(sb
, &dir
, dentry
, NULL
);
3387 #ifdef CONFIG_SDFAT_CHECK_RO_ATTR
3388 if (SDFAT_SB(sb
)->fsi
.fs_func
->get_entry_attr(ep
) & ATTR_READONLY
)
3392 fs_set_vol_flags(sb
, VOL_DIRTY
);
3394 /* (1) update the directory entry */
3395 if (remove_file(inode
, &dir
, dentry
))
3398 /* This doesn't modify fid */
3399 fid
->dir
.dir
= DIR_DELETED
;
3402 fs_set_vol_flags(sb
, VOL_CLEAN
);
3407 /*----------------------------------------------------------------------*/
3408 /* Directory Operation Functions */
3409 /*----------------------------------------------------------------------*/
3411 /* create a directory */
3412 s32
fscore_mkdir(struct inode
*inode
, u8
*path
, FILE_ID_T
*fid
)
3414 s32 ret
/*, dentry*/;
3416 UNI_NAME_T uni_name
;
3417 struct super_block
*sb
= inode
->i_sb
;
3419 TMSG("%s entered\n", __func__
);
3421 /* check the validity of directory name in the given old pathname */
3422 ret
= resolve_path(inode
, path
, &dir
, &uni_name
);
3426 fs_set_vol_flags(sb
, VOL_DIRTY
);
3428 ret
= create_dir(inode
, &dir
, &uni_name
, fid
);
3431 fs_set_vol_flags(sb
, VOL_CLEAN
);
3433 TMSG("%s exited with err(%d)\n", __func__
, ret
);
3437 /* read a directory entry from the opened directory */
3438 s32
fscore_readdir(struct inode
*inode
, DIR_ENTRY_T
*dir_entry
)
3441 s32 dentries_per_clu
, dentries_per_clu_bits
= 0;
3444 UNI_NAME_T uni_name
;
3447 struct super_block
*sb
= inode
->i_sb
;
3448 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
3449 FILE_ID_T
*fid
= &(SDFAT_I(inode
)->fid
);
3450 s32 dentry
= (s32
) fid
->rwoffset
;
3452 /* check if the given file ID is opened */
3453 if (fid
->type
!= TYPE_DIR
)
3456 if (fid
->entry
== -1) {
3457 dir
.dir
= fsi
->root_dir
;
3458 dir
.size
= 0; /* just initialize, but will not use */
3461 dir
.dir
= fid
->start_clu
;
3462 dir
.size
= (s32
)(fid
->size
>> fsi
->cluster_size_bits
);
3463 dir
.flags
= fid
->flags
;
3464 sdfat_debug_bug_on(dentry
>= (dir
.size
* fsi
->dentries_per_clu
));
3467 if (IS_CLUS_FREE(dir
.dir
)) { /* FAT16 root_dir */
3468 dentries_per_clu
= fsi
->dentries_in_root
;
3470 /* Prevent readdir over directory size */
3471 if (dentry
>= dentries_per_clu
) {
3475 clu
.size
= dir
.size
;
3476 clu
.flags
= dir
.flags
;
3479 dentries_per_clu
= fsi
->dentries_per_clu
;
3480 dentries_per_clu_bits
= ilog2(dentries_per_clu
);
3482 clu_offset
= dentry
>> dentries_per_clu_bits
;
3484 clu
.size
= dir
.size
;
3485 clu
.flags
= dir
.flags
;
3487 if (clu
.flags
== 0x03) {
3488 clu
.dir
+= clu_offset
;
3489 clu
.size
-= clu_offset
;
3491 /* hint_information */
3492 if ((clu_offset
> 0) && (fid
->hint_bmap
.off
> 0) &&
3493 (clu_offset
>= fid
->hint_bmap
.off
)) {
3494 clu_offset
-= fid
->hint_bmap
.off
;
3495 clu
.dir
= fid
->hint_bmap
.clu
;
3498 while (clu_offset
> 0) {
3499 if (get_next_clus_safe(sb
, &(clu
.dir
)))
3507 while (!IS_CLUS_EOF(clu
.dir
)) {
3508 if (IS_CLUS_FREE(dir
.dir
)) /* FAT16 root_dir */
3509 i
= dentry
% dentries_per_clu
;
3511 i
= dentry
& (dentries_per_clu
-1);
3513 for ( ; i
< dentries_per_clu
; i
++, dentry
++) {
3514 ep
= get_dentry_in_dir(sb
, &clu
, i
, §or
);
3518 type
= fsi
->fs_func
->get_entry_type(ep
);
3520 if (type
== TYPE_UNUSED
)
3523 if ((type
!= TYPE_FILE
) && (type
!= TYPE_DIR
))
3526 dcache_lock(sb
, sector
);
3527 dir_entry
->Attr
= fsi
->fs_func
->get_entry_attr(ep
);
3529 fsi
->fs_func
->get_entry_time(ep
, &tm
, TM_CREATE
);
3530 dir_entry
->CreateTimestamp
.Year
= tm
.year
;
3531 dir_entry
->CreateTimestamp
.Month
= tm
.mon
;
3532 dir_entry
->CreateTimestamp
.Day
= tm
.day
;
3533 dir_entry
->CreateTimestamp
.Hour
= tm
.hour
;
3534 dir_entry
->CreateTimestamp
.Minute
= tm
.min
;
3535 dir_entry
->CreateTimestamp
.Second
= tm
.sec
;
3536 dir_entry
->CreateTimestamp
.MilliSecond
= 0;
3538 fsi
->fs_func
->get_entry_time(ep
, &tm
, TM_MODIFY
);
3539 dir_entry
->ModifyTimestamp
.Year
= tm
.year
;
3540 dir_entry
->ModifyTimestamp
.Month
= tm
.mon
;
3541 dir_entry
->ModifyTimestamp
.Day
= tm
.day
;
3542 dir_entry
->ModifyTimestamp
.Hour
= tm
.hour
;
3543 dir_entry
->ModifyTimestamp
.Minute
= tm
.min
;
3544 dir_entry
->ModifyTimestamp
.Second
= tm
.sec
;
3545 dir_entry
->ModifyTimestamp
.MilliSecond
= 0;
3547 memset((s8
*) &dir_entry
->AccessTimestamp
, 0, sizeof(DATE_TIME_T
));
3549 *(uni_name
.name
) = 0x0;
3550 fsi
->fs_func
->get_uniname_from_ext_entry(sb
, &dir
, dentry
, uni_name
.name
);
3551 if (*(uni_name
.name
) == 0x0)
3552 get_uniname_from_dos_entry(sb
, (DOS_DENTRY_T
*) ep
, &uni_name
, 0x1);
3553 nls_uni16s_to_vfsname(sb
, &uni_name
,
3554 dir_entry
->NameBuf
.lfn
,
3555 dir_entry
->NameBuf
.lfnbuf_len
);
3556 dcache_unlock(sb
, sector
);
3558 if (fsi
->vol_type
== EXFAT
) {
3559 ep
= get_dentry_in_dir(sb
, &clu
, i
+1, NULL
);
3563 get_uniname_from_dos_entry(sb
, (DOS_DENTRY_T
*) ep
, &uni_name
, 0x0);
3564 nls_uni16s_to_vfsname(sb
, &uni_name
,
3565 dir_entry
->NameBuf
.sfn
,
3566 dir_entry
->NameBuf
.sfnbuf_len
);
3569 dir_entry
->Size
= fsi
->fs_func
->get_entry_size(ep
);
3572 * Update hint information :
3573 * fat16 root directory does not need it.
3575 if (!IS_CLUS_FREE(dir
.dir
)) {
3576 fid
->hint_bmap
.off
= dentry
>> dentries_per_clu_bits
;
3577 fid
->hint_bmap
.clu
= clu
.dir
;
3580 fid
->rwoffset
= (s64
) ++dentry
;
3585 /* fat16 root directory */
3586 if (IS_CLUS_FREE(dir
.dir
))
3589 if (clu
.flags
== 0x03) {
3590 if ((--clu
.size
) > 0)
3595 if (get_next_clus_safe(sb
, &(clu
.dir
)))
3600 dir_entry
->NameBuf
.lfn
[0] = '\0';
3602 fid
->rwoffset
= (s64
) dentry
;
3605 } /* end of fscore_readdir */
3607 /* remove a directory */
3608 s32
fscore_rmdir(struct inode
*inode
, FILE_ID_T
*fid
)
3613 CHAIN_T dir
, clu_to_free
;
3614 struct super_block
*sb
= inode
->i_sb
;
3615 FS_INFO_T
*fsi
= &(SDFAT_SB(sb
)->fsi
);
3617 dir
.dir
= fid
->dir
.dir
;
3618 dir
.size
= fid
->dir
.size
;
3619 dir
.flags
= fid
->dir
.flags
;
3621 dentry
= fid
->entry
;
3623 if (fid
->dir
.dir
== DIR_DELETED
) {
3624 EMSG("%s : abnormal access to deleted dentry\n", __func__
);
3628 /* check if the file is "." or ".." */
3629 if (fsi
->vol_type
!= EXFAT
) {
3630 if ((dir
.dir
!= fsi
->root_dir
) && (dentry
< 2))
3634 ep
= get_dentry_in_dir(sb
, &dir
, dentry
, NULL
);
3638 #ifdef CONFIG_SDFAT_CHECK_RO_ATTR
3639 if (SDFAT_SB(sb
)->fsi
.fs_func
->get_entry_attr(ep
) & ATTR_READONLY
)
3643 clu_to_free
.dir
= fid
->start_clu
;
3644 clu_to_free
.size
= (s32
)((fid
->size
-1) >> fsi
->cluster_size_bits
) + 1;
3645 clu_to_free
.flags
= fid
->flags
;
3647 ret
= check_dir_empty(sb
, &clu_to_free
);
3650 EMSG("%s : failed to check_dir_empty : err(%d)\n",
3655 fs_set_vol_flags(sb
, VOL_DIRTY
);
3657 /* (1) update the directory entry */
3658 ret
= remove_file(inode
, &dir
, dentry
);
3660 EMSG("%s : failed to remove_file : err(%d)\n", __func__
, ret
);
3664 fid
->dir
.dir
= DIR_DELETED
;
3667 fs_set_vol_flags(sb
, VOL_CLEAN
);
3670 } /* end of fscore_rmdir */