Date: Tue, 23 Jun 2009 20:14:36 GMT From: Aditya Sarawgi <truncs@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 164993 for review Message-ID: <200906232014.n5NKEai0055632@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=164993 Change 164993 by truncs@aditya on 2009/06/23 20:14:31 Function to mark the buffer dirty. Removed some NetBSDism from it. Affected files ... .. //depot/projects/soc2009/soc_ext2fs/src/sys/gnu/fs/ext2fs/ext2_alloc.c#10 edit Differences ... ==== //depot/projects/soc2009/soc_ext2fs/src/sys/gnu/fs/ext2fs/ext2_alloc.c#10 (text+ko) ==== @@ -57,6 +57,8 @@ daddr_t (*)(struct inode *, int, daddr_t, int)); static daddr_t ext2fs_nodealloccg(struct inode *, int, daddr_t. int); +static daddr_t ext2fs_mapsearch(struct m_ext2fs *, char *, daddr_t); + /* * Linux calls this functions at the following locations: * (1) the inode is freed @@ -614,3 +616,202 @@ return (0); } +/* + * Determine whether a block can be allocated. + * + * Check to see if a block of the appropriate size is available, + * and if it is, allocate it. + */ + +static daddr_t +ext2_alloccg(struct inode *ip, int cg, daddr_t bpref, int size) +{ + struct m_ext2fs *fs; + char *bbp; + struct buf *bp; + /* XXX ondisk32 */ + int error, bno, start, end, loc; + + fs = ip->i_e2fs; + if (fs->e2fs_gd[cg].ext2bgd_nbfree == 0) + return (0); + error = bread(ip->i_devvp, fsbtodb(fs, + fs->e2fs_gd[cg].ext2bgd_b_bitmap), + (int)fs->e2fs_bsize, NOCRED, &bp); + if (error) { + brelse(bp, 0); + return (0); + } + bbp = (char *)bp->b_data; + + if (dtog(fs, bpref) != cg) + bpref = 0; + if (bpref != 0) { + bpref = dtogd(fs, bpref); + /* + * if the requested block is available, use it + */ + if (isclr(bbp, bpref)) { + bno = bpref; + goto gotit; + } + } + /* + * no blocks in the requested cylinder, so take next + * available one in this cylinder group. + * first try to get 8 contigous blocks, then fall back to a single + * block. + */ + 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; + } + } + + bno = ext2fs_mapsearch(fs, bbp, bpref); + if (bno < 0) + return (0); +gotit: +#ifdef DIAGNOSTIC + if (isset(bbp, (daddr_t)bno)) { + printf("ext2fs_alloccgblk: cg=%d bno=%d fs=%s\n", + cg, bno, fs->e2fs_fsmnt); + panic("ext2fs_alloccg: dup alloc"); + } +#endif + setbit(bbp, (daddr_t)bno); + fs->e2fs.e2fs_fbcount--; + fs->e2fs_gd[cg].ext2bgd_nbfree--; + mark_buffer_dirty(bp); + fs->e2fs_fmod = 1; + + return (cg * fs->e2fs.e2fs_fpg + fs->e2fs.e2fs_first_dblock + bno); +} + +/* + * Determine whether an inode can be allocated. + * + * Check to see if an inode is available, and if it is, + * allocate it using tode in the specified cylinder group. + */ +static daddr_t +ext2_nodealloccg(struct inode *ip, int cg, daddr_t ipref, int mode) +{ + struct m_ext2fs *fs; + char *ibp; + struct buf *bp; + int error, start, len, loc, map, i; + + ipref--; /* to avoid a lot of (ipref -1) */ + if (ipref == -1) + ipref = 0; + fs = ip->i_e2fs; + if (fs->e2fs_gd[cg].ext2bgd_nifree == 0) + return (0); + error = bread(ip->i_devvp, fsbtodb(fs, + fs->e2fs_gd[cg].ext2bgd_i_bitmap), + (int)fs->e2fs_bsize, NOCRED, &bp); + if (error) { + brelse(bp, 0); + return (0); + } + ibp = (char *)bp->b_data; + if (ipref) { + ipref %= fs->e2fs.e2fs_ipg; + if (isclr(ibp, ipref)) + goto gotit; + } + start = ipref / NBBY; + len = howmany(fs->e2fs.e2fs_ipg - ipref, NBBY); + loc = skpc(0xff, len, &ibp[start]); + if (l} + i = start + len - loc; + map = ibp[i]; + ipref = i * NBBY; + for (i = 1; i < (1 << NBBY); i <<= 1, ipref++) { + if ((map & i) == 0) { + goto gotit; + } + } + printf("fs = %s\n", fs->e2fs_fsmnt); + panic("ext2fs_nodealloccg: block not in map"); + /* NOTREACHED */ +gotit: + setbit(ibp, ipref); + fs->e2fs.e2fs_ficount--; + fs->e2fs_gd[cg].ext2bgd_nifree--; + fs->e2fs_fmod = 1; + if (S_ISDIR(mode)) { + fs->e2fs_gd[cg].ext2bgd_ndirs++; + } + mark_buffer_dirty(bp); + return (cg * fs->e2fs.e2fs_ipg + ipref +1); +} + +/* + * Find a block in the specified cylinder group. + * + * It is a panic if a request is made to find a block if none are + * available. + */ + +static daddr_t +ext2fs_mapsearch(struct m_ext2fs *fs, char *bbp, daddr_t bpref) +{ + daddr_t bno; + int start, len, loc, i, map; + + /* + * find the fragment by searching through the free block + * map for an appropriate bit pattern + */ + if (bpref) + start = dtogd(fs, bpref) / NBBY; + else + start = 0; + len = howmany(fs->e2fs.e2fs_fpg, NBBY) - start; + loc = skpc(0xff, len, &bbp[start]); + if (loc == 0) { + len = start + 1; + start = 0; + loc = skpc(0xff, len, &bbp[start]); + if (loc == 0) { + printf("start = %d, len = %d, fs = %s\n", + start, len, fs->e2fs_fsmnt); + panic("ext2fs_alloccg: map corrupted"); + /* NOTREACHED */ + } + } + i = start + len - loc; + map = bbp[i]; + bno = i * NBBY; + for (i = 1; i < (1 << NBBY); i <<= 1, bno++) { + if ((map & i) == 0) + return (bno); + } + printf("fs = %s\n", fs->e2fs_fsmnt); + panic("ext2fs_mapsearch: block not in map"); + /* NOTREACHED */ +} + +void mark_buffer_dirty(struct buf *bh) +{ + int s; + + s = splbio(); + bh->b_flags |= B_DIRTY; + splx(s); +} +
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906232014.n5NKEai0055632>