fs/exfat: send uevnet from workqueue

We can not send uevent directly because it might be called
from atomic context.

Change-Id: I384a7f197b22b1fcb8d068c98908e4fa5a1d3b82
Signed-off-by: Lianwei Wang <a22439@motorola.com>
Signed-off-by: Shiyong Li <a22381@motorola.com>
Reviewed-on: https://gerrit.mot.com/1102182
SLTApproved: Slta Waiver
SME-Granted: SME Approvals Granted
Tested-by: Jira Key
Reviewed-by: Igor Kovalenko <igork@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
Shiyong Li 2017-12-08 17:36:20 -08:00 • committed by Shi-Yong Li
commit 5b326dd273
3 changed files with 22 additions and 1 deletions

View file

@ -1754,12 +1754,14 @@ void fs_sync(struct super_block *sb, s32 do_sync)
void fs_error(struct super_block *sb)
{
struct exfat_mount_options *opts = &EXFAT_SB(sb)->options;
struct exfat_sb_info *sbi = EXFAT_SB(sb);
if (opts->errors == EXFAT_ERRORS_PANIC)
panic("[EXFAT] Filesystem panic from previous error\n");
else if ((opts->errors == EXFAT_ERRORS_RO) && !(sb->s_flags & MS_RDONLY)) {
sb->s_flags |= MS_RDONLY;
kobject_uevent(&disk_to_dev(sb->s_bdev->bd_disk)->kobj, KOBJ_CHANGE);
if (sbi && !sbi->disable_uevent)
schedule_work(&sbi->uevent_work);
printk(KERN_ERR "[EXFAT] Filesystem has been set read-only\n");
}
}

View file

@ -72,6 +72,7 @@
#include <linux/sched.h>
#include <linux/fs_struct.h>
#include <linux/namei.h>
#include <linux/genhd.h>
#include <asm/current.h>
#include <asm/unaligned.h>
@ -132,6 +133,14 @@ static time_t accum_days_in_year[] = {
static void _exfat_truncate(struct inode *inode, loff_t old_size);
static void exfat_sbi_uevent_work(struct work_struct *work)
{
struct exfat_sb_info *sbi = container_of(work, struct exfat_sb_info,
uevent_work);
kobject_uevent(&disk_to_dev(sbi->sb->s_bdev->bd_disk)->kobj, KOBJ_CHANGE);
}
/* Convert a FAT time/date pair to a UNIX date (seconds since 1 1 70). */
void exfat_time_fat2unix(struct exfat_sb_info *sbi, struct timespec *ts,
DATE_TIME_T *tp)
@ -2057,6 +2066,10 @@ static void exfat_free_super(struct exfat_sb_info *sbi)
static void exfat_put_super(struct super_block *sb)
{
struct exfat_sb_info *sbi = EXFAT_SB(sb);
sbi->disable_uevent = 1;
cancel_work_sync(&sbi->uevent_work);
if (__is_sb_dirty(sb))
exfat_write_super(sb);
@ -2480,6 +2493,9 @@ static int exfat_fill_super(struct super_block *sb, void *data, int silent)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)
mutex_init(&sbi->s_lock);
#endif
sbi->sb = sb;
INIT_WORK(&sbi->uevent_work, exfat_sbi_uevent_work);
sb->s_fs_info = sbi;
sb->s_flags |= MS_NODIRATIME;
sb->s_magic = EXFAT_SUPER_MAGIC;

View file

@ -91,6 +91,9 @@ struct exfat_sb_info {
#ifdef CONFIG_EXFAT_KERNEL_DEBUG
long debug_flags;
#endif /* CONFIG_EXFAT_KERNEL_DEBUG */
struct super_block *sb;
struct work_struct uevent_work;
int disable_uevent;
};
/*