|
@@ -293,10 +293,12 @@ static int fat_bmap_cluster(struct inode *inode, int cluster)
|
|
|
}
|
|
|
|
|
|
int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys,
|
|
|
- unsigned long *mapped_blocks)
|
|
|
+ unsigned long *mapped_blocks, int create)
|
|
|
{
|
|
|
struct super_block *sb = inode->i_sb;
|
|
|
struct msdos_sb_info *sbi = MSDOS_SB(sb);
|
|
|
+ const unsigned long blocksize = sb->s_blocksize;
|
|
|
+ const unsigned char blocksize_bits = sb->s_blocksize_bits;
|
|
|
sector_t last_block;
|
|
|
int cluster, offset;
|
|
|
|
|
@@ -309,10 +311,21 @@ int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys,
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
- last_block = (MSDOS_I(inode)->mmu_private + (sb->s_blocksize - 1))
|
|
|
- >> sb->s_blocksize_bits;
|
|
|
- if (sector >= last_block)
|
|
|
- return 0;
|
|
|
+
|
|
|
+ last_block = (i_size_read(inode) + (blocksize - 1)) >> blocksize_bits;
|
|
|
+ if (sector >= last_block) {
|
|
|
+ if (!create)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * ->mmu_private can access on only allocation path.
|
|
|
+ * (caller must hold ->i_mutex)
|
|
|
+ */
|
|
|
+ last_block = (MSDOS_I(inode)->mmu_private + (blocksize - 1))
|
|
|
+ >> blocksize_bits;
|
|
|
+ if (sector >= last_block)
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
|
|
|
cluster = sector >> (sbi->cluster_bits - sb->s_blocksize_bits);
|
|
|
offset = sector & (sbi->sec_per_clus - 1);
|