aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fat
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fat')
-rw-r--r--fs/fat/dir.c4
-rw-r--r--fs/fat/fat.h6
-rw-r--r--fs/fat/fatent.c21
-rw-r--r--fs/fat/inode.c54
4 files changed, 48 insertions, 37 deletions
diff --git a/fs/fat/dir.c b/fs/fat/dir.c
index aca191bd5f8f..6eaa28c98ad1 100644
--- a/fs/fat/dir.c
+++ b/fs/fat/dir.c
@@ -98,8 +98,8 @@ next:
98 98
99 *bh = sb_bread(sb, phys); 99 *bh = sb_bread(sb, phys);
100 if (*bh == NULL) { 100 if (*bh == NULL) {
101 fat_msg(sb, KERN_ERR, "Directory bread(block %llu) failed", 101 fat_msg_ratelimit(sb, KERN_ERR,
102 (llu)phys); 102 "Directory bread(block %llu) failed", (llu)phys);
103 /* skip this block */ 103 /* skip this block */
104 *pos = (iblock + 1) << sb->s_blocksize_bits; 104 *pos = (iblock + 1) << sb->s_blocksize_bits;
105 goto next; 105 goto next;
diff --git a/fs/fat/fat.h b/fs/fat/fat.h
index 66994f316e18..fc35c5c69136 100644
--- a/fs/fat/fat.h
+++ b/fs/fat/fat.h
@@ -82,6 +82,7 @@ struct msdos_sb_info {
82 int fatent_shift; 82 int fatent_shift;
83 struct fatent_operations *fatent_ops; 83 struct fatent_operations *fatent_ops;
84 struct inode *fat_inode; 84 struct inode *fat_inode;
85 struct inode *fsinfo_inode;
85 86
86 struct ratelimit_state ratelimit; 87 struct ratelimit_state ratelimit;
87 88
@@ -334,6 +335,11 @@ void __fat_fs_error(struct super_block *sb, int report, const char *fmt, ...);
334 __fat_fs_error(sb, __ratelimit(&MSDOS_SB(sb)->ratelimit), fmt , ## args) 335 __fat_fs_error(sb, __ratelimit(&MSDOS_SB(sb)->ratelimit), fmt , ## args)
335__printf(3, 4) __cold 336__printf(3, 4) __cold
336void fat_msg(struct super_block *sb, const char *level, const char *fmt, ...); 337void fat_msg(struct super_block *sb, const char *level, const char *fmt, ...);
338#define fat_msg_ratelimit(sb, level, fmt, args...) \
339 do { \
340 if (__ratelimit(&MSDOS_SB(sb)->ratelimit)) \
341 fat_msg(sb, level, fmt, ## args); \
342 } while (0)
337extern int fat_clusters_flush(struct super_block *sb); 343extern int fat_clusters_flush(struct super_block *sb);
338extern int fat_chain_add(struct inode *inode, int new_dclus, int nr_cluster); 344extern int fat_chain_add(struct inode *inode, int new_dclus, int nr_cluster);
339extern void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec *ts, 345extern void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec *ts,
diff --git a/fs/fat/fatent.c b/fs/fat/fatent.c
index 2e81ac0df7e2..31f08ab62c56 100644
--- a/fs/fat/fatent.c
+++ b/fs/fat/fatent.c
@@ -308,6 +308,16 @@ void fat_ent_access_init(struct super_block *sb)
308 } 308 }
309} 309}
310 310
311static void mark_fsinfo_dirty(struct super_block *sb)
312{
313 struct msdos_sb_info *sbi = MSDOS_SB(sb);
314
315 if (sb->s_flags & MS_RDONLY || sbi->fat_bits != 32)
316 return;
317
318 __mark_inode_dirty(sbi->fsinfo_inode, I_DIRTY_SYNC);
319}
320
311static inline int fat_ent_update_ptr(struct super_block *sb, 321static inline int fat_ent_update_ptr(struct super_block *sb,
312 struct fat_entry *fatent, 322 struct fat_entry *fatent,
313 int offset, sector_t blocknr) 323 int offset, sector_t blocknr)
@@ -498,7 +508,6 @@ int fat_alloc_clusters(struct inode *inode, int *cluster, int nr_cluster)
498 sbi->prev_free = entry; 508 sbi->prev_free = entry;
499 if (sbi->free_clusters != -1) 509 if (sbi->free_clusters != -1)
500 sbi->free_clusters--; 510 sbi->free_clusters--;
501 sb->s_dirt = 1;
502 511
503 cluster[idx_clus] = entry; 512 cluster[idx_clus] = entry;
504 idx_clus++; 513 idx_clus++;
@@ -520,11 +529,11 @@ int fat_alloc_clusters(struct inode *inode, int *cluster, int nr_cluster)
520 /* Couldn't allocate the free entries */ 529 /* Couldn't allocate the free entries */
521 sbi->free_clusters = 0; 530 sbi->free_clusters = 0;
522 sbi->free_clus_valid = 1; 531 sbi->free_clus_valid = 1;
523 sb->s_dirt = 1;
524 err = -ENOSPC; 532 err = -ENOSPC;
525 533
526out: 534out:
527 unlock_fat(sbi); 535 unlock_fat(sbi);
536 mark_fsinfo_dirty(sb);
528 fatent_brelse(&fatent); 537 fatent_brelse(&fatent);
529 if (!err) { 538 if (!err) {
530 if (inode_needs_sync(inode)) 539 if (inode_needs_sync(inode))
@@ -549,7 +558,7 @@ int fat_free_clusters(struct inode *inode, int cluster)
549 struct fat_entry fatent; 558 struct fat_entry fatent;
550 struct buffer_head *bhs[MAX_BUF_PER_PAGE]; 559 struct buffer_head *bhs[MAX_BUF_PER_PAGE];
551 int i, err, nr_bhs; 560 int i, err, nr_bhs;
552 int first_cl = cluster; 561 int first_cl = cluster, dirty_fsinfo = 0;
553 562
554 nr_bhs = 0; 563 nr_bhs = 0;
555 fatent_init(&fatent); 564 fatent_init(&fatent);
@@ -587,7 +596,7 @@ int fat_free_clusters(struct inode *inode, int cluster)
587 ops->ent_put(&fatent, FAT_ENT_FREE); 596 ops->ent_put(&fatent, FAT_ENT_FREE);
588 if (sbi->free_clusters != -1) { 597 if (sbi->free_clusters != -1) {
589 sbi->free_clusters++; 598 sbi->free_clusters++;
590 sb->s_dirt = 1; 599 dirty_fsinfo = 1;
591 } 600 }
592 601
593 if (nr_bhs + fatent.nr_bhs > MAX_BUF_PER_PAGE) { 602 if (nr_bhs + fatent.nr_bhs > MAX_BUF_PER_PAGE) {
@@ -617,6 +626,8 @@ error:
617 for (i = 0; i < nr_bhs; i++) 626 for (i = 0; i < nr_bhs; i++)
618 brelse(bhs[i]); 627 brelse(bhs[i]);
619 unlock_fat(sbi); 628 unlock_fat(sbi);
629 if (dirty_fsinfo)
630 mark_fsinfo_dirty(sb);
620 631
621 return err; 632 return err;
622} 633}
@@ -677,7 +688,7 @@ int fat_count_free_clusters(struct super_block *sb)
677 } 688 }
678 sbi->free_clusters = free; 689 sbi->free_clusters = free;
679 sbi->free_clus_valid = 1; 690 sbi->free_clus_valid = 1;
680 sb->s_dirt = 1; 691 mark_fsinfo_dirty(sb);
681 fatent_brelse(&fatent); 692 fatent_brelse(&fatent);
682out: 693out:
683 unlock_fat(sbi); 694 unlock_fat(sbi);
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 7edfaadc0787..a3d81ebf6d86 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -459,37 +459,11 @@ static void fat_evict_inode(struct inode *inode)
459 fat_detach(inode); 459 fat_detach(inode);
460} 460}
461 461
462static void fat_write_super(struct super_block *sb)
463{
464 lock_super(sb);
465 sb->s_dirt = 0;
466
467 if (!(sb->s_flags & MS_RDONLY))
468 fat_clusters_flush(sb);
469 unlock_super(sb);
470}
471
472static int fat_sync_fs(struct super_block *sb, int wait)
473{
474 int err = 0;
475
476 if (sb->s_dirt) {
477 lock_super(sb);
478 sb->s_dirt = 0;
479 err = fat_clusters_flush(sb);
480 unlock_super(sb);
481 }
482
483 return err;
484}
485
486static void fat_put_super(struct super_block *sb) 462static void fat_put_super(struct super_block *sb)
487{ 463{
488 struct msdos_sb_info *sbi = MSDOS_SB(sb); 464 struct msdos_sb_info *sbi = MSDOS_SB(sb);
489 465
490 if (sb->s_dirt) 466 iput(sbi->fsinfo_inode);
491 fat_write_super(sb);
492
493 iput(sbi->fat_inode); 467 iput(sbi->fat_inode);
494 468
495 unload_nls(sbi->nls_disk); 469 unload_nls(sbi->nls_disk);
@@ -661,7 +635,18 @@ retry:
661 635
662static int fat_write_inode(struct inode *inode, struct writeback_control *wbc) 636static int fat_write_inode(struct inode *inode, struct writeback_control *wbc)
663{ 637{
664 return __fat_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL); 638 int err;
639
640 if (inode->i_ino == MSDOS_FSINFO_INO) {
641 struct super_block *sb = inode->i_sb;
642
643 lock_super(sb);
644 err = fat_clusters_flush(sb);
645 unlock_super(sb);
646 } else
647 err = __fat_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
648
649 return err;
665} 650}
666 651
667int fat_sync_inode(struct inode *inode) 652int fat_sync_inode(struct inode *inode)
@@ -678,8 +663,6 @@ static const struct super_operations fat_sops = {
678 .write_inode = fat_write_inode, 663 .write_inode = fat_write_inode,
679 .evict_inode = fat_evict_inode, 664 .evict_inode = fat_evict_inode,
680 .put_super = fat_put_super, 665 .put_super = fat_put_super,
681 .write_super = fat_write_super,
682 .sync_fs = fat_sync_fs,
683 .statfs = fat_statfs, 666 .statfs = fat_statfs,
684 .remount_fs = fat_remount, 667 .remount_fs = fat_remount,
685 668
@@ -1243,6 +1226,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
1243 void (*setup)(struct super_block *)) 1226 void (*setup)(struct super_block *))
1244{ 1227{
1245 struct inode *root_inode = NULL, *fat_inode = NULL; 1228 struct inode *root_inode = NULL, *fat_inode = NULL;
1229 struct inode *fsinfo_inode = NULL;
1246 struct buffer_head *bh; 1230 struct buffer_head *bh;
1247 struct fat_boot_sector *b; 1231 struct fat_boot_sector *b;
1248 struct msdos_sb_info *sbi; 1232 struct msdos_sb_info *sbi;
@@ -1489,6 +1473,14 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
1489 goto out_fail; 1473 goto out_fail;
1490 MSDOS_I(fat_inode)->i_pos = 0; 1474 MSDOS_I(fat_inode)->i_pos = 0;
1491 sbi->fat_inode = fat_inode; 1475 sbi->fat_inode = fat_inode;
1476
1477 fsinfo_inode = new_inode(sb);
1478 if (!fsinfo_inode)
1479 goto out_fail;
1480 fsinfo_inode->i_ino = MSDOS_FSINFO_INO;
1481 sbi->fsinfo_inode = fsinfo_inode;
1482 insert_inode_hash(fsinfo_inode);
1483
1492 root_inode = new_inode(sb); 1484 root_inode = new_inode(sb);
1493 if (!root_inode) 1485 if (!root_inode)
1494 goto out_fail; 1486 goto out_fail;
@@ -1515,6 +1507,8 @@ out_invalid:
1515 fat_msg(sb, KERN_INFO, "Can't find a valid FAT filesystem"); 1507 fat_msg(sb, KERN_INFO, "Can't find a valid FAT filesystem");
1516 1508
1517out_fail: 1509out_fail:
1510 if (fsinfo_inode)
1511 iput(fsinfo_inode);
1518 if (fat_inode) 1512 if (fat_inode)
1519 iput(fat_inode); 1513 iput(fat_inode);
1520 unload_nls(sbi->nls_io); 1514 unload_nls(sbi->nls_io);