OSDN Git Service

Modify entry offset meaning.
[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 /**
68  * Cluster + offset from the beginning of the directory to absolute offset.
69  */
70 static off_t co2o(struct exfat* ef, cluster_t cluster, off_t offset)
71 {
72         return exfat_c2o(ef, cluster) + offset % CLUSTER_SIZE(*ef->sb);
73 }
74
75 static int opendir(struct exfat* ef, const struct exfat_node* dir,
76                 struct iterator* it)
77 {
78         if (!(dir->flags & EXFAT_ATTRIB_DIR))
79                 exfat_bug("not a directory");
80         it->cluster = dir->start_cluster;
81         it->offset = 0;
82         it->contiguous = IS_CONTIGUOUS(*dir);
83         it->chunk = malloc(CLUSTER_SIZE(*ef->sb));
84         if (it->chunk == NULL)
85         {
86                 exfat_error("out of memory");
87                 return -ENOMEM;
88         }
89         exfat_read_raw(it->chunk, CLUSTER_SIZE(*ef->sb),
90                         exfat_c2o(ef, it->cluster), ef->fd);
91         return 0;
92 }
93
94 static void closedir(struct iterator* it)
95 {
96         it->cluster = 0;
97         it->offset = 0;
98         it->contiguous = 0;
99         free(it->chunk);
100         it->chunk = NULL;
101 }
102
103 static int fetch_next_entry(struct exfat* ef, const struct exfat_node* parent,
104                 struct iterator* it)
105 {
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)
110         {
111                 it->cluster = exfat_next_cluster(ef, parent, it->cluster);
112                 if (CLUSTER_INVALID(it->cluster))
113                 {
114                         exfat_error("invalid cluster while reading directory");
115                         return 1;
116                 }
117                 exfat_read_raw(it->chunk, CLUSTER_SIZE(*ef->sb),
118                                 exfat_c2o(ef, it->cluster), ef->fd);
119         }
120         return 0;
121 }
122
123 static struct exfat_node* allocate_node(void)
124 {
125         struct exfat_node* node = malloc(sizeof(struct exfat_node));
126         if (node == NULL)
127         {
128                 exfat_error("failed to allocate node");
129                 return NULL;
130         }
131         memset(node, 0, sizeof(struct exfat_node));
132         return node;
133 }
134
135 static void init_node_meta1(struct exfat_node* node,
136                 const struct exfat_entry_meta1* meta1)
137 {
138         node->flags = le16_to_cpu(meta1->attrib);
139         node->mtime = exfat_exfat2unix(meta1->mdate, meta1->mtime);
140         node->atime = exfat_exfat2unix(meta1->adate, meta1->atime);
141 }
142
143 static void init_node_meta2(struct exfat_node* node,
144                 const struct exfat_entry_meta2* meta2)
145 {
146         node->size = le64_to_cpu(meta2->size);
147         node->start_cluster = le32_to_cpu(meta2->start_cluster);
148         node->fptr_cluster = node->start_cluster;
149         if (meta2->flag == EXFAT_FLAG_CONTIGUOUS)
150                 node->flags |= EXFAT_ATTRIB_CONTIGUOUS;
151 }
152
153 /*
154  * Reads one entry in directory at position pointed by iterator and fills
155  * node structure.
156  */
157 static int readdir(struct exfat* ef, const struct exfat_node* parent,
158                 struct exfat_node** node, struct iterator* it)
159 {
160         const struct exfat_entry* entry;
161         const struct exfat_entry_meta1* meta1;
162         const struct exfat_entry_meta2* meta2;
163         const struct exfat_entry_name* file_name;
164         const struct exfat_entry_upcase* upcase;
165         const struct exfat_entry_bitmap* bitmap;
166         const struct exfat_entry_label* label;
167         uint8_t continuations = 0;
168         le16_t* namep = NULL;
169         uint16_t reference_checksum = 0;
170         uint16_t actual_checksum = 0;
171
172         *node = NULL;
173
174         for (;;)
175         {
176                 /* every directory (even empty one) occupies at least one cluster and
177                    must contain EOD entry */
178                 entry = (const struct exfat_entry*)
179                                 (it->chunk + it->offset % CLUSTER_SIZE(*ef->sb));
180
181                 switch (entry->type)
182                 {
183                 case EXFAT_ENTRY_EOD:
184                         if (continuations != 0)
185                         {
186                                 exfat_error("expected %hhu continuations before EOD",
187                                                 continuations);
188                                 goto error;
189                         }
190                         return -ENOENT; /* that's OK, means end of directory */
191
192                 case EXFAT_ENTRY_FILE:
193                         if (continuations != 0)
194                         {
195                                 exfat_error("expected %hhu continuations before new entry",
196                                                 continuations);
197                                 goto error;
198                         }
199                         meta1 = (const struct exfat_entry_meta1*) entry;
200                         continuations = meta1->continuations;
201                         /* each file entry must have at least 2 continuations:
202                            info and name */
203                         if (continuations < 2)
204                         {
205                                 exfat_error("too few continuations (%hhu)", continuations);
206                                 return -EIO;
207                         }
208                         reference_checksum = le16_to_cpu(meta1->checksum);
209                         actual_checksum = exfat_start_checksum(meta1);
210                         *node = allocate_node();
211                         if (*node == NULL)
212                                 return -ENOMEM;
213                         /* new node has zero reference counter */
214                         (*node)->entry_cluster = it->cluster;
215                         (*node)->entry_offset = it->offset;
216                         init_node_meta1(*node, meta1);
217                         namep = (*node)->name;
218                         break;
219
220                 case EXFAT_ENTRY_FILE_INFO:
221                         if (continuations < 2)
222                         {
223                                 exfat_error("unexpected continuation (%hhu)",
224                                                 continuations);
225                                 goto error;
226                         }
227                         meta2 = (const struct exfat_entry_meta2*) entry;
228                         init_node_meta2(*node, meta2);
229                         actual_checksum = exfat_add_checksum(entry, actual_checksum);
230                         /* There are two fields that contain file size. Maybe they plan
231                            to add compression support in the future and one of those
232                            fields is visible (uncompressed) size and the other is real
233                            (compressed) size. Anyway, currently it looks like exFAT does
234                            not support compression and both fields must be equal. */
235                         if (le64_to_cpu(meta2->real_size) != (*node)->size)
236                         {
237                                 exfat_error("real size does not equal to size "
238                                                 "(%"PRIu64" != %"PRIu64")",
239                                                 le64_to_cpu(meta2->real_size), (*node)->size);
240                                 goto error;
241                         }
242                         /* directories must be aligned on at cluster boundary */
243                         if (((*node)->flags & EXFAT_ATTRIB_DIR) &&
244                                 (*node)->size % CLUSTER_SIZE(*ef->sb) != 0)
245                         {
246                                 char buffer[EXFAT_NAME_MAX + 1];
247
248                                 exfat_get_name(*node, buffer, EXFAT_NAME_MAX);
249                                 exfat_error("directory `%s' has invalid size %"PRIu64" bytes",
250                                                 buffer, (*node)->size);
251                                 goto error;
252                         }
253                         --continuations;
254                         break;
255
256                 case EXFAT_ENTRY_FILE_NAME:
257                         if (continuations == 0)
258                         {
259                                 exfat_error("unexpected continuation");
260                                 goto error;
261                         }
262                         file_name = (const struct exfat_entry_name*) entry;
263                         actual_checksum = exfat_add_checksum(entry, actual_checksum);
264
265                         memcpy(namep, file_name->name, EXFAT_ENAME_MAX * sizeof(le16_t));
266                         namep += EXFAT_ENAME_MAX;
267                         if (--continuations == 0)
268                         {
269                                 if (actual_checksum != reference_checksum)
270                                 {
271                                         exfat_error("invalid checksum (0x%hx != 0x%hx)",
272                                                         actual_checksum, reference_checksum);
273                                         return -EIO;
274                                 }
275                                 if (fetch_next_entry(ef, parent, it) != 0)
276                                         goto error;
277                                 return 0; /* entry completed */
278                         }
279                         break;
280
281                 case EXFAT_ENTRY_UPCASE:
282                         if (ef->upcase != NULL)
283                                 break;
284                         upcase = (const struct exfat_entry_upcase*) entry;
285                         if (CLUSTER_INVALID(le32_to_cpu(upcase->start_cluster)))
286                         {
287                                 exfat_error("invalid cluster in upcase table");
288                                 return -EIO;
289                         }
290                         if (le64_to_cpu(upcase->size) == 0 ||
291                                 le64_to_cpu(upcase->size) > 0xffff * sizeof(uint16_t) ||
292                                 le64_to_cpu(upcase->size) % sizeof(uint16_t) != 0)
293                         {
294                                 exfat_error("bad upcase table size (%"PRIu64" bytes)",
295                                                 le64_to_cpu(upcase->size));
296                                 return -EIO;
297                         }
298                         ef->upcase = malloc(le64_to_cpu(upcase->size));
299                         if (ef->upcase == NULL)
300                         {
301                                 exfat_error("failed to allocate upcase table (%"PRIu64" bytes)",
302                                                 le64_to_cpu(upcase->size));
303                                 return -ENOMEM;
304                         }
305                         ef->upcase_chars = le64_to_cpu(upcase->size) / sizeof(le16_t);
306
307                         exfat_read_raw(ef->upcase, le64_to_cpu(upcase->size),
308                                         exfat_c2o(ef, le32_to_cpu(upcase->start_cluster)), ef->fd);
309                         break;
310
311                 case EXFAT_ENTRY_BITMAP:
312                         bitmap = (const struct exfat_entry_bitmap*) entry;
313                         if (CLUSTER_INVALID(le32_to_cpu(bitmap->start_cluster)))
314                         {
315                                 exfat_error("invalid cluster in clusters bitmap");
316                                 return -EIO;
317                         }
318                         ef->cmap.size = le32_to_cpu(ef->sb->cluster_count) -
319                                 EXFAT_FIRST_DATA_CLUSTER;
320                         if (le64_to_cpu(bitmap->size) < (ef->cmap.size + 7) / 8)
321                         {
322                                 exfat_error("invalid clusters bitmap size: %"PRIu64
323                                                 " (expected at least %u)",
324                                                 le64_to_cpu(bitmap->size), (ef->cmap.size + 7) / 8);
325                                 return -EIO;
326                         }
327                         ef->cmap.start_cluster = le32_to_cpu(bitmap->start_cluster);
328                         /* FIXME bitmap can be rather big, up to 512 MB */
329                         ef->cmap.chunk_size = ef->cmap.size;
330                         ef->cmap.chunk = malloc(le64_to_cpu(bitmap->size));
331                         if (ef->cmap.chunk == NULL)
332                         {
333                                 exfat_error("failed to allocate clusters bitmap chunk "
334                                                 "(%"PRIu64" bytes)", le64_to_cpu(bitmap->size));
335                                 return -ENOMEM;
336                         }
337
338                         exfat_read_raw(ef->cmap.chunk, le64_to_cpu(bitmap->size),
339                                         exfat_c2o(ef, ef->cmap.start_cluster), ef->fd);
340                         break;
341
342                 case EXFAT_ENTRY_LABEL:
343                         label = (const struct exfat_entry_label*) entry;
344                         if (label->length > EXFAT_ENAME_MAX)
345                         {
346                                 exfat_error("too long label (%hhu chars)", label->length);
347                                 return -EIO;
348                         }
349                         break;
350
351                 default:
352                         if (entry->type & EXFAT_ENTRY_VALID)
353                         {
354                                 exfat_error("unknown entry type 0x%hhu", entry->type);
355                                 goto error;
356                         }
357                         break;
358                 }
359
360                 if (fetch_next_entry(ef, parent, it) != 0)
361                         goto error;
362         }
363         /* we never reach here */
364
365 error:
366         free(*node);
367         *node = NULL;
368         return -EIO;
369 }
370
371 int exfat_cache_directory(struct exfat* ef, struct exfat_node* dir)
372 {
373         struct iterator it;
374         int rc;
375         struct exfat_node* node;
376         struct exfat_node* current = NULL;
377
378         if (dir->flags & EXFAT_ATTRIB_CACHED)
379                 return 0; /* already cached */
380
381         rc = opendir(ef, dir, &it);
382         if (rc != 0)
383                 return rc;
384         while ((rc = readdir(ef, dir, &node, &it)) == 0)
385         {
386                 node->parent = dir;
387                 if (current != NULL)
388                 {
389                         current->next = node;
390                         node->prev = current;
391                 }
392                 else
393                         dir->child = node;
394
395                 current = node;
396         }
397         closedir(&it);
398
399         if (rc != -ENOENT)
400         {
401                 /* rollback */
402                 for (current = dir->child; current; current = node)
403                 {
404                         node = current->next;
405                         free(current);
406                 }
407                 dir->child = NULL;
408                 return rc;
409         }
410
411         dir->flags |= EXFAT_ATTRIB_CACHED;
412         return 0;
413 }
414
415 static void reset_cache(struct exfat* ef, struct exfat_node* node)
416 {
417         struct exfat_node* child;
418         struct exfat_node* next;
419
420         for (child = node->child; child; child = next)
421         {
422                 reset_cache(ef, child);
423                 next = child->next;
424                 free(child);
425         }
426         if (node->references != 0)
427         {
428                 char buffer[EXFAT_NAME_MAX + 1];
429                 exfat_get_name(node, buffer, EXFAT_NAME_MAX);
430                 exfat_warn("non-zero reference counter (%d) for `%s'",
431                                 node->references, buffer);
432         }
433         while (node->references--)
434                 exfat_put_node(ef, node);
435         node->child = NULL;
436         node->flags &= ~EXFAT_ATTRIB_CACHED;
437 }
438
439 void exfat_reset_cache(struct exfat* ef)
440 {
441         reset_cache(ef, ef->root);
442 }
443
444 void next_entry(struct exfat* ef, const struct exfat_node* parent,
445                 cluster_t* cluster, off_t* offset)
446 {
447         *offset += sizeof(struct exfat_entry);
448         if (*offset % CLUSTER_SIZE(*ef->sb) == 0)
449                 /* next cluster cannot be invalid */
450                 *cluster = exfat_next_cluster(ef, parent, *cluster);
451 }
452
453 void exfat_flush_node(struct exfat* ef, struct exfat_node* node)
454 {
455         cluster_t cluster;
456         off_t offset;
457         off_t meta1_offset, meta2_offset;
458         struct exfat_entry_meta1 meta1;
459         struct exfat_entry_meta2 meta2;
460
461         if (ef->ro)
462                 exfat_bug("unable to flush node to read-only FS");
463
464         if (node->parent == NULL)
465                 return; /* do not flush unlinked node */
466
467         cluster = node->entry_cluster;
468         offset = node->entry_offset;
469         meta1_offset = co2o(ef, cluster, offset);
470         next_entry(ef, node->parent, &cluster, &offset);
471         meta2_offset = co2o(ef, cluster, offset);
472
473         exfat_read_raw(&meta1, sizeof(meta1), meta1_offset, ef->fd);
474         if (meta1.type != EXFAT_ENTRY_FILE)
475                 exfat_bug("invalid type of meta1: 0x%hhx", meta1.type);
476         meta1.attrib = cpu_to_le16(node->flags);
477         exfat_unix2exfat(node->mtime, &meta1.mdate, &meta1.mtime);
478         exfat_unix2exfat(node->atime, &meta1.adate, &meta1.atime);
479
480         exfat_read_raw(&meta2, sizeof(meta2), meta2_offset, ef->fd);
481         if (meta2.type != EXFAT_ENTRY_FILE_INFO)
482                 exfat_bug("invalid type of meta2: 0x%hhx", meta2.type);
483         meta2.size = meta2.real_size = cpu_to_le64(node->size);
484         meta2.start_cluster = cpu_to_le32(node->start_cluster);
485         /* empty files must be marked as fragmented */
486         if (node->size != 0 && IS_CONTIGUOUS(*node))
487                 meta2.flag = EXFAT_FLAG_CONTIGUOUS;
488         else
489                 meta2.flag = EXFAT_FLAG_FRAGMENTED;
490         /* name hash remains unchanged, no need to recalculate it */
491
492         meta1.checksum = exfat_calc_checksum(&meta1, &meta2, node->name);
493
494         exfat_write_raw(&meta1, sizeof(meta1), meta1_offset, ef->fd);
495         exfat_write_raw(&meta2, sizeof(meta2), meta2_offset, ef->fd);
496
497         node->flags &= ~EXFAT_ATTRIB_DIRTY;
498 }
499
500 static void erase_entry(struct exfat* ef, struct exfat_node* node)
501 {
502         cluster_t cluster = node->entry_cluster;
503         off_t offset = node->entry_offset;
504         int name_entries = DIV_ROUND_UP(utf16_length(node->name), EXFAT_ENAME_MAX);
505         uint8_t entry_type;
506
507         entry_type = EXFAT_ENTRY_FILE & ~EXFAT_ENTRY_VALID;
508         exfat_write_raw(&entry_type, 1, co2o(ef, cluster, offset), ef->fd);
509
510         next_entry(ef, node->parent, &cluster, &offset);
511         entry_type = EXFAT_ENTRY_FILE_INFO & ~EXFAT_ENTRY_VALID;
512         exfat_write_raw(&entry_type, 1, co2o(ef, cluster, offset), ef->fd);
513
514         while (name_entries--)
515         {
516                 next_entry(ef, node->parent, &cluster, &offset);
517                 entry_type = EXFAT_ENTRY_FILE_NAME & ~EXFAT_ENTRY_VALID;
518                 exfat_write_raw(&entry_type, 1, co2o(ef, cluster, offset), ef->fd);
519         }
520 }
521
522 static void tree_detach(struct exfat_node* node)
523 {
524         if (node->prev)
525                 node->prev->next = node->next;
526         else /* this is the first node in the list */
527                 node->parent->child = node->next;
528         if (node->next)
529                 node->next->prev = node->prev;
530         node->parent = NULL;
531         node->prev = NULL;
532         node->next = NULL;
533 }
534
535 static void tree_attach(struct exfat_node* dir, struct exfat_node* node)
536 {
537         node->parent = dir;
538         if (dir->child)
539         {
540                 dir->child->prev = node;
541                 node->next = dir->child;
542         }
543         dir->child = node;
544 }
545
546 static void delete(struct exfat* ef, struct exfat_node* node)
547 {
548         erase_entry(ef, node);
549         exfat_update_mtime(node->parent);
550         tree_detach(node);
551         /* file clusters will be freed when node reference counter becomes 0 */
552         node->flags |= EXFAT_ATTRIB_UNLINKED;
553 }
554
555 int exfat_unlink(struct exfat* ef, struct exfat_node* node)
556 {
557         if (node->flags & EXFAT_ATTRIB_DIR)
558                 return -EISDIR;
559         delete(ef, node);
560         return 0;
561 }
562
563 int exfat_rmdir(struct exfat* ef, struct exfat_node* node)
564 {
565         if (!(node->flags & EXFAT_ATTRIB_DIR))
566                 return -ENOTDIR;
567         /* check that directory is empty */
568         exfat_cache_directory(ef, node);
569         if (node->child)
570                 return -ENOTEMPTY;
571         delete(ef, node);
572         return 0;
573 }
574
575 static int grow_directory(struct exfat* ef, struct exfat_node* dir,
576                 uint64_t asize, uint32_t difference)
577 {
578         return exfat_truncate(ef, dir,
579                         DIV_ROUND_UP(asize + difference, CLUSTER_SIZE(*ef->sb))
580                                 * CLUSTER_SIZE(*ef->sb));
581 }
582
583 static int find_slot(struct exfat* ef, struct exfat_node* dir,
584                 cluster_t* cluster, off_t* offset, int subentries)
585 {
586         struct iterator it;
587         int rc;
588         const struct exfat_entry* entry;
589         int contiguous = 0;
590
591         rc = opendir(ef, dir, &it);
592         if (rc != 0)
593                 return rc;
594         for (;;)
595         {
596                 if (contiguous == 0)
597                 {
598                         *cluster = it.cluster;
599                         *offset = it.offset;
600                 }
601                 entry = (const struct exfat_entry*)
602                                 (it.chunk + it.offset % CLUSTER_SIZE(*ef->sb));
603                 if (entry->type == EXFAT_ENTRY_EOD)
604                 {
605                         rc = grow_directory(ef, dir,
606                                         it.offset + sizeof(struct exfat_entry), /* actual size */
607                                         (subentries - contiguous) * sizeof(struct exfat_entry));
608                         if (rc != 0)
609                         {
610                                 closedir(&it);
611                                 return rc;
612                         }
613                         break;
614                 }
615                 if (entry->type & EXFAT_ENTRY_VALID)
616                         contiguous = 0;
617                 else
618                         contiguous++;
619                 if (contiguous == subentries)
620                         break;  /* suitable slot it found */
621                 if (fetch_next_entry(ef, dir, &it) != 0)
622                 {
623                         closedir(&it);
624                         return -EIO;
625                 }
626         }
627         closedir(&it);
628         return 0;
629 }
630
631 static int write_entry(struct exfat* ef, struct exfat_node* dir,
632                 const le16_t* name, cluster_t cluster, off_t offset, uint16_t attrib)
633 {
634         struct exfat_node* node;
635         struct exfat_entry_meta1 meta1;
636         struct exfat_entry_meta2 meta2;
637         const size_t name_length = utf16_length(name);
638         const int name_entries = DIV_ROUND_UP(name_length, EXFAT_ENAME_MAX);
639         int i;
640
641         node = allocate_node();
642         if (node == NULL)
643                 return -ENOMEM;
644         node->entry_cluster = cluster;
645         node->entry_offset = offset;
646         memcpy(node->name, name, name_length * sizeof(le16_t));
647
648         memset(&meta1, 0, sizeof(meta1));
649         meta1.type = EXFAT_ENTRY_FILE;
650         meta1.continuations = 1 + name_entries;
651         meta1.attrib = cpu_to_le16(attrib);
652         exfat_unix2exfat(time(NULL), &meta1.crdate, &meta1.crtime);
653         meta1.adate = meta1.mdate = meta1.crdate;
654         meta1.atime = meta1.mtime = meta1.crtime;
655         /* crtime_cs and mtime_cs contain addition to the time in centiseconds;
656            just ignore those fields because we operate with 2 sec resolution */
657
658         memset(&meta2, 0, sizeof(meta2));
659         meta2.type = EXFAT_ENTRY_FILE_INFO;
660         meta2.flag = EXFAT_FLAG_FRAGMENTED;
661         meta2.name_length = name_length;
662         meta2.name_hash = exfat_calc_name_hash(ef, node->name);
663         meta2.start_cluster = cpu_to_le32(EXFAT_CLUSTER_FREE);
664
665         meta1.checksum = exfat_calc_checksum(&meta1, &meta2, node->name);
666
667         exfat_write_raw(&meta1, sizeof(meta1), co2o(ef, cluster, offset), ef->fd);
668         next_entry(ef, dir, &cluster, &offset);
669         exfat_write_raw(&meta2, sizeof(meta2), co2o(ef, cluster, offset), 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                                 co2o(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), co2o(ef, old_cluster, old_offset),
760                         ef->fd);
761         next_entry(ef, node->parent, &old_cluster, &old_offset);
762         exfat_read_raw(&meta2, sizeof(meta2), co2o(ef, old_cluster, old_offset),
763                         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), co2o(ef, new_cluster, new_offset),
775                         ef->fd);
776         next_entry(ef, dir, &new_cluster, &new_offset);
777         exfat_write_raw(&meta2, sizeof(meta2), co2o(ef, new_cluster, new_offset),
778                         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                                 co2o(ef, new_cluster, new_offset), ef->fd);
788         }
789
790         memcpy(node->name, name, (EXFAT_NAME_MAX + 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         rc = exfat_split(ef, &dir, &existing, name, new_path);
810         if (rc != 0)
811         {
812                 exfat_put_node(ef, node);
813                 return rc;
814         }
815         if (existing != NULL)
816         {
817                 if (existing->flags & EXFAT_ATTRIB_DIR)
818                 {
819                         if (node->flags & EXFAT_ATTRIB_DIR)
820                                 rc = exfat_rmdir(ef, existing);
821                         else
822                                 rc = -ENOTDIR;
823                 }
824                 else
825                 {
826                         if (!(node->flags & EXFAT_ATTRIB_DIR))
827                                 rc = exfat_unlink(ef, existing);
828                         else
829                                 rc = -EISDIR;
830                 }
831                 exfat_put_node(ef, existing);
832                 if (rc != 0)
833                 {
834                         exfat_put_node(ef, dir);
835                         exfat_put_node(ef, node);
836                         return rc;
837                 }
838         }
839
840         rc = find_slot(ef, dir, &cluster, &offset,
841                         2 + DIV_ROUND_UP(utf16_length(name), EXFAT_ENAME_MAX));
842         if (rc != 0)
843         {
844                 exfat_put_node(ef, dir);
845                 exfat_put_node(ef, node);
846                 return rc;
847         }
848         rename_entry(ef, dir, node, name, cluster, offset);
849         exfat_put_node(ef, dir);
850         exfat_put_node(ef, node);
851         return 0;
852 }
853
854 void exfat_utimes(struct exfat_node* node, const struct timespec tv[2])
855 {
856         node->atime = tv[0].tv_sec;
857         node->mtime = tv[1].tv_sec;
858         node->flags |= EXFAT_ATTRIB_DIRTY;
859 }
860
861 void exfat_update_atime(struct exfat_node* node)
862 {
863         node->atime = time(NULL);
864         node->flags |= EXFAT_ATTRIB_DIRTY;
865 }
866
867 void exfat_update_mtime(struct exfat_node* node)
868 {
869         node->mtime = time(NULL);
870         node->flags |= EXFAT_ATTRIB_DIRTY;
871 }