From owner-svn-src-head@FreeBSD.ORG Thu Nov 11 11:54:01 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 AEC48106566B; Thu, 11 Nov 2010 11:54:01 +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 832038FC2C; Thu, 11 Nov 2010 11:54:01 +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 oABBs1He066497; Thu, 11 Nov 2010 11:54:01 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id oABBs1Yu066495; Thu, 11 Nov 2010 11:54:01 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <201011111154.oABBs1Yu066495@svn.freebsd.org> From: Konstantin Belousov Date: Thu, 11 Nov 2010 11:54:01 +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: r215117 - 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, 11 Nov 2010 11:54:01 -0000 Author: kib Date: Thu Nov 11 11:54:01 2010 New Revision: 215117 URL: http://svn.freebsd.org/changeset/base/215117 Log: The softdep_setup_freeblocks() adds worklist items before deallocate_dependencies() is done. This opens a race between softdep thread and the thread that does the truncation: A write of the indirect block causes the freeblks to become ALLCOMPLETE while softdep_setup_freeblocks() dropped softdep lock. And then, softdep_disk_write_complete() would reassign the workitem to the mount point worklist, causing premature processing of the workitem, or journal write exhaust the fb_jfreeblkhd and handle_written_jfreeblk does the same reassign. indir_trunc() then would find the indirect block that is locked (with lock owned by kernel) but without any dependencies, causing it to hang in getblk() waiting for buffer lock. Do not mark freeblks as DEPCOMPLETE until deallocate_dependencies() finished. Analyzed, suggested and reviewed by: jeff Tested by: 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 Nov 11 11:46:19 2010 (r215116) +++ head/sys/ufs/ffs/ffs_softdep.c Thu Nov 11 11:54:01 2010 (r215117) @@ -5270,7 +5270,7 @@ softdep_setup_freeblocks(ip, length, fla if (delay) WORKLIST_INSERT(&bp->b_dep, &freeblks->fb_list); else if (needj) - freeblks->fb_state |= DEPCOMPLETE | COMPLETE; + freeblks->fb_state |= COMPLETE; /* * Because the file length has been truncated to zero, any * pending block allocation dependency structures associated @@ -5332,8 +5332,9 @@ restart: if (inodedep_lookup(mp, ip->i_number, 0, &inodedep) != 0) (void) free_inodedep(inodedep); - if (delay) { + if (delay || needj) freeblks->fb_state |= DEPCOMPLETE; + if (delay) { /* * If the inode with zeroed block pointers is now on disk * we can start freeing blocks. Add freeblks to the worklist @@ -5344,6 +5345,8 @@ restart: if ((freeblks->fb_state & ALLCOMPLETE) == ALLCOMPLETE) add_to_worklist(&freeblks->fb_list, 1); } + if (needj && LIST_EMPTY(&freeblks->fb_jfreeblkhd)) + needj = 0; FREE_LOCK(&lk); /*