From: Jean-Pierre André Date: Mon, 9 Sep 2013 13:27:38 +0000 (+0200) Subject: Fixed expanding a resident attribute without inserting holes X-Git-Tag: android-x86-6.0-r1~48 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=89af38f687a3dd03ec1229e81ecd46b23ad54b47;p=android-x86%2Fexternal-ntfs-3g.git 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). --- diff --git a/include/ntfs-3g/attrib.h b/include/ntfs-3g/attrib.h index 1979ba68..a0bee265 100644 --- a/include/ntfs-3g/attrib.h +++ b/include/ntfs-3g/attrib.h @@ -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; /** diff --git a/libntfs-3g/attrib.c b/libntfs-3g/attrib.c index 01eaa46b..269ccf86 100644 --- a/libntfs-3g/attrib.c +++ b/libntfs-3g/attrib.c @@ -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;