Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fat: introduce special inode for managing the FSINFO block

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>

authored by

Artem Bityutskiy and committed by
Linus Torvalds
020ac5b6 7bc1bac7

+15 -1
+1
fs/fat/fat.h
··· 82 82 int fatent_shift; 83 83 struct fatent_operations *fatent_ops; 84 84 struct inode *fat_inode; 85 + struct inode *fsinfo_inode; 85 86 86 87 struct ratelimit_state ratelimit; 87 88
+12
fs/fat/inode.c
··· 490 490 if (sb->s_dirt) 491 491 fat_write_super(sb); 492 492 493 + iput(sbi->fsinfo_inode); 493 494 iput(sbi->fat_inode); 494 495 495 496 unload_nls(sbi->nls_disk); ··· 1245 1244 void (*setup)(struct super_block *)) 1246 1245 { 1247 1246 struct inode *root_inode = NULL, *fat_inode = NULL; 1247 + struct inode *fsinfo_inode = NULL; 1248 1248 struct buffer_head *bh; 1249 1249 struct fat_boot_sector *b; 1250 1250 struct msdos_sb_info *sbi; ··· 1492 1490 goto out_fail; 1493 1491 MSDOS_I(fat_inode)->i_pos = 0; 1494 1492 sbi->fat_inode = fat_inode; 1493 + 1494 + fsinfo_inode = new_inode(sb); 1495 + if (!fsinfo_inode) 1496 + goto out_fail; 1497 + fsinfo_inode->i_ino = MSDOS_FSINFO_INO; 1498 + sbi->fsinfo_inode = fsinfo_inode; 1499 + insert_inode_hash(fsinfo_inode); 1500 + 1495 1501 root_inode = new_inode(sb); 1496 1502 if (!root_inode) 1497 1503 goto out_fail; ··· 1526 1516 fat_msg(sb, KERN_INFO, "Can't find a valid FAT filesystem"); 1527 1517 1528 1518 out_fail: 1519 + if (fsinfo_inode) 1520 + iput(fsinfo_inode); 1529 1521 if (fat_inode) 1530 1522 iput(fat_inode); 1531 1523 unload_nls(sbi->nls_io);
+2 -1
include/linux/msdos_fs.h
··· 21 21 #define CT_LE_W(v) cpu_to_le16(v) 22 22 #define CT_LE_L(v) cpu_to_le32(v) 23 23 24 + #define MSDOS_ROOT_INO 1 /* The root inode number */ 25 + #define MSDOS_FSINFO_INO 2 /* Used for managing the FSINFO block */ 24 26 25 - #define MSDOS_ROOT_INO 1 /* == MINIX_ROOT_INO */ 26 27 #define MSDOS_DIR_BITS 5 /* log2(sizeof(struct msdos_dir_entry)) */ 27 28 28 29 /* directory limit */