X-Git-Url: https://git.sven.stormbind.net/?a=blobdiff_plain;f=fsck%2Ffsck.c;h=00d1ca7f2c3620770547fc014ffc14a2d99d70e3;hb=refs%2Fheads%2Fmaster;hp=cd9ee9a193e344af59482af52256cbe98b4c5896;hpb=dca2019dad1a2b3db50c3613743914d41e62daa3;p=sven%2Fexfatprogs.git diff --git a/fsck/fsck.c b/fsck/fsck.c index cd9ee9a..fe8a122 100644 --- a/fsck/fsck.c +++ b/fsck/fsck.c @@ -102,32 +102,22 @@ static void usage(char *name) exfat_de_iter_device_offset(iter)); \ }) -static int check_clus_chain(struct exfat_de_iter *de_iter, - struct exfat_inode *node) +static int check_clus_chain(struct exfat_de_iter *de_iter, int stream_idx, + struct exfat_inode *node) { struct exfat *exfat = de_iter->exfat; struct exfat_dentry *stream_de; - clus_t clus, prev, next, new_clus; + clus_t clus, prev, next; uint64_t count, max_count; - int err; clus = node->first_clus; prev = EXFAT_EOF_CLUSTER; count = 0; max_count = DIV_ROUND_UP(node->size, exfat->clus_size); - if (node->size == 0 && node->first_clus == EXFAT_FREE_CLUSTER) { - /* locate a cluster for the empty dir if the dir starts with EXFAT_FREE_CLUSTER */ - if (node->attr & ATTR_SUBDIR) { - if (repair_file_ask(de_iter, node, - ER_DE_FIRST_CLUS, - "size %#" PRIx64 ", but the first cluster %#x", - node->size, node->first_clus)) - goto allocate_cluster; - return -EINVAL; - } + if (node->size == 0 && node->first_clus == EXFAT_FREE_CLUSTER) return 0; - } + /* the first cluster is wrong */ if ((node->size == 0 && node->first_clus != EXFAT_FREE_CLUSTER) || (node->size > 0 && !exfat_heap_clus(exfat, node->first_clus))) { @@ -225,45 +215,13 @@ static int check_clus_chain(struct exfat_de_iter *de_iter, } return 0; -allocate_cluster: - exfat_de_iter_get_dirty(de_iter, 1, &stream_de); - err = exfat_find_free_cluster(exfat, exfat->start_clu, &new_clus); - if (err) { - exfat->start_clu = EXFAT_FIRST_CLUSTER; - exfat_err("failed to find a free cluster\n"); - return -ENOSPC; - } - exfat->start_clu = new_clus; - - if (exfat_set_fat(exfat, new_clus, EXFAT_EOF_CLUSTER)) - return -EIO; - - /* zero out the new cluster */ - if (exfat_write(exfat->blk_dev->dev_fd, exfat->zero_cluster, - exfat->clus_size, exfat_c2o(exfat, new_clus)) != - (ssize_t)exfat->clus_size) { - exfat_err("failed to fill new cluster with zeroes\n"); - return -EIO; - } - - /* modify the number of cluster form 0 to 1 */ - count = 1; - stream_de->stream_start_clu = cpu_to_le32(new_clus); - stream_de->stream_size = cpu_to_le64(count * exfat->clus_size); - stream_de->stream_valid_size = cpu_to_le64(count * exfat->clus_size); - stream_de->dentry.stream.flags |= EXFAT_SF_CONTIGUOUS; - node->first_clus = new_clus; - node->size = count * exfat->clus_size; - node->is_contiguous = true; - exfat_bitmap_set(exfat->alloc_bitmap, new_clus); - return 1; truncate_file: node->size = count * exfat->clus_size; if (!exfat_heap_clus(exfat, prev)) node->first_clus = EXFAT_FREE_CLUSTER; - exfat_de_iter_get_dirty(de_iter, 1, &stream_de); - if (count * exfat->clus_size < + exfat_de_iter_get_dirty(de_iter, stream_idx, &stream_de); + if (stream_idx == 1 && count * exfat->clus_size < le64_to_cpu(stream_de->stream_valid_size)) stream_de->stream_valid_size = cpu_to_le64( count * exfat->clus_size); @@ -413,9 +371,10 @@ static int read_boot_region(struct exfat_blk_dev *bd, struct pbr **pbr, { struct pbr *bs; int ret = -EINVAL; + unsigned long long clu_max_count; *pbr = NULL; - bs = (struct pbr *)malloc(sizeof(struct pbr)); + bs = malloc(sizeof(struct pbr)); if (!bs) { exfat_err("failed to allocate memory\n"); return -ENOMEM; @@ -476,12 +435,13 @@ static int read_boot_region(struct exfat_blk_dev *bd, struct pbr **pbr, goto err; } - if (le32_to_cpu(bs->bsx.clu_count) * EXFAT_CLUSTER_SIZE(bs) > - bd->size) { + clu_max_count = (le64_to_cpu(bs->bsx.vol_length) - le32_to_cpu(bs->bsx.clu_offset)) >> + bs->bsx.sect_per_clus_bits; + if (le32_to_cpu(bs->bsx.clu_count) > clu_max_count) { if (verbose) - exfat_err("too large cluster count: %u, expected: %u\n", + exfat_err("too large cluster count: %u, expected: %llu\n", le32_to_cpu(bs->bsx.clu_count), - bd->num_clusters); + MIN(clu_max_count, EXFAT_MAX_NUM_CLUSTER)); goto err; } @@ -607,21 +567,24 @@ restore: return ret; } -static uint16_t file_calc_checksum(struct exfat_de_iter *iter) +static int file_calc_checksum(struct exfat_de_iter *iter, uint16_t *checksum) { - uint16_t checksum; struct exfat_dentry *file_de, *de; - int i; + int i, ret; - checksum = 0; - exfat_de_iter_get(iter, 0, &file_de); + *checksum = 0; + ret = exfat_de_iter_get(iter, 0, &file_de); + if (ret) + return ret; - exfat_calc_dentry_checksum(file_de, &checksum, true); + exfat_calc_dentry_checksum(file_de, checksum, true); for (i = 1; i <= file_de->file_num_ext; i++) { - exfat_de_iter_get(iter, i, &de); - exfat_calc_dentry_checksum(de, &checksum, false); + ret = exfat_de_iter_get(iter, i, &de); + if (ret) + return ret; + exfat_calc_dentry_checksum(de, checksum, false); } - return checksum; + return 0; } /* @@ -636,7 +599,7 @@ static int check_inode(struct exfat_de_iter *iter, struct exfat_inode *node) uint16_t checksum; bool valid = true; - ret = check_clus_chain(iter, node); + ret = check_clus_chain(iter, 1, node); if (ret < 0) return ret; @@ -666,7 +629,9 @@ static int check_inode(struct exfat_de_iter *iter, struct exfat_inode *node) valid = false; } - checksum = file_calc_checksum(iter); + ret = file_calc_checksum(iter, &checksum); + if (ret) + return ret; exfat_de_iter_get(iter, 0, &dentry); if (checksum != le16_to_cpu(dentry->file_checksum)) { exfat_de_iter_get_dirty(iter, 0, &dentry); @@ -677,12 +642,42 @@ static int check_inode(struct exfat_de_iter *iter, struct exfat_inode *node) return valid ? ret : -EINVAL; } +static int handle_duplicated_filename(struct exfat_de_iter *iter, + struct exfat_inode *inode) +{ + int ret; + struct exfat_lookup_filter filter; + char filename[PATH_MAX + 1] = {0}; + + ret = exfat_lookup_file_by_utf16name(iter->exfat, iter->parent, + inode->name, &filter); + if (ret) + return ret; + + free(filter.out.dentry_set); + + /* Hash is same, but filename is not same */ + if (exfat_de_iter_device_offset(iter) == filter.out.dev_offset) + return 0; + + ret = exfat_utf16_dec(inode->name, NAME_BUFFER_SIZE, filename, + PATH_MAX); + if (ret < 0) { + exfat_err("failed to decode filename\n"); + return ret; + } + + return exfat_repair_rename_ask(&exfat_fsck, iter, filename, + ER_DE_DUPLICATED_NAME, "filename is duplicated"); +} + static int check_name_dentry_set(struct exfat_de_iter *iter, struct exfat_inode *inode) { struct exfat_dentry *stream_de; size_t name_len; __u16 hash; + int ret = 0; exfat_de_iter_get(iter, 1, &stream_de); @@ -692,6 +687,7 @@ static int check_name_dentry_set(struct exfat_de_iter *iter, "the name length of a file is wrong")) { exfat_de_iter_get_dirty(iter, 1, &stream_de); stream_de->stream_name_len = (__u8)name_len; + ret = 1; } else { return -EINVAL; } @@ -703,81 +699,18 @@ static int check_name_dentry_set(struct exfat_de_iter *iter, "the name hash of a file is wrong")) { exfat_de_iter_get_dirty(iter, 1, &stream_de); stream_de->stream_name_hash = cpu_to_le16(hash); + ret = 1; } else { return -EINVAL; } } - return 0; -} -static int check_bad_char(char w) -{ - return (w < 0x0020) || (w == '*') || (w == '?') || (w == '<') || - (w == '>') || (w == '|') || (w == '"') || (w == ':') || - (w == '/') || (w == '\\'); -} - -static char *get_rename_from_user(struct exfat_de_iter *iter) -{ - char *rename = malloc(ENTRY_NAME_MAX + 2); - - if (!rename) - return NULL; - -retry: - /* +2 means LF(Line Feed) and NULL terminator */ - memset(rename, 0x1, ENTRY_NAME_MAX + 2); - printf("New name: "); - if (fgets(rename, ENTRY_NAME_MAX + 2, stdin)) { - int i, len, err; - struct exfat_lookup_filter filter; - - len = strlen(rename); - /* Remove LF in filename */ - rename[len - 1] = '\0'; - for (i = 0; i < len - 1; i++) { - if (check_bad_char(rename[i])) { - printf("filename contain invalid character(%c)\n", rename[i]); - goto retry; - } - } + if (BITMAP_GET(iter->name_hash_bitmap, hash)) { + ret = handle_duplicated_filename(iter, inode); + } else + BITMAP_SET(iter->name_hash_bitmap, hash); - exfat_de_iter_flush(iter); - err = exfat_lookup_file(iter->exfat, iter->parent, rename, &filter); - if (!err) { - printf("file(%s) already exists, retry to insert name\n", rename); - goto retry; - } - } - - return rename; -} - -static char *generate_rename(struct exfat_de_iter *iter) -{ - char *rename; - - if (iter->dot_name_num > DOT_NAME_NUM_MAX) - return NULL; - - rename = malloc(ENTRY_NAME_MAX + 1); - if (!rename) - return NULL; - - while (1) { - struct exfat_lookup_filter filter; - int err; - - snprintf(rename, ENTRY_NAME_MAX + 1, "FILE%07d.CHK", - iter->dot_name_num++); - err = exfat_lookup_file(iter->exfat, iter->parent, rename, - &filter); - if (!err) - continue; - break; - } - - return rename; + return ret; } const __le16 MSDOS_DOT[ENTRY_NAME_MAX] = {cpu_to_le16(46), 0, }; @@ -788,8 +721,6 @@ static int handle_dot_dotdot_filename(struct exfat_de_iter *iter, int strm_name_len) { char *filename; - char error_msg[150]; - int num; if (!memcmp(dentry->name_unicode, MSDOS_DOT, strm_name_len * 2)) filename = "."; @@ -799,56 +730,8 @@ static int handle_dot_dotdot_filename(struct exfat_de_iter *iter, else return 0; - sprintf(error_msg, "ERROR: '%s' filename is not allowed.\n" - " [1] Insert the name you want to rename.\n" - " [2] Automatically renames filename.\n" - " [3] Bypass this check(No repair)\n", filename); -ask_again: - num = exfat_repair_ask(&exfat_fsck, ER_DE_DOT_NAME, - error_msg); - if (num) { - __le16 utf16_name[ENTRY_NAME_MAX]; - char *rename = NULL; - __u16 hash; - struct exfat_dentry *stream_de; - int name_len, ret; - - switch (num) { - case 1: - rename = get_rename_from_user(iter); - break; - case 2: - rename = generate_rename(iter); - break; - case 3: - break; - default: - exfat_info("select 1 or 2 number instead of %d\n", num); - goto ask_again; - } - - if (!rename) - return -EINVAL; - - exfat_info("%s filename is renamed to %s\n", filename, rename); - - exfat_de_iter_get_dirty(iter, 2, &dentry); - - memset(utf16_name, 0, sizeof(utf16_name)); - ret = exfat_utf16_enc(rename, utf16_name, sizeof(utf16_name)); - free(rename); - if (ret < 0) - return ret; - - memcpy(dentry->name_unicode, utf16_name, ENTRY_NAME_MAX * 2); - name_len = exfat_utf16_len(utf16_name, ENTRY_NAME_MAX * 2); - hash = exfat_calc_name_hash(iter->exfat, utf16_name, (int)name_len); - exfat_de_iter_get_dirty(iter, 1, &stream_de); - stream_de->stream_name_len = (__u8)name_len; - stream_de->stream_name_hash = cpu_to_le16(hash); - } - - return 0; + return exfat_repair_rename_ask(&exfat_fsck, iter, filename, + ER_DE_DOT_NAME, "filename is not allowed"); } static int read_file_dentry_set(struct exfat_de_iter *iter, @@ -856,8 +739,8 @@ static int read_file_dentry_set(struct exfat_de_iter *iter, { struct exfat_dentry *file_de, *stream_de, *dentry; struct exfat_inode *node = NULL; - int i, ret; - bool need_delete = false; + int i, j, ret, name_de_count; + bool need_delete = false, need_copy_up = false; uint16_t checksum; ret = exfat_de_iter_get(iter, 0, &file_de); @@ -866,10 +749,11 @@ static int read_file_dentry_set(struct exfat_de_iter *iter, return -EINVAL; } - checksum = file_calc_checksum(iter); - if (checksum != le16_to_cpu(file_de->file_checksum)) { + ret = file_calc_checksum(iter, &checksum); + if (ret || checksum != le16_to_cpu(file_de->file_checksum)) { if (repair_file_ask(iter, NULL, ER_DE_CHECKSUM, - "the checksum of a file is wrong")) + "the checksum %#x of a file is wrong, expected: %#x", + le16_to_cpu(file_de->file_checksum), checksum)) need_delete = true; *skip_dentries = 1; goto skip_dset; @@ -898,17 +782,22 @@ static int read_file_dentry_set(struct exfat_de_iter *iter, if (!node) return -ENOMEM; - for (i = 2; i <= file_de->file_num_ext; i++) { + name_de_count = DIV_ROUND_UP(stream_de->stream_name_len, ENTRY_NAME_MAX); + for (i = 2; i <= MIN(name_de_count + 1, file_de->file_num_ext); i++) { ret = exfat_de_iter_get(iter, i, &dentry); if (ret || dentry->type != EXFAT_NAME) { - if (i > 2 && repair_file_ask(iter, NULL, ER_DE_NAME, - "failed to get name dentry")) { - exfat_de_iter_get_dirty(iter, 0, &file_de); - file_de->file_num_ext = i - 1; + if (repair_file_ask(iter, NULL, ER_DE_NAME, + "failed to get name dentry")) { + if (i == 2) { + need_delete = 1; + *skip_dentries = i + 1; + goto skip_dset; + } break; + } else { + *skip_dentries = i + 1; + goto skip_dset; } - *skip_dentries = i + 1; - goto skip_dset; } memcpy(node->name + @@ -917,9 +806,14 @@ static int read_file_dentry_set(struct exfat_de_iter *iter, } ret = check_name_dentry_set(iter, node); - if (ret) { + if (ret < 0) { *skip_dentries = file_de->file_num_ext + 1; goto skip_dset; + } else if (ret) { + exfat_de_iter_get(iter, 1, &stream_de); + if (DIV_ROUND_UP(stream_de->stream_name_len, ENTRY_NAME_MAX) != + name_de_count) + i = DIV_ROUND_UP(stream_de->stream_name_len, ENTRY_NAME_MAX) + 2; } if (file_de->file_num_ext == 2 && stream_de->stream_name_len <= 2) { @@ -931,6 +825,69 @@ static int read_file_dentry_set(struct exfat_de_iter *iter, } } + for (j = i; i <= file_de->file_num_ext; i++) { + exfat_de_iter_get(iter, i, &dentry); + if (dentry->type == EXFAT_VENDOR_EXT || + dentry->type == EXFAT_VENDOR_ALLOC) { + char zeroes[EXFAT_GUID_LEN] = {0}; + /* + * Vendor GUID should not be zero, But Windows fsck + * also does not check and fix it. + */ + if (!memcmp(dentry->dentry.vendor_ext.guid, + zeroes, EXFAT_GUID_LEN)) + repair_file_ask(iter, NULL, ER_VENDOR_GUID, + "Vendor Extension has zero filled GUID"); + if (dentry->type == EXFAT_VENDOR_ALLOC) { + struct exfat_inode *vendor_node; + + /* verify cluster chain */ + vendor_node = exfat_alloc_inode(0); + if (!vendor_node) { + *skip_dentries = i + i; + goto skip_dset; + } + vendor_node->first_clus = + le32_to_cpu(dentry->dentry.vendor_alloc.start_clu); + vendor_node->is_contiguous = ((dentry->dentry.vendor_alloc.flags + & EXFAT_SF_CONTIGUOUS) != 0); + vendor_node->size = + le64_to_cpu(dentry->dentry.vendor_alloc.size); + if (check_clus_chain(iter, i, vendor_node) < 0) { + exfat_free_inode(vendor_node); + *skip_dentries = i + 1; + goto skip_dset; + } + if (vendor_node->size == 0 && + vendor_node->is_contiguous) { + exfat_de_iter_get_dirty(iter, i, &dentry); + dentry->stream_flags &= ~EXFAT_SF_CONTIGUOUS; + + } + exfat_free_inode(vendor_node); + } + + if (need_copy_up) { + struct exfat_dentry *src_de; + + exfat_de_iter_get_dirty(iter, j, &src_de); + memcpy(src_de, dentry, sizeof(struct exfat_dentry)); + } + j++; + } else { + if (need_copy_up) { + continue; + } else if (repair_file_ask(iter, NULL, ER_DE_UNKNOWN, + "unknown entry type %#x", dentry->type)) { + j = i; + need_copy_up = true; + } else { + *skip_dentries = i + 1; + goto skip_dset; + } + } + } + node->first_clus = le32_to_cpu(stream_de->stream_start_clu); node->is_contiguous = ((stream_de->stream_flags & EXFAT_SF_CONTIGUOUS) != 0); @@ -951,6 +908,18 @@ static int read_file_dentry_set(struct exfat_de_iter *iter, } } + if (file_de->file_num_ext != j - 1) { + if (repair_file_ask(iter, node, ER_DE_SECONDARY_COUNT, + "SecondaryCount %d is different with %d", + file_de->file_num_ext, j - 1)) { + exfat_de_iter_get_dirty(iter, 0, &file_de); + file_de->file_num_ext = j - 1; + } else { + *skip_dentries = file_de->file_num_ext + 1; + goto skip_dset; + } + } + *skip_dentries = (file_de->file_num_ext + 1); *new_node = node; return 0; @@ -1004,6 +973,7 @@ static int read_bitmap(struct exfat *exfat) { struct exfat_lookup_filter filter = { .in.type = EXFAT_BITMAP, + .in.dentry_count = 0, .in.filter = NULL, .in.param = NULL, }; @@ -1078,6 +1048,7 @@ static int read_upcase_table(struct exfat *exfat) { struct exfat_lookup_filter filter = { .in.type = EXFAT_UPCASE, + .in.dentry_count = 0, .in.filter = NULL, .in.param = NULL, }; @@ -1109,7 +1080,7 @@ static int read_upcase_table(struct exfat *exfat) goto out; } - upcase = (__le16 *)malloc(size); + upcase = malloc(size); if (!upcase) { exfat_err("failed to allocate upcase table\n"); retval = -ENOMEM; @@ -1138,8 +1109,7 @@ static int read_upcase_table(struct exfat *exfat) DIV_ROUND_UP(le64_to_cpu(dentry->upcase_size), exfat->clus_size)); - exfat->upcase_table = calloc(1, - sizeof(uint16_t) * EXFAT_UPCASE_TABLE_CHARS); + exfat->upcase_table = calloc(EXFAT_UPCASE_TABLE_CHARS, sizeof(uint16_t)); if (!exfat->upcase_table) { retval = -EIO; goto out; @@ -1171,6 +1141,10 @@ static int read_children(struct exfat_fsck *fsck, struct exfat_inode *dir) else if (ret) return ret; + de_iter->name_hash_bitmap = fsck->name_hash_bitmap; + memset(fsck->name_hash_bitmap, 0, + EXFAT_BITMAP_SIZE(EXFAT_MAX_HASH_COUNT)); + while (1) { ret = exfat_de_iter_get(de_iter, 0, &dentry); if (ret == EOF) { @@ -1211,6 +1185,7 @@ static int read_children(struct exfat_fsck *fsck, struct exfat_inode *dir) case EXFAT_VOLUME: case EXFAT_BITMAP: case EXFAT_UPCASE: + case EXFAT_GUID: if (dir == exfat->root) break; /* fallthrough */ @@ -1218,9 +1193,7 @@ static int read_children(struct exfat_fsck *fsck, struct exfat_inode *dir) if (IS_EXFAT_DELETED(dentry->type)) break; if (repair_file_ask(de_iter, NULL, ER_DE_UNKNOWN, - "unknown entry type %#x at %07" PRIx64, - dentry->type, - exfat_de_iter_file_offset(de_iter))) { + "unknown entry type %#x", dentry->type)) { struct exfat_dentry *dentry; exfat_de_iter_get_dirty(de_iter, 0, &dentry); @@ -1300,6 +1273,12 @@ static int exfat_filesystem_check(struct exfat_fsck *fsck) return -ENOENT; } + fsck->name_hash_bitmap = malloc(EXFAT_BITMAP_SIZE(EXFAT_MAX_HASH_COUNT)); + if (!fsck->name_hash_bitmap) { + exfat_err("failed to allocate name hash bitmap\n"); + return -ENOMEM; + } + list_add(&exfat->root->list, &exfat->dir_list); while (!list_empty(&exfat->dir_list)) { @@ -1328,6 +1307,7 @@ static int exfat_filesystem_check(struct exfat_fsck *fsck) } out: exfat_free_dir_list(exfat); + free(fsck->name_hash_bitmap); return ret; } @@ -1358,7 +1338,6 @@ static int exfat_root_dir_check(struct exfat *exfat) err = exfat_read_volume_label(exfat); if (err && err != EOF) exfat_err("failed to read volume label\n"); - err = 0; err = read_bitmap(exfat); if (err) { @@ -1427,9 +1406,40 @@ static int rescue_orphan_clusters(struct exfat_fsck *fsck) struct exfat_dentry_loc loc; struct exfat_lookup_filter lf = { .in.type = EXFAT_INVAL, + .in.dentry_count = 0, .in.filter = NULL, }; + clu_count = le32_to_cpu(exfat->bs->bsx.clu_count); + + /* find clusters which are not marked as free, but not allocated to + * any files. + */ + disk_b = (bitmap_t *)exfat->disk_bitmap; + alloc_b = (bitmap_t *)exfat->alloc_bitmap; + ohead_b = (bitmap_t *)exfat->ohead_bitmap; + for (i = 0; i < EXFAT_BITMAP_SIZE(clu_count) / sizeof(bitmap_t); i++) + ohead_b[i] = disk_b[i] & ~alloc_b[i]; + + /* no orphan clusters */ + if (exfat_bitmap_find_one(exfat, exfat->ohead_bitmap, + EXFAT_FIRST_CLUSTER, &s_clu)) + return 0; + + err = exfat_create_file(exfat_fsck.exfat, + exfat_fsck.exfat->root, + "LOST+FOUND", + ATTR_SUBDIR); + if (err) { + exfat_err("failed to create LOST+FOUND directory\n"); + return err; + } + + if (fsync(exfat_fsck.exfat->blk_dev->dev_fd) != 0) { + exfat_err("failed to sync()\n"); + return -EIO; + } + err = read_lostfound(exfat, &lostfound); if (err) { exfat_err("failed to find LOST+FOUND\n"); @@ -1455,17 +1465,6 @@ static int rescue_orphan_clusters(struct exfat_fsck *fsck) } dset[1].dentry.stream.flags |= EXFAT_SF_CONTIGUOUS; - clu_count = le32_to_cpu(exfat->bs->bsx.clu_count); - - /* find clusters which are not marked as free, but not allocated to - * any files. - */ - disk_b = (bitmap_t *)exfat->disk_bitmap; - alloc_b = (bitmap_t *)exfat->alloc_bitmap; - ohead_b = (bitmap_t *)exfat->ohead_bitmap; - for (i = 0; i < EXFAT_BITMAP_SIZE(clu_count) / sizeof(bitmap_t); i++) - ohead_b[i] = disk_b[i] & ~alloc_b[i]; - /* create temporary files and allocate contiguous orphan clusters * to each file. */ @@ -1636,9 +1635,7 @@ int main(int argc, char * const argv[]) goto err; } - exfat_fsck.buffer_desc = exfat_alloc_buffer(2, - exfat_fsck.exfat->clus_size, - exfat_fsck.exfat->sect_size); + exfat_fsck.buffer_desc = exfat_alloc_buffer(exfat_fsck.exfat); if (!exfat_fsck.buffer_desc) { ret = -ENOMEM; goto err; @@ -1657,23 +1654,6 @@ int main(int argc, char * const argv[]) goto out; } - if (exfat_fsck.options & FSCK_OPTS_RESCUE_CLUS) { - ret = exfat_create_file(exfat_fsck.exfat, - exfat_fsck.exfat->root, - "LOST+FOUND", - ATTR_SUBDIR); - if (ret) { - exfat_err("failed to create lost+found directory\n"); - goto out; - } - - if (fsync(exfat_fsck.exfat->blk_dev->dev_fd) != 0) { - ret = -EIO; - exfat_err("failed to sync()\n"); - goto out; - } - } - exfat_debug("verifying directory entries...\n"); ret = exfat_filesystem_check(&exfat_fsck); if (ret) @@ -1715,7 +1695,7 @@ err: exit_code = FSCK_EXIT_NO_ERRORS; if (exfat_fsck.buffer_desc) - exfat_free_buffer(exfat_fsck.buffer_desc, 2); + exfat_free_buffer(exfat_fsck.exfat, exfat_fsck.buffer_desc); if (exfat_fsck.exfat) exfat_free_exfat(exfat_fsck.exfat); close(bd.dev_fd);