]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
ext4: make sure quota gets properly shutdown on error
authorJan Kara <jack@suse.cz>
Thu, 7 Oct 2021 15:53:35 +0000 (17:53 +0200)
committerPaolo Pisati <paolo.pisati@canonical.com>
Fri, 28 Jan 2022 10:03:12 +0000 (11:03 +0100)
BugLink: https://bugs.launchpad.net/bugs/1959376
commit 15fc69bbbbbc8c72e5f6cc4e1be0f51283c5448e upstream.

When we hit an error when enabling quotas and setting inode flags, we do
not properly shutdown quota subsystem despite returning error from
Q_QUOTAON quotactl. This can lead to some odd situations like kernel
using quota file while it is still writeable for userspace. Make sure we
properly cleanup the quota subsystem in case of error.

Signed-off-by: Jan Kara <jack@suse.cz>
Cc: stable@kernel.org
Link: https://lore.kernel.org/r/20211007155336.12493-2-jack@suse.cz
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com>
fs/ext4/super.c

index 0e5d51ebeb7b7fde8b4c5d95848cc7bcc67df64c..6261aad8294a6671e597213beb3eb5f40e40e5d0 100644 (file)
@@ -6266,10 +6266,7 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id,
 
        lockdep_set_quota_inode(path->dentry->d_inode, I_DATA_SEM_QUOTA);
        err = dquot_quota_on(sb, type, format_id, path);
-       if (err) {
-               lockdep_set_quota_inode(path->dentry->d_inode,
-                                            I_DATA_SEM_NORMAL);
-       } else {
+       if (!err) {
                struct inode *inode = d_inode(path->dentry);
                handle_t *handle;
 
@@ -6289,7 +6286,12 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id,
                ext4_journal_stop(handle);
        unlock_inode:
                inode_unlock(inode);
+               if (err)
+                       dquot_quota_off(sb, type);
        }
+       if (err)
+               lockdep_set_quota_inode(path->dentry->d_inode,
+                                            I_DATA_SEM_NORMAL);
        return err;
 }