Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / fs / fat / cache.c
index 7c52e46..97b967b 100644 (file)
@@ -49,14 +49,14 @@ int __init fat_cache_init(void)
 {
        fat_cache_cachep = kmem_cache_create("fat_cache",
                                sizeof(struct fat_cache),
-                               0, SLAB_RECLAIM_ACCOUNT,
+                               0, SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD,
                                init_once, NULL);
        if (fat_cache_cachep == NULL)
                return -ENOMEM;
        return 0;
 }
 
-void __exit fat_cache_destroy(void)
+void fat_cache_destroy(void)
 {
        if (kmem_cache_destroy(fat_cache_cachep))
                printk(KERN_INFO "fat_cache: not all structures were freed\n");
@@ -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;
 }