From owner-p4-projects@FreeBSD.ORG Fri Jul 23 07:59:33 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 1DE9B1065676; Fri, 23 Jul 2010 07:59:33 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id C63A71065672 for ; Fri, 23 Jul 2010 07:59:32 +0000 (UTC) (envelope-from lz@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id B40DB8FC27 for ; Fri, 23 Jul 2010 07:59:32 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id o6N7xWQM008886 for ; Fri, 23 Jul 2010 07:59:32 GMT (envelope-from lz@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id o6N7xW2L008884 for perforce@freebsd.org; Fri, 23 Jul 2010 07:59:32 GMT (envelope-from lz@FreeBSD.org) Date: Fri, 23 Jul 2010 07:59:32 GMT Message-Id: <201007230759.o6N7xW2L008884@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to lz@FreeBSD.org using -f From: Zheng Liu To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 181353 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 23 Jul 2010 07:59:33 -0000 http://p4web.freebsd.org/@@181353?ac=10 Change 181353 by lz@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 #include #include +#include + +#include #include #include @@ -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 #include #include +#include /* * 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; }; /*