From: Jan Kara <jack@suse.cz>
To: Dmitry Monakhov <dmonakhov@openvz.org>
Cc: linux-fsdevel@vger.kernel.org, jack@suse.cz, hch@infradead.org
Subject: Re: [PATCH 02/12] quota: Check what quota is properly initialized for inode before charge
Date: Thu, 20 May 2010 20:13:33 +0200 [thread overview]
Message-ID: <20100520181332.GN3395@quack.suse.cz> (raw)
In-Reply-To: <1274248928-5113-3-git-send-email-dmonakhov@openvz.org>
On Wed 19-05-10 10:01:58, Dmitry Monakhov wrote:
> Due to previous IO error or other bugs an inode may not has quota
> pointer. This definite sign of quota inconsistency/corruption.
> In fact this condition must being checked in all charge/uncharge
> functions. And if error was detected it is reasonable to fail whole
> operation. But uncharge(free_space/claim_space/free_inode) functions
> has no fail nature. This is because caller can't handle errors from
> such functions. How can you handle error from following call-trace?
> write_page()->quota_claim_space()
>
> So alloc_space() and alloc_inode() are the only functions which we may
> reliably abort in case of any errors.
>
> This patch add corresponding checks only for charge functions.
Actually, I've realized that this patch has a problem if
dquot_alloc_space is called while add_dquot_ref() is running. Then it would
return EIO although it should just silently succeed (and yes, quotas will
be inconsistent but that's "life" when quota isn't filesystem metadata...).
So I don't think this is a move in the right direction at least for now...
Honza
>
> Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
> ---
> fs/quota/dquot.c | 41 +++++++++++++++++++++++++++++++++++------
> 1 files changed, 35 insertions(+), 6 deletions(-)
>
> diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
> index 95aa445..f0e68b3 100644
> --- a/fs/quota/dquot.c
> +++ b/fs/quota/dquot.c
> @@ -1541,7 +1541,7 @@ static void inode_decr_space(struct inode *inode, qsize_t number, int reserve)
> int __dquot_alloc_space(struct inode *inode, qsize_t number,
> int warn, int reserve)
> {
> - int cnt, ret = 0;
> + int cnt, active, ret = 0;
> char warntype[MAXQUOTAS];
>
> /*
> @@ -1554,13 +1554,28 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number,
> }
>
> down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
> + /* Now recheck reliably when holding dqptr_sem */
> + active = sb_any_quota_active(inode->i_sb);
> + if (!active || IS_NOQUOTA(inode)) {
> + inode_incr_space(inode, number, reserve);
> + goto out;
> + }
> +
> for (cnt = 0; cnt < MAXQUOTAS; cnt++)
> warntype[cnt] = QUOTA_NL_NOWARN;
>
> spin_lock(&dq_data_lock);
> for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
> - if (!inode->i_dquot[cnt])
> + if (!(active & (1 << cnt)))
> continue;
> + /*
> + * Given quota type is active, so quota must being
> + * initialized for this inode
> + */
> + if (!inode->i_dquot[cnt]) {
> + ret = -EIO;
> + goto out_flush_warn;
> + }
> ret = check_bdq(inode->i_dquot[cnt], number, !warn,
> warntype+cnt);
> if (ret) {
> @@ -1569,7 +1584,7 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number,
> }
> }
> for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
> - if (!inode->i_dquot[cnt])
> + if (!(active & (1 << cnt)))
> continue;
> if (reserve)
> dquot_resv_space(inode->i_dquot[cnt], number);
> @@ -1595,7 +1610,7 @@ EXPORT_SYMBOL(__dquot_alloc_space);
> */
> int dquot_alloc_inode(const struct inode *inode)
> {
> - int cnt, ret = 0;
> + int cnt, active, ret = 0;
> char warntype[MAXQUOTAS];
>
> /* First test before acquiring mutex - solves deadlocks when we
> @@ -1605,17 +1620,31 @@ int dquot_alloc_inode(const struct inode *inode)
> for (cnt = 0; cnt < MAXQUOTAS; cnt++)
> warntype[cnt] = QUOTA_NL_NOWARN;
> down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
> + /* Now recheck reliably when holding dqptr_sem */
> + active = sb_any_quota_active(inode->i_sb);
> + if (!active || IS_NOQUOTA(inode)) {
> + return 0;
> + }
> +
> spin_lock(&dq_data_lock);
> for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
> - if (!inode->i_dquot[cnt])
> + if (!(active & (1 < cnt)))
> continue;
> + /*
> + * Given quota type is active, so quota must being
> + * initialized for this inode
> + */
> + if (!inode->i_dquot[cnt]) {
> + ret = -EIO;
> + goto warn_put_all;
> + }
> ret = check_idq(inode->i_dquot[cnt], 1, warntype + cnt);
> if (ret)
> goto warn_put_all;
> }
>
> for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
> - if (!inode->i_dquot[cnt])
> + if ((!active & (1 < cnt)))
> continue;
> dquot_incr_inodes(inode->i_dquot[cnt], 1);
> }
> --
> 1.6.6.1
>
--
Jan Kara <jack@suse.cz>
SUSE Labs, CR
next prev parent reply other threads:[~2010-05-20 18:13 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-05-19 6:01 [PATCH 00/12] quota: Redesign IO error handling interface V2 Dmitry Monakhov
2010-05-19 6:01 ` [PATCH 01/12] quota: Add proper error handling on quota initialization Dmitry Monakhov
2010-05-19 6:01 ` [PATCH 02/12] quota: Check what quota is properly initialized for inode before charge Dmitry Monakhov
2010-05-19 6:01 ` [PATCH 03/12] ext3: handle errors in orphan_cleanup Dmitry Monakhov
2010-05-19 6:02 ` [PATCH 04/12] ext4: " Dmitry Monakhov
2010-05-19 6:02 ` [PATCH 05/12] ufs: add error handling for dquot_initialize Dmitry Monakhov
2010-05-19 6:02 ` [PATCH 06/12] udf: " Dmitry Monakhov
2010-05-19 6:02 ` [PATCH 07/12] reiserfs: " Dmitry Monakhov
2010-05-19 6:02 ` [PATCH 08/12] ocfs2: " Dmitry Monakhov
2010-05-19 6:02 ` [PATCH 09/12] jfs: " Dmitry Monakhov
2010-05-19 6:02 ` [PATCH 10/12] ext4: " Dmitry Monakhov
2010-05-19 6:02 ` [PATCH 11/12] ext3: " Dmitry Monakhov
2010-05-19 6:02 ` [PATCH 12/12] ext2: " Dmitry Monakhov
2010-05-20 17:30 ` Jan Kara
2010-05-20 17:32 ` [PATCH 11/12] ext3: " Jan Kara
2010-05-20 17:34 ` [PATCH 06/12] udf: " Jan Kara
2010-05-20 17:33 ` [PATCH 05/12] ufs: " Jan Kara
2010-05-20 17:35 ` [PATCH 03/12] ext3: handle errors in orphan_cleanup Jan Kara
2010-05-20 18:13 ` Jan Kara [this message]
2010-05-20 18:05 ` [PATCH 01/12] quota: Add proper error handling on quota initialization Jan Kara
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=20100520181332.GN3395@quack.suse.cz \
--to=jack@suse.cz \
--cc=dmonakhov@openvz.org \
--cc=hch@infradead.org \
--cc=linux-fsdevel@vger.kernel.org \
/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).