From d9bea2ddd44fdcfbaf6f153f72d944603560036c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 26 Jun 1996 15:57:54 +0000 Subject: [PATCH] added support for non-mmap operation --- match.c | 36 +++++++++++++++++++++++------------- rsync.c | 23 +++++------------------ rsync.h | 1 + util.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 85 insertions(+), 32 deletions(-) diff --git a/match.c b/match.c index 1591fdc6..ee22ca3e 100644 --- a/match.c +++ b/match.c @@ -87,7 +87,8 @@ static void build_hash_table(struct sum_struct *s) static off_t last_match; -static void matched(int f,struct sum_struct *s,char *buf,off_t len,int offset,int i) +static void matched(int f,struct sum_struct *s,char *buf,off_t len, + int offset,int i) { int n = offset - last_match; @@ -97,8 +98,13 @@ static void matched(int f,struct sum_struct *s,char *buf,off_t len,int offset,in (int)offset,(int)last_match,i,(int)s->sums[i].len,n); if (n > 0) { + int l = 0; write_int(f,n); - write_buf(f,buf+last_match,n); + while (l < n) { + int n1 = MIN(WRITE_BLOCK_SIZE,n-l); + write_buf(f,map_ptr(buf,last_match+l,n1),n1); + l += n1; + } data_transfer += n; } write_int(f,-(i+1)); @@ -114,13 +120,17 @@ static void hash_search(int f,struct sum_struct *s,char *buf,off_t len) int offset,j,k; int end; char sum2[SUM_LENGTH]; - uint32 s1, s2, sum; + uint32 s1, s2, sum; + char *map; if (verbose > 2) fprintf(stderr,"hash search b=%d len=%d\n",s->n,(int)len); k = MIN(len, s->n); - sum = get_checksum1(buf, k); + + map = map_ptr(buf,0,k); + + sum = get_checksum1(map, k); s1 = sum & 0xFFFF; s2 = sum >> 16; if (verbose > 3) @@ -155,14 +165,17 @@ static void hash_search(int f,struct sum_struct *s,char *buf,off_t len) offset,j,i,sum); if (!done_csum2) { - get_checksum2(buf+offset,MIN(s->n,len-offset),sum2); + int l = MIN(s->n,len-offset); + map = map_ptr(buf,offset,l); + get_checksum2(map,l,sum2); done_csum2 = 1; } if (memcmp(sum2,s->sums[i].sum2,SUM_LENGTH) == 0) { matched(f,s,buf,len,offset,i); offset += s->sums[i].len - 1; k = MIN((len-offset), s->n); - sum = get_checksum1(buf+offset, k); + map = map_ptr(buf,offset,k); + sum = get_checksum1(map, k); s1 = sum & 0xFFFF; s2 = sum >> 16; ++matches; @@ -176,21 +189,18 @@ static void hash_search(int f,struct sum_struct *s,char *buf,off_t len) } /* Trim off the first byte from the checksum */ - s1 -= buf[offset]; - s2 -= k * buf[offset]; + map = map_ptr(buf,offset,k+1); + s1 -= map[0]; + s2 -= k * map[0]; /* Add on the next byte (if there is one) to the checksum */ if (k < (len-offset)) { - s1 += buf[offset+k]; + s1 += map[k]; s2 += s1; } else { --k; } - if (verbose > 3) - fprintf(stderr,"s2:s1 = %.4x%.4x sum=%.8x k=%d offset=%d took %x added %x\n", - s2&0xffff, s1&0xffff, get_checksum1(buf+offset+1,k), - k, (int)offset, buf[offset], buf[offset+k]); } while (++offset < end); matched(f,s,buf,len,len,-1); diff --git a/rsync.c b/rsync.c index 0bc7119d..8046b705 100644 --- a/rsync.c +++ b/rsync.c @@ -111,9 +111,10 @@ static struct sum_struct *generate_sums(char *buf,off_t len,int n) for (i=0;isums[i].sum1 = get_checksum1(buf,n1); - get_checksum2(buf,n1,s->sums[i].sum2); + s->sums[i].sum1 = get_checksum1(map,n1); + get_checksum2(map,n1,s->sums[i].sum2); s->sums[i].offset = offset; s->sums[i].len = n1; @@ -124,7 +125,6 @@ static struct sum_struct *generate_sums(char *buf,off_t len,int n) i,(int)s->sums[i].offset,s->sums[i].len,s->sums[i].sum1); len -= n1; - buf += n1; offset += n1; } @@ -363,11 +363,6 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out) if (st.st_size > 0) { buf = map_file(fd,st.st_size); - if (!buf) { - fprintf(stderr,"mmap : %s\n",strerror(errno)); - close(fd); - return; - } } else { buf = NULL; } @@ -420,7 +415,7 @@ static void receive_data(int f_in,char *buf,int fd,char *fname) fprintf(stderr,"chunk[%d] of size %d at %d offset=%d\n", i,len,(int)offset2,(int)offset); - if (write(fd,buf+offset2,len) != len) { + if (write(fd,map_ptr(buf,offset2,len),len) != len) { fprintf(stderr,"write failed on %s : %s\n",fname,strerror(errno)); exit(1); } @@ -529,10 +524,6 @@ int recv_files(int f_in,struct file_list *flist,char *local_name) if (fd1 != -1 && st.st_size > 0) { buf = map_file(fd1,st.st_size); - if (!buf) { - fprintf(stderr,"map_file failed\n"); - return -1; - } } else { buf = NULL; } @@ -546,7 +537,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name) fprintf(stderr,"mktemp %s failed\n",fnametmp); return -1; } - fd2 = open(fnametmp,O_WRONLY|O_CREAT,st.st_mode); + fd2 = open(fnametmp,O_WRONLY|O_CREAT,flist->files[i].mode); if (fd2 == -1) { fprintf(stderr,"open %s : %s\n",fnametmp,strerror(errno)); return -1; @@ -655,10 +646,6 @@ off_t send_files(struct file_list *flist,int f_out,int f_in) if (st.st_size > 0) { buf = map_file(fd,st.st_size); - if (!buf) { - fprintf(stderr,"map_file failed : %s\n",strerror(errno)); - return -1; - } } else { buf = NULL; } diff --git a/rsync.h b/rsync.h index 2b3b6464..9c326e13 100644 --- a/rsync.h +++ b/rsync.h @@ -29,6 +29,7 @@ /* block size to write files in */ #define WRITE_BLOCK_SIZE (32*1024) +#define MAX_MAP_SIZE (4*1024*1024) #define BLOCKING_TIMEOUT 10 diff --git a/util.c b/util.c index df60d0a0..22ca8c2f 100644 --- a/util.c +++ b/util.c @@ -31,16 +31,71 @@ int num_waiting(int fd) return(len); } +static int map_fd = -1; +static off_t map_size = 0; +static char *p = NULL; +static int p_size = 0; +static int p_offset = 0; +static int p_len = 0; + + char *map_file(int fd,off_t len) { - char *ret = (char *)mmap(NULL,len,PROT_READ,MAP_SHARED,fd,0); + char *ret = NULL; +#ifdef HAVE_MMAP + if (len < MAX_MAP_SIZE) + ret = (char *)mmap(NULL,len,PROT_READ,MAP_SHARED,fd,0); +#endif + map_fd = fd; + map_size = len; return ret; } +char *map_ptr(char *buf,off_t offset,int len) +{ + if (buf) + return buf+offset; + + if (len == 0) + return NULL; + + len = MIN(len,map_size-offset); + + if (offset >= p_offset && + offset+len <= p_offset+p_len) { + return (p + (offset - p_offset)); + } + + len = MAX(len,WRITE_BLOCK_SIZE); + len = MIN(len,map_size - offset); + + if (len > p_size) { + if (p) free(p); + p = (char *)malloc(len); + if (!p) out_of_memory("map_ptr"); + p_size = len; + } + + if (lseek(map_fd,offset,SEEK_SET) != offset || + read(map_fd,p,len) != len) { + fprintf(stderr,"EOF in map_ptr!\n"); + exit(1); + } + + p_offset = offset; + p_len = len; + + return p; +} + + void unmap_file(char *buf,off_t len) { if (len > 0 && buf) munmap(buf,len); + map_fd = -1; + map_size = 0; + p_len = 0; } -- 2.34.1