Whamcloud - gitweb
LU-4017 e2fsprogs: add project quota support 62/15762/22
authorLi Xi <lixi@ddn.com>
Fri, 20 Mar 2015 04:46:25 +0000 (12:46 +0800)
committerAndreas Dilger <andreas.dilger@intel.com>
Tue, 19 Jul 2016 09:55:36 +0000 (09:55 +0000)
Adds project ID support for ext4, this patch implement
it by adding a new internal field of ext4 inode to save
project identifier.

Project inode number is allocated dynamically, to fix
compatibility, project feature is disabled in default.

If users want to use project quota, they can do it by:

mkfs.ext4 -O quota,project <dev>

or enable project later by:

tune2fs -O project <dev>
tune2fs -Q prjquota <dev>

Signed-off-by: Li Xi <lixi@ddn.com>
Signed-off-by: Wang Shilong <wshilong@ddn.com>
Change-Id: I2497c56802f0ab155b16908012a2e83beb70f9cd
Reviewed-on: http://review.whamcloud.com/15762
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Niu Yawei <yawei.niu@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
19 files changed:
debugfs/set_fields.c
e2fsck/pass1.c
e2fsck/pass4.c
lib/e2p/ls.c
lib/ext2fs/ext2_fs.h
lib/ext2fs/swapfs.c
lib/ext2fs/tst_inode_size.c
lib/ext2fs/tst_super_size.c
lib/quota/mkquota.c
lib/quota/quotaio.c
lib/quota/quotaio.h
misc/mke2fs.c
misc/tune2fs.8.in
misc/tune2fs.c
tests/f_expisize_ea_del/expect.1
tests/m_bigjournal/expect.1
tests/m_large_file/expect.1
tests/m_quota/expect.1
tests/m_quota/script

index 601dc52..920f17d 100644 (file)
@@ -150,6 +150,7 @@ static struct field_set_info super_fields[] = {
        { "mount_opts",  &set_sb.s_mount_opts, NULL, 64, parse_string },
        { "usr_quota_inum", &set_sb.s_usr_quota_inum, NULL, 4, parse_uint },
        { "grp_quota_inum", &set_sb.s_grp_quota_inum, NULL, 4, parse_uint },
+       { "prj_quota_inum", &set_sb.s_prj_quota_inum, NULL, 4, parse_uint },
        { "overhead_blocks", &set_sb.s_overhead_blocks, NULL, 4, parse_uint },
        { "backup_bgs", &set_sb.s_backup_bgs[0], NULL, 4, parse_uint,
          FLAG_ARRAY, 2 },
@@ -216,6 +217,7 @@ static struct field_set_info inode_fields[] = {
        { "crtime", &set_inode.i_crtime, NULL, 4, parse_uint },
        { "crtime_extra", &set_inode.i_crtime_extra, NULL,
                4, parse_uint },
+       { "i_projid", &set_inode.i_projid, NULL, 4, parse_uint },
        { "bmap", NULL, NULL, 4, parse_bmap, FLAG_ARRAY },
        { 0, 0, 0, 0 }
 };
index b73b8ab..a7d8ad4 100644 (file)
@@ -2731,7 +2731,8 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
                }
        }
 
