5
5
6
6
#include <linux/blkdev.h>
7
7
#include <linux/slab.h>
8
+ #include <linux/bitmap.h>
8
9
#include <linux/buffer_head.h>
9
10
10
11
#include "exfat_raw.h"
11
12
#include "exfat_fs.h"
12
13
13
- static const unsigned char free_bit [] = {
14
- 0 , 1 , 0 , 2 , 0 , 1 , 0 , 3 , 0 , 1 , 0 , 2 , 0 , 1 , 0 , 4 , 0 , 1 , 0 , 2 ,/* 0 ~ 19*/
15
- 0 , 1 , 0 , 3 , 0 , 1 , 0 , 2 , 0 , 1 , 0 , 5 , 0 , 1 , 0 , 2 , 0 , 1 , 0 , 3 ,/* 20 ~ 39*/
16
- 0 , 1 , 0 , 2 , 0 , 1 , 0 , 4 , 0 , 1 , 0 , 2 , 0 , 1 , 0 , 3 , 0 , 1 , 0 , 2 ,/* 40 ~ 59*/
17
- 0 , 1 , 0 , 6 , 0 , 1 , 0 , 2 , 0 , 1 , 0 , 3 , 0 , 1 , 0 , 2 , 0 , 1 , 0 , 4 ,/* 60 ~ 79*/
18
- 0 , 1 , 0 , 2 , 0 , 1 , 0 , 3 , 0 , 1 , 0 , 2 , 0 , 1 , 0 , 5 , 0 , 1 , 0 , 2 ,/* 80 ~ 99*/
19
- 0 , 1 , 0 , 3 , 0 , 1 , 0 , 2 , 0 , 1 , 0 , 4 , 0 , 1 , 0 , 2 , 0 , 1 , 0 , 3 ,/*100 ~ 119*/
20
- 0 , 1 , 0 , 2 , 0 , 1 , 0 , 7 , 0 , 1 , 0 , 2 , 0 , 1 , 0 , 3 , 0 , 1 , 0 , 2 ,/*120 ~ 139*/
21
- 0 , 1 , 0 , 4 , 0 , 1 , 0 , 2 , 0 , 1 , 0 , 3 , 0 , 1 , 0 , 2 , 0 , 1 , 0 , 5 ,/*140 ~ 159*/
22
- 0 , 1 , 0 , 2 , 0 , 1 , 0 , 3 , 0 , 1 , 0 , 2 , 0 , 1 , 0 , 4 , 0 , 1 , 0 , 2 ,/*160 ~ 179*/
23
- 0 , 1 , 0 , 3 , 0 , 1 , 0 , 2 , 0 , 1 , 0 , 6 , 0 , 1 , 0 , 2 , 0 , 1 , 0 , 3 ,/*180 ~ 199*/
24
- 0 , 1 , 0 , 2 , 0 , 1 , 0 , 4 , 0 , 1 , 0 , 2 , 0 , 1 , 0 , 3 , 0 , 1 , 0 , 2 ,/*200 ~ 219*/
25
- 0 , 1 , 0 , 5 , 0 , 1 , 0 , 2 , 0 , 1 , 0 , 3 , 0 , 1 , 0 , 2 , 0 , 1 , 0 , 4 ,/*220 ~ 239*/
26
- 0 , 1 , 0 , 2 , 0 , 1 , 0 , 3 , 0 , 1 , 0 , 2 , 0 , 1 , 0 /*240 ~ 254*/
27
- };
28
-
29
- static const unsigned char used_bit [] = {
30
- 0 , 1 , 1 , 2 , 1 , 2 , 2 , 3 , 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 1 , 2 , 2 , 3 ,/* 0 ~ 19*/
31
- 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 ,/* 20 ~ 39*/
32
- 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 ,/* 40 ~ 59*/
33
- 4 , 5 , 5 , 6 , 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 ,/* 60 ~ 79*/
34
- 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 2 , 3 , 3 , 4 ,/* 80 ~ 99*/
35
- 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 ,/*100 ~ 119*/
36
- 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7 , 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 ,/*120 ~ 139*/
37
- 3 , 4 , 4 , 5 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 ,/*140 ~ 159*/
38
- 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 3 , 4 , 4 , 5 ,/*160 ~ 179*/
39
- 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 ,/*180 ~ 199*/
40
- 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 ,/*200 ~ 219*/
41
- 5 , 6 , 6 , 7 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7 ,/*220 ~ 239*/
42
- 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7 , 5 , 6 , 6 , 7 , 6 , 7 , 7 , 8 /*240 ~ 255*/
43
- };
14
+ #if BITS_PER_LONG == 32
15
+ #define __le_long __le32
16
+ #define lel_to_cpu (A ) le32_to_cpu(A)
17
+ #define cpu_to_lel (A ) cpu_to_le32(A)
18
+ #elif BITS_PER_LONG == 64
19
+ #define __le_long __le64
20
+ #define lel_to_cpu (A ) le64_to_cpu(A)
21
+ #define cpu_to_lel (A ) cpu_to_le64(A)
22
+ #else
23
+ #error "BITS_PER_LONG not 32 or 64"
24
+ #endif
44
25
45
26
/*
46
27
* Allocation Bitmap Management Functions
@@ -200,32 +181,35 @@ unsigned int exfat_find_free_bitmap(struct super_block *sb, unsigned int clu)
200
181
{
201
182
unsigned int i , map_i , map_b , ent_idx ;
202
183
unsigned int clu_base , clu_free ;
203
- unsigned char k , clu_mask ;
184
+ unsigned long clu_bits , clu_mask ;
204
185
struct exfat_sb_info * sbi = EXFAT_SB (sb );
186
+ __le_long bitval ;
205
187
206
188
WARN_ON (clu < EXFAT_FIRST_CLUSTER );
207
- ent_idx = CLUSTER_TO_BITMAP_ENT (clu );
208
- 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 );
209
191
clu_mask = IGNORED_BITS_REMAINED (clu , clu_base );
210
192
211
193
map_i = BITMAP_OFFSET_SECTOR_INDEX (sb , ent_idx );
212
194
map_b = BITMAP_OFFSET_BYTE_IN_SECTOR (sb , ent_idx );
213
195
214
196
for (i = EXFAT_FIRST_CLUSTER ; i < sbi -> num_clusters ;
215
- i += BITS_PER_BYTE ) {
216
- 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 );
217
199
if (clu_mask > 0 ) {
218
- k |= clu_mask ;
200
+ bitval |= cpu_to_lel ( clu_mask ) ;
219
201
clu_mask = 0 ;
220
202
}
221
- if (k < 0xFF ) {
222
- 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 );
223
206
if (clu_free < sbi -> num_clusters )
224
207
return clu_free ;
225
208
}
226
- clu_base += BITS_PER_BYTE ;
209
+ clu_base += BITS_PER_LONG ;
210
+ map_b += sizeof (long );
227
211
228
- if (++ map_b >= sb -> s_blocksize ||
212
+ if (map_b >= sb -> s_blocksize ||
229
213
clu_base >= sbi -> num_clusters ) {
230
214
if (++ map_i >= sbi -> map_sectors ) {
231
215
clu_base = EXFAT_FIRST_CLUSTER ;
@@ -244,25 +228,24 @@ int exfat_count_used_clusters(struct super_block *sb, unsigned int *ret_count)
244
228
unsigned int count = 0 ;
245
229
unsigned int i , map_i = 0 , map_b = 0 ;
246
230
unsigned int total_clus = EXFAT_DATA_CLUSTER_COUNT (sbi );
247
- unsigned int last_mask = total_clus & BITS_PER_BYTE_MASK ;
248
- unsigned char clu_bits ;
249
- const unsigned char last_bit_mask [] = {0 , 0b00000001 , 0b00000011 ,
250
- 0b00000111 , 0b00001111 , 0b00011111 , 0b00111111 , 0b01111111 };
231
+ unsigned int last_mask = total_clus & (BITS_PER_LONG - 1 );
232
+ unsigned long * bitmap , clu_bits ;
251
233
252
234
total_clus &= ~last_mask ;
253
- for (i = 0 ; i < total_clus ; i += BITS_PER_BYTE ) {
254
- clu_bits = * (sbi -> vol_amap [map_i ]-> b_data + map_b );
255
- count += used_bit [clu_bits ];
256
- if (++ map_b >= (unsigned int )sb -> s_blocksize ) {
235
+ for (i = 0 ; i < total_clus ; i += BITS_PER_LONG ) {
236
+ bitmap = (void * )(sbi -> vol_amap [map_i ]-> b_data + map_b );
237
+ count += hweight_long (* bitmap );
238
+ map_b += sizeof (long );
239
+ if (map_b >= (unsigned int )sb -> s_blocksize ) {
257
240
map_i ++ ;
258
241
map_b = 0 ;
259
242
}
260
243
}
261
244
262
245
if (last_mask ) {
263
- clu_bits = * (sbi -> vol_amap [map_i ]-> b_data + map_b );
264
- clu_bits &= last_bit_mask [ last_mask ] ;
265
- count += used_bit [ clu_bits ] ;
246
+ bitmap = ( void * ) (sbi -> vol_amap [map_i ]-> b_data + map_b );
247
+ clu_bits = lel_to_cpu ( * ( __le_long * ) bitmap ) ;
248
+ count += hweight_long ( clu_bits & BITMAP_LAST_WORD_MASK ( last_mask )) ;
266
249
}
267
250
268
251
* ret_count = count ;
0 commit comments