3 * exFAT file system implementation library.
5 * Created by Andrew Nayenko on 09.10.09.
6 * This software is distributed under the GNU General Public License
7 * version 3 or any later.
15 /* on-disk nodes iterator */
24 struct exfat_node* exfat_get_node(struct exfat_node* node)
26 /* if we switch to multi-threaded mode we will need atomic
27 increment here and atomic decrement in exfat_put_node() */
32 void exfat_put_node(struct exfat* ef, struct exfat_node* node)
34 if (--node->references < 0)
36 char buffer[EXFAT_NAME_MAX + 1];
37 exfat_get_name(node, buffer, EXFAT_NAME_MAX);
38 exfat_bug("reference counter of `%s' is below zero", buffer);
41 if (node->references == 0)
43 if (node->flags & EXFAT_ATTRIB_DIRTY)
44 exfat_flush_node(ef, node);
45 if (node->flags & EXFAT_ATTRIB_UNLINKED)
47 /* free all clusters and node structure itself */
48 exfat_truncate(ef, node, 0);
56 static int opendir(struct exfat* ef, const struct exfat_node* dir,
59 if (!(dir->flags & EXFAT_ATTRIB_DIR))
60 exfat_bug("not a directory");
61 it->cluster = dir->start_cluster;
63 it->contiguous = IS_CONTIGUOUS(*dir);
64 it->chunk = malloc(CLUSTER_SIZE(*ef->sb));
65 if (it->chunk == NULL)
67 exfat_error("out of memory");
70 exfat_read_raw(it->chunk, CLUSTER_SIZE(*ef->sb),
71 exfat_c2o(ef, it->cluster), ef->fd);
75 static void closedir(struct iterator* it)
84 static int fetch_next_entry(struct exfat* ef, const struct exfat_node* parent,
87 /* move iterator to the next entry in the directory */
88 it->offset += sizeof(struct exfat_entry);
89 /* fetch the next cluster if needed */
90 if ((it->offset & (CLUSTER_SIZE(*ef->sb) - 1)) == 0)
92 it->cluster = exfat_next_cluster(ef, parent, it->cluster);
93 if (CLUSTER_INVALID(it->cluster))
95 exfat_error("invalid cluster while reading directory");
98 exfat_read_raw(it->chunk, CLUSTER_SIZE(*ef->sb),
99 exfat_c2o(ef, it->cluster), ef->fd);
104 static struct exfat_node* allocate_node(void)
106 struct exfat_node* node = malloc(sizeof(struct exfat_node));
109 exfat_error("failed to allocate node");
112 memset(node, 0, sizeof(struct exfat_node));
116 static void init_node_meta1(struct exfat_node* node,
117 const struct exfat_file* meta1)
119 node->flags = le16_to_cpu(meta1->attrib);
120 node->mtime = exfat_exfat2unix(meta1->mdate, meta1->mtime);
121 node->atime = exfat_exfat2unix(meta1->adate, meta1->atime);
124 static void init_node_meta2(struct exfat_node* node,
125 const struct exfat_file_info* meta2)
127 node->size = le64_to_cpu(meta2->size);
128 node->start_cluster = le32_to_cpu(meta2->start_cluster);
129 node->fptr_cluster = node->start_cluster;
130 if (meta2->flag == EXFAT_FLAG_CONTIGUOUS)
131 node->flags |= EXFAT_ATTRIB_CONTIGUOUS;
135 * Reads one entry in directory at position pointed by iterator and fills
138 static int readdir(struct exfat* ef, const struct exfat_node* parent,
139 struct exfat_node** node, struct iterator* it)
141 const struct exfat_entry* entry;
142 const struct exfat_file* file;
143 const struct exfat_file_info* file_info;
144 const struct exfat_file_name* file_name;
145 const struct exfat_upcase* upcase;
146 const struct exfat_bitmap* bitmap;
147 const struct exfat_label* label;
148 uint8_t continuations = 0;
149 le16_t* namep = NULL;
150 uint16_t reference_checksum = 0;
151 uint16_t actual_checksum = 0;
157 /* every directory (even empty one) occupies at least one cluster and
158 must contain EOD entry */
159 entry = (const struct exfat_entry*)
160 (it->chunk + it->offset % CLUSTER_SIZE(*ef->sb));
164 case EXFAT_ENTRY_EOD:
165 if (continuations != 0)
167 exfat_error("expected %hhu continuations before EOD",
171 return -ENOENT; /* that's OK, means end of directory */
173 case EXFAT_ENTRY_FILE:
174 if (continuations != 0)
176 exfat_error("expected %hhu continuations before new entry",
180 file = (const struct exfat_file*) entry;
181 continuations = file->continuations;
182 /* each file entry must have at least 2 continuations:
184 if (continuations < 2)
186 exfat_error("too few continuations (%hhu)", continuations);
189 reference_checksum = le16_to_cpu(file->checksum);
190 actual_checksum = exfat_start_checksum(file);
191 *node = allocate_node();
194 /* new node has zero reference counter */
195 (*node)->entry_cluster = it->cluster;
196 (*node)->entry_offset = it->offset % CLUSTER_SIZE(*ef->sb);
197 init_node_meta1(*node, file);
198 namep = (*node)->name;
201 case EXFAT_ENTRY_FILE_INFO:
202 if (continuations < 2)
204 exfat_error("unexpected continuation (%hhu)",
208 file_info = (const struct exfat_file_info*) entry;
209 init_node_meta2(*node, file_info);
210 actual_checksum = exfat_add_checksum(entry, actual_checksum);
211 /* There are two fields that contain file size. Maybe they plan
212 to add compression support in the future and one of those
213 fields is visible (uncompressed) size and the other is real
214 (compressed) size. Anyway, currently it looks like exFAT does
215 not support compression and both fields must be equal. */
216 if (le64_to_cpu(file_info->real_size) != (*node)->size)
218 exfat_error("real size does not equal to size "
219 "(%"PRIu64" != %"PRIu64")",
220 le64_to_cpu(file_info->real_size), (*node)->size);
223 /* directories must be aligned on at cluster boundary */
224 if (((*node)->flags & EXFAT_ATTRIB_DIR) &&
225 (*node)->size % CLUSTER_SIZE(*ef->sb) != 0)
227 char buffer[EXFAT_NAME_MAX + 1];
229 exfat_get_name(*node, buffer, EXFAT_NAME_MAX);
230 exfat_error("directory `%s' has invalid size %"PRIu64" bytes",
231 buffer, (*node)->size);
237 case EXFAT_ENTRY_FILE_NAME:
238 if (continuations == 0)
240 exfat_error("unexpected continuation");
243 file_name = (const struct exfat_file_name*) entry;
244 actual_checksum = exfat_add_checksum(entry, actual_checksum);
246 memcpy(namep, file_name->name, EXFAT_ENAME_MAX * sizeof(le16_t));
247 namep += EXFAT_ENAME_MAX;
248 if (--continuations == 0)
250 if (actual_checksum != reference_checksum)
252 exfat_error("invalid checksum (0x%hx != 0x%hx)",
253 actual_checksum, reference_checksum);
256 if (fetch_next_entry(ef, parent, it) != 0)
258 return 0; /* entry completed */
262 case EXFAT_ENTRY_UPCASE:
263 if (ef->upcase != NULL)
265 upcase = (const struct exfat_upcase*) entry;
266 if (CLUSTER_INVALID(le32_to_cpu(upcase->start_cluster)))
268 exfat_error("invalid cluster in upcase table");
271 if (le64_to_cpu(upcase->size) == 0 ||
272 le64_to_cpu(upcase->size) > 0xffff * sizeof(uint16_t) ||
273 le64_to_cpu(upcase->size) % sizeof(uint16_t) != 0)
275 exfat_error("bad upcase table size (%"PRIu64" bytes)",
276 le64_to_cpu(upcase->size));
279 ef->upcase = malloc(le64_to_cpu(upcase->size));
280 if (ef->upcase == NULL)
282 exfat_error("failed to allocate upcase table (%"PRIu64" bytes)",
283 le64_to_cpu(upcase->size));
286 ef->upcase_chars = le64_to_cpu(upcase->size) / sizeof(le16_t);
288 exfat_read_raw(ef->upcase, le64_to_cpu(upcase->size),
289 exfat_c2o(ef, le32_to_cpu(upcase->start_cluster)), ef->fd);
292 case EXFAT_ENTRY_BITMAP:
293 bitmap = (const struct exfat_bitmap*) entry;
294 if (CLUSTER_INVALID(le32_to_cpu(bitmap->start_cluster)))
296 exfat_error("invalid cluster in clusters bitmap");
299 ef->cmap.size = le32_to_cpu(ef->sb->cluster_count) -
300 EXFAT_FIRST_DATA_CLUSTER;
301 if (le64_to_cpu(bitmap->size) != (ef->cmap.size + 7) / 8)
303 exfat_error("invalid bitmap size: %"PRIu64" (expected %u)",
304 le64_to_cpu(bitmap->size), (ef->cmap.size + 7) / 8);
307 ef->cmap.start_cluster = le32_to_cpu(bitmap->start_cluster);
308 /* FIXME bitmap can be rather big, up to 512 MB */
309 ef->cmap.chunk_size = ef->cmap.size;
310 ef->cmap.chunk = malloc(le64_to_cpu(bitmap->size));
311 if (ef->cmap.chunk == NULL)
313 exfat_error("failed to allocate clusters map chunk "
314 "(%"PRIu64" bytes)", le64_to_cpu(bitmap->size));
318 exfat_read_raw(ef->cmap.chunk, le64_to_cpu(bitmap->size),
319 exfat_c2o(ef, ef->cmap.start_cluster), ef->fd);
322 case EXFAT_ENTRY_LABEL:
323 label = (const struct exfat_label*) entry;
324 if (label->length > EXFAT_ENAME_MAX)
326 exfat_error("too long label (%hhu chars)", label->length);
332 if (entry->type & EXFAT_ENTRY_VALID)
334 exfat_error("unknown entry type 0x%hhu", entry->type);
340 if (fetch_next_entry(ef, parent, it) != 0)
343 /* we never reach here */
351 int exfat_cache_directory(struct exfat* ef, struct exfat_node* dir)
355 struct exfat_node* node;
356 struct exfat_node* current = NULL;
358 if (dir->flags & EXFAT_ATTRIB_CACHED)
359 return 0; /* already cached */
361 rc = opendir(ef, dir, &it);
364 while ((rc = readdir(ef, dir, &node, &it)) == 0)
369 current->next = node;
370 node->prev = current;
382 for (current = dir->child; current; current = node)
384 node = current->next;
391 dir->flags |= EXFAT_ATTRIB_CACHED;
395 static void reset_cache(struct exfat* ef, struct exfat_node* node)
397 struct exfat_node* child;
398 struct exfat_node* next;
400 for (child = node->child; child; child = next)
402 reset_cache(ef, child);
406 if (node->references != 0)
408 char buffer[EXFAT_NAME_MAX + 1];
409 exfat_get_name(node, buffer, EXFAT_NAME_MAX);
410 exfat_warn("non-zero reference counter (%d) for `%s'",
411 node->references, buffer);
413 while (node->references--)
414 exfat_put_node(ef, node);
416 node->flags &= ~EXFAT_ATTRIB_CACHED;
419 void exfat_reset_cache(struct exfat* ef)
421 reset_cache(ef, ef->root);
424 void next_entry(struct exfat* ef, const struct exfat_node* parent,
425 cluster_t* cluster, off_t* offset)
427 if (*offset + sizeof(struct exfat_entry) == CLUSTER_SIZE(*ef->sb))
429 /* next cluster cannot be invalid */
430 *cluster = exfat_next_cluster(ef, parent, *cluster);
434 *offset += sizeof(struct exfat_entry);
438 void exfat_flush_node(struct exfat* ef, struct exfat_node* node)
442 off_t meta1_offset, meta2_offset;
443 struct exfat_file meta1;
444 struct exfat_file_info meta2;
447 exfat_bug("unable to flush node to read-only FS");
449 if (node->parent == NULL)
450 return; /* do not flush unlinked node */
452 cluster = node->entry_cluster;
453 offset = node->entry_offset;
454 meta1_offset = exfat_c2o(ef, cluster) + offset;
455 next_entry(ef, node->parent, &cluster, &offset);
456 meta2_offset = exfat_c2o(ef, cluster) + offset;
458 exfat_read_raw(&meta1, sizeof(meta1), meta1_offset, ef->fd);
459 if (meta1.type != EXFAT_ENTRY_FILE)
460 exfat_bug("invalid type of meta1: 0x%hhx", meta1.type);
461 meta1.attrib = cpu_to_le16(node->flags);
462 exfat_unix2exfat(node->mtime, &meta1.mdate, &meta1.mtime);
463 exfat_unix2exfat(node->atime, &meta1.adate, &meta1.atime);
465 exfat_read_raw(&meta2, sizeof(meta2), meta2_offset, ef->fd);
466 if (meta2.type != EXFAT_ENTRY_FILE_INFO)
467 exfat_bug("invalid type of meta2: 0x%hhx", meta2.type);
468 meta2.size = meta2.real_size = cpu_to_le64(node->size);
469 meta2.start_cluster = cpu_to_le32(node->start_cluster);
470 /* empty files must be marked as fragmented */
471 if (node->size != 0 && IS_CONTIGUOUS(*node))
472 meta2.flag = EXFAT_FLAG_CONTIGUOUS;
474 meta2.flag = EXFAT_FLAG_FRAGMENTED;
475 /* name hash remains unchanged, no need to recalculate it */
477 meta1.checksum = exfat_calc_checksum(&meta1, &meta2, node->name);
479 exfat_write_raw(&meta1, sizeof(meta1), meta1_offset, ef->fd);
480 exfat_write_raw(&meta2, sizeof(meta2), meta2_offset, ef->fd);
482 node->flags &= ~EXFAT_ATTRIB_DIRTY;
485 static void erase_entry(struct exfat* ef, struct exfat_node* node)
487 cluster_t cluster = node->entry_cluster;
488 off_t offset = node->entry_offset;
489 int name_entries = DIV_ROUND_UP(utf16_length(node->name), EXFAT_ENAME_MAX);
492 entry_type = EXFAT_ENTRY_FILE & ~EXFAT_ENTRY_VALID;
493 exfat_write_raw(&entry_type, 1, exfat_c2o(ef, cluster) + offset, ef->fd);
495 next_entry(ef, node->parent, &cluster, &offset);
496 entry_type = EXFAT_ENTRY_FILE_INFO & ~EXFAT_ENTRY_VALID;
497 exfat_write_raw(&entry_type, 1, exfat_c2o(ef, cluster) + offset, ef->fd);
499 while (name_entries--)
501 next_entry(ef, node->parent, &cluster, &offset);
502 entry_type = EXFAT_ENTRY_FILE_NAME & ~EXFAT_ENTRY_VALID;
503 exfat_write_raw(&entry_type, 1, exfat_c2o(ef, cluster) + offset,
508 static void tree_detach(struct exfat_node* node)
511 node->prev->next = node->next;
512 else /* this is the first node in the list */
513 node->parent->child = node->next;
515 node->next->prev = node->prev;
521 static void tree_attach(struct exfat_node* dir, struct exfat_node* node)
526 dir->child->prev = node;
527 node->next = dir->child;
532 static void delete(struct exfat* ef, struct exfat_node* node)
534 erase_entry(ef, node);
535 exfat_update_mtime(node->parent);
537 /* file clusters will be freed when node reference counter becomes 0 */
538 node->flags |= EXFAT_ATTRIB_UNLINKED;
541 int exfat_unlink(struct exfat* ef, struct exfat_node* node)
543 if (node->flags & EXFAT_ATTRIB_DIR)
549 int exfat_rmdir(struct exfat* ef, struct exfat_node* node)
551 if (!(node->flags & EXFAT_ATTRIB_DIR))
553 /* check that directory is empty */
554 exfat_cache_directory(ef, node);
561 static int grow_directory(struct exfat* ef, struct exfat_node* dir,
562 uint64_t asize, uint32_t difference)
564 return exfat_truncate(ef, dir,
565 DIV_ROUND_UP(asize + difference, CLUSTER_SIZE(*ef->sb))
566 * CLUSTER_SIZE(*ef->sb));
569 static void write_eod(struct exfat* ef, struct exfat_node* dir,
570 cluster_t cluster, off_t offset, int seek)
572 struct exfat_entry eod;
575 next_entry(ef, dir, &cluster, &offset);
576 memset(&eod, 0, sizeof(struct exfat_entry));
577 exfat_write_raw(&eod, sizeof(struct exfat_entry),
578 exfat_c2o(ef, cluster) + offset, ef->fd);
581 static int find_slot(struct exfat* ef, struct exfat_node* dir,
582 cluster_t* cluster, off_t* offset, int subentries)
586 const struct exfat_entry* entry;
589 rc = opendir(ef, dir, &it);
596 *cluster = it.cluster;
597 *offset = it.offset % CLUSTER_SIZE(*ef->sb);
599 entry = (const struct exfat_entry*)
600 (it.chunk + it.offset % CLUSTER_SIZE(*ef->sb));
601 if (entry->type == EXFAT_ENTRY_EOD)
603 rc = grow_directory(ef, dir,
604 it.offset + sizeof(struct exfat_entry), /* actual size */
605 (subentries - contiguous) * sizeof(struct exfat_entry));
611 write_eod(ef, dir, *cluster, *offset, subentries - contiguous);
614 if (entry->type & EXFAT_ENTRY_VALID)
618 if (contiguous == subentries)
619 break; /* suitable slot it found */
620 if (fetch_next_entry(ef, dir, &it) != 0)
630 static int write_entry(struct exfat* ef, struct exfat_node* dir,
631 const le16_t* name, cluster_t cluster, off_t offset, uint16_t attrib)
633 struct exfat_node* node;
634 struct exfat_file meta1;
635 struct exfat_file_info meta2;
636 const size_t name_length = utf16_length(name);
637 const int name_entries = DIV_ROUND_UP(name_length, EXFAT_ENAME_MAX);
640 node = allocate_node();
643 node->entry_cluster = cluster;
644 node->entry_offset = offset;
645 memcpy(node->name, name, name_length * sizeof(le16_t));
647 memset(&meta1, 0, sizeof(meta1));
648 meta1.type = EXFAT_ENTRY_FILE;
649 meta1.continuations = 1 + name_entries;
650 meta1.attrib = cpu_to_le16(attrib);
651 exfat_unix2exfat(time(NULL), &meta1.crdate, &meta1.crtime);
652 meta1.adate = meta1.mdate = meta1.crdate;
653 meta1.atime = meta1.mtime = meta1.crtime;
654 /* crtime_cs and mtime_cs contain addition to the time in centiseconds;
655 just ignore those fields because we operate with 2 sec resolution */
657 memset(&meta2, 0, sizeof(meta2));
658 meta2.type = EXFAT_ENTRY_FILE_INFO;
659 meta2.flag = EXFAT_FLAG_FRAGMENTED;
660 meta2.name_length = name_length;
661 meta2.name_hash = exfat_calc_name_hash(ef, node->name);
662 meta2.start_cluster = cpu_to_le32(EXFAT_CLUSTER_FREE);
664 meta1.checksum = exfat_calc_checksum(&meta1, &meta2, node->name);
666 exfat_write_raw(&meta1, sizeof(meta1), exfat_c2o(ef, cluster) + offset,
668 next_entry(ef, dir, &cluster, &offset);
669 exfat_write_raw(&meta2, sizeof(meta2), exfat_c2o(ef, cluster) + offset,
671 for (i = 0; i < name_entries; i++)
673 struct exfat_file_name name_entry = {EXFAT_ENTRY_FILE_NAME, 0};
674 memcpy(name_entry.name, node->name + i * EXFAT_ENAME_MAX,
675 EXFAT_ENAME_MAX * sizeof(le16_t));
676 next_entry(ef, dir, &cluster, &offset);
677 exfat_write_raw(&name_entry, sizeof(name_entry),
678 exfat_c2o(ef, cluster) + offset, ef->fd);
681 init_node_meta1(node, &meta1);
682 init_node_meta2(node, &meta2);
684 tree_attach(dir, node);
685 exfat_update_mtime(dir);
689 static int create(struct exfat* ef, const char* path, uint16_t attrib)
691 struct exfat_node* dir;
692 cluster_t cluster = EXFAT_CLUSTER_BAD;
694 le16_t name[EXFAT_NAME_MAX + 1];
697 /* FIXME filter name characters */
699 rc = exfat_split(ef, &dir, name, path);
703 rc = find_slot(ef, dir, &cluster, &offset,
704 2 + DIV_ROUND_UP(utf16_length(name), EXFAT_ENAME_MAX));
707 exfat_put_node(ef, dir);
710 rc = write_entry(ef, dir, name, cluster, offset, attrib);
711 exfat_put_node(ef, dir);
715 int exfat_mknod(struct exfat* ef, const char* path)
717 return create(ef, path, EXFAT_ATTRIB_ARCH);
720 int exfat_mkdir(struct exfat* ef, const char* path)
723 struct exfat_node* node;
725 rc = create(ef, path, EXFAT_ATTRIB_ARCH | EXFAT_ATTRIB_DIR);
728 rc = exfat_lookup(ef, &node, path);
731 /* directories always have at least one cluster */
732 rc = exfat_truncate(ef, node, CLUSTER_SIZE(*ef->sb));
736 exfat_put_node(ef, node);
739 exfat_put_node(ef, node);
743 void exfat_utimes(struct exfat_node* node, const struct timespec tv[2])
745 node->atime = tv[0].tv_sec;
746 node->mtime = tv[1].tv_sec;
747 node->flags |= EXFAT_ATTRIB_DIRTY;
750 void exfat_update_atime(struct exfat_node* node)
752 node->atime = time(NULL);
753 node->flags |= EXFAT_ATTRIB_DIRTY;
756 void exfat_update_mtime(struct exfat_node* node)
758 node->mtime = time(NULL);
759 node->flags |= EXFAT_ATTRIB_DIRTY;