Fixed updating compressed sizes

PERMISSION_HANDLING_BRANCH
Jean-Pierre André 2010-07-22 15:00:37 +02:00
parent 04c561a0d1
commit 400632dea5
2 changed files with 42 additions and 7 deletions

View File

@ -1228,6 +1228,8 @@ static int ntfs_attr_fill_hole(ntfs_attr *na, s64 count, s64 *ofs,
lcn_seek_from, DATA_ZONE);
if (!rlc)
goto err_out;
if (na->data_flags & (ATTR_COMPRESSION_MASK | ATTR_IS_SPARSE))
na->compressed_size += need << vol->cluster_size_bits;
*rl = ntfs_runlists_merge(na->rl, rlc);
/*
@ -5273,7 +5275,7 @@ static int ntfs_attr_update_meta(ATTR_RECORD *a, ntfs_attr *na, MFT_RECORD *m,
* allocated size in the index.
*/
if (na->type == AT_DATA && na->name == AT_UNNAMED) {
if (sparse)
if (sparse || (na->data_flags & ATTR_COMPRESSION_MASK))
na->ni->allocated_size = na->compressed_size;
else
na->ni->allocated_size = na->allocated_size;
@ -5300,6 +5302,7 @@ static int ntfs_attr_update_mapping_pairs_i(ntfs_attr *na, VCN from_vcn)
const runlist_element *stop_rl;
int err, mp_size, cur_max_mp_size, exp_max_mp_size, ret = -1;
BOOL finished_build;
BOOL first_updated = FALSE;
retry:
if (!na || !na->rl) {
@ -5334,6 +5337,8 @@ retry:
CASE_SENSITIVE, from_vcn, NULL, 0, ctx)) {
a = ctx->attr;
m = ctx->mrec;
if (!a->lowest_vcn)
first_updated = TRUE;
/*
* If runlist is updating not from the beginning, then set
* @stop_vcn properly, i.e. to the lowest vcn of record that
@ -5483,6 +5488,34 @@ retry:
ntfs_log_perror("%s: Attribute lookup failed", __FUNCTION__);
goto put_err_out;
}
/*
* If the base extent was skipped in the above process,
* we still may have to update the sizes.
*/
if (!first_updated) {
le16 spcomp;
ntfs_attr_reinit_search_ctx(ctx);
if (!ntfs_attr_lookup(na->type, na->name, na->name_len,
CASE_SENSITIVE, 0, NULL, 0, ctx)) {
a = ctx->attr;
a->allocated_size = cpu_to_sle64(na->allocated_size);
spcomp = na->data_flags
& (ATTR_IS_COMPRESSED | ATTR_IS_SPARSE);
if (spcomp)
a->compressed_size = cpu_to_sle64(na->compressed_size);
if ((na->type == AT_DATA) && (na->name == AT_UNNAMED)) {
na->ni->allocated_size
= (spcomp
? na->compressed_size
: na->allocated_size);
NInoFileNameSetDirty(na->ni);
}
} else {
ntfs_log_error("Failed to update sizes in base extent\n");
goto put_err_out;
}
}
/* Deallocate not used attribute extents and return with success. */
if (finished_build) {

View File

@ -1157,16 +1157,14 @@ static int ntfs_compress_overwr_free(ntfs_attr *na, runlist_element *rl,
BOOL threeparts;
/* free the unneeded clusters from initial run, then freerl */
freed = freelength;
threeparts = FALSE;
if (freed > freecnt) {
threeparts = TRUE;
freed = freecnt;
}
threeparts = (freelength > freecnt);
freed = 0;
frl = freerl;
if (freelength) {
res = ntfs_cluster_free_basic(vol,freelcn,
(threeparts ? freecnt : freelength));
if (!res)
freed += (threeparts ? freecnt : freelength);
if (!usedcnt) {
holes++;
freerl--;
@ -1199,6 +1197,7 @@ static int ntfs_compress_overwr_free(ntfs_attr *na, runlist_element *rl,
}
frl++;
}
na->compressed_size -= freed << vol->cluster_size_bits;
switch (holes) {
case 0 :
/* there are no hole, must insert one */
@ -1310,6 +1309,7 @@ static int ntfs_compress_overwr_free(ntfs_attr *na, runlist_element *rl,
*++xrl = *frl++;
}
*++xrl = *frl; /* terminator */
na->compressed_size -= freed << vol->cluster_size_bits;
}
return (res);
}
@ -1425,6 +1425,8 @@ static int ntfs_compress_free(ntfs_attr *na, runlist_element *rl,
/* free the hole */
res = ntfs_cluster_free_from_rl(vol,freerl);
if (!res) {
na->compressed_size -= freecnt
<< vol->cluster_size_bits;
if (mergeholes) {
/* merge with adjacent hole */
freerl--;