From: Dmitry Monakhov <dmonakhov@openvz.org>
To: linux-fsdevel@vger.kernel.org
Cc: jack@suse.cz, hch@infradead.org, sandeen@redhat.com,
Dmitry Monakhov <dmonakhov@openvz.org>
Subject: [PATCH 3/6] quota: Check what quota is properly initialized for inode before charge
Date: Thu, 8 Apr 2010 22:04:22 +0400 [thread overview]
Message-ID: <1270749865-25441-4-git-send-email-dmonakhov@openvz.org> (raw)
In-Reply-To: <1270749865-25441-3-git-send-email-dmonakhov@openvz.org>
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.
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
fs/quota/dquot.c | 39 +++++++++++++++++++++++++++++++++------
1 files changed, 33 insertions(+), 6 deletions(-)
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 3f4541e..7480e03 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -1516,7 +1516,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];
/*
@@ -1529,13 +1529,27 @@ 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 */
+ if (!(active = sb_any_quota_active(inode->i_sb)) || 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) {
@@ -1544,7 +1558,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);
@@ -1570,7 +1584,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
@@ -1580,17 +1594,30 @@ 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 */
+ if (!(active = sb_any_quota_active(inode->i_sb)) || 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
next prev parent reply other threads:[~2010-04-08 18:05 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-04-08 18:04 [PATCH 0/6] RFC quota: Redesign IO error handling interface Dmitry Monakhov
2010-04-08 18:04 ` [PATCH 1/6] quota: unify quota init condition in setattr Dmitry Monakhov
2010-04-08 18:04 ` [PATCH 2/6] quota: Add proper error handling on quota initialization Dmitry Monakhov
2010-04-08 18:04 ` Dmitry Monakhov [this message]
2010-04-08 18:04 ` [PATCH 4/6] ext3: handle errors in orphan_cleanup Dmitry Monakhov
2010-04-08 18:04 ` [PATCH 5/6] ext4: " Dmitry Monakhov
2010-04-08 18:04 ` [PATCH 6/6] quota: check error code from dquot_initialize Dmitry Monakhov
2010-05-07 17:01 ` Jan Kara
2010-05-07 16:59 ` [PATCH 4/6] ext3: handle errors in orphan_cleanup Jan Kara
2010-05-07 16:48 ` [PATCH 3/6] quota: Check what quota is properly initialized for inode before charge Jan Kara
2010-05-17 6:22 ` Dmitry Monakhov
2010-05-07 16:44 ` [PATCH 2/6] quota: Add proper error handling on quota initialization Jan Kara
2010-05-07 16:39 ` [PATCH 1/6] quota: unify quota init condition in setattr Jan Kara
2010-05-13 16:29 ` Jan Kara
2010-05-05 8:45 ` [PATCH 0/6] RFC quota: Redesign IO error handling interface Dmitry Monakhov
2010-05-07 16:38 ` 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=1270749865-25441-4-git-send-email-dmonakhov@openvz.org \
--to=dmonakhov@openvz.org \
--cc=hch@infradead.org \
--cc=jack@suse.cz \
--cc=linux-fsdevel@vger.kernel.org \
--cc=sandeen@redhat.com \
/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).