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