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