From patchwork Fri May 4 07:09:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artem Blagodarenko X-Patchwork-Id: 908549 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Cx5W8zlF"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40cjnJ14tYz9s3D for ; Fri, 4 May 2018 17:09:40 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751329AbeEDHJj (ORCPT ); Fri, 4 May 2018 03:09:39 -0400 Received: from mail-lf0-f67.google.com ([209.85.215.67]:34945 "EHLO mail-lf0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751107AbeEDHJh (ORCPT ); Fri, 4 May 2018 03:09:37 -0400 Received: by mail-lf0-f67.google.com with SMTP id y72-v6so15709707lfd.2 for ; Fri, 04 May 2018 00:09:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=IZlYoJYUZ+IUdslKN/hjJxsvwDc6C3Xxyw2XBeBIWos=; b=Cx5W8zlFs1+MwRn3W5R7fcrCQ8k2ZMtrhMcN/vulJuiVLvfhMD1Pr1W/2TO7SW38Ek c032AQbJR3Nw3NNNqumIl/54WWtgGPqrPtb07gK+uXfXRSHzkqNF3xlxsgdUjgI+cnP7 Qe6p4YzKrQlg5CWei+OXsUm7N4aElf4vF7V3telqqZTiLeIrdm7F6OlLD8jHga4FiQUq xpyLpA3XWGX4h4DXGoCfFmUT+j/1lygIobn+h1yfGUjyTPvyhyvV1skyeMuUdNaaXleR 6kDldllLt1KaS7R1vbdnO1q/bEC5jJ5ZrAk9yTx+T32PvJgqkm1bWVOn9BayBwlOsmTb Hm4Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=IZlYoJYUZ+IUdslKN/hjJxsvwDc6C3Xxyw2XBeBIWos=; b=XiJFuHMlgwprQ2GbBdqvEYvkVPrC7hm3VXp3XKDexy0ZWnpDJA5Vp97OdIMwGc09QV QppuGm4oTfi2JEPP6EFdyS3M0Ijc65AaCMOLPZlVHbO0OkxPW7T1+dAYqDyse8ClrmaL 2NWPelKBlnePrCbwSTO6vqzrgasFTqmzW8OO+2HiHgkctCW1SNTQq0fAS3JwVESv02ro VO5RyWzUrMU5gnRmck1NBMLVEuvF5K3IggoudvQ+GegfktvPFp51EngamvJNFdNhAxVi V8OOr8uKQ4MoxCXIxr/U7XR9cN6VKCNldsTWftJUw5tgvVrMEBxA5IV4qDqoL2tTntGV NHNQ== X-Gm-Message-State: ALQs6tDq717lu8xdkKtfgh/IbZJVR8ezrUuOCrlU/0WHhjlsmsmNkAw6 nY/95p71T5UCSDPoDl074I/wAdDF X-Google-Smtp-Source: AB8JxZqRZfwWJ7eXb+vnLnWjowp2BQrLjqByNVus5b2Upeh+2lhOTJMLId21zvL1e38IRcbKiah+NQ== X-Received: by 2002:a2e:9911:: with SMTP id v17-v6mr17675632lji.57.1525417774649; Fri, 04 May 2018 00:09:34 -0700 (PDT) Received: from C02TN4C6HTD6.lan ([80.72.234.202]) by smtp.gmail.com with ESMTPSA id f16-v6sm3170296lfh.94.2018.05.04.00.09.33 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 04 May 2018 00:09:34 -0700 (PDT) From: c17828 X-Google-Original-From: c17828 To: linux-ext4@vger.kernel.org Cc: adilger.kernel@dilger.ca, Andreas Dilger , Bobi Jam , Manisha Salve , Pravin Shelar , Artem Blagodarenko Subject: [PATCH v4 1/7] e2fsck: add support for dirdata feature Date: Fri, 4 May 2018 10:09:17 +0300 Message-Id: <20180504070923.45140-2-c17828@cray.com> X-Mailer: git-send-email 2.14.3 (Apple Git-98) In-Reply-To: <20180504070923.45140-1-c17828@cray.com> References: <20180504070923.45140-1-c17828@cray.com> Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org From: Andreas Dilger Add support for the INCOMPAT_DIRDATA feature, which allows storing extra data in the directory entry beyond the name. This allows the Lustre File IDentifier to be accessed in an efficient manner, and would be useful for expanding a filesystem to allow more than 2^32 inodes in the future. Include this patches: e2fsck: e2fsck -D does not change dirdata content Fix dir optimization to preserve dirdata content for dot and dotdot entries. Lustre-bug: https://jira.hpdd.intel.com/browse/LU-1774 Signed-off-by: Bobi Jam Change-Id: Iae190794da75a2080a8e5cc5b95a49e0c894f72f e2fsprogs: Consider DIRENT_LUFID flag in link_proc(). While adding the new file entry in directory block, link_proc() calculates minimum record length of the existing directory entry without considering the dirent data size and which leads to corruption. Changed the code to use EXT2_DIR_REC_LEN() which will return correct record length including dirent data size. Lustre-bug: https://jira.hpdd.intel.com/browse/LU-2462 Signed-off-by: Manisha Salve Change-Id: Ic593c558c47a78183143ec8e99d8385ac94d06f7 libext2fs, e2fsck: don't use ext2_dir_entry_2 Due to endian issues, do not use ext2_dir_entry_2 because it will have the wrong byte order on directory entries that are swabbed. Instead, use the standard practice of mask-and-shift to access the file_type and dirdata flags. Lustre-bug: https://jira.hpdd.intel.com/browse/LU-4677 Signed-off-by: Pravin Shelar Signed-off-by: Andreas Dilger Signed-off-by: Artem Blagodarenko --- debugfs/htree.c | 2 +- debugfs/ls.c | 67 ++++++++++++++++++++++- e2fsck/pass1.c | 4 +- e2fsck/pass2.c | 139 ++++++++++++++++++++++++++++++++++++++--------- e2fsck/pass3.c | 7 +++ e2fsck/problem.c | 5 ++ e2fsck/problem.h | 3 + e2fsck/rehash.c | 82 ++++++++++++++++------------ lib/ext2fs/dirblock.c | 33 +++++++++++ lib/ext2fs/ext2_fs.h | 18 +++++- lib/ext2fs/ext2fs.h | 22 +++++++- lib/ext2fs/inline_data.c | 14 ++--- lib/ext2fs/link.c | 10 ++-- lib/ext2fs/newdir.c | 4 +- misc/mke2fs.c | 8 +++ misc/tune2fs.c | 2 + 16 files changed, 338 insertions(+), 82 deletions(-) diff --git a/debugfs/htree.c b/debugfs/htree.c index cf7d78aa..b7f1add0 100644 --- a/debugfs/htree.c +++ b/debugfs/htree.c @@ -278,7 +278,7 @@ void do_htree_dump(int argc, char *argv[]) goto errout; } - rootnode = (struct ext2_dx_root_info *) (buf + 24); + rootnode = get_ext2_dx_root_info(current_fs, buf); fprintf(pager, "Root node dump:\n"); fprintf(pager, "\t Reserved zero: %u\n", rootnode->reserved_zero); diff --git a/debugfs/ls.c b/debugfs/ls.c index 61b63196..082c14b9 100644 --- a/debugfs/ls.c +++ b/debugfs/ls.c @@ -25,6 +25,30 @@ extern char *optarg; #include "debugfs.h" +#ifndef DFID +#define DFID "[%#llx:0x%x:0x%x]" +#define PFID(fid) ((unsigned long long)fid_seq(fid),\ + fid_oid(fid), fid_ver(fid)) +struct lu_fid { + __u64 f_seq; + __u32 f_oid; + __u32 f_ver; +}; +#endif /* !DFID */ + +#ifndef HAVE_LUSTRE_LUSTRE_IDL_H +#define fid_seq(fid) ((fid)->f_seq) +#define fid_oid(fid) ((fid)->f_oid) +#define fid_ver(fid) ((fid)->f_ver) + +static inline void fid_be_to_cpu(struct lu_fid *dst, struct lu_fid *src) +{ + dst->f_seq = ext2fs_be64_to_cpu(src->f_seq); + dst->f_oid = ext2fs_be32_to_cpu(src->f_oid); + dst->f_ver = ext2fs_be32_to_cpu(src->f_ver); +} +#endif + /* * list directory */ @@ -32,6 +56,7 @@ extern char *optarg; #define LONG_OPT 0x0001 #define PARSE_OPT 0x0002 #define RAW_OPT 0x0004 +#define DIRDATA_OPT 0x0008 #define ENCRYPT_OPT 0x8000 struct list_dir_struct { @@ -44,6 +69,41 @@ struct list_dir_struct { static const char *monstr[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; +static void list_dirdata(struct list_dir_struct *ls, + struct ext2_dir_entry *dirent) +{ + unsigned char *data; + int dlen; + __u8 dirdata_mask; + __u8 file_type = dirent->name_len >> 8; + + data = (unsigned char *)dirent->name + + (dirent->name_len & EXT2_NAME_LEN) + 1; + + for (dirdata_mask = EXT2_FT_MASK + 1; + dirdata_mask != 0; dirdata_mask <<= 1) { + if ((dirdata_mask & file_type) == 0) + continue; + + dlen = data[0]; + + if (dirdata_mask == EXT2_DIRENT_LUFID) { + struct lu_fid *fid = (struct lu_fid *)(data + 1); + + fid_be_to_cpu(fid, fid); + fprintf(ls->f, "fid:"DFID, PFID(fid)); + } else { + int i; + + for (i = 1; i < dlen; i++) + fprintf(ls->f, "%02x", data[i]); + } + + fprintf(ls->f, " "); + data += dlen; + } +} + static int print_filename(FILE *f, struct ext2_dir_entry *dirent, int options) { unsigned char ch; @@ -157,6 +217,8 @@ static int list_dir_proc(ext2_ino_t dir EXT2FS_ATTR((unused)), else fprintf(ls->f, "%5llu", EXT2_I_SIZE(&inode)); fprintf(ls->f, " %s ", datestr); + if ((ls->options & DIRDATA_OPT) != 0) + list_dirdata(ls, dirent); print_filename(ls->f, dirent, options); fputc('\n', ls->f); } else { @@ -204,7 +266,7 @@ void do_list_dir(int argc, char *argv[]) return; reset_getopt(); - while ((c = getopt (argc, argv, "cdlpr")) != EOF) { + while ((c = getopt(argc, argv, "cdDlpr")) != EOF) { switch (c) { case 'c': flags |= DIRENT_FLAG_INCLUDE_CSUM; @@ -212,6 +274,9 @@ void do_list_dir(int argc, char *argv[]) case 'l': ls.options |= LONG_OPT; break; + case 'D': + ls.options |= DIRDATA_OPT; + break; case 'd': flags |= DIRENT_FLAG_INCLUDE_REMOVED; break; diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c index 5015d938..d39086d2 100644 --- a/e2fsck/pass1.c +++ b/e2fsck/pass1.c @@ -719,7 +719,7 @@ static void check_is_really_dir(e2fsck_t ctx, struct problem_context *pctx, */ memcpy(&dotdot, inode->i_block, sizeof(dotdot)); memcpy(&de, ((char *)inode->i_block) + EXT4_INLINE_DATA_DOTDOT_SIZE, - EXT2_DIR_REC_LEN(0)); + EXT2_DIR_NAME_LEN(0)); dotdot = ext2fs_le32_to_cpu(dotdot); de.inode = ext2fs_le32_to_cpu(de.inode); de.rec_len = ext2fs_le16_to_cpu(de.rec_len); @@ -2646,7 +2646,7 @@ static int handle_htree(e2fsck_t ctx, struct problem_context *pctx, return 1; /* XXX should check that beginning matches a directory */ - root = (struct ext2_dx_root_info *) (block_buf + 24); + root = get_ext2_dx_root_info(fs, block_buf); if ((root->reserved_zero || root->info_length < 8) && fix_problem(ctx, PR_1_HTREE_BADROOT, pctx)) diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c index 1b0504c8..c419a016 100644 --- a/e2fsck/pass2.c +++ b/e2fsck/pass2.c @@ -366,13 +366,88 @@ static EXT2_QSORT_TYPE special_dir_block_cmp(const void *a, const void *b) return (int) (db_a->blockcnt - db_b->blockcnt); } +void ext2_fix_dirent_dirdata(struct ext2_dir_entry *de) +{ + __u16 file_type = de->name_len & (EXT2_FT_MASK << 8); + __u8 de_flags = (de->name_len >> 8) & ~EXT2_FT_MASK; + __u8 name_len = de->name_len & EXT2_NAME_LEN; + __u8 new_flag = 0; + int i; + + for (i = 0; i < 4; i++) { + __u8 flags = new_flag | (1 << i) << 4; + + /* new_flag is accumulating flags that are set in de_flags + * and still fit inside rec_len. ext2_get_dirent_dirdata_size() + * returns the size of all the dirdata entries in flags, and + * chops off any that are beyond rec_len. + */ + if ((de_flags & flags) == flags) { + int dirdatalen = ext2_get_dirdata_field_size(de, + flags); + int rlen = EXT2_DIR_NAME_LEN(name_len + dirdatalen); + + if (rlen > de->rec_len) + break; + + new_flag |= flags; + } + } + + de->name_len = name_len | file_type | (new_flag << 8); +} + +/* + * check for dirent data in ext3 dirent. + * return 0 if dirent data is ok. + * return 1 if dirent data does not exist. + * return 2 if dirent was modified due to error. + */ +int e2fsck_check_dirent_data(e2fsck_t ctx, struct ext2_dir_entry *de, + unsigned int offset, struct problem_context *pctx) +{ + if (!(ctx->fs->super->s_feature_incompat & + EXT4_FEATURE_INCOMPAT_DIRDATA)) { + if ((de->name_len >> 8) & ~EXT2_FT_MASK) { + /* clear dirent extra data flags. */ + if (fix_problem(ctx, PR_2_CLEAR_DIRDATA, pctx)) { + de->name_len &= (EXT2_FT_MASK << 8) | + EXT2_NAME_LEN; + return 2; + } + } + return 1; + } + if ((de->name_len >> 8) & ~EXT2_FT_MASK) { + if (de->rec_len >= EXT2_DIR_REC_LEN(de) || + de->rec_len + offset == EXT2_BLOCK_SIZE(ctx->fs->super)) { + if (ext2_get_dirdata_field_size(de, + EXT2_DIRENT_LUFID) % + EXT2_DIRENT_LUFID_SIZE == 1 /*size*/ + 1 /*NULL*/) + return 0; + } + /* just clear dirent data flags for now, we should fix FID data + * in lustre specific pass. + */ + if (fix_problem(ctx, PR_2_CLEAR_DIRDATA, pctx)) { + ext2_fix_dirent_dirdata(de); + if (ext2_get_dirdata_field_size(de, + EXT2_DIRENT_LUFID) != + EXT2_DIRENT_LUFID_SIZE) + de->name_len &= ~(EXT2_DIRENT_LUFID << 8); + + return 2; + } + } + return 1; +} /* * Make sure the first entry in the directory is '.', and that the * directory entry is sane. */ static int check_dot(e2fsck_t ctx, - struct ext2_dir_entry *dirent, + struct ext2_dir_entry *dirent, unsigned int offset, ext2_ino_t ino, struct problem_context *pctx) { struct ext2_dir_entry *nextdir; @@ -380,6 +455,7 @@ static int check_dot(e2fsck_t ctx, int status = 0; int created = 0; problem_t problem = 0; + int dir_data_error; if (!dirent->inode) problem = PR_2_MISSING_DOT; @@ -389,10 +465,12 @@ static int check_dot(e2fsck_t ctx, else if (dirent->name[1] != '\0') problem = PR_2_DOT_NULL_TERM; + dir_data_error = e2fsck_check_dirent_data(ctx, dirent, offset, pctx); + (void) ext2fs_get_rec_len(ctx->fs, dirent, &rec_len); if (problem) { if (fix_problem(ctx, problem, pctx)) { - if (rec_len < 12) + if (rec_len < 12 && dir_data_error) rec_len = dirent->rec_len = 12; dirent->inode = ino; ext2fs_dirent_set_name_len(dirent, 1); @@ -411,7 +489,7 @@ static int check_dot(e2fsck_t ctx, } if (rec_len > 12) { new_len = rec_len - 12; - if (new_len > 12) { + if (new_len > 12 && dir_data_error) { if (created || fix_problem(ctx, PR_2_SPLIT_DOT, pctx)) { nextdir = (struct ext2_dir_entry *) @@ -436,11 +514,12 @@ static int check_dot(e2fsck_t ctx, * here; this gets done in pass 3. */ static int check_dotdot(e2fsck_t ctx, - struct ext2_dir_entry *dirent, + struct ext2_dir_entry *dirent, unsigned int offset, ext2_ino_t ino, struct problem_context *pctx) { problem_t problem = 0; unsigned int rec_len; + int dir_data_error; if (!dirent->inode) problem = PR_2_MISSING_DOT_DOT; @@ -451,10 +530,12 @@ static int check_dotdot(e2fsck_t ctx, else if (dirent->name[2] != '\0') problem = PR_2_DOT_DOT_NULL_TERM; + dir_data_error = e2fsck_check_dirent_data(ctx, dirent, offset, pctx); + (void) ext2fs_get_rec_len(ctx->fs, dirent, &rec_len); if (problem) { if (fix_problem(ctx, problem, pctx)) { - if (rec_len < 12) + if (rec_len < 12 && dir_data_error) dirent->rec_len = 12; /* * Note: we don't have the parent inode just @@ -528,6 +609,12 @@ static _INLINE_ int check_filetype(e2fsck_t ctx, int filetype = ext2fs_dirent_file_type(dirent); int should_be = EXT2_FT_UNKNOWN; struct ext2_inode inode; + __u8 dirdata = 0; + + if (ext2fs_has_feature_dirdata(ctx->fs->super)) { + dirdata = filetype & ~EXT2_FT_MASK; + filetype = filetype & EXT2_FT_MASK; + } if (!ext2fs_has_feature_filetype(ctx->fs->super)) { if (filetype == 0 || @@ -558,8 +645,7 @@ static _INLINE_ int check_filetype(e2fsck_t ctx, if (fix_problem(ctx, filetype ? PR_2_BAD_FILETYPE : PR_2_SET_FILETYPE, pctx) == 0) return 0; - - ext2fs_dirent_set_file_type(dirent, should_be); + ext2fs_dirent_set_file_type(dirent, should_be | dirdata); return 1; } @@ -581,7 +667,7 @@ static void parse_int_node(ext2_filsys fs, int csum_size = 0; if (db->blockcnt == 0) { - root = (struct ext2_dx_root_info *) (block_buf + 24); + root = get_ext2_dx_root_info(fs, block_buf); #ifdef DX_DEBUG printf("Root node dump:\n"); @@ -591,8 +677,8 @@ static void parse_int_node(ext2_filsys fs, printf("\t Indirect levels: %d\n", root->indirect_levels); printf("\t Flags: %d\n", root->unused_flags); #endif - - ent = (struct ext2_dx_entry *) (block_buf + 24 + root->info_length); + ent = (struct ext2_dx_entry *)((char *)root + + root->info_length); if (failed_csum && (e2fsck_dir_will_be_rehashed(cd->ctx, cd->pctx.ino) || @@ -600,7 +686,7 @@ static void parse_int_node(ext2_filsys fs, &cd->pctx))) goto clear_and_exit; } else { - ent = (struct ext2_dx_entry *) (block_buf+8); + ent = (struct ext2_dx_entry *)(block_buf + 8); if (failed_csum && (e2fsck_dir_will_be_rehashed(cd->ctx, cd->pctx.ino) || @@ -608,8 +694,7 @@ static void parse_int_node(ext2_filsys fs, &cd->pctx))) goto clear_and_exit; } - - limit = (struct ext2_dx_countlimit *) ent; + limit = (struct ext2_dx_countlimit *)ent; #ifdef DX_DEBUG printf("Number of entries (count): %d\n", @@ -780,7 +865,6 @@ static void salvage_directory(ext2_filsys fs, } } -#define NEXT_DIRENT(d) ((void *)((char *)(d) + (d)->rec_len)) static errcode_t insert_dirent_tail(ext2_filsys fs, void *dirbuf) { struct ext2_dir_entry *d; @@ -790,11 +874,11 @@ static errcode_t insert_dirent_tail(ext2_filsys fs, void *dirbuf) d = dirbuf; top = EXT2_DIRENT_TAIL(dirbuf, fs->blocksize); - while (d->rec_len && !(d->rec_len & 0x3) && NEXT_DIRENT(d) <= top) - d = NEXT_DIRENT(d); + while (d->rec_len && !(d->rec_len & 0x3) && EXT2_NEXT_DIRENT(d) <= top) + d = EXT2_NEXT_DIRENT(d); if (d != top) { - unsigned int min_size = EXT2_DIR_REC_LEN( + unsigned int min_size = EXT2_DIR_NAME_LEN( ext2fs_dirent_name_len(dirbuf)); if (min_size > (char *)top - (char *)d) return EXT2_ET_DIR_NO_SPACE_FOR_CSUM; @@ -809,7 +893,6 @@ static errcode_t insert_dirent_tail(ext2_filsys fs, void *dirbuf) return 0; } -#undef NEXT_DIRENT static errcode_t fix_inline_dir_size(e2fsck_t ctx, ext2_ino_t ino, size_t *inline_data_size, @@ -828,7 +911,7 @@ static errcode_t fix_inline_dir_size(e2fsck_t ctx, ext2_ino_t ino, */ if (old_size > EXT4_MIN_INLINE_DATA_SIZE && old_size < EXT4_MIN_INLINE_DATA_SIZE + - EXT2_DIR_REC_LEN(1)) { + EXT2_DIR_NAME_LEN(1)) { old_size = EXT4_MIN_INLINE_DATA_SIZE; new_size = old_size; } else @@ -1035,7 +1118,7 @@ inline_read_fail: if (((inline_data_size & 3) || (inline_data_size > EXT4_MIN_INLINE_DATA_SIZE && inline_data_size < EXT4_MIN_INLINE_DATA_SIZE + - EXT2_DIR_REC_LEN(1))) && + EXT2_DIR_NAME_LEN(1))) && fix_problem(ctx, PR_2_BAD_INLINE_DIR_SIZE, &pctx)) { errcode_t err = fix_inline_dir_size(ctx, ino, &inline_data_size, &pctx, @@ -1085,7 +1168,7 @@ inline_read_fail: (void) ext2fs_get_rec_len(fs, dirent, &rec_len); limit = (struct ext2_dx_countlimit *) (buf+8); if (db->blockcnt == 0) { - root = (struct ext2_dx_root_info *) (buf + 24); + root = get_ext2_dx_root_info(fs, buf); dx_db->type = DX_DIRBLOCK_ROOT; dx_db->flags |= DX_FLAG_FIRST | DX_FLAG_LAST; if ((root->reserved_zero || @@ -1165,7 +1248,7 @@ skip_checksum: * force salvaging this dir. */ if (max_block_size - offset < EXT2_DIR_ENTRY_HEADER_LEN) - rec_len = EXT2_DIR_REC_LEN(1); + rec_len = EXT2_DIR_NAME_LEN(1); else (void) ext2fs_get_rec_len(fs, dirent, &rec_len); cd->pctx.dirent = dirent; @@ -1227,7 +1310,7 @@ skip_checksum: memset(&dot, 0, sizeof(dot)); dirent = ˙ dirent->inode = ino; - dirent->rec_len = EXT2_DIR_REC_LEN(1); + dirent->rec_len = EXT2_DIR_NAME_LEN(1); dirent->name_len = 1 | filetype; dirent->name[0] = '.'; } else if (dot_state == 1) { @@ -1235,7 +1318,7 @@ skip_checksum: dirent = &dotdot; dirent->inode = ((struct ext2_dir_entry *)buf)->inode; - dirent->rec_len = EXT2_DIR_REC_LEN(2); + dirent->rec_len = EXT2_DIR_NAME_LEN(2); dirent->name_len = 2 | filetype; dirent->name[0] = '.'; dirent->name[1] = '.'; @@ -1247,10 +1330,10 @@ skip_checksum: } if (dot_state == 0) { - if (check_dot(ctx, dirent, ino, &cd->pctx)) + if (check_dot(ctx, dirent, offset, ino, &cd->pctx)) dir_modified++; } else if (dot_state == 1) { - ret = check_dotdot(ctx, dirent, ino, &cd->pctx); + ret = check_dotdot(ctx, dirent, offset, ino, &cd->pctx); if (ret < 0) goto abort_free_dict; if (ret) @@ -1266,6 +1349,10 @@ skip_checksum: if (!dirent->inode) goto next; + ret = e2fsck_check_dirent_data(ctx, dirent, offset, &cd->pctx); + if (ret == 2) + dir_modified++; + /* * Make sure the inode listed is a legal one. */ diff --git a/e2fsck/pass3.c b/e2fsck/pass3.c index 6a975b36..4a777213 100644 --- a/e2fsck/pass3.c +++ b/e2fsck/pass3.c @@ -698,6 +698,7 @@ static int fix_dotdot_proc(struct ext2_dir_entry *dirent, struct fix_dotdot_struct *fp = (struct fix_dotdot_struct *) priv_data; errcode_t retval; struct problem_context pctx; + __u16 dirdata = 0; if (ext2fs_dirent_name_len(dirent) != 2) return 0; @@ -717,11 +718,17 @@ static int fix_dotdot_proc(struct ext2_dir_entry *dirent, fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx); } dirent->inode = fp->parent; + + dirdata = dirent->name_len & (~EXT2_FT_MASK << 8); + if (ext2fs_has_feature_filetype(fp->ctx->fs->super)) ext2fs_dirent_set_file_type(dirent, EXT2_FT_DIR); else ext2fs_dirent_set_file_type(dirent, EXT2_FT_UNKNOWN); + if (ext2fs_has_feature_dirdata(fp->ctx->fs->super)) + dirent->name_len |= dirdata; + fp->done++; return DIRENT_ABORT | DIRENT_CHANGED; } diff --git a/e2fsck/problem.c b/e2fsck/problem.c index edc9d51f..2a86d528 100644 --- a/e2fsck/problem.c +++ b/e2fsck/problem.c @@ -1671,6 +1671,11 @@ static struct e2fsck_problem problem_table[] = { N_("Encrypted @E is too short.\n"), PROMPT_CLEAR, 0 }, + /* Directory entry dirdata length set incorrectly */ + { PR_2_CLEAR_DIRDATA, + N_("@E dirdata length set incorrectly.\n"), + PROMPT_CLEAR, PR_PREEN_OK }, + /* Pass 3 errors */ /* Pass 3: Checking directory connectivity */ diff --git a/e2fsck/problem.h b/e2fsck/problem.h index 482d111a..05214840 100644 --- a/e2fsck/problem.h +++ b/e2fsck/problem.h @@ -1004,6 +1004,9 @@ struct problem_context { /* Encrypted directory entry is too short */ #define PR_2_BAD_ENCRYPTED_NAME 0x020050 +/* Entry dirdata length set incorrectly */ +#define PR_2_CLEAR_DIRDATA 0x020051 + /* * Pass 3 errors */ diff --git a/e2fsck/rehash.c b/e2fsck/rehash.c index 486e1f21..546b073c 100644 --- a/e2fsck/rehash.c +++ b/e2fsck/rehash.c @@ -85,6 +85,8 @@ struct fill_dir_struct { int compress; ino_t parent; ext2_ino_t dir; + struct ext2_dir_entry *dot_de; + struct ext2_dir_entry *dotdot_de; }; struct hash_entry { @@ -160,11 +162,14 @@ static int fill_dir_block(ext2_filsys fs, if (dirent->inode == 0) continue; if (!fd->compress && (name_len == 1) && - (dirent->name[0] == '.')) + (dirent->name[0] == '.')) { + fd->dot_de = dirent; continue; + } if (!fd->compress && (name_len == 2) && (dirent->name[0] == '.') && (dirent->name[1] == '.')) { fd->parent = dirent->inode; + fd->dotdot_de = dirent; continue; } if (fd->num_array >= fd->max_array) { @@ -179,7 +184,7 @@ static int fill_dir_block(ext2_filsys fs, } ent = fd->harray + fd->num_array++; ent->dir = dirent; - fd->dir_size += EXT2_DIR_REC_LEN(name_len); + fd->dir_size += EXT2_DIR_REC_LEN(dirent); ent->ino = dirent->inode; if (fd->compress) ent->hash = ent->minor_hash = 0; @@ -475,7 +480,7 @@ static errcode_t copy_dir_entries(e2fsck_t ctx, ent = fd->harray + i; if (ent->dir->inode == 0) continue; - rec_len = EXT2_DIR_REC_LEN(ext2fs_dirent_name_len(ent->dir)); + rec_len = EXT2_DIR_REC_LEN(ent->dir); if (rec_len > left) { if (left) { left += prev_rec_len; @@ -510,8 +515,7 @@ static errcode_t copy_dir_entries(e2fsck_t ctx, if (retval) return retval; prev_rec_len = rec_len; - memcpy(dirent->name, ent->dir->name, - ext2fs_dirent_name_len(dirent)); + memcpy(dirent->name, ent->dir->name, rec_len); offset += rec_len; left -= rec_len; if (left < slack) { @@ -536,44 +540,49 @@ static errcode_t copy_dir_entries(e2fsck_t ctx, static struct ext2_dx_root_info *set_root_node(ext2_filsys fs, char *buf, - ext2_ino_t ino, ext2_ino_t parent) + ext2_ino_t ino, ext2_ino_t parent, + struct ext2_dir_entry *dot_de, + struct ext2_dir_entry *dotdot_de) { - struct ext2_dir_entry *dir; - struct ext2_dx_root_info *root; + struct ext2_dir_entry *dirent; + struct ext2_dx_root_info *root; struct ext2_dx_countlimit *limits; - int filetype = 0; int csum_size = 0; - - if (ext2fs_has_feature_filetype(fs->super)) - filetype = EXT2_FT_DIR; + int offset; + int rec_len; memset(buf, 0, fs->blocksize); - dir = (struct ext2_dir_entry *) buf; - dir->inode = ino; - dir->name[0] = '.'; - ext2fs_dirent_set_name_len(dir, 1); - ext2fs_dirent_set_file_type(dir, filetype); - dir->rec_len = 12; - dir = (struct ext2_dir_entry *) (buf + 12); - dir->inode = parent; - dir->name[0] = '.'; - dir->name[1] = '.'; - ext2fs_dirent_set_name_len(dir, 2); - ext2fs_dirent_set_file_type(dir, filetype); - dir->rec_len = fs->blocksize - 12; - - root = (struct ext2_dx_root_info *) (buf+24); + dirent = (struct ext2_dir_entry *) buf; + dirent->inode = ino; + + dirent->name_len = dot_de->name_len; + offset = rec_len = dirent->rec_len = dot_de->rec_len; + memcpy(dirent->name, dot_de->name, rec_len); + + dirent = EXT2_NEXT_DIRENT(dirent); + /* set to jump over the index block */ + + dirent->inode = parent; + + dirent->name_len = dotdot_de->name_len; + dirent->rec_len = fs->blocksize - rec_len; + rec_len = EXT2_DIR_REC_LEN(dotdot_de); + memcpy(dirent->name, dotdot_de->name, rec_len); + offset += rec_len; + + root = (struct ext2_dx_root_info *)(buf + offset); root->reserved_zero = 0; root->hash_version = fs->super->s_def_hash_version; - root->info_length = 8; + root->info_length = sizeof(*root); root->indirect_levels = 0; root->unused_flags = 0; + offset += root->info_length; if (ext2fs_has_feature_metadata_csum(fs->super)) csum_size = sizeof(struct ext2_dx_tail); - limits = (struct ext2_dx_countlimit *) (buf+32); - limits->limit = (fs->blocksize - (32 + csum_size)) / + limits = (struct ext2_dx_countlimit *) (buf + offset); + limits->limit = (fs->blocksize - (offset + csum_size)) / sizeof(struct ext2_dx_entry); limits->count = 0; @@ -647,7 +656,9 @@ static int alloc_blocks(ext2_filsys fs, static errcode_t calculate_tree(ext2_filsys fs, struct out_dir *outdir, ext2_ino_t ino, - ext2_ino_t parent) + ext2_ino_t parent, + struct ext2_dir_entry *dot_de, + struct ext2_dir_entry *dotdot_de) { struct ext2_dx_root_info *root_info; struct ext2_dx_entry *root, *int_ent, *dx_ent = 0; @@ -657,7 +668,9 @@ static errcode_t calculate_tree(ext2_filsys fs, int i, c1, c2, c3, nblks; int limit_offset, int_offset, root_offset; - root_info = set_root_node(fs, outdir->buf, ino, parent); + root_info = set_root_node(fs, outdir->buf, ino, parent, dot_de, + dotdot_de); + root_offset = limit_offset = ((char *) root_info - outdir->buf) + root_info->info_length; root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset); @@ -944,11 +957,10 @@ resort: if (retval) goto errout; - free(dir_buf); dir_buf = 0; - if (!fd.compress) { /* Calculate the interior nodes */ - retval = calculate_tree(fs, &outdir, ino, fd.parent); + retval = calculate_tree(fs, &outdir, ino, fd.parent, + fd.dot_de, fd.dotdot_de); if (retval) goto errout; } diff --git a/lib/ext2fs/dirblock.c b/lib/ext2fs/dirblock.c index 54b27772..3563138d 100644 --- a/lib/ext2fs/dirblock.c +++ b/lib/ext2fs/dirblock.c @@ -50,6 +50,39 @@ errcode_t ext2fs_read_dir_block3(ext2_filsys fs, blk64_t block, return ext2fs_read_dir_block4(fs, block, buf, flags, 0); } +/* + * Compute the dirdata length. This includes only optional extensions. + * Each extension has a bit set in the high 4 bits of + * de->file_type, and the extension length is the first byte in each entry. + */ +int ext2_get_dirdata_field_size(struct ext2_dir_entry *de, + char dirdata_flags) +{ + char *lenp = de->name + (de->name_len & EXT2_NAME_LEN) + 1 /* NUL */; + __u8 extra_data_flags = (de->name_len & ~(EXT2_FT_MASK << 8)) >> 12; + int dlen = 0; + + dirdata_flags >>= 4; + while ((extra_data_flags & dirdata_flags) != 0) { + if (extra_data_flags & 1) { + if (dirdata_flags & 1) + dlen += *lenp; + + lenp += *lenp; + } + extra_data_flags >>= 1; + dirdata_flags >>= 1; + } + + /* add NUL terminator byte to dirdata length */ + return dlen + (dlen != 0); +} + +int ext2_get_dirdata_size(struct ext2_dir_entry *de) +{ + return ext2_get_dirdata_field_size(de, ~EXT2_FT_MASK); +} + errcode_t ext2fs_read_dir_block2(ext2_filsys fs, blk_t block, void *buf, int flags EXT2FS_ATTR((unused))) { diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h index 2496d16d..4919f946 100644 --- a/lib/ext2fs/ext2_fs.h +++ b/lib/ext2fs/ext2_fs.h @@ -923,7 +923,8 @@ EXT4_FEATURE_INCOMPAT_FUNCS(encrypt, 4, ENCRYPT) #define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \ EXT4_FEATURE_INCOMPAT_MMP| \ EXT4_FEATURE_INCOMPAT_LARGEDIR| \ - EXT4_FEATURE_INCOMPAT_EA_INODE) + EXT4_FEATURE_INCOMPAT_EA_INODE| \ + EXT4_FEATURE_INCOMPAT_DIRDATA) #define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \ EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \ EXT4_FEATURE_RO_COMPAT_DIR_NLINK| \ @@ -1011,6 +1012,7 @@ struct ext2_dir_entry_tail { #define EXT2_FT_SYMLINK 7 #define EXT2_FT_MAX 8 +#define EXT2_FT_MASK 0x0f /* * Annoyingly, e2fsprogs always swab16s ext2_dir_entry.name_len, so we @@ -1028,11 +1030,18 @@ struct ext2_dir_entry_tail { #define EXT2_DIR_ENTRY_HEADER_LEN 8 #define EXT2_DIR_PAD 4 #define EXT2_DIR_ROUND (EXT2_DIR_PAD - 1) -#define EXT2_DIR_REC_LEN(name_len) (((name_len) + \ +#define EXT2_DIR_NAME_LEN(name_len) (((name_len) + \ EXT2_DIR_ENTRY_HEADER_LEN + \ EXT2_DIR_ROUND) & \ ~EXT2_DIR_ROUND) +#define EXT2_DIR_REC_LEN(de) (EXT2_DIR_NAME_LEN(((de)->name_len & \ + EXT2_NAME_LEN) + \ + ext2_get_dirdata_size(de))) +/* lu_fid size and NUL char */ +#define EXT2_DIRENT_LUFID_SIZE 16 +#define EXT2_DIRENT_LUFID 0x10 + /* * Constants for ext4's extended time encoding */ @@ -1091,6 +1100,9 @@ struct mmp_struct { */ #define EXT4_MMP_MIN_CHECK_INTERVAL 5 +int ext2_get_dirdata_field_size(struct ext2_dir_entry *de, char dirdata_flags); +int ext2_get_dirent_size(struct ext2_dir_entry *de); + /* * Minimum size of inline data. */ @@ -1101,4 +1113,6 @@ struct mmp_struct { */ #define EXT4_INLINE_DATA_DOTDOT_SIZE (4) +#define EXT2_NEXT_DIRENT(d) ((void *)((char *)(d) + (d)->rec_len)) + #endif /* _LINUX_EXT2_FS_H */ diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h index 6774e32c..fbe4398f 100644 --- a/lib/ext2fs/ext2fs.h +++ b/lib/ext2fs/ext2fs.h @@ -600,6 +600,7 @@ typedef struct ext2_icount *ext2_icount_t; EXT3_FEATURE_INCOMPAT_EXTENTS|\ EXT4_FEATURE_INCOMPAT_FLEX_BG|\ EXT4_FEATURE_INCOMPAT_EA_INODE|\ + EXT4_FEATURE_INCOMPAT_DIRDATA|\ EXT4_LIB_INCOMPAT_MMP|\ EXT4_FEATURE_INCOMPAT_64BIT|\ EXT4_FEATURE_INCOMPAT_INLINE_DATA|\ @@ -1978,6 +1979,25 @@ _INLINE_ int ext2fs_htree_intnode_maxrecs(ext2_filsys fs, int blocks) return blocks * ((fs->blocksize - 8) / sizeof(struct ext2_dx_entry)); } +_INLINE_ struct ext2_dx_root_info *get_ext2_dx_root_info(ext2_filsys fs, + char *buf) +{ + struct ext2_dir_entry *de = (struct ext2_dir_entry *)buf; + + if (!(fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_DIRDATA)) + return (struct ext2_dx_root_info *)(buf + + EXT2_DIR_NAME_LEN(1) + + EXT2_DIR_NAME_LEN(2)); + + /* get dotdot first */ + de = (struct ext2_dir_entry *)((char *)de + de->rec_len); + + /* dx root info is after dotdot entry */ + de = (struct ext2_dir_entry *)((char *)de + EXT2_DIR_REC_LEN(de)); + + return (struct ext2_dx_root_info *)de; +} + /* * This is an efficient, overflow safe way of calculating ceil((1.0 * a) / b) */ @@ -1997,7 +2017,7 @@ _INLINE_ __u64 ext2fs_div64_ceil(__u64 a, __u64 b) _INLINE_ int ext2fs_dirent_name_len(const struct ext2_dir_entry *entry) { - return entry->name_len & 0xff; + return entry->name_len & EXT2_NAME_LEN; } _INLINE_ void ext2fs_dirent_set_name_len(struct ext2_dir_entry *entry, int len) diff --git a/lib/ext2fs/inline_data.c b/lib/ext2fs/inline_data.c index 7215c517..684972b3 100644 --- a/lib/ext2fs/inline_data.c +++ b/lib/ext2fs/inline_data.c @@ -149,7 +149,7 @@ int ext2fs_inline_data_dir_iterate(ext2_filsys fs, ext2_ino_t ino, /* we first check '.' and '..' dir */ dirent.inode = ino; dirent.name_len = 1; - ext2fs_set_rec_len(fs, EXT2_DIR_REC_LEN(2), &dirent); + ext2fs_set_rec_len(fs, EXT2_DIR_NAME_LEN(2), &dirent); dirent.name[0] = '.'; dirent.name[1] = '\0'; ctx->buf = (char *)&dirent; @@ -160,7 +160,7 @@ int ext2fs_inline_data_dir_iterate(ext2_filsys fs, ext2_ino_t ino, dirent.inode = ext2fs_le32_to_cpu(inode.i_block[0]); dirent.name_len = 2; - ext2fs_set_rec_len(fs, EXT2_DIR_REC_LEN(3), &dirent); + ext2fs_set_rec_len(fs, EXT2_DIR_NAME_LEN(3), &dirent); dirent.name[0] = '.'; dirent.name[1] = '.'; dirent.name[2] = '\0'; @@ -296,14 +296,14 @@ static errcode_t ext2fs_inline_data_convert_dir(ext2_filsys fs, ext2_ino_t ino, ext2fs_dirent_set_name_len(dir, 1); ext2fs_dirent_set_file_type(dir, filetype); dir->name[0] = '.'; - rec_len = (fs->blocksize - csum_size) - EXT2_DIR_REC_LEN(1); - dir->rec_len = EXT2_DIR_REC_LEN(1); + rec_len = (fs->blocksize - csum_size) - EXT2_DIR_NAME_LEN(1); + dir->rec_len = EXT2_DIR_NAME_LEN(1); /* * Set up entry for '..' */ dir = (struct ext2_dir_entry *) (bbuf + dir->rec_len); - dir->rec_len = EXT2_DIR_REC_LEN(2); + dir->rec_len = EXT2_DIR_NAME_LEN(2); dir->inode = ext2fs_le32_to_cpu(((__u32 *)ibuf)[0]); ext2fs_dirent_set_name_len(dir, 2); ext2fs_dirent_set_file_type(dir, filetype); @@ -313,11 +313,11 @@ static errcode_t ext2fs_inline_data_convert_dir(ext2_filsys fs, ext2_ino_t ino, /* * Adjust the last rec_len */ - offset = EXT2_DIR_REC_LEN(1) + EXT2_DIR_REC_LEN(2); + offset = EXT2_DIR_NAME_LEN(1) + EXT2_DIR_NAME_LEN(2); dir = (struct ext2_dir_entry *) (bbuf + offset); memcpy(bbuf + offset, ibuf + EXT4_INLINE_DATA_DOTDOT_SIZE, size - EXT4_INLINE_DATA_DOTDOT_SIZE); - size += EXT2_DIR_REC_LEN(1) + EXT2_DIR_REC_LEN(2) - + size += EXT2_DIR_NAME_LEN(1) + EXT2_DIR_NAME_LEN(2) - EXT4_INLINE_DATA_DOTDOT_SIZE; do { diff --git a/lib/ext2fs/link.c b/lib/ext2fs/link.c index 65dc8877..a038a104 100644 --- a/lib/ext2fs/link.c +++ b/lib/ext2fs/link.c @@ -47,7 +47,7 @@ static int link_proc(struct ext2_dir_entry *dirent, if (ls->done) return DIRENT_ABORT; - rec_len = EXT2_DIR_REC_LEN(ls->namelen); + rec_len = EXT2_DIR_NAME_LEN(ls->namelen); ls->err = ext2fs_get_rec_len(ls->fs, dirent, &curr_rec_len); if (ls->err) @@ -92,8 +92,8 @@ static int link_proc(struct ext2_dir_entry *dirent, /* De-convert a dx_root block */ if (csum_size && - curr_rec_len == ls->fs->blocksize - EXT2_DIR_REC_LEN(1) && - offset == EXT2_DIR_REC_LEN(1) && + curr_rec_len == ls->fs->blocksize - EXT2_DIR_NAME_LEN(1) && + offset == EXT2_DIR_NAME_LEN(1) && dirent->name[0] == '.' && dirent->name[1] == '.') { curr_rec_len -= csum_size; ls->err = ext2fs_set_rec_len(ls->fs, curr_rec_len, dirent); @@ -110,7 +110,7 @@ static int link_proc(struct ext2_dir_entry *dirent, * truncate it and return. */ if (dirent->inode) { - min_rec_len = EXT2_DIR_REC_LEN(ext2fs_dirent_name_len(dirent)); + min_rec_len = EXT2_DIR_REC_LEN(dirent); if (curr_rec_len < (min_rec_len + rec_len)) return ret; rec_len = curr_rec_len - min_rec_len; @@ -138,7 +138,7 @@ static int link_proc(struct ext2_dir_entry *dirent, ext2fs_dirent_set_name_len(dirent, ls->namelen); strncpy(dirent->name, ls->name, ls->namelen); if (ext2fs_has_feature_filetype(ls->sb)) - ext2fs_dirent_set_file_type(dirent, ls->flags & 0x7); + ext2fs_dirent_set_file_type(dirent, ls->flags & EXT2_FT_MASK); ls->done++; return DIRENT_ABORT|DIRENT_CHANGED; diff --git a/lib/ext2fs/newdir.c b/lib/ext2fs/newdir.c index 7f472850..f168d668 100644 --- a/lib/ext2fs/newdir.c +++ b/lib/ext2fs/newdir.c @@ -64,8 +64,8 @@ errcode_t ext2fs_new_dir_block(ext2_filsys fs, ext2_ino_t dir_ino, ext2fs_dirent_set_name_len(dir, 1); ext2fs_dirent_set_file_type(dir, filetype); dir->name[0] = '.'; - rec_len = (fs->blocksize - csum_size) - EXT2_DIR_REC_LEN(1); - dir->rec_len = EXT2_DIR_REC_LEN(1); + rec_len = (fs->blocksize - csum_size) - EXT2_DIR_NAME_LEN(1); + dir->rec_len = EXT2_DIR_NAME_LEN(1); /* * Set up entry for '..' diff --git a/misc/mke2fs.c b/misc/mke2fs.c index cfb10bc4..4d8593f7 100644 --- a/misc/mke2fs.c +++ b/misc/mke2fs.c @@ -1084,6 +1084,7 @@ static __u32 ok_features[3] = { EXT4_FEATURE_INCOMPAT_FLEX_BG| EXT4_FEATURE_INCOMPAT_EA_INODE| EXT4_FEATURE_INCOMPAT_MMP | + EXT4_FEATURE_INCOMPAT_DIRDATA| EXT4_FEATURE_INCOMPAT_64BIT| EXT4_FEATURE_INCOMPAT_INLINE_DATA| EXT4_FEATURE_INCOMPAT_ENCRYPT | @@ -2900,6 +2901,13 @@ int main (int argc, char *argv[]) exit(1); } + if (ext2fs_has_feature_inline_data(fs->super) && + ext2fs_has_feature_dirdata(fs->super)) { + printf("%s", _("The dirdata feature can not enabled " + "with inline data feature.\n")); + exit(1); + } + /* Calculate journal blocks */ if (!journal_device && ((journal_size) || ext2fs_has_feature_journal(&fs_param))) diff --git a/misc/tune2fs.c b/misc/tune2fs.c index d0a18a18..44dd41a5 100644 --- a/misc/tune2fs.c +++ b/misc/tune2fs.c @@ -157,6 +157,7 @@ static __u32 ok_features[3] = { EXT4_FEATURE_INCOMPAT_FLEX_BG | EXT4_FEATURE_INCOMPAT_EA_INODE| EXT4_FEATURE_INCOMPAT_MMP | + EXT4_FEATURE_INCOMPAT_DIRDATA | EXT4_FEATURE_INCOMPAT_64BIT | EXT4_FEATURE_INCOMPAT_ENCRYPT | EXT4_FEATURE_INCOMPAT_CSUM_SEED | @@ -183,6 +184,7 @@ static __u32 clear_ok_features[3] = { EXT2_FEATURE_INCOMPAT_FILETYPE | EXT4_FEATURE_INCOMPAT_FLEX_BG | EXT4_FEATURE_INCOMPAT_MMP | + EXT4_FEATURE_INCOMPAT_DIRDATA | EXT4_FEATURE_INCOMPAT_64BIT | EXT4_FEATURE_INCOMPAT_CSUM_SEED, /* R/O compat */ From patchwork Fri May 4 07:09:18 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artem Blagodarenko X-Patchwork-Id: 908551 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="haE8FL3S"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40cjnj1nKzz9s3D for ; Fri, 4 May 2018 17:10:01 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751464AbeEDHKA (ORCPT ); Fri, 4 May 2018 03:10:00 -0400 Received: from mail-lf0-f67.google.com ([209.85.215.67]:46368 "EHLO mail-lf0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751336AbeEDHJm (ORCPT ); Fri, 4 May 2018 03:09:42 -0400 Received: by mail-lf0-f67.google.com with SMTP id v85-v6so29431003lfa.13 for ; Fri, 04 May 2018 00:09:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=MFpkDFtPjlV/MEq8J+7hrjSFRIClLbWYV1gydEScJoQ=; b=haE8FL3ShDHL0lieynAGpxB7x9hAZhFqhEaC0fcYGE5zGuut7eXnpXzqnrYkcVe6bd DdC5sUqFvgxD7BzX7dzlpiKvkSD/lcqqlh76fCywkPUTVEAll+7fSDj1dByhGY5WIRpQ K7cnNXhfxN5f51bBL97lB+4fu5kZXQ5chuQRD/xfO6BsuT3747E6vNnOo0MdyihSVlIO v4Wju6Ahx1VO9G4bJhBfcy7foUO+Wj47MyxFhtJfCJ3qANv92GBL6J6Ku+iGoKTeQcSZ fol3HSldQn8HictMsGCevoclojFfbfKhgdeAW+PCRz2/BogQrNrvIEJ+JpBkblGOaKv1 hnRg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=MFpkDFtPjlV/MEq8J+7hrjSFRIClLbWYV1gydEScJoQ=; b=CQVMhAkpO9g3CWbsrYEvtAF0A16xpNlJZ9dl1gCscsk9yiHMCDKQXcvWHH7v1RyHEV gKT0ZjtpaR4a60UXllUnDu8d1H7S8Tr4KbOAG0YRTGWX6y4X6nF85xFZ36MKstuWnV5w SpAhaTqV76D+PYzVnEDvSl+Ea3r8EnBxCRgo1nZcExQR7VyKTo2NNJq/gjqdY3EcUjLu duxiDsmZ/uMc14UGPuOSH2KMq1fZH2qKEf6bAsXDq2TDRteAV244ZD/99+pUSP5aqcPV pTIt87rMH9P6/T8GQYzuggu2R7JgWywZsi2g2UkwhKiTFGeIiF5NLHRJWnzuLSG9VorI FSdA== X-Gm-Message-State: ALQs6tBQ1Vu2jrU4AibAnWaQg96bBizh1g1XCXwVQo1B1yXhl64va12S cYJ4eBKDMRY9IBQv9wUWCIWmDbMM X-Google-Smtp-Source: AB8JxZqTLriGb+QT2X3kJ84sMXKLi8d8ExYTn+t0vVh/rNEvtkNfG5hdFJhHtKXKUU8uRVpstcrUkA== X-Received: by 2002:a2e:880a:: with SMTP id x10-v6mr17759312ljh.45.1525417776862; Fri, 04 May 2018 00:09:36 -0700 (PDT) Received: from C02TN4C6HTD6.lan ([80.72.234.202]) by smtp.gmail.com with ESMTPSA id f16-v6sm3170296lfh.94.2018.05.04.00.09.34 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 04 May 2018 00:09:36 -0700 (PDT) From: c17828 X-Google-Original-From: c17828 To: linux-ext4@vger.kernel.org Cc: adilger.kernel@dilger.ca, Andreas Dilger , Pravin Shelar , Artem Blagodarenko Subject: [PATCH v4 2/7] tests: add basic tests for dirdata feature Date: Fri, 4 May 2018 10:09:18 +0300 Message-Id: <20180504070923.45140-3-c17828@cray.com> X-Mailer: git-send-email 2.14.3 (Apple Git-98) In-Reply-To: <20180504070923.45140-1-c17828@cray.com> References: <20180504070923.45140-1-c17828@cray.com> Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org From: Andreas Dilger Signed-off-by: Pravin Shelar Signed-off-by: Andreas Dilger Signed-off-by: Artem Blagodarenko --- tests/f_dirdata/expect.1 | 15 +++++++++++++++ tests/f_dirdata/expect.2 | 7 +++++++ tests/f_dirdata/image.gz | Bin 0 -> 72169 bytes tests/f_dirdata/name | 1 + 4 files changed, 23 insertions(+) diff --git a/tests/f_dirdata/expect.1 b/tests/f_dirdata/expect.1 new file mode 100644 index 00000000..17e24325 --- /dev/null +++ b/tests/f_dirdata/expect.1 @@ -0,0 +1,15 @@ +Pass 1: Checking inodes, blocks, and sizes +Pass 2: Checking directory structure +Entry 'foobar2' in /ROOT/dir1 (439) dirdata length set incorrectly. +Clear? yes + +Entry 'foobar1' in /ROOT/dir1 (439) dirdata length set incorrectly. +Clear? yes + +Pass 3: Checking directory connectivity +Pass 4: Checking reference counts +Pass 5: Checking group summary information + +test_filesys: ***** FILE SYSTEM WAS MODIFIED ***** +test_filesys: 543/5000 files (0.9% non-contiguous), 707/5000 blocks +Exit status is 1 diff --git a/tests/f_dirdata/expect.2 b/tests/f_dirdata/expect.2 new file mode 100644 index 00000000..84cce856 --- /dev/null +++ b/tests/f_dirdata/expect.2 @@ -0,0 +1,7 @@ +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: 543/5000 files (0.9% non-contiguous), 707/5000 blocks +Exit status is 0 diff --git a/tests/f_dirdata/image.gz b/tests/f_dirdata/image.gz new file mode 100644 index 0000000000000000000000000000000000000000..ccd900e1c6da30a76be4334767922b2babf0f88a GIT binary patch literal 72169 zcmZ^Ldt6NEA3u`N5?b12nYGv=X|YM09M_Fpa#<>2C<$S#q*d~eOLFVGx=9!$EsgEQ zMyaC}EzxvgQmF}>shw(~xzssxp3m<&XZrpA`~By2=IJ?~`{(_+9HP_x`#*Fq@a$u@ zeb?r|fL^Wj7T&*9|7FoJH|waM`;!LO0`DyQ@9gxa`u|~fs*j&$(C~0gfnnpyR~NR; zJ9G1o7RGP)k5dmkdug-GZ}&k}FYDi1+wLoB-!=W&8ZS{Uj+;5

