- Remove attrlist.[ch]::ntfs_attrlist_set because it was very bad idea to separate it from ntfs_attrlist_entry_{add,rm}.
- Update ntfs_attrlist_entry_{add,rm} and ntfs_inode_add_attrlist to work without it. - Some other fixes, improvements and cleanups. (Logical change 1.615)edge.strict_endians
parent
758dcd21ce
commit
3cb8b787bd
|
@ -48,8 +48,6 @@ xx/xx/2004 - 2.0.0-WIP
|
|||
- Add new API unistr.[hc]::ntfs_ucsndup(). (Anton)
|
||||
- Make libntfs/attrib.c::ntfs_attr_open() make a copy of the attribute
|
||||
name unless it is one of the internal names. (Anton)
|
||||
- Move out common part of ntfs_attrlist_entry_{add,rm} to new API:
|
||||
attrlist.[ch]::ntfs_attrlist_set. (Yura)
|
||||
- New API: attrib.[ch]::ntfs_resident_attr_record_add. (Yura)
|
||||
- New API: inode.[ch]::ntfs_inode_add_attrlist. (Yura)
|
||||
- New API: attrlist.[ch]::ntfs_attrlist_need. (Yura)
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
|
||||
extern int ntfs_attrlist_need(ntfs_inode *ni);
|
||||
|
||||
extern int ntfs_attrlist_set(ntfs_inode *ni, u8 *new_al, int new_al_len);
|
||||
extern int ntfs_attrlist_entry_add(ntfs_inode *ni, ATTR_RECORD *attr);
|
||||
extern int ntfs_attrlist_entry_rm(ntfs_attr_search_ctx *ctx);
|
||||
|
||||
|
|
|
@ -2396,7 +2396,7 @@ int ntfs_resident_attr_record_add(ntfs_inode *ni, ATTR_TYPES type,
|
|||
base_ni = ni->base_ni;
|
||||
else
|
||||
base_ni = ni;
|
||||
if (NInoAttrList(base_ni)) {
|
||||
if (type != AT_ATTRIBUTE_LIST && NInoAttrList(base_ni)) {
|
||||
if (ntfs_attrlist_entry_add(ni, a)) {
|
||||
err = errno;
|
||||
ntfs_attr_record_resize(m, a, 0);
|
||||
|
@ -2526,7 +2526,7 @@ int ntfs_non_resident_attr_record_add(ntfs_inode *ni, ATTR_TYPES type,
|
|||
base_ni = ni->base_ni;
|
||||
else
|
||||
base_ni = ni;
|
||||
if (NInoAttrList(base_ni)) {
|
||||
if (type != AT_ATTRIBUTE_LIST && NInoAttrList(base_ni)) {
|
||||
if (ntfs_attrlist_entry_add(ni, a)) {
|
||||
err = errno;
|
||||
ntfs_attr_record_resize(m, a, 0);
|
||||
|
@ -2583,29 +2583,15 @@ int ntfs_attr_record_rm(ntfs_attr_search_ctx *ctx) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
Dprintf("%s(): Entering for inode 0x%llx, attr 0x%x, lowest_vcn "
|
||||
"%lld.\n", __FUNCTION__, (long long) ctx->ntfs_ino->mft_no,
|
||||
(unsigned) le32_to_cpu(ctx->attr->type),
|
||||
(long long) sle64_to_cpu(ctx->attr->lowest_vcn));
|
||||
Dprintf("%s(): Entering for inode 0x%llx, attr 0x%x.\n",
|
||||
__FUNCTION__, (long long) ctx->ntfs_ino->mft_no,
|
||||
(unsigned) le32_to_cpu(ctx->attr->type));
|
||||
type = ctx->attr->type;
|
||||
ni = ctx->ntfs_ino;
|
||||
if (ctx->base_ntfs_ino)
|
||||
base_ni = ctx->base_ntfs_ino;
|
||||
else
|
||||
base_ni = ctx->ntfs_ino;
|
||||
/*
|
||||
* Remove record from $ATTRIBUTE_LIST if present and we don't want
|
||||
* delete $ATTRIBUTE_LIST itself.
|
||||
*/
|
||||
if (NInoAttrList(base_ni) && type != AT_ATTRIBUTE_LIST) {
|
||||
if (ntfs_attrlist_entry_rm(ctx)) {
|
||||
err = errno;
|
||||
Dprintf("%s(): Coudn't delete record from "
|
||||
"$ATTRIBUTE_LIST.\n", __FUNCTION__);
|
||||
errno = err;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove attribute itself. */
|
||||
if (ntfs_attr_record_resize(ctx->mrec, ctx->attr, 0)) {
|
||||
|
@ -2620,10 +2606,25 @@ int ntfs_attr_record_rm(ntfs_attr_search_ctx *ctx) {
|
|||
}
|
||||
ntfs_inode_mark_dirty(ni);
|
||||
|
||||
/*
|
||||
* Remove record from $ATTRIBUTE_LIST if present and we don't want
|
||||
* delete $ATTRIBUTE_LIST itself.
|
||||
*/
|
||||
if (NInoAttrList(base_ni) && type != AT_ATTRIBUTE_LIST) {
|
||||
if (ntfs_attrlist_entry_rm(ctx)) {
|
||||
err = errno;
|
||||
Dprintf("%s(): Coudn't delete record from "
|
||||
"$ATTRIBUTE_LIST.\n", __FUNCTION__);
|
||||
errno = err;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Post $ATTRIBUTE_LIST delete setup. */
|
||||
if (type == AT_ATTRIBUTE_LIST) {
|
||||
if (NInoAttrList(base_ni) && base_ni->attr_list)
|
||||
free(base_ni->attr_list);
|
||||
base_ni->attr_list = NULL;
|
||||
NInoClearAttrList(base_ni);
|
||||
NInoAttrListClearDirty(base_ni);
|
||||
}
|
||||
|
@ -3321,10 +3322,19 @@ static int ntfs_resident_attr_resize(ntfs_attr *na, const s64 newsize)
|
|||
goto put_err_out;
|
||||
}
|
||||
|
||||
/* We can't move out attribute list. */
|
||||
/* We can't move out attribute list, thus move out others. */
|
||||
if (na->type == AT_ATTRIBUTE_LIST) {
|
||||
err = ENOSPC;
|
||||
goto put_err_out;
|
||||
ntfs_attr_put_search_ctx(ctx);
|
||||
if (ntfs_inode_free_space(na->ni, offsetof(ATTR_RECORD,
|
||||
non_resident_attr_end) + 8)) {
|
||||
err = errno;
|
||||
Dprintf("%s(): Couldn't free space in the MFT record "
|
||||
"to make attribute list non resident.\n",
|
||||
__FUNCTION__);
|
||||
errno = err;
|
||||
return -1;
|
||||
}
|
||||
return ntfs_resident_attr_resize(na, newsize);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -3712,7 +3722,7 @@ int ntfs_attr_update_mapping_pairs(ntfs_attr *na)
|
|||
if (na->type == AT_ATTRIBUTE_LIST) {
|
||||
ntfs_attr_put_search_ctx(ctx);
|
||||
if (ntfs_inode_free_space(na->ni, mp_size -
|
||||
exp_max_mp_size)) {
|
||||
cur_max_mp_size)) {
|
||||
if (errno != ENOSPC)
|
||||
return -1;
|
||||
Dprintf("%s(): Attribute list mapping "
|
||||
|
@ -4287,6 +4297,7 @@ put_err_out:
|
|||
int ntfs_attr_truncate(ntfs_attr *na, const s64 newsize)
|
||||
{
|
||||
if (!na || newsize < 0 || (na->ni == FILE_MFT && na->type == AT_DATA)) {
|
||||
Dprintf("%s(): Invalid aruments passed.\n", __FUNCTION__);
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -82,77 +82,6 @@ int ntfs_attrlist_need(ntfs_inode *ni)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_attrlist_set - set new attribute list for ntfs inode
|
||||
* @ni: opened ntfs inode attribute list set for
|
||||
* @new_al: new attribute list
|
||||
* @new_al_len: length of new attribute list
|
||||
*
|
||||
* Return 0 on success and -1 on error with errno set to the error code. The
|
||||
* following error codes are defined:
|
||||
* EINVAL - Invalid argumets passed to function.
|
||||
* ENOMEM - Not enough memory to allocate necessary buffers.
|
||||
* ENOTSUP - Code that required for set is not implemented yet.
|
||||
* EIO - I/O error occured or damaged filesystem.
|
||||
*/
|
||||
int ntfs_attrlist_set(ntfs_inode *ni, u8 *new_al, int new_al_len)
|
||||
{
|
||||
ntfs_attr *na = NULL;
|
||||
int err;
|
||||
|
||||
if (!ni || !new_al || new_al_len < 1) {
|
||||
Dprintf("%s(): Invalid argumets.\n", __FUNCTION__);
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
Dprintf("%s(): Entering for inode 0x%llx, new_al_len %d.\n",
|
||||
__FUNCTION__, (long long) ni->mft_no, new_al_len);
|
||||
|
||||
/* Make attribute list length 8 byte aligment. */
|
||||
new_al_len = (new_al_len + 7) & ~7;
|
||||
|
||||
na = ntfs_attr_open(ni, AT_ATTRIBUTE_LIST, 0, 0);
|
||||
if (!na) {
|
||||
err = errno;
|
||||
Dprintf("%s(): Coudn't open $ATTRIBUTE_LIST.\n", __FUNCTION__);
|
||||
goto err_out;
|
||||
}
|
||||
/*
|
||||
* Setup im-memory attribute list. We need this to perform attribute
|
||||
* truncate (we need update attribute list in case other attributes
|
||||
* will be moved away from their current MFT record).
|
||||
*/
|
||||
if (NInoAttrList(ni) && ni->attr_list)
|
||||
free(ni->attr_list);
|
||||
ni->attr_list = new_al;
|
||||
ni->attr_list_size = new_al_len;
|
||||
NInoSetAttrList(ni);
|
||||
NInoAttrListSetDirty(ni);
|
||||
/* Resize $ATTRIBUTE_LIST attribute. */
|
||||
if (ntfs_attr_truncate(na, new_al_len)) {
|
||||
/*
|
||||
* FIXME: We leave new attribute list. But need to restore old
|
||||
* and update in it records for moved attributes. Difficult to
|
||||
* do if we haven't attribute list before truncate and records
|
||||
* were moved.
|
||||
*/
|
||||
err = errno;
|
||||
Dprintf("%s(): Eeek! $ATTRIBUTE_LIST resize failed. Probably "
|
||||
"leaving inconsist metadata.\n", __FUNCTION__);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
/* Done! */
|
||||
ntfs_attr_close(na);
|
||||
return 0;
|
||||
err_out:
|
||||
if (na)
|
||||
ntfs_attr_close(na);
|
||||
errno = err;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_attrlist_entry_add - add an attribute list attribute entry
|
||||
* @ni: opened ntfs inode, which contains that attribute
|
||||
|
@ -169,6 +98,7 @@ int ntfs_attrlist_entry_add(ntfs_inode *ni, ATTR_RECORD *attr)
|
|||
{
|
||||
ATTR_LIST_ENTRY *ale;
|
||||
MFT_REF mref;
|
||||
ntfs_attr *na = NULL;
|
||||
u8 *new_al;
|
||||
int new_al_len;
|
||||
int err;
|
||||
|
@ -193,6 +123,7 @@ int ntfs_attrlist_entry_add(ntfs_inode *ni, ATTR_RECORD *attr)
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* Determine size and allocate memory for new attribute list. */
|
||||
new_al_len = (ni->attr_list_size + sizeof(ATTR_LIST_ENTRY) +
|
||||
sizeof(ntfschar) * attr->name_length + 7) & ~7;
|
||||
new_al = malloc(new_al_len);
|
||||
|
@ -202,6 +133,20 @@ int ntfs_attrlist_entry_add(ntfs_inode *ni, ATTR_RECORD *attr)
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* Reisze $ATTRIBUTE_LIST to new length. */
|
||||
na = ntfs_attr_open(ni, AT_ATTRIBUTE_LIST, NULL, 0);
|
||||
if (!na) {
|
||||
err = errno;
|
||||
Dprintf("%s(): Failed to open $ATTRIBUTE_LIST attribute.\n",
|
||||
__FUNCTION__);
|
||||
goto err_out;
|
||||
}
|
||||
if (ntfs_attr_truncate(na, new_al_len)) {
|
||||
err = errno;
|
||||
Dprintf("%s(): $ATTRIBUTE_LIST resize failed.\n", __FUNCTION__);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
/* Find offset at which insert new entry. */
|
||||
ale = (ATTR_LIST_ENTRY *) ni->attr_list;
|
||||
for(; (u8 *)ale < ni->attr_list + ni->attr_list_size;
|
||||
|
@ -218,7 +163,7 @@ int ntfs_attrlist_entry_add(ntfs_inode *ni, ATTR_RECORD *attr)
|
|||
err = EIO;
|
||||
Dprintf("%s(): Corrupt attribute name. Run chkdsk.\n",
|
||||
__FUNCTION__);
|
||||
goto err_out;
|
||||
goto rollback;
|
||||
}
|
||||
if (err < 0)
|
||||
continue;
|
||||
|
@ -233,7 +178,7 @@ int ntfs_attrlist_entry_add(ntfs_inode *ni, ATTR_RECORD *attr)
|
|||
Dprintf("%s(): Attribute with same type, name and "
|
||||
"lowest vcn already present in attribute "
|
||||
"list.\n", __FUNCTION__);
|
||||
goto err_out;
|
||||
goto rollback;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -262,13 +207,22 @@ int ntfs_attrlist_entry_add(ntfs_inode *ni, ATTR_RECORD *attr)
|
|||
attr->name_length * sizeof(ntfschar));
|
||||
|
||||
/* Set new runlist. */
|
||||
if (ntfs_attrlist_set(ni, new_al, new_al_len)) {
|
||||
err = errno;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (ni->attr_list)
|
||||
free(ni->attr_list);
|
||||
ni->attr_list = new_al;
|
||||
ni->attr_list_size = new_al_len;
|
||||
NInoAttrListSetDirty(ni);
|
||||
/* Done! */
|
||||
ntfs_attr_close(na);
|
||||
return 0;
|
||||
rollback:
|
||||
if (ntfs_attr_truncate(na, ni->attr_list_size)) {
|
||||
Dprintf("%s(): $ATTRIBUTE_LIST resize failed. Rollback failed. "
|
||||
"Leaving inconsist metadata.\n", __FUNCTION__);
|
||||
}
|
||||
err_out:
|
||||
if (na)
|
||||
ntfs_attr_close(na);
|
||||
free(new_al);
|
||||
errno = err;
|
||||
return -1;
|
||||
|
@ -278,8 +232,7 @@ err_out:
|
|||
* ntfs_attrlist_entry_rm - remove an attribute list attribute entry
|
||||
* @ctx: attribute search context describing the attrubute list entry
|
||||
*
|
||||
* Remove the attribute list entry @ctx->al_entry from the attribute list
|
||||
* attribute of the base mft record to which the attribute @ctx->attr belongs.
|
||||
* Remove the attribute list entry @ctx->al_entry from the attribute list.
|
||||
*
|
||||
* Return 0 on success and -1 on error with errno set to the error code.
|
||||
*/
|
||||
|
@ -288,10 +241,11 @@ int ntfs_attrlist_entry_rm(ntfs_attr_search_ctx *ctx)
|
|||
u8 *new_al;
|
||||
int new_al_len;
|
||||
ntfs_inode *base_ni;
|
||||
ntfs_attr *na;
|
||||
ATTR_LIST_ENTRY *ale;
|
||||
int err;
|
||||
|
||||
if (!ctx || !ctx->ntfs_ino || !ctx->attr || !ctx->al_entry) {
|
||||
if (!ctx || !ctx->ntfs_ino || !ctx->al_entry) {
|
||||
Dprintf("%s(): Invalid argumets.\n", __FUNCTION__);
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
|
@ -305,8 +259,8 @@ int ntfs_attrlist_entry_rm(ntfs_attr_search_ctx *ctx)
|
|||
|
||||
Dprintf("%s(): Entering for inode 0x%llx, attr 0x%x, lowest_vcn "
|
||||
"%lld.\n", __FUNCTION__, (long long) ctx->ntfs_ino->mft_no,
|
||||
(unsigned) le32_to_cpu(ctx->attr->type),
|
||||
(long long) le64_to_cpu(ctx->attr->lowest_vcn));
|
||||
(unsigned) le32_to_cpu(ctx->al_entry->type),
|
||||
(long long) le64_to_cpu(ctx->al_entry->lowest_vcn));
|
||||
|
||||
if (!NInoAttrList(base_ni)) {
|
||||
Dprintf("%s(): Attribute list isn't present.\n", __FUNCTION__);
|
||||
|
@ -322,6 +276,20 @@ int ntfs_attrlist_entry_rm(ntfs_attr_search_ctx *ctx)
|
|||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Reisze $ATTRIBUTE_LIST to new length. */
|
||||
na = ntfs_attr_open(base_ni, AT_ATTRIBUTE_LIST, NULL, 0);
|
||||
if (!na) {
|
||||
err = errno;
|
||||
Dprintf("%s(): Failed to open $ATTRIBUTE_LIST attribute.\n",
|
||||
__FUNCTION__);
|
||||
goto err_out;
|
||||
}
|
||||
if (ntfs_attr_truncate(na, new_al_len)) {
|
||||
err = errno;
|
||||
Dprintf("%s(): $ATTRIBUTE_LIST resize failed.\n", __FUNCTION__);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
/* Copy entries from old attribute list to new. */
|
||||
memcpy(new_al, base_ni->attr_list, (u8*)ale - base_ni->attr_list);
|
||||
|
@ -329,12 +297,17 @@ int ntfs_attrlist_entry_rm(ntfs_attr_search_ctx *ctx)
|
|||
ale->length), new_al_len - ((u8*)ale - base_ni->attr_list));
|
||||
|
||||
/* Set new runlist. */
|
||||
if (ntfs_attrlist_set(base_ni, new_al, new_al_len)) {
|
||||
err = errno;
|
||||
goto err_out;
|
||||
}
|
||||
if (base_ni->attr_list)
|
||||
free(base_ni->attr_list);
|
||||
base_ni->attr_list = new_al;
|
||||
base_ni->attr_list_size = new_al_len;
|
||||
NInoAttrListSetDirty(base_ni);
|
||||
/* Done! */
|
||||
ntfs_attr_close(na);
|
||||
return 0;
|
||||
err_out:
|
||||
if (na)
|
||||
ntfs_attr_close(na);
|
||||
free(new_al);
|
||||
errno = err;
|
||||
return -1;
|
||||
|
|
|
@ -525,6 +525,7 @@ int ntfs_inode_add_attrlist(ntfs_inode *ni)
|
|||
u8 *al, *aln;
|
||||
int al_len, al_allocated;
|
||||
ATTR_LIST_ENTRY *ale;
|
||||
ntfs_attr *na;
|
||||
|
||||
if (!ni) {
|
||||
Dprintf("%s(): Invalid argumets.\n", __FUNCTION__);
|
||||
|
@ -617,52 +618,47 @@ int ntfs_inode_add_attrlist(ntfs_inode *ni)
|
|||
al = aln;
|
||||
ntfs_attr_put_search_ctx(ctx);
|
||||
|
||||
/* Set in-memory attribute list. */
|
||||
ni->attr_list = al;
|
||||
ni->attr_list_size = al_len;
|
||||
NInoSetAttrList(ni);
|
||||
|
||||
/* Free space if there is not enough it for $ATTRIBUTE_LIST. */
|
||||
if (le32_to_cpu(ni->mrec->bytes_allocated) -
|
||||
le32_to_cpu(ni->mrec->bytes_in_use) <
|
||||
offsetof(ATTR_RECORD, resident_attr_end)) {
|
||||
/*
|
||||
* Set temporary in-memory attribute list. We need this to be
|
||||
* able perform attribute lookups and move out attributes.
|
||||
*/
|
||||
ni->attr_list = al;
|
||||
ni->attr_list_size = al_len;
|
||||
NInoSetAttrList(ni);
|
||||
/* Free space. */
|
||||
if (ntfs_inode_free_space(ni,
|
||||
offsetof(ATTR_RECORD, resident_attr_end))) {
|
||||
/*
|
||||
* Couldn't free space, unset temporary in-memory
|
||||
* attribute list and fail.
|
||||
*/
|
||||
/* Failed to free space. */
|
||||
err = errno;
|
||||
Dprintf("%s(): Failed to free space for "
|
||||
"$ATTRIBUTE_LIST.\n", __FUNCTION__);
|
||||
ni->attr_list = NULL;
|
||||
NInoClearAttrList(ni);
|
||||
goto err_out;
|
||||
free(al);
|
||||
goto rollback;
|
||||
}
|
||||
/* Unset temporary in-memory attribute list. */
|
||||
ni->attr_list = NULL;
|
||||
NInoClearAttrList(ni);
|
||||
}
|
||||
|
||||
/* Add $ATTRIBUTE_LIST to mft record. */
|
||||
if (ntfs_resident_attr_record_add(ni, AT_ATTRIBUTE_LIST, 0, 0, 0) < 0) {
|
||||
na = ntfs_inode_add_attr(ni, AT_ATTRIBUTE_LIST, NULL, 0, al_len);
|
||||
if (!na) {
|
||||
err = errno;
|
||||
Dprintf("%s(): Couldn't add $ATTRIBUTE_LIST to MFT record.\n",
|
||||
__FUNCTION__);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
/* Set new attribute list. */
|
||||
if (ntfs_attrlist_set(ni, al, al_len)) {
|
||||
err = errno;
|
||||
Dprintf("%s(): Coudn't set attribute list.\n", __FUNCTION__);
|
||||
goto err_out;
|
||||
Dprintf("%s(): Failed to add $ATTRIBUTE_LIST.\n", __FUNCTION__);
|
||||
goto rollback;
|
||||
}
|
||||
/* Done! */
|
||||
ntfs_attr_close(na);
|
||||
return 0;
|
||||
rollback:
|
||||
/*
|
||||
* FIXME: We should here scan attribute list for attributes that placed
|
||||
* not in the base MFT record and move them to it.
|
||||
*/
|
||||
|
||||
/* Unset in-memory attribute list. */
|
||||
ni->attr_list = NULL;
|
||||
NInoClearAttrList(ni);
|
||||
errno = err;
|
||||
return -1;
|
||||
put_err_out:
|
||||
ntfs_attr_put_search_ctx(ctx);
|
||||
err_out:
|
||||
|
@ -681,7 +677,7 @@ err_out:
|
|||
int ntfs_inode_free_space(ntfs_inode *ni, int size)
|
||||
{
|
||||
ntfs_attr_search_ctx *ctx;
|
||||
int freed = 0, err;
|
||||
int freed, err;
|
||||
|
||||
if (!ni || size < 0) {
|
||||
Dprintf("%s(): Invalid argumets.\n", __FUNCTION__);
|
||||
|
@ -691,8 +687,11 @@ int ntfs_inode_free_space(ntfs_inode *ni, int size)
|
|||
|
||||
Dprintf("%s(): Entering for inode 0x%llx, size %d.\n",
|
||||
__FUNCTION__, (long long) ni->mft_no, size);
|
||||
|
||||
freed = (le32_to_cpu(ni->mrec->bytes_allocated) -
|
||||
le32_to_cpu(ni->mrec->bytes_in_use));
|
||||
|
||||
if (!size)
|
||||
if (size <= freed)
|
||||
return 0;
|
||||
|
||||
ctx = ntfs_attr_get_search_ctx(ni, 0);
|
||||
|
@ -820,11 +819,12 @@ put_err_out:
|
|||
ntfs_attr *ntfs_inode_add_attr(ntfs_inode *ni, ATTR_TYPES type,
|
||||
ntfschar *name, u8 name_len, s64 size)
|
||||
{
|
||||
int attr_rec_size, err, i, offset;
|
||||
u32 attr_rec_size;
|
||||
int err, i, offset;
|
||||
ntfs_inode *attr_ni;
|
||||
ntfs_attr *na;
|
||||
|
||||
if (!ni || size < 0 || type == AT_ATTRIBUTE_LIST) {
|
||||
if (!ni || size < 0) {
|
||||
Dprintf("%s(): Invalid arguments passed.\n", __FUNCTION__);
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
|
@ -883,6 +883,12 @@ ntfs_attr *ntfs_inode_add_attr(ntfs_inode *ni, ATTR_TYPES type,
|
|||
goto add_attr_record;
|
||||
}
|
||||
|
||||
/* Attribute list can be placed only in the base MFT record. */
|
||||
if (type == AT_ATTRIBUTE_LIST) {
|
||||
err = ENOSPC;
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
/* Try to add to extent inodes. */
|
||||
if (ntfs_inode_attach_all_extents(ni)) {
|
||||
err = errno;
|
||||
|
|
Loading…
Reference in New Issue