Fixes in quotas in 2.2.13

Jan Kara (jack@atrey.karlin.mff.cuni.cz)
Thu, 11 Nov 1999 12:45:45 +0100


--oyUTqETQ0mS9luUI
Content-Type: text/plain; charset=us-ascii

Hello.

I've done a fix to one deadlock in quotas in write_dquot(). I thought
I fixed earlier but combined with dquot_transfer() it was still there.
The basic think which causes these deadlocks is that we account quotas
in quotafiles and so we run into problems when quotafile is enlarged while
writing some structures...
My fix simply turns off quotas on quota files because other fixes are
really nasty hacks... I know there can arise some inconsistencies as
quotacheck will count quota files but the only result will be that root
will eventually have more blocks accounted.
Please apply following patch.

Honza.

--oyUTqETQ0mS9luUI
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="quota-fix-2.2.13-2.diff"

--- linux/fs/dquot.c Sun Oct 31 18:25:11 1999
+++ linux/fs/dquot.c Wed Nov 10 17:47:47 1999
@@ -31,6 +31,9 @@
* add_dquot_ref() restarts after blocking
* Added check for bogus uid and fixed check for group in quotactl.
* Jan Kara, <jack@atrey.karlin.mff.cuni.cz>, 4-6/99
+ * Definitely (hopefully) fixed deadlock in write_dquot(). We no
+ * longer account quota files.
+ * Jan Kara, <jack@suse.cz>, 11/99, sposored by SuSE CR
*
* (C) Copyright 1994 - 1997 Marco van Wieringen
*/
@@ -245,6 +248,9 @@
wake_up(&dquot->dq_wait);
}

+/*
+ * We don't have to be afraid of deadlocks as we never have quotas on quota files...
+ */
static void write_dquot(struct dquot *dquot)
{
short type = dquot->dq_type;
@@ -252,20 +258,14 @@
mm_segment_t fs;
loff_t offset;
ssize_t ret;
- struct dqblk data;
struct semaphore *sem = &dquot->dq_mnt->mnt_dquot.dqio_sem;

- /*
- * We copy our data to preserve consistency when dquot is not locked.
- * We can't lock it because it can cause deadlocks - think about
- * growing the quota file...
- */
- memcpy(&data, &dquot->dq_dqb, sizeof(struct dqblk));
- down(sem);
+ lock_dquot(dquot);
if (!dquot->dq_mnt) { /* Invalidated quota? */
- up(sem);
+ unlock_dquot(dquot);
return;
}
+ down(sem);
filp = dquot->dq_mnt->mnt_dquot.files[type];
offset = dqoff(dquot->dq_id);
fs = get_fs();
@@ -278,18 +278,15 @@
dquot->dq_flags &= ~DQ_MOD;
ret = 0;
if (filp)
- ret = filp->f_op->write(filp, (char *)&data,
+ ret = filp->f_op->write(filp, (char *)&dquot->dq_dqb,
sizeof(struct dqblk), &offset);
if (ret != sizeof(struct dqblk))
printk(KERN_WARNING "VFS: dquota write failed on dev %s\n",
kdevname(dquot->dq_dev));

- /*
- * Be sure that anybody didn't invalidated the dquot in the mean time...
- * Nasty but I don't see other choice when we don't want to lock dquot.
- */
- up(sem);
set_fs(fs);
+ up(sem);
+ unlock_dquot(dquot);

dqstats.writes++;
}
@@ -652,12 +649,31 @@
return dquot;
}

+/* Check whether this inode is quota file */
+static inline int is_quotafile(struct inode *inode)
+{
+ int cnt;
+ struct vfsmount *vfsmnt;
+ struct file **files;
+
+ vfsmnt = lookup_vfsmnt(inode->i_dev);
+ if (!vfsmnt)
+ return 0;
+ files = vfsmnt->mnt_dquot.files;
+ for (cnt = 0; cnt < MAXQUOTAS; cnt++)
+ if (files[cnt] && files[cnt]->f_dentry->d_inode == inode)
+ return 1;
+ return 0;
+}
+
static int dqinit_needed(struct inode *inode, short type)
{
int cnt;

if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)))
return 0;
+ if (is_quotafile(inode))
+ return 0;
if (type != -1)
return inode->i_dquot[type] == NODQUOT;
for (cnt = 0; cnt < MAXQUOTAS; cnt++)
@@ -1070,6 +1086,9 @@
if (S_ISREG(inode->i_mode) ||
S_ISDIR(inode->i_mode) ||
S_ISLNK(inode->i_mode)) {
+ /* We don't want to have quotas on quota files - nasty deadlocks possible */
+ if (is_quotafile(inode))
+ return;
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (type != -1 && cnt != type)
continue;
@@ -1513,6 +1532,7 @@
error = -EINVAL;
if (inode->i_size == 0 || (inode->i_size % sizeof(struct dqblk)) != 0)
goto out_f;
+ dquot_drop(inode); /* We don't want quota on quota files */

set_enable_flags(vfsmnt, type);
mnt_dquot->files[type] = f;
--- linux/CREDITS Sun Oct 31 18:24:35 1999
+++ linux/CREDITS Wed Nov 10 17:43:04 1999
@@ -997,6 +997,7 @@

N: Jan Kara
E: jack@atrey.karlin.mff.cuni.cz
+E: jack@suse.cz
D: Quota fixes for 2.2 kernel
D: Few other fixes in filesystem area (isofs, loopback)
W: http://atrey.karlin.mff.cuni.cz/~jack/

--oyUTqETQ0mS9luUI--

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/