Пример #1
0
int __hfs_brec_find(struct hfs_bnode *bnode, struct hfs_find_data *fd)
{
	int cmpval;
	u16 off, len, keylen;
	int rec;
	int b, e;
	int res;

	b = 0;
	e = bnode->num_recs - 1;
	res = -ENOENT;
	do {
		rec = (e + b) / 2;
		len = hfs_brec_lenoff(bnode, rec, &off);
		keylen = hfs_brec_keylen(bnode, rec);
		if (keylen == 0) {
			res = -EINVAL;
			goto fail;
		}
		hfs_bnode_read(bnode, fd->key, off, keylen);
		cmpval = bnode->tree->keycmp(fd->key, fd->search_key);
		if (!cmpval) {
			e = rec;
			res = 0;
			goto done;
		}
		if (cmpval < 0)
			b = rec + 1;
		else
			e = rec - 1;
	} while (b <= e);
	if (rec != e && e >= 0) {
		len = hfs_brec_lenoff(bnode, e, &off);
		keylen = hfs_brec_keylen(bnode, e);
		if (keylen == 0) {
			res = -EINVAL;
			goto fail;
		}
		hfs_bnode_read(bnode, fd->key, off, keylen);
	}
done:
	fd->record = e;
	fd->keyoffset = off;
	fd->keylength = keylen;
	fd->entryoffset = off + keylen;
	fd->entrylength = len - keylen;
fail:
	return res;
}
Пример #2
0
/* Find the record in bnode that best matches key (not greater than...)*/
int __hfs_brec_find(struct hfs_bnode *bnode, struct hfs_find_data *fd,
					search_strategy_t rec_found)
{
	u16 off, len, keylen;
	int rec;
	int b, e;
	int res;

	if (!rec_found)
		BUG();

	b = 0;
	e = bnode->num_recs - 1;
	res = -ENOENT;
	do {
		rec = (e + b) / 2;
		len = hfs_brec_lenoff(bnode, rec, &off);
		keylen = hfs_brec_keylen(bnode, rec);
		if (keylen == 0) {
			res = -EINVAL;
			goto fail;
		}
		hfs_bnode_read(bnode, fd->key, off, keylen);
		if (rec_found(bnode, fd, &b, &e, &rec)) {
			res = 0;
			goto done;
		}
	} while (b <= e);

	if (rec != e && e >= 0) {
		len = hfs_brec_lenoff(bnode, e, &off);
		keylen = hfs_brec_keylen(bnode, e);
		if (keylen == 0) {
			res = -EINVAL;
			goto fail;
		}
		hfs_bnode_read(bnode, fd->key, off, keylen);
	}

done:
	fd->record = e;
	fd->keyoffset = off;
	fd->keylength = keylen;
	fd->entryoffset = off + keylen;
	fd->entrylength = len - keylen;

fail:
	return res;
}
Пример #3
0
int hfs_brec_goto(struct hfs_find_data *fd, int cnt)
{
    struct hfs_btree *tree;
    struct hfs_bnode *bnode;
    int idx, res = 0;
    u16 off, len, keylen;

    bnode = fd->bnode;
    tree = bnode->tree;

    if (cnt < 0) {
        cnt = -cnt;
        while (cnt > fd->record) {
            cnt -= fd->record + 1;
            fd->record = bnode->num_recs - 1;
            idx = bnode->prev;
            if (!idx) {
                res = -ENOENT;
                goto out;
            }
            hfs_bnode_put(bnode);
            bnode = hfs_bnode_find(tree, idx);
            if (IS_ERR(bnode)) {
                res = PTR_ERR(bnode);
                bnode = NULL;
                goto out;
            }
        }
        fd->record -= cnt;
    } else {
        while (cnt >= bnode->num_recs - fd->record) {
            cnt -= bnode->num_recs - fd->record;
            fd->record = 0;
            idx = bnode->next;
            if (!idx) {
                res = -ENOENT;
                goto out;
            }
            hfs_bnode_put(bnode);
            bnode = hfs_bnode_find(tree, idx);
            if (IS_ERR(bnode)) {
                res = PTR_ERR(bnode);
                bnode = NULL;
                goto out;
            }
        }
        fd->record += cnt;
    }

    len = hfs_brec_lenoff(bnode, fd->record, &off);
    keylen = hfs_brec_keylen(bnode, fd->record);
    fd->keyoffset = off;
    fd->keylength = keylen;
    fd->entryoffset = off + keylen;
    fd->entrylength = len - keylen;
    hfs_bnode_read(bnode, fd->key, off, keylen);
out:
    fd->bnode = bnode;
    return res;
}