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 exfat_flush_node(ef, node);
57 if (node->flags & EXFAT_ATTRIB_UNLINKED)
59 /* free all clusters and node structure itself */
60 exfat_truncate(ef, node, 0, true);
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 if (exfat_pread(ef->dev, it->chunk, CLUSTER_SIZE(*ef->sb),
90 exfat_c2o(ef, it->cluster)) < 0)
92 exfat_error("failed to read directory cluster %#x", it->cluster);
98 static void closedir(struct iterator* it)
107 static int fetch_next_entry(struct exfat* ef, const struct exfat_node* parent,
110 /* move iterator to the next entry in the directory */
111 it->offset += sizeof(struct exfat_entry);
112 /* fetch the next cluster if needed */
113 if ((it->offset & (CLUSTER_SIZE(*ef->sb) - 1)) == 0)
115 /* reached the end of directory; the caller should check this
117 if (it->offset >= parent->size)
119 it->cluster = exfat_next_cluster(ef, parent, it->cluster);
120 if (CLUSTER_INVALID(it->cluster))
122 exfat_error("invalid cluster 0x%x while reading directory",
126 if (exfat_pread(ef->dev, it->chunk, CLUSTER_SIZE(*ef->sb),
127 exfat_c2o(ef, it->cluster)) < 0)
129 exfat_error("failed to read the next directory cluster %#x",
137 static struct exfat_node* allocate_node(void)
139 struct exfat_node* node = malloc(sizeof(struct exfat_node));
142 exfat_error("failed to allocate node");
145 memset(node, 0, sizeof(struct exfat_node));
149 static void init_node_meta1(struct exfat_node* node,
150 const struct exfat_entry_meta1* meta1)
152 node->flags = le16_to_cpu(meta1->attrib);
153 node->mtime = exfat_exfat2unix(meta1->mdate, meta1->mtime,
155 /* there is no centiseconds field for atime */
156 node->atime = exfat_exfat2unix(meta1->adate, meta1->atime, 0);
159 static void init_node_meta2(struct exfat_node* node,
160 const struct exfat_entry_meta2* meta2)
162 node->size = le64_to_cpu(meta2->size);
163 node->start_cluster = le32_to_cpu(meta2->start_cluster);
164 node->fptr_cluster = node->start_cluster;
165 if (meta2->flags & EXFAT_FLAG_CONTIGUOUS)
166 node->flags |= EXFAT_ATTRIB_CONTIGUOUS;
169 static const struct exfat_entry* get_entry_ptr(const struct exfat* ef,
170 const struct iterator* it)
172 return (const struct exfat_entry*)
173 (it->chunk + it->offset % CLUSTER_SIZE(*ef->sb));
177 * Reads one entry in directory at position pointed by iterator and fills
180 static int readdir(struct exfat* ef, const struct exfat_node* parent,
181 struct exfat_node** node, struct iterator* it)
184 const struct exfat_entry* entry;
185 const struct exfat_entry_meta1* meta1;
186 const struct exfat_entry_meta2* meta2;
187 const struct exfat_entry_name* file_name;
188 const struct exfat_entry_upcase* upcase;
189 const struct exfat_entry_bitmap* bitmap;
190 const struct exfat_entry_label* label;
191 uint8_t continuations = 0;
192 le16_t* namep = NULL;
193 uint16_t reference_checksum = 0;
194 uint16_t actual_checksum = 0;
195 uint64_t real_size = 0;
201 if (it->offset >= parent->size)
203 if (continuations != 0)
205 exfat_error("expected %hhu continuations", continuations);
208 return -ENOENT; /* that's OK, means end of directory */
211 entry = get_entry_ptr(ef, it);
214 case EXFAT_ENTRY_FILE:
215 if (continuations != 0)
217 exfat_error("expected %hhu continuations before new entry",
221 meta1 = (const struct exfat_entry_meta1*) entry;
222 continuations = meta1->continuations;
223 /* each file entry must have at least 2 continuations:
225 if (continuations < 2)
227 exfat_error("too few continuations (%hhu)", continuations);
230 if (continuations > 1 +
231 DIV_ROUND_UP(EXFAT_NAME_MAX, EXFAT_ENAME_MAX))
233 exfat_error("too many continuations (%hhu)", continuations);
236 reference_checksum = le16_to_cpu(meta1->checksum);
237 actual_checksum = exfat_start_checksum(meta1);
238 *node = allocate_node();
244 /* new node has zero reference counter */
245 (*node)->entry_cluster = it->cluster;
246 (*node)->entry_offset = it->offset;
247 init_node_meta1(*node, meta1);
248 namep = (*node)->name;
251 case EXFAT_ENTRY_FILE_INFO:
252 if (continuations < 2)
254 exfat_error("unexpected continuation (%hhu)",
258 meta2 = (const struct exfat_entry_meta2*) entry;
259 if (meta2->flags & ~(EXFAT_FLAG_ALWAYS1 | EXFAT_FLAG_CONTIGUOUS))
261 exfat_error("unknown flags in meta2 (0x%hhx)", meta2->flags);
264 init_node_meta2(*node, meta2);
265 actual_checksum = exfat_add_checksum(entry, actual_checksum);
266 real_size = le64_to_cpu(meta2->real_size);
267 /* empty files must be marked as non-contiguous */
268 if ((*node)->size == 0 && (meta2->flags & EXFAT_FLAG_CONTIGUOUS))
270 exfat_error("empty file marked as contiguous (0x%hhx)",
274 /* directories must be aligned on at cluster boundary */
275 if (((*node)->flags & EXFAT_ATTRIB_DIR) &&
276 (*node)->size % CLUSTER_SIZE(*ef->sb) != 0)
278 exfat_error("directory has invalid size %"PRIu64" bytes",
285 case EXFAT_ENTRY_FILE_NAME:
286 if (continuations == 0)
288 exfat_error("unexpected continuation");
291 file_name = (const struct exfat_entry_name*) entry;
292 actual_checksum = exfat_add_checksum(entry, actual_checksum);
294 memcpy(namep, file_name->name,
296 ((*node)->name + EXFAT_NAME_MAX - namep)) *
298 namep += EXFAT_ENAME_MAX;
299 if (--continuations == 0)
302 There are two fields that contain file size. Maybe they
303 plan to add compression support in the future and one of
304 those fields is visible (uncompressed) size and the other
305 is real (compressed) size. Anyway, currently it looks like
306 exFAT does not support compression and both fields must be
309 There is an exception though: pagefile.sys (its real_size
312 if (real_size != (*node)->size)
314 char buffer[UTF8_BYTES(EXFAT_NAME_MAX) + 1];
316 exfat_get_name(*node, buffer, sizeof(buffer) - 1);
317 exfat_error("`%s' real size does not equal to size "
318 "(%"PRIu64" != %"PRIu64")", buffer,
319 real_size, (*node)->size);
322 if (actual_checksum != reference_checksum)
324 char buffer[UTF8_BYTES(EXFAT_NAME_MAX) + 1];
326 exfat_get_name(*node, buffer, sizeof(buffer) - 1);
327 exfat_error("`%s' has invalid checksum (0x%hx != 0x%hx)",
328 buffer, actual_checksum, reference_checksum);
331 if (fetch_next_entry(ef, parent, it) != 0)
333 return 0; /* entry completed */
337 case EXFAT_ENTRY_UPCASE:
338 if (ef->upcase != NULL)
340 upcase = (const struct exfat_entry_upcase*) entry;
341 if (CLUSTER_INVALID(le32_to_cpu(upcase->start_cluster)))
343 exfat_error("invalid cluster 0x%x in upcase table",
344 le32_to_cpu(upcase->start_cluster));
347 if (le64_to_cpu(upcase->size) == 0 ||
348 le64_to_cpu(upcase->size) > 0xffff * sizeof(uint16_t) ||
349 le64_to_cpu(upcase->size) % sizeof(uint16_t) != 0)
351 exfat_error("bad upcase table size (%"PRIu64" bytes)",
352 le64_to_cpu(upcase->size));
355 ef->upcase = malloc(le64_to_cpu(upcase->size));
356 if (ef->upcase == NULL)
358 exfat_error("failed to allocate upcase table (%"PRIu64" bytes)",
359 le64_to_cpu(upcase->size));
363 ef->upcase_chars = le64_to_cpu(upcase->size) / sizeof(le16_t);
365 if (exfat_pread(ef->dev, ef->upcase, le64_to_cpu(upcase->size),
366 exfat_c2o(ef, le32_to_cpu(upcase->start_cluster))) < 0)
368 exfat_error("failed to read upper case table "
369 "(%"PRIu64" bytes starting at cluster %#x)",
370 le64_to_cpu(upcase->size),
371 le32_to_cpu(upcase->start_cluster));
376 case EXFAT_ENTRY_BITMAP:
377 bitmap = (const struct exfat_entry_bitmap*) entry;
378 ef->cmap.start_cluster = le32_to_cpu(bitmap->start_cluster);
379 if (CLUSTER_INVALID(ef->cmap.start_cluster))
381 exfat_error("invalid cluster 0x%x in clusters bitmap",
382 ef->cmap.start_cluster);
385 ef->cmap.size = le32_to_cpu(ef->sb->cluster_count) -
386 EXFAT_FIRST_DATA_CLUSTER;
387 if (le64_to_cpu(bitmap->size) < DIV_ROUND_UP(ef->cmap.size, 8))
389 exfat_error("invalid clusters bitmap size: %"PRIu64
390 " (expected at least %u)",
391 le64_to_cpu(bitmap->size),
392 DIV_ROUND_UP(ef->cmap.size, 8));
395 /* FIXME bitmap can be rather big, up to 512 MB */
396 ef->cmap.chunk_size = ef->cmap.size;
397 ef->cmap.chunk = malloc(BMAP_SIZE(ef->cmap.chunk_size));
398 if (ef->cmap.chunk == NULL)
400 exfat_error("failed to allocate clusters bitmap chunk "
401 "(%"PRIu64" bytes)", le64_to_cpu(bitmap->size));
406 if (exfat_pread(ef->dev, ef->cmap.chunk,
407 BMAP_SIZE(ef->cmap.chunk_size),
408 exfat_c2o(ef, ef->cmap.start_cluster)) < 0)
410 exfat_error("failed to read clusters bitmap "
411 "(%"PRIu64" bytes starting at cluster %#x)",
412 le64_to_cpu(bitmap->size), ef->cmap.start_cluster);
417 case EXFAT_ENTRY_LABEL:
418 label = (const struct exfat_entry_label*) entry;
419 if (label->length > EXFAT_ENAME_MAX)
421 exfat_error("too long label (%hhu chars)", label->length);
424 if (utf16_to_utf8(ef->label, label->name,
425 sizeof(ef->label) - 1, EXFAT_ENAME_MAX) != 0)
430 if (entry->type & EXFAT_ENTRY_VALID)
432 exfat_error("unknown entry type 0x%hhx", entry->type);
438 if (fetch_next_entry(ef, parent, it) != 0)
441 /* we never reach here */
449 int exfat_cache_directory(struct exfat* ef, struct exfat_node* dir)
453 struct exfat_node* node;
454 struct exfat_node* current = NULL;
456 if (dir->flags & EXFAT_ATTRIB_CACHED)
457 return 0; /* already cached */
459 rc = opendir(ef, dir, &it);
462 while ((rc = readdir(ef, dir, &node, &it)) == 0)
467 current->next = node;
468 node->prev = current;
480 for (current = dir->child; current; current = node)
482 node = current->next;
489 dir->flags |= EXFAT_ATTRIB_CACHED;
493 static void tree_attach(struct exfat_node* dir, struct exfat_node* node)
498 dir->child->prev = node;
499 node->next = dir->child;
504 static void tree_detach(struct exfat_node* node)
507 node->prev->next = node->next;
508 else /* this is the first node in the list */
509 node->parent->child = node->next;
511 node->next->prev = node->prev;
517 static void reset_cache(struct exfat* ef, struct exfat_node* node)
521 struct exfat_node* p = node->child;
526 node->flags &= ~EXFAT_ATTRIB_CACHED;
527 if (node->references != 0)
529 char buffer[UTF8_BYTES(EXFAT_NAME_MAX) + 1];
530 exfat_get_name(node, buffer, sizeof(buffer) - 1);
531 exfat_warn("non-zero reference counter (%d) for `%s'",
532 node->references, buffer);
534 while (node->references)
535 exfat_put_node(ef, node);
538 void exfat_reset_cache(struct exfat* ef)
540 reset_cache(ef, ef->root);
543 static void next_entry(struct exfat* ef, const struct exfat_node* parent,
544 cluster_t* cluster, off_t* offset)
546 *offset += sizeof(struct exfat_entry);
547 if (*offset % CLUSTER_SIZE(*ef->sb) == 0)
548 /* next cluster cannot be invalid */
549 *cluster = exfat_next_cluster(ef, parent, *cluster);
552 void exfat_flush_node(struct exfat* ef, struct exfat_node* node)
556 off_t meta1_offset, meta2_offset;
557 struct exfat_entry_meta1 meta1;
558 struct exfat_entry_meta2 meta2;
560 if (!(node->flags & EXFAT_ATTRIB_DIRTY))
561 return; /* no need to flush */
564 exfat_bug("unable to flush node to read-only FS");
566 if (node->parent == NULL)
567 return; /* do not flush unlinked node */
569 cluster = node->entry_cluster;
570 offset = node->entry_offset;
571 meta1_offset = co2o(ef, cluster, offset);
572 next_entry(ef, node->parent, &cluster, &offset);
573 meta2_offset = co2o(ef, cluster, offset);
575 /* FIXME handle I/O error */
576 if (exfat_pread(ef->dev, &meta1, sizeof(meta1), meta1_offset) < 0)
577 exfat_bug("failed to read meta1 entry on flush");
578 if (meta1.type != EXFAT_ENTRY_FILE)
579 exfat_bug("invalid type of meta1: 0x%hhx", meta1.type);
580 meta1.attrib = cpu_to_le16(node->flags);
581 exfat_unix2exfat(node->mtime, &meta1.mdate, &meta1.mtime, &meta1.mtime_cs);
582 exfat_unix2exfat(node->atime, &meta1.adate, &meta1.atime, NULL);
584 /* FIXME handle I/O error */
585 if (exfat_pread(ef->dev, &meta2, sizeof(meta2), meta2_offset) < 0)
586 exfat_bug("failed to read meta2 entry on flush");
587 if (meta2.type != EXFAT_ENTRY_FILE_INFO)
588 exfat_bug("invalid type of meta2: 0x%hhx", meta2.type);
589 meta2.size = meta2.real_size = cpu_to_le64(node->size);
590 meta2.start_cluster = cpu_to_le32(node->start_cluster);
591 meta2.flags = EXFAT_FLAG_ALWAYS1;
592 /* empty files must not be marked as contiguous */
593 if (node->size != 0 && IS_CONTIGUOUS(*node))
594 meta2.flags |= EXFAT_FLAG_CONTIGUOUS;
595 /* name hash remains unchanged, no need to recalculate it */
597 meta1.checksum = exfat_calc_checksum(&meta1, &meta2, node->name);
599 /* FIXME handle I/O error */
600 if (exfat_pwrite(ef->dev, &meta1, sizeof(meta1), meta1_offset) < 0)
601 exfat_bug("failed to write meta1 entry on flush");
602 /* FIXME handle I/O error */
603 if (exfat_pwrite(ef->dev, &meta2, sizeof(meta2), meta2_offset) < 0)
604 exfat_bug("failed to write meta2 entry on flush");
606 node->flags &= ~EXFAT_ATTRIB_DIRTY;
609 static void erase_entry(struct exfat* ef, struct exfat_node* node)
611 cluster_t cluster = node->entry_cluster;
612 off_t offset = node->entry_offset;
613 int name_entries = DIV_ROUND_UP(utf16_length(node->name), EXFAT_ENAME_MAX);
616 entry_type = EXFAT_ENTRY_FILE & ~EXFAT_ENTRY_VALID;
617 /* FIXME handle I/O error */
618 if (exfat_pwrite(ef->dev, &entry_type, 1, co2o(ef, cluster, offset)) < 0)
619 exfat_bug("failed to erase meta1 entry");
621 next_entry(ef, node->parent, &cluster, &offset);
622 entry_type = EXFAT_ENTRY_FILE_INFO & ~EXFAT_ENTRY_VALID;
623 /* FIXME handle I/O error */
624 if (exfat_pwrite(ef->dev, &entry_type, 1, co2o(ef, cluster, offset)) < 0)
625 exfat_bug("failed to erase meta2 entry");
627 while (name_entries--)
629 next_entry(ef, node->parent, &cluster, &offset);
630 entry_type = EXFAT_ENTRY_FILE_NAME & ~EXFAT_ENTRY_VALID;
631 /* FIXME handle I/O error */
632 if (exfat_pwrite(ef->dev, &entry_type, 1,
633 co2o(ef, cluster, offset)) < 0)
634 exfat_bug("failed to erase name entry");
638 static int shrink_directory(struct exfat* ef, struct exfat_node* dir,
639 off_t deleted_offset)
641 const struct exfat_node* node;
642 const struct exfat_node* last_node;
643 uint64_t entries = 0;
647 if (!(dir->flags & EXFAT_ATTRIB_DIR))
648 exfat_bug("attempted to shrink a file");
649 if (!(dir->flags & EXFAT_ATTRIB_CACHED))
650 exfat_bug("attempted to shrink uncached directory");
652 for (last_node = node = dir->child; node; node = node->next)
654 if (deleted_offset < node->entry_offset)
656 /* there are other entries after the removed one, no way to shrink
660 if (last_node->entry_offset < node->entry_offset)
666 /* offset of the last entry */
667 entries += last_node->entry_offset / sizeof(struct exfat_entry);
668 /* two subentries with meta info */
670 /* subentries with file name */
671 entries += DIV_ROUND_UP(utf16_length(last_node->name),
675 new_size = DIV_ROUND_UP(entries * sizeof(struct exfat_entry),
676 CLUSTER_SIZE(*ef->sb)) * CLUSTER_SIZE(*ef->sb);
677 if (new_size == 0) /* directory always has at least 1 cluster */
678 new_size = CLUSTER_SIZE(*ef->sb);
679 if (new_size == dir->size)
681 rc = exfat_truncate(ef, dir, new_size, true);
687 static int delete(struct exfat* ef, struct exfat_node* node)
689 struct exfat_node* parent = node->parent;
690 off_t deleted_offset = node->entry_offset;
693 exfat_get_node(parent);
694 erase_entry(ef, node);
695 exfat_update_mtime(parent);
697 rc = shrink_directory(ef, parent, deleted_offset);
698 exfat_put_node(ef, parent);
699 /* file clusters will be freed when node reference counter becomes 0 */
700 node->flags |= EXFAT_ATTRIB_UNLINKED;
704 int exfat_unlink(struct exfat* ef, struct exfat_node* node)
706 if (node->flags & EXFAT_ATTRIB_DIR)
708 return delete(ef, node);
711 int exfat_rmdir(struct exfat* ef, struct exfat_node* node)
713 if (!(node->flags & EXFAT_ATTRIB_DIR))
715 /* check that directory is empty */
716 exfat_cache_directory(ef, node);
719 return delete(ef, node);
722 static int grow_directory(struct exfat* ef, struct exfat_node* dir,
723 uint64_t asize, uint32_t difference)
725 return exfat_truncate(ef, dir,
726 DIV_ROUND_UP(asize + difference, CLUSTER_SIZE(*ef->sb))
727 * CLUSTER_SIZE(*ef->sb), true);
730 static int find_slot(struct exfat* ef, struct exfat_node* dir,
731 cluster_t* cluster, off_t* offset, int subentries)
735 const struct exfat_entry* entry;
738 rc = opendir(ef, dir, &it);
745 *cluster = it.cluster;
748 entry = get_entry_ptr(ef, &it);
749 if (entry->type & EXFAT_ENTRY_VALID)
753 if (contiguous == subentries)
754 break; /* suitable slot is found */
755 if (it.offset + sizeof(struct exfat_entry) >= dir->size)
757 rc = grow_directory(ef, dir, dir->size,
758 (subentries - contiguous) * sizeof(struct exfat_entry));
765 if (fetch_next_entry(ef, dir, &it) != 0)
775 static int write_entry(struct exfat* ef, struct exfat_node* dir,
776 const le16_t* name, cluster_t cluster, off_t offset, uint16_t attrib)
778 struct exfat_node* node;
779 struct exfat_entry_meta1 meta1;
780 struct exfat_entry_meta2 meta2;
781 const size_t name_length = utf16_length(name);
782 const int name_entries = DIV_ROUND_UP(name_length, EXFAT_ENAME_MAX);
785 node = allocate_node();
788 node->entry_cluster = cluster;
789 node->entry_offset = offset;
790 memcpy(node->name, name, name_length * sizeof(le16_t));
792 memset(&meta1, 0, sizeof(meta1));
793 meta1.type = EXFAT_ENTRY_FILE;
794 meta1.continuations = 1 + name_entries;
795 meta1.attrib = cpu_to_le16(attrib);
796 exfat_unix2exfat(time(NULL), &meta1.crdate, &meta1.crtime,
798 meta1.adate = meta1.mdate = meta1.crdate;
799 meta1.atime = meta1.mtime = meta1.crtime;
800 meta1.mtime_cs = meta1.crtime_cs; /* there is no atime_cs */
802 memset(&meta2, 0, sizeof(meta2));
803 meta2.type = EXFAT_ENTRY_FILE_INFO;
804 meta2.flags = EXFAT_FLAG_ALWAYS1;
805 meta2.name_length = name_length;
806 meta2.name_hash = exfat_calc_name_hash(ef, node->name);
807 meta2.start_cluster = cpu_to_le32(EXFAT_CLUSTER_FREE);
809 meta1.checksum = exfat_calc_checksum(&meta1, &meta2, node->name);
811 if (exfat_pwrite(ef->dev, &meta1, sizeof(meta1),
812 co2o(ef, cluster, offset)) < 0)
814 exfat_error("failed to write meta1 entry");
817 next_entry(ef, dir, &cluster, &offset);
818 if (exfat_pwrite(ef->dev, &meta2, sizeof(meta2),
819 co2o(ef, cluster, offset)) < 0)
821 exfat_error("failed to write meta2 entry");
824 for (i = 0; i < name_entries; i++)
826 struct exfat_entry_name name_entry = {EXFAT_ENTRY_FILE_NAME, 0};
827 memcpy(name_entry.name, node->name + i * EXFAT_ENAME_MAX,
828 MIN(EXFAT_ENAME_MAX, EXFAT_NAME_MAX - i * EXFAT_ENAME_MAX) *
830 next_entry(ef, dir, &cluster, &offset);
831 if (exfat_pwrite(ef->dev, &name_entry, sizeof(name_entry),
832 co2o(ef, cluster, offset)) < 0)
834 exfat_error("failed to write name entry");
839 init_node_meta1(node, &meta1);
840 init_node_meta2(node, &meta2);
842 tree_attach(dir, node);
843 exfat_update_mtime(dir);
847 static int create(struct exfat* ef, const char* path, uint16_t attrib)
849 struct exfat_node* dir;
850 struct exfat_node* existing;
851 cluster_t cluster = EXFAT_CLUSTER_BAD;
853 le16_t name[EXFAT_NAME_MAX + 1];
856 rc = exfat_split(ef, &dir, &existing, name, path);
859 if (existing != NULL)
861 exfat_put_node(ef, existing);
862 exfat_put_node(ef, dir);
866 rc = find_slot(ef, dir, &cluster, &offset,
867 2 + DIV_ROUND_UP(utf16_length(name), EXFAT_ENAME_MAX));
870 exfat_put_node(ef, dir);
873 rc = write_entry(ef, dir, name, cluster, offset, attrib);
874 exfat_put_node(ef, dir);
878 int exfat_mknod(struct exfat* ef, const char* path)
880 return create(ef, path, EXFAT_ATTRIB_ARCH);
883 int exfat_mkdir(struct exfat* ef, const char* path)
886 struct exfat_node* node;
888 rc = create(ef, path, EXFAT_ATTRIB_ARCH | EXFAT_ATTRIB_DIR);
891 rc = exfat_lookup(ef, &node, path);
894 /* directories always have at least one cluster */
895 rc = exfat_truncate(ef, node, CLUSTER_SIZE(*ef->sb), true);
899 exfat_put_node(ef, node);
902 exfat_put_node(ef, node);
906 static int rename_entry(struct exfat* ef, struct exfat_node* dir,
907 struct exfat_node* node, const le16_t* name, cluster_t new_cluster,
910 struct exfat_entry_meta1 meta1;
911 struct exfat_entry_meta2 meta2;
912 cluster_t old_cluster = node->entry_cluster;
913 off_t old_offset = node->entry_offset;
914 const size_t name_length = utf16_length(name);
915 const int name_entries = DIV_ROUND_UP(name_length, EXFAT_ENAME_MAX);
918 if (exfat_pread(ef->dev, &meta1, sizeof(meta1),
919 co2o(ef, old_cluster, old_offset)) < 0)
921 exfat_error("failed to read meta1 entry on rename");
924 next_entry(ef, node->parent, &old_cluster, &old_offset);
925 if (exfat_pread(ef->dev, &meta2, sizeof(meta2),
926 co2o(ef, old_cluster, old_offset)) < 0)
928 exfat_error("failed to read meta2 entry on rename");
931 meta1.continuations = 1 + name_entries;
932 meta2.name_hash = exfat_calc_name_hash(ef, name);
933 meta2.name_length = name_length;
934 meta1.checksum = exfat_calc_checksum(&meta1, &meta2, name);
936 erase_entry(ef, node);
938 node->entry_cluster = new_cluster;
939 node->entry_offset = new_offset;
941 if (exfat_pwrite(ef->dev, &meta1, sizeof(meta1),
942 co2o(ef, new_cluster, new_offset)) < 0)
944 exfat_error("failed to write meta1 entry on rename");
947 next_entry(ef, dir, &new_cluster, &new_offset);
948 if (exfat_pwrite(ef->dev, &meta2, sizeof(meta2),
949 co2o(ef, new_cluster, new_offset)) < 0)
951 exfat_error("failed to write meta2 entry on rename");
955 for (i = 0; i < name_entries; i++)
957 struct exfat_entry_name name_entry = {EXFAT_ENTRY_FILE_NAME, 0};
958 memcpy(name_entry.name, name + i * EXFAT_ENAME_MAX,
959 EXFAT_ENAME_MAX * sizeof(le16_t));
960 next_entry(ef, dir, &new_cluster, &new_offset);
961 if (exfat_pwrite(ef->dev, &name_entry, sizeof(name_entry),
962 co2o(ef, new_cluster, new_offset)) < 0)
964 exfat_error("failed to write name entry on rename");
969 memcpy(node->name, name, (EXFAT_NAME_MAX + 1) * sizeof(le16_t));
971 tree_attach(dir, node);
975 int exfat_rename(struct exfat* ef, const char* old_path, const char* new_path)
977 struct exfat_node* node;
978 struct exfat_node* existing;
979 struct exfat_node* dir;
980 cluster_t cluster = EXFAT_CLUSTER_BAD;
982 le16_t name[EXFAT_NAME_MAX + 1];
985 rc = exfat_lookup(ef, &node, old_path);
989 rc = exfat_split(ef, &dir, &existing, name, new_path);
992 exfat_put_node(ef, node);
996 /* check that target is not a subdirectory of the source */
997 if (node->flags & EXFAT_ATTRIB_DIR)
999 struct exfat_node* p;
1001 for (p = dir; p; p = p->parent)
1004 if (existing != NULL)
1005 exfat_put_node(ef, existing);
1006 exfat_put_node(ef, dir);
1007 exfat_put_node(ef, node);
1012 if (existing != NULL)
1014 /* remove target if it's not the same node as source */
1015 if (existing != node)
1017 if (existing->flags & EXFAT_ATTRIB_DIR)
1019 if (node->flags & EXFAT_ATTRIB_DIR)
1020 rc = exfat_rmdir(ef, existing);
1026 if (!(node->flags & EXFAT_ATTRIB_DIR))
1027 rc = exfat_unlink(ef, existing);
1031 exfat_put_node(ef, existing);
1034 exfat_put_node(ef, dir);
1035 exfat_put_node(ef, node);
1040 exfat_put_node(ef, existing);
1043 rc = find_slot(ef, dir, &cluster, &offset,
1044 2 + DIV_ROUND_UP(utf16_length(name), EXFAT_ENAME_MAX));
1047 exfat_put_node(ef, dir);
1048 exfat_put_node(ef, node);
1051 rc = rename_entry(ef, dir, node, name, cluster, offset);
1052 exfat_put_node(ef, dir);
1053 exfat_put_node(ef, node);
1057 void exfat_utimes(struct exfat_node* node, const struct timespec tv[2])
1059 node->atime = tv[0].tv_sec;
1060 node->mtime = tv[1].tv_sec;
1061 node->flags |= EXFAT_ATTRIB_DIRTY;
1064 void exfat_update_atime(struct exfat_node* node)
1066 node->atime = time(NULL);
1067 node->flags |= EXFAT_ATTRIB_DIRTY;
1070 void exfat_update_mtime(struct exfat_node* node)
1072 node->mtime = time(NULL);
1073 node->flags |= EXFAT_ATTRIB_DIRTY;
1076 const char* exfat_get_label(struct exfat* ef)
1081 static int find_label(struct exfat* ef, cluster_t* cluster, off_t* offset)
1086 rc = opendir(ef, ef->root, &it);
1092 if (it.offset >= ef->root->size)
1098 if (get_entry_ptr(ef, &it)->type == EXFAT_ENTRY_LABEL)
1100 *cluster = it.cluster;
1101 *offset = it.offset;
1106 if (fetch_next_entry(ef, ef->root, &it) != 0)
1114 int exfat_set_label(struct exfat* ef, const char* label)
1116 le16_t label_utf16[EXFAT_ENAME_MAX + 1];
1120 struct exfat_entry_label entry;
1122 memset(label_utf16, 0, sizeof(label_utf16));
1123 rc = utf8_to_utf16(label_utf16, label, EXFAT_ENAME_MAX, strlen(label));
1127 rc = find_label(ef, &cluster, &offset);
1129 rc = find_slot(ef, ef->root, &cluster, &offset, 1);
1133 entry.type = EXFAT_ENTRY_LABEL;
1134 entry.length = utf16_length(label_utf16);
1135 memcpy(entry.name, label_utf16, sizeof(entry.name));
1136 if (entry.length == 0)
1137 entry.type ^= EXFAT_ENTRY_VALID;
1139 if (exfat_pwrite(ef->dev, &entry, sizeof(struct exfat_entry_label),
1140 co2o(ef, cluster, offset)) < 0)
1142 exfat_error("failed to write label entry");
1145 strcpy(ef->label, label);