summaryrefslogtreecommitdiffstats
path: root/fs/dquot.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/dquot.c')
-rw-r--r--fs/dquot.c67
1 files changed, 37 insertions, 30 deletions
diff --git a/fs/dquot.c b/fs/dquot.c
index 2c8778995..5236ed38e 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -13,12 +13,13 @@
* diskquota system. This implementation is not based on any BSD
* kernel sourcecode.
*
- * Version: $Id: dquot.c,v 5.6 1995/11/15 20:30:27 mvw Exp mvw $
+ * Version: $Id: dquot.c,v 1.11 1997/01/06 06:53:02 davem Exp $
*
* Author: Marco van Wieringen <mvw@mcs.ow.nl> <mvw@tnix.net>
*
* Fixes: Dmitry Gorodchanin <begemot@bgm.rosprint.net>, 11 Feb 96
* removed race conditions in dqput(), dqget() and iput().
+ * Andi Kleen removed all verify_area() calls, 31 Dec 96
*
* (C) Copyright 1994, 1995 Marco van Wieringen
*
@@ -34,6 +35,8 @@
#include <linux/tty.h>
#include <linux/malloc.h>
#include <linux/mount.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
#include <asm/uaccess.h>
@@ -585,15 +588,13 @@ static int set_dqblk(kdev_t dev, int id, short type, int flags, struct dqblk *dq
{
struct dquot *dquot;
struct dqblk dq_dqblk;
- int error;
if (dqblk == (struct dqblk *)NULL)
return(-EFAULT);
if (flags & QUOTA_SYSCALL) {
- if ((error = verify_area(VERIFY_READ, dqblk, sizeof(struct dqblk))) != 0)
- return(error);
- copy_from_user(&dq_dqblk, dqblk, sizeof(struct dqblk));
+ if (copy_from_user(&dq_dqblk, dqblk, sizeof(struct dqblk)))
+ return -EFAULT;
} else {
memcpy(&dq_dqblk, dqblk, sizeof(struct dqblk));
}
@@ -649,13 +650,10 @@ static int get_quota(kdev_t dev, int id, short type, struct dqblk *dqblk)
if (dqblk == (struct dqblk *)NULL)
return(-EFAULT);
- if ((error = verify_area(VERIFY_WRITE, dqblk, sizeof(struct dqblk))) != 0)
- return(error);
-
if ((dquot = dqget(dev, id, type)) != NODQUOT) {
- copy_to_user(dqblk, (char *)&dquot->dq_dqb, sizeof(struct dqblk));
+ error = copy_to_user(dqblk, (char *)&dquot->dq_dqb, sizeof(struct dqblk));
dqput(dquot);
- return(0);
+ return error ? -EFAULT : 0;
}
}
return(-ESRCH);
@@ -663,15 +661,10 @@ static int get_quota(kdev_t dev, int id, short type, struct dqblk *dqblk)
static int get_stats(caddr_t addr)
{
- int error;
-
- if ((error = verify_area(VERIFY_WRITE, addr, sizeof(struct dqstats))) != 0)
- return(error);
-
dqstats.allocated_dquots = nr_dquots;
dqstats.free_dquots = nr_free_dquots;
- copy_to_user(addr, (caddr_t)&dqstats, sizeof(struct dqstats));
- return(0);
+ return copy_to_user(addr, (caddr_t)&dqstats, sizeof(struct dqstats))
+ ? -EFAULT : 0;
}
/*
@@ -1014,12 +1007,15 @@ asmlinkage int sys_quotactl(int cmd, const char *special, int id, caddr_t addr)
int cmds = 0, type = 0, flags = 0;
struct inode *ino;
kdev_t dev;
+ int ret = -EINVAL;
+ lock_kernel();
cmds = cmd >> SUBCMDSHIFT;
type = cmd & SUBCMDMASK;
if ((u_int) type >= MAXQUOTAS)
- return(-EINVAL);
+ goto out;
+ ret = -EPERM;
switch (cmds) {
case Q_SYNC:
case Q_GETSTATS:
@@ -1027,33 +1023,39 @@ asmlinkage int sys_quotactl(int cmd, const char *special, int id, caddr_t addr)
case Q_GETQUOTA:
if (((type == USRQUOTA && current->uid != id) ||
(type == GRPQUOTA && current->gid != id)) && !fsuser())
- return(-EPERM);
+ goto out;
break;
default:
if (!fsuser())
- return(-EPERM);
+ goto out;
}
+ ret = -EINVAL;
if (special == (char *)NULL && (cmds == Q_SYNC || cmds == Q_GETSTATS))
dev = 0;
else {
if (namei(special, &ino))
- return(-EINVAL);
+ goto out;
dev = ino->i_rdev;
+ ret = -ENOTBLK;
if (!S_ISBLK(ino->i_mode)) {
iput(ino);
- return(-ENOTBLK);
+ goto out;
}
iput(ino);
}
+ ret = -EINVAL;
switch (cmds) {
case Q_QUOTAON:
- return(quota_on(dev, type, (char *) addr));
+ ret = quota_on(dev, type, (char *) addr);
+ goto out;
case Q_QUOTAOFF:
- return(quota_off(dev, type));
+ ret = quota_off(dev, type);
+ goto out;
case Q_GETQUOTA:
- return(get_quota(dev, id, type, (struct dqblk *) addr));
+ ret = get_quota(dev, id, type, (struct dqblk *) addr);
+ goto out;
case Q_SETQUOTA:
flags |= SET_QUOTA;
break;
@@ -1064,15 +1066,20 @@ asmlinkage int sys_quotactl(int cmd, const char *special, int id, caddr_t addr)
flags |= SET_QLIMIT;
break;
case Q_SYNC:
- return(sync_dquots(dev, type));
+ ret = sync_dquots(dev, type);
+ goto out;
case Q_GETSTATS:
- return(get_stats(addr));
+ ret = get_stats(addr);
default:
- return(-EINVAL);
+ goto out;
}
flags |= QUOTA_SYSCALL;
if (has_quota_enabled(dev, type))
- return(set_dqblk(dev, id, type, flags, (struct dqblk *) addr));
- return(-ESRCH);
+ ret = set_dqblk(dev, id, type, flags, (struct dqblk *) addr);
+ else
+ ret = -ESRCH;
+out:
+ unlock_kernel();
+ return ret;
}