OSDN Git Service

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