xref: /linux/fs/ntfs/index.c (revision cdd4dc3aebeab43a72ce0bc2b5bab6f0a80b97a5)
11e9ea7e0SNamjae Jeon // SPDX-License-Identifier: GPL-2.0-or-later
21e9ea7e0SNamjae Jeon /*
30a8ac0c1SNamjae Jeon  * NTFS kernel index handling.
41e9ea7e0SNamjae Jeon  *
51e9ea7e0SNamjae Jeon  * Copyright (c) 2004-2005 Anton Altaparmakov
60a8ac0c1SNamjae Jeon  * Copyright (c) 2025 LG Electronics Co., Ltd.
70a8ac0c1SNamjae Jeon  *
80a8ac0c1SNamjae Jeon  * Part of this file is based on code from the NTFS-3G.
90a8ac0c1SNamjae Jeon  * and is copyrighted by the respective authors below:
100a8ac0c1SNamjae Jeon  * Copyright (c) 2004-2005 Anton Altaparmakov
110a8ac0c1SNamjae Jeon  * Copyright (c) 2004-2005 Richard Russon
120a8ac0c1SNamjae Jeon  * Copyright (c) 2005-2006 Yura Pakhuchiy
130a8ac0c1SNamjae Jeon  * Copyright (c) 2005-2008 Szabolcs Szakacsits
140a8ac0c1SNamjae Jeon  * Copyright (c) 2007-2021 Jean-Pierre Andre
151e9ea7e0SNamjae Jeon  */
161e9ea7e0SNamjae Jeon 
171e9ea7e0SNamjae Jeon #include "collate.h"
181e9ea7e0SNamjae Jeon #include "index.h"
191e9ea7e0SNamjae Jeon #include "ntfs.h"
200a8ac0c1SNamjae Jeon #include "attrlist.h"
211e9ea7e0SNamjae Jeon 
220a8ac0c1SNamjae Jeon /*
230a8ac0c1SNamjae Jeon  * ntfs_index_entry_inconsistent - Check the consistency of an index entry
241e9ea7e0SNamjae Jeon  *
250a8ac0c1SNamjae Jeon  * Make sure data and key do not overflow from entry.
260a8ac0c1SNamjae Jeon  * As a side effect, an entry with zero length is rejected.
270a8ac0c1SNamjae Jeon  * This entry must be a full one (no INDEX_ENTRY_END flag), and its
280a8ac0c1SNamjae Jeon  * length must have been checked beforehand to not overflow from the
290a8ac0c1SNamjae Jeon  * index record.
301e9ea7e0SNamjae Jeon  */
310a8ac0c1SNamjae Jeon int ntfs_index_entry_inconsistent(struct ntfs_index_context *icx,
320a8ac0c1SNamjae Jeon 		struct ntfs_volume *vol, const struct index_entry *ie,
330a8ac0c1SNamjae Jeon 		__le32 collation_rule, u64 inum)
341e9ea7e0SNamjae Jeon {
350a8ac0c1SNamjae Jeon 	if (icx) {
360a8ac0c1SNamjae Jeon 		struct index_header *ih;
370a8ac0c1SNamjae Jeon 		u8 *ie_start, *ie_end;
381e9ea7e0SNamjae Jeon 
390a8ac0c1SNamjae Jeon 		if (icx->is_in_root)
400a8ac0c1SNamjae Jeon 			ih = &icx->ir->index;
410a8ac0c1SNamjae Jeon 		else
420a8ac0c1SNamjae Jeon 			ih = &icx->ib->index;
430a8ac0c1SNamjae Jeon 
440a8ac0c1SNamjae Jeon 		if ((le32_to_cpu(ih->index_length) > le32_to_cpu(ih->allocated_size)) ||
450a8ac0c1SNamjae Jeon 				(le32_to_cpu(ih->index_length) > icx->block_size)) {
460a8ac0c1SNamjae Jeon 			ntfs_error(vol->sb, "%s Index entry(0x%p)'s length is too big.",
470a8ac0c1SNamjae Jeon 					icx->is_in_root ? "Index root" : "Index block",
480a8ac0c1SNamjae Jeon 					(u8 *)icx->entry);
490a8ac0c1SNamjae Jeon 			return -EINVAL;
501e9ea7e0SNamjae Jeon 		}
511e9ea7e0SNamjae Jeon 
520a8ac0c1SNamjae Jeon 		ie_start = (u8 *)ih + le32_to_cpu(ih->entries_offset);
530a8ac0c1SNamjae Jeon 		ie_end = (u8 *)ih + le32_to_cpu(ih->index_length);
540a8ac0c1SNamjae Jeon 
550a8ac0c1SNamjae Jeon 		if (ie_start > (u8 *)ie ||
560a8ac0c1SNamjae Jeon 		    ie_end <= (u8 *)ie + le16_to_cpu(ie->length) ||
570a8ac0c1SNamjae Jeon 		    le16_to_cpu(ie->length) > le32_to_cpu(ih->allocated_size) ||
580a8ac0c1SNamjae Jeon 		    le16_to_cpu(ie->length) > icx->block_size) {
590a8ac0c1SNamjae Jeon 			ntfs_error(vol->sb, "Index entry(0x%p) is out of range from %s",
600a8ac0c1SNamjae Jeon 					(u8 *)icx->entry,
610a8ac0c1SNamjae Jeon 					icx->is_in_root ? "index root" : "index block");
620a8ac0c1SNamjae Jeon 			return -EIO;
630a8ac0c1SNamjae Jeon 		}
640a8ac0c1SNamjae Jeon 	}
650a8ac0c1SNamjae Jeon 
660a8ac0c1SNamjae Jeon 	if (ie->key_length &&
670a8ac0c1SNamjae Jeon 	    ((le16_to_cpu(ie->key_length) + offsetof(struct index_entry, key)) >
680a8ac0c1SNamjae Jeon 	     le16_to_cpu(ie->length))) {
690a8ac0c1SNamjae Jeon 		ntfs_error(vol->sb, "Overflow from index entry in inode %lld\n",
700a8ac0c1SNamjae Jeon 				(long long)inum);
710a8ac0c1SNamjae Jeon 		return -EIO;
720a8ac0c1SNamjae Jeon 
731e9ea7e0SNamjae Jeon 	} else {
740a8ac0c1SNamjae Jeon 		if (collation_rule == COLLATION_FILE_NAME) {
750a8ac0c1SNamjae Jeon 			if ((offsetof(struct index_entry, key.file_name.file_name) +
760a8ac0c1SNamjae Jeon 			     ie->key.file_name.file_name_length	* sizeof(__le16)) >
770a8ac0c1SNamjae Jeon 					le16_to_cpu(ie->length)) {
780a8ac0c1SNamjae Jeon 				ntfs_error(vol->sb,
790a8ac0c1SNamjae Jeon 					"File name overflow from index entry in inode %lld\n",
800a8ac0c1SNamjae Jeon 					(long long)inum);
810a8ac0c1SNamjae Jeon 				return -EIO;
820a8ac0c1SNamjae Jeon 			}
830a8ac0c1SNamjae Jeon 		} else {
840a8ac0c1SNamjae Jeon 			if (ie->data.vi.data_length &&
850a8ac0c1SNamjae Jeon 			    ((le16_to_cpu(ie->data.vi.data_offset) +
860a8ac0c1SNamjae Jeon 			      le16_to_cpu(ie->data.vi.data_length)) >
870a8ac0c1SNamjae Jeon 			     le16_to_cpu(ie->length))) {
880a8ac0c1SNamjae Jeon 				ntfs_error(vol->sb,
890a8ac0c1SNamjae Jeon 					"Data overflow from index entry in inode %lld\n",
900a8ac0c1SNamjae Jeon 					(long long)inum);
910a8ac0c1SNamjae Jeon 				return -EIO;
921e9ea7e0SNamjae Jeon 			}
931e9ea7e0SNamjae Jeon 		}
941e9ea7e0SNamjae Jeon 	}
951e9ea7e0SNamjae Jeon 
960a8ac0c1SNamjae Jeon 	return 0;
970a8ac0c1SNamjae Jeon }
980a8ac0c1SNamjae Jeon 
990a8ac0c1SNamjae Jeon /*
1000a8ac0c1SNamjae Jeon  * ntfs_index_entry_mark_dirty - mark an index entry dirty
1010a8ac0c1SNamjae Jeon  * @ictx:	ntfs index context describing the index entry
1021e9ea7e0SNamjae Jeon  *
1030a8ac0c1SNamjae Jeon  * Mark the index entry described by the index entry context @ictx dirty.
1041e9ea7e0SNamjae Jeon  *
1050a8ac0c1SNamjae Jeon  * If the index entry is in the index root attribute, simply mark the inode
1060a8ac0c1SNamjae Jeon  * containing the index root attribute dirty.  This ensures the mftrecord, and
1070a8ac0c1SNamjae Jeon  * hence the index root attribute, will be written out to disk later.
1081e9ea7e0SNamjae Jeon  *
1090a8ac0c1SNamjae Jeon  * If the index entry is in an index block belonging to the index allocation
1100a8ac0c1SNamjae Jeon  * attribute, set ib_dirty to true, thus index block will be updated during
1110a8ac0c1SNamjae Jeon  * ntfs_index_ctx_put.
1121e9ea7e0SNamjae Jeon  */
1130a8ac0c1SNamjae Jeon void ntfs_index_entry_mark_dirty(struct ntfs_index_context *ictx)
1141e9ea7e0SNamjae Jeon {
1150a8ac0c1SNamjae Jeon 	if (ictx->is_in_root)
1160a8ac0c1SNamjae Jeon 		mark_mft_record_dirty(ictx->actx->ntfs_ino);
1170a8ac0c1SNamjae Jeon 	else if (ictx->ib)
1180a8ac0c1SNamjae Jeon 		ictx->ib_dirty = true;
1190a8ac0c1SNamjae Jeon }
1201e9ea7e0SNamjae Jeon 
1210a8ac0c1SNamjae Jeon static s64 ntfs_ib_vcn_to_pos(struct ntfs_index_context *icx, s64 vcn)
1220a8ac0c1SNamjae Jeon {
1230a8ac0c1SNamjae Jeon 	return vcn << icx->vcn_size_bits;
1241e9ea7e0SNamjae Jeon }
1250a8ac0c1SNamjae Jeon 
1260a8ac0c1SNamjae Jeon static s64 ntfs_ib_pos_to_vcn(struct ntfs_index_context *icx, s64 pos)
1270a8ac0c1SNamjae Jeon {
1280a8ac0c1SNamjae Jeon 	return pos >> icx->vcn_size_bits;
1291e9ea7e0SNamjae Jeon }
1300a8ac0c1SNamjae Jeon 
1310a8ac0c1SNamjae Jeon static int ntfs_ib_write(struct ntfs_index_context *icx, struct index_block *ib)
1320a8ac0c1SNamjae Jeon {
1330a8ac0c1SNamjae Jeon 	s64 ret, vcn = le64_to_cpu(ib->index_block_vcn);
1340a8ac0c1SNamjae Jeon 
1350a8ac0c1SNamjae Jeon 	ntfs_debug("vcn: %lld\n", vcn);
1360a8ac0c1SNamjae Jeon 
1370a8ac0c1SNamjae Jeon 	ret = pre_write_mst_fixup((struct ntfs_record *)ib, icx->block_size);
1380a8ac0c1SNamjae Jeon 	if (ret)
1390a8ac0c1SNamjae Jeon 		return -EIO;
1400a8ac0c1SNamjae Jeon 
1410a8ac0c1SNamjae Jeon 	ret = ntfs_inode_attr_pwrite(VFS_I(icx->ia_ni),
1420a8ac0c1SNamjae Jeon 			ntfs_ib_vcn_to_pos(icx, vcn), icx->block_size,
1430a8ac0c1SNamjae Jeon 			(u8 *)ib, icx->sync_write);
1440a8ac0c1SNamjae Jeon 	if (ret != icx->block_size) {
1450a8ac0c1SNamjae Jeon 		ntfs_debug("Failed to write index block %lld, inode %llu",
1460a8ac0c1SNamjae Jeon 				vcn, (unsigned long long)icx->idx_ni->mft_no);
1470a8ac0c1SNamjae Jeon 		return ret;
1480a8ac0c1SNamjae Jeon 	}
1490a8ac0c1SNamjae Jeon 
1500a8ac0c1SNamjae Jeon 	return 0;
1510a8ac0c1SNamjae Jeon }
1520a8ac0c1SNamjae Jeon 
1530a8ac0c1SNamjae Jeon static int ntfs_icx_ib_write(struct ntfs_index_context *icx)
1540a8ac0c1SNamjae Jeon {
1550a8ac0c1SNamjae Jeon 	int err;
1560a8ac0c1SNamjae Jeon 
1570a8ac0c1SNamjae Jeon 	err = ntfs_ib_write(icx, icx->ib);
1580a8ac0c1SNamjae Jeon 	if (err)
1590a8ac0c1SNamjae Jeon 		return err;
1600a8ac0c1SNamjae Jeon 
1610a8ac0c1SNamjae Jeon 	icx->ib_dirty = false;
1620a8ac0c1SNamjae Jeon 
1630a8ac0c1SNamjae Jeon 	return 0;
1640a8ac0c1SNamjae Jeon }
1650a8ac0c1SNamjae Jeon 
1660a8ac0c1SNamjae Jeon int ntfs_icx_ib_sync_write(struct ntfs_index_context *icx)
1670a8ac0c1SNamjae Jeon {
1680a8ac0c1SNamjae Jeon 	int ret;
1690a8ac0c1SNamjae Jeon 
1700a8ac0c1SNamjae Jeon 	if (icx->ib_dirty == false)
1710a8ac0c1SNamjae Jeon 		return 0;
1720a8ac0c1SNamjae Jeon 
1730a8ac0c1SNamjae Jeon 	icx->sync_write = true;
1740a8ac0c1SNamjae Jeon 
1750a8ac0c1SNamjae Jeon 	ret = ntfs_ib_write(icx, icx->ib);
1760a8ac0c1SNamjae Jeon 	if (!ret) {
1770a8ac0c1SNamjae Jeon 		kvfree(icx->ib);
1780a8ac0c1SNamjae Jeon 		icx->ib = NULL;
1790a8ac0c1SNamjae Jeon 		icx->ib_dirty = false;
1800a8ac0c1SNamjae Jeon 	} else {
1810a8ac0c1SNamjae Jeon 		post_write_mst_fixup((struct ntfs_record *)icx->ib);
1820a8ac0c1SNamjae Jeon 		icx->sync_write = false;
1830a8ac0c1SNamjae Jeon 	}
1840a8ac0c1SNamjae Jeon 
1850a8ac0c1SNamjae Jeon 	return ret;
1860a8ac0c1SNamjae Jeon }
1870a8ac0c1SNamjae Jeon 
1880a8ac0c1SNamjae Jeon /*
1890a8ac0c1SNamjae Jeon  * ntfs_index_ctx_get - allocate and initialize a new index context
1900a8ac0c1SNamjae Jeon  * @ni:		ntfs inode with which to initialize the context
1910a8ac0c1SNamjae Jeon  * @name:	name of the which context describes
1920a8ac0c1SNamjae Jeon  * @name_len:	length of the index name
1930a8ac0c1SNamjae Jeon  *
1940a8ac0c1SNamjae Jeon  * Allocate a new index context, initialize it with @ni and return it.
1950a8ac0c1SNamjae Jeon  * Return NULL if allocation failed.
1960a8ac0c1SNamjae Jeon  */
1970a8ac0c1SNamjae Jeon struct ntfs_index_context *ntfs_index_ctx_get(struct ntfs_inode *ni,
1980a8ac0c1SNamjae Jeon 		__le16 *name, u32 name_len)
1990a8ac0c1SNamjae Jeon {
2000a8ac0c1SNamjae Jeon 	struct ntfs_index_context *icx;
2010a8ac0c1SNamjae Jeon 
2020a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
2030a8ac0c1SNamjae Jeon 
2040a8ac0c1SNamjae Jeon 	if (!ni)
2050a8ac0c1SNamjae Jeon 		return NULL;
2060a8ac0c1SNamjae Jeon 
2070a8ac0c1SNamjae Jeon 	if (ni->nr_extents == -1)
2080a8ac0c1SNamjae Jeon 		ni = ni->ext.base_ntfs_ino;
2090a8ac0c1SNamjae Jeon 
2100a8ac0c1SNamjae Jeon 	icx = kmem_cache_alloc(ntfs_index_ctx_cache, GFP_NOFS);
2110a8ac0c1SNamjae Jeon 	if (icx)
2120a8ac0c1SNamjae Jeon 		*icx = (struct ntfs_index_context) {
2130a8ac0c1SNamjae Jeon 			.idx_ni = ni,
2140a8ac0c1SNamjae Jeon 			.name = name,
2150a8ac0c1SNamjae Jeon 			.name_len = name_len,
2160a8ac0c1SNamjae Jeon 		};
2170a8ac0c1SNamjae Jeon 	return icx;
2180a8ac0c1SNamjae Jeon }
2190a8ac0c1SNamjae Jeon 
2200a8ac0c1SNamjae Jeon static void ntfs_index_ctx_free(struct ntfs_index_context *icx)
2210a8ac0c1SNamjae Jeon {
2220a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
2230a8ac0c1SNamjae Jeon 
2240a8ac0c1SNamjae Jeon 	if (icx->actx) {
2250a8ac0c1SNamjae Jeon 		ntfs_attr_put_search_ctx(icx->actx);
2260a8ac0c1SNamjae Jeon 		icx->actx = NULL;
2270a8ac0c1SNamjae Jeon 	}
2280a8ac0c1SNamjae Jeon 
2290a8ac0c1SNamjae Jeon 	if (!icx->is_in_root) {
2300a8ac0c1SNamjae Jeon 		if (icx->ib_dirty)
2310a8ac0c1SNamjae Jeon 			ntfs_ib_write(icx, icx->ib);
2320a8ac0c1SNamjae Jeon 		kvfree(icx->ib);
2330a8ac0c1SNamjae Jeon 		icx->ib = NULL;
2340a8ac0c1SNamjae Jeon 	}
2350a8ac0c1SNamjae Jeon 
2360a8ac0c1SNamjae Jeon 	if (icx->ia_ni) {
2370a8ac0c1SNamjae Jeon 		iput(VFS_I(icx->ia_ni));
2380a8ac0c1SNamjae Jeon 		icx->ia_ni = NULL;
2390a8ac0c1SNamjae Jeon 	}
2400a8ac0c1SNamjae Jeon }
2410a8ac0c1SNamjae Jeon 
2420a8ac0c1SNamjae Jeon /*
2430a8ac0c1SNamjae Jeon  * ntfs_index_ctx_put - release an index context
2440a8ac0c1SNamjae Jeon  * @icx:	index context to free
2450a8ac0c1SNamjae Jeon  *
2460a8ac0c1SNamjae Jeon  * Release the index context @icx, releasing all associated resources.
2470a8ac0c1SNamjae Jeon  */
2480a8ac0c1SNamjae Jeon void ntfs_index_ctx_put(struct ntfs_index_context *icx)
2490a8ac0c1SNamjae Jeon {
2500a8ac0c1SNamjae Jeon 	ntfs_index_ctx_free(icx);
2510a8ac0c1SNamjae Jeon 	kmem_cache_free(ntfs_index_ctx_cache, icx);
2520a8ac0c1SNamjae Jeon }
2530a8ac0c1SNamjae Jeon 
2540a8ac0c1SNamjae Jeon /*
2550a8ac0c1SNamjae Jeon  * ntfs_index_ctx_reinit - reinitialize an index context
2560a8ac0c1SNamjae Jeon  * @icx:	index context to reinitialize
2570a8ac0c1SNamjae Jeon  *
2580a8ac0c1SNamjae Jeon  * Reinitialize the index context @icx so it can be used for ntfs_index_lookup.
2590a8ac0c1SNamjae Jeon  */
2600a8ac0c1SNamjae Jeon void ntfs_index_ctx_reinit(struct ntfs_index_context *icx)
2610a8ac0c1SNamjae Jeon {
2620a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
2630a8ac0c1SNamjae Jeon 
2640a8ac0c1SNamjae Jeon 	ntfs_index_ctx_free(icx);
2650a8ac0c1SNamjae Jeon 
2660a8ac0c1SNamjae Jeon 	*icx = (struct ntfs_index_context) {
2670a8ac0c1SNamjae Jeon 		.idx_ni = icx->idx_ni,
2680a8ac0c1SNamjae Jeon 		.name = icx->name,
2690a8ac0c1SNamjae Jeon 		.name_len = icx->name_len,
2700a8ac0c1SNamjae Jeon 	};
2710a8ac0c1SNamjae Jeon }
2720a8ac0c1SNamjae Jeon 
2730a8ac0c1SNamjae Jeon static __le64 *ntfs_ie_get_vcn_addr(struct index_entry *ie)
2740a8ac0c1SNamjae Jeon {
2750a8ac0c1SNamjae Jeon 	return (__le64 *)((u8 *)ie + le16_to_cpu(ie->length) - sizeof(s64));
2760a8ac0c1SNamjae Jeon }
2770a8ac0c1SNamjae Jeon 
2780a8ac0c1SNamjae Jeon /*
2790a8ac0c1SNamjae Jeon  *  Get the subnode vcn to which the index entry refers.
2800a8ac0c1SNamjae Jeon  */
2810a8ac0c1SNamjae Jeon static s64 ntfs_ie_get_vcn(struct index_entry *ie)
2820a8ac0c1SNamjae Jeon {
2830a8ac0c1SNamjae Jeon 	return le64_to_cpup(ntfs_ie_get_vcn_addr(ie));
2840a8ac0c1SNamjae Jeon }
2850a8ac0c1SNamjae Jeon 
2860a8ac0c1SNamjae Jeon static struct index_entry *ntfs_ie_get_first(struct index_header *ih)
2870a8ac0c1SNamjae Jeon {
2880a8ac0c1SNamjae Jeon 	return (struct index_entry *)((u8 *)ih + le32_to_cpu(ih->entries_offset));
2890a8ac0c1SNamjae Jeon }
2900a8ac0c1SNamjae Jeon 
2910a8ac0c1SNamjae Jeon static struct index_entry *ntfs_ie_get_next(struct index_entry *ie)
2920a8ac0c1SNamjae Jeon {
2930a8ac0c1SNamjae Jeon 	return (struct index_entry *)((char *)ie + le16_to_cpu(ie->length));
2940a8ac0c1SNamjae Jeon }
2950a8ac0c1SNamjae Jeon 
2960a8ac0c1SNamjae Jeon static u8 *ntfs_ie_get_end(struct index_header *ih)
2970a8ac0c1SNamjae Jeon {
2980a8ac0c1SNamjae Jeon 	return (u8 *)ih + le32_to_cpu(ih->index_length);
2990a8ac0c1SNamjae Jeon }
3000a8ac0c1SNamjae Jeon 
3010a8ac0c1SNamjae Jeon static int ntfs_ie_end(struct index_entry *ie)
3020a8ac0c1SNamjae Jeon {
3030a8ac0c1SNamjae Jeon 	return ie->flags & INDEX_ENTRY_END || !ie->length;
3040a8ac0c1SNamjae Jeon }
3050a8ac0c1SNamjae Jeon 
3060a8ac0c1SNamjae Jeon /*
3070a8ac0c1SNamjae Jeon  *  Find the last entry in the index block
3080a8ac0c1SNamjae Jeon  */
3090a8ac0c1SNamjae Jeon static struct index_entry *ntfs_ie_get_last(struct index_entry *ie, char *ies_end)
3100a8ac0c1SNamjae Jeon {
3110a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
3120a8ac0c1SNamjae Jeon 
3130a8ac0c1SNamjae Jeon 	while ((char *)ie < ies_end && !ntfs_ie_end(ie))
3140a8ac0c1SNamjae Jeon 		ie = ntfs_ie_get_next(ie);
3150a8ac0c1SNamjae Jeon 
3160a8ac0c1SNamjae Jeon 	return ie;
3170a8ac0c1SNamjae Jeon }
3180a8ac0c1SNamjae Jeon 
3190a8ac0c1SNamjae Jeon static struct index_entry *ntfs_ie_get_by_pos(struct index_header *ih, int pos)
3200a8ac0c1SNamjae Jeon {
3210a8ac0c1SNamjae Jeon 	struct index_entry *ie;
3220a8ac0c1SNamjae Jeon 
3230a8ac0c1SNamjae Jeon 	ntfs_debug("pos: %d\n", pos);
3240a8ac0c1SNamjae Jeon 
3250a8ac0c1SNamjae Jeon 	ie = ntfs_ie_get_first(ih);
3260a8ac0c1SNamjae Jeon 
3270a8ac0c1SNamjae Jeon 	while (pos-- > 0)
3280a8ac0c1SNamjae Jeon 		ie = ntfs_ie_get_next(ie);
3290a8ac0c1SNamjae Jeon 
3300a8ac0c1SNamjae Jeon 	return ie;
3310a8ac0c1SNamjae Jeon }
3320a8ac0c1SNamjae Jeon 
3330a8ac0c1SNamjae Jeon static struct index_entry *ntfs_ie_prev(struct index_header *ih, struct index_entry *ie)
3340a8ac0c1SNamjae Jeon {
3350a8ac0c1SNamjae Jeon 	struct index_entry *ie_prev = NULL;
3360a8ac0c1SNamjae Jeon 	struct index_entry *tmp;
3370a8ac0c1SNamjae Jeon 
3380a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
3390a8ac0c1SNamjae Jeon 
3400a8ac0c1SNamjae Jeon 	tmp = ntfs_ie_get_first(ih);
3410a8ac0c1SNamjae Jeon 
3420a8ac0c1SNamjae Jeon 	while (tmp != ie) {
3430a8ac0c1SNamjae Jeon 		ie_prev = tmp;
3440a8ac0c1SNamjae Jeon 		tmp = ntfs_ie_get_next(tmp);
3450a8ac0c1SNamjae Jeon 	}
3460a8ac0c1SNamjae Jeon 
3470a8ac0c1SNamjae Jeon 	return ie_prev;
3480a8ac0c1SNamjae Jeon }
3490a8ac0c1SNamjae Jeon 
3500a8ac0c1SNamjae Jeon static int ntfs_ih_numof_entries(struct index_header *ih)
3510a8ac0c1SNamjae Jeon {
3520a8ac0c1SNamjae Jeon 	int n;
3530a8ac0c1SNamjae Jeon 	struct index_entry *ie;
3540a8ac0c1SNamjae Jeon 	u8 *end;
3550a8ac0c1SNamjae Jeon 
3560a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
3570a8ac0c1SNamjae Jeon 
3580a8ac0c1SNamjae Jeon 	end = ntfs_ie_get_end(ih);
3590a8ac0c1SNamjae Jeon 	ie = ntfs_ie_get_first(ih);
3600a8ac0c1SNamjae Jeon 	for (n = 0; !ntfs_ie_end(ie) && (u8 *)ie < end; n++)
3610a8ac0c1SNamjae Jeon 		ie = ntfs_ie_get_next(ie);
3620a8ac0c1SNamjae Jeon 	return n;
3630a8ac0c1SNamjae Jeon }
3640a8ac0c1SNamjae Jeon 
3650a8ac0c1SNamjae Jeon static int ntfs_ih_one_entry(struct index_header *ih)
3660a8ac0c1SNamjae Jeon {
3670a8ac0c1SNamjae Jeon 	return (ntfs_ih_numof_entries(ih) == 1);
3680a8ac0c1SNamjae Jeon }
3690a8ac0c1SNamjae Jeon 
3700a8ac0c1SNamjae Jeon static int ntfs_ih_zero_entry(struct index_header *ih)
3710a8ac0c1SNamjae Jeon {
3720a8ac0c1SNamjae Jeon 	return (ntfs_ih_numof_entries(ih) == 0);
3730a8ac0c1SNamjae Jeon }
3740a8ac0c1SNamjae Jeon 
3750a8ac0c1SNamjae Jeon static void ntfs_ie_delete(struct index_header *ih, struct index_entry *ie)
3760a8ac0c1SNamjae Jeon {
3770a8ac0c1SNamjae Jeon 	u32 new_size;
3780a8ac0c1SNamjae Jeon 
3790a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
3800a8ac0c1SNamjae Jeon 
3810a8ac0c1SNamjae Jeon 	new_size = le32_to_cpu(ih->index_length) - le16_to_cpu(ie->length);
3820a8ac0c1SNamjae Jeon 	ih->index_length = cpu_to_le32(new_size);
3830a8ac0c1SNamjae Jeon 	memmove(ie, (u8 *)ie + le16_to_cpu(ie->length),
3840a8ac0c1SNamjae Jeon 			new_size - ((u8 *)ie - (u8 *)ih));
3850a8ac0c1SNamjae Jeon }
3860a8ac0c1SNamjae Jeon 
3870a8ac0c1SNamjae Jeon static void ntfs_ie_set_vcn(struct index_entry *ie, s64 vcn)
3880a8ac0c1SNamjae Jeon {
3890a8ac0c1SNamjae Jeon 	*ntfs_ie_get_vcn_addr(ie) = cpu_to_le64(vcn);
3900a8ac0c1SNamjae Jeon }
3910a8ac0c1SNamjae Jeon 
3920a8ac0c1SNamjae Jeon /*
3930a8ac0c1SNamjae Jeon  *  Insert @ie index entry at @pos entry. Used @ih values should be ok already.
3940a8ac0c1SNamjae Jeon  */
3950a8ac0c1SNamjae Jeon static void ntfs_ie_insert(struct index_header *ih, struct index_entry *ie,
3960a8ac0c1SNamjae Jeon 		struct index_entry *pos)
3970a8ac0c1SNamjae Jeon {
3980a8ac0c1SNamjae Jeon 	int ie_size = le16_to_cpu(ie->length);
3990a8ac0c1SNamjae Jeon 
4000a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
4010a8ac0c1SNamjae Jeon 
4020a8ac0c1SNamjae Jeon 	ih->index_length = cpu_to_le32(le32_to_cpu(ih->index_length) + ie_size);
4030a8ac0c1SNamjae Jeon 	memmove((u8 *)pos + ie_size, pos,
4040a8ac0c1SNamjae Jeon 			le32_to_cpu(ih->index_length) - ((u8 *)pos - (u8 *)ih) - ie_size);
4050a8ac0c1SNamjae Jeon 	memcpy(pos, ie, ie_size);
4060a8ac0c1SNamjae Jeon }
4070a8ac0c1SNamjae Jeon 
4080a8ac0c1SNamjae Jeon static struct index_entry *ntfs_ie_dup(struct index_entry *ie)
4090a8ac0c1SNamjae Jeon {
4100a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
4110a8ac0c1SNamjae Jeon 
4120a8ac0c1SNamjae Jeon 	return kmemdup(ie, le16_to_cpu(ie->length), GFP_NOFS);
4130a8ac0c1SNamjae Jeon }
4140a8ac0c1SNamjae Jeon 
4150a8ac0c1SNamjae Jeon static struct index_entry *ntfs_ie_dup_novcn(struct index_entry *ie)
4160a8ac0c1SNamjae Jeon {
4170a8ac0c1SNamjae Jeon 	struct index_entry *dup;
4180a8ac0c1SNamjae Jeon 	int size = le16_to_cpu(ie->length);
4190a8ac0c1SNamjae Jeon 
4200a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
4210a8ac0c1SNamjae Jeon 
4220a8ac0c1SNamjae Jeon 	if (ie->flags & INDEX_ENTRY_NODE)
4230a8ac0c1SNamjae Jeon 		size -= sizeof(s64);
4240a8ac0c1SNamjae Jeon 
4250a8ac0c1SNamjae Jeon 	dup = kmemdup(ie, size, GFP_NOFS);
4260a8ac0c1SNamjae Jeon 	if (dup) {
4270a8ac0c1SNamjae Jeon 		dup->flags &= ~INDEX_ENTRY_NODE;
4280a8ac0c1SNamjae Jeon 		dup->length = cpu_to_le16(size);
4290a8ac0c1SNamjae Jeon 	}
4300a8ac0c1SNamjae Jeon 	return dup;
4310a8ac0c1SNamjae Jeon }
4320a8ac0c1SNamjae Jeon 
4330a8ac0c1SNamjae Jeon /*
4340a8ac0c1SNamjae Jeon  * Check the consistency of an index block
4350a8ac0c1SNamjae Jeon  *
4360a8ac0c1SNamjae Jeon  * Make sure the index block does not overflow from the index record.
4370a8ac0c1SNamjae Jeon  * The size of block is assumed to have been checked to be what is
4380a8ac0c1SNamjae Jeon  * defined in the index root.
4390a8ac0c1SNamjae Jeon  *
4400a8ac0c1SNamjae Jeon  * Returns 0 if no error was found -1 otherwise (with errno unchanged)
4410a8ac0c1SNamjae Jeon  *
4420a8ac0c1SNamjae Jeon  * |<--->|  offsetof(struct index_block, index)
4430a8ac0c1SNamjae Jeon  * |     |<--->|  sizeof(struct index_header)
4440a8ac0c1SNamjae Jeon  * |     |     |
4450a8ac0c1SNamjae Jeon  * |     |     | seq          index entries         unused
4460a8ac0c1SNamjae Jeon  * |=====|=====|=====|===========================|==============|
4470a8ac0c1SNamjae Jeon  * |     |           |                           |              |
4480a8ac0c1SNamjae Jeon  * |     |<--------->| entries_offset            |              |
4490a8ac0c1SNamjae Jeon  * |     |<---------------- index_length ------->|              |
4500a8ac0c1SNamjae Jeon  * |     |<--------------------- allocated_size --------------->|
4510a8ac0c1SNamjae Jeon  * |<--------------------------- block_size ------------------->|
4520a8ac0c1SNamjae Jeon  *
4530a8ac0c1SNamjae Jeon  * size(struct index_header) <= ent_offset < ind_length <= alloc_size < bk_size
4540a8ac0c1SNamjae Jeon  */
4550a8ac0c1SNamjae Jeon static int ntfs_index_block_inconsistent(struct ntfs_index_context *icx,
4560a8ac0c1SNamjae Jeon 		struct index_block *ib, s64 vcn)
4570a8ac0c1SNamjae Jeon {
4580a8ac0c1SNamjae Jeon 	u32 ib_size = (unsigned int)le32_to_cpu(ib->index.allocated_size) +
4590a8ac0c1SNamjae Jeon 		offsetof(struct index_block, index);
4600a8ac0c1SNamjae Jeon 	struct super_block *sb = icx->idx_ni->vol->sb;
4610a8ac0c1SNamjae Jeon 	unsigned long long inum = icx->idx_ni->mft_no;
4620a8ac0c1SNamjae Jeon 
4630a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
4640a8ac0c1SNamjae Jeon 
4650a8ac0c1SNamjae Jeon 	if (!ntfs_is_indx_record(ib->magic)) {
4660a8ac0c1SNamjae Jeon 
4670a8ac0c1SNamjae Jeon 		ntfs_error(sb, "Corrupt index block signature: vcn %lld inode %llu\n",
4680a8ac0c1SNamjae Jeon 				vcn, (unsigned long long)icx->idx_ni->mft_no);
4690a8ac0c1SNamjae Jeon 		return -1;
4700a8ac0c1SNamjae Jeon 	}
4710a8ac0c1SNamjae Jeon 
4720a8ac0c1SNamjae Jeon 	if (le64_to_cpu(ib->index_block_vcn) != vcn) {
4730a8ac0c1SNamjae Jeon 		ntfs_error(sb,
4740a8ac0c1SNamjae Jeon 			"Corrupt index block: s64 (%lld) is different from expected s64 (%lld) in inode %llu\n",
4750a8ac0c1SNamjae Jeon 			(long long)le64_to_cpu(ib->index_block_vcn),
4760a8ac0c1SNamjae Jeon 			vcn, inum);
4770a8ac0c1SNamjae Jeon 		return -1;
4780a8ac0c1SNamjae Jeon 	}
4790a8ac0c1SNamjae Jeon 
4800a8ac0c1SNamjae Jeon 	if (ib_size != icx->block_size) {
4810a8ac0c1SNamjae Jeon 		ntfs_error(sb,
4820a8ac0c1SNamjae Jeon 			"Corrupt index block : s64 (%lld) of inode %llu has a size (%u) differing from the index specified size (%u)\n",
4830a8ac0c1SNamjae Jeon 			vcn, inum, ib_size, icx->block_size);
4840a8ac0c1SNamjae Jeon 		return -1;
4850a8ac0c1SNamjae Jeon 	}
4860a8ac0c1SNamjae Jeon 
4870a8ac0c1SNamjae Jeon 	if (le32_to_cpu(ib->index.entries_offset) < sizeof(struct index_header)) {
4880a8ac0c1SNamjae Jeon 		ntfs_error(sb, "Invalid index entry offset in inode %lld\n", inum);
4890a8ac0c1SNamjae Jeon 		return -1;
4900a8ac0c1SNamjae Jeon 	}
4910a8ac0c1SNamjae Jeon 	if (le32_to_cpu(ib->index.index_length) <=
4920a8ac0c1SNamjae Jeon 	    le32_to_cpu(ib->index.entries_offset)) {
4930a8ac0c1SNamjae Jeon 		ntfs_error(sb, "No space for index entries in inode %lld\n", inum);
4940a8ac0c1SNamjae Jeon 		return -1;
4950a8ac0c1SNamjae Jeon 	}
4960a8ac0c1SNamjae Jeon 	if (le32_to_cpu(ib->index.allocated_size) <
4970a8ac0c1SNamjae Jeon 	    le32_to_cpu(ib->index.index_length)) {
4980a8ac0c1SNamjae Jeon 		ntfs_error(sb, "Index entries overflow in inode %lld\n", inum);
4990a8ac0c1SNamjae Jeon 		return -1;
5000a8ac0c1SNamjae Jeon 	}
5010a8ac0c1SNamjae Jeon 
5020a8ac0c1SNamjae Jeon 	return 0;
5030a8ac0c1SNamjae Jeon }
5040a8ac0c1SNamjae Jeon 
5050a8ac0c1SNamjae Jeon static struct index_root *ntfs_ir_lookup(struct ntfs_inode *ni, __le16 *name,
5060a8ac0c1SNamjae Jeon 		u32 name_len, struct ntfs_attr_search_ctx **ctx)
5070a8ac0c1SNamjae Jeon {
5080a8ac0c1SNamjae Jeon 	struct attr_record *a;
5090a8ac0c1SNamjae Jeon 	struct index_root *ir = NULL;
5100a8ac0c1SNamjae Jeon 
5110a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
5120a8ac0c1SNamjae Jeon 	*ctx = ntfs_attr_get_search_ctx(ni, NULL);
5130a8ac0c1SNamjae Jeon 	if (!*ctx) {
5140a8ac0c1SNamjae Jeon 		ntfs_error(ni->vol->sb, "%s, Failed to get search context", __func__);
5150a8ac0c1SNamjae Jeon 		return NULL;
5160a8ac0c1SNamjae Jeon 	}
5170a8ac0c1SNamjae Jeon 
5180a8ac0c1SNamjae Jeon 	if (ntfs_attr_lookup(AT_INDEX_ROOT, name, name_len, CASE_SENSITIVE,
5190a8ac0c1SNamjae Jeon 				0, NULL, 0, *ctx)) {
5200a8ac0c1SNamjae Jeon 		ntfs_error(ni->vol->sb, "Failed to lookup $INDEX_ROOT");
5211e9ea7e0SNamjae Jeon 		goto err_out;
5221e9ea7e0SNamjae Jeon 	}
5230a8ac0c1SNamjae Jeon 
5240a8ac0c1SNamjae Jeon 	a = (*ctx)->attr;
5250a8ac0c1SNamjae Jeon 	if (a->non_resident) {
5260a8ac0c1SNamjae Jeon 		ntfs_error(ni->vol->sb, "Non-resident $INDEX_ROOT detected");
5271e9ea7e0SNamjae Jeon 		goto err_out;
5281e9ea7e0SNamjae Jeon 	}
5290a8ac0c1SNamjae Jeon 
5300a8ac0c1SNamjae Jeon 	ir = (struct index_root *)((char *)a + le16_to_cpu(a->data.resident.value_offset));
5310a8ac0c1SNamjae Jeon err_out:
5320a8ac0c1SNamjae Jeon 	if (!ir) {
5330a8ac0c1SNamjae Jeon 		ntfs_attr_put_search_ctx(*ctx);
5340a8ac0c1SNamjae Jeon 		*ctx = NULL;
5350a8ac0c1SNamjae Jeon 	}
5360a8ac0c1SNamjae Jeon 	return ir;
5370a8ac0c1SNamjae Jeon }
5380a8ac0c1SNamjae Jeon 
5390a8ac0c1SNamjae Jeon static struct index_root *ntfs_ir_lookup2(struct ntfs_inode *ni, __le16 *name, u32 len)
5400a8ac0c1SNamjae Jeon {
5410a8ac0c1SNamjae Jeon 	struct ntfs_attr_search_ctx *ctx;
5420a8ac0c1SNamjae Jeon 	struct index_root *ir;
5430a8ac0c1SNamjae Jeon 
5440a8ac0c1SNamjae Jeon 	ir = ntfs_ir_lookup(ni, name, len, &ctx);
5450a8ac0c1SNamjae Jeon 	if (ir)
5460a8ac0c1SNamjae Jeon 		ntfs_attr_put_search_ctx(ctx);
5470a8ac0c1SNamjae Jeon 	return ir;
5480a8ac0c1SNamjae Jeon }
5490a8ac0c1SNamjae Jeon 
5500a8ac0c1SNamjae Jeon /*
5510a8ac0c1SNamjae Jeon  * Find a key in the index block.
5520a8ac0c1SNamjae Jeon  */
5530a8ac0c1SNamjae Jeon static int ntfs_ie_lookup(const void *key, const u32 key_len,
5540a8ac0c1SNamjae Jeon 		struct ntfs_index_context *icx, struct index_header *ih,
5550a8ac0c1SNamjae Jeon 		s64 *vcn, struct index_entry **ie_out)
5560a8ac0c1SNamjae Jeon {
5570a8ac0c1SNamjae Jeon 	struct index_entry *ie;
5580a8ac0c1SNamjae Jeon 	u8 *index_end;
5590a8ac0c1SNamjae Jeon 	int rc, item = 0;
5600a8ac0c1SNamjae Jeon 
5610a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
5620a8ac0c1SNamjae Jeon 
5630a8ac0c1SNamjae Jeon 	index_end = ntfs_ie_get_end(ih);
5640a8ac0c1SNamjae Jeon 
5651e9ea7e0SNamjae Jeon 	/*
5661e9ea7e0SNamjae Jeon 	 * Loop until we exceed valid memory (corruption case) or until we
5671e9ea7e0SNamjae Jeon 	 * reach the last entry.
5681e9ea7e0SNamjae Jeon 	 */
5690a8ac0c1SNamjae Jeon 	for (ie = ntfs_ie_get_first(ih); ; ie = ntfs_ie_get_next(ie)) {
5701e9ea7e0SNamjae Jeon 		/* Bounds checks. */
5710a8ac0c1SNamjae Jeon 		if ((u8 *)ie + sizeof(struct index_entry_header) > index_end ||
5720a8ac0c1SNamjae Jeon 				(u8 *)ie + le16_to_cpu(ie->length) > index_end) {
5730a8ac0c1SNamjae Jeon 			ntfs_error(icx->idx_ni->vol->sb,
5740a8ac0c1SNamjae Jeon 					"Index entry out of bounds in inode %llu.\n",
5750a8ac0c1SNamjae Jeon 					(unsigned long long)icx->idx_ni->mft_no);
5760a8ac0c1SNamjae Jeon 			return -ERANGE;
5770a8ac0c1SNamjae Jeon 		}
5780a8ac0c1SNamjae Jeon 
5791e9ea7e0SNamjae Jeon 		/*
5801e9ea7e0SNamjae Jeon 		 * The last entry cannot contain a key.  It can however contain
5811e9ea7e0SNamjae Jeon 		 * a pointer to a child node in the B+tree so we just break out.
5821e9ea7e0SNamjae Jeon 		 */
5830a8ac0c1SNamjae Jeon 		if (ntfs_ie_end(ie))
5841e9ea7e0SNamjae Jeon 			break;
5850a8ac0c1SNamjae Jeon 
5861e9ea7e0SNamjae Jeon 		/*
5871e9ea7e0SNamjae Jeon 		 * Not a perfect match, need to do full blown collation so we
5881e9ea7e0SNamjae Jeon 		 * know which way in the B+tree we have to go.
5891e9ea7e0SNamjae Jeon 		 */
5900a8ac0c1SNamjae Jeon 		rc = ntfs_collate(icx->idx_ni->vol, icx->cr, key, key_len, &ie->key,
5910a8ac0c1SNamjae Jeon 				le16_to_cpu(ie->key_length));
5920a8ac0c1SNamjae Jeon 		if (rc == -EINVAL) {
5930a8ac0c1SNamjae Jeon 			ntfs_error(icx->idx_ni->vol->sb,
5940a8ac0c1SNamjae Jeon 				"Collation error. Perhaps a filename contains invalid characters?\n");
5950a8ac0c1SNamjae Jeon 			return -ERANGE;
5960a8ac0c1SNamjae Jeon 		}
5971e9ea7e0SNamjae Jeon 		/*
5981e9ea7e0SNamjae Jeon 		 * If @key collates before the key of the current entry, there
5991e9ea7e0SNamjae Jeon 		 * is definitely no such key in this index but we might need to
6001e9ea7e0SNamjae Jeon 		 * descend into the B+tree so we just break out of the loop.
6011e9ea7e0SNamjae Jeon 		 */
6021e9ea7e0SNamjae Jeon 		if (rc == -1)
6031e9ea7e0SNamjae Jeon 			break;
6040a8ac0c1SNamjae Jeon 
6050a8ac0c1SNamjae Jeon 		if (!rc) {
6060a8ac0c1SNamjae Jeon 			*ie_out = ie;
6070a8ac0c1SNamjae Jeon 			icx->parent_pos[icx->pindex] = item;
6080a8ac0c1SNamjae Jeon 			return 0;
6090a8ac0c1SNamjae Jeon 		}
6100a8ac0c1SNamjae Jeon 
6110a8ac0c1SNamjae Jeon 		item++;
6121e9ea7e0SNamjae Jeon 	}
6131e9ea7e0SNamjae Jeon 	/*
6140a8ac0c1SNamjae Jeon 	 * We have finished with this index block without success. Check for the
6150a8ac0c1SNamjae Jeon 	 * presence of a child node and if not present return with errno ENOENT,
6160a8ac0c1SNamjae Jeon 	 * otherwise we will keep searching in another index block.
6171e9ea7e0SNamjae Jeon 	 */
6181e9ea7e0SNamjae Jeon 	if (!(ie->flags & INDEX_ENTRY_NODE)) {
6190a8ac0c1SNamjae Jeon 		ntfs_debug("Index entry wasn't found.\n");
6200a8ac0c1SNamjae Jeon 		*ie_out = ie;
6210a8ac0c1SNamjae Jeon 		return -ENOENT;
6221e9ea7e0SNamjae Jeon 	}
6230a8ac0c1SNamjae Jeon 
6241e9ea7e0SNamjae Jeon 	/* Get the starting vcn of the index_block holding the child node. */
6250a8ac0c1SNamjae Jeon 	*vcn = ntfs_ie_get_vcn(ie);
6260a8ac0c1SNamjae Jeon 	if (*vcn < 0) {
6270a8ac0c1SNamjae Jeon 		ntfs_error(icx->idx_ni->vol->sb, "Negative vcn in inode %llu\n",
6280a8ac0c1SNamjae Jeon 				(unsigned long long)icx->idx_ni->mft_no);
6290a8ac0c1SNamjae Jeon 		return -EINVAL;
6300a8ac0c1SNamjae Jeon 	}
6310a8ac0c1SNamjae Jeon 
6320a8ac0c1SNamjae Jeon 	ntfs_debug("Parent entry number %d\n", item);
6330a8ac0c1SNamjae Jeon 	icx->parent_pos[icx->pindex] = item;
6340a8ac0c1SNamjae Jeon 
6350a8ac0c1SNamjae Jeon 	return -EAGAIN;
6360a8ac0c1SNamjae Jeon }
6370a8ac0c1SNamjae Jeon 
6380a8ac0c1SNamjae Jeon struct ntfs_inode *ntfs_ia_open(struct ntfs_index_context *icx, struct ntfs_inode *ni)
6390a8ac0c1SNamjae Jeon {
6400a8ac0c1SNamjae Jeon 	struct inode *ia_vi;
6410a8ac0c1SNamjae Jeon 
6420a8ac0c1SNamjae Jeon 	ia_vi = ntfs_index_iget(VFS_I(ni), icx->name, icx->name_len);
6430a8ac0c1SNamjae Jeon 	if (IS_ERR(ia_vi)) {
6440a8ac0c1SNamjae Jeon 		ntfs_error(icx->idx_ni->vol->sb,
6450a8ac0c1SNamjae Jeon 				"Failed to open index allocation of inode %llu",
6460a8ac0c1SNamjae Jeon 				(unsigned long long)ni->mft_no);
6470a8ac0c1SNamjae Jeon 		return NULL;
6480a8ac0c1SNamjae Jeon 	}
6490a8ac0c1SNamjae Jeon 
6500a8ac0c1SNamjae Jeon 	return NTFS_I(ia_vi);
6510a8ac0c1SNamjae Jeon }
6520a8ac0c1SNamjae Jeon 
6530a8ac0c1SNamjae Jeon static int ntfs_ib_read(struct ntfs_index_context *icx, s64 vcn, struct index_block *dst)
6540a8ac0c1SNamjae Jeon {
6550a8ac0c1SNamjae Jeon 	s64 pos, ret;
6560a8ac0c1SNamjae Jeon 
6570a8ac0c1SNamjae Jeon 	ntfs_debug("vcn: %lld\n", vcn);
6580a8ac0c1SNamjae Jeon 
6590a8ac0c1SNamjae Jeon 	pos = ntfs_ib_vcn_to_pos(icx, vcn);
6600a8ac0c1SNamjae Jeon 
6610a8ac0c1SNamjae Jeon 	ret = ntfs_inode_attr_pread(VFS_I(icx->ia_ni), pos, icx->block_size, (u8 *)dst);
6620a8ac0c1SNamjae Jeon 	if (ret != icx->block_size) {
6630a8ac0c1SNamjae Jeon 		if (ret == -1)
6640a8ac0c1SNamjae Jeon 			ntfs_error(icx->idx_ni->vol->sb, "Failed to read index block");
6650a8ac0c1SNamjae Jeon 		else
6660a8ac0c1SNamjae Jeon 			ntfs_error(icx->idx_ni->vol->sb,
6670a8ac0c1SNamjae Jeon 				"Failed to read full index block at %lld\n", pos);
6680a8ac0c1SNamjae Jeon 		return -1;
6690a8ac0c1SNamjae Jeon 	}
6700a8ac0c1SNamjae Jeon 
6710a8ac0c1SNamjae Jeon 	post_read_mst_fixup((struct ntfs_record *)((u8 *)dst), icx->block_size);
6720a8ac0c1SNamjae Jeon 	if (ntfs_index_block_inconsistent(icx, dst, vcn))
6730a8ac0c1SNamjae Jeon 		return -1;
6740a8ac0c1SNamjae Jeon 
6750a8ac0c1SNamjae Jeon 	return 0;
6760a8ac0c1SNamjae Jeon }
6770a8ac0c1SNamjae Jeon 
6780a8ac0c1SNamjae Jeon static int ntfs_icx_parent_inc(struct ntfs_index_context *icx)
6790a8ac0c1SNamjae Jeon {
6800a8ac0c1SNamjae Jeon 	icx->pindex++;
6810a8ac0c1SNamjae Jeon 	if (icx->pindex >= MAX_PARENT_VCN) {
6820a8ac0c1SNamjae Jeon 		ntfs_error(icx->idx_ni->vol->sb, "Index is over %d level deep", MAX_PARENT_VCN);
6830a8ac0c1SNamjae Jeon 		return -EOPNOTSUPP;
6840a8ac0c1SNamjae Jeon 	}
6850a8ac0c1SNamjae Jeon 	return 0;
6860a8ac0c1SNamjae Jeon }
6870a8ac0c1SNamjae Jeon 
6880a8ac0c1SNamjae Jeon static int ntfs_icx_parent_dec(struct ntfs_index_context *icx)
6890a8ac0c1SNamjae Jeon {
6900a8ac0c1SNamjae Jeon 	icx->pindex--;
6910a8ac0c1SNamjae Jeon 	if (icx->pindex < 0) {
6920a8ac0c1SNamjae Jeon 		ntfs_error(icx->idx_ni->vol->sb, "Corrupt index pointer (%d)", icx->pindex);
6930a8ac0c1SNamjae Jeon 		return -EINVAL;
6940a8ac0c1SNamjae Jeon 	}
6950a8ac0c1SNamjae Jeon 	return 0;
6960a8ac0c1SNamjae Jeon }
6970a8ac0c1SNamjae Jeon 
6981e9ea7e0SNamjae Jeon /*
6990a8ac0c1SNamjae Jeon  * ntfs_index_lookup - find a key in an index and return its index entry
7000a8ac0c1SNamjae Jeon  * @key:	key for which to search in the index
7010a8ac0c1SNamjae Jeon  * @key_len:	length of @key in bytes
7020a8ac0c1SNamjae Jeon  * @icx:	context describing the index and the returned entry
7030a8ac0c1SNamjae Jeon  *
7040a8ac0c1SNamjae Jeon  * Before calling ntfs_index_lookup(), @icx must have been obtained from a
7050a8ac0c1SNamjae Jeon  * call to ntfs_index_ctx_get().
7060a8ac0c1SNamjae Jeon  *
7070a8ac0c1SNamjae Jeon  * Look for the @key in the index specified by the index lookup context @icx.
7080a8ac0c1SNamjae Jeon  * ntfs_index_lookup() walks the contents of the index looking for the @key.
7090a8ac0c1SNamjae Jeon  *
7100a8ac0c1SNamjae Jeon  * If the @key is found in the index, 0 is returned and @icx is setup to
7110a8ac0c1SNamjae Jeon  * describe the index entry containing the matching @key.  @icx->entry is the
7120a8ac0c1SNamjae Jeon  * index entry and @icx->data and @icx->data_len are the index entry data and
7130a8ac0c1SNamjae Jeon  * its length in bytes, respectively.
7140a8ac0c1SNamjae Jeon  *
7150a8ac0c1SNamjae Jeon  * If the @key is not found in the index, -ENOENT is returned and
7160a8ac0c1SNamjae Jeon  * @icx is setup to describe the index entry whose key collates immediately
7170a8ac0c1SNamjae Jeon  * after the search @key, i.e. this is the position in the index at which
7180a8ac0c1SNamjae Jeon  * an index entry with a key of @key would need to be inserted.
7190a8ac0c1SNamjae Jeon  *
7200a8ac0c1SNamjae Jeon  * When finished with the entry and its data, call ntfs_index_ctx_put() to free
7210a8ac0c1SNamjae Jeon  * the context and other associated resources.
7220a8ac0c1SNamjae Jeon  *
7230a8ac0c1SNamjae Jeon  * If the index entry was modified, call ntfs_index_entry_mark_dirty() before
7240a8ac0c1SNamjae Jeon  * the call to ntfs_index_ctx_put() to ensure that the changes are written
7250a8ac0c1SNamjae Jeon  * to disk.
7261e9ea7e0SNamjae Jeon  */
7270a8ac0c1SNamjae Jeon int ntfs_index_lookup(const void *key, const u32 key_len, struct ntfs_index_context *icx)
7280a8ac0c1SNamjae Jeon {
7290a8ac0c1SNamjae Jeon 	s64 old_vcn, vcn;
7300a8ac0c1SNamjae Jeon 	struct ntfs_inode *ni = icx->idx_ni;
7310a8ac0c1SNamjae Jeon 	struct super_block *sb = ni->vol->sb;
7320a8ac0c1SNamjae Jeon 	struct index_root *ir;
7330a8ac0c1SNamjae Jeon 	struct index_entry *ie;
7340a8ac0c1SNamjae Jeon 	struct index_block *ib = NULL;
7350a8ac0c1SNamjae Jeon 	int err = 0;
7360a8ac0c1SNamjae Jeon 
7370a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
7380a8ac0c1SNamjae Jeon 
7390a8ac0c1SNamjae Jeon 	if (!key) {
7400a8ac0c1SNamjae Jeon 		ntfs_error(sb, "key: %p  key_len: %d", key, key_len);
7410a8ac0c1SNamjae Jeon 		return -EINVAL;
7420a8ac0c1SNamjae Jeon 	}
7430a8ac0c1SNamjae Jeon 
7440a8ac0c1SNamjae Jeon 	ir = ntfs_ir_lookup(ni, icx->name, icx->name_len, &icx->actx);
7450a8ac0c1SNamjae Jeon 	if (!ir)
7460a8ac0c1SNamjae Jeon 		return -EIO;
7470a8ac0c1SNamjae Jeon 
7480a8ac0c1SNamjae Jeon 	icx->block_size = le32_to_cpu(ir->index_block_size);
7490a8ac0c1SNamjae Jeon 	if (icx->block_size < NTFS_BLOCK_SIZE) {
7500a8ac0c1SNamjae Jeon 		err = -EINVAL;
7510a8ac0c1SNamjae Jeon 		ntfs_error(sb,
7520a8ac0c1SNamjae Jeon 			"Index block size (%d) is smaller than the sector size (%d)",
7530a8ac0c1SNamjae Jeon 			icx->block_size, NTFS_BLOCK_SIZE);
7541e9ea7e0SNamjae Jeon 		goto err_out;
7551e9ea7e0SNamjae Jeon 	}
7560a8ac0c1SNamjae Jeon 
7570a8ac0c1SNamjae Jeon 	if (ni->vol->cluster_size <= icx->block_size)
7580a8ac0c1SNamjae Jeon 		icx->vcn_size_bits = ni->vol->cluster_size_bits;
7590a8ac0c1SNamjae Jeon 	else
7600a8ac0c1SNamjae Jeon 		icx->vcn_size_bits = ni->vol->sector_size_bits;
7610a8ac0c1SNamjae Jeon 
7620a8ac0c1SNamjae Jeon 	icx->cr = ir->collation_rule;
7630a8ac0c1SNamjae Jeon 	if (!ntfs_is_collation_rule_supported(icx->cr)) {
7640a8ac0c1SNamjae Jeon 		err = -EOPNOTSUPP;
7650a8ac0c1SNamjae Jeon 		ntfs_error(sb, "Unknown collation rule 0x%x",
7660a8ac0c1SNamjae Jeon 				(unsigned int)le32_to_cpu(icx->cr));
7670a8ac0c1SNamjae Jeon 		goto err_out;
7681e9ea7e0SNamjae Jeon 	}
7690a8ac0c1SNamjae Jeon 
7700a8ac0c1SNamjae Jeon 	old_vcn = VCN_INDEX_ROOT_PARENT;
7710a8ac0c1SNamjae Jeon 	err = ntfs_ie_lookup(key, key_len, icx, &ir->index, &vcn, &ie);
7720a8ac0c1SNamjae Jeon 	if (err == -ERANGE || err == -EINVAL)
7730a8ac0c1SNamjae Jeon 		goto err_out;
7740a8ac0c1SNamjae Jeon 
7750a8ac0c1SNamjae Jeon 	icx->ir = ir;
7760a8ac0c1SNamjae Jeon 	if (err != -EAGAIN) {
7770a8ac0c1SNamjae Jeon 		icx->is_in_root = true;
7780a8ac0c1SNamjae Jeon 		icx->parent_vcn[icx->pindex] = old_vcn;
7791e9ea7e0SNamjae Jeon 		goto done;
7801e9ea7e0SNamjae Jeon 	}
7810a8ac0c1SNamjae Jeon 
7821e9ea7e0SNamjae Jeon 	/* Child node present, descend into it. */
7830a8ac0c1SNamjae Jeon 	icx->ia_ni = ntfs_ia_open(icx, ni);
7840a8ac0c1SNamjae Jeon 	if (!icx->ia_ni) {
7850a8ac0c1SNamjae Jeon 		err = -ENOENT;
7860a8ac0c1SNamjae Jeon 		goto err_out;
7871e9ea7e0SNamjae Jeon 	}
7880a8ac0c1SNamjae Jeon 
7890a8ac0c1SNamjae Jeon 	ib = kvzalloc(icx->block_size, GFP_NOFS);
7900a8ac0c1SNamjae Jeon 	if (!ib) {
7910a8ac0c1SNamjae Jeon 		err = -ENOMEM;
7920a8ac0c1SNamjae Jeon 		goto err_out;
7930a8ac0c1SNamjae Jeon 	}
7940a8ac0c1SNamjae Jeon 
7950a8ac0c1SNamjae Jeon descend_into_child_node:
7960a8ac0c1SNamjae Jeon 	icx->parent_vcn[icx->pindex] = old_vcn;
7970a8ac0c1SNamjae Jeon 	if (ntfs_icx_parent_inc(icx)) {
7980a8ac0c1SNamjae Jeon 		err = -EIO;
7990a8ac0c1SNamjae Jeon 		goto err_out;
8000a8ac0c1SNamjae Jeon 	}
8010a8ac0c1SNamjae Jeon 	old_vcn = vcn;
8020a8ac0c1SNamjae Jeon 
8030a8ac0c1SNamjae Jeon 	ntfs_debug("Descend into node with s64 %lld.\n", vcn);
8040a8ac0c1SNamjae Jeon 
8050a8ac0c1SNamjae Jeon 	if (ntfs_ib_read(icx, vcn, ib)) {
8060a8ac0c1SNamjae Jeon 		err = -EIO;
8070a8ac0c1SNamjae Jeon 		goto err_out;
8080a8ac0c1SNamjae Jeon 	}
8090a8ac0c1SNamjae Jeon 	err = ntfs_ie_lookup(key, key_len, icx, &ib->index, &vcn, &ie);
8100a8ac0c1SNamjae Jeon 	if (err != -EAGAIN) {
8110a8ac0c1SNamjae Jeon 		if (err == -EINVAL || err == -ERANGE)
8120a8ac0c1SNamjae Jeon 			goto err_out;
8130a8ac0c1SNamjae Jeon 
8140a8ac0c1SNamjae Jeon 		icx->is_in_root = false;
8150a8ac0c1SNamjae Jeon 		icx->ib = ib;
8160a8ac0c1SNamjae Jeon 		icx->parent_vcn[icx->pindex] = vcn;
8170a8ac0c1SNamjae Jeon 		goto done;
8180a8ac0c1SNamjae Jeon 	}
8190a8ac0c1SNamjae Jeon 
8200a8ac0c1SNamjae Jeon 	if ((ib->index.flags & NODE_MASK) == LEAF_NODE) {
8210a8ac0c1SNamjae Jeon 		ntfs_error(icx->idx_ni->vol->sb,
8220a8ac0c1SNamjae Jeon 			"Index entry with child node found in a leaf node in inode 0x%llx.\n",
8230a8ac0c1SNamjae Jeon 			(unsigned long long)ni->mft_no);
8240a8ac0c1SNamjae Jeon 		goto err_out;
8250a8ac0c1SNamjae Jeon 	}
8260a8ac0c1SNamjae Jeon 
8270a8ac0c1SNamjae Jeon 	goto descend_into_child_node;
8281e9ea7e0SNamjae Jeon err_out:
8290a8ac0c1SNamjae Jeon 	if (icx->actx) {
8300a8ac0c1SNamjae Jeon 		ntfs_attr_put_search_ctx(icx->actx);
8310a8ac0c1SNamjae Jeon 		icx->actx = NULL;
8320a8ac0c1SNamjae Jeon 	}
8330a8ac0c1SNamjae Jeon 	kvfree(ib);
8341e9ea7e0SNamjae Jeon 	if (!err)
8351e9ea7e0SNamjae Jeon 		err = -EIO;
8361e9ea7e0SNamjae Jeon 	return err;
8370a8ac0c1SNamjae Jeon done:
8380a8ac0c1SNamjae Jeon 	icx->entry = ie;
8390a8ac0c1SNamjae Jeon 	icx->data = (u8 *)ie + offsetof(struct index_entry, key);
8400a8ac0c1SNamjae Jeon 	icx->data_len = le16_to_cpu(ie->key_length);
8410a8ac0c1SNamjae Jeon 	ntfs_debug("Done.\n");
8420a8ac0c1SNamjae Jeon 	return err;
8430a8ac0c1SNamjae Jeon 
8440a8ac0c1SNamjae Jeon }
8450a8ac0c1SNamjae Jeon 
8460a8ac0c1SNamjae Jeon static struct index_block *ntfs_ib_alloc(s64 ib_vcn, u32 ib_size,
8470a8ac0c1SNamjae Jeon 		u8 node_type)
8480a8ac0c1SNamjae Jeon {
8490a8ac0c1SNamjae Jeon 	struct index_block *ib;
8500a8ac0c1SNamjae Jeon 	int ih_size = sizeof(struct index_header);
8510a8ac0c1SNamjae Jeon 
8520a8ac0c1SNamjae Jeon 	ntfs_debug("Entering ib_vcn = %lld ib_size = %u\n", ib_vcn, ib_size);
8530a8ac0c1SNamjae Jeon 
8540a8ac0c1SNamjae Jeon 	ib = kvzalloc(ib_size, GFP_NOFS);
8550a8ac0c1SNamjae Jeon 	if (!ib)
8560a8ac0c1SNamjae Jeon 		return NULL;
8570a8ac0c1SNamjae Jeon 
8580a8ac0c1SNamjae Jeon 	ib->magic = magic_INDX;
8590a8ac0c1SNamjae Jeon 	ib->usa_ofs = cpu_to_le16(sizeof(struct index_block));
8600a8ac0c1SNamjae Jeon 	ib->usa_count = cpu_to_le16(ib_size / NTFS_BLOCK_SIZE + 1);
8610a8ac0c1SNamjae Jeon 	/* Set USN to 1 */
8620a8ac0c1SNamjae Jeon 	*(__le16 *)((char *)ib + le16_to_cpu(ib->usa_ofs)) = cpu_to_le16(1);
8630a8ac0c1SNamjae Jeon 	ib->lsn = 0;
8640a8ac0c1SNamjae Jeon 	ib->index_block_vcn = cpu_to_le64(ib_vcn);
8650a8ac0c1SNamjae Jeon 	ib->index.entries_offset = cpu_to_le32((ih_size +
8660a8ac0c1SNamjae Jeon 				le16_to_cpu(ib->usa_count) * 2 + 7) & ~7);
8670a8ac0c1SNamjae Jeon 	ib->index.index_length = 0;
8680a8ac0c1SNamjae Jeon 	ib->index.allocated_size = cpu_to_le32(ib_size -
8690a8ac0c1SNamjae Jeon 			(sizeof(struct index_block) - ih_size));
8700a8ac0c1SNamjae Jeon 	ib->index.flags = node_type;
8710a8ac0c1SNamjae Jeon 
8720a8ac0c1SNamjae Jeon 	return ib;
8730a8ac0c1SNamjae Jeon }
8740a8ac0c1SNamjae Jeon 
8750a8ac0c1SNamjae Jeon /*
8760a8ac0c1SNamjae Jeon  *  Find the median by going through all the entries
8770a8ac0c1SNamjae Jeon  */
8780a8ac0c1SNamjae Jeon static struct index_entry *ntfs_ie_get_median(struct index_header *ih)
8790a8ac0c1SNamjae Jeon {
8800a8ac0c1SNamjae Jeon 	struct index_entry *ie, *ie_start;
8810a8ac0c1SNamjae Jeon 	u8 *ie_end;
8820a8ac0c1SNamjae Jeon 	int i = 0, median;
8830a8ac0c1SNamjae Jeon 
8840a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
8850a8ac0c1SNamjae Jeon 
8860a8ac0c1SNamjae Jeon 	ie = ie_start = ntfs_ie_get_first(ih);
8870a8ac0c1SNamjae Jeon 	ie_end = (u8 *)ntfs_ie_get_end(ih);
8880a8ac0c1SNamjae Jeon 
8890a8ac0c1SNamjae Jeon 	while ((u8 *)ie < ie_end && !ntfs_ie_end(ie)) {
8900a8ac0c1SNamjae Jeon 		ie = ntfs_ie_get_next(ie);
8910a8ac0c1SNamjae Jeon 		i++;
8920a8ac0c1SNamjae Jeon 	}
8930a8ac0c1SNamjae Jeon 	/*
8940a8ac0c1SNamjae Jeon 	 * NOTE: this could be also the entry at the half of the index block.
8950a8ac0c1SNamjae Jeon 	 */
8960a8ac0c1SNamjae Jeon 	median = i / 2 - 1;
8970a8ac0c1SNamjae Jeon 
8980a8ac0c1SNamjae Jeon 	ntfs_debug("Entries: %d  median: %d\n", i, median);
8990a8ac0c1SNamjae Jeon 
9000a8ac0c1SNamjae Jeon 	for (i = 0, ie = ie_start; i <= median; i++)
9010a8ac0c1SNamjae Jeon 		ie = ntfs_ie_get_next(ie);
9020a8ac0c1SNamjae Jeon 
9030a8ac0c1SNamjae Jeon 	return ie;
9040a8ac0c1SNamjae Jeon }
9050a8ac0c1SNamjae Jeon 
9060a8ac0c1SNamjae Jeon static u64 ntfs_ibm_vcn_to_pos(struct ntfs_index_context *icx, s64 vcn)
9070a8ac0c1SNamjae Jeon {
9080a8ac0c1SNamjae Jeon 	u64 pos = ntfs_ib_vcn_to_pos(icx, vcn);
9090a8ac0c1SNamjae Jeon 
9100a8ac0c1SNamjae Jeon 	do_div(pos, icx->block_size);
9110a8ac0c1SNamjae Jeon 	return pos;
9120a8ac0c1SNamjae Jeon }
9130a8ac0c1SNamjae Jeon 
9140a8ac0c1SNamjae Jeon static s64 ntfs_ibm_pos_to_vcn(struct ntfs_index_context *icx, s64 pos)
9150a8ac0c1SNamjae Jeon {
9160a8ac0c1SNamjae Jeon 	return ntfs_ib_pos_to_vcn(icx, pos * icx->block_size);
9170a8ac0c1SNamjae Jeon }
9180a8ac0c1SNamjae Jeon 
9190a8ac0c1SNamjae Jeon static int ntfs_ibm_add(struct ntfs_index_context *icx)
9200a8ac0c1SNamjae Jeon {
9210a8ac0c1SNamjae Jeon 	u8 bmp[8];
9220a8ac0c1SNamjae Jeon 
9230a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
9240a8ac0c1SNamjae Jeon 
9250a8ac0c1SNamjae Jeon 	if (ntfs_attr_exist(icx->idx_ni, AT_BITMAP, icx->name, icx->name_len))
9260a8ac0c1SNamjae Jeon 		return 0;
9270a8ac0c1SNamjae Jeon 	/*
9280a8ac0c1SNamjae Jeon 	 * AT_BITMAP must be at least 8 bytes.
9290a8ac0c1SNamjae Jeon 	 */
9300a8ac0c1SNamjae Jeon 	memset(bmp, 0, sizeof(bmp));
9310a8ac0c1SNamjae Jeon 	if (ntfs_attr_add(icx->idx_ni, AT_BITMAP, icx->name, icx->name_len,
9320a8ac0c1SNamjae Jeon 				bmp, sizeof(bmp))) {
9330a8ac0c1SNamjae Jeon 		ntfs_error(icx->idx_ni->vol->sb, "Failed to add AT_BITMAP");
9340a8ac0c1SNamjae Jeon 		return -EINVAL;
9350a8ac0c1SNamjae Jeon 	}
9360a8ac0c1SNamjae Jeon 
9370a8ac0c1SNamjae Jeon 	return 0;
9380a8ac0c1SNamjae Jeon }
9390a8ac0c1SNamjae Jeon 
9400a8ac0c1SNamjae Jeon static int ntfs_ibm_modify(struct ntfs_index_context *icx, s64 vcn, int set)
9410a8ac0c1SNamjae Jeon {
9420a8ac0c1SNamjae Jeon 	u8 byte;
9430a8ac0c1SNamjae Jeon 	u64 pos = ntfs_ibm_vcn_to_pos(icx, vcn);
9440a8ac0c1SNamjae Jeon 	u32 bpos = pos / 8;
9450a8ac0c1SNamjae Jeon 	u32 bit = 1 << (pos % 8);
9460a8ac0c1SNamjae Jeon 	struct ntfs_inode *bmp_ni;
9470a8ac0c1SNamjae Jeon 	struct inode *bmp_vi;
9480a8ac0c1SNamjae Jeon 	int ret = 0;
9490a8ac0c1SNamjae Jeon 
9500a8ac0c1SNamjae Jeon 	ntfs_debug("%s vcn: %lld\n", set ? "set" : "clear", vcn);
9510a8ac0c1SNamjae Jeon 
9520a8ac0c1SNamjae Jeon 	bmp_vi = ntfs_attr_iget(VFS_I(icx->idx_ni), AT_BITMAP, icx->name, icx->name_len);
9530a8ac0c1SNamjae Jeon 	if (IS_ERR(bmp_vi)) {
9540a8ac0c1SNamjae Jeon 		ntfs_error(icx->idx_ni->vol->sb, "Failed to open $BITMAP attribute");
9550a8ac0c1SNamjae Jeon 		return PTR_ERR(bmp_vi);
9560a8ac0c1SNamjae Jeon 	}
9570a8ac0c1SNamjae Jeon 
9580a8ac0c1SNamjae Jeon 	bmp_ni = NTFS_I(bmp_vi);
9590a8ac0c1SNamjae Jeon 
9600a8ac0c1SNamjae Jeon 	if (set) {
9610a8ac0c1SNamjae Jeon 		if (bmp_ni->data_size < bpos + 1) {
9620a8ac0c1SNamjae Jeon 			ret = ntfs_attr_truncate(bmp_ni, (bmp_ni->data_size + 8) & ~7);
9630a8ac0c1SNamjae Jeon 			if (ret) {
9640a8ac0c1SNamjae Jeon 				ntfs_error(icx->idx_ni->vol->sb, "Failed to truncate AT_BITMAP");
9650a8ac0c1SNamjae Jeon 				goto err;
9660a8ac0c1SNamjae Jeon 			}
9670a8ac0c1SNamjae Jeon 			i_size_write(bmp_vi, (loff_t)bmp_ni->data_size);
9680a8ac0c1SNamjae Jeon 		}
9690a8ac0c1SNamjae Jeon 	}
9700a8ac0c1SNamjae Jeon 
9710a8ac0c1SNamjae Jeon 	if (ntfs_inode_attr_pread(bmp_vi, bpos, 1, &byte) != 1) {
9720a8ac0c1SNamjae Jeon 		ret = -EIO;
9730a8ac0c1SNamjae Jeon 		ntfs_error(icx->idx_ni->vol->sb, "Failed to read $BITMAP");
9740a8ac0c1SNamjae Jeon 		goto err;
9750a8ac0c1SNamjae Jeon 	}
9760a8ac0c1SNamjae Jeon 
9770a8ac0c1SNamjae Jeon 	if (set)
9780a8ac0c1SNamjae Jeon 		byte |= bit;
9790a8ac0c1SNamjae Jeon 	else
9800a8ac0c1SNamjae Jeon 		byte &= ~bit;
9810a8ac0c1SNamjae Jeon 
9820a8ac0c1SNamjae Jeon 	if (ntfs_inode_attr_pwrite(bmp_vi, bpos, 1, &byte, false) != 1) {
9830a8ac0c1SNamjae Jeon 		ret = -EIO;
9840a8ac0c1SNamjae Jeon 		ntfs_error(icx->idx_ni->vol->sb, "Failed to write $Bitmap");
9850a8ac0c1SNamjae Jeon 		goto err;
9860a8ac0c1SNamjae Jeon 	}
9870a8ac0c1SNamjae Jeon 
9880a8ac0c1SNamjae Jeon err:
9890a8ac0c1SNamjae Jeon 	iput(bmp_vi);
9900a8ac0c1SNamjae Jeon 	return ret;
9910a8ac0c1SNamjae Jeon }
9920a8ac0c1SNamjae Jeon 
9930a8ac0c1SNamjae Jeon static int ntfs_ibm_set(struct ntfs_index_context *icx, s64 vcn)
9940a8ac0c1SNamjae Jeon {
9950a8ac0c1SNamjae Jeon 	return ntfs_ibm_modify(icx, vcn, 1);
9960a8ac0c1SNamjae Jeon }
9970a8ac0c1SNamjae Jeon 
9980a8ac0c1SNamjae Jeon static int ntfs_ibm_clear(struct ntfs_index_context *icx, s64 vcn)
9990a8ac0c1SNamjae Jeon {
10000a8ac0c1SNamjae Jeon 	return ntfs_ibm_modify(icx, vcn, 0);
10010a8ac0c1SNamjae Jeon }
10020a8ac0c1SNamjae Jeon 
10030a8ac0c1SNamjae Jeon static s64 ntfs_ibm_get_free(struct ntfs_index_context *icx)
10040a8ac0c1SNamjae Jeon {
10050a8ac0c1SNamjae Jeon 	u8 *bm;
10060a8ac0c1SNamjae Jeon 	int bit;
10070a8ac0c1SNamjae Jeon 	s64 vcn, byte, size;
10080a8ac0c1SNamjae Jeon 
10090a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
10100a8ac0c1SNamjae Jeon 
10110a8ac0c1SNamjae Jeon 	bm = ntfs_attr_readall(icx->idx_ni, AT_BITMAP,  icx->name, icx->name_len,
10120a8ac0c1SNamjae Jeon 			&size);
10130a8ac0c1SNamjae Jeon 	if (!bm)
10140a8ac0c1SNamjae Jeon 		return (s64)-1;
10150a8ac0c1SNamjae Jeon 
10160a8ac0c1SNamjae Jeon 	for (byte = 0; byte < size; byte++) {
10170a8ac0c1SNamjae Jeon 		if (bm[byte] == 255)
10180a8ac0c1SNamjae Jeon 			continue;
10190a8ac0c1SNamjae Jeon 
10200a8ac0c1SNamjae Jeon 		for (bit = 0; bit < 8; bit++) {
10210a8ac0c1SNamjae Jeon 			if (!(bm[byte] & (1 << bit))) {
10220a8ac0c1SNamjae Jeon 				vcn = ntfs_ibm_pos_to_vcn(icx, byte * 8 + bit);
10230a8ac0c1SNamjae Jeon 				goto out;
10240a8ac0c1SNamjae Jeon 			}
10250a8ac0c1SNamjae Jeon 		}
10260a8ac0c1SNamjae Jeon 	}
10270a8ac0c1SNamjae Jeon 
10280a8ac0c1SNamjae Jeon 	vcn = ntfs_ibm_pos_to_vcn(icx, size * 8);
10290a8ac0c1SNamjae Jeon out:
10300a8ac0c1SNamjae Jeon 	ntfs_debug("allocated vcn: %lld\n", vcn);
10310a8ac0c1SNamjae Jeon 
10320a8ac0c1SNamjae Jeon 	if (ntfs_ibm_set(icx, vcn))
10330a8ac0c1SNamjae Jeon 		vcn = (s64)-1;
10340a8ac0c1SNamjae Jeon 
10350a8ac0c1SNamjae Jeon 	kvfree(bm);
10360a8ac0c1SNamjae Jeon 	return vcn;
10370a8ac0c1SNamjae Jeon }
10380a8ac0c1SNamjae Jeon 
10390a8ac0c1SNamjae Jeon static struct index_block *ntfs_ir_to_ib(struct index_root *ir, s64 ib_vcn)
10400a8ac0c1SNamjae Jeon {
10410a8ac0c1SNamjae Jeon 	struct index_block *ib;
10420a8ac0c1SNamjae Jeon 	struct index_entry *ie_last;
10430a8ac0c1SNamjae Jeon 	char *ies_start, *ies_end;
10440a8ac0c1SNamjae Jeon 	int i;
10450a8ac0c1SNamjae Jeon 
10460a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
10470a8ac0c1SNamjae Jeon 
10480a8ac0c1SNamjae Jeon 	ib = ntfs_ib_alloc(ib_vcn, le32_to_cpu(ir->index_block_size), LEAF_NODE);
10490a8ac0c1SNamjae Jeon 	if (!ib)
10500a8ac0c1SNamjae Jeon 		return NULL;
10510a8ac0c1SNamjae Jeon 
10520a8ac0c1SNamjae Jeon 	ies_start = (char *)ntfs_ie_get_first(&ir->index);
10530a8ac0c1SNamjae Jeon 	ies_end   = (char *)ntfs_ie_get_end(&ir->index);
10540a8ac0c1SNamjae Jeon 	ie_last   = ntfs_ie_get_last((struct index_entry *)ies_start, ies_end);
10550a8ac0c1SNamjae Jeon 	/*
10560a8ac0c1SNamjae Jeon 	 * Copy all entries, including the termination entry
10570a8ac0c1SNamjae Jeon 	 * as well, which can never have any data.
10580a8ac0c1SNamjae Jeon 	 */
10590a8ac0c1SNamjae Jeon 	i = (char *)ie_last - ies_start + le16_to_cpu(ie_last->length);
10600a8ac0c1SNamjae Jeon 	memcpy(ntfs_ie_get_first(&ib->index), ies_start, i);
10610a8ac0c1SNamjae Jeon 
10620a8ac0c1SNamjae Jeon 	ib->index.flags = ir->index.flags;
10630a8ac0c1SNamjae Jeon 	ib->index.index_length = cpu_to_le32(i +
10640a8ac0c1SNamjae Jeon 			le32_to_cpu(ib->index.entries_offset));
10650a8ac0c1SNamjae Jeon 	return ib;
10660a8ac0c1SNamjae Jeon }
10670a8ac0c1SNamjae Jeon 
10680a8ac0c1SNamjae Jeon static void ntfs_ir_nill(struct index_root *ir)
10690a8ac0c1SNamjae Jeon {
10700a8ac0c1SNamjae Jeon 	struct index_entry *ie_last;
10710a8ac0c1SNamjae Jeon 	char *ies_start, *ies_end;
10720a8ac0c1SNamjae Jeon 
10730a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
10740a8ac0c1SNamjae Jeon 
10750a8ac0c1SNamjae Jeon 	ies_start = (char *)ntfs_ie_get_first(&ir->index);
10760a8ac0c1SNamjae Jeon 	ies_end   = (char *)ntfs_ie_get_end(&ir->index);
10770a8ac0c1SNamjae Jeon 	ie_last   = ntfs_ie_get_last((struct index_entry *)ies_start, ies_end);
10780a8ac0c1SNamjae Jeon 	/*
10790a8ac0c1SNamjae Jeon 	 * Move the index root termination entry forward
10800a8ac0c1SNamjae Jeon 	 */
10810a8ac0c1SNamjae Jeon 	if ((char *)ie_last > ies_start) {
10820a8ac0c1SNamjae Jeon 		memmove((char *)ntfs_ie_get_first(&ir->index),
10830a8ac0c1SNamjae Jeon 			(char *)ie_last, le16_to_cpu(ie_last->length));
10840a8ac0c1SNamjae Jeon 		ie_last = (struct index_entry *)ies_start;
10850a8ac0c1SNamjae Jeon 	}
10860a8ac0c1SNamjae Jeon }
10870a8ac0c1SNamjae Jeon 
10880a8ac0c1SNamjae Jeon static int ntfs_ib_copy_tail(struct ntfs_index_context *icx, struct index_block *src,
10890a8ac0c1SNamjae Jeon 		struct index_entry *median, s64 new_vcn)
10900a8ac0c1SNamjae Jeon {
10910a8ac0c1SNamjae Jeon 	u8 *ies_end;
10920a8ac0c1SNamjae Jeon 	struct index_entry *ie_head;		/* first entry after the median */
10930a8ac0c1SNamjae Jeon 	int tail_size, ret;
10940a8ac0c1SNamjae Jeon 	struct index_block *dst;
10950a8ac0c1SNamjae Jeon 
10960a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
10970a8ac0c1SNamjae Jeon 
10980a8ac0c1SNamjae Jeon 	dst = ntfs_ib_alloc(new_vcn, icx->block_size,
10990a8ac0c1SNamjae Jeon 			src->index.flags & NODE_MASK);
11000a8ac0c1SNamjae Jeon 	if (!dst)
11010a8ac0c1SNamjae Jeon 		return -ENOMEM;
11020a8ac0c1SNamjae Jeon 
11030a8ac0c1SNamjae Jeon 	ie_head = ntfs_ie_get_next(median);
11040a8ac0c1SNamjae Jeon 
11050a8ac0c1SNamjae Jeon 	ies_end = (u8 *)ntfs_ie_get_end(&src->index);
11060a8ac0c1SNamjae Jeon 	tail_size = ies_end - (u8 *)ie_head;
11070a8ac0c1SNamjae Jeon 	memcpy(ntfs_ie_get_first(&dst->index), ie_head, tail_size);
11080a8ac0c1SNamjae Jeon 
11090a8ac0c1SNamjae Jeon 	dst->index.index_length = cpu_to_le32(tail_size +
11100a8ac0c1SNamjae Jeon 			le32_to_cpu(dst->index.entries_offset));
11110a8ac0c1SNamjae Jeon 	ret = ntfs_ib_write(icx, dst);
11120a8ac0c1SNamjae Jeon 
11130a8ac0c1SNamjae Jeon 	kvfree(dst);
11140a8ac0c1SNamjae Jeon 	return ret;
11150a8ac0c1SNamjae Jeon }
11160a8ac0c1SNamjae Jeon 
11170a8ac0c1SNamjae Jeon static int ntfs_ib_cut_tail(struct ntfs_index_context *icx, struct index_block *ib,
11180a8ac0c1SNamjae Jeon 		struct index_entry *ie)
11190a8ac0c1SNamjae Jeon {
11200a8ac0c1SNamjae Jeon 	char *ies_start, *ies_end;
11210a8ac0c1SNamjae Jeon 	struct index_entry *ie_last;
11220a8ac0c1SNamjae Jeon 	int ret;
11230a8ac0c1SNamjae Jeon 
11240a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
11250a8ac0c1SNamjae Jeon 
11260a8ac0c1SNamjae Jeon 	ies_start = (char *)ntfs_ie_get_first(&ib->index);
11270a8ac0c1SNamjae Jeon 	ies_end   = (char *)ntfs_ie_get_end(&ib->index);
11280a8ac0c1SNamjae Jeon 
11290a8ac0c1SNamjae Jeon 	ie_last   = ntfs_ie_get_last((struct index_entry *)ies_start, ies_end);
11300a8ac0c1SNamjae Jeon 	if (ie_last->flags & INDEX_ENTRY_NODE)
11310a8ac0c1SNamjae Jeon 		ntfs_ie_set_vcn(ie_last, ntfs_ie_get_vcn(ie));
11320a8ac0c1SNamjae Jeon 
11330a8ac0c1SNamjae Jeon 	unsafe_memcpy(ie, ie_last, le16_to_cpu(ie_last->length),
11340a8ac0c1SNamjae Jeon 			/* alloc is larger than ie_last->length, see ntfs_ie_get_last() */);
11350a8ac0c1SNamjae Jeon 
11360a8ac0c1SNamjae Jeon 	ib->index.index_length = cpu_to_le32(((char *)ie - ies_start) +
11370a8ac0c1SNamjae Jeon 			le16_to_cpu(ie->length) + le32_to_cpu(ib->index.entries_offset));
11380a8ac0c1SNamjae Jeon 
11390a8ac0c1SNamjae Jeon 	ret = ntfs_ib_write(icx, ib);
11400a8ac0c1SNamjae Jeon 	return ret;
11410a8ac0c1SNamjae Jeon }
11420a8ac0c1SNamjae Jeon 
11430a8ac0c1SNamjae Jeon static int ntfs_ia_add(struct ntfs_index_context *icx)
11440a8ac0c1SNamjae Jeon {
11450a8ac0c1SNamjae Jeon 	int ret;
11460a8ac0c1SNamjae Jeon 
11470a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
11480a8ac0c1SNamjae Jeon 
11490a8ac0c1SNamjae Jeon 	ret = ntfs_ibm_add(icx);
11500a8ac0c1SNamjae Jeon 	if (ret)
11510a8ac0c1SNamjae Jeon 		return ret;
11520a8ac0c1SNamjae Jeon 
11530a8ac0c1SNamjae Jeon 	if (!ntfs_attr_exist(icx->idx_ni, AT_INDEX_ALLOCATION, icx->name, icx->name_len)) {
11540a8ac0c1SNamjae Jeon 		ret = ntfs_attr_add(icx->idx_ni, AT_INDEX_ALLOCATION, icx->name,
11550a8ac0c1SNamjae Jeon 					icx->name_len, NULL, 0);
11560a8ac0c1SNamjae Jeon 		if (ret) {
11570a8ac0c1SNamjae Jeon 			ntfs_error(icx->idx_ni->vol->sb, "Failed to add AT_INDEX_ALLOCATION");
11580a8ac0c1SNamjae Jeon 			return ret;
11590a8ac0c1SNamjae Jeon 		}
11600a8ac0c1SNamjae Jeon 	}
11610a8ac0c1SNamjae Jeon 
11620a8ac0c1SNamjae Jeon 	icx->ia_ni = ntfs_ia_open(icx, icx->idx_ni);
11630a8ac0c1SNamjae Jeon 	if (!icx->ia_ni)
11640a8ac0c1SNamjae Jeon 		return -ENOENT;
11650a8ac0c1SNamjae Jeon 
11660a8ac0c1SNamjae Jeon 	return 0;
11670a8ac0c1SNamjae Jeon }
11680a8ac0c1SNamjae Jeon 
11690a8ac0c1SNamjae Jeon static int ntfs_ir_reparent(struct ntfs_index_context *icx)
11700a8ac0c1SNamjae Jeon {
11710a8ac0c1SNamjae Jeon 	struct ntfs_attr_search_ctx *ctx = NULL;
11720a8ac0c1SNamjae Jeon 	struct index_root *ir;
11730a8ac0c1SNamjae Jeon 	struct index_entry *ie;
11740a8ac0c1SNamjae Jeon 	struct index_block *ib = NULL;
11750a8ac0c1SNamjae Jeon 	s64 new_ib_vcn;
11760a8ac0c1SNamjae Jeon 	int ix_root_size;
11770a8ac0c1SNamjae Jeon 	int ret = 0;
11780a8ac0c1SNamjae Jeon 
11790a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
11800a8ac0c1SNamjae Jeon 
11810a8ac0c1SNamjae Jeon 	ir = ntfs_ir_lookup2(icx->idx_ni, icx->name, icx->name_len);
11820a8ac0c1SNamjae Jeon 	if (!ir) {
11830a8ac0c1SNamjae Jeon 		ret = -ENOENT;
11840a8ac0c1SNamjae Jeon 		goto out;
11850a8ac0c1SNamjae Jeon 	}
11860a8ac0c1SNamjae Jeon 
11870a8ac0c1SNamjae Jeon 	if ((ir->index.flags & NODE_MASK) == SMALL_INDEX) {
11880a8ac0c1SNamjae Jeon 		ret = ntfs_ia_add(icx);
11890a8ac0c1SNamjae Jeon 		if (ret)
11900a8ac0c1SNamjae Jeon 			goto out;
11910a8ac0c1SNamjae Jeon 	}
11920a8ac0c1SNamjae Jeon 
11930a8ac0c1SNamjae Jeon 	new_ib_vcn = ntfs_ibm_get_free(icx);
11940a8ac0c1SNamjae Jeon 	if (new_ib_vcn < 0) {
11950a8ac0c1SNamjae Jeon 		ret = -EINVAL;
11960a8ac0c1SNamjae Jeon 		goto out;
11970a8ac0c1SNamjae Jeon 	}
11980a8ac0c1SNamjae Jeon 
11990a8ac0c1SNamjae Jeon 	ir = ntfs_ir_lookup2(icx->idx_ni, icx->name, icx->name_len);
12000a8ac0c1SNamjae Jeon 	if (!ir) {
12010a8ac0c1SNamjae Jeon 		ret = -ENOENT;
12020a8ac0c1SNamjae Jeon 		goto clear_bmp;
12030a8ac0c1SNamjae Jeon 	}
12040a8ac0c1SNamjae Jeon 
12050a8ac0c1SNamjae Jeon 	ib = ntfs_ir_to_ib(ir, new_ib_vcn);
12060a8ac0c1SNamjae Jeon 	if (ib == NULL) {
12070a8ac0c1SNamjae Jeon 		ret = -EIO;
12080a8ac0c1SNamjae Jeon 		ntfs_error(icx->idx_ni->vol->sb, "Failed to move index root to index block");
12090a8ac0c1SNamjae Jeon 		goto clear_bmp;
12100a8ac0c1SNamjae Jeon 	}
12110a8ac0c1SNamjae Jeon 
12120a8ac0c1SNamjae Jeon 	ret = ntfs_ib_write(icx, ib);
12130a8ac0c1SNamjae Jeon 	if (ret)
12140a8ac0c1SNamjae Jeon 		goto clear_bmp;
12150a8ac0c1SNamjae Jeon 
12160a8ac0c1SNamjae Jeon retry:
12170a8ac0c1SNamjae Jeon 	ir = ntfs_ir_lookup(icx->idx_ni, icx->name, icx->name_len, &ctx);
12180a8ac0c1SNamjae Jeon 	if (!ir) {
12190a8ac0c1SNamjae Jeon 		ret = -ENOENT;
12200a8ac0c1SNamjae Jeon 		goto clear_bmp;
12210a8ac0c1SNamjae Jeon 	}
12220a8ac0c1SNamjae Jeon 
12230a8ac0c1SNamjae Jeon 	ntfs_ir_nill(ir);
12240a8ac0c1SNamjae Jeon 
12250a8ac0c1SNamjae Jeon 	ie = ntfs_ie_get_first(&ir->index);
12260a8ac0c1SNamjae Jeon 	ie->flags |= INDEX_ENTRY_NODE;
12270a8ac0c1SNamjae Jeon 	ie->length = cpu_to_le16(sizeof(struct index_entry_header) + sizeof(s64));
12280a8ac0c1SNamjae Jeon 
12290a8ac0c1SNamjae Jeon 	ir->index.flags = LARGE_INDEX;
12300a8ac0c1SNamjae Jeon 	NInoSetIndexAllocPresent(icx->idx_ni);
12310a8ac0c1SNamjae Jeon 	ir->index.index_length = cpu_to_le32(le32_to_cpu(ir->index.entries_offset) +
12320a8ac0c1SNamjae Jeon 			le16_to_cpu(ie->length));
12330a8ac0c1SNamjae Jeon 	ir->index.allocated_size = ir->index.index_length;
12340a8ac0c1SNamjae Jeon 
12350a8ac0c1SNamjae Jeon 	ix_root_size = sizeof(struct index_root) - sizeof(struct index_header) +
12360a8ac0c1SNamjae Jeon 		le32_to_cpu(ir->index.allocated_size);
12370a8ac0c1SNamjae Jeon 	ret  = ntfs_resident_attr_value_resize(ctx->mrec, ctx->attr, ix_root_size);
12380a8ac0c1SNamjae Jeon 	if (ret) {
12390a8ac0c1SNamjae Jeon 		/*
12400a8ac0c1SNamjae Jeon 		 * When there is no space to build a non-resident
12410a8ac0c1SNamjae Jeon 		 * index, we may have to move the root to an extent
12420a8ac0c1SNamjae Jeon 		 */
12430a8ac0c1SNamjae Jeon 		if ((ret == -ENOSPC) && (ctx->al_entry || !ntfs_inode_add_attrlist(icx->idx_ni))) {
12440a8ac0c1SNamjae Jeon 			ntfs_attr_put_search_ctx(ctx);
12450a8ac0c1SNamjae Jeon 			ctx = NULL;
12460a8ac0c1SNamjae Jeon 			ir = ntfs_ir_lookup(icx->idx_ni, icx->name, icx->name_len, &ctx);
12470a8ac0c1SNamjae Jeon 			if (ir && !ntfs_attr_record_move_away(ctx, ix_root_size -
12480a8ac0c1SNamjae Jeon 					le32_to_cpu(ctx->attr->data.resident.value_length))) {
12490a8ac0c1SNamjae Jeon 				if (ntfs_attrlist_update(ctx->base_ntfs_ino ?
12500a8ac0c1SNamjae Jeon 							 ctx->base_ntfs_ino : ctx->ntfs_ino))
12510a8ac0c1SNamjae Jeon 					goto clear_bmp;
12520a8ac0c1SNamjae Jeon 				ntfs_attr_put_search_ctx(ctx);
12530a8ac0c1SNamjae Jeon 				ctx = NULL;
12540a8ac0c1SNamjae Jeon 				goto retry;
12550a8ac0c1SNamjae Jeon 			}
12560a8ac0c1SNamjae Jeon 		}
12570a8ac0c1SNamjae Jeon 		goto clear_bmp;
12580a8ac0c1SNamjae Jeon 	} else {
12590a8ac0c1SNamjae Jeon 		icx->idx_ni->data_size = icx->idx_ni->initialized_size = ix_root_size;
12600a8ac0c1SNamjae Jeon 		icx->idx_ni->allocated_size = (ix_root_size  + 7) & ~7;
12610a8ac0c1SNamjae Jeon 	}
12620a8ac0c1SNamjae Jeon 	ntfs_ie_set_vcn(ie, new_ib_vcn);
12630a8ac0c1SNamjae Jeon 
12640a8ac0c1SNamjae Jeon err_out:
12650a8ac0c1SNamjae Jeon 	kvfree(ib);
12660a8ac0c1SNamjae Jeon 	if (ctx)
12670a8ac0c1SNamjae Jeon 		ntfs_attr_put_search_ctx(ctx);
12680a8ac0c1SNamjae Jeon out:
12690a8ac0c1SNamjae Jeon 	return ret;
12700a8ac0c1SNamjae Jeon clear_bmp:
12710a8ac0c1SNamjae Jeon 	ntfs_ibm_clear(icx, new_ib_vcn);
12721e9ea7e0SNamjae Jeon 	goto err_out;
12731e9ea7e0SNamjae Jeon }
12740a8ac0c1SNamjae Jeon 
12750a8ac0c1SNamjae Jeon /*
12760a8ac0c1SNamjae Jeon  * ntfs_ir_truncate - Truncate index root attribute
12770a8ac0c1SNamjae Jeon  * @icx: index context
12780a8ac0c1SNamjae Jeon  * @data_size: new data size for the index root
12790a8ac0c1SNamjae Jeon  */
12800a8ac0c1SNamjae Jeon static int ntfs_ir_truncate(struct ntfs_index_context *icx, int data_size)
12810a8ac0c1SNamjae Jeon {
12820a8ac0c1SNamjae Jeon 	int ret;
12830a8ac0c1SNamjae Jeon 
12840a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
12850a8ac0c1SNamjae Jeon 
12860a8ac0c1SNamjae Jeon 	/*
12870a8ac0c1SNamjae Jeon 	 *  INDEX_ROOT must be resident and its entries can be moved to
12880a8ac0c1SNamjae Jeon 	 *  struct index_block, so ENOSPC isn't a real error.
12890a8ac0c1SNamjae Jeon 	 */
12900a8ac0c1SNamjae Jeon 	ret = ntfs_attr_truncate(icx->idx_ni, data_size + offsetof(struct index_root, index));
12910a8ac0c1SNamjae Jeon 	if (!ret) {
12920a8ac0c1SNamjae Jeon 		i_size_write(VFS_I(icx->idx_ni), icx->idx_ni->initialized_size);
12930a8ac0c1SNamjae Jeon 		icx->ir = ntfs_ir_lookup2(icx->idx_ni, icx->name, icx->name_len);
12940a8ac0c1SNamjae Jeon 		if (!icx->ir)
12950a8ac0c1SNamjae Jeon 			return -ENOENT;
12960a8ac0c1SNamjae Jeon 
12970a8ac0c1SNamjae Jeon 		icx->ir->index.allocated_size = cpu_to_le32(data_size);
12980a8ac0c1SNamjae Jeon 	} else if (ret != -ENOSPC)
12990a8ac0c1SNamjae Jeon 		ntfs_error(icx->idx_ni->vol->sb, "Failed to truncate INDEX_ROOT");
13000a8ac0c1SNamjae Jeon 
13010a8ac0c1SNamjae Jeon 	return ret;
13020a8ac0c1SNamjae Jeon }
13030a8ac0c1SNamjae Jeon 
13040a8ac0c1SNamjae Jeon /*
13050a8ac0c1SNamjae Jeon  * ntfs_ir_make_space - Make more space for the index root attribute
13060a8ac0c1SNamjae Jeon  * @icx: index context
13070a8ac0c1SNamjae Jeon  * @data_size: required data size for the index root
13080a8ac0c1SNamjae Jeon  */
13090a8ac0c1SNamjae Jeon static int ntfs_ir_make_space(struct ntfs_index_context *icx, int data_size)
13100a8ac0c1SNamjae Jeon {
13110a8ac0c1SNamjae Jeon 	int ret;
13120a8ac0c1SNamjae Jeon 
13130a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
13140a8ac0c1SNamjae Jeon 
13150a8ac0c1SNamjae Jeon 	ret = ntfs_ir_truncate(icx, data_size);
13160a8ac0c1SNamjae Jeon 	if (ret == -ENOSPC) {
13170a8ac0c1SNamjae Jeon 		ret = ntfs_ir_reparent(icx);
13180a8ac0c1SNamjae Jeon 		if (!ret)
13190a8ac0c1SNamjae Jeon 			ret = -EAGAIN;
13200a8ac0c1SNamjae Jeon 		else
13210a8ac0c1SNamjae Jeon 			ntfs_error(icx->idx_ni->vol->sb, "Failed to modify INDEX_ROOT");
13220a8ac0c1SNamjae Jeon 	}
13230a8ac0c1SNamjae Jeon 
13240a8ac0c1SNamjae Jeon 	return ret;
13250a8ac0c1SNamjae Jeon }
13260a8ac0c1SNamjae Jeon 
13270a8ac0c1SNamjae Jeon /*
13280a8ac0c1SNamjae Jeon  * NOTE: 'ie' must be a copy of a real index entry.
13290a8ac0c1SNamjae Jeon  */
13300a8ac0c1SNamjae Jeon static int ntfs_ie_add_vcn(struct index_entry **ie)
13310a8ac0c1SNamjae Jeon {
13320a8ac0c1SNamjae Jeon 	struct index_entry *p, *old = *ie;
13330a8ac0c1SNamjae Jeon 
13340a8ac0c1SNamjae Jeon 	old->length = cpu_to_le16(le16_to_cpu(old->length) + sizeof(s64));
13350a8ac0c1SNamjae Jeon 	p = krealloc(old, le16_to_cpu(old->length), GFP_NOFS);
13360a8ac0c1SNamjae Jeon 	if (!p)
13370a8ac0c1SNamjae Jeon 		return -ENOMEM;
13380a8ac0c1SNamjae Jeon 
13390a8ac0c1SNamjae Jeon 	p->flags |= INDEX_ENTRY_NODE;
13400a8ac0c1SNamjae Jeon 	*ie = p;
13410a8ac0c1SNamjae Jeon 	return 0;
13420a8ac0c1SNamjae Jeon }
13430a8ac0c1SNamjae Jeon 
13440a8ac0c1SNamjae Jeon static int ntfs_ih_insert(struct index_header *ih, struct index_entry *orig_ie, s64 new_vcn,
13450a8ac0c1SNamjae Jeon 		int pos)
13460a8ac0c1SNamjae Jeon {
13470a8ac0c1SNamjae Jeon 	struct index_entry *ie_node, *ie;
13480a8ac0c1SNamjae Jeon 	int ret = 0;
13490a8ac0c1SNamjae Jeon 	s64 old_vcn;
13500a8ac0c1SNamjae Jeon 
13510a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
13520a8ac0c1SNamjae Jeon 	ie = ntfs_ie_dup(orig_ie);
13530a8ac0c1SNamjae Jeon 	if (!ie)
13540a8ac0c1SNamjae Jeon 		return -ENOMEM;
13550a8ac0c1SNamjae Jeon 
13560a8ac0c1SNamjae Jeon 	if (!(ie->flags & INDEX_ENTRY_NODE)) {
13570a8ac0c1SNamjae Jeon 		ret = ntfs_ie_add_vcn(&ie);
13580a8ac0c1SNamjae Jeon 		if (ret)
13590a8ac0c1SNamjae Jeon 			goto out;
13600a8ac0c1SNamjae Jeon 	}
13610a8ac0c1SNamjae Jeon 
13620a8ac0c1SNamjae Jeon 	ie_node = ntfs_ie_get_by_pos(ih, pos);
13630a8ac0c1SNamjae Jeon 	old_vcn = ntfs_ie_get_vcn(ie_node);
13640a8ac0c1SNamjae Jeon 	ntfs_ie_set_vcn(ie_node, new_vcn);
13650a8ac0c1SNamjae Jeon 
13660a8ac0c1SNamjae Jeon 	ntfs_ie_insert(ih, ie, ie_node);
13670a8ac0c1SNamjae Jeon 	ntfs_ie_set_vcn(ie_node, old_vcn);
13680a8ac0c1SNamjae Jeon out:
13690a8ac0c1SNamjae Jeon 	kfree(ie);
13700a8ac0c1SNamjae Jeon 	return ret;
13710a8ac0c1SNamjae Jeon }
13720a8ac0c1SNamjae Jeon 
13730a8ac0c1SNamjae Jeon static s64 ntfs_icx_parent_vcn(struct ntfs_index_context *icx)
13740a8ac0c1SNamjae Jeon {
13750a8ac0c1SNamjae Jeon 	return icx->parent_vcn[icx->pindex];
13760a8ac0c1SNamjae Jeon }
13770a8ac0c1SNamjae Jeon 
13780a8ac0c1SNamjae Jeon static s64 ntfs_icx_parent_pos(struct ntfs_index_context *icx)
13790a8ac0c1SNamjae Jeon {
13800a8ac0c1SNamjae Jeon 	return icx->parent_pos[icx->pindex];
13810a8ac0c1SNamjae Jeon }
13820a8ac0c1SNamjae Jeon 
13830a8ac0c1SNamjae Jeon static int ntfs_ir_insert_median(struct ntfs_index_context *icx, struct index_entry *median,
13840a8ac0c1SNamjae Jeon 		s64 new_vcn)
13850a8ac0c1SNamjae Jeon {
13860a8ac0c1SNamjae Jeon 	u32 new_size;
13870a8ac0c1SNamjae Jeon 	int ret;
13880a8ac0c1SNamjae Jeon 
13890a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
13900a8ac0c1SNamjae Jeon 
13910a8ac0c1SNamjae Jeon 	icx->ir = ntfs_ir_lookup2(icx->idx_ni, icx->name, icx->name_len);
13920a8ac0c1SNamjae Jeon 	if (!icx->ir)
13930a8ac0c1SNamjae Jeon 		return -ENOENT;
13940a8ac0c1SNamjae Jeon 
13950a8ac0c1SNamjae Jeon 	new_size = le32_to_cpu(icx->ir->index.index_length) +
13960a8ac0c1SNamjae Jeon 		le16_to_cpu(median->length);
13970a8ac0c1SNamjae Jeon 	if (!(median->flags & INDEX_ENTRY_NODE))
13980a8ac0c1SNamjae Jeon 		new_size += sizeof(s64);
13990a8ac0c1SNamjae Jeon 
14000a8ac0c1SNamjae Jeon 	ret = ntfs_ir_make_space(icx, new_size);
14010a8ac0c1SNamjae Jeon 	if (ret)
14020a8ac0c1SNamjae Jeon 		return ret;
14030a8ac0c1SNamjae Jeon 
14040a8ac0c1SNamjae Jeon 	icx->ir = ntfs_ir_lookup2(icx->idx_ni, icx->name, icx->name_len);
14050a8ac0c1SNamjae Jeon 	if (!icx->ir)
14060a8ac0c1SNamjae Jeon 		return -ENOENT;
14070a8ac0c1SNamjae Jeon 
14080a8ac0c1SNamjae Jeon 	return ntfs_ih_insert(&icx->ir->index, median, new_vcn,
14090a8ac0c1SNamjae Jeon 			ntfs_icx_parent_pos(icx));
14100a8ac0c1SNamjae Jeon }
14110a8ac0c1SNamjae Jeon 
14120a8ac0c1SNamjae Jeon static int ntfs_ib_split(struct ntfs_index_context *icx, struct index_block *ib);
14130a8ac0c1SNamjae Jeon 
14140a8ac0c1SNamjae Jeon struct split_info {
14150a8ac0c1SNamjae Jeon 	struct list_head entry;
14160a8ac0c1SNamjae Jeon 	s64 new_vcn;
14170a8ac0c1SNamjae Jeon 	struct index_block *ib;
14180a8ac0c1SNamjae Jeon };
14190a8ac0c1SNamjae Jeon 
14200a8ac0c1SNamjae Jeon static int ntfs_ib_insert(struct ntfs_index_context *icx, struct index_entry *ie, s64 new_vcn,
14210a8ac0c1SNamjae Jeon 		struct split_info *si)
14220a8ac0c1SNamjae Jeon {
14230a8ac0c1SNamjae Jeon 	struct index_block *ib;
14240a8ac0c1SNamjae Jeon 	u32 idx_size, allocated_size;
14250a8ac0c1SNamjae Jeon 	int err;
14260a8ac0c1SNamjae Jeon 	s64 old_vcn;
14270a8ac0c1SNamjae Jeon 
14280a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
14290a8ac0c1SNamjae Jeon 
14300a8ac0c1SNamjae Jeon 	ib = kvzalloc(icx->block_size, GFP_NOFS);
14310a8ac0c1SNamjae Jeon 	if (!ib)
14320a8ac0c1SNamjae Jeon 		return -ENOMEM;
14330a8ac0c1SNamjae Jeon 
14340a8ac0c1SNamjae Jeon 	old_vcn = ntfs_icx_parent_vcn(icx);
14350a8ac0c1SNamjae Jeon 
14360a8ac0c1SNamjae Jeon 	err = ntfs_ib_read(icx, old_vcn, ib);
14370a8ac0c1SNamjae Jeon 	if (err)
14380a8ac0c1SNamjae Jeon 		goto err_out;
14390a8ac0c1SNamjae Jeon 
14400a8ac0c1SNamjae Jeon 	idx_size = le32_to_cpu(ib->index.index_length);
14410a8ac0c1SNamjae Jeon 	allocated_size = le32_to_cpu(ib->index.allocated_size);
14420a8ac0c1SNamjae Jeon 	if (idx_size + le16_to_cpu(ie->length) + sizeof(s64) > allocated_size) {
14430a8ac0c1SNamjae Jeon 		si->ib = ib;
14440a8ac0c1SNamjae Jeon 		si->new_vcn = new_vcn;
14450a8ac0c1SNamjae Jeon 		return -EAGAIN;
14460a8ac0c1SNamjae Jeon 	}
14470a8ac0c1SNamjae Jeon 
14480a8ac0c1SNamjae Jeon 	err = ntfs_ih_insert(&ib->index, ie, new_vcn, ntfs_icx_parent_pos(icx));
14490a8ac0c1SNamjae Jeon 	if (err)
14500a8ac0c1SNamjae Jeon 		goto err_out;
14510a8ac0c1SNamjae Jeon 
14520a8ac0c1SNamjae Jeon 	err = ntfs_ib_write(icx, ib);
14530a8ac0c1SNamjae Jeon 
14540a8ac0c1SNamjae Jeon err_out:
14550a8ac0c1SNamjae Jeon 	kvfree(ib);
14560a8ac0c1SNamjae Jeon 	return err;
14570a8ac0c1SNamjae Jeon }
14580a8ac0c1SNamjae Jeon 
14590a8ac0c1SNamjae Jeon /*
14600a8ac0c1SNamjae Jeon  * ntfs_ib_split - Split an index block
14610a8ac0c1SNamjae Jeon  * @icx: index context
14620a8ac0c1SNamjae Jeon  * @ib: index block to split
14630a8ac0c1SNamjae Jeon  */
14640a8ac0c1SNamjae Jeon static int ntfs_ib_split(struct ntfs_index_context *icx, struct index_block *ib)
14650a8ac0c1SNamjae Jeon {
14660a8ac0c1SNamjae Jeon 	struct index_entry *median;
14670a8ac0c1SNamjae Jeon 	s64 new_vcn;
14680a8ac0c1SNamjae Jeon 	int ret;
14690a8ac0c1SNamjae Jeon 	struct split_info *si;
14700a8ac0c1SNamjae Jeon 	LIST_HEAD(ntfs_cut_tail_list);
14710a8ac0c1SNamjae Jeon 
14720a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
14730a8ac0c1SNamjae Jeon 
14740a8ac0c1SNamjae Jeon resplit:
14750a8ac0c1SNamjae Jeon 	ret = ntfs_icx_parent_dec(icx);
14760a8ac0c1SNamjae Jeon 	if (ret)
14770a8ac0c1SNamjae Jeon 		goto out;
14780a8ac0c1SNamjae Jeon 
14790a8ac0c1SNamjae Jeon 	median  = ntfs_ie_get_median(&ib->index);
14800a8ac0c1SNamjae Jeon 	new_vcn = ntfs_ibm_get_free(icx);
14810a8ac0c1SNamjae Jeon 	if (new_vcn < 0) {
14820a8ac0c1SNamjae Jeon 		ret = -EINVAL;
14830a8ac0c1SNamjae Jeon 		goto out;
14840a8ac0c1SNamjae Jeon 	}
14850a8ac0c1SNamjae Jeon 
14860a8ac0c1SNamjae Jeon 	ret = ntfs_ib_copy_tail(icx, ib, median, new_vcn);
14870a8ac0c1SNamjae Jeon 	if (ret) {
14880a8ac0c1SNamjae Jeon 		ntfs_ibm_clear(icx, new_vcn);
14890a8ac0c1SNamjae Jeon 		goto out;
14900a8ac0c1SNamjae Jeon 	}
14910a8ac0c1SNamjae Jeon 
14920a8ac0c1SNamjae Jeon 	if (ntfs_icx_parent_vcn(icx) == VCN_INDEX_ROOT_PARENT) {
14930a8ac0c1SNamjae Jeon 		ret = ntfs_ir_insert_median(icx, median, new_vcn);
14940a8ac0c1SNamjae Jeon 		if (ret) {
14950a8ac0c1SNamjae Jeon 			ntfs_ibm_clear(icx, new_vcn);
14960a8ac0c1SNamjae Jeon 			goto out;
14970a8ac0c1SNamjae Jeon 		}
14980a8ac0c1SNamjae Jeon 	} else {
14990a8ac0c1SNamjae Jeon 		si = kzalloc(sizeof(struct split_info), GFP_NOFS);
15000a8ac0c1SNamjae Jeon 		if (!si) {
15010a8ac0c1SNamjae Jeon 			ntfs_ibm_clear(icx, new_vcn);
15020a8ac0c1SNamjae Jeon 			ret = -ENOMEM;
15030a8ac0c1SNamjae Jeon 			goto out;
15040a8ac0c1SNamjae Jeon 		}
15050a8ac0c1SNamjae Jeon 
15060a8ac0c1SNamjae Jeon 		ret = ntfs_ib_insert(icx, median, new_vcn, si);
15070a8ac0c1SNamjae Jeon 		if (ret == -EAGAIN) {
15080a8ac0c1SNamjae Jeon 			list_add_tail(&si->entry, &ntfs_cut_tail_list);
15090a8ac0c1SNamjae Jeon 			ib = si->ib;
15100a8ac0c1SNamjae Jeon 			goto resplit;
15110a8ac0c1SNamjae Jeon 		} else if (ret) {
15120a8ac0c1SNamjae Jeon 			kvfree(si->ib);
15130a8ac0c1SNamjae Jeon 			kfree(si);
15140a8ac0c1SNamjae Jeon 			ntfs_ibm_clear(icx, new_vcn);
15150a8ac0c1SNamjae Jeon 			goto out;
15160a8ac0c1SNamjae Jeon 		}
15170a8ac0c1SNamjae Jeon 		kfree(si);
15180a8ac0c1SNamjae Jeon 	}
15190a8ac0c1SNamjae Jeon 
15200a8ac0c1SNamjae Jeon 	ret = ntfs_ib_cut_tail(icx, ib, median);
15210a8ac0c1SNamjae Jeon 
15220a8ac0c1SNamjae Jeon out:
15230a8ac0c1SNamjae Jeon 	while (!list_empty(&ntfs_cut_tail_list)) {
15240a8ac0c1SNamjae Jeon 		si = list_last_entry(&ntfs_cut_tail_list, struct split_info, entry);
15250a8ac0c1SNamjae Jeon 		ntfs_ibm_clear(icx, si->new_vcn);
15260a8ac0c1SNamjae Jeon 		kvfree(si->ib);
15270a8ac0c1SNamjae Jeon 		list_del(&si->entry);
15280a8ac0c1SNamjae Jeon 		kfree(si);
15290a8ac0c1SNamjae Jeon 		if (!ret)
15300a8ac0c1SNamjae Jeon 			ret = -EAGAIN;
15310a8ac0c1SNamjae Jeon 	}
15320a8ac0c1SNamjae Jeon 
15330a8ac0c1SNamjae Jeon 	return ret;
15340a8ac0c1SNamjae Jeon }
15350a8ac0c1SNamjae Jeon 
15360a8ac0c1SNamjae Jeon int ntfs_ie_add(struct ntfs_index_context *icx, struct index_entry *ie)
15370a8ac0c1SNamjae Jeon {
15380a8ac0c1SNamjae Jeon 	struct index_header *ih;
15390a8ac0c1SNamjae Jeon 	int allocated_size, new_size;
15400a8ac0c1SNamjae Jeon 	int ret;
15410a8ac0c1SNamjae Jeon 
15420a8ac0c1SNamjae Jeon 	while (1) {
15430a8ac0c1SNamjae Jeon 		ret = ntfs_index_lookup(&ie->key, le16_to_cpu(ie->key_length), icx);
15440a8ac0c1SNamjae Jeon 		if (!ret) {
15450a8ac0c1SNamjae Jeon 			ret = -EEXIST;
15460a8ac0c1SNamjae Jeon 			ntfs_error(icx->idx_ni->vol->sb, "Index already have such entry");
15470a8ac0c1SNamjae Jeon 			goto err_out;
15480a8ac0c1SNamjae Jeon 		}
15490a8ac0c1SNamjae Jeon 		if (ret != -ENOENT) {
15500a8ac0c1SNamjae Jeon 			ntfs_error(icx->idx_ni->vol->sb, "Failed to find place for new entry");
15510a8ac0c1SNamjae Jeon 			goto err_out;
15520a8ac0c1SNamjae Jeon 		}
15530a8ac0c1SNamjae Jeon 		ret = 0;
15540a8ac0c1SNamjae Jeon 
15550a8ac0c1SNamjae Jeon 		if (icx->is_in_root)
15560a8ac0c1SNamjae Jeon 			ih = &icx->ir->index;
15570a8ac0c1SNamjae Jeon 		else
15580a8ac0c1SNamjae Jeon 			ih = &icx->ib->index;
15590a8ac0c1SNamjae Jeon 
15600a8ac0c1SNamjae Jeon 		allocated_size = le32_to_cpu(ih->allocated_size);
15610a8ac0c1SNamjae Jeon 		new_size = le32_to_cpu(ih->index_length) + le16_to_cpu(ie->length);
15620a8ac0c1SNamjae Jeon 
15630a8ac0c1SNamjae Jeon 		if (new_size <= allocated_size)
15640a8ac0c1SNamjae Jeon 			break;
15650a8ac0c1SNamjae Jeon 
15660a8ac0c1SNamjae Jeon 		ntfs_debug("index block sizes: allocated: %d  needed: %d\n",
15670a8ac0c1SNamjae Jeon 				allocated_size, new_size);
15680a8ac0c1SNamjae Jeon 
15690a8ac0c1SNamjae Jeon 		if (icx->is_in_root)
15700a8ac0c1SNamjae Jeon 			ret = ntfs_ir_make_space(icx, new_size);
15710a8ac0c1SNamjae Jeon 		else
15720a8ac0c1SNamjae Jeon 			ret = ntfs_ib_split(icx, icx->ib);
15730a8ac0c1SNamjae Jeon 		if (ret && ret != -EAGAIN)
15740a8ac0c1SNamjae Jeon 			goto err_out;
15750a8ac0c1SNamjae Jeon 
15760a8ac0c1SNamjae Jeon 		mark_mft_record_dirty(icx->actx->ntfs_ino);
15770a8ac0c1SNamjae Jeon 		ntfs_index_ctx_reinit(icx);
15780a8ac0c1SNamjae Jeon 	}
15790a8ac0c1SNamjae Jeon 
15800a8ac0c1SNamjae Jeon 	ntfs_ie_insert(ih, ie, icx->entry);
15810a8ac0c1SNamjae Jeon 	ntfs_index_entry_mark_dirty(icx);
15820a8ac0c1SNamjae Jeon 
15830a8ac0c1SNamjae Jeon err_out:
15840a8ac0c1SNamjae Jeon 	ntfs_debug("%s\n", ret ? "Failed" : "Done");
15850a8ac0c1SNamjae Jeon 	return ret;
15860a8ac0c1SNamjae Jeon }
15870a8ac0c1SNamjae Jeon 
15880a8ac0c1SNamjae Jeon /*
15890a8ac0c1SNamjae Jeon  * ntfs_index_add_filename - add filename to directory index
15900a8ac0c1SNamjae Jeon  * @ni:		ntfs inode describing directory to which index add filename
15910a8ac0c1SNamjae Jeon  * @fn:		FILE_NAME attribute to add
15920a8ac0c1SNamjae Jeon  * @mref:	reference of the inode which @fn describes
15930a8ac0c1SNamjae Jeon  */
15940a8ac0c1SNamjae Jeon int ntfs_index_add_filename(struct ntfs_inode *ni, struct file_name_attr *fn, u64 mref)
15950a8ac0c1SNamjae Jeon {
15960a8ac0c1SNamjae Jeon 	struct index_entry *ie;
15970a8ac0c1SNamjae Jeon 	struct ntfs_index_context *icx;
15980a8ac0c1SNamjae Jeon 	int fn_size, ie_size, err;
15990a8ac0c1SNamjae Jeon 
16000a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
16010a8ac0c1SNamjae Jeon 
16020a8ac0c1SNamjae Jeon 	if (!ni || !fn)
16030a8ac0c1SNamjae Jeon 		return -EINVAL;
16040a8ac0c1SNamjae Jeon 
16050a8ac0c1SNamjae Jeon 	fn_size = (fn->file_name_length * sizeof(__le16)) +
16060a8ac0c1SNamjae Jeon 		sizeof(struct file_name_attr);
16070a8ac0c1SNamjae Jeon 	ie_size = (sizeof(struct index_entry_header) + fn_size + 7) & ~7;
16080a8ac0c1SNamjae Jeon 
16090a8ac0c1SNamjae Jeon 	ie = kzalloc(ie_size, GFP_NOFS);
16100a8ac0c1SNamjae Jeon 	if (!ie)
16110a8ac0c1SNamjae Jeon 		return -ENOMEM;
16120a8ac0c1SNamjae Jeon 
16130a8ac0c1SNamjae Jeon 	ie->data.dir.indexed_file = cpu_to_le64(mref);
16140a8ac0c1SNamjae Jeon 	ie->length	 = cpu_to_le16(ie_size);
16150a8ac0c1SNamjae Jeon 	ie->key_length	 = cpu_to_le16(fn_size);
16160a8ac0c1SNamjae Jeon 
16170a8ac0c1SNamjae Jeon 	unsafe_memcpy(&ie->key, fn, fn_size,
16180a8ac0c1SNamjae Jeon 		      /* "fn_size" was correctly calculated above */);
16190a8ac0c1SNamjae Jeon 
16200a8ac0c1SNamjae Jeon 	icx = ntfs_index_ctx_get(ni, I30, 4);
16210a8ac0c1SNamjae Jeon 	if (!icx) {
16220a8ac0c1SNamjae Jeon 		err = -ENOMEM;
16230a8ac0c1SNamjae Jeon 		goto out;
16240a8ac0c1SNamjae Jeon 	}
16250a8ac0c1SNamjae Jeon 
16260a8ac0c1SNamjae Jeon 	err = ntfs_ie_add(icx, ie);
16270a8ac0c1SNamjae Jeon 	ntfs_index_ctx_put(icx);
16280a8ac0c1SNamjae Jeon out:
16290a8ac0c1SNamjae Jeon 	kfree(ie);
16300a8ac0c1SNamjae Jeon 	return err;
16310a8ac0c1SNamjae Jeon }
16320a8ac0c1SNamjae Jeon 
16330a8ac0c1SNamjae Jeon static int ntfs_ih_takeout(struct ntfs_index_context *icx, struct index_header *ih,
16340a8ac0c1SNamjae Jeon 		struct index_entry *ie, struct index_block *ib)
16350a8ac0c1SNamjae Jeon {
16360a8ac0c1SNamjae Jeon 	struct index_entry *ie_roam;
16370a8ac0c1SNamjae Jeon 	int freed_space;
16380a8ac0c1SNamjae Jeon 	bool full;
16390a8ac0c1SNamjae Jeon 	int ret = 0;
16400a8ac0c1SNamjae Jeon 
16410a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
16420a8ac0c1SNamjae Jeon 
16430a8ac0c1SNamjae Jeon 	full = ih->index_length == ih->allocated_size;
16440a8ac0c1SNamjae Jeon 	ie_roam = ntfs_ie_dup_novcn(ie);
16450a8ac0c1SNamjae Jeon 	if (!ie_roam)
16460a8ac0c1SNamjae Jeon 		return -ENOMEM;
16470a8ac0c1SNamjae Jeon 
16480a8ac0c1SNamjae Jeon 	ntfs_ie_delete(ih, ie);
16490a8ac0c1SNamjae Jeon 
16500a8ac0c1SNamjae Jeon 	if (ntfs_icx_parent_vcn(icx) == VCN_INDEX_ROOT_PARENT) {
16510a8ac0c1SNamjae Jeon 		/*
16520a8ac0c1SNamjae Jeon 		 * Recover the space which may have been freed
16530a8ac0c1SNamjae Jeon 		 * while deleting an entry from root index
16540a8ac0c1SNamjae Jeon 		 */
16550a8ac0c1SNamjae Jeon 		freed_space = le32_to_cpu(ih->allocated_size) -
16560a8ac0c1SNamjae Jeon 			le32_to_cpu(ih->index_length);
16570a8ac0c1SNamjae Jeon 		if (full && (freed_space > 0) && !(freed_space & 7)) {
16580a8ac0c1SNamjae Jeon 			ntfs_ir_truncate(icx, le32_to_cpu(ih->index_length));
16590a8ac0c1SNamjae Jeon 			/* do nothing if truncation fails */
16600a8ac0c1SNamjae Jeon 		}
16610a8ac0c1SNamjae Jeon 
16620a8ac0c1SNamjae Jeon 		mark_mft_record_dirty(icx->actx->ntfs_ino);
16630a8ac0c1SNamjae Jeon 	} else {
16640a8ac0c1SNamjae Jeon 		ret = ntfs_ib_write(icx, ib);
16650a8ac0c1SNamjae Jeon 		if (ret)
16660a8ac0c1SNamjae Jeon 			goto out;
16670a8ac0c1SNamjae Jeon 	}
16680a8ac0c1SNamjae Jeon 
16690a8ac0c1SNamjae Jeon 	ntfs_index_ctx_reinit(icx);
16700a8ac0c1SNamjae Jeon 
16710a8ac0c1SNamjae Jeon 	ret = ntfs_ie_add(icx, ie_roam);
16720a8ac0c1SNamjae Jeon out:
16730a8ac0c1SNamjae Jeon 	kfree(ie_roam);
16740a8ac0c1SNamjae Jeon 	return ret;
16750a8ac0c1SNamjae Jeon }
16760a8ac0c1SNamjae Jeon 
16770a8ac0c1SNamjae Jeon /*
16780a8ac0c1SNamjae Jeon  *  Used if an empty index block to be deleted has END entry as the parent
16790a8ac0c1SNamjae Jeon  *  in the INDEX_ROOT which is the only one there.
16800a8ac0c1SNamjae Jeon  */
16810a8ac0c1SNamjae Jeon static void ntfs_ir_leafify(struct ntfs_index_context *icx, struct index_header *ih)
16820a8ac0c1SNamjae Jeon {
16830a8ac0c1SNamjae Jeon 	struct index_entry *ie;
16840a8ac0c1SNamjae Jeon 
16850a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
16860a8ac0c1SNamjae Jeon 
16870a8ac0c1SNamjae Jeon 	ie = ntfs_ie_get_first(ih);
16880a8ac0c1SNamjae Jeon 	ie->flags &= ~INDEX_ENTRY_NODE;
16890a8ac0c1SNamjae Jeon 	ie->length = cpu_to_le16(le16_to_cpu(ie->length) - sizeof(s64));
16900a8ac0c1SNamjae Jeon 
16910a8ac0c1SNamjae Jeon 	ih->index_length = cpu_to_le32(le32_to_cpu(ih->index_length) - sizeof(s64));
16920a8ac0c1SNamjae Jeon 	ih->flags &= ~LARGE_INDEX;
16930a8ac0c1SNamjae Jeon 	NInoClearIndexAllocPresent(icx->idx_ni);
16940a8ac0c1SNamjae Jeon 
16950a8ac0c1SNamjae Jeon 	/* Not fatal error */
16960a8ac0c1SNamjae Jeon 	ntfs_ir_truncate(icx, le32_to_cpu(ih->index_length));
16970a8ac0c1SNamjae Jeon }
16980a8ac0c1SNamjae Jeon 
16990a8ac0c1SNamjae Jeon /*
17000a8ac0c1SNamjae Jeon  *  Used if an empty index block to be deleted has END entry as the parent
17010a8ac0c1SNamjae Jeon  *  in the INDEX_ROOT which is not the only one there.
17020a8ac0c1SNamjae Jeon  */
17030a8ac0c1SNamjae Jeon static int ntfs_ih_reparent_end(struct ntfs_index_context *icx, struct index_header *ih,
17040a8ac0c1SNamjae Jeon 		struct index_block *ib)
17050a8ac0c1SNamjae Jeon {
17060a8ac0c1SNamjae Jeon 	struct index_entry *ie, *ie_prev;
17070a8ac0c1SNamjae Jeon 
17080a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
17090a8ac0c1SNamjae Jeon 
17100a8ac0c1SNamjae Jeon 	ie = ntfs_ie_get_by_pos(ih, ntfs_icx_parent_pos(icx));
17110a8ac0c1SNamjae Jeon 	ie_prev = ntfs_ie_prev(ih, ie);
17120a8ac0c1SNamjae Jeon 	if (!ie_prev)
17130a8ac0c1SNamjae Jeon 		return -EIO;
17140a8ac0c1SNamjae Jeon 	ntfs_ie_set_vcn(ie, ntfs_ie_get_vcn(ie_prev));
17150a8ac0c1SNamjae Jeon 
17160a8ac0c1SNamjae Jeon 	return ntfs_ih_takeout(icx, ih, ie_prev, ib);
17170a8ac0c1SNamjae Jeon }
17180a8ac0c1SNamjae Jeon 
17190a8ac0c1SNamjae Jeon static int ntfs_index_rm_leaf(struct ntfs_index_context *icx)
17200a8ac0c1SNamjae Jeon {
17210a8ac0c1SNamjae Jeon 	struct index_block *ib = NULL;
17220a8ac0c1SNamjae Jeon 	struct index_header *parent_ih;
17230a8ac0c1SNamjae Jeon 	struct index_entry *ie;
17240a8ac0c1SNamjae Jeon 	int ret;
17250a8ac0c1SNamjae Jeon 
17260a8ac0c1SNamjae Jeon 	ntfs_debug("pindex: %d\n", icx->pindex);
17270a8ac0c1SNamjae Jeon 
17280a8ac0c1SNamjae Jeon 	ret = ntfs_icx_parent_dec(icx);
17290a8ac0c1SNamjae Jeon 	if (ret)
17300a8ac0c1SNamjae Jeon 		return ret;
17310a8ac0c1SNamjae Jeon 
17320a8ac0c1SNamjae Jeon 	ret = ntfs_ibm_clear(icx, icx->parent_vcn[icx->pindex + 1]);
17330a8ac0c1SNamjae Jeon 	if (ret)
17340a8ac0c1SNamjae Jeon 		return ret;
17350a8ac0c1SNamjae Jeon 
17360a8ac0c1SNamjae Jeon 	if (ntfs_icx_parent_vcn(icx) == VCN_INDEX_ROOT_PARENT)
17370a8ac0c1SNamjae Jeon 		parent_ih = &icx->ir->index;
17380a8ac0c1SNamjae Jeon 	else {
17390a8ac0c1SNamjae Jeon 		ib = kvzalloc(icx->block_size, GFP_NOFS);
17400a8ac0c1SNamjae Jeon 		if (!ib)
17410a8ac0c1SNamjae Jeon 			return -ENOMEM;
17420a8ac0c1SNamjae Jeon 
17430a8ac0c1SNamjae Jeon 		ret = ntfs_ib_read(icx, ntfs_icx_parent_vcn(icx), ib);
17440a8ac0c1SNamjae Jeon 		if (ret)
17450a8ac0c1SNamjae Jeon 			goto out;
17460a8ac0c1SNamjae Jeon 
17470a8ac0c1SNamjae Jeon 		parent_ih = &ib->index;
17480a8ac0c1SNamjae Jeon 	}
17490a8ac0c1SNamjae Jeon 
17500a8ac0c1SNamjae Jeon 	ie = ntfs_ie_get_by_pos(parent_ih, ntfs_icx_parent_pos(icx));
17510a8ac0c1SNamjae Jeon 	if (!ntfs_ie_end(ie)) {
17520a8ac0c1SNamjae Jeon 		ret = ntfs_ih_takeout(icx, parent_ih, ie, ib);
17530a8ac0c1SNamjae Jeon 		goto out;
17540a8ac0c1SNamjae Jeon 	}
17550a8ac0c1SNamjae Jeon 
17560a8ac0c1SNamjae Jeon 	if (ntfs_ih_zero_entry(parent_ih)) {
17570a8ac0c1SNamjae Jeon 		if (ntfs_icx_parent_vcn(icx) == VCN_INDEX_ROOT_PARENT) {
17580a8ac0c1SNamjae Jeon 			ntfs_ir_leafify(icx, parent_ih);
17590a8ac0c1SNamjae Jeon 			goto out;
17600a8ac0c1SNamjae Jeon 		}
17610a8ac0c1SNamjae Jeon 
17620a8ac0c1SNamjae Jeon 		ret = ntfs_index_rm_leaf(icx);
17630a8ac0c1SNamjae Jeon 		goto out;
17640a8ac0c1SNamjae Jeon 	}
17650a8ac0c1SNamjae Jeon 
17660a8ac0c1SNamjae Jeon 	ret = ntfs_ih_reparent_end(icx, parent_ih, ib);
17670a8ac0c1SNamjae Jeon out:
17680a8ac0c1SNamjae Jeon 	kvfree(ib);
17690a8ac0c1SNamjae Jeon 	return ret;
17700a8ac0c1SNamjae Jeon }
17710a8ac0c1SNamjae Jeon 
17720a8ac0c1SNamjae Jeon static int ntfs_index_rm_node(struct ntfs_index_context *icx)
17730a8ac0c1SNamjae Jeon {
17740a8ac0c1SNamjae Jeon 	int entry_pos, pindex;
17750a8ac0c1SNamjae Jeon 	s64 vcn;
17760a8ac0c1SNamjae Jeon 	struct index_block *ib = NULL;
17770a8ac0c1SNamjae Jeon 	struct index_entry *ie_succ, *ie, *entry = icx->entry;
17780a8ac0c1SNamjae Jeon 	struct index_header *ih;
17790a8ac0c1SNamjae Jeon 	u32 new_size;
17800a8ac0c1SNamjae Jeon 	int delta, ret;
17810a8ac0c1SNamjae Jeon 
17820a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
17830a8ac0c1SNamjae Jeon 
17840a8ac0c1SNamjae Jeon 	if (!icx->ia_ni) {
17850a8ac0c1SNamjae Jeon 		icx->ia_ni = ntfs_ia_open(icx, icx->idx_ni);
17860a8ac0c1SNamjae Jeon 		if (!icx->ia_ni)
17870a8ac0c1SNamjae Jeon 			return -EINVAL;
17880a8ac0c1SNamjae Jeon 	}
17890a8ac0c1SNamjae Jeon 
17900a8ac0c1SNamjae Jeon 	ib = kvzalloc(icx->block_size, GFP_NOFS);
17910a8ac0c1SNamjae Jeon 	if (!ib)
17920a8ac0c1SNamjae Jeon 		return -ENOMEM;
17930a8ac0c1SNamjae Jeon 
17940a8ac0c1SNamjae Jeon 	ie_succ = ntfs_ie_get_next(icx->entry);
17950a8ac0c1SNamjae Jeon 	entry_pos = icx->parent_pos[icx->pindex]++;
17960a8ac0c1SNamjae Jeon 	pindex = icx->pindex;
17970a8ac0c1SNamjae Jeon descend:
17980a8ac0c1SNamjae Jeon 	vcn = ntfs_ie_get_vcn(ie_succ);
17990a8ac0c1SNamjae Jeon 	ret = ntfs_ib_read(icx, vcn, ib);
18000a8ac0c1SNamjae Jeon 	if (ret)
18010a8ac0c1SNamjae Jeon 		goto out;
18020a8ac0c1SNamjae Jeon 
18030a8ac0c1SNamjae Jeon 	ie_succ = ntfs_ie_get_first(&ib->index);
18040a8ac0c1SNamjae Jeon 
18050a8ac0c1SNamjae Jeon 	ret = ntfs_icx_parent_inc(icx);
18060a8ac0c1SNamjae Jeon 	if (ret)
18070a8ac0c1SNamjae Jeon 		goto out;
18080a8ac0c1SNamjae Jeon 
18090a8ac0c1SNamjae Jeon 	icx->parent_vcn[icx->pindex] = vcn;
18100a8ac0c1SNamjae Jeon 	icx->parent_pos[icx->pindex] = 0;
18110a8ac0c1SNamjae Jeon 
18120a8ac0c1SNamjae Jeon 	if ((ib->index.flags & NODE_MASK) == INDEX_NODE)
18130a8ac0c1SNamjae Jeon 		goto descend;
18140a8ac0c1SNamjae Jeon 
18150a8ac0c1SNamjae Jeon 	if (ntfs_ih_zero_entry(&ib->index)) {
18160a8ac0c1SNamjae Jeon 		ret = -EIO;
18170a8ac0c1SNamjae Jeon 		ntfs_error(icx->idx_ni->vol->sb, "Empty index block");
18180a8ac0c1SNamjae Jeon 		goto out;
18190a8ac0c1SNamjae Jeon 	}
18200a8ac0c1SNamjae Jeon 
18210a8ac0c1SNamjae Jeon 	ie = ntfs_ie_dup(ie_succ);
18220a8ac0c1SNamjae Jeon 	if (!ie) {
18230a8ac0c1SNamjae Jeon 		ret = -ENOMEM;
18240a8ac0c1SNamjae Jeon 		goto out;
18250a8ac0c1SNamjae Jeon 	}
18260a8ac0c1SNamjae Jeon 
18270a8ac0c1SNamjae Jeon 	ret = ntfs_ie_add_vcn(&ie);
18280a8ac0c1SNamjae Jeon 	if (ret)
18290a8ac0c1SNamjae Jeon 		goto out2;
18300a8ac0c1SNamjae Jeon 
18310a8ac0c1SNamjae Jeon 	ntfs_ie_set_vcn(ie, ntfs_ie_get_vcn(icx->entry));
18320a8ac0c1SNamjae Jeon 
18330a8ac0c1SNamjae Jeon 	if (icx->is_in_root)
18340a8ac0c1SNamjae Jeon 		ih = &icx->ir->index;
18350a8ac0c1SNamjae Jeon 	else
18360a8ac0c1SNamjae Jeon 		ih = &icx->ib->index;
18370a8ac0c1SNamjae Jeon 
18380a8ac0c1SNamjae Jeon 	delta = le16_to_cpu(ie->length) - le16_to_cpu(icx->entry->length);
18390a8ac0c1SNamjae Jeon 	new_size = le32_to_cpu(ih->index_length) + delta;
18400a8ac0c1SNamjae Jeon 	if (delta > 0) {
18410a8ac0c1SNamjae Jeon 		if (icx->is_in_root) {
18420a8ac0c1SNamjae Jeon 			ret = ntfs_ir_make_space(icx, new_size);
18430a8ac0c1SNamjae Jeon 			if (ret != 0)
18440a8ac0c1SNamjae Jeon 				goto out2;
18450a8ac0c1SNamjae Jeon 
18460a8ac0c1SNamjae Jeon 			ih = &icx->ir->index;
18470a8ac0c1SNamjae Jeon 			entry = ntfs_ie_get_by_pos(ih, entry_pos);
18480a8ac0c1SNamjae Jeon 
18490a8ac0c1SNamjae Jeon 		} else if (new_size > le32_to_cpu(ih->allocated_size)) {
18500a8ac0c1SNamjae Jeon 			icx->pindex = pindex;
18510a8ac0c1SNamjae Jeon 			ret = ntfs_ib_split(icx, icx->ib);
18520a8ac0c1SNamjae Jeon 			if (!ret)
18530a8ac0c1SNamjae Jeon 				ret = -EAGAIN;
18540a8ac0c1SNamjae Jeon 			goto out2;
18550a8ac0c1SNamjae Jeon 		}
18560a8ac0c1SNamjae Jeon 	}
18570a8ac0c1SNamjae Jeon 
18580a8ac0c1SNamjae Jeon 	ntfs_ie_delete(ih, entry);
18590a8ac0c1SNamjae Jeon 	ntfs_ie_insert(ih, ie, entry);
18600a8ac0c1SNamjae Jeon 
18610a8ac0c1SNamjae Jeon 	if (icx->is_in_root)
18620a8ac0c1SNamjae Jeon 		ret = ntfs_ir_truncate(icx, new_size);
18630a8ac0c1SNamjae Jeon 	else
18640a8ac0c1SNamjae Jeon 		ret = ntfs_icx_ib_write(icx);
18650a8ac0c1SNamjae Jeon 	if (ret)
18660a8ac0c1SNamjae Jeon 		goto out2;
18670a8ac0c1SNamjae Jeon 
18680a8ac0c1SNamjae Jeon 	ntfs_ie_delete(&ib->index, ie_succ);
18690a8ac0c1SNamjae Jeon 
18700a8ac0c1SNamjae Jeon 	if (ntfs_ih_zero_entry(&ib->index))
18710a8ac0c1SNamjae Jeon 		ret = ntfs_index_rm_leaf(icx);
18720a8ac0c1SNamjae Jeon 	else
18730a8ac0c1SNamjae Jeon 		ret = ntfs_ib_write(icx, ib);
18740a8ac0c1SNamjae Jeon 
18750a8ac0c1SNamjae Jeon out2:
18760a8ac0c1SNamjae Jeon 	kfree(ie);
18770a8ac0c1SNamjae Jeon out:
18780a8ac0c1SNamjae Jeon 	kvfree(ib);
18790a8ac0c1SNamjae Jeon 	return ret;
18800a8ac0c1SNamjae Jeon }
18810a8ac0c1SNamjae Jeon 
18820a8ac0c1SNamjae Jeon /*
18830a8ac0c1SNamjae Jeon  * ntfs_index_rm - remove entry from the index
18840a8ac0c1SNamjae Jeon  * @icx:	index context describing entry to delete
18850a8ac0c1SNamjae Jeon  *
18860a8ac0c1SNamjae Jeon  * Delete entry described by @icx from the index. Index context is always
18870a8ac0c1SNamjae Jeon  * reinitialized after use of this function, so it can be used for index
18880a8ac0c1SNamjae Jeon  * lookup once again.
18890a8ac0c1SNamjae Jeon  */
18900a8ac0c1SNamjae Jeon int ntfs_index_rm(struct ntfs_index_context *icx)
18910a8ac0c1SNamjae Jeon {
18920a8ac0c1SNamjae Jeon 	struct index_header *ih;
18930a8ac0c1SNamjae Jeon 	int ret = 0;
18940a8ac0c1SNamjae Jeon 
18950a8ac0c1SNamjae Jeon 	ntfs_debug("Entering\n");
18960a8ac0c1SNamjae Jeon 
18970a8ac0c1SNamjae Jeon 	if (!icx || (!icx->ib && !icx->ir) || ntfs_ie_end(icx->entry)) {
18980a8ac0c1SNamjae Jeon 		ret = -EINVAL;
18990a8ac0c1SNamjae Jeon 		goto err_out;
19000a8ac0c1SNamjae Jeon 	}
19010a8ac0c1SNamjae Jeon 	if (icx->is_in_root)
19020a8ac0c1SNamjae Jeon 		ih = &icx->ir->index;
19030a8ac0c1SNamjae Jeon 	else
19040a8ac0c1SNamjae Jeon 		ih = &icx->ib->index;
19050a8ac0c1SNamjae Jeon 
19060a8ac0c1SNamjae Jeon 	if (icx->entry->flags & INDEX_ENTRY_NODE) {
19070a8ac0c1SNamjae Jeon 		ret = ntfs_index_rm_node(icx);
19080a8ac0c1SNamjae Jeon 		if (ret)
19090a8ac0c1SNamjae Jeon 			goto err_out;
19100a8ac0c1SNamjae Jeon 	} else if (icx->is_in_root || !ntfs_ih_one_entry(ih)) {
19110a8ac0c1SNamjae Jeon 		ntfs_ie_delete(ih, icx->entry);
19120a8ac0c1SNamjae Jeon 
19130a8ac0c1SNamjae Jeon 		if (icx->is_in_root)
19140a8ac0c1SNamjae Jeon 			ret = ntfs_ir_truncate(icx, le32_to_cpu(ih->index_length));
19150a8ac0c1SNamjae Jeon 		else
19160a8ac0c1SNamjae Jeon 			ret = ntfs_icx_ib_write(icx);
19170a8ac0c1SNamjae Jeon 		if (ret)
19180a8ac0c1SNamjae Jeon 			goto err_out;
19190a8ac0c1SNamjae Jeon 	} else {
19200a8ac0c1SNamjae Jeon 		ret = ntfs_index_rm_leaf(icx);
19210a8ac0c1SNamjae Jeon 		if (ret)
19220a8ac0c1SNamjae Jeon 			goto err_out;
19230a8ac0c1SNamjae Jeon 	}
19240a8ac0c1SNamjae Jeon 
19250a8ac0c1SNamjae Jeon 	return 0;
19260a8ac0c1SNamjae Jeon err_out:
19270a8ac0c1SNamjae Jeon 	return ret;
19280a8ac0c1SNamjae Jeon }
19290a8ac0c1SNamjae Jeon 
19300a8ac0c1SNamjae Jeon int ntfs_index_remove(struct ntfs_inode *dir_ni, const void *key, const u32 keylen)
19310a8ac0c1SNamjae Jeon {
19320a8ac0c1SNamjae Jeon 	int ret = 0;
19330a8ac0c1SNamjae Jeon 	struct ntfs_index_context *icx;
19340a8ac0c1SNamjae Jeon 
19350a8ac0c1SNamjae Jeon 	icx = ntfs_index_ctx_get(dir_ni, I30, 4);
19360a8ac0c1SNamjae Jeon 	if (!icx)
19370a8ac0c1SNamjae Jeon 		return -EINVAL;
19380a8ac0c1SNamjae Jeon 
19390a8ac0c1SNamjae Jeon 	while (1) {
19400a8ac0c1SNamjae Jeon 		ret = ntfs_index_lookup(key, keylen, icx);
19410a8ac0c1SNamjae Jeon 		if (ret)
19420a8ac0c1SNamjae Jeon 			goto err_out;
19430a8ac0c1SNamjae Jeon 
19440a8ac0c1SNamjae Jeon 		ret = ntfs_index_rm(icx);
19450a8ac0c1SNamjae Jeon 		if (ret && ret != -EAGAIN)
19460a8ac0c1SNamjae Jeon 			goto err_out;
19470a8ac0c1SNamjae Jeon 		else if (!ret)
19480a8ac0c1SNamjae Jeon 			break;
19490a8ac0c1SNamjae Jeon 
19500a8ac0c1SNamjae Jeon 		mark_mft_record_dirty(icx->actx->ntfs_ino);
19510a8ac0c1SNamjae Jeon 		ntfs_index_ctx_reinit(icx);
19520a8ac0c1SNamjae Jeon 	}
19530a8ac0c1SNamjae Jeon 
19540a8ac0c1SNamjae Jeon 	mark_mft_record_dirty(icx->actx->ntfs_ino);
19550a8ac0c1SNamjae Jeon 
19560a8ac0c1SNamjae Jeon 	ntfs_index_ctx_put(icx);
19570a8ac0c1SNamjae Jeon 	return 0;
19580a8ac0c1SNamjae Jeon err_out:
19590a8ac0c1SNamjae Jeon 	ntfs_index_ctx_put(icx);
19600a8ac0c1SNamjae Jeon 	ntfs_error(dir_ni->vol->sb, "Delete failed");
19610a8ac0c1SNamjae Jeon 	return ret;
19620a8ac0c1SNamjae Jeon }
19630a8ac0c1SNamjae Jeon 
19640a8ac0c1SNamjae Jeon /*
19650a8ac0c1SNamjae Jeon  * ntfs_index_walk_down - walk down the index tree (leaf bound)
19660a8ac0c1SNamjae Jeon  * until there are no subnode in the first index entry returns
19670a8ac0c1SNamjae Jeon  * the entry at the bottom left in subnode
19680a8ac0c1SNamjae Jeon  */
19690a8ac0c1SNamjae Jeon struct index_entry *ntfs_index_walk_down(struct index_entry *ie, struct ntfs_index_context *ictx)
19700a8ac0c1SNamjae Jeon {
19710a8ac0c1SNamjae Jeon 	struct index_entry *entry;
19720a8ac0c1SNamjae Jeon 	s64 vcn;
19730a8ac0c1SNamjae Jeon 
19740a8ac0c1SNamjae Jeon 	entry = ie;
19750a8ac0c1SNamjae Jeon 	do {
19760a8ac0c1SNamjae Jeon 		vcn = ntfs_ie_get_vcn(entry);
19770a8ac0c1SNamjae Jeon 		if (ictx->is_in_root) {
19780a8ac0c1SNamjae Jeon 			/* down from level zero */
19790a8ac0c1SNamjae Jeon 			ictx->ir = NULL;
19800a8ac0c1SNamjae Jeon 			ictx->ib = kvzalloc(ictx->block_size, GFP_NOFS);
19810a8ac0c1SNamjae Jeon 			ictx->pindex = 1;
19820a8ac0c1SNamjae Jeon 			ictx->is_in_root = false;
19830a8ac0c1SNamjae Jeon 		} else {
19840a8ac0c1SNamjae Jeon 			/* down from non-zero level */
19850a8ac0c1SNamjae Jeon 			ictx->pindex++;
19860a8ac0c1SNamjae Jeon 		}
19870a8ac0c1SNamjae Jeon 
19880a8ac0c1SNamjae Jeon 		ictx->parent_pos[ictx->pindex] = 0;
19890a8ac0c1SNamjae Jeon 		ictx->parent_vcn[ictx->pindex] = vcn;
19900a8ac0c1SNamjae Jeon 		if (!ntfs_ib_read(ictx, vcn, ictx->ib)) {
19910a8ac0c1SNamjae Jeon 			ictx->entry = ntfs_ie_get_first(&ictx->ib->index);
19920a8ac0c1SNamjae Jeon 			entry = ictx->entry;
19930a8ac0c1SNamjae Jeon 		} else
19940a8ac0c1SNamjae Jeon 			entry = NULL;
19950a8ac0c1SNamjae Jeon 	} while (entry && (entry->flags & INDEX_ENTRY_NODE));
19960a8ac0c1SNamjae Jeon 
19970a8ac0c1SNamjae Jeon 	return entry;
19980a8ac0c1SNamjae Jeon }
19990a8ac0c1SNamjae Jeon 
20000a8ac0c1SNamjae Jeon /*
20010a8ac0c1SNamjae Jeon  * ntfs_index_walk_up - walk up the index tree (root bound) until
20020a8ac0c1SNamjae Jeon  * there is a valid data entry in parent returns the parent entry
20030a8ac0c1SNamjae Jeon  * or NULL if no more parent.
20040a8ac0c1SNamjae Jeon  * @ie: current index entry
20050a8ac0c1SNamjae Jeon  * @ictx: index context
20060a8ac0c1SNamjae Jeon  */
20070a8ac0c1SNamjae Jeon static struct index_entry *ntfs_index_walk_up(struct index_entry *ie,
20080a8ac0c1SNamjae Jeon 		struct ntfs_index_context *ictx)
20090a8ac0c1SNamjae Jeon {
2010*068a35fdSHyunchul Lee 	struct index_entry *entry = ie;
20110a8ac0c1SNamjae Jeon 	s64 vcn;
20120a8ac0c1SNamjae Jeon 
2013*068a35fdSHyunchul Lee 	if (ictx->pindex <= 0)
2014*068a35fdSHyunchul Lee 		return NULL;
2015*068a35fdSHyunchul Lee 
20160a8ac0c1SNamjae Jeon 	do {
20170a8ac0c1SNamjae Jeon 		ictx->pindex--;
20180a8ac0c1SNamjae Jeon 		if (!ictx->pindex) {
20190a8ac0c1SNamjae Jeon 			/* we have reached the root */
20200a8ac0c1SNamjae Jeon 			kfree(ictx->ib);
20210a8ac0c1SNamjae Jeon 			ictx->ib = NULL;
20220a8ac0c1SNamjae Jeon 			ictx->is_in_root = true;
20230a8ac0c1SNamjae Jeon 			/* a new search context is to be allocated */
20240a8ac0c1SNamjae Jeon 			if (ictx->actx)
20250a8ac0c1SNamjae Jeon 				ntfs_attr_put_search_ctx(ictx->actx);
20260a8ac0c1SNamjae Jeon 			ictx->ir = ntfs_ir_lookup(ictx->idx_ni, ictx->name,
20270a8ac0c1SNamjae Jeon 						  ictx->name_len, &ictx->actx);
20280a8ac0c1SNamjae Jeon 			if (ictx->ir)
2029*068a35fdSHyunchul Lee 				entry = ntfs_ie_get_by_pos(
2030*068a35fdSHyunchul Lee 					&ictx->ir->index,
20310a8ac0c1SNamjae Jeon 					ictx->parent_pos[ictx->pindex]);
20320a8ac0c1SNamjae Jeon 			else
20330a8ac0c1SNamjae Jeon 				entry = NULL;
20340a8ac0c1SNamjae Jeon 		} else {
20350a8ac0c1SNamjae Jeon 			/* up into non-root node */
20360a8ac0c1SNamjae Jeon 			vcn = ictx->parent_vcn[ictx->pindex];
20370a8ac0c1SNamjae Jeon 			if (!ntfs_ib_read(ictx, vcn, ictx->ib)) {
2038*068a35fdSHyunchul Lee 				entry = ntfs_ie_get_by_pos(
2039*068a35fdSHyunchul Lee 					&ictx->ib->index,
20400a8ac0c1SNamjae Jeon 					ictx->parent_pos[ictx->pindex]);
20410a8ac0c1SNamjae Jeon 			} else
20420a8ac0c1SNamjae Jeon 				entry = NULL;
20430a8ac0c1SNamjae Jeon 		}
20440a8ac0c1SNamjae Jeon 		ictx->entry = entry;
20450a8ac0c1SNamjae Jeon 	} while (entry && (ictx->pindex > 0) &&
20460a8ac0c1SNamjae Jeon 		 (entry->flags & INDEX_ENTRY_END));
20470a8ac0c1SNamjae Jeon 	return entry;
20480a8ac0c1SNamjae Jeon }
20490a8ac0c1SNamjae Jeon 
20500a8ac0c1SNamjae Jeon /*
20510a8ac0c1SNamjae Jeon  * ntfs_index_next - get next entry in an index according to collating sequence.
20520a8ac0c1SNamjae Jeon  * Returns next entry or NULL if none.
20530a8ac0c1SNamjae Jeon  *
20540a8ac0c1SNamjae Jeon  * Sample layout :
20550a8ac0c1SNamjae Jeon  *
20560a8ac0c1SNamjae Jeon  *                 +---+---+---+---+---+---+---+---+    n ptrs to subnodes
20570a8ac0c1SNamjae Jeon  *                 |   |   | 10| 25| 33|   |   |   |    n-1 keys in between
20580a8ac0c1SNamjae Jeon  *                 +---+---+---+---+---+---+---+---+    no key in last entry
20590a8ac0c1SNamjae Jeon  *                              | A | A
20600a8ac0c1SNamjae Jeon  *                              | | | +-------------------------------+
20610a8ac0c1SNamjae Jeon  *   +--------------------------+ | +-----+                           |
20620a8ac0c1SNamjae Jeon  *   |                            +--+    |                           |
20630a8ac0c1SNamjae Jeon  *   V                               |    V                           |
20640a8ac0c1SNamjae Jeon  * +---+---+---+---+---+---+---+---+ |  +---+---+---+---+---+---+---+---+
20650a8ac0c1SNamjae Jeon  * | 11| 12| 13| 14| 15| 16| 17|   | |  | 26| 27| 28| 29| 30| 31| 32|   |
20660a8ac0c1SNamjae Jeon  * +---+---+---+---+---+---+---+---+ |  +---+---+---+---+---+---+---+---+
20670a8ac0c1SNamjae Jeon  *                               |   |
20680a8ac0c1SNamjae Jeon  *       +-----------------------+   |
20690a8ac0c1SNamjae Jeon  *       |                           |
20700a8ac0c1SNamjae Jeon  *     +---+---+---+---+---+---+---+---+
20710a8ac0c1SNamjae Jeon  *     | 18| 19| 20| 21| 22| 23| 24|   |
20720a8ac0c1SNamjae Jeon  *     +---+---+---+---+---+---+---+---+
20730a8ac0c1SNamjae Jeon  *
20740a8ac0c1SNamjae Jeon  * @ie: current index entry
20750a8ac0c1SNamjae Jeon  * @ictx: index context
20760a8ac0c1SNamjae Jeon  */
20770a8ac0c1SNamjae Jeon struct index_entry *ntfs_index_next(struct index_entry *ie, struct ntfs_index_context *ictx)
20780a8ac0c1SNamjae Jeon {
20790a8ac0c1SNamjae Jeon 	struct index_entry *next;
20800a8ac0c1SNamjae Jeon 	__le16 flags;
20810a8ac0c1SNamjae Jeon 
20820a8ac0c1SNamjae Jeon 	/*
20830a8ac0c1SNamjae Jeon 	 * lookup() may have returned an invalid node
20840a8ac0c1SNamjae Jeon 	 * when searching for a partial key
20850a8ac0c1SNamjae Jeon 	 * if this happens, walk up
20860a8ac0c1SNamjae Jeon 	 */
20870a8ac0c1SNamjae Jeon 	if (ie->flags & INDEX_ENTRY_END)
20880a8ac0c1SNamjae Jeon 		next = ntfs_index_walk_up(ie, ictx);
20890a8ac0c1SNamjae Jeon 	else {
20900a8ac0c1SNamjae Jeon 		/*
20910a8ac0c1SNamjae Jeon 		 * get next entry in same node
20920a8ac0c1SNamjae Jeon 		 * there is always one after any entry with data
20930a8ac0c1SNamjae Jeon 		 */
20940a8ac0c1SNamjae Jeon 		next = (struct index_entry *)((char *)ie + le16_to_cpu(ie->length));
20950a8ac0c1SNamjae Jeon 		++ictx->parent_pos[ictx->pindex];
20960a8ac0c1SNamjae Jeon 		flags = next->flags;
20970a8ac0c1SNamjae Jeon 
20980a8ac0c1SNamjae Jeon 		/* walk down if it has a subnode */
20990a8ac0c1SNamjae Jeon 		if (flags & INDEX_ENTRY_NODE) {
21000a8ac0c1SNamjae Jeon 			if (!ictx->ia_ni)
21010a8ac0c1SNamjae Jeon 				ictx->ia_ni = ntfs_ia_open(ictx, ictx->idx_ni);
21020a8ac0c1SNamjae Jeon 
21030a8ac0c1SNamjae Jeon 			next = ntfs_index_walk_down(next, ictx);
21040a8ac0c1SNamjae Jeon 		} else {
21050a8ac0c1SNamjae Jeon 
21060a8ac0c1SNamjae Jeon 			/* walk up it has no subnode, nor data */
21070a8ac0c1SNamjae Jeon 			if (flags & INDEX_ENTRY_END)
21080a8ac0c1SNamjae Jeon 				next = ntfs_index_walk_up(next, ictx);
21090a8ac0c1SNamjae Jeon 		}
21100a8ac0c1SNamjae Jeon 	}
21110a8ac0c1SNamjae Jeon 
21120a8ac0c1SNamjae Jeon 	/* return NULL if stuck at end of a block */
21130a8ac0c1SNamjae Jeon 	if (next && (next->flags & INDEX_ENTRY_END))
21140a8ac0c1SNamjae Jeon 		next = NULL;
21150a8ac0c1SNamjae Jeon 
21160a8ac0c1SNamjae Jeon 	return next;
21170a8ac0c1SNamjae Jeon }
2118