Fixed expanding a resident attribute without inserting holes

When calling ntfstruncate() to expand a resident attribute, the function
is called again recursively, losing the requirement for not inserting
holes. This is for forwarding the requirement (used by ntfscp).
edge.strict_endians
Jean-Pierre André 2013-09-09 15:27:38 +02:00
parent 1f7fd0160f
commit 89af38f687
2 changed files with 13 additions and 12 deletions

View File

@ -61,7 +61,8 @@ typedef enum {
typedef enum { /* ways of processing holes when expanding */
HOLES_NO,
HOLES_OK,
HOLES_DELAY
HOLES_DELAY,
HOLES_NONRES
} hole_type;
/**

View File

@ -4929,7 +4929,7 @@ static int ntfs_resident_attr_resize(ntfs_attr *na, const s64 newsize);
* ENOSPC - There is no enough space in base mft to resize $ATTRIBUTE_LIST.
*/
static int ntfs_resident_attr_resize_i(ntfs_attr *na, const s64 newsize,
BOOL force_non_resident)
hole_type holes)
{
ntfs_attr_search_ctx *ctx;
ntfs_volume *vol;
@ -4967,7 +4967,7 @@ static int ntfs_resident_attr_resize_i(ntfs_attr *na, const s64 newsize,
* attribute non-resident if the attribute type supports it. If it is
* smaller we can go ahead and attempt the resize.
*/
if ((newsize < vol->mft_record_size) && !force_non_resident) {
if ((newsize < vol->mft_record_size) && (holes != HOLES_NONRES)) {
/* Perform the resize of the attribute record. */
if (!(ret = ntfs_resident_attr_value_resize(ctx->mrec, ctx->attr,
newsize))) {
@ -5012,7 +5012,7 @@ static int ntfs_resident_attr_resize_i(ntfs_attr *na, const s64 newsize,
* could cause the attribute to be made resident again,
* so size changes are not allowed.
*/
if (force_non_resident) {
if (holes == HOLES_NONRES) {
ret = 0;
if (newsize != na->data_size) {
ntfs_log_error("Cannot change size when"
@ -5023,7 +5023,7 @@ static int ntfs_resident_attr_resize_i(ntfs_attr *na, const s64 newsize,
return (ret);
}
/* Resize non-resident attribute */
return ntfs_attr_truncate_i(na, newsize, HOLES_OK);
return ntfs_attr_truncate_i(na, newsize, holes);
} else if (errno != ENOSPC && errno != EPERM) {
err = errno;
ntfs_log_perror("Failed to make attribute non-resident");
@ -5079,7 +5079,7 @@ static int ntfs_resident_attr_resize_i(ntfs_attr *na, const s64 newsize,
ntfs_inode_mark_dirty(tna->ni);
ntfs_attr_close(tna);
ntfs_attr_put_search_ctx(ctx);
return ntfs_resident_attr_resize_i(na, newsize, force_non_resident);
return ntfs_resident_attr_resize_i(na, newsize, holes);
}
/* Check whether error occurred. */
if (errno != ENOENT) {
@ -5099,7 +5099,7 @@ static int ntfs_resident_attr_resize_i(ntfs_attr *na, const s64 newsize,
ntfs_log_perror("Could not free space in MFT record");
return -1;
}
return ntfs_resident_attr_resize_i(na, newsize, force_non_resident);
return ntfs_resident_attr_resize_i(na, newsize, holes);
}
/*
@ -5138,7 +5138,7 @@ static int ntfs_resident_attr_resize_i(ntfs_attr *na, const s64 newsize,
ntfs_attr_put_search_ctx(ctx);
if (ntfs_inode_add_attrlist(ni))
return -1;
return ntfs_resident_attr_resize_i(na, newsize, force_non_resident);
return ntfs_resident_attr_resize_i(na, newsize, holes);
}
/* Allocate new mft record. */
ni = ntfs_mft_record_alloc(vol, ni);
@ -5159,7 +5159,7 @@ static int ntfs_resident_attr_resize_i(ntfs_attr *na, const s64 newsize,
ntfs_attr_put_search_ctx(ctx);
/* Try to perform resize once again. */
return ntfs_resident_attr_resize_i(na, newsize, force_non_resident);
return ntfs_resident_attr_resize_i(na, newsize, holes);
resize_done:
/*
@ -5180,7 +5180,7 @@ static int ntfs_resident_attr_resize(ntfs_attr *na, const s64 newsize)
int ret;
ntfs_log_enter("Entering\n");
ret = ntfs_resident_attr_resize_i(na, newsize, FALSE);
ret = ntfs_resident_attr_resize_i(na, newsize, HOLES_OK);
ntfs_log_leave("\n");
return ret;
}
@ -5204,7 +5204,7 @@ int ntfs_attr_force_non_resident(ntfs_attr *na)
{
int res;
res = ntfs_resident_attr_resize_i(na, na->data_size, TRUE);
res = ntfs_resident_attr_resize_i(na, na->data_size, HOLES_NONRES);
if (!res && !NAttrNonResident(na)) {
res = -1;
errno = EIO;
@ -6442,7 +6442,7 @@ static int ntfs_attr_truncate_i(ntfs_attr *na, const s64 newsize,
else
ret = ntfs_non_resident_attr_shrink(na, fullsize);
} else
ret = ntfs_resident_attr_resize(na, newsize);
ret = ntfs_resident_attr_resize_i(na, newsize, holes);
out:
ntfs_log_leave("Return status %d\n", ret);
return ret;