From owner-svn-src-stable@FreeBSD.ORG Wed Sep 28 19:38:48 2011 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 28089106564A; Wed, 28 Sep 2011 19:38:48 +0000 (UTC) (envelope-from mckusick@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 0D6968FC21; Wed, 28 Sep 2011 19:38:48 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id p8SJclMW087022; Wed, 28 Sep 2011 19:38:47 GMT (envelope-from mckusick@svn.freebsd.org) Received: (from mckusick@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p8SJclbt087020; Wed, 28 Sep 2011 19:38:47 GMT (envelope-from mckusick@svn.freebsd.org) Message-Id: <201109281938.p8SJclbt087020@svn.freebsd.org> From: Kirk McKusick Date: Wed, 28 Sep 2011 19:38:47 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-other@freebsd.org X-SVN-Group: stable-other MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r225851 - stable/9/sys/ufs/ffs X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Sep 2011 19:38:48 -0000 Author: mckusick Date: Wed Sep 28 19:38:47 2011 New Revision: 225851 URL: http://svn.freebsd.org/changeset/base/225851 Log: MFC r225807: This update eliminates a lock-order reversal warning discovered whle tracking down the system hang reported in kern/160662 and corrected in revision 225806 (MFC'ed as 225850). The LOR is not the cause of the system hang and indeed cannot cause an actual deadlock. However, it can be easily eliminated by defering the acquisition of a buflock until after all the vnode locks have been acquired. As journaled soft updates first appeared in 9.0, this will be the only MFC of this change. Approved by: re (kib) Reported by: Hans Ottevanger PR: kern/160662 Modified: stable/9/sys/ufs/ffs/ffs_snapshot.c Modified: stable/9/sys/ufs/ffs/ffs_snapshot.c ============================================================================== --- stable/9/sys/ufs/ffs/ffs_snapshot.c Wed Sep 28 19:36:21 2011 (r225850) +++ stable/9/sys/ufs/ffs/ffs_snapshot.c Wed Sep 28 19:38:47 2011 (r225851) @@ -212,7 +212,7 @@ ffs_snapshot(mp, snapfile) struct fs *copy_fs = NULL, *fs; struct thread *td = curthread; struct inode *ip, *xp; - struct buf *bp, *nbp, *ibp, *sbp = NULL; + struct buf *bp, *nbp, *ibp; struct nameidata nd; struct mount *wrtmp; struct vattr vat; @@ -460,21 +460,14 @@ restart: * Grab a copy of the superblock and its summary information. * We delay writing it until the suspension is released below. */ - error = bread(vp, lblkno(fs, fs->fs_sblockloc), fs->fs_bsize, - KERNCRED, &sbp); - if (error) { - brelse(sbp); - sbp = NULL; - goto out1; - } - loc = blkoff(fs, fs->fs_sblockloc); - copy_fs = (struct fs *)(sbp->b_data + loc); + copy_fs = malloc((u_long)fs->fs_bsize, M_UFSMNT, M_WAITOK); bcopy(fs, copy_fs, fs->fs_sbsize); if ((fs->fs_flags & (FS_UNCLEAN | FS_NEEDSFSCK)) == 0) copy_fs->fs_clean = 1; size = fs->fs_bsize < SBLOCKSIZE ? fs->fs_bsize : SBLOCKSIZE; if (fs->fs_sbsize < size) - bzero(&sbp->b_data[loc + fs->fs_sbsize], size - fs->fs_sbsize); + bzero(&((char *)copy_fs)[fs->fs_sbsize], + size - fs->fs_sbsize); size = blkroundup(fs, fs->fs_cssize); if (fs->fs_contigsumsize > 0) size += fs->fs_ncg * sizeof(int32_t); @@ -490,8 +483,8 @@ restart: len, KERNCRED, &bp)) != 0) { brelse(bp); free(copy_fs->fs_csp, M_UFSMNT); - bawrite(sbp); - sbp = NULL; + free(copy_fs, M_UFSMNT); + copy_fs = NULL; goto out1; } bcopy(bp->b_data, space, (u_int)len); @@ -606,8 +599,8 @@ loop: vdrop(xvp); if (error) { free(copy_fs->fs_csp, M_UFSMNT); - bawrite(sbp); - sbp = NULL; + free(copy_fs, M_UFSMNT); + copy_fs = NULL; MNT_VNODE_FOREACH_ABORT(mp, mvp); goto out1; } @@ -621,8 +614,8 @@ loop: error = softdep_journal_lookup(mp, &xvp); if (error) { free(copy_fs->fs_csp, M_UFSMNT); - bawrite(sbp); - sbp = NULL; + free(copy_fs, M_UFSMNT); + copy_fs = NULL; goto out1; } xp = VTOI(xvp); @@ -688,8 +681,8 @@ loop: VI_UNLOCK(devvp); ASSERT_VOP_LOCKED(vp, "ffs_snapshot vp"); out1: - KASSERT((sn != NULL && sbp != NULL && error == 0) || - (sn == NULL && sbp == NULL && error != 0), + KASSERT((sn != NULL && copy_fs != NULL && error == 0) || + (sn == NULL && copy_fs == NULL && error != 0), ("email phk@ and mckusick@")); /* * Resume operation on filesystem. @@ -703,7 +696,7 @@ out1: vp->v_mount->mnt_stat.f_mntonname, (long)endtime.tv_sec, endtime.tv_nsec / 1000000, redo, fs->fs_ncg); } - if (sbp == NULL) + if (copy_fs == NULL) goto out; /* * Copy allocation information from all the snapshots in @@ -793,6 +786,15 @@ out1: space = (char *)space + fs->fs_bsize; bawrite(nbp); } + error = bread(vp, lblkno(fs, fs->fs_sblockloc), fs->fs_bsize, + KERNCRED, &nbp); + if (error) { + brelse(nbp); + } else { + loc = blkoff(fs, fs->fs_sblockloc); + bcopy((char *)copy_fs, &nbp->b_data[loc], fs->fs_bsize); + bawrite(nbp); + } /* * As this is the newest list, it is the most inclusive, so * should replace the previous list. @@ -822,7 +824,8 @@ out1: vrele(vp); /* Drop extra reference */ done: free(copy_fs->fs_csp, M_UFSMNT); - bawrite(sbp); + free(copy_fs, M_UFSMNT); + copy_fs = NULL; out: NDFREE(&nd, NDF_ONLY_PNBUF); if (saved_nice > 0) {