- if (continuations != 0)
- {
- exfat_error("expected %hhu continuations before new entry",
- continuations);
- goto error;
- }
- meta1 = (const struct exfat_entry_meta1*) entry;
- continuations = meta1->continuations;
- /* each file entry must have at least 2 continuations:
- info and name */
- if (continuations < 2)
- {
- exfat_error("too few continuations (%hhu)", continuations);
- goto error;
- }
- if (continuations > 1 +
- DIV_ROUND_UP(EXFAT_NAME_MAX, EXFAT_ENAME_MAX))
- {
- exfat_error("too many continuations (%hhu)", continuations);
- goto error;
- }
- reference_checksum = le16_to_cpu(meta1->checksum);
- actual_checksum = exfat_start_checksum(meta1);
- *node = allocate_node();
- if (*node == NULL)
- {
- rc = -ENOMEM;
- goto error;
- }
- /* new node has zero reference counter */
- (*node)->entry_cluster = it->cluster;
- (*node)->entry_offset = it->offset;
- init_node_meta1(*node, meta1);
- namep = (*node)->name;
- break;
-
- case EXFAT_ENTRY_FILE_INFO:
- if (continuations < 2)
- {
- exfat_error("unexpected continuation (%hhu)",
- continuations);
- goto error;
- }
- meta2 = (const struct exfat_entry_meta2*) entry;
- if (meta2->flags & ~(EXFAT_FLAG_ALWAYS1 | EXFAT_FLAG_CONTIGUOUS))
- {
- exfat_error("unknown flags in meta2 (0x%hhx)", meta2->flags);
- goto error;
- }
- init_node_meta2(*node, meta2);
- actual_checksum = exfat_add_checksum(entry, actual_checksum);
- valid_size = le64_to_cpu(meta2->valid_size);
- --continuations;
- break;
-
- case EXFAT_ENTRY_FILE_NAME:
- if (continuations == 0)
- {
- exfat_error("unexpected continuation");
- goto error;
- }
- file_name = (const struct exfat_entry_name*) entry;
- actual_checksum = exfat_add_checksum(entry, actual_checksum);
-
- memcpy(namep, file_name->name,
- MIN(EXFAT_ENAME_MAX,
- ((*node)->name + EXFAT_NAME_MAX - namep)) *
- sizeof(le16_t));
- namep += EXFAT_ENAME_MAX;
- if (--continuations == 0)
- {
- if (!check_node(*node, actual_checksum, reference_checksum,
- valid_size, CLUSTER_SIZE(*ef->sb)))
- goto error;
- if (!fetch_next_entry(ef, parent, it))
- goto error;
- return 0; /* entry completed */
- }
- break;