From: Jan Kara <jack@suse.cz>
To: Aditya Kali <adityakali@google.com>
Cc: adilger@dilger.ca, tytso@mit.edu, dmonakhov@openvz.org,
jack@suse.cz, linux-ext4@vger.kernel.org
Subject: Re: [PATCH v3] ext4: make quota as first class supported feature
Date: Tue, 8 Nov 2011 14:55:14 +0100 [thread overview]
Message-ID: <20111108135514.GB9658@quack.suse.cz> (raw)
In-Reply-To: <1320372920-21308-1-git-send-email-adityakali@google.com>
Thanks for the patch. I did a detailed review of it. I have quite some
comments but all of them are easily fixable so I think we should be mostly
ready in the next iteration.
On Thu 03-11-11 19:15:20, Aditya Kali wrote:
> +static const struct quotactl_ops ext4_new_qctl_operations = {
ext4_new_qctl_operations is rather poor name. What if you need to create
even newer set of operations in future? So I'd rather name them by "what
they do" - so something like ext4_sysfile_qctl_operations - meaning that these
operations handle quota stored in hidden system files.
> + .quota_on_meta = ext4_quota_on_meta,
> + .quota_off = ext4_quota_off,
> + .quota_sync = dquot_quota_sync,
> + .get_info = dquot_get_dqinfo,
> + .set_info = dquot_set_dqinfo,
> + .get_dqblk = dquot_get_dqblk,
> + .set_dqblk = dquot_set_dqblk
..
> @@ -3610,6 +3623,15 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
> #ifdef CONFIG_QUOTA
> sb->s_qcop = &ext4_qctl_operations;
> sb->dq_op = &ext4_quota_operations;
> +
> + if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA)) {
> + /* Use new qctl operations with quota on function that does not
> + * require user specified quota file path. */
> + sb->s_qcop = &ext4_new_qctl_operations;
> +
> + sbi->s_qf_inums[USRQUOTA] = es->s_usr_quota_inum;
> + sbi->s_qf_inums[GRPQUOTA] = es->s_grp_quota_inum;
You need to convert from ondisk format here - i.e. use le32_to_cpu().
> + }
> #endif
> memcpy(sb->s_uuid, es->s_uuid, sizeof(es->s_uuid));
>
> @@ -3815,8 +3837,21 @@ no_journal:
> } else
> descr = "out journal";
>
> - ext4_msg(sb, KERN_INFO, "mounted filesystem with%s. "
> - "Opts: %s%s%s", descr, sbi->s_es->s_mount_opts,
> +#ifdef CONFIG_QUOTA
> + /* Enable quota usage during mount. */
> + if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA) &&
> + !(sb->s_flags & MS_RDONLY)) {
> + ext4_quota_enable(sb, USRQUOTA, QFMT_VFS_V1,
> + DQUOT_USAGE_ENABLED);
> + ext4_quota_enable(sb, GRPQUOTA, QFMT_VFS_V1,
> + DQUOT_USAGE_ENABLED);
> + }
You should check the return value here and fail the mount in case turning
quotas on fails... Also you should set DQUOT_QUOTA_SYS_FILE in
sb_dqopt(sb)->flags before calling ext4_quota_enable() to indicate that
quota file is a hidden system file and generic quota code can then skip
some rather costly steps during quota handling to keep user visible and
kernel visible content in sync.
> +#endif /* CONFIG_QUOTA */
> +
> + ext4_msg(sb, KERN_INFO, "mounted filesystem with%s. quota=%s. "
> + "Opts: %s%s%s", descr,
> + sb_any_quota_loaded(sb) ? "on" : "off",
> + sbi->s_es->s_mount_opts,
> *sbi->s_es->s_mount_opts ? "; " : "", orig_data);
Should info about quotas really be in the message? After all it's just
another feature and we definitely don't report all the features filesystem
has set.
> @@ -4183,6 +4218,12 @@ static int ext4_commit_super(struct super_block *sb, int sync)
> es->s_free_inodes_count =
> cpu_to_le32(percpu_counter_sum_positive(
> &EXT4_SB(sb)->s_freeinodes_counter));
> +#ifdef CONFIG_QUOTA
> + if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA)) {
> + es->s_usr_quota_inum = EXT4_SB(sb)->s_qf_inums[USRQUOTA];
> + es->s_grp_quota_inum = EXT4_SB(sb)->s_qf_inums[GRPQUOTA];
> + }
> +#endif
Is there really need to reset these numbers? They should be stable
during the whole lifetime of a filesystem, no (modulo changes by tune2fs)?
If I'm missing something and numbers indeed can change, you should convert
them to on disk format - i.e. cpu_to_le32().
> @@ -4814,6 +4855,59 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id,
> return dquot_quota_on(sb, type, format_id, path);
> }
>
> +static int ext4_quota_enable(struct super_block *sb, int type, int format_id,
> + unsigned int flags)
> +{
> + struct ext4_sb_info *sbi = EXT4_SB(sb);
> + struct inode *qf_inode;
> + int err;
> +
> + if (!sbi->s_qf_inums[type])
> + return -EPERM;
> +
> + qf_inode = ext4_iget(sb, sbi->s_qf_inums[type]);
> + if (IS_ERR(qf_inode)) {
> + ext4_error(sb, "Bad quota inode # %lu", sbi->s_qf_inums[type]);
> + return PTR_ERR(qf_inode);
> + }
> +
> + /*
> + * When we journal data on quota file, we have to flush journal to see
> + * all updates to the file when we bypass pagecache...
> + */
> + if (sbi->s_journal &&
> + ext4_should_journal_data(qf_inode)) {
> + /*
> + * We don't need to lock updates but journal_flush() could
> + * otherwise be livelocked...
> + */
> + jbd2_journal_lock_updates(sbi->s_journal);
> + err = jbd2_journal_flush(sbi->s_journal);
> + jbd2_journal_unlock_updates(sbi->s_journal);
> + if (err)
> + return err;
> + }
Why do you have the above check? Since this function is called only for
reserved quota inodes which are hidden, ext4_should_journal_data() will
never be true for them.
> +
> + err = dquot_enable(qf_inode, type, format_id, flags);
> + iput(qf_inode);
> +
> + return err;
> +}
> @@ -4837,7 +4931,12 @@ static int ext4_quota_off(struct super_block *sb, int type)
> ext4_journal_stop(handle);
>
> out:
> - return dquot_quota_off(sb, type);
> + /* Disable only the limits if QUOTA feature is set. */
> + if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_QUOTA))
> + return dquot_disable(sb, type, DQUOT_LIMITS_ENABLED);
> + else
> + return dquot_disable(sb, type,
> + DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
> }
Hmm, most of the work ext4_quota_off() does is unnecessary when quota is
handled internally - there's no need to sync the filesystem, no need to
update mtime or ctime... So I'd rather provide a new ext4_quota_off()
function in case quota feature is enabled and that would just call
dquot_disable(sb, type, DQUOT_LIMITS_ENABLED).
Honza
--
Jan Kara <jack@suse.cz>
SUSE Labs, CR
next prev parent reply other threads:[~2011-11-08 13:55 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-11-04 2:15 [PATCH v3] ext4: make quota as first class supported feature Aditya Kali
2011-11-04 2:17 ` Aditya Kali
2011-11-04 9:20 ` Johann Lombardi
[not found] ` <CAGr1F2GfixM0m0Hz7eK7CNJHY40Rpxi2szYXw=PT9jZaqSncBg@mail.gmail.com>
2011-11-07 20:35 ` Johann Lombardi
2011-11-08 13:55 ` Jan Kara [this message]
2011-11-11 0:59 ` Aditya Kali
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20111108135514.GB9658@quack.suse.cz \
--to=jack@suse.cz \
--cc=adilger@dilger.ca \
--cc=adityakali@google.com \
--cc=dmonakhov@openvz.org \
--cc=linux-ext4@vger.kernel.org \
--cc=tytso@mit.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).