PERFORCE change 168852 for review

Aditya Sarawgi truncs at FreeBSD.org
Thu Sep 24 16:28:59 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=168852

Change 168852 by truncs at aditya on 2009/09/24 16:28:35

	Finish Orlov Block allocator for FreeBSD.

Affected files ...

.. //depot/projects/soc2009/soc_ext2fs/src/sys/fs/ext2fs/ext2_alloc.c#8 edit
.. //depot/projects/soc2009/soc_ext2fs/src/sys/fs/ext2fs/ext2_vfsops.c#7 edit
.. //depot/projects/soc2009/soc_ext2fs/src/sys/fs/ext2fs/ext2fs.h#3 edit

Differences ...

==== //depot/projects/soc2009/soc_ext2fs/src/sys/fs/ext2fs/ext2_alloc.c#8 (text+ko) ====

@@ -446,8 +446,60 @@
 		return (mincg);
 	}
 
+	/*
+	 * Count various limits which used for
+	 * optimal allocation of a directory inode.
+	 */
+	maxndir = min(avgndir + fs->e2fs_ipg / 16, fs->e2fs_ipg);
+	minifree = avgifree - avgifree / 4;
+	if (minifree < 1)
+		minifree = 1;
+	minbfree = avgbfree - avgbfree / 4;
+	if (minbfree < 1)
+		minbfree = 1;
+	cgsize = fs->e2fs_fsize * fs->e2fs_fpg;
+	dirsize = AVGDIRSIZE;
+	curdirsize = avgndir ? (cgsize - avgbfree * fs->e2fs_bsize) / avgndir : 0;
+	if (dirsize < curdirsize)
+		dirsize = curdirsize;
+	if (dirsize <= 0)
+		maxcontigdirs = 0;		/* dirsize overflowed */
+	else
+		maxcontigdirs = min((avgbfree * fs->e2fs_bsize) / dirsize, 255);
+		maxcontigdirs = min(maxcontigdirs, fs->fs_ipg / AFPDIR);
+	if (maxcontigdirs == 0)
+		maxcontigdirs = 1;
 
-
+	/*
+	 * Limit number of dirs in one cg and reserve space for 
+	 * regular files, but only if we have no deficit in
+	 * inodes or space.
+	 */
+	prefcg = ino_to_cg(fs, pip->i_number);
+	for (cg = prefcg; cg < fs->e2fs_gcount; cg++)
+		if (fs->e2fs_gd[cg].ext2bgd_ndirs < maxndir &&
+		    fs->e2fs_gd[cg].ext2bgd_nifree >= minifree &&
+	    	    fs->e2fs_gd[cg].ext2bgd_nbfree >= minbfree) {
+			if (fs->e2fs_contigdirs[cg] < maxcontigdirs)
+				return (cg);
+		}
+	for (cg = 0; cg < prefcg; cg++)
+		if (fs->e2fs_gd[cg].ext2bgd_ndirs < maxndir &&
+		    fs->e2fs_gd[cg].ext2bgd_nifree >= minifree &&
+	    	    fs->e2fs_gd[cg].ext2bgd_nbfree >= minbfree) {
+			if (fs->e2fs_contigdirs[cg] < maxcontigdirs)
+				return (cg);
+		}
+	/*
+	 * This is a backstop when we have deficit in space.
+	 */
+	for (cg = prefcg; cg < fs->e2fs_gcount; cg++)
+		if (fs->e2fs_gd[cg].ext2bgd_nifree >= avgifree)
+			return (cg);
+	for (cg = 0; cg < prefcg; cg++)
+		if (fs->e2fs_gd[cg].ext2bgd_nifree >= avgifree)
+			break;
+	return (cg);
 }
 
 /*

==== //depot/projects/soc2009/soc_ext2fs/src/sys/fs/ext2fs/ext2_vfsops.c#7 (text+ko) ====

@@ -357,6 +357,8 @@
 	fs->e2fs_gdbcount = db_count;
 	fs->e2fs_gd = malloc(db_count * fs->e2fs_bsize,
 	    M_EXT2MNT, M_WAITOK);
+	fs->e2fs_contigdirs = malloc(fs->e2fs_gcount * sizeof(*fs->e2fs_contigdirs), 
+	    M_EXT2MNT, M_WAITOK);
 
 	/*
 	 * Adjust logic_sb_block.
@@ -384,6 +386,7 @@
 	fs->e2fs_total_dir = 0;
 	for (i=0; i < fs->e2fs_gcount; i++){
 		fs->e2fs_total_dir += fs->e2fs_gd[i].ext2bgd_ndirs;
+		fs->e2fs_contigdirs[i] = 0;
 	}
 	uprintf("Total dirs %d", fs->e2fs_total_dir);
 	if (es->e2fs_rev == E2FS_REV0 ||
@@ -627,6 +630,7 @@
 	}
 	if (ump) {
 		free(ump->um_e2fs->e2fs_gd, M_EXT2MNT);
+		free(ump->um_e2fs->e2fs_contigdirs, M_EXT2MNT);
 		free(ump->um_e2fs->e2fs, M_EXT2MNT);
 		free(ump->um_e2fs, M_EXT2MNT);
 		free(ump, M_EXT2MNT);
@@ -669,6 +673,7 @@
 	PICKUP_GIANT();
 	vrele(ump->um_devvp);
 	free(fs->e2fs_gd, M_EXT2MNT);
+	free(fs->e2fs_contigdirs, M_EXT2MNT);
 	free(fs->e2fs, M_EXT2MNT);
 	free(fs, M_EXT2MNT);
 	free(ump, M_EXT2MNT);

==== //depot/projects/soc2009/soc_ext2fs/src/sys/fs/ext2fs/ext2fs.h#3 (text+ko) ====

@@ -188,6 +188,7 @@
 	uint32_t e2fs_mount_opt;
 	uint32_t e2fs_blocksize_bits;
 	uint32_t e2fs_total_dir;  /* Total number of directories */
+	uint8_t	*e2fs_contigdirs;
 	char e2fs_wasvalid;       /* valid at mount time */
 	off_t e2fs_maxfilesize;
 	struct ext2_gd *e2fs_gd; /* Group Descriptors */


More information about the p4-projects mailing list