Commit 0703fb8b authored by Hirofumi Ogawa's avatar Hirofumi Ogawa Committed by Linus Torvalds

[PATCH] more use new fat_get_cluster (9/11)

This uses the new fat_get_cluster() in fat_free(), fat_calc_dir_size()
and fat_add_cluster().
parent 54f6d887
...@@ -232,6 +232,8 @@ void fat_cache_add(struct inode *inode, int f_clu, int d_clu) ...@@ -232,6 +232,8 @@ void fat_cache_add(struct inode *inode, int f_clu, int d_clu)
struct fat_cache *walk, *last; struct fat_cache *walk, *last;
int first, prev_f_clu, prev_d_clu; int first, prev_f_clu, prev_d_clu;
if (f_clu == 0)
return;
first = MSDOS_I(inode)->i_start; first = MSDOS_I(inode)->i_start;
if (!first) if (!first)
return; return;
...@@ -380,41 +382,47 @@ int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys) ...@@ -380,41 +382,47 @@ int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys)
return 0; return 0;
} }
/* Free all clusters after the skip'th cluster. */
/* Free all clusters after the skip'th cluster. Doesn't use the cache, int fat_free(struct inode *inode, int skip)
because this way we get an additional sanity check. */
int fat_free(struct inode *inode,int skip)
{ {
struct super_block *sb = inode->i_sb; struct super_block *sb = inode->i_sb;
int nr,last; int nr, ret, fclus, dclus;
if (MSDOS_I(inode)->i_start == 0)
return 0;
if (skip) {
ret = fat_get_cluster(inode, skip - 1, &fclus, &dclus);
if (ret < 0)
return ret;
else if (ret == FAT_ENT_EOF)
return 0;
if (!(nr = MSDOS_I(inode)->i_start)) return 0; nr = fat_access(sb, dclus, -1);
last = 0;
while (skip--) {
last = nr;
nr = fat_access(sb, nr, -1);
if (nr == FAT_ENT_EOF) if (nr == FAT_ENT_EOF)
return 0; return 0;
else if (nr == FAT_ENT_FREE) { else if (nr > 0) {
fat_fs_panic(sb, "%s: invalid cluster chain (ino %lu)", /*
__FUNCTION__, inode->i_ino); * write a new EOF, and get the remaining cluster
return -EIO; * chain for freeing.
} else if (nr < 0) */
return nr; nr = fat_access(sb, dclus, FAT_ENT_EOF);
} }
if (last) { if (nr < 0)
fat_access(sb, last, FAT_ENT_EOF); return nr;
fat_cache_inval_inode(inode); fat_cache_inval_inode(inode);
} else { } else {
fat_cache_inval_inode(inode); fat_cache_inval_inode(inode);
nr = MSDOS_I(inode)->i_start;
MSDOS_I(inode)->i_start = 0; MSDOS_I(inode)->i_start = 0;
MSDOS_I(inode)->i_logstart = 0; MSDOS_I(inode)->i_logstart = 0;
mark_inode_dirty(inode); mark_inode_dirty(inode);
} }
lock_fat(sb); lock_fat(sb);
while (nr != FAT_ENT_EOF) { do {
nr = fat_access(sb, nr, FAT_ENT_FREE); nr = fat_access(sb, nr, FAT_ENT_FREE);
if (nr < 0) if (nr < 0)
goto error; goto error;
...@@ -427,7 +435,7 @@ int fat_free(struct inode *inode,int skip) ...@@ -427,7 +435,7 @@ int fat_free(struct inode *inode,int skip)
if (MSDOS_SB(sb)->free_clusters != -1) if (MSDOS_SB(sb)->free_clusters != -1)
MSDOS_SB(sb)->free_clusters++; MSDOS_SB(sb)->free_clusters++;
inode->i_blocks -= (1 << MSDOS_SB(sb)->cluster_bits) >> 9; inode->i_blocks -= (1 << MSDOS_SB(sb)->cluster_bits) >> 9;
} } while (nr != FAT_ENT_EOF);
fat_clusters_flush(sb); fat_clusters_flush(sb);
nr = 0; nr = 0;
error: error:
......
...@@ -465,32 +465,17 @@ static int parse_options(char *options, int is_vfat, int *debug, ...@@ -465,32 +465,17 @@ static int parse_options(char *options, int is_vfat, int *debug,
static int fat_calc_dir_size(struct inode *inode) static int fat_calc_dir_size(struct inode *inode)
{ {
struct super_block *sb = inode->i_sb; struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
int nr; int ret, fclus, dclus;
inode->i_size = 0; inode->i_size = 0;
if (MSDOS_I(inode)->i_start == 0) if (MSDOS_I(inode)->i_start == 0)
return 0; return 0;
nr = MSDOS_I(inode)->i_start; ret = fat_get_cluster(inode, FAT_ENT_EOF, &fclus, &dclus);
do { if (ret < 0)
inode->i_size += 1 << MSDOS_SB(sb)->cluster_bits; return ret;
nr = fat_access(sb, nr, -1); inode->i_size = (fclus + 1) << sbi->cluster_bits;
if (nr < 0)
return nr;
else if (nr == FAT_ENT_FREE) {
fat_fs_panic(sb, "Directory %lu: invalid cluster chain",
inode->i_ino);
return -EIO;
}
if (inode->i_size > FAT_MAX_DIR_SIZE) {
fat_fs_panic(sb, "Directory %lu: "
"exceeded the maximum size of directory",
inode->i_ino);
inode->i_size = FAT_MAX_DIR_SIZE;
break;
}
} while (nr != FAT_ENT_EOF);
return 0; return 0;
} }
......
...@@ -88,41 +88,25 @@ void fat_clusters_flush(struct super_block *sb) ...@@ -88,41 +88,25 @@ 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;
int count, nr, limit, last, curr, file_cluster; int count, limit, new_dclus, new_fclus, last;
int cluster_bits = MSDOS_SB(sb)->cluster_bits; int cluster_bits = MSDOS_SB(sb)->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
* one (nr) to the end of the link list (the FAT). * one (new_dclus) to the end of the link list (the FAT).
* *
* In order to confirm that the cluster chain is valid, we * In order to confirm that the cluster chain is valid, we
* find out EOF first. * find out EOF first.
*/ */
nr = -EIO; last = new_fclus = 0;
last = file_cluster = 0; if (MSDOS_I(inode)->i_start) {
if ((curr = MSDOS_I(inode)->i_start) != 0) { int ret, fclus, dclus;
int max_cluster = MSDOS_I(inode)->mmu_private >> cluster_bits;
ret = fat_get_cluster(inode, FAT_ENT_EOF, &fclus, &dclus);
fat_cache_lookup(inode, INT_MAX, &last, &curr); if (ret < 0)
file_cluster = last; return ret;
while (curr && curr != FAT_ENT_EOF) { new_fclus = fclus + 1;
file_cluster++; last = dclus;
curr = fat_access(sb, last = curr, -1);
if (curr < 0)
return curr;
else if (curr == FAT_ENT_FREE) {
fat_fs_panic(sb, "%s: invalid cluster chain"
" (ino %lu)",
__FUNCTION__, inode->i_ino);
goto out;
}
if (file_cluster > max_cluster) {
fat_fs_panic(sb, "%s: bad cluster counts"
" (ino %lu)",
__FUNCTION__, inode->i_ino);
goto out;
}
}
} }
/* find free FAT entry */ /* find free FAT entry */
...@@ -134,12 +118,12 @@ int fat_add_cluster(struct inode *inode) ...@@ -134,12 +118,12 @@ int fat_add_cluster(struct inode *inode)
} }
limit = MSDOS_SB(sb)->clusters + 2; limit = MSDOS_SB(sb)->clusters + 2;
nr = MSDOS_SB(sb)->prev_free + 1; new_dclus = MSDOS_SB(sb)->prev_free + 1;
for (count = 0; count < MSDOS_SB(sb)->clusters; count++, nr++) { for (count = 0; count < MSDOS_SB(sb)->clusters; count++, new_dclus++) {
nr = nr % limit; new_dclus = new_dclus % limit;
if (nr < 2) if (new_dclus < 2)
nr = 2; new_dclus = 2;
if (fat_access(sb, nr, -1) == FAT_ENT_FREE) if (fat_access(sb, new_dclus, -1) == FAT_ENT_FREE)
break; break;
} }
if (count >= MSDOS_SB(sb)->clusters) { if (count >= MSDOS_SB(sb)->clusters) {
...@@ -147,9 +131,9 @@ int fat_add_cluster(struct inode *inode) ...@@ -147,9 +131,9 @@ int fat_add_cluster(struct inode *inode)
unlock_fat(sb); unlock_fat(sb);
return -ENOSPC; return -ENOSPC;
} }
MSDOS_SB(sb)->prev_free = nr; MSDOS_SB(sb)->prev_free = new_dclus;
fat_access(sb, nr, FAT_ENT_EOF); fat_access(sb, new_dclus, FAT_ENT_EOF);
if (MSDOS_SB(sb)->free_clusters != -1) if (MSDOS_SB(sb)->free_clusters != -1)
MSDOS_SB(sb)->free_clusters--; MSDOS_SB(sb)->free_clusters--;
fat_clusters_flush(sb); fat_clusters_flush(sb);
...@@ -158,22 +142,21 @@ int fat_add_cluster(struct inode *inode) ...@@ -158,22 +142,21 @@ int fat_add_cluster(struct inode *inode)
/* add new one to the last of the cluster chain */ /* add new one to the last of the cluster chain */
if (last) { if (last) {
fat_access(sb, last, nr); fat_access(sb, last, new_dclus);
fat_cache_add(inode, file_cluster, nr); fat_cache_add(inode, new_fclus, new_dclus);
} else { } else {
MSDOS_I(inode)->i_start = nr; MSDOS_I(inode)->i_start = new_dclus;
MSDOS_I(inode)->i_logstart = nr; MSDOS_I(inode)->i_logstart = new_dclus;
mark_inode_dirty(inode); mark_inode_dirty(inode);
} }
if (file_cluster != (inode->i_blocks >> (cluster_bits - 9))) { if (new_fclus != (inode->i_blocks >> (cluster_bits - 9))) {
printk (KERN_ERR "file_cluster badly computed!!! %d <> %ld\n", fat_fs_panic(sb, "clusters badly computed (%d != %ld)",
file_cluster, 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 += (1 << cluster_bits) >> 9; inode->i_blocks += (1 << cluster_bits) >> 9;
out: return new_dclus;
return nr;
} }
struct buffer_head *fat_extend_dir(struct inode *inode) struct buffer_head *fat_extend_dir(struct inode *inode)
......
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