OSDN Git Service

Change source files headings to meet FSF recommendations.
[android-x86/external-exfat.git] / libexfat / node.c
1 /*
2         node.c (09.10.09)
3         exFAT file system implementation library.
4
5         Copyright (C) 2009, 2010  Andrew Nayenko
6
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.
11
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.
16
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/>.
19 */
20
21 #include "exfat.h"
22 #include <errno.h>
23 #include <string.h>
24 #include <inttypes.h>
25
26 /* on-disk nodes iterator */
27 struct iterator
28 {
29         cluster_t cluster;
30         off_t offset;
31         int contiguous;
32         char* chunk;
33 };
34
35 struct exfat_node* exfat_get_node(struct exfat_node* node)
36 {
37         /* if we switch to multi-threaded mode we will need atomic
38            increment here and atomic decrement in exfat_put_node() */
39         node->references++;
40         return node;
41 }
42
43 void exfat_put_node(struct exfat* ef, struct exfat_node* node)
44 {
45         if (--node->references < 0)
46         {
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);
50         }
51
52         if (node->references == 0)
53         {
54                 if (node->flags & EXFAT_ATTRIB_DIRTY)
55                         exfat_flush_node(ef, node);
56                 if (node->flags & EXFAT_ATTRIB_UNLINKED)
57                 {
58                         /* free all clusters and node structure itself */
59                         exfat_truncate(ef, node, 0);
60                         free(node);
61                 }
62                 if (ef->cmap.dirty)
63                         exfat_flush_cmap(ef);
64         }
65 }
66
67 static int opendir(struct exfat* ef, const struct exfat_node* dir,
68                 struct iterator* it)
69 {
70         if (!(dir->flags & EXFAT_ATTRIB_DIR))
71                 exfat_bug("not a directory");
72         it->cluster = dir->start_cluster;
73         it->offset = 0;
74         it->contiguous = IS_CONTIGUOUS(*dir);
75         it->chunk = malloc(CLUSTER_SIZE(*ef->sb));
76         if (it->chunk == NULL)
77         {
78                 exfat_error("out of memory");
79                 return -ENOMEM;
80         }
81         exfat_read_raw(it->chunk, CLUSTER_SIZE(*ef->sb),
82                         exfat_c2o(ef, it->cluster), ef->fd);
83         return 0;
84 }
85
86 static void closedir(struct iterator* it)
87 {
88         it->cluster = 0;
89         it->offset = 0;
90         it->contiguous = 0;
91         free(it->chunk);
92         it->chunk = NULL;
93 }
94
95 static int fetch_next_entry(struct exfat* ef, const struct exfat_node* parent,
96                 struct iterator* it)
97 {
98         /* move iterator to the next entry in the directory */
99         it->offset += sizeof(struct exfat_entry);
100         /* fetch the next cluster if needed */
101         if ((it->offset & (CLUSTER_SIZE(*ef->sb) - 1)) == 0)
102         {
103                 it->cluster = exfat_next_cluster(ef, parent, it->cluster);
104                 if (CLUSTER_INVALID(it->cluster))
105                 {
106                         exfat_error("invalid cluster while reading directory");
107                         return 1;
108                 }
109                 exfat_read_raw(it->chunk, CLUSTER_SIZE(*ef->sb),
110                                 exfat_c2o(ef, it->cluster), ef->fd);
111         }
112         return 0;
113 }
114
115 static struct exfat_node* allocate_node(void)
116 {
117         struct exfat_node* node = malloc(sizeof(struct exfat_node));
118         if (node == NULL)
119         {
120                 exfat_error("failed to allocate node");
121                 return NULL;
122         }
123         memset(node, 0, sizeof(struct exfat_node));
124         return node;
125 }
126
127 static void init_node_meta1(struct exfat_node* node,
128                 const struct exfat_file* meta1)
129 {
130         node->flags = le16_to_cpu(meta1->attrib);
131         node->mtime = exfat_exfat2unix(meta1->mdate, meta1->mtime);
132         node->atime = exfat_exfat2unix(meta1->adate, meta1->atime);
133 }
134
135 static void init_node_meta2(struct exfat_node* node,
136                 const struct exfat_file_info* meta2)
137 {
138         node->size = le64_to_cpu(meta2->size);
139         node->start_cluster = le32_to_cpu(meta2->start_cluster);
140         node->fptr_cluster = node->start_cluster;
141         if (meta2->flag == EXFAT_FLAG_CONTIGUOUS)
142                 node->flags |= EXFAT_ATTRIB_CONTIGUOUS;
143 }
144
145 /*
146  * Reads one entry in directory at position pointed by iterator and fills
147  * node structure.
148  */
149 static int readdir(struct exfat* ef, const struct exfat_node* parent,
150                 struct exfat_node** node, struct iterator* it)
151 {
152         const struct exfat_entry* entry;
153         const struct exfat_file* file;
154         const struct exfat_file_info* file_info;
155         const struct exfat_file_name* file_name;
156         const struct exfat_upcase* upcase;
157         const struct exfat_bitmap* bitmap;
158         const struct exfat_label* label;
159         uint8_t continuations = 0;
160         le16_t* namep = NULL;
161         uint16_t reference_checksum = 0;
162         uint16_t actual_checksum = 0;
163
164         *node = NULL;
165
166         for (;;)
167         {
168                 /* every directory (even empty one) occupies at least one cluster and
169                    must contain EOD entry */
170                 entry = (const struct exfat_entry*)
171                                 (it->chunk + it->offset % CLUSTER_SIZE(*ef->sb));
172
173                 switch (entry->type)
174                 {
175                 case EXFAT_ENTRY_EOD:
176                         if (continuations != 0)
177                         {
178                                 exfat_error("expected %hhu continuations before EOD",
179                                                 continuations);
180                                 goto error;
181                         }
182                         return -ENOENT; /* that's OK, means end of directory */
183
184                 case EXFAT_ENTRY_FILE:
185                         if (continuations != 0)
186                         {
187                                 exfat_error("expected %hhu continuations before new entry",
188                                                 continuations);
189                                 goto error;
190                         }
191                         file = (const struct exfat_file*) entry;
192                         continuations = file->continuations;
193                         /* each file entry must have at least 2 continuations:
194                            info and name */
195                         if (continuations < 2)
196                         {
197                                 exfat_error("too few continuations (%hhu)", continuations);
198                                 return -EIO;
199                         }
200                         reference_checksum = le16_to_cpu(file->checksum);
201                         actual_checksum = exfat_start_checksum(file);
202                         *node = allocate_node();
203                         if (*node == NULL)
204                                 return -ENOMEM;
205                         /* new node has zero reference counter */
206                         (*node)->entry_cluster = it->cluster;
207                         (*node)->entry_offset = it->offset % CLUSTER_SIZE(*ef->sb);
208                         init_node_meta1(*node, file);
209                         namep = (*node)->name;
210                         break;
211
212                 case EXFAT_ENTRY_FILE_INFO:
213                         if (continuations < 2)
214                         {
215                                 exfat_error("unexpected continuation (%hhu)",
216                                                 continuations);
217                                 goto error;
218                         }
219                         file_info = (const struct exfat_file_info*) entry;
220                         init_node_meta2(*node, file_info);
221                         actual_checksum = exfat_add_checksum(entry, actual_checksum);
222                         /* There are two fields that contain file size. Maybe they plan
223                            to add compression support in the future and one of those
224                            fields is visible (uncompressed) size and the other is real
225                            (compressed) size. Anyway, currently it looks like exFAT does
226                            not support compression and both fields must be equal. */
227                         if (le64_to_cpu(file_info->real_size) != (*node)->size)
228                         {
229                                 exfat_error("real size does not equal to size "
230                                                 "(%"PRIu64" != %"PRIu64")",
231                                                 le64_to_cpu(file_info->real_size), (*node)->size);
232                                 goto error;
233                         }
234                         /* directories must be aligned on at cluster boundary */
235                         if (((*node)->flags & EXFAT_ATTRIB_DIR) &&
236                                 (*node)->size % CLUSTER_SIZE(*ef->sb) != 0)
237                         {
238                                 char buffer[EXFAT_NAME_MAX + 1];
239
240                                 exfat_get_name(*node, buffer, EXFAT_NAME_MAX);
241                                 exfat_error("directory `%s' has invalid size %"PRIu64" bytes",
242                                                 buffer, (*node)->size);
243                                 goto error;
244                         }
245                         --continuations;
246                         break;
247
248                 case EXFAT_ENTRY_FILE_NAME:
249                         if (continuations == 0)
250                         {
251                                 exfat_error("unexpected continuation");
252                                 goto error;
253                         }
254                         file_name = (const struct exfat_file_name*) entry;
255                         actual_checksum = exfat_add_checksum(entry, actual_checksum);
256
257                         memcpy(namep, file_name->name, EXFAT_ENAME_MAX * sizeof(le16_t));
258                         namep += EXFAT_ENAME_MAX;
259                         if (--continuations == 0)
260                         {
261                                 if (actual_checksum != reference_checksum)
262                                 {
263                                         exfat_error("invalid checksum (0x%hx != 0x%hx)",
264                                                         actual_checksum, reference_checksum);
265                                         return -EIO;
266                                 }
267                                 if (fetch_next_entry(ef, parent, it) != 0)
268                                         goto error;
269                                 return 0; /* entry completed */
270                         }
271                         break;
272
273                 case EXFAT_ENTRY_UPCASE:
274                         if (ef->upcase != NULL)
275                                 break;
276                         upcase = (const struct exfat_upcase*) entry;
277                         if (CLUSTER_INVALID(le32_to_cpu(upcase->start_cluster)))
278                         {
279                                 exfat_error("invalid cluster in upcase table");
280                                 return -EIO;
281                         }
282                         if (le64_to_cpu(upcase->size) == 0 ||
283                                 le64_to_cpu(upcase->size) > 0xffff * sizeof(uint16_t) ||
284                                 le64_to_cpu(upcase->size) % sizeof(uint16_t) != 0)
285                         {
286                                 exfat_error("bad upcase table size (%"PRIu64" bytes)",
287                                                 le64_to_cpu(upcase->size));
288                                 return -EIO;
289                         }
290                         ef->upcase = malloc(le64_to_cpu(upcase->size));
291                         if (ef->upcase == NULL)
292                         {
293                                 exfat_error("failed to allocate upcase table (%"PRIu64" bytes)",
294                                                 le64_to_cpu(upcase->size));
295                                 return -ENOMEM;
296                         }
297                         ef->upcase_chars = le64_to_cpu(upcase->size) / sizeof(le16_t);
298
299                         exfat_read_raw(ef->upcase, le64_to_cpu(upcase->size),
300                                         exfat_c2o(ef, le32_to_cpu(upcase->start_cluster)), ef->fd);
301                         break;
302
303                 case EXFAT_ENTRY_BITMAP:
304                         bitmap = (const struct exfat_bitmap*) entry;
305                         if (CLUSTER_INVALID(le32_to_cpu(bitmap->start_cluster)))
306                         {
307                                 exfat_error("invalid cluster in clusters bitmap");
308                                 return -EIO;
309                         }
310                         ef->cmap.size = le32_to_cpu(ef->sb->cluster_count) -
311                                 EXFAT_FIRST_DATA_CLUSTER;
312                         if (le64_to_cpu(bitmap->size) != (ef->cmap.size + 7) / 8)
313                         {
314                                 exfat_error("invalid bitmap size: %"PRIu64" (expected %u)",
315                                                 le64_to_cpu(bitmap->size), (ef->cmap.size + 7) / 8);
316                                 return -EIO;
317                         }
318                         ef->cmap.start_cluster = le32_to_cpu(bitmap->start_cluster);
319                         /* FIXME bitmap can be rather big, up to 512 MB */
320                         ef->cmap.chunk_size = ef->cmap.size;
321                         ef->cmap.chunk = malloc(le64_to_cpu(bitmap->size));
322                         if (ef->cmap.chunk == NULL)
323                         {
324                                 exfat_error("failed to allocate clusters map chunk "
325                                                 "(%"PRIu64" bytes)", le64_to_cpu(bitmap->size));
326                                 return -ENOMEM;
327                         }
328
329                         exfat_read_raw(ef->cmap.chunk, le64_to_cpu(bitmap->size),
330                                         exfat_c2o(ef, ef->cmap.start_cluster), ef->fd);
331                         break;
332
333                 case EXFAT_ENTRY_LABEL:
334                         label = (const struct exfat_label*) entry;
335                         if (label->length > EXFAT_ENAME_MAX)
336                         {
337                                 exfat_error("too long label (%hhu chars)", label->length);
338                                 return -EIO;
339                         }
340                         break;
341
342                 default:
343                         if (entry->type & EXFAT_ENTRY_VALID)
344                         {
345                                 exfat_error("unknown entry type 0x%hhu", entry->type);
346                                 goto error;
347                         }
348                         break;
349                 }
350
351                 if (fetch_next_entry(ef, parent, it) != 0)
352                         goto error;
353         }
354         /* we never reach here */
355
356 error:
357         free(*node);
358         *node = NULL;
359         return -EIO;
360 }
361
362 int exfat_cache_directory(struct exfat* ef, struct exfat_node* dir)
363 {
364         struct iterator it;
365         int rc;
366         struct exfat_node* node;
367         struct exfat_node* current = NULL;
368
369         if (dir->flags & EXFAT_ATTRIB_CACHED)
370                 return 0; /* already cached */
371
372         rc = opendir(ef, dir, &it);
373         if (rc != 0)
374                 return rc;
375         while ((rc = readdir(ef, dir, &node, &it)) == 0)
376         {
377                 node->parent = dir;
378                 if (current != NULL)
379                 {
380                         current->next = node;
381                         node->prev = current;
382                 }
383                 else
384                         dir->child = node;
385
386                 current = node;
387         }
388         closedir(&it);
389
390         if (rc != -ENOENT)
391         {
392                 /* rollback */
393                 for (current = dir->child; current; current = node)
394                 {
395                         node = current->next;
396                         free(current);
397                 }
398                 dir->child = NULL;
399                 return rc;
400         }
401
402         dir->flags |= EXFAT_ATTRIB_CACHED;
403         return 0;
404 }
405
406 static void reset_cache(struct exfat* ef, struct exfat_node* node)
407 {
408         struct exfat_node* child;
409         struct exfat_node* next;
410
411         for (child = node->child; child; child = next)
412         {
413                 reset_cache(ef, child);
414                 next = child->next;
415                 free(child);
416         }
417         if (node->references != 0)
418         {
419                 char buffer[EXFAT_NAME_MAX + 1];
420                 exfat_get_name(node, buffer, EXFAT_NAME_MAX);
421                 exfat_warn("non-zero reference counter (%d) for `%s'",
422                                 node->references, buffer);
423         }
424         while (node->references--)
425                 exfat_put_node(ef, node);
426         node->child = NULL;
427         node->flags &= ~EXFAT_ATTRIB_CACHED;
428 }
429
430 void exfat_reset_cache(struct exfat* ef)
431 {
432         reset_cache(ef, ef->root);
433 }
434
435 void next_entry(struct exfat* ef, const struct exfat_node* parent,
436                 cluster_t* cluster, off_t* offset)
437 {
438         if (*offset + sizeof(struct exfat_entry) == CLUSTER_SIZE(*ef->sb))
439         {
440                 /* next cluster cannot be invalid */
441                 *cluster = exfat_next_cluster(ef, parent, *cluster);
442                 *offset = 0;
443         }
444         else
445                 *offset += sizeof(struct exfat_entry);
446
447 }
448
449 void exfat_flush_node(struct exfat* ef, struct exfat_node* node)
450 {
451         cluster_t cluster;
452         off_t offset;
453         off_t meta1_offset, meta2_offset;
454         struct exfat_file meta1;
455         struct exfat_file_info meta2;
456
457         if (ef->ro)
458                 exfat_bug("unable to flush node to read-only FS");
459
460         if (node->parent == NULL)
461                 return; /* do not flush unlinked node */
462
463         cluster = node->entry_cluster;
464         offset = node->entry_offset;
465         meta1_offset = exfat_c2o(ef, cluster) + offset;
466         next_entry(ef, node->parent, &cluster, &offset);
467         meta2_offset = exfat_c2o(ef, cluster) + offset;
468
469         exfat_read_raw(&meta1, sizeof(meta1), meta1_offset, ef->fd);
470         if (meta1.type != EXFAT_ENTRY_FILE)
471                 exfat_bug("invalid type of meta1: 0x%hhx", meta1.type);
472         meta1.attrib = cpu_to_le16(node->flags);
473         exfat_unix2exfat(node->mtime, &meta1.mdate, &meta1.mtime);
474         exfat_unix2exfat(node->atime, &meta1.adate, &meta1.atime);
475
476         exfat_read_raw(&meta2, sizeof(meta2), meta2_offset, ef->fd);
477         if (meta2.type != EXFAT_ENTRY_FILE_INFO)
478                 exfat_bug("invalid type of meta2: 0x%hhx", meta2.type);
479         meta2.size = meta2.real_size = cpu_to_le64(node->size);
480         meta2.start_cluster = cpu_to_le32(node->start_cluster);
481         /* empty files must be marked as fragmented */
482         if (node->size != 0 && IS_CONTIGUOUS(*node))
483                 meta2.flag = EXFAT_FLAG_CONTIGUOUS;
484         else
485                 meta2.flag = EXFAT_FLAG_FRAGMENTED;
486         /* name hash remains unchanged, no need to recalculate it */
487
488         meta1.checksum = exfat_calc_checksum(&meta1, &meta2, node->name);
489
490         exfat_write_raw(&meta1, sizeof(meta1), meta1_offset, ef->fd);
491         exfat_write_raw(&meta2, sizeof(meta2), meta2_offset, ef->fd);
492
493         node->flags &= ~EXFAT_ATTRIB_DIRTY;
494 }
495
496 static void erase_entry(struct exfat* ef, struct exfat_node* node)
497 {
498         cluster_t cluster = node->entry_cluster;
499         off_t offset = node->entry_offset;
500         int name_entries = DIV_ROUND_UP(utf16_length(node->name), EXFAT_ENAME_MAX);
501         uint8_t entry_type;
502
503         entry_type = EXFAT_ENTRY_FILE & ~EXFAT_ENTRY_VALID;
504         exfat_write_raw(&entry_type, 1, exfat_c2o(ef, cluster) + offset, ef->fd);
505
506         next_entry(ef, node->parent, &cluster, &offset);
507         entry_type = EXFAT_ENTRY_FILE_INFO & ~EXFAT_ENTRY_VALID;
508         exfat_write_raw(&entry_type, 1, exfat_c2o(ef, cluster) + offset, ef->fd);
509
510         while (name_entries--)
511         {
512                 next_entry(ef, node->parent, &cluster, &offset);
513                 entry_type = EXFAT_ENTRY_FILE_NAME & ~EXFAT_ENTRY_VALID;
514                 exfat_write_raw(&entry_type, 1, exfat_c2o(ef, cluster) + offset,
515                                 ef->fd);
516         }
517 }
518
519 static void tree_detach(struct exfat_node* node)
520 {
521         if (node->prev)
522                 node->prev->next = node->next;
523         else /* this is the first node in the list */
524                 node->parent->child = node->next;
525         if (node->next)
526                 node->next->prev = node->prev;
527         node->parent = NULL;
528         node->prev = NULL;
529         node->next = NULL;
530 }
531
532 static void tree_attach(struct exfat_node* dir, struct exfat_node* node)
533 {
534         node->parent = dir;
535         if (dir->child)
536         {
537                 dir->child->prev = node;
538                 node->next = dir->child;
539         }
540         dir->child = node;
541 }
542
543 static void delete(struct exfat* ef, struct exfat_node* node)
544 {
545         erase_entry(ef, node);
546         exfat_update_mtime(node->parent);
547         tree_detach(node);
548         /* file clusters will be freed when node reference counter becomes 0 */
549         node->flags |= EXFAT_ATTRIB_UNLINKED;
550 }
551
552 int exfat_unlink(struct exfat* ef, struct exfat_node* node)
553 {
554         if (node->flags & EXFAT_ATTRIB_DIR)
555                 return -EISDIR;
556         delete(ef, node);
557         return 0;
558 }
559
560 int exfat_rmdir(struct exfat* ef, struct exfat_node* node)
561 {
562         if (!(node->flags & EXFAT_ATTRIB_DIR))
563                 return -ENOTDIR;
564         /* check that directory is empty */
565         exfat_cache_directory(ef, node);
566         if (node->child)
567                 return -ENOTEMPTY;
568         delete(ef, node);
569         return 0;
570 }
571
572 static int grow_directory(struct exfat* ef, struct exfat_node* dir,
573                 uint64_t asize, uint32_t difference)
574 {
575         return exfat_truncate(ef, dir,
576                         DIV_ROUND_UP(asize + difference, CLUSTER_SIZE(*ef->sb))
577                                 * CLUSTER_SIZE(*ef->sb));
578 }
579
580 static void write_eod(struct exfat* ef, struct exfat_node* dir,
581                 cluster_t cluster, off_t offset, int seek)
582 {
583         struct exfat_entry eod;
584
585         while (seek--)
586                 next_entry(ef, dir, &cluster, &offset);
587         memset(&eod, 0, sizeof(struct exfat_entry));
588         exfat_write_raw(&eod, sizeof(struct exfat_entry),
589                         exfat_c2o(ef, cluster) + offset, ef->fd);
590 }
591
592 static int find_slot(struct exfat* ef, struct exfat_node* dir,
593                 cluster_t* cluster, off_t* offset, int subentries)
594 {
595         struct iterator it;
596         int rc;
597         const struct exfat_entry* entry;
598         int contiguous = 0;
599
600         rc = opendir(ef, dir, &it);
601         if (rc != 0)
602                 return rc;
603         for (;;)
604         {
605                 if (contiguous == 0)
606                 {
607                         *cluster = it.cluster;
608                         *offset = it.offset % CLUSTER_SIZE(*ef->sb);
609                 }
610                 entry = (const struct exfat_entry*)
611                                 (it.chunk + it.offset % CLUSTER_SIZE(*ef->sb));
612                 if (entry->type == EXFAT_ENTRY_EOD)
613                 {
614                         rc = grow_directory(ef, dir,
615                                         it.offset + sizeof(struct exfat_entry), /* actual size */
616                                         (subentries - contiguous) * sizeof(struct exfat_entry));
617                         if (rc != 0)
618                         {
619                                 closedir(&it);
620                                 return rc;
621                         }
622                         write_eod(ef, dir, *cluster, *offset, subentries - contiguous);
623                         break;
624                 }
625                 if (entry->type & EXFAT_ENTRY_VALID)
626                         contiguous = 0;
627                 else
628                         contiguous++;
629                 if (contiguous == subentries)
630                         break;  /* suitable slot it found */
631                 if (fetch_next_entry(ef, dir, &it) != 0)
632                 {
633                         closedir(&it);
634                         return -EIO;
635                 }
636         }
637         closedir(&it);
638         return 0;
639 }
640
641 static int write_entry(struct exfat* ef, struct exfat_node* dir,
642                 const le16_t* name, cluster_t cluster, off_t offset, uint16_t attrib)
643 {
644         struct exfat_node* node;
645         struct exfat_file meta1;
646         struct exfat_file_info meta2;
647         const size_t name_length = utf16_length(name);
648         const int name_entries = DIV_ROUND_UP(name_length, EXFAT_ENAME_MAX);
649         int i;
650
651         node = allocate_node();
652         if (node == NULL)
653                 return -ENOMEM;
654         node->entry_cluster = cluster;
655         node->entry_offset = offset;
656         memcpy(node->name, name, name_length * sizeof(le16_t));
657
658         memset(&meta1, 0, sizeof(meta1));
659         meta1.type = EXFAT_ENTRY_FILE;
660         meta1.continuations = 1 + name_entries;
661         meta1.attrib = cpu_to_le16(attrib);
662         exfat_unix2exfat(time(NULL), &meta1.crdate, &meta1.crtime);
663         meta1.adate = meta1.mdate = meta1.crdate;
664         meta1.atime = meta1.mtime = meta1.crtime;
665         /* crtime_cs and mtime_cs contain addition to the time in centiseconds;
666            just ignore those fields because we operate with 2 sec resolution */
667
668         memset(&meta2, 0, sizeof(meta2));
669         meta2.type = EXFAT_ENTRY_FILE_INFO;
670         meta2.flag = EXFAT_FLAG_FRAGMENTED;
671         meta2.name_length = name_length;
672         meta2.name_hash = exfat_calc_name_hash(ef, node->name);
673         meta2.start_cluster = cpu_to_le32(EXFAT_CLUSTER_FREE);
674
675         meta1.checksum = exfat_calc_checksum(&meta1, &meta2, node->name);
676
677         exfat_write_raw(&meta1, sizeof(meta1), exfat_c2o(ef, cluster) + offset,
678                         ef->fd);
679         next_entry(ef, dir, &cluster, &offset);
680         exfat_write_raw(&meta2, sizeof(meta2), exfat_c2o(ef, cluster) + offset,
681                         ef->fd);
682         for (i = 0; i < name_entries; i++)
683         {
684                 struct exfat_file_name name_entry = {EXFAT_ENTRY_FILE_NAME, 0};
685                 memcpy(name_entry.name, node->name + i * EXFAT_ENAME_MAX,
686                                 EXFAT_ENAME_MAX * sizeof(le16_t));
687                 next_entry(ef, dir, &cluster, &offset);
688                 exfat_write_raw(&name_entry, sizeof(name_entry),
689                                 exfat_c2o(ef, cluster) + offset, ef->fd);
690         }
691
692         init_node_meta1(node, &meta1);
693         init_node_meta2(node, &meta2);
694
695         tree_attach(dir, node);
696         exfat_update_mtime(dir);
697         return 0;
698 }
699
700 static int create(struct exfat* ef, const char* path, uint16_t attrib)
701 {
702         struct exfat_node* dir;
703         cluster_t cluster = EXFAT_CLUSTER_BAD;
704         off_t offset = -1;
705         le16_t name[EXFAT_NAME_MAX + 1];
706         int rc;
707
708         /* FIXME filter name characters */
709
710         rc = exfat_split(ef, &dir, name, path);
711         if (rc != 0)
712                 return rc;
713
714         rc = find_slot(ef, dir, &cluster, &offset,
715                         2 + DIV_ROUND_UP(utf16_length(name), EXFAT_ENAME_MAX));
716         if (rc != 0)
717         {
718                 exfat_put_node(ef, dir);
719                 return rc;
720         }
721         rc = write_entry(ef, dir, name, cluster, offset, attrib);
722         exfat_put_node(ef, dir);
723         return rc;
724 }
725
726 int exfat_mknod(struct exfat* ef, const char* path)
727 {
728         return create(ef, path, EXFAT_ATTRIB_ARCH);
729 }
730
731 int exfat_mkdir(struct exfat* ef, const char* path)
732 {
733         int rc;
734         struct exfat_node* node;
735
736         rc = create(ef, path, EXFAT_ATTRIB_ARCH | EXFAT_ATTRIB_DIR);
737         if (rc != 0)
738                 return rc;
739         rc = exfat_lookup(ef, &node, path);
740         if (rc != 0)
741                 return 0;
742         /* directories always have at least one cluster */
743         rc = exfat_truncate(ef, node, CLUSTER_SIZE(*ef->sb));
744         if (rc != 0)
745         {
746                 delete(ef, node);
747                 exfat_put_node(ef, node);
748                 return rc;
749         }
750         exfat_put_node(ef, node);
751         return 0;
752 }
753
754 static void rename_entry(struct exfat* ef, struct exfat_node* dir,
755                 struct exfat_node* node, const le16_t* name, cluster_t new_cluster,
756                 off_t new_offset)
757 {
758         struct exfat_file meta1;
759         struct exfat_file_info meta2;
760         cluster_t old_cluster = node->entry_cluster;
761         off_t old_offset = node->entry_offset;
762         const size_t name_length = utf16_length(name);
763         const int name_entries = DIV_ROUND_UP(name_length, EXFAT_ENAME_MAX);
764         int i;
765
766         exfat_read_raw(&meta1, sizeof(meta1),
767                         exfat_c2o(ef, old_cluster) + old_offset, ef->fd);
768         next_entry(ef, node->parent, &old_cluster, &old_offset);
769         exfat_read_raw(&meta2, sizeof(meta2),
770                         exfat_c2o(ef, old_cluster) + old_offset, ef->fd);
771         meta1.continuations = 1 + name_entries;
772         meta2.name_hash = exfat_calc_name_hash(ef, name);
773         meta2.name_length = name_length;
774         meta1.checksum = exfat_calc_checksum(&meta1, &meta2, name);
775
776         erase_entry(ef, node);
777
778         node->entry_cluster = new_cluster;
779         node->entry_offset = new_offset;
780
781         exfat_write_raw(&meta1, sizeof(meta1),
782             exfat_c2o(ef, new_cluster) + new_offset, ef->fd);
783         next_entry(ef, dir, &new_cluster, &new_offset);
784         exfat_write_raw(&meta2, sizeof(meta2),
785             exfat_c2o(ef, new_cluster) + new_offset, ef->fd);
786
787         for (i = 0; i < name_entries; i++)
788         {
789                 struct exfat_file_name name_entry = {EXFAT_ENTRY_FILE_NAME, 0};
790                 memcpy(name_entry.name, name + i * EXFAT_ENAME_MAX,
791                                 EXFAT_ENAME_MAX * sizeof(le16_t));
792                 next_entry(ef, dir, &new_cluster, &new_offset);
793                 exfat_write_raw(&name_entry, sizeof(name_entry),
794                                 exfat_c2o(ef, new_cluster) + new_offset, ef->fd);
795         }
796
797         memcpy(node->name, name, (name_length + 1) * sizeof(le16_t));
798         tree_detach(node);
799         tree_attach(dir, node);
800 }
801
802 int exfat_rename(struct exfat* ef, const char* old_path, const char* new_path)
803 {
804         struct exfat_node* node;
805         struct exfat_node* dir;
806         cluster_t cluster = EXFAT_CLUSTER_BAD;
807         off_t offset = -1;
808         le16_t name[EXFAT_NAME_MAX + 1];
809         int rc;
810
811         rc = exfat_lookup(ef, &node, old_path);
812         if (rc != 0)
813                 return rc;
814
815         memset(name, 0, (EXFAT_NAME_MAX + 1) * sizeof(le16_t));
816         rc = exfat_split(ef, &dir, name, new_path);
817         if (rc != 0)
818         {
819                 exfat_put_node(ef, node);
820                 return rc;
821         }
822
823         rc = find_slot(ef, dir, &cluster, &offset,
824                         2 + DIV_ROUND_UP(utf16_length(name), EXFAT_ENAME_MAX));
825         if (rc != 0)
826         {
827                 exfat_put_node(ef, dir);
828                 exfat_put_node(ef, node);
829                 return rc;
830         }
831         rename_entry(ef, dir, node, name, cluster, offset);
832         exfat_put_node(ef, dir);
833         exfat_put_node(ef, node);
834         return 0;
835 }
836
837 void exfat_utimes(struct exfat_node* node, const struct timespec tv[2])
838 {
839         node->atime = tv[0].tv_sec;
840         node->mtime = tv[1].tv_sec;
841         node->flags |= EXFAT_ATTRIB_DIRTY;
842 }
843
844 void exfat_update_atime(struct exfat_node* node)
845 {
846         node->atime = time(NULL);
847         node->flags |= EXFAT_ATTRIB_DIRTY;
848 }
849
850 void exfat_update_mtime(struct exfat_node* node)
851 {
852         node->mtime = time(NULL);
853         node->flags |= EXFAT_ATTRIB_DIRTY;
854 }