don't make F_GETLK or the common case of F_UNLCK fail for per-user limit.

This commit is contained in:
yamt 2009-06-10 22:34:35 +00:00
parent 5216f042b0
commit 724fd50176

View File

@ -1,4 +1,4 @@
/* $NetBSD: vfs_lockf.c,v 1.70 2009/06/10 22:23:15 yamt Exp $ */
/* $NetBSD: vfs_lockf.c,v 1.71 2009/06/10 22:34:35 yamt Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vfs_lockf.c,v 1.70 2009/06/10 22:23:15 yamt Exp $");
__KERNEL_RCSID(0, "$NetBSD: vfs_lockf.c,v 1.71 2009/06/10 22:34:35 yamt Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -190,11 +190,12 @@ lf_printlist(const char *tag, struct lockf *lock)
* 0 - always allocate. 1 - cutoff at limit. 2 - cutoff at double limit.
*/
static struct lockf *
lf_alloc(uid_t uid, int allowfail)
lf_alloc(int allowfail)
{
struct uidinfo *uip;
struct lockf *lock;
u_long lcnt;
const uid_t uid = kauth_cred_geteuid(kauth_cred_get());
uip = uid_find(uid);
lcnt = atomic_inc_ulong_nv(&uip->ui_lockcnt);
@ -807,7 +808,6 @@ lf_getlock(struct lockf *lock, struct flock *fl)
int
lf_advlock(struct vop_advlock_args *ap, struct lockf **head, off_t size)
{
struct lwp *l = curlwp;
struct flock *fl = ap->a_fl;
struct lockf *lock = NULL;
struct lockf *sparelock;
@ -852,7 +852,7 @@ lf_advlock(struct vop_advlock_args *ap, struct lockf **head, off_t size)
/*
* Byte-range lock might need one more lock.
*/
sparelock = lf_alloc(kauth_cred_geteuid(l->l_cred), 0);
sparelock = lf_alloc(0);
if (sparelock == NULL) {
error = ENOMEM;
goto quit;
@ -869,8 +869,28 @@ lf_advlock(struct vop_advlock_args *ap, struct lockf **head, off_t size)
return EINVAL;
}
lock = lf_alloc(kauth_cred_geteuid(l->l_cred),
ap->a_op != F_UNLCK ? 1 : 2);
if (fl->l_len == 0)
end = -1;
else
end = start + fl->l_len - 1;
switch (ap->a_op) {
case F_SETLK:
lock = lf_alloc(1);
break;
case F_UNLCK:
if (start == 0 || end == -1) {
/* never split */
lock = lf_alloc(0);
} else {
/* might split */
lock = lf_alloc(2);
}
break;
case F_GETLK:
lock = lf_alloc(0);
break;
}
if (lock == NULL) {
error = ENOMEM;
goto quit;
@ -889,10 +909,6 @@ lf_advlock(struct vop_advlock_args *ap, struct lockf **head, off_t size)
}
}
if (fl->l_len == 0)
end = -1;
else
end = start + fl->l_len - 1;
/*
* Create the lockf structure.
*/