Messages in this thread Patch in this message | | | Date | Sat, 11 Sep 1999 20:28:17 +0200 | From | Jan Kara <> | Subject | Re: Quota speedup in 2.2.12 and bugfix |
| |
> Hello. > > I'm sending you a small patch to quota code in 2.2.12. It does two things: > > 1) Fixes possible race in sync_dquots() where we could end up writing invalidated quota. > 2) Speeds up quotaoff - currently when inode cache was full of inodes with quota pointers > set, which is likely when quota enabled on root, quotaoff could take a few seconds > which is unpleasant. So I made a bit more finegrained detection of blocking when we > remove references from inodes and so we don't have to restart so often. > > The patch is attached. > > Bye > Honza. Oops. The patch was NOT attached... So I'll retry ;-).
--- linux/fs/dquot.c Fri Aug 20 12:38:58 1999 +++ linux/fs/dquot.c Sat Sep 11 16:52:38 1999 @@ -97,6 +97,9 @@ static struct wait_queue *dquot_wait = (struct wait_queue *)NULL, *update_wait = (struct wait_queue *)NULL; +void dqput(struct dquot *); +static struct dquot *dqduplicate(struct dquot *); + static inline char is_enabled(struct vfsmount *vfsmnt, short type) { switch (type) { @@ -390,7 +393,7 @@ int sync_dquots(kdev_t dev, short type) { - struct dquot *dquot, *next; + struct dquot *dquot, *next, *ddquot; int need_restart; restart: @@ -407,9 +410,11 @@ if (!(dquot->dq_flags & (DQ_LOCKED | DQ_MOD))) continue; - wait_on_dquot(dquot); - if (dquot->dq_flags & DQ_MOD) - write_dquot(dquot); + if ((ddquot = dqduplicate(dquot)) == NODQUOT) + continue; + if (ddquot->dq_flags & DQ_MOD) + write_dquot(ddquot); + dqput(ddquot); /* Set the flag for another pass. */ need_restart = 1; } @@ -424,6 +429,7 @@ return(0); } +/* NOTE: If you change this function please check whether dqput_blocks() works right... */ void dqput(struct dquot *dquot) { if (!dquot) @@ -688,6 +694,16 @@ } } +/* Return 0 if dqput() won't block (note that 1 doesn't necessarily mean blocking) */ +static inline int dqput_blocks(struct dquot *dquot) +{ + if (dquot->dq_flags & DQ_LOCKED) + return 1; + if (dquot->dq_count == 1) + return 1; + return 0; +} + static int reset_inode_dquot_ptrs(struct inode *inode, short type) { struct dquot *dquot = inode->i_dquot[type]; @@ -701,13 +717,16 @@ } inode->i_flags &= ~S_QUOTA; put_it: - if (dquot != NODQUOT) { - spin_unlock(&inode_lock); /* We may block so drop the lock... */ - dqput(dquot); - spin_lock(&inode_lock); /* And capture lock again */ - /* we may have blocked ... */ - return 1; - } + if (dquot != NODQUOT) + if (dqput_blocks(dquot)) { + spin_unlock(&inode_lock); /* We may block so drop the lock... */ + dqput(dquot); + spin_lock(&inode_lock); /* And capture lock again */ + /* we may have blocked ... */ + return 1; + } + else + dqput(dquot); /* dqput() won't block so we can hold locks... */ return 0; } | |