svn commit: r321347 - head/sys/ufs/ffs

Konstantin Belousov kib at FreeBSD.org
Fri Jul 21 18:28:28 UTC 2017


Author: kib
Date: Fri Jul 21 18:28:27 2017
New Revision: 321347
URL: https://svnweb.freebsd.org/changeset/base/321347

Log:
  Account for lock recursion when transfering snaplock to the vnode lock
  in ffs_snapremove().
  
  Apparently ffs_snapremove() may be called with the snap lock recursed,
  at least one trace demonstrated this when snapshot vnode was unlinked
  while synced.  It was inactivated from the syncer thread.
  
  Reported and tested by:	pho
  Sponsored by:	The FreeBSD Foundation
  MFC after:	2 weeks

Modified:
  head/sys/ufs/ffs/ffs_snapshot.c

Modified: head/sys/ufs/ffs/ffs_snapshot.c
==============================================================================
--- head/sys/ufs/ffs/ffs_snapshot.c	Fri Jul 21 18:14:06 2017	(r321346)
+++ head/sys/ufs/ffs/ffs_snapshot.c	Fri Jul 21 18:28:27 2017	(r321347)
@@ -1598,7 +1598,7 @@ ffs_snapremove(vp)
 	struct buf *ibp;
 	struct fs *fs;
 	ufs2_daddr_t numblks, blkno, dblk;
-	int error, loc, last;
+	int error, i, last, loc;
 	struct snapdata *sn;
 
 	ip = VTOI(vp);
@@ -1618,10 +1618,14 @@ ffs_snapremove(vp)
 		ip->i_nextsnap.tqe_prev = 0;
 		VI_UNLOCK(devvp);
 		lockmgr(&vp->v_lock, LK_EXCLUSIVE, NULL);
+		for (i = 0; i < sn->sn_lock.lk_recurse; i++)
+			lockmgr(&vp->v_lock, LK_EXCLUSIVE, NULL);
 		KASSERT(vp->v_vnlock == &sn->sn_lock,
 			("ffs_snapremove: lost lock mutation")); 
 		vp->v_vnlock = &vp->v_lock;
 		VI_LOCK(devvp);
+		while (sn->sn_lock.lk_recurse > 0)
+			lockmgr(&sn->sn_lock, LK_RELEASE, NULL);
 		lockmgr(&sn->sn_lock, LK_RELEASE, NULL);
 		try_free_snapdata(devvp);
 	} else


More information about the svn-src-head mailing list