From 31a118f1dea4ea57e11d2ebb008721e76ac71aa9 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Sun, 28 Dec 2008 09:11:02 +0200 Subject: [PATCH] --- yaml --- r: 125473 b: refs/heads/master c: 26d05777b0a23062a39e83c369c0a3583918f164 h: refs/heads/master i: 125471: cfaa8467b3bc449f5934f5d60206119ea01b5b00 v: v3 --- [refs] | 2 +- trunk/fs/ubifs/super.c | 26 +++++++++++++++----------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/[refs] b/[refs] index bd6da8bf4639..bd84aabe871a 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: cb5c6a2b2be59b480a3746c5113cb3411c053bff +refs/heads/master: 26d05777b0a23062a39e83c369c0a3583918f164 diff --git a/trunk/fs/ubifs/super.c b/trunk/fs/ubifs/super.c index a14703e0a9ad..1c1bbe4135c6 100644 --- a/trunk/fs/ubifs/super.c +++ b/trunk/fs/ubifs/super.c @@ -1570,20 +1570,24 @@ static int ubifs_remount_rw(struct ubifs_info *c) * @c: UBIFS file-system description object * * This function is called during un-mounting and re-mounting, and it commits - * the journal unless the "fast unmount" mode is enabled. It also avoids - * committing the journal if it contains too few data. + * the journal unless the "fast unmount" mode is enabled. */ static void commit_on_unmount(struct ubifs_info *c) { - if (!c->fast_unmount) { - long long bud_bytes; + struct super_block *sb = c->vfs_sb; + long long bud_bytes; - spin_lock(&c->buds_lock); - bud_bytes = c->bud_bytes; - spin_unlock(&c->buds_lock); - if (bud_bytes > c->leb_size) - ubifs_run_commit(c); - } + /* + * This function is called before the background thread is stopped, so + * we may race with ongoing commit, which means we have to take + * @c->bud_lock to access @c->bud_bytes. + */ + spin_lock(&c->buds_lock); + bud_bytes = c->bud_bytes; + spin_unlock(&c->buds_lock); + + if (!c->fast_unmount && !(sb->s_flags & MS_RDONLY) && bud_bytes) + ubifs_run_commit(c); } /** @@ -2009,7 +2013,7 @@ static void ubifs_kill_sb(struct super_block *sb) * We do 'commit_on_unmount()' here instead of 'ubifs_put_super()' * in order to be outside BKL. */ - if (sb->s_root && !(sb->s_flags & MS_RDONLY)) + if (sb->s_root) commit_on_unmount(c); /* The un-mount routine is actually done in put_super() */ generic_shutdown_super(sb);