%i*C$-Laa(zkS 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 literal 0 HcmV?d00001 diff --git a/tests/f_dirdata/name b/tests/f_dirdata/name new file mode 100644 index 00000000..5abb9391 --- /dev/null +++ b/tests/f_dirdata/name @@ -0,0 +1 @@ +corrupted dirdata length From patchwork Fri May 4 07:09:19 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artem Blagodarenko X-Patchwork-Id: 908550 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="mba0Usbw"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40cjnL60Y2z9s3D for ; Fri, 4 May 2018 17:09:42 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751342AbeEDHJm (ORCPT ); Fri, 4 May 2018 03:09:42 -0400 Received: from mail-lf0-f66.google.com ([209.85.215.66]:34205 "EHLO mail-lf0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751261AbeEDHJj (ORCPT ); Fri, 4 May 2018 03:09:39 -0400 Received: by mail-lf0-f66.google.com with SMTP id h4-v6so29482059lfc.1 for ; Fri, 04 May 2018 00:09:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=7n+Th4iK8T6OUn50sFMDyEAMAJJnXY0GigXM5yHRlRQ=; b=mba0Usbwjr+T+f/Fvu88gTGwh069kYIpID7cCMq133oO416qT7GHj1r29II64ewRVM b/zP6nv4nZmD9JA7x83l/XHCH6MMT9feODJJzoLvhjnCiniAVufbhSLWEU2JoFbXakfC zi53zKKewu5DZuMxtMdcGlD10dvBaYOyrlbqYI5MemC6iNZ4B2sRsqRFvlTJo2FaegBe cvvwHThQfRktC/3+8fcKqTcgB5HL2Gm1gJQvcsyuXx7nOqqTqs8AgQufoA5nZqZPgIyc VYGLbAtKh+zC2YNwI80omzC/coaK1V+nSGfNkN9/cqgUM2/eyMTHojZtytJZ8SuQcl2h hHDA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=7n+Th4iK8T6OUn50sFMDyEAMAJJnXY0GigXM5yHRlRQ=; b=dDz3/4ezzwknlVRk13CXnguwsX5RpJHzJNbwuRv31WPOfv7MfPyjSmDWW3GN2w4btV TOkIQpFWRwEZ5WfogMeGLnmzgW176bf2kOOXaPejRMGgS5q7IcyMN8J0YdoJ1/Q132Fd Zdh1wYcPH6Q6AA+gFf9wKVWBMImV4AQv07hOBwTiqakBEyu+Io6uRyhx9vGARQQMFRg5 QHYFCehfoFOmiLvFpmeX0JO0JSkf+NIFI0/zUHzZOScID20UXofeSsyPFO+KWJmS3h/6 Kr1rYqpH6X6mtqlxm3J9jptISQt8reIIdTl4eRyz1qh/GA2awmKoePVrXGPo/M92j2nx hY0A== X-Gm-Message-State: ALQs6tAIrhFzk/3MoOQpkMH/2zKNxm2tUEKNj7acyGfpCJLgUCxzGfiA QDbF2ZwCx6ATQBZzxb+HJtHvZg== X-Google-Smtp-Source: AB8JxZoZIU2KJIkfi2MtsJR6eN9g14pGuYv3HRHCa/pCMujcTO6a4fuLpzzxFQvpJa1hkj6nsaqIYQ== X-Received: by 2002:a2e:9797:: with SMTP id y23-v6mr18986168lji.52.1525417777987; Fri, 04 May 2018 00:09:37 -0700 (PDT) Received: from C02TN4C6HTD6.lan ([80.72.234.202]) by smtp.gmail.com with ESMTPSA id f16-v6sm3170296lfh.94.2018.05.04.00.09.37 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 04 May 2018 00:09:37 -0700 (PDT) From: c17828 X-Google-Original-From: c17828 To: linux-ext4@vger.kernel.org Cc: adilger.kernel@dilger.ca, Artem Blagodarenko Subject: [PATCH v4 3/7] debugfs: 64bit inode support Date: Fri, 4 May 2018 10:09:19 +0300 Message-Id: <20180504070923.45140-4-c17828@cray.com> X-Mailer: git-send-email 2.14.3 (Apple Git-98) In-Reply-To: <20180504070923.45140-1-c17828@cray.com> References: <20180504070923.45140-1-c17828@cray.com> Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org From: Artem Blagodarenko New dirdata type EXT2_DIRENT_INODE is added. Lustre-bug: https://jira.hpdd.intel.com/browse/LU-9309 Signed-off-by: Artem Blagodarenko Reviewed-by: Andreas Dilger --- debugfs/ls.c | 4 +++- lib/ext2fs/ext2_fs.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/debugfs/ls.c b/debugfs/ls.c index 082c14b9..bed4ad44 100644 --- a/debugfs/ls.c +++ b/debugfs/ls.c @@ -87,7 +87,9 @@ static void list_dirdata(struct list_dir_struct *ls, dlen = data[0]; - if (dirdata_mask == EXT2_DIRENT_LUFID) { + if (dirdata_mask == EXT2_DIRENT_INODE) { + fprintf(ls->f, "ino64:%04\n", *(__u32 *)(data + 1)); + } else if (dirdata_mask == EXT2_DIRENT_LUFID) { struct lu_fid *fid = (struct lu_fid *)(data + 1); fid_be_to_cpu(fid, fid); diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h index 4919f946..4681a216 100644 --- a/lib/ext2fs/ext2_fs.h +++ b/lib/ext2fs/ext2_fs.h @@ -1041,6 +1041,7 @@ struct ext2_dir_entry_tail { /* lu_fid size and NUL char */ #define EXT2_DIRENT_LUFID_SIZE 16 #define EXT2_DIRENT_LUFID 0x10 +#define EXT2_DIRENT_INODE 0x20 /* * Constants for ext4's extended time encoding From patchwork Fri May 4 07:09:21 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artem Blagodarenko X-Patchwork-Id: 908552 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Kav1KWNg"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40cjnl2h6jz9s3Z for ; Fri, 4 May 2018 17:10:03 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751465AbeEDHKC (ORCPT ); Fri, 4 May 2018 03:10:02 -0400 Received: from mail-lf0-f66.google.com ([209.85.215.66]:33599 "EHLO mail-lf0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751261AbeEDHJq (ORCPT ); Fri, 4 May 2018 03:09:46 -0400 Received: by mail-lf0-f66.google.com with SMTP id m18-v6so29470267lfb.0 for ; Fri, 04 May 2018 00:09:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=BlVvEOjqWChnvYi6h5Rn/aYhvnhwGTrAEXDna+D/2PE=; b=Kav1KWNgqjnG1jmo5m/9i8TCmBplvPAt0oRAGWuTwTcXslDrJfJW6k9bfLsfgmjMGZ KbYUEvCoxtMt7lA/MMLOCBia+I30f9/zBnmJ4nU92mp/9fzwpEg7o7/7bcq2YLsj3+JD s4qYXIfm9Xw9WUgYluMSznuj7zrhICjfqng/ZOBlbb1AfbMgAb5hNH37HDYjy3758zg2 8AZjYo7chIjN3yh6rZ+KbzwWLTUnamzUx7RzkmQzgNb7MFM+b1C227Ssysi9sjUHkgxw ZFaGL86r7qft3uvRx7pDsc40zS7WZse+V+l/hEElyryPeOCdHrZhJIcATTylPhWfzQdP Vf6Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=BlVvEOjqWChnvYi6h5Rn/aYhvnhwGTrAEXDna+D/2PE=; b=WUJmpoQye8ngd9/YxooVpTPxfiN7EWh9fYaFaANF4e7oV8hcB64ApeyInGzNcbCZVH DCUUh4FSfO7aF9YBFo7nn/b3ACdAMLSvAv2eIgwgAdGVtNqslsreSBoBPfrLSgk7SjCt B0EUoHEu5pLYKDUOR6+AfxgOtLGUeR0csCxqOO7GaFbSEqEXdKTtDaGwhPSwAVHuFe90 wChOMytLcR1bWpNUfzjSfnhzsJqLBX64cAu0HZKDoSILcpQOIlE73jaVQMnWHF4hlxrM tsEyk/owfUGqt9sromHQ6QYQoKfjJx+7cTIMOTtya0s5l4XUeIotvrPLjn3Ut91B1PTM YDJQ== X-Gm-Message-State: ALQs6tBpfRrHlyiB4zWU5lm549Vjul0/Cx8xV/8jEqtoFGUgSvvudoAU N2s3PENhWh7W6tS7qiH+pSaxqA== X-Google-Smtp-Source: AB8JxZoawFnOniRU1U2ZLiqaN9N718cri++MJRbljZQ5J6cCeop6eOgqclQ15e7z8/AerLabK+pRVw== X-Received: by 2002:a19:164f:: with SMTP id m76-v6mr17190276lfi.27.1525417783520; Fri, 04 May 2018 00:09:43 -0700 (PDT) Received: from C02TN4C6HTD6.lan ([80.72.234.202]) by smtp.gmail.com with ESMTPSA id f16-v6sm3170296lfh.94.2018.05.04.00.09.41 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 04 May 2018 00:09:42 -0700 (PDT) From: c17828 X-Google-Original-From: c17828 To: linux-ext4@vger.kernel.org Cc: adilger.kernel@dilger.ca, Artem Blagodarenko Subject: [PATCH v4 5/7] ext2fs: Add helper functions to access inode numbers Date: Fri, 4 May 2018 10:09:21 +0300 Message-Id: <20180504070923.45140-6-c17828@cray.com> X-Mailer: git-send-email 2.14.3 (Apple Git-98) In-Reply-To: <20180504070923.45140-1-c17828@cray.com> References: <20180504070923.45140-1-c17828@cray.com> Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org From: Artem Blagodarenko 64-bit inodes counter uses extra fields to store hight part. Let's incapsulate inode number reading and writing to extend counter in next commits. Lustre-bug: https://jira.hpdd.intel.com/browse/LU-9309 Signed-off-by: Artem Blagodarenko --- debugfs/util.c | 7 ++++--- e2fsck/extents.c | 8 ++++---- e2fsck/journal.c | 2 +- e2fsck/pass1.c | 20 ++++++++++---------- e2fsck/pass1b.c | 2 +- e2fsck/pass2.c | 4 ++-- e2fsck/pass4.c | 2 +- e2fsck/pass5.c | 20 ++++++++++---------- e2fsck/quota.c | 2 +- e2fsck/super.c | 22 ++++++++++++---------- e2fsck/unix.c | 17 +++++++++-------- ext2ed/inode_com.c | 7 +++++-- ext2ed/super_com.c | 6 ++++-- lib/e2p/ls.c | 17 ++++++++++------- lib/ext2fs/alloc.c | 8 ++++---- lib/ext2fs/alloc_stats.c | 6 ++++-- lib/ext2fs/bitmaps.c | 2 +- lib/ext2fs/ext2fs.h | 37 +++++++++++++++++++++++++++++++++++++ lib/ext2fs/extent.c | 2 +- lib/ext2fs/gen_bitmap64.c | 3 ++- lib/ext2fs/get_num_dirs.c | 4 ++-- lib/ext2fs/icount.c | 7 ++++--- lib/ext2fs/initialize.c | 20 ++++++++++++-------- lib/ext2fs/inline_data.c | 2 +- lib/ext2fs/inode.c | 8 ++++---- lib/ext2fs/openfs.c | 2 +- lib/ext2fs/rw_bitmaps.c | 2 +- lib/ext2fs/tst_bitmaps.c | 7 ++++--- lib/ext2fs/tst_iscan.c | 2 +- misc/findsuper.c | 8 +++++--- misc/fuse2fs.c | 12 ++++++------ misc/mke2fs.c | 8 ++++---- misc/tune2fs.c | 7 ++++--- resize/main.c | 3 ++- resize/resize2fs.c | 30 ++++++++++++++++-------------- tests/progs/test_icount.c | 4 ++-- 36 files changed, 192 insertions(+), 128 deletions(-) diff --git a/debugfs/util.c b/debugfs/util.c index 452de749..b5b04c28 100644 --- a/debugfs/util.c +++ b/debugfs/util.c @@ -119,7 +119,8 @@ ext2_ino_t string_to_inode(char *str) */ if ((len > 2) && (str[0] == '<') && (str[len-1] == '>')) { ino = strtoul(str+1, &end, 0); - if (*end=='>' && (ino <= current_fs->super->s_inodes_count)) + if (*end == '>' && + ino <= ext2fs_get_inodes_count(current_fs->super)) return ino; } @@ -128,8 +129,8 @@ ext2_ino_t string_to_inode(char *str) com_err(str, retval, 0); return 0; } - if (ino > current_fs->super->s_inodes_count) { - com_err(str, 0, "resolves to an illegal inode number: %u\n", + if (ino > ext2fs_get_inodes_count(current_fs->super)) { + com_err(str, 0, "resolves to an illegal inode number: %lu\n", ino); return 0; } diff --git a/e2fsck/extents.c b/e2fsck/extents.c index ef3146d8..ba88f310 100644 --- a/e2fsck/extents.c +++ b/e2fsck/extents.c @@ -381,7 +381,7 @@ static void rebuild_extents(e2fsck_t ctx, const char *pass_name, int pr_header) while (1) { retval = ext2fs_find_first_set_inode_bitmap2( ctx->inodes_to_rebuild, ino + 1, - ctx->fs->super->s_inodes_count, &ino); + ext2fs_get_inodes_count(ctx->fs->super), &ino); if (retval) break; pctx.ino = ino; @@ -396,9 +396,9 @@ static void rebuild_extents(e2fsck_t ctx, const char *pass_name, int pr_header) } if (ctx->progress && !ctx->progress_fd) e2fsck_simple_progress(ctx, "Rebuilding extents", - 100.0 * (float) ino / - (float) ctx->fs->super->s_inodes_count, - ino); + 100.0 * (float)ino / + (float)ext2fs_get_inodes_count(ctx->fs->super), + ino); } end_problem_latch(ctx, PR_LATCH_OPTIMIZE_EXT); diff --git a/e2fsck/journal.c b/e2fsck/journal.c index c4f58f1b..9b107384 100644 --- a/e2fsck/journal.c +++ b/e2fsck/journal.c @@ -1132,7 +1132,7 @@ void e2fsck_move_ext3_journal(e2fsck_t ctx) ext2fs_mark_ib_dirty(fs); ext2fs_bg_free_inodes_count_set(fs, group, ext2fs_bg_free_inodes_count(fs, group) + 1); ext2fs_group_desc_csum_set(fs, group); - fs->super->s_free_inodes_count++; + ext2fs_inc_free_inodes_count(fs->super); return; err_out: diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c index d39086d2..c30e54b2 100644 --- a/e2fsck/pass1.c +++ b/e2fsck/pass1.c @@ -341,7 +341,7 @@ static problem_t check_large_ea_inode(e2fsck_t ctx, /* Check if inode is within valid range */ if ((entry->e_value_inum < EXT2_FIRST_INODE(ctx->fs->super)) || - (entry->e_value_inum > ctx->fs->super->s_inodes_count)) { + (entry->e_value_inum > ext2fs_get_inodes_count(ctx->fs->super))) { pctx->num = entry->e_value_inum; return PR_1_ATTR_VALUE_EA_INODE; } @@ -724,10 +724,10 @@ static void check_is_really_dir(e2fsck_t ctx, struct problem_context *pctx, de.inode = ext2fs_le32_to_cpu(de.inode); de.rec_len = ext2fs_le16_to_cpu(de.rec_len); ext2fs_get_rec_len(ctx->fs, &de, &rec_len2); - if (dotdot >= ctx->fs->super->s_inodes_count || + if (dotdot >= ext2fs_get_inodes_count(ctx->fs->super) || (dotdot < EXT2_FIRST_INO(ctx->fs->super) && dotdot != EXT2_ROOT_INO) || - de.inode >= ctx->fs->super->s_inodes_count || + de.inode >= ext2fs_get_inodes_count(ctx->fs->super) || (de.inode < EXT2_FIRST_INO(ctx->fs->super) && de.inode != 0) || rec_len2 > EXT4_MIN_INLINE_DATA_SIZE - @@ -1098,7 +1098,7 @@ out: if (err) { /* Error; disable itable readahead */ *group = ctx->fs->group_desc_count; - *next_ino = ctx->fs->super->s_inodes_count; + *next_ino = ext2fs_get_inodes_count(ctx->fs->super); } else { /* * Don't do more readahead until we've reached the first inode @@ -1301,8 +1301,8 @@ void e2fsck_pass1(e2fsck_t ctx) * ext3 mount code won't get confused. */ if (!(ctx->options & E2F_OPT_READONLY)) { - if (fs->super->s_last_orphan) { - fs->super->s_last_orphan = 0; + if (ext2fs_get_last_orphan(fs->super)) { + ext2fs_set_last_orphan(fs->super, 0); ext2fs_mark_super_dirty(fs); } } @@ -1338,10 +1338,10 @@ void e2fsck_pass1(e2fsck_t ctx) if (ctx->progress && ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count))) goto endit; - if ((fs->super->s_wtime < fs->super->s_inodes_count) || - (fs->super->s_mtime < fs->super->s_inodes_count) || + if ((fs->super->s_wtime < ext2fs_get_inodes_count(fs->super)) || + (fs->super->s_mtime < ext2fs_get_inodes_count(fs->super)) || (fs->super->s_mkfs_time && - fs->super->s_mkfs_time < fs->super->s_inodes_count)) + fs->super->s_mkfs_time < ext2fs_get_inodes_count(fs->super))) low_dtime_check = 0; if (ext2fs_has_feature_mmp(fs->super) && @@ -1444,7 +1444,7 @@ void e2fsck_pass1(e2fsck_t ctx) * shouldn't be any bugs in the orphan list handling. :-) */ if (inode->i_dtime && low_dtime_check && - inode->i_dtime < ctx->fs->super->s_inodes_count) { + inode->i_dtime < ext2fs_get_inodes_count(ctx->fs->super)) { if (fix_problem(ctx, PR_1_LOW_DTIME, &pctx)) { inode->i_dtime = inode->i_links_count ? 0 : ctx->now; diff --git a/e2fsck/pass1b.c b/e2fsck/pass1b.c index 392ff2c6..1607bfb0 100644 --- a/e2fsck/pass1b.c +++ b/e2fsck/pass1b.c @@ -470,7 +470,7 @@ static void pass1c(e2fsck_t ctx, char *block_buf) */ sd.count = dup_inode_count - dup_inode_founddir; sd.first_inode = EXT2_FIRST_INODE(fs->super); - sd.max_inode = fs->super->s_inodes_count; + sd.max_inode = ext2fs_get_inodes_count(fs->super); ext2fs_dblist_dir_iterate(fs->dblist, 0, block_buf, search_dirent_proc, &sd); } diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c index c419a016..a8ccc465 100644 --- a/e2fsck/pass2.c +++ b/e2fsck/pass2.c @@ -827,7 +827,7 @@ static void salvage_directory(ext2_filsys fs, if ((left < 0) && ((int) rec_len + left > EXT2_DIR_ENTRY_HEADER_LEN) && ((int) name_len + EXT2_DIR_ENTRY_HEADER_LEN <= (int) rec_len + left) && - dirent->inode <= fs->super->s_inodes_count && + dirent->inode <= ext2fs_get_inodes_count(fs->super) && strnlen(dirent->name, name_len) == name_len) { (void) ext2fs_set_rec_len(fs, (int) rec_len + left, dirent); return; @@ -1359,7 +1359,7 @@ skip_checksum: name_len = ext2fs_dirent_name_len(dirent); if (((dirent->inode != EXT2_ROOT_INO) && (dirent->inode < EXT2_FIRST_INODE(fs->super))) || - (dirent->inode > fs->super->s_inodes_count)) { + (dirent->inode > ext2fs_get_inodes_count(fs->super))) { problem = PR_2_BAD_INO; } else if (ctx->inode_bb_map && (ext2fs_test_inode_bitmap2(ctx->inode_bb_map, diff --git a/e2fsck/pass4.c b/e2fsck/pass4.c index 9a491b13..7a76c472 100644 --- a/e2fsck/pass4.c +++ b/e2fsck/pass4.c @@ -177,7 +177,7 @@ void e2fsck_pass4(e2fsck_t ctx) inode = e2fsck_allocate_memory(ctx, inode_size, "scratch inode"); /* Protect loop from wrap-around if s_inodes_count maxed */ - for (i=1; i <= fs->super->s_inodes_count && i > 0; i++) { + for (i = 1; i <= ext2fs_get_inodes_count(fs->super) && i > 0; i++) { int isdir; if (ctx->flags & E2F_FLAG_SIGNAL_MASK) diff --git a/e2fsck/pass5.c b/e2fsck/pass5.c index 7803e8b8..746d8299 100644 --- a/e2fsck/pass5.c +++ b/e2fsck/pass5.c @@ -587,11 +587,11 @@ static void check_inode_bitmaps(e2fsck_t ctx) fs->group_desc_count * sizeof(ext2_ino_t), "directory count array"); if ((1 < ext2fs_get_inode_bitmap_start2(ctx->inode_used_map)) || - (fs->super->s_inodes_count > + (ext2fs_get_inodes_count(fs->super) > ext2fs_get_inode_bitmap_end2(ctx->inode_used_map))) { pctx.num = 3; pctx.blk = 1; - pctx.blk2 = fs->super->s_inodes_count; + pctx.blk2 = ext2fs_get_inodes_count(fs->super); pctx.ino = ext2fs_get_inode_bitmap_start2(ctx->inode_used_map); pctx.ino2 = ext2fs_get_inode_bitmap_end2(ctx->inode_used_map); fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx); @@ -600,11 +600,11 @@ static void check_inode_bitmaps(e2fsck_t ctx) goto errout; } if ((1 < ext2fs_get_inode_bitmap_start2(fs->inode_map)) || - (fs->super->s_inodes_count > + (ext2fs_get_inodes_count(fs->super) > ext2fs_get_inode_bitmap_end2(fs->inode_map))) { pctx.num = 4; pctx.blk = 1; - pctx.blk2 = fs->super->s_inodes_count; + pctx.blk2 = ext2fs_get_inodes_count(fs->super); pctx.ino = ext2fs_get_inode_bitmap_start2(fs->inode_map); pctx.ino2 = ext2fs_get_inode_bitmap_end2(fs->inode_map); fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx); @@ -623,7 +623,7 @@ redo_counts: skip_group++; /* Protect loop from wrap-around if inodes_count is maxed */ - for (i = 1; i <= fs->super->s_inodes_count && i > 0; i++) { + for (i = 1; i <= ext2fs_get_inodes_count(fs->super) && i > 0; i++) { bitmap = 0; if (skip_group && i % fs->super->s_inodes_per_group == 1) { @@ -721,7 +721,7 @@ do_counts: } if ((inodes == fs->super->s_inodes_per_group) || - (i == fs->super->s_inodes_count)) { + (i == ext2fs_get_inodes_count(fs->super))) { /* * If the last inode is free, we can discard it as well. */ @@ -755,7 +755,7 @@ do_counts: fs->group_desc_count*2)) goto errout; if (csum_flag && - (i != fs->super->s_inodes_count) && + (i != ext2fs_get_inodes_count(fs->super)) && (ext2fs_bg_flags_test(fs, group, EXT2_BG_INODE_UNINIT) )) skip_group++; @@ -818,13 +818,13 @@ do_counts: ext2fs_unmark_valid(fs); } } - if (free_inodes != fs->super->s_free_inodes_count) { + if (free_inodes != ext2fs_get_free_inodes_count(fs->super)) { pctx.group = -1; - pctx.ino = fs->super->s_free_inodes_count; + pctx.ino = ext2fs_get_free_inodes_count(fs->super); pctx.ino2 = free_inodes; if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) { - fs->super->s_free_inodes_count = free_inodes; + ext2fs_set_free_inodes_count(fs->super, free_inodes); ext2fs_mark_super_dirty(fs); } } diff --git a/e2fsck/quota.c b/e2fsck/quota.c index b0f9af63..529e87ef 100644 --- a/e2fsck/quota.c +++ b/e2fsck/quota.c @@ -108,7 +108,7 @@ void e2fsck_validate_quota_inodes(e2fsck_t ctx) (pctx.ino == EXT2_JOURNAL_INO) || (pctx.ino == EXT2_EXCLUDE_INO) || (pctx.ino == EXT4_REPLICA_INO) || - (pctx.ino > fs->super->s_inodes_count)) && + (pctx.ino > ext2fs_get_inodes_count(fs->super))) && fix_problem(ctx, PR_0_INVALID_QUOTA_INO, &pctx)) { *quota_sb_inump(sb, qtype) = 0; ext2fs_mark_super_dirty(fs); diff --git a/e2fsck/super.c b/e2fsck/super.c index 47c89c56..20d6190c 100644 --- a/e2fsck/super.c +++ b/e2fsck/super.c @@ -253,14 +253,15 @@ static int release_orphan_inodes(e2fsck_t ctx) struct problem_context pctx; char *block_buf; - if ((ino = fs->super->s_last_orphan) == 0) + ino = ext2fs_get_last_orphan(fs->super); + if (ino == 0) return 0; /* * Win or lose, we won't be using the head of the orphan inode * list again. */ - fs->super->s_last_orphan = 0; + ext2fs_set_last_orphan(fs->super, 0); ext2fs_mark_super_dirty(fs); /* @@ -272,7 +273,7 @@ static int release_orphan_inodes(e2fsck_t ctx) return 0; if ((ino < EXT2_FIRST_INODE(fs->super)) || - (ino > fs->super->s_inodes_count)) { + (ino > ext2fs_get_inodes_count(fs->super))) { clear_problem_context(&pctx); pctx.ino = ino; fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_HEAD_INODE, &pctx); @@ -296,7 +297,7 @@ static int release_orphan_inodes(e2fsck_t ctx) next_ino = inode.i_dtime; if (next_ino && ((next_ino < EXT2_FIRST_INODE(fs->super)) || - (next_ino > fs->super->s_inodes_count))) { + (next_ino > ext2fs_get_inodes_count(fs->super)))) { pctx.ino = next_ino; fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx); goto return_abort; @@ -529,7 +530,7 @@ void check_super_block(e2fsck_t ctx) /* * Verify the super block constants... */ - check_super_value(ctx, "inodes_count", sb->s_inodes_count, + check_super_value(ctx, "inodes_count", ext2fs_get_inodes_count(sb), MIN_CHECK, 1, 0); check_super_value64(ctx, "blocks_count", ext2fs_blocks_count(sb), MIN_CHECK | MAX_CHECK, 1, blks_max); @@ -560,7 +561,8 @@ void check_super_block(e2fsck_t ctx) if (sb->s_rev_level > EXT2_GOOD_OLD_REV) check_super_value(ctx, "first_ino", sb->s_first_ino, MIN_CHECK | MAX_CHECK, - EXT2_GOOD_OLD_FIRST_INO, sb->s_inodes_count); + EXT2_GOOD_OLD_FIRST_INO, + ext2fs_get_inodes_count(sb)); inode_size = EXT2_INODE_SIZE(sb); check_super_value(ctx, "inode_size", inode_size, MIN_CHECK | MAX_CHECK | LOG2_CHECK, @@ -597,11 +599,11 @@ void check_super_block(e2fsck_t ctx) should_be = (blk64_t)sb->s_inodes_per_group * fs->group_desc_count; if (should_be > UINT_MAX) should_be = UINT_MAX; - if (sb->s_inodes_count != should_be) { - pctx.ino = sb->s_inodes_count; + if (ext2fs_get_inodes_count(sb) != should_be) { + pctx.ino = ext2fs_get_inodes_count(sb); pctx.ino2 = should_be; if (fix_problem(ctx, PR_0_INODE_COUNT_WRONG, &pctx)) { - sb->s_inodes_count = should_be; + ext2fs_set_inodes_count(sb, should_be); ext2fs_mark_super_dirty(fs); } } @@ -789,7 +791,7 @@ void check_super_block(e2fsck_t ctx) ctx->free_inodes = free_inodes; if ((ext2fs_free_blocks_count(sb) > ext2fs_blocks_count(sb)) || - (sb->s_free_inodes_count > sb->s_inodes_count)) + (ext2fs_get_free_inodes_count(sb) > ext2fs_get_inodes_count(sb))) ext2fs_unmark_valid(fs); diff --git a/e2fsck/unix.c b/e2fsck/unix.c index b46dcb2d..284d097e 100644 --- a/e2fsck/unix.c +++ b/e2fsck/unix.c @@ -112,9 +112,9 @@ static void show_stats(e2fsck_t ctx) dir_links = 2 * ctx->fs_directory_count - 1; num_files = ctx->fs_total_count - dir_links; num_links = ctx->fs_links_count - dir_links; - inodes = fs->super->s_inodes_count; - inodes_used = (fs->super->s_inodes_count - - fs->super->s_free_inodes_count); + inodes = ext2fs_get_inodes_count(fs->super); + inodes_used = (ext2fs_get_inodes_count(fs->super) - + ext2fs_get_free_inodes_count(fs->super)); blocks = ext2fs_blocks_count(fs->super); blocks_used = (ext2fs_blocks_count(fs->super) - ext2fs_free_blocks_count(fs->super)); @@ -412,12 +412,12 @@ static void check_if_skip(e2fsck_t ctx) * using dumpe2fs. (This is for cosmetic reasons only.) */ clear_problem_context(&pctx); - pctx.ino = fs->super->s_free_inodes_count; + pctx.ino = ext2fs_get_free_inodes_count(fs->super); pctx.ino2 = ctx->free_inodes; if ((pctx.ino != pctx.ino2) && !(ctx->options & E2F_OPT_READONLY) && fix_problem(ctx, PR_0_FREE_INODE_COUNT, &pctx)) { - fs->super->s_free_inodes_count = ctx->free_inodes; + ext2fs_set_free_inodes_count(fs->super, ctx->free_inodes); ext2fs_mark_super_dirty(fs); } clear_problem_context(&pctx); @@ -431,10 +431,11 @@ static void check_if_skip(e2fsck_t ctx) } /* Print the summary message when we're skipping a full check */ - log_out(ctx, _("%s: clean, %u/%u files, %llu/%llu blocks"), + log_out(ctx, _("%s: clean, %lu/%llu files, %llu/%llu blocks"), ctx->device_name, - fs->super->s_inodes_count - fs->super->s_free_inodes_count, - fs->super->s_inodes_count, + ext2fs_get_inodes_count(fs->super) - + ext2fs_get_free_inodes_count(fs->super), + ext2fs_get_inodes_count(fs->super), ext2fs_blocks_count(fs->super) - ext2fs_free_blocks_count(fs->super), ext2fs_blocks_count(fs->super)); diff --git a/ext2ed/inode_com.c b/ext2ed/inode_com.c index 2d3dd6d6..279ce3c1 100644 --- a/ext2ed/inode_com.c +++ b/ext2ed/inode_com.c @@ -210,8 +210,11 @@ void type_ext2_inode___show (char *command_line) wmove (show_win,1,0); - wprintw (show_win,"Inode %ld of %ld. Entry %ld of %ld in group descriptor %ld.\n" - ,inode_num,file_system_info.super_block.s_inodes_count,entry_num,last_entry,group_num); + wprintw (show_win, + "Inode %ld of %ld. Entry %ld of %ld in group descriptor %ld.\n", + inode_num, + ext2fs_get_inodes_count(&file_system_info.super_block), + entry_num, last_entry, group_num); wprintw (show_win,"Inode type: "); diff --git a/ext2ed/super_com.c b/ext2ed/super_com.c index a998970e..98558c58 100644 --- a/ext2ed/super_com.c +++ b/ext2ed/super_com.c @@ -35,8 +35,10 @@ void type_ext2_super_block___show (char *command_line) wmove (show_pad,3,40);wprintw (show_pad,"%2.2f%%",100*(float) ext2fs_free_blocks_count(super)/ (float) ext2fs_blocks_count(super)); } - if (super->s_inodes_count != 0) { - wmove (show_pad,4,40);wprintw (show_pad,"%2.2f%%",100*(float) super->s_free_inodes_count/ (float) super->s_inodes_count); + if (ext2fs_get_inodes_count(super) != 0) { + wmove(show_pad, 4, 40); wprintw(show_pad, "%2.2f%%", + 100*(float) ext2fs_get_free_inodes_count(super)/ + (float) ext2fs_get_inodes_count(super); } wmove (show_pad,6,40); diff --git a/lib/e2p/ls.c b/lib/e2p/ls.c index a7586e09..365a8ac4 100644 --- a/lib/e2p/ls.c +++ b/lib/e2p/ls.c @@ -269,14 +269,17 @@ void list_super2(struct ext2_super_block * sb, FILE *f) str = e2p_os2string(sb->s_creator_os); fprintf(f, "Filesystem OS type: %s\n", str); free(str); - fprintf(f, "Inode count: %u\n", sb->s_inodes_count); + fprintf(f, "Inode count: %lu\n", + ext2fs_get_inodes_count(sb)); fprintf(f, "Block count: %llu\n", e2p_blocks_count(sb)); fprintf(f, "Reserved block count: %llu\n", e2p_r_blocks_count(sb)); if (sb->s_overhead_blocks) fprintf(f, "Overhead blocks: %u\n", sb->s_overhead_blocks); - fprintf(f, "Free blocks: %llu\n", e2p_free_blocks_count(sb)); - fprintf(f, "Free inodes: %u\n", sb->s_free_inodes_count); + fprintf(f, "Free blocks: %llu\n", + e2p_free_blocks_count(sb)); + fprintf(f, "Free inodes: %lu\n", + ext2fs_get_free_inodes_count(sb)); fprintf(f, "First block: %u\n", sb->s_first_data_block); fprintf(f, "Block size: %u\n", EXT2_BLOCK_SIZE(sb)); if (ext2fs_has_feature_bigalloc(sb)) @@ -374,9 +377,9 @@ void list_super2(struct ext2_super_block * sb, FILE *f) if (sb->s_journal_dev) fprintf(f, "Journal device: 0x%04x\n", sb->s_journal_dev); - if (sb->s_last_orphan) + if (ext2fs_get_last_orphan(sb)) fprintf(f, "First orphan inode: %u\n", - sb->s_last_orphan); + ext2fs_get_last_orphan(sb)); if (ext2fs_has_feature_dir_index(sb) || sb->s_def_hash_version) fprintf(f, "Default directory hash: %s\n", @@ -424,7 +427,7 @@ void list_super2(struct ext2_super_block * sb, FILE *f) sizeof(sb->s_first_error_func)); fprintf(f, "First error function: %s\n", buf); fprintf(f, "First error line #: %u\n", - sb->s_first_error_line); + ext2fs_get_first_error_ino(sb)); fprintf(f, "First error inode #: %u\n", sb->s_first_error_ino); fprintf(f, "First error block #: %llu\n", @@ -440,7 +443,7 @@ void list_super2(struct ext2_super_block * sb, FILE *f) fprintf(f, "Last error line #: %u\n", sb->s_last_error_line); fprintf(f, "Last error inode #: %u\n", - sb->s_last_error_ino); + ext2fs_get_last_error_ino(sb)); fprintf(f, "Last error block #: %llu\n", sb->s_last_error_block); } diff --git a/lib/ext2fs/alloc.c b/lib/ext2fs/alloc.c index 3fd92167..e4ef9061 100644 --- a/lib/ext2fs/alloc.c +++ b/lib/ext2fs/alloc.c @@ -107,7 +107,7 @@ errcode_t ext2fs_new_inode(ext2_filsys fs, ext2_ino_t dir, } if (start_inode < EXT2_FIRST_INODE(fs->super)) start_inode = EXT2_FIRST_INODE(fs->super); - if (start_inode > fs->super->s_inodes_count) + if (start_inode > ext2fs_get_inodes_count(fs->super)) return EXT2_ET_INODE_ALLOC_FAIL; i = start_inode; do { @@ -118,8 +118,8 @@ errcode_t ext2fs_new_inode(ext2_filsys fs, ext2_ino_t dir, upto = i + (EXT2_INODES_PER_GROUP(fs->super) - ino_in_group); if (i < start_inode && upto >= start_inode) upto = start_inode - 1; - if (upto > fs->super->s_inodes_count) - upto = fs->super->s_inodes_count; + if (upto > ext2fs_get_inodes_count(fs->super)) + upto = ext2fs_get_inodes_count(fs->super); retval = ext2fs_find_first_zero_inode_bitmap2(map, i, upto, &first_zero); @@ -130,7 +130,7 @@ errcode_t ext2fs_new_inode(ext2_filsys fs, ext2_ino_t dir, if (retval != ENOENT) return EXT2_ET_INODE_ALLOC_FAIL; i = upto + 1; - if (i > fs->super->s_inodes_count) + if (i > ext2fs_get_inodes_count(fs->super)) i = EXT2_FIRST_INODE(fs->super); } while (i != start_inode); diff --git a/lib/ext2fs/alloc_stats.c b/lib/ext2fs/alloc_stats.c index 3949f618..cb5f9122 100644 --- a/lib/ext2fs/alloc_stats.c +++ b/lib/ext2fs/alloc_stats.c @@ -20,7 +20,7 @@ void ext2fs_inode_alloc_stats2(ext2_filsys fs, ext2_ino_t ino, { int group = ext2fs_group_of_ino(fs, ino); - if (ino > fs->super->s_inodes_count) { + if (ino > ext2fs_get_inodes_count(fs->super)) { #ifndef OMIT_COM_ERR com_err("ext2fs_inode_alloc_stats2", 0, "Illegal inode number: %lu", (unsigned long) ino); @@ -48,7 +48,9 @@ void ext2fs_inode_alloc_stats2(ext2_filsys fs, ext2_ino_t ino, ext2fs_group_desc_csum_set(fs, group); } - fs->super->s_free_inodes_count -= inuse; + ext2fs_set_free_inodes_count(fs->super, + ext2fs_get_free_inodes_count(fs->super) - + inuse); ext2fs_mark_super_dirty(fs); ext2fs_mark_ib_dirty(fs); } diff --git a/lib/ext2fs/bitmaps.c b/lib/ext2fs/bitmaps.c index 84021917..bbfab1ae 100644 --- a/lib/ext2fs/bitmaps.c +++ b/lib/ext2fs/bitmaps.c @@ -61,7 +61,7 @@ errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs, fs->write_bitmaps = ext2fs_write_bitmaps; start = 1; - end = fs->super->s_inodes_count; + end = ext2fs_get_inodes_count(fs->super); real_end = (EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count); /* Are we permitted to use new-style bitmaps? */ diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h index fbe4398f..2a546acc 100644 --- a/lib/ext2fs/ext2fs.h +++ b/lib/ext2fs/ext2fs.h @@ -2048,6 +2048,43 @@ ext2fs_const_inode(const struct ext2_inode_large * large_inode) return (const struct ext2_inode *) large_inode; } +/* + * ext2fs_set_inodes_count + * ext2fs_get_inodes_count + * ext2fs_set_free_inodes_count + * ext2fs_get_free_inodes_count + * ext2fs_inc_free_inodes_count + * ext2fs_set_last_orphan + * ext2fs_get_last_orphan + * ext2fs_set_first_error_ino + * ext2fs_get_first_error_ino + * ext2fs_set_last_error_ino + * ext2fs_get_last_error_ino + */ +#define EXT2FS_SB_VALUES(name) \ +static inline unsigned long ext2fs_get_##name(struct ext2_super_block *sb) \ +{ \ + unsigned long value = sb->s_##name; \ + return value; \ +} \ +static inline void ext2fs_set_##name(struct ext2_super_block *sb,\ + unsigned long val) \ +{ \ + sb->s_##name = val; \ +} +EXT2FS_SB_VALUES(inodes_count) +EXT2FS_SB_VALUES(free_inodes_count) +EXT2FS_SB_VALUES(last_orphan) +EXT2FS_SB_VALUES(first_error_ino) +EXT2FS_SB_VALUES(last_error_ino) + +static inline void ext2fs_inc_free_inodes_count(struct ext2_super_block *sb) +{ + __u64 val = ext2fs_get_free_inodes_count(sb); + + ext2fs_set_free_inodes_count(sb, ++val); +} + #undef _INLINE_ #endif diff --git a/lib/ext2fs/extent.c b/lib/ext2fs/extent.c index a9cdae79..7d14da67 100644 --- a/lib/ext2fs/extent.c +++ b/lib/ext2fs/extent.c @@ -226,7 +226,7 @@ errcode_t ext2fs_extent_open2(ext2_filsys fs, ext2_ino_t ino, EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); if (!inode) - if ((ino == 0) || (ino > fs->super->s_inodes_count)) + if ((ino == 0) || (ino > ext2fs_get_inodes_count(fs->super))) return EXT2_ET_BAD_INODE_NUM; retval = ext2fs_get_mem(sizeof(struct ext2_extent_handle), &handle); diff --git a/lib/ext2fs/gen_bitmap64.c b/lib/ext2fs/gen_bitmap64.c index 3fc73498..4c676f23 100644 --- a/lib/ext2fs/gen_bitmap64.c +++ b/lib/ext2fs/gen_bitmap64.c @@ -110,7 +110,8 @@ errcode_t ext2fs_alloc_generic_bmap(ext2_filsys fs, errcode_t magic, break; case EXT2FS_BMAP64_AUTODIR: retval = ext2fs_get_num_dirs(fs, &num_dirs); - if (retval || num_dirs > (fs->super->s_inodes_count / 320)) + if (retval || + num_dirs > (ext2fs_get_inodes_count(fs->super) / 320)) ops = &ext2fs_blkmap64_bitarray; else ops = &ext2fs_blkmap64_rbtree; diff --git a/lib/ext2fs/get_num_dirs.c b/lib/ext2fs/get_num_dirs.c index f5644f8e..552ac477 100644 --- a/lib/ext2fs/get_num_dirs.c +++ b/lib/ext2fs/get_num_dirs.c @@ -40,8 +40,8 @@ errcode_t ext2fs_get_num_dirs(ext2_filsys fs, ext2_ino_t *ret_num_dirs) else num_dirs += ext2fs_bg_used_dirs_count(fs, i); } - if (num_dirs > fs->super->s_inodes_count) - num_dirs = fs->super->s_inodes_count; + if (num_dirs > ext2fs_get_inodes_count(fs->super)) + num_dirs = ext2fs_get_inodes_count(fs->super); *ret_num_dirs = num_dirs; diff --git a/lib/ext2fs/icount.c b/lib/ext2fs/icount.c index d7de19fe..e652a0ad 100644 --- a/lib/ext2fs/icount.c +++ b/lib/ext2fs/icount.c @@ -112,7 +112,7 @@ static errcode_t alloc_icount(ext2_filsys fs, int flags, ext2_icount_t *ret) return retval; memset(icount, 0, sizeof(struct ext2_icount)); icount->magic = EXT2_ET_MAGIC_ICOUNT; - icount->num_inodes = fs->super->s_inodes_count; + icount->num_inodes = ext2fs_get_inodes_count(fs->super); if ((flags & EXT2_ICOUNT_OPT_FULLMAP) && (flags & EXT2_ICOUNT_OPT_INCREMENT)) { @@ -235,7 +235,8 @@ errcode_t ext2fs_create_icount_tdb(ext2_filsys fs EXT2FS_NO_TDB_UNUSED, * which case the number of inodes in use approaches the ideal * value. */ - num_inodes = fs->super->s_inodes_count - fs->super->s_free_inodes_count; + num_inodes = ext2fs_get_inodes_count(fs->super) - + ext2fs_get_free_inodes_count(fs->super); icount->tdb = tdb_open(fn, num_inodes, TDB_NOLOCK | TDB_NOSYNC, O_RDWR | O_CREAT | O_TRUNC, 0600); @@ -286,7 +287,7 @@ errcode_t ext2fs_create_icount2(ext2_filsys fs, int flags, unsigned int size, retval = ext2fs_get_num_dirs(fs, &icount->size); if (retval) goto errout; - icount->size += fs->super->s_inodes_count / 50; + icount->size += ext2fs_get_inodes_count(fs->super) / 50; } bytes = (size_t) (icount->size * sizeof(struct ext2_icount_el)); diff --git a/lib/ext2fs/initialize.c b/lib/ext2fs/initialize.c index 32f43210..1447f8a4 100644 --- a/lib/ext2fs/initialize.c +++ b/lib/ext2fs/initialize.c @@ -285,16 +285,19 @@ retry: if (ext2fs_has_feature_64bit(super) && (ext2fs_blocks_count(super) / i) > (1ULL << 32)) - set_field(s_inodes_count, ~0U); + ext2fs_set_inodes_count(super, ext2fs_get_inodes_count(param) ? + ext2fs_get_inodes_count(param) : ~0U); else - set_field(s_inodes_count, ext2fs_blocks_count(super) / i); + ext2fs_set_inodes_count(super, ext2fs_get_inodes_count(param) ? + ext2fs_get_inodes_count(param) : + ext2fs_blocks_count(super) / i); /* * Make sure we have at least EXT2_FIRST_INO + 1 inodes, so * that we have enough inodes for the filesystem(!) */ - if (super->s_inodes_count < EXT2_FIRST_INODE(super)+1) - super->s_inodes_count = EXT2_FIRST_INODE(super)+1; + if (ext2fs_get_inodes_count(super) < EXT2_FIRST_INODE(super) + 1) + ext2fs_set_inodes_count(super, EXT2_FIRST_INODE(super) + 1); /* * There should be at least as many inodes as the user @@ -302,7 +305,8 @@ retry: * should be. But make sure that we don't allocate more than * one bitmap's worth of inodes each group. */ - ipg = ext2fs_div_ceil(super->s_inodes_count, fs->group_desc_count); + ipg = ext2fs_div_ceil(ext2fs_get_inodes_count(super), + fs->group_desc_count); if (ipg > fs->blocksize * 8) { if (!bigalloc_flag && super->s_blocks_per_group >= 256) { /* Try again with slightly different parameters */ @@ -355,9 +359,9 @@ ipg_retry: ipg--; goto ipg_retry; } - super->s_inodes_count = super->s_inodes_per_group * - fs->group_desc_count; - super->s_free_inodes_count = super->s_inodes_count; + ext2fs_set_inodes_count(super, super->s_inodes_per_group * + fs->group_desc_count); + ext2fs_set_free_inodes_count(super, ext2fs_get_inodes_count(super)); /* * check the number of reserved group descriptor table blocks diff --git a/lib/ext2fs/inline_data.c b/lib/ext2fs/inline_data.c index 684972b3..8afbd704 100644 --- a/lib/ext2fs/inline_data.c +++ b/lib/ext2fs/inline_data.c @@ -784,7 +784,7 @@ int main(int argc, char *argv[]) memset(¶m, 0, sizeof(param)); ext2fs_blocks_count_set(¶m, 32768); - param.s_inodes_count = 100; + ext2fs_set_inodes_count(¶m, 100); param.s_feature_incompat |= EXT4_FEATURE_INCOMPAT_INLINE_DATA; param.s_rev_level = EXT2_DYNAMIC_REV; diff --git a/lib/ext2fs/inode.c b/lib/ext2fs/inode.c index ad01a9fc..182e9819 100644 --- a/lib/ext2fs/inode.c +++ b/lib/ext2fs/inode.c @@ -752,7 +752,7 @@ errcode_t ext2fs_read_inode_full(ext2_filsys fs, ext2_ino_t ino, if (retval != EXT2_ET_CALLBACK_NOTHANDLED) return retval; } - if ((ino == 0) || (ino > fs->super->s_inodes_count)) + if ((ino == 0) || (ino > ext2fs_get_inodes_count(fs->super))) return EXT2_ET_BAD_INODE_NUM; /* Create inode cache if not present */ if (!fs->icache) { @@ -867,7 +867,7 @@ errcode_t ext2fs_write_inode_full(ext2_filsys fs, ext2_ino_t ino, return retval; } - if ((ino == 0) || (ino > fs->super->s_inodes_count)) + if ((ino == 0) || (ino > ext2fs_get_inodes_count(fs->super))) return EXT2_ET_BAD_INODE_NUM; /* Prepare our shadow buffer for read/modify/byteswap/write */ @@ -1022,7 +1022,7 @@ errcode_t ext2fs_get_blocks(ext2_filsys fs, ext2_ino_t ino, blk_t *blocks) EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); - if (ino > fs->super->s_inodes_count) + if (ino > ext2fs_get_inodes_count(fs->super)) return EXT2_ET_BAD_INODE_NUM; if (fs->get_blocks) { @@ -1044,7 +1044,7 @@ errcode_t ext2fs_check_directory(ext2_filsys fs, ext2_ino_t ino) EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); - if (ino > fs->super->s_inodes_count) + if (ino > ext2fs_get_inodes_count(fs->super)) return EXT2_ET_BAD_INODE_NUM; if (fs->check_directory) { diff --git a/lib/ext2fs/openfs.c b/lib/ext2fs/openfs.c index f74cd245..7514591f 100644 --- a/lib/ext2fs/openfs.c +++ b/lib/ext2fs/openfs.c @@ -381,7 +381,7 @@ errcode_t ext2fs_open2(const char *name, const char *io_options, } fs->group_desc_count = groups_cnt; if (fs->group_desc_count * EXT2_INODES_PER_GROUP(fs->super) != - fs->super->s_inodes_count) { + ext2fs_get_inodes_count(fs->super)) { retval = EXT2_ET_CORRUPT_SUPERBLOCK; goto cleanup; } diff --git a/lib/ext2fs/rw_bitmaps.c b/lib/ext2fs/rw_bitmaps.c index ae593d49..66c8ee69 100644 --- a/lib/ext2fs/rw_bitmaps.c +++ b/lib/ext2fs/rw_bitmaps.c @@ -252,7 +252,7 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block) if (fs->flags & EXT2_FLAG_IMAGE_FILE) { blk = (fs->image_header->offset_inodemap / fs->blocksize); - ino_cnt = fs->super->s_inodes_count; + ino_cnt = ext2fs_get_inodes_count(fs->super); while (inode_nbytes > 0) { retval = io_channel_read_blk64(fs->image_io, blk++, 1, inode_bitmap); diff --git a/lib/ext2fs/tst_bitmaps.c b/lib/ext2fs/tst_bitmaps.c index 574fb7a7..5ca4c680 100644 --- a/lib/ext2fs/tst_bitmaps.c +++ b/lib/ext2fs/tst_bitmaps.c @@ -158,7 +158,7 @@ static void setup_filesystem(const char *name, memset(¶m, 0, sizeof(param)); ext2fs_blocks_count_set(¶m, blocks); - param.s_inodes_count = inodes; + ext2fs_set_inodes_count(¶m, inodes); retval = ext2fs_initialize("test fs", flags, ¶m, test_io_manager, &test_fs); @@ -275,9 +275,10 @@ void dump_inode_bitmap_cmd(int argc, char **argv) return; printf("inode bitmap: "); - dump_bitmap(test_fs->inode_map, 1, test_fs->super->s_inodes_count); + dump_bitmap(test_fs->inode_map, 1, + ext2fs_get_inodes_count(test_fs->super)); } - + void dump_block_bitmap_cmd(int argc, char **argv) { if (check_fs_open(argv[0])) diff --git a/lib/ext2fs/tst_iscan.c b/lib/ext2fs/tst_iscan.c index 70bfbecc..6c9ceaf6 100644 --- a/lib/ext2fs/tst_iscan.c +++ b/lib/ext2fs/tst_iscan.c @@ -200,7 +200,7 @@ static void check_map(void) } } printf("Bad inodes: "); - for (i=1; i <= test_fs->super->s_inodes_count; i++) { + for (i = 1; i <= ext2fs_get_inodes_count(test_fs->super); i++) { if (ext2fs_test_inode_bitmap2(bad_inode_map, i)) { if (first) first = 0; diff --git a/misc/findsuper.c b/misc/findsuper.c index ff20b988..e73e92a5 100644 --- a/misc/findsuper.c +++ b/misc/findsuper.c @@ -226,9 +226,11 @@ int main(int argc, char *argv[]) WHY("free_blocks_count > blocks_count\n (%u > %u)\n", ext2fs_free_blocks_count(&ext2), ext2fs_blocks_count(&ext2)); - if (ext2.s_free_inodes_count > ext2.s_inodes_count) - WHY("free_inodes_count > inodes_count (%u > %u)\n", - ext2.s_free_inodes_count, ext2.s_inodes_count); + if (ext2fs_get_free_inodes_count(&ext2) > + ext2fs_get_inodes_count(&ext2)) + WHY("free_inodes_count > inodes_count (%lu > %lu)\n", + ext2fs_get_free_inodes_count(&ext2), + ext2fs_get_inodes_count(&ext); if (ext2.s_mkfs_time != 0) tm = ext2.s_mkfs_time; diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c index 9feafd72..24023400 100644 --- a/misc/fuse2fs.c +++ b/misc/fuse2fs.c @@ -2368,9 +2368,9 @@ static int op_statfs(const char *path EXT2FS_ATTR((unused)), buf->f_bavail = 0; else buf->f_bavail = free - reserved; - buf->f_files = fs->super->s_inodes_count; - buf->f_ffree = fs->super->s_free_inodes_count; - buf->f_favail = fs->super->s_free_inodes_count; + buf->f_files = ext2fs_get_inodes_count(fs->super); + buf->f_ffree = ext2fs_get_free_inodes_count(fs->super); + buf->f_favail = ext2fs_get_free_inodes_count(fs->super); f = (uint64_t *)fs->super->s_uuid; fsid = *f; f++; @@ -3822,7 +3822,7 @@ int main(int argc, char *argv[]) global_fs->super->s_checkinterval) <= time(0)) printf("%s", _("Warning: Check time reached; running e2fsck " "is recommended.\n")); - if (global_fs->super->s_last_orphan) + if (ext2fs_get_last_orphan(global_fs->super)) printf("%s", _("Orphans detected; running e2fsck is recommended.\n")); @@ -3952,14 +3952,14 @@ no_translation: /* Make a note in the error log */ get_now(&now); fs->super->s_last_error_time = now.tv_sec; - fs->super->s_last_error_ino = ino; + ext2fs_set_last_error_ino(fs->super, ino); fs->super->s_last_error_line = line; fs->super->s_last_error_block = err; /* Yeah... */ strncpy((char *)fs->super->s_last_error_func, file, sizeof(fs->super->s_last_error_func)); if (fs->super->s_first_error_time == 0) { fs->super->s_first_error_time = now.tv_sec; - fs->super->s_first_error_ino = ino; + ext2fs_set_first_error_ino(fs->super, ino); fs->super->s_first_error_line = line; fs->super->s_first_error_block = err; strncpy((char *)fs->super->s_first_error_func, file, diff --git a/misc/mke2fs.c b/misc/mke2fs.c index 4d8593f7..8edb7546 100644 --- a/misc/mke2fs.c +++ b/misc/mke2fs.c @@ -654,9 +654,9 @@ static void show_stats(ext2_filsys fs) if (!verbose) { printf(_("Creating filesystem with %llu %dk blocks and " - "%u inodes\n"), + "%lu inodes\n"), ext2fs_blocks_count(s), fs->blocksize >> 10, - s->s_inodes_count); + ext2fs_get_inodes_count(s)); goto skip_details; } @@ -682,7 +682,7 @@ static void show_stats(ext2_filsys fs) s->s_log_cluster_size); printf(_("Stride=%u blocks, Stripe width=%u blocks\n"), s->s_raid_stride, s->s_raid_stripe_width); - printf(_("%u inodes, %llu blocks\n"), s->s_inodes_count, + printf(_("%lu inodes, %llu blocks\n"), ext2fs_get_inodes_count(s), ext2fs_blocks_count(s)); printf(_("%llu blocks (%2.2f%%) reserved for the super user\n"), ext2fs_r_blocks_count(s), @@ -2489,7 +2489,7 @@ profile_error: "specify higher inode_ratio (-i)\n\t" "or lower inode count (-N).\n"), inode_size ? inode_size : EXT2_GOOD_OLD_INODE_SIZE, - fs_param.s_inodes_count, + ext2fs_get_inodes_count(&fs_param), (unsigned long long) ext2fs_blocks_count(&fs_param)); exit(1); } diff --git a/misc/tune2fs.c b/misc/tune2fs.c index 44dd41a5..421c1d98 100644 --- a/misc/tune2fs.c +++ b/misc/tune2fs.c @@ -2614,21 +2614,22 @@ static errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs) group = 0; /* Protect loop from wrap-around if s_inodes_count maxed */ - for (ino = 1; ino <= fs->super->s_inodes_count && ino > 0; ino++) { + for (ino = 1; + ino <= ext2fs_get_inodes_count(fs->super) && ino > 0; ino++) { if (!ext2fs_fast_test_inode_bitmap2(fs->inode_map, ino)) { group_free++; total_free++; } count++; if ((count == fs->super->s_inodes_per_group) || - (ino == fs->super->s_inodes_count)) { + (ino == ext2fs_get_inodes_count(fs->super))) { ext2fs_bg_free_inodes_count_set(fs, group++, group_free); count = 0; group_free = 0; } } - fs->super->s_free_inodes_count = total_free; + ext2fs_set_free_inodes_count(fs->super, total_free); ext2fs_mark_super_dirty(fs); return 0; } diff --git a/resize/main.c b/resize/main.c index ba6bb6b1..79523803 100644 --- a/resize/main.c +++ b/resize/main.c @@ -441,7 +441,8 @@ int main (int argc, char ** argv) checkit = 1; if ((fs->super->s_free_blocks_count > fs->super->s_blocks_count) || - (fs->super->s_free_inodes_count > fs->super->s_inodes_count)) + (ext2fs_get_free_inodes_count(fs->super) > + ext2fs_get_inodes_count(fs->super))) checkit = 1; if (checkit) { diff --git a/resize/resize2fs.c b/resize/resize2fs.c index 0bd325ba..ec13436c 100644 --- a/resize/resize2fs.c +++ b/resize/resize2fs.c @@ -760,8 +760,8 @@ retry: new_inodes, ~0U); return EXT2_ET_TOO_MANY_INODES; } - fs->super->s_inodes_count = fs->super->s_inodes_per_group * - fs->group_desc_count; + ext2fs_set_inodes_count(fs->super, fs->super->s_inodes_per_group * + fs->group_desc_count); /* * Adjust the number of free blocks @@ -788,8 +788,8 @@ retry: /* * Adjust the bitmaps for size */ - retval = ext2fs_resize_inode_bitmap2(fs->super->s_inodes_count, - fs->super->s_inodes_count, + retval = ext2fs_resize_inode_bitmap2(ext2fs_get_inodes_count(fs->super), + ext2fs_get_inodes_count(fs->super), fs->inode_map); if (retval) goto errout; @@ -987,8 +987,9 @@ retry: numblocks -= adjblocks; ext2fs_free_blocks_count_set(fs->super, ext2fs_free_blocks_count(fs->super) - adjblocks); - fs->super->s_free_inodes_count += - fs->super->s_inodes_per_group; + ext2fs_set_free_inodes_count(fs->super, + ext2fs_get_free_inodes_count(fs->super) + + fs->super->s_inodes_per_group); ext2fs_bg_free_blocks_count_set(fs, i, numblocks); ext2fs_bg_free_inodes_count_set(fs, i, fs->super->s_inodes_per_group); @@ -1046,9 +1047,9 @@ static errcode_t adjust_superblock(ext2_resize_t rfs, blk64_t new_size) /* * Check to make sure there are enough inodes */ - if ((rfs->old_fs->super->s_inodes_count - - rfs->old_fs->super->s_free_inodes_count) > - rfs->new_fs->super->s_inodes_count) { + if ((ext2fs_get_inodes_count(rfs->old_fs->super) - + ext2fs_get_free_inodes_count(rfs->old_fs->super)) > + ext2fs_get_inodes_count(rfs->new_fs->super)) { retval = ENOSPC; goto errout; } @@ -2866,7 +2867,8 @@ static errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs) /* Protect loop from wrap-around if s_inodes_count maxed */ uninit = ext2fs_bg_flags_test(fs, group, EXT2_BG_INODE_UNINIT); - for (ino = 1; ino <= fs->super->s_inodes_count && ino > 0; ino++) { + for (ino = 1; + ino <= ext2fs_get_inodes_count(fs->super) && ino > 0; ino++) { if (uninit || !ext2fs_fast_test_inode_bitmap2(fs->inode_map, ino)) { group_free++; @@ -2874,7 +2876,7 @@ static errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs) } count++; if ((count == fs->super->s_inodes_per_group) || - (ino == fs->super->s_inodes_count)) { + (ino == ext2fs_get_inodes_count(fs->super))) { ext2fs_bg_free_inodes_count_set(fs, group, group_free); ext2fs_group_desc_csum_set(fs, group); group++; @@ -2885,7 +2887,7 @@ static errcode_t ext2fs_calculate_summary_stats(ext2_filsys fs) uninit = ext2fs_bg_flags_test(fs, group, EXT2_BG_INODE_UNINIT); } } - fs->super->s_free_inodes_count = total_inodes_free; + ext2fs_set_free_inodes_count(fs->super, total_inodes_free); ext2fs_mark_super_dirty(fs); return 0; } @@ -2955,8 +2957,8 @@ blk64_t calculate_minimum_resize_size(ext2_filsys fs, int flags) * first figure out how many group descriptors we need to * handle the number of inodes we have */ - inode_count = fs->super->s_inodes_count - - fs->super->s_free_inodes_count; + inode_count = ext2fs_get_inodes_count(fs->super) - + ext2fs_get_free_inodes_count(fs->super); blks_needed = ext2fs_div_ceil(inode_count, fs->super->s_inodes_per_group) * (blk64_t) EXT2_BLOCKS_PER_GROUP(fs->super); diff --git a/tests/progs/test_icount.c b/tests/progs/test_icount.c index d028a601..b4dd013b 100644 --- a/tests/progs/test_icount.c +++ b/tests/progs/test_icount.c @@ -208,7 +208,7 @@ void do_dump(int argc, char **argv) if (check_icount(argv[0])) return; - for (i=1; i <= test_fs->super->s_inodes_count; i++) { + for (i = 1; i <= ext2fs_get_inodes_count(test_fs->super); i++) { retval = ext2fs_icount_fetch(test_icount, i, &count); if (retval) { com_err(argv[0], retval, @@ -312,7 +312,7 @@ int main(int argc, char **argv) */ memset(¶m, 0, sizeof(struct ext2_super_block)); ext2fs_blocks_count_set(¶m, 80000); - param.s_inodes_count = 20000; + ext2fs_set_inodes_count(¶m, 20000); retval = ext2fs_initialize("/dev/null", 0, ¶m, unix_io_manager, &test_fs); if (retval) { From patchwork Fri May 4 07:09:22 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artem Blagodarenko X-Patchwork-Id: 908553 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="AeNgMR1p"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40cjnn1sgLz9s3Z for ; Fri, 4 May 2018 17:10:05 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751469AbeEDHKE (ORCPT ); Fri, 4 May 2018 03:10:04 -0400 Received: from mail-lf0-f66.google.com ([209.85.215.66]:36193 "EHLO mail-lf0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751360AbeEDHJr (ORCPT ); Fri, 4 May 2018 03:09:47 -0400 Received: by mail-lf0-f66.google.com with SMTP id w8-v6so29489912lfe.3 for ; Fri, 04 May 2018 00:09:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=+c7RYUcVHzf+jRvf+AdjVqSgAkElYIobcJDshzKuaTM=; b=AeNgMR1pG2Y9cO8Yvp4nddCVyrv8NVOWZcDIrr6DVUy5neG5fksygB8LAAo1MEsZ/w NEnWMyafb3zQrevio9VB2aL70ufdzRtfEVki40zd8TNGmOB/6tJSl9fUP+G1hBgWepud mQn7D8oB91RNcb4VJkjqwFEgkgCy9n8kaTryQskN1Oz7R4eY0OMJ3Ti9ii2EkjiUgQLM B+JFSBB3XNBAvUj8rBUT2gwRYd6atHnmlh5kXa2w5R87sKK0AkKzKDHadSOMgruFWUYE CuTMZevOeOW0/i54kgsZ570cWukLdGZeluxFz4Bq2FvD4lRto1S8qPqZqE6U3hEwLFiX Cuew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=+c7RYUcVHzf+jRvf+AdjVqSgAkElYIobcJDshzKuaTM=; b=EKUmP+S5RfFih7F6y3fqRYUElwFgUzzIiJXAAWk2anYnGT8NSevux3KAedAMdq2hxa mPT25H722Utj/MWY/eBKjfZVMoexEWyuVQcVKLdFsQL9fpMiEk3/QcezKGiZxEibFru2 SqPhfzoDzefnGb15H8xDyv/QRSkZ5LoaN8PupOn/gqWijFAxclcsCXpG2EApOIOsb6he okxpEhA+grqCxbgC+7u3/AeVaxbPYGOLKxnB8xVhorHY5L39XL3v0jc4OPxo2mpJZ02P JoA+1iP/wXz74pTyB9QKaknvvZDJJtJs8yDwXgfP+QdyJarUH6Lul3d9t1wCTW9Y/nr4 QjOg== X-Gm-Message-State: ALQs6tCQKPv2to5DN64WK1ARjo3ddNu4zs4KKXj4dCUrdr7CLy6OkJXM BhDg/CySixglMu84N8Toy6lGmg== X-Google-Smtp-Source: AB8JxZqtLuBlLzi/veEEGF+GH5ISGV+5d0GH/AzCobaC+kMvnBb2pzGx7BRLksSaQfmTkKTLzRBEhg== X-Received: by 2002:a19:d514:: with SMTP id m20-v6mr15564890lfg.5.1525417784836; Fri, 04 May 2018 00:09:44 -0700 (PDT) Received: from C02TN4C6HTD6.lan ([80.72.234.202]) by smtp.gmail.com with ESMTPSA id f16-v6sm3170296lfh.94.2018.05.04.00.09.43 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 04 May 2018 00:09:44 -0700 (PDT) From: c17828 X-Google-Original-From: c17828 To: linux-ext4@vger.kernel.org Cc: adilger.kernel@dilger.ca, Artem Blagodarenko Subject: [PATCH v4 6/7] ext2fs: add EXT4_FEATURE_INCOMPAT_64INODE support Date: Fri, 4 May 2018 10:09:22 +0300 Message-Id: <20180504070923.45140-7-c17828@cray.com> X-Mailer: git-send-email 2.14.3 (Apple Git-98) In-Reply-To: <20180504070923.45140-1-c17828@cray.com> References: <20180504070923.45140-1-c17828@cray.com> Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org From: Artem Blagodarenko Inodes count and free inodes count should be 64 bit long. This patch also changes s_inodes_count* to 64 bit Lustre-bug: https://jira.hpdd.intel.com/browse/LU-9309 Signed-off-by: Artem Blagodarenko --- debugfs/debugfs.c | 2 +- debugfs/set_fields.c | 3 ++- e2fsck/dirinfo.c | 28 ++++++++++++++-------------- e2fsck/e2fsck.h | 22 +++++++++++----------- e2fsck/pass2.c | 11 ++++++++--- e2fsck/pass3.c | 2 +- e2fsck/problem.c | 5 +++++ e2fsck/problem.h | 5 ++++- e2fsck/super.c | 1 + lib/e2p/feature.c | 2 ++ lib/ext2fs/ext2_fs.h | 15 +++++++++++++-- lib/ext2fs/ext2fs.h | 14 ++++++++++---- lib/ext2fs/swapfs.c | 6 ++++++ lib/ext2fs/tst_super_size.c | 8 +++++++- misc/fuse2fs.c | 8 ++++---- misc/mke2fs.c | 22 ++++++++++++++-------- misc/tune2fs.c | 3 ++- 17 files changed, 105 insertions(+), 52 deletions(-) diff --git a/debugfs/debugfs.c b/debugfs/debugfs.c index 4a533b53..a80cf668 100644 --- a/debugfs/debugfs.c +++ b/debugfs/debugfs.c @@ -829,7 +829,7 @@ void internal_dump_inode(FILE *out, const char *prefix, else if (LINUX_S_ISFIFO(inode->i_mode)) i_type = "FIFO"; else if (LINUX_S_ISSOCK(inode->i_mode)) i_type = "socket"; else i_type = "bad type"; - fprintf(out, "%sInode: %u Type: %s ", prefix, inode_num, i_type); + fprintf(out, "%sInode: %lu Type: %s ", prefix, inode_num, i_type); fprintf(out, "%sMode: 0%03o Flags: 0x%x\n", prefix, inode->i_mode & 07777, inode->i_flags); if (is_large_inode && large_inode->i_extra_isize >= 24) { diff --git a/debugfs/set_fields.c b/debugfs/set_fields.c index 8dfbba9c..bfab7ff8 100644 --- a/debugfs/set_fields.c +++ b/debugfs/set_fields.c @@ -79,7 +79,8 @@ static errcode_t parse_mmp_clear(struct field_set_info *info, char *field, #pragma GCC diagnostic ignored "-Wmissing-field-initializers" static struct field_set_info super_fields[] = { - { "inodes_count", &set_sb.s_inodes_count, NULL, 4, parse_uint }, + { "inodes_count", &set_sb.s_inodes_count, &set_sb.s_inodes_count_hi, + 4, parse_uint }, { "blocks_count", &set_sb.s_blocks_count, &set_sb.s_blocks_count_hi, 4, parse_uint }, { "r_blocks_count", &set_sb.s_r_blocks_count, diff --git a/e2fsck/dirinfo.c b/e2fsck/dirinfo.c index b29f7e92..e8f1f26d 100644 --- a/e2fsck/dirinfo.c +++ b/e2fsck/dirinfo.c @@ -35,8 +35,8 @@ struct dir_info_iter { }; struct dir_info_ent { - ext2_ino_t dotdot; /* Parent according to '..' */ - ext2_ino_t parent; /* Parent according to treewalk */ + ext2_ino64_t dotdot; /* Parent according to '..' */ + ext2_ino64_t parent; /* Parent according to treewalk */ }; @@ -201,7 +201,7 @@ void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent) * get_dir_info() --- given an inode number, try to find the directory * information entry for it. */ -static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino) +static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino64_t ino) { struct dir_info_db *db = ctx->dir_info; int low, high, mid; @@ -210,7 +210,7 @@ static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino) return 0; #ifdef DIRINFO_DEBUG - printf("e2fsck_get_dir_info %d...", ino); + printf("e2fsck_get_dir_info %ld...", ino); #endif #ifdef CONFIG_TDB @@ -220,7 +220,7 @@ static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino) struct dir_info_ent *buf; key.dptr = (unsigned char *) &ino; - key.dsize = sizeof(ext2_ino_t); + key.dsize = sizeof(ext2_ino64_t); data = tdb_fetch(db->tdb, key); if (!data.dptr) { @@ -235,7 +235,7 @@ static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino) ret_dir_info.dotdot = buf->dotdot; ret_dir_info.parent = buf->parent; #ifdef DIRINFO_DEBUG - printf("(%d,%d,%d)\n", ino, buf->dotdot, buf->parent); + printf("(%ld,%d,%d)\n", ino, buf->dotdot, buf->parent); #endif free(data.dptr); return &ret_dir_info; @@ -422,8 +422,8 @@ struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, struct dir_info_iter *iter) * This function only sets the parent pointer, and requires that * dirinfo structure has already been created. */ -int e2fsck_dir_info_set_parent(e2fsck_t ctx, ext2_ino_t ino, - ext2_ino_t parent) +int e2fsck_dir_info_set_parent(e2fsck_t ctx, ext2_ino64_t ino, + ext2_ino64_t parent) { struct dir_info *p; @@ -439,8 +439,8 @@ int e2fsck_dir_info_set_parent(e2fsck_t ctx, ext2_ino_t ino, * This function only sets the dot dot pointer, and requires that * dirinfo structure has already been created. */ -int e2fsck_dir_info_set_dotdot(e2fsck_t ctx, ext2_ino_t ino, - ext2_ino_t dotdot) +int e2fsck_dir_info_set_dotdot(e2fsck_t ctx, ext2_ino64_t ino, + ext2_ino64_t dotdot) { struct dir_info *p; @@ -456,8 +456,8 @@ int e2fsck_dir_info_set_dotdot(e2fsck_t ctx, ext2_ino_t ino, * This function only sets the parent pointer, and requires that * dirinfo structure has already been created. */ -int e2fsck_dir_info_get_parent(e2fsck_t ctx, ext2_ino_t ino, - ext2_ino_t *parent) +int e2fsck_dir_info_get_parent(e2fsck_t ctx, ext2_ino64_t ino, + ext2_ino64_t *parent) { struct dir_info *p; @@ -472,8 +472,8 @@ int e2fsck_dir_info_get_parent(e2fsck_t ctx, ext2_ino_t ino, * This function only sets the dot dot pointer, and requires that * dirinfo structure has already been created. */ -int e2fsck_dir_info_get_dotdot(e2fsck_t ctx, ext2_ino_t ino, - ext2_ino_t *dotdot) +int e2fsck_dir_info_get_dotdot(e2fsck_t ctx, ext2_ino64_t ino, + ext2_ino64_t *dotdot) { struct dir_info *p; diff --git a/e2fsck/e2fsck.h b/e2fsck/e2fsck.h index 9eee4bc2..2e038fbe 100644 --- a/e2fsck/e2fsck.h +++ b/e2fsck/e2fsck.h @@ -93,9 +93,9 @@ * directory information. */ struct dir_info { - ext2_ino_t ino; /* Inode number */ - ext2_ino_t dotdot; /* Parent according to '..' */ - ext2_ino_t parent; /* Parent according to treewalk */ + ext2_ino64_t ino; /* Inode number */ + ext2_ino64_t dotdot; /* Parent according to '..' */ + ext2_ino64_t parent; /* Parent according to treewalk */ }; @@ -460,14 +460,14 @@ extern struct dir_info_iter *e2fsck_dir_info_iter_begin(e2fsck_t ctx); extern struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, struct dir_info_iter *); extern void e2fsck_dir_info_iter_end(e2fsck_t ctx, struct dir_info_iter *); -extern int e2fsck_dir_info_set_parent(e2fsck_t ctx, ext2_ino_t ino, - ext2_ino_t parent); -extern int e2fsck_dir_info_set_dotdot(e2fsck_t ctx, ext2_ino_t ino, - ext2_ino_t dotdot); -extern int e2fsck_dir_info_get_parent(e2fsck_t ctx, ext2_ino_t ino, - ext2_ino_t *parent); -extern int e2fsck_dir_info_get_dotdot(e2fsck_t ctx, ext2_ino_t ino, - ext2_ino_t *dotdot); +extern int e2fsck_dir_info_set_parent(e2fsck_t ctx, ext2_ino64_t ino, + ext2_ino64_t parent); +extern int e2fsck_dir_info_set_dotdot(e2fsck_t ctx, ext2_ino64_t ino, + ext2_ino64_t dotdot); +extern int e2fsck_dir_info_get_parent(e2fsck_t ctx, ext2_ino64_t ino, + ext2_ino64_t *parent); +extern int e2fsck_dir_info_get_dotdot(e2fsck_t ctx, ext2_ino64_t ino, + ext2_ino64_t *dotdot); /* dx_dirinfo.c */ extern void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks); diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c index a8ccc465..ef0b97c0 100644 --- a/e2fsck/pass2.c +++ b/e2fsck/pass2.c @@ -179,7 +179,12 @@ void e2fsck_pass2(e2fsck_t ctx) if (ext2fs_has_feature_dir_index(fs->super)) ext2fs_dblist_sort2(fs->dblist, special_dir_block_cmp); - + if (ext2fs_has_feature_inode64(ctx->fs->super) && + !ext2fs_has_feature_dirdata(ctx->fs->super)) { + if (fix_problem(ctx, PR_2_FIX_DIRDATA_FEATURE, &cd.pctx)) + ctx->fs->super->s_feature_incompat |= + EXT4_FEATURE_INCOMPAT_DIRDATA; + } check_dir_func = cd.ra_entries ? check_dir_block2 : check_dir_block; cd.pctx.errcode = ext2fs_dblist_iterate2(fs->dblist, check_dir_func, &cd); @@ -995,8 +1000,8 @@ static int check_dir_block(ext2_filsys fs, int dot_state; unsigned int rec_len; blk64_t block_nr = db->blk; - ext2_ino_t ino = db->ino; - ext2_ino_t subdir_parent; + ext2_ino64_t ino = db->ino; + ext2_ino64_t subdir_parent; __u16 links; struct check_dir_struct *cd; char *buf, *ibuf; diff --git a/e2fsck/pass3.c b/e2fsck/pass3.c index 4a777213..b6bee3f8 100644 --- a/e2fsck/pass3.c +++ b/e2fsck/pass3.c @@ -284,7 +284,7 @@ static int check_directory(e2fsck_t ctx, ext2_ino_t dir, struct problem_context *pctx) { ext2_filsys fs = ctx->fs; - ext2_ino_t ino = dir, parent; + ext2_ino64_t ino = dir, parent; int loop_pass = 0, parent_count = 0; while (1) { diff --git a/e2fsck/problem.c b/e2fsck/problem.c index 2a86d528..d8620b93 100644 --- a/e2fsck/problem.c +++ b/e2fsck/problem.c @@ -1676,6 +1676,11 @@ static struct e2fsck_problem problem_table[] = { N_("@E dirdata length set incorrectly.\n"), PROMPT_CLEAR, PR_PREEN_OK }, + /* dirdata feature is needed for inode64 */ + { PR_2_FIX_DIRDATA_FEATURE, + N_("@E ino64 feature without dirdata.\n"), + PROMPT_FIX, PR_PREEN_OK }, + /* Pass 3 errors */ /* Pass 3: Checking directory connectivity */ diff --git a/e2fsck/problem.h b/e2fsck/problem.h index 05214840..c847063e 100644 --- a/e2fsck/problem.h +++ b/e2fsck/problem.h @@ -13,7 +13,7 @@ typedef __u32 problem_t; struct problem_context { errcode_t errcode; - ext2_ino_t ino, ino2, dir; + ext2_ino64_t ino, ino2, dir; struct ext2_inode *inode; struct ext2_dir_entry *dirent; blk64_t blk, blk2; @@ -1007,6 +1007,9 @@ struct problem_context { /* Entry dirdata length set incorrectly */ #define PR_2_CLEAR_DIRDATA 0x020051 +/* inode64 feature without dirdata */ +#define PR_2_FIX_DIRDATA_FEATURE 0x020052 + /* * Pass 3 errors */ diff --git a/e2fsck/super.c b/e2fsck/super.c index 20d6190c..37e5dbfc 100644 --- a/e2fsck/super.c +++ b/e2fsck/super.c @@ -1048,6 +1048,7 @@ int check_backup_super_block(e2fsck_t ctx) SUPER_DIFFERENT(s_blocks_count) || SUPER_DIFFERENT(s_blocks_count_hi) || SUPER_DIFFERENT(s_inodes_count) || + SUPER_DIFFERENT(s_inodes_count_hi) || memcmp(fs->super->s_uuid, backup_sb->s_uuid, sizeof(fs->super->s_uuid))) ret = 1; diff --git a/lib/e2p/feature.c b/lib/e2p/feature.c index b7f6c1d2..fd77dedd 100644 --- a/lib/e2p/feature.c +++ b/lib/e2p/feature.c @@ -105,6 +105,8 @@ static struct feature feature_list[] = { "inline_data"}, { E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_ENCRYPT, "encrypt"}, + { E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_INODE64, + "inode64"}, { 0, 0, 0 }, }; diff --git a/lib/ext2fs/ext2_fs.h b/lib/ext2fs/ext2_fs.h index 4681a216..9ce48321 100644 --- a/lib/ext2fs/ext2_fs.h +++ b/lib/ext2fs/ext2_fs.h @@ -737,7 +737,13 @@ struct ext2_super_block { __le32 s_lpf_ino; /* Location of the lost+found inode */ __le32 s_prj_quota_inum; /* inode for tracking project quota */ __le32 s_checksum_seed; /* crc32c(orig_uuid) if csum_seed set */ - __le32 s_reserved[98]; /* Padding to the end of the block */ + __le32 s_inodes_count_hi; /* high part of inode count */ + __le32 s_free_inodes_count_hi; /* Free inodes count */ + __le32 s_prj_quota_inum_hi; /* high part of project quota inode */ + __le32 s_last_orphan_hi; /* high part of last orphan */ + __le32 s_first_error_ino_hi; /* high part of first error ino */ + __le32 s_last_error_ino_hi; /* high part of last error ino */ + __le32 s_reserved[92]; /* Padding to the end of the block */ __u32 s_checksum; /* crc32c(superblock) */ }; @@ -827,6 +833,8 @@ struct ext2_super_block { #define EXT4_FEATURE_INCOMPAT_LARGEDIR 0x4000 /* >2GB or 3-lvl htree */ #define EXT4_FEATURE_INCOMPAT_INLINE_DATA 0x8000 /* data in inode */ #define EXT4_FEATURE_INCOMPAT_ENCRYPT 0x10000 +#define EXT4_FEATURE_INCOMPAT_INODE64 0x20000 + #define EXT4_FEATURE_COMPAT_FUNCS(name, ver, flagname) \ static inline int ext2fs_has_feature_##name(struct ext2_super_block *sb) \ @@ -918,13 +926,16 @@ EXT4_FEATURE_INCOMPAT_FUNCS(csum_seed, 4, CSUM_SEED) EXT4_FEATURE_INCOMPAT_FUNCS(largedir, 4, LARGEDIR) EXT4_FEATURE_INCOMPAT_FUNCS(inline_data, 4, INLINE_DATA) EXT4_FEATURE_INCOMPAT_FUNCS(encrypt, 4, ENCRYPT) +EXT4_FEATURE_INCOMPAT_FUNCS(inode64, 4, INODE64) + #define EXT2_FEATURE_COMPAT_SUPP 0 #define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \ EXT4_FEATURE_INCOMPAT_MMP| \ EXT4_FEATURE_INCOMPAT_LARGEDIR| \ EXT4_FEATURE_INCOMPAT_EA_INODE| \ - EXT4_FEATURE_INCOMPAT_DIRDATA) + EXT4_FEATURE_INCOMPAT_DIRDATA \ + EXT4_FEATURE_INCOMPAT_INODE64) #define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \ EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \ EXT4_FEATURE_RO_COMPAT_DIR_NLINK| \ diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h index 2a546acc..246cd52a 100644 --- a/lib/ext2fs/ext2fs.h +++ b/lib/ext2fs/ext2fs.h @@ -74,6 +74,7 @@ extern "C" { #endif /* EXT2_FLAT_INCLUDES */ typedef __u32 __bitwise ext2_ino_t; +typedef __u64 __bitwise ext2_ino64_t; typedef __u32 __bitwise blk_t; typedef __u64 __bitwise blk64_t; typedef __u32 __bitwise dgrp_t; @@ -601,6 +602,7 @@ typedef struct ext2_icount *ext2_icount_t; EXT4_FEATURE_INCOMPAT_FLEX_BG|\ EXT4_FEATURE_INCOMPAT_EA_INODE|\ EXT4_FEATURE_INCOMPAT_DIRDATA|\ + EXT4_FEATURE_INCOMPAT_INODE64|\ EXT4_LIB_INCOMPAT_MMP|\ EXT4_FEATURE_INCOMPAT_64BIT|\ EXT4_FEATURE_INCOMPAT_INLINE_DATA|\ @@ -2062,14 +2064,18 @@ ext2fs_const_inode(const struct ext2_inode_large * large_inode) * ext2fs_get_last_error_ino */ #define EXT2FS_SB_VALUES(name) \ -static inline unsigned long ext2fs_get_##name(struct ext2_super_block *sb) \ +static inline ext2_ino64_t ext2fs_get_##name(struct ext2_super_block *sb) \ { \ - unsigned long value = sb->s_##name; \ - return value; \ + ext2_ino64_t inodes_count = sb->s_##name; \ + if (ext2fs_has_feature_inode64(sb)) \ + inodes_count |= (ext2_ino64_t)sb->s_##name##_hi << 32; \ + return inodes_count; \ } \ static inline void ext2fs_set_##name(struct ext2_super_block *sb,\ - unsigned long val) \ + ext2_ino64_t val) \ { \ + if (ext2fs_has_feature_inode64(sb)) \ + sb->s_##name##_hi = (__u32)(val >> 32); \ sb->s_##name = val; \ } EXT2FS_SB_VALUES(inodes_count) diff --git a/lib/ext2fs/swapfs.c b/lib/ext2fs/swapfs.c index c1da8509..4d98286e 100644 --- a/lib/ext2fs/swapfs.c +++ b/lib/ext2fs/swapfs.c @@ -83,6 +83,12 @@ void ext2fs_swap_super(struct ext2_super_block * sb) sb->s_usr_quota_inum = ext2fs_swab32(sb->s_usr_quota_inum); sb->s_grp_quota_inum = ext2fs_swab32(sb->s_grp_quota_inum); sb->s_overhead_blocks = ext2fs_swab32(sb->s_overhead_blocks); + sb->s_inodes_count_hi = ext2fs_swab32(sb->s_inodes_count_hi); + sb->s_free_inodes_count_hi = ext2fs_swab32(sb->s_free_inodes_count_hi); + sb->s_last_orphan_hi = ext2fs_swab32(sb->s_last_orphan_hi); + sb->s_prj_quota_inum_hi = ext2fs_swab32(sb->s_prj_quota_inum_hi); + sb->s_first_error_ino_hi = ext2fs_swab32(sb->s_first_error_ino_hi); + sb->s_last_error_ino_hi = ext2fs_swab32(sb->s_last_error_ino_hi); sb->s_checksum = ext2fs_swab32(sb->s_checksum); for (i=0; i < 4; i++) diff --git a/lib/ext2fs/tst_super_size.c b/lib/ext2fs/tst_super_size.c index 0adac411..137081dd 100644 --- a/lib/ext2fs/tst_super_size.c +++ b/lib/ext2fs/tst_super_size.c @@ -142,7 +142,13 @@ int main(int argc, char **argv) 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_inodes_count_hi, 4); + check_field(s_free_inodes_count_hi, 4); + check_field(s_prj_quota_inum_hi, 4); + check_field(s_last_orphan_hi, 4); + check_field(s_first_error_ino_hi, 4); + check_field(s_last_error_ino_hi, 4); + check_field(s_reserved, 92 * 4); check_field(s_checksum, 4); do_field("Superblock end", 0, 0, cur_offset, 1024); #endif diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c index 24023400..47f48bdf 100644 --- a/misc/fuse2fs.c +++ b/misc/fuse2fs.c @@ -299,7 +299,7 @@ out: #define FUSE2FS_FILE_MAGIC (0xEF53DEAFUL) struct fuse2fs_file_handle { unsigned long magic; - ext2_ino_t ino; + ext2_ino64_t ino; int open_flags; }; @@ -328,7 +328,7 @@ struct fuse2fs { return translate_error(global_fs, 0, EXT2_ET_BAD_MAGIC); \ } while (0) -static int __translate_error(ext2_filsys fs, errcode_t err, ext2_ino_t ino, +static int __translate_error(ext2_filsys fs, errcode_t err, ext2_ino64_t ino, const char *file, int line); #define translate_error(fs, ino, err) __translate_error((fs), (err), (ino), \ __FILE__, __LINE__) @@ -3866,7 +3866,7 @@ out: return ret; } -static int __translate_error(ext2_filsys fs, errcode_t err, ext2_ino_t ino, +static int __translate_error(ext2_filsys fs, errcode_t err, ext2_ino64_t ino, const char *file, int line) { struct timespec now; @@ -3940,7 +3940,7 @@ no_translation: return ret; if (ino) - fprintf(ff->err_fp, "FUSE2FS (%s): %s (inode #%d) at %s:%d.\n", + fprintf(ff->err_fp, "FUSE2FS (%s): %s (inode #%ld) at %s:%d.\n", fs->device_name ? fs->device_name : "???", error_message(err), ino, file, line); else diff --git a/misc/mke2fs.c b/misc/mke2fs.c index 8edb7546..2878aadc 100644 --- a/misc/mke2fs.c +++ b/misc/mke2fs.c @@ -1089,7 +1089,8 @@ static __u32 ok_features[3] = { EXT4_FEATURE_INCOMPAT_INLINE_DATA| EXT4_FEATURE_INCOMPAT_ENCRYPT | EXT4_FEATURE_INCOMPAT_CSUM_SEED | - EXT4_FEATURE_INCOMPAT_LARGEDIR, + EXT4_FEATURE_INCOMPAT_LARGEDIR| + EXT4_FEATURE_INCOMPAT_INODE64, /* R/O compat */ EXT2_FEATURE_RO_COMPAT_LARGE_FILE| EXT4_FEATURE_RO_COMPAT_HUGE_FILE| @@ -2457,13 +2458,15 @@ profile_error: if (num_inodes == 0) { unsigned long long n; n = ext2fs_blocks_count(&fs_param) * blocksize / inode_ratio; - if (n > MAX_32_NUM) { - if (ext2fs_has_feature_64bit(&fs_param)) + if (n > MAX_32_NUM && !ext2fs_has_feature_inode64(&fs_param)) { + if (ext2fs_has_feature_64bit(&fs_param)) { num_inodes = MAX_32_NUM; + } else { com_err(program_name, 0, - _("too many inodes (%llu), raise " - "inode ratio?"), n); + _("too many inodes (%llu), raise inode" + "ratio or enable dirdata and inode64?"), + num_inodes); exit(1); } } @@ -2476,10 +2479,13 @@ profile_error: /* * Calculate number of inodes based on the inode ratio */ - fs_param.s_inodes_count = num_inodes ? num_inodes : - (ext2fs_blocks_count(&fs_param) * blocksize) / inode_ratio; + if (num_inodes == 0) + num_inodes = (ext2fs_blocks_count(&fs_param) * blocksize) / + inode_ratio; + + ext2fs_set_inodes_count(&fs_param, num_inodes); - if ((((unsigned long long)fs_param.s_inodes_count) * + if ((ext2fs_get_inodes_count(&fs_param) * (inode_size ? inode_size : EXT2_GOOD_OLD_INODE_SIZE)) >= ((ext2fs_blocks_count(&fs_param)) * EXT2_BLOCK_SIZE(&fs_param))) { diff --git a/misc/tune2fs.c b/misc/tune2fs.c index 421c1d98..3538ab9c 100644 --- a/misc/tune2fs.c +++ b/misc/tune2fs.c @@ -161,7 +161,8 @@ static __u32 ok_features[3] = { EXT4_FEATURE_INCOMPAT_64BIT | EXT4_FEATURE_INCOMPAT_ENCRYPT | EXT4_FEATURE_INCOMPAT_CSUM_SEED | - EXT4_FEATURE_INCOMPAT_LARGEDIR, + EXT4_FEATURE_INCOMPAT_LARGEDIR | + EXT4_FEATURE_INCOMPAT_INODE64, /* R/O compat */ EXT2_FEATURE_RO_COMPAT_LARGE_FILE | EXT4_FEATURE_RO_COMPAT_HUGE_FILE| From patchwork Fri May 4 07:09:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artem Blagodarenko X-Patchwork-Id: 908554 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="dvF8lXWp"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40cjnp4SjXz9s3G for ; Fri, 4 May 2018 17:10:06 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751360AbeEDHKF (ORCPT ); Fri, 4 May 2018 03:10:05 -0400 Received: from mail-lf0-f65.google.com ([209.85.215.65]:46381 "EHLO mail-lf0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751447AbeEDHJr (ORCPT ); Fri, 4 May 2018 03:09:47 -0400 Received: by mail-lf0-f65.google.com with SMTP id v85-v6so29431350lfa.13 for ; Fri, 04 May 2018 00:09:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=B+0eDfZMxf/18rYwxFGMBeFKJZJmcje1wmsvEKsw46s=; b=dvF8lXWpUfdXMms0ayD9JL28rmeDSaTRL4/zqTSMruo531j6De+824Y+IjRwy13JEn 73SVtGifkq8LIMe/YUMNvNqw9uTA4/+zQXAY8cHhOmWFs2sYokrE5OD6Etg++BTkcGbq e0eA8NwhS89tAE+M6ksN+2i5AbOdRkVyW6+NbNXPyLAkKjc1bRecp0bxDh1MWBZAuXE3 PLuxPZfRzbji0ScINHzVoOjhZGGW22aNrw24jxNlk3O1q8PjyhSgW2EGdf8gXIcQGnkQ zq+eh4fHvnm3ynuTJlVmixiniUCLHNdERE1NiafRjFfnTmxurx2tApR6seSIg9WZwule ckFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=B+0eDfZMxf/18rYwxFGMBeFKJZJmcje1wmsvEKsw46s=; b=n7FPaLuvRXhhkiio+bQRk/uMGClD1Le4DZQnT9jxzNYv/vEZqu/cY20oWfTdPhkXRf VFPmJXI7gAJgWWjubTn9r4TCE9npb53E/An+CURyDpsU12b5iI3F7uX3t5AHVxBRIyp9 IgjiMC3et4FbgS2RTfv4eL/RLKDs8XdXRg5SQVCWA1fAC5rw721ApdN+YgQxzbmr8Plb L138AFgMIzKrSBHolXOszeJrQ+lZ3n7pc70VV1TTxPoaH3aNPuVzKmIVobJvaWTMmFBx BuOrGSaLrX+K6I/qBQbV5wE8qaHP2WHW/YwzUeSm9gXHz9uwkrSuxRF7n1AS/YmwO7Qn rVcQ== X-Gm-Message-State: ALQs6tBCU0JrQ4AjwL4tqlb5BgBycGIulNCYSJ+TCKOV43SzkHjKOHJ2 EENL/o2HRTS4x4wMz8rxX/QZew== X-Google-Smtp-Source: AB8JxZrI0i1gagb0QntP78MC+yEOR8T4Pz5ZM8Q5S84/59jiq2x5AjFcS79eMOOfgjR29EDpUCC5mg== X-Received: by 2002:a19:5386:: with SMTP id h6-v6mr14587306lfl.45.1525417786003; Fri, 04 May 2018 00:09:46 -0700 (PDT) Received: from C02TN4C6HTD6.lan ([80.72.234.202]) by smtp.gmail.com with ESMTPSA id f16-v6sm3170296lfh.94.2018.05.04.00.09.44 (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 04 May 2018 00:09:45 -0700 (PDT) From: c17828 X-Google-Original-From: c17828 To: linux-ext4@vger.kernel.org Cc: adilger.kernel@dilger.ca, Artem Blagodarenko Subject: [PATCH v4 7/7] e2fsck: INODE64 high part is more important then LUFID Date: Fri, 4 May 2018 10:09:23 +0300 Message-Id: <20180504070923.45140-8-c17828@cray.com> X-Mailer: git-send-email 2.14.3 (Apple Git-98) In-Reply-To: <20180504070923.45140-1-c17828@cray.com> References: <20180504070923.45140-1-c17828@cray.com> Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org From: Artem Blagodarenko Keep the INO64 field over LUFID, since it is both smaller, and more important. Lustre-bug: https://jira.hpdd.intel.com/browse/LU-9309 Signed-off-by: Artem Blagodarenko --- e2fsck/pass2.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c index ef0b97c0..21cbcd8e 100644 --- a/e2fsck/pass2.c +++ b/e2fsck/pass2.c @@ -377,10 +377,14 @@ void ext2_fix_dirent_dirdata(struct ext2_dir_entry *de) __u8 de_flags = (de->name_len >> 8) & ~EXT2_FT_MASK; __u8 name_len = de->name_len & EXT2_NAME_LEN; __u8 new_flag = 0; + char *startp = de->name + (de->name_len & EXT2_NAME_LEN) + 1 /* NUL */; + char *lenp = startp; + char *inop = NULL; int i; for (i = 0; i < 4; i++) { - __u8 flags = new_flag | (1 << i) << 4; + __u8 current_flag = (1 << i) << 4; + __u8 flags = new_flag | current_flag; /* new_flag is accumulating flags that are set in de_flags * and still fit inside rec_len. ext2_get_dirent_dirdata_size() @@ -392,6 +396,11 @@ void ext2_fix_dirent_dirdata(struct ext2_dir_entry *de) flags); int rlen = EXT2_DIR_NAME_LEN(name_len + dirdatalen); + if (current_flag == EXT2_DIRENT_INODE) + inop = lenp; + + lenp += *lenp; + if (rlen > de->rec_len) break; @@ -399,6 +408,17 @@ void ext2_fix_dirent_dirdata(struct ext2_dir_entry *de) } } + /* Keep the INO64 field over LUFID, since it is both smaller, + * and more important. + */ + if (inop && (ext2_get_dirdata_field_size(de, new_flag) >= 5) && + !(new_flag & EXT2_DIRENT_INODE)) { + new_flag &= ~EXT2_DIRENT_LUFID; + new_flag |= EXT2_DIRENT_INODE; + memmove(startp, inop, + ext2_get_dirdata_field_size(de, new_flag)); + } + de->name_len = name_len | file_type | (new_flag << 8); }