ntfs_attr_update_mapping_pairs: refactoring
parent
c8176a77a2
commit
be0cdbb04a
|
@ -3983,6 +3983,125 @@ static int ntfs_attr_make_resident(ntfs_attr *na, ntfs_attr_search_ctx *ctx)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we are in the first extent, then set/clean sparse bit,
|
||||
* update allocated and compressed size.
|
||||
*/
|
||||
static int ntfs_attr_update_meta(ATTR_RECORD *a, ntfs_attr *na, MFT_RECORD *m,
|
||||
ntfs_attr_search_ctx *ctx)
|
||||
{
|
||||
int sparse, ret = 0;
|
||||
|
||||
ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x\n",
|
||||
(unsigned long long)na->ni->mft_no, na->type);
|
||||
|
||||
if (a->lowest_vcn)
|
||||
goto out;
|
||||
|
||||
a->allocated_size = cpu_to_sle64(na->allocated_size);
|
||||
|
||||
/* Update sparse bit. */
|
||||
sparse = ntfs_rl_sparse(na->rl);
|
||||
if (sparse == -1) {
|
||||
errno = EIO;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Attribute become sparse. */
|
||||
if (sparse && !(a->flags & (ATTR_IS_SPARSE | ATTR_IS_COMPRESSED))) {
|
||||
/*
|
||||
* Move attribute to another mft record, if attribute is too
|
||||
* small to add compressed_size field to it and we have no
|
||||
* free space in the current mft record.
|
||||
*/
|
||||
if ((le32_to_cpu(a->length) -
|
||||
le16_to_cpu(a->mapping_pairs_offset) == 8)
|
||||
&& !(le32_to_cpu(m->bytes_allocated) -
|
||||
le32_to_cpu(m->bytes_in_use))) {
|
||||
|
||||
if (!NInoAttrList(na->ni)) {
|
||||
ntfs_attr_put_search_ctx(ctx);
|
||||
if (ntfs_inode_add_attrlist(na->ni))
|
||||
goto leave;
|
||||
goto retry;
|
||||
}
|
||||
if (ntfs_attr_record_move_away(ctx, 8)) {
|
||||
ntfs_log_perror("Failed to move attribute");
|
||||
goto error;
|
||||
}
|
||||
ntfs_attr_put_search_ctx(ctx);
|
||||
goto retry;
|
||||
}
|
||||
if (!(le32_to_cpu(a->length) - le16_to_cpu(
|
||||
a->mapping_pairs_offset))) {
|
||||
errno = EIO;
|
||||
ntfs_log_perror("Mapping pairs space is 0");
|
||||
goto error;
|
||||
}
|
||||
|
||||
NAttrSetSparse(na);
|
||||
a->flags |= ATTR_IS_SPARSE;
|
||||
a->compression_unit = 4; /* Windows set it so, even if attribute
|
||||
is not actually compressed. */
|
||||
|
||||
memmove((u8*)a + le16_to_cpu(a->name_offset) + 8,
|
||||
(u8*)a + le16_to_cpu(a->name_offset),
|
||||
a->name_length * sizeof(ntfschar));
|
||||
|
||||
a->name_offset = cpu_to_le16(le16_to_cpu(a->name_offset) + 8);
|
||||
|
||||
a->mapping_pairs_offset =
|
||||
cpu_to_le16(le16_to_cpu(a->mapping_pairs_offset) + 8);
|
||||
}
|
||||
|
||||
/* Attribute no longer sparse. */
|
||||
if (!sparse && (a->flags & ATTR_IS_SPARSE) &&
|
||||
!(a->flags & ATTR_IS_COMPRESSED)) {
|
||||
|
||||
NAttrClearSparse(na);
|
||||
a->flags &= ~ATTR_IS_SPARSE;
|
||||
a->compression_unit = 0;
|
||||
|
||||
memmove((u8*)a + le16_to_cpu(a->name_offset) - 8,
|
||||
(u8*)a + le16_to_cpu(a->name_offset),
|
||||
a->name_length * sizeof(ntfschar));
|
||||
|
||||
if (le16_to_cpu(a->name_offset) >= 8)
|
||||
a->name_offset = cpu_to_le16(le16_to_cpu(a->name_offset) - 8);
|
||||
|
||||
a->mapping_pairs_offset =
|
||||
cpu_to_le16(le16_to_cpu(a->mapping_pairs_offset) - 8);
|
||||
}
|
||||
|
||||
/* Update compressed size if required. */
|
||||
if (sparse) {
|
||||
s64 new_compr_size;
|
||||
|
||||
new_compr_size = ntfs_rl_get_compressed_size(na->ni->vol, na->rl);
|
||||
if (new_compr_size == -1)
|
||||
goto error;
|
||||
|
||||
na->compressed_size = new_compr_size;
|
||||
a->compressed_size = cpu_to_sle64(new_compr_size);
|
||||
}
|
||||
/*
|
||||
* Set FILE_NAME dirty flag, to update sparse bit and
|
||||
* allocated size in the index.
|
||||
*/
|
||||
if (na->type == AT_DATA && na->name == AT_UNNAMED) {
|
||||
if (sparse)
|
||||
na->ni->allocated_size = na->compressed_size;
|
||||
else
|
||||
na->ni->allocated_size = na->allocated_size;
|
||||
NInoFileNameSetDirty(na->ni);
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
leave: ret = -1; goto out; /* return -1 */
|
||||
retry: ret = -2; goto out;
|
||||
error: ret = -3; goto out;
|
||||
}
|
||||
|
||||
#define NTFS_VCN_DELETE_MARK -2
|
||||
/**
|
||||
* ntfs_attr_update_mapping_pairs - update mapping pairs for ntfs attribute
|
||||
|
@ -4095,124 +4214,13 @@ retry:
|
|||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we in the first extent, then set/clean sparse bit,
|
||||
* update allocated and compressed size.
|
||||
*/
|
||||
if (!a->lowest_vcn) {
|
||||
int sparse;
|
||||
|
||||
/* Update allocated size. */
|
||||
a->allocated_size = cpu_to_sle64(na->allocated_size);
|
||||
/* Update sparse bit. */
|
||||
sparse = ntfs_rl_sparse(na->rl);
|
||||
if (sparse == -1) {
|
||||
ntfs_log_trace("Bad runlist.\n");
|
||||
err = EIO;
|
||||
goto put_err_out;
|
||||
}
|
||||
/* Attribute become sparse. */
|
||||
if (sparse && !(a->flags & (ATTR_IS_SPARSE |
|
||||
ATTR_IS_COMPRESSED))) {
|
||||
/*
|
||||
* We need to move attribute to another mft
|
||||
* record, if attribute is to small to add
|
||||
* compressed_size field to it and we have no
|
||||
* free space in the current mft record.
|
||||
*/
|
||||
if ((le32_to_cpu(a->length) - le16_to_cpu(
|
||||
a->mapping_pairs_offset)
|
||||
== 8) && !(le32_to_cpu(
|
||||
m->bytes_allocated) -
|
||||
le32_to_cpu(m->bytes_in_use))) {
|
||||
if (!NInoAttrList(na->ni)) {
|
||||
ntfs_attr_put_search_ctx(ctx);
|
||||
if (ntfs_inode_add_attrlist(
|
||||
na->ni))
|
||||
return -1;
|
||||
goto retry;
|
||||
}
|
||||
if (ntfs_attr_record_move_away(ctx,
|
||||
8)) {
|
||||
ntfs_log_trace("Failed to move "
|
||||
"attribute to another "
|
||||
"extent. Aborting..\n");
|
||||
err = errno;
|
||||
goto put_err_out;
|
||||
}
|
||||
ntfs_attr_put_search_ctx(ctx);
|
||||
goto retry;
|
||||
}
|
||||
if (!(le32_to_cpu(a->length) - le16_to_cpu(
|
||||
a->mapping_pairs_offset))) {
|
||||
ntfs_log_trace("Size of the space "
|
||||
"allocated for mapping "
|
||||
"pairs should not be 0."
|
||||
" Aborting ...\n");
|
||||
err = EIO;
|
||||
goto put_err_out;
|
||||
}
|
||||
NAttrSetSparse(na);
|
||||
a->flags |= ATTR_IS_SPARSE;
|
||||
a->compression_unit = 4; /* Windows set it so,
|
||||
even if attribute
|
||||
is not actually
|
||||
compressed. */
|
||||
memmove((u8*)a + le16_to_cpu(a->name_offset) +
|
||||
8, (u8*)a + le16_to_cpu(a->name_offset),
|
||||
a->name_length * sizeof(ntfschar));
|
||||
a->name_offset = cpu_to_le16(le16_to_cpu(
|
||||
a->name_offset) + 8);
|
||||
a->mapping_pairs_offset =
|
||||
cpu_to_le16(le16_to_cpu(
|
||||
a->mapping_pairs_offset) + 8);
|
||||
}
|
||||
/* Attribute no longer sparse. */
|
||||
if (!sparse && (a->flags & ATTR_IS_SPARSE) &&
|
||||
!(a->flags & ATTR_IS_COMPRESSED)) {
|
||||
NAttrClearSparse(na);
|
||||
a->flags &= ~ATTR_IS_SPARSE;
|
||||
a->compression_unit = 0;
|
||||
memmove((u8*)a + le16_to_cpu(a->name_offset) -
|
||||
8, (u8*)a + le16_to_cpu(a->name_offset),
|
||||
a->name_length * sizeof(ntfschar));
|
||||
if (le16_to_cpu(a->name_offset) >= 8)
|
||||
a->name_offset = cpu_to_le16(
|
||||
le16_to_cpu(a->name_offset) - 8);
|
||||
a->mapping_pairs_offset =
|
||||
cpu_to_le16(le16_to_cpu(
|
||||
a->mapping_pairs_offset) - 8);
|
||||
}
|
||||
/* Update compressed size if required. */
|
||||
if (sparse) {
|
||||
s64 new_compr_size;
|
||||
|
||||
new_compr_size = ntfs_rl_get_compressed_size(
|
||||
na->ni->vol, na->rl);
|
||||
if (new_compr_size == -1) {
|
||||
err = errno;
|
||||
ntfs_log_trace("BUG! Leaving inconstant"
|
||||
" metadata.\n");
|
||||
goto put_err_out;
|
||||
}
|
||||
na->compressed_size = new_compr_size;
|
||||
a->compressed_size = cpu_to_sle64(
|
||||
new_compr_size);
|
||||
}
|
||||
/*
|
||||
* Set FILE_NAME dirty flag, to update sparse bit and
|
||||
* allocated size in the index.
|
||||
*/
|
||||
if (na->type == AT_DATA && na->name == AT_UNNAMED) {
|
||||
if (sparse)
|
||||
na->ni->allocated_size =
|
||||
na->compressed_size;
|
||||
else
|
||||
na->ni->allocated_size =
|
||||
na->allocated_size;
|
||||
NInoFileNameSetDirty(na->ni);
|
||||
}
|
||||
err = ntfs_attr_update_meta(a, na, m, ctx);
|
||||
switch (err) {
|
||||
case -1: return -1;
|
||||
case -2: goto retry;
|
||||
case -3: goto put_err_out;
|
||||
}
|
||||
|
||||
/* Get the size for the rest of mapping pairs array. */
|
||||
mp_size = ntfs_get_size_for_mapping_pairs(na->ni->vol, na->rl,
|
||||
stop_vcn);
|
||||
|
|
Loading…
Reference in New Issue