From b424ca3013b04b65f5c901cda5fa8593384b340a Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Sun, 21 Sep 2008 02:58:31 +0000 Subject: [PATCH] HAMMER: Fix a couple of minor non-corrupting bugs in HAMMER. * Fix a few cases where the kmalloc space for hammer inodes can become exhausted. Add calls to hammer_inode_waitreclaims() in several places where modified inodes can build up without the related vnodes necessarily being VOP_OPEN()'d or VOP_CLOSE()'d. * Fix a deadlock which can occur in fsync(). fsync() was holding the vnode lock while waiting for the inode to sync. The inode sync can be held up indefinitely by dependancies on other vnodes, so holding the lock can result in a deadlock. * Fix a bug where ap->a_ctllen test results were being ignored. This path is only used by mountd. Reported-by: Francois Tigeot , Damian Lubosch --- sys/vfs/hammer/hammer_vnops.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/sys/vfs/hammer/hammer_vnops.c b/sys/vfs/hammer/hammer_vnops.c index 8732fe24a5..3f725b4723 100644 --- a/sys/vfs/hammer/hammer_vnops.c +++ b/sys/vfs/hammer/hammer_vnops.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/vfs/hammer/hammer_vnops.c,v 1.96 2008/08/09 07:04:16 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer_vnops.c,v 1.97 2008/09/21 02:58:31 dillon Exp $ */ #include @@ -186,8 +186,11 @@ hammer_vop_fsync(struct vop_fsync_args *ap) ++hammer_count_fsyncs; vfsync(ap->a_vp, ap->a_waitfor, 1, NULL, NULL); hammer_flush_inode(ip, HAMMER_FLUSH_SIGNAL); - if (ap->a_waitfor == MNT_WAIT) + if (ap->a_waitfor == MNT_WAIT) { + vn_unlock(ap->a_vp); hammer_wait_inode(ip); + vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY); + } return (ip->error); } @@ -1038,6 +1041,7 @@ hammer_vop_nlink(struct vop_nlink_args *ap) cache_setvp(nch, ap->a_vp); } hammer_done_transaction(&trans); + hammer_inode_waitreclaims(dip->hmp); return (error); } @@ -1108,6 +1112,7 @@ hammer_vop_nmkdir(struct vop_nmkdir_args *ap) } } hammer_done_transaction(&trans); + hammer_inode_waitreclaims(dip->hmp); return (error); } @@ -1873,6 +1878,8 @@ done: if (error == 0) hammer_modify_inode(ip, modflags); hammer_done_transaction(&trans); + if (ap->a_vp->v_opencount == 0) + hammer_inode_waitreclaims(ip->hmp); return (error); } @@ -2027,7 +2034,8 @@ hammer_vop_mountctl(struct vop_mountctl_args *ap) case MOUNTCTL_SET_EXPORT: if (ap->a_ctllen != sizeof(struct export_args)) error = EINVAL; - error = hammer_vfs_export(mp, ap->a_op, + else + error = hammer_vfs_export(mp, ap->a_op, (const struct export_args *)ap->a_ctl); break; default: -- 2.41.0