From 895b64f4158738ea5850c86f15494642e49980b2 Mon Sep 17 00:00:00 2001 From: szaka Date: Wed, 25 Mar 2009 20:52:24 +0000 Subject: [PATCH] fix "no space on device" error during file creation introduced in 2009.3.6 (Jean-Pierre Andre, Szabolcs Szakacsits) --- libntfs-3g/attrib.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/libntfs-3g/attrib.c b/libntfs-3g/attrib.c index d5a43578..fa448af7 100644 --- a/libntfs-3g/attrib.c +++ b/libntfs-3g/attrib.c @@ -3402,11 +3402,11 @@ int ntfs_attr_record_resize(MFT_RECORD *m, ATTR_RECORD *a, u32 new_size) } if (a->type == AT_INDEX_ROOT && new_size > attr_size && - new_muse + 120 > alloc_size) { + new_muse + 120 > alloc_size && old_size + 120 <= alloc_size) { errno = ENOSPC; ntfs_log_trace("Too big INDEX_ROOT (%u > %u)\n", new_muse, alloc_size); - return -1; + return STATUS_RESIDENT_ATTRIBUTE_FILLED_MFT; } /* Move attributes following @a to their new location. */ @@ -3440,12 +3440,14 @@ int ntfs_attr_record_resize(MFT_RECORD *m, ATTR_RECORD *a, u32 new_size) int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a, const u32 new_size) { + int ret; + ntfs_log_trace("Entering for new size %u.\n", (unsigned)new_size); /* Resize the resident part of the attribute record. */ - if (ntfs_attr_record_resize(m, a, (le16_to_cpu(a->value_offset) + - new_size + 7) & ~7) < 0) - return -1; + if ((ret = ntfs_attr_record_resize(m, a, (le16_to_cpu(a->value_offset) + + new_size + 7) & ~7)) < 0) + return ret; /* * If we made the attribute value bigger, clear the area between the * old size and @new_size. @@ -3860,8 +3862,8 @@ static int ntfs_resident_attr_resize_i(ntfs_attr *na, const s64 newsize) */ if (newsize < vol->mft_record_size) { /* Perform the resize of the attribute record. */ - if (!ntfs_resident_attr_value_resize(ctx->mrec, ctx->attr, - newsize)) { + if (!(ret = ntfs_resident_attr_value_resize(ctx->mrec, ctx->attr, + newsize))) { /* Update attribute size everywhere. */ na->data_size = na->initialized_size = newsize; na->allocated_size = (newsize + 7) & ~7; @@ -3874,6 +3876,11 @@ static int ntfs_resident_attr_resize_i(ntfs_attr *na, const s64 newsize) } goto resize_done; } + /* Prefer AT_INDEX_ALLOCATION instead of AT_ATTRIBUTE_LIST */ + if (ret == STATUS_RESIDENT_ATTRIBUTE_FILLED_MFT) { + err = errno; + goto put_err_out; + } } /* There is not enough space in the mft record to perform the resize. */ @@ -3931,14 +3938,6 @@ static int ntfs_resident_attr_resize_i(ntfs_attr *na, const s64 newsize) goto put_err_out; } - /* Prefer to add AT_INDEX_ALLOCATION instead of AT_ATTRIBUTE_LIST */ - if (na->type == AT_INDEX_ROOT) { - err = ENOSPC; - ntfs_log_trace("INDEX_ROOT can not be enlarged\n"); - ret = STATUS_RESIDENT_ATTRIBUTE_FILLED_MFT; - goto put_err_out; - } - /* * The standard information and attribute list attributes can't be * moved out from the base MFT record, so try to move out others.