From owner-svn-src-head@FreeBSD.ORG Thu Dec 30 10:41:17 2010 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id CC9A1106566B; Thu, 30 Dec 2010 10:41:17 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id A183F8FC0A; Thu, 30 Dec 2010 10:41:17 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id oBUAfHI2037199; Thu, 30 Dec 2010 10:41:17 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id oBUAfHVF037197; Thu, 30 Dec 2010 10:41:17 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <201012301041.oBUAfHVF037197@svn.freebsd.org> From: Konstantin Belousov Date: Thu, 30 Dec 2010 10:41:17 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r216817 - head/sys/ufs/ffs X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 30 Dec 2010 10:41:17 -0000 Author: kib Date: Thu Dec 30 10:41:17 2010 New Revision: 216817 URL: http://svn.freebsd.org/changeset/base/216817 Log: In indir_trunc(), when processing jnewblk entries that are not written to the disk, recurse to handle indirect blocks of next level that are hidden by the corresponding entry. In collaboration with: pho Reviewed by: jeff, mckusick Tested by: mckusick, pho Modified: head/sys/ufs/ffs/ffs_softdep.c Modified: head/sys/ufs/ffs/ffs_softdep.c ============================================================================== --- head/sys/ufs/ffs/ffs_softdep.c Thu Dec 30 09:46:45 2010 (r216816) +++ head/sys/ufs/ffs/ffs_softdep.c Thu Dec 30 10:41:17 2010 (r216817) @@ -6140,17 +6140,20 @@ indir_trunc(freework, dbn, lbn) ufs1fmt = 0; bap2 = (ufs2_daddr_t *)bp->b_data; } + + if (needj) + freework->fw_ref += NINDIR(fs) + 1; + /* * Reclaim indirect blocks which never made it to disk. */ cnt = 0; LIST_FOREACH_SAFE(wk, &wkhd, wk_list, wkn) { - struct workhead freewk; if (wk->wk_type != D_JNEWBLK) continue; - WORKLIST_REMOVE_UNLOCKED(wk); - LIST_INIT(&freewk); - WORKLIST_INSERT_UNLOCKED(&freewk, wk); + ACQUIRE_LOCK(&lk); + WORKLIST_REMOVE(wk); + FREE_LOCK(&lk); jnewblk = WK_JNEWBLK(wk); if (jnewblk->jn_lbn > 0) i = (jnewblk->jn_lbn - -lbn) / lbnadd; @@ -6158,8 +6161,8 @@ indir_trunc(freework, dbn, lbn) i = (-(jnewblk->jn_lbn + level - 1) - -(lbn + level)) / lbnadd; KASSERT(i >= 0 && i < NINDIR(fs), - ("indir_trunc: Index out of range %d parent %jd lbn %jd", - i, lbn, jnewblk->jn_lbn)); + ("indir_trunc: Index out of range %d parent %jd lbn %jd level %d", + i, lbn, jnewblk->jn_lbn, level)); /* Clear the pointer so it isn't found below. */ if (ufs1fmt) { nb = bap1[i]; @@ -6171,13 +6174,29 @@ indir_trunc(freework, dbn, lbn) KASSERT(nb == jnewblk->jn_blkno, ("indir_trunc: Block mismatch %jd != %jd", nb, jnewblk->jn_blkno)); - ffs_blkfree(ump, fs, freeblks->fb_devvp, jnewblk->jn_blkno, - fs->fs_bsize, freeblks->fb_previousinum, &freewk); + if (level != 0) { + ufs_lbn_t nlbn; + + nlbn = (lbn + 1) - (i * lbnadd); + nfreework = newfreework(freeblks, freework, + nlbn, nb, fs->fs_frag, 0); + WORKLIST_INSERT_UNLOCKED(&nfreework->fw_jwork, wk); + freedeps++; + indir_trunc(nfreework, fsbtodb(fs, nb), nlbn); + } else { + struct workhead freewk; + + LIST_INIT(&freewk); + ACQUIRE_LOCK(&lk); + WORKLIST_INSERT(&freewk, wk); + FREE_LOCK(&lk); + ffs_blkfree(ump, fs, freeblks->fb_devvp, + jnewblk->jn_blkno, fs->fs_bsize, + freeblks->fb_previousinum, &freewk); + } cnt++; } ACQUIRE_LOCK(&lk); - if (needj) - freework->fw_ref += NINDIR(fs) + 1; /* Any remaining journal work can be completed with freeblks. */ jwork_move(&freeblks->fb_jwork, &wkhd); FREE_LOCK(&lk);