@@ -301,15 +301,59 @@ static int fat_bmap_cluster(struct inode *inode, int cluster)
301
301
return dclus ;
302
302
}
303
303
304
- int fat_bmap (struct inode * inode , sector_t sector , sector_t * phys ,
305
- unsigned long * mapped_blocks , int create )
304
+ int fat_get_mapped_cluster (struct inode * inode , sector_t sector ,
305
+ sector_t last_block ,
306
+ unsigned long * mapped_blocks , sector_t * bmap )
306
307
{
307
308
struct super_block * sb = inode -> i_sb ;
308
309
struct msdos_sb_info * sbi = MSDOS_SB (sb );
310
+ int cluster , offset ;
311
+
312
+ cluster = sector >> (sbi -> cluster_bits - sb -> s_blocksize_bits );
313
+ offset = sector & (sbi -> sec_per_clus - 1 );
314
+ cluster = fat_bmap_cluster (inode , cluster );
315
+ if (cluster < 0 )
316
+ return cluster ;
317
+ else if (cluster ) {
318
+ * bmap = fat_clus_to_blknr (sbi , cluster ) + offset ;
319
+ * mapped_blocks = sbi -> sec_per_clus - offset ;
320
+ if (* mapped_blocks > last_block - sector )
321
+ * mapped_blocks = last_block - sector ;
322
+ }
323
+
324
+ return 0 ;
325
+ }
326
+
327
+ static int is_exceed_eof (struct inode * inode , sector_t sector ,
328
+ sector_t * last_block , int create )
329
+ {
330
+ struct super_block * sb = inode -> i_sb ;
309
331
const unsigned long blocksize = sb -> s_blocksize ;
310
332
const unsigned char blocksize_bits = sb -> s_blocksize_bits ;
333
+
334
+ * last_block = (i_size_read (inode ) + (blocksize - 1 )) >> blocksize_bits ;
335
+ if (sector >= * last_block ) {
336
+ if (!create )
337
+ return 1 ;
338
+
339
+ /*
340
+ * ->mmu_private can access on only allocation path.
341
+ * (caller must hold ->i_mutex)
342
+ */
343
+ * last_block = (MSDOS_I (inode )-> mmu_private + (blocksize - 1 ))
344
+ >> blocksize_bits ;
345
+ if (sector >= * last_block )
346
+ return 1 ;
347
+ }
348
+
349
+ return 0 ;
350
+ }
351
+
352
+ int fat_bmap (struct inode * inode , sector_t sector , sector_t * phys ,
353
+ unsigned long * mapped_blocks , int create , bool from_bmap )
354
+ {
355
+ struct msdos_sb_info * sbi = MSDOS_SB (inode -> i_sb );
311
356
sector_t last_block ;
312
- int cluster , offset ;
313
357
314
358
* phys = 0 ;
315
359
* mapped_blocks = 0 ;
@@ -321,31 +365,16 @@ int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys,
321
365
return 0 ;
322
366
}
323
367
324
- last_block = (i_size_read (inode ) + (blocksize - 1 )) >> blocksize_bits ;
325
- if (sector >= last_block ) {
326
- if (!create )
368
+ if (!from_bmap ) {
369
+ if (is_exceed_eof (inode , sector , & last_block , create ))
327
370
return 0 ;
328
-
329
- /*
330
- * ->mmu_private can access on only allocation path.
331
- * (caller must hold ->i_mutex)
332
- */
333
- last_block = (MSDOS_I (inode )-> mmu_private + (blocksize - 1 ))
334
- >> blocksize_bits ;
371
+ } else {
372
+ last_block = inode -> i_blocks >>
373
+ (inode -> i_sb -> s_blocksize_bits - 9 );
335
374
if (sector >= last_block )
336
375
return 0 ;
337
376
}
338
377
339
- cluster = sector >> (sbi -> cluster_bits - sb -> s_blocksize_bits );
340
- offset = sector & (sbi -> sec_per_clus - 1 );
341
- cluster = fat_bmap_cluster (inode , cluster );
342
- if (cluster < 0 )
343
- return cluster ;
344
- else if (cluster ) {
345
- * phys = fat_clus_to_blknr (sbi , cluster ) + offset ;
346
- * mapped_blocks = sbi -> sec_per_clus - offset ;
347
- if (* mapped_blocks > last_block - sector )
348
- * mapped_blocks = last_block - sector ;
349
- }
350
- return 0 ;
378
+ return fat_get_mapped_cluster (inode , sector , last_block , mapped_blocks ,
379
+ phys );
351
380
}
0 commit comments