aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fat/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fat/inode.c')
-rw-r--r--fs/fat/inode.c63
1 files changed, 28 insertions, 35 deletions
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index b3d290c1b513..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
@@ -752,10 +735,9 @@ static struct dentry *fat_fh_to_dentry(struct super_block *sb,
752} 735}
753 736
754static int 737static int
755fat_encode_fh(struct dentry *de, __u32 *fh, int *lenp, int connectable) 738fat_encode_fh(struct inode *inode, __u32 *fh, int *lenp, struct inode *parent)
756{ 739{
757 int len = *lenp; 740 int len = *lenp;
758 struct inode *inode = de->d_inode;
759 u32 ipos_h, ipos_m, ipos_l; 741 u32 ipos_h, ipos_m, ipos_l;
760 742
761 if (len < 5) { 743 if (len < 5) {
@@ -771,9 +753,9 @@ fat_encode_fh(struct dentry *de, __u32 *fh, int *lenp, int connectable)
771 fh[1] = inode->i_generation; 753 fh[1] = inode->i_generation;
772 fh[2] = ipos_h; 754 fh[2] = ipos_h;
773 fh[3] = ipos_m | MSDOS_I(inode)->i_logstart; 755 fh[3] = ipos_m | MSDOS_I(inode)->i_logstart;
774 spin_lock(&de->d_lock); 756 fh[4] = ipos_l;
775 fh[4] = ipos_l | MSDOS_I(de->d_parent->d_inode)->i_logstart; 757 if (parent)
776 spin_unlock(&de->d_lock); 758 fh[4] |= MSDOS_I(parent)->i_logstart;
777 return 3; 759 return 3;
778} 760}
779 761
@@ -1244,6 +1226,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
1244 void (*setup)(struct super_block *)) 1226 void (*setup)(struct super_block *))
1245{ 1227{
1246 struct inode *root_inode = NULL, *fat_inode = NULL; 1228 struct inode *root_inode = NULL, *fat_inode = NULL;
1229 struct inode *fsinfo_inode = NULL;
1247 struct buffer_head *bh; 1230 struct buffer_head *bh;
1248 struct fat_boot_sector *b; 1231 struct fat_boot_sector *b;
1249 struct msdos_sb_info *sbi; 1232 struct msdos_sb_info *sbi;
@@ -1490,6 +1473,14 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
1490 goto out_fail; 1473 goto out_fail;
1491 MSDOS_I(fat_inode)->i_pos = 0; 1474 MSDOS_I(fat_inode)->i_pos = 0;
1492 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
1493 root_inode = new_inode(sb); 1484 root_inode = new_inode(sb);
1494 if (!root_inode) 1485 if (!root_inode)
1495 goto out_fail; 1486 goto out_fail;
@@ -1516,6 +1507,8 @@ out_invalid:
1516 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");
1517 1508
1518out_fail: 1509out_fail:
1510 if (fsinfo_inode)
1511 iput(fsinfo_inode);
1519 if (fat_inode) 1512 if (fat_inode)
1520 iput(fat_inode); 1513 iput(fat_inode);
1521 unload_nls(sbi->nls_io); 1514 unload_nls(sbi->nls_io);