3 exFAT file system implementation library.
5 Copyright (C) 2010-2012 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;
191 if (it->offset >= parent->size)
193 if (continuations != 0)
195 exfat_error("expected %hhu continuations", continuations);
198 return -ENOENT; /* that's OK, means end of directory */
201 entry = get_entry_ptr(ef, it);
204 case EXFAT_ENTRY_FILE:
205 if (continuations != 0)
207 exfat_error("expected %hhu continuations before new entry",
211 meta1 = (const struct exfat_entry_meta1*) entry;
212 continuations = meta1->continuations;
213 /* each file entry must have at least 2 continuations:
215 if (continuations < 2)
217 exfat_error("too few continuations (%hhu)", continuations);
220 reference_checksum = le16_to_cpu(meta1->checksum);
221 actual_checksum = exfat_start_checksum(meta1);
222 *node = allocate_node();
228 /* new node has zero reference counter */
229 (*node)->entry_cluster = it->cluster;
230 (*node)->entry_offset = it->offset;
231 init_node_meta1(*node, meta1);
232 namep = (*node)->name;
235 case EXFAT_ENTRY_FILE_INFO:
236 if (continuations < 2)
238 exfat_error("unexpected continuation (%hhu)",
242 meta2 = (const struct exfat_entry_meta2*) entry;
243 if (meta2->flags & ~(EXFAT_FLAG_ALWAYS1 | EXFAT_FLAG_CONTIGUOUS))
245 exfat_error("unknown flags in meta2 (0x%hhx)", meta2->flags);
248 init_node_meta2(*node, meta2);
249 actual_checksum = exfat_add_checksum(entry, actual_checksum);
250 /* There are two fields that contain file size. Maybe they plan
251 to add compression support in the future and one of those
252 fields is visible (uncompressed) size and the other is real
253 (compressed) size. Anyway, currently it looks like exFAT does
254 not support compression and both fields must be equal. */
255 if (le64_to_cpu(meta2->real_size) != (*node)->size)
257 exfat_error("real size does not equal to size "
258 "(%"PRIu64" != %"PRIu64")",
259 le64_to_cpu(meta2->real_size), (*node)->size);
262 /* empty files must be marked as non-contiguous */
263 if ((*node)->size == 0 && (meta2->flags & EXFAT_FLAG_CONTIGUOUS))
265 exfat_error("empty file marked as contiguous (0x%hhx)",
269 /* directories must be aligned on at cluster boundary */
270 if (((*node)->flags & EXFAT_ATTRIB_DIR) &&
271 (*node)->size % CLUSTER_SIZE(*ef->sb) != 0)
273 exfat_error("directory has invalid size %"PRIu64" bytes",
280 case EXFAT_ENTRY_FILE_NAME:
281 if (continuations == 0)
283 exfat_error("unexpected continuation");
286 file_name = (const struct exfat_entry_name*) entry;
287 actual_checksum = exfat_add_checksum(entry, actual_checksum);
289 memcpy(namep, file_name->name, EXFAT_ENAME_MAX * sizeof(le16_t));
290 namep += EXFAT_ENAME_MAX;
291 if (--continuations == 0)
293 if (actual_checksum != reference_checksum)
295 exfat_error("invalid checksum (0x%hx != 0x%hx)",
296 actual_checksum, reference_checksum);
299 if (fetch_next_entry(ef, parent, it) != 0)
301 return 0; /* entry completed */
305 case EXFAT_ENTRY_UPCASE:
306 if (ef->upcase != NULL)
308 upcase = (const struct exfat_entry_upcase*) entry;
309 if (CLUSTER_INVALID(le32_to_cpu(upcase->start_cluster)))
311 exfat_error("invalid cluster 0x%x in upcase table",
312 le32_to_cpu(upcase->start_cluster));
315 if (le64_to_cpu(upcase->size) == 0 ||
316 le64_to_cpu(upcase->size) > 0xffff * sizeof(uint16_t) ||
317 le64_to_cpu(upcase->size) % sizeof(uint16_t) != 0)
319 exfat_error("bad upcase table size (%"PRIu64" bytes)",
320 le64_to_cpu(upcase->size));
323 ef->upcase = malloc(le64_to_cpu(upcase->size));
324 if (ef->upcase == NULL)
326 exfat_error("failed to allocate upcase table (%"PRIu64" bytes)",
327 le64_to_cpu(upcase->size));
331 ef->upcase_chars = le64_to_cpu(upcase->size) / sizeof(le16_t);
333 exfat_pread(ef->dev, ef->upcase, le64_to_cpu(upcase->size),
334 exfat_c2o(ef, le32_to_cpu(upcase->start_cluster)));
337 case EXFAT_ENTRY_BITMAP:
338 bitmap = (const struct exfat_entry_bitmap*) entry;
339 ef->cmap.start_cluster = le32_to_cpu(bitmap->start_cluster);
340 if (CLUSTER_INVALID(ef->cmap.start_cluster))
342 exfat_error("invalid cluster 0x%x in clusters bitmap",
343 ef->cmap.start_cluster);
346 ef->cmap.size = le32_to_cpu(ef->sb->cluster_count) -
347 EXFAT_FIRST_DATA_CLUSTER;
348 if (le64_to_cpu(bitmap->size) < (ef->cmap.size + 7) / 8)
350 exfat_error("invalid clusters bitmap size: %"PRIu64
351 " (expected at least %u)",
352 le64_to_cpu(bitmap->size), (ef->cmap.size + 7) / 8);
355 /* FIXME bitmap can be rather big, up to 512 MB */
356 ef->cmap.chunk_size = ef->cmap.size;
357 ef->cmap.chunk = malloc(le64_to_cpu(bitmap->size));
358 if (ef->cmap.chunk == NULL)
360 exfat_error("failed to allocate clusters bitmap chunk "
361 "(%"PRIu64" bytes)", le64_to_cpu(bitmap->size));
366 exfat_pread(ef->dev, ef->cmap.chunk, le64_to_cpu(bitmap->size),
367 exfat_c2o(ef, ef->cmap.start_cluster));
370 case EXFAT_ENTRY_LABEL:
371 label = (const struct exfat_entry_label*) entry;
372 if (label->length > EXFAT_ENAME_MAX)
374 exfat_error("too long label (%hhu chars)", label->length);
377 if (utf16_to_utf8(ef->label, label->name,
378 sizeof(ef->label), EXFAT_ENAME_MAX) != 0)
383 if (entry->type & EXFAT_ENTRY_VALID)
385 exfat_error("unknown entry type 0x%hhx", entry->type);
391 if (fetch_next_entry(ef, parent, it) != 0)
394 /* we never reach here */
402 int exfat_cache_directory(struct exfat* ef, struct exfat_node* dir)
406 struct exfat_node* node;
407 struct exfat_node* current = NULL;
409 if (dir->flags & EXFAT_ATTRIB_CACHED)
410 return 0; /* already cached */
412 rc = opendir(ef, dir, &it);
415 while ((rc = readdir(ef, dir, &node, &it)) == 0)
420 current->next = node;
421 node->prev = current;
433 for (current = dir->child; current; current = node)
435 node = current->next;
442 dir->flags |= EXFAT_ATTRIB_CACHED;
446 static void reset_cache(struct exfat* ef, struct exfat_node* node)
448 struct exfat_node* child;
449 struct exfat_node* next;
451 for (child = node->child; child; child = next)
453 reset_cache(ef, child);
457 if (node->references != 0)
459 char buffer[EXFAT_NAME_MAX + 1];
460 exfat_get_name(node, buffer, EXFAT_NAME_MAX);
461 exfat_warn("non-zero reference counter (%d) for `%s'",
462 node->references, buffer);
464 while (node->references--)
465 exfat_put_node(ef, node);
467 node->flags &= ~EXFAT_ATTRIB_CACHED;
470 void exfat_reset_cache(struct exfat* ef)
472 reset_cache(ef, ef->root);
475 void next_entry(struct exfat* ef, const struct exfat_node* parent,
476 cluster_t* cluster, off_t* offset)
478 *offset += sizeof(struct exfat_entry);
479 if (*offset % CLUSTER_SIZE(*ef->sb) == 0)
480 /* next cluster cannot be invalid */
481 *cluster = exfat_next_cluster(ef, parent, *cluster);
484 void exfat_flush_node(struct exfat* ef, struct exfat_node* node)
488 off_t meta1_offset, meta2_offset;
489 struct exfat_entry_meta1 meta1;
490 struct exfat_entry_meta2 meta2;
493 exfat_bug("unable to flush node to read-only FS");
495 if (node->parent == NULL)
496 return; /* do not flush unlinked node */
498 cluster = node->entry_cluster;
499 offset = node->entry_offset;
500 meta1_offset = co2o(ef, cluster, offset);
501 next_entry(ef, node->parent, &cluster, &offset);
502 meta2_offset = co2o(ef, cluster, offset);
504 exfat_pread(ef->dev, &meta1, sizeof(meta1), meta1_offset);
505 if (meta1.type != EXFAT_ENTRY_FILE)
506 exfat_bug("invalid type of meta1: 0x%hhx", meta1.type);
507 meta1.attrib = cpu_to_le16(node->flags);
508 exfat_unix2exfat(node->mtime, &meta1.mdate, &meta1.mtime, &meta1.mtime_cs);
509 exfat_unix2exfat(node->atime, &meta1.adate, &meta1.atime, NULL);
511 exfat_pread(ef->dev, &meta2, sizeof(meta2), meta2_offset);
512 if (meta2.type != EXFAT_ENTRY_FILE_INFO)
513 exfat_bug("invalid type of meta2: 0x%hhx", meta2.type);
514 meta2.size = meta2.real_size = cpu_to_le64(node->size);
515 meta2.start_cluster = cpu_to_le32(node->start_cluster);
516 meta2.flags = EXFAT_FLAG_ALWAYS1;
517 /* empty files must not be marked as contiguous */
518 if (node->size != 0 && IS_CONTIGUOUS(*node))
519 meta2.flags |= EXFAT_FLAG_CONTIGUOUS;
520 /* name hash remains unchanged, no need to recalculate it */
522 meta1.checksum = exfat_calc_checksum(&meta1, &meta2, node->name);
524 exfat_pwrite(ef->dev, &meta1, sizeof(meta1), meta1_offset);
525 exfat_pwrite(ef->dev, &meta2, sizeof(meta2), meta2_offset);
527 node->flags &= ~EXFAT_ATTRIB_DIRTY;
530 static void erase_entry(struct exfat* ef, struct exfat_node* node)
532 cluster_t cluster = node->entry_cluster;
533 off_t offset = node->entry_offset;
534 int name_entries = DIV_ROUND_UP(utf16_length(node->name), EXFAT_ENAME_MAX);
537 entry_type = EXFAT_ENTRY_FILE & ~EXFAT_ENTRY_VALID;
538 exfat_pwrite(ef->dev, &entry_type, 1, co2o(ef, cluster, offset));
540 next_entry(ef, node->parent, &cluster, &offset);
541 entry_type = EXFAT_ENTRY_FILE_INFO & ~EXFAT_ENTRY_VALID;
542 exfat_pwrite(ef->dev, &entry_type, 1, co2o(ef, cluster, offset));
544 while (name_entries--)
546 next_entry(ef, node->parent, &cluster, &offset);
547 entry_type = EXFAT_ENTRY_FILE_NAME & ~EXFAT_ENTRY_VALID;
548 exfat_pwrite(ef->dev, &entry_type, 1, co2o(ef, cluster, offset));
552 static void tree_detach(struct exfat_node* node)
555 node->prev->next = node->next;
556 else /* this is the first node in the list */
557 node->parent->child = node->next;
559 node->next->prev = node->prev;
565 static void tree_attach(struct exfat_node* dir, struct exfat_node* node)
570 dir->child->prev = node;
571 node->next = dir->child;
576 static int shrink_directory(struct exfat* ef, struct exfat_node* dir,
577 off_t deleted_offset)
579 const struct exfat_node* node;
580 const struct exfat_node* last_node;
581 uint64_t entries = 0;
585 if (!(dir->flags & EXFAT_ATTRIB_DIR))
586 exfat_bug("attempted to shrink a file");
587 if (!(dir->flags & EXFAT_ATTRIB_CACHED))
588 exfat_bug("attempted to shrink uncached directory");
590 for (last_node = node = dir->child; node; node = node->next)
592 if (deleted_offset < node->entry_offset)
594 /* there are other entries after the removed one, no way to shrink
598 if (last_node->entry_offset < node->entry_offset)
604 /* offset of the last entry */
605 entries += last_node->entry_offset / sizeof(struct exfat_entry);
606 /* two subentries with meta info */
608 /* subentries with file name */
609 entries += DIV_ROUND_UP(utf16_length(last_node->name),
613 new_size = DIV_ROUND_UP(entries * sizeof(struct exfat_entry),
614 CLUSTER_SIZE(*ef->sb)) * CLUSTER_SIZE(*ef->sb);
615 if (new_size == 0) /* directory always has at least 1 cluster */
616 new_size = CLUSTER_SIZE(*ef->sb);
617 if (new_size == dir->size)
619 rc = exfat_truncate(ef, dir, new_size);
625 static int delete(struct exfat* ef, struct exfat_node* node)
627 struct exfat_node* parent = node->parent;
628 off_t deleted_offset = node->entry_offset;
631 exfat_get_node(parent);
632 erase_entry(ef, node);
633 exfat_update_mtime(parent);
635 rc = shrink_directory(ef, parent, deleted_offset);
636 exfat_put_node(ef, parent);
637 /* file clusters will be freed when node reference counter becomes 0 */
638 node->flags |= EXFAT_ATTRIB_UNLINKED;
642 int exfat_unlink(struct exfat* ef, struct exfat_node* node)
644 if (node->flags & EXFAT_ATTRIB_DIR)
646 return delete(ef, node);
649 int exfat_rmdir(struct exfat* ef, struct exfat_node* node)
651 if (!(node->flags & EXFAT_ATTRIB_DIR))
653 /* check that directory is empty */
654 exfat_cache_directory(ef, node);
657 return delete(ef, node);
660 static int grow_directory(struct exfat* ef, struct exfat_node* dir,
661 uint64_t asize, uint32_t difference)
663 return exfat_truncate(ef, dir,
664 DIV_ROUND_UP(asize + difference, CLUSTER_SIZE(*ef->sb))
665 * CLUSTER_SIZE(*ef->sb));
668 static int find_slot(struct exfat* ef, struct exfat_node* dir,
669 cluster_t* cluster, off_t* offset, int subentries)
673 const struct exfat_entry* entry;
676 rc = opendir(ef, dir, &it);
683 *cluster = it.cluster;
686 entry = get_entry_ptr(ef, &it);
687 if (entry->type & EXFAT_ENTRY_VALID)
691 if (contiguous == subentries)
692 break; /* suitable slot is found */
693 if (it.offset + sizeof(struct exfat_entry) >= dir->size)
695 rc = grow_directory(ef, dir, dir->size,
696 (subentries - contiguous) * sizeof(struct exfat_entry));
703 if (fetch_next_entry(ef, dir, &it) != 0)
713 static int write_entry(struct exfat* ef, struct exfat_node* dir,
714 const le16_t* name, cluster_t cluster, off_t offset, uint16_t attrib)
716 struct exfat_node* node;
717 struct exfat_entry_meta1 meta1;
718 struct exfat_entry_meta2 meta2;
719 const size_t name_length = utf16_length(name);
720 const int name_entries = DIV_ROUND_UP(name_length, EXFAT_ENAME_MAX);
723 node = allocate_node();
726 node->entry_cluster = cluster;
727 node->entry_offset = offset;
728 memcpy(node->name, name, name_length * sizeof(le16_t));
730 memset(&meta1, 0, sizeof(meta1));
731 meta1.type = EXFAT_ENTRY_FILE;
732 meta1.continuations = 1 + name_entries;
733 meta1.attrib = cpu_to_le16(attrib);
734 exfat_unix2exfat(time(NULL), &meta1.crdate, &meta1.crtime,
736 meta1.adate = meta1.mdate = meta1.crdate;
737 meta1.atime = meta1.mtime = meta1.crtime;
738 meta1.mtime_cs = meta1.crtime_cs; /* there is no atime_cs */
740 memset(&meta2, 0, sizeof(meta2));
741 meta2.type = EXFAT_ENTRY_FILE_INFO;
742 meta2.flags = EXFAT_FLAG_ALWAYS1;
743 meta2.name_length = name_length;
744 meta2.name_hash = exfat_calc_name_hash(ef, node->name);
745 meta2.start_cluster = cpu_to_le32(EXFAT_CLUSTER_FREE);
747 meta1.checksum = exfat_calc_checksum(&meta1, &meta2, node->name);
749 exfat_pwrite(ef->dev, &meta1, sizeof(meta1), co2o(ef, cluster, offset));
750 next_entry(ef, dir, &cluster, &offset);
751 exfat_pwrite(ef->dev, &meta2, sizeof(meta2), co2o(ef, cluster, offset));
752 for (i = 0; i < name_entries; i++)
754 struct exfat_entry_name name_entry = {EXFAT_ENTRY_FILE_NAME, 0};
755 memcpy(name_entry.name, node->name + i * EXFAT_ENAME_MAX,
756 EXFAT_ENAME_MAX * sizeof(le16_t));
757 next_entry(ef, dir, &cluster, &offset);
758 exfat_pwrite(ef->dev, &name_entry, sizeof(name_entry),
759 co2o(ef, cluster, offset));
762 init_node_meta1(node, &meta1);
763 init_node_meta2(node, &meta2);
765 tree_attach(dir, node);
766 exfat_update_mtime(dir);
770 static int create(struct exfat* ef, const char* path, uint16_t attrib)
772 struct exfat_node* dir;
773 struct exfat_node* existing;
774 cluster_t cluster = EXFAT_CLUSTER_BAD;
776 le16_t name[EXFAT_NAME_MAX + 1];
779 rc = exfat_split(ef, &dir, &existing, name, path);
782 if (existing != NULL)
784 exfat_put_node(ef, existing);
785 exfat_put_node(ef, dir);
789 rc = find_slot(ef, dir, &cluster, &offset,
790 2 + DIV_ROUND_UP(utf16_length(name), EXFAT_ENAME_MAX));
793 exfat_put_node(ef, dir);
796 rc = write_entry(ef, dir, name, cluster, offset, attrib);
797 exfat_put_node(ef, dir);
801 int exfat_mknod(struct exfat* ef, const char* path)
803 return create(ef, path, EXFAT_ATTRIB_ARCH);
806 int exfat_mkdir(struct exfat* ef, const char* path)
809 struct exfat_node* node;
811 rc = create(ef, path, EXFAT_ATTRIB_ARCH | EXFAT_ATTRIB_DIR);
814 rc = exfat_lookup(ef, &node, path);
817 /* directories always have at least one cluster */
818 rc = exfat_truncate(ef, node, CLUSTER_SIZE(*ef->sb));
822 exfat_put_node(ef, node);
825 exfat_put_node(ef, node);
829 static void rename_entry(struct exfat* ef, struct exfat_node* dir,
830 struct exfat_node* node, const le16_t* name, cluster_t new_cluster,
833 struct exfat_entry_meta1 meta1;
834 struct exfat_entry_meta2 meta2;
835 cluster_t old_cluster = node->entry_cluster;
836 off_t old_offset = node->entry_offset;
837 const size_t name_length = utf16_length(name);
838 const int name_entries = DIV_ROUND_UP(name_length, EXFAT_ENAME_MAX);
841 exfat_pread(ef->dev, &meta1, sizeof(meta1),
842 co2o(ef, old_cluster, old_offset));
843 next_entry(ef, node->parent, &old_cluster, &old_offset);
844 exfat_pread(ef->dev, &meta2, sizeof(meta2),
845 co2o(ef, old_cluster, old_offset));
846 meta1.continuations = 1 + name_entries;
847 meta2.name_hash = exfat_calc_name_hash(ef, name);
848 meta2.name_length = name_length;
849 meta1.checksum = exfat_calc_checksum(&meta1, &meta2, name);
851 erase_entry(ef, node);
853 node->entry_cluster = new_cluster;
854 node->entry_offset = new_offset;
856 exfat_pwrite(ef->dev, &meta1, sizeof(meta1),
857 co2o(ef, new_cluster, new_offset));
858 next_entry(ef, dir, &new_cluster, &new_offset);
859 exfat_pwrite(ef->dev, &meta2, sizeof(meta2),
860 co2o(ef, new_cluster, new_offset));
862 for (i = 0; i < name_entries; i++)
864 struct exfat_entry_name name_entry = {EXFAT_ENTRY_FILE_NAME, 0};
865 memcpy(name_entry.name, name + i * EXFAT_ENAME_MAX,
866 EXFAT_ENAME_MAX * sizeof(le16_t));
867 next_entry(ef, dir, &new_cluster, &new_offset);
868 exfat_pwrite(ef->dev, &name_entry, sizeof(name_entry),
869 co2o(ef, new_cluster, new_offset));
872 memcpy(node->name, name, (EXFAT_NAME_MAX + 1) * sizeof(le16_t));
874 tree_attach(dir, node);
877 int exfat_rename(struct exfat* ef, const char* old_path, const char* new_path)
879 struct exfat_node* node;
880 struct exfat_node* existing;
881 struct exfat_node* dir;
882 cluster_t cluster = EXFAT_CLUSTER_BAD;
884 le16_t name[EXFAT_NAME_MAX + 1];
887 rc = exfat_lookup(ef, &node, old_path);
891 rc = exfat_split(ef, &dir, &existing, name, new_path);
894 exfat_put_node(ef, node);
897 if (existing != NULL)
899 if (existing->flags & EXFAT_ATTRIB_DIR)
901 if (node->flags & EXFAT_ATTRIB_DIR)
902 rc = exfat_rmdir(ef, existing);
908 if (!(node->flags & EXFAT_ATTRIB_DIR))
909 rc = exfat_unlink(ef, existing);
913 exfat_put_node(ef, existing);
916 exfat_put_node(ef, dir);
917 exfat_put_node(ef, node);
922 rc = find_slot(ef, dir, &cluster, &offset,
923 2 + DIV_ROUND_UP(utf16_length(name), EXFAT_ENAME_MAX));
926 exfat_put_node(ef, dir);
927 exfat_put_node(ef, node);
930 rename_entry(ef, dir, node, name, cluster, offset);
931 exfat_put_node(ef, dir);
932 exfat_put_node(ef, node);
936 void exfat_utimes(struct exfat_node* node, const struct timespec tv[2])
938 node->atime = tv[0].tv_sec;
939 node->mtime = tv[1].tv_sec;
940 node->flags |= EXFAT_ATTRIB_DIRTY;
943 void exfat_update_atime(struct exfat_node* node)
945 node->atime = time(NULL);
946 node->flags |= EXFAT_ATTRIB_DIRTY;
949 void exfat_update_mtime(struct exfat_node* node)
951 node->mtime = time(NULL);
952 node->flags |= EXFAT_ATTRIB_DIRTY;
955 const char* exfat_get_label(struct exfat* ef)
960 static int find_label(struct exfat* ef, cluster_t* cluster, off_t* offset)
965 rc = opendir(ef, ef->root, &it);
971 if (it.offset >= ef->root->size)
977 if (get_entry_ptr(ef, &it)->type == EXFAT_ENTRY_LABEL)
979 *cluster = it.cluster;
985 if (fetch_next_entry(ef, ef->root, &it) != 0)
993 int exfat_set_label(struct exfat* ef, const char* label)
995 le16_t label_utf16[EXFAT_ENAME_MAX + 1];
999 struct exfat_entry_label entry;
1001 memset(label_utf16, 0, sizeof(label_utf16));
1002 rc = utf8_to_utf16(label_utf16, label, EXFAT_ENAME_MAX, strlen(label));
1006 rc = find_label(ef, &cluster, &offset);
1008 rc = find_slot(ef, ef->root, &cluster, &offset, 1);
1012 entry.type = EXFAT_ENTRY_LABEL;
1013 entry.length = utf16_length(label_utf16);
1014 memcpy(entry.name, label_utf16, sizeof(entry.name));
1015 if (entry.length == 0)
1016 entry.type ^= EXFAT_ENTRY_VALID;
1018 exfat_pwrite(ef->dev, &entry, sizeof(struct exfat_entry_label),
1019 co2o(ef, cluster, offset));