[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20191031165905.GE13321@quack2.suse.cz>
Date: Thu, 31 Oct 2019 17:59:05 +0100
From: Jan Kara <jack@...e.cz>
To: Dmitry Monakhov <dmonakhov@...nvz.org>
Cc: linux-fsdevel@...r.kernel.org, linux-ext4@...r.kernel.org,
linux-kernel@...r.kernel.org, jack@...e.cz, tytso@....edu,
lixi@....com, Dmitry Monakhov <dmtrmonakhov@...dex-team.ru>,
Konstantin Khlebnikov <khlebnikov@...dex-team.ru>
Subject: Re: [PATCH] fs/ext4: get project quota from inode for mangling
statfs results
On Thu 31-10-19 11:03:48, Dmitry Monakhov wrote:
> From: Dmitry Monakhov <dmtrmonakhov@...dex-team.ru>
>
> Right now ext4_statfs_project() does quota lookup by id every time.
> This is costly operation, especially if there is no inode who hold
> reference to this dquot. This means that each statfs performs useless
> ext4_acquire_dquot()/ext4_release_dquot() which serialized on __jbd2_log_wait_for_space()
> dqget()
> ->ext4_acquire_dquot
> -> ext4_journal_start
> -> __jbd2_log_wait_for_space
> dqput()
> -> ext4_release_dquot
> ->ext4_journal_start
> ->__jbd2_log_wait_for_space
>
>
> Function ext4_statfs_project() could be moved into generic quota code,
> it is required for every filesystem which uses generic project quota.
>
> Reported-by: Dmitry Monakhov <dmtrmonakhov@...dex-team.ru>
> Signed-off-by: Konstantin Khlebnikov <khlebnikov@...dex-team.ru>
Thanks! The patch looks good to me. You can add:
Reviewed-by: Jan Kara <jack@...e.cz>
Honza
> ---
> fs/ext4/super.c | 25 ++++++++++++++++---------
> 1 file changed, 16 insertions(+), 9 deletions(-)
>
> diff --git a/fs/ext4/super.c b/fs/ext4/super.c
> index 2318e5f..4e8f97d68 100644
> --- a/fs/ext4/super.c
> +++ b/fs/ext4/super.c
> @@ -5532,18 +5532,23 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
> }
>
> #ifdef CONFIG_QUOTA
> -static int ext4_statfs_project(struct super_block *sb,
> - kprojid_t projid, struct kstatfs *buf)
> +static int ext4_statfs_project(struct inode *inode, struct kstatfs *buf)
> {
> - struct kqid qid;
> + struct super_block *sb = inode->i_sb;
> struct dquot *dquot;
> u64 limit;
> u64 curblock;
> + int err;
> +
> + err = dquot_initialize(inode);
> + if (err)
> + return err;
> +
> + spin_lock(&inode->i_lock);
> + dquot = ext4_get_dquots(inode)[PRJQUOTA];
> + if (!dquot)
> + goto out_unlock;
>
> - qid = make_kqid_projid(projid);
> - dquot = dqget(sb, qid);
> - if (IS_ERR(dquot))
> - return PTR_ERR(dquot);
> spin_lock(&dquot->dq_dqb_lock);
>
> limit = (dquot->dq_dqb.dqb_bsoftlimit ?
> @@ -5569,7 +5574,9 @@ static int ext4_statfs_project(struct super_block *sb,
> }
>
> spin_unlock(&dquot->dq_dqb_lock);
> - dqput(dquot);
> +out_unlock:
> + spin_unlock(&inode->i_lock);
> +
> return 0;
> }
> #endif
> @@ -5609,7 +5616,7 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf)
> #ifdef CONFIG_QUOTA
> if (ext4_test_inode_flag(dentry->d_inode, EXT4_INODE_PROJINHERIT) &&
> sb_has_quota_limits_enabled(sb, PRJQUOTA))
> - ext4_statfs_project(sb, EXT4_I(dentry->d_inode)->i_projid, buf);
> + ext4_statfs_project(dentry->d_inode, buf);
> #endif
> return 0;
> }
> --
> 2.7.4
>
--
Jan Kara <jack@...e.com>
SUSE Labs, CR
Powered by blists - more mailing lists