*/
static struct NTFS_DE *hdr_find_e(const struct ntfs_index *indx,
const struct INDEX_HDR *hdr, const void *key,
- size_t key_len, const void *ctx, int *diff)
+ size_t key_len, const void *ctx, int *diff,
+ NTFS_CMP_FUNC cmp)
{
struct NTFS_DE *e, *found = NULL;
- NTFS_CMP_FUNC cmp = indx->cmp;
int min_idx = 0, mid_idx, max_idx = 0;
int diff2;
int table_size = 8;
u32 total = le32_to_cpu(hdr->total);
u16 offs[128];
- if (unlikely(!cmp))
- return NULL;
-
fill_table:
if (end > total)
return NULL;
static struct NTFS_DE *hdr_insert_de(const struct ntfs_index *indx,
struct INDEX_HDR *hdr,
const struct NTFS_DE *de,
- struct NTFS_DE *before, const void *ctx)
+ struct NTFS_DE *before, const void *ctx,
+ NTFS_CMP_FUNC cmp)
{
int diff;
size_t off = PtrOffset(hdr, before);
}
/* No insert point is applied. Get it manually. */
before = hdr_find_e(indx, hdr, de + 1, le16_to_cpu(de->key_size), ctx,
- &diff);
+ &diff, cmp);
if (!before)
return NULL;
off = PtrOffset(hdr, before);
init_rwsem(&indx->run_lock);
- indx->cmp = get_cmp_func(root);
- if (!indx->cmp)
- goto out;
-
return 0;
out:
int err;
struct NTFS_DE *e;
struct indx_node *node;
+ NTFS_CMP_FUNC cmp;
if (!root)
root = indx_get_root(&ni->dir, ni, NULL, NULL);
return -EINVAL;
}
+ cmp = get_cmp_func(root);
+ if (unlikely(!cmp)) {
+ WARN_ON_ONCE(1);
+ return -EINVAL;
+ }
+
/* Check cache. */
e = fnd->level ? fnd->de[fnd->level - 1] : fnd->root_de;
if (e && !de_is_last(e) &&
- !(*indx->cmp)(key, key_len, e + 1, le16_to_cpu(e->key_size), ctx)) {
+ !(*cmp)(key, key_len, e + 1, le16_to_cpu(e->key_size), ctx)) {
*entry = e;
*diff = 0;
return 0;
fnd_clear(fnd);
/* Lookup entry that is <= to the search value. */
- e = hdr_find_e(indx, &root->ihdr, key, key_len, ctx, diff);
+ e = hdr_find_e(indx, &root->ihdr, key, key_len, ctx, diff, cmp);
if (!e)
return -EINVAL;
/* Lookup entry that is <= to the search value. */
e = hdr_find_e(indx, &node->index->ihdr, key, key_len, ctx,
- diff);
+ diff, cmp);
if (!e) {
put_indx_node(node);
return -EINVAL;
static int indx_insert_into_root(struct ntfs_index *indx, struct ntfs_inode *ni,
const struct NTFS_DE *new_de,
struct NTFS_DE *root_de, const void *ctx,
- struct ntfs_fnd *fnd, bool undo)
+ struct ntfs_fnd *fnd, bool undo, NTFS_CMP_FUNC cmp)
{
int err = 0;
struct NTFS_DE *e, *e0, *re;
if ((undo || asize + ds_root < sbi->max_bytes_per_attr) &&
mi_resize_attr(mi, attr, ds_root)) {
hdr->total = cpu_to_le32(hdr_total + ds_root);
- e = hdr_insert_de(indx, hdr, new_de, root_de, ctx);
+ e = hdr_insert_de(indx, hdr, new_de, root_de, ctx, cmp);
WARN_ON(!e);
fnd_clear(fnd);
fnd->root_de = e;
* Now root is a parent for new index buffer.
* Insert NewEntry a new buffer.
*/
- e = hdr_insert_de(indx, hdr, new_de, NULL, ctx);
+ e = hdr_insert_de(indx, hdr, new_de, NULL, ctx, cmp);
if (!e) {
err = -EINVAL;
goto out_put_n;
static int
indx_insert_into_buffer(struct ntfs_index *indx, struct ntfs_inode *ni,
struct INDEX_ROOT *root, const struct NTFS_DE *new_de,
- const void *ctx, int level, struct ntfs_fnd *fnd)
+ const void *ctx, int level, struct ntfs_fnd *fnd, NTFS_CMP_FUNC cmp)
{
int err;
const struct NTFS_DE *sp;
/* Try the most easy case. */
e = fnd->level - 1 == level ? fnd->de[level] : NULL;
- e = hdr_insert_de(indx, hdr1, new_de, e, ctx);
+ e = hdr_insert_de(indx, hdr1, new_de, e, ctx, cmp);
fnd->de[level] = e;
if (e) {
/* Just write updated index into disk. */
* (depending on sp <=> new_de).
*/
hdr_insert_de(indx,
- (*indx->cmp)(new_de + 1, le16_to_cpu(new_de->key_size),
+ (*cmp)(new_de + 1, le16_to_cpu(new_de->key_size),
up_e + 1, le16_to_cpu(up_e->key_size),
ctx) < 0 ?
hdr2 :
hdr1,
- new_de, NULL, ctx);
+ new_de, NULL, ctx, cmp);
indx_mark_used(indx, ni, new_vbn >> indx->idx2vbn_bits);
*/
if (!level) {
/* Insert in root. */
- err = indx_insert_into_root(indx, ni, up_e, NULL, ctx, fnd, 0);
+ err = indx_insert_into_root(indx, ni, up_e, NULL, ctx, fnd, 0, cmp);
} else {
/*
* The target buffer's parent is another index buffer.
* TODO: Remove recursion.
*/
err = indx_insert_into_buffer(indx, ni, root, up_e, ctx,
- level - 1, fnd);
+ level - 1, fnd, cmp);
}
if (err) {
struct NTFS_DE *e;
struct ntfs_fnd *fnd_a = NULL;
struct INDEX_ROOT *root;
+ NTFS_CMP_FUNC cmp;
if (!fnd) {
fnd_a = fnd_get();
goto out;
}
+ cmp = get_cmp_func(root);
+ if (unlikely(!cmp)) {
+ WARN_ON_ONCE(1);
+ return -EINVAL;
+ }
+
if (fnd_is_empty(fnd)) {
/*
* Find the spot the tree where we want to
* new entry into it.
*/
err = indx_insert_into_root(indx, ni, new_de, fnd->root_de, ctx,
- fnd, undo);
+ fnd, undo, cmp);
} else {
/*
* Found a leaf buffer, so we'll insert the new entry into it.
*/
err = indx_insert_into_buffer(indx, ni, root, new_de, ctx,
- fnd->level - 1, fnd);
+ fnd->level - 1, fnd, cmp);
}
indx->version += 1;
u32 e_size, root_size, new_root_size;
size_t trim_bit;
const struct INDEX_NAMES *in;
+ NTFS_CMP_FUNC cmp;
fnd = fnd_get();
if (!fnd) {
goto out;
}
+ cmp = get_cmp_func(root);
+ if (unlikely(!cmp)) {
+ WARN_ON_ONCE(1);
+ return -EINVAL;
+ }
+
/* Locate the entry to remove. */
err = indx_find(indx, ni, root, key, key_len, ctx, &diff, &e, fnd);
if (err)
err = level ? indx_insert_into_buffer(indx, ni, root,
re, ctx,
fnd->level - 1,
- fnd) :
+ fnd, cmp) :
indx_insert_into_root(indx, ni, re, e,
- ctx, fnd, 0);
+ ctx, fnd, 0, cmp);
kfree(re);
if (err)
struct INDEX_ROOT *root;
struct mft_inode *mi;
struct ntfs_index *indx = &ni->dir;
+ NTFS_CMP_FUNC cmp;
fnd = fnd_get();
if (!fnd)
goto out;
}
+ cmp = get_cmp_func(root);
+ if (unlikely(!cmp)) {
+ WARN_ON_ONCE(1);
+ return -EINVAL;
+ }
+
/* Find entry in directory. */
err = indx_find(indx, ni, root, fname, fname_full_size(fname), sbi,
&diff, &e, fnd);