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);
}
/*