From 216d0fc5a560a2ac952432288ad2a6f090035e5f Mon Sep 17 00:00:00 2001 From: Hyunchul Lee Date: Mon, 12 Apr 2021 15:29:45 +0900 Subject: [PATCH] fsck: change cluster argument of bitmap operations Change the cluster argument of bitmap operations to start with EXFAT_FIRST_CLUSTER instead of 0. Signed-off-by: Hyunchul Lee --- fsck/fsck.c | 28 +++++++++++----------------- include/libexfat.h | 20 +++++++++++++++----- lib/libexfat.c | 5 ++--- mkfs/mkfs.c | 7 ++++--- 4 files changed, 32 insertions(+), 28 deletions(-) diff --git a/fsck/fsck.c b/fsck/fsck.c index aab59a76..0b14b1a3 100644 --- a/fsck/fsck.c +++ b/fsck/fsck.c @@ -139,8 +139,7 @@ static int check_clus_chain(struct exfat_de_iter *de_iter, * This cluster is already allocated. it may be shared with * the other file, or there is a loop in cluster chain. */ - if (EXFAT_BITMAP_GET(exfat->alloc_bitmap, - clus - EXFAT_FIRST_CLUSTER)) { + if (exfat_bitmap_get(exfat->alloc_bitmap, clus)) { if (repair_file_ask(de_iter, node, ER_FILE_DUPLICATED_CLUS, "cluster is already allocated for the other file. truncated to %" @@ -151,9 +150,8 @@ static int check_clus_chain(struct exfat_de_iter *de_iter, return -EINVAL; } - if (!EXFAT_BITMAP_GET(exfat->disk_bitmap, - clus - EXFAT_FIRST_CLUSTER)) { - if (!repair_file_ask(&exfat->de_iter, node, + if (!exfat_bitmap_get(exfat->disk_bitmap, clus)) { + if (!repair_file_ask(de_iter, node, ER_FILE_INVALID_CLUS, "cluster %#x is marked as free", clus)) @@ -182,8 +180,8 @@ static int check_clus_chain(struct exfat_de_iter *de_iter, (count + 1) * exfat->clus_size)) { count++; prev = clus; - EXFAT_BITMAP_SET(exfat->alloc_bitmap, - clus - EXFAT_FIRST_CLUSTER); + exfat_bitmap_set(exfat->alloc_bitmap, + clus); goto truncate_file; } else { return -EINVAL; @@ -192,8 +190,7 @@ static int check_clus_chain(struct exfat_de_iter *de_iter, } count++; - EXFAT_BITMAP_SET(exfat->alloc_bitmap, - clus - EXFAT_FIRST_CLUSTER); + exfat_bitmap_set(exfat->alloc_bitmap, clus); prev = clus; clus = next; } @@ -248,15 +245,13 @@ static bool root_get_clus_count(struct exfat *exfat, struct exfat_inode *node, return false; } - if (EXFAT_BITMAP_GET(exfat->alloc_bitmap, - clus - EXFAT_FIRST_CLUSTER)) { + if (exfat_bitmap_get(exfat->alloc_bitmap, clus)) { exfat_err("/: cluster is already allocated, or " "there is a loop in cluster chain\n"); return false; } - EXFAT_BITMAP_SET(exfat->alloc_bitmap, - clus - EXFAT_FIRST_CLUSTER); + exfat_bitmap_set(exfat->alloc_bitmap, clus); if (exfat_get_next_clus(exfat, node, clus, &clus) != 0) { exfat_err("/: broken cluster chain\n"); @@ -1027,10 +1022,9 @@ static int write_dirty_fat(struct exfat_fsck *fsck) for (i = clus ? clus : EXFAT_FIRST_CLUSTER; i < clus + clus_count; i++) { - if (!EXFAT_BITMAP_GET(exfat->alloc_bitmap, - i - EXFAT_FIRST_CLUSTER) && - ((clus_t *)bd[idx].buffer)[i - clus] != - EXFAT_FREE_CLUSTER) { + if (!exfat_bitmap_get(exfat->alloc_bitmap, i) && + ((clus_t *)bd[idx].buffer)[i - clus] != + EXFAT_FREE_CLUSTER) { ((clus_t *)bd[idx].buffer)[i - clus] = EXFAT_FREE_CLUSTER; bd[idx].dirty[(i - clus) / diff --git a/include/libexfat.h b/include/libexfat.h index 714f605e..cac88512 100644 --- a/include/libexfat.h +++ b/include/libexfat.h @@ -101,11 +101,21 @@ typedef __u32 bitmap_t; #define EXFAT_BITMAP_SIZE(__c_count) \ (DIV_ROUND_UP(__c_count, BITS_PER) * sizeof(bitmap_t)) -#define EXFAT_BITMAP_GET(__bmap, __c) \ - (((bitmap_t *)(__bmap))[BIT_ENTRY(__c)] & BIT_MASK(__c)) -#define EXFAT_BITMAP_SET(__bmap, __c) \ - (((bitmap_t *)(__bmap))[BIT_ENTRY(__c)] |= \ - BIT_MASK(__c)) + +static inline bool exfat_bitmap_get(char *bmap, clus_t c) +{ + clus_t cc = c - EXFAT_FIRST_CLUSTER; + + return ((bitmap_t *)(bmap))[BIT_ENTRY(cc)] & BIT_MASK(cc); +} + +static inline void exfat_bitmap_set(char *bmap, clus_t c) +{ + clus_t cc = c - EXFAT_FIRST_CLUSTER; + + (((bitmap_t *)(bmap))[BIT_ENTRY(cc)] |= BIT_MASK(cc)); +} + void exfat_bitmap_set_range(struct exfat *exfat, char *bitmap, clus_t start_clus, clus_t count); diff --git a/lib/libexfat.c b/lib/libexfat.c index 9b79a84d..d805b50b 100644 --- a/lib/libexfat.c +++ b/lib/libexfat.c @@ -29,13 +29,12 @@ void exfat_bitmap_set_range(struct exfat *exfat, char *bitmap, clus_t clus; if (!exfat_heap_clus(exfat, start_clus) || - !exfat_heap_clus(exfat, start_clus + count)) + !exfat_heap_clus(exfat, start_clus + count - 1)) return; clus = start_clus; while (clus < start_clus + count) { - EXFAT_BITMAP_SET(bitmap, - clus - EXFAT_FIRST_CLUSTER); + exfat_bitmap_set(bitmap, clus); clus++; } } diff --git a/mkfs/mkfs.c b/mkfs/mkfs.c index cc1f62dc..511662b5 100644 --- a/mkfs/mkfs.c +++ b/mkfs/mkfs.c @@ -314,12 +314,13 @@ static int exfat_create_bitmap(struct exfat_blk_dev *bd) char *bitmap; unsigned int i, nbytes; - bitmap = calloc(EXFAT_BITMAP_SIZE(finfo.total_clu_cnt), sizeof(*bitmap)); + bitmap = calloc(round_up(finfo.bitmap_byte_len, sizeof(bitmap_t)), + sizeof(*bitmap)); if (!bitmap) return -1; - for (i = 0; i < finfo.used_clu_cnt - EXFAT_FIRST_CLUSTER; i++) - EXFAT_BITMAP_SET(bitmap, i); + for (i = EXFAT_FIRST_CLUSTER; i < finfo.used_clu_cnt; i++) + exfat_bitmap_set(bitmap, i); nbytes = pwrite(bd->dev_fd, bitmap, finfo.bitmap_byte_len, finfo.bitmap_byte_off); if (nbytes != finfo.bitmap_byte_len) {