- add ntfs_attr_record_move_away

- make ntfs_attr_update_mapping_pairs use ntfs_inode_free_space
- cleanups

(Logical change 1.599)
edge.strict_endians
(none)!yura 2004-10-10 17:20:48 +00:00
parent db92f7bfbf
commit 3f9fac7647
1 changed files with 105 additions and 7 deletions

View File

@ -1668,7 +1668,7 @@ find_attr_list_attr:
/* Not found?!? Absurd! Must be a bug... )-: */
Dprintf("%s(): BUG! Attribute list attribute not found "
"but it exists! Returning error "
"(EINVAL).", __FUNCTION__);
"(EINVAL).\n", __FUNCTION__);
errno = EINVAL;
return -1;
}
@ -2636,6 +2636,7 @@ int ntfs_attr_record_rm(ntfs_attr_search_ctx *ctx) {
"Couldn't free clusters from attribute "
"list runlist. Succeed anyway.\n",
__FUNCTION__);
return 0;
}
}
/* Remove attribute record itself. */
@ -2790,8 +2791,9 @@ int ntfs_attr_record_move_to(ntfs_attr_search_ctx *ctx, ntfs_inode *ni)
}
Dprintf("%s(): Entering for ctx->attr->type 0x%x, ctx->ntfs_ino->mft_no"
" 0x%llx, ni->mft_no 0x%llx.\n", __FUNCTION__, ctx->attr->type,
(long long) ctx->ntfs_ino->mft_no, (long long) ni->mft_no);
" 0x%llx, ni->mft_no 0x%llx.\n", __FUNCTION__, (unsigned)
le32_to_cpu(ctx->attr->type), (long long) ctx->ntfs_ino->mft_no,
(long long) ni->mft_no);
if (ctx->ntfs_ino == ni)
return 0;
@ -2857,6 +2859,89 @@ put_err_out:
return -1;
}
/**
* ntfs_attr_record_move_away - move away attribute record from it's mft record
* @ctx: attribute search context describing the attrubute record
*
* If this function succeed, user should reinit search context if he/she wants
* use it anymore.
*
* Return 0 on success and -1 on error with errno set to the error code.
*/
int ntfs_attr_record_move_away(ntfs_attr_search_ctx *ctx)
{
ntfs_inode *base_ni, *ni;
MFT_RECORD *m;
int i, err;
if (!ctx || !ctx->attr || !ctx->ntfs_ino) {
Dprintf("%s(): Invalid arguments passed.\n", __FUNCTION__);
errno = EINVAL;
return -1;
}
Dprintf("%s(): Entering for attr 0x%x, inode 0x%llx.\n", __FUNCTION__,
(unsigned) le32_to_cpu(ctx->attr->type),
(long long) ctx->ntfs_ino->mft_no);
if (ctx->ntfs_ino->nr_extents == -1)
base_ni = ctx->base_ntfs_ino;
else
base_ni = ctx->ntfs_ino;
if (!NInoAttrList(base_ni)) {
Dprintf("%s(): Inode should contain attribute list to use "
"this function.\n", __FUNCTION__);
errno = EINVAL;
return -1;
}
if (ntfs_inode_attach_all_extents(ctx->ntfs_ino)) {
err = errno;
Dprintf("%s(): Couldn't attach extent inode.\n", __FUNCTION__);
errno = err;
return -1;
}
/* Walk through all extents and try to move attribute to them. */
for (i = 0; i < base_ni->nr_extents; i++) {
ni = base_ni->extent_nis[i];
m = ni->mrec;
if (ctx->ntfs_ino->mft_no == ni->mft_no)
continue;
if (le32_to_cpu(m->bytes_allocated) -
le32_to_cpu(m->bytes_in_use) <
le32_to_cpu(ctx->attr->length))
continue;
if (!ntfs_attr_record_move_to(ctx, ni))
return 0;
}
/*
* Failed to move attribute to one of the current extents, so allocate
* new extent and move attribute to it.
*/
ni = ntfs_mft_record_alloc(base_ni->vol, base_ni);
if (!ni) {
err = errno;
Dprintf("%s(): Couldn't allocate new MFT record.\n",
__FUNCTION__);
errno = err;
return -1;
}
if (ntfs_attr_record_move_to(ctx, ni)) {
err = errno;
Dprintf("%s(): Couldn't move attribute to new MFT record.\n",
__FUNCTION__);
errno = err;
return -1;
}
return 0;
}
/**
* ntfs_attr_make_non_resident - convert a resident to a non-resident attribute
* @na: open ntfs attribute to make non-resident
@ -3227,7 +3312,7 @@ static int ntfs_resident_attr_resize(ntfs_attr *na, const s64 newsize)
ni = na->ni->base_ni;
else
ni = na->ni;
if (!NInoAttrList(na->ni)) {
if (!NInoAttrList(ni)) {
ntfs_attr_put_search_ctx(ctx);
if (ntfs_inode_add_attrlist(ni))
return -1;
@ -3569,11 +3654,24 @@ int ntfs_attr_update_mapping_pairs(ntfs_attr *na)
if (mp_size > exp_max_mp_size) {
/*
* Mapping pairs of $ATTRIBUTE_LIST attribute must fit
* in the base mft record.
* in the base mft record. Try to move out other
* attibutes and try again.
*/
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, mp_size -
exp_max_mp_size)) {
if (errno != ENOSPC)
return -1;
Dprintf("%s(): Attribute list mapping "
"pairs size to big, can't fit "
"them in the base MFT record. "
"Defragment volume and try "
"once again.\n", __FUNCTION__);
errno = ENOSPC;
return -1;
}
return ntfs_attr_update_mapping_pairs(na);
}
/* Add attribute list if it isn't present, and retry. */