Fixed cluster mapping ahead of mapped runlist

A corner case was wrong and could cause aborted writes with error
"Run lists overlap. Cannot merge" when the clusters required by the
write are described in different MFT extents.
This can only happen in very fragmented files when the cluster size
is smaller than 4096 bytes. It does not cause any metadata corruption.
This commit is contained in:
Jean-Pierre André 2011-03-01 12:14:53 +01:00
parent e20c1df1e5
commit 402924cc50

View File

@ -603,6 +603,7 @@ static int ntfs_attr_map_partial_runlist(ntfs_attr *na, VCN vcn)
VCN last_vcn; VCN last_vcn;
VCN highest_vcn; VCN highest_vcn;
VCN needed; VCN needed;
VCN existing_vcn;
runlist_element *rl; runlist_element *rl;
ATTR_RECORD *a; ATTR_RECORD *a;
BOOL startseen; BOOL startseen;
@ -612,6 +613,8 @@ static int ntfs_attr_map_partial_runlist(ntfs_attr *na, VCN vcn)
if (lcn >= 0 || lcn == LCN_HOLE || lcn == LCN_ENOENT) if (lcn >= 0 || lcn == LCN_HOLE || lcn == LCN_ENOENT)
return 0; return 0;
existing_vcn = (na->rl ? na->rl->vcn : -1);
ctx = ntfs_attr_get_search_ctx(na->ni, NULL); ctx = ntfs_attr_get_search_ctx(na->ni, NULL);
if (!ctx) if (!ctx)
return -1; return -1;
@ -643,6 +646,11 @@ static int ntfs_attr_map_partial_runlist(ntfs_attr *na, VCN vcn)
needed = highest_vcn + 1; needed = highest_vcn + 1;
if (!a->lowest_vcn) if (!a->lowest_vcn)
startseen = TRUE; startseen = TRUE;
/* reaching a previously allocated part ? */
if ((existing_vcn >= 0)
&& (needed >= existing_vcn)) {
needed = last_vcn;
}
} }
} else } else
rl = (runlist_element*)NULL; rl = (runlist_element*)NULL;