PERFORCE change 181353 for review
Zheng Liu
lz at FreeBSD.org
Fri Jul 23 07:59:33 UTC 2010
http://p4web.freebsd.org/@@181353?ac=10
Change 181353 by lz at gnehzuil-freebsd on 2010/07/23 07:59:03
Add flex group data structure and add a function to initialize it.
* FLEX_BG feature don't be required in read-only mode. However, I add a
data structure and a function into ext2fs.
* Now ext2fs can read ext4 file system, which is with some features:
+ HAS_JOURNAL (NOT support this feature. It just can read data when file system
with this feature.)
+ FILETYPE
+ SPARSE_SUPER
+ HUGE_FILE
+ EXTENTS (NOW it just can read data from ext4 extents.)
+ DIR_NLINK
+ UNINIT_BG (IT don't be required in read-only mode.)
+ FLEX_BG (IT dont't be required in read-only mode.)
Affected files ...
.. //depot/projects/soc2010/ext4fs/src/sys/fs/ext2fs/ext2_vfsops.c#8 edit
.. //depot/projects/soc2010/ext4fs/src/sys/fs/ext2fs/ext2fs.h#4 edit
Differences ...
==== //depot/projects/soc2010/ext4fs/src/sys/fs/ext2fs/ext2_vfsops.c#8 (text+ko) ====
@@ -51,6 +51,9 @@
#include <sys/malloc.h>
#include <sys/stat.h>
#include <sys/mutex.h>
+#include <sys/types.h>
+
+#include <machine/atomic.h>
#include <geom/geom.h>
#include <geom/geom_vfs.h>
@@ -94,6 +97,8 @@
int ronly);
static int compute_sb_data(struct vnode * devvp,
struct ext2fs * es, struct m_ext2fs * fs);
+static int ext4_init_fg(struct m_ext2fs *);
+static int find_most_set_bit(int64_t n);
static const char *ext2_opts[] = { "from", "export", "acls", "noexec",
"noatime", "union", "suiddir", "multilabel", "nosymfollow",
@@ -349,6 +354,7 @@
fs->e2fs_ipb = fs->e2fs_bsize / EXT2_INODE_SIZE(fs);
fs->e2fs_itpg = fs->e2fs_ipg /fs->e2fs_ipb;
fs->e2fs_descpb = fs->e2fs_bsize / sizeof (struct ext2_gd);
+ fs->e2fs_descpbbits = find_most_set_bit(fs->e2fs_descpb);
/* s_resuid / s_resgid ? */
fs->e2fs_gcount = (((int64_t)(es->e2fs_bcount_hi) << 32 | es->e2fs_bcount_lo)
- es->e2fs_first_dblock + EXT2_BLOCKS_PER_GROUP(fs) - 1) /
@@ -384,6 +390,10 @@
brelse(bp);
bp = NULL;
}
+
+ /* initialize flex groups */
+ ext4_init_fg(fs);
+
fs->e2fs_total_dir = 0;
for (i=0; i < fs->e2fs_gcount; i++){
fs->e2fs_total_dir += (fs->e2fs_gd[i].ext2bgd_ndirs_lo);
@@ -398,6 +408,71 @@
}
/*
+ * Initialize flex groups data structure.
+ */
+static int
+ext4_init_fg(struct m_ext2fs *fs)
+{
+ struct ext2fs *es = fs->e2fs;
+ int i, gpf = 0;
+ unsigned int fgcount, fg;
+ long nifree, nbfree, ndirs;
+
+ fs->e2fs_log_gpf = es->e2fs_log_gpf;
+ gpf = 1 << fs->e2fs_log_gpf;
+
+ if (gpf < 2) {
+ fs->e2fs_log_gpf = 0;
+ return (0);
+ }
+
+ fgcount = ((fs->e2fs_gcount + gpf - 1) +
+ ((es->e2fs_reserved_ngdb + 1) << fs->e2fs_descpbbits)) / gpf;
+
+ fs->e2fs_fg = malloc(fgcount * sizeof(struct ext4_flex_groups),
+ M_EXT2MNT, M_WAITOK | M_ZERO);
+
+ for (i = 0; i < fs->e2fs_gcount; i++) {
+ nifree = 0;
+ nbfree = 0;
+ ndirs = 0;
+ fg = i >> fs->e2fs_log_gpf;
+
+ /* XXX: need to support 64 bits. */
+ nifree = fs->e2fs_gd[i].ext2bgd_nifree_lo;
+ nbfree = fs->e2fs_gd[i].ext2bgd_nbfree_lo;
+ ndirs = fs->e2fs_gd[i].ext2bgd_ndirs_lo;
+
+ atomic_add_long(&fs->e2fs_fg[fg].e2fg_nifree, nifree);
+ atomic_add_long(&fs->e2fs_fg[fg].e2fg_nbfree, nbfree);
+ atomic_add_long(&fs->e2fs_fg[fg].e2fg_ndirs, ndirs);
+ }
+
+ return (0);
+}
+
+/*
+ * Find most significant set bit.
+ *
+ * TODO: Maybe it need to rewrite by assembly language for
+ * improving the performance.
+ */
+static int
+find_most_set_bit(int64_t n)
+{
+ int64_t num, i;
+ unsigned int pos, res = 0;
+
+ for (num = 1; num <= n; num++) {
+ for (i = (num >> 1), pos = 0; i != 0; pos++)
+ i >>= 1;
+ res = pos;
+ }
+
+ return res;
+}
+
+/*
* Reload all incore data for a filesystem (used after running fsck on
* the root filesystem and finding things to fix). The filesystem must
* be mounted read-only.
@@ -688,6 +763,7 @@
PICKUP_GIANT();
vrele(ump->um_devvp);
mtx_destroy(&fs->e2fs_rsv_lock);
+ free(fs->e2fs_fg, M_EXT2MNT);
free(fs->e2fs_gd, M_EXT2MNT);
free(fs->e2fs_contigdirs, M_EXT2MNT);
free(fs->e2fs, M_EXT2MNT);
==== //depot/projects/soc2010/ext4fs/src/sys/fs/ext2fs/ext2fs.h#4 (text+ko) ====
@@ -40,6 +40,7 @@
#include <sys/types.h>
#include <sys/lock.h>
#include <fs/ext2fs/ext2_rsv_win.h>
+#include <machine/atomic.h>
/*
* Special inode numbers
@@ -92,6 +93,15 @@
*/
#define MAXMNTLEN 512
+/* ext4 flex block group data structure */
+struct ext4_flex_groups {
+ long e2fg_nifree;
+ long e2fg_nbfree;
+ long e2fg_ndirs;
+};
+
+#define EXT4_FLEX_ALLOC_DIR_SIZE 4
+
/*
* Super block for an ext2fs file system.
*/
@@ -203,10 +213,14 @@
uint8_t *e2fs_contigdirs;
char e2fs_wasvalid; /* valid at mount time */
off_t e2fs_maxfilesize;
- struct ext2_gd *e2fs_gd; /* Group Descriptors */
+ struct ext2_gd *e2fs_gd; /* Group Descriptors */
struct mtx e2fs_rsv_lock; /* Protect reservation window RB tree */
struct ext2_rsv_win_tree e2fs_rsv_tree; /* Reservation window index */
+
+ u_int8_t e2fs_log_gpf; /* FLEX_BG group size */
+ int e2fs_descpbbits;
+ struct ext4_flex_groups *e2fs_fg;
};
/*
More information about the p4-projects
mailing list