-       if (ino == EXT2_ROOT_INO || ino >= EXT2_FIRST_INODE(ctx->fs->super)) {
+       if (ino != quota_type2inum(PRJQUOTA, fs->super) &&
+           (ino == EXT2_ROOT_INO || ino >= EXT2_FIRST_INODE(ctx->fs->super))) {
                quota_data_add(ctx->qctx, inode, ino,
                               pb.num_blocks * fs->blocksize);
                quota_data_inodes(ctx->qctx, inode, ino, +1);
index 81fd846..d9210ea 100644 (file)
@@ -148,7 +148,8 @@ void e2fsck_pass4(e2fsck_t ctx)
                                if ((ctx->progress)(ctx, 4, group, maxgroup))
                                        goto errout;
                }
-               if (i == EXT2_BAD_INO ||
+               if (i == quota_type2inum(PRJQUOTA, ctx->fs->super) ||
+                   i == EXT2_BAD_INO ||
                    (i > EXT2_ROOT_INO && i < EXT2_FIRST_INODE(fs->super)))
                        continue;
                if (!(ext2fs_test_inode_bitmap2(ctx->inode_used_map, i)) ||
index 0df3622..3c1d6e1 100644 (file)
@@ -200,6 +200,7 @@ static __u64 e2p_free_blocks_count(struct ext2_super_block *super)
 static const char *quota_prefix[MAXQUOTAS] = {
        [USRQUOTA] = "User quota inode:",
        [GRPQUOTA] = "Group quota inode:",
+       [PRJQUOTA] = "Project quota inode:",
 };
 
 /**
index efde7a5..0438720 100644 (file)
@@ -457,6 +457,7 @@ struct ext2_inode_large {
        __u32   i_crtime;       /* File creation time */
        __u32   i_crtime_extra; /* extra File creation time (nsec << 2 | epoch)*/
        __u32   i_version_hi;   /* high 32 bits for 64-bit version */
+       __u32   i_projid;       /* Project ID */
 };
 
 #define i_dir_acl      i_size_high
@@ -467,6 +468,10 @@ struct ext2_inode_large {
                         (EXT2_GOOD_OLD_INODE_SIZE +    \
                          (inode)->i_extra_isize))      \
 
+#define inode_includes(size, field)                    \
+       (size >= (sizeof(((struct ext2_inode_large *)0)->field) + \
+                 offsetof(struct ext2_inode_large, field)))
+
 #if defined(__KERNEL__) || defined(__linux__)
 #define i_reserved1    osd1.linux1.l_i_reserved1
 #define i_frag         osd2.linux2.l_i_frag
@@ -490,6 +495,7 @@ struct ext2_inode_large {
 
 #define inode_uid(inode)       ((inode).i_uid | (inode).osd2.linux2.l_i_uid_high << 16)
 #define inode_gid(inode)       ((inode).i_gid | (inode).osd2.linux2.l_i_gid_high << 16)
+#define inode_projid(inode)    ((inode).i_projid)
 #define ext2fs_set_i_uid_high(inode,x) ((inode).osd2.linux2.l_i_uid_high = (x))
 #define ext2fs_set_i_gid_high(inode,x) ((inode).osd2.linux2.l_i_gid_high = (x))
 
@@ -657,7 +663,12 @@ struct ext2_super_block {
        __u32   s_grp_quota_inum;       /* inode number of group quota file */
        __u32   s_overhead_blocks;      /* overhead blocks/clusters in fs */
        __u32   s_backup_bgs[2];        /* If sparse_super2 enabled */
-       __u32   s_reserved[106];        /* Padding to the end of the block */
+       __u8    s_encrypt_algos[4];     /* Encryption algorithms in use  */
+       __u8    s_encrypt_pw_salt[16];  /* Salt used for string2key algorithm */
+       __u32   s_lpf_ino;              /* Location of the lost+found inode */
+       __u32   s_prj_quota_inum;       /* project quota file inode number */
+       __u32   s_checksum_seed;        /* crc32c(uuid) if csum_seed set */
+       __u32   s_reserved[98];         /* Padding to the end of the block */
        __u32   s_checksum;             /* crc32c(superblock) */
 };
 
index dfb1cab..6356874 100644 (file)
@@ -210,6 +210,7 @@ void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
        int has_extents = 0;
        int islnk = 0;
        __u32 *eaf, *eat;
+       int inode_size;
 
        if (hostorder && LINUX_S_ISLNK(f->i_mode))
                islnk = 1;
@@ -295,21 +296,24 @@ void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
                /* this is error case: i_extra_size is too large */
                return;
        }
+       inode_size = EXT2_GOOD_OLD_INODE_SIZE + extra_isize;
 
-       if (extra_isize >= 4)
+       if (inode_includes(inode_size, i_checksum_hi))
                t->i_checksum_hi = ext2fs_swab16(f->i_checksum_hi);
-       if (extra_isize >= 8)
+       if (inode_includes(inode_size, i_ctime_extra))
                t->i_ctime_extra = ext2fs_swab32(f->i_ctime_extra);
-       if (extra_isize >= 12)
+       if (inode_includes(inode_size, i_mtime_extra))
                t->i_mtime_extra = ext2fs_swab32(f->i_mtime_extra);
-       if (extra_isize >= 16)
+       if (inode_includes(inode_size, i_atime_extra))
                t->i_atime_extra = ext2fs_swab32(f->i_atime_extra);
-       if (extra_isize >= 20)
+       if (inode_includes(inode_size, i_crtime))
                t->i_crtime = ext2fs_swab32(f->i_crtime);
-       if (extra_isize >= 24)
+       if (inode_includes(inode_size, i_crtime_extra))
                t->i_crtime_extra = ext2fs_swab32(f->i_crtime_extra);
-       if (extra_isize >= 28)
+       if (inode_includes(inode_size, i_version_hi))
                t->i_version_hi = ext2fs_swab32(f->i_version_hi);
+       if (inode_includes(inode_size, i_projid))
+                t->i_projid = ext2fs_swab16(f->i_projid);
 
        i = sizeof(struct ext2_inode) + extra_isize + sizeof(__u32);
        if (bufsize < (int) i)
index e20ec98..cc5d165 100644 (file)
@@ -81,6 +81,7 @@ int main(int argc, char **argv)
        check_field(i_crtime, 4);
        check_field(i_crtime_extra, 4);
        check_field(i_version_hi, 4);
+       check_field(i_projid, 4);
        /* This size will change as new fields are added */
        do_field("Large inode end", 0, 0, cur_offset, sizeof(inode));
 #endif
index f9cec8a..8bf08d4 100644 (file)
@@ -136,7 +136,12 @@ int main(int argc, char **argv)
        check_field(s_grp_quota_inum, 4);
        check_field(s_overhead_blocks, 4);
        check_field(s_backup_bgs, 8);
-       check_field(s_reserved, 106 * 4);
+       check_field(s_encrypt_algos, 4);
+       check_field(s_encrypt_pw_salt, 16);
+       check_field(s_lpf_ino, 4);
+       check_field(s_prj_quota_inum, 4);
+       check_field(s_checksum_seed, 4);
+       check_field(s_reserved, 98 * 4);
        check_field(s_checksum, 4);
        do_field("Superblock end", 0, 0, cur_offset, 1024);
 #endif
index 7467eb9..a3a617c 100644 (file)
@@ -110,10 +110,22 @@ errcode_t quota_remove_inode(ext2_filsys fs, enum quota_type qtype)
                return retval;
        }
        qf_ino = *quota_sb_inump(fs->super, qtype);
-       quota_set_sb_inum(fs, 0, qtype);
-       /* Truncate the inode only if its a reserved one. */
-       if (qf_ino < EXT2_FIRST_INODE(fs->super))
+       if (qf_ino < EXT2_FIRST_INODE(fs->super)) {
                quota_inode_truncate(fs, qf_ino);
+       } else {
+               struct ext2_inode inode;
+
+               quota_inode_truncate(fs, qf_ino);
+               retval = ext2fs_read_inode(fs, qf_ino, &inode);
+               if (!retval) {
+                       memset(&inode, 0, sizeof(struct ext2_inode));
+                       ext2fs_write_inode(fs, qf_ino, &inode);
+               }
+               ext2fs_inode_alloc_stats2(fs, qf_ino, -1, 0);
+               ext2fs_mark_ib_dirty(fs);
+
+       }
+       quota_set_sb_inum(fs, 0, qtype);
 
        ext2fs_mark_super_dirty(fs);
        fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
@@ -229,13 +241,21 @@ static int dict_uint_cmp(const void *a, const void *b)
                return -1;
 }
 
