From owner-p4-projects@FreeBSD.ORG Wed Jan 26 04:05:43 2011 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 383651065675; Wed, 26 Jan 2011 04:05:43 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D83B9106566B for ; Wed, 26 Jan 2011 04:05:42 +0000 (UTC) (envelope-from lz@FreeBSD.org) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:4f8:fff6::2d]) by mx1.freebsd.org (Postfix) with ESMTP id C4B368FC19 for ; Wed, 26 Jan 2011 04:05:42 +0000 (UTC) Received: from skunkworks.freebsd.org (localhost [127.0.0.1]) by skunkworks.freebsd.org (8.14.4/8.14.4) with ESMTP id p0Q45g8O070845 for ; Wed, 26 Jan 2011 04:05:42 GMT (envelope-from lz@FreeBSD.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.4/8.14.4/Submit) id p0Q45go8070842 for perforce@freebsd.org; Wed, 26 Jan 2011 04:05:42 GMT (envelope-from lz@FreeBSD.org) Date: Wed, 26 Jan 2011 04:05:42 GMT Message-Id: <201101260405.p0Q45go8070842@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to lz@FreeBSD.org using -f From: Zheng Liu To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 188181 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 26 Jan 2011 04:05:43 -0000 http://p4web.freebsd.org/@@188181?ac=10 Change 188181 by lz@gnehzuil-freebsd on 2011/01/26 04:05:10 Add ext2_clusteralloc() function. Affected files ... .. //depot/projects/soc2010/extfs/src/sys/fs/ext2fs/ext2_alloc.c#31 edit Differences ... ==== //depot/projects/soc2010/extfs/src/sys/fs/ext2fs/ext2_alloc.c#31 (text+ko) ==== @@ -53,6 +53,8 @@ #include #include +#define FANCY_REALLOC 1 + #define phy_blk(cg, fs) (((cg) * (fs->e2fs->e2fs_fpg)) + fs->e2fs->e2fs_first_dblock) static daddr_t ext2_alloccg(struct inode *, int, daddr_t, int); @@ -64,6 +66,11 @@ static daddr_t ext2_nodealloccg(struct inode *, int, daddr_t, int); static daddr_t ext2_mapsearch(struct m_ext2fs *, char *, daddr_t); +/* For reallocblks */ +#ifdef FANCY_REALLOC +static daddr_t ext2_clusteralloc(struct inode *, int, daddr_t, int); +#endif + /* For reservation window */ static u_long ext2_alloc_blk(struct inode *, int, struct buf *, int32_t, struct ext2_rsv_win *); static int ext2_alloc_new_rsv(struct inode *, int, struct buf *, int32_t); @@ -94,7 +101,7 @@ SYSCTL_NODE(_vfs, OID_AUTO, ext2fs, CTLFLAG_RW, 0, "EXT2FS filesystem"); -static int rsv = 1; +static int rsv = 0; SYSCTL_INT(_vfs_ext2fs, OID_AUTO, rsv, CTLFLAG_RW, &rsv, 0, ""); static int rsv_winsize = 8; @@ -667,13 +674,15 @@ */ #ifdef FANCY_REALLOC -#include + static int doasyncfree = 1; + +SYSCTL_INT(_vfs_ext2fs, OID_AUTO, doasyncfree, CTLFLAG_RW, &doasyncfree, 0, + "Use asychronous writes to update block pointers when freeing blocks"); + static int doreallocblks = 1; -#ifdef OPT_DEBUG -SYSCTL_INT(_debug, 14, doasyncfree, CTLFLAG_RW, &doasyncfree, 0, ""); -#endif /* OPT_DEBUG */ +SYSCTL_INT(_vfs_ext2fs, OID_AUTO, doreallocblks, CTLFLAG_RW, &doreallocblks, 0, ""); #endif int @@ -840,6 +849,80 @@ #endif /* FANCY_REALLOC */ } +static daddr_t +ext2_clusteralloc(struct inode *ip, int cg, daddr_t bpref, int len) +{ + struct m_ext2fs *fs; + struct ext2mount *ump; + struct buf *bp; + int error, i, got, run; + char *bbp; + daddr_t bno; + + fs = ip->i_e2fs; + ump = ip->i_ump; + + /* + * TODO: we need to define a new member in m_ext2fs structure + * to save max cluster. But for simplicity, we assume that the + * max cluster is equal to the number of blocks per group. + */ + if (fs->e2fs_gd[cg].ext2bgd_nbfree < len) + return (0); + + EXT2_UNLOCK(ump); + error = bread(ip->i_devvp, + fsbtodb(fs, fs->e2fs_gd[cg].ext2bgd_b_bitmap), + (int)fs->e2fs_bsize, NOCRED, &bp); + if (error) + goto fail_lock; + + bbp = (char *)bp->b_data; + bp->b_xflags |= BX_BKGRDWRITE; + + /* + * TODO: check to see if a cluster of the needed size is + * available in this cg. + */ + + if (dtog(fs, bpref) != cg) + bpref = 0; + else + bpref = dtogd(fs, bpref); + + for (run = 0, got = bpref; got < fs->e2fs_bpg; got++) { + if (!isclr(bbp, got)) + run = 0; + else { + run++; + if (run == len) + break; + } + } + + if (got >= fs->e2fs_bpg) + goto fail_lock; + + for (i = 1; i <= len; i++) + if (!isclr(bbp, got - run + i)) + panic("ext2_clusteralloc: map mismatch"); + bno = got - run + 1; + if (bno >= fs->e2fs_bpg) + panic("ext2_clusteralloc: allocated out of group"); + + for (i = 0; i < len; i++) + setbit(bbp, (daddr_t)bno + i); + + bdwrite(bp); + + return (phy_blk(cg, fs) + bno); + +fail_lock: + EXT2_LOCK(ump); + brelse(bp); + return (0); +} + /* * Allocate an inode in the file system. * @@ -1148,7 +1231,10 @@ struct m_ext2fs *fs; struct buf *bp; struct ext2mount *ump; - int error, bno, start, end, loc; + /*daddr_t bno, runstart, runlen;*/ + /*int bit, loc, end, error, start;*/ + daddr_t bno; + int error; char *bbp; /* XXX ondisk32 */ fs = ip->i_e2fs; @@ -1184,23 +1270,59 @@ * first try to get 8 contigous blocks, then fall back to a single * block. */ +#if 0 if (bpref) start = dtogd(fs, bpref) / NBBY; else start = 0; end = howmany(fs->e2fs->e2fs_fpg, NBBY) - start; - for (loc = start; loc < end; loc++) { - if (bbp[loc] == 0) { - bno = loc * NBBY; - goto gotit; - } - } - for (loc = 0; loc < start; loc++) { - if (bbp[loc] == 0) { - bno = loc * NBBY; - goto gotit; - } - } +retry: + runlen = 0; + runstart = 0; + for (loc = start; loc < end; loc++) { + if (bbp[loc] == (char)0xff) { + runlen = 0; + continue; + } + + /* Start of a run, find the number of high clear bits. */ + if (runlen == 0) { + bit = fls(bbp[loc]); + runlen = NBBY - bit; + runstart = loc * NBBY + bit; + } else if (bbp[loc] == 0) { + /* Contunue a run. */ + runlen += NBBY; + } else { + /* + * Finish the current run. If it isn't long + * enough, start a new one. + */ + bit = fls(bbp[loc]) - 1; + runlen += bit; + if (runlen >= 8) { + bno = runstart; + goto gotit; + } + + /* Run was too short, start a new one. */ + bit = fls(bbp[loc]); + runlen = NBBY - bit; + runstart = loc * NBBY + bit; + } + + /* If the current run is long enough, use it. */ + if (runlen >= 8) { + bno = runstart; + goto gotit; + } + } + if (start != 0) { + end = start; + start = 0; + goto retry; + } +#endif /* 0 */ bno = ext2_mapsearch(fs, bbp, bpref); if (bno < 0){ @@ -1433,11 +1555,14 @@ loc = skpc(0xff, len, &bbp[start]); if (loc == 0) { /* XXX: just for reservation window */ - return -1; - /*printf("start = %d, len = %d, fs = %s\n",*/ - /*start, len, fs->e2fs_fsmnt);*/ - /*panic("ext2fs_alloccg: map corrupted");*/ - /* NOTREACHED */ + if (rsv == 1) + return (-1); + else { + printf("start = %d, len = %d, fs = %s\n", + start, len, fs->e2fs_fsmnt); + panic("ext2fs_alloccg: map corrupted"); + /* NOTREACHED */ + } } } i = start + len - loc;