diff --git a/fs/exfat/super.c b/fs/exfat/super.c index 84f599b37a45..c13852eb1cc5 100644 --- a/fs/exfat/super.c +++ b/fs/exfat/super.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "exfat_raw.h" #include "exfat_fs.h" @@ -69,16 +70,28 @@ static int exfat_statfs(struct dentry *dentry, struct kstatfs *buf) return 0; } +static inline __u8 exfat_calc_perc_in_use(const struct exfat_sb_info *sbi) +{ + return (__u8)mul_u64_u32_div(sbi->used_clusters, 100, + EXFAT_DATA_CLUSTER_COUNT(sbi)); +} + static int exfat_set_vol_flags(struct super_block *sb, unsigned short new_flags) { struct exfat_sb_info *sbi = EXFAT_SB(sb); struct boot_sector *p_boot = (struct boot_sector *)sbi->boot_bh->b_data; + __u8 new_piu; /* retain persistent-flags */ new_flags |= sbi->vol_flags_persistent; + if (new_flags & VOLUME_DIRTY) + new_piu = 0xFF; + else + new_piu = exfat_calc_perc_in_use(sbi); + /* flags are not changed */ - if (sbi->vol_flags == new_flags) + if (sbi->vol_flags == new_flags && new_piu == p_boot->percent_in_use) return 0; sbi->vol_flags = new_flags; @@ -90,6 +103,7 @@ static int exfat_set_vol_flags(struct super_block *sb, unsigned short new_flags) return 0; p_boot->vol_flags = cpu_to_le16(new_flags); + p_boot->percent_in_use = new_piu; set_buffer_uptodate(sbi->boot_bh); mark_buffer_dirty(sbi->boot_bh);