projects
/
unix-history
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
tags
|
clone url
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
have to protect acct_process from acctwatch closing the vnode
[unix-history]
/
usr
/
src
/
sys
/
kern
/
kern_acct.c
diff --git
a/usr/src/sys/kern/kern_acct.c
b/usr/src/sys/kern/kern_acct.c
index
66a9e8a
..
235c2e0
100644
(file)
--- a/
usr/src/sys/kern/kern_acct.c
+++ b/
usr/src/sys/kern/kern_acct.c
@@
-9,7
+9,7
@@
*
* %sccs.include.proprietary.c%
*
*
* %sccs.include.proprietary.c%
*
- * @(#)kern_acct.c 8.
3
(Berkeley) %G%
+ * @(#)kern_acct.c 8.
6
(Berkeley) %G%
*/
#include <sys/param.h>
*/
#include <sys/param.h>
@@
-98,7
+98,9
@@
acct(p, uap, retval)
/*
* Periodically check the file system to see if accounting
/*
* Periodically check the file system to see if accounting
- * should be turned on or off.
+ * should be turned on or off. Beware the case where the vnode
+ * has been vgone()'d out from underneath us, e.g. when the file
+ * system containing the accounting file has been forcibly unmounted.
*/
/* ARGSUSED */
void
*/
/* ARGSUSED */
void
@@
-108,6
+110,11
@@
acctwatch(a)
struct statfs sb;
if (savacctp) {
struct statfs sb;
if (savacctp) {
+ if (savacctp->v_type == VBAD) {
+ (void) vn_close(savacctp, FWRITE, NOCRED, NULL);
+ savacctp = NULL;
+ return;
+ }
(void)VFS_STATFS(savacctp->v_mount, &sb, (struct proc *)0);
if (sb.f_bavail > acctresume * sb.f_blocks / 100) {
acctp = savacctp;
(void)VFS_STATFS(savacctp->v_mount, &sb, (struct proc *)0);
if (sb.f_bavail > acctresume * sb.f_blocks / 100) {
acctp = savacctp;
@@
-117,6
+124,11
@@
acctwatch(a)
} else {
if (acctp == NULL)
return;
} else {
if (acctp == NULL)
return;
+ if (acctp->v_type == VBAD) {
+ (void) vn_close(acctp, FWRITE, NOCRED, NULL);
+ acctp = NULL;
+ return;
+ }
(void)VFS_STATFS(acctp->v_mount, &sb, (struct proc *)0);
if (sb.f_bavail <= acctsuspend * sb.f_blocks / 100) {
savacctp = acctp;
(void)VFS_STATFS(acctp->v_mount, &sb, (struct proc *)0);
if (sb.f_bavail <= acctsuspend * sb.f_blocks / 100) {
savacctp = acctp;
@@
-137,18
+149,25
@@
acct_process(p)
register struct rusage *ru;
struct vnode *vp;
struct timeval t, ut, st;
register struct rusage *ru;
struct vnode *vp;
struct timeval t, ut, st;
- int i, s;
+ int
error,
i, s;
struct acct acctbuf;
register struct acct *ap = &acctbuf;
struct acct acctbuf;
register struct acct *ap = &acctbuf;
- if ((vp = acctp) == NULL)
+ s = splclock();
+ if ((vp = acctp) == NULL) {
+ splx(s);
return (0);
return (0);
+ }
+ if (vp->v_type == VBAD) {
+ (void) vn_close(vp, FWRITE, NOCRED, NULL);
+ acctp = NULL;
+ splx(s);
+ return (0);
+ }
bcopy(p->p_comm, ap->ac_comm, sizeof(ap->ac_comm));
ru = &p->p_stats->p_ru;
calcru(p, &ut, &st, NULL);
bcopy(p->p_comm, ap->ac_comm, sizeof(ap->ac_comm));
ru = &p->p_stats->p_ru;
calcru(p, &ut, &st, NULL);
- s = splclock();
t = time;
t = time;
- splx(s);
ap->ac_utime = compress(ut.tv_sec, ut.tv_usec);
ap->ac_stime = compress(st.tv_sec, st.tv_usec);
timevalsub(&t, &p->p_stats->p_start);
ap->ac_utime = compress(ut.tv_sec, ut.tv_usec);
ap->ac_stime = compress(st.tv_sec, st.tv_usec);
timevalsub(&t, &p->p_stats->p_start);
@@
-168,10
+187,12
@@
acct_process(p)
else
ap->ac_tty = NODEV;
ap->ac_flag = p->p_acflag;
else
ap->ac_tty = NODEV;
ap->ac_flag = p->p_acflag;
-
LEASE_CHECK
(vp, p, p->p_ucred, LEASE_WRITE);
-
return (
vn_rdwr(UIO_WRITE, vp, (caddr_t)ap, sizeof (acctbuf), (off_t)0,
+
VOP_LEASE
(vp, p, p->p_ucred, LEASE_WRITE);
+
error =
vn_rdwr(UIO_WRITE, vp, (caddr_t)ap, sizeof (acctbuf), (off_t)0,
UIO_SYSSPACE, IO_UNIT|IO_APPEND, p->p_ucred, (int *)0,
UIO_SYSSPACE, IO_UNIT|IO_APPEND, p->p_ucred, (int *)0,
- (struct proc *)0));
+ (struct proc *)0);
+ splx(s);
+ return (error);
}
/*
}
/*