fat: introduce special inode for managing the FSINFO block
authorArtem Bityutskiy <artem.bityutskiy@linux.intel.com>
Thu, 31 May 2012 23:26:12 +0000 (16:26 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 1 Jun 2012 00:49:27 +0000 (17:49 -0700)
This is patchset makes fatfs stop using the VFS '->write_super()' method
for writing out the FSINFO block.

The final goal is to get rid of the 'sync_supers()' kernel thread.  This
kernel thread wakes up every 5 seconds (by default) and calls
'->write_super()' for all mounted file-systems.  And the bad thing is that
this is done even if all the superblocks are clean.  Moreover, some
file-systems do not even need this end they do not register the
'->write_super()' method at all (e.g., btrfs).

So 'sync_supers()' most often just generates useless wake-ups and wastes
power.  I am trying to make all file-systems independent of
'->write_super()' and plan to remove 'sync_supers()' and '->write_super'
completely once there are no more users.

The '->write_supers()' method is mostly used by baroque file-systems like
hfs, udf, etc.  Modern file-systems like btrfs and xfs do not use it.
This justifies removing this stuff from VFS completely and make every FS
self-manage own superblock.

Tested with xfstests.

This patch:

Preparation for further changes.  It introduces a special inode
('fsinfo_inode') in FAT file-system which we'll later use for managing the
FSINFO block.  Note, this there is already one special inode ('fat_inode')
which is used for managing the FAT tables.

Introduce new 'MSDOS_FSINFO_INO' constant for this special inode.  It is
safe to do because FAT file-system does not store inode numbers on the
media but generates them run-time.

I've also cleaned up the comment to existing 'MSDOS_ROOT_INO' constant,
while on it.

Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Cc: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
fs/fat/fat.h
fs/fat/inode.c
include/linux/msdos_fs.h

index 66994f316e18d11f052c85b97922cc1407347a70..951d12b61b588863374f553bb74f8beda5ee83f7 100644 (file)
@@ -82,6 +82,7 @@ struct msdos_sb_info {
        int fatent_shift;
        struct fatent_operations *fatent_ops;
        struct inode *fat_inode;
+       struct inode *fsinfo_inode;
 
        struct ratelimit_state ratelimit;
 
index b3d290c1b51392ac949bdf8e00514e29e29bd2e9..84c602b4bb25a8a5d5698b426d2e32122c212530 100644 (file)
@@ -490,6 +490,7 @@ static void fat_put_super(struct super_block *sb)
        if (sb->s_dirt)
                fat_write_super(sb);
 
+       iput(sbi->fsinfo_inode);
        iput(sbi->fat_inode);
 
        unload_nls(sbi->nls_disk);
@@ -1244,6 +1245,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
                   void (*setup)(struct super_block *))
 {
        struct inode *root_inode = NULL, *fat_inode = NULL;
+       struct inode *fsinfo_inode = NULL;
        struct buffer_head *bh;
        struct fat_boot_sector *b;
        struct msdos_sb_info *sbi;
@@ -1490,6 +1492,14 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
                goto out_fail;
        MSDOS_I(fat_inode)->i_pos = 0;
        sbi->fat_inode = fat_inode;
+
+       fsinfo_inode = new_inode(sb);
+       if (!fsinfo_inode)
+               goto out_fail;
+       fsinfo_inode->i_ino = MSDOS_FSINFO_INO;
+       sbi->fsinfo_inode = fsinfo_inode;
+       insert_inode_hash(fsinfo_inode);
+
        root_inode = new_inode(sb);
        if (!root_inode)
                goto out_fail;
@@ -1516,6 +1526,8 @@ out_invalid:
                fat_msg(sb, KERN_INFO, "Can't find a valid FAT filesystem");
 
 out_fail:
+       if (fsinfo_inode)
+               iput(fsinfo_inode);
        if (fat_inode)
                iput(fat_inode);
        unload_nls(sbi->nls_io);
index 34066e65fdeb327b4da8e0fd58e4dc143d985fc4..11cc2ac67e756af2b633a8badabcc49f4ffe8cb7 100644 (file)
@@ -21,8 +21,9 @@
 #define CT_LE_W(v)     cpu_to_le16(v)
 #define CT_LE_L(v)     cpu_to_le32(v)
 
+#define MSDOS_ROOT_INO  1      /* The root inode number */
+#define MSDOS_FSINFO_INO 2     /* Used for managing the FSINFO block */
 
-#define MSDOS_ROOT_INO 1       /* == MINIX_ROOT_INO */
 #define MSDOS_DIR_BITS 5       /* log2(sizeof(struct msdos_dir_entry)) */
 
 /* directory limit */