Changes by: cha0smaster
Update of /cvsroot/linux-ntfs/ntfsprogs/libntfs
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7008/libntfs
Modified Files:
attrlist.c
Log Message:
fix attribute list adding
Index: attrlist.c
===================================================================
RCS file: /cvsroot/linux-ntfs/ntfsprogs/libntfs/attrlist.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -p -r1.28 -r1.29
--- attrlist.c 22 Aug 2005 21:33:07 -0000 1.28
+++ attrlist.c 24 Sep 2005 13:03:07 -0000 1.29
@@ -99,6 +99,7 @@ int ntfs_attrlist_entry_add(ntfs_inode *
ATTR_LIST_ENTRY *ale;
MFT_REF mref;
ntfs_attr *na = NULL;
+ ntfs_attr_search_ctx *ctx;
u8 *new_al;
int entry_len, entry_offset, err;
@@ -133,41 +134,46 @@ int ntfs_attrlist_entry_add(ntfs_inode *
return -1;
}
- /* Find offset at which insert new entry. */
- ale = (ATTR_LIST_ENTRY *) ni->attr_list;
- for(; (u8 *)ale < ni->attr_list + ni->attr_list_size;
- ale = (ATTR_LIST_ENTRY *)((u8 *) ale +
- le16_to_cpu(ale->length))) {
- if (le32_to_cpu(ale->type) < le32_to_cpu(attr->type))
- continue;
- if (le32_to_cpu(ale->type) > le32_to_cpu(attr->type))
- break;
- err = ntfs_names_collate(ale->name, ale->name_length,
- (ntfschar*)((u8*)attr + le16_to_cpu(attr->name_offset)),
- attr->name_length, -2, CASE_SENSITIVE, NULL, 0);
- if (err == -2) {
- err = EIO;
- Dprintf("%s(): Corrupt attribute name. Run chkdsk.\n",
- __FUNCTION__);
+ /* Find place for the new entry. */
+ ctx = ntfs_attr_get_search_ctx(ni, NULL);
+ if (!ctx) {
+ err = errno;
+ Dprintf("%s(): Failed to obtain attribute search context.\n",
+ __FUNCTION__);
+ goto err_out;
+ }
+ if (!ntfs_attr_lookup(attr->type, (attr->name_length) ? (ntfschar*)
+ ((u8*)attr + le16_to_cpu(attr->name_offset)) :
+ AT_UNNAMED, attr->name_length, CASE_SENSITIVE,
+ (attr->non_resident) ? le64_to_cpu(attr->lowest_vcn) :
+ 0, (attr->non_resident) ? NULL : ((u8*)attr +
+ le16_to_cpu(attr->value_offset)), (attr->non_resident) ?
+ 0 : le32_to_cpu(attr->value_length), ctx)) {
+ /* Found some extent, check it to be before new extent. */
+ if (ctx->al_entry->lowest_vcn == attr->lowest_vcn) {
+ err = EEXIST;
+ Dprintf("%s(): Such attribute already present in the "
+ "attribute list.\n", __FUNCTION__);
+ ntfs_attr_put_search_ctx(ctx);
goto err_out;
}
- if (err < 0)
- continue;
- if (err > 0)
- break;
- if (sle64_to_cpu(ale->lowest_vcn) <
- sle64_to_cpu(attr->lowest_vcn))
- continue;
- if (sle64_to_cpu(ale->lowest_vcn) ==
- sle64_to_cpu(attr->lowest_vcn)) {
- err = EEXIST;
- Dprintf("%s(): Attribute with same type, name and "
- "lowest vcn already present in attribute "
- "list.\n", __FUNCTION__);
+ /* Add new entry after this extent. */
+ ale = (ATTR_LIST_ENTRY*)((u8*)ctx->al_entry +
+ le16_to_cpu(ctx->al_entry->length));
+ } else {
+ /* Check for real errors. */
+ if (errno != ENOENT) {
+ err = errno;
+ Dprintf("%s(): Attribute lookup failed.\n",
+ __FUNCTION__);
+ ntfs_attr_put_search_ctx(ctx);
goto err_out;
}
- break;
+ /* No previous extents found. */
+ ale = ctx->al_entry;
}
+ /* Don't need it anymore, @ctx->al_entry points to @ni->attr_list. */
+ ntfs_attr_put_search_ctx(ctx);
/* Determine new entry offset. */
entry_offset = ((u8 *)ale - ni->attr_list);
|