Improve ntfs_resident_attr_resize to try make attributes non-resident

when such convert is reasonable.

(Logical change 1.596)
edge.strict_endians
(none)!yura 2004-10-08 16:50:36 +00:00
parent 100b892e5b
commit 1b5c000662
1 changed files with 54 additions and 7 deletions

View File

@ -3105,7 +3105,6 @@ static int ntfs_resident_attr_resize(ntfs_attr *na, const s64 newsize)
if (ntfs_attr_size_bounds_check(vol, na->type, newsize) < 0) {
err = errno;
if (err == ERANGE) {
// FIXME: Eeek!
Dprintf("%s(): Eeek! Size bounds check failed. "
"Aborting...\n", __FUNCTION__);
} else if (err == ENOENT)
@ -3131,7 +3130,6 @@ static int ntfs_resident_attr_resize(ntfs_attr *na, const s64 newsize)
/* Error! If not enough space, just continue. */
if (errno != ENOSPC) {
err = errno;
// FIXME: Eeek!
if (err != ENOTSUP)
Dprintf("%s(): Eeek! Failed to resize "
"resident part of attribute. "
@ -3144,7 +3142,7 @@ static int ntfs_resident_attr_resize(ntfs_attr *na, const s64 newsize)
/* Make the attribute non-resident if possible. */
if (!ntfs_attr_make_non_resident(na, ctx)) {
/* Resize non-resident attribute */
if (ntfs_attr_truncate (na, newsize)) {
if (ntfs_attr_truncate(na, newsize)) {
/*
* Resize failed, but mark inode dirty because we made
* it non-resident.
@ -3156,16 +3154,56 @@ static int ntfs_resident_attr_resize(ntfs_attr *na, const s64 newsize)
goto resize_done;
} else if (errno != ENOSPC && errno != EPERM) {
err = errno;
// FIXME: Eeek!
Dprintf("%s(): Eeek! Failed to make attribute non-resident. "
"Aborting...\n", __FUNCTION__);
goto put_err_out;
}
// TODO: Try to make other attributes non-resident and retry each time.
/* Try to make other attributes non-resident and retry each time. */
ntfs_attr_init_search_ctx(ctx, 0, na->ni->mrec);
while (!ntfs_attr_lookup(AT_UNUSED, NULL, 0, 0, 0, NULL, 0, ctx)) {
ntfs_attr *tna;
ATTR_RECORD *a;
a = ctx->attr;
if (a->non_resident)
continue;
if (na->type == AT_ATTRIBUTE_LIST) {
/*
* Check out whether convert is reasonable. Assume that mapping
* pairs will take 8 bytes.
*/
if (le32_to_cpu(a->length) <= offsetof(ATTR_RECORD,
compressed_size) + ((a->name_length *
sizeof(ntfschar) + 7) & ~7) + 8)
continue;
tna = ntfs_attr_open(na->ni, a->type, (ntfschar*)((u8*)a +
le16_to_cpu(a->name_offset)), a->name_length);
if (!tna) {
err = errno;
Dprintf("%s(): Couldn't open attribute.\n",
__FUNCTION__);
goto put_err_out;
}
if (ntfs_attr_make_non_resident(tna, ctx)) {
ntfs_attr_close(tna);
continue;
}
ntfs_attr_close(tna);
ntfs_attr_put_search_ctx(ctx);
return ntfs_resident_attr_resize(na, newsize);
}
/* Check whether error occured. */
if (errno != ENOENT) {
err = errno;
Dprintf("%s(): Attribute lookup failed.\n", __FUNCTION__);
goto put_err_out;
}
/* We can't move out attribute list. */
if (na->type == AT_ATTRIBUTE_LIST) {
err = ENOSPC;
goto put_err_out;
}
@ -3174,6 +3212,15 @@ static int ntfs_resident_attr_resize(ntfs_attr *na, const s64 newsize)
* attribute or modifying it if it is already present.
*/
/* Point search context back to attribute which we need resize. */
ntfs_attr_init_search_ctx(ctx, na->ni, 0);
if (ntfs_attr_lookup(na->type, na->name, na->name_len, 0, 0, NULL, 0,
ctx)) {
Dprintf("%s(): Attribute lookup failed.\n", __FUNCTION__);
err = errno;
goto put_err_out;
}
/* Add attribute list if not present. */
if (na->ni->nr_extents == -1)
ni = na->ni->base_ni;
@ -3596,7 +3643,7 @@ int ntfs_attr_update_mapping_pairs(ntfs_attr *na)
}
a->highest_vcn = cpu_to_sle64(stop_vcn - 1);
}
/* Check wether error occured. */
/* Check whether error occured. */
if (errno != ENOENT) {
err = errno;
Dprintf("%s(): Attribute lookup failed.\n", __FUNCTION__);