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;
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 reset_cache(struct exfat* ef, struct exfat_node* node)
462 struct exfat_node* child;
463 struct exfat_node* next;
465 for (child = node->child; child; child = next)
467 reset_cache(ef, child);
471 if (node->references != 0)
473 char buffer[EXFAT_NAME_MAX + 1];
474 exfat_get_name(node, buffer, EXFAT_NAME_MAX);
475 exfat_warn("non-zero reference counter (%d) for `%s'",
476 node->references, buffer);
478 while (node->references)
479 exfat_put_node(ef, node);
481 node->flags &= ~EXFAT_ATTRIB_CACHED;
484 void exfat_reset_cache(struct exfat* ef)
486 reset_cache(ef, ef->root);
489 void next_entry(struct exfat* ef, const struct exfat_node* parent,
490 cluster_t* cluster, off_t* offset)
492 *offset += sizeof(struct exfat_entry);
493 if (*offset % CLUSTER_SIZE(*ef->sb) == 0)
494 /* next cluster cannot be invalid */
495 *cluster = exfat_next_cluster(ef, parent, *cluster);
498 void exfat_flush_node(struct exfat* ef, struct exfat_node* node)
502 off_t meta1_offset, meta2_offset;
503 struct exfat_entry_meta1 meta1;
504 struct exfat_entry_meta2 meta2;
507 exfat_bug("unable to flush node to read-only FS");
509 if (node->parent == NULL)
510 return; /* do not flush unlinked node */
512 cluster = node->entry_cluster;
513 offset = node->entry_offset;
514 meta1_offset = co2o(ef, cluster, offset);
515 next_entry(ef, node->parent, &cluster, &offset);
516 meta2_offset = co2o(ef, cluster, offset);
518 exfat_pread(ef->dev, &meta1, sizeof(meta1), meta1_offset);
519 if (meta1.type != EXFAT_ENTRY_FILE)
520 exfat_bug("invalid type of meta1: 0x%hhx", meta1.type);
521 meta1.attrib = cpu_to_le16(node->flags);
522 exfat_unix2exfat(node->mtime, &meta1.mdate, &meta1.mtime, &meta1.mtime_cs);
523 exfat_unix2exfat(node->atime, &meta1.adate, &meta1.atime, NULL);
525 exfat_pread(ef->dev, &meta2, sizeof(meta2), meta2_offset);
526 if (meta2.type != EXFAT_ENTRY_FILE_INFO)
527 exfat_bug("invalid type of meta2: 0x%hhx", meta2.type);
528 meta2.size = meta2.real_size = cpu_to_le64(node->size);
529 meta2.start_cluster = cpu_to_le32(node->start_cluster);
530 meta2.flags = EXFAT_FLAG_ALWAYS1;
531 /* empty files must not be marked as contiguous */
532 if (node->size != 0 && IS_CONTIGUOUS(*node))
533 meta2.flags |= EXFAT_FLAG_CONTIGUOUS;
534 /* name hash remains unchanged, no need to recalculate it */
536 meta1.checksum = exfat_calc_checksum(&meta1, &meta2, node->name);
538 exfat_pwrite(ef->dev, &meta1, sizeof(meta1), meta1_offset);
539 exfat_pwrite(ef->dev, &meta2, sizeof(meta2), meta2_offset);
541 node->flags &= ~EXFAT_ATTRIB_DIRTY;
544 static void erase_entry(struct exfat* ef, struct exfat_node* node)
546 cluster_t cluster = node->entry_cluster;
547 off_t offset = node->entry_offset;
548 int name_entries = DIV_ROUND_UP(utf16_length(node->name), EXFAT_ENAME_MAX);
551 entry_type = EXFAT_ENTRY_FILE & ~EXFAT_ENTRY_VALID;
552 exfat_pwrite(ef->dev, &entry_type, 1, co2o(ef, cluster, offset));
554 next_entry(ef, node->parent, &cluster, &offset);
555 entry_type = EXFAT_ENTRY_FILE_INFO & ~EXFAT_ENTRY_VALID;
556 exfat_pwrite(ef->dev, &entry_type, 1, co2o(ef, cluster, offset));
558 while (name_entries--)
560 next_entry(ef, node->parent, &cluster, &offset);
561 entry_type = EXFAT_ENTRY_FILE_NAME & ~EXFAT_ENTRY_VALID;
562 exfat_pwrite(ef->dev, &entry_type, 1, co2o(ef, cluster, offset));
566 static void tree_detach(struct exfat_node* node)
569 node->prev->next = node->next;
570 else /* this is the first node in the list */
571 node->parent->child = node->next;
573 node->next->prev = node->prev;
579 static void tree_attach(struct exfat_node* dir, struct exfat_node* node)
584 dir->child->prev = node;
585 node->next = dir->child;
590 static int shrink_directory(struct exfat* ef, struct exfat_node* dir,
591 off_t deleted_offset)
593 const struct exfat_node* node;
594 const struct exfat_node* last_node;
595 uint64_t entries = 0;
599 if (!(dir->flags & EXFAT_ATTRIB_DIR))
600 exfat_bug("attempted to shrink a file");
601 if (!(dir->flags & EXFAT_ATTRIB_CACHED))
602 exfat_bug("attempted to shrink uncached directory");
604 for (last_node = node = dir->child; node; node = node->next)
606 if (deleted_offset < node->entry_offset)
608 /* there are other entries after the removed one, no way to shrink
612 if (last_node->entry_offset < node->entry_offset)
618 /* offset of the last entry */
619 entries += last_node->entry_offset / sizeof(struct exfat_entry);
620 /* two subentries with meta info */
622 /* subentries with file name */
623 entries += DIV_ROUND_UP(utf16_length(last_node->name),
627 new_size = DIV_ROUND_UP(entries * sizeof(struct exfat_entry),
628 CLUSTER_SIZE(*ef->sb)) * CLUSTER_SIZE(*ef->sb);
629 if (new_size == 0) /* directory always has at least 1 cluster */
630 new_size = CLUSTER_SIZE(*ef->sb);
631 if (new_size == dir->size)
633 rc = exfat_truncate(ef, dir, new_size);
639 static int delete(struct exfat* ef, struct exfat_node* node)
641 struct exfat_node* parent = node->parent;
642 off_t deleted_offset = node->entry_offset;
645 exfat_get_node(parent);
646 erase_entry(ef, node);
647 exfat_update_mtime(parent);
649 rc = shrink_directory(ef, parent, deleted_offset);
650 exfat_put_node(ef, parent);
651 /* file clusters will be freed when node reference counter becomes 0 */
652 node->flags |= EXFAT_ATTRIB_UNLINKED;
656 int exfat_unlink(struct exfat* ef, struct exfat_node* node)
658 if (node->flags & EXFAT_ATTRIB_DIR)
660 return delete(ef, node);
663 int exfat_rmdir(struct exfat* ef, struct exfat_node* node)
665 if (!(node->flags & EXFAT_ATTRIB_DIR))
667 /* check that directory is empty */
668 exfat_cache_directory(ef, node);
671 return delete(ef, node);
674 static int grow_directory(struct exfat* ef, struct exfat_node* dir,
675 uint64_t asize, uint32_t difference)
677 return exfat_truncate(ef, dir,
678 DIV_ROUND_UP(asize + difference, CLUSTER_SIZE(*ef->sb))
679 * CLUSTER_SIZE(*ef->sb));
682 static int find_slot(struct exfat* ef, struct exfat_node* dir,
683 cluster_t* cluster, off_t* offset, int subentries)
687 const struct exfat_entry* entry;
690 rc = opendir(ef, dir, &it);
697 *cluster = it.cluster;
700 entry = get_entry_ptr(ef, &it);
701 if (entry->type & EXFAT_ENTRY_VALID)
705 if (contiguous == subentries)
706 break; /* suitable slot is found */
707 if (it.offset + sizeof(struct exfat_entry) >= dir->size)
709 rc = grow_directory(ef, dir, dir->size,
710 (subentries - contiguous) * sizeof(struct exfat_entry));
717 if (fetch_next_entry(ef, dir, &it) != 0)
727 static int write_entry(struct exfat* ef, struct exfat_node* dir,
728 const le16_t* name, cluster_t cluster, off_t offset, uint16_t attrib)
730 struct exfat_node* node;
731 struct exfat_entry_meta1 meta1;
732 struct exfat_entry_meta2 meta2;
733 const size_t name_length = utf16_length(name);
734 const int name_entries = DIV_ROUND_UP(name_length, EXFAT_ENAME_MAX);
737 node = allocate_node();
740 node->entry_cluster = cluster;
741 node->entry_offset = offset;
742 memcpy(node->name, name, name_length * sizeof(le16_t));
744 memset(&meta1, 0, sizeof(meta1));
745 meta1.type = EXFAT_ENTRY_FILE;
746 meta1.continuations = 1 + name_entries;
747 meta1.attrib = cpu_to_le16(attrib);
748 exfat_unix2exfat(time(NULL), &meta1.crdate, &meta1.crtime,
750 meta1.adate = meta1.mdate = meta1.crdate;
751 meta1.atime = meta1.mtime = meta1.crtime;
752 meta1.mtime_cs = meta1.crtime_cs; /* there is no atime_cs */
754 memset(&meta2, 0, sizeof(meta2));
755 meta2.type = EXFAT_ENTRY_FILE_INFO;
756 meta2.flags = EXFAT_FLAG_ALWAYS1;
757 meta2.name_length = name_length;
758 meta2.name_hash = exfat_calc_name_hash(ef, node->name);
759 meta2.start_cluster = cpu_to_le32(EXFAT_CLUSTER_FREE);
761 meta1.checksum = exfat_calc_checksum(&meta1, &meta2, node->name);
763 exfat_pwrite(ef->dev, &meta1, sizeof(meta1), co2o(ef, cluster, offset));
764 next_entry(ef, dir, &cluster, &offset);
765 exfat_pwrite(ef->dev, &meta2, sizeof(meta2), co2o(ef, cluster, offset));
766 for (i = 0; i < name_entries; i++)
768 struct exfat_entry_name name_entry = {EXFAT_ENTRY_FILE_NAME, 0};
769 memcpy(name_entry.name, node->name + i * EXFAT_ENAME_MAX,
770 EXFAT_ENAME_MAX * sizeof(le16_t));
771 next_entry(ef, dir, &cluster, &offset);
772 exfat_pwrite(ef->dev, &name_entry, sizeof(name_entry),
773 co2o(ef, cluster, offset));
776 init_node_meta1(node, &meta1);
777 init_node_meta2(node, &meta2);
779 tree_attach(dir, node);
780 exfat_update_mtime(dir);
784 static int create(struct exfat* ef, const char* path, uint16_t attrib)
786 struct exfat_node* dir;
787 struct exfat_node* existing;
788 cluster_t cluster = EXFAT_CLUSTER_BAD;
790 le16_t name[EXFAT_NAME_MAX + 1];
793 rc = exfat_split(ef, &dir, &existing, name, path);
796 if (existing != NULL)
798 exfat_put_node(ef, existing);
799 exfat_put_node(ef, dir);
803 rc = find_slot(ef, dir, &cluster, &offset,
804 2 + DIV_ROUND_UP(utf16_length(name), EXFAT_ENAME_MAX));
807 exfat_put_node(ef, dir);
810 rc = write_entry(ef, dir, name, cluster, offset, attrib);
811 exfat_put_node(ef, dir);
815 int exfat_mknod(struct exfat* ef, const char* path)
817 return create(ef, path, EXFAT_ATTRIB_ARCH);
820 int exfat_mkdir(struct exfat* ef, const char* path)
823 struct exfat_node* node;
825 rc = create(ef, path, EXFAT_ATTRIB_ARCH | EXFAT_ATTRIB_DIR);
828 rc = exfat_lookup(ef, &node, path);
831 /* directories always have at least one cluster */
832 rc = exfat_truncate(ef, node, CLUSTER_SIZE(*ef->sb));
836 exfat_put_node(ef, node);
839 exfat_put_node(ef, node);
843 static void rename_entry(struct exfat* ef, struct exfat_node* dir,
844 struct exfat_node* node, const le16_t* name, cluster_t new_cluster,
847 struct exfat_entry_meta1 meta1;
848 struct exfat_entry_meta2 meta2;
849 cluster_t old_cluster = node->entry_cluster;
850 off_t old_offset = node->entry_offset;
851 const size_t name_length = utf16_length(name);
852 const int name_entries = DIV_ROUND_UP(name_length, EXFAT_ENAME_MAX);
855 exfat_pread(ef->dev, &meta1, sizeof(meta1),
856 co2o(ef, old_cluster, old_offset));
857 next_entry(ef, node->parent, &old_cluster, &old_offset);
858 exfat_pread(ef->dev, &meta2, sizeof(meta2),
859 co2o(ef, old_cluster, old_offset));
860 meta1.continuations = 1 + name_entries;
861 meta2.name_hash = exfat_calc_name_hash(ef, name);
862 meta2.name_length = name_length;
863 meta1.checksum = exfat_calc_checksum(&meta1, &meta2, name);
865 erase_entry(ef, node);
867 node->entry_cluster = new_cluster;
868 node->entry_offset = new_offset;
870 exfat_pwrite(ef->dev, &meta1, sizeof(meta1),
871 co2o(ef, new_cluster, new_offset));
872 next_entry(ef, dir, &new_cluster, &new_offset);
873 exfat_pwrite(ef->dev, &meta2, sizeof(meta2),
874 co2o(ef, new_cluster, new_offset));
876 for (i = 0; i < name_entries; i++)
878 struct exfat_entry_name name_entry = {EXFAT_ENTRY_FILE_NAME, 0};
879 memcpy(name_entry.name, name + i * EXFAT_ENAME_MAX,
880 EXFAT_ENAME_MAX * sizeof(le16_t));
881 next_entry(ef, dir, &new_cluster, &new_offset);
882 exfat_pwrite(ef->dev, &name_entry, sizeof(name_entry),
883 co2o(ef, new_cluster, new_offset));
886 memcpy(node->name, name, (EXFAT_NAME_MAX + 1) * sizeof(le16_t));
888 tree_attach(dir, node);
891 int exfat_rename(struct exfat* ef, const char* old_path, const char* new_path)
893 struct exfat_node* node;
894 struct exfat_node* existing;
895 struct exfat_node* dir;
896 cluster_t cluster = EXFAT_CLUSTER_BAD;
898 le16_t name[EXFAT_NAME_MAX + 1];
901 rc = exfat_lookup(ef, &node, old_path);
905 rc = exfat_split(ef, &dir, &existing, name, new_path);
908 exfat_put_node(ef, node);
911 if (existing != NULL)
913 /* remove target if it's not the same node as source */
914 if (existing != node)
916 if (existing->flags & EXFAT_ATTRIB_DIR)
918 if (node->flags & EXFAT_ATTRIB_DIR)
919 rc = exfat_rmdir(ef, existing);
925 if (!(node->flags & EXFAT_ATTRIB_DIR))
926 rc = exfat_unlink(ef, existing);
930 exfat_put_node(ef, existing);
933 exfat_put_node(ef, dir);
934 exfat_put_node(ef, node);
939 exfat_put_node(ef, existing);
942 rc = find_slot(ef, dir, &cluster, &offset,
943 2 + DIV_ROUND_UP(utf16_length(name), EXFAT_ENAME_MAX));
946 exfat_put_node(ef, dir);
947 exfat_put_node(ef, node);
950 rename_entry(ef, dir, node, name, cluster, offset);
951 exfat_put_node(ef, dir);
952 exfat_put_node(ef, node);
956 void exfat_utimes(struct exfat_node* node, const struct timespec tv[2])
958 node->atime = tv[0].tv_sec;
959 node->mtime = tv[1].tv_sec;
960 node->flags |= EXFAT_ATTRIB_DIRTY;
963 void exfat_update_atime(struct exfat_node* node)
965 node->atime = time(NULL);
966 node->flags |= EXFAT_ATTRIB_DIRTY;
969 void exfat_update_mtime(struct exfat_node* node)
971 node->mtime = time(NULL);
972 node->flags |= EXFAT_ATTRIB_DIRTY;
975 const char* exfat_get_label(struct exfat* ef)
980 static int find_label(struct exfat* ef, cluster_t* cluster, off_t* offset)
985 rc = opendir(ef, ef->root, &it);
991 if (it.offset >= ef->root->size)
997 if (get_entry_ptr(ef, &it)->type == EXFAT_ENTRY_LABEL)
999 *cluster = it.cluster;
1000 *offset = it.offset;
1005 if (fetch_next_entry(ef, ef->root, &it) != 0)
1013 int exfat_set_label(struct exfat* ef, const char* label)
1015 le16_t label_utf16[EXFAT_ENAME_MAX + 1];
1019 struct exfat_entry_label entry;
1021 memset(label_utf16, 0, sizeof(label_utf16));
1022 rc = utf8_to_utf16(label_utf16, label, EXFAT_ENAME_MAX, strlen(label));
1026 rc = find_label(ef, &cluster, &offset);
1028 rc = find_slot(ef, ef->root, &cluster, &offset, 1);
1032 entry.type = EXFAT_ENTRY_LABEL;
1033 entry.length = utf16_length(label_utf16);
1034 memcpy(entry.name, label_utf16, sizeof(entry.name));
1035 if (entry.length == 0)
1036 entry.type ^= EXFAT_ENTRY_VALID;
1038 exfat_pwrite(ef->dev, &entry, sizeof(struct exfat_entry_label),
1039 co2o(ef, cluster, offset));