blob: 0edab46dd13e255fc56af418310d8dd072fda8e2 [file] [log] [blame]
relan77f4a932009-10-22 18:38:01 +00001/*
relana43ba0c2010-01-10 19:53:49 +00002 node.c (09.10.09)
3 exFAT file system implementation library.
4
relan48573ff2013-07-08 07:30:45 +00005 Free exFAT implementation.
reland2a4dd42016-06-03 08:20:53 +03006 Copyright (C) 2010-2016 Andrew Nayenko
relana43ba0c2010-01-10 19:53:49 +00007
relan48573ff2013-07-08 07:30:45 +00008 This program is free software; you can redistribute it and/or modify
relana43ba0c2010-01-10 19:53:49 +00009 it under the terms of the GNU General Public License as published by
relan48573ff2013-07-08 07:30:45 +000010 the Free Software Foundation, either version 2 of the License, or
relana43ba0c2010-01-10 19:53:49 +000011 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
relan48573ff2013-07-08 07:30:45 +000018 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
relana43ba0c2010-01-10 19:53:49 +000021*/
relan77f4a932009-10-22 18:38:01 +000022
23#include "exfat.h"
Steve Kondik4a8592e2016-01-21 14:46:00 -080024#include "utf.h"
relan77f4a932009-10-22 18:38:01 +000025#include <errno.h>
26#include <string.h>
27#include <inttypes.h>
28
29/* on-disk nodes iterator */
30struct iterator
31{
32 cluster_t cluster;
33 off_t offset;
34 int contiguous;
35 char* chunk;
36};
37
38struct exfat_node* exfat_get_node(struct exfat_node* node)
39{
40 /* if we switch to multi-threaded mode we will need atomic
41 increment here and atomic decrement in exfat_put_node() */
42 node->references++;
43 return node;
44}
45
relan4cde6f72009-11-14 18:56:40 +000046void exfat_put_node(struct exfat* ef, struct exfat_node* node)
relan77f4a932009-10-22 18:38:01 +000047{
relancb1f91e2014-04-08 04:21:21 +000048 char buffer[UTF8_BYTES(EXFAT_NAME_MAX) + 1];
49
50 --node->references;
51 if (node->references < 0)
relan77f4a932009-10-22 18:38:01 +000052 {
relan2a2e7d42013-05-20 16:33:27 +000053 exfat_get_name(node, buffer, sizeof(buffer) - 1);
relaneca4ae82014-06-01 19:53:48 +000054 exfat_bug("reference counter of '%s' is below zero", buffer);
relan77f4a932009-10-22 18:38:01 +000055 }
relancb1f91e2014-04-08 04:21:21 +000056 else if (node->references == 0 && node != ef->root)
reland455a832009-11-14 19:53:44 +000057 {
relancb1f91e2014-04-08 04:21:21 +000058 if (node->flags & EXFAT_ATTRIB_DIRTY)
reland97a42c2009-11-28 18:07:02 +000059 {
relancb1f91e2014-04-08 04:21:21 +000060 exfat_get_name(node, buffer, sizeof(buffer) - 1);
relaneca4ae82014-06-01 19:53:48 +000061 exfat_warn("dirty node '%s' with zero references", buffer);
reland97a42c2009-11-28 18:07:02 +000062 }
reland455a832009-11-14 19:53:44 +000063 }
relan77f4a932009-10-22 18:38:01 +000064}
65
relanc5d86462010-08-21 08:07:50 +000066/**
relancb1f91e2014-04-08 04:21:21 +000067 * This function must be called on rmdir and unlink (after the last
68 * exfat_put_node()) to free clusters.
69 */
70int exfat_cleanup_node(struct exfat* ef, struct exfat_node* node)
71{
72 int rc = 0;
73
74 if (node->references != 0)
75 exfat_bug("unable to cleanup a node with %d references",
76 node->references);
77
78 if (node->flags & EXFAT_ATTRIB_UNLINKED)
79 {
80 /* free all clusters and node structure itself */
81 rc = exfat_truncate(ef, node, 0, true);
82 /* free the node even in case of error or its memory will be lost */
83 free(node);
84 }
85 return rc;
86}
87
88/**
relanc5d86462010-08-21 08:07:50 +000089 * Cluster + offset from the beginning of the directory to absolute offset.
90 */
91static off_t co2o(struct exfat* ef, cluster_t cluster, off_t offset)
92{
93 return exfat_c2o(ef, cluster) + offset % CLUSTER_SIZE(*ef->sb);
94}
95
relane9c7ca72009-12-13 10:37:32 +000096static int opendir(struct exfat* ef, const struct exfat_node* dir,
97 struct iterator* it)
relan77f4a932009-10-22 18:38:01 +000098{
99 if (!(dir->flags & EXFAT_ATTRIB_DIR))
relan3c71cf22009-12-20 16:17:57 +0000100 exfat_bug("not a directory");
relan77f4a932009-10-22 18:38:01 +0000101 it->cluster = dir->start_cluster;
102 it->offset = 0;
103 it->contiguous = IS_CONTIGUOUS(*dir);
relane9c7ca72009-12-13 10:37:32 +0000104 it->chunk = malloc(CLUSTER_SIZE(*ef->sb));
105 if (it->chunk == NULL)
106 {
107 exfat_error("out of memory");
108 return -ENOMEM;
109 }
relanfdf590e2013-08-06 18:56:09 +0000110 if (exfat_pread(ef->dev, it->chunk, CLUSTER_SIZE(*ef->sb),
111 exfat_c2o(ef, it->cluster)) < 0)
112 {
113 exfat_error("failed to read directory cluster %#x", it->cluster);
114 return -EIO;
115 }
relane9c7ca72009-12-13 10:37:32 +0000116 return 0;
relan77f4a932009-10-22 18:38:01 +0000117}
118
119static void closedir(struct iterator* it)
120{
121 it->cluster = 0;
122 it->offset = 0;
123 it->contiguous = 0;
124 free(it->chunk);
125 it->chunk = NULL;
126}
127
relan5f362f62014-07-08 12:27:54 +0000128static bool fetch_next_entry(struct exfat* ef, const struct exfat_node* parent,
relan13c16962009-11-17 19:56:37 +0000129 struct iterator* it)
130{
131 /* move iterator to the next entry in the directory */
132 it->offset += sizeof(struct exfat_entry);
133 /* fetch the next cluster if needed */
134 if ((it->offset & (CLUSTER_SIZE(*ef->sb) - 1)) == 0)
135 {
relanc08dfaa2012-01-28 10:23:27 +0000136 /* reached the end of directory; the caller should check this
137 condition too */
relan466a5322011-08-31 16:30:41 +0000138 if (it->offset >= parent->size)
relan5f362f62014-07-08 12:27:54 +0000139 return true;
relan13c16962009-11-17 19:56:37 +0000140 it->cluster = exfat_next_cluster(ef, parent, it->cluster);
141 if (CLUSTER_INVALID(it->cluster))
142 {
relan152b33d2012-11-25 12:03:51 +0000143 exfat_error("invalid cluster 0x%x while reading directory",
144 it->cluster);
relan5f362f62014-07-08 12:27:54 +0000145 return false;
relan13c16962009-11-17 19:56:37 +0000146 }
relanfdf590e2013-08-06 18:56:09 +0000147 if (exfat_pread(ef->dev, it->chunk, CLUSTER_SIZE(*ef->sb),
148 exfat_c2o(ef, it->cluster)) < 0)
149 {
150 exfat_error("failed to read the next directory cluster %#x",
151 it->cluster);
relan5f362f62014-07-08 12:27:54 +0000152 return false;
relanfdf590e2013-08-06 18:56:09 +0000153 }
relan13c16962009-11-17 19:56:37 +0000154 }
relan5f362f62014-07-08 12:27:54 +0000155 return true;
relan13c16962009-11-17 19:56:37 +0000156}
157
relanc61c68d2009-12-13 10:48:54 +0000158static struct exfat_node* allocate_node(void)
159{
160 struct exfat_node* node = malloc(sizeof(struct exfat_node));
161 if (node == NULL)
162 {
163 exfat_error("failed to allocate node");
164 return NULL;
165 }
166 memset(node, 0, sizeof(struct exfat_node));
167 return node;
168}
169
170static void init_node_meta1(struct exfat_node* node,
relan94bc6dc2010-01-14 19:48:42 +0000171 const struct exfat_entry_meta1* meta1)
relanc61c68d2009-12-13 10:48:54 +0000172{
173 node->flags = le16_to_cpu(meta1->attrib);
relane45a2412010-09-05 09:10:18 +0000174 node->mtime = exfat_exfat2unix(meta1->mdate, meta1->mtime,
175 meta1->mtime_cs);
176 /* there is no centiseconds field for atime */
177 node->atime = exfat_exfat2unix(meta1->adate, meta1->atime, 0);
relanc61c68d2009-12-13 10:48:54 +0000178}
179
180static void init_node_meta2(struct exfat_node* node,
relan94bc6dc2010-01-14 19:48:42 +0000181 const struct exfat_entry_meta2* meta2)
relanc61c68d2009-12-13 10:48:54 +0000182{
183 node->size = le64_to_cpu(meta2->size);
184 node->start_cluster = le32_to_cpu(meta2->start_cluster);
185 node->fptr_cluster = node->start_cluster;
relan48c1d232011-05-14 11:36:15 +0000186 if (meta2->flags & EXFAT_FLAG_CONTIGUOUS)
relanc61c68d2009-12-13 10:48:54 +0000187 node->flags |= EXFAT_ATTRIB_CONTIGUOUS;
188}
189
relan82561932011-01-21 21:10:29 +0000190static const struct exfat_entry* get_entry_ptr(const struct exfat* ef,
191 const struct iterator* it)
192{
193 return (const struct exfat_entry*)
194 (it->chunk + it->offset % CLUSTER_SIZE(*ef->sb));
195}
196
reland52759f2013-11-11 17:24:21 +0000197static bool check_node(const struct exfat_node* node, uint16_t actual_checksum,
relan5119f7a2014-07-08 12:05:07 +0000198 uint16_t reference_checksum, uint64_t valid_size)
reland52759f2013-11-11 17:24:21 +0000199{
200 char buffer[UTF8_BYTES(EXFAT_NAME_MAX) + 1];
201
202 /*
203 Validate checksum first. If it's invalid all other fields probably
204 contain just garbage.
205 */
206 if (actual_checksum != reference_checksum)
207 {
208 exfat_get_name(node, buffer, sizeof(buffer) - 1);
relaneca4ae82014-06-01 19:53:48 +0000209 exfat_error("'%s' has invalid checksum (%#hx != %#hx)", buffer,
reland52759f2013-11-11 17:24:21 +0000210 actual_checksum, reference_checksum);
211 return false;
212 }
213
214 /*
relan5119f7a2014-07-08 12:05:07 +0000215 exFAT does not support sparse files but allows files with uninitialized
216 clusters. For such files valid_size means initialized data size and
217 cannot be greater than file size. See SetFileValidData() function
218 description in MSDN.
reland52759f2013-11-11 17:24:21 +0000219 */
relan5119f7a2014-07-08 12:05:07 +0000220 if (valid_size > node->size)
reland52759f2013-11-11 17:24:21 +0000221 {
222 exfat_get_name(node, buffer, sizeof(buffer) - 1);
relan5119f7a2014-07-08 12:05:07 +0000223 exfat_error("'%s' has valid size (%"PRIu64") greater than size "
224 "(%"PRIu64")", buffer, valid_size, node->size);
reland52759f2013-11-11 17:24:21 +0000225 return false;
226 }
227
228 return true;
229}
230
relanaab123c2016-03-25 13:06:25 +0300231static void decompress_upcase(uint16_t* output, const le16_t* source,
232 size_t size)
233{
234 size_t si;
235 size_t oi;
236
237 for (oi = 0; oi < EXFAT_UPCASE_CHARS; oi++)
238 output[oi] = oi;
239
240 for (si = 0, oi = 0; si < size && oi < EXFAT_UPCASE_CHARS; si++)
241 {
242 uint16_t ch = le16_to_cpu(source[si]);
243
244 if (ch == 0xffff && si + 1 < size) /* indicates a run */
245 oi += le16_to_cpu(source[++si]);
246 else
247 output[oi++] = ch;
248 }
249}
250
relan77f4a932009-10-22 18:38:01 +0000251/*
252 * Reads one entry in directory at position pointed by iterator and fills
253 * node structure.
254 */
255static int readdir(struct exfat* ef, const struct exfat_node* parent,
256 struct exfat_node** node, struct iterator* it)
257{
relan956bc762011-08-31 16:35:31 +0000258 int rc = -EIO;
relan77f4a932009-10-22 18:38:01 +0000259 const struct exfat_entry* entry;
relan94bc6dc2010-01-14 19:48:42 +0000260 const struct exfat_entry_meta1* meta1;
261 const struct exfat_entry_meta2* meta2;
262 const struct exfat_entry_name* file_name;
263 const struct exfat_entry_upcase* upcase;
264 const struct exfat_entry_bitmap* bitmap;
265 const struct exfat_entry_label* label;
relan77f4a932009-10-22 18:38:01 +0000266 uint8_t continuations = 0;
267 le16_t* namep = NULL;
relan1f830fb2009-10-31 08:44:47 +0000268 uint16_t reference_checksum = 0;
269 uint16_t actual_checksum = 0;
relan5119f7a2014-07-08 12:05:07 +0000270 uint64_t valid_size = 0;
relanaab123c2016-03-25 13:06:25 +0300271 uint64_t upcase_size = 0;
272 le16_t* upcase_comp = NULL;
relan77f4a932009-10-22 18:38:01 +0000273
274 *node = NULL;
275
relan77f4a932009-10-22 18:38:01 +0000276 for (;;)
277 {
relanc08dfaa2012-01-28 10:23:27 +0000278 if (it->offset >= parent->size)
relan77f4a932009-10-22 18:38:01 +0000279 {
relan77f4a932009-10-22 18:38:01 +0000280 if (continuations != 0)
281 {
relanc08dfaa2012-01-28 10:23:27 +0000282 exfat_error("expected %hhu continuations", continuations);
relan77f4a932009-10-22 18:38:01 +0000283 goto error;
284 }
285 return -ENOENT; /* that's OK, means end of directory */
relanc08dfaa2012-01-28 10:23:27 +0000286 }
relan77f4a932009-10-22 18:38:01 +0000287
relanc08dfaa2012-01-28 10:23:27 +0000288 entry = get_entry_ptr(ef, it);
289 switch (entry->type)
290 {
relan77f4a932009-10-22 18:38:01 +0000291 case EXFAT_ENTRY_FILE:
292 if (continuations != 0)
293 {
294 exfat_error("expected %hhu continuations before new entry",
295 continuations);
296 goto error;
297 }
relan94bc6dc2010-01-14 19:48:42 +0000298 meta1 = (const struct exfat_entry_meta1*) entry;
299 continuations = meta1->continuations;
relan77f4a932009-10-22 18:38:01 +0000300 /* each file entry must have at least 2 continuations:
301 info and name */
302 if (continuations < 2)
303 {
304 exfat_error("too few continuations (%hhu)", continuations);
relan956bc762011-08-31 16:35:31 +0000305 goto error;
relan77f4a932009-10-22 18:38:01 +0000306 }
relanddc1dc32013-08-03 08:42:58 +0000307 if (continuations > 1 +
308 DIV_ROUND_UP(EXFAT_NAME_MAX, EXFAT_ENAME_MAX))
309 {
310 exfat_error("too many continuations (%hhu)", continuations);
311 goto error;
312 }
relan94bc6dc2010-01-14 19:48:42 +0000313 reference_checksum = le16_to_cpu(meta1->checksum);
314 actual_checksum = exfat_start_checksum(meta1);
relanc61c68d2009-12-13 10:48:54 +0000315 *node = allocate_node();
relan77f4a932009-10-22 18:38:01 +0000316 if (*node == NULL)
relan956bc762011-08-31 16:35:31 +0000317 {
318 rc = -ENOMEM;
319 goto error;
320 }
relan77f4a932009-10-22 18:38:01 +0000321 /* new node has zero reference counter */
relana4cec4b2009-11-24 20:22:24 +0000322 (*node)->entry_cluster = it->cluster;
relanc5d86462010-08-21 08:07:50 +0000323 (*node)->entry_offset = it->offset;
relan94bc6dc2010-01-14 19:48:42 +0000324 init_node_meta1(*node, meta1);
relan77f4a932009-10-22 18:38:01 +0000325 namep = (*node)->name;
326 break;
327
328 case EXFAT_ENTRY_FILE_INFO:
329 if (continuations < 2)
330 {
331 exfat_error("unexpected continuation (%hhu)",
332 continuations);
333 goto error;
334 }
relan94bc6dc2010-01-14 19:48:42 +0000335 meta2 = (const struct exfat_entry_meta2*) entry;
relan48c1d232011-05-14 11:36:15 +0000336 if (meta2->flags & ~(EXFAT_FLAG_ALWAYS1 | EXFAT_FLAG_CONTIGUOUS))
337 {
338 exfat_error("unknown flags in meta2 (0x%hhx)", meta2->flags);
339 goto error;
340 }
relan94bc6dc2010-01-14 19:48:42 +0000341 init_node_meta2(*node, meta2);
relan1f830fb2009-10-31 08:44:47 +0000342 actual_checksum = exfat_add_checksum(entry, actual_checksum);
relan5119f7a2014-07-08 12:05:07 +0000343 valid_size = le64_to_cpu(meta2->valid_size);
relan48c1d232011-05-14 11:36:15 +0000344 /* empty files must be marked as non-contiguous */
345 if ((*node)->size == 0 && (meta2->flags & EXFAT_FLAG_CONTIGUOUS))
346 {
347 exfat_error("empty file marked as contiguous (0x%hhx)",
348 meta2->flags);
349 goto error;
350 }
relan33f510a2009-11-09 19:16:32 +0000351 /* directories must be aligned on at cluster boundary */
352 if (((*node)->flags & EXFAT_ATTRIB_DIR) &&
353 (*node)->size % CLUSTER_SIZE(*ef->sb) != 0)
354 {
relan7c5d91d2012-12-08 11:53:58 +0000355 exfat_error("directory has invalid size %"PRIu64" bytes",
356 (*node)->size);
relan33f510a2009-11-09 19:16:32 +0000357 goto error;
358 }
relan77f4a932009-10-22 18:38:01 +0000359 --continuations;
360 break;
361
362 case EXFAT_ENTRY_FILE_NAME:
363 if (continuations == 0)
364 {
365 exfat_error("unexpected continuation");
366 goto error;
367 }
relan94bc6dc2010-01-14 19:48:42 +0000368 file_name = (const struct exfat_entry_name*) entry;
relan1f830fb2009-10-31 08:44:47 +0000369 actual_checksum = exfat_add_checksum(entry, actual_checksum);
370
relanbd57f2a2013-08-03 08:36:54 +0000371 memcpy(namep, file_name->name,
372 MIN(EXFAT_ENAME_MAX,
373 ((*node)->name + EXFAT_NAME_MAX - namep)) *
374 sizeof(le16_t));
relan77f4a932009-10-22 18:38:01 +0000375 namep += EXFAT_ENAME_MAX;
376 if (--continuations == 0)
relan1f830fb2009-10-31 08:44:47 +0000377 {
reland52759f2013-11-11 17:24:21 +0000378 if (!check_node(*node, actual_checksum, reference_checksum,
relan5119f7a2014-07-08 12:05:07 +0000379 valid_size))
relanae4a80a2012-12-08 12:32:33 +0000380 goto error;
relan5f362f62014-07-08 12:27:54 +0000381 if (!fetch_next_entry(ef, parent, it))
relan13c16962009-11-17 19:56:37 +0000382 goto error;
relan77f4a932009-10-22 18:38:01 +0000383 return 0; /* entry completed */
relan1f830fb2009-10-31 08:44:47 +0000384 }
relan77f4a932009-10-22 18:38:01 +0000385 break;
386
387 case EXFAT_ENTRY_UPCASE:
388 if (ef->upcase != NULL)
389 break;
relan94bc6dc2010-01-14 19:48:42 +0000390 upcase = (const struct exfat_entry_upcase*) entry;
relan77f4a932009-10-22 18:38:01 +0000391 if (CLUSTER_INVALID(le32_to_cpu(upcase->start_cluster)))
392 {
relan152b33d2012-11-25 12:03:51 +0000393 exfat_error("invalid cluster 0x%x in upcase table",
394 le32_to_cpu(upcase->start_cluster));
relan956bc762011-08-31 16:35:31 +0000395 goto error;
relan77f4a932009-10-22 18:38:01 +0000396 }
relanaab123c2016-03-25 13:06:25 +0300397 upcase_size = le64_to_cpu(upcase->size);
398 if (upcase_size == 0 ||
399 upcase_size > EXFAT_UPCASE_CHARS * sizeof(uint16_t) ||
400 upcase_size % sizeof(uint16_t) != 0)
relan77f4a932009-10-22 18:38:01 +0000401 {
402 exfat_error("bad upcase table size (%"PRIu64" bytes)",
relanaab123c2016-03-25 13:06:25 +0300403 upcase_size);
relan956bc762011-08-31 16:35:31 +0000404 goto error;
relan77f4a932009-10-22 18:38:01 +0000405 }
relanaab123c2016-03-25 13:06:25 +0300406 upcase_comp = malloc(upcase_size);
407 if (upcase_comp == NULL)
relan77f4a932009-10-22 18:38:01 +0000408 {
409 exfat_error("failed to allocate upcase table (%"PRIu64" bytes)",
relanaab123c2016-03-25 13:06:25 +0300410 upcase_size);
relan956bc762011-08-31 16:35:31 +0000411 rc = -ENOMEM;
412 goto error;
relan77f4a932009-10-22 18:38:01 +0000413 }
relan77f4a932009-10-22 18:38:01 +0000414
relanaab123c2016-03-25 13:06:25 +0300415 /* read compressed upcase table */
416 if (exfat_pread(ef->dev, upcase_comp, upcase_size,
relanfdf590e2013-08-06 18:56:09 +0000417 exfat_c2o(ef, le32_to_cpu(upcase->start_cluster))) < 0)
418 {
relanaab123c2016-03-25 13:06:25 +0300419 free(upcase_comp);
relanfdf590e2013-08-06 18:56:09 +0000420 exfat_error("failed to read upper case table "
421 "(%"PRIu64" bytes starting at cluster %#x)",
relanaab123c2016-03-25 13:06:25 +0300422 upcase_size,
relanfdf590e2013-08-06 18:56:09 +0000423 le32_to_cpu(upcase->start_cluster));
424 goto error;
425 }
relanaab123c2016-03-25 13:06:25 +0300426
427 /* decompress upcase table */
428 ef->upcase = calloc(EXFAT_UPCASE_CHARS, sizeof(uint16_t));
429 if (ef->upcase == NULL)
430 {
431 free(upcase_comp);
432 exfat_error("failed to allocate decompressed upcase table");
433 rc = -ENOMEM;
434 goto error;
435 }
436 decompress_upcase(ef->upcase, upcase_comp,
437 upcase_size / sizeof(uint16_t));
438 free(upcase_comp);
relan77f4a932009-10-22 18:38:01 +0000439 break;
440
441 case EXFAT_ENTRY_BITMAP:
relan94bc6dc2010-01-14 19:48:42 +0000442 bitmap = (const struct exfat_entry_bitmap*) entry;
relan152b33d2012-11-25 12:03:51 +0000443 ef->cmap.start_cluster = le32_to_cpu(bitmap->start_cluster);
444 if (CLUSTER_INVALID(ef->cmap.start_cluster))
relan77f4a932009-10-22 18:38:01 +0000445 {
relan152b33d2012-11-25 12:03:51 +0000446 exfat_error("invalid cluster 0x%x in clusters bitmap",
447 ef->cmap.start_cluster);
relan956bc762011-08-31 16:35:31 +0000448 goto error;
relan77f4a932009-10-22 18:38:01 +0000449 }
relanc84249f2009-11-06 19:36:26 +0000450 ef->cmap.size = le32_to_cpu(ef->sb->cluster_count) -
451 EXFAT_FIRST_DATA_CLUSTER;
relan30336a72013-08-03 13:25:28 +0000452 if (le64_to_cpu(bitmap->size) < DIV_ROUND_UP(ef->cmap.size, 8))
relan77f4a932009-10-22 18:38:01 +0000453 {
relan30daeec2010-07-11 09:22:41 +0000454 exfat_error("invalid clusters bitmap size: %"PRIu64
relan1d7738a2010-06-01 17:11:16 +0000455 " (expected at least %u)",
relan30336a72013-08-03 13:25:28 +0000456 le64_to_cpu(bitmap->size),
457 DIV_ROUND_UP(ef->cmap.size, 8));
relan956bc762011-08-31 16:35:31 +0000458 goto error;
relan77f4a932009-10-22 18:38:01 +0000459 }
relan793e3b52009-10-31 18:20:49 +0000460 /* FIXME bitmap can be rather big, up to 512 MB */
461 ef->cmap.chunk_size = ef->cmap.size;
relan30336a72013-08-03 13:25:28 +0000462 ef->cmap.chunk = malloc(BMAP_SIZE(ef->cmap.chunk_size));
relan793e3b52009-10-31 18:20:49 +0000463 if (ef->cmap.chunk == NULL)
464 {
relan30daeec2010-07-11 09:22:41 +0000465 exfat_error("failed to allocate clusters bitmap chunk "
relan793e3b52009-10-31 18:20:49 +0000466 "(%"PRIu64" bytes)", le64_to_cpu(bitmap->size));
relan956bc762011-08-31 16:35:31 +0000467 rc = -ENOMEM;
468 goto error;
relan793e3b52009-10-31 18:20:49 +0000469 }
470
relanfdf590e2013-08-06 18:56:09 +0000471 if (exfat_pread(ef->dev, ef->cmap.chunk,
relan30336a72013-08-03 13:25:28 +0000472 BMAP_SIZE(ef->cmap.chunk_size),
relanfdf590e2013-08-06 18:56:09 +0000473 exfat_c2o(ef, ef->cmap.start_cluster)) < 0)
474 {
475 exfat_error("failed to read clusters bitmap "
476 "(%"PRIu64" bytes starting at cluster %#x)",
477 le64_to_cpu(bitmap->size), ef->cmap.start_cluster);
478 goto error;
479 }
relan77f4a932009-10-22 18:38:01 +0000480 break;
481
482 case EXFAT_ENTRY_LABEL:
relan94bc6dc2010-01-14 19:48:42 +0000483 label = (const struct exfat_entry_label*) entry;
relan77f4a932009-10-22 18:38:01 +0000484 if (label->length > EXFAT_ENAME_MAX)
485 {
486 exfat_error("too long label (%hhu chars)", label->length);
relan956bc762011-08-31 16:35:31 +0000487 goto error;
relan77f4a932009-10-22 18:38:01 +0000488 }
relanfd702362011-01-21 20:54:34 +0000489 if (utf16_to_utf8(ef->label, label->name,
relanbf738122013-05-20 16:41:35 +0000490 sizeof(ef->label) - 1, EXFAT_ENAME_MAX) != 0)
relan956bc762011-08-31 16:35:31 +0000491 goto error;
relan77f4a932009-10-22 18:38:01 +0000492 break;
493
494 default:
relan8c4c5fa2015-07-11 11:07:53 +0300495 if (!(entry->type & EXFAT_ENTRY_VALID))
496 break; /* deleted entry, ignore it */
497 if (!(entry->type & EXFAT_ENTRY_OPTIONAL))
relan77f4a932009-10-22 18:38:01 +0000498 {
relan8c4c5fa2015-07-11 11:07:53 +0300499 exfat_error("unknown entry type %#hhx", entry->type);
relan77f4a932009-10-22 18:38:01 +0000500 goto error;
501 }
relan8c4c5fa2015-07-11 11:07:53 +0300502 /* optional entry, warn and skip */
503 exfat_warn("unknown entry type %#hhx", entry->type);
504 if (continuations == 0)
505 {
506 exfat_error("unexpected continuation");
507 goto error;
508 }
509 --continuations;
relan77f4a932009-10-22 18:38:01 +0000510 break;
511 }
512
relan5f362f62014-07-08 12:27:54 +0000513 if (!fetch_next_entry(ef, parent, it))
relan13c16962009-11-17 19:56:37 +0000514 goto error;
relan77f4a932009-10-22 18:38:01 +0000515 }
516 /* we never reach here */
517
518error:
519 free(*node);
520 *node = NULL;
relan956bc762011-08-31 16:35:31 +0000521 return rc;
relan77f4a932009-10-22 18:38:01 +0000522}
523
524int exfat_cache_directory(struct exfat* ef, struct exfat_node* dir)
525{
526 struct iterator it;
527 int rc;
528 struct exfat_node* node;
529 struct exfat_node* current = NULL;
530
531 if (dir->flags & EXFAT_ATTRIB_CACHED)
532 return 0; /* already cached */
533
relane9c7ca72009-12-13 10:37:32 +0000534 rc = opendir(ef, dir, &it);
535 if (rc != 0)
536 return rc;
relan77f4a932009-10-22 18:38:01 +0000537 while ((rc = readdir(ef, dir, &node, &it)) == 0)
538 {
relana5959022009-11-28 17:22:40 +0000539 node->parent = dir;
relan77f4a932009-10-22 18:38:01 +0000540 if (current != NULL)
541 {
542 current->next = node;
543 node->prev = current;
544 }
545 else
546 dir->child = node;
547
548 current = node;
549 }
550 closedir(&it);
551
552 if (rc != -ENOENT)
553 {
554 /* rollback */
555 for (current = dir->child; current; current = node)
556 {
557 node = current->next;
558 free(current);
559 }
560 dir->child = NULL;
561 return rc;
562 }
563
564 dir->flags |= EXFAT_ATTRIB_CACHED;
565 return 0;
566}
567
relanf266a3b2013-01-10 17:00:27 +0000568static void tree_attach(struct exfat_node* dir, struct exfat_node* node)
569{
570 node->parent = dir;
571 if (dir->child)
572 {
573 dir->child->prev = node;
574 node->next = dir->child;
575 }
576 dir->child = node;
577}
578
579static void tree_detach(struct exfat_node* node)
580{
581 if (node->prev)
582 node->prev->next = node->next;
583 else /* this is the first node in the list */
584 node->parent->child = node->next;
585 if (node->next)
586 node->next->prev = node->prev;
587 node->parent = NULL;
588 node->prev = NULL;
589 node->next = NULL;
590}
591
relan4cde6f72009-11-14 18:56:40 +0000592static void reset_cache(struct exfat* ef, struct exfat_node* node)
relan77f4a932009-10-22 18:38:01 +0000593{
relancb1f91e2014-04-08 04:21:21 +0000594 char buffer[UTF8_BYTES(EXFAT_NAME_MAX) + 1];
595
relan6a0ff012013-01-10 17:09:43 +0000596 while (node->child)
relan77f4a932009-10-22 18:38:01 +0000597 {
relan6a0ff012013-01-10 17:09:43 +0000598 struct exfat_node* p = node->child;
599 reset_cache(ef, p);
600 tree_detach(p);
601 free(p);
relan77f4a932009-10-22 18:38:01 +0000602 }
relan6a0ff012013-01-10 17:09:43 +0000603 node->flags &= ~EXFAT_ATTRIB_CACHED;
relan77f4a932009-10-22 18:38:01 +0000604 if (node->references != 0)
605 {
relan2a2e7d42013-05-20 16:33:27 +0000606 exfat_get_name(node, buffer, sizeof(buffer) - 1);
relaneca4ae82014-06-01 19:53:48 +0000607 exfat_warn("non-zero reference counter (%d) for '%s'",
relan77f4a932009-10-22 18:38:01 +0000608 node->references, buffer);
609 }
relancb1f91e2014-04-08 04:21:21 +0000610 if (node != ef->root && (node->flags & EXFAT_ATTRIB_DIRTY))
611 {
612 exfat_get_name(node, buffer, sizeof(buffer) - 1);
relaneca4ae82014-06-01 19:53:48 +0000613 exfat_bug("node '%s' is dirty", buffer);
relancb1f91e2014-04-08 04:21:21 +0000614 }
relandfc952f2013-01-09 17:50:14 +0000615 while (node->references)
relan9de5a692009-11-14 19:22:12 +0000616 exfat_put_node(ef, node);
relan77f4a932009-10-22 18:38:01 +0000617}
618
619void exfat_reset_cache(struct exfat* ef)
620{
relan4cde6f72009-11-14 18:56:40 +0000621 reset_cache(ef, ef->root);
relan77f4a932009-10-22 18:38:01 +0000622}
relan793e3b52009-10-31 18:20:49 +0000623
relanbbf2fe82013-10-21 07:11:48 +0000624static bool next_entry(struct exfat* ef, const struct exfat_node* parent,
relan7078c652009-11-28 17:40:45 +0000625 cluster_t* cluster, off_t* offset)
626{
relanc5d86462010-08-21 08:07:50 +0000627 *offset += sizeof(struct exfat_entry);
628 if (*offset % CLUSTER_SIZE(*ef->sb) == 0)
relanbbf2fe82013-10-21 07:11:48 +0000629 {
relan7078c652009-11-28 17:40:45 +0000630 *cluster = exfat_next_cluster(ef, parent, *cluster);
relanbbf2fe82013-10-21 07:11:48 +0000631 if (CLUSTER_INVALID(*cluster))
632 {
633 exfat_error("invalid cluster %#x while getting next entry",
634 *cluster);
635 return false;
636 }
637 }
638 return true;
relan7078c652009-11-28 17:40:45 +0000639}
640
reland9227502013-08-06 20:08:06 +0000641int exfat_flush_node(struct exfat* ef, struct exfat_node* node)
relan793e3b52009-10-31 18:20:49 +0000642{
relan7078c652009-11-28 17:40:45 +0000643 cluster_t cluster;
644 off_t offset;
relana4cec4b2009-11-24 20:22:24 +0000645 off_t meta1_offset, meta2_offset;
relan94bc6dc2010-01-14 19:48:42 +0000646 struct exfat_entry_meta1 meta1;
647 struct exfat_entry_meta2 meta2;
relan793e3b52009-10-31 18:20:49 +0000648
relan1688f272013-07-22 18:04:26 +0000649 if (!(node->flags & EXFAT_ATTRIB_DIRTY))
reland9227502013-08-06 20:08:06 +0000650 return 0; /* no need to flush */
relan1688f272013-07-22 18:04:26 +0000651
relanf9283be2010-01-08 09:06:55 +0000652 if (ef->ro)
653 exfat_bug("unable to flush node to read-only FS");
654
relan7078c652009-11-28 17:40:45 +0000655 if (node->parent == NULL)
reland9227502013-08-06 20:08:06 +0000656 return 0; /* do not flush unlinked node */
reland97a42c2009-11-28 18:07:02 +0000657
relan7078c652009-11-28 17:40:45 +0000658 cluster = node->entry_cluster;
659 offset = node->entry_offset;
relanc5d86462010-08-21 08:07:50 +0000660 meta1_offset = co2o(ef, cluster, offset);
relanbbf2fe82013-10-21 07:11:48 +0000661 if (!next_entry(ef, node->parent, &cluster, &offset))
662 return -EIO;
relanc5d86462010-08-21 08:07:50 +0000663 meta2_offset = co2o(ef, cluster, offset);
relana4cec4b2009-11-24 20:22:24 +0000664
relanfdf590e2013-08-06 18:56:09 +0000665 if (exfat_pread(ef->dev, &meta1, sizeof(meta1), meta1_offset) < 0)
reland9227502013-08-06 20:08:06 +0000666 {
667 exfat_error("failed to read meta1 entry on flush");
668 return -EIO;
669 }
relan793e3b52009-10-31 18:20:49 +0000670 if (meta1.type != EXFAT_ENTRY_FILE)
671 exfat_bug("invalid type of meta1: 0x%hhx", meta1.type);
672 meta1.attrib = cpu_to_le16(node->flags);
relane45a2412010-09-05 09:10:18 +0000673 exfat_unix2exfat(node->mtime, &meta1.mdate, &meta1.mtime, &meta1.mtime_cs);
674 exfat_unix2exfat(node->atime, &meta1.adate, &meta1.atime, NULL);
relan793e3b52009-10-31 18:20:49 +0000675
relanfdf590e2013-08-06 18:56:09 +0000676 if (exfat_pread(ef->dev, &meta2, sizeof(meta2), meta2_offset) < 0)
reland9227502013-08-06 20:08:06 +0000677 {
678 exfat_error("failed to read meta2 entry on flush");
679 return -EIO;
680 }
relan793e3b52009-10-31 18:20:49 +0000681 if (meta2.type != EXFAT_ENTRY_FILE_INFO)
682 exfat_bug("invalid type of meta2: 0x%hhx", meta2.type);
relan5119f7a2014-07-08 12:05:07 +0000683 meta2.size = meta2.valid_size = cpu_to_le64(node->size);
relan793e3b52009-10-31 18:20:49 +0000684 meta2.start_cluster = cpu_to_le32(node->start_cluster);
relan48c1d232011-05-14 11:36:15 +0000685 meta2.flags = EXFAT_FLAG_ALWAYS1;
686 /* empty files must not be marked as contiguous */
relan9f44e252009-12-19 12:52:03 +0000687 if (node->size != 0 && IS_CONTIGUOUS(*node))
relan48c1d232011-05-14 11:36:15 +0000688 meta2.flags |= EXFAT_FLAG_CONTIGUOUS;
relan614bd512009-12-20 10:09:29 +0000689 /* name hash remains unchanged, no need to recalculate it */
relan793e3b52009-10-31 18:20:49 +0000690
relan870974f2009-12-13 10:23:42 +0000691 meta1.checksum = exfat_calc_checksum(&meta1, &meta2, node->name);
relan793e3b52009-10-31 18:20:49 +0000692
relanfdf590e2013-08-06 18:56:09 +0000693 if (exfat_pwrite(ef->dev, &meta1, sizeof(meta1), meta1_offset) < 0)
reland9227502013-08-06 20:08:06 +0000694 {
695 exfat_error("failed to write meta1 entry on flush");
696 return -EIO;
697 }
relanfdf590e2013-08-06 18:56:09 +0000698 if (exfat_pwrite(ef->dev, &meta2, sizeof(meta2), meta2_offset) < 0)
reland9227502013-08-06 20:08:06 +0000699 {
700 exfat_error("failed to write meta2 entry on flush");
701 return -EIO;
702 }
relan9de5a692009-11-14 19:22:12 +0000703
704 node->flags &= ~EXFAT_ATTRIB_DIRTY;
relanc4d1bc12015-11-07 11:10:29 +0300705 return exfat_flush(ef);
relan793e3b52009-10-31 18:20:49 +0000706}
reland97a42c2009-11-28 18:07:02 +0000707
reland1f054d2013-08-06 19:51:50 +0000708static bool erase_entry(struct exfat* ef, struct exfat_node* node)
reland97a42c2009-11-28 18:07:02 +0000709{
710 cluster_t cluster = node->entry_cluster;
711 off_t offset = node->entry_offset;
712 int name_entries = DIV_ROUND_UP(utf16_length(node->name), EXFAT_ENAME_MAX);
713 uint8_t entry_type;
714
715 entry_type = EXFAT_ENTRY_FILE & ~EXFAT_ENTRY_VALID;
relanfdf590e2013-08-06 18:56:09 +0000716 if (exfat_pwrite(ef->dev, &entry_type, 1, co2o(ef, cluster, offset)) < 0)
reland1f054d2013-08-06 19:51:50 +0000717 {
718 exfat_error("failed to erase meta1 entry");
719 return false;
720 }
reland97a42c2009-11-28 18:07:02 +0000721
relanbbf2fe82013-10-21 07:11:48 +0000722 if (!next_entry(ef, node->parent, &cluster, &offset))
723 return false;
reland97a42c2009-11-28 18:07:02 +0000724 entry_type = EXFAT_ENTRY_FILE_INFO & ~EXFAT_ENTRY_VALID;
relanfdf590e2013-08-06 18:56:09 +0000725 if (exfat_pwrite(ef->dev, &entry_type, 1, co2o(ef, cluster, offset)) < 0)
reland1f054d2013-08-06 19:51:50 +0000726 {
727 exfat_error("failed to erase meta2 entry");
728 return false;
729 }
reland97a42c2009-11-28 18:07:02 +0000730
731 while (name_entries--)
732 {
relanbbf2fe82013-10-21 07:11:48 +0000733 if (!next_entry(ef, node->parent, &cluster, &offset))
734 return false;
reland97a42c2009-11-28 18:07:02 +0000735 entry_type = EXFAT_ENTRY_FILE_NAME & ~EXFAT_ENTRY_VALID;
relanfdf590e2013-08-06 18:56:09 +0000736 if (exfat_pwrite(ef->dev, &entry_type, 1,
737 co2o(ef, cluster, offset)) < 0)
reland1f054d2013-08-06 19:51:50 +0000738 {
739 exfat_error("failed to erase name entry");
740 return false;
741 }
reland97a42c2009-11-28 18:07:02 +0000742 }
reland1f054d2013-08-06 19:51:50 +0000743 return true;
reland97a42c2009-11-28 18:07:02 +0000744}
745
relane2127712010-08-21 09:41:10 +0000746static int shrink_directory(struct exfat* ef, struct exfat_node* dir,
747 off_t deleted_offset)
relana683b6c2010-01-08 09:23:42 +0000748{
relane2127712010-08-21 09:41:10 +0000749 const struct exfat_node* node;
750 const struct exfat_node* last_node;
relanc08dfaa2012-01-28 10:23:27 +0000751 uint64_t entries = 0;
relane2127712010-08-21 09:41:10 +0000752 uint64_t new_size;
relane2127712010-08-21 09:41:10 +0000753
754 if (!(dir->flags & EXFAT_ATTRIB_DIR))
755 exfat_bug("attempted to shrink a file");
756 if (!(dir->flags & EXFAT_ATTRIB_CACHED))
757 exfat_bug("attempted to shrink uncached directory");
758
759 for (last_node = node = dir->child; node; node = node->next)
760 {
761 if (deleted_offset < node->entry_offset)
762 {
763 /* there are other entries after the removed one, no way to shrink
764 this directory */
765 return 0;
766 }
767 if (last_node->entry_offset < node->entry_offset)
768 last_node = node;
769 }
770
771 if (last_node)
772 {
773 /* offset of the last entry */
774 entries += last_node->entry_offset / sizeof(struct exfat_entry);
775 /* two subentries with meta info */
776 entries += 2;
777 /* subentries with file name */
778 entries += DIV_ROUND_UP(utf16_length(last_node->name),
779 EXFAT_ENAME_MAX);
780 }
781
782 new_size = DIV_ROUND_UP(entries * sizeof(struct exfat_entry),
783 CLUSTER_SIZE(*ef->sb)) * CLUSTER_SIZE(*ef->sb);
relanc08dfaa2012-01-28 10:23:27 +0000784 if (new_size == 0) /* directory always has at least 1 cluster */
785 new_size = CLUSTER_SIZE(*ef->sb);
relane2127712010-08-21 09:41:10 +0000786 if (new_size == dir->size)
787 return 0;
relan4af0e4c2013-11-10 15:15:19 +0000788 return exfat_truncate(ef, dir, new_size, true);
relane2127712010-08-21 09:41:10 +0000789}
790
791static int delete(struct exfat* ef, struct exfat_node* node)
792{
793 struct exfat_node* parent = node->parent;
794 off_t deleted_offset = node->entry_offset;
795 int rc;
796
797 exfat_get_node(parent);
reland1f054d2013-08-06 19:51:50 +0000798 if (!erase_entry(ef, node))
799 {
800 exfat_put_node(ef, parent);
801 return -EIO;
802 }
relane2127712010-08-21 09:41:10 +0000803 exfat_update_mtime(parent);
relana683b6c2010-01-08 09:23:42 +0000804 tree_detach(node);
relane2127712010-08-21 09:41:10 +0000805 rc = shrink_directory(ef, parent, deleted_offset);
reland97a42c2009-11-28 18:07:02 +0000806 node->flags |= EXFAT_ATTRIB_UNLINKED;
relancb1f91e2014-04-08 04:21:21 +0000807 if (rc != 0)
808 {
809 exfat_flush_node(ef, parent);
810 exfat_put_node(ef, parent);
811 return rc;
812 }
813 rc = exfat_flush_node(ef, parent);
814 exfat_put_node(ef, parent);
relane2127712010-08-21 09:41:10 +0000815 return rc;
reland97a42c2009-11-28 18:07:02 +0000816}
817
818int exfat_unlink(struct exfat* ef, struct exfat_node* node)
819{
820 if (node->flags & EXFAT_ATTRIB_DIR)
821 return -EISDIR;
relane2127712010-08-21 09:41:10 +0000822 return delete(ef, node);
reland97a42c2009-11-28 18:07:02 +0000823}
824
825int exfat_rmdir(struct exfat* ef, struct exfat_node* node)
826{
relancb1f91e2014-04-08 04:21:21 +0000827 int rc;
828
reland97a42c2009-11-28 18:07:02 +0000829 if (!(node->flags & EXFAT_ATTRIB_DIR))
830 return -ENOTDIR;
831 /* check that directory is empty */
relancb1f91e2014-04-08 04:21:21 +0000832 rc = exfat_cache_directory(ef, node);
833 if (rc != 0)
834 return rc;
reland97a42c2009-11-28 18:07:02 +0000835 if (node->child)
836 return -ENOTEMPTY;
relane2127712010-08-21 09:41:10 +0000837 return delete(ef, node);
reland97a42c2009-11-28 18:07:02 +0000838}
relan614bd512009-12-20 10:09:29 +0000839
840static int grow_directory(struct exfat* ef, struct exfat_node* dir,
841 uint64_t asize, uint32_t difference)
842{
843 return exfat_truncate(ef, dir,
844 DIV_ROUND_UP(asize + difference, CLUSTER_SIZE(*ef->sb))
relan36a79d42013-02-26 18:58:36 +0000845 * CLUSTER_SIZE(*ef->sb), true);
relan614bd512009-12-20 10:09:29 +0000846}
847
relan614bd512009-12-20 10:09:29 +0000848static int find_slot(struct exfat* ef, struct exfat_node* dir,
849 cluster_t* cluster, off_t* offset, int subentries)
850{
851 struct iterator it;
852 int rc;
853 const struct exfat_entry* entry;
854 int contiguous = 0;
855
856 rc = opendir(ef, dir, &it);
857 if (rc != 0)
858 return rc;
859 for (;;)
860 {
861 if (contiguous == 0)
862 {
863 *cluster = it.cluster;
relanc5d86462010-08-21 08:07:50 +0000864 *offset = it.offset;
relan614bd512009-12-20 10:09:29 +0000865 }
relan82561932011-01-21 21:10:29 +0000866 entry = get_entry_ptr(ef, &it);
relan614bd512009-12-20 10:09:29 +0000867 if (entry->type & EXFAT_ENTRY_VALID)
868 contiguous = 0;
869 else
870 contiguous++;
871 if (contiguous == subentries)
relan56b6d122011-01-21 20:55:28 +0000872 break; /* suitable slot is found */
relanc08dfaa2012-01-28 10:23:27 +0000873 if (it.offset + sizeof(struct exfat_entry) >= dir->size)
874 {
875 rc = grow_directory(ef, dir, dir->size,
876 (subentries - contiguous) * sizeof(struct exfat_entry));
877 if (rc != 0)
878 {
879 closedir(&it);
880 return rc;
881 }
882 }
relan5f362f62014-07-08 12:27:54 +0000883 if (!fetch_next_entry(ef, dir, &it))
relan614bd512009-12-20 10:09:29 +0000884 {
885 closedir(&it);
886 return -EIO;
887 }
888 }
889 closedir(&it);
890 return 0;
891}
892
893static int write_entry(struct exfat* ef, struct exfat_node* dir,
894 const le16_t* name, cluster_t cluster, off_t offset, uint16_t attrib)
895{
896 struct exfat_node* node;
relan94bc6dc2010-01-14 19:48:42 +0000897 struct exfat_entry_meta1 meta1;
898 struct exfat_entry_meta2 meta2;
relan614bd512009-12-20 10:09:29 +0000899 const size_t name_length = utf16_length(name);
900 const int name_entries = DIV_ROUND_UP(name_length, EXFAT_ENAME_MAX);
901 int i;
902
903 node = allocate_node();
904 if (node == NULL)
905 return -ENOMEM;
906 node->entry_cluster = cluster;
907 node->entry_offset = offset;
908 memcpy(node->name, name, name_length * sizeof(le16_t));
909
910 memset(&meta1, 0, sizeof(meta1));
911 meta1.type = EXFAT_ENTRY_FILE;
912 meta1.continuations = 1 + name_entries;
913 meta1.attrib = cpu_to_le16(attrib);
relane45a2412010-09-05 09:10:18 +0000914 exfat_unix2exfat(time(NULL), &meta1.crdate, &meta1.crtime,
915 &meta1.crtime_cs);
relan614bd512009-12-20 10:09:29 +0000916 meta1.adate = meta1.mdate = meta1.crdate;
917 meta1.atime = meta1.mtime = meta1.crtime;
reland1b19f72012-02-04 08:07:17 +0000918 meta1.mtime_cs = meta1.crtime_cs; /* there is no atime_cs */
relan614bd512009-12-20 10:09:29 +0000919
920 memset(&meta2, 0, sizeof(meta2));
921 meta2.type = EXFAT_ENTRY_FILE_INFO;
relan48c1d232011-05-14 11:36:15 +0000922 meta2.flags = EXFAT_FLAG_ALWAYS1;
relan614bd512009-12-20 10:09:29 +0000923 meta2.name_length = name_length;
924 meta2.name_hash = exfat_calc_name_hash(ef, node->name);
925 meta2.start_cluster = cpu_to_le32(EXFAT_CLUSTER_FREE);
926
927 meta1.checksum = exfat_calc_checksum(&meta1, &meta2, node->name);
928
relanfdf590e2013-08-06 18:56:09 +0000929 if (exfat_pwrite(ef->dev, &meta1, sizeof(meta1),
930 co2o(ef, cluster, offset)) < 0)
931 {
932 exfat_error("failed to write meta1 entry");
933 return -EIO;
934 }
relanbbf2fe82013-10-21 07:11:48 +0000935 if (!next_entry(ef, dir, &cluster, &offset))
936 return -EIO;
relanfdf590e2013-08-06 18:56:09 +0000937 if (exfat_pwrite(ef->dev, &meta2, sizeof(meta2),
938 co2o(ef, cluster, offset)) < 0)
939 {
940 exfat_error("failed to write meta2 entry");
941 return -EIO;
942 }
relan614bd512009-12-20 10:09:29 +0000943 for (i = 0; i < name_entries; i++)
944 {
Steve Kondik49c64de2016-08-28 00:27:19 -0700945 struct exfat_entry_name name_entry = {EXFAT_ENTRY_FILE_NAME, 0, {} };
relan614bd512009-12-20 10:09:29 +0000946 memcpy(name_entry.name, node->name + i * EXFAT_ENAME_MAX,
relanbd57f2a2013-08-03 08:36:54 +0000947 MIN(EXFAT_ENAME_MAX, EXFAT_NAME_MAX - i * EXFAT_ENAME_MAX) *
948 sizeof(le16_t));
relanbbf2fe82013-10-21 07:11:48 +0000949 if (!next_entry(ef, dir, &cluster, &offset))
950 return -EIO;
relanfdf590e2013-08-06 18:56:09 +0000951 if (exfat_pwrite(ef->dev, &name_entry, sizeof(name_entry),
952 co2o(ef, cluster, offset)) < 0)
953 {
954 exfat_error("failed to write name entry");
955 return -EIO;
956 }
relan614bd512009-12-20 10:09:29 +0000957 }
958
959 init_node_meta1(node, &meta1);
960 init_node_meta2(node, &meta2);
961
relana683b6c2010-01-08 09:23:42 +0000962 tree_attach(dir, node);
relan445e7162010-01-08 09:05:22 +0000963 exfat_update_mtime(dir);
relan614bd512009-12-20 10:09:29 +0000964 return 0;
965}
966
967static int create(struct exfat* ef, const char* path, uint16_t attrib)
968{
969 struct exfat_node* dir;
relana4b68c22010-02-07 07:26:10 +0000970 struct exfat_node* existing;
relan614bd512009-12-20 10:09:29 +0000971 cluster_t cluster = EXFAT_CLUSTER_BAD;
972 off_t offset = -1;
973 le16_t name[EXFAT_NAME_MAX + 1];
974 int rc;
975
relana4b68c22010-02-07 07:26:10 +0000976 rc = exfat_split(ef, &dir, &existing, name, path);
relan614bd512009-12-20 10:09:29 +0000977 if (rc != 0)
978 return rc;
relana4b68c22010-02-07 07:26:10 +0000979 if (existing != NULL)
980 {
981 exfat_put_node(ef, existing);
982 exfat_put_node(ef, dir);
983 return -EEXIST;
984 }
relan614bd512009-12-20 10:09:29 +0000985
986 rc = find_slot(ef, dir, &cluster, &offset,
987 2 + DIV_ROUND_UP(utf16_length(name), EXFAT_ENAME_MAX));
988 if (rc != 0)
989 {
990 exfat_put_node(ef, dir);
991 return rc;
992 }
993 rc = write_entry(ef, dir, name, cluster, offset, attrib);
relancb1f91e2014-04-08 04:21:21 +0000994 if (rc != 0)
995 {
996 exfat_put_node(ef, dir);
997 return rc;
998 }
999 rc = exfat_flush_node(ef, dir);
relan614bd512009-12-20 10:09:29 +00001000 exfat_put_node(ef, dir);
1001 return rc;
1002}
1003
1004int exfat_mknod(struct exfat* ef, const char* path)
1005{
1006 return create(ef, path, EXFAT_ATTRIB_ARCH);
1007}
1008
1009int exfat_mkdir(struct exfat* ef, const char* path)
1010{
1011 int rc;
1012 struct exfat_node* node;
1013
relan5d3dd6f2015-09-10 12:24:59 +03001014 rc = create(ef, path, EXFAT_ATTRIB_DIR);
relan614bd512009-12-20 10:09:29 +00001015 if (rc != 0)
1016 return rc;
1017 rc = exfat_lookup(ef, &node, path);
1018 if (rc != 0)
1019 return 0;
1020 /* directories always have at least one cluster */
relan36a79d42013-02-26 18:58:36 +00001021 rc = exfat_truncate(ef, node, CLUSTER_SIZE(*ef->sb), true);
relan614bd512009-12-20 10:09:29 +00001022 if (rc != 0)
1023 {
1024 delete(ef, node);
1025 exfat_put_node(ef, node);
1026 return rc;
1027 }
relancb1f91e2014-04-08 04:21:21 +00001028 rc = exfat_flush_node(ef, node);
1029 if (rc != 0)
1030 {
1031 delete(ef, node);
1032 exfat_put_node(ef, node);
1033 return rc;
1034 }
relan614bd512009-12-20 10:09:29 +00001035 exfat_put_node(ef, node);
1036 return 0;
1037}
relana1bc7092009-12-21 20:20:47 +00001038
relan0c4b5cb2013-08-06 19:27:43 +00001039static int rename_entry(struct exfat* ef, struct exfat_node* dir,
relane630c232010-01-10 08:18:49 +00001040 struct exfat_node* node, const le16_t* name, cluster_t new_cluster,
1041 off_t new_offset)
1042{
relan94bc6dc2010-01-14 19:48:42 +00001043 struct exfat_entry_meta1 meta1;
1044 struct exfat_entry_meta2 meta2;
relane630c232010-01-10 08:18:49 +00001045 cluster_t old_cluster = node->entry_cluster;
1046 off_t old_offset = node->entry_offset;
1047 const size_t name_length = utf16_length(name);
1048 const int name_entries = DIV_ROUND_UP(name_length, EXFAT_ENAME_MAX);
1049 int i;
1050
relanfdf590e2013-08-06 18:56:09 +00001051 if (exfat_pread(ef->dev, &meta1, sizeof(meta1),
1052 co2o(ef, old_cluster, old_offset)) < 0)
relan0c4b5cb2013-08-06 19:27:43 +00001053 {
1054 exfat_error("failed to read meta1 entry on rename");
1055 return -EIO;
1056 }
relanbbf2fe82013-10-21 07:11:48 +00001057 if (!next_entry(ef, node->parent, &old_cluster, &old_offset))
1058 return -EIO;
relanfdf590e2013-08-06 18:56:09 +00001059 if (exfat_pread(ef->dev, &meta2, sizeof(meta2),
1060 co2o(ef, old_cluster, old_offset)) < 0)
relan0c4b5cb2013-08-06 19:27:43 +00001061 {
1062 exfat_error("failed to read meta2 entry on rename");
1063 return -EIO;
1064 }
relane630c232010-01-10 08:18:49 +00001065 meta1.continuations = 1 + name_entries;
1066 meta2.name_hash = exfat_calc_name_hash(ef, name);
1067 meta2.name_length = name_length;
1068 meta1.checksum = exfat_calc_checksum(&meta1, &meta2, name);
1069
reland1f054d2013-08-06 19:51:50 +00001070 if (!erase_entry(ef, node))
1071 return -EIO;
relane630c232010-01-10 08:18:49 +00001072
1073 node->entry_cluster = new_cluster;
1074 node->entry_offset = new_offset;
1075
relanfdf590e2013-08-06 18:56:09 +00001076 if (exfat_pwrite(ef->dev, &meta1, sizeof(meta1),
1077 co2o(ef, new_cluster, new_offset)) < 0)
relan0c4b5cb2013-08-06 19:27:43 +00001078 {
1079 exfat_error("failed to write meta1 entry on rename");
1080 return -EIO;
1081 }
relanbbf2fe82013-10-21 07:11:48 +00001082 if (!next_entry(ef, dir, &new_cluster, &new_offset))
1083 return -EIO;
relanfdf590e2013-08-06 18:56:09 +00001084 if (exfat_pwrite(ef->dev, &meta2, sizeof(meta2),
1085 co2o(ef, new_cluster, new_offset)) < 0)
relan0c4b5cb2013-08-06 19:27:43 +00001086 {
1087 exfat_error("failed to write meta2 entry on rename");
1088 return -EIO;
1089 }
relane630c232010-01-10 08:18:49 +00001090
1091 for (i = 0; i < name_entries; i++)
1092 {
Steve Kondik49c64de2016-08-28 00:27:19 -07001093 struct exfat_entry_name name_entry = {EXFAT_ENTRY_FILE_NAME, 0, {} };
relane630c232010-01-10 08:18:49 +00001094 memcpy(name_entry.name, name + i * EXFAT_ENAME_MAX,
1095 EXFAT_ENAME_MAX * sizeof(le16_t));
relanbbf2fe82013-10-21 07:11:48 +00001096 if (!next_entry(ef, dir, &new_cluster, &new_offset))
1097 return -EIO;
relanfdf590e2013-08-06 18:56:09 +00001098 if (exfat_pwrite(ef->dev, &name_entry, sizeof(name_entry),
1099 co2o(ef, new_cluster, new_offset)) < 0)
relan0c4b5cb2013-08-06 19:27:43 +00001100 {
1101 exfat_error("failed to write name entry on rename");
1102 return -EIO;
1103 }
relane630c232010-01-10 08:18:49 +00001104 }
1105
relan4e509802010-07-06 18:59:39 +00001106 memcpy(node->name, name, (EXFAT_NAME_MAX + 1) * sizeof(le16_t));
relane630c232010-01-10 08:18:49 +00001107 tree_detach(node);
1108 tree_attach(dir, node);
relan0c4b5cb2013-08-06 19:27:43 +00001109 return 0;
relane630c232010-01-10 08:18:49 +00001110}
1111
1112int exfat_rename(struct exfat* ef, const char* old_path, const char* new_path)
1113{
1114 struct exfat_node* node;
relana4b68c22010-02-07 07:26:10 +00001115 struct exfat_node* existing;
relane630c232010-01-10 08:18:49 +00001116 struct exfat_node* dir;
1117 cluster_t cluster = EXFAT_CLUSTER_BAD;
1118 off_t offset = -1;
1119 le16_t name[EXFAT_NAME_MAX + 1];
1120 int rc;
1121
1122 rc = exfat_lookup(ef, &node, old_path);
1123 if (rc != 0)
1124 return rc;
1125
relana4b68c22010-02-07 07:26:10 +00001126 rc = exfat_split(ef, &dir, &existing, name, new_path);
relane630c232010-01-10 08:18:49 +00001127 if (rc != 0)
1128 {
1129 exfat_put_node(ef, node);
1130 return rc;
1131 }
relan3869d4b2013-01-25 19:07:05 +00001132
1133 /* check that target is not a subdirectory of the source */
1134 if (node->flags & EXFAT_ATTRIB_DIR)
1135 {
1136 struct exfat_node* p;
1137
1138 for (p = dir; p; p = p->parent)
1139 if (node == p)
1140 {
1141 if (existing != NULL)
1142 exfat_put_node(ef, existing);
1143 exfat_put_node(ef, dir);
1144 exfat_put_node(ef, node);
1145 return -EINVAL;
1146 }
1147 }
1148
relana4b68c22010-02-07 07:26:10 +00001149 if (existing != NULL)
1150 {
relan09224d82012-12-15 08:51:09 +00001151 /* remove target if it's not the same node as source */
1152 if (existing != node)
relana4b68c22010-02-07 07:26:10 +00001153 {
relan09224d82012-12-15 08:51:09 +00001154 if (existing->flags & EXFAT_ATTRIB_DIR)
1155 {
1156 if (node->flags & EXFAT_ATTRIB_DIR)
1157 rc = exfat_rmdir(ef, existing);
1158 else
1159 rc = -ENOTDIR;
1160 }
relana4b68c22010-02-07 07:26:10 +00001161 else
relan09224d82012-12-15 08:51:09 +00001162 {
1163 if (!(node->flags & EXFAT_ATTRIB_DIR))
1164 rc = exfat_unlink(ef, existing);
1165 else
1166 rc = -EISDIR;
1167 }
1168 exfat_put_node(ef, existing);
1169 if (rc != 0)
1170 {
relan1bacc532015-12-19 11:16:21 +03001171 /* free clusters even if something went wrong; overwise they
1172 will be just lost */
1173 exfat_cleanup_node(ef, existing);
1174 exfat_put_node(ef, dir);
1175 exfat_put_node(ef, node);
1176 return rc;
1177 }
1178 rc = exfat_cleanup_node(ef, existing);
1179 if (rc != 0)
1180 {
relan09224d82012-12-15 08:51:09 +00001181 exfat_put_node(ef, dir);
1182 exfat_put_node(ef, node);
1183 return rc;
1184 }
relana4b68c22010-02-07 07:26:10 +00001185 }
1186 else
relan09224d82012-12-15 08:51:09 +00001187 exfat_put_node(ef, existing);
relana4b68c22010-02-07 07:26:10 +00001188 }
relane630c232010-01-10 08:18:49 +00001189
1190 rc = find_slot(ef, dir, &cluster, &offset,
1191 2 + DIV_ROUND_UP(utf16_length(name), EXFAT_ENAME_MAX));
1192 if (rc != 0)
1193 {
1194 exfat_put_node(ef, dir);
1195 exfat_put_node(ef, node);
1196 return rc;
1197 }
relan0c4b5cb2013-08-06 19:27:43 +00001198 rc = rename_entry(ef, dir, node, name, cluster, offset);
relane630c232010-01-10 08:18:49 +00001199 exfat_put_node(ef, dir);
1200 exfat_put_node(ef, node);
relan2fbb5dc2014-01-18 07:36:44 +00001201 return rc;
relane630c232010-01-10 08:18:49 +00001202}
1203
relana1bc7092009-12-21 20:20:47 +00001204void exfat_utimes(struct exfat_node* node, const struct timespec tv[2])
1205{
1206 node->atime = tv[0].tv_sec;
1207 node->mtime = tv[1].tv_sec;
1208 node->flags |= EXFAT_ATTRIB_DIRTY;
1209}
reland028f3c2010-01-08 08:56:44 +00001210
1211void exfat_update_atime(struct exfat_node* node)
1212{
1213 node->atime = time(NULL);
1214 node->flags |= EXFAT_ATTRIB_DIRTY;
1215}
relan8c3e8df2010-01-08 09:02:55 +00001216
1217void exfat_update_mtime(struct exfat_node* node)
1218{
1219 node->mtime = time(NULL);
1220 node->flags |= EXFAT_ATTRIB_DIRTY;
1221}
relanfd702362011-01-21 20:54:34 +00001222
1223const char* exfat_get_label(struct exfat* ef)
1224{
1225 return ef->label;
1226}
1227
1228static int find_label(struct exfat* ef, cluster_t* cluster, off_t* offset)
1229{
1230 struct iterator it;
1231 int rc;
relanfd702362011-01-21 20:54:34 +00001232
1233 rc = opendir(ef, ef->root, &it);
1234 if (rc != 0)
1235 return rc;
1236
1237 for (;;)
1238 {
relanc08dfaa2012-01-28 10:23:27 +00001239 if (it.offset >= ef->root->size)
relanfd702362011-01-21 20:54:34 +00001240 {
1241 closedir(&it);
1242 return -ENOENT;
1243 }
relanc08dfaa2012-01-28 10:23:27 +00001244
1245 if (get_entry_ptr(ef, &it)->type == EXFAT_ENTRY_LABEL)
relanfd702362011-01-21 20:54:34 +00001246 {
1247 *cluster = it.cluster;
1248 *offset = it.offset;
1249 closedir(&it);
1250 return 0;
1251 }
1252
relan5f362f62014-07-08 12:27:54 +00001253 if (!fetch_next_entry(ef, ef->root, &it))
relanfd702362011-01-21 20:54:34 +00001254 {
1255 closedir(&it);
1256 return -EIO;
1257 }
1258 }
1259}
1260
1261int exfat_set_label(struct exfat* ef, const char* label)
1262{
1263 le16_t label_utf16[EXFAT_ENAME_MAX + 1];
1264 int rc;
1265 cluster_t cluster;
1266 off_t offset;
1267 struct exfat_entry_label entry;
1268
1269 memset(label_utf16, 0, sizeof(label_utf16));
1270 rc = utf8_to_utf16(label_utf16, label, EXFAT_ENAME_MAX, strlen(label));
1271 if (rc != 0)
1272 return rc;
1273
1274 rc = find_label(ef, &cluster, &offset);
1275 if (rc == -ENOENT)
1276 rc = find_slot(ef, ef->root, &cluster, &offset, 1);
1277 if (rc != 0)
1278 return rc;
1279
1280 entry.type = EXFAT_ENTRY_LABEL;
1281 entry.length = utf16_length(label_utf16);
1282 memcpy(entry.name, label_utf16, sizeof(entry.name));
1283 if (entry.length == 0)
1284 entry.type ^= EXFAT_ENTRY_VALID;
1285
relanfdf590e2013-08-06 18:56:09 +00001286 if (exfat_pwrite(ef->dev, &entry, sizeof(struct exfat_entry_label),
1287 co2o(ef, cluster, offset)) < 0)
1288 {
1289 exfat_error("failed to write label entry");
1290 return -EIO;
1291 }
relanbf738122013-05-20 16:41:35 +00001292 strcpy(ef->label, label);
relanfd702362011-01-21 20:54:34 +00001293 return 0;
1294}