Commit f3b47f39 authored by Hirofumi Ogawa's avatar Hirofumi Ogawa Committed by Linus Torvalds

[PATCH] fat: reserved clusters cleanup

- Replaces the "number of reserved clusters" by FAT_START_ENT.

- The ->clusters is total number of clusters. Instead of it, use the
  maximum cluster number (->max_cluster).

  By this change, removes the some "->clusters + 2" calculation.

- Adds inline function for cluster to block number conversion. And
  replaces the open-coding for it.
Signed-off-by: default avatarOGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent e8759df1
...@@ -305,7 +305,7 @@ int fat_access(struct super_block *sb, int nr, int new_value) ...@@ -305,7 +305,7 @@ int fat_access(struct super_block *sb, int nr, int new_value)
int next; int next;
next = -EIO; next = -EIO;
if (nr < 2 || MSDOS_SB(sb)->clusters + 2 <= nr) { if (nr < FAT_START_ENT || MSDOS_SB(sb)->max_cluster <= nr) {
fat_fs_panic(sb, "invalid access to FAT (entry 0x%08x)", nr); fat_fs_panic(sb, "invalid access to FAT (entry 0x%08x)", nr);
goto out; goto out;
} }
...@@ -431,9 +431,7 @@ int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys) ...@@ -431,9 +431,7 @@ int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys)
cluster = fat_bmap_cluster(inode, cluster); cluster = fat_bmap_cluster(inode, cluster);
if (cluster < 0) if (cluster < 0)
return cluster; return cluster;
else if (cluster) { else if (cluster)
*phys = ((sector_t)cluster - 2) * sbi->sec_per_clus *phys = fat_clus_to_blknr(sbi, cluster) + offset;
+ sbi->data_start + offset;
}
return 0; return 0;
} }
...@@ -767,7 +767,7 @@ static struct buffer_head *fat_extend_dir(struct inode *inode) ...@@ -767,7 +767,7 @@ static struct buffer_head *fat_extend_dir(struct inode *inode)
if (nr < 0) if (nr < 0)
return ERR_PTR(nr); return ERR_PTR(nr);
sector = ((sector_t)nr - 2) * sec_per_clus + MSDOS_SB(sb)->data_start; sector = fat_clus_to_blknr(MSDOS_SB(sb), nr);
last_sector = sector + sec_per_clus; last_sector = sector + sec_per_clus;
for ( ; sector < last_sector; sector++) { for ( ; sector < last_sector; sector++) {
if ((bh = sb_getblk(sb, sector))) { if ((bh = sb_getblk(sb, sector))) {
......
...@@ -419,17 +419,18 @@ static int fat_remount(struct super_block *sb, int *flags, char *data) ...@@ -419,17 +419,18 @@ static int fat_remount(struct super_block *sb, int *flags, char *data)
static int fat_statfs(struct super_block *sb, struct kstatfs *buf) static int fat_statfs(struct super_block *sb, struct kstatfs *buf)
{ {
struct msdos_sb_info *sbi = MSDOS_SB(sb);
int free, nr, ret; int free, nr, ret;
if (MSDOS_SB(sb)->free_clusters != -1) if (sbi->free_clusters != -1)
free = MSDOS_SB(sb)->free_clusters; free = sbi->free_clusters;
else { else {
lock_fat(sb); lock_fat(sb);
if (MSDOS_SB(sb)->free_clusters != -1) if (sbi->free_clusters != -1)
free = MSDOS_SB(sb)->free_clusters; free = sbi->free_clusters;
else { else {
free = 0; free = 0;
for (nr = 2; nr < MSDOS_SB(sb)->clusters + 2; nr++) { for (nr = FAT_START_ENT; nr < sbi->max_cluster; nr++) {
ret = fat_access(sb, nr, -1); ret = fat_access(sb, nr, -1);
if (ret < 0) { if (ret < 0) {
unlock_fat(sb); unlock_fat(sb);
...@@ -437,17 +438,17 @@ static int fat_statfs(struct super_block *sb, struct kstatfs *buf) ...@@ -437,17 +438,17 @@ static int fat_statfs(struct super_block *sb, struct kstatfs *buf)
} else if (ret == FAT_ENT_FREE) } else if (ret == FAT_ENT_FREE)
free++; free++;
} }
MSDOS_SB(sb)->free_clusters = free; sbi->free_clusters = free;
} }
unlock_fat(sb); unlock_fat(sb);
} }
buf->f_type = sb->s_magic; buf->f_type = sb->s_magic;
buf->f_bsize = MSDOS_SB(sb)->cluster_size; buf->f_bsize = sbi->cluster_size;
buf->f_blocks = MSDOS_SB(sb)->clusters; buf->f_blocks = sbi->max_cluster - FAT_START_ENT;
buf->f_bfree = free; buf->f_bfree = free;
buf->f_bavail = free; buf->f_bavail = free;
buf->f_namelen = MSDOS_SB(sb)->options.isvfat ? 260 : 12; buf->f_namelen = sbi->options.isvfat ? 260 : 12;
return 0; return 0;
} }
...@@ -1232,7 +1233,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, ...@@ -1232,7 +1233,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent,
/* check that FAT table does not overflow */ /* check that FAT table does not overflow */
fat_clusters = sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits; fat_clusters = sbi->fat_length * sb->s_blocksize * 8 / sbi->fat_bits;
total_clusters = min(total_clusters, fat_clusters - 2); total_clusters = min(total_clusters, fat_clusters - FAT_START_ENT);
if (total_clusters > MAX_FAT(sb)) { if (total_clusters > MAX_FAT(sb)) {
if (!silent) if (!silent)
printk(KERN_ERR "FAT: count of clusters too big (%u)\n", printk(KERN_ERR "FAT: count of clusters too big (%u)\n",
...@@ -1241,9 +1242,9 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, ...@@ -1241,9 +1242,9 @@ int fat_fill_super(struct super_block *sb, void *data, int silent,
goto out_invalid; goto out_invalid;
} }
sbi->clusters = total_clusters; sbi->max_cluster = total_clusters + FAT_START_ENT;
/* check the free_clusters, it's not necessarily correct */ /* check the free_clusters, it's not necessarily correct */
if (sbi->free_clusters != -1 && sbi->free_clusters > sbi->clusters) if (sbi->free_clusters != -1 && sbi->free_clusters > total_clusters)
sbi->free_clusters = -1; sbi->free_clusters = -1;
brelse(bh); brelse(bh);
......
...@@ -86,8 +86,9 @@ void fat_clusters_flush(struct super_block *sb) ...@@ -86,8 +86,9 @@ void fat_clusters_flush(struct super_block *sb)
int fat_add_cluster(struct inode *inode) int fat_add_cluster(struct inode *inode)
{ {
struct super_block *sb = inode->i_sb; struct super_block *sb = inode->i_sb;
struct msdos_sb_info *sbi = MSDOS_SB(sb);
int ret, count, limit, new_dclus, new_fclus, last; int ret, count, limit, new_dclus, new_fclus, last;
int cluster_bits = MSDOS_SB(sb)->cluster_bits; int cluster_bits = sbi->cluster_bits;
/* /*
* We must locate the last cluster of the file to add this new * We must locate the last cluster of the file to add this new
...@@ -110,17 +111,17 @@ int fat_add_cluster(struct inode *inode) ...@@ -110,17 +111,17 @@ int fat_add_cluster(struct inode *inode)
/* find free FAT entry */ /* find free FAT entry */
lock_fat(sb); lock_fat(sb);
if (MSDOS_SB(sb)->free_clusters == 0) { if (sbi->free_clusters == 0) {
unlock_fat(sb); unlock_fat(sb);
return -ENOSPC; return -ENOSPC;
} }
limit = MSDOS_SB(sb)->clusters + 2; limit = sbi->max_cluster;
new_dclus = MSDOS_SB(sb)->prev_free + 1; new_dclus = sbi->prev_free + 1;
for (count = 0; count < MSDOS_SB(sb)->clusters; count++, new_dclus++) { for (count = FAT_START_ENT; count < limit; count++, new_dclus++) {
new_dclus = new_dclus % limit; new_dclus = new_dclus % limit;
if (new_dclus < 2) if (new_dclus < FAT_START_ENT)
new_dclus = 2; new_dclus = FAT_START_ENT;
ret = fat_access(sb, new_dclus, -1); ret = fat_access(sb, new_dclus, -1);
if (ret < 0) { if (ret < 0) {
...@@ -129,8 +130,8 @@ int fat_add_cluster(struct inode *inode) ...@@ -129,8 +130,8 @@ int fat_add_cluster(struct inode *inode)
} else if (ret == FAT_ENT_FREE) } else if (ret == FAT_ENT_FREE)
break; break;
} }
if (count >= MSDOS_SB(sb)->clusters) { if (count >= limit) {
MSDOS_SB(sb)->free_clusters = 0; sbi->free_clusters = 0;
unlock_fat(sb); unlock_fat(sb);
return -ENOSPC; return -ENOSPC;
} }
...@@ -141,9 +142,9 @@ int fat_add_cluster(struct inode *inode) ...@@ -141,9 +142,9 @@ int fat_add_cluster(struct inode *inode)
return ret; return ret;
} }
MSDOS_SB(sb)->prev_free = new_dclus; sbi->prev_free = new_dclus;
if (MSDOS_SB(sb)->free_clusters != -1) if (sbi->free_clusters != -1)
MSDOS_SB(sb)->free_clusters--; sbi->free_clusters--;
fat_clusters_flush(sb); fat_clusters_flush(sb);
unlock_fat(sb); unlock_fat(sb);
...@@ -164,7 +165,7 @@ int fat_add_cluster(struct inode *inode) ...@@ -164,7 +165,7 @@ int fat_add_cluster(struct inode *inode)
new_fclus, inode->i_blocks >> (cluster_bits - 9)); new_fclus, inode->i_blocks >> (cluster_bits - 9));
fat_cache_inval_inode(inode); fat_cache_inval_inode(inode);
} }
inode->i_blocks += MSDOS_SB(sb)->cluster_size >> 9; inode->i_blocks += sbi->cluster_size >> 9;
return new_dclus; return new_dclus;
} }
......
...@@ -64,6 +64,9 @@ ...@@ -64,6 +64,9 @@
#define FAT_FIRST_ENT(s, x) ((MSDOS_SB(s)->fat_bits == 32 ? 0x0FFFFF00 : \ #define FAT_FIRST_ENT(s, x) ((MSDOS_SB(s)->fat_bits == 32 ? 0x0FFFFF00 : \
MSDOS_SB(s)->fat_bits == 16 ? 0xFF00 : 0xF00) | (x)) MSDOS_SB(s)->fat_bits == 16 ? 0xFF00 : 0xF00) | (x))
/* start of data cluster's entry (number of reserved clusters) */
#define FAT_START_ENT 2
/* maximum number of clusters */ /* maximum number of clusters */
#define MAX_FAT12 0xFF4 #define MAX_FAT12 0xFF4
#define MAX_FAT16 0xFFF4 #define MAX_FAT16 0xFFF4
...@@ -221,7 +224,7 @@ struct msdos_sb_info { ...@@ -221,7 +224,7 @@ struct msdos_sb_info {
unsigned long dir_start; unsigned long dir_start;
unsigned short dir_entries; /* root dir start & entries */ unsigned short dir_entries; /* root dir start & entries */
unsigned long data_start; /* first data sector */ unsigned long data_start; /* first data sector */
unsigned long clusters; /* number of clusters */ unsigned long max_cluster; /* maximum cluster number */
unsigned long root_cluster; /* first cluster of the root directory */ unsigned long root_cluster; /* first cluster of the root directory */
unsigned long fsinfo_sector; /* sector number of FAT32 fsinfo */ unsigned long fsinfo_sector; /* sector number of FAT32 fsinfo */
struct semaphore fat_lock; struct semaphore fat_lock;
...@@ -270,6 +273,12 @@ static inline struct msdos_inode_info *MSDOS_I(struct inode *inode) ...@@ -270,6 +273,12 @@ static inline struct msdos_inode_info *MSDOS_I(struct inode *inode)
return container_of(inode, struct msdos_inode_info, vfs_inode); return container_of(inode, struct msdos_inode_info, vfs_inode);
} }
static inline sector_t fat_clus_to_blknr(struct msdos_sb_info *sbi, int clus)
{
return ((sector_t)clus - FAT_START_ENT) * sbi->sec_per_clus
+ sbi->data_start;
}
static inline void fat16_towchar(wchar_t *dst, const __u8 *src, size_t len) static inline void fat16_towchar(wchar_t *dst, const __u8 *src, size_t len)
{ {
#ifdef __BIG_ENDIAN #ifdef __BIG_ENDIAN
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment