Skip site navigation (1)Skip section navigation (2)
Date:      18 Mar 2002 10:00:42 +0100
From:      Dag-Erling Smorgrav <des@ofug.org>
To:        Alfred Perlstein <alfred@freebsd.org>
Cc:        Kris Kennaway <kris@obsecurity.org>, current@FreeBSD.org, fs@FreeBSD.org
Subject:   Re: panic: bwrite: buffer is not busy???
Message-ID:  <xzpadt6p7wl.fsf@flood.ping.uio.no>
In-Reply-To: <20020318071623.GD894@elvis.mu.org>
References:  <20020317124958.A34008@xor.obsecurity.org> <xzpadt6r1xr.fsf@flood.ping.uio.no> <20020318061739.GB894@elvis.mu.org> <xzpvgbupdqa.fsf@flood.ping.uio.no> <20020318071623.GD894@elvis.mu.org>

next in thread | previous in thread | raw e-mail | index | archive | help
Alfred Perlstein <alfred@freebsd.org> writes:
> It was untested. :)  I'm sure you can fix it, I've got to get some
> sleep, let me know if it works for you.

Sure.  Turns out the patch doesn't work, because closef() needs
p->p_fd to be valid.  This is really tricky; you either need to
protect *every* access to p->p_fd with the proc lock, or figure out
some other way of handling things.

fdfree() is currently used in a handful of places:

 - in kern_exec.c, an fdcopy() / fdfree() combo is used to unshare the
   file table in case it is shared (vfork()); this is a waste of time
   unless the table actually *is* shared, which is easy to check.
   This could replaced by a single call to a new function,
   fdunshare(), which checks the reference count and does an fdcopy()
   if it is greater than 1.

 - in kern_exit.c, fdfree() is used to close all file descriptors and
   destroy the table before turning the process into a zombie (this is
   the one that's giving us trouble).  This could be handled by an
   fdclear() function, with the actual destruction of the filedesc and
   its mutex (performed by a new fddestroy() function?) left off until
   the last possible moment, after the process has been removed from
   the process table.

 - in kern_fork.c, one case where an fdcopy() / fdfree() combo is used
   to unshare the file table (see comment above about fdunshare()) and
   one case where fdfree() / fdinit() is used to completely clear the
   file table (RFCFDG case).  The latter could be handled by a new
   fdclear() function.

 - in vfs_aio.c, fdfree() is called once to destroy the aio daemon's
   file table, and twice to dereference the client's file table after
   it has been temporarily "borrowed" by the aio daemon.  This code
   gives me a headache, for several reasons (one of which is a
   potential race condition similar to the one we're already seeing in
   kern_exit.c; another is its rather cavalier treatment of curproc)

DES
-- 
Dag-Erling Smorgrav - des@ofug.org

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?xzpadt6p7wl.fsf>