-static inline qid_t get_qid(struct ext2_inode *inode, enum quota_type qtype)
+static inline qid_t get_qid(struct ext2_inode_large *inode, enum quota_type qtype)
 {
+       struct ext2_inode_large *large_inode;
+       int inode_size;
+
        switch (qtype) {
        case USRQUOTA:
                return inode_uid(*inode);
        case GRPQUOTA:
                return inode_gid(*inode);
+       case PRJQUOTA:
+               inode_size = EXT2_GOOD_OLD_INODE_SIZE +
+                               inode->i_extra_isize;
+               if (inode_includes(inode_size, i_projid))
+                       return inode_projid(*inode);
        default:
                return 0;
        }
@@ -345,8 +365,8 @@ static struct dquot *get_dq(dict_t *dict, __u32 key)
 /*
  * Called to update the blocks used by a particular inode
  */
-void quota_data_add(quota_ctx_t qctx, struct ext2_inode *inode, ext2_ino_t ino,
-                   qsize_t space)
+void quota_data_add(quota_ctx_t qctx, struct ext2_inode_large *inode,
+                   ext2_ino_t ino, qsize_t space)
 {
        struct dquot    *dq;
        dict_t          *dict;
@@ -371,8 +391,8 @@ void quota_data_add(quota_ctx_t qctx, struct ext2_inode *inode, ext2_ino_t ino,
 /*
  * Called to remove some blocks used by a particular inode
  */
-void quota_data_sub(quota_ctx_t qctx, struct ext2_inode *inode, ext2_ino_t ino,
-                   qsize_t space)
+void quota_data_sub(quota_ctx_t qctx, struct ext2_inode_large *inode,
+                   ext2_ino_t ino, qsize_t space)
 {
        struct dquot    *dq;
        dict_t          *dict;
@@ -396,7 +416,7 @@ void quota_data_sub(quota_ctx_t qctx, struct ext2_inode *inode, ext2_ino_t ino,
 /*
  * Called to count the files used by an inode's user/group
  */
-void quota_data_inodes(quota_ctx_t qctx, struct ext2_inode *inode,
+void quota_data_inodes(quota_ctx_t qctx, struct ext2_inode_large *inode,
                       ext2_ino_t ino, int adjust)
 {
        struct dquot    *dq;
@@ -457,8 +477,10 @@ errcode_t quota_compute_usage(quota_ctx_t qctx)
                    (ino == EXT2_ROOT_INO ||
                     ino >= EXT2_FIRST_INODE(fs->super))) {
                        space = ext2fs_inode_i_blocks(fs, inode) << 9;
-                       quota_data_add(qctx, inode, ino, space);
-                       quota_data_inodes(qctx, inode, ino, +1);
+                       quota_data_add(qctx, (struct ext2_inode_large *)inode,
+                                      ino, space);
+                       quota_data_inodes(qctx, (struct ext2_inode_large *)inode,
+                                         ino, +1);
                }
        }
 
index 1fbf610..b48bc69 100644 (file)
 #include "common.h"
 #include "quotaio.h"
 
-static const char * const extensions[MAXQUOTAS] = {"user", "group"};
+static const char * const extensions[MAXQUOTAS] = {
+       [USRQUOTA] = "user",
+       [GRPQUOTA] = "group",
+       [PRJQUOTA] = "project",
+};
 static const char * const basenames[] = {
        "",             /* undefined */
        "quota",        /* QFMT_VFS_OLD */
@@ -53,6 +57,8 @@ ext2_ino_t quota_type2inum(enum quota_type qtype,
                return EXT4_USR_QUOTA_INO;
        case GRPQUOTA:
                return EXT4_GRP_QUOTA_INO;
+       case PRJQUOTA:
+               return sb->s_prj_quota_inum;
        default:
                return 0;
        }
@@ -338,15 +344,23 @@ errcode_t quota_file_create(struct quota_handle *h, ext2_filsys fs,
 {
        ext2_file_t e2_file;
        int err;
-       unsigned long qf_inum;
+       ext2_ino_t qf_inum = 0;
 
        if (fmt == -1)
                fmt = QFMT_VFS_V1;
 
        h->qh_qf.fs = fs;
        qf_inum = quota_type2inum(qtype, fs->super);
-       if (qf_inum == 0)
+       if (qf_inum == 0 && qtype == PRJQUOTA) {
+               err = ext2fs_new_inode(fs, EXT2_ROOT_INO, LINUX_S_IFREG | 0600,
+                                      0, &qf_inum);
+               if (err)
+                       return -1;
+               ext2fs_inode_alloc_stats2(fs, qf_inum, +1, 0);
+               ext2fs_mark_ib_dirty(fs);
+       } else if (qf_inum == 0) {
                return -1;
+       }
 
        err = ext2fs_read_bitmaps(fs);
        if (err)
index 64361fa..b7496e7 100644 (file)
@@ -47,6 +47,7 @@ typedef int64_t qsize_t;      /* Type in which we store size limitations */
 enum quota_type {
        USRQUOTA = 0,
        GRPQUOTA = 1,
+       PRJQUOTA = 2,
        MAXQUOTAS
 };
 
@@ -56,7 +57,8 @@ enum quota_type {
 
 #define QUOTA_USR_BIT (1 << USRQUOTA)
 #define QUOTA_GRP_BIT (1 << GRPQUOTA)
-#define QUOTA_ALL_BIT (QUOTA_USR_BIT | QUOTA_GRP_BIT)
+#define QUOTA_PRJ_BIT (1 << PRJQUOTA)
+#define QUOTA_ALL_BIT (QUOTA_USR_BIT | QUOTA_GRP_BIT | QUOTA_PRJ_BIT)
 
 typedef struct quota_ctx *quota_ctx_t;
 
@@ -71,7 +73,8 @@ struct quota_ctx {
  */
 #define INITQMAGICS {\
        0xd9c01f11,     /* USRQUOTA */\
-       0xd9c01927      /* GRPQUOTA */\
+       0xd9c01927,     /* GRPQUOTA */\
+       0xd9c03f14      /* PRJQUOTA */\
 }
 
 /* Size of blocks in which are counted size limits in generic utility parts */
@@ -216,12 +219,12 @@ const char *quota_get_qf_path(const char *mntpt, enum quota_type qtype, int fmt,
 /* In mkquota.c */
 errcode_t quota_init_context(quota_ctx_t *qctx, ext2_filsys fs,
                             unsigned int qtype_bits);
-void quota_data_inodes(quota_ctx_t qctx, struct ext2_inode *inode, ext2_ino_t ino,
-               int adjust);
-void quota_data_add(quota_ctx_t qctx, struct ext2_inode *inode, ext2_ino_t ino,
-               qsize_t space);
-void quota_data_sub(quota_ctx_t qctx, struct ext2_inode *inode, ext2_ino_t ino,
-               qsize_t space);
+void quota_data_inodes(quota_ctx_t qctx, struct ext2_inode_large *inode,
+                      ext2_ino_t ino, int adjust);
+void quota_data_add(quota_ctx_t qctx, struct ext2_inode_large *inode,
+                   ext2_ino_t ino, qsize_t space);
+void quota_data_sub(quota_ctx_t qctx, struct ext2_inode_large *inode,
+                   ext2_ino_t ino, qsize_t space);
 errcode_t quota_write_inode(quota_ctx_t qctx, enum quota_type qtype);
 errcode_t quota_update_limits(quota_ctx_t qctx, ext2_ino_t qf_ino,
                              enum quota_type type);
@@ -249,6 +252,8 @@ static inline ext2_ino_t *quota_sb_inump(struct ext2_super_block *sb,
                return &sb->s_usr_quota_inum;
        case GRPQUOTA:
                return &sb->s_grp_quota_inum;
+       case PRJQUOTA:
+               return &sb->s_prj_quota_inum;
        default:
                return NULL;
        }
index 99e2d64..53c30ce 100644 (file)
@@ -684,6 +684,8 @@ static int option_handle_function(char *token, void *data)
                quotatype_bits |= QUOTA_USR_BIT;
        } else if (!strncmp(token, "grp", 3)) {
                quotatype_bits |= QUOTA_GRP_BIT;
+       } else if (!strncmp(token, "prj", 3)) {
+               quotatype_bits |= QUOTA_PRJ_BIT;
        } else {
                fprintf(stderr, _("Invalid quotatype parameter: %s\n"),
                                token);
@@ -2221,6 +2223,20 @@ profile_error:
                fs_param.s_inode_size = inode_size;
        }
 
+       /*
+        * If inode size is 128 and project quota is enabled, we need
+        * to notify users that project ID will never be useful.
+        */
+       if (fs_param.s_feature_incompat & EXT4_FEATURE_RO_COMPAT_QUOTA &&
+           fs_param.s_feature_incompat & EXT4_FEATURE_RO_COMPAT_PROJECT &&
+           fs_param.s_inode_size == EXT2_GOOD_OLD_INODE_SIZE) {
+               com_err(program_name, 0,
+                       _("%d byte inodes are too small for project quota; "
+                         "specify larger size"),
+                       fs_param.s_inode_size);
+               exit(1);
+       }
+
        /* Make sure number of inodes specified will fit in 32 bits */
        if (num_inodes == 0) {
                unsigned long long n;
@@ -2876,6 +2892,9 @@ no_journal:
                                       EXT4_FEATURE_RO_COMPAT_BIGALLOC))
                fix_cluster_bg_counts(fs);
        if (EXT2_HAS_RO_COMPAT_FEATURE(&fs_param,
+                                      EXT4_FEATURE_RO_COMPAT_PROJECT))
+               quotatype_bits |= QUOTA_PRJ_BIT;
+       if (EXT2_HAS_RO_COMPAT_FEATURE(&fs_param,
                                       EXT4_FEATURE_RO_COMPAT_QUOTA))
                create_quota_inodes(fs);
 
index c50d475..e38355c 100644 (file)
@@ -619,6 +619,9 @@ Sets/clears user quota inode in the superblock.
 .TP
 .BR [^]grpquota
 Sets/clears group quota inode in the superblock.
+.TP
+.BR [^]prjquota
+Sets/clears project quota inode in the superblock.
 .RE
 .TP
 .BI \-T " time-last-checked"
index 2cd6093..f44a2ae 100644 (file)
@@ -651,13 +651,27 @@ mmp_error:
                 */
                if (!Q_flag) {
                        Q_flag = 1;
-                       /* Enable all quota by default */
-                       for (qtype = 0; qtype < MAXQUOTAS; qtype++)
-                               quota_enable[qtype] = QOPT_ENABLE;
+                       /* Enable usr/grp by default */
+                       for (qtype = 0; qtype < MAXQUOTAS; qtype++) {
+                               if (qtype != PRJQUOTA)
+                                       quota_enable[qtype] = QOPT_ENABLE;
+                               else
+                                       quota_enable[qtype] = QOPT_DISABLE;
+                       }
                }
                sb->s_feature_ro_compat &= ~EXT4_FEATURE_RO_COMPAT_QUOTA;
        }
 
+       if (FEATURE_ON(E2P_FEATURE_RO_INCOMPAT,
+                      EXT4_FEATURE_RO_COMPAT_PROJECT)) {
+               if (!Q_flag && !(sb->s_feature_ro_compat &
+                                EXT4_FEATURE_RO_COMPAT_QUOTA))
+                       fputs(_("\nWarning: enabled project without quota together\n"),
+                               stderr);
+               Q_flag = 1;
+               quota_enable[PRJQUOTA] = QOPT_ENABLE;
+       }
+
        if (FEATURE_OFF(E2P_FEATURE_RO_INCOMPAT,
                                EXT4_FEATURE_RO_COMPAT_QUOTA)) {
                /*
@@ -848,12 +862,17 @@ static int option_handle_function(char *token, void *data)
                quota_enable[GRPQUOTA] = QOPT_ENABLE;
        } else if (strncmp(token, "^grp", 4) == 0) {
                quota_enable[GRPQUOTA] = QOPT_DISABLE;
+       } else if (strncmp(token, "prj", 3) == 0) {
+               quota_enable[PRJQUOTA] = QOPT_ENABLE;
+       } else if (strncmp(token, "^prj", 4) == 0) {
+               quota_enable[PRJQUOTA] = QOPT_DISABLE;
        } else {
                fputs(_("\nBad quota options specified.\n\n"
                        "Following valid quota options are available "
                        "(pass by separating with comma):\n"
                        "\t[^]usr[quota]\n"
                        "\t[^]grp[quota]\n"
+                       "\t[^]prj[quota]\n"
                        "\n\n"), stderr);
                return 1;
        }
index 1315439..59d616d 100644 (file)
@@ -1,6 +1,8 @@
 Adding dirhash hint to filesystem.
 
 Pass 1: Checking inodes, blocks, and sizes
+Expanding inode 2.
+Expanding inode 11.
 Expanding inode 12.
 An EA needs to be deleted for inode 12 but e2fsck is being run
 with -p or -y mode.
index 7246739..1a9639a 100644 (file)
@@ -35,8 +35,8 @@ Reserved blocks uid:      0
 Reserved blocks gid:      0
 First inode:              11
 Inode size:              256
-Required extra isize:     28
-Desired extra isize:      28
+Required extra isize:     32
+Desired extra isize:      32
 Journal inode:            8
 Default directory hash:   half_md4
 Journal backup:           inode blocks
index 8ab2711..5c1cb20 100644 (file)
@@ -40,8 +40,8 @@ Reserved blocks uid:      0
 Reserved blocks gid:      0
 First inode:              11
 Inode size:              256
-Required extra isize:     28
-Desired extra isize:      28
+Required extra isize:     32
+Desired extra isize:      32
 Default directory hash:   half_md4
 
 
index 787871c..8cdad30 100644 (file)
@@ -6,19 +6,19 @@ Allocating group tables:      \b\b\b\b\bdone
 Writing inode tables:      \b\b\b\b\bdone                            
 Writing superblocks and filesystem accounting information:      \b\b\b\b\bdone
 
-Filesystem features: ext_attr resize_inode dir_index filetype sparse_super quota
+Filesystem features: ext_attr resize_inode dir_index filetype sparse_super quota project
 Pass 1: Checking inodes, blocks, and sizes
 Pass 2: Checking directory structure
 Pass 3: Checking directory connectivity
 Pass 4: Checking reference counts
 Pass 5: Checking group summary information
-test_filesys: 11/32768 files (18.2% non-contiguous), 5703/131072 blocks
+test_filesys: 12/32768 files (25.0% non-contiguous), 9805/131072 blocks
 Exit status is 0
 Filesystem volume name:   <none>
 Last mounted on:          <not available>
 Filesystem magic number:  0xEF53
 Filesystem revision #:    1 (dynamic)
-Filesystem features:      ext_attr resize_inode dir_index filetype sparse_super quota
+Filesystem features:      ext_attr resize_inode dir_index filetype sparse_super quota project
 Default mount options:    (none)
 Filesystem state:         clean
 Errors behavior:          Continue
@@ -26,8 +26,8 @@ Filesystem OS type:       Linux
 Inode count:              32768
 Block count:              131072
 Reserved block count:     6553
-Free blocks:              125369
-Free inodes:              32757
+Free blocks:              121267
+Free inodes:              32756
 First block:              1
 Block size:               1024
 Fragment size:            1024
@@ -35,123 +35,126 @@ Reserved GDT blocks:      256
 Blocks per group:         8192
 Fragments per group:      8192
 Inodes per group:         2048
-Inode blocks per group:   256
+Inode blocks per group:   512
 Mount count:              0
 Check interval:           15552000 (6 months)
 Reserved blocks uid:      0
 Reserved blocks gid:      0
 First inode:              11
-Inode size:              128
+Inode size:              256
+Required extra isize:     32
+Desired extra isize:      32
 Default directory hash:   half_md4
 User quota inode:         3
 Group quota inode:        4
+Project quota inode:      12
 
 
 Group 0: (Blocks 1-8192)
   Primary superblock at 1, Group descriptors at 2-2
   Reserved GDT blocks at 3-258
   Block bitmap at 259 (+258), Inode bitmap at 260 (+259)
-  Inode table at 261-516 (+260)
-  7650 free blocks, 2037 free inodes, 2 directories
-  Free blocks: 543-8192
-  Free inodes: 12-2048
+  Inode table at 261-772 (+260)
+  7388 free blocks, 2036 free inodes, 2 directories
+  Free blocks: 805-8192
+  Free inodes: 13-2048
 Group 1: (Blocks 8193-16384)
   Backup superblock at 8193, Group descriptors at 8194-8194
   Reserved GDT blocks at 8195-8450
   Block bitmap at 8451 (+258), Inode bitmap at 8452 (+259)
-  Inode table at 8453-8708 (+260)
-  7676 free blocks, 2048 free inodes, 0 directories
-  Free blocks: 8709-16384
+  Inode table at 8453-8964 (+260)
+  7420 free blocks, 2048 free inodes, 0 directories
+  Free blocks: 8965-16384
   Free inodes: 2049-4096
 Group 2: (Blocks 16385-24576)
   Block bitmap at 16385 (+0), Inode bitmap at 16386 (+1)
-  Inode table at 16387-16642 (+2)
-  7934 free blocks, 2048 free inodes, 0 directories
-  Free blocks: 16643-24576
+  Inode table at 16387-16898 (+2)
+  7678 free blocks, 2048 free inodes, 0 directories
+  Free blocks: 16899-24576
   Free inodes: 4097-6144
 Group 3: (Blocks 24577-32768)
   Backup superblock at 24577, Group descriptors at 24578-24578
   Reserved GDT blocks at 24579-24834
   Block bitmap at 24835 (+258), Inode bitmap at 24836 (+259)
-  Inode table at 24837-25092 (+260)
-  7676 free blocks, 2048 free inodes, 0 directories
-  Free blocks: 25093-32768
+  Inode table at 24837-25348 (+260)
+  7420 free blocks, 2048 free inodes, 0 directories
+  Free blocks: 25349-32768
   Free inodes: 6145-8192
 Group 4: (Blocks 32769-40960)
   Block bitmap at 32769 (+0), Inode bitmap at 32770 (+1)
-  Inode table at 32771-33026 (+2)
-  7934 free blocks, 2048 free inodes, 0 directories
-  Free blocks: 33027-40960
+  Inode table at 32771-33282 (+2)
+  7678 free blocks, 2048 free inodes, 0 directories
+  Free blocks: 33283-40960
   Free inodes: 8193-10240
 Group 5: (Blocks 40961-49152)
   Backup superblock at 40961, Group descriptors at 40962-40962
   Reserved GDT blocks at 40963-41218
   Block bitmap at 41219 (+258), Inode bitmap at 41220 (+259)
-  Inode table at 41221-41476 (+260)
-  7676 free blocks, 2048 free inodes, 0 directories
-  Free blocks: 41477-49152
+  Inode table at 41221-41732 (+260)
+  7420 free blocks, 2048 free inodes, 0 directories
+  Free blocks: 41733-49152
   Free inodes: 10241-12288
 Group 6: (Blocks 49153-57344)
   Block bitmap at 49153 (+0), Inode bitmap at 49154 (+1)
-  Inode table at 49155-49410 (+2)
-  7934 free blocks, 2048 free inodes, 0 directories
-  Free blocks: 49411-57344
+  Inode table at 49155-49666 (+2)
+  7678 free blocks, 2048 free inodes, 0 directories
+  Free blocks: 49667-57344
   Free inodes: 12289-14336
 Group 7: (Blocks 57345-65536)
   Backup superblock at 57345, Group descriptors at 57346-57346
   Reserved GDT blocks at 57347-57602
   Block bitmap at 57603 (+258), Inode bitmap at 57604 (+259)
-  Inode table at 57605-57860 (+260)
-  7676 free blocks, 2048 free inodes, 0 directories
-  Free blocks: 57861-65536
+  Inode table at 57605-58116 (+260)
+  7420 free blocks, 2048 free inodes, 0 directories
+  Free blocks: 58117-65536
   Free inodes: 14337-16384
 Group 8: (Blocks 65537-73728)
   Block bitmap at 65537 (+0), Inode bitmap at 65538 (+1)
-  Inode table at 65539-65794 (+2)
-  7934 free blocks, 2048 free inodes, 0 directories
-  Free blocks: 65795-73728
+  Inode table at 65539-66050 (+2)
+  7678 free blocks, 2048 free inodes, 0 directories
+  Free blocks: 66051-73728
   Free inodes: 16385-18432
 Group 9: (Blocks 73729-81920)
   Backup superblock at 73729, Group descriptors at 73730-73730
   Reserved GDT blocks at 73731-73986
   Block bitmap at 73987 (+258), Inode bitmap at 73988 (+259)
-  Inode table at 73989-74244 (+260)
-  7676 free blocks, 2048 free inodes, 0 directories
-  Free blocks: 74245-81920
+  Inode table at 73989-74500 (+260)
+  7420 free blocks, 2048 free inodes, 0 directories
+  Free blocks: 74501-81920
   Free inodes: 18433-20480
 Group 10: (Blocks 81921-90112)
   Block bitmap at 81921 (+0), Inode bitmap at 81922 (+1)
-  Inode table at 81923-82178 (+2)
-  7934 free blocks, 2048 free inodes, 0 directories
-  Free blocks: 82179-90112
+  Inode table at 81923-82434 (+2)
+  7678 free blocks, 2048 free inodes, 0 directories
+  Free blocks: 82435-90112
   Free inodes: 20481-22528
 Group 11: (Blocks 90113-98304)
   Block bitmap at 90113 (+0), Inode bitmap at 90114 (+1)
-  Inode table at 90115-90370 (+2)
-  7934 free blocks, 2048 free inodes, 0 directories
-  Free blocks: 90371-98304
+  Inode table at 90115-90626 (+2)
+  7678 free blocks, 2048 free inodes, 0 directories
+  Free blocks: 90627-98304
   Free inodes: 22529-24576
 Group 12: (Blocks 98305-106496)
   Block bitmap at 98305 (+0), Inode bitmap at 98306 (+1)
-  Inode table at 98307-98562 (+2)
-  7934 free blocks, 2048 free inodes, 0 directories
-  Free blocks: 98563-106496
+  Inode table at 98307-98818 (+2)
+  7678 free blocks, 2048 free inodes, 0 directories
+  Free blocks: 98819-106496
   Free inodes: 24577-26624
 Group 13: (Blocks 106497-114688)
   Block bitmap at 106497 (+0), Inode bitmap at 106498 (+1)
-  Inode table at 106499-106754 (+2)
-  7934 free blocks, 2048 free inodes, 0 directories
-  Free blocks: 106755-114688
+  Inode table at 106499-107010 (+2)
+  7678 free blocks, 2048 free inodes, 0 directories
+  Free blocks: 107011-114688
   Free inodes: 26625-28672
 Group 14: (Blocks 114689-122880)
   Block bitmap at 114689 (+0), Inode bitmap at 114690 (+1)
-  Inode table at 114691-114946 (+2)
-  7934 free blocks, 2048 free inodes, 0 directories
-  Free blocks: 114947-122880
+  Inode table at 114691-115202 (+2)
+  7678 free blocks, 2048 free inodes, 0 directories
+  Free blocks: 115203-122880
   Free inodes: 28673-30720
 Group 15: (Blocks 122881-131071)
   Block bitmap at 122881 (+0), Inode bitmap at 122882 (+1)
-  Inode table at 122883-123138 (+2)
-  7933 free blocks, 2048 free inodes, 0 directories
-  Free blocks: 123139-131071
+  Inode table at 122883-123394 (+2)
+  7677 free blocks, 2048 free inodes, 0 directories
+  Free blocks: 123395-131071
   Free inodes: 30721-32768
index 36ab630..173feef 100644 (file)
@@ -1,6 +1,6 @@
 DESCRIPTION="enable quota feature on mkfs"
 FS_SIZE=131072
-MKE2FS_OPTS="-O quota"
+MKE2FS_OPTS="-O quota,project -I 256"
 if [ "$QUOTA" != "y" ]; then
        echo "$test_name: $DESCRIPTION: skipped"
        return 0