@@ -33,10 +33,9 @@ static void exfat_get_uniname_from_ext_entry(struct super_block *sb,
33
33
struct exfat_chain * p_dir , int entry , unsigned short * uniname )
34
34
{
35
35
int i ;
36
- struct exfat_entry_set_cache * es ;
36
+ struct exfat_entry_set_cache es ;
37
37
38
- es = exfat_get_dentry_set (sb , p_dir , entry , ES_ALL_ENTRIES );
39
- if (!es )
38
+ if (exfat_get_dentry_set (& es , sb , p_dir , entry , ES_ALL_ENTRIES ))
40
39
return ;
41
40
42
41
/*
@@ -45,8 +44,8 @@ static void exfat_get_uniname_from_ext_entry(struct super_block *sb,
45
44
* Third entry : first file-name entry
46
45
* So, the index of first file-name dentry should start from 2.
47
46
*/
48
- for (i = 2 ; i < es -> num_entries ; i ++ ) {
49
- struct exfat_dentry * ep = exfat_get_dentry_cached (es , i );
47
+ for (i = ES_IDX_FIRST_FILENAME ; i < es . num_entries ; i ++ ) {
48
+ struct exfat_dentry * ep = exfat_get_dentry_cached (& es , i );
50
49
51
50
/* end of name entry */
52
51
if (exfat_get_entry_type (ep ) != TYPE_EXTEND )
@@ -56,13 +55,13 @@ static void exfat_get_uniname_from_ext_entry(struct super_block *sb,
56
55
uniname += EXFAT_FILE_NAME_LEN ;
57
56
}
58
57
59
- exfat_free_dentry_set ( es , false);
58
+ exfat_put_dentry_set ( & es , false);
60
59
}
61
60
62
61
/* read a directory entry from the opened directory */
63
62
static int exfat_readdir (struct inode * inode , loff_t * cpos , struct exfat_dir_entry * dir_entry )
64
63
{
65
- int i , dentries_per_clu , dentries_per_clu_bits = 0 , num_ext ;
64
+ int i , dentries_per_clu , num_ext ;
66
65
unsigned int type , clu_offset , max_dentries ;
67
66
struct exfat_chain dir , clu ;
68
67
struct exfat_uni_name uni_name ;
@@ -84,11 +83,10 @@ static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_ent
84
83
EXFAT_B_TO_CLU (i_size_read (inode ), sbi ), ei -> flags );
85
84
86
85
dentries_per_clu = sbi -> dentries_per_clu ;
87
- dentries_per_clu_bits = ilog2 (dentries_per_clu );
88
86
max_dentries = (unsigned int )min_t (u64 , MAX_EXFAT_DENTRIES ,
89
- (u64 )sbi -> num_clusters << dentries_per_clu_bits );
87
+ (u64 )EXFAT_CLU_TO_DEN ( sbi -> num_clusters , sbi ) );
90
88
91
- clu_offset = dentry >> dentries_per_clu_bits ;
89
+ clu_offset = EXFAT_DEN_TO_CLU ( dentry , sbi ) ;
92
90
exfat_chain_dup (& clu , & dir );
93
91
94
92
if (clu .flags == ALLOC_NO_FAT_CHAIN ) {
@@ -163,7 +161,7 @@ static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_ent
163
161
dir_entry -> entry = dentry ;
164
162
brelse (bh );
165
163
166
- ei -> hint_bmap .off = dentry >> dentries_per_clu_bits ;
164
+ ei -> hint_bmap .off = EXFAT_DEN_TO_CLU ( dentry , sbi ) ;
167
165
ei -> hint_bmap .clu = clu .dir ;
168
166
169
167
* cpos = EXFAT_DEN_TO_B (dentry + 1 + num_ext );
@@ -337,7 +335,7 @@ int exfat_calc_num_entries(struct exfat_uni_name *p_uniname)
337
335
return - EINVAL ;
338
336
339
337
/* 1 file entry + 1 stream entry + name entries */
340
- return (( len - 1 ) / EXFAT_FILE_NAME_LEN + 3 );
338
+ return ES_ENTRY_NUM ( len );
341
339
}
342
340
343
341
unsigned int exfat_get_entry_type (struct exfat_dentry * ep )
@@ -592,18 +590,18 @@ void exfat_update_dir_chksum_with_entry_set(struct exfat_entry_set_cache *es)
592
590
unsigned short chksum = 0 ;
593
591
struct exfat_dentry * ep ;
594
592
595
- for (i = 0 ; i < es -> num_entries ; i ++ ) {
593
+ for (i = ES_IDX_FILE ; i < es -> num_entries ; i ++ ) {
596
594
ep = exfat_get_dentry_cached (es , i );
597
595
chksum = exfat_calc_chksum16 (ep , DENTRY_SIZE , chksum ,
598
596
chksum_type );
599
597
chksum_type = CS_DEFAULT ;
600
598
}
601
- ep = exfat_get_dentry_cached (es , 0 );
599
+ ep = exfat_get_dentry_cached (es , ES_IDX_FILE );
602
600
ep -> dentry .file .checksum = cpu_to_le16 (chksum );
603
601
es -> modified = true;
604
602
}
605
603
606
- int exfat_free_dentry_set (struct exfat_entry_set_cache * es , int sync )
604
+ int exfat_put_dentry_set (struct exfat_entry_set_cache * es , int sync )
607
605
{
608
606
int i , err = 0 ;
609
607
@@ -615,7 +613,10 @@ int exfat_free_dentry_set(struct exfat_entry_set_cache *es, int sync)
615
613
bforget (es -> bh [i ]);
616
614
else
617
615
brelse (es -> bh [i ]);
618
- kfree (es );
616
+
617
+ if (IS_DYNAMIC_ES (es ))
618
+ kfree (es -> bh );
619
+
619
620
return err ;
620
621
}
621
622
@@ -812,89 +813,118 @@ struct exfat_dentry *exfat_get_dentry_cached(
812
813
* pointer of entry set on success,
813
814
* NULL on failure.
814
815
*/
815
- struct exfat_entry_set_cache * exfat_get_dentry_set (struct super_block * sb ,
816
- struct exfat_chain * p_dir , int entry , unsigned int type )
816
+ int exfat_get_dentry_set (struct exfat_entry_set_cache * es ,
817
+ struct super_block * sb , struct exfat_chain * p_dir , int entry ,
818
+ unsigned int type )
817
819
{
818
820
int ret , i , num_bh ;
819
- unsigned int off , byte_offset , clu = 0 ;
821
+ unsigned int off ;
820
822
sector_t sec ;
821
823
struct exfat_sb_info * sbi = EXFAT_SB (sb );
822
- struct exfat_entry_set_cache * es ;
823
824
struct exfat_dentry * ep ;
824
825
int num_entries ;
825
826
enum exfat_validate_dentry_mode mode = ES_MODE_STARTED ;
826
827
struct buffer_head * bh ;
827
828
828
829
if (p_dir -> dir == DIR_DELETED ) {
829
830
exfat_err (sb , "access to deleted dentry" );
830
- return NULL ;
831
+ return - EIO ;
831
832
}
832
833
833
- byte_offset = EXFAT_DEN_TO_B (entry );
834
- ret = exfat_walk_fat_chain (sb , p_dir , byte_offset , & clu );
834
+ ret = exfat_find_location (sb , p_dir , entry , & sec , & off );
835
835
if (ret )
836
- return NULL ;
836
+ return ret ;
837
837
838
- es = kzalloc (sizeof (* es ), GFP_KERNEL );
839
- if (!es )
840
- return NULL ;
838
+ memset (es , 0 , sizeof (* es ));
841
839
es -> sb = sb ;
842
840
es -> modified = false;
843
-
844
- /* byte offset in cluster */
845
- byte_offset = EXFAT_CLU_OFFSET (byte_offset , sbi );
846
-
847
- /* byte offset in sector */
848
- off = EXFAT_BLK_OFFSET (byte_offset , sb );
849
841
es -> start_off = off ;
850
-
851
- /* sector offset in cluster */
852
- sec = EXFAT_B_TO_BLK (byte_offset , sb );
853
- sec += exfat_cluster_to_sector (sbi , clu );
842
+ es -> bh = es -> __bh ;
854
843
855
844
bh = sb_bread (sb , sec );
856
845
if (!bh )
857
- goto free_es ;
846
+ return - EIO ;
858
847
es -> bh [es -> num_bh ++ ] = bh ;
859
848
860
- ep = exfat_get_dentry_cached (es , 0 );
849
+ ep = exfat_get_dentry_cached (es , ES_IDX_FILE );
861
850
if (!exfat_validate_entry (exfat_get_entry_type (ep ), & mode ))
862
- goto free_es ;
851
+ goto put_es ;
863
852
864
853
num_entries = type == ES_ALL_ENTRIES ?
865
854
ep -> dentry .file .num_ext + 1 : type ;
866
855
es -> num_entries = num_entries ;
867
856
868
857
num_bh = EXFAT_B_TO_BLK_ROUND_UP (off + num_entries * DENTRY_SIZE , sb );
858
+ if (num_bh > ARRAY_SIZE (es -> __bh )) {
859
+ es -> bh = kmalloc_array (num_bh , sizeof (* es -> bh ), GFP_KERNEL );
860
+ if (!es -> bh ) {
861
+ brelse (bh );
862
+ return - ENOMEM ;
863
+ }
864
+ es -> bh [0 ] = bh ;
865
+ }
866
+
869
867
for (i = 1 ; i < num_bh ; i ++ ) {
870
868
/* get the next sector */
871
869
if (exfat_is_last_sector_in_cluster (sbi , sec )) {
870
+ unsigned int clu = exfat_sector_to_cluster (sbi , sec );
871
+
872
872
if (p_dir -> flags == ALLOC_NO_FAT_CHAIN )
873
873
clu ++ ;
874
874
else if (exfat_get_next_cluster (sb , & clu ))
875
- goto free_es ;
875
+ goto put_es ;
876
876
sec = exfat_cluster_to_sector (sbi , clu );
877
877
} else {
878
878
sec ++ ;
879
879
}
880
880
881
881
bh = sb_bread (sb , sec );
882
882
if (!bh )
883
- goto free_es ;
883
+ goto put_es ;
884
884
es -> bh [es -> num_bh ++ ] = bh ;
885
885
}
886
886
887
887
/* validate cached dentries */
888
- for (i = 1 ; i < num_entries ; i ++ ) {
888
+ for (i = ES_IDX_STREAM ; i < num_entries ; i ++ ) {
889
889
ep = exfat_get_dentry_cached (es , i );
890
890
if (!exfat_validate_entry (exfat_get_entry_type (ep ), & mode ))
891
- goto free_es ;
891
+ goto put_es ;
892
892
}
893
- return es ;
893
+ return 0 ;
894
+
895
+ put_es :
896
+ exfat_put_dentry_set (es , false);
897
+ return - EIO ;
898
+ }
894
899
895
- free_es :
896
- exfat_free_dentry_set (es , false);
897
- return NULL ;
900
+ static inline void exfat_reset_empty_hint (struct exfat_hint_femp * hint_femp )
901
+ {
902
+ hint_femp -> eidx = EXFAT_HINT_NONE ;
903
+ hint_femp -> count = 0 ;
904
+ }
905
+
906
+ static inline void exfat_set_empty_hint (struct exfat_inode_info * ei ,
907
+ struct exfat_hint_femp * candi_empty , struct exfat_chain * clu ,
908
+ int dentry , int num_entries , int entry_type )
909
+ {
910
+ if (ei -> hint_femp .eidx == EXFAT_HINT_NONE ||
911
+ ei -> hint_femp .eidx > dentry ) {
912
+ int total_entries = EXFAT_B_TO_DEN (i_size_read (& ei -> vfs_inode ));
913
+
914
+ if (candi_empty -> count == 0 ) {
915
+ candi_empty -> cur = * clu ;
916
+ candi_empty -> eidx = dentry ;
917
+ }
918
+
919
+ if (entry_type == TYPE_UNUSED )
920
+ candi_empty -> count += total_entries - dentry ;
921
+ else
922
+ candi_empty -> count ++ ;
923
+
924
+ if (candi_empty -> count == num_entries ||
925
+ candi_empty -> count + candi_empty -> eidx == total_entries )
926
+ ei -> hint_femp = * candi_empty ;
927
+ }
898
928
}
899
929
900
930
enum {
@@ -917,17 +947,21 @@ enum {
917
947
*/
918
948
int exfat_find_dir_entry (struct super_block * sb , struct exfat_inode_info * ei ,
919
949
struct exfat_chain * p_dir , struct exfat_uni_name * p_uniname ,
920
- int num_entries , unsigned int type , struct exfat_hint * hint_opt )
950
+ struct exfat_hint * hint_opt )
921
951
{
922
952
int i , rewind = 0 , dentry = 0 , end_eidx = 0 , num_ext = 0 , len ;
923
953
int order , step , name_len = 0 ;
924
- int dentries_per_clu , num_empty = 0 ;
954
+ int dentries_per_clu ;
925
955
unsigned int entry_type ;
926
956
unsigned short * uniname = NULL ;
927
957
struct exfat_chain clu ;
928
958
struct exfat_hint * hint_stat = & ei -> hint_stat ;
929
959
struct exfat_hint_femp candi_empty ;
930
960
struct exfat_sb_info * sbi = EXFAT_SB (sb );
961
+ int num_entries = exfat_calc_num_entries (p_uniname );
962
+
963
+ if (num_entries < 0 )
964
+ return num_entries ;
931
965
932
966
dentries_per_clu = sbi -> dentries_per_clu ;
933
967
@@ -939,10 +973,13 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
939
973
end_eidx = dentry ;
940
974
}
941
975
942
- candi_empty .eidx = EXFAT_HINT_NONE ;
976
+ exfat_reset_empty_hint (& ei -> hint_femp );
977
+
943
978
rewind :
944
979
order = 0 ;
945
980
step = DIRENT_STEP_FILE ;
981
+ exfat_reset_empty_hint (& candi_empty );
982
+
946
983
while (clu .dir != EXFAT_EOF_CLUSTER ) {
947
984
i = dentry & (dentries_per_clu - 1 );
948
985
for (; i < dentries_per_clu ; i ++ , dentry ++ ) {
@@ -962,44 +999,24 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
962
999
entry_type == TYPE_DELETED ) {
963
1000
step = DIRENT_STEP_FILE ;
964
1001
965
- num_empty ++ ;
966
- if (candi_empty .eidx == EXFAT_HINT_NONE &&
967
- num_empty == 1 ) {
968
- exfat_chain_set (& candi_empty .cur ,
969
- clu .dir , clu .size , clu .flags );
970
- }
971
-
972
- if (candi_empty .eidx == EXFAT_HINT_NONE &&
973
- num_empty >= num_entries ) {
974
- candi_empty .eidx =
975
- dentry - (num_empty - 1 );
976
- WARN_ON (candi_empty .eidx < 0 );
977
- candi_empty .count = num_empty ;
978
-
979
- if (ei -> hint_femp .eidx ==
980
- EXFAT_HINT_NONE ||
981
- candi_empty .eidx <=
982
- ei -> hint_femp .eidx )
983
- ei -> hint_femp = candi_empty ;
984
- }
1002
+ exfat_set_empty_hint (ei , & candi_empty , & clu ,
1003
+ dentry , num_entries ,
1004
+ entry_type );
985
1005
986
1006
brelse (bh );
987
1007
if (entry_type == TYPE_UNUSED )
988
1008
goto not_found ;
989
1009
continue ;
990
1010
}
991
1011
992
- num_empty = 0 ;
993
- candi_empty .eidx = EXFAT_HINT_NONE ;
1012
+ exfat_reset_empty_hint (& candi_empty );
994
1013
995
1014
if (entry_type == TYPE_FILE || entry_type == TYPE_DIR ) {
996
1015
step = DIRENT_STEP_FILE ;
997
1016
hint_opt -> clu = clu .dir ;
998
1017
hint_opt -> eidx = i ;
999
- if (type == TYPE_ALL || type == entry_type ) {
1000
- num_ext = ep -> dentry .file .num_ext ;
1001
- step = DIRENT_STEP_STRM ;
1002
- }
1018
+ num_ext = ep -> dentry .file .num_ext ;
1019
+ step = DIRENT_STEP_STRM ;
1003
1020
brelse (bh );
1004
1021
continue ;
1005
1022
}
@@ -1090,12 +1107,19 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
1090
1107
rewind = 1 ;
1091
1108
dentry = 0 ;
1092
1109
clu .dir = p_dir -> dir ;
1093
- /* reset empty hint */
1094
- num_empty = 0 ;
1095
- candi_empty .eidx = EXFAT_HINT_NONE ;
1096
1110
goto rewind ;
1097
1111
}
1098
1112
1113
+ /*
1114
+ * set the EXFAT_EOF_CLUSTER flag to avoid search
1115
+ * from the beginning again when allocated a new cluster
1116
+ */
1117
+ if (ei -> hint_femp .eidx == EXFAT_HINT_NONE ) {
1118
+ ei -> hint_femp .cur .dir = EXFAT_EOF_CLUSTER ;
1119
+ ei -> hint_femp .eidx = p_dir -> size * dentries_per_clu ;
1120
+ ei -> hint_femp .count = 0 ;
1121
+ }
1122
+
1099
1123
/* initialized hint_stat */
1100
1124
hint_stat -> clu = p_dir -> dir ;
1101
1125
hint_stat -> eidx = 0 ;
0 commit comments