Skip to content

Commit 7db3934

Browse files
committed
Fix --no-i-r-s-u progress: run prescan before fork + track active files
1 parent da99012 commit 7db3934

File tree

7 files changed

+27
-35
lines changed

7 files changed

+27
-35
lines changed

compat.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ int proper_seed_order = 0;
8282
int inplace_partial = 0;
8383
int do_negotiated_strings = 0;
8484
int xmit_id0_names = 0;
85-
int skip_unchanged_negotiated = 0;
8685

8786
struct name_num_item *xattr_sum_nni;
8887
int xattr_sum_len = 0;
@@ -125,7 +124,6 @@ struct name_num_obj valid_compressions = {
125124
#define CF_INPLACE_PARTIAL_DIR (1<<6)
126125
#define CF_VARINT_FLIST_FLAGS (1<<7)
127126
#define CF_ID0_NAMES (1<<8)
128-
#define CF_SKIP_UNCHANGED (1<<9)
129127

130128
static const char *client_info;
131129

@@ -729,8 +727,6 @@ void setup_protocol(int f_out,int f_in)
729727
compat_flags |= CF_INPLACE_PARTIAL_DIR;
730728
if (strchr(client_info, 'u') != NULL)
731729
compat_flags |= CF_ID0_NAMES;
732-
if (strchr(client_info, 'U') != NULL)
733-
compat_flags |= CF_SKIP_UNCHANGED;
734730
if (strchr(client_info, 'v') != NULL) {
735731
do_negotiated_strings = 1;
736732
compat_flags |= CF_VARINT_FLIST_FLAGS;
@@ -752,9 +748,6 @@ void setup_protocol(int f_out,int f_in)
752748
proper_seed_order = compat_flags & CF_CHKSUM_SEED_FIX ? 1 : 0;
753749
xfer_flags_as_varint = compat_flags & CF_VARINT_FLIST_FLAGS ? 1 : 0;
754750
xmit_id0_names = compat_flags & CF_ID0_NAMES ? 1 : 0;
755-
if (compat_flags & CF_SKIP_UNCHANGED) {
756-
skip_unchanged_negotiated = 1;
757-
}
758751
if (!xfer_flags_as_varint && preserve_crtimes) {
759752
fprintf(stderr, "Both rsync versions must be at least 3.2.0 for --crtimes.\n");
760753
exit_cleanup(RERR_PROTOCOL);

generator.c

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ extern int am_sender;
3434
extern int am_daemon;
3535
extern int inc_recurse;
3636
extern int no_i_r_skip_unchanged;
37-
extern int skip_unchanged_negotiated;
3837
extern int relative_paths;
3938
extern struct stats stats;
4039
extern int implied_dirs;
@@ -2236,14 +2235,14 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo)
22362235

22372236
/* Pre-scan the file list to mark unchanged files and adjust stats.total_size.
22382237
* This allows accurate progress reporting on resumed transfers. */
2239-
static void prescan_for_unchanged(const char *local_name, int f_out)
2238+
void prescan_for_unchanged(const char *local_name)
22402239
{
22412240
int i, active_count = 0, skipped_count = 0;
22422241
char fbuf[MAXPATHLEN];
22432242
STRUCT_STAT st;
22442243

2245-
/* Only prescan if feature was negotiated with remote side */
2246-
if (!no_i_r_skip_unchanged || !skip_unchanged_negotiated || !cur_flist)
2244+
/* Only prescan if feature is enabled */
2245+
if (!no_i_r_skip_unchanged || !cur_flist)
22472246
return;
22482247

22492248
if (DEBUG_GTE(GENR, 1))
@@ -2292,21 +2291,13 @@ static void prescan_for_unchanged(const char *local_name, int f_out)
22922291
}
22932292
}
22942293

2295-
/* Update stats to reflect skipped files */
2294+
/* Update stats to reflect only active files for progress display */
22962295
stats.num_files = active_count;
22972296
stats.num_skipped_files = skipped_count;
22982297

22992298
if (DEBUG_GTE(GENR, 1))
23002299
rprintf(FINFO, "skipped %d unchanged files, %d active, adjusted size: %.2f GB\n",
23012300
skipped_count, active_count, (double)stats.total_size / 1024 / 1024 / 1024);
2302-
2303-
/* Send skipped count and adjusted total_size to sender for accurate progress display */
2304-
if (f_out >= 0 && skip_unchanged_negotiated) {
2305-
char buf[12];
2306-
SIVAL(buf, 0, skipped_count);
2307-
SIVAL64(buf, 4, stats.total_size);
2308-
send_msg(MSG_FLIST_COUNT, buf, 12, -1);
2309-
}
23102301
}
23112302

23122303
void generate_files(int f_out, const char *local_name)
@@ -2364,13 +2355,7 @@ void generate_files(int f_out, const char *local_name)
23642355
}
23652356

23662357
dflt_perms = (ACCESSPERMS & ~orig_umask);
2367-
2368-
/* Pre-scan to mark unchanged files for accurate progress reporting */
2369-
if (no_i_r_skip_unchanged && !skip_unchanged_negotiated) {
2370-
rprintf(FWARNING, "WARNING: --no-i-r-skip-unchanged requested but not supported by remote rsync.\n");
2371-
rprintf(FWARNING, " Falling back to standard --no-i-r behavior (no progress optimization).\n");
2372-
}
2373-
prescan_for_unchanged(local_name, f_out);
2358+
stats.current_active_index = 0;
23742359

