Matt McCutchen's Web Site
/
rsync
/
rsync.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Make sure that the hashed hard-link numbers from different file
[rsync/rsync.git]
/
flist.c
diff --git
a/flist.c
b/flist.c
index
688117c
..
dc06f05
100644
(file)
--- a/
flist.c
+++ b/
flist.c
@@
-115,6
+115,7
@@
static char tmp_sum[MAX_DIGEST_LEN];
static char empty_sum[MAX_DIGEST_LEN];
static int flist_count_offset; /* for --delete --progress */
static int dir_count = 0;
static char empty_sum[MAX_DIGEST_LEN];
static int flist_count_offset; /* for --delete --progress */
static int dir_count = 0;
+static int high_hlink_ndx;
static void clean_flist(struct file_list *flist, int strip_root);
static void output_flist(struct file_list *flist);
static void clean_flist(struct file_list *flist, int strip_root);
static void output_flist(struct file_list *flist);
@@
-467,7
+468,8
@@
static void send_file_entry(int f, struct file_struct *file, int ndx, int first_
struct ht_int64_node *np = idev_find(tmp_dev, tmp_ino);
first_hlink_ndx = (int32)(long)np->data - 1;
if (first_hlink_ndx < 0) {
struct ht_int64_node *np = idev_find(tmp_dev, tmp_ino);
first_hlink_ndx = (int32)(long)np->data - 1;
if (first_hlink_ndx < 0) {
- np->data = (void*)(long)(ndx + first_ndx + 1);
+ high_hlink_ndx = ndx + first_ndx;
+ np->data = (void*)(long)(high_hlink_ndx + 1);
xflags |= XMIT_HLINK_FIRST;
}
xflags |= XMIT_HLINKED;
xflags |= XMIT_HLINK_FIRST;
}
xflags |= XMIT_HLINKED;
@@
-941,9
+943,11
@@
static struct file_struct *recv_file_entry(struct file_list *flist,
#ifdef SUPPORT_HARD_LINKS
if (preserve_hard_links && xflags & XMIT_HLINKED) {
if (protocol_version >= 30) {
#ifdef SUPPORT_HARD_LINKS
if (preserve_hard_links && xflags & XMIT_HLINKED) {
if (protocol_version >= 30) {
- F_HL_GNUM(file) = xflags & XMIT_HLINK_FIRST
- ? flist->ndx_start + flist->used
- : first_hlink_ndx;
+ if (xflags & XMIT_HLINK_FIRST) {
+ high_hlink_ndx = flist->ndx_start + flist->used;
+ F_HL_GNUM(file) = high_hlink_ndx;
+ } else
+ F_HL_GNUM(file) = first_hlink_ndx;
} else {
static int32 cnt = 0;
struct ht_int64_node *np;
} else {
static int32 cnt = 0;
struct ht_int64_node *np;
@@
-1551,6
+1555,7
@@
void send_extra_file_list(int f, int at_least)
while (future_cnt < at_least) {
struct file_struct *file = dir_flist->sorted[send_dir_ndx];
int dir_ndx, dstart = dir_count;
while (future_cnt < at_least) {
struct file_struct *file = dir_flist->sorted[send_dir_ndx];
int dir_ndx, dstart = dir_count;
+ const char *pathname = F_PATHNAME(file);
int32 *dp;
flist = flist_new(0, "send_extra_file_list");
int32 *dp;
flist = flist_new(0, "send_extra_file_list");
@@
-1575,7
+1580,8
@@
void send_extra_file_list(int f, int at_least)
&& dir_flist->sorted[dir_ndx]->flags & FLAG_DUPLICATE) {
send_dir_ndx = dir_ndx;
file = dir_flist->sorted[dir_ndx];
&& dir_flist->sorted[dir_ndx]->flags & FLAG_DUPLICATE) {
send_dir_ndx = dir_ndx;
file = dir_flist->sorted[dir_ndx];
- send1extra(f, file, flist);
+ if (F_PATHNAME(file) != pathname)
+ send1extra(f, file, flist);
dp = F_DIR_NODE_P(file);
}
dp = F_DIR_NODE_P(file);
}
@@
-1791,16
+1797,11
@@
struct file_list *send_file_list(int f, int argc, char *argv[])
dirlen = dir ? strlen(dir) : 0;
if (dirlen != lastdir_len || memcmp(lastdir, dir, dirlen) != 0) {
if (!push_pathname(dir ? strdup(dir) : NULL, dirlen))
dirlen = dir ? strlen(dir) : 0;
if (dirlen != lastdir_len || memcmp(lastdir, dir, dirlen) != 0) {
if (!push_pathname(dir ? strdup(dir) : NULL, dirlen))
-
goto push_error
;
+
continue
;
lastdir = pathname;
lastdir_len = pathname_len;
lastdir = pathname;
lastdir_len = pathname_len;
- } else if (!push_pathname(lastdir, lastdir_len)) {
- push_error:
- io_error |= IOERR_GENERAL;
- rsyserr(FERROR, errno, "push_dir %s failed in %s",
- full_fname(dir), curr_dir);
+ } else if (!push_pathname(lastdir, lastdir_len))
continue;
continue;
- }
if (fn != fbuf)
memmove(fbuf, fn, len + 1);
if (fn != fbuf)
memmove(fbuf, fn, len + 1);
@@
-2205,6
+2206,8
@@
struct file_list *flist_new(int flags, char *msg)
flist->file_pool = first_flist->file_pool;
flist->ndx_start = first_flist->prev->ndx_end + 2;
flist->file_pool = first_flist->file_pool;
flist->ndx_start = first_flist->prev->ndx_end + 2;
+ if (flist->ndx_start <= high_hlink_ndx)
+ flist->ndx_start = high_hlink_ndx + 1;
flist->prev = first_flist->prev;
flist->prev->next = first_flist->prev = flist;
flist->prev = first_flist->prev;
flist->prev->next = first_flist->prev = flist;
@@
-2303,19
+2306,20
@@
static void clean_flist(struct file_list *flist, int strip_root)
int keep, drop;
/* If one is a dir and the other is not, we want to
* keep the dir because it might have contents in the
int keep, drop;
/* If one is a dir and the other is not, we want to
* keep the dir because it might have contents in the
- * list. */
+ * list.
Otherwise keep the first one.
*/
if (S_ISDIR(file->mode)) {
struct file_struct *fp = flist->sorted[j];
if (S_ISDIR(file->mode)) {
struct file_struct *fp = flist->sorted[j];
- if (!S_ISDIR(fp->mode))
+ if (!S_ISDIR(fp->mode)
|| !(fp->flags & FLAG_XFER_DIR)
)
keep = i, drop = j;
keep = i, drop = j;
- else
+ else {
+ if (am_sender)
+ file->flags |= FLAG_DUPLICATE;
keep = j, drop = i;
keep = j, drop = i;
+ }
} else
keep = j, drop = i;
} else
keep = j, drop = i;
- if (am_sender)
- flist->sorted[drop]->flags |= FLAG_DUPLICATE;
- else {
+ if (!am_sender) {
if (verbose > 1) {
rprintf(FINFO,
"removing duplicate name %s from file list (%d)\n",
if (verbose > 1) {
rprintf(FINFO,
"removing duplicate name %s from file list (%d)\n",