mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-05-06 14:05:51 -04:00
Detect and report when open or opendir succeed but read and
readdir fail caused by network filesystems issues and truncated files. Thanks to David Norwood and Michael Brown
This commit is contained in:
4
NEWS
4
NEWS
@@ -92,6 +92,10 @@ Changes since version 2.5.6:
|
||||
same path. A directory still cannot be replaced by a
|
||||
regular file unless --delete specified. (J.W. Schultz)
|
||||
|
||||
* Detect and report when open or opendir succeed but read and
|
||||
readdir fail caused by network filesystems issues and truncated
|
||||
files. (David Norwood, Michael Brown, J.W. Schultz)
|
||||
|
||||
INTERNAL:
|
||||
|
||||
* Eliminated vestigial support for old versions that we stopped
|
||||
|
||||
14
fileio.c
14
fileio.c
@@ -115,6 +115,7 @@ struct map_struct *map_file(int fd,OFF_T len)
|
||||
map->p_offset = 0;
|
||||
map->p_fd_offset = 0;
|
||||
map->p_len = 0;
|
||||
map->status = 0;
|
||||
|
||||
return map;
|
||||
}
|
||||
@@ -191,7 +192,11 @@ char *map_ptr(struct map_struct *map,OFF_T offset,int len)
|
||||
}
|
||||
|
||||
if ((nread=read(map->fd,map->p + read_offset,read_size)) != read_size) {
|
||||
if (nread < 0) nread = 0;
|
||||
if (nread < 0) {
|
||||
nread = 0;
|
||||
if (!map->status)
|
||||
map->status = errno;
|
||||
}
|
||||
/* the best we can do is zero the buffer - the file
|
||||
has changed mid transfer! */
|
||||
memset(map->p+read_offset+nread, 0, read_size - nread);
|
||||
@@ -206,13 +211,18 @@ char *map_ptr(struct map_struct *map,OFF_T offset,int len)
|
||||
}
|
||||
|
||||
|
||||
void unmap_file(struct map_struct *map)
|
||||
int unmap_file(struct map_struct *map)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (map->p) {
|
||||
free(map->p);
|
||||
map->p = NULL;
|
||||
}
|
||||
ret = map->status;
|
||||
memset(map, 0, sizeof(*map));
|
||||
free(map);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
11
flist.c
11
flist.c
@@ -877,14 +877,19 @@ static void send_directory(int f, struct file_list *flist, char *dir)
|
||||
}
|
||||
}
|
||||
|
||||
for (di = readdir(d); di; di = readdir(d)) {
|
||||
for (errno = 0, di = readdir(d); di; errno = 0, di = readdir(d)) {
|
||||
char *dname = d_name(di);
|
||||
if (dname[0] == '.' && (dname[1] == '\0' ||
|
||||
(dname[1] == '.' && dname[2] == '\0')))
|
||||
if (dname[0] == '.' && (dname[1] == '\0'
|
||||
|| (dname[1] == '.' && dname[2] == '\0')))
|
||||
continue;
|
||||
strlcpy(p, dname, MAXPATHLEN - l);
|
||||
send_file_name(f, flist, fname, recurse, 0);
|
||||
}
|
||||
if (errno) {
|
||||
io_error = 1;
|
||||
rprintf(FERROR, "readdir(%s): (%d) %s\n",
|
||||
dir, errno, strerror(errno));
|
||||
}
|
||||
|
||||
if (local_exclude_list)
|
||||
free_exclude_list(&local_exclude_list); /* Zeros pointer too */
|
||||
|
||||
18
rsync.c
18
rsync.c
@@ -88,10 +88,10 @@ int delete_file(char *fname)
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (di=readdir(d); di; di=readdir(d)) {
|
||||
for (errno = 0, di = readdir(d); di; errno = 0, di = readdir(d)) {
|
||||
char *dname = d_name(di);
|
||||
if (strcmp(dname,".")==0 ||
|
||||
strcmp(dname,"..")==0)
|
||||
if (strcmp(dname,".") == 0
|
||||
|| strcmp(dname,"..") == 0)
|
||||
continue;
|
||||
snprintf(buf, sizeof(buf), "%s/%s", fname, dname);
|
||||
if (verbose > 0)
|
||||
@@ -101,6 +101,12 @@ int delete_file(char *fname)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (errno) {
|
||||
rprintf(FERROR, "delete_file: readdir(%s): (%d) %s\n",
|
||||
fname, errno, strerror(errno));
|
||||
closedir(d);
|
||||
return -1;
|
||||
}
|
||||
|
||||
closedir(d);
|
||||
|
||||
@@ -148,7 +154,7 @@ static int is_in_group(gid_t gid)
|
||||
}
|
||||
|
||||
int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
|
||||
int report)
|
||||
int report)
|
||||
{
|
||||
int updated = 0;
|
||||
STRUCT_STAT st2;
|
||||
@@ -218,7 +224,7 @@ int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if (verbose > 1 && report) {
|
||||
if (updated)
|
||||
rprintf(FINFO,"%s\n",fname);
|
||||
@@ -245,7 +251,7 @@ void finish_transfer(char *fname, char *fnametmp, struct file_struct *file)
|
||||
/* move tmp file over real file */
|
||||
if (robust_rename(fnametmp,fname) != 0) {
|
||||
if (errno == EXDEV) {
|
||||
/* rename failed on cross-filesystem link.
|
||||
/* rename failed on cross-filesystem link.
|
||||
Copy the file instead. */
|
||||
if (copy_file(fnametmp,fname, file->mode & INITACCESSPERMS)) {
|
||||
rprintf(FERROR, "copy %s -> \"%s\": %s\n",
|
||||
|
||||
14
rsync.h
14
rsync.h
@@ -416,9 +416,17 @@ struct sum_struct {
|
||||
};
|
||||
|
||||
struct map_struct {
|
||||
char *p;
|
||||
int fd,p_size,p_len;
|
||||
OFF_T file_size, p_offset, p_fd_offset;
|
||||
char *p; /* Window pointer */
|
||||
int fd; /* File Descriptor */
|
||||
int p_size; /* Window size at allocation */
|
||||
int p_len; /* Window size after fill */
|
||||
/* p_size and p_len could be
|
||||
* consolodated by using a local
|
||||
* variable in map_ptr() */
|
||||
int status; /* first errno from read errors */
|
||||
OFF_T file_size; /* File size (from stat) */
|
||||
OFF_T p_offset; /* Window start */
|
||||
OFF_T p_fd_offset; /* offset of cursor in fd ala lseek */
|
||||
};
|
||||
|
||||
#define MATCHFLG_WILD 0x0001 /* pattern has '*', '[', and/or '?' */
|
||||
|
||||
12
sender.c
12
sender.c
@@ -277,7 +277,17 @@ void send_files(struct file_list *flist, int f_out, int f_in)
|
||||
}
|
||||
|
||||
if (!read_batch) { /* dw */
|
||||
if (buf) unmap_file(buf);
|
||||
if (buf) {
|
||||
j = unmap_file(buf);
|
||||
if (j) {
|
||||
io_error = 1;
|
||||
rprintf(FERROR,
|
||||
"read errors mapping %s: (%d) %s\n",
|
||||
full_fname(fname),
|
||||
j,
|
||||
strerror(j));
|
||||
}
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user