0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/slab.h>
0009
0010 #include "aops.h"
0011 #include "collate.h"
0012 #include "debug.h"
0013 #include "index.h"
0014 #include "ntfs.h"
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 ntfs_index_context *ntfs_index_ctx_get(ntfs_inode *idx_ni)
0026 {
0027 ntfs_index_context *ictx;
0028
0029 ictx = kmem_cache_alloc(ntfs_index_ctx_cache, GFP_NOFS);
0030 if (ictx)
0031 *ictx = (ntfs_index_context){ .idx_ni = idx_ni };
0032 return ictx;
0033 }
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043 void ntfs_index_ctx_put(ntfs_index_context *ictx)
0044 {
0045 if (ictx->entry) {
0046 if (ictx->is_in_root) {
0047 if (ictx->actx)
0048 ntfs_attr_put_search_ctx(ictx->actx);
0049 if (ictx->base_ni)
0050 unmap_mft_record(ictx->base_ni);
0051 } else {
0052 struct page *page = ictx->page;
0053 if (page) {
0054 BUG_ON(!PageLocked(page));
0055 unlock_page(page);
0056 ntfs_unmap_page(page);
0057 }
0058 }
0059 }
0060 kmem_cache_free(ntfs_index_ctx_cache, ictx);
0061 return;
0062 }
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105 int ntfs_index_lookup(const void *key, const int key_len,
0106 ntfs_index_context *ictx)
0107 {
0108 VCN vcn, old_vcn;
0109 ntfs_inode *idx_ni = ictx->idx_ni;
0110 ntfs_volume *vol = idx_ni->vol;
0111 struct super_block *sb = vol->sb;
0112 ntfs_inode *base_ni = idx_ni->ext.base_ntfs_ino;
0113 MFT_RECORD *m;
0114 INDEX_ROOT *ir;
0115 INDEX_ENTRY *ie;
0116 INDEX_ALLOCATION *ia;
0117 u8 *index_end, *kaddr;
0118 ntfs_attr_search_ctx *actx;
0119 struct address_space *ia_mapping;
0120 struct page *page;
0121 int rc, err = 0;
0122
0123 ntfs_debug("Entering.");
0124 BUG_ON(!NInoAttr(idx_ni));
0125 BUG_ON(idx_ni->type != AT_INDEX_ALLOCATION);
0126 BUG_ON(idx_ni->nr_extents != -1);
0127 BUG_ON(!base_ni);
0128 BUG_ON(!key);
0129 BUG_ON(key_len <= 0);
0130 if (!ntfs_is_collation_rule_supported(
0131 idx_ni->itype.index.collation_rule)) {
0132 ntfs_error(sb, "Index uses unsupported collation rule 0x%x. "
0133 "Aborting lookup.", le32_to_cpu(
0134 idx_ni->itype.index.collation_rule));
0135 return -EOPNOTSUPP;
0136 }
0137
0138 m = map_mft_record(base_ni);
0139 if (IS_ERR(m)) {
0140 ntfs_error(sb, "map_mft_record() failed with error code %ld.",
0141 -PTR_ERR(m));
0142 return PTR_ERR(m);
0143 }
0144 actx = ntfs_attr_get_search_ctx(base_ni, m);
0145 if (unlikely(!actx)) {
0146 err = -ENOMEM;
0147 goto err_out;
0148 }
0149
0150 err = ntfs_attr_lookup(AT_INDEX_ROOT, idx_ni->name, idx_ni->name_len,
0151 CASE_SENSITIVE, 0, NULL, 0, actx);
0152 if (unlikely(err)) {
0153 if (err == -ENOENT) {
0154 ntfs_error(sb, "Index root attribute missing in inode "
0155 "0x%lx.", idx_ni->mft_no);
0156 err = -EIO;
0157 }
0158 goto err_out;
0159 }
0160
0161 ir = (INDEX_ROOT*)((u8*)actx->attr +
0162 le16_to_cpu(actx->attr->data.resident.value_offset));
0163 index_end = (u8*)&ir->index + le32_to_cpu(ir->index.index_length);
0164
0165 ie = (INDEX_ENTRY*)((u8*)&ir->index +
0166 le32_to_cpu(ir->index.entries_offset));
0167
0168
0169
0170
0171 for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) {
0172
0173 if ((u8*)ie < (u8*)actx->mrec || (u8*)ie +
0174 sizeof(INDEX_ENTRY_HEADER) > index_end ||
0175 (u8*)ie + le16_to_cpu(ie->length) > index_end)
0176 goto idx_err_out;
0177
0178
0179
0180
0181 if (ie->flags & INDEX_ENTRY_END)
0182 break;
0183
0184 if ((u32)sizeof(INDEX_ENTRY_HEADER) +
0185 le16_to_cpu(ie->key_length) >
0186 le16_to_cpu(ie->data.vi.data_offset) ||
0187 (u32)le16_to_cpu(ie->data.vi.data_offset) +
0188 le16_to_cpu(ie->data.vi.data_length) >
0189 le16_to_cpu(ie->length))
0190 goto idx_err_out;
0191
0192 if ((key_len == le16_to_cpu(ie->key_length)) && !memcmp(key,
0193 &ie->key, key_len)) {
0194 ir_done:
0195 ictx->is_in_root = true;
0196 ictx->ir = ir;
0197 ictx->actx = actx;
0198 ictx->base_ni = base_ni;
0199 ictx->ia = NULL;
0200 ictx->page = NULL;
0201 done:
0202 ictx->entry = ie;
0203 ictx->data = (u8*)ie +
0204 le16_to_cpu(ie->data.vi.data_offset);
0205 ictx->data_len = le16_to_cpu(ie->data.vi.data_length);
0206 ntfs_debug("Done.");
0207 return err;
0208 }
0209
0210
0211
0212
0213 rc = ntfs_collate(vol, idx_ni->itype.index.collation_rule, key,
0214 key_len, &ie->key, le16_to_cpu(ie->key_length));
0215
0216
0217
0218
0219
0220 if (rc == -1)
0221 break;
0222
0223
0224
0225
0226 if (!rc)
0227 goto ir_done;
0228
0229 }
0230
0231
0232
0233
0234
0235 if (!(ie->flags & INDEX_ENTRY_NODE)) {
0236 ntfs_debug("Entry not found.");
0237 err = -ENOENT;
0238 goto ir_done;
0239 }
0240
0241 if (!NInoIndexAllocPresent(idx_ni)) {
0242 ntfs_error(sb, "No index allocation attribute but index entry "
0243 "requires one. Inode 0x%lx is corrupt or "
0244 "driver bug.", idx_ni->mft_no);
0245 goto err_out;
0246 }
0247
0248 vcn = sle64_to_cpup((sle64*)((u8*)ie + le16_to_cpu(ie->length) - 8));
0249 ia_mapping = VFS_I(idx_ni)->i_mapping;
0250
0251
0252
0253
0254 ntfs_attr_put_search_ctx(actx);
0255 unmap_mft_record(base_ni);
0256 m = NULL;
0257 actx = NULL;
0258 descend_into_child_node:
0259
0260
0261
0262
0263
0264 page = ntfs_map_page(ia_mapping, vcn <<
0265 idx_ni->itype.index.vcn_size_bits >> PAGE_SHIFT);
0266 if (IS_ERR(page)) {
0267 ntfs_error(sb, "Failed to map index page, error %ld.",
0268 -PTR_ERR(page));
0269 err = PTR_ERR(page);
0270 goto err_out;
0271 }
0272 lock_page(page);
0273 kaddr = (u8*)page_address(page);
0274 fast_descend_into_child_node:
0275
0276 ia = (INDEX_ALLOCATION*)(kaddr + ((vcn <<
0277 idx_ni->itype.index.vcn_size_bits) & ~PAGE_MASK));
0278
0279 if ((u8*)ia < kaddr || (u8*)ia > kaddr + PAGE_SIZE) {
0280 ntfs_error(sb, "Out of bounds check failed. Corrupt inode "
0281 "0x%lx or driver bug.", idx_ni->mft_no);
0282 goto unm_err_out;
0283 }
0284
0285 if (unlikely(!ntfs_is_indx_record(ia->magic))) {
0286 ntfs_error(sb, "Index record with vcn 0x%llx is corrupt. "
0287 "Corrupt inode 0x%lx. Run chkdsk.",
0288 (long long)vcn, idx_ni->mft_no);
0289 goto unm_err_out;
0290 }
0291 if (sle64_to_cpu(ia->index_block_vcn) != vcn) {
0292 ntfs_error(sb, "Actual VCN (0x%llx) of index buffer is "
0293 "different from expected VCN (0x%llx). Inode "
0294 "0x%lx is corrupt or driver bug.",
0295 (unsigned long long)
0296 sle64_to_cpu(ia->index_block_vcn),
0297 (unsigned long long)vcn, idx_ni->mft_no);
0298 goto unm_err_out;
0299 }
0300 if (le32_to_cpu(ia->index.allocated_size) + 0x18 !=
0301 idx_ni->itype.index.block_size) {
0302 ntfs_error(sb, "Index buffer (VCN 0x%llx) of inode 0x%lx has "
0303 "a size (%u) differing from the index "
0304 "specified size (%u). Inode is corrupt or "
0305 "driver bug.", (unsigned long long)vcn,
0306 idx_ni->mft_no,
0307 le32_to_cpu(ia->index.allocated_size) + 0x18,
0308 idx_ni->itype.index.block_size);
0309 goto unm_err_out;
0310 }
0311 index_end = (u8*)ia + idx_ni->itype.index.block_size;
0312 if (index_end > kaddr + PAGE_SIZE) {
0313 ntfs_error(sb, "Index buffer (VCN 0x%llx) of inode 0x%lx "
0314 "crosses page boundary. Impossible! Cannot "
0315 "access! This is probably a bug in the "
0316 "driver.", (unsigned long long)vcn,
0317 idx_ni->mft_no);
0318 goto unm_err_out;
0319 }
0320 index_end = (u8*)&ia->index + le32_to_cpu(ia->index.index_length);
0321 if (index_end > (u8*)ia + idx_ni->itype.index.block_size) {
0322 ntfs_error(sb, "Size of index buffer (VCN 0x%llx) of inode "
0323 "0x%lx exceeds maximum size.",
0324 (unsigned long long)vcn, idx_ni->mft_no);
0325 goto unm_err_out;
0326 }
0327
0328 ie = (INDEX_ENTRY*)((u8*)&ia->index +
0329 le32_to_cpu(ia->index.entries_offset));
0330
0331
0332
0333
0334
0335 for (;; ie = (INDEX_ENTRY*)((u8*)ie + le16_to_cpu(ie->length))) {
0336
0337 if ((u8*)ie < (u8*)ia || (u8*)ie +
0338 sizeof(INDEX_ENTRY_HEADER) > index_end ||
0339 (u8*)ie + le16_to_cpu(ie->length) > index_end) {
0340 ntfs_error(sb, "Index entry out of bounds in inode "
0341 "0x%lx.", idx_ni->mft_no);
0342 goto unm_err_out;
0343 }
0344
0345
0346
0347
0348 if (ie->flags & INDEX_ENTRY_END)
0349 break;
0350
0351 if ((u32)sizeof(INDEX_ENTRY_HEADER) +
0352 le16_to_cpu(ie->key_length) >
0353 le16_to_cpu(ie->data.vi.data_offset) ||
0354 (u32)le16_to_cpu(ie->data.vi.data_offset) +
0355 le16_to_cpu(ie->data.vi.data_length) >
0356 le16_to_cpu(ie->length)) {
0357 ntfs_error(sb, "Index entry out of bounds in inode "
0358 "0x%lx.", idx_ni->mft_no);
0359 goto unm_err_out;
0360 }
0361
0362 if ((key_len == le16_to_cpu(ie->key_length)) && !memcmp(key,
0363 &ie->key, key_len)) {
0364 ia_done:
0365 ictx->is_in_root = false;
0366 ictx->actx = NULL;
0367 ictx->base_ni = NULL;
0368 ictx->ia = ia;
0369 ictx->page = page;
0370 goto done;
0371 }
0372
0373
0374
0375
0376 rc = ntfs_collate(vol, idx_ni->itype.index.collation_rule, key,
0377 key_len, &ie->key, le16_to_cpu(ie->key_length));
0378
0379
0380
0381
0382
0383 if (rc == -1)
0384 break;
0385
0386
0387
0388
0389 if (!rc)
0390 goto ia_done;
0391
0392 }
0393
0394
0395
0396
0397 if (!(ie->flags & INDEX_ENTRY_NODE)) {
0398 ntfs_debug("Entry not found.");
0399 err = -ENOENT;
0400 goto ia_done;
0401 }
0402 if ((ia->index.flags & NODE_MASK) == LEAF_NODE) {
0403 ntfs_error(sb, "Index entry with child node found in a leaf "
0404 "node in inode 0x%lx.", idx_ni->mft_no);
0405 goto unm_err_out;
0406 }
0407
0408 old_vcn = vcn;
0409 vcn = sle64_to_cpup((sle64*)((u8*)ie + le16_to_cpu(ie->length) - 8));
0410 if (vcn >= 0) {
0411
0412
0413
0414
0415 if (old_vcn << vol->cluster_size_bits >>
0416 PAGE_SHIFT == vcn <<
0417 vol->cluster_size_bits >>
0418 PAGE_SHIFT)
0419 goto fast_descend_into_child_node;
0420 unlock_page(page);
0421 ntfs_unmap_page(page);
0422 goto descend_into_child_node;
0423 }
0424 ntfs_error(sb, "Negative child node vcn in inode 0x%lx.",
0425 idx_ni->mft_no);
0426 unm_err_out:
0427 unlock_page(page);
0428 ntfs_unmap_page(page);
0429 err_out:
0430 if (!err)
0431 err = -EIO;
0432 if (actx)
0433 ntfs_attr_put_search_ctx(actx);
0434 if (m)
0435 unmap_mft_record(base_ni);
0436 return err;
0437 idx_err_out:
0438 ntfs_error(sb, "Corrupt index. Aborting lookup.");
0439 goto err_out;
0440 }