kern/153584: commit references a PR

dfilter service dfilter at FreeBSD.ORG
Tue Feb 1 18:30:11 UTC 2011


The following reply was made to PR kern/153584; it has been noted by GNATS.

From: dfilter at FreeBSD.ORG (dfilter service)
To: bug-followup at FreeBSD.org
Cc:  
Subject: Re: kern/153584: commit references a PR
Date: Tue,  1 Feb 2011 18:21:52 +0000 (UTC)

 Author: jhb
 Date: Tue Feb  1 18:21:45 2011
 New Revision: 218175
 URL: http://svn.freebsd.org/changeset/base/218175
 
 Log:
   - Set the next_alloc fields for an i-node after allocating a new block
     so that future allocations start with most recently allocated block
     rather than the beginning of the filesystem.
   - Fix ext2_alloccg() to properly scan for 8 block chunks that are not
     aligned on 8-bit boundaries.  Previously this was causing new blocks
     to be allocated in a highly fragmented fashion (block 0 of a file at
     lbn N, block 1 at lbn N + 8, block 2 at lbn N + 16, etc.).
   - Cosmetic tweaks to the currently-disabled fancy realloc sysctls.
   
   PR:		kern/153584
   Discussed with:	bde
   Tested by:	Pedro F. Giffuni  giffunip at yahoo, Zheng Liu (lz)
 
 Modified:
   head/sys/fs/ext2fs/ext2_alloc.c
 
 Modified: head/sys/fs/ext2fs/ext2_alloc.c
 ==============================================================================
 --- head/sys/fs/ext2fs/ext2_alloc.c	Tue Feb  1 17:42:57 2011	(r218174)
 +++ head/sys/fs/ext2fs/ext2_alloc.c	Tue Feb  1 18:21:45 2011	(r218175)
 @@ -59,6 +59,10 @@ static u_long	ext2_hashalloc(struct inod
  						int));
  static daddr_t	ext2_nodealloccg(struct inode *, int, daddr_t, int);
  static daddr_t  ext2_mapsearch(struct m_ext2fs *, char *, daddr_t);
 +#ifdef FANCY_REALLOC
 +static int	ext2_reallocblks(struct vop_reallocblks_args *);
 +#endif
 +
  /*
   * Allocate a block in the file system.
   *
 @@ -108,13 +112,17 @@ ext2_alloc(ip, lbn, bpref, size, cred, b
  		goto nospace;
  	if (bpref >= fs->e2fs->e2fs_bcount)
  		bpref = 0;
 -	 if (bpref == 0)
 +	if (bpref == 0)
                  cg = ino_to_cg(fs, ip->i_number);
          else
                  cg = dtog(fs, bpref);
          bno = (daddr_t)ext2_hashalloc(ip, cg, bpref, fs->e2fs_bsize,
                                                   ext2_alloccg);
          if (bno > 0) {
 +		/* set next_alloc fields as done in block_getblk */
 +		ip->i_next_alloc_block = lbn;
 +		ip->i_next_alloc_goal = bno;
 +
                  ip->i_blocks += btodb(fs->e2fs_bsize);
                  ip->i_flag |= IN_CHANGE | IN_UPDATE;
                  *bnp = bno;
 @@ -143,13 +151,14 @@ nospace:
   */
  
  #ifdef FANCY_REALLOC
 -#include <sys/sysctl.h>
 +SYSCTL_NODE(_vfs, OID_AUTO, ext2fs, CTLFLAG_RW, 0, "EXT2FS filesystem");
 +
  static int doasyncfree = 1;
 -static int doreallocblks = 1;
 +SYSCTL_INT(_vfs_ext2fs, OID_AUTO, doasyncfree, CTLFLAG_RW, &doasyncfree, 0,
 +    "Use asychronous writes to update block pointers when freeing blocks");
  
 -#ifdef	OPT_DEBUG
 -SYSCTL_INT(_debug, 14, doasyncfree, CTLFLAG_RW, &doasyncfree, 0, "");
 -#endif	/* OPT_DEBUG */
 +static int doreallocblks = 1;
 +SYSCTL_INT(_vfs_ext2fs, OID_AUTO, doreallocblks, CTLFLAG_RW, &doreallocblks, 0, "");
  #endif
  
  int
 @@ -624,7 +633,8 @@ ext2_alloccg(struct inode *ip, int cg, d
  	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;
  	char *bbp;
  	/* XXX ondisk32 */
  	fs = ip->i_e2fs;
 @@ -665,18 +675,52 @@ ext2_alloccg(struct inode *ip, int cg, d
  	else
  		start = 0;
  	end = howmany(fs->e2fs->e2fs_fpg, NBBY) - start;
 +retry:
 +	runlen = 0;
 +	runstart = 0;
  	for (loc = start; loc < end; loc++) {
 -		if (bbp[loc] == 0) {
 -			bno = loc * NBBY;
 -			goto gotit;
 +		if (bbp[loc] == (char)0xff) {
 +			runlen = 0;
 +			continue;
  		}
 -	}
 -	for (loc = 0; loc < start; loc++) {
 -		if (bbp[loc] == 0) {
 -			bno = loc * NBBY;
 +
 +		/* 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) {
 +			/* Continue a run. */
 +			runlen += NBBY;
 +		} else {
 +			/*
 +			 * Finish the current run.  If it isn't long
 +			 * enough, start a new one.
 +			 */
 +			bit = ffs(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;
 +	}
  
  	bno = ext2_mapsearch(fs, bbp, bpref);
  	if (bno < 0){
 _______________________________________________
 svn-src-all at freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe at freebsd.org"
 


More information about the freebsd-fs mailing list