OSDN Git Service

Allow clusters bitmap size to exceed minimum value.
[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_entry_meta1* 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_entry_meta2* 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_entry_meta1* meta1;
154         const struct exfat_entry_meta2* meta2;
155         const struct exfat_entry_name* file_name;
156         const struct exfat_entry_upcase* upcase;
157         const struct exfat_entry_bitmap* bitmap;
158         const struct exfat_entry_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                         meta1 = (const struct exfat_entry_meta1*) entry;
192                         continuations = meta1->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(meta1->checksum);
201                         actual_checksum = exfat_start_checksum(meta1);
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, meta1);
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                         meta2 = (const struct exfat_entry_meta2*) entry;
220                         init_node_meta2(*node, meta2);
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(meta2->real_size) != (*node)->size)
228                         {
229                                 exfat_error("real size does not equal to size "
230                                                 "(%"PRIu64" != %"PRIu64")",
231                                                 le64_to_cpu(meta2->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_entry_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_entry_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_entry_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
315                                                 " (expected at least %u)",
316                                                 le64_to_cpu(bitmap->size), (ef->cmap.size + 7) / 8);
317                                 return -EIO;
318                         }
319                         ef->cmap.start_cluster = le32_to_cpu(bitmap->start_cluster);
320                         /* FIXME bitmap can be rather big, up to 512 MB */
321                         ef->cmap.chunk_size = ef->cmap.size;
322                         ef->cmap.chunk = malloc(le64_to_cpu(bitmap->size));
323                         if (ef->cmap.chunk == NULL)
324                         {
325                                 exfat_error("failed to allocate clusters map chunk "
326                                                 "(%"PRIu64" bytes)", le64_to_cpu(bitmap->size));
327                                 return -ENOMEM;
328                         }
329
330                         exfat_read_raw(ef->cmap.chunk, le64_to_cpu(bitmap->size),
331                                         exfat_c2o(ef, ef->cmap.start_cluster), ef->fd);
332                         break;
333
334                 case EXFAT_ENTRY_LABEL:
335                         label = (const struct exfat_entry_label*) entry;
336                         if (label->length > EXFAT_ENAME_MAX)
337                         {
338                                 exfat_error("too long label (%hhu chars)", label->length);
339                                 return -EIO;
340                         }
341                         break;
342
343                 default:
344                         if (entry->type & EXFAT_ENTRY_VALID)
345                         {
346                                 exfat_error("unknown entry type 0x%hhu", entry->type);
347                                 goto error;
348                         }
349                         break;
350                 }
351
352                 if (fetch_next_entry(ef, parent, it) != 0)
353                         goto error;
354         }
355         /* we never reach here */
356
357 error:
358         free(*node);
359         *node = NULL;
360         return -EIO;
361 }
362
363 int exfat_cache_directory(struct exfat* ef, struct exfat_node* dir)
364 {
365         struct iterator it;
366         int rc;
367         struct exfat_node* node;
368         struct exfat_node* current = NULL;
369
370         if (dir->flags & EXFAT_ATTRIB_CACHED)
371                 return 0; /* already cached */
372
373         rc = opendir(ef, dir, &it);
374         if (rc != 0)
375                 return rc;
376         while ((rc = readdir(ef, dir, &node, &it)) == 0)
377         {
378                 node->parent = dir;
379                 if (current != NULL)
380                 {
381                         current->next = node;
382                         node->prev = current;
383                 }
384                 else
385                         dir->child = node;
386
387                 current = node;
388         }
389         closedir(&it);
390
391         if (rc != -ENOENT)
392         {
393                 /* rollback */
394                 for (current = dir->child; current; current = node)
395                 {
396                         node = current->next;
397                         free(current);
398                 }
399                 dir->child = NULL;
400                 return rc;
401         }
402
403         dir->flags |= EXFAT_ATTRIB_CACHED;
404         return 0;
405 }
406
407 static void reset_cache(struct exfat* ef, struct exfat_node* node)
408 {
409         struct exfat_node* child;
410         struct exfat_node* next;
411
412         for (child = node->child; child; child = next)
413         {
414                 reset_cache(ef, child);
415                 next = child->next;
416                 free(child);
417         }
418         if (node->references != 0)
419         {
420                 char buffer[EXFAT_NAME_MAX + 1];
421                 exfat_get_name(node, buffer, EXFAT_NAME_MAX);
422                 exfat_warn("non-zero reference counter (%d) for `%s'",
423                                 node->references, buffer);
424         }
425         while (node->references--)
426                 exfat_put_node(ef, node);
427         node->child = NULL;
428         node->flags &= ~EXFAT_ATTRIB_CACHED;
429 }
430
431 void exfat_reset_cache(struct exfat* ef)
432 {
433         reset_cache(ef, ef->root);
434 }
435
436 void next_entry(struct exfat* ef, const struct exfat_node* parent,
437                 cluster_t* cluster, off_t* offset)
438 {
439         if (*offset + sizeof(struct exfat_entry) == CLUSTER_SIZE(*ef->sb))
440         {
441                 /* next cluster cannot be invalid */
442                 *cluster = exfat_next_cluster(ef, parent, *cluster);
443                 *offset = 0;
444         }
445         else
446                 *offset += sizeof(struct exfat_entry);
447
448 }
449
450 void exfat_flush_node(struct exfat* ef, struct exfat_node* node)
451 {
452         cluster_t cluster;
453         off_t offset;
454         off_t meta1_offset, meta2_offset;
455         struct exfat_entry_meta1 meta1;
456         struct exfat_entry_meta2 meta2;
457
458         if (ef->ro)
459                 exfat_bug("unable to flush node to read-only FS");
460
461         if (node->parent == NULL)
462                 return; /* do not flush unlinked node */
463
464         cluster = node->entry_cluster;
465         offset = node->entry_offset;
466         meta1_offset = exfat_c2o(ef, cluster) + offset;
467         next_entry(ef, node->parent, &cluster, &offset);
468         meta2_offset = exfat_c2o(ef, cluster) + offset;
469
470         exfat_read_raw(&meta1, sizeof(meta1), meta1_offset, ef->fd);
471         if (meta1.type != EXFAT_ENTRY_FILE)
472                 exfat_bug("invalid type of meta1: 0x%hhx", meta1.type);
473         meta1.attrib = cpu_to_le16(node->flags);
474         exfat_unix2exfat(node->mtime, &meta1.mdate, &meta1.mtime);
475         exfat_unix2exfat(node->atime, &meta1.adate, &meta1.atime);
476
477         exfat_read_raw(&meta2, sizeof(meta2), meta2_offset, ef->fd);
478         if (meta2.type != EXFAT_ENTRY_FILE_INFO)
479                 exfat_bug("invalid type of meta2: 0x%hhx", meta2.type);
480         meta2.size = meta2.real_size = cpu_to_le64(node->size);
481         meta2.start_cluster = cpu_to_le32(node->start_cluster);
482         /* empty files must be marked as fragmented */
483         if (node->size != 0 && IS_CONTIGUOUS(*node))
484                 meta2.flag = EXFAT_FLAG_CONTIGUOUS;
485         else
486                 meta2.flag = EXFAT_FLAG_FRAGMENTED;
487         /* name hash remains unchanged, no need to recalculate it */
488
489         meta1.checksum = exfat_calc_checksum(&meta1, &meta2, node->name);
490
491         exfat_write_raw(&meta1, sizeof(meta1), meta1_offset, ef->fd);
492         exfat_write_raw(&meta2, sizeof(meta2), meta2_offset, ef->fd);
493
494         node->flags &= ~EXFAT_ATTRIB_DIRTY;
495 }
496
497 static void erase_entry(struct exfat* ef, struct exfat_node* node)
498 {
499         cluster_t cluster = node->entry_cluster;
500         off_t offset = node->entry_offset;
501         int name_entries = DIV_ROUND_UP(utf16_length(node->name), EXFAT_ENAME_MAX);
502         uint8_t entry_type;
503
504         entry_type = EXFAT_ENTRY_FILE & ~EXFAT_ENTRY_VALID;
505         exfat_write_raw(&entry_type, 1, exfat_c2o(ef, cluster) + offset, ef->fd);
506
507         next_entry(ef, node->parent, &cluster, &offset);
508         entry_type = EXFAT_ENTRY_FILE_INFO & ~EXFAT_ENTRY_VALID;
509         exfat_write_raw(&entry_type, 1, exfat_c2o(ef, cluster) + offset, ef->fd);
510
511         while (name_entries--)
512         {
513                 next_entry(ef, node->parent, &cluster, &offset);
514                 entry_type = EXFAT_ENTRY_FILE_NAME & ~EXFAT_ENTRY_VALID;
515                 exfat_write_raw(&entry_type, 1, exfat_c2o(ef, cluster) + offset,
516                                 ef->fd);
517         }
518 }
519
520 static void tree_detach(struct exfat_node* node)
521 {
522         if (node->prev)
523                 node->prev->next = node->next;
524         else /* this is the first node in the list */
525                 node->parent->child = node->next;
526         if (node->next)
527                 node->next->prev = node->prev;
528         node->parent = NULL;
529         node->prev = NULL;
530         node->next = NULL;
531 }
532
533 static void tree_attach(struct exfat_node* dir, struct exfat_node* node)
534 {
535         node->parent = dir;
536         if (dir->child)
537         {
538                 dir->child->prev = node;
539                 node->next = dir->child;
540         }
541         dir->child = node;
542 }
543
544 static void delete(struct exfat* ef, struct exfat_node* node)
545 {
546         erase_entry(ef, node);
547         exfat_update_mtime(node->parent);
548         tree_detach(node);
549         /* file clusters will be freed when node reference counter becomes 0 */
550         node->flags |= EXFAT_ATTRIB_UNLINKED;
551 }
552
553 int exfat_unlink(struct exfat* ef, struct exfat_node* node)
554 {
555         if (node->flags & EXFAT_ATTRIB_DIR)
556                 return -EISDIR;
557         delete(ef, node);
558         return 0;
559 }
560
561 int exfat_rmdir(struct exfat* ef, struct exfat_node* node)
562 {
563         if (!(node->flags & EXFAT_ATTRIB_DIR))
564                 return -ENOTDIR;
565         /* check that directory is empty */
566         exfat_cache_directory(ef, node);
567         if (node->child)
568                 return -ENOTEMPTY;
569         delete(ef, node);
570         return 0;
571 }
572
573 static int grow_directory(struct exfat* ef, struct exfat_node* dir,
574                 uint64_t asize, uint32_t difference)
575 {
576         return exfat_truncate(ef, dir,
577                         DIV_ROUND_UP(asize + difference, CLUSTER_SIZE(*ef->sb))
578                                 * CLUSTER_SIZE(*ef->sb));
579 }
580
581 static int find_slot(struct exfat* ef, struct exfat_node* dir,
582                 cluster_t* cluster, off_t* offset, int subentries)
583 {
584         struct iterator it;
585         int rc;
586         const struct exfat_entry* entry;
587         int contiguous = 0;
588
589         rc = opendir(ef, dir, &it);
590         if (rc != 0)
591                 return rc;
592         for (;;)
593         {
594                 if (contiguous == 0)
595                 {
596                         *cluster = it.cluster;
597                         *offset = it.offset % CLUSTER_SIZE(*ef->sb);
598                 }
599                 entry = (const struct exfat_entry*)
600                                 (it.chunk + it.offset % CLUSTER_SIZE(*ef->sb));
601                 if (entry->type == EXFAT_ENTRY_EOD)
602                 {
603                         rc = grow_directory(ef, dir,
604                                         it.offset + sizeof(struct exfat_entry), /* actual size */
605                                         (subentries - contiguous) * sizeof(struct exfat_entry));
606                         if (rc != 0)
607                         {
608                                 closedir(&it);
609                                 return rc;
610                         }
611                         break;
612                 }
613                 if (entry->type & EXFAT_ENTRY_VALID)
614                         contiguous = 0;
615                 else
616                         contiguous++;
617                 if (contiguous == subentries)
618                         break;  /* suitable slot it found */
619                 if (fetch_next_entry(ef, dir, &it) != 0)
620                 {
621                         closedir(&it);
622                         return -EIO;
623                 }
624         }
625         closedir(&it);
626         return 0;
627 }
628
629 static int write_entry(struct exfat* ef, struct exfat_node* dir,
630                 const le16_t* name, cluster_t cluster, off_t offset, uint16_t attrib)
631 {
632         struct exfat_node* node;
633         struct exfat_entry_meta1 meta1;
634         struct exfat_entry_meta2 meta2;
635         const size_t name_length = utf16_length(name);
636         const int name_entries = DIV_ROUND_UP(name_length, EXFAT_ENAME_MAX);
637         int i;
638
639         node = allocate_node();
640         if (node == NULL)
641                 return -ENOMEM;
642         node->entry_cluster = cluster;
643         node->entry_offset = offset;
644         memcpy(node->name, name, name_length * sizeof(le16_t));
645
646         memset(&meta1, 0, sizeof(meta1));
647         meta1.type = EXFAT_ENTRY_FILE;
648         meta1.continuations = 1 + name_entries;
649         meta1.attrib = cpu_to_le16(attrib);
650         exfat_unix2exfat(time(NULL), &meta1.crdate, &meta1.crtime);
651         meta1.adate = meta1.mdate = meta1.crdate;
652         meta1.atime = meta1.mtime = meta1.crtime;
653         /* crtime_cs and mtime_cs contain addition to the time in centiseconds;
654            just ignore those fields because we operate with 2 sec resolution */
655
656         memset(&meta2, 0, sizeof(meta2));
657         meta2.type = EXFAT_ENTRY_FILE_INFO;
658         meta2.flag = EXFAT_FLAG_FRAGMENTED;
659         meta2.name_length = name_length;
660         meta2.name_hash = exfat_calc_name_hash(ef, node->name);
661         meta2.start_cluster = cpu_to_le32(EXFAT_CLUSTER_FREE);
662
663         meta1.checksum = exfat_calc_checksum(&meta1, &meta2, node->name);
664
665         exfat_write_raw(&meta1, sizeof(meta1), exfat_c2o(ef, cluster) + offset,
666                         ef->fd);
667         next_entry(ef, dir, &cluster, &offset);
668         exfat_write_raw(&meta2, sizeof(meta2), exfat_c2o(ef, cluster) + offset,
669                         ef->fd);
670         for (i = 0; i < name_entries; i++)
671         {
672                 struct exfat_entry_name name_entry = {EXFAT_ENTRY_FILE_NAME, 0};
673                 memcpy(name_entry.name, node->name + i * EXFAT_ENAME_MAX,
674                                 EXFAT_ENAME_MAX * sizeof(le16_t));
675                 next_entry(ef, dir, &cluster, &offset);
676                 exfat_write_raw(&name_entry, sizeof(name_entry),
677                                 exfat_c2o(ef, cluster) + offset, ef->fd);
678         }
679
680         init_node_meta1(node, &meta1);
681         init_node_meta2(node, &meta2);
682
683         tree_attach(dir, node);
684         exfat_update_mtime(dir);
685         return 0;
686 }
687
688 static int create(struct exfat* ef, const char* path, uint16_t attrib)
689 {
690         struct exfat_node* dir;
691         struct exfat_node* existing;
692         cluster_t cluster = EXFAT_CLUSTER_BAD;
693         off_t offset = -1;
694         le16_t name[EXFAT_NAME_MAX + 1];
695         int rc;
696
697         rc = exfat_split(ef, &dir, &existing, name, path);
698         if (rc != 0)
699                 return rc;
700         if (existing != NULL)
701         {
702                 exfat_put_node(ef, existing);
703                 exfat_put_node(ef, dir);
704                 return -EEXIST;
705         }
706
707         rc = find_slot(ef, dir, &cluster, &offset,
708                         2 + DIV_ROUND_UP(utf16_length(name), EXFAT_ENAME_MAX));
709         if (rc != 0)
710         {
711                 exfat_put_node(ef, dir);
712                 return rc;
713         }
714         rc = write_entry(ef, dir, name, cluster, offset, attrib);
715         exfat_put_node(ef, dir);
716         return rc;
717 }
718
719 int exfat_mknod(struct exfat* ef, const char* path)
720 {
721         return create(ef, path, EXFAT_ATTRIB_ARCH);
722 }
723
724 int exfat_mkdir(struct exfat* ef, const char* path)
725 {
726         int rc;
727         struct exfat_node* node;
728
729         rc = create(ef, path, EXFAT_ATTRIB_ARCH | EXFAT_ATTRIB_DIR);
730         if (rc != 0)
731                 return rc;
732         rc = exfat_lookup(ef, &node, path);
733         if (rc != 0)
734                 return 0;
735         /* directories always have at least one cluster */
736         rc = exfat_truncate(ef, node, CLUSTER_SIZE(*ef->sb));
737         if (rc != 0)
738         {
739                 delete(ef, node);
740                 exfat_put_node(ef, node);
741                 return rc;
742         }
743         exfat_put_node(ef, node);
744         return 0;
745 }
746
747 static void rename_entry(struct exfat* ef, struct exfat_node* dir,
748                 struct exfat_node* node, const le16_t* name, cluster_t new_cluster,
749                 off_t new_offset)
750 {
751         struct exfat_entry_meta1 meta1;
752         struct exfat_entry_meta2 meta2;
753         cluster_t old_cluster = node->entry_cluster;
754         off_t old_offset = node->entry_offset;
755         const size_t name_length = utf16_length(name);
756         const int name_entries = DIV_ROUND_UP(name_length, EXFAT_ENAME_MAX);
757         int i;
758
759         exfat_read_raw(&meta1, sizeof(meta1),
760                         exfat_c2o(ef, old_cluster) + old_offset, ef->fd);
761         next_entry(ef, node->parent, &old_cluster, &old_offset);
762         exfat_read_raw(&meta2, sizeof(meta2),
763                         exfat_c2o(ef, old_cluster) + old_offset, ef->fd);
764         meta1.continuations = 1 + name_entries;
765         meta2.name_hash = exfat_calc_name_hash(ef, name);
766         meta2.name_length = name_length;
767         meta1.checksum = exfat_calc_checksum(&meta1, &meta2, name);
768
769         erase_entry(ef, node);
770
771         node->entry_cluster = new_cluster;
772         node->entry_offset = new_offset;
773
774         exfat_write_raw(&meta1, sizeof(meta1),
775             exfat_c2o(ef, new_cluster) + new_offset, ef->fd);
776         next_entry(ef, dir, &new_cluster, &new_offset);
777         exfat_write_raw(&meta2, sizeof(meta2),
778             exfat_c2o(ef, new_cluster) + new_offset, ef->fd);
779
780         for (i = 0; i < name_entries; i++)
781         {
782                 struct exfat_entry_name name_entry = {EXFAT_ENTRY_FILE_NAME, 0};
783                 memcpy(name_entry.name, name + i * EXFAT_ENAME_MAX,
784                                 EXFAT_ENAME_MAX * sizeof(le16_t));
785                 next_entry(ef, dir, &new_cluster, &new_offset);
786                 exfat_write_raw(&name_entry, sizeof(name_entry),
787                                 exfat_c2o(ef, new_cluster) + new_offset, ef->fd);
788         }
789
790         memcpy(node->name, name, (name_length + 1) * sizeof(le16_t));
791         tree_detach(node);
792         tree_attach(dir, node);
793 }
794
795 int exfat_rename(struct exfat* ef, const char* old_path, const char* new_path)
796 {
797         struct exfat_node* node;
798         struct exfat_node* existing;
799         struct exfat_node* dir;
800         cluster_t cluster = EXFAT_CLUSTER_BAD;
801         off_t offset = -1;
802         le16_t name[EXFAT_NAME_MAX + 1];
803         int rc;
804
805         rc = exfat_lookup(ef, &node, old_path);
806         if (rc != 0)
807                 return rc;
808
809         memset(name, 0, (EXFAT_NAME_MAX + 1) * sizeof(le16_t));
810         rc = exfat_split(ef, &dir, &existing, name, new_path);
811         if (rc != 0)
812         {
813                 exfat_put_node(ef, node);
814                 return rc;
815         }
816         if (existing != NULL)
817         {
818                 if (existing->flags & EXFAT_ATTRIB_DIR)
819                 {
820                         if (node->flags & EXFAT_ATTRIB_DIR)
821                                 rc = exfat_rmdir(ef, existing);
822                         else
823                                 rc = -ENOTDIR;
824                 }
825                 else
826                 {
827                         if (!(node->flags & EXFAT_ATTRIB_DIR))
828                                 rc = exfat_unlink(ef, existing);
829                         else
830                                 rc = -EISDIR;
831                 }
832                 exfat_put_node(ef, existing);
833                 if (rc != 0)
834                 {
835                         exfat_put_node(ef, dir);
836                         exfat_put_node(ef, node);
837                         return rc;
838                 }
839         }
840
841         rc = find_slot(ef, dir, &cluster, &offset,
842                         2 + DIV_ROUND_UP(utf16_length(name), EXFAT_ENAME_MAX));
843         if (rc != 0)
844         {
845                 exfat_put_node(ef, dir);
846                 exfat_put_node(ef, node);
847                 return rc;
848         }
849         rename_entry(ef, dir, node, name, cluster, offset);
850         exfat_put_node(ef, dir);
851         exfat_put_node(ef, node);
852         return 0;
853 }
854
855 void exfat_utimes(struct exfat_node* node, const struct timespec tv[2])
856 {
857         node->atime = tv[0].tv_sec;
858         node->mtime = tv[1].tv_sec;
859         node->flags |= EXFAT_ATTRIB_DIRTY;
860 }
861
862 void exfat_update_atime(struct exfat_node* node)
863 {
864         node->atime = time(NULL);
865         node->flags |= EXFAT_ATTRIB_DIRTY;
866 }
867
868 void exfat_update_mtime(struct exfat_node* node)
869 {
870         node->mtime = time(NULL);
871         node->flags |= EXFAT_ATTRIB_DIRTY;
872 }