Date: Fri, 21 May 2010 12:07:35 GMT From: Zheng Liu <lz@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 178586 for review Message-ID: <201005211207.o4LC7ZXu014144@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@178586?ac=10 Change 178586 by lz@gnehzuil-freebsd on 2010/05/21 12:06:55 Fix bugs and Improve naming. * Fix a bug in ext2_reclaim() * Fix a bug in ext2_alloc_new_rsv_win() * Improve naming in ext2_rsv_win structure * Initialize ip->i_rsv field in ext2_vget() from ext2_balloc() Affected files ... .. //depot/projects/soc2010/extfs/src/sys/fs/ext2fs/ext2_alloc.c#13 edit .. //depot/projects/soc2010/extfs/src/sys/fs/ext2fs/ext2_balloc.c#5 edit .. //depot/projects/soc2010/extfs/src/sys/fs/ext2fs/ext2_inode.c#4 edit .. //depot/projects/soc2010/extfs/src/sys/fs/ext2fs/ext2_rsv_win.h#8 edit .. //depot/projects/soc2010/extfs/src/sys/fs/ext2fs/ext2_vfsops.c#5 edit Differences ... ==== //depot/projects/soc2010/extfs/src/sys/fs/ext2fs/ext2_alloc.c#13 (text+ko) ==== @@ -74,7 +74,7 @@ struct buf *, int32_t, int); struct ext2_rsv_win *ext2_search_rsv_win(struct ext2_rsv_win_tree *, int32_t); -RB_GENERATE(ext2_rsv_win_tree, ext2_rsv_win, rw_link, ext2_rsv_win_cmp); +RB_GENERATE(ext2_rsv_win_tree, ext2_rsv_win, rsv_link, ext2_rsv_win_cmp); /* * Lazily initialize reservation window per inode. @@ -96,11 +96,11 @@ if (rp == NULL) return; - rp->rw_start = EXT2_RWI_NOT_ALLOCATED; - rp->rw_end = EXT2_RWI_NOT_ALLOCATED; + rp->rsv_start = EXT2_RSV_NOT_ALLOCATED; + rp->rsv_end = EXT2_RSV_NOT_ALLOCATED; - rp->rw_goal_size = EXT2_RWI_DEFAULT_RESERVE_BLKS; - rp->rw_alloc_hit = 0; + rp->rsv_goal_size = EXT2_RSV_DEFAULT_RESERVE_BLKS; + rp->rsv_alloc_hit = 0; ip->i_rsv = rp; } @@ -118,18 +118,19 @@ { struct ext2_rsv_win *rp; - /* do not use reservation window */ if (ip->i_rsv == NULL) return; rp = ip->i_rsv; /* If reservation window is empty, nothing to do */ - if (rp->rw_end == EXT2_RWI_NOT_ALLOCATED) + if (rp->rsv_end == EXT2_RSV_NOT_ALLOCATED) return; - if (rp->rw_end != EXT2_RWI_NOT_ALLOCATED) + EXT2_TREE_LOCK(ip->i_e2fs); + if (rp != NULL && rp->rsv_end != EXT2_RSV_NOT_ALLOCATED) ext2_remove_rsv_win(ip->i_e2fs, rp); + EXT2_TREE_UNLOCK(ip->i_e2fs); } /* @@ -138,10 +139,10 @@ static void ext2_remove_rsv_win(struct m_ext2fs *fs, struct ext2_rsv_win *rp) { - rp->rw_start = EXT2_RWI_NOT_ALLOCATED; - rp->rw_end = EXT2_RWI_NOT_ALLOCATED; - rp->rw_alloc_hit = 0; RB_REMOVE(ext2_rsv_win_tree, &fs->e2fs_rsv_tree, rp); + rp->rsv_start = EXT2_RSV_NOT_ALLOCATED; + rp->rsv_end = EXT2_RSV_NOT_ALLOCATED; + rp->rsv_alloc_hit = 0; } /* @@ -168,15 +169,15 @@ next = RB_ROOT(root); do { prev = next; - if (bpref < next->rw_start) - next = RB_LEFT(next, rw_link); - else if (bpref > next->rw_end) - next = RB_RIGHT(next, rw_link); + if (bpref < next->rsv_start) + next = RB_LEFT(next, rsv_link); + else if (bpref > next->rsv_end) + next = RB_RIGHT(next, rsv_link); else return prev; } while(next != NULL); - if (prev->rw_start > bpref) + if (prev->rsv_start > bpref) prev = RB_PREV(ext2_rsv_win_tree, root, prev); return prev; @@ -191,19 +192,21 @@ { struct ext2_rsv_win *rsv, *prev, *next; int32_t cur; - int size = EXT2_RWI_DEFAULT_RESERVE_BLKS; + int size = EXT2_RSV_DEFAULT_RESERVE_BLKS; + + if (search == NULL && RB_EMPTY(&fs->e2fs_rsv_tree)) + return -1; + else + search = RB_ROOT(&fs->e2fs_rsv_tree); cur = bpref; rsv = search; prev = NULL; - if (search == NULL) - return -1; while (1) { - if (cur <= rsv->rw_end) - cur = rsv->rw_end + 1; + if (cur <= rsv->rsv_end) + cur = rsv->rsv_end + 1; - /* TODO: need to be improved */ if (dtog(fs, cur) != cg) return -1; @@ -214,16 +217,16 @@ if (next == NULL); break; - if (cur + size <= rsv->rw_start) + if (cur + size <= rsv->rsv_start) break; } - if (rp->rw_end != EXT2_RWI_NOT_ALLOCATED) + if (rp != NULL && rp->rsv_end != EXT2_RSV_NOT_ALLOCATED) ext2_remove_rsv_win(fs, rp); - rp->rw_start = cur; - rp->rw_end = cur + size - 1; - rp->rw_alloc_hit = 0; + rp->rsv_start = cur; + rp->rsv_end = cur + size - 1; + rp->rsv_alloc_hit = 0; ext2_add_rsv_win(fs, rp); @@ -245,14 +248,12 @@ ump = ip->i_ump; bbp = (char *)bp->b_data; - size = rp->rw_goal_size; + size = rp->rsv_goal_size; - /*mtx_lock_spin(&fs->e2fs_rsv_lock);*/ EXT2_TREE_LOCK(fs); /* If tree is empty, then try to alloc according to bpref */ if (RB_EMPTY(&fs->e2fs_rsv_tree)) { - /*mtx_unlock_spin(&fs->e2fs_rsv_lock);*/ EXT2_TREE_UNLOCK(fs); /* bpref is not in this cylinder group. * So try to allocate it in other group. @@ -283,61 +284,58 @@ } } - EXT2_LOCK(ump); - if (fs->e2fs_gd[cg].ext2bgd_nbfree > 0) - bpref = ext2_mapsearch(fs, bbp, bpref); - EXT2_UNLOCK(ump); + bpref = ext2_mapsearch(fs, bbp, bpref); if (bpref < 0) return 0; - goto allocated1; + goto gotit; } else { search_rsv = ext2_search_rsv_win(&fs->e2fs_rsv_tree, bpref); ret = ext2_find_next_rsv_win(search_rsv, rp, fs, bpref, cg); if (ret < 0) { - if (rp->rw_end != EXT2_RWI_NOT_ALLOCATED) + if (rp != NULL && rp->rsv_end != EXT2_RSV_NOT_ALLOCATED) ext2_remove_rsv_win(fs, rp); - /*mtx_unlock_spin(&fs->e2fs_rsv_lock);*/ EXT2_TREE_UNLOCK(fs); - EXT2_LOCK(ump); - if (fs->e2fs_gd[cg].ext2bgd_nbfree > 0) - bpref = ext2_mapsearch(fs, bbp, bpref); - EXT2_UNLOCK(ump); + bpref = ext2_mapsearch(fs, bbp, bpref); if (bpref < 0) return 0; goto allocated1; } - /*mtx_unlock_spin(&fs->e2fs_rsv_lock);*/ EXT2_TREE_UNLOCK(fs); - if (isclr(bbp, bpref) && - bpref >= rp->rw_start && - bpref < rp->rw_end) - goto allocated; + if (dtog(fs, bpref) != cg) + bpref = 0; + + if (bpref != 0) { + bpref = dtogd(fs, bpref); + if (isclr(bbp, bpref) && + cg * fs->e2fs->e2fs_fpg + fs->e2fs->e2fs_first_dblock + bpref >= rp->rsv_start && + cg * fs->e2fs->e2fs_fpg + fs->e2fs->e2fs_first_dblock + bpref < rp->rsv_end) + goto allocated; + } - start = dtogd(fs, bpref) / NBBY; + if (bpref != 0) + 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 && - loc * NBBY >= rp->rw_start && - loc * NBBY < rp->rw_end) { + cg * fs->e2fs->e2fs_fpg + fs->e2fs->e2fs_first_dblock + loc * NBBY >= rp->rsv_start && + cg * fs->e2fs->e2fs_fpg + fs->e2fs->e2fs_first_dblock + loc * NBBY < rp->rsv_end) { bpref = loc * NBBY; goto allocated; } } if (loc == end) { - /*mtx_lock_spin(&fs->e2fs_rsv_lock);*/ EXT2_TREE_LOCK(fs); - ext2_remove_rsv_win(fs, rp); - /*mtx_unlock_spin(&fs->e2fs_rsv_lock);*/ + if (rp != NULL && rp->rsv_end != EXT2_RSV_NOT_ALLOCATED) + ext2_remove_rsv_win(fs, rp); EXT2_TREE_UNLOCK(fs); - EXT2_LOCK(ump); - if (fs->e2fs_gd[cg].ext2bgd_nbfree > 0) - bpref = ext2_mapsearch(fs, bbp, bpref); - EXT2_UNLOCK(ump); + bpref = ext2_mapsearch(fs, bbp, bpref); if (bpref < 0) return 0; goto allocated1; @@ -345,18 +343,18 @@ } gotit: - rp->rw_start = bpref + cg * fs->e2fs->e2fs_fpg + fs->e2fs->e2fs_first_dblock; - rp->rw_end = rp->rw_start + size - 1; - rp->rw_alloc_hit = 0; - /*mtx_lock_spin(&fs->e2fs_rsv_lock);*/ + rp->rsv_start = bpref + cg * fs->e2fs->e2fs_fpg + fs->e2fs->e2fs_first_dblock; + rp->rsv_end = rp->rsv_start + size - 1; + rp->rsv_alloc_hit = 0; EXT2_TREE_LOCK(fs); ext2_add_rsv_win(fs, rp); - /*mtx_unlock_spin(&fs->e2fs_rsv_lock);*/ EXT2_TREE_UNLOCK(fs); allocated: - rp->rw_alloc_hit = bpref - rp->rw_start + 1; + rp->rsv_alloc_hit++; allocated1: + if (isset(bbp, bpref)) + return 0; setbit(bbp, (daddr_t)bpref); EXT2_LOCK(ump); fs->e2fs->e2fs_fbcount--; @@ -381,31 +379,32 @@ ump = ip->i_ump; bbp = (char *)bp->b_data; - if (rp != NULL && rp->rw_end != EXT2_RWI_NOT_ALLOCATED) - start = dtogd(fs, rp->rw_start + rp->rw_alloc_hit); - else - return 0; + if (rp != NULL && rp->rsv_end != EXT2_RSV_NOT_ALLOCATED) { + start = dtogd(fs, rp->rsv_start + rp->rsv_alloc_hit); + } else + goto find; + + if (dtog(fs, rp->rsv_start + rp->rsv_alloc_hit) != cg) + goto find; + start = dtogd(fs, start); if (isclr(bbp, start)) { bno = start; goto gotit; } - /*mtx_lock_spin(&fs->e2fs_rsv_lock);*/ +find: EXT2_TREE_LOCK(fs); - ext2_remove_rsv_win(fs, rp); - /*mtx_unlock_spin(&fs->e2fs_rsv_lock);*/ + if (rp != NULL && rp->rsv_end != EXT2_RSV_NOT_ALLOCATED); + ext2_remove_rsv_win(fs, rp); EXT2_TREE_UNLOCK(fs); - EXT2_LOCK(ump); - if (fs->e2fs_gd[cg].ext2bgd_nbfree > 0) - bno = ext2_mapsearch(fs, bbp, bpref); - EXT2_UNLOCK(ump); + bno = ext2_mapsearch(fs, bbp, bpref); if (bno < 0) return 0; goto allocated; gotit: - rp->rw_alloc_hit++; + rp->rsv_alloc_hit++; allocated: setbit(bbp, (daddr_t)bno); EXT2_LOCK(ump); @@ -428,15 +427,17 @@ rp = ip->i_rsv; + if (ip->i_rsv == NULL) + return ext2_alloc_blk(fs, ip, cg, bp, bpref, rp); + /* If window is empty or bpref is not in reservation window, * we will try to allocate a new reservation window. * Then we try to allocate a free block. */ - if (rp->rw_end == EXT2_RWI_NOT_ALLOCATED) { + if (rp->rsv_end == EXT2_RSV_NOT_ALLOCATED) return ext2_alloc_new_rsv_win(ip, rp, bpref, fs, cg, bp); - } else if (rp->rw_start + rp->rw_alloc_hit > rp->rw_end) { - return ext2_alloc_new_rsv_win(ip, rp, rp->rw_end, fs, cg, bp); - } + else if (rp->rsv_start + rp->rsv_alloc_hit > rp->rsv_end) + return ext2_alloc_new_rsv_win(ip, rp, rp->rsv_end, fs, cg, bp); return ext2_alloc_blk(fs, ip, cg, bp, bpref, rp); } @@ -486,10 +487,10 @@ goto ioerror; } - EXT2_IRSV_LOCK(ip); + EXT2_RSV_LOCK(ip); /* Try to allocate from reservation window */ bno = ext2_rsvalloc(fs, ip, cg, bp, bpref, size); - EXT2_IRSV_UNLOCK(ip); + EXT2_RSV_UNLOCK(ip); if (bno > 0) goto allocated; @@ -511,9 +512,9 @@ goto ioerror; } - EXT2_IRSV_LOCK(ip); + EXT2_RSV_LOCK(ip); bno = ext2_rsvalloc(fs, ip, cg, bp, bpref, size); - EXT2_IRSV_UNLOCK(ip); + EXT2_RSV_UNLOCK(ip); if (bno > 0) goto allocated; @@ -1353,12 +1354,6 @@ panic("ext2_vfree: range: devvp = %p, ino = %d, fs = %s", pip->i_devvp, ino, fs->e2fs_fsmnt); - EXT2_IRSV_LOCK(pip); - ext2_discard_rsv(pip); - /*free(pip->i_rsv, M_EXT2NODE);*/ - /*pip->i_rsv = NULL;*/ - EXT2_IRSV_UNLOCK(pip); - cg = ino_to_cg(fs, ino); error = bread(pip->i_devvp, fsbtodb(fs, fs->e2fs_gd[cg].ext2bgd_i_bitmap), ==== //depot/projects/soc2010/extfs/src/sys/fs/ext2fs/ext2_balloc.c#5 (text+ko) ==== @@ -79,12 +79,6 @@ fs = ip->i_e2fs; ump = ip->i_ump; - /* lazily initialize the reservation window info in inode */ - EXT2_IRSV_LOCK(ip); - if (ip->i_rsv == NULL) - ext2_init_rsv(ip); - EXT2_IRSV_UNLOCK(ip); - /* * check if this is a sequential block allocation. * If so, increment next_alloc fields to allow ext2_blkpref ==== //depot/projects/soc2010/extfs/src/sys/fs/ext2fs/ext2_inode.c#4 (text+ko) ==== @@ -155,9 +155,9 @@ fs = oip->i_e2fs; osize = oip->i_size; - EXT2_IRSV_LOCK(oip); + EXT2_RSV_LOCK(oip); ext2_discard_rsv(oip); - EXT2_IRSV_UNLOCK(oip); + EXT2_RSV_UNLOCK(oip); /* * Lengthen the size of the file. We must ensure that the @@ -490,9 +490,9 @@ if (prtactive && vrefcnt(vp) != 0) vprint("ext2_inactive: pushing active", vp); - EXT2_IRSV_LOCK(ip); + EXT2_RSV_LOCK(ip); ext2_discard_rsv(ip); - EXT2_IRSV_UNLOCK(ip); + EXT2_RSV_UNLOCK(ip); /* * Ignore inodes related to stale file handles. @@ -536,21 +536,20 @@ vprint("ufs_reclaim: pushing active", vp); ip = VTOI(vp); -#if 0 - EXT2_IRSV_LOCK(ip); - if (ip->i_rsv != NULL) { - free(ip->i_rsv, M_EXT2NODE); - ip->i_rsv = NULL; - } - EXT2_IRSV_UNLOCK(ip); - mtx_destroy(&ip->i_rsv_lock); -#endif - if (ip->i_flag & IN_LAZYMOD) { ip->i_flag |= IN_MODIFIED; ext2_update(vp, 0); } vfs_hash_remove(vp); + + EXT2_RSV_LOCK(ip); + if (ip->i_rsv != NULL) { + free(ip->i_rsv, M_EXT2NODE); + ip->i_rsv = NULL; + } + /*mtx_destroy(&ip->i_rsv_lock);*/ + EXT2_RSV_UNLOCK(ip); + free(vp->v_data, M_EXT2NODE); vp->v_data = 0; vnode_destroy_vobject(vp); ==== //depot/projects/soc2010/extfs/src/sys/fs/ext2fs/ext2_rsv_win.h#8 (text+ko) ==== @@ -30,28 +30,26 @@ #include <sys/tree.h> -#define EXT2_RWI_DEFAULT_RESERVE_BLKS 8 -#define EXT2_RWI_NOT_ALLOCATED 0 +#define EXT2_RSV_DEFAULT_RESERVE_BLKS 8 +#define EXT2_RSV_NOT_ALLOCATED 0 -#define EXT2_MAX_RSV_WIN_BLKS 1027 +#define EXT2_RSV_LOCK(ip) mtx_lock(&ip->i_rsv_lock) +#define EXT2_RSV_UNLOCK(ip) mtx_unlock(&ip->i_rsv_lock) -#define EXT2_IRSV_LOCK(ip) mtx_lock(&ip->i_rsv_lock) -#define EXT2_IRSV_UNLOCK(ip) mtx_unlock(&ip->i_rsv_lock) +#define EXT2_TREE_LOCK(fs) mtx_lock(&fs->e2fs_rsv_lock); +#define EXT2_TREE_UNLOCK(fs) mtx_unlock(&fs->e2fs_rsv_lock); -#define EXT2_TREE_LOCK(fs) mtx_lock_spin(&fs->e2fs_rsv_lock); -#define EXT2_TREE_UNLOCK(fs) mtx_unlock_spin(&fs->e2fs_rsv_lock); - /* * Reservation window entry */ struct ext2_rsv_win { - RB_ENTRY(ext2_rsv_win) rw_link; /* RB tree links */ + RB_ENTRY(ext2_rsv_win) rsv_link; /* RB tree links */ - int32_t rw_goal_size; /* Default reservation window size */ - int32_t rw_alloc_hit; /* Number of allocated windows */ + int32_t rsv_goal_size; /* Default reservation window size */ + int32_t rsv_alloc_hit; /* Number of allocated windows */ - int32_t rw_start; /* First bytes of window */ - int32_t rw_end; /* End bytes of window */ + int32_t rsv_start; /* First bytes of window */ + int32_t rsv_end; /* End bytes of window */ }; RB_HEAD(ext2_rsv_win_tree, ext2_rsv_win); @@ -60,14 +58,14 @@ ext2_rsv_win_cmp(const struct ext2_rsv_win *a, const struct ext2_rsv_win *b) { - if (a->rw_start < b->rw_start) + if (a->rsv_start < b->rsv_start) return -1; - if (a->rw_start == b->rw_start) + if (a->rsv_start == b->rsv_start) return 0; return 1; } -RB_PROTOTYPE(ext2_rsv_win_tree, ext2_rsv_win, rw_link, ext2_rsv_win_cmp); +RB_PROTOTYPE(ext2_rsv_win_tree, ext2_rsv_win, rsv_link, ext2_rsv_win_cmp); struct inode; /* ext2_alloc.c */ ==== //depot/projects/soc2010/extfs/src/sys/fs/ext2fs/ext2_vfsops.c#5 (text+ko) ==== @@ -584,7 +584,7 @@ /* Initial reservation window index and lock */ bzero(&ump->um_e2fs->e2fs_rsv_lock, sizeof(struct mtx)); mtx_init(&ump->um_e2fs->e2fs_rsv_lock, - "rsv tree lock", NULL, MTX_SPIN); + "rsv tree lock", NULL, MTX_DEF); RB_INIT(&ump->um_e2fs->e2fs_rsv_tree); brelse(bp); @@ -892,11 +892,6 @@ ip->i_ump = ump; ip->i_number = ino; - /* lazily initialize reservation window */ - bzero(&ip->i_rsv_lock, sizeof(struct mtx)); - mtx_init(&ip->i_rsv_lock, "inode rsv lock", NULL, MTX_DEF); - ip->i_rsv = NULL; - lockmgr(vp->v_vnlock, LK_EXCLUSIVE, NULL); error = insmntque(vp, mp); if (error != 0) { @@ -931,6 +926,14 @@ ip->i_prealloc_count = 0; ip->i_prealloc_block = 0; + bzero(&ip->i_rsv_lock, sizeof(struct mtx)); + mtx_init(&ip->i_rsv_lock, "inode rsv lock", NULL, MTX_DEF); + EXT2_RSV_LOCK(ip); + ip->i_rsv = NULL; + if (ip->i_rsv == NULL) + ext2_init_rsv(ip); + EXT2_RSV_UNLOCK(ip); + /* * Now we want to make sure that block pointers for unused * blocks are zeroed out - ext2_balloc depends on this
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201005211207.o4LC7ZXu014144>