summaryrefslogtreecommitdiff
path: root/libntfs-3g/attrib.c (plain)
blob: 12ea369edca294e0cc04c8acd4348da65ccc40e1
1/**
2 * attrib.c - Attribute handling code. Originated from the Linux-NTFS project.
3 *
4 * Copyright (c) 2000-2010 Anton Altaparmakov
5 * Copyright (c) 2002-2005 Richard Russon
6 * Copyright (c) 2002-2008 Szabolcs Szakacsits
7 * Copyright (c) 2004-2007 Yura Pakhuchiy
8 * Copyright (c) 2007-2010 Jean-Pierre Andre
9 * Copyright (c) 2010 Erik Larsson
10 *
11 * This program/include file is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as published
13 * by the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program/include file is distributed in the hope that it will be
17 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
18 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program (in the main directory of the NTFS-3G
23 * distribution in the file COPYING); if not, write to the Free Software
24 * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 */
26
27#ifdef HAVE_CONFIG_H
28#include "config.h"
29#endif
30
31#ifdef HAVE_STDIO_H
32#include <stdio.h>
33#endif
34#ifdef HAVE_STRING_H
35#include <string.h>
36#endif
37#ifdef HAVE_STDLIB_H
38#include <stdlib.h>
39#endif
40#ifdef HAVE_ERRNO_H
41#include <errno.h>
42#endif
43#ifdef HAVE_LIMITS_H
44#include <limits.h>
45#endif
46
47#include "param.h"
48#include "compat.h"
49#include "attrib.h"
50#include "attrlist.h"
51#include "device.h"
52#include "mft.h"
53#include "debug.h"
54#include "mst.h"
55#include "volume.h"
56#include "types.h"
57#include "layout.h"
58#include "inode.h"
59#include "runlist.h"
60#include "lcnalloc.h"
61#include "dir.h"
62#include "compress.h"
63#include "bitmap.h"
64#include "logging.h"
65#include "misc.h"
66#include "efs.h"
67
68#define STANDARD_COMPRESSION_UNIT 4
69#define MAX_COMPRESSION_CLUSTER_SIZE 4096
70
71ntfschar AT_UNNAMED[] = { const_cpu_to_le16('\0') };
72ntfschar STREAM_SDS[] = { const_cpu_to_le16('$'),
73 const_cpu_to_le16('S'),
74 const_cpu_to_le16('D'),
75 const_cpu_to_le16('S'),
76 const_cpu_to_le16('\0') };
77
78ntfschar TXF_DATA[] = { const_cpu_to_le16('$'),
79 const_cpu_to_le16('T'),
80 const_cpu_to_le16('X'),
81 const_cpu_to_le16('F'),
82 const_cpu_to_le16('_'),
83 const_cpu_to_le16('D'),
84 const_cpu_to_le16('A'),
85 const_cpu_to_le16('T'),
86 const_cpu_to_le16('A'),
87 const_cpu_to_le16('\0') };
88
89static int NAttrFlag(ntfs_attr *na, FILE_ATTR_FLAGS flag)
90{
91 if (na->type == AT_DATA && na->name == AT_UNNAMED)
92 return (na->ni->flags & flag);
93 return 0;
94}
95
96static void NAttrSetFlag(ntfs_attr *na, FILE_ATTR_FLAGS flag)
97{
98 if (na->type == AT_DATA && na->name == AT_UNNAMED)
99 na->ni->flags |= flag;
100 else
101 ntfs_log_trace("Denied setting flag %d for not unnamed data "
102 "attribute\n", flag);
103}
104
105static void NAttrClearFlag(ntfs_attr *na, FILE_ATTR_FLAGS flag)
106{
107 if (na->type == AT_DATA && na->name == AT_UNNAMED)
108 na->ni->flags &= ~flag;
109}
110
111#define GenNAttrIno(func_name, flag) \
112int NAttr##func_name(ntfs_attr *na) { return NAttrFlag (na, flag); } \
113void NAttrSet##func_name(ntfs_attr *na) { NAttrSetFlag (na, flag); } \
114void NAttrClear##func_name(ntfs_attr *na){ NAttrClearFlag(na, flag); }
115
116GenNAttrIno(Compressed, FILE_ATTR_COMPRESSED)
117GenNAttrIno(Encrypted, FILE_ATTR_ENCRYPTED)
118GenNAttrIno(Sparse, FILE_ATTR_SPARSE_FILE)
119
120/**
121 * ntfs_get_attribute_value_length - Find the length of an attribute
122 * @a:
123 *
124 * Description...
125 *
126 * Returns:
127 */
128s64 ntfs_get_attribute_value_length(const ATTR_RECORD *a)
129{
130 if (!a) {
131 errno = EINVAL;
132 return 0;
133 }
134 errno = 0;
135 if (a->non_resident)
136 return sle64_to_cpu(a->data_size);
137
138 return (s64)le32_to_cpu(a->value_length);
139}
140
141/**
142 * ntfs_get_attribute_value - Get a copy of an attribute
143 * @vol:
144 * @a:
145 * @b:
146 *
147 * Description...
148 *
149 * Returns:
150 */
151s64 ntfs_get_attribute_value(const ntfs_volume *vol,
152 const ATTR_RECORD *a, u8 *b)
153{
154 runlist *rl;
155 s64 total, r;
156 int i;
157
158 /* Sanity checks. */
159 if (!vol || !a || !b) {
160 errno = EINVAL;
161 return 0;
162 }
163 /* Complex attribute? */
164 /*
165 * Ignore the flags in case they are not zero for an attribute list
166 * attribute. Windows does not complain about invalid flags and chkdsk
167 * does not detect or fix them so we need to cope with it, too.
168 */
169 if (a->type != AT_ATTRIBUTE_LIST && a->flags) {
170 ntfs_log_error("Non-zero (%04x) attribute flags. Cannot handle "
171 "this yet.\n", le16_to_cpu(a->flags));
172 errno = EOPNOTSUPP;
173 return 0;
174 }
175 if (!a->non_resident) {
176 /* Attribute is resident. */
177
178 /* Sanity check. */
179 if (le32_to_cpu(a->value_length) + le16_to_cpu(a->value_offset)
180 > le32_to_cpu(a->length)) {
181 return 0;
182 }
183
184 memcpy(b, (const char*)a + le16_to_cpu(a->value_offset),
185 le32_to_cpu(a->value_length));
186 errno = 0;
187 return (s64)le32_to_cpu(a->value_length);
188 }
189
190 /* Attribute is not resident. */
191
192 /* If no data, return 0. */
193 if (!(a->data_size)) {
194 errno = 0;
195 return 0;
196 }
197 /*
198 * FIXME: What about attribute lists?!? (AIA)
199 */
200 /* Decompress the mapping pairs array into a runlist. */
201 rl = ntfs_mapping_pairs_decompress(vol, a, NULL);
202 if (!rl) {
203 errno = EINVAL;
204 return 0;
205 }
206 /*
207 * FIXED: We were overflowing here in a nasty fashion when we
208 * reach the last cluster in the runlist as the buffer will
209 * only be big enough to hold data_size bytes while we are
210 * reading in allocated_size bytes which is usually larger
211 * than data_size, since the actual data is unlikely to have a
212 * size equal to a multiple of the cluster size!
213 * FIXED2: We were also overflowing here in the same fashion
214 * when the data_size was more than one run smaller than the
215 * allocated size which happens with Windows XP sometimes.
216 */
217 /* Now load all clusters in the runlist into b. */
218 for (i = 0, total = 0; rl[i].length; i++) {
219 if (total + (rl[i].length << vol->cluster_size_bits) >=
220 sle64_to_cpu(a->data_size)) {
221 unsigned char *intbuf = NULL;
222 /*
223 * We have reached the last run so we were going to
224 * overflow when executing the ntfs_pread() which is
225 * BAAAAAAAD!
226 * Temporary fix:
227 * Allocate a new buffer with size:
228 * rl[i].length << vol->cluster_size_bits, do the
229 * read into our buffer, then memcpy the correct
230 * amount of data into the caller supplied buffer,
231 * free our buffer, and continue.
232 * We have reached the end of data size so we were
233 * going to overflow in the same fashion.
234 * Temporary fix: same as above.
235 */
236 intbuf = ntfs_malloc(rl[i].length << vol->cluster_size_bits);
237 if (!intbuf) {
238 free(rl);
239 return 0;
240 }
241 /*
242 * FIXME: If compressed file: Only read if lcn != -1.
243 * Otherwise, we are dealing with a sparse run and we
244 * just memset the user buffer to 0 for the length of
245 * the run, which should be 16 (= compression unit
246 * size).
247 * FIXME: Really only when file is compressed, or can
248 * we have sparse runs in uncompressed files as well?
249 * - Yes we can, in sparse files! But not necessarily
250 * size of 16, just run length.
251 */
252 r = ntfs_pread(vol->dev, rl[i].lcn <<
253 vol->cluster_size_bits, rl[i].length <<
254 vol->cluster_size_bits, intbuf);
255 if (r != rl[i].length << vol->cluster_size_bits) {
256#define ESTR "Error reading attribute value"
257 if (r == -1)
258 ntfs_log_perror(ESTR);
259 else if (r < rl[i].length <<
260 vol->cluster_size_bits) {
261 ntfs_log_debug(ESTR ": Ran out of input data.\n");
262 errno = EIO;
263 } else {
264 ntfs_log_debug(ESTR ": unknown error\n");
265 errno = EIO;
266 }
267#undef ESTR
268 free(rl);
269 free(intbuf);
270 return 0;
271 }
272 memcpy(b + total, intbuf, sle64_to_cpu(a->data_size) -
273 total);
274 free(intbuf);
275 total = sle64_to_cpu(a->data_size);
276 break;
277 }
278 /*
279 * FIXME: If compressed file: Only read if lcn != -1.
280 * Otherwise, we are dealing with a sparse run and we just
281 * memset the user buffer to 0 for the length of the run, which
282 * should be 16 (= compression unit size).
283 * FIXME: Really only when file is compressed, or can
284 * we have sparse runs in uncompressed files as well?
285 * - Yes we can, in sparse files! But not necessarily size of
286 * 16, just run length.
287 */
288 r = ntfs_pread(vol->dev, rl[i].lcn << vol->cluster_size_bits,
289 rl[i].length << vol->cluster_size_bits,
290 b + total);
291 if (r != rl[i].length << vol->cluster_size_bits) {
292#define ESTR "Error reading attribute value"
293 if (r == -1)
294 ntfs_log_perror(ESTR);
295 else if (r < rl[i].length << vol->cluster_size_bits) {
296 ntfs_log_debug(ESTR ": Ran out of input data.\n");
297 errno = EIO;
298 } else {
299 ntfs_log_debug(ESTR ": unknown error\n");
300 errno = EIO;
301 }
302#undef ESTR
303 free(rl);
304 return 0;
305 }
306 total += r;
307 }
308 free(rl);
309 return total;
310}
311
312/* Already cleaned up code below, but still look for FIXME:... */
313
314/**
315 * __ntfs_attr_init - primary initialization of an ntfs attribute structure
316 * @na: ntfs attribute to initialize
317 * @ni: ntfs inode with which to initialize the ntfs attribute
318 * @type: attribute type
319 * @name: attribute name in little endian Unicode or NULL
320 * @name_len: length of attribute @name in Unicode characters (if @name given)
321 *
322 * Initialize the ntfs attribute @na with @ni, @type, @name, and @name_len.
323 */
324static void __ntfs_attr_init(ntfs_attr *na, ntfs_inode *ni,
325 const ATTR_TYPES type, ntfschar *name, const u32 name_len)
326{
327 na->rl = NULL;
328 na->ni = ni;
329 na->type = type;
330 na->name = name;
331 if (name)
332 na->name_len = name_len;
333 else
334 na->name_len = 0;
335}
336
337/**
338 * ntfs_attr_init - initialize an ntfs_attr with data sizes and status
339 * @na:
340 * @non_resident:
341 * @compressed:
342 * @encrypted:
343 * @sparse:
344 * @allocated_size:
345 * @data_size:
346 * @initialized_size:
347 * @compressed_size:
348 * @compression_unit:
349 *
350 * Final initialization for an ntfs attribute.
351 */
352void ntfs_attr_init(ntfs_attr *na, const BOOL non_resident,
353 const ATTR_FLAGS data_flags,
354 const BOOL encrypted, const BOOL sparse,
355 const s64 allocated_size, const s64 data_size,
356 const s64 initialized_size, const s64 compressed_size,
357 const u8 compression_unit)
358{
359 if (!NAttrInitialized(na)) {
360 na->data_flags = data_flags;
361 if (non_resident)
362 NAttrSetNonResident(na);
363 if (data_flags & ATTR_COMPRESSION_MASK)
364 NAttrSetCompressed(na);
365 if (encrypted)
366 NAttrSetEncrypted(na);
367 if (sparse)
368 NAttrSetSparse(na);
369 na->allocated_size = allocated_size;
370 na->data_size = data_size;
371 na->initialized_size = initialized_size;
372 if ((data_flags & ATTR_COMPRESSION_MASK) || sparse) {
373 ntfs_volume *vol = na->ni->vol;
374
375 na->compressed_size = compressed_size;
376 na->compression_block_clusters = 1 << compression_unit;
377 na->compression_block_size = 1 << (compression_unit +
378 vol->cluster_size_bits);
379 na->compression_block_size_bits = ffs(
380 na->compression_block_size) - 1;
381 }
382 NAttrSetInitialized(na);
383 }
384}
385
386/**
387 * ntfs_attr_open - open an ntfs attribute for access
388 * @ni: open ntfs inode in which the ntfs attribute resides
389 * @type: attribute type
390 * @name: attribute name in little endian Unicode or AT_UNNAMED or NULL
391 * @name_len: length of attribute @name in Unicode characters (if @name given)
392 *
393 * Allocate a new ntfs attribute structure, initialize it with @ni, @type,
394 * @name, and @name_len, then return it. Return NULL on error with
395 * errno set to the error code.
396 *
397 * If @name is AT_UNNAMED look specifically for an unnamed attribute. If you
398 * do not care whether the attribute is named or not set @name to NULL. In
399 * both those cases @name_len is not used at all.
400 */
401ntfs_attr *ntfs_attr_open(ntfs_inode *ni, const ATTR_TYPES type,
402 ntfschar *name, u32 name_len)
403{
404 ntfs_attr_search_ctx *ctx;
405 ntfs_attr *na = NULL;
406 ntfschar *newname = NULL;
407 ATTR_RECORD *a;
408 BOOL cs;
409
410 ntfs_log_enter("Entering for inode %lld, attr 0x%x.\n",
411 (unsigned long long)ni->mft_no, type);
412
413 if (!ni || !ni->vol || !ni->mrec) {
414 errno = EINVAL;
415 goto out;
416 }
417 na = ntfs_calloc(sizeof(ntfs_attr));
418 if (!na)
419 goto out;
420 if (name && name != AT_UNNAMED && name != NTFS_INDEX_I30) {
421 name = ntfs_ucsndup(name, name_len);
422 if (!name)
423 goto err_out;
424 newname = name;
425 }
426
427 ctx = ntfs_attr_get_search_ctx(ni, NULL);
428 if (!ctx)
429 goto err_out;
430
431 if (ntfs_attr_lookup(type, name, name_len, 0, 0, NULL, 0, ctx))
432 goto put_err_out;
433
434 a = ctx->attr;
435
436 if (!name) {
437 if (a->name_length) {
438 name = ntfs_ucsndup((ntfschar*)((u8*)a + le16_to_cpu(
439 a->name_offset)), a->name_length);
440 if (!name)
441 goto put_err_out;
442 newname = name;
443 name_len = a->name_length;
444 } else {
445 name = AT_UNNAMED;
446 name_len = 0;
447 }
448 }
449
450 __ntfs_attr_init(na, ni, type, name, name_len);
451
452 /*
453 * Wipe the flags in case they are not zero for an attribute list
454 * attribute. Windows does not complain about invalid flags and chkdsk
455 * does not detect or fix them so we need to cope with it, too.
456 */
457 if (type == AT_ATTRIBUTE_LIST)
458 a->flags = 0;
459
460 if ((type == AT_DATA) && !a->initialized_size) {
461 /*
462 * Define/redefine the compression state if stream is
463 * empty, based on the compression mark on parent
464 * directory (for unnamed data streams) or on current
465 * inode (for named data streams). The compression mark
466 * may change any time, the compression state can only
467 * change when stream is wiped out.
468 */
469 a->flags &= ~ATTR_COMPRESSION_MASK;
470 if ((na->ni->flags & FILE_ATTR_COMPRESSED)
471 && (ni->vol->cluster_size <= MAX_COMPRESSION_CLUSTER_SIZE))
472 a->flags |= ATTR_IS_COMPRESSED;
473 }
474
475 cs = a->flags & (ATTR_IS_COMPRESSED | ATTR_IS_SPARSE);
476
477 if (na->type == AT_DATA && na->name == AT_UNNAMED &&
478 ((!(a->flags & ATTR_IS_SPARSE) != !NAttrSparse(na)) ||
479 (!(a->flags & ATTR_IS_ENCRYPTED) != !NAttrEncrypted(na)))) {
480 errno = EIO;
481 ntfs_log_perror("Inode %lld has corrupt attribute flags "
482 "(0x%x <> 0x%x)",(unsigned long long)ni->mft_no,
483 a->flags, na->ni->flags);
484 goto put_err_out;
485 }
486
487 if (a->non_resident) {
488 if ((a->flags & ATTR_COMPRESSION_MASK)
489 && !a->compression_unit) {
490 errno = EIO;
491 ntfs_log_perror("Compressed inode %lld attr 0x%x has "
492 "no compression unit",
493 (unsigned long long)ni->mft_no, type);
494 goto put_err_out;
495 }
496 ntfs_attr_init(na, TRUE, a->flags,
497 a->flags & ATTR_IS_ENCRYPTED,
498 a->flags & ATTR_IS_SPARSE,
499 sle64_to_cpu(a->allocated_size),
500 sle64_to_cpu(a->data_size),
501 sle64_to_cpu(a->initialized_size),
502 cs ? sle64_to_cpu(a->compressed_size) : 0,
503 cs ? a->compression_unit : 0);
504 } else {
505 s64 l = le32_to_cpu(a->value_length);
506 ntfs_attr_init(na, FALSE, a->flags,
507 a->flags & ATTR_IS_ENCRYPTED,
508 a->flags & ATTR_IS_SPARSE, (l + 7) & ~7, l, l,
509 cs ? (l + 7) & ~7 : 0, 0);
510 }
511 ntfs_attr_put_search_ctx(ctx);
512out:
513 ntfs_log_leave("\n");
514 return na;
515
516put_err_out:
517 ntfs_attr_put_search_ctx(ctx);
518err_out:
519 free(newname);
520 free(na);
521 na = NULL;
522 goto out;
523}
524
525/**
526 * ntfs_attr_close - free an ntfs attribute structure
527 * @na: ntfs attribute structure to free
528 *
529 * Release all memory associated with the ntfs attribute @na and then release
530 * @na itself.
531 */
532void ntfs_attr_close(ntfs_attr *na)
533{
534 if (!na)
535 return;
536 if (NAttrNonResident(na) && na->rl)
537 free(na->rl);
538 /* Don't release if using an internal constant. */
539 if (na->name != AT_UNNAMED && na->name != NTFS_INDEX_I30
540 && na->name != STREAM_SDS)
541 free(na->name);
542 free(na);
543}
544
545/**
546 * ntfs_attr_map_runlist - map (a part of) a runlist of an ntfs attribute
547 * @na: ntfs attribute for which to map (part of) a runlist
548 * @vcn: map runlist part containing this vcn
549 *
550 * Map the part of a runlist containing the @vcn of the ntfs attribute @na.
551 *
552 * Return 0 on success and -1 on error with errno set to the error code.
553 */
554int ntfs_attr_map_runlist(ntfs_attr *na, VCN vcn)
555{
556 LCN lcn;
557 ntfs_attr_search_ctx *ctx;
558
559 ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x, vcn 0x%llx.\n",
560 (unsigned long long)na->ni->mft_no, na->type, (long long)vcn);
561
562 lcn = ntfs_rl_vcn_to_lcn(na->rl, vcn);
563 if (lcn >= 0 || lcn == LCN_HOLE || lcn == LCN_ENOENT)
564 return 0;
565
566 ctx = ntfs_attr_get_search_ctx(na->ni, NULL);
567 if (!ctx)
568 return -1;
569
570 /* Find the attribute in the mft record. */
571 if (!ntfs_attr_lookup(na->type, na->name, na->name_len, CASE_SENSITIVE,
572 vcn, NULL, 0, ctx)) {
573 runlist_element *rl;
574
575 /* Decode the runlist. */
576 rl = ntfs_mapping_pairs_decompress(na->ni->vol, ctx->attr,
577 na->rl);
578 if (rl) {
579 na->rl = rl;
580 ntfs_attr_put_search_ctx(ctx);
581 return 0;
582 }
583 }
584
585 ntfs_attr_put_search_ctx(ctx);
586 return -1;
587}
588
589/**
590 * ntfs_attr_map_whole_runlist - map the whole runlist of an ntfs attribute
591 * @na: ntfs attribute for which to map the runlist
592 *
593 * Map the whole runlist of the ntfs attribute @na. For an attribute made up
594 * of only one attribute extent this is the same as calling
595 * ntfs_attr_map_runlist(na, 0) but for an attribute with multiple extents this
596 * will map the runlist fragments from each of the extents thus giving access
597 * to the entirety of the disk allocation of an attribute.
598 *
599 * Return 0 on success and -1 on error with errno set to the error code.
600 */
601int ntfs_attr_map_whole_runlist(ntfs_attr *na)
602{
603 VCN next_vcn, last_vcn, highest_vcn;
604 ntfs_attr_search_ctx *ctx;
605 ntfs_volume *vol = na->ni->vol;
606 ATTR_RECORD *a;
607 int ret = -1;
608
609 ntfs_log_enter("Entering for inode %llu, attr 0x%x.\n",
610 (unsigned long long)na->ni->mft_no, na->type);
611
612 ctx = ntfs_attr_get_search_ctx(na->ni, NULL);
613 if (!ctx)
614 goto out;
615
616 /* Map all attribute extents one by one. */
617 next_vcn = last_vcn = highest_vcn = 0;
618 a = NULL;
619 while (1) {
620 runlist_element *rl;
621
622 int not_mapped = 0;
623 if (ntfs_rl_vcn_to_lcn(na->rl, next_vcn) == LCN_RL_NOT_MAPPED)
624 not_mapped = 1;
625
626 if (ntfs_attr_lookup(na->type, na->name, na->name_len,
627 CASE_SENSITIVE, next_vcn, NULL, 0, ctx))
628 break;
629
630 a = ctx->attr;
631
632 if (not_mapped) {
633 /* Decode the runlist. */
634 rl = ntfs_mapping_pairs_decompress(na->ni->vol,
635 a, na->rl);
636 if (!rl)
637 goto err_out;
638 na->rl = rl;
639 }
640
641 /* Are we in the first extent? */
642 if (!next_vcn) {
643 if (a->lowest_vcn) {
644 errno = EIO;
645 ntfs_log_perror("First extent of inode %llu "
646 "attribute has non-zero lowest_vcn",
647 (unsigned long long)na->ni->mft_no);
648 goto err_out;
649 }
650 /* Get the last vcn in the attribute. */
651 last_vcn = sle64_to_cpu(a->allocated_size) >>
652 vol->cluster_size_bits;
653 }
654
655 /* Get the lowest vcn for the next extent. */
656 highest_vcn = sle64_to_cpu(a->highest_vcn);
657 next_vcn = highest_vcn + 1;
658
659 /* Only one extent or error, which we catch below. */
660 if (next_vcn <= 0) {
661 errno = ENOENT;
662 break;
663 }
664
665 /* Avoid endless loops due to corruption. */
666 if (next_vcn < sle64_to_cpu(a->lowest_vcn)) {
667 errno = EIO;
668 ntfs_log_perror("Inode %llu has corrupt attribute list",
669 (unsigned long long)na->ni->mft_no);
670 goto err_out;
671 }
672 }
673 if (!a) {
674 ntfs_log_perror("Couldn't find attribute for runlist mapping");
675 goto err_out;
676 }
677 if (highest_vcn && highest_vcn != last_vcn - 1) {
678 errno = EIO;
679 ntfs_log_perror("Failed to load full runlist: inode: %llu "
680 "highest_vcn: 0x%llx last_vcn: 0x%llx",
681 (unsigned long long)na->ni->mft_no,
682 (long long)highest_vcn, (long long)last_vcn);
683 goto err_out;
684 }
685 if (errno == ENOENT)
686 ret = 0;
687err_out:
688 ntfs_attr_put_search_ctx(ctx);
689out:
690 ntfs_log_leave("\n");
691 return ret;
692}
693
694/**
695 * ntfs_attr_vcn_to_lcn - convert a vcn into a lcn given an ntfs attribute
696 * @na: ntfs attribute whose runlist to use for conversion
697 * @vcn: vcn to convert
698 *
699 * Convert the virtual cluster number @vcn of an attribute into a logical
700 * cluster number (lcn) of a device using the runlist @na->rl to map vcns to
701 * their corresponding lcns.
702 *
703 * If the @vcn is not mapped yet, attempt to map the attribute extent
704 * containing the @vcn and retry the vcn to lcn conversion.
705 *
706 * Since lcns must be >= 0, we use negative return values with special meaning:
707 *
708 * Return value Meaning / Description
709 * ==========================================
710 * -1 = LCN_HOLE Hole / not allocated on disk.
711 * -3 = LCN_ENOENT There is no such vcn in the attribute.
712 * -4 = LCN_EINVAL Input parameter error.
713 * -5 = LCN_EIO Corrupt fs, disk i/o error, or not enough memory.
714 */
715LCN ntfs_attr_vcn_to_lcn(ntfs_attr *na, const VCN vcn)
716{
717 LCN lcn;
718 BOOL is_retry = FALSE;
719
720 if (!na || !NAttrNonResident(na) || vcn < 0)
721 return (LCN)LCN_EINVAL;
722
723 ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x.\n", (unsigned long
724 long)na->ni->mft_no, na->type);
725retry:
726 /* Convert vcn to lcn. If that fails map the runlist and retry once. */
727 lcn = ntfs_rl_vcn_to_lcn(na->rl, vcn);
728 if (lcn >= 0)
729 return lcn;
730 if (!is_retry && !ntfs_attr_map_runlist(na, vcn)) {
731 is_retry = TRUE;
732 goto retry;
733 }
734 /*
735 * If the attempt to map the runlist failed, or we are getting
736 * LCN_RL_NOT_MAPPED despite having mapped the attribute extent
737 * successfully, something is really badly wrong...
738 */
739 if (!is_retry || lcn == (LCN)LCN_RL_NOT_MAPPED)
740 return (LCN)LCN_EIO;
741 /* lcn contains the appropriate error code. */
742 return lcn;
743}
744
745/**
746 * ntfs_attr_find_vcn - find a vcn in the runlist of an ntfs attribute
747 * @na: ntfs attribute whose runlist to search
748 * @vcn: vcn to find
749 *
750 * Find the virtual cluster number @vcn in the runlist of the ntfs attribute
751 * @na and return the the address of the runlist element containing the @vcn.
752 *
753 * Note you need to distinguish between the lcn of the returned runlist
754 * element being >= 0 and LCN_HOLE. In the later case you have to return zeroes
755 * on read and allocate clusters on write. You need to update the runlist, the
756 * attribute itself as well as write the modified mft record to disk.
757 *
758 * If there is an error return NULL with errno set to the error code. The
759 * following error codes are defined:
760 * EINVAL Input parameter error.
761 * ENOENT There is no such vcn in the runlist.
762 * ENOMEM Not enough memory.
763 * EIO I/O error or corrupt metadata.
764 */
765runlist_element *ntfs_attr_find_vcn(ntfs_attr *na, const VCN vcn)
766{
767 runlist_element *rl;
768 BOOL is_retry = FALSE;
769
770 if (!na || !NAttrNonResident(na) || vcn < 0) {
771 errno = EINVAL;
772 return NULL;
773 }
774
775 ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x, vcn %llx\n",
776 (unsigned long long)na->ni->mft_no, na->type,
777 (long long)vcn);
778retry:
779 rl = na->rl;
780 if (!rl)
781 goto map_rl;
782 if (vcn < rl[0].vcn)
783 goto map_rl;
784 while (rl->length) {
785 if (vcn < rl[1].vcn) {
786 if (rl->lcn >= (LCN)LCN_HOLE)
787 return rl;
788 break;
789 }
790 rl++;
791 }
792 switch (rl->lcn) {
793 case (LCN)LCN_RL_NOT_MAPPED:
794 goto map_rl;
795 case (LCN)LCN_ENOENT:
796 errno = ENOENT;
797 break;
798 case (LCN)LCN_EINVAL:
799 errno = EINVAL;
800 break;
801 default:
802 errno = EIO;
803 break;
804 }
805 return NULL;
806map_rl:
807 /* The @vcn is in an unmapped region, map the runlist and retry. */
808 if (!is_retry && !ntfs_attr_map_runlist(na, vcn)) {
809 is_retry = TRUE;
810 goto retry;
811 }
812 /*
813 * If we already retried or the mapping attempt failed something has
814 * gone badly wrong. EINVAL and ENOENT coming from a failed mapping
815 * attempt are equivalent to errors for us as they should not happen
816 * in our code paths.
817 */
818 if (is_retry || errno == EINVAL || errno == ENOENT)
819 errno = EIO;
820 return NULL;
821}
822
823/**
824 * ntfs_attr_pread_i - see description at ntfs_attr_pread()
825 */
826static s64 ntfs_attr_pread_i(ntfs_attr *na, const s64 pos, s64 count, void *b)
827{
828 s64 br, to_read, ofs, total, total2, max_read, max_init;
829 ntfs_volume *vol;
830 runlist_element *rl;
831 u16 efs_padding_length;
832
833 /* Sanity checking arguments is done in ntfs_attr_pread(). */
834
835 if ((na->data_flags & ATTR_COMPRESSION_MASK) && NAttrNonResident(na)) {
836 if ((na->data_flags & ATTR_COMPRESSION_MASK)
837 == ATTR_IS_COMPRESSED)
838 return ntfs_compressed_attr_pread(na, pos, count, b);
839 else {
840 /* compression mode not supported */
841 errno = EOPNOTSUPP;
842 return -1;
843 }
844 }
845 /*
846 * Encrypted non-resident attributes are not supported. We return
847 * access denied, which is what Windows NT4 does, too.
848 * However, allow if mounted with efs_raw option
849 */
850 vol = na->ni->vol;
851 if (!vol->efs_raw && NAttrEncrypted(na) && NAttrNonResident(na)) {
852 errno = EACCES;
853 return -1;
854 }
855
856 if (!count)
857 return 0;
858 /*
859 * Truncate reads beyond end of attribute,
860 * but round to next 512 byte boundary for encrypted
861 * attributes with efs_raw mount option
862 */
863 max_read = na->data_size;
864 max_init = na->initialized_size;
865 if (na->ni->vol->efs_raw
866 && (na->data_flags & ATTR_IS_ENCRYPTED)
867 && NAttrNonResident(na)) {
868 if (na->data_size != na->initialized_size) {
869 ntfs_log_error("uninitialized encrypted file not supported\n");
870 errno = EINVAL;
871 return -1;
872 }
873 max_init = max_read = ((na->data_size + 511) & ~511) + 2;
874 }
875 if (pos + count > max_read) {
876 if (pos >= max_read)
877 return 0;
878 count = max_read - pos;
879 }
880 /* If it is a resident attribute, get the value from the mft record. */
881 if (!NAttrNonResident(na)) {
882 ntfs_attr_search_ctx *ctx;
883 char *val;
884
885 ctx = ntfs_attr_get_search_ctx(na->ni, NULL);
886 if (!ctx)
887 return -1;
888 if (ntfs_attr_lookup(na->type, na->name, na->name_len, 0,
889 0, NULL, 0, ctx)) {
890res_err_out:
891 ntfs_attr_put_search_ctx(ctx);
892 return -1;
893 }
894 val = (char*)ctx->attr + le16_to_cpu(ctx->attr->value_offset);
895 if (val < (char*)ctx->attr || val +
896 le32_to_cpu(ctx->attr->value_length) >
897 (char*)ctx->mrec + vol->mft_record_size) {
898 errno = EIO;
899 ntfs_log_perror("%s: Sanity check failed", __FUNCTION__);
900 goto res_err_out;
901 }
902 memcpy(b, val + pos, count);
903 ntfs_attr_put_search_ctx(ctx);
904 return count;
905 }
906 total = total2 = 0;
907 /* Zero out reads beyond initialized size. */
908 if (pos + count > max_init) {
909 if (pos >= max_init) {
910 memset(b, 0, count);
911 return count;
912 }
913 total2 = pos + count - max_init;
914 count -= total2;
915 memset((u8*)b + count, 0, total2);
916 }
917 /*
918 * for encrypted non-resident attributes with efs_raw set
919 * the last two bytes aren't read from disk but contain
920 * the number of padding bytes so original size can be
921 * restored
922 */
923 if (na->ni->vol->efs_raw &&
924 (na->data_flags & ATTR_IS_ENCRYPTED) &&
925 ((pos + count) > max_init-2)) {
926 efs_padding_length = 511 - ((na->data_size - 1) & 511);
927 if (pos+count == max_init) {
928 if (count == 1) {
929 *((u8*)b+count-1) = (u8)(efs_padding_length >> 8);
930 count--;
931 total2++;
932 } else {
933 *(u16*)((u8*)b+count-2) = cpu_to_le16(efs_padding_length);
934 count -= 2;
935 total2 +=2;
936 }
937 } else {
938 *((u8*)b+count-1) = (u8)(efs_padding_length & 0xff);
939 count--;
940 total2++;
941 }
942 }
943
944 /* Find the runlist element containing the vcn. */
945 rl = ntfs_attr_find_vcn(na, pos >> vol->cluster_size_bits);
946 if (!rl) {
947 /*
948 * If the vcn is not present it is an out of bounds read.
949 * However, we already truncated the read to the data_size,
950 * so getting this here is an error.
951 */
952 if (errno == ENOENT) {
953 errno = EIO;
954 ntfs_log_perror("%s: Failed to find VCN #1", __FUNCTION__);
955 }
956 return -1;
957 }
958 /*
959 * Gather the requested data into the linear destination buffer. Note,
960 * a partial final vcn is taken care of by the @count capping of read
961 * length.
962 */
963 ofs = pos - (rl->vcn << vol->cluster_size_bits);
964 for (; count; rl++, ofs = 0) {
965 if (rl->lcn == LCN_RL_NOT_MAPPED) {
966 rl = ntfs_attr_find_vcn(na, rl->vcn);
967 if (!rl) {
968 if (errno == ENOENT) {
969 errno = EIO;
970 ntfs_log_perror("%s: Failed to find VCN #2",
971 __FUNCTION__);
972 }
973 goto rl_err_out;
974 }
975 /* Needed for case when runs merged. */
976 ofs = pos + total - (rl->vcn << vol->cluster_size_bits);
977 }
978 if (!rl->length) {
979 errno = EIO;
980 ntfs_log_perror("%s: Zero run length", __FUNCTION__);
981 goto rl_err_out;
982 }
983 if (rl->lcn < (LCN)0) {
984 if (rl->lcn != (LCN)LCN_HOLE) {
985 ntfs_log_perror("%s: Bad run (%lld)",
986 __FUNCTION__,
987 (long long)rl->lcn);
988 goto rl_err_out;
989 }
990 /* It is a hole, just zero the matching @b range. */
991 to_read = min(count, (rl->length <<
992 vol->cluster_size_bits) - ofs);
993 memset(b, 0, to_read);
994 /* Update progress counters. */
995 total += to_read;
996 count -= to_read;
997 b = (u8*)b + to_read;
998 continue;
999 }
1000 /* It is a real lcn, read it into @dst. */
1001 to_read = min(count, (rl->length << vol->cluster_size_bits) -
1002 ofs);
1003retry:
1004 ntfs_log_trace("Reading %lld bytes from vcn %lld, lcn %lld, ofs"
1005 " %lld.\n", (long long)to_read, (long long)rl->vcn,
1006 (long long )rl->lcn, (long long)ofs);
1007 br = ntfs_pread(vol->dev, (rl->lcn << vol->cluster_size_bits) +
1008 ofs, to_read, b);
1009 /* If everything ok, update progress counters and continue. */
1010 if (br > 0) {
1011 total += br;
1012 count -= br;
1013 b = (u8*)b + br;
1014 }
1015 if (br == to_read)
1016 continue;
1017 /* If the syscall was interrupted, try again. */
1018 if (br == (s64)-1 && errno == EINTR)
1019 goto retry;
1020 if (total)
1021 return total;
1022 if (!br)
1023 errno = EIO;
1024 ntfs_log_perror("%s: ntfs_pread failed", __FUNCTION__);
1025 return -1;
1026 }
1027 /* Finally, return the number of bytes read. */
1028 return total + total2;
1029rl_err_out:
1030 if (total)
1031 return total;
1032 errno = EIO;
1033 return -1;
1034}
1035
1036/**
1037 * ntfs_attr_pread - read from an attribute specified by an ntfs_attr structure
1038 * @na: ntfs attribute to read from
1039 * @pos: byte position in the attribute to begin reading from
1040 * @count: number of bytes to read
1041 * @b: output data buffer
1042 *
1043 * This function will read @count bytes starting at offset @pos from the ntfs
1044 * attribute @na into the data buffer @b.
1045 *
1046 * On success, return the number of successfully read bytes. If this number is
1047 * lower than @count this means that the read reached end of file or that an
1048 * error was encountered during the read so that the read is partial. 0 means
1049 * end of file or nothing was read (also return 0 when @count is 0).
1050 *
1051 * On error and nothing has been read, return -1 with errno set appropriately
1052 * to the return code of ntfs_pread(), or to EINVAL in case of invalid
1053 * arguments.
1054 */
1055s64 ntfs_attr_pread(ntfs_attr *na, const s64 pos, s64 count, void *b)
1056{
1057 s64 ret;
1058
1059 if (!na || !na->ni || !na->ni->vol || !b || pos < 0 || count < 0) {
1060 errno = EINVAL;
1061 ntfs_log_perror("%s: na=%p b=%p pos=%lld count=%lld",
1062 __FUNCTION__, na, b, (long long)pos,
1063 (long long)count);
1064 return -1;
1065 }
1066
1067 ntfs_log_enter("Entering for inode %lld attr 0x%x pos %lld count "
1068 "%lld\n", (unsigned long long)na->ni->mft_no,
1069 na->type, (long long)pos, (long long)count);
1070
1071 ret = ntfs_attr_pread_i(na, pos, count, b);
1072
1073 ntfs_log_leave("\n");
1074 return ret;
1075}
1076
1077static int ntfs_attr_fill_zero(ntfs_attr *na, s64 pos, s64 count)
1078{
1079 char *buf;
1080 s64 written, size, end = pos + count;
1081 s64 ofsi;
1082 const runlist_element *rli;
1083 ntfs_volume *vol;
1084 int ret = -1;
1085
1086 ntfs_log_trace("pos %lld, count %lld\n", (long long)pos,
1087 (long long)count);
1088
1089 if (!na || pos < 0 || count < 0) {
1090 errno = EINVAL;
1091 goto err_out;
1092 }
1093
1094 buf = ntfs_calloc(NTFS_BUF_SIZE);
1095 if (!buf)
1096 goto err_out;
1097
1098 rli = na->rl;
1099 ofsi = 0;
1100 vol = na->ni->vol;
1101 while (pos < end) {
1102 while (rli->length && (ofsi + (rli->length <<
1103 vol->cluster_size_bits) <= pos)) {
1104 ofsi += (rli->length << vol->cluster_size_bits);
1105 rli++;
1106 }
1107 size = min(end - pos, NTFS_BUF_SIZE);
1108 written = ntfs_rl_pwrite(vol, rli, ofsi, pos, size, buf);
1109 if (written <= 0) {
1110 ntfs_log_perror("Failed to zero space");
1111 goto err_free;
1112 }
1113 pos += written;
1114 }
1115
1116 ret = 0;
1117err_free:
1118 free(buf);
1119err_out:
1120 return ret;
1121}
1122
1123static int ntfs_attr_fill_hole(ntfs_attr *na, s64 count, s64 *ofs,
1124 runlist_element **rl, VCN *update_from)
1125{
1126 s64 to_write;
1127 s64 need;
1128 ntfs_volume *vol = na->ni->vol;
1129 int eo, ret = -1;
1130 runlist *rlc;
1131 LCN lcn_seek_from = -1;
1132 VCN cur_vcn, from_vcn;
1133
1134 to_write = min(count, ((*rl)->length << vol->cluster_size_bits) - *ofs);
1135
1136 cur_vcn = (*rl)->vcn;
1137 from_vcn = (*rl)->vcn + (*ofs >> vol->cluster_size_bits);
1138
1139 ntfs_log_trace("count: %lld, cur_vcn: %lld, from: %lld, to: %lld, ofs: "
1140 "%lld\n", (long long)count, (long long)cur_vcn,
1141 (long long)from_vcn, (long long)to_write, (long long)*ofs);
1142
1143 /* Map whole runlist to be able update mapping pairs later. */
1144 if (ntfs_attr_map_whole_runlist(na))
1145 goto err_out;
1146
1147 /* Restore @*rl, it probably get lost during runlist mapping. */
1148 *rl = ntfs_attr_find_vcn(na, cur_vcn);
1149 if (!*rl) {
1150 ntfs_log_error("Failed to find run after mapping runlist. "
1151 "Please report to %s.\n", NTFS_DEV_LIST);
1152 errno = EIO;
1153 goto err_out;
1154 }
1155
1156 /* Search backwards to find the best lcn to start seek from. */
1157 rlc = *rl;
1158 while (rlc->vcn) {
1159 rlc--;
1160 if (rlc->lcn >= 0) {
1161 /*
1162 * avoid fragmenting a compressed file
1163 * Windows does not do that, and that may
1164 * not be desirable for files which can
1165 * be updated
1166 */
1167 if (na->data_flags & ATTR_COMPRESSION_MASK)
1168 lcn_seek_from = rlc->lcn + rlc->length;
1169 else
1170 lcn_seek_from = rlc->lcn + (from_vcn - rlc->vcn);
1171 break;
1172 }
1173 }
1174 if (lcn_seek_from == -1) {
1175 /* Backwards search failed, search forwards. */
1176 rlc = *rl;
1177 while (rlc->length) {
1178 rlc++;
1179 if (rlc->lcn >= 0) {
1180 lcn_seek_from = rlc->lcn - (rlc->vcn - from_vcn);
1181 if (lcn_seek_from < -1)
1182 lcn_seek_from = -1;
1183 break;
1184 }
1185 }
1186 }
1187
1188 need = ((*ofs + to_write - 1) >> vol->cluster_size_bits)
1189 + 1 + (*rl)->vcn - from_vcn;
1190 if ((na->data_flags & ATTR_COMPRESSION_MASK)
1191 && (need < na->compression_block_clusters)) {
1192 /*
1193 * for a compressed file, be sure to allocate the full hole.
1194 * We may need space to decompress existing compressed data.
1195 */
1196 rlc = ntfs_cluster_alloc(vol, (*rl)->vcn, (*rl)->length,
1197 lcn_seek_from, DATA_ZONE);
1198 } else
1199 rlc = ntfs_cluster_alloc(vol, from_vcn, need,
1200 lcn_seek_from, DATA_ZONE);
1201 if (!rlc)
1202 goto err_out;
1203
1204 *rl = ntfs_runlists_merge(na->rl, rlc);
1205 /*
1206 * For a compressed attribute, we must be sure there is an
1207 * available entry, so reserve it before it gets too late.
1208 */
1209 if (*rl && (na->data_flags & ATTR_COMPRESSION_MASK))
1210 *rl = ntfs_rl_extend(*rl,1);
1211 if (!*rl) {
1212 eo = errno;
1213 ntfs_log_perror("Failed to merge runlists");
1214 if (ntfs_cluster_free_from_rl(vol, rlc)) {
1215 ntfs_log_perror("Failed to free hot clusters. "
1216 "Please run chkdsk /f");
1217 }
1218 errno = eo;
1219 goto err_out;
1220 }
1221 na->rl = *rl;
1222 if (*update_from == -1)
1223 *update_from = from_vcn;
1224 *rl = ntfs_attr_find_vcn(na, cur_vcn);
1225 if (!*rl) {
1226 /*
1227 * It's definitely a BUG, if we failed to find @cur_vcn, because
1228 * we missed it during instantiating of the hole.
1229 */
1230 ntfs_log_error("Failed to find run after hole instantiation. "
1231 "Please report to %s.\n", NTFS_DEV_LIST);
1232 errno = EIO;
1233 goto err_out;
1234 }
1235 /* If leaved part of the hole go to the next run. */
1236 if ((*rl)->lcn < 0)
1237 (*rl)++;
1238 /* Now LCN shoudn't be less than 0. */
1239 if ((*rl)->lcn < 0) {
1240 ntfs_log_error("BUG! LCN is lesser than 0. "
1241 "Please report to the %s.\n", NTFS_DEV_LIST);
1242 errno = EIO;
1243 goto err_out;
1244 }
1245 if (*ofs) {
1246 /* Clear non-sparse region from @cur_vcn to @*ofs. */
1247 if (ntfs_attr_fill_zero(na, cur_vcn << vol->cluster_size_bits,
1248 *ofs))
1249 goto err_out;
1250 }
1251 if ((*rl)->vcn < cur_vcn) {
1252 /*
1253 * Clusters that replaced hole are merged with
1254 * previous run, so we need to update offset.
1255 */
1256 *ofs += (cur_vcn - (*rl)->vcn) << vol->cluster_size_bits;
1257 }
1258 if ((*rl)->vcn > cur_vcn) {
1259 /*
1260 * We left part of the hole, so we need to update offset
1261 */
1262 *ofs -= ((*rl)->vcn - cur_vcn) << vol->cluster_size_bits;
1263 }
1264
1265 ret = 0;
1266err_out:
1267 return ret;
1268}
1269
1270static int stuff_hole(ntfs_attr *na, const s64 pos);
1271
1272/**
1273 * ntfs_attr_pwrite - positioned write to an ntfs attribute
1274 * @na: ntfs attribute to write to
1275 * @pos: position in the attribute to write to
1276 * @count: number of bytes to write
1277 * @b: data buffer to write to disk
1278 *
1279 * This function will write @count bytes from data buffer @b to ntfs attribute
1280 * @na at position @pos.
1281 *
1282 * On success, return the number of successfully written bytes. If this number
1283 * is lower than @count this means that an error was encountered during the
1284 * write so that the write is partial. 0 means nothing was written (also return
1285 * 0 when @count is 0).
1286 *
1287 * On error and nothing has been written, return -1 with errno set
1288 * appropriately to the return code of ntfs_pwrite(), or to EINVAL in case of
1289 * invalid arguments.
1290 */
1291s64 ntfs_attr_pwrite(ntfs_attr *na, const s64 pos, s64 count, const void *b)
1292{
1293 s64 written, to_write, ofs, old_initialized_size, old_data_size;
1294 s64 total = 0;
1295 VCN update_from = -1;
1296 ntfs_volume *vol;
1297 s64 fullcount;
1298 ntfs_attr_search_ctx *ctx = NULL;
1299 runlist_element *rl;
1300 s64 hole_end;
1301 int eo;
1302 int compressed_part;
1303 struct {
1304 unsigned int undo_initialized_size : 1;
1305 unsigned int undo_data_size : 1;
1306 } need_to = { 0, 0 };
1307 BOOL makingnonresident = FALSE;
1308 BOOL wasnonresident = FALSE;
1309 BOOL compressed;
1310
1311 ntfs_log_enter("Entering for inode %lld, attr 0x%x, pos 0x%llx, count "
1312 "0x%llx.\n", (long long)na->ni->mft_no, na->type,
1313 (long long)pos, (long long)count);
1314
1315 if (!na || !na->ni || !na->ni->vol || !b || pos < 0 || count < 0) {
1316 errno = EINVAL;
1317 ntfs_log_perror("%s", __FUNCTION__);
1318 goto errno_set;
1319 }
1320 vol = na->ni->vol;
1321 compressed = (na->data_flags & ATTR_COMPRESSION_MASK)
1322 != const_cpu_to_le16(0);
1323 /*
1324 * Encrypted attributes are only supported in raw mode. We return
1325 * access denied, which is what Windows NT4 does, too.
1326 * Moreover a file cannot be both encrypted and compressed.
1327 */
1328 if ((na->data_flags & ATTR_IS_ENCRYPTED)
1329 && (compressed || !vol->efs_raw)) {
1330 errno = EACCES;
1331 goto errno_set;
1332 }
1333 /*
1334 * Fill the gap, when writing beyond the end of a compressed
1335 * file. This will make recursive calls
1336 */
1337 if (compressed
1338 && (na->type == AT_DATA)
1339 && (pos > na->initialized_size)
1340 && stuff_hole(na,pos))
1341 goto errno_set;
1342 /* If this is a compressed attribute it needs special treatment. */
1343 wasnonresident = NAttrNonResident(na) != 0;
1344 makingnonresident = wasnonresident /* yes : already changed */
1345 && !pos && (count == na->initialized_size);
1346 /*
1347 * Writing to compressed files is currently restricted
1348 * to appending data. However we have to accept
1349 * recursive write calls to make the attribute non resident.
1350 * These are writing at position 0 up to initialized_size.
1351 * Compression is also restricted to data streams.
1352 * Only ATTR_IS_COMPRESSED compression mode is supported.
1353 */
1354 if (compressed
1355 && ((na->type != AT_DATA)
1356 || ((na->data_flags & ATTR_COMPRESSION_MASK)
1357 != ATTR_IS_COMPRESSED)
1358 || ((pos != na->initialized_size)
1359 && (pos || (count != na->initialized_size))))) {
1360 // TODO: Implement writing compressed attributes! (AIA)
1361 errno = EOPNOTSUPP;
1362 goto errno_set;
1363 }
1364
1365 if (!count)
1366 goto out;
1367 /* for a compressed file, get prepared to reserve a full block */
1368 fullcount = count;
1369 /* If the write reaches beyond the end, extend the attribute. */
1370 old_data_size = na->data_size;
1371 if (pos + count > na->data_size) {
1372 if (ntfs_attr_truncate(na, pos + count)) {
1373 ntfs_log_perror("Failed to enlarge attribute");
1374 goto errno_set;
1375 }
1376 /* resizing may change the compression mode */
1377 compressed = (na->data_flags & ATTR_COMPRESSION_MASK)
1378 != const_cpu_to_le16(0);
1379 need_to.undo_data_size = 1;
1380 }
1381 /*
1382 * For compressed data, a single full block was allocated
1383 * to deal with compression, possibly in a previous call.
1384 * We are not able to process several blocks because
1385 * some clusters are freed after compression and
1386 * new allocations have to be done before proceeding,
1387 * so truncate the requested count if needed (big buffers).
1388 */
1389 if (compressed) {
1390 fullcount = na->data_size - pos;
1391 if (count > fullcount)
1392 count = fullcount;
1393 }
1394 old_initialized_size = na->initialized_size;
1395 /* If it is a resident attribute, write the data to the mft record. */
1396 if (!NAttrNonResident(na)) {
1397 char *val;
1398
1399 ctx = ntfs_attr_get_search_ctx(na->ni, NULL);
1400 if (!ctx)
1401 goto err_out;
1402 if (ntfs_attr_lookup(na->type, na->name, na->name_len, 0,
1403 0, NULL, 0, ctx)) {
1404 ntfs_log_perror("%s: lookup failed", __FUNCTION__);
1405 goto err_out;
1406 }
1407 val = (char*)ctx->attr + le16_to_cpu(ctx->attr->value_offset);
1408 if (val < (char*)ctx->attr || val +
1409 le32_to_cpu(ctx->attr->value_length) >
1410 (char*)ctx->mrec + vol->mft_record_size) {
1411 errno = EIO;
1412 ntfs_log_perror("%s: Sanity check failed", __FUNCTION__);
1413 goto err_out;
1414 }
1415 memcpy(val + pos, b, count);
1416 if (ntfs_mft_record_write(vol, ctx->ntfs_ino->mft_no,
1417 ctx->mrec)) {
1418 /*
1419 * NOTE: We are in a bad state at this moment. We have
1420 * dirtied the mft record but we failed to commit it to
1421 * disk. Since we have read the mft record ok before,
1422 * it is unlikely to fail writing it, so is ok to just
1423 * return error here... (AIA)
1424 */
1425 ntfs_log_perror("%s: failed to write mft record", __FUNCTION__);
1426 goto err_out;
1427 }
1428 ntfs_attr_put_search_ctx(ctx);
1429 total = count;
1430 goto out;
1431 }
1432
1433 /* Handle writes beyond initialized_size. */
1434 if (pos + count > na->initialized_size) {
1435 if (ntfs_attr_map_whole_runlist(na))
1436 goto err_out;
1437 /*
1438 * For a compressed attribute, we must be sure there is an
1439 * available entry, and, when reopening a compressed file,
1440 * we may need to split a hole. So reserve the entries
1441 * before it gets too late.
1442 */
1443 if (compressed) {
1444 na->rl = ntfs_rl_extend(na->rl,2);
1445 if (!na->rl)
1446 goto err_out;
1447 }
1448 /* Set initialized_size to @pos + @count. */
1449 ctx = ntfs_attr_get_search_ctx(na->ni, NULL);
1450 if (!ctx)
1451 goto err_out;
1452 if (ntfs_attr_lookup(na->type, na->name, na->name_len, 0,
1453 0, NULL, 0, ctx))
1454 goto err_out;
1455
1456 /* If write starts beyond initialized_size, zero the gap. */
1457 if (pos > na->initialized_size)
1458 if (ntfs_attr_fill_zero(na, na->initialized_size,
1459 pos - na->initialized_size))
1460 goto err_out;
1461
1462 ctx->attr->initialized_size = cpu_to_sle64(pos + count);
1463 /* fix data_size for compressed files */
1464 if (compressed)
1465 ctx->attr->data_size = ctx->attr->initialized_size;
1466 if (ntfs_mft_record_write(vol, ctx->ntfs_ino->mft_no,
1467 ctx->mrec)) {
1468 /*
1469 * Undo the change in the in-memory copy and send it
1470 * back for writing.
1471 */
1472 ctx->attr->initialized_size =
1473 cpu_to_sle64(old_initialized_size);
1474 ntfs_mft_record_write(vol, ctx->ntfs_ino->mft_no,
1475 ctx->mrec);
1476 goto err_out;
1477 }
1478 na->initialized_size = pos + count;
1479#if CACHE_NIDATA_SIZE
1480 if (na->ni->mrec->flags & MFT_RECORD_IS_DIRECTORY
1481 ? na->type == AT_INDEX_ROOT && na->name == NTFS_INDEX_I30
1482 : na->type == AT_DATA && na->name == AT_UNNAMED) {
1483 na->ni->data_size = na->data_size;
1484 na->ni->allocated_size = na->allocated_size;
1485 set_nino_flag(na->ni,KnownSize);
1486 }
1487#endif
1488 ntfs_attr_put_search_ctx(ctx);
1489 ctx = NULL;
1490 /*
1491 * NOTE: At this point the initialized_size in the mft record
1492 * has been updated BUT there is random data on disk thus if
1493 * we decide to abort, we MUST change the initialized_size
1494 * again.
1495 */
1496 need_to.undo_initialized_size = 1;
1497 }
1498 /* Find the runlist element containing the vcn. */
1499 rl = ntfs_attr_find_vcn(na, pos >> vol->cluster_size_bits);
1500 if (!rl) {
1501 /*
1502 * If the vcn is not present it is an out of bounds write.
1503 * However, we already extended the size of the attribute,
1504 * so getting this here must be an error of some kind.
1505 */
1506 if (errno == ENOENT) {
1507 errno = EIO;
1508 ntfs_log_perror("%s: Failed to find VCN #3", __FUNCTION__);
1509 }
1510 goto err_out;
1511 }
1512 ofs = pos - (rl->vcn << vol->cluster_size_bits);
1513 /*
1514 * Determine if there is compressed data in the current
1515 * compression block (when appending to an existing file).
1516 * If so, decompression will be needed, and the full block
1517 * must be allocated to be identified as uncompressed.
1518 * This comes in two variants, depending on whether
1519 * compression has saved at least one cluster.
1520 * The compressed size can never be over full size by
1521 * more than 485 (maximum for 15 compression blocks
1522 * compressed to 4098 and the last 3640 bytes compressed
1523 * to 3640 + 3640/8 = 4095, with 15*2 + 4095 - 3640 = 485)
1524 * This is less than the smallest cluster, so the hole is
1525 * is never beyond the cluster next to the position of
1526 * the first uncompressed byte to write.
1527 */
1528 compressed_part = 0;
1529 if (compressed) {
1530 if ((rl->lcn == (LCN)LCN_HOLE)
1531 && wasnonresident) {
1532 if (rl->length < na->compression_block_clusters)
1533 compressed_part
1534 = na->compression_block_clusters
1535 - rl->length;
1536 else {
1537 compressed_part
1538 = na->compression_block_clusters;
1539 if (rl->length > na->compression_block_clusters) {
1540 rl[2].lcn = rl[1].lcn;
1541 rl[2].vcn = rl[1].vcn;
1542 rl[2].length = rl[1].length;
1543 rl[1].vcn -= compressed_part;
1544 rl[1].lcn = LCN_HOLE;
1545 rl[1].length = compressed_part;
1546 rl[0].length -= compressed_part;
1547 ofs -= rl->length << vol->cluster_size_bits;
1548 rl++;
1549 }
1550 }
1551 /* normal hole filling will do later */
1552 } else
1553 if ((rl->lcn >= 0) && (rl[1].lcn == (LCN)LCN_HOLE)) {
1554 s64 xofs;
1555
1556 if (wasnonresident)
1557 compressed_part = na->compression_block_clusters
1558 - rl[1].length;
1559 rl++;
1560 xofs = 0;
1561 if (ntfs_attr_fill_hole(na,
1562 rl->length << vol->cluster_size_bits,
1563 &xofs, &rl, &update_from))
1564 goto err_out;
1565 /* the fist allocated cluster was not merged */
1566 if (!xofs)
1567 rl--;
1568 }
1569 }
1570 /*
1571 * Scatter the data from the linear data buffer to the volume. Note, a
1572 * partial final vcn is taken care of by the @count capping of write
1573 * length.
1574 */
1575 for (hole_end = 0; count; rl++, ofs = 0, hole_end = 0) {
1576 if (rl->lcn == LCN_RL_NOT_MAPPED) {
1577 rl = ntfs_attr_find_vcn(na, rl->vcn);
1578 if (!rl) {
1579 if (errno == ENOENT) {
1580 errno = EIO;
1581 ntfs_log_perror("%s: Failed to find VCN"
1582 " #4", __FUNCTION__);
1583 }
1584 goto rl_err_out;
1585 }
1586 /* Needed for case when runs merged. */
1587 ofs = pos + total - (rl->vcn << vol->cluster_size_bits);
1588 }
1589 if (!rl->length) {
1590 errno = EIO;
1591 ntfs_log_perror("%s: Zero run length", __FUNCTION__);
1592 goto rl_err_out;
1593 }
1594 if (rl->lcn < (LCN)0) {
1595 hole_end = rl->vcn + rl->length;
1596
1597 if (rl->lcn != (LCN)LCN_HOLE) {
1598 errno = EIO;
1599 ntfs_log_perror("%s: Unexpected LCN (%lld)",
1600 __FUNCTION__,
1601 (long long)rl->lcn);
1602 goto rl_err_out;
1603 }
1604 if (ntfs_attr_fill_hole(na, fullcount, &ofs, &rl,
1605 &update_from))
1606 goto err_out;
1607 }
1608 if (compressed) {
1609 while (rl->length
1610 && (ofs >= (rl->length << vol->cluster_size_bits))) {
1611 ofs -= rl->length << vol->cluster_size_bits;
1612 rl++;
1613 }
1614 }
1615
1616 /* It is a real lcn, write it to the volume. */
1617 to_write = min(count, (rl->length << vol->cluster_size_bits) - ofs);
1618retry:
1619 ntfs_log_trace("Writing %lld bytes to vcn %lld, lcn %lld, ofs "
1620 "%lld.\n", (long long)to_write, (long long)rl->vcn,
1621 (long long)rl->lcn, (long long)ofs);
1622 if (!NVolReadOnly(vol)) {
1623
1624 s64 wpos = (rl->lcn << vol->cluster_size_bits) + ofs;
1625 s64 wend = (rl->vcn << vol->cluster_size_bits) + ofs + to_write;
1626 u32 bsize = vol->cluster_size;
1627 /* Byte size needed to zero fill a cluster */
1628 s64 rounding = ((wend + bsize - 1) & ~(s64)(bsize - 1)) - wend;
1629 /**
1630 * Zero fill to cluster boundary if we're writing at the
1631 * end of the attribute or into an ex-sparse cluster.
1632 * This will cause the kernel not to seek and read disk
1633 * blocks during write(2) to fill the end of the buffer
1634 * which increases write speed by 2-10 fold typically.
1635 *
1636 * This is done even for compressed files, because
1637 * data is generally first written uncompressed.
1638 */
1639 if (rounding && ((wend == na->initialized_size) ||
1640 (wend < (hole_end << vol->cluster_size_bits)))){
1641
1642 char *cb;
1643
1644 rounding += to_write;
1645
1646 cb = ntfs_malloc(rounding);
1647 if (!cb)
1648 goto err_out;
1649
1650 memcpy(cb, b, to_write);
1651 memset(cb + to_write, 0, rounding - to_write);
1652
1653 if (compressed) {
1654 written = ntfs_compressed_pwrite(na,
1655 rl, wpos, ofs, to_write,
1656 rounding, b, compressed_part);
1657 } else {
1658 written = ntfs_pwrite(vol->dev, wpos,
1659 rounding, cb);
1660 if (written == rounding)
1661 written = to_write;
1662 }
1663
1664 free(cb);
1665 } else {
1666 if (compressed) {
1667 written = ntfs_compressed_pwrite(na,
1668 rl, wpos, ofs, to_write,
1669 to_write, b, compressed_part);
1670 } else
1671 written = ntfs_pwrite(vol->dev, wpos,
1672 to_write, b);
1673 }
1674 } else
1675 written = to_write;
1676 /* If everything ok, update progress counters and continue. */
1677 if (written > 0) {
1678 total += written;
1679 count -= written;
1680 fullcount -= written;
1681 b = (const u8*)b + written;
1682 }
1683 if (written != to_write) {
1684 /* Partial write cannot be dealt with, stop there */
1685 /* If the syscall was interrupted, try again. */
1686 if (written == (s64)-1 && errno == EINTR)
1687 goto retry;
1688 if (!written)
1689 errno = EIO;
1690 goto rl_err_out;
1691 }
1692 compressed_part = 0;
1693 }
1694done:
1695 if (ctx)
1696 ntfs_attr_put_search_ctx(ctx);
1697 /* Update mapping pairs if needed. */
1698 if ((update_from != -1)
1699 || (compressed && !makingnonresident))
1700 if (ntfs_attr_update_mapping_pairs(na, 0 /*update_from*/)) {
1701 /*
1702 * FIXME: trying to recover by goto rl_err_out;
1703 * could cause driver hang by infinite looping.
1704 */
1705 total = -1;
1706 goto out;
1707 }
1708out:
1709 ntfs_log_leave("\n");
1710 return total;
1711rl_err_out:
1712 eo = errno;
1713 if (total) {
1714 if (need_to.undo_initialized_size) {
1715 if (pos + total > na->initialized_size)
1716 goto done;
1717 /*
1718 * TODO: Need to try to change initialized_size. If it
1719 * succeeds goto done, otherwise goto err_out. (AIA)
1720 */
1721 goto err_out;
1722 }
1723 goto done;
1724 }
1725 errno = eo;
1726err_out:
1727 eo = errno;
1728 if (need_to.undo_initialized_size) {
1729 int err;
1730
1731 err = 0;
1732 if (!ctx) {
1733 ctx = ntfs_attr_get_search_ctx(na->ni, NULL);
1734 if (!ctx)
1735 err = 1;
1736 } else
1737 ntfs_attr_reinit_search_ctx(ctx);
1738 if (!err) {
1739 err = ntfs_attr_lookup(na->type, na->name,
1740 na->name_len, 0, 0, NULL, 0, ctx);
1741 if (!err) {
1742 na->initialized_size = old_initialized_size;
1743 ctx->attr->initialized_size = cpu_to_sle64(
1744 old_initialized_size);
1745 err = ntfs_mft_record_write(vol,
1746 ctx->ntfs_ino->mft_no,
1747 ctx->mrec);
1748 }
1749 }
1750 if (err) {
1751 /*
1752 * FIXME: At this stage could try to recover by filling
1753 * old_initialized_size -> new_initialized_size with
1754 * data or at least zeroes. (AIA)
1755 */
1756 ntfs_log_error("Eeek! Failed to recover from error. "
1757 "Leaving metadata in inconsistent "
1758 "state! Run chkdsk!\n");
1759 }
1760 }
1761 if (ctx)
1762 ntfs_attr_put_search_ctx(ctx);
1763 /* Update mapping pairs if needed. */
1764 if (update_from != -1)
1765 ntfs_attr_update_mapping_pairs(na, 0 /*update_from*/);
1766 /* Restore original data_size if needed. */
1767 if (need_to.undo_data_size && ntfs_attr_truncate(na, old_data_size))
1768 ntfs_log_perror("Failed to restore data_size");
1769 errno = eo;
1770errno_set:
1771 total = -1;
1772 goto out;
1773}
1774
1775int ntfs_attr_pclose(ntfs_attr *na)
1776{
1777 s64 ofs;
1778 int failed;
1779 BOOL ok = TRUE;
1780 VCN update_from = -1;
1781 ntfs_volume *vol;
1782 ntfs_attr_search_ctx *ctx = NULL;
1783 runlist_element *rl;
1784 int eo;
1785 s64 hole;
1786 int compressed_part;
1787 BOOL compressed;
1788
1789 ntfs_log_enter("Entering for inode 0x%llx, attr 0x%x.\n",
1790 na->ni->mft_no, na->type);
1791
1792 if (!na || !na->ni || !na->ni->vol) {
1793 errno = EINVAL;
1794 ntfs_log_perror("%s", __FUNCTION__);
1795 goto errno_set;
1796 }
1797 vol = na->ni->vol;
1798 compressed = (na->data_flags & ATTR_COMPRESSION_MASK)
1799 != const_cpu_to_le16(0);
1800 /*
1801 * Encrypted non-resident attributes are not supported. We return
1802 * access denied, which is what Windows NT4 does, too.
1803 */
1804 if (NAttrEncrypted(na) && NAttrNonResident(na)) {
1805 errno = EACCES;
1806 goto errno_set;
1807 }
1808 /* If this is not a compressed attribute get out */
1809 /* same if it is resident */
1810 if (!compressed || !NAttrNonResident(na))
1811 goto out;
1812
1813 /*
1814 * For a compressed attribute, we must be sure there is an
1815 * available entry, so reserve it before it gets too late.
1816 */
1817 if (ntfs_attr_map_whole_runlist(na))
1818 goto err_out;
1819 na->rl = ntfs_rl_extend(na->rl,1);
1820 if (!na->rl)
1821 goto err_out;
1822 /* Find the runlist element containing the terminal vcn. */
1823 rl = ntfs_attr_find_vcn(na, (na->initialized_size - 1) >> vol->cluster_size_bits);
1824 if (!rl) {
1825 /*
1826 * If the vcn is not present it is an out of bounds write.
1827 * However, we have already written the last byte uncompressed,
1828 * so getting this here must be an error of some kind.
1829 */
1830 if (errno == ENOENT) {
1831 errno = EIO;
1832 ntfs_log_perror("%s: Failed to find VCN #5", __FUNCTION__);
1833 }
1834 goto err_out;
1835 }
1836 /*
1837 * Scatter the data from the linear data buffer to the volume. Note, a
1838 * partial final vcn is taken care of by the @count capping of write
1839 * length.
1840 */
1841 compressed_part = 0;
1842 if ((rl->lcn >= 0) && (rl[1].lcn == (LCN)LCN_HOLE))
1843 compressed_part
1844 = na->compression_block_clusters - rl[1].length;
1845 else
1846 if (rl->lcn == (LCN)LCN_HOLE) {
1847 if (rl->length < na->compression_block_clusters)
1848 compressed_part
1849 = na->compression_block_clusters
1850 - rl->length;
1851 else
1852 compressed_part
1853 = na->compression_block_clusters;
1854 }
1855 /* done, if the last block set was compressed */
1856 if (compressed_part)
1857 goto out;
1858
1859 ofs = na->initialized_size - (rl->vcn << vol->cluster_size_bits);
1860
1861 if (rl->lcn == LCN_RL_NOT_MAPPED) {
1862 rl = ntfs_attr_find_vcn(na, rl->vcn);
1863 if (!rl) {
1864 if (errno == ENOENT) {
1865 errno = EIO;
1866 ntfs_log_perror("%s: Failed to find VCN"
1867 " #6", __FUNCTION__);
1868 }
1869 goto rl_err_out;
1870 }
1871 /* Needed for case when runs merged. */
1872 ofs = na->initialized_size - (rl->vcn << vol->cluster_size_bits);
1873 }
1874 if (!rl->length) {
1875 errno = EIO;
1876 ntfs_log_perror("%s: Zero run length", __FUNCTION__);
1877 goto rl_err_out;
1878 }
1879 if (rl->lcn < (LCN)0) {
1880 hole = rl->vcn + rl->length;
1881 if (rl->lcn != (LCN)LCN_HOLE) {
1882 errno = EIO;
1883 ntfs_log_perror("%s: Unexpected LCN (%lld)",
1884 __FUNCTION__,
1885 (long long)rl->lcn);
1886 goto rl_err_out;
1887 }
1888
1889 if (ntfs_attr_fill_hole(na, (s64)0, &ofs, &rl, &update_from))
1890 goto err_out;
1891 }
1892 while (rl->length
1893 && (ofs >= (rl->length << vol->cluster_size_bits))) {
1894 ofs -= rl->length << vol->cluster_size_bits;
1895 rl++;
1896 }
1897
1898retry:
1899 failed = 0;
1900 if (!NVolReadOnly(vol)) {
1901 failed = ntfs_compressed_close(na, rl, ofs);
1902#if CACHE_NIDATA_SIZE
1903 if (na->ni->mrec->flags & MFT_RECORD_IS_DIRECTORY
1904 ? na->type == AT_INDEX_ROOT && na->name == NTFS_INDEX_I30
1905 : na->type == AT_DATA && na->name == AT_UNNAMED) {
1906 na->ni->data_size = na->data_size;
1907 na->ni->allocated_size = na->allocated_size;
1908 set_nino_flag(na->ni,KnownSize);
1909 }
1910#endif
1911 }
1912 if (failed) {
1913 /* If the syscall was interrupted, try again. */
1914 if (errno == EINTR)
1915 goto retry;
1916 else
1917 goto rl_err_out;
1918 }
1919 if (ctx)
1920 ntfs_attr_put_search_ctx(ctx);
1921 /* Update mapping pairs if needed. */
1922 if (ntfs_attr_update_mapping_pairs(na, 0 /*update_from*/)) {
1923 /*
1924 * FIXME: trying to recover by goto rl_err_out;
1925 * could cause driver hang by infinite looping.
1926 */
1927 ok = FALSE;
1928 goto out;
1929 }
1930out:
1931 ntfs_log_leave("\n");
1932 return (!ok);
1933rl_err_out:
1934 /*
1935 * need not restore old sizes, only compressed_size
1936 * can have changed. It has been set according to
1937 * the current runlist while updating the mapping pairs,
1938 * and must be kept consistent with the runlists.
1939 */
1940err_out:
1941 eo = errno;
1942 if (ctx)
1943 ntfs_attr_put_search_ctx(ctx);
1944 /* Update mapping pairs if needed. */
1945 ntfs_attr_update_mapping_pairs(na, 0 /*update_from*/);
1946 errno = eo;
1947errno_set:
1948 ok = FALSE;
1949 goto out;
1950}
1951
1952/**
1953 * ntfs_attr_mst_pread - multi sector transfer protected ntfs attribute read
1954 * @na: multi sector transfer protected ntfs attribute to read from
1955 * @pos: byte position in the attribute to begin reading from
1956 * @bk_cnt: number of mst protected blocks to read
1957 * @bk_size: size of each mst protected block in bytes
1958 * @dst: output data buffer
1959 *
1960 * This function will read @bk_cnt blocks of size @bk_size bytes each starting
1961 * at offset @pos from the ntfs attribute @na into the data buffer @b.
1962 *
1963 * On success, the multi sector transfer fixups are applied and the number of
1964 * read blocks is returned. If this number is lower than @bk_cnt this means
1965 * that the read has either reached end of attribute or that an error was
1966 * encountered during the read so that the read is partial. 0 means end of
1967 * attribute or nothing to read (also return 0 when @bk_cnt or @bk_size are 0).
1968 *
1969 * On error and nothing has been read, return -1 with errno set appropriately
1970 * to the return code of ntfs_attr_pread() or to EINVAL in case of invalid
1971 * arguments.
1972 *
1973 * NOTE: If an incomplete multi sector transfer is detected the magic is
1974 * changed to BAAD but no error is returned, i.e. it is possible that any of
1975 * the returned blocks have multi sector transfer errors. This should be
1976 * detected by the caller by checking each block with is_baad_recordp(&block).
1977 * The reasoning is that we want to fixup as many blocks as possible and we
1978 * want to return even bad ones to the caller so, e.g. in case of ntfsck, the
1979 * errors can be repaired.
1980 */
1981s64 ntfs_attr_mst_pread(ntfs_attr *na, const s64 pos, const s64 bk_cnt,
1982 const u32 bk_size, void *dst)
1983{
1984 s64 br;
1985 u8 *end;
1986
1987 ntfs_log_trace("Entering for inode 0x%llx, attr type 0x%x, pos 0x%llx.\n",
1988 (unsigned long long)na->ni->mft_no, na->type,
1989 (long long)pos);
1990 if (bk_cnt < 0 || bk_size % NTFS_BLOCK_SIZE) {
1991 errno = EINVAL;
1992 ntfs_log_perror("%s", __FUNCTION__);
1993 return -1;
1994 }
1995 br = ntfs_attr_pread(na, pos, bk_cnt * bk_size, dst);
1996 if (br <= 0)
1997 return br;
1998 br /= bk_size;
1999 for (end = (u8*)dst + br * bk_size; (u8*)dst < end; dst = (u8*)dst +
2000 bk_size)
2001 ntfs_mst_post_read_fixup((NTFS_RECORD*)dst, bk_size);
2002 /* Finally, return the number of blocks read. */
2003 return br;
2004}
2005
2006/**
2007 * ntfs_attr_mst_pwrite - multi sector transfer protected ntfs attribute write
2008 * @na: multi sector transfer protected ntfs attribute to write to
2009 * @pos: position in the attribute to write to
2010 * @bk_cnt: number of mst protected blocks to write
2011 * @bk_size: size of each mst protected block in bytes
2012 * @src: data buffer to write to disk
2013 *
2014 * This function will write @bk_cnt blocks of size @bk_size bytes each from
2015 * data buffer @b to multi sector transfer (mst) protected ntfs attribute @na
2016 * at position @pos.
2017 *
2018 * On success, return the number of successfully written blocks. If this number
2019 * is lower than @bk_cnt this means that an error was encountered during the
2020 * write so that the write is partial. 0 means nothing was written (also
2021 * return 0 when @bk_cnt or @bk_size are 0).
2022 *
2023 * On error and nothing has been written, return -1 with errno set
2024 * appropriately to the return code of ntfs_attr_pwrite(), or to EINVAL in case
2025 * of invalid arguments.
2026 *
2027 * NOTE: We mst protect the data, write it, then mst deprotect it using a quick
2028 * deprotect algorithm (no checking). This saves us from making a copy before
2029 * the write and at the same time causes the usn to be incremented in the
2030 * buffer. This conceptually fits in better with the idea that cached data is
2031 * always deprotected and protection is performed when the data is actually
2032 * going to hit the disk and the cache is immediately deprotected again
2033 * simulating an mst read on the written data. This way cache coherency is
2034 * achieved.
2035 */
2036s64 ntfs_attr_mst_pwrite(ntfs_attr *na, const s64 pos, s64 bk_cnt,
2037 const u32 bk_size, void *src)
2038{
2039 s64 written, i;
2040
2041 ntfs_log_trace("Entering for inode 0x%llx, attr type 0x%x, pos 0x%llx.\n",
2042 (unsigned long long)na->ni->mft_no, na->type,
2043 (long long)pos);
2044 if (bk_cnt < 0 || bk_size % NTFS_BLOCK_SIZE) {
2045 errno = EINVAL;
2046 return -1;
2047 }
2048 if (!bk_cnt)
2049 return 0;
2050 /* Prepare data for writing. */
2051 for (i = 0; i < bk_cnt; ++i) {
2052 int err;
2053
2054 err = ntfs_mst_pre_write_fixup((NTFS_RECORD*)
2055 ((u8*)src + i * bk_size), bk_size);
2056 if (err < 0) {
2057 /* Abort write at this position. */
2058 ntfs_log_perror("%s #1", __FUNCTION__);
2059 if (!i)
2060 return err;
2061 bk_cnt = i;
2062 break;
2063 }
2064 }
2065 /* Write the prepared data. */
2066 written = ntfs_attr_pwrite(na, pos, bk_cnt * bk_size, src);
2067 if (written <= 0) {
2068 ntfs_log_perror("%s: written=%lld", __FUNCTION__,
2069 (long long)written);
2070 }
2071 /* Quickly deprotect the data again. */
2072 for (i = 0; i < bk_cnt; ++i)
2073 ntfs_mst_post_write_fixup((NTFS_RECORD*)((u8*)src + i *
2074 bk_size));
2075 if (written <= 0)
2076 return written;
2077 /* Finally, return the number of complete blocks written. */
2078 return written / bk_size;
2079}
2080
2081/**
2082 * ntfs_attr_find - find (next) attribute in mft record
2083 * @type: attribute type to find
2084 * @name: attribute name to find (optional, i.e. NULL means don't care)
2085 * @name_len: attribute name length (only needed if @name present)
2086 * @ic: IGNORE_CASE or CASE_SENSITIVE (ignored if @name not present)
2087 * @val: attribute value to find (optional, resident attributes only)
2088 * @val_len: attribute value length
2089 * @ctx: search context with mft record and attribute to search from
2090 *
2091 * You shouldn't need to call this function directly. Use lookup_attr() instead.
2092 *
2093 * ntfs_attr_find() takes a search context @ctx as parameter and searches the
2094 * mft record specified by @ctx->mrec, beginning at @ctx->attr, for an
2095 * attribute of @type, optionally @name and @val. If found, ntfs_attr_find()
2096 * returns 0 and @ctx->attr will point to the found attribute.
2097 *
2098 * If not found, ntfs_attr_find() returns -1, with errno set to ENOENT and
2099 * @ctx->attr will point to the attribute before which the attribute being
2100 * searched for would need to be inserted if such an action were to be desired.
2101 *
2102 * On actual error, ntfs_attr_find() returns -1 with errno set to the error
2103 * code but not to ENOENT. In this case @ctx->attr is undefined and in
2104 * particular do not rely on it not changing.
2105 *
2106 * If @ctx->is_first is TRUE, the search begins with @ctx->attr itself. If it
2107 * is FALSE, the search begins after @ctx->attr.
2108 *
2109 * If @type is AT_UNUSED, return the first found attribute, i.e. one can
2110 * enumerate all attributes by setting @type to AT_UNUSED and then calling
2111 * ntfs_attr_find() repeatedly until it returns -1 with errno set to ENOENT to
2112 * indicate that there are no more entries. During the enumeration, each
2113 * successful call of ntfs_attr_find() will return the next attribute in the
2114 * mft record @ctx->mrec.
2115 *
2116 * If @type is AT_END, seek to the end and return -1 with errno set to ENOENT.
2117 * AT_END is not a valid attribute, its length is zero for example, thus it is
2118 * safer to return error instead of success in this case. This also allows us
2119 * to interoperate cleanly with ntfs_external_attr_find().
2120 *
2121 * If @name is AT_UNNAMED search for an unnamed attribute. If @name is present
2122 * but not AT_UNNAMED search for a named attribute matching @name. Otherwise,
2123 * match both named and unnamed attributes.
2124 *
2125 * If @ic is IGNORE_CASE, the @name comparison is not case sensitive and
2126 * @ctx->ntfs_ino must be set to the ntfs inode to which the mft record
2127 * @ctx->mrec belongs. This is so we can get at the ntfs volume and hence at
2128 * the upcase table. If @ic is CASE_SENSITIVE, the comparison is case
2129 * sensitive. When @name is present, @name_len is the @name length in Unicode
2130 * characters.
2131 *
2132 * If @name is not present (NULL), we assume that the unnamed attribute is
2133 * being searched for.
2134 *
2135 * Finally, the resident attribute value @val is looked for, if present.
2136 * If @val is not present (NULL), @val_len is ignored.
2137 *
2138 * ntfs_attr_find() only searches the specified mft record and it ignores the
2139 * presence of an attribute list attribute (unless it is the one being searched
2140 * for, obviously). If you need to take attribute lists into consideration, use
2141 * ntfs_attr_lookup() instead (see below). This also means that you cannot use
2142 * ntfs_attr_find() to search for extent records of non-resident attributes, as
2143 * extents with lowest_vcn != 0 are usually described by the attribute list
2144 * attribute only. - Note that it is possible that the first extent is only in
2145 * the attribute list while the last extent is in the base mft record, so don't
2146 * rely on being able to find the first extent in the base mft record.
2147 *
2148 * Warning: Never use @val when looking for attribute types which can be
2149 * non-resident as this most likely will result in a crash!
2150 */
2151static int ntfs_attr_find(const ATTR_TYPES type, const ntfschar *name,
2152 const u32 name_len, const IGNORE_CASE_BOOL ic,
2153 const u8 *val, const u32 val_len, ntfs_attr_search_ctx *ctx)
2154{
2155 ATTR_RECORD *a;
2156 ntfs_volume *vol;
2157 ntfschar *upcase;
2158 u32 upcase_len;
2159
2160 ntfs_log_trace("attribute type 0x%x.\n", type);
2161
2162 if (ctx->ntfs_ino) {
2163 vol = ctx->ntfs_ino->vol;
2164 upcase = vol->upcase;
2165 upcase_len = vol->upcase_len;
2166 } else {
2167 if (name && name != AT_UNNAMED) {
2168 errno = EINVAL;
2169 ntfs_log_perror("%s", __FUNCTION__);
2170 return -1;
2171 }
2172 vol = NULL;
2173 upcase = NULL;
2174 upcase_len = 0;
2175 }
2176 /*
2177 * Iterate over attributes in mft record starting at @ctx->attr, or the
2178 * attribute following that, if @ctx->is_first is TRUE.
2179 */
2180 if (ctx->is_first) {
2181 a = ctx->attr;
2182 ctx->is_first = FALSE;
2183 } else
2184 a = (ATTR_RECORD*)((char*)ctx->attr +
2185 le32_to_cpu(ctx->attr->length));
2186 for (;; a = (ATTR_RECORD*)((char*)a + le32_to_cpu(a->length))) {
2187 if (p2n(a) < p2n(ctx->mrec) || (char*)a > (char*)ctx->mrec +
2188 le32_to_cpu(ctx->mrec->bytes_allocated))
2189 break;
2190 ctx->attr = a;
2191 if (((type != AT_UNUSED) && (le32_to_cpu(a->type) >
2192 le32_to_cpu(type))) ||
2193 (a->type == AT_END)) {
2194 errno = ENOENT;
2195 return -1;
2196 }
2197 if (!a->length)
2198 break;
2199 /* If this is an enumeration return this attribute. */
2200 if (type == AT_UNUSED)
2201 return 0;
2202 if (a->type != type)
2203 continue;
2204 /*
2205 * If @name is AT_UNNAMED we want an unnamed attribute.
2206 * If @name is present, compare the two names.
2207 * Otherwise, match any attribute.
2208 */
2209 if (name == AT_UNNAMED) {
2210 /* The search failed if the found attribute is named. */
2211 if (a->name_length) {
2212 errno = ENOENT;
2213 return -1;
2214 }
2215 } else {
2216 register int rc;
2217 if (name && ((rc = ntfs_names_full_collate(name,
2218 name_len, (ntfschar*)((char*)a +
2219 le16_to_cpu(a->name_offset)),
2220 a->name_length, ic,
2221 upcase, upcase_len)))) {
2222 /*
2223 * If @name collates before a->name,
2224 * there is no matching attribute.
2225 */
2226 if (rc < 0) {
2227 errno = ENOENT;
2228 return -1;
2229 }
2230 /* If the strings are not equal, continue search. */
2231 continue;
2232 }
2233 }
2234 /*
2235 * The names match or @name not present and attribute is
2236 * unnamed. If no @val specified, we have found the attribute
2237 * and are done.
2238 */
2239 if (!val)
2240 return 0;
2241 /* @val is present; compare values. */
2242 else {
2243 register int rc;
2244
2245 rc = memcmp(val, (char*)a +le16_to_cpu(a->value_offset),
2246 min(val_len,
2247 le32_to_cpu(a->value_length)));
2248 /*
2249 * If @val collates before the current attribute's
2250 * value, there is no matching attribute.
2251 */
2252 if (!rc) {
2253 register u32 avl;
2254 avl = le32_to_cpu(a->value_length);
2255 if (val_len == avl)
2256 return 0;
2257 if (val_len < avl) {
2258 errno = ENOENT;
2259 return -1;
2260 }
2261 } else if (rc < 0) {
2262 errno = ENOENT;
2263 return -1;
2264 }
2265 }
2266 }
2267 errno = EIO;
2268 ntfs_log_perror("%s: Corrupt inode (%lld)", __FUNCTION__,
2269 ctx->ntfs_ino ? (long long)ctx->ntfs_ino->mft_no : -1);
2270 return -1;
2271}
2272
2273void ntfs_attr_name_free(char **name)
2274{
2275 if (*name) {
2276 free(*name);
2277 *name = NULL;
2278 }
2279}
2280
2281char *ntfs_attr_name_get(const ntfschar *uname, const int uname_len)
2282{
2283 char *name = NULL;
2284 int name_len;
2285
2286 name_len = ntfs_ucstombs(uname, uname_len, &name, 0);
2287 if (name_len < 0) {
2288 ntfs_log_perror("ntfs_ucstombs");
2289 return NULL;
2290
2291 } else if (name_len > 0)
2292 return name;
2293
2294 ntfs_attr_name_free(&name);
2295 return NULL;
2296}
2297
2298/**
2299 * ntfs_external_attr_find - find an attribute in the attribute list of an inode
2300 * @type: attribute type to find
2301 * @name: attribute name to find (optional, i.e. NULL means don't care)
2302 * @name_len: attribute name length (only needed if @name present)
2303 * @ic: IGNORE_CASE or CASE_SENSITIVE (ignored if @name not present)
2304 * @lowest_vcn: lowest vcn to find (optional, non-resident attributes only)
2305 * @val: attribute value to find (optional, resident attributes only)
2306 * @val_len: attribute value length
2307 * @ctx: search context with mft record and attribute to search from
2308 *
2309 * You shouldn't need to call this function directly. Use ntfs_attr_lookup()
2310 * instead.
2311 *
2312 * Find an attribute by searching the attribute list for the corresponding
2313 * attribute list entry. Having found the entry, map the mft record for read
2314 * if the attribute is in a different mft record/inode, find the attribute in
2315 * there and return it.
2316 *
2317 * If @type is AT_UNUSED, return the first found attribute, i.e. one can
2318 * enumerate all attributes by setting @type to AT_UNUSED and then calling
2319 * ntfs_external_attr_find() repeatedly until it returns -1 with errno set to
2320 * ENOENT to indicate that there are no more entries. During the enumeration,
2321 * each successful call of ntfs_external_attr_find() will return the next
2322 * attribute described by the attribute list of the base mft record described
2323 * by the search context @ctx.
2324 *
2325 * If @type is AT_END, seek to the end of the base mft record ignoring the
2326 * attribute list completely and return -1 with errno set to ENOENT. AT_END is
2327 * not a valid attribute, its length is zero for example, thus it is safer to
2328 * return error instead of success in this case.
2329 *
2330 * If @name is AT_UNNAMED search for an unnamed attribute. If @name is present
2331 * but not AT_UNNAMED search for a named attribute matching @name. Otherwise,
2332 * match both named and unnamed attributes.
2333 *
2334 * On first search @ctx->ntfs_ino must be the inode of the base mft record and
2335 * @ctx must have been obtained from a call to ntfs_attr_get_search_ctx().
2336 * On subsequent calls, @ctx->ntfs_ino can be any extent inode, too
2337 * (@ctx->base_ntfs_ino is then the base inode).
2338 *
2339 * After finishing with the attribute/mft record you need to call
2340 * ntfs_attr_put_search_ctx() to cleanup the search context (unmapping any
2341 * mapped extent inodes, etc).
2342 *
2343 * Return 0 if the search was successful and -1 if not, with errno set to the
2344 * error code.
2345 *
2346 * On success, @ctx->attr is the found attribute, it is in mft record
2347 * @ctx->mrec, and @ctx->al_entry is the attribute list entry for this
2348 * attribute with @ctx->base_* being the base mft record to which @ctx->attr
2349 * belongs.
2350 *
2351 * On error ENOENT, i.e. attribute not found, @ctx->attr is set to the
2352 * attribute which collates just after the attribute being searched for in the
2353 * base ntfs inode, i.e. if one wants to add the attribute to the mft record
2354 * this is the correct place to insert it into, and if there is not enough
2355 * space, the attribute should be placed in an extent mft record.
2356 * @ctx->al_entry points to the position within @ctx->base_ntfs_ino->attr_list
2357 * at which the new attribute's attribute list entry should be inserted. The
2358 * other @ctx fields, base_ntfs_ino, base_mrec, and base_attr are set to NULL.
2359 * The only exception to this is when @type is AT_END, in which case
2360 * @ctx->al_entry is set to NULL also (see above).
2361 *
2362 * The following error codes are defined:
2363 * ENOENT Attribute not found, not an error as such.
2364 * EINVAL Invalid arguments.
2365 * EIO I/O error or corrupt data structures found.
2366 * ENOMEM Not enough memory to allocate necessary buffers.
2367 */
2368static int ntfs_external_attr_find(ATTR_TYPES type, const ntfschar *name,
2369 const u32 name_len, const IGNORE_CASE_BOOL ic,
2370 const VCN lowest_vcn, const u8 *val, const u32 val_len,
2371 ntfs_attr_search_ctx *ctx)
2372{
2373 ntfs_inode *base_ni, *ni;
2374 ntfs_volume *vol;
2375 ATTR_LIST_ENTRY *al_entry, *next_al_entry;
2376 u8 *al_start, *al_end;
2377 ATTR_RECORD *a;
2378 ntfschar *al_name;
2379 u32 al_name_len;
2380 BOOL is_first_search = FALSE;
2381
2382 ni = ctx->ntfs_ino;
2383 base_ni = ctx->base_ntfs_ino;
2384 ntfs_log_trace("Entering for inode %lld, attribute type 0x%x.\n",
2385 (unsigned long long)ni->mft_no, type);
2386 if (!base_ni) {
2387 /* First call happens with the base mft record. */
2388 base_ni = ctx->base_ntfs_ino = ctx->ntfs_ino;
2389 ctx->base_mrec = ctx->mrec;
2390 }
2391 if (ni == base_ni)
2392 ctx->base_attr = ctx->attr;
2393 if (type == AT_END)
2394 goto not_found;
2395 vol = base_ni->vol;
2396 al_start = base_ni->attr_list;
2397 al_end = al_start + base_ni->attr_list_size;
2398 if (!ctx->al_entry) {
2399 ctx->al_entry = (ATTR_LIST_ENTRY*)al_start;
2400 is_first_search = TRUE;
2401 }
2402 /*
2403 * Iterate over entries in attribute list starting at @ctx->al_entry,
2404 * or the entry following that, if @ctx->is_first is TRUE.
2405 */
2406 if (ctx->is_first) {
2407 al_entry = ctx->al_entry;
2408 ctx->is_first = FALSE;
2409 /*
2410 * If an enumeration and the first attribute is higher than
2411 * the attribute list itself, need to return the attribute list
2412 * attribute.
2413 */
2414 if ((type == AT_UNUSED) && is_first_search &&
2415 le32_to_cpu(al_entry->type) >
2416 le32_to_cpu(AT_ATTRIBUTE_LIST))
2417 goto find_attr_list_attr;
2418 } else {
2419 al_entry = (ATTR_LIST_ENTRY*)((char*)ctx->al_entry +
2420 le16_to_cpu(ctx->al_entry->length));
2421 /*
2422 * If this is an enumeration and the attribute list attribute
2423 * is the next one in the enumeration sequence, just return the
2424 * attribute list attribute from the base mft record as it is
2425 * not listed in the attribute list itself.
2426 */
2427 if ((type == AT_UNUSED) && le32_to_cpu(ctx->al_entry->type) <
2428 le32_to_cpu(AT_ATTRIBUTE_LIST) &&
2429 le32_to_cpu(al_entry->type) >
2430 le32_to_cpu(AT_ATTRIBUTE_LIST)) {
2431 int rc;
2432find_attr_list_attr:
2433
2434 /* Check for bogus calls. */
2435 if (name || name_len || val || val_len || lowest_vcn) {
2436 errno = EINVAL;
2437 ntfs_log_perror("%s", __FUNCTION__);
2438 return -1;
2439 }
2440
2441 /* We want the base record. */
2442 ctx->ntfs_ino = base_ni;
2443 ctx->mrec = ctx->base_mrec;
2444 ctx->is_first = TRUE;
2445 /* Sanity checks are performed elsewhere. */
2446 ctx->attr = (ATTR_RECORD*)((u8*)ctx->mrec +
2447 le16_to_cpu(ctx->mrec->attrs_offset));
2448
2449 /* Find the attribute list attribute. */
2450 rc = ntfs_attr_find(AT_ATTRIBUTE_LIST, NULL, 0,
2451 IGNORE_CASE, NULL, 0, ctx);
2452
2453 /*
2454 * Setup the search context so the correct
2455 * attribute is returned next time round.
2456 */
2457 ctx->al_entry = al_entry;
2458 ctx->is_first = TRUE;
2459
2460 /* Got it. Done. */
2461 if (!rc)
2462 return 0;
2463
2464 /* Error! If other than not found return it. */
2465 if (errno != ENOENT)
2466 return rc;
2467
2468 /* Not found?!? Absurd! */
2469 errno = EIO;
2470 ntfs_log_error("Attribute list wasn't found");
2471 return -1;
2472 }
2473 }
2474 for (;; al_entry = next_al_entry) {
2475 /* Out of bounds check. */
2476 if ((u8*)al_entry < base_ni->attr_list ||
2477 (u8*)al_entry > al_end)
2478 break; /* Inode is corrupt. */
2479 ctx->al_entry = al_entry;
2480 /* Catch the end of the attribute list. */
2481 if ((u8*)al_entry == al_end)
2482 goto not_found;
2483 if (!al_entry->length)
2484 break;
2485 if ((u8*)al_entry + 6 > al_end || (u8*)al_entry +
2486 le16_to_cpu(al_entry->length) > al_end)
2487 break;
2488 next_al_entry = (ATTR_LIST_ENTRY*)((u8*)al_entry +
2489 le16_to_cpu(al_entry->length));
2490 if (type != AT_UNUSED) {
2491 if (le32_to_cpu(al_entry->type) > le32_to_cpu(type))
2492 goto not_found;
2493 if (type != al_entry->type)
2494 continue;
2495 }
2496 al_name_len = al_entry->name_length;
2497 al_name = (ntfschar*)((u8*)al_entry + al_entry->name_offset);
2498 /*
2499 * If !@type we want the attribute represented by this
2500 * attribute list entry.
2501 */
2502 if (type == AT_UNUSED)
2503 goto is_enumeration;
2504 /*
2505 * If @name is AT_UNNAMED we want an unnamed attribute.
2506 * If @name is present, compare the two names.
2507 * Otherwise, match any attribute.
2508 */
2509 if (name == AT_UNNAMED) {
2510 if (al_name_len)
2511 goto not_found;
2512 } else {
2513 int rc;
2514
2515 if (name && ((rc = ntfs_names_full_collate(name,
2516 name_len, al_name, al_name_len, ic,
2517 vol->upcase, vol->upcase_len)))) {
2518
2519 /*
2520 * If @name collates before al_name,
2521 * there is no matching attribute.
2522 */
2523 if (rc < 0)
2524 goto not_found;
2525 /* If the strings are not equal, continue search. */
2526 continue;
2527 }
2528 }
2529 /*
2530 * The names match or @name not present and attribute is
2531 * unnamed. Now check @lowest_vcn. Continue search if the
2532 * next attribute list entry still fits @lowest_vcn. Otherwise
2533 * we have reached the right one or the search has failed.
2534 */
2535 if (lowest_vcn && (u8*)next_al_entry >= al_start &&
2536 (u8*)next_al_entry + 6 < al_end &&
2537 (u8*)next_al_entry + le16_to_cpu(
2538 next_al_entry->length) <= al_end &&
2539 sle64_to_cpu(next_al_entry->lowest_vcn) <=
2540 lowest_vcn &&
2541 next_al_entry->type == al_entry->type &&
2542 next_al_entry->name_length == al_name_len &&
2543 ntfs_names_are_equal((ntfschar*)((char*)
2544 next_al_entry +
2545 next_al_entry->name_offset),
2546 next_al_entry->name_length,
2547 al_name, al_name_len, CASE_SENSITIVE,
2548 vol->upcase, vol->upcase_len))
2549 continue;
2550is_enumeration:
2551 if (MREF_LE(al_entry->mft_reference) == ni->mft_no) {
2552 if (MSEQNO_LE(al_entry->mft_reference) !=
2553 le16_to_cpu(
2554 ni->mrec->sequence_number)) {
2555 ntfs_log_error("Found stale mft reference in "
2556 "attribute list!\n");
2557 break;
2558 }
2559 } else { /* Mft references do not match. */
2560 /* Do we want the base record back? */
2561 if (MREF_LE(al_entry->mft_reference) ==
2562 base_ni->mft_no) {
2563 ni = ctx->ntfs_ino = base_ni;
2564 ctx->mrec = ctx->base_mrec;
2565 } else {
2566 /* We want an extent record. */
2567 ni = ntfs_extent_inode_open(base_ni,
2568 al_entry->mft_reference);
2569 if (!ni)
2570 break;
2571 ctx->ntfs_ino = ni;
2572 ctx->mrec = ni->mrec;
2573 }
2574 }
2575 a = ctx->attr = (ATTR_RECORD*)((char*)ctx->mrec +
2576 le16_to_cpu(ctx->mrec->attrs_offset));
2577 /*
2578 * ctx->ntfs_ino, ctx->mrec, and ctx->attr now point to the
2579 * mft record containing the attribute represented by the
2580 * current al_entry.
2581 *
2582 * We could call into ntfs_attr_find() to find the right
2583 * attribute in this mft record but this would be less
2584 * efficient and not quite accurate as ntfs_attr_find() ignores
2585 * the attribute instance numbers for example which become
2586 * important when one plays with attribute lists. Also, because
2587 * a proper match has been found in the attribute list entry
2588 * above, the comparison can now be optimized. So it is worth
2589 * re-implementing a simplified ntfs_attr_find() here.
2590 *
2591 * Use a manual loop so we can still use break and continue
2592 * with the same meanings as above.
2593 */
2594do_next_attr_loop:
2595 if ((char*)a < (char*)ctx->mrec || (char*)a > (char*)ctx->mrec +
2596 le32_to_cpu(ctx->mrec->bytes_allocated))
2597 break;
2598 if (a->type == AT_END)
2599 continue;
2600 if (!a->length)
2601 break;
2602 if (al_entry->instance != a->instance)
2603 goto do_next_attr;
2604 /*
2605 * If the type and/or the name are/is mismatched between the
2606 * attribute list entry and the attribute record, there is
2607 * corruption so we break and return error EIO.
2608 */
2609 if (al_entry->type != a->type)
2610 break;
2611 if (!ntfs_names_are_equal((ntfschar*)((char*)a +
2612 le16_to_cpu(a->name_offset)),
2613 a->name_length, al_name,
2614 al_name_len, CASE_SENSITIVE,
2615 vol->upcase, vol->upcase_len))
2616 break;
2617 ctx->attr = a;
2618 /*
2619 * If no @val specified or @val specified and it matches, we
2620 * have found it! Also, if !@type, it is an enumeration, so we
2621 * want the current attribute.
2622 */
2623 if ((type == AT_UNUSED) || !val || (!a->non_resident &&
2624 le32_to_cpu(a->value_length) == val_len &&
2625 !memcmp((char*)a + le16_to_cpu(a->value_offset),
2626 val, val_len))) {
2627 return 0;
2628 }
2629do_next_attr:
2630 /* Proceed to the next attribute in the current mft record. */
2631 a = (ATTR_RECORD*)((char*)a + le32_to_cpu(a->length));
2632 goto do_next_attr_loop;
2633 }
2634 if (ni != base_ni) {
2635 ctx->ntfs_ino = base_ni;
2636 ctx->mrec = ctx->base_mrec;
2637 ctx->attr = ctx->base_attr;
2638 }
2639 errno = EIO;
2640 ntfs_log_perror("Inode is corrupt (%lld)", (long long)base_ni->mft_no);
2641 return -1;
2642not_found:
2643 /*
2644 * If we were looking for AT_END or we were enumerating and reached the
2645 * end, we reset the search context @ctx and use ntfs_attr_find() to
2646 * seek to the end of the base mft record.
2647 */
2648 if (type == AT_UNUSED || type == AT_END) {
2649 ntfs_attr_reinit_search_ctx(ctx);
2650 return ntfs_attr_find(AT_END, name, name_len, ic, val, val_len,
2651 ctx);
2652 }
2653 /*
2654 * The attribute wasn't found. Before we return, we want to ensure
2655 * @ctx->mrec and @ctx->attr indicate the position at which the
2656 * attribute should be inserted in the base mft record. Since we also
2657 * want to preserve @ctx->al_entry we cannot reinitialize the search
2658 * context using ntfs_attr_reinit_search_ctx() as this would set
2659 * @ctx->al_entry to NULL. Thus we do the necessary bits manually (see
2660 * ntfs_attr_init_search_ctx() below). Note, we _only_ preserve
2661 * @ctx->al_entry as the remaining fields (base_*) are identical to
2662 * their non base_ counterparts and we cannot set @ctx->base_attr
2663 * correctly yet as we do not know what @ctx->attr will be set to by
2664 * the call to ntfs_attr_find() below.
2665 */
2666 ctx->mrec = ctx->base_mrec;
2667 ctx->attr = (ATTR_RECORD*)((u8*)ctx->mrec +
2668 le16_to_cpu(ctx->mrec->attrs_offset));
2669 ctx->is_first = TRUE;
2670 ctx->ntfs_ino = ctx->base_ntfs_ino;
2671 ctx->base_ntfs_ino = NULL;
2672 ctx->base_mrec = NULL;
2673 ctx->base_attr = NULL;
2674 /*
2675 * In case there are multiple matches in the base mft record, need to
2676 * keep enumerating until we get an attribute not found response (or
2677 * another error), otherwise we would keep returning the same attribute
2678 * over and over again and all programs using us for enumeration would
2679 * lock up in a tight loop.
2680 */
2681 {
2682 int ret;
2683
2684 do {
2685 ret = ntfs_attr_find(type, name, name_len, ic, val,
2686 val_len, ctx);
2687 } while (!ret);
2688 return ret;
2689 }
2690}
2691
2692/**
2693 * ntfs_attr_lookup - find an attribute in an ntfs inode
2694 * @type: attribute type to find
2695 * @name: attribute name to find (optional, i.e. NULL means don't care)
2696 * @name_len: attribute name length (only needed if @name present)
2697 * @ic: IGNORE_CASE or CASE_SENSITIVE (ignored if @name not present)
2698 * @lowest_vcn: lowest vcn to find (optional, non-resident attributes only)
2699 * @val: attribute value to find (optional, resident attributes only)
2700 * @val_len: attribute value length
2701 * @ctx: search context with mft record and attribute to search from
2702 *
2703 * Find an attribute in an ntfs inode. On first search @ctx->ntfs_ino must
2704 * be the base mft record and @ctx must have been obtained from a call to
2705 * ntfs_attr_get_search_ctx().
2706 *
2707 * This function transparently handles attribute lists and @ctx is used to
2708 * continue searches where they were left off at.
2709 *
2710 * If @type is AT_UNUSED, return the first found attribute, i.e. one can
2711 * enumerate all attributes by setting @type to AT_UNUSED and then calling
2712 * ntfs_attr_lookup() repeatedly until it returns -1 with errno set to ENOENT
2713 * to indicate that there are no more entries. During the enumeration, each
2714 * successful call of ntfs_attr_lookup() will return the next attribute, with
2715 * the current attribute being described by the search context @ctx.
2716 *
2717 * If @type is AT_END, seek to the end of the base mft record ignoring the
2718 * attribute list completely and return -1 with errno set to ENOENT. AT_END is
2719 * not a valid attribute, its length is zero for example, thus it is safer to
2720 * return error instead of success in this case. It should never be needed to
2721 * do this, but we implement the functionality because it allows for simpler
2722 * code inside ntfs_external_attr_find().
2723 *
2724 * If @name is AT_UNNAMED search for an unnamed attribute. If @name is present
2725 * but not AT_UNNAMED search for a named attribute matching @name. Otherwise,
2726 * match both named and unnamed attributes.
2727 *
2728 * After finishing with the attribute/mft record you need to call
2729 * ntfs_attr_put_search_ctx() to cleanup the search context (unmapping any
2730 * mapped extent inodes, etc).
2731 *
2732 * Return 0 if the search was successful and -1 if not, with errno set to the
2733 * error code.
2734 *
2735 * On success, @ctx->attr is the found attribute, it is in mft record
2736 * @ctx->mrec, and @ctx->al_entry is the attribute list entry for this
2737 * attribute with @ctx->base_* being the base mft record to which @ctx->attr
2738 * belongs. If no attribute list attribute is present @ctx->al_entry and
2739 * @ctx->base_* are NULL.
2740 *
2741 * On error ENOENT, i.e. attribute not found, @ctx->attr is set to the
2742 * attribute which collates just after the attribute being searched for in the
2743 * base ntfs inode, i.e. if one wants to add the attribute to the mft record
2744 * this is the correct place to insert it into, and if there is not enough
2745 * space, the attribute should be placed in an extent mft record.
2746 * @ctx->al_entry points to the position within @ctx->base_ntfs_ino->attr_list
2747 * at which the new attribute's attribute list entry should be inserted. The
2748 * other @ctx fields, base_ntfs_ino, base_mrec, and base_attr are set to NULL.
2749 * The only exception to this is when @type is AT_END, in which case
2750 * @ctx->al_entry is set to NULL also (see above).
2751 *
2752 *
2753 * The following error codes are defined:
2754 * ENOENT Attribute not found, not an error as such.
2755 * EINVAL Invalid arguments.
2756 * EIO I/O error or corrupt data structures found.
2757 * ENOMEM Not enough memory to allocate necessary buffers.
2758 */
2759int ntfs_attr_lookup(const ATTR_TYPES type, const ntfschar *name,
2760 const u32 name_len, const IGNORE_CASE_BOOL ic,
2761 const VCN lowest_vcn, const u8 *val, const u32 val_len,
2762 ntfs_attr_search_ctx *ctx)
2763{
2764 ntfs_volume *vol;
2765 ntfs_inode *base_ni;
2766 int ret = -1;
2767
2768 ntfs_log_enter("Entering for attribute type 0x%x\n", type);
2769
2770 if (!ctx || !ctx->mrec || !ctx->attr || (name && name != AT_UNNAMED &&
2771 (!ctx->ntfs_ino || !(vol = ctx->ntfs_ino->vol) ||
2772 !vol->upcase || !vol->upcase_len))) {
2773 errno = EINVAL;
2774 ntfs_log_perror("%s", __FUNCTION__);
2775 goto out;
2776 }
2777
2778 if (ctx->base_ntfs_ino)
2779 base_ni = ctx->base_ntfs_ino;
2780 else
2781 base_ni = ctx->ntfs_ino;
2782 if (!base_ni || !NInoAttrList(base_ni) || type == AT_ATTRIBUTE_LIST)
2783 ret = ntfs_attr_find(type, name, name_len, ic, val, val_len, ctx);
2784 else
2785 ret = ntfs_external_attr_find(type, name, name_len, ic,
2786 lowest_vcn, val, val_len, ctx);
2787out:
2788 ntfs_log_leave("\n");
2789 return ret;
2790}
2791
2792/**
2793 * ntfs_attr_position - find given or next attribute type in an ntfs inode
2794 * @type: attribute type to start lookup
2795 * @ctx: search context with mft record and attribute to search from
2796 *
2797 * Find an attribute type in an ntfs inode or the next attribute which is not
2798 * the AT_END attribute. Please see more details at ntfs_attr_lookup.
2799 *
2800 * Return 0 if the search was successful and -1 if not, with errno set to the
2801 * error code.
2802 *
2803 * The following error codes are defined:
2804 * EINVAL Invalid arguments.
2805 * EIO I/O error or corrupt data structures found.
2806 * ENOMEM Not enough memory to allocate necessary buffers.
2807 * ENOSPC No attribute was found after 'type', only AT_END.
2808 */
2809int ntfs_attr_position(const ATTR_TYPES type, ntfs_attr_search_ctx *ctx)
2810{
2811 if (ntfs_attr_lookup(type, NULL, 0, CASE_SENSITIVE, 0, NULL, 0, ctx)) {
2812 if (errno != ENOENT)
2813 return -1;
2814 if (ctx->attr->type == AT_END) {
2815 errno = ENOSPC;
2816 return -1;
2817 }
2818 }
2819 return 0;
2820}
2821
2822/**
2823 * ntfs_attr_init_search_ctx - initialize an attribute search context
2824 * @ctx: attribute search context to initialize
2825 * @ni: ntfs inode with which to initialize the search context
2826 * @mrec: mft record with which to initialize the search context
2827 *
2828 * Initialize the attribute search context @ctx with @ni and @mrec.
2829 */
2830static void ntfs_attr_init_search_ctx(ntfs_attr_search_ctx *ctx,
2831 ntfs_inode *ni, MFT_RECORD *mrec)
2832{
2833 if (!mrec)
2834 mrec = ni->mrec;
2835 ctx->mrec = mrec;
2836 /* Sanity checks are performed elsewhere. */
2837 ctx->attr = (ATTR_RECORD*)((u8*)mrec + le16_to_cpu(mrec->attrs_offset));
2838 ctx->is_first = TRUE;
2839 ctx->ntfs_ino = ni;
2840 ctx->al_entry = NULL;
2841 ctx->base_ntfs_ino = NULL;
2842 ctx->base_mrec = NULL;
2843 ctx->base_attr = NULL;
2844}
2845
2846/**
2847 * ntfs_attr_reinit_search_ctx - reinitialize an attribute search context
2848 * @ctx: attribute search context to reinitialize
2849 *
2850 * Reinitialize the attribute search context @ctx.
2851 *
2852 * This is used when a search for a new attribute is being started to reset
2853 * the search context to the beginning.
2854 */
2855void ntfs_attr_reinit_search_ctx(ntfs_attr_search_ctx *ctx)
2856{
2857 if (!ctx->base_ntfs_ino) {
2858 /* No attribute list. */
2859 ctx->is_first = TRUE;
2860 /* Sanity checks are performed elsewhere. */
2861 ctx->attr = (ATTR_RECORD*)((u8*)ctx->mrec +
2862 le16_to_cpu(ctx->mrec->attrs_offset));
2863 /*
2864 * This needs resetting due to ntfs_external_attr_find() which
2865 * can leave it set despite having zeroed ctx->base_ntfs_ino.
2866 */
2867 ctx->al_entry = NULL;
2868 return;
2869 } /* Attribute list. */
2870 ntfs_attr_init_search_ctx(ctx, ctx->base_ntfs_ino, ctx->base_mrec);
2871 return;
2872}
2873
2874/**
2875 * ntfs_attr_get_search_ctx - allocate/initialize a new attribute search context
2876 * @ni: ntfs inode with which to initialize the search context
2877 * @mrec: mft record with which to initialize the search context
2878 *
2879 * Allocate a new attribute search context, initialize it with @ni and @mrec,
2880 * and return it. Return NULL on error with errno set.
2881 *
2882 * @mrec can be NULL, in which case the mft record is taken from @ni.
2883 *
2884 * Note: For low level utilities which know what they are doing we allow @ni to
2885 * be NULL and @mrec to be set. Do NOT do this unless you understand the
2886 * implications!!! For example it is no longer safe to call ntfs_attr_lookup().
2887 */
2888ntfs_attr_search_ctx *ntfs_attr_get_search_ctx(ntfs_inode *ni, MFT_RECORD *mrec)
2889{
2890 ntfs_attr_search_ctx *ctx;
2891
2892 if (!ni && !mrec) {
2893 errno = EINVAL;
2894 ntfs_log_perror("NULL arguments");
2895 return NULL;
2896 }
2897 ctx = ntfs_malloc(sizeof(ntfs_attr_search_ctx));
2898 if (ctx)
2899 ntfs_attr_init_search_ctx(ctx, ni, mrec);
2900 return ctx;
2901}
2902
2903/**
2904 * ntfs_attr_put_search_ctx - release an attribute search context
2905 * @ctx: attribute search context to free
2906 *
2907 * Release the attribute search context @ctx.
2908 */
2909void ntfs_attr_put_search_ctx(ntfs_attr_search_ctx *ctx)
2910{
2911 // NOTE: save errno if it could change and function stays void!
2912 free(ctx);
2913}
2914
2915/**
2916 * ntfs_attr_find_in_attrdef - find an attribute in the $AttrDef system file
2917 * @vol: ntfs volume to which the attribute belongs
2918 * @type: attribute type which to find
2919 *
2920 * Search for the attribute definition record corresponding to the attribute
2921 * @type in the $AttrDef system file.
2922 *
2923 * Return the attribute type definition record if found and NULL if not found
2924 * or an error occurred. On error the error code is stored in errno. The
2925 * following error codes are defined:
2926 * ENOENT - The attribute @type is not specified in $AttrDef.
2927 * EINVAL - Invalid parameters (e.g. @vol is not valid).
2928 */
2929ATTR_DEF *ntfs_attr_find_in_attrdef(const ntfs_volume *vol,
2930 const ATTR_TYPES type)
2931{
2932 ATTR_DEF *ad;
2933
2934 if (!vol || !vol->attrdef || !type) {
2935 errno = EINVAL;
2936 ntfs_log_perror("%s: type=%d", __FUNCTION__, type);
2937 return NULL;
2938 }
2939 for (ad = vol->attrdef; (u8*)ad - (u8*)vol->attrdef <
2940 vol->attrdef_len && ad->type; ++ad) {
2941 /* We haven't found it yet, carry on searching. */
2942 if (le32_to_cpu(ad->type) < le32_to_cpu(type))
2943 continue;
2944 /* We found the attribute; return it. */
2945 if (ad->type == type)
2946 return ad;
2947 /* We have gone too far already. No point in continuing. */
2948 break;
2949 }
2950 errno = ENOENT;
2951 ntfs_log_perror("%s: type=%d", __FUNCTION__, type);
2952 return NULL;
2953}
2954
2955/**
2956 * ntfs_attr_size_bounds_check - check a size of an attribute type for validity
2957 * @vol: ntfs volume to which the attribute belongs
2958 * @type: attribute type which to check
2959 * @size: size which to check
2960 *
2961 * Check whether the @size in bytes is valid for an attribute of @type on the
2962 * ntfs volume @vol. This information is obtained from $AttrDef system file.
2963 *
2964 * Return 0 if valid and -1 if not valid or an error occurred. On error the
2965 * error code is stored in errno. The following error codes are defined:
2966 * ERANGE - @size is not valid for the attribute @type.
2967 * ENOENT - The attribute @type is not specified in $AttrDef.
2968 * EINVAL - Invalid parameters (e.g. @size is < 0 or @vol is not valid).
2969 */
2970int ntfs_attr_size_bounds_check(const ntfs_volume *vol, const ATTR_TYPES type,
2971 const s64 size)
2972{
2973 ATTR_DEF *ad;
2974 s64 min_size, max_size;
2975
2976 if (size < 0) {
2977 errno = EINVAL;
2978 ntfs_log_perror("%s: size=%lld", __FUNCTION__,
2979 (long long)size);
2980 return -1;
2981 }
2982
2983 /*
2984 * $ATTRIBUTE_LIST shouldn't be greater than 0x40000, otherwise
2985 * Windows would crash. This is not listed in the AttrDef.
2986 */
2987 if (type == AT_ATTRIBUTE_LIST && size > 0x40000) {
2988 errno = ERANGE;
2989 ntfs_log_perror("Too large attrlist (%lld)", (long long)size);
2990 return -1;
2991 }
2992
2993 ad = ntfs_attr_find_in_attrdef(vol, type);
2994 if (!ad)
2995 return -1;
2996
2997 min_size = sle64_to_cpu(ad->min_size);
2998 max_size = sle64_to_cpu(ad->max_size);
2999
3000 if ((min_size && (size < min_size)) ||
3001 ((max_size > 0) && (size > max_size))) {
3002 errno = ERANGE;
3003 ntfs_log_perror("Attr type %d size check failed (min,size,max="
3004 "%lld,%lld,%lld)", type, (long long)min_size,
3005 (long long)size, (long long)max_size);
3006 return -1;
3007 }
3008 return 0;
3009}
3010
3011/**
3012 * ntfs_attr_can_be_non_resident - check if an attribute can be non-resident
3013 * @vol: ntfs volume to which the attribute belongs
3014 * @type: attribute type to check
3015 * @name: attribute name to check
3016 * @name_len: attribute name length
3017 *
3018 * Check whether the attribute of @type and @name with name length @name_len on
3019 * the ntfs volume @vol is allowed to be non-resident. This information is
3020 * obtained from $AttrDef system file and is augmented by rules imposed by
3021 * Microsoft (e.g. see http://support.microsoft.com/kb/974729/).
3022 *
3023 * Return 0 if the attribute is allowed to be non-resident and -1 if not or an
3024 * error occurred. On error the error code is stored in errno. The following
3025 * error codes are defined:
3026 * EPERM - The attribute is not allowed to be non-resident.
3027 * ENOENT - The attribute @type is not specified in $AttrDef.
3028 * EINVAL - Invalid parameters (e.g. @vol is not valid).
3029 */
3030static int ntfs_attr_can_be_non_resident(const ntfs_volume *vol, const ATTR_TYPES type,
3031 const ntfschar *name, int name_len)
3032{
3033 ATTR_DEF *ad;
3034 BOOL allowed;
3035
3036 /*
3037 * Microsoft has decreed that $LOGGED_UTILITY_STREAM attributes with a
3038 * name of $TXF_DATA must be resident despite the entry for
3039 * $LOGGED_UTILITY_STREAM in $AttrDef allowing them to be non-resident.
3040 * Failure to obey this on the root directory mft record of a volume
3041 * causes Windows Vista and later to see the volume as a RAW volume and
3042 * thus cannot mount it at all.
3043 */
3044 if ((type == AT_LOGGED_UTILITY_STREAM)
3045 && name
3046 && ntfs_names_are_equal(TXF_DATA, 9, name, name_len,
3047 CASE_SENSITIVE, vol->upcase, vol->upcase_len))
3048 allowed = FALSE;
3049 else {
3050 /* Find the attribute definition record in $AttrDef. */
3051 ad = ntfs_attr_find_in_attrdef(vol, type);
3052 if (!ad)
3053 return -1;
3054 /* Check the flags and return the result. */
3055 allowed = !(ad->flags & ATTR_DEF_RESIDENT);
3056 }
3057 if (!allowed) {
3058 errno = EPERM;
3059 ntfs_log_trace("Attribute can't be non-resident\n");
3060 return -1;
3061 }
3062 return 0;
3063}
3064
3065/**
3066 * ntfs_attr_can_be_resident - check if an attribute can be resident
3067 * @vol: ntfs volume to which the attribute belongs
3068 * @type: attribute type which to check
3069 *
3070 * Check whether the attribute of @type on the ntfs volume @vol is allowed to
3071 * be resident. This information is derived from our ntfs knowledge and may
3072 * not be completely accurate, especially when user defined attributes are
3073 * present. Basically we allow everything to be resident except for index
3074 * allocation and extended attribute attributes.
3075 *
3076 * Return 0 if the attribute is allowed to be resident and -1 if not or an
3077 * error occurred. On error the error code is stored in errno. The following
3078 * error codes are defined:
3079 * EPERM - The attribute is not allowed to be resident.
3080 * EINVAL - Invalid parameters (e.g. @vol is not valid).
3081 *
3082 * Warning: In the system file $MFT the attribute $Bitmap must be non-resident
3083 * otherwise windows will not boot (blue screen of death)! We cannot
3084 * check for this here as we don't know which inode's $Bitmap is being
3085 * asked about so the caller needs to special case this.
3086 */
3087int ntfs_attr_can_be_resident(const ntfs_volume *vol, const ATTR_TYPES type)
3088{
3089 if (!vol || !vol->attrdef || !type) {
3090 errno = EINVAL;
3091 return -1;
3092 }
3093 if (type != AT_INDEX_ALLOCATION)
3094 return 0;
3095
3096 ntfs_log_trace("Attribute can't be resident\n");
3097 errno = EPERM;
3098 return -1;
3099}
3100
3101/**
3102 * ntfs_make_room_for_attr - make room for an attribute inside an mft record
3103 * @m: mft record
3104 * @pos: position at which to make space
3105 * @size: byte size to make available at this position
3106 *
3107 * @pos points to the attribute in front of which we want to make space.
3108 *
3109 * Return 0 on success or -1 on error. On error the error code is stored in
3110 * errno. Possible error codes are:
3111 * ENOSPC - There is not enough space available to complete operation. The
3112 * caller has to make space before calling this.
3113 * EINVAL - Input parameters were faulty.
3114 */
3115int ntfs_make_room_for_attr(MFT_RECORD *m, u8 *pos, u32 size)
3116{
3117 u32 biu;
3118
3119 ntfs_log_trace("Entering for pos 0x%d, size %u.\n",
3120 (int)(pos - (u8*)m), (unsigned) size);
3121
3122 /* Make size 8-byte alignment. */
3123 size = (size + 7) & ~7;
3124
3125 /* Rigorous consistency checks. */
3126 if (!m || !pos || pos < (u8*)m) {
3127 errno = EINVAL;
3128 ntfs_log_perror("%s: pos=%p m=%p", __FUNCTION__, pos, m);
3129 return -1;
3130 }
3131 /* The -8 is for the attribute terminator. */
3132 if (pos - (u8*)m > (int)le32_to_cpu(m->bytes_in_use) - 8) {
3133 errno = EINVAL;
3134 return -1;
3135 }
3136 /* Nothing to do. */
3137 if (!size)
3138 return 0;
3139
3140 biu = le32_to_cpu(m->bytes_in_use);
3141 /* Do we have enough space? */
3142 if (biu + size > le32_to_cpu(m->bytes_allocated) ||
3143 pos + size > (u8*)m + le32_to_cpu(m->bytes_allocated)) {
3144 errno = ENOSPC;
3145 ntfs_log_trace("No enough space in the MFT record\n");
3146 return -1;
3147 }
3148 /* Move everything after pos to pos + size. */
3149 memmove(pos + size, pos, biu - (pos - (u8*)m));
3150 /* Update mft record. */
3151 m->bytes_in_use = cpu_to_le32(biu + size);
3152 return 0;
3153}
3154
3155/**
3156 * ntfs_resident_attr_record_add - add resident attribute to inode
3157 * @ni: opened ntfs inode to which MFT record add attribute
3158 * @type: type of the new attribute
3159 * @name: name of the new attribute
3160 * @name_len: name length of the new attribute
3161 * @val: value of the new attribute
3162 * @size: size of new attribute (length of @val, if @val != NULL)
3163 * @flags: flags of the new attribute
3164 *
3165 * Return offset to attribute from the beginning of the mft record on success
3166 * and -1 on error. On error the error code is stored in errno.
3167 * Possible error codes are:
3168 * EINVAL - Invalid arguments passed to function.
3169 * EEXIST - Attribute of such type and with same name already exists.
3170 * EIO - I/O error occurred or damaged filesystem.
3171 */
3172int ntfs_resident_attr_record_add(ntfs_inode *ni, ATTR_TYPES type,
3173 ntfschar *name, u8 name_len, u8 *val, u32 size,
3174 ATTR_FLAGS data_flags)
3175{
3176 ntfs_attr_search_ctx *ctx;
3177 u32 length;
3178 ATTR_RECORD *a;
3179 MFT_RECORD *m;
3180 int err, offset;
3181 ntfs_inode *base_ni;
3182
3183 ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x, flags 0x%x.\n",
3184 (long long) ni->mft_no, (unsigned) type, (unsigned) data_flags);
3185
3186 if (!ni || (!name && name_len)) {
3187 errno = EINVAL;
3188 return -1;
3189 }
3190
3191 if (ntfs_attr_can_be_resident(ni->vol, type)) {
3192 if (errno == EPERM)
3193 ntfs_log_trace("Attribute can't be resident.\n");
3194 else
3195 ntfs_log_trace("ntfs_attr_can_be_resident failed.\n");
3196 return -1;
3197 }
3198
3199 /* Locate place where record should be. */
3200 ctx = ntfs_attr_get_search_ctx(ni, NULL);
3201 if (!ctx)
3202 return -1;
3203 /*
3204 * Use ntfs_attr_find instead of ntfs_attr_lookup to find place for
3205 * attribute in @ni->mrec, not any extent inode in case if @ni is base
3206 * file record.
3207 */
3208 if (!ntfs_attr_find(type, name, name_len, CASE_SENSITIVE, val, size,
3209 ctx)) {
3210 err = EEXIST;
3211 ntfs_log_trace("Attribute already present.\n");
3212 goto put_err_out;
3213 }
3214 if (errno != ENOENT) {
3215 err = EIO;
3216 goto put_err_out;
3217 }
3218 a = ctx->attr;
3219 m = ctx->mrec;
3220
3221 /* Make room for attribute. */
3222 length = offsetof(ATTR_RECORD, resident_end) +
3223 ((name_len * sizeof(ntfschar) + 7) & ~7) +
3224 ((size + 7) & ~7);
3225 if (ntfs_make_room_for_attr(ctx->mrec, (u8*) ctx->attr, length)) {
3226 err = errno;
3227 ntfs_log_trace("Failed to make room for attribute.\n");
3228 goto put_err_out;
3229 }
3230
3231 /* Setup record fields. */
3232 offset = ((u8*)a - (u8*)m);
3233 a->type = type;
3234 a->length = cpu_to_le32(length);
3235 a->non_resident = 0;
3236 a->name_length = name_len;
3237 a->name_offset = (name_len
3238 ? cpu_to_le16(offsetof(ATTR_RECORD, resident_end))
3239 : const_cpu_to_le16(0));
3240 a->flags = data_flags;
3241 a->instance = m->next_attr_instance;
3242 a->value_length = cpu_to_le32(size);
3243 a->value_offset = cpu_to_le16(length - ((size + 7) & ~7));
3244 if (val)
3245 memcpy((u8*)a + le16_to_cpu(a->value_offset), val, size);
3246 else
3247 memset((u8*)a + le16_to_cpu(a->value_offset), 0, size);
3248 if (type == AT_FILE_NAME)
3249 a->resident_flags = RESIDENT_ATTR_IS_INDEXED;
3250 else
3251 a->resident_flags = 0;
3252 if (name_len)
3253 memcpy((u8*)a + le16_to_cpu(a->name_offset),
3254 name, sizeof(ntfschar) * name_len);
3255 m->next_attr_instance =
3256 cpu_to_le16((le16_to_cpu(m->next_attr_instance) + 1) & 0xffff);
3257 if (ni->nr_extents == -1)
3258 base_ni = ni->base_ni;
3259 else
3260 base_ni = ni;
3261 if (type != AT_ATTRIBUTE_LIST && NInoAttrList(base_ni)) {
3262 if (ntfs_attrlist_entry_add(ni, a)) {
3263 err = errno;
3264 ntfs_attr_record_resize(m, a, 0);
3265 ntfs_log_trace("Failed add attribute entry to "
3266 "ATTRIBUTE_LIST.\n");
3267 goto put_err_out;
3268 }
3269 }
3270 if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY
3271 ? type == AT_INDEX_ROOT && name == NTFS_INDEX_I30
3272 : type == AT_DATA && name == AT_UNNAMED) {
3273 ni->data_size = size;
3274 ni->allocated_size = (size + 7) & ~7;
3275 set_nino_flag(ni,KnownSize);
3276 }
3277 ntfs_inode_mark_dirty(ni);
3278 ntfs_attr_put_search_ctx(ctx);
3279 return offset;
3280put_err_out:
3281 ntfs_attr_put_search_ctx(ctx);
3282 errno = err;
3283 return -1;
3284}
3285
3286/**
3287 * ntfs_non_resident_attr_record_add - add extent of non-resident attribute
3288 * @ni: opened ntfs inode to which MFT record add attribute
3289 * @type: type of the new attribute extent
3290 * @name: name of the new attribute extent
3291 * @name_len: name length of the new attribute extent
3292 * @lowest_vcn: lowest vcn of the new attribute extent
3293 * @dataruns_size: dataruns size of the new attribute extent
3294 * @flags: flags of the new attribute extent
3295 *
3296 * Return offset to attribute from the beginning of the mft record on success
3297 * and -1 on error. On error the error code is stored in errno.
3298 * Possible error codes are:
3299 * EINVAL - Invalid arguments passed to function.
3300 * EEXIST - Attribute of such type, with same lowest vcn and with same
3301 * name already exists.
3302 * EIO - I/O error occurred or damaged filesystem.
3303 */
3304int ntfs_non_resident_attr_record_add(ntfs_inode *ni, ATTR_TYPES type,
3305 ntfschar *name, u8 name_len, VCN lowest_vcn, int dataruns_size,
3306 ATTR_FLAGS flags)
3307{
3308 ntfs_attr_search_ctx *ctx;
3309 u32 length;
3310 ATTR_RECORD *a;
3311 MFT_RECORD *m;
3312 ntfs_inode *base_ni;
3313 int err, offset;
3314
3315 ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x, lowest_vcn %lld, "
3316 "dataruns_size %d, flags 0x%x.\n",
3317 (long long) ni->mft_no, (unsigned) type,
3318 (long long) lowest_vcn, dataruns_size, (unsigned) flags);
3319
3320 if (!ni || dataruns_size <= 0 || (!name && name_len)) {
3321 errno = EINVAL;
3322 return -1;
3323 }
3324
3325 if (ntfs_attr_can_be_non_resident(ni->vol, type, name, name_len)) {
3326 if (errno == EPERM)
3327 ntfs_log_perror("Attribute can't be non resident");
3328 else
3329 ntfs_log_perror("ntfs_attr_can_be_non_resident failed");
3330 return -1;
3331 }
3332
3333 /* Locate place where record should be. */
3334 ctx = ntfs_attr_get_search_ctx(ni, NULL);
3335 if (!ctx)
3336 return -1;
3337 /*
3338 * Use ntfs_attr_find instead of ntfs_attr_lookup to find place for
3339 * attribute in @ni->mrec, not any extent inode in case if @ni is base
3340 * file record.
3341 */
3342 if (!ntfs_attr_find(type, name, name_len, CASE_SENSITIVE, NULL, 0,
3343 ctx)) {
3344 err = EEXIST;
3345 ntfs_log_perror("Attribute 0x%x already present", type);
3346 goto put_err_out;
3347 }
3348 if (errno != ENOENT) {
3349 ntfs_log_perror("ntfs_attr_find failed");
3350 err = EIO;
3351 goto put_err_out;
3352 }
3353 a = ctx->attr;
3354 m = ctx->mrec;
3355
3356 /* Make room for attribute. */
3357 dataruns_size = (dataruns_size + 7) & ~7;
3358 length = offsetof(ATTR_RECORD, compressed_size) + ((sizeof(ntfschar) *
3359 name_len + 7) & ~7) + dataruns_size +
3360 ((flags & (ATTR_IS_COMPRESSED | ATTR_IS_SPARSE)) ?
3361 sizeof(a->compressed_size) : 0);
3362 if (ntfs_make_room_for_attr(ctx->mrec, (u8*) ctx->attr, length)) {
3363 err = errno;
3364 ntfs_log_perror("Failed to make room for attribute");
3365 goto put_err_out;
3366 }
3367
3368 /* Setup record fields. */
3369 a->type = type;
3370 a->length = cpu_to_le32(length);
3371 a->non_resident = 1;
3372 a->name_length = name_len;
3373 a->name_offset = cpu_to_le16(offsetof(ATTR_RECORD, compressed_size) +
3374 ((flags & (ATTR_IS_COMPRESSED | ATTR_IS_SPARSE)) ?
3375 sizeof(a->compressed_size) : 0));
3376 a->flags = flags;
3377 a->instance = m->next_attr_instance;
3378 a->lowest_vcn = cpu_to_sle64(lowest_vcn);
3379 a->mapping_pairs_offset = cpu_to_le16(length - dataruns_size);
3380 a->compression_unit = (flags & ATTR_IS_COMPRESSED)
3381 ? STANDARD_COMPRESSION_UNIT : 0;
3382 /* If @lowest_vcn == 0, than setup empty attribute. */
3383 if (!lowest_vcn) {
3384 a->highest_vcn = cpu_to_sle64(-1);
3385 a->allocated_size = 0;
3386 a->data_size = 0;
3387 a->initialized_size = 0;
3388 /* Set empty mapping pairs. */
3389 *((u8*)a + le16_to_cpu(a->mapping_pairs_offset)) = 0;
3390 }
3391 if (name_len)
3392 memcpy((u8*)a + le16_to_cpu(a->name_offset),
3393 name, sizeof(ntfschar) * name_len);
3394 m->next_attr_instance =
3395 cpu_to_le16((le16_to_cpu(m->next_attr_instance) + 1) & 0xffff);
3396 if (ni->nr_extents == -1)
3397 base_ni = ni->base_ni;
3398 else
3399 base_ni = ni;
3400 if (type != AT_ATTRIBUTE_LIST && NInoAttrList(base_ni)) {
3401 if (ntfs_attrlist_entry_add(ni, a)) {
3402 err = errno;
3403 ntfs_log_perror("Failed add attr entry to attrlist");
3404 ntfs_attr_record_resize(m, a, 0);
3405 goto put_err_out;
3406 }
3407 }
3408 ntfs_inode_mark_dirty(ni);
3409 /*
3410 * Locate offset from start of the MFT record where new attribute is
3411 * placed. We need relookup it, because record maybe moved during
3412 * update of attribute list.
3413 */
3414 ntfs_attr_reinit_search_ctx(ctx);
3415 if (ntfs_attr_lookup(type, name, name_len, CASE_SENSITIVE,
3416 lowest_vcn, NULL, 0, ctx)) {
3417 ntfs_log_perror("%s: attribute lookup failed", __FUNCTION__);
3418 ntfs_attr_put_search_ctx(ctx);
3419 return -1;
3420
3421 }
3422 offset = (u8*)ctx->attr - (u8*)ctx->mrec;
3423 ntfs_attr_put_search_ctx(ctx);
3424 return offset;
3425put_err_out:
3426 ntfs_attr_put_search_ctx(ctx);
3427 errno = err;
3428 return -1;
3429}
3430
3431/**
3432 * ntfs_attr_record_rm - remove attribute extent
3433 * @ctx: search context describing the attribute which should be removed
3434 *
3435 * If this function succeed, user should reinit search context if he/she wants
3436 * use it anymore.
3437 *
3438 * Return 0 on success and -1 on error. On error the error code is stored in
3439 * errno. Possible error codes are:
3440 * EINVAL - Invalid arguments passed to function.
3441 * EIO - I/O error occurred or damaged filesystem.
3442 */
3443int ntfs_attr_record_rm(ntfs_attr_search_ctx *ctx)
3444{
3445 ntfs_inode *base_ni, *ni;
3446 ATTR_TYPES type;
3447
3448 if (!ctx || !ctx->ntfs_ino || !ctx->mrec || !ctx->attr) {
3449 errno = EINVAL;
3450 return -1;
3451 }
3452
3453 ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x.\n",
3454 (long long) ctx->ntfs_ino->mft_no,
3455 (unsigned) le32_to_cpu(ctx->attr->type));
3456 type = ctx->attr->type;
3457 ni = ctx->ntfs_ino;
3458 if (ctx->base_ntfs_ino)
3459 base_ni = ctx->base_ntfs_ino;
3460 else
3461 base_ni = ctx->ntfs_ino;
3462
3463 /* Remove attribute itself. */
3464 if (ntfs_attr_record_resize(ctx->mrec, ctx->attr, 0)) {
3465 ntfs_log_trace("Couldn't remove attribute record. Bug or damaged MFT "
3466 "record.\n");
3467 if (NInoAttrList(base_ni) && type != AT_ATTRIBUTE_LIST)
3468 if (ntfs_attrlist_entry_add(ni, ctx->attr))
3469 ntfs_log_trace("Rollback failed. Leaving inconstant "
3470 "metadata.\n");
3471 errno = EIO;
3472 return -1;
3473 }
3474 ntfs_inode_mark_dirty(ni);
3475
3476 /*
3477 * Remove record from $ATTRIBUTE_LIST if present and we don't want
3478 * delete $ATTRIBUTE_LIST itself.
3479 */
3480 if (NInoAttrList(base_ni) && type != AT_ATTRIBUTE_LIST) {
3481 if (ntfs_attrlist_entry_rm(ctx)) {
3482 ntfs_log_trace("Couldn't delete record from "
3483 "$ATTRIBUTE_LIST.\n");
3484 return -1;
3485 }
3486 }
3487
3488 /* Post $ATTRIBUTE_LIST delete setup. */
3489 if (type == AT_ATTRIBUTE_LIST) {
3490 if (NInoAttrList(base_ni) && base_ni->attr_list)
3491 free(base_ni->attr_list);
3492 base_ni->attr_list = NULL;
3493 NInoClearAttrList(base_ni);
3494 NInoAttrListClearDirty(base_ni);
3495 }
3496
3497 /* Free MFT record, if it doesn't contain attributes. */
3498 if (le32_to_cpu(ctx->mrec->bytes_in_use) -
3499 le16_to_cpu(ctx->mrec->attrs_offset) == 8) {
3500 if (ntfs_mft_record_free(ni->vol, ni)) {
3501 // FIXME: We need rollback here.
3502 ntfs_log_trace("Couldn't free MFT record.\n");
3503 errno = EIO;
3504 return -1;
3505 }
3506 /* Remove done if we freed base inode. */
3507 if (ni == base_ni)
3508 return 0;
3509 }
3510
3511 if (type == AT_ATTRIBUTE_LIST || !NInoAttrList(base_ni))
3512 return 0;
3513
3514 /* Remove attribute list if we don't need it any more. */
3515 if (!ntfs_attrlist_need(base_ni)) {
3516 ntfs_attr_reinit_search_ctx(ctx);
3517 if (ntfs_attr_lookup(AT_ATTRIBUTE_LIST, NULL, 0, CASE_SENSITIVE,
3518 0, NULL, 0, ctx)) {
3519 /*
3520 * FIXME: Should we succeed here? Definitely something
3521 * goes wrong because NInoAttrList(base_ni) returned
3522 * that we have got attribute list.
3523 */
3524 ntfs_log_trace("Couldn't find attribute list. Succeed "
3525 "anyway.\n");
3526 return 0;
3527 }
3528 /* Deallocate clusters. */
3529 if (ctx->attr->non_resident) {
3530 runlist *al_rl;
3531
3532 al_rl = ntfs_mapping_pairs_decompress(base_ni->vol,
3533 ctx->attr, NULL);
3534 if (!al_rl) {
3535 ntfs_log_trace("Couldn't decompress attribute list "
3536 "runlist. Succeed anyway.\n");
3537 return 0;
3538 }
3539 if (ntfs_cluster_free_from_rl(base_ni->vol, al_rl)) {
3540 ntfs_log_trace("Leaking clusters! Run chkdsk. "
3541 "Couldn't free clusters from "
3542 "attribute list runlist.\n");
3543 }
3544 free(al_rl);
3545 }
3546 /* Remove attribute record itself. */
3547 if (ntfs_attr_record_rm(ctx)) {
3548 /*
3549 * FIXME: Should we succeed here? BTW, chkdsk doesn't
3550 * complain if it find MFT record with attribute list,
3551 * but without extents.
3552 */
3553 ntfs_log_trace("Couldn't remove attribute list. Succeed "
3554 "anyway.\n");
3555 return 0;
3556 }
3557 }
3558 return 0;
3559}
3560
3561/**
3562 * ntfs_attr_add - add attribute to inode
3563 * @ni: opened ntfs inode to which add attribute
3564 * @type: type of the new attribute
3565 * @name: name in unicode of the new attribute
3566 * @name_len: name length in unicode characters of the new attribute
3567 * @val: value of new attribute
3568 * @size: size of the new attribute / length of @val (if specified)
3569 *
3570 * @val should always be specified for always resident attributes (eg. FILE_NAME
3571 * attribute), for attributes that can become non-resident @val can be NULL
3572 * (eg. DATA attribute). @size can be specified even if @val is NULL, in this
3573 * case data size will be equal to @size and initialized size will be equal
3574 * to 0.
3575 *
3576 * If inode haven't got enough space to add attribute, add attribute to one of
3577 * it extents, if no extents present or no one of them have enough space, than
3578 * allocate new extent and add attribute to it.
3579 *
3580 * If on one of this steps attribute list is needed but not present, than it is
3581 * added transparently to caller. So, this function should not be called with
3582 * @type == AT_ATTRIBUTE_LIST, if you really need to add attribute list call
3583 * ntfs_inode_add_attrlist instead.
3584 *
3585 * On success return 0. On error return -1 with errno set to the error code.
3586 */
3587int ntfs_attr_add(ntfs_inode *ni, ATTR_TYPES type,
3588 ntfschar *name, u8 name_len, u8 *val, s64 size)
3589{
3590 u32 attr_rec_size;
3591 int err, i, offset;
3592 BOOL is_resident;
3593 BOOL can_be_non_resident = FALSE;
3594 ntfs_inode *attr_ni;
3595 ntfs_attr *na;
3596 ATTR_FLAGS data_flags;
3597
3598 if (!ni || size < 0 || type == AT_ATTRIBUTE_LIST) {
3599 errno = EINVAL;
3600 ntfs_log_perror("%s: ni=%p size=%lld", __FUNCTION__, ni,
3601 (long long)size);
3602 return -1;
3603 }
3604
3605 ntfs_log_trace("Entering for inode %lld, attr %x, size %lld.\n",
3606 (long long)ni->mft_no, type, (long long)size);
3607
3608 if (ni->nr_extents == -1)
3609 ni = ni->base_ni;
3610
3611 /* Check the attribute type and the size. */
3612 if (ntfs_attr_size_bounds_check(ni->vol, type, size)) {
3613 if (errno == ENOENT)
3614 errno = EIO;
3615 return -1;
3616 }
3617
3618 /* Sanity checks for always resident attributes. */
3619 if (ntfs_attr_can_be_non_resident(ni->vol, type, name, name_len)) {
3620 if (errno != EPERM) {
3621 err = errno;
3622 ntfs_log_perror("ntfs_attr_can_be_non_resident failed");
3623 goto err_out;
3624 }
3625 /* @val is mandatory. */
3626 if (!val) {
3627 errno = EINVAL;
3628 ntfs_log_perror("val is mandatory for always resident "
3629 "attributes");
3630 return -1;
3631 }
3632 if (size > ni->vol->mft_record_size) {
3633 errno = ERANGE;
3634 ntfs_log_perror("Attribute is too big");
3635 return -1;
3636 }
3637 } else
3638 can_be_non_resident = TRUE;
3639
3640 /*
3641 * Determine resident or not will be new attribute. We add 8 to size in
3642 * non resident case for mapping pairs.
3643 */
3644 if (!ntfs_attr_can_be_resident(ni->vol, type)) {
3645 is_resident = TRUE;
3646 } else {
3647 if (errno != EPERM) {
3648 err = errno;
3649 ntfs_log_perror("ntfs_attr_can_be_resident failed");
3650 goto err_out;
3651 }
3652 is_resident = FALSE;
3653 }
3654 /* Calculate attribute record size. */
3655 if (is_resident)
3656 attr_rec_size = offsetof(ATTR_RECORD, resident_end) +
3657 ((name_len * sizeof(ntfschar) + 7) & ~7) +
3658 ((size + 7) & ~7);
3659 else
3660 attr_rec_size = offsetof(ATTR_RECORD, non_resident_end) +
3661 ((name_len * sizeof(ntfschar) + 7) & ~7) + 8;
3662
3663 /*
3664 * If we have enough free space for the new attribute in the base MFT
3665 * record, then add attribute to it.
3666 */
3667 if (le32_to_cpu(ni->mrec->bytes_allocated) -
3668 le32_to_cpu(ni->mrec->bytes_in_use) >= attr_rec_size) {
3669 attr_ni = ni;
3670 goto add_attr_record;
3671 }
3672
3673 /* Try to add to extent inodes. */
3674 if (ntfs_inode_attach_all_extents(ni)) {
3675 err = errno;
3676 ntfs_log_perror("Failed to attach all extents to inode");
3677 goto err_out;
3678 }
3679 for (i = 0; i < ni->nr_extents; i++) {
3680 attr_ni = ni->extent_nis[i];
3681 if (le32_to_cpu(attr_ni->mrec->bytes_allocated) -
3682 le32_to_cpu(attr_ni->mrec->bytes_in_use) >=
3683 attr_rec_size)
3684 goto add_attr_record;
3685 }
3686
3687 /* There is no extent that contain enough space for new attribute. */
3688 if (!NInoAttrList(ni)) {
3689 /* Add attribute list not present, add it and retry. */
3690 if (ntfs_inode_add_attrlist(ni)) {
3691 err = errno;
3692 ntfs_log_perror("Failed to add attribute list");
3693 goto err_out;
3694 }
3695 return ntfs_attr_add(ni, type, name, name_len, val, size);
3696 }
3697 /* Allocate new extent. */
3698 attr_ni = ntfs_mft_record_alloc(ni->vol, ni);
3699 if (!attr_ni) {
3700 err = errno;
3701 ntfs_log_perror("Failed to allocate extent record");
3702 goto err_out;
3703 }
3704
3705add_attr_record:
3706 if ((ni->flags & FILE_ATTR_COMPRESSED)
3707 && (ni->vol->cluster_size <= MAX_COMPRESSION_CLUSTER_SIZE)
3708 && ((type == AT_DATA)
3709 || ((type == AT_INDEX_ROOT) && (name == NTFS_INDEX_I30))))
3710 data_flags = ATTR_IS_COMPRESSED;
3711 else
3712 data_flags = const_cpu_to_le16(0);
3713 if (is_resident) {
3714 /* Add resident attribute. */
3715 offset = ntfs_resident_attr_record_add(attr_ni, type, name,
3716 name_len, val, size, data_flags);
3717 if (offset < 0) {
3718 if (errno == ENOSPC && can_be_non_resident)
3719 goto add_non_resident;
3720 err = errno;
3721 ntfs_log_perror("Failed to add resident attribute");
3722 goto free_err_out;
3723 }
3724 return 0;
3725 }
3726
3727add_non_resident:
3728 /* Add non resident attribute. */
3729 offset = ntfs_non_resident_attr_record_add(attr_ni, type, name,
3730 name_len, 0, 8, data_flags);
3731 if (offset < 0) {
3732 err = errno;
3733 ntfs_log_perror("Failed to add non resident attribute");
3734 goto free_err_out;
3735 }
3736
3737 /* If @size == 0, we are done. */
3738 if (!size)
3739 return 0;
3740
3741 /* Open new attribute and resize it. */
3742 na = ntfs_attr_open(ni, type, name, name_len);
3743 if (!na) {
3744 err = errno;
3745 ntfs_log_perror("Failed to open just added attribute");
3746 goto rm_attr_err_out;
3747 }
3748 /* Resize and set attribute value. */
3749 if (ntfs_attr_truncate(na, size) ||
3750 (val && (ntfs_attr_pwrite(na, 0, size, val) != size))) {
3751 err = errno;
3752 ntfs_log_perror("Failed to initialize just added attribute");
3753 if (ntfs_attr_rm(na))
3754 ntfs_log_perror("Failed to remove just added attribute");
3755 ntfs_attr_close(na);
3756 goto err_out;
3757 }
3758 ntfs_attr_close(na);
3759 return 0;
3760
3761rm_attr_err_out:
3762 /* Remove just added attribute. */
3763 if (ntfs_attr_record_resize(attr_ni->mrec,
3764 (ATTR_RECORD*)((u8*)attr_ni->mrec + offset), 0))
3765 ntfs_log_perror("Failed to remove just added attribute #2");
3766free_err_out:
3767 /* Free MFT record, if it doesn't contain attributes. */
3768 if (le32_to_cpu(attr_ni->mrec->bytes_in_use) -
3769 le16_to_cpu(attr_ni->mrec->attrs_offset) == 8)
3770 if (ntfs_mft_record_free(attr_ni->vol, attr_ni))
3771 ntfs_log_perror("Failed to free MFT record");
3772err_out:
3773 errno = err;
3774 return -1;
3775}
3776
3777/*
3778 * Change an attribute flag
3779 */
3780
3781int ntfs_attr_set_flags(ntfs_inode *ni, ATTR_TYPES type,
3782 ntfschar *name, u8 name_len, ATTR_FLAGS flags, ATTR_FLAGS mask)
3783{
3784 ntfs_attr_search_ctx *ctx;
3785 int res;
3786
3787 res = -1;
3788 /* Search for designated attribute */
3789 ctx = ntfs_attr_get_search_ctx(ni, NULL);
3790 if (ctx) {
3791 if (!ntfs_attr_lookup(type, name, name_len,
3792 CASE_SENSITIVE, 0, NULL, 0, ctx)) {
3793 /* do the requested change (all small endian le16) */
3794 ctx->attr->flags = (ctx->attr->flags & ~mask)
3795 | (flags & mask);
3796 NInoSetDirty(ni);
3797 res = 0;
3798 }
3799 ntfs_attr_put_search_ctx(ctx);
3800 }
3801 return (res);
3802}
3803
3804
3805/**
3806 * ntfs_attr_rm - remove attribute from ntfs inode
3807 * @na: opened ntfs attribute to delete
3808 *
3809 * Remove attribute and all it's extents from ntfs inode. If attribute was non
3810 * resident also free all clusters allocated by attribute.
3811 *
3812 * Return 0 on success or -1 on error with errno set to the error code.
3813 */
3814int ntfs_attr_rm(ntfs_attr *na)
3815{
3816 ntfs_attr_search_ctx *ctx;
3817 int ret = 0;
3818
3819 if (!na) {
3820 ntfs_log_trace("Invalid arguments passed.\n");
3821 errno = EINVAL;
3822 return -1;
3823 }
3824
3825 ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x.\n",
3826 (long long) na->ni->mft_no, na->type);
3827
3828 /* Free cluster allocation. */
3829 if (NAttrNonResident(na)) {
3830 if (ntfs_attr_map_whole_runlist(na))
3831 return -1;
3832 if (ntfs_cluster_free(na->ni->vol, na, 0, -1) < 0) {
3833 ntfs_log_trace("Failed to free cluster allocation. Leaving "
3834 "inconstant metadata.\n");
3835 ret = -1;
3836 }
3837 }
3838
3839 /* Search for attribute extents and remove them all. */
3840 ctx = ntfs_attr_get_search_ctx(na->ni, NULL);
3841 if (!ctx)
3842 return -1;
3843 while (!ntfs_attr_lookup(na->type, na->name, na->name_len,
3844 CASE_SENSITIVE, 0, NULL, 0, ctx)) {
3845 if (ntfs_attr_record_rm(ctx)) {
3846 ntfs_log_trace("Failed to remove attribute extent. Leaving "
3847 "inconstant metadata.\n");
3848 ret = -1;
3849 }
3850 ntfs_attr_reinit_search_ctx(ctx);
3851 }
3852 ntfs_attr_put_search_ctx(ctx);
3853 if (errno != ENOENT) {
3854 ntfs_log_trace("Attribute lookup failed. Probably leaving inconstant "
3855 "metadata.\n");
3856 ret = -1;
3857 }
3858
3859 return ret;
3860}
3861
3862/**
3863 * ntfs_attr_record_resize - resize an attribute record
3864 * @m: mft record containing attribute record
3865 * @a: attribute record to resize
3866 * @new_size: new size in bytes to which to resize the attribute record @a
3867 *
3868 * Resize the attribute record @a, i.e. the resident part of the attribute, in
3869 * the mft record @m to @new_size bytes.
3870 *
3871 * Return 0 on success and -1 on error with errno set to the error code.
3872 * The following error codes are defined:
3873 * ENOSPC - Not enough space in the mft record @m to perform the resize.
3874 * Note that on error no modifications have been performed whatsoever.
3875 *
3876 * Warning: If you make a record smaller without having copied all the data you
3877 * are interested in the data may be overwritten!
3878 */
3879int ntfs_attr_record_resize(MFT_RECORD *m, ATTR_RECORD *a, u32 new_size)
3880{
3881 u32 old_size, alloc_size, attr_size;
3882
3883 old_size = le32_to_cpu(m->bytes_in_use);
3884 alloc_size = le32_to_cpu(m->bytes_allocated);
3885 attr_size = le32_to_cpu(a->length);
3886
3887 ntfs_log_trace("Sizes: old=%u alloc=%u attr=%u new=%u\n",
3888 (unsigned)old_size, (unsigned)alloc_size,
3889 (unsigned)attr_size, (unsigned)new_size);
3890
3891 /* Align to 8 bytes, just in case the caller hasn't. */
3892 new_size = (new_size + 7) & ~7;
3893
3894 /* If the actual attribute length has changed, move things around. */
3895 if (new_size != attr_size) {
3896
3897 u32 new_muse = old_size - attr_size + new_size;
3898
3899 /* Not enough space in this mft record. */
3900 if (new_muse > alloc_size) {
3901 errno = ENOSPC;
3902 ntfs_log_trace("Not enough space in the MFT record "
3903 "(%u > %u)\n", new_muse, alloc_size);
3904 return -1;
3905 }
3906
3907 if (a->type == AT_INDEX_ROOT && new_size > attr_size &&
3908 new_muse + 120 > alloc_size && old_size + 120 <= alloc_size) {
3909 errno = ENOSPC;
3910 ntfs_log_trace("Too big INDEX_ROOT (%u > %u)\n",
3911 new_muse, alloc_size);
3912 return STATUS_RESIDENT_ATTRIBUTE_FILLED_MFT;
3913 }
3914
3915 /* Move attributes following @a to their new location. */
3916 memmove((u8 *)a + new_size, (u8 *)a + attr_size,
3917 old_size - ((u8 *)a - (u8 *)m) - attr_size);
3918
3919 /* Adjust @m to reflect the change in used space. */
3920 m->bytes_in_use = cpu_to_le32(new_muse);
3921
3922 /* Adjust @a to reflect the new size. */
3923 if (new_size >= offsetof(ATTR_REC, length) + sizeof(a->length))
3924 a->length = cpu_to_le32(new_size);
3925 }
3926 return 0;
3927}
3928
3929/**
3930 * ntfs_resident_attr_value_resize - resize the value of a resident attribute
3931 * @m: mft record containing attribute record
3932 * @a: attribute record whose value to resize
3933 * @new_size: new size in bytes to which to resize the attribute value of @a
3934 *
3935 * Resize the value of the attribute @a in the mft record @m to @new_size bytes.
3936 * If the value is made bigger, the newly "allocated" space is cleared.
3937 *
3938 * Return 0 on success and -1 on error with errno set to the error code.
3939 * The following error codes are defined:
3940 * ENOSPC - Not enough space in the mft record @m to perform the resize.
3941 * Note that on error no modifications have been performed whatsoever.
3942 */
3943int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a,
3944 const u32 new_size)
3945{
3946 int ret;
3947
3948 ntfs_log_trace("Entering for new size %u.\n", (unsigned)new_size);
3949
3950 /* Resize the resident part of the attribute record. */
3951 if ((ret = ntfs_attr_record_resize(m, a, (le16_to_cpu(a->value_offset) +
3952 new_size + 7) & ~7)) < 0)
3953 return ret;
3954 /*
3955 * If we made the attribute value bigger, clear the area between the
3956 * old size and @new_size.
3957 */
3958 if (new_size > le32_to_cpu(a->value_length))
3959 memset((u8*)a + le16_to_cpu(a->value_offset) +
3960 le32_to_cpu(a->value_length), 0, new_size -
3961 le32_to_cpu(a->value_length));
3962 /* Finally update the length of the attribute value. */
3963 a->value_length = cpu_to_le32(new_size);
3964 return 0;
3965}
3966
3967/**
3968 * ntfs_attr_record_move_to - move attribute record to target inode
3969 * @ctx: attribute search context describing the attribute record
3970 * @ni: opened ntfs inode to which move attribute record
3971 *
3972 * If this function succeed, user should reinit search context if he/she wants
3973 * use it anymore.
3974 *
3975 * Return 0 on success and -1 on error with errno set to the error code.
3976 */
3977int ntfs_attr_record_move_to(ntfs_attr_search_ctx *ctx, ntfs_inode *ni)
3978{
3979 ntfs_attr_search_ctx *nctx;
3980 ATTR_RECORD *a;
3981 int err;
3982
3983 if (!ctx || !ctx->attr || !ctx->ntfs_ino || !ni) {
3984 ntfs_log_trace("Invalid arguments passed.\n");
3985 errno = EINVAL;
3986 return -1;
3987 }
3988
3989 ntfs_log_trace("Entering for ctx->attr->type 0x%x, ctx->ntfs_ino->mft_no "
3990 "0x%llx, ni->mft_no 0x%llx.\n",
3991 (unsigned) le32_to_cpu(ctx->attr->type),
3992 (long long) ctx->ntfs_ino->mft_no,
3993 (long long) ni->mft_no);
3994
3995 if (ctx->ntfs_ino == ni)
3996 return 0;
3997
3998 if (!ctx->al_entry) {
3999 ntfs_log_trace("Inode should contain attribute list to use this "
4000 "function.\n");
4001 errno = EINVAL;
4002 return -1;
4003 }
4004
4005 /* Find place in MFT record where attribute will be moved. */
4006 a = ctx->attr;
4007 nctx = ntfs_attr_get_search_ctx(ni, NULL);
4008 if (!nctx)
4009 return -1;
4010
4011 /*
4012 * Use ntfs_attr_find instead of ntfs_attr_lookup to find place for
4013 * attribute in @ni->mrec, not any extent inode in case if @ni is base
4014 * file record.
4015 */
4016 if (!ntfs_attr_find(a->type, (ntfschar*)((u8*)a + le16_to_cpu(
4017 a->name_offset)), a->name_length, CASE_SENSITIVE, NULL,
4018 0, nctx)) {
4019 ntfs_log_trace("Attribute of such type, with same name already "
4020 "present in this MFT record.\n");
4021 err = EEXIST;
4022 goto put_err_out;
4023 }
4024 if (errno != ENOENT) {
4025 err = errno;
4026 ntfs_log_debug("Attribute lookup failed.\n");
4027 goto put_err_out;
4028 }
4029
4030 /* Make space and move attribute. */
4031 if (ntfs_make_room_for_attr(ni->mrec, (u8*) nctx->attr,
4032 le32_to_cpu(a->length))) {
4033 err = errno;
4034 ntfs_log_trace("Couldn't make space for attribute.\n");
4035 goto put_err_out;
4036 }
4037 memcpy(nctx->attr, a, le32_to_cpu(a->length));
4038 nctx->attr->instance = nctx->mrec->next_attr_instance;
4039 nctx->mrec->next_attr_instance = cpu_to_le16(
4040 (le16_to_cpu(nctx->mrec->next_attr_instance) + 1) & 0xffff);
4041 ntfs_attr_record_resize(ctx->mrec, a, 0);
4042 ntfs_inode_mark_dirty(ctx->ntfs_ino);
4043 ntfs_inode_mark_dirty(ni);
4044
4045 /* Update attribute list. */
4046 ctx->al_entry->mft_reference =
4047 MK_LE_MREF(ni->mft_no, le16_to_cpu(ni->mrec->sequence_number));
4048 ctx->al_entry->instance = nctx->attr->instance;
4049 ntfs_attrlist_mark_dirty(ni);
4050
4051 ntfs_attr_put_search_ctx(nctx);
4052 return 0;
4053put_err_out:
4054 ntfs_attr_put_search_ctx(nctx);
4055 errno = err;
4056 return -1;
4057}
4058
4059/**
4060 * ntfs_attr_record_move_away - move away attribute record from it's mft record
4061 * @ctx: attribute search context describing the attribute record
4062 * @extra: minimum amount of free space in the new holder of record
4063 *
4064 * New attribute record holder must have free @extra bytes after moving
4065 * attribute record to it.
4066 *
4067 * If this function succeed, user should reinit search context if he/she wants
4068 * use it anymore.
4069 *
4070 * Return 0 on success and -1 on error with errno set to the error code.
4071 */
4072int ntfs_attr_record_move_away(ntfs_attr_search_ctx *ctx, int extra)
4073{
4074 ntfs_inode *base_ni, *ni;
4075 MFT_RECORD *m;
4076 int i;
4077
4078 if (!ctx || !ctx->attr || !ctx->ntfs_ino || extra < 0) {
4079 errno = EINVAL;
4080 ntfs_log_perror("%s: ctx=%p ctx->attr=%p extra=%d", __FUNCTION__,
4081 ctx, ctx ? ctx->attr : NULL, extra);
4082 return -1;
4083 }
4084
4085 ntfs_log_trace("Entering for attr 0x%x, inode %llu\n",
4086 (unsigned) le32_to_cpu(ctx->attr->type),
4087 (unsigned long long)ctx->ntfs_ino->mft_no);
4088
4089 if (ctx->ntfs_ino->nr_extents == -1)
4090 base_ni = ctx->base_ntfs_ino;
4091 else
4092 base_ni = ctx->ntfs_ino;
4093
4094 if (!NInoAttrList(base_ni)) {
4095 errno = EINVAL;
4096 ntfs_log_perror("Inode %llu has no attrlist",
4097 (unsigned long long)base_ni->mft_no);
4098 return -1;
4099 }
4100
4101 if (ntfs_inode_attach_all_extents(ctx->ntfs_ino)) {
4102 ntfs_log_perror("Couldn't attach extents, inode=%llu",
4103 (unsigned long long)base_ni->mft_no);
4104 return -1;
4105 }
4106
4107 /* Walk through all extents and try to move attribute to them. */
4108 for (i = 0; i < base_ni->nr_extents; i++) {
4109 ni = base_ni->extent_nis[i];
4110 m = ni->mrec;
4111
4112 if (ctx->ntfs_ino->mft_no == ni->mft_no)
4113 continue;
4114
4115 if (le32_to_cpu(m->bytes_allocated) -
4116 le32_to_cpu(m->bytes_in_use) <
4117 le32_to_cpu(ctx->attr->length) + extra)
4118 continue;
4119
4120 /*
4121 * ntfs_attr_record_move_to can fail if extent with other lowest
4122 * VCN already present in inode we trying move record to. So,
4123 * do not return error.
4124 */
4125 if (!ntfs_attr_record_move_to(ctx, ni))
4126 return 0;
4127 }
4128
4129 /*
4130 * Failed to move attribute to one of the current extents, so allocate
4131 * new extent and move attribute to it.
4132 */
4133 ni = ntfs_mft_record_alloc(base_ni->vol, base_ni);
4134 if (!ni) {
4135 ntfs_log_perror("Couldn't allocate MFT record");
4136 return -1;
4137 }
4138 if (ntfs_attr_record_move_to(ctx, ni)) {
4139 ntfs_log_perror("Couldn't move attribute to MFT record");
4140 return -1;
4141 }
4142 return 0;
4143}
4144
4145/**
4146 * ntfs_attr_make_non_resident - convert a resident to a non-resident attribute
4147 * @na: open ntfs attribute to make non-resident
4148 * @ctx: ntfs search context describing the attribute
4149 *
4150 * Convert a resident ntfs attribute to a non-resident one.
4151 *
4152 * Return 0 on success and -1 on error with errno set to the error code. The
4153 * following error codes are defined:
4154 * EPERM - The attribute is not allowed to be non-resident.
4155 * TODO: others...
4156 *
4157 * NOTE to self: No changes in the attribute list are required to move from
4158 * a resident to a non-resident attribute.
4159 *
4160 * Warning: We do not set the inode dirty and we do not write out anything!
4161 * We expect the caller to do this as this is a fairly low level
4162 * function and it is likely there will be further changes made.
4163 */
4164int ntfs_attr_make_non_resident(ntfs_attr *na,
4165 ntfs_attr_search_ctx *ctx)
4166{
4167 s64 new_allocated_size, bw;
4168 ntfs_volume *vol = na->ni->vol;
4169 ATTR_REC *a = ctx->attr;
4170 runlist *rl;
4171 int mp_size, mp_ofs, name_ofs, arec_size, err;
4172
4173 ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x.\n", (unsigned long
4174 long)na->ni->mft_no, na->type);
4175
4176 /* Some preliminary sanity checking. */
4177 if (NAttrNonResident(na)) {
4178 ntfs_log_trace("Eeek! Trying to make non-resident attribute "
4179 "non-resident. Aborting...\n");
4180 errno = EINVAL;
4181 return -1;
4182 }
4183
4184 /* Check that the attribute is allowed to be non-resident. */
4185 if (ntfs_attr_can_be_non_resident(vol, na->type, na->name, na->name_len))
4186 return -1;
4187
4188 new_allocated_size = (le32_to_cpu(a->value_length) + vol->cluster_size
4189 - 1) & ~(vol->cluster_size - 1);
4190
4191 if (new_allocated_size > 0) {
4192 /* Start by allocating clusters to hold the attribute value. */
4193 rl = ntfs_cluster_alloc(vol, 0, new_allocated_size >>
4194 vol->cluster_size_bits, -1, DATA_ZONE);
4195 if (!rl)
4196 return -1;
4197 } else
4198 rl = NULL;
4199 /*
4200 * Setup the in-memory attribute structure to be non-resident so that
4201 * we can use ntfs_attr_pwrite().
4202 */
4203 NAttrSetNonResident(na);
4204 na->rl = rl;
4205 na->allocated_size = new_allocated_size;
4206 na->data_size = na->initialized_size = le32_to_cpu(a->value_length);
4207 /*
4208 * FIXME: For now just clear all of these as we don't support them when
4209 * writing.
4210 */
4211 NAttrClearSparse(na);
4212 NAttrClearEncrypted(na);
4213 if ((a->flags & ATTR_COMPRESSION_MASK) == ATTR_IS_COMPRESSED) {
4214 /* set compression writing parameters */
4215 na->compression_block_size
4216 = 1 << (STANDARD_COMPRESSION_UNIT + vol->cluster_size_bits);
4217 na->compression_block_clusters = 1 << STANDARD_COMPRESSION_UNIT;
4218 }
4219
4220 if (rl) {
4221 /* Now copy the attribute value to the allocated cluster(s). */
4222 bw = ntfs_attr_pwrite(na, 0, le32_to_cpu(a->value_length),
4223 (u8*)a + le16_to_cpu(a->value_offset));
4224 if (bw != le32_to_cpu(a->value_length)) {
4225 err = errno;
4226 ntfs_log_debug("Eeek! Failed to write out attribute value "
4227 "(bw = %lli, errno = %i). "
4228 "Aborting...\n", (long long)bw, err);
4229 if (bw >= 0)
4230 err = EIO;
4231 goto cluster_free_err_out;
4232 }
4233 }
4234 /* Determine the size of the mapping pairs array. */
4235 mp_size = ntfs_get_size_for_mapping_pairs(vol, rl, 0, INT_MAX);
4236 if (mp_size < 0) {
4237 err = errno;
4238 ntfs_log_debug("Eeek! Failed to get size for mapping pairs array. "
4239 "Aborting...\n");
4240 goto cluster_free_err_out;
4241 }
4242 /* Calculate new offsets for the name and the mapping pairs array. */
4243 if (na->ni->flags & FILE_ATTR_COMPRESSED)
4244 name_ofs = (sizeof(ATTR_REC) + 7) & ~7;
4245 else
4246 name_ofs = (sizeof(ATTR_REC) - sizeof(a->compressed_size) + 7) & ~7;
4247 mp_ofs = (name_ofs + a->name_length * sizeof(ntfschar) + 7) & ~7;
4248 /*
4249 * Determine the size of the resident part of the non-resident
4250 * attribute record. (Not compressed thus no compressed_size element
4251 * present.)
4252 */
4253 arec_size = (mp_ofs + mp_size + 7) & ~7;
4254
4255 /* Resize the resident part of the attribute record. */
4256 if (ntfs_attr_record_resize(ctx->mrec, a, arec_size) < 0) {
4257 err = errno;
4258 goto cluster_free_err_out;
4259 }
4260
4261 /*
4262 * Convert the resident part of the attribute record to describe a
4263 * non-resident attribute.
4264 */
4265 a->non_resident = 1;
4266
4267 /* Move the attribute name if it exists and update the offset. */
4268 if (a->name_length)
4269 memmove((u8*)a + name_ofs, (u8*)a + le16_to_cpu(a->name_offset),
4270 a->name_length * sizeof(ntfschar));
4271 a->name_offset = cpu_to_le16(name_ofs);
4272
4273 /* Setup the fields specific to non-resident attributes. */
4274 a->lowest_vcn = cpu_to_sle64(0);
4275 a->highest_vcn = cpu_to_sle64((new_allocated_size - 1) >>
4276 vol->cluster_size_bits);
4277
4278 a->mapping_pairs_offset = cpu_to_le16(mp_ofs);
4279
4280 /*
4281 * Update the flags to match the in-memory ones.
4282 * However cannot change the compression state if we had
4283 * a fuse_file_info open with a mark for release.
4284 * The decisions about compression can only be made when
4285 * creating/recreating the stream, not when making non resident.
4286 */
4287 a->flags &= ~(ATTR_IS_SPARSE | ATTR_IS_ENCRYPTED);
4288 if ((a->flags & ATTR_COMPRESSION_MASK) == ATTR_IS_COMPRESSED) {
4289 /* support only ATTR_IS_COMPRESSED compression mode */
4290 a->compression_unit = STANDARD_COMPRESSION_UNIT;
4291 a->compressed_size = const_cpu_to_le64(0);
4292 } else {
4293 a->compression_unit = 0;
4294 a->flags &= ~ATTR_COMPRESSION_MASK;
4295 na->data_flags = a->flags;
4296 }
4297
4298 memset(&a->reserved1, 0, sizeof(a->reserved1));
4299
4300 a->allocated_size = cpu_to_sle64(new_allocated_size);
4301 a->data_size = a->initialized_size = cpu_to_sle64(na->data_size);
4302
4303 /* Generate the mapping pairs array in the attribute record. */
4304 if (ntfs_mapping_pairs_build(vol, (u8*)a + mp_ofs, arec_size - mp_ofs,
4305 rl, 0, NULL) < 0) {
4306 // FIXME: Eeek! We need rollback! (AIA)
4307 ntfs_log_trace("Eeek! Failed to build mapping pairs. Leaving "
4308 "corrupt attribute record on disk. In memory "
4309 "runlist is still intact! Error code is %i. "
4310 "FIXME: Need to rollback instead!\n", errno);
4311 return -1;
4312 }
4313
4314 /* Done! */
4315 return 0;
4316
4317cluster_free_err_out:
4318 if (rl && ntfs_cluster_free(vol, na, 0, -1) < 0)
4319 ntfs_log_trace("Eeek! Failed to release allocated clusters in error "
4320 "code path. Leaving inconsistent metadata...\n");
4321 NAttrClearNonResident(na);
4322 na->allocated_size = na->data_size;
4323 na->rl = NULL;
4324 free(rl);
4325 errno = err;
4326 return -1;
4327}
4328
4329
4330static int ntfs_resident_attr_resize(ntfs_attr *na, const s64 newsize);
4331
4332/**
4333 * ntfs_resident_attr_resize - resize a resident, open ntfs attribute
4334 * @na: resident ntfs attribute to resize
4335 * @newsize: new size (in bytes) to which to resize the attribute
4336 *
4337 * Change the size of a resident, open ntfs attribute @na to @newsize bytes.
4338 *
4339 * On success return 0
4340 * On error return values are:
4341 * STATUS_RESIDENT_ATTRIBUTE_FILLED_MFT
4342 * STATUS_ERROR - otherwise
4343 * The following error codes are defined:
4344 * ENOMEM - Not enough memory to complete operation.
4345 * ERANGE - @newsize is not valid for the attribute type of @na.
4346 * ENOSPC - There is no enough space in base mft to resize $ATTRIBUTE_LIST.
4347 */
4348static int ntfs_resident_attr_resize_i(ntfs_attr *na, const s64 newsize)
4349{
4350 ntfs_attr_search_ctx *ctx;
4351 ntfs_volume *vol;
4352 ntfs_inode *ni;
4353 int err, ret = STATUS_ERROR;
4354
4355 ntfs_log_trace("Inode 0x%llx attr 0x%x new size %lld\n",
4356 (unsigned long long)na->ni->mft_no, na->type,
4357 (long long)newsize);
4358
4359 /* Get the attribute record that needs modification. */
4360 ctx = ntfs_attr_get_search_ctx(na->ni, NULL);
4361 if (!ctx)
4362 return -1;
4363 if (ntfs_attr_lookup(na->type, na->name, na->name_len, 0, 0, NULL, 0,
4364 ctx)) {
4365 err = errno;
4366 ntfs_log_perror("ntfs_attr_lookup failed");
4367 goto put_err_out;
4368 }
4369 vol = na->ni->vol;
4370 /*
4371 * Check the attribute type and the corresponding minimum and maximum
4372 * sizes against @newsize and fail if @newsize is out of bounds.
4373 */
4374 if (ntfs_attr_size_bounds_check(vol, na->type, newsize) < 0) {
4375 err = errno;
4376 if (err == ENOENT)
4377 err = EIO;
4378 ntfs_log_perror("%s: bounds check failed", __FUNCTION__);
4379 goto put_err_out;
4380 }
4381 /*
4382 * If @newsize is bigger than the mft record we need to make the
4383 * attribute non-resident if the attribute type supports it. If it is
4384 * smaller we can go ahead and attempt the resize.
4385 */
4386 if (newsize < vol->mft_record_size) {
4387 /* Perform the resize of the attribute record. */
4388 if (!(ret = ntfs_resident_attr_value_resize(ctx->mrec, ctx->attr,
4389 newsize))) {
4390 /* Update attribute size everywhere. */
4391 na->data_size = na->initialized_size = newsize;
4392 na->allocated_size = (newsize + 7) & ~7;
4393 if ((na->data_flags & ATTR_COMPRESSION_MASK)
4394 || NAttrSparse(na))
4395 na->compressed_size = na->allocated_size;
4396 if (na->ni->mrec->flags & MFT_RECORD_IS_DIRECTORY
4397 ? na->type == AT_INDEX_ROOT && na->name == NTFS_INDEX_I30
4398 : na->type == AT_DATA && na->name == AT_UNNAMED) {
4399 na->ni->data_size = na->data_size;
4400 na->ni->allocated_size = na->allocated_size;
4401 set_nino_flag(na->ni,KnownSize);
4402 if (na->type == AT_DATA)
4403 NInoFileNameSetDirty(na->ni);
4404 }
4405 goto resize_done;
4406 }
4407 /* Prefer AT_INDEX_ALLOCATION instead of AT_ATTRIBUTE_LIST */
4408 if (ret == STATUS_RESIDENT_ATTRIBUTE_FILLED_MFT) {
4409 err = errno;
4410 goto put_err_out;
4411 }
4412 }
4413 /* There is not enough space in the mft record to perform the resize. */
4414
4415 /* Make the attribute non-resident if possible. */
4416 if (!ntfs_attr_make_non_resident(na, ctx)) {
4417 ntfs_inode_mark_dirty(ctx->ntfs_ino);
4418 ntfs_attr_put_search_ctx(ctx);
4419 /* Resize non-resident attribute */
4420 return ntfs_attr_truncate(na, newsize);
4421 } else if (errno != ENOSPC && errno != EPERM) {
4422 err = errno;
4423 ntfs_log_perror("Failed to make attribute non-resident");
4424 goto put_err_out;
4425 }
4426
4427 /* Try to make other attributes non-resident and retry each time. */
4428 ntfs_attr_init_search_ctx(ctx, NULL, na->ni->mrec);
4429 while (!ntfs_attr_lookup(AT_UNUSED, NULL, 0, 0, 0, NULL, 0, ctx)) {
4430 ntfs_attr *tna;
4431 ATTR_RECORD *a;
4432
4433 a = ctx->attr;
4434 if (a->non_resident)
4435 continue;
4436
4437 /*
4438 * Check out whether convert is reasonable. Assume that mapping
4439 * pairs will take 8 bytes.
4440 */
4441 if (le32_to_cpu(a->length) <= offsetof(ATTR_RECORD,
4442 compressed_size) + ((a->name_length *
4443 sizeof(ntfschar) + 7) & ~7) + 8)
4444 continue;
4445
4446 tna = ntfs_attr_open(na->ni, a->type, (ntfschar*)((u8*)a +
4447 le16_to_cpu(a->name_offset)), a->name_length);
4448 if (!tna) {
4449 err = errno;
4450 ntfs_log_perror("Couldn't open attribute");
4451 goto put_err_out;
4452 }
4453 if (ntfs_attr_make_non_resident(tna, ctx)) {
4454 ntfs_attr_close(tna);
4455 continue;
4456 }
4457 ntfs_inode_mark_dirty(tna->ni);
4458 ntfs_attr_close(tna);
4459 ntfs_attr_put_search_ctx(ctx);
4460 return ntfs_resident_attr_resize(na, newsize);
4461 }
4462 /* Check whether error occurred. */
4463 if (errno != ENOENT) {
4464 err = errno;
4465 ntfs_log_perror("%s: Attribute lookup failed 1", __FUNCTION__);
4466 goto put_err_out;
4467 }
4468
4469 /*
4470 * The standard information and attribute list attributes can't be
4471 * moved out from the base MFT record, so try to move out others.
4472 */
4473 if (na->type==AT_STANDARD_INFORMATION || na->type==AT_ATTRIBUTE_LIST) {
4474 ntfs_attr_put_search_ctx(ctx);
4475 if (ntfs_inode_free_space(na->ni, offsetof(ATTR_RECORD,
4476 non_resident_end) + 8)) {
4477 ntfs_log_perror("Could not free space in MFT record");
4478 return -1;
4479 }
4480 return ntfs_resident_attr_resize(na, newsize);
4481 }
4482
4483 /*
4484 * Move the attribute to a new mft record, creating an attribute list
4485 * attribute or modifying it if it is already present.
4486 */
4487
4488 /* Point search context back to attribute which we need resize. */
4489 ntfs_attr_init_search_ctx(ctx, na->ni, NULL);
4490 if (ntfs_attr_lookup(na->type, na->name, na->name_len, CASE_SENSITIVE,
4491 0, NULL, 0, ctx)) {
4492 ntfs_log_perror("%s: Attribute lookup failed 2", __FUNCTION__);
4493 err = errno;
4494 goto put_err_out;
4495 }
4496
4497 /*
4498 * Check whether attribute is already single in this MFT record.
4499 * 8 added for the attribute terminator.
4500 */
4501 if (le32_to_cpu(ctx->mrec->bytes_in_use) ==
4502 le16_to_cpu(ctx->mrec->attrs_offset) +
4503 le32_to_cpu(ctx->attr->length) + 8) {
4504 err = ENOSPC;
4505 ntfs_log_trace("MFT record is filled with one attribute\n");
4506 ret = STATUS_RESIDENT_ATTRIBUTE_FILLED_MFT;
4507 goto put_err_out;
4508 }
4509
4510 /* Add attribute list if not present. */
4511 if (na->ni->nr_extents == -1)
4512 ni = na->ni->base_ni;
4513 else
4514 ni = na->ni;
4515 if (!NInoAttrList(ni)) {
4516 ntfs_attr_put_search_ctx(ctx);
4517 if (ntfs_inode_add_attrlist(ni))
4518 return -1;
4519 return ntfs_resident_attr_resize(na, newsize);
4520 }
4521 /* Allocate new mft record. */
4522 ni = ntfs_mft_record_alloc(vol, ni);
4523 if (!ni) {
4524 err = errno;
4525 ntfs_log_perror("Couldn't allocate new MFT record");
4526 goto put_err_out;
4527 }
4528 /* Move attribute to it. */
4529 if (ntfs_attr_record_move_to(ctx, ni)) {
4530 err = errno;
4531 ntfs_log_perror("Couldn't move attribute to new MFT record");
4532 goto put_err_out;
4533 }
4534 /* Update ntfs attribute. */
4535 if (na->ni->nr_extents == -1)
4536 na->ni = ni;
4537
4538 ntfs_attr_put_search_ctx(ctx);
4539 /* Try to perform resize once again. */
4540 return ntfs_resident_attr_resize(na, newsize);
4541
4542resize_done:
4543 /*
4544 * Set the inode (and its base inode if it exists) dirty so it is
4545 * written out later.
4546 */
4547 ntfs_inode_mark_dirty(ctx->ntfs_ino);
4548 ntfs_attr_put_search_ctx(ctx);
4549 return 0;
4550put_err_out:
4551 ntfs_attr_put_search_ctx(ctx);
4552 errno = err;
4553 return ret;
4554}
4555
4556static int ntfs_resident_attr_resize(ntfs_attr *na, const s64 newsize)
4557{
4558 int ret;
4559
4560 ntfs_log_enter("Entering\n");
4561 ret = ntfs_resident_attr_resize_i(na, newsize);
4562 ntfs_log_leave("\n");
4563 return ret;
4564}
4565
4566/**
4567 * ntfs_attr_make_resident - convert a non-resident to a resident attribute
4568 * @na: open ntfs attribute to make resident
4569 * @ctx: ntfs search context describing the attribute
4570 *
4571 * Convert a non-resident ntfs attribute to a resident one.
4572 *
4573 * Return 0 on success and -1 on error with errno set to the error code. The
4574 * following error codes are defined:
4575 * EINVAL - Invalid arguments passed.
4576 * EPERM - The attribute is not allowed to be resident.
4577 * EIO - I/O error, damaged inode or bug.
4578 * ENOSPC - There is no enough space to perform conversion.
4579 * EOPNOTSUPP - Requested conversion is not supported yet.
4580 *
4581 * Warning: We do not set the inode dirty and we do not write out anything!
4582 * We expect the caller to do this as this is a fairly low level
4583 * function and it is likely there will be further changes made.
4584 */
4585static int ntfs_attr_make_resident(ntfs_attr *na, ntfs_attr_search_ctx *ctx)
4586{
4587 ntfs_volume *vol = na->ni->vol;
4588 ATTR_REC *a = ctx->attr;
4589 int name_ofs, val_ofs, err = EIO;
4590 s64 arec_size, bytes_read;
4591
4592 ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x.\n", (unsigned long
4593 long)na->ni->mft_no, na->type);
4594
4595 /* Should be called for the first extent of the attribute. */
4596 if (sle64_to_cpu(a->lowest_vcn)) {
4597 ntfs_log_trace("Eeek! Should be called for the first extent of the "
4598 "attribute. Aborting...\n");
4599 errno = EINVAL;
4600 return -1;
4601 }
4602
4603 /* Some preliminary sanity checking. */
4604 if (!NAttrNonResident(na)) {
4605 ntfs_log_trace("Eeek! Trying to make resident attribute resident. "
4606 "Aborting...\n");
4607 errno = EINVAL;
4608 return -1;
4609 }
4610
4611 /* Make sure this is not $MFT/$BITMAP or Windows will not boot! */
4612 if (na->type == AT_BITMAP && na->ni->mft_no == FILE_MFT) {
4613 errno = EPERM;
4614 return -1;
4615 }
4616
4617 /* Check that the attribute is allowed to be resident. */
4618 if (ntfs_attr_can_be_resident(vol, na->type))
4619 return -1;
4620
4621 if (na->data_flags & ATTR_IS_ENCRYPTED) {
4622 ntfs_log_trace("Making encrypted streams resident is not "
4623 "implemented yet.\n");
4624 errno = EOPNOTSUPP;
4625 return -1;
4626 }
4627
4628 /* Work out offsets into and size of the resident attribute. */
4629 name_ofs = 24; /* = sizeof(resident_ATTR_REC); */
4630 val_ofs = (name_ofs + a->name_length * sizeof(ntfschar) + 7) & ~7;
4631 arec_size = (val_ofs + na->data_size + 7) & ~7;
4632
4633 /* Sanity check the size before we start modifying the attribute. */
4634 if (le32_to_cpu(ctx->mrec->bytes_in_use) - le32_to_cpu(a->length) +
4635 arec_size > le32_to_cpu(ctx->mrec->bytes_allocated)) {
4636 errno = ENOSPC;
4637 ntfs_log_trace("Not enough space to make attribute resident\n");
4638 return -1;
4639 }
4640
4641 /* Read and cache the whole runlist if not already done. */
4642 if (ntfs_attr_map_whole_runlist(na))
4643 return -1;
4644
4645 /* Move the attribute name if it exists and update the offset. */
4646 if (a->name_length) {
4647 memmove((u8*)a + name_ofs, (u8*)a + le16_to_cpu(a->name_offset),
4648 a->name_length * sizeof(ntfschar));
4649 }
4650 a->name_offset = cpu_to_le16(name_ofs);
4651
4652 /* Resize the resident part of the attribute record. */
4653 if (ntfs_attr_record_resize(ctx->mrec, a, arec_size) < 0) {
4654 /*
4655 * Bug, because ntfs_attr_record_resize should not fail (we
4656 * already checked that attribute fits MFT record).
4657 */
4658 ntfs_log_error("BUG! Failed to resize attribute record. "
4659 "Please report to the %s. Aborting...\n",
4660 NTFS_DEV_LIST);
4661 errno = EIO;
4662 return -1;
4663 }
4664
4665 /* Convert the attribute record to describe a resident attribute. */
4666 a->non_resident = 0;
4667 a->flags = 0;
4668 a->value_length = cpu_to_le32(na->data_size);
4669 a->value_offset = cpu_to_le16(val_ofs);
4670 /*
4671 * If a data stream was wiped out, adjust the compression mode
4672 * to current state of compression flag
4673 */
4674 if (!na->data_size
4675 && (na->type == AT_DATA)
4676 && (na->ni->vol->cluster_size <= MAX_COMPRESSION_CLUSTER_SIZE)
4677 && (na->ni->flags & FILE_ATTR_COMPRESSED)) {
4678 a->flags |= ATTR_IS_COMPRESSED;
4679 na->data_flags = a->flags;
4680 }
4681 /*
4682 * File names cannot be non-resident so we would never see this here
4683 * but at least it serves as a reminder that there may be attributes
4684 * for which we do need to set this flag. (AIA)
4685 */
4686 if (a->type == AT_FILE_NAME)
4687 a->resident_flags = RESIDENT_ATTR_IS_INDEXED;
4688 else
4689 a->resident_flags = 0;
4690 a->reservedR = 0;
4691
4692 /* Sanity fixup... Shouldn't really happen. (AIA) */
4693 if (na->initialized_size > na->data_size)
4694 na->initialized_size = na->data_size;
4695
4696 /* Copy data from run list to resident attribute value. */
4697 bytes_read = ntfs_rl_pread(vol, na->rl, 0, na->initialized_size,
4698 (u8*)a + val_ofs);
4699 if (bytes_read != na->initialized_size) {
4700 if (bytes_read < 0)
4701 err = errno;
4702 ntfs_log_trace("Eeek! Failed to read attribute data. Leaving "
4703 "inconstant metadata. Run chkdsk. "
4704 "Aborting...\n");
4705 errno = err;
4706 return -1;
4707 }
4708
4709 /* Clear memory in gap between initialized_size and data_size. */
4710 if (na->initialized_size < na->data_size)
4711 memset((u8*)a + val_ofs + na->initialized_size, 0,
4712 na->data_size - na->initialized_size);
4713
4714 /*
4715 * Deallocate clusters from the runlist.
4716 *
4717 * NOTE: We can use ntfs_cluster_free() because we have already mapped
4718 * the whole run list and thus it doesn't matter that the attribute
4719 * record is in a transiently corrupted state at this moment in time.
4720 */
4721 if (ntfs_cluster_free(vol, na, 0, -1) < 0) {
4722 err = errno;
4723 ntfs_log_perror("Eeek! Failed to release allocated clusters");
4724 ntfs_log_trace("Ignoring error and leaving behind wasted "
4725 "clusters.\n");
4726 }
4727
4728 /* Throw away the now unused runlist. */
4729 free(na->rl);
4730 na->rl = NULL;
4731
4732 /* Update in-memory struct ntfs_attr. */
4733 NAttrClearNonResident(na);
4734 NAttrClearSparse(na);
4735 NAttrClearEncrypted(na);
4736 na->initialized_size = na->data_size;
4737 na->allocated_size = na->compressed_size = (na->data_size + 7) & ~7;
4738 na->compression_block_size = 0;
4739 na->compression_block_size_bits = na->compression_block_clusters = 0;
4740 return 0;
4741}
4742
4743/*
4744 * If we are in the first extent, then set/clean sparse bit,
4745 * update allocated and compressed size.
4746 */
4747static int ntfs_attr_update_meta(ATTR_RECORD *a, ntfs_attr *na, MFT_RECORD *m,
4748 ntfs_attr_search_ctx *ctx)
4749{
4750 int sparse, ret = 0;
4751
4752 ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x\n",
4753 (unsigned long long)na->ni->mft_no, na->type);
4754
4755 if (a->lowest_vcn)
4756 goto out;
4757
4758 a->allocated_size = cpu_to_sle64(na->allocated_size);
4759
4760 /* Update sparse bit. */
4761 sparse = ntfs_rl_sparse(na->rl);
4762 if (sparse == -1) {
4763 errno = EIO;
4764 goto error;
4765 }
4766
4767 /* Attribute become sparse. */
4768 if (sparse && !(a->flags & (ATTR_IS_SPARSE | ATTR_IS_COMPRESSED))) {
4769 /*
4770 * Move attribute to another mft record, if attribute is too
4771 * small to add compressed_size field to it and we have no
4772 * free space in the current mft record.
4773 */
4774 if ((le32_to_cpu(a->length) -
4775 le16_to_cpu(a->mapping_pairs_offset) == 8)
4776 && !(le32_to_cpu(m->bytes_allocated) -
4777 le32_to_cpu(m->bytes_in_use))) {
4778
4779 if (!NInoAttrList(na->ni)) {
4780 ntfs_attr_put_search_ctx(ctx);
4781 if (ntfs_inode_add_attrlist(na->ni))
4782 goto leave;
4783 goto retry;
4784 }
4785 if (ntfs_attr_record_move_away(ctx, 8)) {
4786 ntfs_log_perror("Failed to move attribute");
4787 goto error;
4788 }
4789 ntfs_attr_put_search_ctx(ctx);
4790 goto retry;
4791 }
4792 if (!(le32_to_cpu(a->length) - le16_to_cpu(
4793 a->mapping_pairs_offset))) {
4794 errno = EIO;
4795 ntfs_log_perror("Mapping pairs space is 0");
4796 goto error;
4797 }
4798
4799 NAttrSetSparse(na);
4800 a->flags |= ATTR_IS_SPARSE;
4801 a->compression_unit = STANDARD_COMPRESSION_UNIT; /* Windows
4802 set it so, even if attribute is not actually compressed. */
4803
4804 memmove((u8*)a + le16_to_cpu(a->name_offset) + 8,
4805 (u8*)a + le16_to_cpu(a->name_offset),
4806 a->name_length * sizeof(ntfschar));
4807
4808 a->name_offset = cpu_to_le16(le16_to_cpu(a->name_offset) + 8);
4809
4810 a->mapping_pairs_offset =
4811 cpu_to_le16(le16_to_cpu(a->mapping_pairs_offset) + 8);
4812 }
4813
4814 /* Attribute no longer sparse. */
4815 if (!sparse && (a->flags & ATTR_IS_SPARSE) &&
4816 !(a->flags & ATTR_IS_COMPRESSED)) {
4817
4818 NAttrClearSparse(na);
4819 a->flags &= ~ATTR_IS_SPARSE;
4820 a->compression_unit = 0;
4821
4822 memmove((u8*)a + le16_to_cpu(a->name_offset) - 8,
4823 (u8*)a + le16_to_cpu(a->name_offset),
4824 a->name_length * sizeof(ntfschar));
4825
4826 if (le16_to_cpu(a->name_offset) >= 8)
4827 a->name_offset = cpu_to_le16(le16_to_cpu(a->name_offset) - 8);
4828
4829 a->mapping_pairs_offset =
4830 cpu_to_le16(le16_to_cpu(a->mapping_pairs_offset) - 8);
4831 }
4832
4833 /* Update compressed size if required. */
4834 if (sparse || (na->data_flags & ATTR_COMPRESSION_MASK)) {
4835 s64 new_compr_size;
4836
4837 new_compr_size = ntfs_rl_get_compressed_size(na->ni->vol, na->rl);
4838 if (new_compr_size == -1)
4839 goto error;
4840
4841 na->compressed_size = new_compr_size;
4842 a->compressed_size = cpu_to_sle64(new_compr_size);
4843 }
4844 /*
4845 * Set FILE_NAME dirty flag, to update sparse bit and
4846 * allocated size in the index.
4847 */
4848 if (na->type == AT_DATA && na->name == AT_UNNAMED) {
4849 if (sparse)
4850 na->ni->allocated_size = na->compressed_size;
4851 else
4852 na->ni->allocated_size = na->allocated_size;
4853 NInoFileNameSetDirty(na->ni);
4854 }
4855out:
4856 return ret;
4857leave: ret = -1; goto out; /* return -1 */
4858retry: ret = -2; goto out;
4859error: ret = -3; goto out;
4860}
4861
4862#define NTFS_VCN_DELETE_MARK -2
4863/**
4864 * ntfs_attr_update_mapping_pairs_i - see ntfs_attr_update_mapping_pairs
4865 */
4866static int ntfs_attr_update_mapping_pairs_i(ntfs_attr *na, VCN from_vcn)
4867{
4868 ntfs_attr_search_ctx *ctx;
4869 ntfs_inode *ni, *base_ni;
4870 MFT_RECORD *m;
4871 ATTR_RECORD *a;
4872 VCN stop_vcn;
4873 const runlist_element *stop_rl;
4874 int err, mp_size, cur_max_mp_size, exp_max_mp_size, ret = -1;
4875 BOOL finished_build;
4876
4877retry:
4878 if (!na || !na->rl || from_vcn) {
4879 errno = EINVAL;
4880 ntfs_log_perror("%s: na=%p", __FUNCTION__, na);
4881 return -1;
4882 }
4883
4884 ntfs_log_trace("Entering for inode %llu, attr 0x%x\n",
4885 (unsigned long long)na->ni->mft_no, na->type);
4886
4887 if (!NAttrNonResident(na)) {
4888 errno = EINVAL;
4889 ntfs_log_perror("%s: resident attribute", __FUNCTION__);
4890 return -1;
4891 }
4892
4893 if (na->ni->nr_extents == -1)
4894 base_ni = na->ni->base_ni;
4895 else
4896 base_ni = na->ni;
4897
4898 ctx = ntfs_attr_get_search_ctx(base_ni, NULL);
4899 if (!ctx)
4900 return -1;
4901
4902 /* Fill attribute records with new mapping pairs. */
4903 stop_vcn = 0;
4904 stop_rl = na->rl;
4905 finished_build = FALSE;
4906 while (!ntfs_attr_lookup(na->type, na->name, na->name_len,
4907 CASE_SENSITIVE, from_vcn, NULL, 0, ctx)) {
4908 a = ctx->attr;
4909 m = ctx->mrec;
4910 /*
4911 * If runlist is updating not from the beginning, then set
4912 * @stop_vcn properly, i.e. to the lowest vcn of record that
4913 * contain @from_vcn. Also we do not need @from_vcn anymore,
4914 * set it to 0 to make ntfs_attr_lookup enumerate attributes.
4915 */
4916 if (from_vcn) {
4917 LCN first_lcn;
4918
4919 stop_vcn = sle64_to_cpu(a->lowest_vcn);
4920 from_vcn = 0;
4921 /*
4922 * Check whether the first run we need to update is
4923 * the last run in runlist, if so, then deallocate
4924 * all attrubute extents starting this one.
4925 */
4926 first_lcn = ntfs_rl_vcn_to_lcn(na->rl, stop_vcn);
4927 if (first_lcn == LCN_EINVAL) {
4928 errno = EIO;
4929 ntfs_log_perror("Bad runlist");
4930 goto put_err_out;
4931 }
4932 if (first_lcn == LCN_ENOENT ||
4933 first_lcn == LCN_RL_NOT_MAPPED)
4934 finished_build = TRUE;
4935 }
4936
4937 /*
4938 * Check whether we finished mapping pairs build, if so mark
4939 * extent as need to delete (by setting highest vcn to
4940 * NTFS_VCN_DELETE_MARK (-2), we shall check it later and
4941 * delete extent) and continue search.
4942 */
4943 if (finished_build) {
4944 ntfs_log_trace("Mark attr 0x%x for delete in inode "
4945 "%lld.\n", (unsigned)le32_to_cpu(a->type),
4946 (long long)ctx->ntfs_ino->mft_no);
4947 a->highest_vcn = cpu_to_sle64(NTFS_VCN_DELETE_MARK);
4948 ntfs_inode_mark_dirty(ctx->ntfs_ino);
4949 continue;
4950 }
4951
4952 switch (ntfs_attr_update_meta(a, na, m, ctx)) {
4953 case -1: return -1;
4954 case -2: goto retry;
4955 case -3: goto put_err_out;
4956 }
4957
4958 /*
4959 * Determine maximum possible length of mapping pairs,
4960 * if we shall *not* expand space for mapping pairs.
4961 */
4962 cur_max_mp_size = le32_to_cpu(a->length) -
4963 le16_to_cpu(a->mapping_pairs_offset);
4964 /*
4965 * Determine maximum possible length of mapping pairs in the
4966 * current mft record, if we shall expand space for mapping
4967 * pairs.
4968 */
4969 exp_max_mp_size = le32_to_cpu(m->bytes_allocated) -
4970 le32_to_cpu(m->bytes_in_use) + cur_max_mp_size;
4971 /* Get the size for the rest of mapping pairs array. */
4972 mp_size = ntfs_get_size_for_mapping_pairs(na->ni->vol, stop_rl,
4973 stop_vcn, exp_max_mp_size);
4974 if (mp_size <= 0) {
4975 ntfs_log_perror("%s: get MP size failed", __FUNCTION__);
4976 goto put_err_out;
4977 }
4978 /* Test mapping pairs for fitting in the current mft record. */
4979 if (mp_size > exp_max_mp_size) {
4980 /*
4981 * Mapping pairs of $ATTRIBUTE_LIST attribute must fit
4982 * in the base mft record. Try to move out other
4983 * attributes and try again.
4984 */
4985 if (na->type == AT_ATTRIBUTE_LIST) {
4986 ntfs_attr_put_search_ctx(ctx);
4987 if (ntfs_inode_free_space(na->ni, mp_size -
4988 cur_max_mp_size)) {
4989 ntfs_log_perror("Attribute list is too "
4990 "big. Defragment the "
4991 "volume\n");
4992 return -1;
4993 }
4994 goto retry;
4995 }
4996
4997 /* Add attribute list if it isn't present, and retry. */
4998 if (!NInoAttrList(base_ni)) {
4999 ntfs_attr_put_search_ctx(ctx);
5000 if (ntfs_inode_add_attrlist(base_ni)) {
5001 ntfs_log_perror("Can not add attrlist");
5002 return -1;
5003 }
5004 goto retry;
5005 }
5006
5007 /*
5008 * Set mapping pairs size to maximum possible for this
5009 * mft record. We shall write the rest of mapping pairs
5010 * to another MFT records.
5011 */
5012 mp_size = exp_max_mp_size;
5013 }
5014
5015 /* Change space for mapping pairs if we need it. */
5016 if (((mp_size + 7) & ~7) != cur_max_mp_size) {
5017 if (ntfs_attr_record_resize(m, a,
5018 le16_to_cpu(a->mapping_pairs_offset) +
5019 mp_size)) {
5020 errno = EIO;
5021 ntfs_log_perror("Failed to resize attribute");
5022 goto put_err_out;
5023 }
5024 }
5025
5026 /* Update lowest vcn. */
5027 a->lowest_vcn = cpu_to_sle64(stop_vcn);
5028 ntfs_inode_mark_dirty(ctx->ntfs_ino);
5029 if ((ctx->ntfs_ino->nr_extents == -1 ||
5030 NInoAttrList(ctx->ntfs_ino)) &&
5031 ctx->attr->type != AT_ATTRIBUTE_LIST) {
5032 ctx->al_entry->lowest_vcn = cpu_to_sle64(stop_vcn);
5033 ntfs_attrlist_mark_dirty(ctx->ntfs_ino);
5034 }
5035
5036 /*
5037 * Generate the new mapping pairs array directly into the
5038 * correct destination, i.e. the attribute record itself.
5039 */
5040 if (!ntfs_mapping_pairs_build(na->ni->vol, (u8*)a + le16_to_cpu(
5041 a->mapping_pairs_offset), mp_size, na->rl,
5042 stop_vcn, &stop_rl))
5043 finished_build = TRUE;
5044 if (stop_rl)
5045 stop_vcn = stop_rl->vcn;
5046 else
5047 stop_vcn = 0;
5048 if (!finished_build && errno != ENOSPC) {
5049 ntfs_log_perror("Failed to build mapping pairs");
5050 goto put_err_out;
5051 }
5052 a->highest_vcn = cpu_to_sle64(stop_vcn - 1);
5053 }
5054 /* Check whether error occurred. */
5055 if (errno != ENOENT) {
5056 ntfs_log_perror("%s: Attribute lookup failed", __FUNCTION__);
5057 goto put_err_out;
5058 }
5059
5060 /* Deallocate not used attribute extents and return with success. */
5061 if (finished_build) {
5062 ntfs_attr_reinit_search_ctx(ctx);
5063 ntfs_log_trace("Deallocate marked extents.\n");
5064 while (!ntfs_attr_lookup(na->type, na->name, na->name_len,
5065 CASE_SENSITIVE, 0, NULL, 0, ctx)) {
5066 if (sle64_to_cpu(ctx->attr->highest_vcn) !=
5067 NTFS_VCN_DELETE_MARK)
5068 continue;
5069 /* Remove unused attribute record. */
5070 if (ntfs_attr_record_rm(ctx)) {
5071 ntfs_log_perror("Could not remove unused attr");
5072 goto put_err_out;
5073 }
5074 ntfs_attr_reinit_search_ctx(ctx);
5075 }
5076 if (errno != ENOENT) {
5077 ntfs_log_perror("%s: Attr lookup failed", __FUNCTION__);
5078 goto put_err_out;
5079 }
5080 ntfs_log_trace("Deallocate done.\n");
5081 ntfs_attr_put_search_ctx(ctx);
5082 goto ok;
5083 }
5084 ntfs_attr_put_search_ctx(ctx);
5085 ctx = NULL;
5086
5087 /* Allocate new MFT records for the rest of mapping pairs. */
5088 while (1) {
5089 /* Calculate size of rest mapping pairs. */
5090 mp_size = ntfs_get_size_for_mapping_pairs(na->ni->vol,
5091 na->rl, stop_vcn, INT_MAX);
5092 if (mp_size <= 0) {
5093 ntfs_log_perror("%s: get mp size failed", __FUNCTION__);
5094 goto put_err_out;
5095 }
5096 /* Allocate new mft record. */
5097 ni = ntfs_mft_record_alloc(na->ni->vol, base_ni);
5098 if (!ni) {
5099 ntfs_log_perror("Could not allocate new MFT record");
5100 goto put_err_out;
5101 }
5102 m = ni->mrec;
5103 /*
5104 * If mapping size exceed available space, set them to
5105 * possible maximum.
5106 */
5107 cur_max_mp_size = le32_to_cpu(m->bytes_allocated) -
5108 le32_to_cpu(m->bytes_in_use) -
5109 (offsetof(ATTR_RECORD, compressed_size) +
5110 (((na->data_flags & ATTR_COMPRESSION_MASK)
5111 || NAttrSparse(na)) ?
5112 sizeof(a->compressed_size) : 0)) -
5113 ((sizeof(ntfschar) * na->name_len + 7) & ~7);
5114 if (mp_size > cur_max_mp_size)
5115 mp_size = cur_max_mp_size;
5116 /* Add attribute extent to new record. */
5117 err = ntfs_non_resident_attr_record_add(ni, na->type,
5118 na->name, na->name_len, stop_vcn, mp_size,
5119 na->data_flags);
5120 if (err == -1) {
5121 err = errno;
5122 ntfs_log_perror("Could not add attribute extent");
5123 if (ntfs_mft_record_free(na->ni->vol, ni))
5124 ntfs_log_perror("Could not free MFT record");
5125 errno = err;
5126 goto put_err_out;
5127 }
5128 a = (ATTR_RECORD*)((u8*)m + err);
5129
5130 err = ntfs_mapping_pairs_build(na->ni->vol, (u8*)a +
5131 le16_to_cpu(a->mapping_pairs_offset), mp_size, na->rl,
5132 stop_vcn, &stop_rl);
5133 if (stop_rl)
5134 stop_vcn = stop_rl->vcn;
5135 else
5136 stop_vcn = 0;
5137 if (err < 0 && errno != ENOSPC) {
5138 err = errno;
5139 ntfs_log_perror("Failed to build MP");
5140 if (ntfs_mft_record_free(na->ni->vol, ni))
5141 ntfs_log_perror("Couldn't free MFT record");
5142 errno = err;
5143 goto put_err_out;
5144 }
5145 a->highest_vcn = cpu_to_sle64(stop_vcn - 1);
5146 ntfs_inode_mark_dirty(ni);
5147 /* All mapping pairs has been written. */
5148 if (!err)
5149 break;
5150 }
5151ok:
5152 ret = 0;
5153out:
5154 return ret;
5155put_err_out:
5156 if (ctx)
5157 ntfs_attr_put_search_ctx(ctx);
5158 goto out;
5159}
5160#undef NTFS_VCN_DELETE_MARK
5161
5162/**
5163 * ntfs_attr_update_mapping_pairs - update mapping pairs for ntfs attribute
5164 * @na: non-resident ntfs open attribute for which we need update
5165 * @from_vcn: update runlist starting this VCN
5166 *
5167 * Build mapping pairs from @na->rl and write them to the disk. Also, this
5168 * function updates sparse bit, allocated and compressed size (allocates/frees
5169 * space for this field if required).
5170 *
5171 * @na->allocated_size should be set to correct value for the new runlist before
5172 * call to this function. Vice-versa @na->compressed_size will be calculated and
5173 * set to correct value during this function.
5174 *
5175 * FIXME: This function does not update sparse bit and compressed size correctly
5176 * if called with @from_vcn != 0.
5177 *
5178 * FIXME: Rewrite without using NTFS_VCN_DELETE_MARK define.
5179 *
5180 * On success return 0 and on error return -1 with errno set to the error code.
5181 * The following error codes are defined:
5182 * EINVAL - Invalid arguments passed.
5183 * ENOMEM - Not enough memory to complete operation.
5184 * ENOSPC - There is no enough space in base mft to resize $ATTRIBUTE_LIST
5185 * or there is no free MFT records left to allocate.
5186 */
5187int ntfs_attr_update_mapping_pairs(ntfs_attr *na, VCN from_vcn)
5188{
5189 int ret;
5190
5191 ntfs_log_enter("Entering\n");
5192 ret = ntfs_attr_update_mapping_pairs_i(na, from_vcn);
5193 ntfs_log_leave("\n");
5194 return ret;
5195}
5196
5197/**
5198 * ntfs_non_resident_attr_shrink - shrink a non-resident, open ntfs attribute
5199 * @na: non-resident ntfs attribute to shrink
5200 * @newsize: new size (in bytes) to which to shrink the attribute
5201 *
5202 * Reduce the size of a non-resident, open ntfs attribute @na to @newsize bytes.
5203 *
5204 * On success return 0 and on error return -1 with errno set to the error code.
5205 * The following error codes are defined:
5206 * ENOMEM - Not enough memory to complete operation.
5207 * ERANGE - @newsize is not valid for the attribute type of @na.
5208 */
5209static int ntfs_non_resident_attr_shrink(ntfs_attr *na, const s64 newsize)
5210{
5211 ntfs_volume *vol;
5212 ntfs_attr_search_ctx *ctx;
5213 VCN first_free_vcn;
5214 s64 nr_freed_clusters;
5215 int err;
5216
5217 ntfs_log_trace("Inode 0x%llx attr 0x%x new size %lld\n", (unsigned long long)
5218 na->ni->mft_no, na->type, (long long)newsize);
5219
5220 vol = na->ni->vol;
5221
5222 /*
5223 * Check the attribute type and the corresponding minimum size
5224 * against @newsize and fail if @newsize is too small.
5225 */
5226 if (ntfs_attr_size_bounds_check(vol, na->type, newsize) < 0) {
5227 if (errno == ERANGE) {
5228 ntfs_log_trace("Eeek! Size bounds check failed. "
5229 "Aborting...\n");
5230 } else if (errno == ENOENT)
5231 errno = EIO;
5232 return -1;
5233 }
5234
5235 /* The first cluster outside the new allocation. */
5236 first_free_vcn = (newsize + vol->cluster_size - 1) >>
5237 vol->cluster_size_bits;
5238 /*
5239 * Compare the new allocation with the old one and only deallocate
5240 * clusters if there is a change.
5241 */
5242 if ((na->allocated_size >> vol->cluster_size_bits) != first_free_vcn) {
5243 if (ntfs_attr_map_whole_runlist(na)) {
5244 ntfs_log_trace("Eeek! ntfs_attr_map_whole_runlist "
5245 "failed.\n");
5246 return -1;
5247 }
5248 /* Deallocate all clusters starting with the first free one. */
5249 nr_freed_clusters = ntfs_cluster_free(vol, na, first_free_vcn,
5250 -1);
5251 if (nr_freed_clusters < 0) {
5252 ntfs_log_trace("Eeek! Freeing of clusters failed. "
5253 "Aborting...\n");
5254 return -1;
5255 }
5256
5257 /* Truncate the runlist itself. */
5258 if (ntfs_rl_truncate(&na->rl, first_free_vcn)) {
5259 /*
5260 * Failed to truncate the runlist, so just throw it
5261 * away, it will be mapped afresh on next use.
5262 */
5263 free(na->rl);
5264 na->rl = NULL;
5265 ntfs_log_trace("Eeek! Run list truncation failed.\n");
5266 return -1;
5267 }
5268
5269 /* Prepare to mapping pairs update. */
5270 na->allocated_size = first_free_vcn << vol->cluster_size_bits;
5271 /* Write mapping pairs for new runlist. */
5272 if (ntfs_attr_update_mapping_pairs(na, 0 /*first_free_vcn*/)) {
5273 ntfs_log_trace("Eeek! Mapping pairs update failed. "
5274 "Leaving inconstant metadata. "
5275 "Run chkdsk.\n");
5276 return -1;
5277 }
5278 }
5279
5280 /* Get the first attribute record. */
5281 ctx = ntfs_attr_get_search_ctx(na->ni, NULL);
5282 if (!ctx)
5283 return -1;
5284
5285 if (ntfs_attr_lookup(na->type, na->name, na->name_len, CASE_SENSITIVE,
5286 0, NULL, 0, ctx)) {
5287 err = errno;
5288 if (err == ENOENT)
5289 err = EIO;
5290 ntfs_log_trace("Eeek! Lookup of first attribute extent failed. "
5291 "Leaving inconstant metadata.\n");
5292 goto put_err_out;
5293 }
5294
5295 /* Update data and initialized size. */
5296 na->data_size = newsize;
5297 ctx->attr->data_size = cpu_to_sle64(newsize);
5298 if (newsize < na->initialized_size) {
5299 na->initialized_size = newsize;
5300 ctx->attr->initialized_size = cpu_to_sle64(newsize);
5301 }
5302 /* Update data size in the index. */
5303 if (na->ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) {
5304 if (na->type == AT_INDEX_ROOT && na->name == NTFS_INDEX_I30) {
5305 na->ni->data_size = na->data_size;
5306 na->ni->allocated_size = na->allocated_size;
5307 set_nino_flag(na->ni,KnownSize);
5308 }
5309 } else {
5310 if (na->type == AT_DATA && na->name == AT_UNNAMED) {
5311 na->ni->data_size = na->data_size;
5312 NInoFileNameSetDirty(na->ni);
5313 }
5314 }
5315
5316 /* If the attribute now has zero size, make it resident. */
5317 if (!newsize) {
5318 if (ntfs_attr_make_resident(na, ctx)) {
5319 /* If couldn't make resident, just continue. */
5320 if (errno != EPERM)
5321 ntfs_log_error("Failed to make attribute "
5322 "resident. Leaving as is...\n");
5323 }
5324 }
5325
5326 /* Set the inode dirty so it is written out later. */
5327 ntfs_inode_mark_dirty(ctx->ntfs_ino);
5328 /* Done! */
5329 ntfs_attr_put_search_ctx(ctx);
5330 return 0;
5331put_err_out:
5332 ntfs_attr_put_search_ctx(ctx);
5333 errno = err;
5334 return -1;
5335}
5336
5337/**
5338 * ntfs_non_resident_attr_expand - expand a non-resident, open ntfs attribute
5339 * @na: non-resident ntfs attribute to expand
5340 * @newsize: new size (in bytes) to which to expand the attribute
5341 *
5342 * Expand the size of a non-resident, open ntfs attribute @na to @newsize bytes,
5343 * by allocating new clusters.
5344 *
5345 * On success return 0 and on error return -1 with errno set to the error code.
5346 * The following error codes are defined:
5347 * ENOMEM - Not enough memory to complete operation.
5348 * ERANGE - @newsize is not valid for the attribute type of @na.
5349 * ENOSPC - There is no enough space in base mft to resize $ATTRIBUTE_LIST.
5350 */
5351static int ntfs_non_resident_attr_expand_i(ntfs_attr *na, const s64 newsize)
5352{
5353 LCN lcn_seek_from;
5354 VCN first_free_vcn;
5355 ntfs_volume *vol;
5356 ntfs_attr_search_ctx *ctx;
5357 runlist *rl, *rln;
5358 s64 org_alloc_size;
5359 int err;
5360
5361 ntfs_log_trace("Inode %lld, attr 0x%x, new size %lld old size %lld\n",
5362 (unsigned long long)na->ni->mft_no, na->type,
5363 (long long)newsize, (long long)na->data_size);
5364
5365 vol = na->ni->vol;
5366
5367 /*
5368 * Check the attribute type and the corresponding maximum size
5369 * against @newsize and fail if @newsize is too big.
5370 */
5371 if (ntfs_attr_size_bounds_check(vol, na->type, newsize) < 0) {
5372 if (errno == ENOENT)
5373 errno = EIO;
5374 ntfs_log_perror("%s: bounds check failed", __FUNCTION__);
5375 return -1;
5376 }
5377
5378 /* Save for future use. */
5379 org_alloc_size = na->allocated_size;
5380 /* The first cluster outside the new allocation. */
5381 first_free_vcn = (newsize + vol->cluster_size - 1) >>
5382 vol->cluster_size_bits;
5383 /*
5384 * Compare the new allocation with the old one and only allocate
5385 * clusters if there is a change.
5386 */
5387 if ((na->allocated_size >> vol->cluster_size_bits) < first_free_vcn) {
5388 if (ntfs_attr_map_whole_runlist(na)) {
5389 ntfs_log_perror("ntfs_attr_map_whole_runlist failed");
5390 return -1;
5391 }
5392
5393 /*
5394 * If we extend $DATA attribute on NTFS 3+ volume, we can add
5395 * sparse runs instead of real allocation of clusters.
5396 */
5397 if (na->type == AT_DATA && vol->major_ver >= 3) {
5398 rl = ntfs_malloc(0x1000);
5399 if (!rl)
5400 return -1;
5401
5402 rl[0].vcn = (na->allocated_size >>
5403 vol->cluster_size_bits);
5404 rl[0].lcn = LCN_HOLE;
5405 rl[0].length = first_free_vcn -
5406 (na->allocated_size >> vol->cluster_size_bits);
5407 rl[1].vcn = first_free_vcn;
5408 rl[1].lcn = LCN_ENOENT;
5409 rl[1].length = 0;
5410 } else {
5411 /*
5412 * Determine first after last LCN of attribute.
5413 * We will start seek clusters from this LCN to avoid
5414 * fragmentation. If there are no valid LCNs in the
5415 * attribute let the cluster allocator choose the
5416 * starting LCN.
5417 */
5418 lcn_seek_from = -1;
5419 if (na->rl->length) {
5420 /* Seek to the last run list element. */
5421 for (rl = na->rl; (rl + 1)->length; rl++)
5422 ;
5423 /*
5424 * If the last LCN is a hole or similar seek
5425 * back to last valid LCN.
5426 */
5427 while (rl->lcn < 0 && rl != na->rl)
5428 rl--;
5429 /*
5430 * Only set lcn_seek_from it the LCN is valid.
5431 */
5432 if (rl->lcn >= 0)
5433 lcn_seek_from = rl->lcn + rl->length;
5434 }
5435
5436 rl = ntfs_cluster_alloc(vol, na->allocated_size >>
5437 vol->cluster_size_bits, first_free_vcn -
5438 (na->allocated_size >>
5439 vol->cluster_size_bits), lcn_seek_from,
5440 DATA_ZONE);
5441 if (!rl) {
5442 ntfs_log_perror("Cluster allocation failed "
5443 "(%lld)",
5444 (long long)first_free_vcn -
5445 ((long long)na->allocated_size >>
5446 vol->cluster_size_bits));
5447 return -1;
5448 }
5449 }
5450
5451 /* Append new clusters to attribute runlist. */
5452 rln = ntfs_runlists_merge(na->rl, rl);
5453 if (!rln) {
5454 /* Failed, free just allocated clusters. */
5455 err = errno;
5456 ntfs_log_perror("Run list merge failed");
5457 ntfs_cluster_free_from_rl(vol, rl);
5458 free(rl);
5459 errno = err;
5460 return -1;
5461 }
5462 na->rl = rln;
5463
5464 /* Prepare to mapping pairs update. */
5465 na->allocated_size = first_free_vcn << vol->cluster_size_bits;
5466 /* Write mapping pairs for new runlist. */
5467 if (ntfs_attr_update_mapping_pairs(na, 0 /*na->allocated_size >>
5468 vol->cluster_size_bits*/)) {
5469 err = errno;
5470 ntfs_log_perror("Mapping pairs update failed");
5471 goto rollback;
5472 }
5473 }
5474
5475 ctx = ntfs_attr_get_search_ctx(na->ni, NULL);
5476 if (!ctx) {
5477 err = errno;
5478 if (na->allocated_size == org_alloc_size) {
5479 errno = err;
5480 return -1;
5481 } else
5482 goto rollback;
5483 }
5484
5485 if (ntfs_attr_lookup(na->type, na->name, na->name_len, CASE_SENSITIVE,
5486 0, NULL, 0, ctx)) {
5487 err = errno;
5488 ntfs_log_perror("Lookup of first attribute extent failed");
5489 if (err == ENOENT)
5490 err = EIO;
5491 if (na->allocated_size != org_alloc_size) {
5492 ntfs_attr_put_search_ctx(ctx);
5493 goto rollback;
5494 } else
5495 goto put_err_out;
5496 }
5497
5498 /* Update data size. */
5499 na->data_size = newsize;
5500 ctx->attr->data_size = cpu_to_sle64(newsize);
5501 /* Update data size in the index. */
5502 if (na->ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) {
5503 if (na->type == AT_INDEX_ROOT && na->name == NTFS_INDEX_I30) {
5504 na->ni->data_size = na->data_size;
5505 na->ni->allocated_size = na->allocated_size;
5506 set_nino_flag(na->ni,KnownSize);
5507 }
5508 } else {
5509 if (na->type == AT_DATA && na->name == AT_UNNAMED) {
5510 na->ni->data_size = na->data_size;
5511 NInoFileNameSetDirty(na->ni);
5512 }
5513 }
5514 /* Set the inode dirty so it is written out later. */
5515 ntfs_inode_mark_dirty(ctx->ntfs_ino);
5516 /* Done! */
5517 ntfs_attr_put_search_ctx(ctx);
5518 return 0;
5519rollback:
5520 /* Free allocated clusters. */
5521 if (ntfs_cluster_free(vol, na, org_alloc_size >>
5522 vol->cluster_size_bits, -1) < 0) {
5523 err = EIO;
5524 ntfs_log_perror("Leaking clusters");
5525 }
5526 /* Now, truncate the runlist itself. */
5527 if (ntfs_rl_truncate(&na->rl, org_alloc_size >>
5528 vol->cluster_size_bits)) {
5529 /*
5530 * Failed to truncate the runlist, so just throw it away, it
5531 * will be mapped afresh on next use.
5532 */
5533 free(na->rl);
5534 na->rl = NULL;
5535 ntfs_log_perror("Couldn't truncate runlist. Rollback failed");
5536 } else {
5537 /* Prepare to mapping pairs update. */
5538 na->allocated_size = org_alloc_size;
5539 /* Restore mapping pairs. */
5540 if (ntfs_attr_update_mapping_pairs(na, 0 /*na->allocated_size >>
5541 vol->cluster_size_bits*/)) {
5542 ntfs_log_perror("Failed to restore old mapping pairs");
5543 }
5544 }
5545 errno = err;
5546 return -1;
5547put_err_out:
5548 ntfs_attr_put_search_ctx(ctx);
5549 errno = err;
5550 return -1;
5551}
5552
5553
5554static int ntfs_non_resident_attr_expand(ntfs_attr *na, const s64 newsize)
5555{
5556 int ret;
5557
5558 ntfs_log_enter("Entering\n");
5559 ret = ntfs_non_resident_attr_expand_i(na, newsize);
5560 ntfs_log_leave("\n");
5561 return ret;
5562}
5563
5564/**
5565 * ntfs_attr_truncate - resize an ntfs attribute
5566 * @na: open ntfs attribute to resize
5567 * @newsize: new size (in bytes) to which to resize the attribute
5568 *
5569 * Change the size of an open ntfs attribute @na to @newsize bytes. If the
5570 * attribute is made bigger and the attribute is resident the newly
5571 * "allocated" space is cleared and if the attribute is non-resident the
5572 * newly allocated space is marked as not initialised and no real allocation
5573 * on disk is performed.
5574 *
5575 * On success return 0.
5576 * On error return values are:
5577 * STATUS_RESIDENT_ATTRIBUTE_FILLED_MFT
5578 * STATUS_ERROR - otherwise
5579 * The following error codes are defined:
5580 * EINVAL - Invalid arguments were passed to the function.
5581 * EOPNOTSUPP - The desired resize is not implemented yet.
5582 * EACCES - Encrypted attribute.
5583 */
5584int ntfs_attr_truncate(ntfs_attr *na, const s64 newsize)
5585{
5586 int ret = STATUS_ERROR;
5587 s64 fullsize;
5588 BOOL compressed;
5589
5590 if (!na || newsize < 0 ||
5591 (na->ni->mft_no == FILE_MFT && na->type == AT_DATA)) {
5592 ntfs_log_trace("Invalid arguments passed.\n");
5593 errno = EINVAL;
5594 return STATUS_ERROR;
5595 }
5596
5597 ntfs_log_enter("Entering for inode %lld, attr 0x%x, size %lld\n",
5598 (unsigned long long)na->ni->mft_no, na->type,
5599 (long long)newsize);
5600
5601 if (na->data_size == newsize) {
5602 ntfs_log_trace("Size is already ok\n");
5603 ret = STATUS_OK;
5604 goto out;
5605 }
5606 /*
5607 * Encrypted attributes are not supported. We return access denied,
5608 * which is what Windows NT4 does, too.
5609 */
5610 if (na->data_flags & ATTR_IS_ENCRYPTED) {
5611 errno = EACCES;
5612 ntfs_log_trace("Cannot truncate encrypted attribute\n");
5613 goto out;
5614 }
5615 /*
5616 * TODO: Implement making handling of compressed attributes.
5617 * Currently we can only expand the attribute or delete it,
5618 * and only for ATTR_IS_COMPRESSED. This is however possible
5619 * for resident attributes when there is no open fuse context
5620 * (important case : $INDEX_ROOT:$I30)
5621 */
5622 compressed = (na->data_flags & ATTR_COMPRESSION_MASK)
5623 != const_cpu_to_le16(0);
5624 if (compressed
5625 && NAttrNonResident(na)
5626 && (((na->data_flags & ATTR_COMPRESSION_MASK) != ATTR_IS_COMPRESSED)
5627 || (newsize && (newsize < na->data_size)))) {
5628 errno = EOPNOTSUPP;
5629 ntfs_log_perror("Failed to truncate compressed attribute");
5630 goto out;
5631 }
5632 if (NAttrNonResident(na)) {
5633 /*
5634 * For compressed data, the last block must be fully
5635 * allocated, and we do not known the size of compression
5636 * block until the attribute has been made non-resident.
5637 * Moreover we can only process a single compression
5638 * block at a time (from where we are about to write),
5639 * so we silently do not allocate more.
5640 *
5641 * Note : do not request truncate on compressed files
5642 * unless being able to face the consequences !
5643 */
5644 if (compressed && newsize)
5645 fullsize = (na->initialized_size
5646 | (na->compression_block_size - 1)) + 1;
5647 else
5648 fullsize = newsize;
5649 if (fullsize > na->data_size)
5650 ret = ntfs_non_resident_attr_expand(na, fullsize);
5651 else
5652 ret = ntfs_non_resident_attr_shrink(na, fullsize);
5653 } else
5654 ret = ntfs_resident_attr_resize(na, newsize);
5655out:
5656 ntfs_log_leave("Return status %d\n", ret);
5657 return ret;
5658}
5659
5660/*
5661 * Stuff a hole in a compressed file
5662 *
5663 * An unallocated hole must be aligned on compression block size.
5664 * If needed current block and target block are stuffed with zeroes.
5665 *
5666 * Returns 0 if succeeded,
5667 * -1 if it failed (as explained in errno)
5668 */
5669
5670static int stuff_hole(ntfs_attr *na, const s64 pos)
5671{
5672 s64 size;
5673 s64 begin_size;
5674 s64 end_size;
5675 char *buf;
5676 int ret;
5677
5678 ret = 0;
5679 /*
5680 * If the attribute is resident, the compression block size
5681 * is not defined yet and we can make no decision.
5682 * So we first try resizing to the target and if the
5683 * attribute is still resident, we're done
5684 */
5685 if (!NAttrNonResident(na)) {
5686 ret = ntfs_resident_attr_resize(na, pos);
5687 if (!ret && !NAttrNonResident(na))
5688 na->initialized_size = na->data_size = pos;
5689 }
5690 if (!ret && NAttrNonResident(na)) {
5691 /* does the hole span over several compression block ? */
5692 if ((pos ^ na->initialized_size)
5693 & ~(na->compression_block_size - 1)) {
5694 begin_size = ((na->initialized_size - 1)
5695 | (na->compression_block_size - 1))
5696 + 1 - na->initialized_size;
5697 end_size = pos & (na->compression_block_size - 1);
5698 size = (begin_size > end_size ? begin_size : end_size);
5699 } else {
5700 /* short stuffing in a single compression block */
5701 begin_size = size = pos - na->initialized_size;
5702 end_size = 0;
5703 }
5704 if (size)
5705 buf = (char*)ntfs_malloc(size);
5706 else
5707 buf = (char*)NULL;
5708 if (buf || !size) {
5709 memset(buf,0,size);
5710 /* stuff into current block */
5711 if (begin_size
5712 && (ntfs_attr_pwrite(na,
5713 na->initialized_size, begin_size, buf)
5714 != begin_size))
5715 ret = -1;
5716 /* create an unstuffed hole */
5717 if (!ret
5718 && ((na->initialized_size + end_size) < pos)
5719 && ntfs_non_resident_attr_expand(na,
5720 pos - end_size))
5721 ret = -1;
5722 else
5723 na->initialized_size
5724 = na->data_size = pos - end_size;
5725 /* stuff into the target block */
5726 if (!ret && end_size
5727 && (ntfs_attr_pwrite(na,
5728 na->initialized_size, end_size, buf)
5729 != end_size))
5730 ret = -1;
5731 if (buf)
5732 free(buf);
5733 } else
5734 ret = -1;
5735 }
5736 /* make absolutely sure we have reached the target */
5737 if (!ret && (na->initialized_size != pos)) {
5738 ntfs_log_error("Failed to stuff a compressed file"
5739 "target %lld reached %lld\n",
5740 (long long)pos, (long long)na->initialized_size);
5741 errno = EIO;
5742 ret = -1;
5743 }
5744 return (ret);
5745}
5746
5747/**
5748 * ntfs_attr_readall - read the entire data from an ntfs attribute
5749 * @ni: open ntfs inode in which the ntfs attribute resides
5750 * @type: attribute type
5751 * @name: attribute name in little endian Unicode or AT_UNNAMED or NULL
5752 * @name_len: length of attribute @name in Unicode characters (if @name given)
5753 * @data_size: if non-NULL then store here the data size
5754 *
5755 * This function will read the entire content of an ntfs attribute.
5756 * If @name is AT_UNNAMED then look specifically for an unnamed attribute.
5757 * If @name is NULL then the attribute could be either named or not.
5758 * In both those cases @name_len is not used at all.
5759 *
5760 * On success a buffer is allocated with the content of the attribute
5761 * and which needs to be freed when it's not needed anymore. If the
5762 * @data_size parameter is non-NULL then the data size is set there.
5763 *
5764 * On error NULL is returned with errno set to the error code.
5765 */
5766void *ntfs_attr_readall(ntfs_inode *ni, const ATTR_TYPES type,
5767 ntfschar *name, u32 name_len, s64 *data_size)
5768{
5769 ntfs_attr *na;
5770 void *data, *ret = NULL;
5771 s64 size;
5772
5773 ntfs_log_enter("Entering\n");
5774
5775 na = ntfs_attr_open(ni, type, name, name_len);
5776 if (!na) {
5777 ntfs_log_perror("ntfs_attr_open failed");
5778 goto err_exit;
5779 }
5780 data = ntfs_malloc(na->data_size);
5781 if (!data)
5782 goto out;
5783
5784 size = ntfs_attr_pread(na, 0, na->data_size, data);
5785 if (size != na->data_size) {
5786 ntfs_log_perror("ntfs_attr_pread failed");
5787 free(data);
5788 goto out;
5789 }
5790 ret = data;
5791 if (data_size)
5792 *data_size = size;
5793out:
5794 ntfs_attr_close(na);
5795err_exit:
5796 ntfs_log_leave("\n");
5797 return ret;
5798}
5799
5800
5801
5802int ntfs_attr_exist(ntfs_inode *ni, const ATTR_TYPES type, ntfschar *name,
5803 u32 name_len)
5804{
5805 ntfs_attr_search_ctx *ctx;
5806 int ret;
5807
5808 ntfs_log_trace("Entering\n");
5809
5810 ctx = ntfs_attr_get_search_ctx(ni, NULL);
5811 if (!ctx)
5812 return 0;
5813
5814 ret = ntfs_attr_lookup(type, name, name_len, CASE_SENSITIVE, 0, NULL, 0,
5815 ctx);
5816
5817 ntfs_attr_put_search_ctx(ctx);
5818
5819 return !ret;
5820}
5821
5822int ntfs_attr_remove(ntfs_inode *ni, const ATTR_TYPES type, ntfschar *name,
5823 u32 name_len)
5824{
5825 ntfs_attr *na;
5826 int ret;
5827
5828 ntfs_log_trace("Entering\n");
5829
5830 if (!ni) {
5831 ntfs_log_error("%s: NULL inode pointer", __FUNCTION__);
5832 errno = EINVAL;
5833 return -1;
5834 }
5835
5836 na = ntfs_attr_open(ni, type, name, name_len);
5837 if (!na) {
5838 /* do not log removal of non-existent stream */
5839 if (type != AT_DATA) {
5840 ntfs_log_perror("Failed to open attribute 0x%02x of inode "
5841 "0x%llx", type, (unsigned long long)ni->mft_no);
5842 }
5843 return -1;
5844 }
5845
5846 ret = ntfs_attr_rm(na);
5847 if (ret)
5848 ntfs_log_perror("Failed to remove attribute 0x%02x of inode "
5849 "0x%llx", type, (unsigned long long)ni->mft_no);
5850 ntfs_attr_close(na);
5851
5852 return ret;
5853}
5854
5855/* Below macros are 32-bit ready. */
5856#define BCX(x) ((x) - (((x) >> 1) & 0x77777777) - \
5857 (((x) >> 2) & 0x33333333) - \
5858 (((x) >> 3) & 0x11111111))
5859#define BITCOUNT(x) (((BCX(x) + (BCX(x) >> 4)) & 0x0F0F0F0F) % 255)
5860
5861static u8 *ntfs_init_lut256(void)
5862{
5863 int i;
5864 u8 *lut;
5865
5866 lut = ntfs_malloc(256);
5867 if (lut)
5868 for(i = 0; i < 256; i++)
5869 *(lut + i) = 8 - BITCOUNT(i);
5870 return lut;
5871}
5872
5873s64 ntfs_attr_get_free_bits(ntfs_attr *na)
5874{
5875 u8 *buf, *lut;
5876 s64 br = 0;
5877 s64 total = 0;
5878 s64 nr_free = 0;
5879
5880 lut = ntfs_init_lut256();
5881 if (!lut)
5882 return -1;
5883
5884 buf = ntfs_malloc(65536);
5885 if (!buf)
5886 goto out;
5887
5888 while (1) {
5889 u32 *p;
5890 br = ntfs_attr_pread(na, total, 65536, buf);
5891 if (br <= 0)
5892 break;
5893 total += br;
5894 p = (u32 *)buf + br / 4 - 1;
5895 for (; (u8 *)p >= buf; p--) {
5896 nr_free += lut[ *p & 255] +
5897 lut[(*p >> 8) & 255] +
5898 lut[(*p >> 16) & 255] +
5899 lut[(*p >> 24) ];
5900 }
5901 switch (br % 4) {
5902 case 3: nr_free += lut[*(buf + br - 3)];
5903 case 2: nr_free += lut[*(buf + br - 2)];
5904 case 1: nr_free += lut[*(buf + br - 1)];
5905 }
5906 }
5907 free(buf);
5908out:
5909 free(lut);
5910 if (!total || br < 0)
5911 return -1;
5912 return nr_free;
5913}
5914