From owner-svn-src-all@FreeBSD.ORG Mon Jul 4 22:08:05 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 07B721065670; Mon, 4 Jul 2011 22:08:05 +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 EA9C88FC12; Mon, 4 Jul 2011 22:08:04 +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 p64M8404036305; Mon, 4 Jul 2011 22:08:04 GMT (envelope-from jeff@svn.freebsd.org) Received: (from jeff@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id p64M84I8036302; Mon, 4 Jul 2011 22:08:04 GMT (envelope-from jeff@svn.freebsd.org) Message-Id: <201107042208.p64M84I8036302@svn.freebsd.org> From: Jeff Roberson Date: Mon, 4 Jul 2011 22:08:04 +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: r223772 - head/sys/ufs/ffs X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 04 Jul 2011 22:08:05 -0000 Author: jeff Date: Mon Jul 4 22:08:04 2011 New Revision: 223772 URL: http://svn.freebsd.org/changeset/base/223772 Log: - Speed up pendingblock processing again. Having too much delay between ffs_blkfree() and the pending adjustment causes all kinds of space related problems. Modified: head/sys/ufs/ffs/ffs_softdep.c head/sys/ufs/ffs/softdep.h Modified: head/sys/ufs/ffs/ffs_softdep.c ============================================================================== --- head/sys/ufs/ffs/ffs_softdep.c Mon Jul 4 21:04:25 2011 (r223771) +++ head/sys/ufs/ffs/ffs_softdep.c Mon Jul 4 22:08:04 2011 (r223772) @@ -880,6 +880,7 @@ static inline void setup_freeext(struct static inline void setup_freeindir(struct freeblks *, struct inode *, int, ufs_lbn_t, int); static inline struct freeblks *newfreeblks(struct mount *, struct inode *); +static void freeblks_free(struct ufsmount *, struct freeblks *, int); static void indir_trunc(struct freework *, ufs2_daddr_t, ufs_lbn_t); ufs2_daddr_t blkcount(struct fs *, ufs2_daddr_t, off_t); static int trunc_check_buf(struct buf *, int *, ufs_lbn_t, int, int); @@ -5751,7 +5752,6 @@ newfreeblks(mp, ip) freeblks->fb_modrev = DIP(ip, i_modrev); freeblks->fb_devvp = ip->i_devvp; freeblks->fb_chkcnt = 0; - freeblks->fb_freecnt = 0; freeblks->fb_len = 0; return (freeblks); @@ -6199,7 +6199,7 @@ softdep_journal_freeblocks(ip, cred, len quotaref(vp, freeblks->fb_quota); (void) chkdq(ip, -datablocks, NOCRED, 0); #endif - freeblks->fb_chkcnt = datablocks; + freeblks->fb_chkcnt = -datablocks; UFS_LOCK(ip->i_ump); fs->fs_pendingblocks += datablocks; UFS_UNLOCK(ip->i_ump); @@ -6429,7 +6429,7 @@ softdep_setup_freeblocks(ip, length, fla quotaref(vp, freeblks->fb_quota); (void) chkdq(ip, -datablocks, NOCRED, 0); #endif - freeblks->fb_chkcnt = datablocks; + freeblks->fb_chkcnt = -datablocks; UFS_LOCK(ip->i_ump); fs->fs_pendingblocks += datablocks; UFS_UNLOCK(ip->i_ump); @@ -7284,8 +7284,8 @@ freework_freeblock(freework) freeblks->fb_cgwait++; WORKLIST_INSERT(&wkhd, &freework->fw_list); } - freeblks->fb_freecnt += btodb(bsize); FREE_LOCK(&lk); + freeblks_free(ump, freeblks, btodb(bsize)); ffs_blkfree(ump, fs, freeblks->fb_devvp, freework->fw_blkno, bsize, freeblks->fb_inum, freeblks->fb_vtype, &wkhd); ACQUIRE_LOCK(&lk); @@ -7459,6 +7459,33 @@ handle_workitem_freeblocks(freeblks, fla } /* + * Handle completion of block free via truncate. This allows fs_pending + * to track the actual free block count more closely than if we only updated + * it at the end. We must be careful to handle cases where the block count + * on free was incorrect. + */ +static void +freeblks_free(ump, freeblks, blocks) + struct ufsmount *ump; + struct freeblks *freeblks; + int blocks; +{ + struct fs *fs; + ufs2_daddr_t remain; + + UFS_LOCK(ump); + remain = -freeblks->fb_chkcnt; + freeblks->fb_chkcnt += blocks; + if (remain > 0) { + if (remain < blocks) + blocks = remain; + fs = ump->um_fs; + fs->fs_pendingblocks -= blocks; + } + UFS_UNLOCK(ump); +} + +/* * Once all of the freework workitems are complete we can retire the * freeblocks dependency and any journal work awaiting completion. This * can not be called until all other dependencies are stable on disk. @@ -7478,7 +7505,7 @@ handle_complete_freeblocks(freeblks, fla ump = VFSTOUFS(freeblks->fb_list.wk_mp); fs = ump->um_fs; flags = LK_EXCLUSIVE | flags; - spare = freeblks->fb_freecnt - freeblks->fb_chkcnt; + spare = freeblks->fb_chkcnt; /* * If we did not release the expected number of blocks we may have @@ -7501,9 +7528,9 @@ handle_complete_freeblocks(freeblks, fla } vput(vp); } - if (freeblks->fb_chkcnt) { + if (spare < 0) { UFS_LOCK(ump); - fs->fs_pendingblocks -= freeblks->fb_chkcnt; + fs->fs_pendingblocks += spare; UFS_UNLOCK(ump); } #ifdef QUOTA @@ -7559,7 +7586,7 @@ indir_trunc(freework, dbn, lbn) ufs2_daddr_t nb, nnb, *bap2 = 0; ufs_lbn_t lbnadd, nlbn; int i, nblocks, ufs1fmt; - int fs_pendingblocks; + int freedblocks; int goingaway; int freedeps; int needj; @@ -7701,16 +7728,18 @@ indir_trunc(freework, dbn, lbn) bp->b_flags |= B_INVAL | B_NOCACHE; brelse(bp); } - fs_pendingblocks = 0; + freedblocks = 0; if (level == 0) - fs_pendingblocks = (nblocks * cnt); + freedblocks = (nblocks * cnt); + if (needj == 0) + freedblocks += nblocks; + freeblks_free(ump, freeblks, freedblocks); /* * If we are journaling set up the ref counts and offset so this * indirect can be completed when its children are free. */ if (needj) { ACQUIRE_LOCK(&lk); - freeblks->fb_freecnt += fs_pendingblocks; freework->fw_off = i; freework->fw_ref += freedeps; freework->fw_ref -= NINDIR(fs) + 1; @@ -7724,12 +7753,10 @@ indir_trunc(freework, dbn, lbn) /* * If we're not journaling we can free the indirect now. */ - fs_pendingblocks += nblocks; dbn = dbtofsb(fs, dbn); ffs_blkfree(ump, fs, freeblks->fb_devvp, dbn, fs->fs_bsize, freeblks->fb_inum, freeblks->fb_vtype, NULL); /* Non SUJ softdep does single-threaded truncations. */ - freeblks->fb_freecnt += fs_pendingblocks; if (freework->fw_blkno == dbn) { freework->fw_state |= ALLCOMPLETE; ACQUIRE_LOCK(&lk); Modified: head/sys/ufs/ffs/softdep.h ============================================================================== --- head/sys/ufs/ffs/softdep.h Mon Jul 4 21:04:25 2011 (r223771) +++ head/sys/ufs/ffs/softdep.h Mon Jul 4 22:08:04 2011 (r223772) @@ -536,8 +536,7 @@ struct freeblks { #endif uint64_t fb_modrev; /* Inode revision at start of trunc. */ off_t fb_len; /* Length we're truncating to. */ - ufs2_daddr_t fb_chkcnt; /* Expected blks released. */ - ufs2_daddr_t fb_freecnt; /* Actual blocks released. */ + ufs2_daddr_t fb_chkcnt; /* Blocks released. */ ino_t fb_inum; /* inode owner of blocks */ enum vtype fb_vtype; /* inode owner's file type */ uid_t fb_uid; /* uid of previous owner of blocks */