Fix a deadlock in ffs_balloc(). This function was incorrectly obtaining a
authorMatthew Dillon <dillon@dragonflybsd.org>
Sun, 28 Aug 2005 23:23:10 +0000 (23:23 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Sun, 28 Aug 2005 23:23:10 +0000 (23:23 +0000)
commit481df61e2f649320c55231bf6fb0b0ffcb146eae
treec69f09a35e85e7ea7d3b3c796ab9e809c7d24e04
parent4971758070251405abdcc5096fa16c706b4f71c3
Fix a deadlock in ffs_balloc().  This function was incorrectly obtaining a
locked indirect buffer followed by a locked data block buffer, where as other
procedures in the kernel generally held a locked data buffer and then
called procedures which locked the indirect buffer.  Programs like rtorrent,
which write data into the mmap'd files whos blocks had not yet been
allocated, could easily deadlock the vnode.

A typical deadlock would be: syncer calls putpages->ffs_write->balloc->getblk->
allocbuf->(blocked on VM page with indirect block and data block locked), while
at the same time some process takes a write fault which locks the VM page and
then attempts to do a BMAP, blocking on the indirect block buffer.  Deadlock.

The fix for ffs_balloc() is simply to obtain the data buffer prior to
obtaining the indirect block(s).

Reported-by: Mitja Horvat
MFC: 1 week
sys/vfs/ufs/ffs_balloc.c