Module Name: src Committed By: hannken Date: Fri Feb 18 08:39:13 UTC 2011
Modified Files: src/sys/ufs/ffs: ffs_snapshot.c Log Message: Revert rev. 1.101. Dead snapshots would hang around until unmount. Adresses PR #44568 (WAPBL doens't play nice with snapshots). To generate a diff of this commit: cvs rdiff -u -r1.103 -r1.104 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.103 src/sys/ufs/ffs/ffs_snapshot.c:1.104 --- src/sys/ufs/ffs/ffs_snapshot.c:1.103 Wed Feb 16 19:43:50 2011 +++ src/sys/ufs/ffs/ffs_snapshot.c Fri Feb 18 08:39:13 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: ffs_snapshot.c,v 1.103 2011/02/16 19:43:50 hannken Exp $ */ +/* $NetBSD: ffs_snapshot.c,v 1.104 2011/02/18 08:39:13 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.103 2011/02/16 19:43:50 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ffs_snapshot.c,v 1.104 2011/02/18 08:39:13 hannken Exp $"); #if defined(_KERNEL_OPT) #include "opt_ffs.h" @@ -280,7 +280,6 @@ fs->fs_snapinum[snaploc] = ip->i_number; mutex_enter(&si->si_lock); - vref(vp); if (is_active_snapshot(si, ip)) panic("ffs_snapshot: %"PRIu64" already on list", ip->i_number); TAILQ_INSERT_TAIL(&si->si_snapshots, ip, i_nextsnap); @@ -394,7 +393,8 @@ (void) ffs_truncate(vp, (off_t)0, 0, NOCRED); UFS_WAPBL_END(mp); } - } + } else + vref(vp); return (error); } @@ -1313,8 +1313,10 @@ if (xp == ip) break; mutex_exit(&si->si_lock); + if (xp != NULL) + vrele(ITOV(ip)); #ifdef DEBUG - if (snapdebug && xp == NULL) + else if (snapdebug) printf("ffs_snapgone: lost snapshot vnode %llu\n", (unsigned long long)ip->i_number); #endif @@ -1382,7 +1384,6 @@ free(ip->i_snapblklist, M_UFSMNT); ip->i_snapblklist = NULL; } - vrele(vp); } else mutex_exit(&si->si_lock); /* @@ -1763,25 +1764,28 @@ ffs_snapshot_unmount(struct mount *mp) { struct vnode *devvp = VFSTOUFS(mp)->um_devvp; - struct inode *ip; + struct inode *xp; + struct vnode *vp = NULL; struct snap_info *si; - bool list_empty = true; si = VFSTOUFS(mp)->um_snapinfo; mutex_enter(&si->si_lock); - while ((ip = TAILQ_FIRST(&si->si_snapshots)) != 0) { - list_empty = false; - TAILQ_REMOVE(&si->si_snapshots, ip, i_nextsnap); - if (ip->i_snapblklist == si->si_snapblklist) + while ((xp = TAILQ_FIRST(&si->si_snapshots)) != 0) { + vp = ITOV(xp); + TAILQ_REMOVE(&si->si_snapshots, xp, i_nextsnap); + if (xp->i_snapblklist == si->si_snapblklist) si->si_snapblklist = NULL; - free(ip->i_snapblklist, M_UFSMNT); - si->si_gen++; - mutex_exit(&si->si_lock); - vrele(ITOV(ip)); - mutex_enter(&si->si_lock); + free(xp->i_snapblklist, M_UFSMNT); + if (xp->i_nlink > 0) { + si->si_gen++; + mutex_exit(&si->si_lock); + vrele(vp); + mutex_enter(&si->si_lock); + } } + si->si_gen++; mutex_exit(&si->si_lock); - if (! list_empty) + if (vp) fscow_disestablish(mp, ffs_copyonwrite, devvp); }