3 exFAT file system implementation library.
5 Copyright (C) 2010-2013 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_pread(ef->dev, it->chunk, CLUSTER_SIZE(*ef->sb),
90 exfat_c2o(ef, it->cluster));
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 /* reached the end of directory; the caller should check this
113 if (it->offset >= parent->size)
115 it->cluster = exfat_next_cluster(ef, parent, it->cluster);
116 if (CLUSTER_INVALID(it->cluster))
118 exfat_error("invalid cluster 0x%x while reading directory",
122 exfat_pread(ef->dev, it->chunk, CLUSTER_SIZE(*ef->sb),
123 exfat_c2o(ef, it->cluster));
128 static struct exfat_node* allocate_node(void)
130 struct exfat_node* node = malloc(sizeof(struct exfat_node));
133 exfat_error("failed to allocate node");
136 memset(node, 0, sizeof(struct exfat_node));
140 static void init_node_meta1(struct exfat_node* node,
141 const struct exfat_entry_meta1* meta1)
143 node->flags = le16_to_cpu(meta1->attrib);
144 node->mtime = exfat_exfat2unix(meta1->mdate, meta1->mtime,
146 /* there is no centiseconds field for atime */
147 node->atime = exfat_exfat2unix(meta1->adate, meta1->atime, 0);
150 static void init_node_meta2(struct exfat_node* node,
151 const struct exfat_entry_meta2* meta2)
153 node->size = le64_to_cpu(meta2->size);
154 node->start_cluster = le32_to_cpu(meta2->start_cluster);
155 node->fptr_cluster = node->start_cluster;
156 if (meta2->flags & EXFAT_FLAG_CONTIGUOUS)
157 node->flags |= EXFAT_ATTRIB_CONTIGUOUS;
160 static const struct exfat_entry* get_entry_ptr(const struct exfat* ef,
161 const struct iterator* it)
163 return (const struct exfat_entry*)
164 (it->chunk + it->offset % CLUSTER_SIZE(*ef->sb));
168 * Reads one entry in directory at position pointed by iterator and fills
171 static int readdir(struct exfat* ef, const struct exfat_node* parent,
172 struct exfat_node** node, struct iterator* it)
175 const struct exfat_entry* entry;
176 const struct exfat_entry_meta1* meta1;
177 const struct exfat_entry_meta2* meta2;
178 const struct exfat_entry_name* file_name;
179 const struct exfat_entry_upcase* upcase;
180 const struct exfat_entry_bitmap* bitmap;
181 const struct exfat_entry_label* label;
182 uint8_t continuations = 0;
183 le16_t* namep = NULL;
184 uint16_t reference_checksum = 0;
185 uint16_t actual_checksum = 0;
186 uint64_t real_size = 0;
192 if (it->offset >= parent->size)
194 if (continuations != 0)
196 exfat_error("expected %hhu continuations", continuations);
199 return -ENOENT; /* that's OK, means end of directory */
202 entry = get_entry_ptr(ef, it);
205 case EXFAT_ENTRY_FILE:
206 if (continuations != 0)
208 exfat_error("expected %hhu continuations before new entry",
212 meta1 = (const struct exfat_entry_meta1*) entry;
213 continuations = meta1->continuations;
214 /* each file entry must have at least 2 continuations:
216 if (continuations < 2)
218 exfat_error("too few continuations (%hhu)", continuations);
221 reference_checksum = le16_to_cpu(meta1->checksum);
222 actual_checksum = exfat_start_checksum(meta1);
223 *node = allocate_node();
229 /* new node has zero reference counter */
230 (*node)->entry_cluster = it->cluster;
231 (*node)->entry_offset = it->offset;
232 init_node_meta1(*node, meta1);
233 namep = (*node)->name;
236 case EXFAT_ENTRY_FILE_INFO:
237 if (continuations < 2)
239 exfat_error("unexpected continuation (%hhu)",
243 meta2 = (const struct exfat_entry_meta2*) entry;
244 if (meta2->flags & ~(EXFAT_FLAG_ALWAYS1 | EXFAT_FLAG_CONTIGUOUS))
246 exfat_error("unknown flags in meta2 (0x%hhx)", meta2->flags);
249 init_node_meta2(*node, meta2);
250 actual_checksum = exfat_add_checksum(entry, actual_checksum);
251 real_size = le64_to_cpu(meta2->real_size);
252 /* empty files must be marked as non-contiguous */
253 if ((*node)->size == 0 && (meta2->flags & EXFAT_FLAG_CONTIGUOUS))
255 exfat_error("empty file marked as contiguous (0x%hhx)",
259 /* directories must be aligned on at cluster boundary */
260 if (((*node)->flags & EXFAT_ATTRIB_DIR) &&
261 (*node)->size % CLUSTER_SIZE(*ef->sb) != 0)
263 exfat_error("directory has invalid size %"PRIu64" bytes",
270 case EXFAT_ENTRY_FILE_NAME:
271 if (continuations == 0)
273 exfat_error("unexpected continuation");
276 file_name = (const struct exfat_entry_name*) entry;
277 actual_checksum = exfat_add_checksum(entry, actual_checksum);
279 memcpy(namep, file_name->name, EXFAT_ENAME_MAX * sizeof(le16_t));
280 namep += EXFAT_ENAME_MAX;
281 if (--continuations == 0)
284 There are two fields that contain file size. Maybe they
285 plan to add compression support in the future and one of
286 those fields is visible (uncompressed) size and the other
287 is real (compressed) size. Anyway, currently it looks like
288 exFAT does not support compression and both fields must be
291 There is an exception though: pagefile.sys (its real_size
294 if (real_size != (*node)->size)
296 char buffer[EXFAT_NAME_MAX + 1];
298 exfat_get_name(*node, buffer, EXFAT_NAME_MAX);
299 exfat_error("`%s' real size does not equal to size "
300 "(%"PRIu64" != %"PRIu64")", buffer,
301 real_size, (*node)->size);
304 if (actual_checksum != reference_checksum)
306 char buffer[EXFAT_NAME_MAX + 1];
308 exfat_get_name(*node, buffer, EXFAT_NAME_MAX);
309 exfat_error("`%s' has invalid checksum (0x%hx != 0x%hx)",
310 buffer, actual_checksum, reference_checksum);
313 if (fetch_next_entry(ef, parent, it) != 0)
315 return 0; /* entry completed */
319 case EXFAT_ENTRY_UPCASE:
320 if (ef->upcase != NULL)
322 upcase = (const struct exfat_entry_upcase*) entry;
323 if (CLUSTER_INVALID(le32_to_cpu(upcase->start_cluster)))
325 exfat_error("invalid cluster 0x%x in upcase table",
326 le32_to_cpu(upcase->start_cluster));
329 if (le64_to_cpu(upcase->size) == 0 ||
330 le64_to_cpu(upcase->size) > 0xffff * sizeof(uint16_t) ||
331 le64_to_cpu(upcase->size) % sizeof(uint16_t) != 0)
333 exfat_error("bad upcase table size (%"PRIu64" bytes)",
334 le64_to_cpu(upcase->size));
337 ef->upcase = malloc(le64_to_cpu(upcase->size));
338 if (ef->upcase == NULL)
340 exfat_error("failed to allocate upcase table (%"PRIu64" bytes)",
341 le64_to_cpu(upcase->size));
345 ef->upcase_chars = le64_to_cpu(upcase->size) / sizeof(le16_t);
347 exfat_pread(ef->dev, ef->upcase, le64_to_cpu(upcase->size),
348 exfat_c2o(ef, le32_to_cpu(upcase->start_cluster)));
351 case EXFAT_ENTRY_BITMAP:
352 bitmap = (const struct exfat_entry_bitmap*) entry;
353 ef->cmap.start_cluster = le32_to_cpu(bitmap->start_cluster);
354 if (CLUSTER_INVALID(ef->cmap.start_cluster))
356 exfat_error("invalid cluster 0x%x in clusters bitmap",
357 ef->cmap.start_cluster);
360 ef->cmap.size = le32_to_cpu(ef->sb->cluster_count) -
361 EXFAT_FIRST_DATA_CLUSTER;
362 if (le64_to_cpu(bitmap->size) < (ef->cmap.size + 7) / 8)
364 exfat_error("invalid clusters bitmap size: %"PRIu64
365 " (expected at least %u)",
366 le64_to_cpu(bitmap->size), (ef->cmap.size + 7) / 8);
369 /* FIXME bitmap can be rather big, up to 512 MB */
370 ef->cmap.chunk_size = ef->cmap.size;
371 ef->cmap.chunk = malloc(le64_to_cpu(bitmap->size));
372 if (ef->cmap.chunk == NULL)
374 exfat_error("failed to allocate clusters bitmap chunk "
375 "(%"PRIu64" bytes)", le64_to_cpu(bitmap->size));
380 exfat_pread(ef->dev, ef->cmap.chunk, le64_to_cpu(bitmap->size),
381 exfat_c2o(ef, ef->cmap.start_cluster));
384 case EXFAT_ENTRY_LABEL:
385 label = (const struct exfat_entry_label*) entry;
386 if (label->length > EXFAT_ENAME_MAX)
388 exfat_error("too long label (%hhu chars)", label->length);
391 if (utf16_to_utf8(ef->label, label->name,
392 sizeof(ef->label), EXFAT_ENAME_MAX) != 0)
397 if (entry->type & EXFAT_ENTRY_VALID)
399 exfat_error("unknown entry type 0x%hhx", entry->type);
405 if (fetch_next_entry(ef, parent, it) != 0)
408 /* we never reach here */
416 int exfat_cache_directory(struct exfat* ef, struct exfat_node* dir)
420 struct exfat_node* node;
421 struct exfat_node* current = NULL;
423 if (dir->flags & EXFAT_ATTRIB_CACHED)
424 return 0; /* already cached */
426 rc = opendir(ef, dir, &it);
429 while ((rc = readdir(ef, dir, &node, &it)) == 0)
434 current->next = node;
435 node->prev = current;
447 for (current = dir->child; current; current = node)
449 node = current->next;
456 dir->flags |= EXFAT_ATTRIB_CACHED;
460 static void tree_attach(struct exfat_node* dir, struct exfat_node* node)
465 dir->child->prev = node;
466 node->next = dir->child;
471 static void tree_detach(struct exfat_node* node)
474 node->prev->next = node->next;
475 else /* this is the first node in the list */
476 node->parent->child = node->next;
478 node->next->prev = node->prev;
484 static void reset_cache(struct exfat* ef, struct exfat_node* node)
488 struct exfat_node* p = node->child;
493 node->flags &= ~EXFAT_ATTRIB_CACHED;
494 if (node->references != 0)
496 char buffer[EXFAT_NAME_MAX + 1];
497 exfat_get_name(node, buffer, EXFAT_NAME_MAX);
498 exfat_warn("non-zero reference counter (%d) for `%s'",
499 node->references, buffer);
501 while (node->references)
502 exfat_put_node(ef, node);
505 void exfat_reset_cache(struct exfat* ef)
507 reset_cache(ef, ef->root);
510 void next_entry(struct exfat* ef, const struct exfat_node* parent,
511 cluster_t* cluster, off_t* offset)
513 *offset += sizeof(struct exfat_entry);
514 if (*offset % CLUSTER_SIZE(*ef->sb) == 0)
515 /* next cluster cannot be invalid */
516 *cluster = exfat_next_cluster(ef, parent, *cluster);
519 void exfat_flush_node(struct exfat* ef, struct exfat_node* node)
523 off_t meta1_offset, meta2_offset;
524 struct exfat_entry_meta1 meta1;
525 struct exfat_entry_meta2 meta2;
528 exfat_bug("unable to flush node to read-only FS");
530 if (node->parent == NULL)
531 return; /* do not flush unlinked node */
533 cluster = node->entry_cluster;
534 offset = node->entry_offset;
535 meta1_offset = co2o(ef, cluster, offset);
536 next_entry(ef, node->parent, &cluster, &offset);
537 meta2_offset = co2o(ef, cluster, offset);
539 exfat_pread(ef->dev, &meta1, sizeof(meta1), meta1_offset);
540 if (meta1.type != EXFAT_ENTRY_FILE)
541 exfat_bug("invalid type of meta1: 0x%hhx", meta1.type);
542 meta1.attrib = cpu_to_le16(node->flags);
543 exfat_unix2exfat(node->mtime, &meta1.mdate, &meta1.mtime, &meta1.mtime_cs);
544 exfat_unix2exfat(node->atime, &meta1.adate, &meta1.atime, NULL);
546 exfat_pread(ef->dev, &meta2, sizeof(meta2), meta2_offset);
547 if (meta2.type != EXFAT_ENTRY_FILE_INFO)
548 exfat_bug("invalid type of meta2: 0x%hhx", meta2.type);
549 meta2.size = meta2.real_size = cpu_to_le64(node->size);
550 meta2.start_cluster = cpu_to_le32(node->start_cluster);
551 meta2.flags = EXFAT_FLAG_ALWAYS1;
552 /* empty files must not be marked as contiguous */
553 if (node->size != 0 && IS_CONTIGUOUS(*node))
554 meta2.flags |= EXFAT_FLAG_CONTIGUOUS;
555 /* name hash remains unchanged, no need to recalculate it */
557 meta1.checksum = exfat_calc_checksum(&meta1, &meta2, node->name);
559 exfat_pwrite(ef->dev, &meta1, sizeof(meta1), meta1_offset);
560 exfat_pwrite(ef->dev, &meta2, sizeof(meta2), meta2_offset);
562 node->flags &= ~EXFAT_ATTRIB_DIRTY;
565 static void erase_entry(struct exfat* ef, struct exfat_node* node)
567 cluster_t cluster = node->entry_cluster;
568 off_t offset = node->entry_offset;
569 int name_entries = DIV_ROUND_UP(utf16_length(node->name), EXFAT_ENAME_MAX);
572 entry_type = EXFAT_ENTRY_FILE & ~EXFAT_ENTRY_VALID;
573 exfat_pwrite(ef->dev, &entry_type, 1, co2o(ef, cluster, offset));
575 next_entry(ef, node->parent, &cluster, &offset);
576 entry_type = EXFAT_ENTRY_FILE_INFO & ~EXFAT_ENTRY_VALID;
577 exfat_pwrite(ef->dev, &entry_type, 1, co2o(ef, cluster, offset));
579 while (name_entries--)
581 next_entry(ef, node->parent, &cluster, &offset);
582 entry_type = EXFAT_ENTRY_FILE_NAME & ~EXFAT_ENTRY_VALID;
583 exfat_pwrite(ef->dev, &entry_type, 1, co2o(ef, cluster, offset));
587 static int shrink_directory(struct exfat* ef, struct exfat_node* dir,
588 off_t deleted_offset)
590 const struct exfat_node* node;
591 const struct exfat_node* last_node;
592 uint64_t entries = 0;
596 if (!(dir->flags & EXFAT_ATTRIB_DIR))
597 exfat_bug("attempted to shrink a file");
598 if (!(dir->flags & EXFAT_ATTRIB_CACHED))
599 exfat_bug("attempted to shrink uncached directory");
601 for (last_node = node = dir->child; node; node = node->next)
603 if (deleted_offset < node->entry_offset)
605 /* there are other entries after the removed one, no way to shrink
609 if (last_node->entry_offset < node->entry_offset)
615 /* offset of the last entry */
616 entries += last_node->entry_offset / sizeof(struct exfat_entry);
617 /* two subentries with meta info */
619 /* subentries with file name */
620 entries += DIV_ROUND_UP(utf16_length(last_node->name),
624 new_size = DIV_ROUND_UP(entries * sizeof(struct exfat_entry),
625 CLUSTER_SIZE(*ef->sb)) * CLUSTER_SIZE(*ef->sb);
626 if (new_size == 0) /* directory always has at least 1 cluster */
627 new_size = CLUSTER_SIZE(*ef->sb);
628 if (new_size == dir->size)
630 rc = exfat_truncate(ef, dir, new_size);
636 static int delete(struct exfat* ef, struct exfat_node* node)
638 struct exfat_node* parent = node->parent;
639 off_t deleted_offset = node->entry_offset;
642 exfat_get_node(parent);
643 erase_entry(ef, node);
644 exfat_update_mtime(parent);
646 rc = shrink_directory(ef, parent, deleted_offset);
647 exfat_put_node(ef, parent);
648 /* file clusters will be freed when node reference counter becomes 0 */
649 node->flags |= EXFAT_ATTRIB_UNLINKED;
653 int exfat_unlink(struct exfat* ef, struct exfat_node* node)
655 if (node->flags & EXFAT_ATTRIB_DIR)
657 return delete(ef, node);
660 int exfat_rmdir(struct exfat* ef, struct exfat_node* node)
662 if (!(node->flags & EXFAT_ATTRIB_DIR))
664 /* check that directory is empty */
665 exfat_cache_directory(ef, node);
668 return delete(ef, node);
671 static int grow_directory(struct exfat* ef, struct exfat_node* dir,
672 uint64_t asize, uint32_t difference)
674 return exfat_truncate(ef, dir,
675 DIV_ROUND_UP(asize + difference, CLUSTER_SIZE(*ef->sb))
676 * CLUSTER_SIZE(*ef->sb));
679 static int find_slot(struct exfat* ef, struct exfat_node* dir,
680 cluster_t* cluster, off_t* offset, int subentries)
684 const struct exfat_entry* entry;
687 rc = opendir(ef, dir, &it);
694 *cluster = it.cluster;
697 entry = get_entry_ptr(ef, &it);
698 if (entry->type & EXFAT_ENTRY_VALID)
702 if (contiguous == subentries)
703 break; /* suitable slot is found */
704 if (it.offset + sizeof(struct exfat_entry) >= dir->size)
706 rc = grow_directory(ef, dir, dir->size,
707 (subentries - contiguous) * sizeof(struct exfat_entry));
714 if (fetch_next_entry(ef, dir, &it) != 0)
724 static int write_entry(struct exfat* ef, struct exfat_node* dir,
725 const le16_t* name, cluster_t cluster, off_t offset, uint16_t attrib)
727 struct exfat_node* node;
728 struct exfat_entry_meta1 meta1;
729 struct exfat_entry_meta2 meta2;
730 const size_t name_length = utf16_length(name);
731 const int name_entries = DIV_ROUND_UP(name_length, EXFAT_ENAME_MAX);
734 node = allocate_node();
737 node->entry_cluster = cluster;
738 node->entry_offset = offset;
739 memcpy(node->name, name, name_length * sizeof(le16_t));
741 memset(&meta1, 0, sizeof(meta1));
742 meta1.type = EXFAT_ENTRY_FILE;
743 meta1.continuations = 1 + name_entries;
744 meta1.attrib = cpu_to_le16(attrib);
745 exfat_unix2exfat(time(NULL), &meta1.crdate, &meta1.crtime,
747 meta1.adate = meta1.mdate = meta1.crdate;
748 meta1.atime = meta1.mtime = meta1.crtime;
749 meta1.mtime_cs = meta1.crtime_cs; /* there is no atime_cs */
751 memset(&meta2, 0, sizeof(meta2));
752 meta2.type = EXFAT_ENTRY_FILE_INFO;
753 meta2.flags = EXFAT_FLAG_ALWAYS1;
754 meta2.name_length = name_length;
755 meta2.name_hash = exfat_calc_name_hash(ef, node->name);
756 meta2.start_cluster = cpu_to_le32(EXFAT_CLUSTER_FREE);
758 meta1.checksum = exfat_calc_checksum(&meta1, &meta2, node->name);
760 exfat_pwrite(ef->dev, &meta1, sizeof(meta1), co2o(ef, cluster, offset));
761 next_entry(ef, dir, &cluster, &offset);
762 exfat_pwrite(ef->dev, &meta2, sizeof(meta2), co2o(ef, cluster, offset));
763 for (i = 0; i < name_entries; i++)
765 struct exfat_entry_name name_entry = {EXFAT_ENTRY_FILE_NAME, 0};
766 memcpy(name_entry.name, node->name + i * EXFAT_ENAME_MAX,
767 EXFAT_ENAME_MAX * sizeof(le16_t));
768 next_entry(ef, dir, &cluster, &offset);
769 exfat_pwrite(ef->dev, &name_entry, sizeof(name_entry),
770 co2o(ef, cluster, offset));
773 init_node_meta1(node, &meta1);
774 init_node_meta2(node, &meta2);
776 tree_attach(dir, node);
777 exfat_update_mtime(dir);
781 static int create(struct exfat* ef, const char* path, uint16_t attrib)
783 struct exfat_node* dir;
784 struct exfat_node* existing;
785 cluster_t cluster = EXFAT_CLUSTER_BAD;
787 le16_t name[EXFAT_NAME_MAX + 1];
790 rc = exfat_split(ef, &dir, &existing, name, path);
793 if (existing != NULL)
795 exfat_put_node(ef, existing);
796 exfat_put_node(ef, dir);
800 rc = find_slot(ef, dir, &cluster, &offset,
801 2 + DIV_ROUND_UP(utf16_length(name), EXFAT_ENAME_MAX));
804 exfat_put_node(ef, dir);
807 rc = write_entry(ef, dir, name, cluster, offset, attrib);
808 exfat_put_node(ef, dir);
812 int exfat_mknod(struct exfat* ef, const char* path)
814 return create(ef, path, EXFAT_ATTRIB_ARCH);
817 int exfat_mkdir(struct exfat* ef, const char* path)
820 struct exfat_node* node;
822 rc = create(ef, path, EXFAT_ATTRIB_ARCH | EXFAT_ATTRIB_DIR);
825 rc = exfat_lookup(ef, &node, path);
828 /* directories always have at least one cluster */
829 rc = exfat_truncate(ef, node, CLUSTER_SIZE(*ef->sb));
833 exfat_put_node(ef, node);
836 exfat_put_node(ef, node);
840 static void rename_entry(struct exfat* ef, struct exfat_node* dir,
841 struct exfat_node* node, const le16_t* name, cluster_t new_cluster,
844 struct exfat_entry_meta1 meta1;
845 struct exfat_entry_meta2 meta2;
846 cluster_t old_cluster = node->entry_cluster;
847 off_t old_offset = node->entry_offset;
848 const size_t name_length = utf16_length(name);
849 const int name_entries = DIV_ROUND_UP(name_length, EXFAT_ENAME_MAX);
852 exfat_pread(ef->dev, &meta1, sizeof(meta1),
853 co2o(ef, old_cluster, old_offset));
854 next_entry(ef, node->parent, &old_cluster, &old_offset);
855 exfat_pread(ef->dev, &meta2, sizeof(meta2),
856 co2o(ef, old_cluster, old_offset));
857 meta1.continuations = 1 + name_entries;
858 meta2.name_hash = exfat_calc_name_hash(ef, name);
859 meta2.name_length = name_length;
860 meta1.checksum = exfat_calc_checksum(&meta1, &meta2, name);
862 erase_entry(ef, node);
864 node->entry_cluster = new_cluster;
865 node->entry_offset = new_offset;
867 exfat_pwrite(ef->dev, &meta1, sizeof(meta1),
868 co2o(ef, new_cluster, new_offset));
869 next_entry(ef, dir, &new_cluster, &new_offset);
870 exfat_pwrite(ef->dev, &meta2, sizeof(meta2),
871 co2o(ef, new_cluster, new_offset));
873 for (i = 0; i < name_entries; i++)
875 struct exfat_entry_name name_entry = {EXFAT_ENTRY_FILE_NAME, 0};
876 memcpy(name_entry.name, name + i * EXFAT_ENAME_MAX,
877 EXFAT_ENAME_MAX * sizeof(le16_t));
878 next_entry(ef, dir, &new_cluster, &new_offset);
879 exfat_pwrite(ef->dev, &name_entry, sizeof(name_entry),
880 co2o(ef, new_cluster, new_offset));
883 memcpy(node->name, name, (EXFAT_NAME_MAX + 1) * sizeof(le16_t));
885 tree_attach(dir, node);
888 int exfat_rename(struct exfat* ef, const char* old_path, const char* new_path)
890 struct exfat_node* node;
891 struct exfat_node* existing;
892 struct exfat_node* dir;
893 cluster_t cluster = EXFAT_CLUSTER_BAD;
895 le16_t name[EXFAT_NAME_MAX + 1];
898 rc = exfat_lookup(ef, &node, old_path);
902 rc = exfat_split(ef, &dir, &existing, name, new_path);
905 exfat_put_node(ef, node);
908 if (existing != NULL)
910 /* remove target if it's not the same node as source */
911 if (existing != node)
913 if (existing->flags & EXFAT_ATTRIB_DIR)
915 if (node->flags & EXFAT_ATTRIB_DIR)
916 rc = exfat_rmdir(ef, existing);
922 if (!(node->flags & EXFAT_ATTRIB_DIR))
923 rc = exfat_unlink(ef, existing);
927 exfat_put_node(ef, existing);
930 exfat_put_node(ef, dir);
931 exfat_put_node(ef, node);
936 exfat_put_node(ef, existing);
939 rc = find_slot(ef, dir, &cluster, &offset,
940 2 + DIV_ROUND_UP(utf16_length(name), EXFAT_ENAME_MAX));
943 exfat_put_node(ef, dir);
944 exfat_put_node(ef, node);
947 rename_entry(ef, dir, node, name, cluster, offset);
948 exfat_put_node(ef, dir);
949 exfat_put_node(ef, node);
953 void exfat_utimes(struct exfat_node* node, const struct timespec tv[2])
955 node->atime = tv[0].tv_sec;
956 node->mtime = tv[1].tv_sec;
957 node->flags |= EXFAT_ATTRIB_DIRTY;
960 void exfat_update_atime(struct exfat_node* node)
962 node->atime = time(NULL);
963 node->flags |= EXFAT_ATTRIB_DIRTY;
966 void exfat_update_mtime(struct exfat_node* node)
968 node->mtime = time(NULL);
969 node->flags |= EXFAT_ATTRIB_DIRTY;
972 const char* exfat_get_label(struct exfat* ef)
977 static int find_label(struct exfat* ef, cluster_t* cluster, off_t* offset)
982 rc = opendir(ef, ef->root, &it);
988 if (it.offset >= ef->root->size)
994 if (get_entry_ptr(ef, &it)->type == EXFAT_ENTRY_LABEL)
996 *cluster = it.cluster;
1002 if (fetch_next_entry(ef, ef->root, &it) != 0)
1010 int exfat_set_label(struct exfat* ef, const char* label)
1012 le16_t label_utf16[EXFAT_ENAME_MAX + 1];
1016 struct exfat_entry_label entry;
1018 memset(label_utf16, 0, sizeof(label_utf16));
1019 rc = utf8_to_utf16(label_utf16, label, EXFAT_ENAME_MAX, strlen(label));
1023 rc = find_label(ef, &cluster, &offset);
1025 rc = find_slot(ef, ef->root, &cluster, &offset, 1);
1029 entry.type = EXFAT_ENTRY_LABEL;
1030 entry.length = utf16_length(label_utf16);
1031 memcpy(entry.name, label_utf16, sizeof(entry.name));
1032 if (entry.length == 0)
1033 entry.type ^= EXFAT_ENTRY_VALID;
1035 exfat_pwrite(ef->dev, &entry, sizeof(struct exfat_entry_label),
1036 co2o(ef, cluster, offset));