Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/ufs/ffs Fix a deadlock where fscow_disestablish() blocks...



details:   https://anonhg.NetBSD.org/src/rev/f8f9df8dc4c5
branches:  trunk
changeset: 748095:f8f9df8dc4c5
user:      hannken <hannken%NetBSD.org@localhost>
date:      Tue Oct 13 12:38:14 2009 +0000

description:
Fix a deadlock where fscow_disestablish() blocks because outstanding
copy-on-write operations wait for si_snaplock.

diffstat:

 sys/ufs/ffs/ffs_snapshot.c |  15 ++++++---------
 1 files changed, 6 insertions(+), 9 deletions(-)

diffs (63 lines):

diff -r 0c063be21752 -r f8f9df8dc4c5 sys/ufs/ffs/ffs_snapshot.c
--- a/sys/ufs/ffs/ffs_snapshot.c        Tue Oct 13 12:37:19 2009 +0000
+++ b/sys/ufs/ffs/ffs_snapshot.c        Tue Oct 13 12:38:14 2009 +0000
@@ -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);
                }
        }
+       si->si_gen++;
+       mutex_exit(&si->si_lock);
        if (vp)
                fscow_disestablish(mp, ffs_copyonwrite, devvp);
-       si->si_gen++;
-       mutex_exit(&si->si_lock);
 }
 
 /*



Home | Main Index | Thread Index | Old Index