From owner-svn-src-head@FreeBSD.ORG Mon Jul 4 20:53:55 2011 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 86A89106566C; Mon, 4 Jul 2011 20:53:55 +0000 (UTC) (envelope-from jeff@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 75CEC8FC1F; Mon, 4 Jul 2011 20:53:55 +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 p64KrtNO034052; Mon, 4 Jul 2011 20:53:55 GMT (envelope-from jeff@svn.freebsd.org) Received: (from jeff@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p64Krtf9034050; Mon, 4 Jul 2011 20:53:55 GMT (envelope-from jeff@svn.freebsd.org) Message-Id: <201107042053.p64Krtf9034050@svn.freebsd.org> From: Jeff Roberson Date: Mon, 4 Jul 2011 20:53:55 +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: r223770 - 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: Mon, 04 Jul 2011 20:53:55 -0000 Author: jeff Date: Mon Jul 4 20:53:55 2011 New Revision: 223770 URL: http://svn.freebsd.org/changeset/base/223770 Log: - It is impossible to run request_cleanup() while doing a copyonwrite. This will most likely cause new block allocations which can recurse into request cleanup. - While here optimize the ufs locking slightly. We need only acquire and drop once. - process_removes() and process_truncates() also is only needed once. - Attempt to flush each item on the worklist once but do not loop forever if some can not be completed. Discussed with: mckusick Modified: head/sys/ufs/ffs/ffs_softdep.c Modified: head/sys/ufs/ffs/ffs_softdep.c ============================================================================== --- head/sys/ufs/ffs/ffs_softdep.c Mon Jul 4 20:52:23 2011 (r223769) +++ head/sys/ufs/ffs/ffs_softdep.c Mon Jul 4 20:53:55 2011 (r223770) @@ -12510,33 +12510,36 @@ softdep_request_cleanup(fs, vp, cred, re int error; mp = vp->v_mount; - ump = VTOI(vp)->i_ump; + ump = VFSTOUFS(mp); mtx_assert(UFS_MTX(ump), MA_OWNED); if (resource == FLUSH_BLOCKS_WAIT) stat_cleanup_blkrequests += 1; else stat_cleanup_inorequests += 1; + /* * If we are being called because of a process doing a - * copy-on-write, then it is not safe to update the vnode - * as we may recurse into the copy-on-write routine. + * copy-on-write, then it is not safe to process any + * worklist items as we will recurse into the copyonwrite + * routine. This will result in an incoherent snapshot. */ - if (!(curthread->td_pflags & TDP_COWINPROGRESS)) { - UFS_UNLOCK(ump); - error = ffs_update(vp, 1); + if (curthread->td_pflags & TDP_COWINPROGRESS) + return (0); + UFS_UNLOCK(ump); + error = ffs_update(vp, 1); + if (error != 0) { UFS_LOCK(ump); - if (error != 0) - return (0); + return (0); } /* * If we are in need of resources, consider pausing for * tickdelay to give ourselves some breathing room. */ - UFS_UNLOCK(ump); ACQUIRE_LOCK(&lk); + process_removes(vp); + process_truncates(vp); request_cleanup(UFSTOVFS(ump), resource); FREE_LOCK(&lk); - UFS_LOCK(ump); /* * Now clean up at least as many resources as we will need. * @@ -12568,29 +12571,23 @@ softdep_request_cleanup(fs, vp, cred, re roundup((fs->fs_dsize * fs->fs_minfree / 100) - fs->fs_cstotal.cs_nffree, fs->fs_frag)); } else { + UFS_LOCK(ump); printf("softdep_request_cleanup: Unknown resource type %d\n", resource); return (0); } starttime = time_second; retry: - while ((resource == FLUSH_BLOCKS_WAIT && ump->softdep_on_worklist > 0 && - fs->fs_cstotal.cs_nbfree <= needed) || - (resource == FLUSH_INODES_WAIT && fs->fs_pendinginodes > 0 && - fs->fs_cstotal.cs_nifree <= needed)) { - UFS_UNLOCK(ump); + if ((resource == FLUSH_BLOCKS_WAIT && ump->softdep_on_worklist > 0 && + fs->fs_cstotal.cs_nbfree <= needed) || + (resource == FLUSH_INODES_WAIT && fs->fs_pendinginodes > 0 && + fs->fs_cstotal.cs_nifree <= needed)) { ACQUIRE_LOCK(&lk); - process_removes(vp); - process_truncates(vp); if (ump->softdep_on_worklist > 0 && - process_worklist_item(UFSTOVFS(ump), 1, LK_NOWAIT) != 0) { + process_worklist_item(UFSTOVFS(ump), + ump->softdep_on_worklist, LK_NOWAIT) != 0) stat_worklist_push += 1; - FREE_LOCK(&lk); - UFS_LOCK(ump); - continue; - } FREE_LOCK(&lk); - UFS_LOCK(ump); } /* * If we still need resources and there are no more worklist @@ -12604,7 +12601,6 @@ retry: fs->fs_cstotal.cs_nbfree <= needed) || (resource == FLUSH_INODES_WAIT && fs->fs_pendinginodes > 0 && fs->fs_cstotal.cs_nifree <= needed)) { - UFS_UNLOCK(ump); MNT_ILOCK(mp); MNT_VNODE_FOREACH(lvp, mp, mvp) { VI_LOCK(lvp); @@ -12633,7 +12629,6 @@ retry: VOP_FSYNC(lvp, MNT_NOWAIT, curthread); VOP_UNLOCK(lvp, 0); } - UFS_LOCK(ump); if (ump->softdep_on_worklist > 0) { stat_cleanup_retries += 1; goto retry; @@ -12642,6 +12637,7 @@ retry: } if (time_second - starttime > stat_cleanup_high_delay) stat_cleanup_high_delay = time_second - starttime; + UFS_LOCK(ump); return (1); }