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