X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/0d5ebab1d6df5169c5834c02c978fd5bb67421ca..1b502f3ec234bf1045c6bb146f64734d09e81956:/flist.c diff --git a/flist.c b/flist.c index 7208efa4..a167c3b9 100644 --- a/flist.c +++ b/flist.c @@ -87,6 +87,14 @@ extern int filesfrom_convert; extern iconv_t ic_send, ic_recv; #endif +#ifdef HAVE_UTIMENSAT +#ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC +#define ST_MTIME_NSEC st_mtim.tv_nsec +#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC) +#define ST_MTIME_NSEC st_mtimensec +#endif +#endif + #define PTR_SIZE (sizeof (struct file_struct *)) int io_error; @@ -97,6 +105,7 @@ struct file_list *cur_flist, *first_flist, *dir_flist; int send_dir_ndx = -1, send_dir_depth = -1; int flist_cnt = 0; /* how many (non-tmp) file list objects exist */ int file_total = 0; /* total of all active items over all file-lists */ +int file_old_total = 0; /* total of active items that will soon be gone */ int flist_eof = 0; /* all the file-lists are now known */ #define NORMAL_NAME 0 @@ -195,7 +204,7 @@ static int readlink_stat(const char *path, STRUCT_STAT *stp, char *linkbuf) if (link_stat(path, stp, copy_dirlinks) < 0) return -1; if (S_ISLNK(stp->st_mode)) { - int llen = readlink(path, linkbuf, MAXPATHLEN - 1); + int llen = do_readlink(path, linkbuf, MAXPATHLEN - 1); if (llen < 0) return -1; linkbuf[llen] = '\0'; @@ -494,6 +503,8 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file, xflags |= XMIT_SAME_TIME; else modtime = file->modtime; + if (NSEC_BUMP(file) && protocol_version >= 31) + xflags |= XMIT_MOD_NSEC; #ifdef SUPPORT_HARD_LINKS if (tmp_dev != 0) { @@ -576,6 +587,8 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file, else write_int(f, modtime); } + if (xflags & XMIT_MOD_NSEC) + write_varint(f, F_MOD_NSEC(file)); if (!(xflags & XMIT_SAME_MODE)) write_int(f, to_wire_mode(mode)); if (preserve_uid && !(xflags & XMIT_SAME_UID)) { @@ -661,8 +674,7 @@ static void send_file_entry(int f, const char *fname, struct file_struct *file, stats.total_size += F_LENGTH(file); } -static struct file_struct *recv_file_entry(struct file_list *flist, - int xflags, int f) +static struct file_struct *recv_file_entry(int f, struct file_list *flist, int xflags) { static int64 modtime; static mode_t mode; @@ -684,6 +696,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist, int extra_len = file_extra_cnt * EXTRA_LEN; int first_hlink_ndx = -1; int64 file_length; + uint32 modtime_nsec; const char *basename; struct file_struct *file; alloc_pool_t *pool; @@ -767,6 +780,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist, struct file_struct *first = flist->files[first_hlink_ndx - flist->ndx_start]; file_length = F_LENGTH(first); modtime = first->modtime; + modtime_nsec = F_MOD_NSEC(first); mode = first->mode; if (preserve_uid) uid = F_OWNER(first); @@ -800,6 +814,10 @@ static struct file_struct *recv_file_entry(struct file_list *flist, } else modtime = read_int(f); } + if (xflags & XMIT_MOD_NSEC) + modtime_nsec = read_varint(f); + else + modtime_nsec = 0; if (!(xflags & XMIT_SAME_MODE)) mode = from_wire_mode(read_int(f)); @@ -897,6 +915,10 @@ static struct file_struct *recv_file_entry(struct file_list *flist, #if SIZEOF_INT64 >= 8 if (file_length > 0xFFFFFFFFu && S_ISREG(mode)) extra_len += EXTRA_LEN; +#endif +#ifdef HAVE_UTIMENSAT + if (modtime_nsec) + extra_len += EXTRA_LEN; #endif if (file_length < 0) { rprintf(FERROR, "Offset underflow: file-length is negative\n"); @@ -933,6 +955,12 @@ static struct file_struct *recv_file_entry(struct file_list *flist, file->flags |= FLAG_HLINKED; #endif file->modtime = (time_t)modtime; +#ifdef HAVE_UTIMENSAT + if (modtime_nsec) { + file->flags |= FLAG_MOD_NSEC; + OPT_EXTRA(file, 0)->unum = modtime_nsec; + } +#endif file->len32 = (uint32)file_length; #if SIZEOF_INT64 >= 8 if (file_length > 0xFFFFFFFFu && S_ISREG(mode)) { @@ -941,7 +969,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist, exit_cleanup(RERR_UNSUPPORTED); #else file->flags |= FLAG_LENGTH64; - OPT_EXTRA(file, 0)->unum = (uint32)(file_length >> 32); + OPT_EXTRA(file, NSEC_BUMP(file))->unum = (uint32)(file_length >> 32); #endif } #endif @@ -1087,11 +1115,11 @@ static struct file_struct *recv_file_entry(struct file_list *flist, #ifdef SUPPORT_ACLS if (preserve_acls && !S_ISLNK(mode)) - receive_acl(file, f); + receive_acl(f, file); #endif #ifdef SUPPORT_XATTRS if (preserve_xattrs) - receive_xattr(file, f ); + receive_xattr(f, file); #endif if (S_ISREG(mode) || S_ISLNK(mode)) @@ -1271,6 +1299,10 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, linkname_len = 0; #endif +#ifdef ST_MTIME_NSEC + if (st.ST_MTIME_NSEC && protocol_version >= 31) + extra_len += EXTRA_LEN; +#endif #if SIZEOF_CAPITAL_OFF_T >= 8 if (st.st_size > 0xFFFFFFFFu && S_ISREG(st.st_mode)) extra_len += EXTRA_LEN; @@ -1325,11 +1357,17 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, file->flags = flags; file->modtime = st.st_mtime; +#ifdef ST_MTIME_NSEC + if (st.ST_MTIME_NSEC && protocol_version >= 31) { + file->flags |= FLAG_MOD_NSEC; + OPT_EXTRA(file, 0)->unum = st.ST_MTIME_NSEC; + } +#endif file->len32 = (uint32)st.st_size; #if SIZEOF_CAPITAL_OFF_T >= 8 if (st.st_size > 0xFFFFFFFFu && S_ISREG(st.st_mode)) { file->flags |= FLAG_LENGTH64; - OPT_EXTRA(file, 0)->unum = (uint32)(st.st_size >> 32); + OPT_EXTRA(file, NSEC_BUMP(file))->unum = (uint32)(st.st_size >> 32); } #endif file->mode = st.st_mode; @@ -1492,13 +1530,13 @@ static struct file_struct *send_file_name(int f, struct file_list *flist, #ifdef SUPPORT_ACLS if (preserve_acls && !S_ISLNK(file->mode)) { - send_acl(&sx, f); + send_acl(f, &sx); free_acl(&sx); } #endif #ifdef SUPPORT_XATTRS if (preserve_xattrs) { - F_XATTR(file) = send_xattr(&sx, f); + F_XATTR(file) = send_xattr(f, &sx); free_xattr(&sx); } #endif @@ -1905,17 +1943,17 @@ void send_extra_file_list(int f, int at_least) struct file_list *flist; int64 start_write; uint16 prev_flags; - int old_cnt, save_io_error = io_error; + int save_io_error = io_error; if (flist_eof) return; + if (at_least < 0) + at_least = file_total - file_old_total + 1; + /* Keep sending data until we have the requested number of * files in the upcoming file-lists. */ - old_cnt = cur_flist->used; - for (flist = first_flist; flist != cur_flist; flist = flist->next) - old_cnt += flist->used; - while (file_total - old_cnt < at_least) { + while (file_total - file_old_total < at_least) { struct file_struct *file = dir_flist->sorted[send_dir_ndx]; int dir_ndx, dstart = stats.num_dirs; const char *pathname = F_PATHNAME(file); @@ -2402,7 +2440,7 @@ struct file_list *recv_file_list(int f) } flist_expand(flist, 1); - file = recv_file_entry(flist, flags, f); + file = recv_file_entry(f, flist, flags); if (S_ISREG(file->mode)) { /* Already counted */