Module Name: src Committed By: hannken Date: Tue Oct 13 12:38:14 UTC 2009
Modified Files: src/sys/ufs/ffs: ffs_snapshot.c Log Message: Fix a deadlock where fscow_disestablish() blocks because outstanding copy-on-write operations wait for si_snaplock. To generate a diff of this commit: cvs rdiff -u -r1.95 -r1.96 src/sys/ufs/ffs/ffs_snapshot.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/ufs/ffs/ffs_snapshot.c diff -u src/sys/ufs/ffs/ffs_snapshot.c:1.95 src/sys/ufs/ffs/ffs_snapshot.c:1.96 --- src/sys/ufs/ffs/ffs_snapshot.c:1.95 Sat Apr 18 14:58:07 2009 +++ src/sys/ufs/ffs/ffs_snapshot.c Tue Oct 13 12:38:14 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: ffs_snapshot.c,v 1.95 2009/04/18 14:58:07 tsutsui Exp $ */ +/* $NetBSD: ffs_snapshot.c,v 1.96 2009/10/13 12:38:14 hannken Exp $ */ /* * Copyright 2000 Marshall Kirk McKusick. All Rights Reserved. @@ -38,7 +38,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ffs_snapshot.c,v 1.95 2009/04/18 14:58:07 tsutsui Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ffs_snapshot.c,v 1.96 2009/10/13 12:38:14 hannken Exp $"); #if defined(_KERNEL_OPT) #include "opt_ffs.h" @@ -1311,7 +1311,6 @@ int error, loc, last; si = VFSTOUFS(mp)->um_snapinfo; - mutex_enter(&si->si_snaplock); /* * If active, delete from incore list (this snapshot may * already have been in the process of being deleted, so @@ -1327,21 +1326,19 @@ /* Roll back the list of preallocated blocks. */ xp = TAILQ_LAST(&si->si_snapshots, inodelst); si->si_snapblklist = xp->i_snapblklist; + si->si_gen++; + mutex_exit(&si->si_lock); } else { si->si_snapblklist = 0; si->si_gen++; mutex_exit(&si->si_lock); fscow_disestablish(mp, ffs_copyonwrite, devvp); - mutex_enter(&si->si_lock); } - si->si_gen++; - mutex_exit(&si->si_lock); if (ip->i_snapblklist != NULL) { free(ip->i_snapblklist, M_UFSMNT); ip->i_snapblklist = NULL; } } - mutex_exit(&si->si_snaplock); /* * Clear all BLK_NOCOPY fields. Pass any block claims to other * snapshots that want them (see ffs_snapblkfree below). @@ -1734,10 +1731,10 @@ mutex_enter(&si->si_lock); } } - if (vp) - fscow_disestablish(mp, ffs_copyonwrite, devvp); si->si_gen++; mutex_exit(&si->si_lock); + if (vp) + fscow_disestablish(mp, ffs_copyonwrite, devvp); } /*