]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/commit
MFC r244014 (by ken):
authormav <mav@ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f>
Thu, 21 Feb 2013 19:02:29 +0000 (19:02 +0000)
committermav <mav@ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f>
Thu, 21 Feb 2013 19:02:29 +0000 (19:02 +0000)
commitcf71d7a20243037ae3b3841955df15204af32005
tree24f4390ba28eb401673439db2ef50cd1ac4213b1
parentd81cf0a3f36273cd775362dbd4c37189460477e1
MFC r244014 (by ken):

Fix a device departure bug for the the pass(4), enc(4), sg(4) and ch(4)
drivers.

The bug occurrs when a userland process has the driver instance
open and the underlying device goes away.  We get the devfs
callback that the device node has been destroyed, but not all of
the closes necessary to fully decrement the reference count on the
CAM peripheral.

The reason is that once devfs calls back and says the device has
been destroyed, it is moved off to deadfs, and devfs guarantees
that there will be no more open or close calls.  So the solution
is to keep track of how many outstanding open calls there are on
the device, and just release that many references when we get the
callback from devfs.

scsi_pass.c,
scsi_enc.c,
scsi_enc_internal.h:    Add an open count to the softc in these
                        drivers.  Increment it on open and
                        decrement it on close.

                        When we get a devfs callback to say that
                        the device node has gone away, decrement
                        the peripheral reference count by the
                        number of still outstanding opens.

                        Make sure we don't access the peripheral
                        with cam_periph_unlock() after what might
                        be the final call to
                        cam_periph_release_locked().  The
                        peripheral might have been freed, and we
                        will be dereferencing freed memory.

scsi_ch.c,
scsi_sg.c:              For the ch(4) and sg(4) drivers, add the
                        same changes described above, and in
                        addition, fix another bug that was
                        previously fixed in the pass(4) and enc(4)
                        drivers.

                        These drivers were calling destroy_dev()
                        from their cleanup routine, but that could
                        cause a deadlock because the cleanup
                        routine could be indirectly called from
                        the driver's close routine.  This would
                        cause a deadlock, because the device node
                        is being held open by the active close
                        call, and can't be destroyed.

git-svn-id: svn://svn.freebsd.org/base/stable/9@247115 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f
sys/cam/scsi/scsi_ch.c
sys/cam/scsi/scsi_enc.c
sys/cam/scsi/scsi_enc_internal.h
sys/cam/scsi/scsi_pass.c
sys/cam/scsi/scsi_sg.c