If remount failed due to some reason we have to fallback quota to it's original
state
otherwise it will stay in suspended state which is incorrect.
#TEST_CASE
dd if=/dev/zero of=/tmp/imgfile bs=1M count=100
# any fs with quota are affected
mkfs.ext4 -F /tmp/imgfile
mount /tmp/imgfile /mnt -oloop,quota
quotacheck -cug /mnt
quotaon /mnt
# remount to RO state , and explicitly provide bad option
mount /mnt -oremount,ro,some-bad-option
# At this point fs is in broken state because it is RW, but quota is in
# suspended state. Later activity will trigger NULL pointer dereference
mount /mnt -oremount,ro,some-bad-option
Bug was silently fixed in: e0ccfd959cd890 v2.6.34-7101-ge0ccfd9, All previous
kernel versions are affected.
Signed-off-by: Dmitry Monakhov <[email protected]>
---
fs/super.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/fs/super.c b/fs/super.c
index 1fb63e3..457e70d 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -607,8 +607,13 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force)
if (sb->s_op->remount_fs) {
retval = sb->s_op->remount_fs(sb, &flags, data);
- if (retval)
+ printk("remount_fs %s ret:%d\n", sb->s_id, retval);
+ if (retval) {
+ /* Remount failed, fallback quota to original state */
+ if (remount_ro)
+ vfs_dq_quota_on_remount(sb);
return retval;
+ }
}
sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK);
if (remount_rw)