Subject: minor tweak to ffs_blkpref
To: None <tech-kern@netbsd.org>
From: Darrin B.Jewell <dbj@netbsd.org>
List: tech-kern
Date: 06/06/2005 13:53:58
--=-=-=


Each ffs filesystem cylinder group reserves blocks for its
administrative data near the start of the cylinder group, but offset
slightly to leave room for the boot blocks and superblock in cylinder
group 0.  As a result, each brand new ffs filesystem contains a small
region of free blocks at the start of each cylinder group, separated
from the large region of free blocks.  With the newly increased size
of the bootblock region, this area is now frequently several fs_bsize
units largs, although usually much smaller than fs_maxbpg, which is
typically the largest run the allocator will attempt to place in each
cylinder group.

The current blkpref algorithm will attempt to start a new run of
blocks in each cylinder group at an offset of one block from the start
of the cylinder group.  Unfortunately, this is now frequently inside
the small region of free blocks at the start of the cylinder group,
and the run will immediately get broken and end up continuing on
the other side of the cylinder group administrative data.

The following patch starts the search for free blocks immediately
after the administration data in each cylinder group.  This results in
better contiguous layout and the small allocation region now will
only get used once the filesystem starts to get full.

Does anyone see any downside?

Darrin


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment; filename=ffsblkpref.diff
Content-Description: tweak cylinder group block allocation start

Index: sys/ufs/ffs/ffs_alloc.c
===================================================================
RCS file: /u3/n/rsync/cvsroot/src/sys/ufs/ffs/ffs_alloc.c,v
retrieving revision 1.84
diff -u -u -b -p -r1.84 ffs_alloc.c
--- sys/ufs/ffs/ffs_alloc.c	6 Jun 2005 17:10:25 -0000	1.84
+++ sys/ufs/ffs/ffs_alloc.c	6 Jun 2005 17:30:48 -0000
@@ -895,7 +895,7 @@ ffs_blkpref_ufs1(ip, lbn, indx, bap)
 	if (indx % fs->fs_maxbpg == 0 || bap[indx - 1] == 0) {
 		if (lbn < NDADDR + NINDIR(fs)) {
 			cg = ino_to_cg(fs, ip->i_number);
-			return (fs->fs_fpg * cg + fs->fs_frag);
+			return cgdmin(fs, cg);
 		}
 		/*
 		 * Find a cylinder with greater than average number of
@@ -911,11 +911,11 @@ ffs_blkpref_ufs1(ip, lbn, indx, bap)
 		avgbfree = fs->fs_cstotal.cs_nbfree / fs->fs_ncg;
 		for (cg = startcg; cg < fs->fs_ncg; cg++)
 			if (fs->fs_cs(fs, cg).cs_nbfree >= avgbfree) {
-				return (fs->fs_fpg * cg + fs->fs_frag);
+				return cgdmin(fs, cg);
 			}
 		for (cg = 0; cg < startcg; cg++)
 			if (fs->fs_cs(fs, cg).cs_nbfree >= avgbfree) {
-				return (fs->fs_fpg * cg + fs->fs_frag);
+				return cgdmin(fs, cg);
 			}
 		return (0);
 	}
@@ -940,7 +940,7 @@ ffs_blkpref_ufs2(ip, lbn, indx, bap)
 	if (indx % fs->fs_maxbpg == 0 || bap[indx - 1] == 0) {
 		if (lbn < NDADDR + NINDIR(fs)) {
 			cg = ino_to_cg(fs, ip->i_number);
-			return (fs->fs_fpg * cg + fs->fs_frag);
+			return cgdmin(fs, cg);
 		}
 		/*
 		 * Find a cylinder with greater than average number of
@@ -956,11 +956,11 @@ ffs_blkpref_ufs2(ip, lbn, indx, bap)
 		avgbfree = fs->fs_cstotal.cs_nbfree / fs->fs_ncg;
 		for (cg = startcg; cg < fs->fs_ncg; cg++)
 			if (fs->fs_cs(fs, cg).cs_nbfree >= avgbfree) {
-				return (fs->fs_fpg * cg + fs->fs_frag);
+				return cgdmin(fs, cg);
 			}
 		for (cg = 0; cg < startcg; cg++)
 			if (fs->fs_cs(fs, cg).cs_nbfree >= avgbfree) {
-				return (fs->fs_fpg * cg + fs->fs_frag);
+				return cgdmin(fs, cg);
 			}
 		return (0);
 	}

--=-=-=--