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 3222f51c41cf..b42602298087 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); |