3 exFAT file system implementation library.
5 Copyright (C) 2009, 2010 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_read_raw(it->chunk, CLUSTER_SIZE(*ef->sb),
90 exfat_c2o(ef, it->cluster), ef->fd);
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 it->cluster = exfat_next_cluster(ef, parent, it->cluster);
112 if (CLUSTER_INVALID(it->cluster))
114 exfat_error("invalid cluster while reading directory");
117 exfat_read_raw(it->chunk, CLUSTER_SIZE(*ef->sb),
118 exfat_c2o(ef, it->cluster), ef->fd);
123 static struct exfat_node* allocate_node(void)
125 struct exfat_node* node = malloc(sizeof(struct exfat_node));
128 exfat_error("failed to allocate node");
131 memset(node, 0, sizeof(struct exfat_node));
135 static void init_node_meta1(struct exfat_node* node,
136 const struct exfat_entry_meta1* meta1)
138 node->flags = le16_to_cpu(meta1->attrib);
139 node->mtime = exfat_exfat2unix(meta1->mdate, meta1->mtime,
141 /* there is no centiseconds field for atime */
142 node->atime = exfat_exfat2unix(meta1->adate, meta1->atime, 0);
145 static void init_node_meta2(struct exfat_node* node,
146 const struct exfat_entry_meta2* meta2)
148 node->size = le64_to_cpu(meta2->size);
149 node->start_cluster = le32_to_cpu(meta2->start_cluster);
150 node->fptr_cluster = node->start_cluster;
151 if (meta2->flag == EXFAT_FLAG_CONTIGUOUS)
152 node->flags |= EXFAT_ATTRIB_CONTIGUOUS;
155 static const struct exfat_entry* get_entry_ptr(const struct exfat* ef,
156 const struct iterator* it)
158 return (const struct exfat_entry*)
159 (it->chunk + it->offset % CLUSTER_SIZE(*ef->sb));
163 * Reads one entry in directory at position pointed by iterator and fills
166 static int readdir(struct exfat* ef, const struct exfat_node* parent,
167 struct exfat_node** node, struct iterator* it)
169 const struct exfat_entry* entry;
170 const struct exfat_entry_meta1* meta1;
171 const struct exfat_entry_meta2* meta2;
172 const struct exfat_entry_name* file_name;
173 const struct exfat_entry_upcase* upcase;
174 const struct exfat_entry_bitmap* bitmap;
175 const struct exfat_entry_label* label;
176 uint8_t continuations = 0;
177 le16_t* namep = NULL;
178 uint16_t reference_checksum = 0;
179 uint16_t actual_checksum = 0;
185 /* every directory (even empty one) occupies at least one cluster and
186 must contain EOD entry */
187 entry = get_entry_ptr(ef, it);
191 case EXFAT_ENTRY_EOD:
192 if (continuations != 0)
194 exfat_error("expected %hhu continuations before EOD",
198 return -ENOENT; /* that's OK, means end of directory */
200 case EXFAT_ENTRY_FILE:
201 if (continuations != 0)
203 exfat_error("expected %hhu continuations before new entry",
207 meta1 = (const struct exfat_entry_meta1*) entry;
208 continuations = meta1->continuations;
209 /* each file entry must have at least 2 continuations:
211 if (continuations < 2)
213 exfat_error("too few continuations (%hhu)", continuations);
216 reference_checksum = le16_to_cpu(meta1->checksum);
217 actual_checksum = exfat_start_checksum(meta1);
218 *node = allocate_node();
221 /* new node has zero reference counter */
222 (*node)->entry_cluster = it->cluster;
223 (*node)->entry_offset = it->offset;
224 init_node_meta1(*node, meta1);
225 namep = (*node)->name;
228 case EXFAT_ENTRY_FILE_INFO:
229 if (continuations < 2)
231 exfat_error("unexpected continuation (%hhu)",
235 meta2 = (const struct exfat_entry_meta2*) entry;
236 init_node_meta2(*node, meta2);
237 actual_checksum = exfat_add_checksum(entry, actual_checksum);
238 /* There are two fields that contain file size. Maybe they plan
239 to add compression support in the future and one of those
240 fields is visible (uncompressed) size and the other is real
241 (compressed) size. Anyway, currently it looks like exFAT does
242 not support compression and both fields must be equal. */
243 if (le64_to_cpu(meta2->real_size) != (*node)->size)
245 exfat_error("real size does not equal to size "
246 "(%"PRIu64" != %"PRIu64")",
247 le64_to_cpu(meta2->real_size), (*node)->size);
250 /* directories must be aligned on at cluster boundary */
251 if (((*node)->flags & EXFAT_ATTRIB_DIR) &&
252 (*node)->size % CLUSTER_SIZE(*ef->sb) != 0)
254 char buffer[EXFAT_NAME_MAX + 1];
256 exfat_get_name(*node, buffer, EXFAT_NAME_MAX);
257 exfat_error("directory `%s' has invalid size %"PRIu64" bytes",
258 buffer, (*node)->size);
264 case EXFAT_ENTRY_FILE_NAME:
265 if (continuations == 0)
267 exfat_error("unexpected continuation");
270 file_name = (const struct exfat_entry_name*) entry;
271 actual_checksum = exfat_add_checksum(entry, actual_checksum);
273 memcpy(namep, file_name->name, EXFAT_ENAME_MAX * sizeof(le16_t));
274 namep += EXFAT_ENAME_MAX;
275 if (--continuations == 0)
277 if (actual_checksum != reference_checksum)
279 exfat_error("invalid checksum (0x%hx != 0x%hx)",
280 actual_checksum, reference_checksum);
283 if (fetch_next_entry(ef, parent, it) != 0)
285 return 0; /* entry completed */
289 case EXFAT_ENTRY_UPCASE:
290 if (ef->upcase != NULL)
292 upcase = (const struct exfat_entry_upcase*) entry;
293 if (CLUSTER_INVALID(le32_to_cpu(upcase->start_cluster)))
295 exfat_error("invalid cluster in upcase table");
298 if (le64_to_cpu(upcase->size) == 0 ||
299 le64_to_cpu(upcase->size) > 0xffff * sizeof(uint16_t) ||
300 le64_to_cpu(upcase->size) % sizeof(uint16_t) != 0)
302 exfat_error("bad upcase table size (%"PRIu64" bytes)",
303 le64_to_cpu(upcase->size));
306 ef->upcase = malloc(le64_to_cpu(upcase->size));
307 if (ef->upcase == NULL)
309 exfat_error("failed to allocate upcase table (%"PRIu64" bytes)",
310 le64_to_cpu(upcase->size));
313 ef->upcase_chars = le64_to_cpu(upcase->size) / sizeof(le16_t);
315 exfat_read_raw(ef->upcase, le64_to_cpu(upcase->size),
316 exfat_c2o(ef, le32_to_cpu(upcase->start_cluster)), ef->fd);
319 case EXFAT_ENTRY_BITMAP:
320 bitmap = (const struct exfat_entry_bitmap*) entry;
321 if (CLUSTER_INVALID(le32_to_cpu(bitmap->start_cluster)))
323 exfat_error("invalid cluster in clusters bitmap");
326 ef->cmap.size = le32_to_cpu(ef->sb->cluster_count) -
327 EXFAT_FIRST_DATA_CLUSTER;
328 if (le64_to_cpu(bitmap->size) < (ef->cmap.size + 7) / 8)
330 exfat_error("invalid clusters bitmap size: %"PRIu64
331 " (expected at least %u)",
332 le64_to_cpu(bitmap->size), (ef->cmap.size + 7) / 8);
335 ef->cmap.start_cluster = le32_to_cpu(bitmap->start_cluster);
336 /* FIXME bitmap can be rather big, up to 512 MB */
337 ef->cmap.chunk_size = ef->cmap.size;
338 ef->cmap.chunk = malloc(le64_to_cpu(bitmap->size));
339 if (ef->cmap.chunk == NULL)
341 exfat_error("failed to allocate clusters bitmap chunk "
342 "(%"PRIu64" bytes)", le64_to_cpu(bitmap->size));
346 exfat_read_raw(ef->cmap.chunk, le64_to_cpu(bitmap->size),
347 exfat_c2o(ef, ef->cmap.start_cluster), ef->fd);
350 case EXFAT_ENTRY_LABEL:
351 label = (const struct exfat_entry_label*) entry;
352 if (label->length > EXFAT_ENAME_MAX)
354 exfat_error("too long label (%hhu chars)", label->length);
357 if (utf16_to_utf8(ef->label, label->name,
358 sizeof(ef->label), EXFAT_ENAME_MAX) != 0)
363 if (entry->type & EXFAT_ENTRY_VALID)
365 exfat_error("unknown entry type 0x%hhu", entry->type);
371 if (fetch_next_entry(ef, parent, it) != 0)
374 /* we never reach here */
382 int exfat_cache_directory(struct exfat* ef, struct exfat_node* dir)
386 struct exfat_node* node;
387 struct exfat_node* current = NULL;
389 if (dir->flags & EXFAT_ATTRIB_CACHED)
390 return 0; /* already cached */
392 rc = opendir(ef, dir, &it);
395 while ((rc = readdir(ef, dir, &node, &it)) == 0)
400 current->next = node;
401 node->prev = current;
413 for (current = dir->child; current; current = node)
415 node = current->next;
422 dir->flags |= EXFAT_ATTRIB_CACHED;
426 static void reset_cache(struct exfat* ef, struct exfat_node* node)
428 struct exfat_node* child;
429 struct exfat_node* next;
431 for (child = node->child; child; child = next)
433 reset_cache(ef, child);
437 if (node->references != 0)
439 char buffer[EXFAT_NAME_MAX + 1];
440 exfat_get_name(node, buffer, EXFAT_NAME_MAX);
441 exfat_warn("non-zero reference counter (%d) for `%s'",
442 node->references, buffer);
444 while (node->references--)
445 exfat_put_node(ef, node);
447 node->flags &= ~EXFAT_ATTRIB_CACHED;
450 void exfat_reset_cache(struct exfat* ef)
452 reset_cache(ef, ef->root);
455 void next_entry(struct exfat* ef, const struct exfat_node* parent,
456 cluster_t* cluster, off_t* offset)
458 *offset += sizeof(struct exfat_entry);
459 if (*offset % CLUSTER_SIZE(*ef->sb) == 0)
460 /* next cluster cannot be invalid */
461 *cluster = exfat_next_cluster(ef, parent, *cluster);
464 void exfat_flush_node(struct exfat* ef, struct exfat_node* node)
468 off_t meta1_offset, meta2_offset;
469 struct exfat_entry_meta1 meta1;
470 struct exfat_entry_meta2 meta2;
473 exfat_bug("unable to flush node to read-only FS");
475 if (node->parent == NULL)
476 return; /* do not flush unlinked node */
478 cluster = node->entry_cluster;
479 offset = node->entry_offset;
480 meta1_offset = co2o(ef, cluster, offset);
481 next_entry(ef, node->parent, &cluster, &offset);
482 meta2_offset = co2o(ef, cluster, offset);
484 exfat_read_raw(&meta1, sizeof(meta1), meta1_offset, ef->fd);
485 if (meta1.type != EXFAT_ENTRY_FILE)
486 exfat_bug("invalid type of meta1: 0x%hhx", meta1.type);
487 meta1.attrib = cpu_to_le16(node->flags);
488 exfat_unix2exfat(node->mtime, &meta1.mdate, &meta1.mtime, &meta1.mtime_cs);
489 exfat_unix2exfat(node->atime, &meta1.adate, &meta1.atime, NULL);
491 exfat_read_raw(&meta2, sizeof(meta2), meta2_offset, ef->fd);
492 if (meta2.type != EXFAT_ENTRY_FILE_INFO)
493 exfat_bug("invalid type of meta2: 0x%hhx", meta2.type);
494 meta2.size = meta2.real_size = cpu_to_le64(node->size);
495 meta2.start_cluster = cpu_to_le32(node->start_cluster);
496 /* empty files must be marked as fragmented */
497 if (node->size != 0 && IS_CONTIGUOUS(*node))
498 meta2.flag = EXFAT_FLAG_CONTIGUOUS;
500 meta2.flag = EXFAT_FLAG_FRAGMENTED;
501 /* name hash remains unchanged, no need to recalculate it */
503 meta1.checksum = exfat_calc_checksum(&meta1, &meta2, node->name);
505 exfat_write_raw(&meta1, sizeof(meta1), meta1_offset, ef->fd);
506 exfat_write_raw(&meta2, sizeof(meta2), meta2_offset, ef->fd);
508 node->flags &= ~EXFAT_ATTRIB_DIRTY;
511 static void erase_entry(struct exfat* ef, struct exfat_node* node)
513 cluster_t cluster = node->entry_cluster;
514 off_t offset = node->entry_offset;
515 int name_entries = DIV_ROUND_UP(utf16_length(node->name), EXFAT_ENAME_MAX);
518 entry_type = EXFAT_ENTRY_FILE & ~EXFAT_ENTRY_VALID;
519 exfat_write_raw(&entry_type, 1, co2o(ef, cluster, offset), ef->fd);
521 next_entry(ef, node->parent, &cluster, &offset);
522 entry_type = EXFAT_ENTRY_FILE_INFO & ~EXFAT_ENTRY_VALID;
523 exfat_write_raw(&entry_type, 1, co2o(ef, cluster, offset), ef->fd);
525 while (name_entries--)
527 next_entry(ef, node->parent, &cluster, &offset);
528 entry_type = EXFAT_ENTRY_FILE_NAME & ~EXFAT_ENTRY_VALID;
529 exfat_write_raw(&entry_type, 1, co2o(ef, cluster, offset), ef->fd);
533 static void tree_detach(struct exfat_node* node)
536 node->prev->next = node->next;
537 else /* this is the first node in the list */
538 node->parent->child = node->next;
540 node->next->prev = node->prev;
546 static void tree_attach(struct exfat_node* dir, struct exfat_node* node)
551 dir->child->prev = node;
552 node->next = dir->child;
557 static int shrink_directory(struct exfat* ef, struct exfat_node* dir,
558 off_t deleted_offset)
560 const struct exfat_node* node;
561 const struct exfat_node* last_node;
562 uint64_t entries = 1; /* a directory always has at leat 1 entry (EOD) */
564 struct exfat_entry eod;
568 if (!(dir->flags & EXFAT_ATTRIB_DIR))
569 exfat_bug("attempted to shrink a file");
570 if (!(dir->flags & EXFAT_ATTRIB_CACHED))
571 exfat_bug("attempted to shrink uncached directory");
573 for (last_node = node = dir->child; node; node = node->next)
575 if (deleted_offset < node->entry_offset)
577 /* there are other entries after the removed one, no way to shrink
581 if (last_node->entry_offset < node->entry_offset)
587 /* offset of the last entry */
588 entries += last_node->entry_offset / sizeof(struct exfat_entry);
589 /* two subentries with meta info */
591 /* subentries with file name */
592 entries += DIV_ROUND_UP(utf16_length(last_node->name),
596 new_size = DIV_ROUND_UP(entries * sizeof(struct exfat_entry),
597 CLUSTER_SIZE(*ef->sb)) * CLUSTER_SIZE(*ef->sb);
598 if (new_size == dir->size)
600 rc = exfat_truncate(ef, dir, new_size);
604 /* put EOD entry at the end of the last cluster */
605 memset(&eod, 0, sizeof(eod));
606 eod_offset = new_size - sizeof(struct exfat_entry);
608 exfat_write_raw(&eod, sizeof(eod),
609 co2o(ef, last_node->entry_cluster, eod_offset), ef->fd);
611 exfat_write_raw(&eod, sizeof(eod),
612 co2o(ef, dir->start_cluster, eod_offset), ef->fd);
616 static int delete(struct exfat* ef, struct exfat_node* node)
618 struct exfat_node* parent = node->parent;
619 off_t deleted_offset = node->entry_offset;
622 exfat_get_node(parent);
623 erase_entry(ef, node);
624 exfat_update_mtime(parent);
626 rc = shrink_directory(ef, parent, deleted_offset);
627 exfat_put_node(ef, parent);
628 /* file clusters will be freed when node reference counter becomes 0 */
629 node->flags |= EXFAT_ATTRIB_UNLINKED;
633 int exfat_unlink(struct exfat* ef, struct exfat_node* node)
635 if (node->flags & EXFAT_ATTRIB_DIR)
637 return delete(ef, node);
640 int exfat_rmdir(struct exfat* ef, struct exfat_node* node)
642 if (!(node->flags & EXFAT_ATTRIB_DIR))
644 /* check that directory is empty */
645 exfat_cache_directory(ef, node);
648 return delete(ef, node);
651 static int grow_directory(struct exfat* ef, struct exfat_node* dir,
652 uint64_t asize, uint32_t difference)
654 return exfat_truncate(ef, dir,
655 DIV_ROUND_UP(asize + difference, CLUSTER_SIZE(*ef->sb))
656 * CLUSTER_SIZE(*ef->sb));
659 static int find_slot(struct exfat* ef, struct exfat_node* dir,
660 cluster_t* cluster, off_t* offset, int subentries)
664 const struct exfat_entry* entry;
667 rc = opendir(ef, dir, &it);
674 *cluster = it.cluster;
677 entry = get_entry_ptr(ef, &it);
678 if (entry->type == EXFAT_ENTRY_EOD)
680 rc = grow_directory(ef, dir,
681 it.offset + sizeof(struct exfat_entry), /* actual size */
682 (subentries - contiguous) * sizeof(struct exfat_entry));
690 if (entry->type & EXFAT_ENTRY_VALID)
694 if (contiguous == subentries)
695 break; /* suitable slot is found */
696 if (fetch_next_entry(ef, dir, &it) != 0)
706 static int write_entry(struct exfat* ef, struct exfat_node* dir,
707 const le16_t* name, cluster_t cluster, off_t offset, uint16_t attrib)
709 struct exfat_node* node;
710 struct exfat_entry_meta1 meta1;
711 struct exfat_entry_meta2 meta2;
712 const size_t name_length = utf16_length(name);
713 const int name_entries = DIV_ROUND_UP(name_length, EXFAT_ENAME_MAX);
716 node = allocate_node();
719 node->entry_cluster = cluster;
720 node->entry_offset = offset;
721 memcpy(node->name, name, name_length * sizeof(le16_t));
723 memset(&meta1, 0, sizeof(meta1));
724 meta1.type = EXFAT_ENTRY_FILE;
725 meta1.continuations = 1 + name_entries;
726 meta1.attrib = cpu_to_le16(attrib);
727 exfat_unix2exfat(time(NULL), &meta1.crdate, &meta1.crtime,
729 meta1.adate = meta1.mdate = meta1.crdate;
730 meta1.atime = meta1.mtime = meta1.crtime;
731 /* crtime_cs and mtime_cs contain addition to the time in centiseconds;
732 just ignore those fields because we operate with 2 sec resolution */
734 memset(&meta2, 0, sizeof(meta2));
735 meta2.type = EXFAT_ENTRY_FILE_INFO;
736 meta2.flag = EXFAT_FLAG_FRAGMENTED;
737 meta2.name_length = name_length;
738 meta2.name_hash = exfat_calc_name_hash(ef, node->name);
739 meta2.start_cluster = cpu_to_le32(EXFAT_CLUSTER_FREE);
741 meta1.checksum = exfat_calc_checksum(&meta1, &meta2, node->name);
743 exfat_write_raw(&meta1, sizeof(meta1), co2o(ef, cluster, offset), ef->fd);
744 next_entry(ef, dir, &cluster, &offset);
745 exfat_write_raw(&meta2, sizeof(meta2), co2o(ef, cluster, offset), ef->fd);
746 for (i = 0; i < name_entries; i++)
748 struct exfat_entry_name name_entry = {EXFAT_ENTRY_FILE_NAME, 0};
749 memcpy(name_entry.name, node->name + i * EXFAT_ENAME_MAX,
750 EXFAT_ENAME_MAX * sizeof(le16_t));
751 next_entry(ef, dir, &cluster, &offset);
752 exfat_write_raw(&name_entry, sizeof(name_entry),
753 co2o(ef, cluster, offset), ef->fd);
756 init_node_meta1(node, &meta1);
757 init_node_meta2(node, &meta2);
759 tree_attach(dir, node);
760 exfat_update_mtime(dir);
764 static int create(struct exfat* ef, const char* path, uint16_t attrib)
766 struct exfat_node* dir;
767 struct exfat_node* existing;
768 cluster_t cluster = EXFAT_CLUSTER_BAD;
770 le16_t name[EXFAT_NAME_MAX + 1];
773 rc = exfat_split(ef, &dir, &existing, name, path);
776 if (existing != NULL)
778 exfat_put_node(ef, existing);
779 exfat_put_node(ef, dir);
783 rc = find_slot(ef, dir, &cluster, &offset,
784 2 + DIV_ROUND_UP(utf16_length(name), EXFAT_ENAME_MAX));
787 exfat_put_node(ef, dir);
790 rc = write_entry(ef, dir, name, cluster, offset, attrib);
791 exfat_put_node(ef, dir);
795 int exfat_mknod(struct exfat* ef, const char* path)
797 return create(ef, path, EXFAT_ATTRIB_ARCH);
800 int exfat_mkdir(struct exfat* ef, const char* path)
803 struct exfat_node* node;
805 rc = create(ef, path, EXFAT_ATTRIB_ARCH | EXFAT_ATTRIB_DIR);
808 rc = exfat_lookup(ef, &node, path);
811 /* directories always have at least one cluster */
812 rc = exfat_truncate(ef, node, CLUSTER_SIZE(*ef->sb));
816 exfat_put_node(ef, node);
819 exfat_put_node(ef, node);
823 static void rename_entry(struct exfat* ef, struct exfat_node* dir,
824 struct exfat_node* node, const le16_t* name, cluster_t new_cluster,
827 struct exfat_entry_meta1 meta1;
828 struct exfat_entry_meta2 meta2;
829 cluster_t old_cluster = node->entry_cluster;
830 off_t old_offset = node->entry_offset;
831 const size_t name_length = utf16_length(name);
832 const int name_entries = DIV_ROUND_UP(name_length, EXFAT_ENAME_MAX);
835 exfat_read_raw(&meta1, sizeof(meta1), co2o(ef, old_cluster, old_offset),
837 next_entry(ef, node->parent, &old_cluster, &old_offset);
838 exfat_read_raw(&meta2, sizeof(meta2), co2o(ef, old_cluster, old_offset),
840 meta1.continuations = 1 + name_entries;
841 meta2.name_hash = exfat_calc_name_hash(ef, name);
842 meta2.name_length = name_length;
843 meta1.checksum = exfat_calc_checksum(&meta1, &meta2, name);
845 erase_entry(ef, node);
847 node->entry_cluster = new_cluster;
848 node->entry_offset = new_offset;
850 exfat_write_raw(&meta1, sizeof(meta1), co2o(ef, new_cluster, new_offset),
852 next_entry(ef, dir, &new_cluster, &new_offset);
853 exfat_write_raw(&meta2, sizeof(meta2), co2o(ef, new_cluster, new_offset),
856 for (i = 0; i < name_entries; i++)
858 struct exfat_entry_name name_entry = {EXFAT_ENTRY_FILE_NAME, 0};
859 memcpy(name_entry.name, name + i * EXFAT_ENAME_MAX,
860 EXFAT_ENAME_MAX * sizeof(le16_t));
861 next_entry(ef, dir, &new_cluster, &new_offset);
862 exfat_write_raw(&name_entry, sizeof(name_entry),
863 co2o(ef, new_cluster, new_offset), ef->fd);
866 memcpy(node->name, name, (EXFAT_NAME_MAX + 1) * sizeof(le16_t));
868 tree_attach(dir, node);
871 int exfat_rename(struct exfat* ef, const char* old_path, const char* new_path)
873 struct exfat_node* node;
874 struct exfat_node* existing;
875 struct exfat_node* dir;
876 cluster_t cluster = EXFAT_CLUSTER_BAD;
878 le16_t name[EXFAT_NAME_MAX + 1];
881 rc = exfat_lookup(ef, &node, old_path);
885 rc = exfat_split(ef, &dir, &existing, name, new_path);
888 exfat_put_node(ef, node);
891 if (existing != NULL)
893 if (existing->flags & EXFAT_ATTRIB_DIR)
895 if (node->flags & EXFAT_ATTRIB_DIR)
896 rc = exfat_rmdir(ef, existing);
902 if (!(node->flags & EXFAT_ATTRIB_DIR))
903 rc = exfat_unlink(ef, existing);
907 exfat_put_node(ef, existing);
910 exfat_put_node(ef, dir);
911 exfat_put_node(ef, node);
916 rc = find_slot(ef, dir, &cluster, &offset,
917 2 + DIV_ROUND_UP(utf16_length(name), EXFAT_ENAME_MAX));
920 exfat_put_node(ef, dir);
921 exfat_put_node(ef, node);
924 rename_entry(ef, dir, node, name, cluster, offset);
925 exfat_put_node(ef, dir);
926 exfat_put_node(ef, node);
930 void exfat_utimes(struct exfat_node* node, const struct timespec tv[2])
932 node->atime = tv[0].tv_sec;
933 node->mtime = tv[1].tv_sec;
934 node->flags |= EXFAT_ATTRIB_DIRTY;
937 void exfat_update_atime(struct exfat_node* node)
939 node->atime = time(NULL);
940 node->flags |= EXFAT_ATTRIB_DIRTY;
943 void exfat_update_mtime(struct exfat_node* node)
945 node->mtime = time(NULL);
946 node->flags |= EXFAT_ATTRIB_DIRTY;
949 const char* exfat_get_label(struct exfat* ef)
954 static int find_label(struct exfat* ef, cluster_t* cluster, off_t* offset)
958 const struct exfat_entry* entry;
960 rc = opendir(ef, ef->root, &it);
966 entry = get_entry_ptr(ef, &it);
968 if (entry->type == EXFAT_ENTRY_EOD)
973 if (entry->type == EXFAT_ENTRY_LABEL)
975 *cluster = it.cluster;
981 if (fetch_next_entry(ef, ef->root, &it) != 0)
989 int exfat_set_label(struct exfat* ef, const char* label)
991 le16_t label_utf16[EXFAT_ENAME_MAX + 1];
995 struct exfat_entry_label entry;
997 memset(label_utf16, 0, sizeof(label_utf16));
998 rc = utf8_to_utf16(label_utf16, label, EXFAT_ENAME_MAX, strlen(label));
1002 rc = find_label(ef, &cluster, &offset);
1004 rc = find_slot(ef, ef->root, &cluster, &offset, 1);
1008 entry.type = EXFAT_ENTRY_LABEL;
1009 entry.length = utf16_length(label_utf16);
1010 memcpy(entry.name, label_utf16, sizeof(entry.name));
1011 if (entry.length == 0)
1012 entry.type ^= EXFAT_ENTRY_VALID;
1014 exfat_write_raw(&entry, sizeof(struct exfat_entry_label),
1015 co2o(ef, cluster, offset), ef->fd);