ntfs_make_room_for_attr(): "no space" condition must be ENOSPC, not EINVAL

ntfs_attr_add(): fix adding attribute which can be resident and non-resident
This commit is contained in:
szaka 2008-04-02 17:21:11 +00:00
parent 69423166cb
commit 77e5ff36d1

View File

@ -2591,9 +2591,9 @@ int ntfs_make_room_for_attr(MFT_RECORD *m, u8 *pos, u32 size)
size = (size + 7) & ~7;
/* Rigorous consistency checks. */
if (!m || !pos || pos < (u8*)m || pos + size >
(u8*)m + le32_to_cpu(m->bytes_allocated)) {
if (!m || !pos || pos < (u8*)m) {
errno = EINVAL;
ntfs_log_perror("%s: pos=%p m=%p", __FUNCTION__, pos, m);
return -1;
}
/* The -8 is for the attribute terminator. */
@ -2607,7 +2607,8 @@ int ntfs_make_room_for_attr(MFT_RECORD *m, u8 *pos, u32 size)
biu = le32_to_cpu(m->bytes_in_use);
/* Do we have enough space? */
if (biu + size > le32_to_cpu(m->bytes_allocated)) {
if (biu + size > le32_to_cpu(m->bytes_allocated) ||
pos + size > (u8*)m + le32_to_cpu(m->bytes_allocated)) {
errno = ENOSPC;
ntfs_log_trace("No enough space in the MFT record\n");
return -1;
@ -2652,6 +2653,8 @@ int ntfs_resident_attr_record_add(ntfs_inode *ni, ATTR_TYPES type,
if (!ni || (!name && name_len)) {
errno = EINVAL;
ntfs_log_perror("%s: ni=%p, name=%p, len=%d", __FUNCTION__, ni,
name, name_len);
return -1;
}
@ -3052,6 +3055,7 @@ int ntfs_attr_add(ntfs_inode *ni, ATTR_TYPES type,
u32 attr_rec_size;
int err, i, offset;
BOOL is_resident;
BOOL can_be_non_resident = FALSE;
ntfs_inode *attr_ni;
ntfs_attr *na;
@ -3094,7 +3098,8 @@ int ntfs_attr_add(ntfs_inode *ni, ATTR_TYPES type,
ntfs_log_perror("Attribute is too big");
return -1;
}
}
} else
can_be_non_resident = TRUE;
/*
* Determine resident or not will be new attribute. We add 8 to size in
@ -3167,6 +3172,8 @@ add_attr_record:
offset = ntfs_resident_attr_record_add(attr_ni, type, name,
name_len, val, size, 0);
if (offset < 0) {
if (errno == ENOSPC && can_be_non_resident)
goto add_non_resident;
err = errno;
ntfs_log_perror("Failed to add resident attribute");
goto free_err_out;
@ -3174,6 +3181,7 @@ add_attr_record:
return 0;
}
add_non_resident:
/* Add non resident attribute. */
offset = ntfs_non_resident_attr_record_add(attr_ni, type, name,
name_len, 0, 8, 0);