static int nodeck(struct exfat* ef, struct exfat_node* node) { const cluster_t cluster_size = CLUSTER_SIZE(*ef->sb); cluster_t clusters = (node->size + cluster_size - 1) / cluster_size; cluster_t c = node->start_cluster; int rc = 0; while (clusters--) { if (CLUSTER_INVALID(c)) { char name[UTF8_BYTES(EXFAT_NAME_MAX) + 1]; exfat_get_name(node, name, sizeof(name) - 1); exfat_error("file '%s' has invalid cluster 0x%x", name, c); rc = 1; break; } if (BMAP_GET(ef->cmap.chunk, c - EXFAT_FIRST_DATA_CLUSTER) == 0) { char name[UTF8_BYTES(EXFAT_NAME_MAX) + 1]; exfat_get_name(node, name, sizeof(name) - 1); exfat_error("cluster 0x%x of file '%s' is not allocated", c, name); rc = 1; } c = exfat_next_cluster(ef, node, c); } return rc; }
uint32_t exfat_count_free_clusters(const struct exfat* ef) { uint32_t free_clusters = 0; uint32_t i; for (i = 0; i < ef->cmap.size; i++) if (BMAP_GET(ef->cmap.chunk, i) == 0) free_clusters++; return free_clusters; }
static int find_used_clusters(const struct exfat* ef, cluster_t* a, cluster_t* b) { const cluster_t end = le32_to_cpu(ef->sb->cluster_count); /* find first used cluster */ for (*a = *b + 1; *a < end; (*a)++) if (BMAP_GET(ef->cmap.chunk, *a - EXFAT_FIRST_DATA_CLUSTER)) break; if (*a >= end) return 1; /* find last contiguous used cluster */ for (*b = *a; *b < end; (*b)++) if (BMAP_GET(ef->cmap.chunk, *b - EXFAT_FIRST_DATA_CLUSTER) == 0) { (*b)--; break; } return 0; }
static cluster_t find_bit_and_set(uint8_t* bitmap, cluster_t start, cluster_t end) { const cluster_t mid_start = (start + 7) / 8 * 8; const cluster_t mid_end = end / 8 * 8; cluster_t c; cluster_t byte; for (c = start; c < mid_start; c++) if (BMAP_GET(bitmap, c) == 0) { BMAP_SET(bitmap, c); return c + EXFAT_FIRST_DATA_CLUSTER; } for (byte = mid_start / 8; byte < mid_end / 8; byte++) if (bitmap[byte] != 0xff) { cluster_t bit; for (bit = 0; bit < 8; bit++) if (!(bitmap[byte] & (1u << bit))) { bitmap[byte] |= (1u << bit); return byte * 8 + bit + EXFAT_FIRST_DATA_CLUSTER; } } for (c = mid_end; c < end; c++) if (BMAP_GET(bitmap, c) == 0) { BMAP_SET(bitmap, c); return c + EXFAT_FIRST_DATA_CLUSTER; } return EXFAT_CLUSTER_END; }
static cluster_t find_bit_and_set(uint8_t* bitmap, size_t start, size_t end) { const size_t start_index = start / 8; const size_t end_index = DIV_ROUND_UP(end, 8); size_t i; size_t c; for (i = start_index; i < end_index; i++) { if (bitmap[i] == 0xff) continue; for (c = MAX(i * 8, start); c < MIN((i + 1) * 8, end); c++) if (BMAP_GET(bitmap, c) == 0) { BMAP_SET(bitmap, c); return c + EXFAT_FIRST_DATA_CLUSTER; } } return EXFAT_CLUSTER_END; }
static cluster_t find_bit_and_set(bitmap_t* bitmap, size_t start, size_t end) { const size_t start_index = start / sizeof(bitmap_t) / 8; const size_t end_index = DIV_ROUND_UP(end, sizeof(bitmap_t) * 8); size_t i; size_t start_bitindex; size_t end_bitindex; size_t c; for (i = start_index; i < end_index; i++) { if (bitmap[i] == ~((bitmap_t) 0)) continue; start_bitindex = MAX(i * sizeof(bitmap_t) * 8, start); end_bitindex = MIN((i + 1) * sizeof(bitmap_t) * 8, end); for (c = start_bitindex; c < end_bitindex; c++) if (BMAP_GET(bitmap, c) == 0) { BMAP_SET(bitmap, c); return c + EXFAT_FIRST_DATA_CLUSTER; } } return EXFAT_CLUSTER_END; }