3 exFAT file system implementation library.
5 Free exFAT implementation.
6 Copyright (C) 2010-2013 Andrew Nayenko
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 /* on-disk nodes iterator */
37 struct exfat_node* exfat_get_node(struct exfat_node* node)
39 /* if we switch to multi-threaded mode we will need atomic
40 increment here and atomic decrement in exfat_put_node() */
45 void exfat_put_node(struct exfat* ef, struct exfat_node* node)
47 if (--node->references < 0)
49 char buffer[UTF8_BYTES(EXFAT_NAME_MAX) + 1];
50 exfat_get_name(node, buffer, sizeof(buffer) - 1);
51 exfat_bug("reference counter of `%s' is below zero", buffer);
54 if (node->references == 0)
56 if (node->flags & EXFAT_ATTRIB_DIRTY)
57 exfat_flush_node(ef, node);
58 if (node->flags & EXFAT_ATTRIB_UNLINKED)
60 /* free all clusters and node structure itself */
61 exfat_truncate(ef, node, 0, true);
70 * Cluster + offset from the beginning of the directory to absolute offset.
72 static off_t co2o(struct exfat* ef, cluster_t cluster, off_t offset)
74 return exfat_c2o(ef, cluster) + offset % CLUSTER_SIZE(*ef->sb);
77 static int opendir(struct exfat* ef, const struct exfat_node* dir,
80 if (!(dir->flags & EXFAT_ATTRIB_DIR))
81 exfat_bug("not a directory");
82 it->cluster = dir->start_cluster;
84 it->contiguous = IS_CONTIGUOUS(*dir);
85 it->chunk = malloc(CLUSTER_SIZE(*ef->sb));
86 if (it->chunk == NULL)
88 exfat_error("out of memory");
91 exfat_pread(ef->dev, it->chunk, CLUSTER_SIZE(*ef->sb),
92 exfat_c2o(ef, it->cluster));
96 static void closedir(struct iterator* it)
105 static int fetch_next_entry(struct exfat* ef, const struct exfat_node* parent,
108 /* move iterator to the next entry in the directory */
109 it->offset += sizeof(struct exfat_entry);
110 /* fetch the next cluster if needed */
111 if ((it->offset & (CLUSTER_SIZE(*ef->sb) - 1)) == 0)
113 /* reached the end of directory; the caller should check this
115 if (it->offset >= parent->size)
117 it->cluster = exfat_next_cluster(ef, parent, it->cluster);
118 if (CLUSTER_INVALID(it->cluster))
120 exfat_error("invalid cluster 0x%x while reading directory",
124 exfat_pread(ef->dev, it->chunk, CLUSTER_SIZE(*ef->sb),
125 exfat_c2o(ef, it->cluster));
130 static struct exfat_node* allocate_node(void)
132 struct exfat_node* node = malloc(sizeof(struct exfat_node));
135 exfat_error("failed to allocate node");
138 memset(node, 0, sizeof(struct exfat_node));
142 static void init_node_meta1(struct exfat_node* node,
143 const struct exfat_entry_meta1* meta1)
145 node->flags = le16_to_cpu(meta1->attrib);
146 node->mtime = exfat_exfat2unix(meta1->mdate, meta1->mtime,
148 /* there is no centiseconds field for atime */
149 node->atime = exfat_exfat2unix(meta1->adate, meta1->atime, 0);
152 static void init_node_meta2(struct exfat_node* node,
153 const struct exfat_entry_meta2* meta2)
155 node->size = le64_to_cpu(meta2->size);
156 node->start_cluster = le32_to_cpu(meta2->start_cluster);
157 node->fptr_cluster = node->start_cluster;
158 if (meta2->flags & EXFAT_FLAG_CONTIGUOUS)
159 node->flags |= EXFAT_ATTRIB_CONTIGUOUS;
162 static const struct exfat_entry* get_entry_ptr(const struct exfat* ef,
163 const struct iterator* it)
165 return (const struct exfat_entry*)
166 (it->chunk + it->offset % CLUSTER_SIZE(*ef->sb));
170 * Reads one entry in directory at position pointed by iterator and fills
173 static int readdir(struct exfat* ef, const struct exfat_node* parent,
174 struct exfat_node** node, struct iterator* it)
177 const struct exfat_entry* entry;
178 const struct exfat_entry_meta1* meta1;
179 const struct exfat_entry_meta2* meta2;
180 const struct exfat_entry_name* file_name;
181 const struct exfat_entry_upcase* upcase;
182 const struct exfat_entry_bitmap* bitmap;
183 const struct exfat_entry_label* label;
184 uint8_t continuations = 0;
185 le16_t* namep = NULL;
186 uint16_t reference_checksum = 0;
187 uint16_t actual_checksum = 0;
188 uint64_t real_size = 0;
194 if (it->offset >= parent->size)
196 if (continuations != 0)
198 exfat_error("expected %hhu continuations", continuations);
201 return -ENOENT; /* that's OK, means end of directory */
204 entry = get_entry_ptr(ef, it);
207 case EXFAT_ENTRY_FILE:
208 if (continuations != 0)
210 exfat_error("expected %hhu continuations before new entry",
214 meta1 = (const struct exfat_entry_meta1*) entry;
215 continuations = meta1->continuations;
216 /* each file entry must have at least 2 continuations:
218 if (continuations < 2)
220 exfat_error("too few continuations (%hhu)", continuations);
223 reference_checksum = le16_to_cpu(meta1->checksum);
224 actual_checksum = exfat_start_checksum(meta1);
225 *node = allocate_node();
231 /* new node has zero reference counter */
232 (*node)->entry_cluster = it->cluster;
233 (*node)->entry_offset = it->offset;
234 init_node_meta1(*node, meta1);
235 namep = (*node)->name;
238 case EXFAT_ENTRY_FILE_INFO:
239 if (continuations < 2)
241 exfat_error("unexpected continuation (%hhu)",
245 meta2 = (const struct exfat_entry_meta2*) entry;
246 if (meta2->flags & ~(EXFAT_FLAG_ALWAYS1 | EXFAT_FLAG_CONTIGUOUS))
248 exfat_error("unknown flags in meta2 (0x%hhx)", meta2->flags);
251 init_node_meta2(*node, meta2);
252 actual_checksum = exfat_add_checksum(entry, actual_checksum);
253 real_size = le64_to_cpu(meta2->real_size);
254 /* empty files must be marked as non-contiguous */
255 if ((*node)->size == 0 && (meta2->flags & EXFAT_FLAG_CONTIGUOUS))
257 exfat_error("empty file marked as contiguous (0x%hhx)",
261 /* directories must be aligned on at cluster boundary */
262 if (((*node)->flags & EXFAT_ATTRIB_DIR) &&
263 (*node)->size % CLUSTER_SIZE(*ef->sb) != 0)
265 exfat_error("directory has invalid size %"PRIu64" bytes",
272 case EXFAT_ENTRY_FILE_NAME:
273 if (continuations == 0)
275 exfat_error("unexpected continuation");
278 file_name = (const struct exfat_entry_name*) entry;
279 actual_checksum = exfat_add_checksum(entry, actual_checksum);
281 memcpy(namep, file_name->name, EXFAT_ENAME_MAX * sizeof(le16_t));
282 namep += EXFAT_ENAME_MAX;
283 if (--continuations == 0)
286 There are two fields that contain file size. Maybe they
287 plan to add compression support in the future and one of
288 those fields is visible (uncompressed) size and the other
289 is real (compressed) size. Anyway, currently it looks like
290 exFAT does not support compression and both fields must be
293 There is an exception though: pagefile.sys (its real_size
296 if (real_size != (*node)->size)
298 char buffer[UTF8_BYTES(EXFAT_NAME_MAX) + 1];
300 exfat_get_name(*node, buffer, sizeof(buffer) - 1);
301 exfat_error("`%s' real size does not equal to size "
302 "(%"PRIu64" != %"PRIu64")", buffer,
303 real_size, (*node)->size);
306 if (actual_checksum != reference_checksum)
308 char buffer[UTF8_BYTES(EXFAT_NAME_MAX) + 1];
310 exfat_get_name(*node, buffer, sizeof(buffer) - 1);
311 exfat_error("`%s' has invalid checksum (0x%hx != 0x%hx)",
312 buffer, actual_checksum, reference_checksum);
315 if (fetch_next_entry(ef, parent, it) != 0)
317 return 0; /* entry completed */
321 case EXFAT_ENTRY_UPCASE:
322 if (ef->upcase != NULL)
324 upcase = (const struct exfat_entry_upcase*) entry;
325 if (CLUSTER_INVALID(le32_to_cpu(upcase->start_cluster)))
327 exfat_error("invalid cluster 0x%x in upcase table",
328 le32_to_cpu(upcase->start_cluster));
331 if (le64_to_cpu(upcase->size) == 0 ||
332 le64_to_cpu(upcase->size) > 0xffff * sizeof(uint16_t) ||
333 le64_to_cpu(upcase->size) % sizeof(uint16_t) != 0)
335 exfat_error("bad upcase table size (%"PRIu64" bytes)",
336 le64_to_cpu(upcase->size));
339 ef->upcase = malloc(le64_to_cpu(upcase->size));
340 if (ef->upcase == NULL)
342 exfat_error("failed to allocate upcase table (%"PRIu64" bytes)",
343 le64_to_cpu(upcase->size));
347 ef->upcase_chars = le64_to_cpu(upcase->size) / sizeof(le16_t);
349 exfat_pread(ef->dev, ef->upcase, le64_to_cpu(upcase->size),
350 exfat_c2o(ef, le32_to_cpu(upcase->start_cluster)));
353 case EXFAT_ENTRY_BITMAP:
354 bitmap = (const struct exfat_entry_bitmap*) entry;
355 ef->cmap.start_cluster = le32_to_cpu(bitmap->start_cluster);
356 if (CLUSTER_INVALID(ef->cmap.start_cluster))
358 exfat_error("invalid cluster 0x%x in clusters bitmap",
359 ef->cmap.start_cluster);
362 ef->cmap.size = le32_to_cpu(ef->sb->cluster_count) -
363 EXFAT_FIRST_DATA_CLUSTER;
364 if (le64_to_cpu(bitmap->size) < (ef->cmap.size + 7) / 8)
366 exfat_error("invalid clusters bitmap size: %"PRIu64
367 " (expected at least %u)",
368 le64_to_cpu(bitmap->size), (ef->cmap.size + 7) / 8);
371 /* FIXME bitmap can be rather big, up to 512 MB */
372 ef->cmap.chunk_size = ef->cmap.size;
373 ef->cmap.chunk = malloc(le64_to_cpu(bitmap->size));
374 if (ef->cmap.chunk == NULL)
376 exfat_error("failed to allocate clusters bitmap chunk "
377 "(%"PRIu64" bytes)", le64_to_cpu(bitmap->size));
382 exfat_pread(ef->dev, ef->cmap.chunk, le64_to_cpu(bitmap->size),
383 exfat_c2o(ef, ef->cmap.start_cluster));
386 case EXFAT_ENTRY_LABEL:
387 label = (const struct exfat_entry_label*) entry;
388 if (label->length > EXFAT_ENAME_MAX)
390 exfat_error("too long label (%hhu chars)", label->length);
393 if (utf16_to_utf8(ef->label, label->name,
394 sizeof(ef->label) - 1, EXFAT_ENAME_MAX) != 0)
399 if (entry->type & EXFAT_ENTRY_VALID)
401 exfat_error("unknown entry type 0x%hhx", entry->type);
407 if (fetch_next_entry(ef, parent, it) != 0)
410 /* we never reach here */
418 int exfat_cache_directory(struct exfat* ef, struct exfat_node* dir)
422 struct exfat_node* node;
423 struct exfat_node* current = NULL;
425 if (dir->flags & EXFAT_ATTRIB_CACHED)
426 return 0; /* already cached */
428 rc = opendir(ef, dir, &it);
431 while ((rc = readdir(ef, dir, &node, &it)) == 0)
436 current->next = node;
437 node->prev = current;
449 for (current = dir->child; current; current = node)
451 node = current->next;
458 dir->flags |= EXFAT_ATTRIB_CACHED;
462 static void tree_attach(struct exfat_node* dir, struct exfat_node* node)
467 dir->child->prev = node;
468 node->next = dir->child;
473 static void tree_detach(struct exfat_node* node)
476 node->prev->next = node->next;
477 else /* this is the first node in the list */
478 node->parent->child = node->next;
480 node->next->prev = node->prev;
486 static void reset_cache(struct exfat* ef, struct exfat_node* node)
490 struct exfat_node* p = node->child;
495 node->flags &= ~EXFAT_ATTRIB_CACHED;
496 if (node->references != 0)
498 char buffer[UTF8_BYTES(EXFAT_NAME_MAX) + 1];
499 exfat_get_name(node, buffer, sizeof(buffer) - 1);
500 exfat_warn("non-zero reference counter (%d) for `%s'",
501 node->references, buffer);
503 while (node->references)
504 exfat_put_node(ef, node);
507 void exfat_reset_cache(struct exfat* ef)
509 reset_cache(ef, ef->root);
512 static void next_entry(struct exfat* ef, const struct exfat_node* parent,
513 cluster_t* cluster, off_t* offset)
515 *offset += sizeof(struct exfat_entry);
516 if (*offset % CLUSTER_SIZE(*ef->sb) == 0)
517 /* next cluster cannot be invalid */
518 *cluster = exfat_next_cluster(ef, parent, *cluster);
521 void exfat_flush_node(struct exfat* ef, struct exfat_node* node)
525 off_t meta1_offset, meta2_offset;
526 struct exfat_entry_meta1 meta1;
527 struct exfat_entry_meta2 meta2;
530 exfat_bug("unable to flush node to read-only FS");
532 if (node->parent == NULL)
533 return; /* do not flush unlinked node */
535 cluster = node->entry_cluster;
536 offset = node->entry_offset;
537 meta1_offset = co2o(ef, cluster, offset);
538 next_entry(ef, node->parent, &cluster, &offset);
539 meta2_offset = co2o(ef, cluster, offset);
541 exfat_pread(ef->dev, &meta1, sizeof(meta1), meta1_offset);
542 if (meta1.type != EXFAT_ENTRY_FILE)
543 exfat_bug("invalid type of meta1: 0x%hhx", meta1.type);
544 meta1.attrib = cpu_to_le16(node->flags);
545 exfat_unix2exfat(node->mtime, &meta1.mdate, &meta1.mtime, &meta1.mtime_cs);
546 exfat_unix2exfat(node->atime, &meta1.adate, &meta1.atime, NULL);
548 exfat_pread(ef->dev, &meta2, sizeof(meta2), meta2_offset);
549 if (meta2.type != EXFAT_ENTRY_FILE_INFO)
550 exfat_bug("invalid type of meta2: 0x%hhx", meta2.type);
551 meta2.size = meta2.real_size = cpu_to_le64(node->size);
552 meta2.start_cluster = cpu_to_le32(node->start_cluster);
553 meta2.flags = EXFAT_FLAG_ALWAYS1;
554 /* empty files must not be marked as contiguous */
555 if (node->size != 0 && IS_CONTIGUOUS(*node))
556 meta2.flags |= EXFAT_FLAG_CONTIGUOUS;
557 /* name hash remains unchanged, no need to recalculate it */
559 meta1.checksum = exfat_calc_checksum(&meta1, &meta2, node->name);
561 exfat_pwrite(ef->dev, &meta1, sizeof(meta1), meta1_offset);
562 exfat_pwrite(ef->dev, &meta2, sizeof(meta2), meta2_offset);
564 node->flags &= ~EXFAT_ATTRIB_DIRTY;
567 static void erase_entry(struct exfat* ef, struct exfat_node* node)
569 cluster_t cluster = node->entry_cluster;
570 off_t offset = node->entry_offset;
571 int name_entries = DIV_ROUND_UP(utf16_length(node->name), EXFAT_ENAME_MAX);
574 entry_type = EXFAT_ENTRY_FILE & ~EXFAT_ENTRY_VALID;
575 exfat_pwrite(ef->dev, &entry_type, 1, co2o(ef, cluster, offset));
577 next_entry(ef, node->parent, &cluster, &offset);
578 entry_type = EXFAT_ENTRY_FILE_INFO & ~EXFAT_ENTRY_VALID;
579 exfat_pwrite(ef->dev, &entry_type, 1, co2o(ef, cluster, offset));
581 while (name_entries--)
583 next_entry(ef, node->parent, &cluster, &offset);
584 entry_type = EXFAT_ENTRY_FILE_NAME & ~EXFAT_ENTRY_VALID;
585 exfat_pwrite(ef->dev, &entry_type, 1, co2o(ef, cluster, offset));
589 static int shrink_directory(struct exfat* ef, struct exfat_node* dir,
590 off_t deleted_offset)
592 const struct exfat_node* node;
593 const struct exfat_node* last_node;
594 uint64_t entries = 0;
598 if (!(dir->flags & EXFAT_ATTRIB_DIR))
599 exfat_bug("attempted to shrink a file");
600 if (!(dir->flags & EXFAT_ATTRIB_CACHED))
601 exfat_bug("attempted to shrink uncached directory");
603 for (last_node = node = dir->child; node; node = node->next)
605 if (deleted_offset < node->entry_offset)
607 /* there are other entries after the removed one, no way to shrink
611 if (last_node->entry_offset < node->entry_offset)
617 /* offset of the last entry */
618 entries += last_node->entry_offset / sizeof(struct exfat_entry);
619 /* two subentries with meta info */
621 /* subentries with file name */
622 entries += DIV_ROUND_UP(utf16_length(last_node->name),
626 new_size = DIV_ROUND_UP(entries * sizeof(struct exfat_entry),
627 CLUSTER_SIZE(*ef->sb)) * CLUSTER_SIZE(*ef->sb);
628 if (new_size == 0) /* directory always has at least 1 cluster */
629 new_size = CLUSTER_SIZE(*ef->sb);
630 if (new_size == dir->size)
632 rc = exfat_truncate(ef, dir, new_size, true);
638 static int delete(struct exfat* ef, struct exfat_node* node)
640 struct exfat_node* parent = node->parent;
641 off_t deleted_offset = node->entry_offset;
644 exfat_get_node(parent);
645 erase_entry(ef, node);
646 exfat_update_mtime(parent);
648 rc = shrink_directory(ef, parent, deleted_offset);
649 exfat_put_node(ef, parent);
650 /* file clusters will be freed when node reference counter becomes 0 */
651 node->flags |= EXFAT_ATTRIB_UNLINKED;
655 int exfat_unlink(struct exfat* ef, struct exfat_node* node)
657 if (node->flags & EXFAT_ATTRIB_DIR)
659 return delete(ef, node);
662 int exfat_rmdir(struct exfat* ef, struct exfat_node* node)
664 if (!(node->flags & EXFAT_ATTRIB_DIR))
666 /* check that directory is empty */
667 exfat_cache_directory(ef, node);
670 return delete(ef, node);
673 static int grow_directory(struct exfat* ef, struct exfat_node* dir,
674 uint64_t asize, uint32_t difference)
676 return exfat_truncate(ef, dir,
677 DIV_ROUND_UP(asize + difference, CLUSTER_SIZE(*ef->sb))
678 * CLUSTER_SIZE(*ef->sb), true);
681 static int find_slot(struct exfat* ef, struct exfat_node* dir,
682 cluster_t* cluster, off_t* offset, int subentries)
686 const struct exfat_entry* entry;
689 rc = opendir(ef, dir, &it);
696 *cluster = it.cluster;
699 entry = get_entry_ptr(ef, &it);
700 if (entry->type & EXFAT_ENTRY_VALID)
704 if (contiguous == subentries)
705 break; /* suitable slot is found */
706 if (it.offset + sizeof(struct exfat_entry) >= dir->size)
708 rc = grow_directory(ef, dir, dir->size,
709 (subentries - contiguous) * sizeof(struct exfat_entry));
716 if (fetch_next_entry(ef, dir, &it) != 0)
726 static int write_entry(struct exfat* ef, struct exfat_node* dir,
727 const le16_t* name, cluster_t cluster, off_t offset, uint16_t attrib)
729 struct exfat_node* node;
730 struct exfat_entry_meta1 meta1;
731 struct exfat_entry_meta2 meta2;
732 const size_t name_length = utf16_length(name);
733 const int name_entries = DIV_ROUND_UP(name_length, EXFAT_ENAME_MAX);
736 node = allocate_node();
739 node->entry_cluster = cluster;
740 node->entry_offset = offset;
741 memcpy(node->name, name, name_length * sizeof(le16_t));
743 memset(&meta1, 0, sizeof(meta1));
744 meta1.type = EXFAT_ENTRY_FILE;
745 meta1.continuations = 1 + name_entries;
746 meta1.attrib = cpu_to_le16(attrib);
747 exfat_unix2exfat(time(NULL), &meta1.crdate, &meta1.crtime,
749 meta1.adate = meta1.mdate = meta1.crdate;
750 meta1.atime = meta1.mtime = meta1.crtime;
751 meta1.mtime_cs = meta1.crtime_cs; /* there is no atime_cs */
753 memset(&meta2, 0, sizeof(meta2));
754 meta2.type = EXFAT_ENTRY_FILE_INFO;
755 meta2.flags = EXFAT_FLAG_ALWAYS1;
756 meta2.name_length = name_length;
757 meta2.name_hash = exfat_calc_name_hash(ef, node->name);
758 meta2.start_cluster = cpu_to_le32(EXFAT_CLUSTER_FREE);
760 meta1.checksum = exfat_calc_checksum(&meta1, &meta2, node->name);
762 exfat_pwrite(ef->dev, &meta1, sizeof(meta1), co2o(ef, cluster, offset));
763 next_entry(ef, dir, &cluster, &offset);
764 exfat_pwrite(ef->dev, &meta2, sizeof(meta2), co2o(ef, cluster, offset));
765 for (i = 0; i < name_entries; i++)
767 struct exfat_entry_name name_entry = {EXFAT_ENTRY_FILE_NAME, 0};
768 memcpy(name_entry.name, node->name + i * EXFAT_ENAME_MAX,
769 EXFAT_ENAME_MAX * sizeof(le16_t));
770 next_entry(ef, dir, &cluster, &offset);
771 exfat_pwrite(ef->dev, &name_entry, sizeof(name_entry),
772 co2o(ef, cluster, offset));
775 init_node_meta1(node, &meta1);
776 init_node_meta2(node, &meta2);
778 tree_attach(dir, node);
779 exfat_update_mtime(dir);
783 static int create(struct exfat* ef, const char* path, uint16_t attrib)
785 struct exfat_node* dir;
786 struct exfat_node* existing;
787 cluster_t cluster = EXFAT_CLUSTER_BAD;
789 le16_t name[EXFAT_NAME_MAX + 1];
792 rc = exfat_split(ef, &dir, &existing, name, path);
795 if (existing != NULL)
797 exfat_put_node(ef, existing);
798 exfat_put_node(ef, dir);
802 rc = find_slot(ef, dir, &cluster, &offset,
803 2 + DIV_ROUND_UP(utf16_length(name), EXFAT_ENAME_MAX));
806 exfat_put_node(ef, dir);
809 rc = write_entry(ef, dir, name, cluster, offset, attrib);
810 exfat_put_node(ef, dir);
814 int exfat_mknod(struct exfat* ef, const char* path)
816 return create(ef, path, EXFAT_ATTRIB_ARCH);
819 int exfat_mkdir(struct exfat* ef, const char* path)
822 struct exfat_node* node;
824 rc = create(ef, path, EXFAT_ATTRIB_ARCH | EXFAT_ATTRIB_DIR);
827 rc = exfat_lookup(ef, &node, path);
830 /* directories always have at least one cluster */
831 rc = exfat_truncate(ef, node, CLUSTER_SIZE(*ef->sb), true);
835 exfat_put_node(ef, node);
838 exfat_put_node(ef, node);
842 static void rename_entry(struct exfat* ef, struct exfat_node* dir,
843 struct exfat_node* node, const le16_t* name, cluster_t new_cluster,
846 struct exfat_entry_meta1 meta1;
847 struct exfat_entry_meta2 meta2;
848 cluster_t old_cluster = node->entry_cluster;
849 off_t old_offset = node->entry_offset;
850 const size_t name_length = utf16_length(name);
851 const int name_entries = DIV_ROUND_UP(name_length, EXFAT_ENAME_MAX);
854 exfat_pread(ef->dev, &meta1, sizeof(meta1),
855 co2o(ef, old_cluster, old_offset));
856 next_entry(ef, node->parent, &old_cluster, &old_offset);
857 exfat_pread(ef->dev, &meta2, sizeof(meta2),
858 co2o(ef, old_cluster, old_offset));
859 meta1.continuations = 1 + name_entries;
860 meta2.name_hash = exfat_calc_name_hash(ef, name);
861 meta2.name_length = name_length;
862 meta1.checksum = exfat_calc_checksum(&meta1, &meta2, name);
864 erase_entry(ef, node);
866 node->entry_cluster = new_cluster;
867 node->entry_offset = new_offset;
869 exfat_pwrite(ef->dev, &meta1, sizeof(meta1),
870 co2o(ef, new_cluster, new_offset));
871 next_entry(ef, dir, &new_cluster, &new_offset);
872 exfat_pwrite(ef->dev, &meta2, sizeof(meta2),
873 co2o(ef, new_cluster, new_offset));
875 for (i = 0; i < name_entries; i++)
877 struct exfat_entry_name name_entry = {EXFAT_ENTRY_FILE_NAME, 0};
878 memcpy(name_entry.name, name + i * EXFAT_ENAME_MAX,
879 EXFAT_ENAME_MAX * sizeof(le16_t));
880 next_entry(ef, dir, &new_cluster, &new_offset);
881 exfat_pwrite(ef->dev, &name_entry, sizeof(name_entry),
882 co2o(ef, new_cluster, new_offset));
885 memcpy(node->name, name, (EXFAT_NAME_MAX + 1) * sizeof(le16_t));
887 tree_attach(dir, node);
890 int exfat_rename(struct exfat* ef, const char* old_path, const char* new_path)
892 struct exfat_node* node;
893 struct exfat_node* existing;
894 struct exfat_node* dir;
895 cluster_t cluster = EXFAT_CLUSTER_BAD;
897 le16_t name[EXFAT_NAME_MAX + 1];
900 rc = exfat_lookup(ef, &node, old_path);
904 rc = exfat_split(ef, &dir, &existing, name, new_path);
907 exfat_put_node(ef, node);
911 /* check that target is not a subdirectory of the source */
912 if (node->flags & EXFAT_ATTRIB_DIR)
914 struct exfat_node* p;
916 for (p = dir; p; p = p->parent)
919 if (existing != NULL)
920 exfat_put_node(ef, existing);
921 exfat_put_node(ef, dir);
922 exfat_put_node(ef, node);
927 if (existing != NULL)
929 /* remove target if it's not the same node as source */
930 if (existing != node)
932 if (existing->flags & EXFAT_ATTRIB_DIR)
934 if (node->flags & EXFAT_ATTRIB_DIR)
935 rc = exfat_rmdir(ef, existing);
941 if (!(node->flags & EXFAT_ATTRIB_DIR))
942 rc = exfat_unlink(ef, existing);
946 exfat_put_node(ef, existing);
949 exfat_put_node(ef, dir);
950 exfat_put_node(ef, node);
955 exfat_put_node(ef, existing);
958 rc = find_slot(ef, dir, &cluster, &offset,
959 2 + DIV_ROUND_UP(utf16_length(name), EXFAT_ENAME_MAX));
962 exfat_put_node(ef, dir);
963 exfat_put_node(ef, node);
966 rename_entry(ef, dir, node, name, cluster, offset);
967 exfat_put_node(ef, dir);
968 exfat_put_node(ef, node);
972 void exfat_utimes(struct exfat_node* node, const struct timespec tv[2])
974 node->atime = tv[0].tv_sec;
975 node->mtime = tv[1].tv_sec;
976 node->flags |= EXFAT_ATTRIB_DIRTY;
979 void exfat_update_atime(struct exfat_node* node)
981 node->atime = time(NULL);
982 node->flags |= EXFAT_ATTRIB_DIRTY;
985 void exfat_update_mtime(struct exfat_node* node)
987 node->mtime = time(NULL);
988 node->flags |= EXFAT_ATTRIB_DIRTY;
991 const char* exfat_get_label(struct exfat* ef)
996 static int find_label(struct exfat* ef, cluster_t* cluster, off_t* offset)
1001 rc = opendir(ef, ef->root, &it);
1007 if (it.offset >= ef->root->size)
1013 if (get_entry_ptr(ef, &it)->type == EXFAT_ENTRY_LABEL)
1015 *cluster = it.cluster;
1016 *offset = it.offset;
1021 if (fetch_next_entry(ef, ef->root, &it) != 0)
1029 int exfat_set_label(struct exfat* ef, const char* label)
1031 le16_t label_utf16[EXFAT_ENAME_MAX + 1];
1035 struct exfat_entry_label entry;
1037 memset(label_utf16, 0, sizeof(label_utf16));
1038 rc = utf8_to_utf16(label_utf16, label, EXFAT_ENAME_MAX, strlen(label));
1042 rc = find_label(ef, &cluster, &offset);
1044 rc = find_slot(ef, ef->root, &cluster, &offset, 1);
1048 entry.type = EXFAT_ENTRY_LABEL;
1049 entry.length = utf16_length(label_utf16);
1050 memcpy(entry.name, label_utf16, sizeof(entry.name));
1051 if (entry.length == 0)
1052 entry.type ^= EXFAT_ENTRY_VALID;
1054 exfat_pwrite(ef->dev, &entry, sizeof(struct exfat_entry_label),
1055 co2o(ef, cluster, offset));
1056 strcpy(ef->label, label);