Implemented a function giving next entry in an index


			
			
				N2009_11_14_FIXES
			
			
		
jpandre 2007-10-12 12:54:49 +00:00
parent 5c1d979b88
commit 91a4873a23
1 changed files with 155 additions and 4 deletions

View File

@ -240,8 +240,7 @@ static INDEX_ENTRY *ntfs_ie_get_last(INDEX_ENTRY *ie, char *ies_end)
return ie;
}
/* static JPA removed for use in security.c */
INDEX_ENTRY *ntfs_ie_get_by_pos(INDEX_HEADER *ih, int pos)
static INDEX_ENTRY *ntfs_ie_get_by_pos(INDEX_HEADER *ih, int pos)
{
INDEX_ENTRY *ie;
@ -425,8 +424,7 @@ static int ntfs_ia_check(ntfs_index_context *icx, INDEX_BLOCK *ib, VCN vcn)
return 0;
}
/* static JPA removed for use in security.c */
INDEX_ROOT *ntfs_ir_lookup(ntfs_inode *ni, ntfschar *name,
static INDEX_ROOT *ntfs_ir_lookup(ntfs_inode *ni, ntfschar *name,
u32 name_len, ntfs_attr_search_ctx **ctx)
{
ATTR_RECORD *a;
@ -1869,3 +1867,156 @@ out:
}
/*
* Walk down the index tree (leaf bound)
* until there are no subnode in the first index entry
* returns the entry at the bottom left in subnode
*/
static INDEX_ENTRY *ntfs_index_walk_down(INDEX_ENTRY *ie,
ntfs_index_context *ictx)
{
INDEX_ENTRY *entry;
s64 vcn;
entry = ie;
do {
vcn = ntfs_ie_get_vcn(entry);
if (ictx->is_in_root) {
/* down from level zero */
free(ictx->ir);
ictx->ir = (INDEX_ROOT*)NULL;
ictx->ib = (INDEX_BLOCK*)ntfs_malloc(ictx->block_size);
ictx->pindex = 1;
ictx->is_in_root = FALSE;
} else {
/* down from non-zero level */
ictx->pindex++;
}
ictx->parent_pos[ictx->pindex] = 0;
ictx->parent_vcn[ictx->pindex] = vcn;
if (!ntfs_ib_read(ictx,vcn,ictx->ib)) {
ictx->entry = ntfs_ie_get_first(&ictx->ib->index);
entry = ictx->entry;
} else
entry = (INDEX_ENTRY*)NULL;
} while (entry && (entry->ie_flags & INDEX_ENTRY_NODE));
return (entry);
}
/*
* Walk up the index tree (root bound)
* until there is a valid data entry in parent
* returns the parent entry or NULL if no more parent
*/
static INDEX_ENTRY *ntfs_index_walk_up(INDEX_ENTRY *ie,
ntfs_index_context *ictx)
{
INDEX_ENTRY *entry;
s64 vcn;
entry = ie;
if (ictx->pindex > 0) {
do {
ictx->pindex--;
if (!ictx->pindex) {
/* we have reached the root */
free(ictx->ib);
ictx->ib = (INDEX_BLOCK*)NULL;
ictx->is_in_root = TRUE;
/* a new search context is to be allocated */
if (ictx->actx)
free(ictx->actx);
ictx->ir = ntfs_ir_lookup(ictx->ni,
ictx->name, ictx->name_len,
&ictx->actx);
if (ictx->ir)
entry = ntfs_ie_get_by_pos(
&ictx->ir->index,
ictx->parent_pos[ictx->pindex]);
else
entry = (INDEX_ENTRY*)NULL;
} else {
/* up into non-root node */
vcn = ictx->parent_vcn[ictx->pindex];
if (!ntfs_ib_read(ictx,vcn,ictx->ib)) {
entry = ntfs_ie_get_by_pos(
&ictx->ib->index,
ictx->parent_pos[ictx->pindex]);
} else
entry = (INDEX_ENTRY*)NULL;
}
ictx->entry = entry;
} while (entry && (ictx->pindex > 0)
&& (entry->ie_flags & INDEX_ENTRY_END));
} else
entry = (INDEX_ENTRY*)NULL;
return (entry);
}
/*
* Get next entry in an index according to collating sequence.
* Must be initialized through a ntfs_index_lookup()
*
* Returns next entry or NULL if none
*
* Sample layout :
*
* +---+---+---+---+---+---+---+---+ n ptrs to subnodes
* | | | 10| 25| 33| | | | n-1 keys in between
* +---+---+---+---+---+---+---+---+ no key in last entry
* | A | A
* | | | +-------------------------------+
* +--------------------------+ | +-----+ |
* | +--+ | |
* V | V |
* +---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+
* | 11| 12| 13| 14| 15| 16| 17| | | | 26| 27| 28| 29| 30| 31| 32| |
* +---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+
* | |
* +-----------------------+ |
* | |
* +---+---+---+---+---+---+---+---+
* | 18| 19| 20| 21| 22| 23| 24| |
* +---+---+---+---+---+---+---+---+
*/
INDEX_ENTRY *ntfs_index_next(INDEX_ENTRY *ie, ntfs_index_context *ictx)
{
INDEX_ENTRY *next;
int flags;
/* get next entry in same node */
/* there is always one after any entry with data */
next = (INDEX_ENTRY*)((char*)ie + le16_to_cpu(ie->length));
++ictx->parent_pos[ictx->pindex];
flags = next->ie_flags;
/* walk down if it has a subnode */
if (flags & INDEX_ENTRY_NODE) {
next = ntfs_index_walk_down(next,ictx);
} else {
/* walk up it has no subnode, nor data */
if (flags & INDEX_ENTRY_END) {
next = ntfs_index_walk_up(next, ictx);
}
}
/* return NULL if stuck at end of a block */
if (next && (next->ie_flags & INDEX_ENTRY_END))
next = (INDEX_ENTRY*)NULL;
return (next);
}