diff -drupN a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c --- a/fs/fat/namei_vfat.c 2018-08-06 17:23:04.000000000 +0300 +++ b/fs/fat/namei_vfat.c 2022-06-12 05:28:14.000000000 +0300 @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include "fat.h" static inline unsigned long vfat_d_version(struct dentry *dentry) @@ -1077,11 +1079,71 @@ static struct dentry *vfat_mount(struct return mount_bdev(fs_type, flags, dev_name, data, vfat_fill_super); } +#ifdef CONFIG_FAT_READ_FAT_DIR_SUNXI +void sunxi_vfat_kill_block_super(struct super_block *sb) +{ + int i; + struct msdos_sb_info *sbi = sb->s_fs_info; + struct buffer_head *fat_bh; + struct buffer_head *dir_bh; + struct buffer_head *fsinfo_bh; + + +/* + printk("%s,%d,na %s\n",__FUNCTION__, __LINE__, sb->s_bdev->bd_disk->disk_name); + if(strncmp(sb->s_bdev->bd_disk->disk_name, "mmcblk0", 7) != 0) + goto out; +*/ + if (!sbi) { + printk("no sbi\n"); + goto out; + } + printk("kill:fat start %ld,fat len %ld\n", sbi->fat_start, sbi->fat_length); + for (i = sbi->fat_start; i < (sbi->fat_start+sbi->fat_length); i++) { + fat_bh = __find_get_block(sb->s_bdev, i, sb->s_blocksize); + if (!fat_bh) { + //fat_msg(sb, KERN_WARNING, "kill free:%s,%d can't find fat bh %d\n", __FUNCTION__, __LINE__ , i); + continue; + } + + brelse(fat_bh); + brelse(fat_bh); + } + printk("Relase fat\n"); + + for (i = sbi->dir_start; i <= (sbi->dir_start + 0x1ff); i++) { + dir_bh = __find_get_block(sb->s_bdev, i, sb->s_blocksize); + if (!dir_bh) { + //fat_msg(sb, KERN_WARNING, "kill free:%s,%d can't find fat dir bh %d\n", __FUNCTION__, __LINE__, i); + continue; + } + + brelse(dir_bh); + brelse(dir_bh); + } + printk("Release fat dir\n"); + + fsinfo_bh = __find_get_block(sb->s_bdev, 1, sb->s_blocksize); + if (fsinfo_bh) { + brelse(fsinfo_bh); + brelse(fsinfo_bh); + } + printk("Release fsinfo\n"); + +out: + kill_block_super(sb); +} +#endif + static struct file_system_type vfat_fs_type = { .owner = THIS_MODULE, .name = "vfat", .mount = vfat_mount, +#ifdef CONFIG_FAT_READ_FAT_DIR_SUNXI + .kill_sb = sunxi_vfat_kill_block_super, +#else .kill_sb = kill_block_super, +#endif .fs_flags = FS_REQUIRES_DEV, }; MODULE_ALIAS_FS("vfat");