Changes by: flatcap
Update of /cvsroot/linux-ntfs/ntfsprogs/libntfs
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17705/libntfs
Modified Files:
runlist.c
Log Message:
runlist behaviour changed! please check your applications.
test case 16, where a run is added beyond the end of a file, now behaves
differently. the discontinuity (gap) is now filled with a "not mapped"
run (before the preceding hole would have been extended).
Anton's bugfix applied and tested
minor code tidyups
loads more comments in runlist_{insert,append,split,replace}
test cases checked and updated where necessary
valgrind happy
Index: runlist.c
===================================================================
RCS file: /cvsroot/linux-ntfs/ntfsprogs/libntfs/runlist.c,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -p -r1.55 -r1.56
--- runlist.c 13 Sep 2005 18:51:16 -0000 1.55
+++ runlist.c 15 Sep 2005 23:42:02 -0000 1.56
@@ -166,8 +166,8 @@ static __inline__ void __ntfs_rl_merge(r
static __inline__ runlist_element *ntfs_rl_append(runlist_element *dst,
int dsize, runlist_element *src, int ssize, int loc)
{
- BOOL right;
- int magic;
+ BOOL right; /* Right end of @src needs merging */
+ int marker; /* End of the inserted runs */
if (!dst || !src) {
Dputs("Eeek. ntfs_rl_append() invoked with NULL pointer!");
@@ -181,7 +181,7 @@ static __inline__ runlist_element *ntfs_
/* Space required: @dst size + @src size, less one if we merged. */
dst = ntfs_rl_realloc(dst, dsize, dsize + ssize - right);
if (!dst)
- return dst;
+ return NULL;
/*
* We are guaranteed to succeed from here so can start modifying the
* original runlists.
@@ -191,19 +191,19 @@ static __inline__ runlist_element *ntfs_
if (right)
__ntfs_rl_merge(src + ssize - 1, dst + loc + 1);
- /* FIXME: What does this mean? (AIA) */
- magic = loc + ssize;
+ /* marker - First run after the @src runs that have been inserted */
+ marker = loc + ssize + 1;
/* Move the tail of @dst out of the way, then copy in @src. */
- ntfs_rl_mm(dst, magic + 1, loc + 1 + right, dsize - loc - 1 - right);
+ ntfs_rl_mm(dst, marker, loc + 1 + right, dsize - loc - 1 - right);
ntfs_rl_mc(dst, loc + 1, src, 0, ssize);
/* Adjust the size of the preceding hole. */
dst[loc].length = dst[loc + 1].vcn - dst[loc].vcn;
/* We may have changed the length of the file, so fix the end marker */
- if (dst[magic + 1].lcn == LCN_ENOENT)
- dst[magic + 1].vcn = dst[magic].vcn + dst[magic].length;
+ if (dst[marker].lcn == LCN_ENOENT)
+ dst[marker].vcn = dst[marker-1].vcn + dst[marker-1].length;
return dst;
}
@@ -233,10 +233,9 @@ static __inline__ runlist_element *ntfs_
static __inline__ runlist_element *ntfs_rl_insert(runlist_element *dst,
int dsize, runlist_element *src, int ssize, int loc)
{
- BOOL left = FALSE;
- BOOL disc = FALSE; /* Discontinuity */
- BOOL hole = FALSE; /* Following a hole */
- int magic;
+ BOOL left = FALSE; /* Left end of @src needs merging */
+ BOOL disc = FALSE; /* Discontinuity between @dst and @src */
+ int marker; /* End of the inserted runs */
if (!dst || !src) {
Dputs("Eeek. ntfs_rl_insert() invoked with NULL pointer!");
@@ -245,9 +244,7 @@ static __inline__ runlist_element *ntfs_
}
/* disc => Discontinuity between the end of @dst and the start of @src.
- * This means we might need to insert a hole.
- * hole => @dst ends with a hole or an unmapped region which we can
- * extend to match the discontinuity.
+ * This means we might need to insert a "notmapped" run.
*/
if (loc == 0)
disc = (src[0].vcn > 0);
@@ -261,16 +258,14 @@ static __inline__ runlist_element *ntfs_
merged_length += src->length;
disc = (src[0].vcn > dst[loc - 1].vcn + merged_length);
- if (disc)
- hole = (dst[loc - 1].lcn == LCN_HOLE);
}
/* Space required: @dst size + @src size, less one if we merged, plus
- * one if there was a discontinuity, less one for a trailing hole.
+ * one if there was a discontinuity.
*/
- dst = ntfs_rl_realloc(dst, dsize, dsize + ssize - left + disc - hole);
+ dst = ntfs_rl_realloc(dst, dsize, dsize + ssize - left + disc);
if (!dst)
- return dst;
+ return NULL;
/*
* We are guaranteed to succeed from here so can start modifying the
* original runlist.
@@ -279,40 +274,34 @@ static __inline__ runlist_element *ntfs_
if (left)
__ntfs_rl_merge(dst + loc - 1, src);
- /* FIXME: What does this mean? (AIA) */
- magic = loc + ssize - left + disc - hole;
+ /*
+ * marker - First run after the @src runs that have been inserted
+ * 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.
+ * If "disc", then @dst and @src don't meet and we need an extra run to fill the gap.
+ */
+ marker = loc + ssize - left + disc;
/* Move the tail of @dst out of the way, then copy in @src. */
- ntfs_rl_mm(dst, magic, loc, dsize - loc);
- ntfs_rl_mc(dst, loc + disc - hole, src, left, ssize - left);
+ ntfs_rl_mm(dst, marker, loc, dsize - loc);
+ ntfs_rl_mc(dst, loc + disc, src, left, ssize - left);
- /* Adjust the VCN of the last run ... */
- if (dst[magic].lcn <= LCN_HOLE)
- dst[magic].vcn = dst[magic - 1].vcn + dst[magic - 1].length;
+ /* Adjust the VCN of the first run after the insertion ... */
+ dst[marker].vcn = dst[marker - 1].vcn + dst[marker - 1].length;
/* ... and the length. */
- if (dst[magic].lcn == LCN_HOLE || dst[magic].lcn == LCN_RL_NOT_MAPPED)
- dst[magic].length = dst[magic + 1].vcn - dst[magic].vcn;
+ if (dst[marker].lcn == LCN_HOLE || dst[marker].lcn == LCN_RL_NOT_MAPPED)
+ dst[marker].length = dst[marker + 1].vcn - dst[marker].vcn;
/* Writing beyond the end of the file and there's a discontinuity. */
if (disc) {
- if (hole)
- dst[loc - 1].length = dst[loc].vcn - dst[loc - 1].vcn;
- else {
- if (loc > 0) {
- dst[loc].vcn = dst[loc - 1].vcn +
- dst[loc - 1].length;
- dst[loc].length = dst[loc + 1].vcn -
- dst[loc].vcn;
- } else {
- dst[loc].vcn = 0;
- dst[loc].length = dst[loc + 1].vcn;
- }
- dst[loc].lcn = LCN_RL_NOT_MAPPED;
+ if (loc > 0) {
+ dst[loc].vcn = dst[loc - 1].vcn + dst[loc - 1].length;
+ dst[loc].length = dst[loc + 1].vcn - dst[loc].vcn;
+ } else {
+ dst[loc].vcn = 0;
+ dst[loc].length = dst[loc + 1].vcn;
}
-
- if (dst[magic].lcn == LCN_ENOENT)
- dst[magic].vcn = dst[magic - 1].vcn +
- dst[magic - 1].length;
+ dst[loc].lcn = LCN_RL_NOT_MAPPED;
}
return dst;
}
@@ -341,9 +330,9 @@ static __inline__ runlist_element *ntfs_
static __inline__ runlist_element *ntfs_rl_replace(runlist_element *dst,
int dsize, runlist_element *src, int ssize, int loc)
{
- BOOL left = FALSE;
- BOOL right;
- int magic;
+ BOOL left = FALSE; /* Left end of @src needs merging */
+ BOOL right; /* Right end of @src needs merging */
+ int marker; /* End of the inserted runs */
if (!dst || !src) {
Dputs("Eeek. ntfs_rl_replace() invoked with NULL pointer!");
@@ -361,7 +350,7 @@ static __inline__ runlist_element *ntfs_
*/
dst = ntfs_rl_realloc(dst, dsize, dsize + ssize - left - right);
if (!dst)
- return dst;
+ return NULL;
/*
* We are guaranteed to succeed from here so can start modifying the
* original runlists.
@@ -371,16 +360,21 @@ static __inline__ runlist_element *ntfs_
if (left)
__ntfs_rl_merge(dst + loc - 1, src);
- /* FIXME: What does this mean? (AIA) */
- magic = loc + ssize - left;
+ /*
+ * marker - First run after the @src runs that have been inserted
+ * 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, magic, loc + right + 1, dsize - loc - right - 1);
+ ntfs_rl_mm(dst, marker, loc + right + 1, dsize - loc - right - 1);
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[magic].lcn == LCN_ENOENT))
- dst[magic].vcn = dst[magic - 1].vcn + dst[magic - 1].length;
+ if (((dsize - loc - right - 1) > 0) && (dst[marker].lcn == LCN_ENOENT))
+ dst[marker].vcn = dst[marker - 1].vcn + dst[marker - 1].length;
+
return dst;
}
@@ -498,6 +492,7 @@ runlist_element *ntfs_runlists_merge(run
/* Scan to the end of the source runlist. */
for (dend = 0; drl[dend].length; dend++)
;
+ dend++;
drl = ntfs_rl_realloc(drl, dend, dend + 1);
if (!drl)
return drl;
@@ -574,7 +569,7 @@ runlist_element *ntfs_runlists_merge(run
(srl[send - 1].vcn + srl[send - 1].length)));
/* Or we'll lose an end marker */
- if (start && finish && (drl[dins].length == 0))
+ if (finish && !drl[dins].length)
ss++;
if (marker && (drl[dins].vcn + drl[dins].length > srl[send - 1].vcn))
finish = FALSE;
@@ -1732,11 +1727,9 @@ static void test_rl_dump_runlist (const
if (ind > -LCN_ENOENT - 1)
ind = 3;
- //printf("%8llx %8s %8llx\n",
printf("%8lld %8s %8lld\n",
rl->vcn, lcn_str[ind], rl->length);
} else
- //printf("%8llx %8llx %8llx\n",
printf("%8lld %8lld %8lld\n",
rl->vcn, rl->lcn, rl->length);
if (!rl->length)
@@ -1834,7 +1827,6 @@ static void test_rl_pure_test (int test,
res = test_rl_runlists_merge (dst, src);
free (res);
- test = 0;
}
/**
|