#include <linux/module.h>
#include <linux/fs.h>
#include <linux/msdos_fs.h>
+#include <linux/blkdev.h>
struct fatent_operations {
void (*ent_blocknr)(struct super_block *, int, int *, sector_t *);
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;
}
/* Couldn't allocate the free entries */
sbi->free_clusters = 0;
+ sbi->free_clus_valid = 1;
sb->s_dirt = 1;
err = -ENOSPC;
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);
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++;
brelse(bhs[i]);
unlock_fat(sbi);
- fat_clusters_flush(sb);
-
return err;
}
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;
} while (fat_ent_next(sbi, &fatent));
}
sbi->free_clusters = free;
+ sbi->free_clus_valid = 1;
sb->s_dirt = 1;
fatent_brelse(&fatent);
out: