6 #include <linux/module.h>
8 #include <linux/msdos_fs.h>
28 int bytes = entry + (entry >> 1);
46 struct buffer_head **bhs = fatent->
bhs;
48 WARN_ON(offset >= (bhs[0]->b_size - 1));
50 fatent->
u.
ent12_p[1] = bhs[0]->b_data + (offset + 1);
52 WARN_ON(offset != (bhs[0]->b_size - 1));
54 fatent->
u.
ent12_p[1] = bhs[1]->b_data;
58 static void fat16_ent_set_ptr(
struct fat_entry *fatent,
int offset)
64 static void fat32_ent_set_ptr(
struct fat_entry *fatent,
int offset)
73 struct buffer_head **bhs = fatent->
bhs;
75 WARN_ON(blocknr < MSDOS_SB(sb)->fat_start);
76 fatent->
fat_inode = MSDOS_SB(sb)->fat_inode;
78 bhs[0] = sb_bread(sb, blocknr);
87 bhs[1] = sb_bread(sb, blocknr);
92 fat12_ent_set_ptr(fatent, offset);
107 WARN_ON(blocknr < MSDOS_SB(sb)->fat_start);
108 fatent->
fat_inode = MSDOS_SB(sb)->fat_inode;
109 fatent->
bhs[0] = sb_bread(sb, blocknr);
110 if (!fatent->
bhs[0]) {
120 static int fat12_ent_get(
struct fat_entry *fatent)
125 spin_lock(&fat12_entry_lock);
126 if (fatent->
entry & 1)
127 next = (*ent12_p[0] >> 4) | (*ent12_p[1] << 4);
129 next = (*ent12_p[1] << 8) | *ent12_p[0];
130 spin_unlock(&fat12_entry_lock);
138 static int fat16_ent_get(
struct fat_entry *fatent)
147 static int fat32_ent_get(
struct fat_entry *fatent)
156 static void fat12_ent_put(
struct fat_entry *fatent,
int new)
163 spin_lock(&fat12_entry_lock);
164 if (fatent->
entry & 1) {
165 *ent12_p[0] = (
new << 4) | (*ent12_p[0] & 0x0f);
166 *ent12_p[1] =
new >> 4;
168 *ent12_p[0] =
new & 0xff;
169 *ent12_p[1] = (*ent12_p[1] & 0xf0) | (
new >> 8);
171 spin_unlock(&fat12_entry_lock);
178 static void fat16_ent_put(
struct fat_entry *fatent,
int new)
187 static void fat32_ent_put(
struct fat_entry *fatent,
int new)
195 static int fat12_ent_next(
struct fat_entry *fatent)
198 struct buffer_head **bhs = fatent->
bhs;
202 if (fatent->
nr_bhs == 1) {
203 WARN_ON(ent12_p[0] > (
u8 *)(bhs[0]->b_data +
204 (bhs[0]->b_size - 2)));
205 WARN_ON(ent12_p[1] > (
u8 *)(bhs[0]->b_data +
206 (bhs[0]->b_size - 1)));
207 if (nextp < (
u8 *)(bhs[0]->b_data + (bhs[0]->b_size - 1))) {
208 ent12_p[0] = nextp - 1;
213 WARN_ON(ent12_p[0] != (
u8 *)(bhs[0]->b_data +
214 (bhs[0]->b_size - 1)));
215 WARN_ON(ent12_p[1] != (
u8 *)bhs[1]->b_data);
216 ent12_p[0] = nextp - 1;
228 static int fat16_ent_next(
struct fat_entry *fatent)
230 const struct buffer_head *bh = fatent->
bhs[0];
232 if (fatent->
u.
ent16_p < (
__le16 *)(bh->b_data + (bh->b_size - 2))) {
240 static int fat32_ent_next(
struct fat_entry *fatent)
242 const struct buffer_head *bh = fatent->
bhs[0];
244 if (fatent->
u.
ent32_p < (
__le32 *)(bh->b_data + (bh->b_size - 4))) {
253 .ent_blocknr = fat12_ent_blocknr,
254 .ent_set_ptr = fat12_ent_set_ptr,
255 .ent_bread = fat12_ent_bread,
256 .ent_get = fat12_ent_get,
257 .ent_put = fat12_ent_put,
258 .ent_next = fat12_ent_next,
262 .ent_blocknr = fat_ent_blocknr,
263 .ent_set_ptr = fat16_ent_set_ptr,
264 .ent_bread = fat_ent_bread,
265 .ent_get = fat16_ent_get,
266 .ent_put = fat16_ent_put,
267 .ent_next = fat16_ent_next,
271 .ent_blocknr = fat_ent_blocknr,
272 .ent_set_ptr = fat32_ent_set_ptr,
273 .ent_bread = fat_ent_bread,
274 .ent_get = fat32_ent_get,
275 .ent_put = fat32_ent_put,
276 .ent_next = fat32_ent_next,
311 static void mark_fsinfo_dirty(
struct super_block *sb)
321 static inline int fat_ent_update_ptr(
struct super_block *sb,
327 struct buffer_head **bhs = fatent->
bhs;
330 if (!fatent->
nr_bhs || bhs[0]->b_blocknr != blocknr)
335 if (fatent->
nr_bhs == 2) {
343 if (bhs[1]->b_blocknr != (blocknr + 1))
360 fatent_brelse(fatent);
361 fat_fs_error(sb,
"invalid access to FAT (entry 0x%08x)", entry);
365 fatent_set_entry(fatent, entry);
368 if (!fat_ent_update_ptr(sb, fatent, offset, blocknr)) {
369 fatent_brelse(fatent);
370 err = ops->
ent_bread(sb, fatent, offset, blocknr);
378 static int fat_mirror_bhs(
struct super_block *sb,
struct buffer_head **bhs,
382 struct buffer_head *c_bh;
386 for (copy = 1; copy < sbi->
fats; copy++) {
389 for (n = 0; n < nr_bhs; n++) {
390 c_bh = sb_getblk(sb, backup_fat + bhs[n]->b_blocknr);
396 set_buffer_uptodate(c_bh);
422 return fat_mirror_bhs(sb, fatent->
bhs, fatent->
nr_bhs);
435 static inline int fat_ent_read_block(
struct super_block *sb,
442 fatent_brelse(fatent);
444 return ops->
ent_bread(sb, fatent, offset, blocknr);
447 static void fat_collect_bhs(
struct buffer_head **bhs,
int *nr_bhs,
452 for (n = 0; n < fatent->
nr_bhs; n++) {
453 for (i = 0; i < *nr_bhs; i++) {
454 if (fatent->
bhs[n] == bhs[i])
458 get_bh(fatent->
bhs[n]);
459 bhs[
i] = fatent->
bhs[
n];
471 struct buffer_head *bhs[MAX_BUF_PER_PAGE];
474 BUG_ON(nr_cluster > (MAX_BUF_PER_PAGE / 2));
483 err = nr_bhs = idx_clus = 0;
485 fatent_init(&prev_ent);
486 fatent_init(&fatent);
487 fatent_set_entry(&fatent, sbi->
prev_free + 1);
488 while (count < sbi->max_cluster) {
491 fatent_set_entry(&fatent, fatent.
entry);
492 err = fat_ent_read_block(sb, &fatent);
504 ops->
ent_put(&prev_ent, entry);
506 fat_collect_bhs(bhs, &nr_bhs, &fatent);
512 cluster[idx_clus] =
entry;
514 if (idx_clus == nr_cluster)
526 }
while (fat_ent_next(sbi, &fatent));
536 mark_fsinfo_dirty(sb);
537 fatent_brelse(&fatent);
542 err = fat_mirror_bhs(sb, bhs, nr_bhs);
544 for (i = 0; i < nr_bhs; i++)
559 struct buffer_head *bhs[MAX_BUF_PER_PAGE];
561 int first_cl =
cluster, dirty_fsinfo = 0;
564 fatent_init(&fatent);
584 if (cluster != fatent.
entry + 1) {
585 int nr_clus = fatent.
entry - first_cl + 1;
588 fat_clus_to_blknr(sbi, first_cl),
602 if (nr_bhs + fatent.
nr_bhs > MAX_BUF_PER_PAGE) {
608 err = fat_mirror_bhs(sb, bhs, nr_bhs);
611 for (i = 0; i < nr_bhs; i++)
615 fat_collect_bhs(bhs, &nr_bhs, &fatent);
623 err = fat_mirror_bhs(sb, bhs, nr_bhs);
625 fatent_brelse(&fatent);
626 for (i = 0; i < nr_bhs; i++)
630 mark_fsinfo_dirty(sb);
637 #define FAT_READA_SIZE (128 * 1024)
640 unsigned long reada_blocks)
648 for (i = 0; i < reada_blocks; i++)
649 sb_breadahead(sb, blocknr + i);
657 unsigned long reada_blocks, reada_mask, cur_block;
665 reada_mask = reada_blocks - 1;
669 fatent_init(&fatent);
673 if ((cur_block & reada_mask) == 0) {
675 fat_ent_reada(sb, &fatent,
min(reada_blocks, rest));
679 err = fat_ent_read_block(sb, &fatent);
686 }
while (fat_ent_next(sbi, &fatent));
690 mark_fsinfo_dirty(sb);
691 fatent_brelse(&fatent);