3 exFAT file system implementation library.
5 Copyright (C) 2009, 2010 Andrew Nayenko
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 /* on-disk nodes iterator */
35 struct exfat_node* exfat_get_node(struct exfat_node* node)
37 /* if we switch to multi-threaded mode we will need atomic
38 increment here and atomic decrement in exfat_put_node() */
43 void exfat_put_node(struct exfat* ef, struct exfat_node* node)
45 if (--node->references < 0)
47 char buffer[EXFAT_NAME_MAX + 1];
48 exfat_get_name(node, buffer, EXFAT_NAME_MAX);
49 exfat_bug("reference counter of `%s' is below zero", buffer);
52 if (node->references == 0)
54 if (node->flags & EXFAT_ATTRIB_DIRTY)
55 exfat_flush_node(ef, node);
56 if (node->flags & EXFAT_ATTRIB_UNLINKED)
58 /* free all clusters and node structure itself */
59 exfat_truncate(ef, node, 0);
68 * Cluster + offset from the beginning of the directory to absolute offset.
70 static off_t co2o(struct exfat* ef, cluster_t cluster, off_t offset)
72 return exfat_c2o(ef, cluster) + offset % CLUSTER_SIZE(*ef->sb);
75 static int opendir(struct exfat* ef, const struct exfat_node* dir,
78 if (!(dir->flags & EXFAT_ATTRIB_DIR))
79 exfat_bug("not a directory");
80 it->cluster = dir->start_cluster;
82 it->contiguous = IS_CONTIGUOUS(*dir);
83 it->chunk = malloc(CLUSTER_SIZE(*ef->sb));
84 if (it->chunk == NULL)
86 exfat_error("out of memory");
89 exfat_read_raw(it->chunk, CLUSTER_SIZE(*ef->sb),
90 exfat_c2o(ef, it->cluster), ef->fd);
94 static void closedir(struct iterator* it)
103 static int fetch_next_entry(struct exfat* ef, const struct exfat_node* parent,
106 /* move iterator to the next entry in the directory */
107 it->offset += sizeof(struct exfat_entry);
108 /* fetch the next cluster if needed */
109 if ((it->offset & (CLUSTER_SIZE(*ef->sb) - 1)) == 0)
111 it->cluster = exfat_next_cluster(ef, parent, it->cluster);
112 if (CLUSTER_INVALID(it->cluster))
114 exfat_error("invalid cluster while reading directory");
117 exfat_read_raw(it->chunk, CLUSTER_SIZE(*ef->sb),
118 exfat_c2o(ef, it->cluster), ef->fd);
123 static struct exfat_node* allocate_node(void)
125 struct exfat_node* node = malloc(sizeof(struct exfat_node));
128 exfat_error("failed to allocate node");
131 memset(node, 0, sizeof(struct exfat_node));
135 static void init_node_meta1(struct exfat_node* node,
136 const struct exfat_entry_meta1* meta1)
138 node->flags = le16_to_cpu(meta1->attrib);
139 node->mtime = exfat_exfat2unix(meta1->mdate, meta1->mtime,
141 /* there is no centiseconds field for atime */
142 node->atime = exfat_exfat2unix(meta1->adate, meta1->atime, 0);
145 static void init_node_meta2(struct exfat_node* node,
146 const struct exfat_entry_meta2* meta2)
148 node->size = le64_to_cpu(meta2->size);
149 node->start_cluster = le32_to_cpu(meta2->start_cluster);
150 node->fptr_cluster = node->start_cluster;
151 if (meta2->flags & EXFAT_FLAG_CONTIGUOUS)
152 node->flags |= EXFAT_ATTRIB_CONTIGUOUS;
155 static const struct exfat_entry* get_entry_ptr(const struct exfat* ef,
156 const struct iterator* it)
158 return (const struct exfat_entry*)
159 (it->chunk + it->offset % CLUSTER_SIZE(*ef->sb));
163 * Reads one entry in directory at position pointed by iterator and fills
166 static int readdir(struct exfat* ef, const struct exfat_node* parent,
167 struct exfat_node** node, struct iterator* it)
169 const struct exfat_entry* entry;
170 const struct exfat_entry_meta1* meta1;
171 const struct exfat_entry_meta2* meta2;
172 const struct exfat_entry_name* file_name;
173 const struct exfat_entry_upcase* upcase;
174 const struct exfat_entry_bitmap* bitmap;
175 const struct exfat_entry_label* label;
176 uint8_t continuations = 0;
177 le16_t* namep = NULL;
178 uint16_t reference_checksum = 0;
179 uint16_t actual_checksum = 0;
185 /* every directory (even empty one) occupies at least one cluster and
186 must contain EOD entry */
187 entry = get_entry_ptr(ef, it);
191 case EXFAT_ENTRY_EOD:
192 if (continuations != 0)
194 exfat_error("expected %hhu continuations before EOD",
198 return -ENOENT; /* that's OK, means end of directory */
200 case EXFAT_ENTRY_FILE:
201 if (continuations != 0)
203 exfat_error("expected %hhu continuations before new entry",
207 meta1 = (const struct exfat_entry_meta1*) entry;
208 continuations = meta1->continuations;
209 /* each file entry must have at least 2 continuations:
211 if (continuations < 2)
213 exfat_error("too few continuations (%hhu)", continuations);
216 reference_checksum = le16_to_cpu(meta1->checksum);
217 actual_checksum = exfat_start_checksum(meta1);
218 *node = allocate_node();
221 /* new node has zero reference counter */
222 (*node)->entry_cluster = it->cluster;
223 (*node)->entry_offset = it->offset;
224 init_node_meta1(*node, meta1);
225 namep = (*node)->name;
228 case EXFAT_ENTRY_FILE_INFO:
229 if (continuations < 2)
231 exfat_error("unexpected continuation (%hhu)",
235 meta2 = (const struct exfat_entry_meta2*) entry;
236 if (meta2->flags & ~(EXFAT_FLAG_ALWAYS1 | EXFAT_FLAG_CONTIGUOUS))
238 exfat_error("unknown flags in meta2 (0x%hhx)", meta2->flags);
241 init_node_meta2(*node, meta2);
242 actual_checksum = exfat_add_checksum(entry, actual_checksum);
243 /* There are two fields that contain file size. Maybe they plan
244 to add compression support in the future and one of those
245 fields is visible (uncompressed) size and the other is real
246 (compressed) size. Anyway, currently it looks like exFAT does
247 not support compression and both fields must be equal. */
248 if (le64_to_cpu(meta2->real_size) != (*node)->size)
250 exfat_error("real size does not equal to size "
251 "(%"PRIu64" != %"PRIu64")",
252 le64_to_cpu(meta2->real_size), (*node)->size);
255 /* empty files must be marked as non-contiguous */
256 if ((*node)->size == 0 && (meta2->flags & EXFAT_FLAG_CONTIGUOUS))
258 exfat_error("empty file marked as contiguous (0x%hhx)",
262 /* directories must be aligned on at cluster boundary */
263 if (((*node)->flags & EXFAT_ATTRIB_DIR) &&
264 (*node)->size % CLUSTER_SIZE(*ef->sb) != 0)
266 char buffer[EXFAT_NAME_MAX + 1];
268 exfat_get_name(*node, buffer, EXFAT_NAME_MAX);
269 exfat_error("directory `%s' has invalid size %"PRIu64" bytes",
270 buffer, (*node)->size);
276 case EXFAT_ENTRY_FILE_NAME:
277 if (continuations == 0)
279 exfat_error("unexpected continuation");
282 file_name = (const struct exfat_entry_name*) entry;
283 actual_checksum = exfat_add_checksum(entry, actual_checksum);
285 memcpy(namep, file_name->name, EXFAT_ENAME_MAX * sizeof(le16_t));
286 namep += EXFAT_ENAME_MAX;
287 if (--continuations == 0)
289 if (actual_checksum != reference_checksum)
291 exfat_error("invalid checksum (0x%hx != 0x%hx)",
292 actual_checksum, reference_checksum);
295 if (fetch_next_entry(ef, parent, it) != 0)
297 return 0; /* entry completed */
301 case EXFAT_ENTRY_UPCASE:
302 if (ef->upcase != NULL)
304 upcase = (const struct exfat_entry_upcase*) entry;
305 if (CLUSTER_INVALID(le32_to_cpu(upcase->start_cluster)))
307 exfat_error("invalid cluster in upcase table");
310 if (le64_to_cpu(upcase->size) == 0 ||
311 le64_to_cpu(upcase->size) > 0xffff * sizeof(uint16_t) ||
312 le64_to_cpu(upcase->size) % sizeof(uint16_t) != 0)
314 exfat_error("bad upcase table size (%"PRIu64" bytes)",
315 le64_to_cpu(upcase->size));
318 ef->upcase = malloc(le64_to_cpu(upcase->size));
319 if (ef->upcase == NULL)
321 exfat_error("failed to allocate upcase table (%"PRIu64" bytes)",
322 le64_to_cpu(upcase->size));
325 ef->upcase_chars = le64_to_cpu(upcase->size) / sizeof(le16_t);
327 exfat_read_raw(ef->upcase, le64_to_cpu(upcase->size),
328 exfat_c2o(ef, le32_to_cpu(upcase->start_cluster)), ef->fd);
331 case EXFAT_ENTRY_BITMAP:
332 bitmap = (const struct exfat_entry_bitmap*) entry;
333 if (CLUSTER_INVALID(le32_to_cpu(bitmap->start_cluster)))
335 exfat_error("invalid cluster in clusters bitmap");
338 ef->cmap.size = le32_to_cpu(ef->sb->cluster_count) -
339 EXFAT_FIRST_DATA_CLUSTER;
340 if (le64_to_cpu(bitmap->size) < (ef->cmap.size + 7) / 8)
342 exfat_error("invalid clusters bitmap size: %"PRIu64
343 " (expected at least %u)",
344 le64_to_cpu(bitmap->size), (ef->cmap.size + 7) / 8);
347 ef->cmap.start_cluster = le32_to_cpu(bitmap->start_cluster);
348 /* FIXME bitmap can be rather big, up to 512 MB */
349 ef->cmap.chunk_size = ef->cmap.size;
350 ef->cmap.chunk = malloc(le64_to_cpu(bitmap->size));
351 if (ef->cmap.chunk == NULL)
353 exfat_error("failed to allocate clusters bitmap chunk "
354 "(%"PRIu64" bytes)", le64_to_cpu(bitmap->size));
358 exfat_read_raw(ef->cmap.chunk, le64_to_cpu(bitmap->size),
359 exfat_c2o(ef, ef->cmap.start_cluster), ef->fd);
362 case EXFAT_ENTRY_LABEL:
363 label = (const struct exfat_entry_label*) entry;
364 if (label->length > EXFAT_ENAME_MAX)
366 exfat_error("too long label (%hhu chars)", label->length);
369 if (utf16_to_utf8(ef->label, label->name,
370 sizeof(ef->label), EXFAT_ENAME_MAX) != 0)
375 if (entry->type & EXFAT_ENTRY_VALID)
377 exfat_error("unknown entry type 0x%hhx", entry->type);
383 if (fetch_next_entry(ef, parent, it) != 0)
386 /* we never reach here */
394 int exfat_cache_directory(struct exfat* ef, struct exfat_node* dir)
398 struct exfat_node* node;
399 struct exfat_node* current = NULL;
401 if (dir->flags & EXFAT_ATTRIB_CACHED)
402 return 0; /* already cached */
404 rc = opendir(ef, dir, &it);
407 while ((rc = readdir(ef, dir, &node, &it)) == 0)
412 current->next = node;
413 node->prev = current;
425 for (current = dir->child; current; current = node)
427 node = current->next;
434 dir->flags |= EXFAT_ATTRIB_CACHED;
438 static void reset_cache(struct exfat* ef, struct exfat_node* node)
440 struct exfat_node* child;
441 struct exfat_node* next;
443 for (child = node->child; child; child = next)
445 reset_cache(ef, child);
449 if (node->references != 0)
451 char buffer[EXFAT_NAME_MAX + 1];
452 exfat_get_name(node, buffer, EXFAT_NAME_MAX);
453 exfat_warn("non-zero reference counter (%d) for `%s'",
454 node->references, buffer);
456 while (node->references--)
457 exfat_put_node(ef, node);
459 node->flags &= ~EXFAT_ATTRIB_CACHED;
462 void exfat_reset_cache(struct exfat* ef)
464 reset_cache(ef, ef->root);
467 void next_entry(struct exfat* ef, const struct exfat_node* parent,
468 cluster_t* cluster, off_t* offset)
470 *offset += sizeof(struct exfat_entry);
471 if (*offset % CLUSTER_SIZE(*ef->sb) == 0)
472 /* next cluster cannot be invalid */
473 *cluster = exfat_next_cluster(ef, parent, *cluster);
476 void exfat_flush_node(struct exfat* ef, struct exfat_node* node)
480 off_t meta1_offset, meta2_offset;
481 struct exfat_entry_meta1 meta1;
482 struct exfat_entry_meta2 meta2;
485 exfat_bug("unable to flush node to read-only FS");
487 if (node->parent == NULL)
488 return; /* do not flush unlinked node */
490 cluster = node->entry_cluster;
491 offset = node->entry_offset;
492 meta1_offset = co2o(ef, cluster, offset);
493 next_entry(ef, node->parent, &cluster, &offset);
494 meta2_offset = co2o(ef, cluster, offset);
496 exfat_read_raw(&meta1, sizeof(meta1), meta1_offset, ef->fd);
497 if (meta1.type != EXFAT_ENTRY_FILE)
498 exfat_bug("invalid type of meta1: 0x%hhx", meta1.type);
499 meta1.attrib = cpu_to_le16(node->flags);
500 exfat_unix2exfat(node->mtime, &meta1.mdate, &meta1.mtime, &meta1.mtime_cs);
501 exfat_unix2exfat(node->atime, &meta1.adate, &meta1.atime, NULL);
503 exfat_read_raw(&meta2, sizeof(meta2), meta2_offset, ef->fd);
504 if (meta2.type != EXFAT_ENTRY_FILE_INFO)
505 exfat_bug("invalid type of meta2: 0x%hhx", meta2.type);
506 meta2.size = meta2.real_size = cpu_to_le64(node->size);
507 meta2.start_cluster = cpu_to_le32(node->start_cluster);
508 meta2.flags = EXFAT_FLAG_ALWAYS1;
509 /* empty files must not be marked as contiguous */
510 if (node->size != 0 && IS_CONTIGUOUS(*node))
511 meta2.flags |= EXFAT_FLAG_CONTIGUOUS;
512 /* name hash remains unchanged, no need to recalculate it */
514 meta1.checksum = exfat_calc_checksum(&meta1, &meta2, node->name);
516 exfat_write_raw(&meta1, sizeof(meta1), meta1_offset, ef->fd);
517 exfat_write_raw(&meta2, sizeof(meta2), meta2_offset, ef->fd);
519 node->flags &= ~EXFAT_ATTRIB_DIRTY;
522 static void erase_entry(struct exfat* ef, struct exfat_node* node)
524 cluster_t cluster = node->entry_cluster;
525 off_t offset = node->entry_offset;
526 int name_entries = DIV_ROUND_UP(utf16_length(node->name), EXFAT_ENAME_MAX);
529 entry_type = EXFAT_ENTRY_FILE & ~EXFAT_ENTRY_VALID;
530 exfat_write_raw(&entry_type, 1, co2o(ef, cluster, offset), ef->fd);
532 next_entry(ef, node->parent, &cluster, &offset);
533 entry_type = EXFAT_ENTRY_FILE_INFO & ~EXFAT_ENTRY_VALID;
534 exfat_write_raw(&entry_type, 1, co2o(ef, cluster, offset), ef->fd);
536 while (name_entries--)
538 next_entry(ef, node->parent, &cluster, &offset);
539 entry_type = EXFAT_ENTRY_FILE_NAME & ~EXFAT_ENTRY_VALID;
540 exfat_write_raw(&entry_type, 1, co2o(ef, cluster, offset), ef->fd);
544 static void tree_detach(struct exfat_node* node)
547 node->prev->next = node->next;
548 else /* this is the first node in the list */
549 node->parent->child = node->next;
551 node->next->prev = node->prev;
557 static void tree_attach(struct exfat_node* dir, struct exfat_node* node)
562 dir->child->prev = node;
563 node->next = dir->child;
568 static int shrink_directory(struct exfat* ef, struct exfat_node* dir,
569 off_t deleted_offset)
571 const struct exfat_node* node;
572 const struct exfat_node* last_node;
573 uint64_t entries = 1; /* a directory always has at leat 1 entry (EOD) */
575 struct exfat_entry eod;
579 if (!(dir->flags & EXFAT_ATTRIB_DIR))
580 exfat_bug("attempted to shrink a file");
581 if (!(dir->flags & EXFAT_ATTRIB_CACHED))
582 exfat_bug("attempted to shrink uncached directory");
584 for (last_node = node = dir->child; node; node = node->next)
586 if (deleted_offset < node->entry_offset)
588 /* there are other entries after the removed one, no way to shrink
592 if (last_node->entry_offset < node->entry_offset)
598 /* offset of the last entry */
599 entries += last_node->entry_offset / sizeof(struct exfat_entry);
600 /* two subentries with meta info */
602 /* subentries with file name */
603 entries += DIV_ROUND_UP(utf16_length(last_node->name),
607 new_size = DIV_ROUND_UP(entries * sizeof(struct exfat_entry),
608 CLUSTER_SIZE(*ef->sb)) * CLUSTER_SIZE(*ef->sb);
609 if (new_size == dir->size)
611 rc = exfat_truncate(ef, dir, new_size);
615 /* put EOD entry at the end of the last cluster */
616 memset(&eod, 0, sizeof(eod));
617 eod_offset = new_size - sizeof(struct exfat_entry);
619 exfat_write_raw(&eod, sizeof(eod),
620 co2o(ef, last_node->entry_cluster, eod_offset), ef->fd);
622 exfat_write_raw(&eod, sizeof(eod),
623 co2o(ef, dir->start_cluster, eod_offset), ef->fd);
627 static int delete(struct exfat* ef, struct exfat_node* node)
629 struct exfat_node* parent = node->parent;
630 off_t deleted_offset = node->entry_offset;
633 exfat_get_node(parent);
634 erase_entry(ef, node);
635 exfat_update_mtime(parent);
637 rc = shrink_directory(ef, parent, deleted_offset);
638 exfat_put_node(ef, parent);
639 /* file clusters will be freed when node reference counter becomes 0 */
640 node->flags |= EXFAT_ATTRIB_UNLINKED;
644 int exfat_unlink(struct exfat* ef, struct exfat_node* node)
646 if (node->flags & EXFAT_ATTRIB_DIR)
648 return delete(ef, node);
651 int exfat_rmdir(struct exfat* ef, struct exfat_node* node)
653 if (!(node->flags & EXFAT_ATTRIB_DIR))
655 /* check that directory is empty */
656 exfat_cache_directory(ef, node);
659 return delete(ef, node);
662 static int grow_directory(struct exfat* ef, struct exfat_node* dir,
663 uint64_t asize, uint32_t difference)
665 return exfat_truncate(ef, dir,
666 DIV_ROUND_UP(asize + difference, CLUSTER_SIZE(*ef->sb))
667 * CLUSTER_SIZE(*ef->sb));
670 static int find_slot(struct exfat* ef, struct exfat_node* dir,
671 cluster_t* cluster, off_t* offset, int subentries)
675 const struct exfat_entry* entry;
678 rc = opendir(ef, dir, &it);
685 *cluster = it.cluster;
688 entry = get_entry_ptr(ef, &it);
689 if (entry->type == EXFAT_ENTRY_EOD)
691 rc = grow_directory(ef, dir,
692 it.offset + sizeof(struct exfat_entry), /* actual size */
693 (subentries - contiguous) * sizeof(struct exfat_entry));
701 if (entry->type & EXFAT_ENTRY_VALID)
705 if (contiguous == subentries)
706 break; /* suitable slot is found */
707 if (fetch_next_entry(ef, dir, &it) != 0)
717 static int write_entry(struct exfat* ef, struct exfat_node* dir,
718 const le16_t* name, cluster_t cluster, off_t offset, uint16_t attrib)
720 struct exfat_node* node;
721 struct exfat_entry_meta1 meta1;
722 struct exfat_entry_meta2 meta2;
723 const size_t name_length = utf16_length(name);
724 const int name_entries = DIV_ROUND_UP(name_length, EXFAT_ENAME_MAX);
727 node = allocate_node();
730 node->entry_cluster = cluster;
731 node->entry_offset = offset;
732 memcpy(node->name, name, name_length * sizeof(le16_t));
734 memset(&meta1, 0, sizeof(meta1));
735 meta1.type = EXFAT_ENTRY_FILE;
736 meta1.continuations = 1 + name_entries;
737 meta1.attrib = cpu_to_le16(attrib);
738 exfat_unix2exfat(time(NULL), &meta1.crdate, &meta1.crtime,
740 meta1.adate = meta1.mdate = meta1.crdate;
741 meta1.atime = meta1.mtime = meta1.crtime;
742 /* crtime_cs and mtime_cs contain addition to the time in centiseconds;
743 just ignore those fields because we operate with 2 sec resolution */
745 memset(&meta2, 0, sizeof(meta2));
746 meta2.type = EXFAT_ENTRY_FILE_INFO;
747 meta2.flags = EXFAT_FLAG_ALWAYS1;
748 meta2.name_length = name_length;
749 meta2.name_hash = exfat_calc_name_hash(ef, node->name);
750 meta2.start_cluster = cpu_to_le32(EXFAT_CLUSTER_FREE);
752 meta1.checksum = exfat_calc_checksum(&meta1, &meta2, node->name);
754 exfat_write_raw(&meta1, sizeof(meta1), co2o(ef, cluster, offset), ef->fd);
755 next_entry(ef, dir, &cluster, &offset);
756 exfat_write_raw(&meta2, sizeof(meta2), co2o(ef, cluster, offset), ef->fd);
757 for (i = 0; i < name_entries; i++)
759 struct exfat_entry_name name_entry = {EXFAT_ENTRY_FILE_NAME, 0};
760 memcpy(name_entry.name, node->name + i * EXFAT_ENAME_MAX,
761 EXFAT_ENAME_MAX * sizeof(le16_t));
762 next_entry(ef, dir, &cluster, &offset);
763 exfat_write_raw(&name_entry, sizeof(name_entry),
764 co2o(ef, cluster, offset), ef->fd);
767 init_node_meta1(node, &meta1);
768 init_node_meta2(node, &meta2);
770 tree_attach(dir, node);
771 exfat_update_mtime(dir);
775 static int create(struct exfat* ef, const char* path, uint16_t attrib)
777 struct exfat_node* dir;
778 struct exfat_node* existing;
779 cluster_t cluster = EXFAT_CLUSTER_BAD;
781 le16_t name[EXFAT_NAME_MAX + 1];
784 rc = exfat_split(ef, &dir, &existing, name, path);
787 if (existing != NULL)
789 exfat_put_node(ef, existing);
790 exfat_put_node(ef, dir);
794 rc = find_slot(ef, dir, &cluster, &offset,
795 2 + DIV_ROUND_UP(utf16_length(name), EXFAT_ENAME_MAX));
798 exfat_put_node(ef, dir);
801 rc = write_entry(ef, dir, name, cluster, offset, attrib);
802 exfat_put_node(ef, dir);
806 int exfat_mknod(struct exfat* ef, const char* path)
808 return create(ef, path, EXFAT_ATTRIB_ARCH);
811 int exfat_mkdir(struct exfat* ef, const char* path)
814 struct exfat_node* node;
816 rc = create(ef, path, EXFAT_ATTRIB_ARCH | EXFAT_ATTRIB_DIR);
819 rc = exfat_lookup(ef, &node, path);
822 /* directories always have at least one cluster */
823 rc = exfat_truncate(ef, node, CLUSTER_SIZE(*ef->sb));
827 exfat_put_node(ef, node);
830 exfat_put_node(ef, node);
834 static void rename_entry(struct exfat* ef, struct exfat_node* dir,
835 struct exfat_node* node, const le16_t* name, cluster_t new_cluster,
838 struct exfat_entry_meta1 meta1;
839 struct exfat_entry_meta2 meta2;
840 cluster_t old_cluster = node->entry_cluster;
841 off_t old_offset = node->entry_offset;
842 const size_t name_length = utf16_length(name);
843 const int name_entries = DIV_ROUND_UP(name_length, EXFAT_ENAME_MAX);
846 exfat_read_raw(&meta1, sizeof(meta1), co2o(ef, old_cluster, old_offset),
848 next_entry(ef, node->parent, &old_cluster, &old_offset);
849 exfat_read_raw(&meta2, sizeof(meta2), co2o(ef, old_cluster, old_offset),
851 meta1.continuations = 1 + name_entries;
852 meta2.name_hash = exfat_calc_name_hash(ef, name);
853 meta2.name_length = name_length;
854 meta1.checksum = exfat_calc_checksum(&meta1, &meta2, name);
856 erase_entry(ef, node);
858 node->entry_cluster = new_cluster;
859 node->entry_offset = new_offset;
861 exfat_write_raw(&meta1, sizeof(meta1), co2o(ef, new_cluster, new_offset),
863 next_entry(ef, dir, &new_cluster, &new_offset);
864 exfat_write_raw(&meta2, sizeof(meta2), co2o(ef, new_cluster, new_offset),
867 for (i = 0; i < name_entries; i++)
869 struct exfat_entry_name name_entry = {EXFAT_ENTRY_FILE_NAME, 0};
870 memcpy(name_entry.name, name + i * EXFAT_ENAME_MAX,
871 EXFAT_ENAME_MAX * sizeof(le16_t));
872 next_entry(ef, dir, &new_cluster, &new_offset);
873 exfat_write_raw(&name_entry, sizeof(name_entry),
874 co2o(ef, new_cluster, new_offset), ef->fd);
877 memcpy(node->name, name, (EXFAT_NAME_MAX + 1) * sizeof(le16_t));
879 tree_attach(dir, node);
882 int exfat_rename(struct exfat* ef, const char* old_path, const char* new_path)
884 struct exfat_node* node;
885 struct exfat_node* existing;
886 struct exfat_node* dir;
887 cluster_t cluster = EXFAT_CLUSTER_BAD;
889 le16_t name[EXFAT_NAME_MAX + 1];
892 rc = exfat_lookup(ef, &node, old_path);
896 rc = exfat_split(ef, &dir, &existing, name, new_path);
899 exfat_put_node(ef, node);
902 if (existing != NULL)
904 if (existing->flags & EXFAT_ATTRIB_DIR)
906 if (node->flags & EXFAT_ATTRIB_DIR)
907 rc = exfat_rmdir(ef, existing);
913 if (!(node->flags & EXFAT_ATTRIB_DIR))
914 rc = exfat_unlink(ef, existing);
918 exfat_put_node(ef, existing);
921 exfat_put_node(ef, dir);
922 exfat_put_node(ef, node);
927 rc = find_slot(ef, dir, &cluster, &offset,
928 2 + DIV_ROUND_UP(utf16_length(name), EXFAT_ENAME_MAX));
931 exfat_put_node(ef, dir);
932 exfat_put_node(ef, node);
935 rename_entry(ef, dir, node, name, cluster, offset);
936 exfat_put_node(ef, dir);
937 exfat_put_node(ef, node);
941 void exfat_utimes(struct exfat_node* node, const struct timespec tv[2])
943 node->atime = tv[0].tv_sec;
944 node->mtime = tv[1].tv_sec;
945 node->flags |= EXFAT_ATTRIB_DIRTY;
948 void exfat_update_atime(struct exfat_node* node)
950 node->atime = time(NULL);
951 node->flags |= EXFAT_ATTRIB_DIRTY;
954 void exfat_update_mtime(struct exfat_node* node)
956 node->mtime = time(NULL);
957 node->flags |= EXFAT_ATTRIB_DIRTY;
960 const char* exfat_get_label(struct exfat* ef)
965 static int find_label(struct exfat* ef, cluster_t* cluster, off_t* offset)
969 const struct exfat_entry* entry;
971 rc = opendir(ef, ef->root, &it);
977 entry = get_entry_ptr(ef, &it);
979 if (entry->type == EXFAT_ENTRY_EOD)
984 if (entry->type == EXFAT_ENTRY_LABEL)
986 *cluster = it.cluster;
992 if (fetch_next_entry(ef, ef->root, &it) != 0)
1000 int exfat_set_label(struct exfat* ef, const char* label)
1002 le16_t label_utf16[EXFAT_ENAME_MAX + 1];
1006 struct exfat_entry_label entry;
1008 memset(label_utf16, 0, sizeof(label_utf16));
1009 rc = utf8_to_utf16(label_utf16, label, EXFAT_ENAME_MAX, strlen(label));
1013 rc = find_label(ef, &cluster, &offset);
1015 rc = find_slot(ef, ef->root, &cluster, &offset, 1);
1019 entry.type = EXFAT_ENTRY_LABEL;
1020 entry.length = utf16_length(label_utf16);
1021 memcpy(entry.name, label_utf16, sizeof(entry.name));
1022 if (entry.length == 0)
1023 entry.type ^= EXFAT_ENTRY_VALID;
1025 exfat_write_raw(&entry, sizeof(struct exfat_entry_label),
1026 co2o(ef, cluster, offset), ef->fd);