fix a couple of range bugs (insert,replace)

Anton: fix mergeable - use to merge non-adjacent holes
Anton: factor out "tail" in replace - simplifying code
comment and retest code
edge.strict_endians
flatcap 2005-09-19 20:50:01 +00:00
parent 94be253f74
commit 459f98c2b2
1 changed files with 40 additions and 20 deletions

View File

@ -111,17 +111,21 @@ static __inline__ BOOL ntfs_rl_are_mergeable(runlist_element *dst,
return FALSE;
}
if ((dst->lcn < 0) || (src->lcn < 0)) { /* Are we merging holes? */
if (dst->lcn == LCN_HOLE && src->lcn == LCN_HOLE)
return TRUE;
/* We can merge unmapped regions even if they are misaligned. */
if ((dst->lcn == LCN_RL_NOT_MAPPED) && (src->lcn == LCN_RL_NOT_MAPPED))
return TRUE;
/* If the runs are misaligned, we cannot merge them. */
if ((dst->vcn + dst->length) != src->vcn)
return FALSE;
}
if ((dst->lcn + dst->length) != src->lcn) /* Are the runs contiguous? */
return FALSE;
if ((dst->vcn + dst->length) != src->vcn) /* Are the runs misaligned? */
return FALSE;
return TRUE;
/* If both runs are non-sparse and contiguous, we can merge them. */
if ((dst->lcn >= 0) && (src->lcn >= 0) &&
((dst->lcn + dst->length) == src->lcn))
return TRUE;
/* If we are merging two holes, we can merge them. */
if ((dst->lcn == LCN_HOLE) && (src->lcn == LCN_HOLE))
return TRUE;
/* Cannot merge. */
return FALSE;
}
/**
@ -166,7 +170,7 @@ static __inline__ void __ntfs_rl_merge(runlist_element *dst,
static __inline__ runlist_element *ntfs_rl_append(runlist_element *dst,
int dsize, runlist_element *src, int ssize, int loc)
{
BOOL right; /* Right end of @src needs merging */
BOOL right = FALSE; /* Right end of @src needs merging */
int marker; /* End of the inserted runs */
if (!dst || !src) {
@ -176,7 +180,8 @@ static __inline__ runlist_element *ntfs_rl_append(runlist_element *dst,
}
/* First, check if the right hand end needs merging. */
right = ntfs_rl_are_mergeable(src + ssize - 1, dst + loc + 1);
if ((loc + 1) < dsize)
right = ntfs_rl_are_mergeable(src + ssize - 1, dst + loc + 1);
/* Space required: @dst size + @src size, less one if we merged. */
dst = ntfs_rl_realloc(dst, dsize, dsize + ssize - right);
@ -330,8 +335,9 @@ static __inline__ runlist_element *ntfs_rl_insert(runlist_element *dst,
static __inline__ runlist_element *ntfs_rl_replace(runlist_element *dst,
int dsize, runlist_element *src, int ssize, int loc)
{
BOOL left = FALSE; /* Left end of @src needs merging */
BOOL right; /* Right end of @src needs merging */
BOOL left = FALSE; /* Left end of @src needs merging */
BOOL right = FALSE; /* Right end of @src needs merging */
int tail; /* Start of tail of @dst */
int marker; /* End of the inserted runs */
if (!dst || !src) {
@ -340,13 +346,14 @@ static __inline__ runlist_element *ntfs_rl_replace(runlist_element *dst,
return NULL;
}
/* First, merge the left and right ends, if necessary. */
right = ntfs_rl_are_mergeable(src + ssize - 1, dst + loc + 1);
/* First, see if the left and right ends need merging. */
if ((loc + 1) < dsize)
right = ntfs_rl_are_mergeable(src + ssize - 1, dst + loc + 1);
if (loc > 0)
left = ntfs_rl_are_mergeable(dst + loc - 1, src);
/* Allocate some space. We'll need less if the left, right, or both
* ends were merged.
* ends get merged.
*/
dst = ntfs_rl_realloc(dst, dsize, dsize + ssize - left - right);
if (!dst)
@ -355,24 +362,33 @@ static __inline__ runlist_element *ntfs_rl_replace(runlist_element *dst,
* We are guaranteed to succeed from here so can start modifying the
* original runlists.
*/
/* First, merge the left and right ends, if necessary. */
if (right)
__ntfs_rl_merge(src + ssize - 1, dst + loc + 1);
if (left)
__ntfs_rl_merge(dst + loc - 1, src);
/*
* tail - Offset of the tail of @dst
* Nominally: @tail = @loc + 1 (location, skipping the replaced run)
* If "right", then one of @dst's runs is already merged into @src.
*/
tail = loc + right + 1;
/*
* marker - First run after the @src runs that have been inserted
* Nominally: marker = @loc + @ssize (location + number of runs in @src)
* Nominally: @marker = @loc + @ssize (location + number of runs in @src)
* If "left", then the first run in @src has been merged with one in @dst.
*/
marker = loc + ssize - left;
/* Move the tail of @dst out of the way, then copy in @src. */
ntfs_rl_mm(dst, marker, loc + right + 1, dsize - loc - right - 1);
ntfs_rl_mm(dst, marker, tail, dsize - tail);
ntfs_rl_mc(dst, loc, src, left, ssize - left);
/* We may have changed the length of the file, so fix the end marker */
if (((dsize - loc - right - 1) > 0) && (dst[marker].lcn == LCN_ENOENT))
if (((dsize - tail) > 0) && (dst[marker].lcn == LCN_ENOENT))
dst[marker].vcn = dst[marker - 1].vcn + dst[marker - 1].length;
return dst;
@ -1855,6 +1871,7 @@ static void test_rl_pure (char *contig, char *multi)
static runlist_element file4[] = {
{ 0, -3, 0 } /* NOENT */
};
#if 0
static runlist_element file5[] = {
{ 0, -2, 100 }, /* NOTMAP */
{ 100, 1100, 100 }, /* DATA */
@ -1868,6 +1885,7 @@ static void test_rl_pure (char *contig, char *multi)
{ 100, -2, 100 }, /* NOTMAP */
{ 200, -3, 0 } /* NOENT */
};
#endif
BOOL c, m;
if (strcmp (contig, "contig") == 0)
@ -1907,6 +1925,7 @@ static void test_rl_pure (char *contig, char *multi)
test_rl_pure_test (18, c, m, 140, 40, file3, sizeof (file3));
test_rl_pure_test (19, c, m, 0, 40, file4, sizeof (file4));
test_rl_pure_test (20, c, m, 40, 40, file4, sizeof (file4));
#if 0
test_rl_pure_test (21, c, m, 0, 40, file5, sizeof (file5));
test_rl_pure_test (22, c, m, 40, 40, file5, sizeof (file5));
test_rl_pure_test (23, c, m, 60, 40, file5, sizeof (file5));
@ -1921,6 +1940,7 @@ static void test_rl_pure (char *contig, char *multi)
test_rl_pure_test (32, c, m, 400, 100, file5, sizeof (file5));
test_rl_pure_test (33, c, m, 160, 100, file6, sizeof (file6));
test_rl_pure_test (34, c, m, 100, 140, file6, sizeof (file6));
#endif
}
/**