The rpc server does not require that service threads take the BKL.
[safe/jmp/linux-2.6] / fs / fat / cache.c
index 3222f51..923990e 100644 (file)
@@ -9,8 +9,8 @@
  */
 
 #include <linux/fs.h>
-#include <linux/msdos_fs.h>
 #include <linux/buffer_head.h>
+#include "fat.h"
 
 /* this must be > 0. */
 #define FAT_MAX_CACHE  8
@@ -241,7 +241,7 @@ int fat_get_cluster(struct inode *inode, int cluster, int *fclus, int *dclus)
        while (*fclus < cluster) {
                /* prevent the infinite loop of cluster chain */
                if (*fclus > limit) {
-                       fat_fs_panic(sb, "%s: detected the cluster chain loop"
+                       fat_fs_error(sb, "%s: detected the cluster chain loop"
                                     " (i_pos %lld)", __func__,
                                     MSDOS_I(inode)->i_pos);
                        nr = -EIO;
@@ -252,7 +252,7 @@ int fat_get_cluster(struct inode *inode, int cluster, int *fclus, int *dclus)
                if (nr < 0)
                        goto out;
                else if (nr == FAT_ENT_FREE) {
-                       fat_fs_panic(sb, "%s: invalid cluster chain"
+                       fat_fs_error(sb, "%s: invalid cluster chain"
                                     " (i_pos %lld)", __func__,
                                     MSDOS_I(inode)->i_pos);
                        nr = -EIO;
@@ -285,7 +285,7 @@ static int fat_bmap_cluster(struct inode *inode, int cluster)
        if (ret < 0)
                return ret;
        else if (ret == FAT_ENT_EOF) {
-               fat_fs_panic(sb, "%s: request beyond EOF (i_pos %lld)",
+               fat_fs_error(sb, "%s: request beyond EOF (i_pos %lld)",
                             __func__, MSDOS_I(inode)->i_pos);
                return -EIO;
        }
@@ -293,10 +293,12 @@ static int fat_bmap_cluster(struct inode *inode, int cluster)
 }
 
 int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys,
-            unsigned long *mapped_blocks)
+            unsigned long *mapped_blocks, int create)
 {
        struct super_block *sb = inode->i_sb;
        struct msdos_sb_info *sbi = MSDOS_SB(sb);
+       const unsigned long blocksize = sb->s_blocksize;
+       const unsigned char blocksize_bits = sb->s_blocksize_bits;
        sector_t last_block;
        int cluster, offset;
 
@@ -309,10 +311,21 @@ int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys,
                }
                return 0;
        }
-       last_block = (MSDOS_I(inode)->mmu_private + (sb->s_blocksize - 1))
-               >> sb->s_blocksize_bits;
-       if (sector >= last_block)
-               return 0;
+
+       last_block = (i_size_read(inode) + (blocksize - 1)) >> blocksize_bits;
+       if (sector >= last_block) {
+               if (!create)
+                       return 0;
+
+               /*
+                * ->mmu_private can access on only allocation path.
+                * (caller must hold ->i_mutex)
+                */
+               last_block = (MSDOS_I(inode)->mmu_private + (blocksize - 1))
+                       >> blocksize_bits;
+               if (sector >= last_block)
+                       return 0;
+       }
 
        cluster = sector >> (sbi->cluster_bits - sb->s_blocksize_bits);
        offset  = sector & (sbi->sec_per_clus - 1);