Remove the FIXME in ntfs_attr_lookup() and complete the
implementation of ntfs_external_attr_find() so it now returns the attribute list attribute position at which the attribute should be inserted in @ctx->al_entry (see descritpion for ntfs_attr_lookup() in attrib.c for details). (Logical change 1.343)edge.strict_endians
parent
8f77300f3a
commit
b1f8254930
115
libntfs/attrib.c
115
libntfs/attrib.c
|
@ -1493,9 +1493,10 @@ static int ntfs_attr_find(const ATTR_TYPES type, const uchar_t *name,
|
|||
* attribute described by the attribute list of the base mft record described
|
||||
* by the search context @ctx.
|
||||
*
|
||||
* If @type is AT_END, seek to the end and return -1 with errno set to ENOENT.
|
||||
* AT_END is not a valid attribute, its length is zero for example, thus it is
|
||||
* safer to return error instead of success in this case.
|
||||
* If @type is AT_END, seek to the end of the base mft record ignoring the
|
||||
* attribute list completely and return -1 with errno set to ENOENT. AT_END is
|
||||
* not a valid attribute, its length is zero for example, thus it is safer to
|
||||
* return error instead of success in this case.
|
||||
*
|
||||
* If @name is AT_UNNAMED search for an unnamed attribute. If @name is present
|
||||
* but not AT_UNNAMED search for a named attribute matching @name. Otherwise,
|
||||
|
@ -1513,19 +1514,21 @@ static int ntfs_attr_find(const ATTR_TYPES type, const uchar_t *name,
|
|||
* Return 0 if the search was successful and -1 if not, with errno set to the
|
||||
* error code.
|
||||
*
|
||||
* On success, @ctx->attr is the found attribute and it is in mft record
|
||||
* @ctx->mrec.
|
||||
* On success, @ctx->attr is the found attribute, it is in mft record
|
||||
* @ctx->mrec, and @ctx->al_entry is the attribute list entry for this
|
||||
* attribute with @ctx->base_* being the base mft record to which @ctx->attr
|
||||
* belongs.
|
||||
*
|
||||
* On error, @ctx->attr is the attribute which collates just after the attribute
|
||||
* being searched for in the base ntfs inode, i.e. if one wants to add the
|
||||
* attribute to the mft record this is the correct place to insert it into,
|
||||
* and if there is not enough space, the attribute should be placed in an
|
||||
* extent mft record. @ctx->al_entry points to the position within
|
||||
* @ctx->base_ntfs_ino->attr_list at which the new attribute's attribute list
|
||||
* entry should be inserted.
|
||||
*
|
||||
* FIXME: This is how it should be but unfortunately the current code sets
|
||||
* @ctx->al_entry to NULL, so beware! (AIA)
|
||||
* On error ENOENT, i.e. attribute not found, @ctx->attr is set to the
|
||||
* attribute which collates just after the attribute being searched for in the
|
||||
* base ntfs inode, i.e. if one wants to add the attribute to the mft record
|
||||
* this is the correct place to insert it into, and if there is not enough
|
||||
* space, the attribute should be placed in an extent mft record.
|
||||
* @ctx->al_entry points to the position within @ctx->base_ntfs_ino->attr_list
|
||||
* at which the new attribute's attribute list entry should be inserted. The
|
||||
* other @ctx fields, base_ntfs_ino, base_mrec, and base_attr are set to NULL.
|
||||
* The only exception to this is when @type is AT_END, in which case
|
||||
* @ctx->al_entry is set to NULL also (see above).
|
||||
*
|
||||
* The following error codes are defined:
|
||||
* ENOENT Attribute not found, not an error as such.
|
||||
|
@ -1555,11 +1558,10 @@ static int ntfs_external_attr_find(ATTR_TYPES type, const uchar_t *name,
|
|||
/* First call happens with the base mft record. */
|
||||
base_ni = ctx->base_ntfs_ino = ctx->ntfs_ino;
|
||||
ctx->base_mrec = ctx->mrec;
|
||||
ctx->base_attr = ctx->attr;
|
||||
}
|
||||
if (type == AT_END)
|
||||
goto not_found;
|
||||
if (ni == base_ni)
|
||||
ctx->base_attr = ctx->attr;
|
||||
vol = base_ni->vol;
|
||||
al_start = base_ni->attr_list;
|
||||
al_end = al_start + base_ni->attr_list_size;
|
||||
|
@ -1831,21 +1833,36 @@ do_next_attr:
|
|||
return -1;
|
||||
not_found:
|
||||
/*
|
||||
* The attribute wasn't found. Before we return, we want to ensure
|
||||
* ctx->mrec and ctx->attr indicate the position at which the attribute
|
||||
* should be inserted in the base mft record.
|
||||
* If we were looking for AT_END or we were enumerating and reached the
|
||||
* end, we reset the search context @ctx and use ntfs_attr_find() to
|
||||
* seek to the end of the base mft record.
|
||||
*/
|
||||
/* Rewind the current search so ntfs_attr_find() is happy. */
|
||||
ntfs_attr_reinit_search_ctx(ctx);
|
||||
/*
|
||||
* If we were enumerating and reached the end, we can't just use @type
|
||||
* because that would return the first attribute instead of the last
|
||||
* one. Thus we just use AT_END which causes ntfs_attr_find() to seek
|
||||
* to the end.
|
||||
*/
|
||||
if (type == AT_UNUSED)
|
||||
if (type == AT_UNUSED || type == AT_END) {
|
||||
ntfs_attr_reinit_search_ctx(ctx);
|
||||
return ntfs_attr_find(AT_END, name, name_len, ic, val, val_len,
|
||||
ctx);
|
||||
}
|
||||
/*
|
||||
* The attribute wasn't found. Before we return, we want to ensure
|
||||
* @ctx->mrec and @ctx->attr indicate the position at which the
|
||||
* attribute should be inserted in the base mft record. Since we also
|
||||
* want to preserve @ctx->al_entry we cannot reinitialize the search
|
||||
* context using ntfs_attr_reinit_search_ctx() as this would set
|
||||
* @ctx->al_entry to NULL. Thus we do the necessary bits manually (see
|
||||
* ntfs_attr_init_search_ctx() below). Note, we _only_ preserve
|
||||
* @ctx->al_entry as the remaining fields (base_*) are identical to
|
||||
* their non base_ counterparts and we cannot set @ctx->base_attr
|
||||
* correctly yet as we do not know what @ctx->attr will be set to by
|
||||
* the call to ntfs_attr_find() below.
|
||||
*/
|
||||
ctx->mrec = ctx->base_mrec;
|
||||
ctx->attr = (ATTR_RECORD*)((u8*)ctx->mrec +
|
||||
le16_to_cpu(ctx->mrec->attrs_offset));
|
||||
ctx->is_first = TRUE;
|
||||
ctx->ntfs_ino = ctx->base_ntfs_ino;
|
||||
ctx->base_ntfs_ino = NULL;
|
||||
ctx->base_mrec = NULL;
|
||||
ctx->base_attr = NULL;
|
||||
/*
|
||||
* In case there are multiple matches in the base mft record, need to
|
||||
* keep enumerating until we get an attribute not found response (or
|
||||
|
@ -1889,11 +1906,12 @@ not_found:
|
|||
* successful call of ntfs_attr_lookup() will return the next attribute, with
|
||||
* the current attribute being described by the search context @ctx.
|
||||
*
|
||||
* If @type is AT_END, seek to the end of the attribute and return -1 with
|
||||
* errno set to ENOENT. AT_END is not a valid attribute, its length is zero for
|
||||
* example, thus it is safer to return error instead of success in this case.
|
||||
* It should never ne needed to do this, but we implement the functionality
|
||||
* because it allows for simpler code inside ntfs_external_attr_find().
|
||||
* If @type is AT_END, seek to the end of the base mft record ignoring the
|
||||
* attribute list completely and return -1 with errno set to ENOENT. AT_END is
|
||||
* not a valid attribute, its length is zero for example, thus it is safer to
|
||||
* return error instead of success in this case. It should never ne needed to
|
||||
* do this, but we implement the functionality because it allows for simpler
|
||||
* code inside ntfs_external_attr_find().
|
||||
*
|
||||
* If @name is AT_UNNAMED search for an unnamed attribute. If @name is present
|
||||
* but not AT_UNNAMED search for a named attribute matching @name. Otherwise,
|
||||
|
@ -1906,17 +1924,23 @@ not_found:
|
|||
* Return 0 if the search was successful and -1 if not, with errno set to the
|
||||
* error code.
|
||||
*
|
||||
* On success, @ctx->attr is the found attribute and it is in mft record
|
||||
* @ctx->mrec.
|
||||
* On success, @ctx->attr is the found attribute, it is in mft record
|
||||
* @ctx->mrec, and @ctx->al_entry is the attribute list entry for this
|
||||
* attribute with @ctx->base_* being the base mft record to which @ctx->attr
|
||||
* belongs. If no attribute list attribute is present @ctx->al_entry and
|
||||
* @ctx->base_* are NULL.
|
||||
*
|
||||
* On error, @ctx->attr is the attribute which collates just after the attribute
|
||||
* being searched for, i.e. if one wants to add the attribute to the mft
|
||||
* record this is the correct place to insert it into. @ctx->al_entry points to
|
||||
* the position within @ctx->base_ntfs_ino->attr_list at which the new
|
||||
* attribute's attribute list entry should be inserted.
|
||||
* On error ENOENT, i.e. attribute not found, @ctx->attr is set to the
|
||||
* attribute which collates just after the attribute being searched for in the
|
||||
* base ntfs inode, i.e. if one wants to add the attribute to the mft record
|
||||
* this is the correct place to insert it into, and if there is not enough
|
||||
* space, the attribute should be placed in an extent mft record.
|
||||
* @ctx->al_entry points to the position within @ctx->base_ntfs_ino->attr_list
|
||||
* at which the new attribute's attribute list entry should be inserted. The
|
||||
* other @ctx fields, base_ntfs_ino, base_mrec, and base_attr are set to NULL.
|
||||
* The only exception to this is when @type is AT_END, in which case
|
||||
* @ctx->al_entry is set to NULL also (see above).
|
||||
*
|
||||
* FIXME: This is how it should be but unfortunately the current code sets
|
||||
* @ctx->al_entry to NULL, so beware! (AIA)
|
||||
*
|
||||
* The following error codes are defined:
|
||||
* ENOENT Attribute not found, not an error as such.
|
||||
|
@ -1963,8 +1987,7 @@ static __inline__ void ntfs_attr_init_search_ctx(ntfs_attr_search_ctx *ctx,
|
|||
mrec = ni->mrec;
|
||||
ctx->mrec = mrec;
|
||||
/* Sanity checks are performed elsewhere. */
|
||||
ctx->attr = (ATTR_RECORD*)((char*)mrec +
|
||||
le16_to_cpu(mrec->attrs_offset));
|
||||
ctx->attr = (ATTR_RECORD*)((u8*)mrec + le16_to_cpu(mrec->attrs_offset));
|
||||
ctx->is_first = TRUE;
|
||||
ctx->ntfs_ino = ni;
|
||||
ctx->al_entry = NULL;
|
||||
|
@ -1988,7 +2011,7 @@ void ntfs_attr_reinit_search_ctx(ntfs_attr_search_ctx *ctx)
|
|||
/* No attribute list. */
|
||||
ctx->is_first = TRUE;
|
||||
/* Sanity checks are performed elsewhere. */
|
||||
ctx->attr = (ATTR_RECORD*)((char*)ctx->mrec +
|
||||
ctx->attr = (ATTR_RECORD*)((u8*)ctx->mrec +
|
||||
le16_to_cpu(ctx->mrec->attrs_offset));
|
||||
return;
|
||||
} /* Attribute list. */
|
||||
|
|
Loading…
Reference in New Issue