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
parent
1f7fd0160f
commit
89af38f687
|
@ -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;
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue