Re: Quota broken in 2.1.61 - patch included

Linus Torvalds (torvalds@transmeta.com)
Sat, 1 Nov 1997 11:08:34 -0800 (PST)


On Sat, 1 Nov 1997, James Box wrote:
>
> In 2.1.60, quotaon -avug failed with a kernel oops during startup.
> 2.1.61 didn't fix it so I decided to investigate.
>
> I tracked the problem down to fs/dquot.c, where the read/write file
> operation calls hadn't been converted to the new argument lists.
> I'm not 100% sure I got the arguments right, so someone might want
> to check it first, but it fixed quota for me.
>
> Here's the patch:

The patch looks ok, however there is now a better way to do this. Rather
than doing the lseek, the quota stuff might as well just use the new
read/write functionality that allows you to specify an offset directly.

I don't use quotas myself, could you (and anybody else on the kernel list
that does use quotas) verify whether this alternate patch (relative to a
clean 2.1.61) works for you?

Btw, this is a perfect example of a new better interface simplifying code.
Thanks to Richard for doing the gruntwork for pread/pwrite.

Linus

-----
--- v2.1.61/linux/fs/dquot.c Thu Sep 11 09:02:23 1997
+++ linux/fs/dquot.c Sat Nov 1 10:59:56 1997
@@ -223,25 +223,17 @@
short type = dquot->dq_type;
struct file *filp = dquot->dq_mnt->mnt_quotas[type];
unsigned long fs;
+ loff_t offset;

if (!(dquot->dq_flags & DQ_MOD) || (filp == (struct file *)NULL))
return;
lock_dquot(dquot);
down(&dquot->dq_mnt->mnt_sem);
- if (filp->f_op->llseek) {
- if (filp->f_op->llseek(filp->f_dentry->d_inode, filp,
- dqoff(dquot->dq_id), 0) != dqoff(dquot->dq_id)) {
- up(&dquot->dq_mnt->mnt_sem);
- unlock_dquot(dquot);
- return;
- }
- } else
- filp->f_pos = dqoff(dquot->dq_id);
+ offset = dqoff(dquot->dq_id);
fs = get_fs();
set_fs(KERNEL_DS);

- if (filp->f_op->write(filp->f_dentry->d_inode, filp,
- (char *)&dquot->dq_dqb, sizeof(struct dqblk)) == sizeof(struct dqblk))
+ if (filp->f_op->write(filp, (char *)&dquot->dq_dqb, sizeof(struct dqblk), &offset) == sizeof(struct dqblk))
dquot->dq_flags &= ~DQ_MOD;

up(&dquot->dq_mnt->mnt_sem);
@@ -255,23 +247,16 @@
short type = dquot->dq_type;
struct file *filp = dquot->dq_mnt->mnt_quotas[type];
unsigned long fs;
+ loff_t offset;

if (filp == (struct file *)NULL)
return;
lock_dquot(dquot);
down(&dquot->dq_mnt->mnt_sem);
- if (filp->f_op->llseek) {
- if (filp->f_op->llseek(filp->f_dentry->d_inode, filp,
- dqoff(dquot->dq_id), 0) != dqoff(dquot->dq_id)) {
- up(&dquot->dq_mnt->mnt_sem);
- unlock_dquot(dquot);
- return;
- }
- } else
- filp->f_pos = dqoff(dquot->dq_id);
+ offset = dqoff(dquot->dq_id);
fs = get_fs();
set_fs(KERNEL_DS);
- filp->f_op->read(filp->f_dentry->d_inode, filp, (char *)&dquot->dq_dqb, sizeof(struct dqblk));
+ filp->f_op->read(filp, (char *)&dquot->dq_dqb, sizeof(struct dqblk), &offset);
up(&dquot->dq_mnt->mnt_sem);
set_fs(fs);
if (dquot->dq_bhardlimit == 0 && dquot->dq_bsoftlimit == 0 &&
-----