* Dag-Erling Smorgrav <[EMAIL PROTECTED]> [020317 19:27] wrote:
> 
> ...the process has no open files at all, because...
> 
> (kgdb) p p->p_pid
> $4 = 10099
> (kgdb) p p->p_comm
> $5 = "wc\000oot", '\000' <repeats 13 times>
> (kgdb) p p->p_stat
> $6 = 3
> (kgdb) p/x p->p_flag
> $7 = 0x6000
> 
> ...it's exiting, and fdfree() has already run.
> 
> Solution: p->p_fd must be protected by p's proc lock; fdfree() must
> set it to NULL immediately after freeing it; checkdirs() must lock
> each process before examining its fd list.
> 
> Other problem spotted while investigating this: fdfree() can fail
> silently; fdfree() should panic if fdp->fd_refcnt is non-zero.

Please let me know if this works for you.

Index: vfs_syscalls.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.231
diff -u -r1.231 vfs_syscalls.c
--- vfs_syscalls.c      12 Mar 2002 04:00:10 -0000      1.231
+++ vfs_syscalls.c      18 Mar 2002 06:23:41 -0000
@@ -451,10 +451,14 @@
                return;
        sx_slock(&allproc_lock);
        LIST_FOREACH(p, &allproc, p_list) {
+               PROC_LOCK(p);
                fdp = p->p_fd;
-               if (fdp == NULL)
+               if (fdp == NULL) {
+                       PROC_UNLOCK(p);
                        continue;
+               }
                FILEDESC_LOCK(fdp);
+               PROC_UNLOCK(p);
                if (fdp->fd_cdir == olddp) {
                        VREF(newdp);
                        fdp->fd_cdir = newdp;
Index: kern_descrip.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_descrip.c,v
retrieving revision 1.128
diff -u -r1.128 kern_descrip.c
--- kern_descrip.c      15 Mar 2002 08:03:46 -0000      1.128
+++ kern_descrip.c      18 Mar 2002 06:23:39 -0000
@@ -1321,19 +1321,26 @@
 fdfree(td)
        struct thread *td;
 {
-       register struct filedesc *fdp = td->td_proc->p_fd;
+       register struct filedesc *fdp;
        struct file **fpp;
        register int i;
 
+       PROC_LOCK(td);
+       fdp = td->td_proc->p_fd;
        /* Certain daemons might not have file descriptors. */
-       if (fdp == NULL)
+       if (fdp == NULL) {
+               PROC_UNLOCK(td);
                return;
+       }
 
        FILEDESC_LOCK(fdp);
        if (--fdp->fd_refcnt > 0) {
                FILEDESC_UNLOCK(fdp);
+               PROC_UNLOCK(td);
                return;
        }
+       td->td_proc->p_fd = NULL;
+       PROC_UNLOCK(td);
        /*
         * we are the last reference to the structure, we can
         * safely assume it will not change out from under us.

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to