]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/fat/fatent.c
fat: split include/msdos_fs.h
[linux-2.6-omap-h63xx.git] / fs / fat / fatent.c
index 5fb366992b73dcfdbf6a936c510622087b324444..5b5f49061b7c7ccbfe76eea416475fc691936346 100644 (file)
@@ -6,6 +6,8 @@
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/msdos_fs.h>
+#include <linux/blkdev.h>
+#include "fat.h"
 
 struct fatent_operations {
        void (*ent_blocknr)(struct super_block *, int, int *, sector_t *);
@@ -450,7 +452,8 @@ int fat_alloc_clusters(struct inode *inode, int *cluster, int nr_cluster)
        BUG_ON(nr_cluster > (MAX_BUF_PER_PAGE / 2));    /* fixed limit */
 
        lock_fat(sbi);
-       if (sbi->free_clusters != -1 && sbi->free_clusters < nr_cluster) {
+       if (sbi->free_clusters != -1 && sbi->free_clus_valid &&
+           sbi->free_clusters < nr_cluster) {
                unlock_fat(sbi);
                return -ENOSPC;
        }
@@ -504,6 +507,7 @@ int fat_alloc_clusters(struct inode *inode, int *cluster, int nr_cluster)
 
        /* Couldn't allocate the free entries */
        sbi->free_clusters = 0;
+       sbi->free_clus_valid = 1;
        sb->s_dirt = 1;
        err = -ENOSPC;
 
@@ -533,6 +537,7 @@ int fat_free_clusters(struct inode *inode, int cluster)
        struct fat_entry fatent;
        struct buffer_head *bhs[MAX_BUF_PER_PAGE];
        int i, err, nr_bhs;
+       int first_cl = cluster;
 
        nr_bhs = 0;
        fatent_init(&fatent);
@@ -544,11 +549,23 @@ int fat_free_clusters(struct inode *inode, int cluster)
                        goto error;
                } else if (cluster == FAT_ENT_FREE) {
                        fat_fs_panic(sb, "%s: deleting FAT entry beyond EOF",
-                                    __FUNCTION__);
+                                    __func__);
                        err = -EIO;
                        goto error;
                }
 
+               /* 
+                * Issue discard for the sectors we no longer care about,
+                * batching contiguous clusters into one request
+                */
+               if (cluster != fatent.entry + 1) {
+                       int nr_clus = fatent.entry - first_cl + 1;
+
+                       sb_issue_discard(sb, fat_clus_to_blknr(sbi, first_cl),
+                                        nr_clus * sbi->sec_per_clus);
+                       first_cl = cluster;
+               }
+
                ops->ent_put(&fatent, FAT_ENT_FREE);
                if (sbi->free_clusters != -1) {
                        sbi->free_clusters++;
@@ -583,8 +600,6 @@ error:
                brelse(bhs[i]);
        unlock_fat(sbi);
 
-       fat_clusters_flush(sb);
-
        return err;
 }
 
@@ -615,7 +630,7 @@ int fat_count_free_clusters(struct super_block *sb)
        int err = 0, free;
 
        lock_fat(sbi);
-       if (sbi->free_clusters != -1)
+       if (sbi->free_clusters != -1 && sbi->free_clus_valid)
                goto out;
 
        reada_blocks = FAT_READA_SIZE >> sb->s_blocksize_bits;
@@ -643,6 +658,7 @@ int fat_count_free_clusters(struct super_block *sb)
                } while (fat_ent_next(sbi, &fatent));
        }
        sbi->free_clusters = free;
+       sbi->free_clus_valid = 1;
        sb->s_dirt = 1;
        fatent_brelse(&fatent);
 out: