diff options
Diffstat (limited to 'fs/fat/cache.c')
| -rw-r--r-- | fs/fat/cache.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/fs/fat/cache.c b/fs/fat/cache.c index 3222f51c41c..b4260229808 100644 --- a/fs/fat/cache.c +++ b/fs/fat/cache.c | |||
| @@ -9,8 +9,8 @@ | |||
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #include <linux/fs.h> | 11 | #include <linux/fs.h> |
| 12 | #include <linux/msdos_fs.h> | ||
| 13 | #include <linux/buffer_head.h> | 12 | #include <linux/buffer_head.h> |
| 13 | #include "fat.h" | ||
| 14 | 14 | ||
| 15 | /* this must be > 0. */ | 15 | /* this must be > 0. */ |
| 16 | #define FAT_MAX_CACHE 8 | 16 | #define FAT_MAX_CACHE 8 |
| @@ -293,10 +293,12 @@ static int fat_bmap_cluster(struct inode *inode, int cluster) | |||
| 293 | } | 293 | } |
| 294 | 294 | ||
| 295 | int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys, | 295 | int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys, |
| 296 | unsigned long *mapped_blocks) | 296 | unsigned long *mapped_blocks, int create) |
| 297 | { | 297 | { |
| 298 | struct super_block *sb = inode->i_sb; | 298 | struct super_block *sb = inode->i_sb; |
| 299 | struct msdos_sb_info *sbi = MSDOS_SB(sb); | 299 | struct msdos_sb_info *sbi = MSDOS_SB(sb); |
| 300 | const unsigned long blocksize = sb->s_blocksize; | ||
| 301 | const unsigned char blocksize_bits = sb->s_blocksize_bits; | ||
| 300 | sector_t last_block; | 302 | sector_t last_block; |
| 301 | int cluster, offset; | 303 | int cluster, offset; |
| 302 | 304 | ||
| @@ -309,10 +311,21 @@ int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys, | |||
| 309 | } | 311 | } |
| 310 | return 0; | 312 | return 0; |
| 311 | } | 313 | } |
| 312 | last_block = (MSDOS_I(inode)->mmu_private + (sb->s_blocksize - 1)) | 314 | |
| 313 | >> sb->s_blocksize_bits; | 315 | last_block = (i_size_read(inode) + (blocksize - 1)) >> blocksize_bits; |
| 314 | if (sector >= last_block) | 316 | if (sector >= last_block) { |
| 315 | return 0; | 317 | if (!create) |
| 318 | return 0; | ||
| 319 | |||
| 320 | /* | ||
| 321 | * ->mmu_private can access on only allocation path. | ||
| 322 | * (caller must hold ->i_mutex) | ||
| 323 | */ | ||
| 324 | last_block = (MSDOS_I(inode)->mmu_private + (blocksize - 1)) | ||
| 325 | >> blocksize_bits; | ||
| 326 | if (sector >= last_block) | ||
| 327 | return 0; | ||
| 328 | } | ||
| 316 | 329 | ||
| 317 | cluster = sector >> (sbi->cluster_bits - sb->s_blocksize_bits); | 330 | cluster = sector >> (sbi->cluster_bits - sb->s_blocksize_bits); |
| 318 | offset = sector & (sbi->sec_per_clus - 1); | 331 | offset = sector & (sbi->sec_per_clus - 1); |
