PERFORCE change 168680 for review
Aditya Sarawgi
truncs at FreeBSD.org
Sat Sep 19 13:43:36 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=168680
Change 168680 by truncs at aditya on 2009/09/19 13:43:32
WIP - Orlov block allocator for ext2fs. It will restrict many directories
to be in the same group. This will result in other directories having
sufficient space for their sub-directories and file. It also allows
spreading of directories in the root directory.
Affected files ...
.. //depot/projects/soc2009/soc_ext2fs/src/sys/fs/ext2fs/ext2_alloc.c#7 edit
.. //depot/projects/soc2009/soc_ext2fs/src/sys/fs/ext2fs/ext2fs.h#2 edit
Differences ...
==== //depot/projects/soc2009/soc_ext2fs/src/sys/fs/ext2fs/ext2_alloc.c#7 (text+ko) ====
@@ -52,7 +52,7 @@
#include <fs/ext2fs/ext2_extern.h>
static daddr_t ext2_alloccg(struct inode *, int, daddr_t, int);
-static u_long ext2_dirpref(struct m_ext2fs *);
+static u_long ext2_dirpref(struct inode *);
static void ext2_fserr(struct m_ext2fs *, u_int, char *);
static u_long ext2_hashalloc(struct inode *, int, long, int,
daddr_t (*)(struct inode *, int, daddr_t,
@@ -344,7 +344,7 @@
* inode.
*/
if((mode & IFMT) == IFDIR)
- cg = ext2_dirpref(fs);
+ cg = ext2_dirpref(pip);
else
cg = ino_to_cg(fs, pip->i_number);
ipref = cg * fs->e2fs->e2fs_ipg + 1;
@@ -393,26 +393,61 @@
/*
* Find a cylinder to place a directory.
*
- * The policy implemented by this algorithm is to select from
- * among those cylinder groups with above the average number of
- * free inodes, the one with the smallest number of directories.
+ * The policy implemented by this algorithm is to allocate a
+ * directory inode in the same cylinder group as its parent
+ * directory, but also to reserve space for its files inodes
+ * and data. Restrict the number of directories which may be
+ * allocated one after another in the same cylinder group
+ * without intervening allocation of files.
+ *
+ * If we allocate a first level directory then force allocation
+ * in another cylinder group.
+ *
*/
static u_long
-ext2_dirpref(struct m_ext2fs *fs)
+ext2_dirpref(struct inode *pip)
{
- int cg, maxspace, mincg, avgifree;
- avgifree = fs->e2fs->e2fs_ficount / fs->e2fs_gcount;
- maxspace = 0;
- mincg = -1;
- for (cg = 0; cg < fs->e2fs_gcount; cg++) {
- if ( fs->e2fs_gd[cg].ext2bgd_nifree >= avgifree) {
- if (mincg == -1 || fs->e2fs_gd[cg].ext2bgd_nbfree > maxspace) {
+ struct m_ext2fs *fs;
+ int cg, prefcg, dirsize, cgsize;
+ int avgifree, avgbfree, avgndir, curdirsize;
+ int minifree, minbfree, maxndir;
+ int mincg, minndir;
+ int maxcontigdirs;
+
+ fs = pip->i_e2fs;
+
+ avgifree = fs->e2fs->e2fs_ficount / fs->e2fs_gcount;
+ avgbfree = fs->e2fs->e2fs_fbcount / fs->e2fs_gcount;
+ avgndir = fs->e2fs_total_dir / e2fs->e2fs_gcount;
+
+ /*
+ * Force allocation in another cg if creating a first level dir.
+ */
+ ASSERT_VOP_LOCKED(ITOV(pip), "ext2fs_dirpref");
+ if (ITOV(pip)->v_vflag & VV_ROOT) {
+ prefcg = arc4random() % fs->e2fs_gcount;
+ mincg = prefcg;
+ minndir = fs->e2fs_ipg;
+ for (cg = prefcg; cg < fs->e2fs_gcount; cg++)
+ if (fs->e2fs_gd[cg].ext2bgd_ndirs < minndir &&
+ fs->e2fs_gd[cg].ext2bgd_nifree >= avgifree &&
+ fs->e2fs_gd[cg].ext2bgd_nbfree >= avgbfree) {
+ mincg = cg;
+ minndir = fs->e2fs_gd[cg].ext2bgd_ndirs;
+ }
+ for (cg = 0; cg < prefcg; cg++)
+ if (fs->e2fs_gd[cg].ext2bgd_ndirs < minndir &&
+ fs->e2fs_gd[cg].ext2bgd_nifree >= avgifree &&
+ fs->e2fs_gd[cg].ext2bgd_nbfree >= avgbfree) {
mincg = cg;
- maxspace = fs->e2fs_gd[cg].ext2bgd_nbfree;
+ minndir = fs->e2fs_gd[cg].ext2bgd_ndirs;
}
- }
+
+ return (mincg);
}
- return mincg;
+
+
+
}
/*
==== //depot/projects/soc2009/soc_ext2fs/src/sys/fs/ext2fs/ext2fs.h#2 (text+ko) ====
@@ -187,6 +187,7 @@
int32_t e2fs_isize; /* Size of inode */
uint32_t e2fs_mount_opt;
uint32_t e2fs_blocksize_bits;
+ uint32_t e2fs_total_dir; /* Total number of directories */
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