Messages in this thread Patch in this message | ![/](/images/icornerl.gif) | | Subject | [PATCH] adds fat_get_cluster (7/11) | From | OGAWA Hirofumi <> | Date | Tue, 22 Jul 2003 00:55:38 +0900 |
| |
This adds the fat_get_cluster() for generic reads of FAT cluster-chains, and old fat_get_cluster() is renamed to fat_bmap_cluster().
fs/fat/cache.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- include/linux/msdos_fs.h | 2 ++ 2 files changed, 46 insertions(+), 2 deletions(-)
diff -puN fs/fat/cache.c~fat_add-get_cluster fs/fat/cache.c --- linux-2.6.0-test1/fs/fat/cache.c~fat_add-get_cluster 2003-07-21 02:48:24.000000000 +0900 +++ linux-2.6.0-test1-hirofumi/fs/fat/cache.c 2003-07-21 02:48:24.000000000 +0900 @@ -287,7 +287,49 @@ out: spin_unlock(&sbi->cache_lock); } -static int fat_get_cluster(struct inode *inode, int cluster) +int fat_get_cluster(struct inode *inode, int cluster, int *fclus, int *dclus) +{ + struct super_block *sb = inode->i_sb; + const int limit = sb->s_maxbytes >> MSDOS_SB(sb)->cluster_bits; + int nr; + + BUG_ON(MSDOS_I(inode)->i_start == 0); + + *fclus = 0; + *dclus = MSDOS_I(inode)->i_start; + if (cluster == 0) + return 0; + + fat_cache_lookup(inode, cluster, fclus, dclus); + while (*fclus < cluster) { + /* prevent the infinite loop of cluster chain */ + if (*fclus > limit) { + fat_fs_panic(sb, "%s: detected the cluster chain loop" + " (i_pos %llu)", __FUNCTION__, + MSDOS_I(inode)->i_pos); + return -EIO; + } + + nr = fat_access(sb, *dclus, -1); + if (nr < 0) + return nr; + else if (nr == FAT_ENT_FREE) { + fat_fs_panic(sb, "%s: invalid cluster chain" + " (i_pos %llu)", __FUNCTION__, + MSDOS_I(inode)->i_pos); + return -EIO; + } else if (nr == FAT_ENT_EOF) { + fat_cache_add(inode, *fclus, *dclus); + return FAT_ENT_EOF; + } + (*fclus)++; + *dclus = nr; + } + fat_cache_add(inode, *fclus, *dclus); + return 0; +} + +static int fat_bmap_cluster(struct inode *inode, int cluster) { struct super_block *sb = inode->i_sb; int nr,count; @@ -336,7 +378,7 @@ int fat_bmap(struct inode *inode, sector cluster = sector >> (sbi->cluster_bits - sb->s_blocksize_bits); offset = sector & (sbi->cluster_size - 1); - cluster = fat_get_cluster(inode, cluster); + cluster = fat_bmap_cluster(inode, cluster); if (cluster < 0) return cluster; else if (cluster) { diff -puN include/linux/msdos_fs.h~fat_add-get_cluster include/linux/msdos_fs.h --- linux-2.6.0-test1/include/linux/msdos_fs.h~fat_add-get_cluster 2003-07-21 02:48:24.000000000 +0900 +++ linux-2.6.0-test1-hirofumi/include/linux/msdos_fs.h 2003-07-21 02:48:24.000000000 +0900 @@ -237,6 +237,8 @@ extern void fat_cache_lookup(struct inod int *d_clu); extern void fat_cache_add(struct inode *inode, int f_clu, int d_clu); extern void fat_cache_inval_inode(struct inode *inode); +extern int fat_get_cluster(struct inode *inode, int cluster, + int *fclus, int *dclus); extern int fat_free(struct inode *inode, int skip); /* fat/dir.c */ _
-- OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| ![\](/images/icornerr.gif) |