summaryrefslogtreecommitdiff
path: root/fs/fat/cache.c
diff options
context:
space:
mode:
authorOGAWA Hirofumi <hirofumi@mail.parknet.co.jp>2006-01-08 01:02:11 -0800
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-08 20:13:46 -0800
commite5174baaea7585760f02eef23b225847d209a8db (patch)
tree34198b0f205a91670104abc800ec560e14296db3 /fs/fat/cache.c
parent7c709d00d614d0f2b6a80895b2a1aedbe04e8478 (diff)
[PATCH] fat: support ->direct_IO()
This patch add to support of ->direct_IO() for mostly read. The user of this seems to want to use for streaming read. So, current direct I/O has limitation, it can only overwrite. (For write operation, mainly we need to handle the hole etc..) Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/fat/cache.c')
-rw-r--r--fs/fat/cache.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/fs/fat/cache.c b/fs/fat/cache.c
index 77c24fcf712a..1acc941245fb 100644
--- a/fs/fat/cache.c
+++ b/fs/fat/cache.c
@@ -295,7 +295,8 @@ static int fat_bmap_cluster(struct inode *inode, int cluster)
return dclus;
}
-int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys)
+int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys,
+ unsigned long *mapped_blocks)
{
struct super_block *sb = inode->i_sb;
struct msdos_sb_info *sbi = MSDOS_SB(sb);
@@ -303,9 +304,12 @@ int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys)
int cluster, offset;
*phys = 0;
+ *mapped_blocks = 0;
if ((sbi->fat_bits != 32) && (inode->i_ino == MSDOS_ROOT_INO)) {
- if (sector < (sbi->dir_entries >> sbi->dir_per_block_bits))
+ if (sector < (sbi->dir_entries >> sbi->dir_per_block_bits)) {
*phys = sector + sbi->dir_start;
+ *mapped_blocks = 1;
+ }
return 0;
}
last_block = (MSDOS_I(inode)->mmu_private + (sb->s_blocksize - 1))
@@ -318,7 +322,11 @@ int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys)
cluster = fat_bmap_cluster(inode, cluster);
if (cluster < 0)
return cluster;
- else if (cluster)
+ else if (cluster) {
*phys = fat_clus_to_blknr(sbi, cluster) + offset;
+ *mapped_blocks = sbi->sec_per_clus - offset;
+ if (*mapped_blocks > last_block - sector)
+ *mapped_blocks = last_block - sector;
+ }
return 0;
}