23752360
do {
23762361
#ifdef SUPPORT_HARD_LINKS

io.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ extern int daemon_connection;
6060
extern int protocol_version;
6161
extern int remove_source_files;
6262
extern int preserve_hard_links;
63-
extern int skip_unchanged_negotiated;
6463
extern BOOL extra_flist_sending_enabled;
6564
extern BOOL flush_ok_after_signal;
6665
extern struct stats stats;
@@ -1513,17 +1512,15 @@ static void read_a_msg(void)
15131512
iobuf.in_multiplexed = 1;
15141513
break;
15151514
case MSG_FLIST_COUNT:
1516-
if (msg_bytes != 12 || !am_sender || !skip_unchanged_negotiated)
1515+
if (msg_bytes != 12 || !am_sender)
15171516
goto invalid_msg;
15181517
val = raw_read_int();
15191518
stats.num_skipped_files = val;
1520-
/* Adjust total file count to reflect only active files */
15211519
stats.num_files -= val;
1522-
/* Read and update adjusted total_size for accurate progress percentage */
15231520
raw_read_buf((char*)&stats.total_size, 8);
15241521
iobuf.in_multiplexed = 1;
15251522
if (DEBUG_GTE(IO, 1))
1526-
rprintf(FINFO, "[%s] received MSG_FLIST_COUNT: %d skipped, %d active, size: %.2f GB\n",
1523+
rprintf(FINFO, "[%s] received MSG_FLIST_COUNT: %d skipped, %d active, size: %.2f GB\n",
15271524
who_am_i(), val, stats.num_files, (double)stats.total_size / 1024 / 1024 / 1024);
15281525
break;
15291526
case MSG_REDO:

main.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ extern int am_server;
4040
extern int am_sender;
4141
extern int am_daemon;
4242
extern int inc_recurse;
43+
extern int no_i_r_skip_unchanged;
4344
extern int blocking_io;
4445
extern int always_checksum;
4546
extern int remove_source_files;
@@ -1029,6 +1030,18 @@ static int do_recv(int f_in, int f_out, char *local_name)
10291030

10301031
io_flush(FULL_FLUSH);
10311032

1033+
/* Pre-scan for unchanged files before forking so both processes get updated stats */
1034+
prescan_for_unchanged(local_name);
1035+
1036+
/* Send adjusted stats to sender for accurate progress (local→remote transfers) */
1037+
if (no_i_r_skip_unchanged && stats.num_skipped_files > 0) {
1038+
char buf[12];
1039+
SIVAL(buf, 0, stats.num_skipped_files);
1040+
SIVAL64(buf, 4, stats.total_size);
1041+
send_msg(MSG_FLIST_COUNT, buf, 12, 0);
1042+
io_flush(NORMAL_FLUSH);
1043+
}
1044+
10321045
if ((pid = do_fork()) == -1) {
10331046
rsyserr(FERROR, errno, "fork failed in do_recv");
10341047
exit_cleanup(RERR_IPC);

options.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3050,7 +3050,6 @@ int maybe_add_e_option(char *buf, int buf_len)
30503050
buf[x++] = 'I'; /* support inplace_partial behavior */
30513051
buf[x++] = 'v'; /* use varint for flist & compat flags; negotiate checksum */
30523052
buf[x++] = 'u'; /* include name of uid 0 & gid 0 in the id map */
3053-
buf[x++] = 'U'; /* support --no-i-r-skip-unchanged feature */
30543053

30553054
/* NOTE: Avoid using 'V' -- it was represented with the high bit of a write_byte() that became a write_varint(). */
30563055
}

progress.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ static void rprint_progress(OFF_T ofs, OFF_T size, struct timeval *now, int is_l
7878
int len = snprintf(eol, sizeof eol,
7979
" (xfr#%d, %s-chk=%d/%d)\n",
8080
stats.xferred_files, flist_eof ? "to" : "ir",
81-
stats.num_files - (current_file_index - stats.num_skipped_files) - 1,
81+
stats.num_files - stats.current_active_index,
8282
stats.num_files);
8383
if (INFO_GTE(PROGRESS, 2)) {
8484
static int last_len = 0;
@@ -153,6 +153,10 @@ void set_current_file_index(struct file_struct *file, int ndx)
153153
else
154154
current_file_index = ndx;
155155
current_file_index -= cur_flist->flist_num;
156+
157+
/* Track active file index for accurate progress with --no-i-r-skip-unchanged */
158+
if (file && F_IS_ACTIVE(file))
159+
stats.current_active_index++;
156160
}
157161

158162
void instant_progress(const char *fname)

rsync.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ enum msgcode {
269269
MSG_LOG=FLOG, MSG_CLIENT=FCLIENT, /* sibling logging */
270270
MSG_REDO=9, /* reprocess indicated flist index */
271271
MSG_STATS=10, /* message has stats data for generator */
272-
MSG_FLIST_COUNT=11, /* generator sends updated file count to sender */
272+
MSG_FLIST_COUNT=11, /* receiver sends adjusted stats to sender after prescan */
273273
MSG_IO_ERROR=22,/* the sending side had an I/O error */
274274
MSG_IO_TIMEOUT=33,/* tell client about a daemon's timeout value */
275275
MSG_NOOP=42, /* a do-nothing message (legacy protocol-30 only) */
@@ -1046,6 +1046,7 @@ struct stats {
10461046
int deleted_files, deleted_dirs, deleted_symlinks, deleted_devices, deleted_specials;
10471047
int xferred_files;
10481048
int num_skipped_files; /* files marked as unchanged by --no-i-r-skip-unchanged */
1049+
int current_active_index; /* current index among active files (excluding skipped) */
10491050
};
10501051

10511052
struct chmod_mode_struct;

0 commit comments

Comments
 (0)