From 402924cc50293b153f9742cd0eb7f1264ce3d81c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Pierre=20Andr=C3=A9?= Date: Tue, 1 Mar 2011 12:14:53 +0100 Subject: [PATCH] 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. --- libntfs-3g/attrib.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libntfs-3g/attrib.c b/libntfs-3g/attrib.c index e366c204..e9e66244 100644 --- a/libntfs-3g/attrib.c +++ b/libntfs-3g/attrib.c @@ -603,6 +603,7 @@ static int ntfs_attr_map_partial_runlist(ntfs_attr *na, VCN vcn) VCN last_vcn; VCN highest_vcn; VCN needed; + VCN existing_vcn; runlist_element *rl; ATTR_RECORD *a; 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) return 0; + existing_vcn = (na->rl ? na->rl->vcn : -1); + ctx = ntfs_attr_get_search_ctx(na->ni, NULL); if (!ctx) return -1; @@ -643,6 +646,11 @@ static int ntfs_attr_map_partial_runlist(ntfs_attr *na, VCN vcn) needed = highest_vcn + 1; if (!a->lowest_vcn) startseen = TRUE; + /* reaching a previously allocated part ? */ + if ((existing_vcn >= 0) + && (needed >= existing_vcn)) { + needed = last_vcn; + } } } else rl = (runlist_element*)NULL;