Skip to content

Commit 34939ae

Browse files
sanpeqfnamjaejeon
authored andcommitted
exfat: using ffs instead of internal logic
Replaced the internal table lookup algorithm with ffs of the bitops library with better performance. Use it to increase the single processing length of the exfat_find_free_bitmap function, from single-byte search to long type. Signed-off-by: John Sanpe <[email protected]> Acked-by: Sungjong Seo <[email protected]> Signed-off-by: Namjae Jeon <[email protected]>
1 parent 7423546 commit 34939ae

File tree

2 files changed

+16
-28
lines changed

2 files changed

+16
-28
lines changed

fs/exfat/balloc.c

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,29 +14,15 @@
1414
#if BITS_PER_LONG == 32
1515
#define __le_long __le32
1616
#define lel_to_cpu(A) le32_to_cpu(A)
17+
#define cpu_to_lel(A) cpu_to_le32(A)
1718
#elif BITS_PER_LONG == 64
1819
#define __le_long __le64
1920
#define lel_to_cpu(A) le64_to_cpu(A)
21+
#define cpu_to_lel(A) cpu_to_le64(A)
2022
#else
2123
#error "BITS_PER_LONG not 32 or 64"
2224
#endif
2325

24-
static const unsigned char free_bit[] = {
25-
0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2,/* 0 ~ 19*/
26-
0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3,/* 20 ~ 39*/
27-
0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2,/* 40 ~ 59*/
28-
0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4,/* 60 ~ 79*/
29-
0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2,/* 80 ~ 99*/
30-
0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3,/*100 ~ 119*/
31-
0, 1, 0, 2, 0, 1, 0, 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2,/*120 ~ 139*/
32-
0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5,/*140 ~ 159*/
33-
0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2,/*160 ~ 179*/
34-
0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3,/*180 ~ 199*/
35-
0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2,/*200 ~ 219*/
36-
0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4,/*220 ~ 239*/
37-
0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 /*240 ~ 254*/
38-
};
39-
4026
/*
4127
* Allocation Bitmap Management Functions
4228
*/
@@ -195,32 +181,35 @@ unsigned int exfat_find_free_bitmap(struct super_block *sb, unsigned int clu)
195181
{
196182
unsigned int i, map_i, map_b, ent_idx;
197183
unsigned int clu_base, clu_free;
198-
unsigned char k, clu_mask;
184+
unsigned long clu_bits, clu_mask;
199185
struct exfat_sb_info *sbi = EXFAT_SB(sb);
186+
__le_long bitval;
200187

201188
WARN_ON(clu < EXFAT_FIRST_CLUSTER);
202-
ent_idx = CLUSTER_TO_BITMAP_ENT(clu);
203-
clu_base = BITMAP_ENT_TO_CLUSTER(ent_idx & ~(BITS_PER_BYTE_MASK));
189+
ent_idx = ALIGN_DOWN(CLUSTER_TO_BITMAP_ENT(clu), BITS_PER_LONG);
190+
clu_base = BITMAP_ENT_TO_CLUSTER(ent_idx);
204191
clu_mask = IGNORED_BITS_REMAINED(clu, clu_base);
205192

206193
map_i = BITMAP_OFFSET_SECTOR_INDEX(sb, ent_idx);
207194
map_b = BITMAP_OFFSET_BYTE_IN_SECTOR(sb, ent_idx);
208195

209196
for (i = EXFAT_FIRST_CLUSTER; i < sbi->num_clusters;
210-
i += BITS_PER_BYTE) {
211-
k = *(sbi->vol_amap[map_i]->b_data + map_b);
197+
i += BITS_PER_LONG) {
198+
bitval = *(__le_long *)(sbi->vol_amap[map_i]->b_data + map_b);
212199
if (clu_mask > 0) {
213-
k |= clu_mask;
200+
bitval |= cpu_to_lel(clu_mask);
214201
clu_mask = 0;
215202
}
216-
if (k < 0xFF) {
217-
clu_free = clu_base + free_bit[k];
203+
if (lel_to_cpu(bitval) != ULONG_MAX) {
204+
clu_bits = lel_to_cpu(bitval);
205+
clu_free = clu_base + ffz(clu_bits);
218206
if (clu_free < sbi->num_clusters)
219207
return clu_free;
220208
}
221-
clu_base += BITS_PER_BYTE;
209+
clu_base += BITS_PER_LONG;
210+
map_b += sizeof(long);
222211

223-
if (++map_b >= sb->s_blocksize ||
212+
if (map_b >= sb->s_blocksize ||
224213
clu_base >= sbi->num_clusters) {
225214
if (++map_i >= sbi->map_sectors) {
226215
clu_base = EXFAT_FIRST_CLUSTER;

fs/exfat/exfat_fs.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,7 @@ enum {
135135
#define BITMAP_OFFSET_BIT_IN_SECTOR(sb, ent) (ent & BITS_PER_SECTOR_MASK(sb))
136136
#define BITMAP_OFFSET_BYTE_IN_SECTOR(sb, ent) \
137137
((ent / BITS_PER_BYTE) & ((sb)->s_blocksize - 1))
138-
#define BITS_PER_BYTE_MASK 0x7
139-
#define IGNORED_BITS_REMAINED(clu, clu_base) ((1 << ((clu) - (clu_base))) - 1)
138+
#define IGNORED_BITS_REMAINED(clu, clu_base) ((1UL << ((clu) - (clu_base))) - 1)
140139

141140
#define ES_ENTRY_NUM(name_len) (ES_IDX_LAST_FILENAME(name_len) + 1)
142141
/* 19 entries = 1 file entry + 1 stream entry + 17 filename entries */

0 commit comments

Comments
 (0)