diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 39f00f05f981..5c79ed46e2cf 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -6387,6 +6387,7 @@ static int __ext4_remount(struct fs_context *fc, struct super_block *sb) struct ext4_mount_options old_opts; ext4_group_t g; int err = 0; + int enable_rw = 0; #ifdef CONFIG_QUOTA int enable_quota = 0; int i, j; @@ -6487,12 +6488,14 @@ static int __ext4_remount(struct fs_context *fc, struct super_block *sb) } if (fc->sb_flags & SB_RDONLY) { + ext4_warning(sb, "Remounting file system r/o"); err = sync_filesystem(sb); if (err < 0) goto restore_opts; err = dquot_suspend(sb, -1); if (err < 0) goto restore_opts; + ext4_warning(sb, "Quota suspended"); /* * First of all, the unconditional stuff we have to do @@ -6573,13 +6576,13 @@ static int __ext4_remount(struct fs_context *fc, struct super_block *sb) if (err) goto restore_opts; - sb->s_flags &= ~SB_RDONLY; if (ext4_has_feature_mmp(sb)) { err = ext4_multi_mount_protect(sb, le64_to_cpu(es->s_mmp_block)); if (err) goto restore_opts; } + enable_rw = 1; #ifdef CONFIG_QUOTA enable_quota = 1; #endif @@ -6620,24 +6623,46 @@ static int __ext4_remount(struct fs_context *fc, struct super_block *sb) for (i = 0; i < EXT4_MAXQUOTAS; i++) kfree(old_opts.s_qf_names[i]); if (enable_quota) { - if (sb_any_quota_suspended(sb)) + ext4_warning(sb, "trying to enable quota"); + if (sb_any_quota_suspended(sb)) { dquot_resume(sb, -1); + ext4_warning(sb, "resumed quota"); + } else if (ext4_has_feature_quota(sb)) { err = ext4_enable_quotas(sb); - if (err) + if (err) { + ext4_warning(sb, "failed to enable quota: %d", + err); goto restore_opts; + } + ext4_warning(sb, "enabled quota"); + } } #endif if (!test_opt(sb, BLOCK_VALIDITY) && sbi->s_system_blks) ext4_release_system_zone(sb); + if (enable_rw) + sb->s_flags &= ~SB_RDONLY; + if (!ext4_has_feature_mmp(sb) || sb_rdonly(sb)) ext4_stop_mmpd(sbi); return 0; restore_opts: + ext4_warning(sb, "remount failed! was %s attempted %s", + (old_sb_flags & SB_RDONLY) ? "ro" : "rw", + (sb->s_flags & SB_RDONLY) ? "ro" : "rw"); + if ((sb->s_flags & SB_RDONLY) && + !(old_sb_flags & SB_RDONLY)) { + ext4_warning(sb, "failing rw->ro transition"); + if (sb_any_quota_suspended(sb)) { + ext4_warning(sb, "would resume quotas"); +// dquot_resume(sb, -1); + } + } sb->s_flags = old_sb_flags; sbi->s_mount_opt = old_opts.s_mount_opt; sbi->s_mount_opt2 = old_opts.s_mount_opt2; @@ -6678,8 +6703,8 @@ static int ext4_reconfigure(struct fs_context *fc) if (ret < 0) return ret; - ext4_msg(sb, KERN_INFO, "re-mounted %pU. Quota mode: %s.", - &sb->s_uuid, ext4_quota_mode(sb)); + ext4_msg(sb, KERN_INFO, "re-mounted %pU %s. Quota mode: %s.", + &sb->s_uuid, sb_rdonly(sb) ? "ro" : "rw", ext4_quota_mode(sb)); return 0; } diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 767454d74cd6..fe47fc8e1b02 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -2138,6 +2138,9 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode, /* We need to allocate a new block */ ext4_fsblk_t goal, block; + if (dquot_initialize_needed(inode)) + ext4_warning(sb, "dquot initialize needed %s", + sb_rdonly(sb) ? "ro" : "rw"); WARN_ON_ONCE(dquot_initialize_needed(inode)); goal = ext4_group_first_block_no(sb,