From: Dmitry <dmonakhov@openvz.org>
To: Jan Kara <jack@suse.cz>
Cc: linux-fsdevel@vger.kernel.org, jack@suse.cz, hch@infradead.org,
Dmitry Monakhov <dmonakhov@gmail.com>
Subject: Re: [PATCH 09/11] quota: protect dquot mem info with objects's lock
Date: Wed, 06 Oct 2010 17:41:43 +0400 [thread overview]
Message-ID: <87tykz8mlk.fsf@dmon-lap.sw.ru> (raw)
In-Reply-To: <20101006133018.GM3676@quack.suse.cz>
On Wed, 6 Oct 2010 15:30:18 +0200, Jan Kara <jack@suse.cz> wrote:
> On Tue 05-10-10 22:20:25, Dmitry Monakhov wrote:
> > @@ -1762,14 +1810,16 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to)
> > return 0;
> > }
> > spin_lock(&sb_dqopt(inode->i_sb)->dq_data_lock);
> > + inode_dquot_lock(inode, transfer_from);
> > cur_space = inode_get_bytes(inode);
> > rsv_space = inode_get_rsv_space(inode);
> > space = cur_space + rsv_space;
> > + dquot_lock_all(transfer_to);
> One more problem I've spotted - here you cannot lock new and old dquot
> structures in an arbitrary order as that would lead to deadlocks when two
> dquot_transfers run in parallel. So you have to establish some ordering and
> follow that while locking...
Absolutely, WOW, i've even written a remiander for that somewhere,
And as usually simply forgot about that :(
Minor issue: I've also forgot to place different quota types to different
lockdep classes. Which result complain from lockdep. Also will fix.
>
> Honza
>
> > /* Build the transfer_from list and check the limits */
> > +
> > for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
> > if (!transfer_to[cnt])
> > continue;
> > - transfer_from[cnt] = inode->i_dquot[cnt];
> > ret = check_idq(transfer_to[cnt], 1, warntype_to + cnt);
> > if (ret)
> > goto over_quota;
> > @@ -1806,6 +1856,8 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to)
> >
> > inode->i_dquot[cnt] = transfer_to[cnt];
> > }
> > + dquot_unlock_all(transfer_to);
> > + dquot_unlock_all(transfer_from);
> > spin_unlock(&sb_dqopt(inode->i_sb)->dq_data_lock);
> > up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
> >
> > @@ -1820,6 +1872,8 @@ warn:
> > flush_warnings(transfer_from, warntype_from_space);
> > return ret;
> > over_quota:
> > + dquot_unlock_all(transfer_to);
> > + dquot_unlock_all(transfer_from);
> > spin_unlock(&sb_dqopt(inode->i_sb)->dq_data_lock);
> > up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
> > goto warn;
> > @@ -2363,6 +2417,7 @@ static void do_get_dqblk(struct dquot *dquot, struct fs_disk_quota *di)
> > di->d_id = dquot->dq_id;
> >
> > spin_lock(&dq_opt(dquot)->dq_data_lock);
> > + spin_lock(&dquot->dq_lock);
> > di->d_blk_hardlimit = stoqb(dm->dqb_bhardlimit);
> > di->d_blk_softlimit = stoqb(dm->dqb_bsoftlimit);
> > di->d_ino_hardlimit = dm->dqb_ihardlimit;
> > @@ -2371,6 +2426,7 @@ static void do_get_dqblk(struct dquot *dquot, struct fs_disk_quota *di)
> > di->d_icount = dm->dqb_curinodes;
> > di->d_btimer = dm->dqb_btime;
> > di->d_itimer = dm->dqb_itime;
> > + spin_unlock(&dquot->dq_lock);
> > spin_unlock(&dq_opt(dquot)->dq_data_lock);
> > }
> >
> > @@ -2415,6 +2471,7 @@ static int do_set_dqblk(struct dquot *dquot, struct fs_disk_quota *di)
> > return -ERANGE;
> >
> > spin_lock(&dq_opt(dquot)->dq_data_lock);
> > + spin_lock(&dquot->dq_lock);
> > if (di->d_fieldmask & FS_DQ_BCOUNT) {
> > dm->dqb_curspace = di->d_bcount - dm->dqb_rsvspace;
> > check_blim = 1;
> > @@ -2480,6 +2537,7 @@ static int do_set_dqblk(struct dquot *dquot, struct fs_disk_quota *di)
> > clear_bit(DQ_FAKE_B, &dquot->dq_flags);
> > else
> > set_bit(DQ_FAKE_B, &dquot->dq_flags);
> > + spin_unlock(&dquot->dq_lock);
> > spin_unlock(&dq_opt(dquot)->dq_data_lock);
> > mark_dquot_dirty(dquot);
> >
> > diff --git a/fs/quota/quota_tree.c b/fs/quota/quota_tree.c
> > index 8b04f24..1643c30 100644
> > --- a/fs/quota/quota_tree.c
> > +++ b/fs/quota/quota_tree.c
> > @@ -376,7 +376,9 @@ int qtree_write_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot)
> > }
> > }
> > spin_lock(&sb_dqopt(sb)->dq_data_lock);
> > + spin_lock(&dquot->dq_lock);
> > info->dqi_ops->mem2disk_dqblk(ddquot, dquot);
> > + spin_unlock(&dquot->dq_lock);
> > spin_unlock(&sb_dqopt(sb)->dq_data_lock);
> > ret = sb->s_op->quota_write(sb, type, ddquot, info->dqi_entry_size,
> > dquot->dq_off);
> > @@ -632,12 +634,14 @@ int qtree_read_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot)
> > goto out;
> > }
> > spin_lock(&sb_dqopt(sb)->dq_data_lock);
> > + spin_lock(&dquot->dq_lock);
> > info->dqi_ops->disk2mem_dqblk(dquot, ddquot);
> > if (!dquot->dq_dqb.dqb_bhardlimit &&
> > !dquot->dq_dqb.dqb_bsoftlimit &&
> > !dquot->dq_dqb.dqb_ihardlimit &&
> > !dquot->dq_dqb.dqb_isoftlimit)
> > set_bit(DQ_FAKE_B, &dquot->dq_flags);
> > + spin_unlock(&dquot->dq_lock);
> > spin_unlock(&sb_dqopt(sb)->dq_data_lock);
> > kfree(ddquot);
> > out:
> > diff --git a/include/linux/quota.h b/include/linux/quota.h
> > index 9e7a102..197660f 100644
> > --- a/include/linux/quota.h
> > +++ b/include/linux/quota.h
> > @@ -294,6 +294,7 @@ struct dquot {
> > unsigned long dq_flags; /* See DQ_* */
> > short dq_type; /* Type of quota */
> > struct mem_dqblk dq_dqb; /* Diskquota usage */
> > + spinlock_t dq_lock; /* protect in mem_dqblk */
> > };
> >
> > /* Operations which must be implemented by each quota format */
> > --
> > 1.6.6.1
> >
> --
> Jan Kara <jack@suse.cz>
> SUSE Labs, CR
> --
> To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2010-10-06 13:43 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-10-05 18:20 (unknown), Dmitry Monakhov
2010-10-05 18:20 ` [PATCH 01/11] quota: add wrapper function Dmitry Monakhov
2010-10-06 8:56 ` Christoph Hellwig
2010-10-06 10:01 ` Jan Kara
2010-10-05 18:20 ` [PATCH 02/11] quota: Convert dq_state_lock to per-sb dq_state_lock Dmitry Monakhov
2010-10-06 10:04 ` Jan Kara
2010-10-05 18:20 ` [PATCH 03/11] quota: add quota format lock Dmitry Monakhov
2010-10-06 10:05 ` Jan Kara
2010-10-05 18:20 ` [PATCH 04/11] quota: make dquot lists per-sb Dmitry Monakhov
2010-10-06 8:57 ` Christoph Hellwig
2010-10-06 9:39 ` Dmitry
2010-10-06 10:22 ` Jan Kara
2010-10-06 10:40 ` Dmitry
2010-10-06 10:54 ` Jan Kara
2010-10-05 18:20 ` [PATCH 05/11] quota: make per-sb hash array Dmitry Monakhov
2010-10-06 10:38 ` Jan Kara
2010-10-05 18:20 ` [PATCH 06/11] quota: remove global dq_list_lock Dmitry Monakhov
2010-10-05 18:20 ` [PATCH 07/11] quota: rename dq_lock Dmitry Monakhov
2010-10-05 18:20 ` [PATCH 08/11] quota: make per-sb dq_data_lock Dmitry Monakhov
2010-10-06 11:01 ` Jan Kara
2010-10-05 18:20 ` [PATCH 09/11] quota: protect dquot mem info with objects's lock Dmitry Monakhov
2010-10-06 12:37 ` Jan Kara
2010-10-06 13:17 ` Dmitry
2010-10-06 13:41 ` Jan Kara
2010-10-06 14:19 ` Dmitry
2010-10-06 13:30 ` Jan Kara
2010-10-06 13:41 ` Dmitry [this message]
2010-10-05 18:20 ` [PATCH 10/11] quota: drop dq_data_lock where possible Dmitry Monakhov
2010-10-05 18:20 ` [PATCH 11/11] quota: relax dq_data_lock dq_lock locking consistency Dmitry Monakhov
2010-10-06 11:56 ` Jan Kara
2010-10-06 7:08 ` [PATCH 0/11] RFC quota scalability V1 Dmitry
2010-10-06 9:44 ` Jan Kara
2010-10-06 10:15 ` Dmitry
2010-10-06 10:47 ` Jan Kara
2010-10-10 3:50 ` Brad Boyer
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=87tykz8mlk.fsf@dmon-lap.sw.ru \
--to=dmonakhov@openvz.org \
--cc=dmonakhov@gmail.com \
--cc=hch@infradead.org \
--cc=jack@suse.cz \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.