Received: by 2002:ac0:a581:0:0:0:0:0 with SMTP id m1-v6csp5031835imm; Tue, 26 Jun 2018 04:55:33 -0700 (PDT) X-Google-Smtp-Source: AAOMgpc/+NHvL62UHlzmh5YJH95CKRj909cs3Qt4kIW79TLkBkzxwkAM4EVBGeU5ER5Fk0RaVPvg X-Received: by 2002:a62:d388:: with SMTP id z8-v6mr1277859pfk.8.1530014133016; Tue, 26 Jun 2018 04:55:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1530014132; cv=none; d=google.com; s=arc-20160816; b=wxhwYBXUDKE+TULdarjGHR1SUmjOPE8m1vbxTQ1PC2iivUhQCkx9Y7rB2QboEMemM/ TzNB9Uvb8yNKs4p1yv6nR3KYSySYZzlkKZWdARvyl5I913xetK0AMAUSq4j+o6svJPmC Y12U1MoW8bkfgZNIE+1UHcN9ZYbkMaGmhy3H8Bhq8wgyLOjHjkJVjaNYSsX6q59WEc6H WKjdW0VuFWeE5w9sntOHlXC2ze8+b1++KEUNLLeOcETxd6oQEe5AjbUL2zr4KrpfmMum TT53m8+7xAvG9GBdb9A13jgf/o+F58pwS5Csg4DZPXlU71CnqrcdKeiAaJCj5ra+N9ZR cMfA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:message-id:date:subject:cc :to:from:arc-authentication-results; bh=Qhs/WLbj3LTQMsHl+v9eogchWjMJvZYx1ci4tSc/glY=; b=cxYRaZUfIKRNqTmjlW1NDnbLUhXmHuGSd9H1s5hSSvSnv2/4r8nl55cHoeYZCSSCXn 0n1xeCWpTmbz/EhhczIwiiMNtF2UHQEDYsDv0HMGsWwjDF/d4xxcq4KjVNlsB/jMuQBl xi+hKTxxG1rRGi82gfoTH8PgGTV2+3IgO7K5Py0BNMaL0aWfE0yu+JGs1u2ZkBM4XgSV QcixY2Zyu1u/7CifCwgbhKQQobtDPHGJxbnIXAeN8/66MiSNVL7s+0b5kK8ZMfZvt15G /TN/2/tHD/K+Wq/5Tza3ddFegqj+BM0chASjBUuOj4Qa9wzfBS2rbNN1WfsB+phyD6F4 m6/Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id v187-v6si1288995pgv.678.2018.06.26.04.55.19; Tue, 26 Jun 2018 04:55:32 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935032AbeFZLy3 (ORCPT + 99 others); Tue, 26 Jun 2018 07:54:29 -0400 Received: from szxga05-in.huawei.com ([45.249.212.191]:8734 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S934962AbeFZLy1 (ORCPT ); Tue, 26 Jun 2018 07:54:27 -0400 Received: from DGGEMS412-HUB.china.huawei.com (unknown [172.30.72.59]) by Forcepoint Email with ESMTP id CD88FCAB5FB16; Tue, 26 Jun 2018 19:54:11 +0800 (CST) Received: from lfgphicpra76918.huawei.com (10.251.127.181) by DGGEMS412-HUB.china.huawei.com (10.3.19.212) with Microsoft SMTP Server id 14.3.382.0; Tue, 26 Jun 2018 19:54:07 +0800 From: GaoMing To: CC: , , , Subject: [PATCH] ext4: e2fsprogs: fix inode bitmap num not integer,incompatible for ancient android devices Date: Tue, 26 Jun 2018 19:54:06 +0800 Message-ID: <1530014046-62466-1-git-send-email-gaoming20@huawei.com> X-Mailer: git-send-email 2.8.1 MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.251.127.181] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org for example, 1708 inodes every group,3 block groups, bitmap bytes are 1708/8=213.5 when the inode bitmap has some errors, e2fsprogs cannot fix it Signed-off-by: GaoMing --- e2fsck/pass5.c | 9 ++++----- lib/ext2fs/imager.c | 35 +++++++++++++++++++++++++++-------- lib/ext2fs/rw_bitmaps.c | 39 ++++++++++++++++++++++++++++----------- misc/dumpe2fs.c | 4 ++-- 4 files changed, 61 insertions(+), 26 deletions(-) diff --git a/e2fsck/pass5.c b/e2fsck/pass5.c index 7803e8b..4970dae 100644 --- a/e2fsck/pass5.c +++ b/e2fsck/pass5.c @@ -95,7 +95,7 @@ static void check_inode_bitmap_checksum(e2fsck_t ctx) if (ext2fs_test_ib_dirty(ctx->fs)) return; - nbytes = (size_t)(EXT2_INODES_PER_GROUP(ctx->fs->super) / 8); + nbytes = (size_t)((EXT2_INODES_PER_GROUP(ctx->fs->super)+7) / 8); retval = ext2fs_get_mem(ctx->fs->blocksize, &buf); if (retval) { com_err(ctx->program_name, 0, "%s", @@ -108,14 +108,13 @@ static void check_inode_bitmap_checksum(e2fsck_t ctx) if (ext2fs_bg_flags_test(ctx->fs, i, EXT2_BG_INODE_UNINIT)) continue; - ino_itr = 1 + (i * (nbytes << 3)); + ino_itr = 1 + (i * EXT2_INODES_PER_GROUP(ctx->fs->super)); retval = ext2fs_get_inode_bitmap_range2(ctx->fs->inode_map, - ino_itr, nbytes << 3, + ino_itr, EXT2_INODES_PER_GROUP(ctx->fs->super), buf); if (retval) break; - - if (ext2fs_inode_bitmap_csum_verify(ctx->fs, i, buf, nbytes)) + if (ext2fs_inode_bitmap_csum_verify(ctx->fs, i, buf, EXT2_INODES_PER_GROUP(ctx->fs->super) / 8)) continue; pctx.group = i; if (!fix_problem(ctx, PR_5_INODE_BITMAP_CSUM_INVALID, &pctx)) diff --git a/lib/ext2fs/imager.c b/lib/ext2fs/imager.c index 7fd06f7..346ec70 100644 --- a/lib/ext2fs/imager.c +++ b/lib/ext2fs/imager.c @@ -341,7 +341,8 @@ errcode_t ext2fs_image_bitmap_write(ext2_filsys fs, int fd, int flags) bmap = fs->inode_map; itr = 1; cnt = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count; - size = (EXT2_INODES_PER_GROUP(fs->super) / 8); + size = ((EXT2_INODES_PER_GROUP(fs->super)+7) / 8); + total_size = (EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count+7)/8; } else { if (!fs->block_map) { retval = ext2fs_read_block_bitmap(fs); @@ -352,13 +353,14 @@ errcode_t ext2fs_image_bitmap_write(ext2_filsys fs, int fd, int flags) itr = fs->super->s_first_data_block; cnt = EXT2_GROUPS_TO_CLUSTERS(fs->super, fs->group_desc_count); size = EXT2_CLUSTERS_PER_GROUP(fs->super) / 8; + total_size = size * fs->group_desc_count; } - total_size = size * fs->group_desc_count; + while (cnt > 0) { size = sizeof(buf); - if (size > (cnt >> 3)) - size = (cnt >> 3); + if (size > ((cnt+7) >> 3)) + size = ((cnt+7) >> 3); retval = ext2fs_get_generic_bmap_range(bmap, itr, size << 3, buf); @@ -372,7 +374,10 @@ errcode_t ext2fs_image_bitmap_write(ext2_filsys fs, int fd, int flags) return EXT2_ET_SHORT_READ; itr += size << 3; - cnt -= size << 3; + if (cnt < (size << 3)) + cnt = 0; + else + cnt -= size << 3; } size = total_size % fs->blocksize; @@ -406,6 +411,7 @@ errcode_t ext2fs_image_bitmap_read(ext2_filsys fs, int fd, int flags) char buf[1024]; unsigned int size; ssize_t actual; + __u64 count, pos; if (flags & IMAGER_FLAG_INODEMAP) { if (!fs->inode_map) { @@ -431,8 +437,8 @@ errcode_t ext2fs_image_bitmap_read(ext2_filsys fs, int fd, int flags) while (cnt > 0) { size = sizeof(buf); - if (size > (cnt >> 3)) - size = (cnt >> 3); + if (size > ((cnt+7) >> 3)) + size = ((cnt+7) >> 3); actual = read(fd, buf, size); if (actual == -1) @@ -440,13 +446,26 @@ errcode_t ext2fs_image_bitmap_read(ext2_filsys fs, int fd, int flags) if (actual != (int) size) return EXT2_ET_SHORT_READ; + if (cnt%8 != 0 && cnt < sizeof(buf)) { + pos = cnt; + count = (((cnt + 7)>>3)<<3)-cnt; + while (count > 0) { + ext2fs_fast_clear_bit(pos, buf); + pos++; + count--; + } + } + retval = ext2fs_set_generic_bmap_range(bmap, itr, size << 3, buf); if (retval) return retval; itr += size << 3; - cnt -= size << 3; + if (cnt < (size << 3)) + cnt = 0; + else + cnt -= size << 3; } return 0; } diff --git a/lib/ext2fs/rw_bitmaps.c b/lib/ext2fs/rw_bitmaps.c index e86bacd..e2499ff 100644 --- a/lib/ext2fs/rw_bitmaps.c +++ b/lib/ext2fs/rw_bitmaps.c @@ -40,6 +40,7 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block) blk64_t blk; blk64_t blk_itr = EXT2FS_B2C(fs, fs->super->s_first_data_block); ext2_ino_t ino_itr = 1; + __u64 count, pos; EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); @@ -115,19 +116,25 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block) if (csum_flag && ext2fs_bg_flags_test(fs, i, EXT2_BG_INODE_UNINIT) ) goto skip_this_inode_bitmap; - retval = ext2fs_get_inode_bitmap_range2(fs->inode_map, - ino_itr, inode_nbytes << 3, inode_buf); + ino_itr, EXT2_INODES_PER_GROUP(fs->super), inode_buf); if (retval) goto errout; - retval = ext2fs_inode_bitmap_csum_set(fs, i, inode_buf, - inode_nbytes); + EXT2_INODES_PER_GROUP(fs->super) / 8); if (retval) goto errout; + if (EXT2_INODES_PER_GROUP(fs->super)%8 != 0) { + pos = EXT2_INODES_PER_GROUP(fs->super); + count = (((pos + 7) >> 3)<<3)-pos; + while (count > 0) { + ext2fs_fast_set_bit(pos, inode_buf); + pos++; + count--; + } + } ext2fs_group_desc_csum_set(fs, i); fs->flags |= EXT2_FLAG_DIRTY; - blk = ext2fs_inode_bitmap_loc(fs, i); if (blk) { retval = io_channel_write_blk64(fs->io, blk, 1, @@ -138,7 +145,7 @@ static errcode_t write_bitmaps(ext2_filsys fs, int do_inode, int do_block) } } skip_this_inode_bitmap: - ino_itr += inode_nbytes << 3; + ino_itr += EXT2_INODES_PER_GROUP(fs->super); } if (do_block) { @@ -202,7 +209,7 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block) char *buf; errcode_t retval; int block_nbytes = EXT2_CLUSTERS_PER_GROUP(fs->super) / 8; - int inode_nbytes = EXT2_INODES_PER_GROUP(fs->super) / 8; + int inode_nbytes = (EXT2_INODES_PER_GROUP(fs->super) + 7) / 8; int csum_flag; unsigned int cnt; blk64_t blk; @@ -210,6 +217,7 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block) blk64_t blk_cnt; ext2_ino_t ino_itr = 1; ext2_ino_t ino_cnt; + __u64 count, pos; EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); @@ -337,24 +345,33 @@ static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block) retval = EXT2_ET_INODE_BITMAP_READ; goto cleanup; } - + if (EXT2_INODES_PER_GROUP(fs->super)%8 != 0) { + pos = EXT2_INODES_PER_GROUP(fs->super); + count = (((pos + 7) >> 3)<<3)-pos; + while (count > 0) { + ext2fs_fast_clear_bit(pos, inode_bitmap); + pos++; + count--; + } + } /* verify inode bitmap checksum */ if (!(fs->flags & EXT2_FLAG_IGNORE_CSUM_ERRORS) && !ext2fs_inode_bitmap_csum_verify(fs, i, - inode_bitmap, inode_nbytes)) { + inode_bitmap, + EXT2_INODES_PER_GROUP(fs->super) / 8)) { retval = EXT2_ET_INODE_BITMAP_CSUM_INVALID; goto cleanup; } } else memset(inode_bitmap, 0, inode_nbytes); - cnt = inode_nbytes << 3; + cnt = EXT2_INODES_PER_GROUP(fs->super); retval = ext2fs_set_inode_bitmap_range2(fs->inode_map, ino_itr, cnt, inode_bitmap); if (retval) goto cleanup; - ino_itr += inode_nbytes << 3; + ino_itr += EXT2_INODES_PER_GROUP(fs->super); } } diff --git a/misc/dumpe2fs.c b/misc/dumpe2fs.c index 395ea9e..5cf431a 100644 --- a/misc/dumpe2fs.c +++ b/misc/dumpe2fs.c @@ -168,7 +168,7 @@ static void list_desc(ext2_filsys fs, int grp_only) units = _("clusters"); block_nbytes = EXT2_CLUSTERS_PER_GROUP(fs->super) / 8; - inode_nbytes = EXT2_INODES_PER_GROUP(fs->super) / 8; + inode_nbytes = (EXT2_INODES_PER_GROUP(fs->super)+7) / 8; if (fs->block_map) block_bitmap = malloc(block_nbytes); @@ -303,7 +303,7 @@ static void list_desc(ext2_filsys fs, int grp_only) if (inode_bitmap) { fputs(_(" Free inodes: "), stdout); retval = ext2fs_get_inode_bitmap_range2(fs->inode_map, - ino_itr, inode_nbytes << 3, inode_bitmap); + ino_itr, EXT2_INODES_PER_GROUP(fs->super), inode_bitmap); if (retval) com_err("list_desc", retval, "while reading inode bitmap"); -- 2.8.1