From owner-p4-projects@FreeBSD.ORG Tue Jun 8 06:24:19 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id B9A171065674; Tue, 8 Jun 2010 06:24:18 +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 7C5BB1065673 for ; Tue, 8 Jun 2010 06:24:18 +0000 (UTC) (envelope-from lz@FreeBSD.org) Received: from repoman.freebsd.org (unknown [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 697778FC0A for ; Tue, 8 Jun 2010 06:24:18 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id o586OIgD029912 for ; Tue, 8 Jun 2010 06:24:18 GMT (envelope-from lz@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id o586OIij029910 for perforce@freebsd.org; Tue, 8 Jun 2010 06:24:18 GMT (envelope-from lz@FreeBSD.org) Date: Tue, 8 Jun 2010 06:24:18 GMT Message-Id: <201006080624.o586OIij029910@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to lz@FreeBSD.org using -f From: Zheng Liu To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 179311 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: Tue, 08 Jun 2010 06:24:19 -0000 http://p4web.freebsd.org/@@179311?ac=10 Change 179311 by lz@gnehzuil-freebsd on 2010/06/08 06:23:32 Dynamiclly adjust the size of reservation window. Affected files ... .. //depot/projects/soc2010/extfs/src/sys/fs/ext2fs/ext2_alloc.c#22 edit .. //depot/projects/soc2010/extfs/src/sys/fs/ext2fs/ext2_rsv_win.h#10 edit Differences ... ==== //depot/projects/soc2010/extfs/src/sys/fs/ext2fs/ext2_alloc.c#22 (text+ko) ==== @@ -52,6 +52,7 @@ #include #include +/* Just for clear */ #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); @@ -68,15 +69,40 @@ static int ext2_alloc_new_rsv(struct inode *, int, struct buf *, int32_t); static int ext2_bpref_in_rsv(struct ext2_rsv_win *, int32_t); static int ext2_find_rsv(struct ext2_rsv_win *, struct ext2_rsv_win *, - struct m_ext2fs *, int32_t, int); + struct m_ext2fs *, int32_t, int); static void ext2_remove_rsv_win(struct m_ext2fs *, struct ext2_rsv_win *); -static u_long ext2_rsvalloc(struct m_ext2fs *, struct inode *, int, - struct buf *, int32_t, int); +static u_long ext2_rsvalloc(struct m_ext2fs *, struct inode *, + int, struct buf *, int32_t, int); static daddr_t ext2_search_next_block(struct m_ext2fs *, char *, int, int); static struct ext2_rsv_win *ext2_search_rsv(struct ext2_rsv_win_tree *, int32_t); RB_GENERATE(ext2_rsv_win_tree, ext2_rsv_win, rsv_link, ext2_rsv_win_cmp); +/* + * Allocate a block in the file system. + * + * By given preference: + * It checks whether inode has a reservation window and preference + * is within it. If so, it will try to allocate a free block from + * this reservation window. + * Otherwise, it traverses RB tree to find a place, which is not + * in any window. then it inserts it to RB tree and tries to allocate + * a free block again. + * If fails, it will try to allocate a free block in other cylinder + * groups without perference. + */ + +/* + * Allocate a free block. + * + * Firstly it checks whether reservation window is used. + * If it use reservation window, it will try to allocate a free + * block from the reservation window. If failed, it will traverse + * the bitmap to find a free block. + * If it not use reservation window, it will try to allocate + * a free block by bpref. If failed, it will traverse the bitmap + * to find a free block. + */ static u_long ext2_alloc_blk(struct inode *ip, int cg, struct buf *bp, int32_t bpref, struct ext2_rsv_win *rp) @@ -96,19 +122,34 @@ if (bpref < 0) bpref = 0; + /* Check whther it use reservation window */ if (rp != NULL) { + /* + * If window's start is not in this cylinder group, + * try to allocate from the beginning of this group. + * Otherwise, try to allocate from the beginning of + * the window. + */ if (dtog(fs, rp->rsv_start) != cg) start = phy_blk(cg, fs); else start = rp->rsv_start; + + /* + * If window's end cross the end of this group, + * set end variable to the end of this group. + * Otherwise, set it to window's end. + */ if (dtog(fs, rp->rsv_end) != cg) end = fs->e2fs->e2fs_fpg; else end = rp->rsv_end; + /* If preference block is within the window, try to allocate it. */ if (start <= bpref && bpref <= end) { bpref = dtogd(fs, bpref); if (isclr(bbp, bpref)) { + rp->rsv_alloc_hit++; bno = bpref; goto gotit; } @@ -156,7 +197,7 @@ /* * If malloc failed, we just do not use - * reservation window mechanism + * reservation window mechanism. */ if (rp == NULL) return; @@ -210,6 +251,9 @@ rp->rsv_alloc_hit = 0; } +/* + * Check bpref is in the reservation window. + */ static int ext2_bpref_in_rsv(struct ext2_rsv_win *rp, int32_t bpref) { @@ -219,6 +263,10 @@ return (1); } +/* + * Search a tree node from RB tree. It includes the bpref or + * the previous one if bpref is not in any window. + */ static struct ext2_rsv_win * ext2_search_rsv(struct ext2_rsv_win_tree *root, int32_t start) { @@ -247,6 +295,10 @@ return (prev); } +/* + * Find a reservation window by given range from start to + * the end of this cylinder group. + */ static int ext2_find_rsv(struct ext2_rsv_win *search, struct ext2_rsv_win *rp, struct m_ext2fs *fs, int32_t start, int cg) @@ -265,6 +317,11 @@ return (0); } + /* + * Make the start of reservation window byte-aligned + * in order to can find a free block with bit operations + * in ext2_search_next_block() function. + */ cur = start & ~7; rsv = search; prev = NULL; @@ -299,6 +356,10 @@ return (0); } +/* + * Find a free block by given range from bpref to + * the end of this cylinder group. + */ static daddr_t ext2_search_next_block(struct m_ext2fs *fs, char *bbp, int bpref, int cg) { @@ -322,6 +383,9 @@ return (-1); } +/* + * Allocate a new reservation window. + */ static int ext2_alloc_new_rsv(struct inode *ip, int cg, struct buf *bp, int32_t bpref) { @@ -340,6 +404,17 @@ else start = bpref; + /* Dynamically increase the size of window */ + if (rp->rsv_end != EXT2_RSV_NOT_ALLOCATED) { + if (rp->rsv_alloc_hit > + ((rp->rsv_end - rp->rsv_start + 1) / 2)) { + size = size * 2; + if (size > EXT2_RSV_MAX_RESERVE_BLKS) + size = EXT2_RSV_MAX_RESERVE_BLKS; + rp->rsv_goal_size = size; + } + } + EXT2_TREE_LOCK(fs); search = ext2_search_rsv(&fs->e2fs_rsv_tree, start); @@ -502,38 +577,6 @@ return EIO; } -/* - * Allocate a block in the file system. - * - * A preference may be optionally specified. If a preference is given - * the following hierarchy is used to allocate a block: - * 1) allocate the requested block. - * 2) allocate a rotationally optimal block in the same cylinder. - * 3) allocate a block in the same cylinder group. - * 4) quadradically rehash into other cylinder groups, until an - * available block is located. - * If no block preference is given the following hierarchy is used - * to allocate a block: - * 1) allocate a block in the cylinder group that contains the - * inode for the file. - * 2) quadradically rehash into other cylinder groups, until an - * available block is located. - * - * A preference may be optionally specified. If a preference is given - * the following hierarchy is used to allocate a block: - * 1) allocate the requested block. - * 2) allocate a rotationally optimal block in the same cylinder. - * 3) allocate a block in the same cylinder group. - * 4) quadradically rehash into other cylinder groups, until an - * available block is located. - * If no block preference is given the following hierarchy is used - * to allocate a block: - * 1) allocate a block in the cylinder group that contains the - * inode for the file. - * 2) quadradically rehash into other cylinder groups, until an - * available block is located. - */ - int ext2_alloc(ip, lbn, bpref, size, cred, bnp) struct inode *ip; ==== //depot/projects/soc2010/extfs/src/sys/fs/ext2fs/ext2_rsv_win.h#10 (text+ko) ==== @@ -31,7 +31,7 @@ #include #define EXT2_RSV_DEFAULT_RESERVE_BLKS 8 -#define EXT2_RSV_MAX_RESERVE_BLKS 1027 +#define EXT2_RSV_MAX_RESERVE_BLKS 1024 #define EXT2_RSV_NOT_ALLOCATED 0 #define EXT2_RSV_LOCK(ip) mtx_lock(&ip->i_rsv_lock)