mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-10-20 04:51:58 -04:00
use mmap() for files of any size. This should be much more buffer
cache friendly.
This commit is contained in:
1 parent
8e9871303b
commit
754d120c98
2 files changed
+74
-24
No files matched your search
@@ -149,6 +149,17 @@ OFF_T do_lseek(int fd, OFF_T offset, int whence)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if HAVE_MMAP
|
||||
void *do_mmap(void *start, int len, int prot, int flags, int fd, OFF_T offset)
|
||||
{
|
||||
#if HAVE_OFF64_T
|
||||
return mmap64(start, len, prot, flags, fd, offset);
|
||||
#else
|
||||
return mmap(start, len, prot, flags, fd, offset);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
char *d_name(struct dirent *di)
|
||||
{
|
||||
#if HAVE_BROKEN_READDIR
|
||||
|
||||
@@ -34,27 +34,28 @@ int num_waiting(int fd)
|
||||
|
||||
struct map_struct *map_file(int fd,OFF_T len)
|
||||
{
|
||||
struct map_struct *ret;
|
||||
ret = (struct map_struct *)malloc(sizeof(*ret));
|
||||
if (!ret) out_of_memory("map_file");
|
||||
struct map_struct *ret;
|
||||
ret = (struct map_struct *)malloc(sizeof(*ret));
|
||||
if (!ret) out_of_memory("map_file");
|
||||
|
||||
ret->map = NULL;
|
||||
ret->fd = fd;
|
||||
ret->size = len;
|
||||
ret->p = NULL;
|
||||
ret->p_size = 0;
|
||||
ret->p_offset = 0;
|
||||
ret->p_len = 0;
|
||||
ret->map = NULL;
|
||||
ret->fd = fd;
|
||||
ret->size = len;
|
||||
ret->p = NULL;
|
||||
ret->p_size = 0;
|
||||
ret->p_offset = 0;
|
||||
ret->p_len = 0;
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
if (len < MAX_MAP_SIZE) {
|
||||
ret->map = (char *)mmap(NULL,len,PROT_READ,MAP_SHARED,fd,0);
|
||||
if (ret->map == (char *)-1) {
|
||||
ret->map = NULL;
|
||||
}
|
||||
}
|
||||
len = MIN(len, MAX_MAP_SIZE);
|
||||
ret->map = (char *)do_mmap(NULL,len,PROT_READ,MAP_SHARED,fd,0);
|
||||
if (ret->map == (char *)-1) {
|
||||
ret->map = NULL;
|
||||
} else {
|
||||
ret->p_len = len;
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -62,15 +63,47 @@ char *map_ptr(struct map_struct *map,OFF_T offset,int len)
|
||||
{
|
||||
int nread;
|
||||
|
||||
if (map->map)
|
||||
return map->map+offset;
|
||||
|
||||
if (len == 0)
|
||||
return NULL;
|
||||
|
||||
if (len > (map->size-offset))
|
||||
len = map->size-offset;
|
||||
|
||||
if (map->map) {
|
||||
if (offset >= map->p_offset &&
|
||||
offset+len <= map->p_offset+map->p_len) {
|
||||
return (map->map + (offset - map->p_offset));
|
||||
}
|
||||
if (munmap(map->map, map->p_len) != 0) {
|
||||
rprintf(FERROR,"munmap failed : %s\n", strerror(errno));
|
||||
exit_cleanup(1);
|
||||
}
|
||||
|
||||
/* align the mmap region on a nice boundary back a bit from
|
||||
where it is asked for to allow for some seeking */
|
||||
if (offset > 2*CHUNK_SIZE) {
|
||||
map->p_offset = offset - 2*CHUNK_SIZE;
|
||||
map->p_offset &= ~((OFF_T)(CHUNK_SIZE-1));
|
||||
} else {
|
||||
map->p_offset = 0;
|
||||
}
|
||||
|
||||
/* map up to MAX_MAP_SIZE */
|
||||
map->p_len = MAX(len, MAX_MAP_SIZE);
|
||||
map->p_len = MIN(map->p_len, map->size - map->p_offset);
|
||||
|
||||
map->map = (char *)do_mmap(NULL,map->p_len,PROT_READ,
|
||||
MAP_SHARED,map->fd,map->p_offset);
|
||||
|
||||
if (map->map == (char *)-1) {
|
||||
map->map = NULL;
|
||||
map->p_len = 0;
|
||||
map->p_offset = 0;
|
||||
} else {
|
||||
return (map->map + (offset - map->p_offset));
|
||||
}
|
||||
}
|
||||
|
||||
if (offset >= map->p_offset &&
|
||||
offset+len <= map->p_offset+map->p_len) {
|
||||
return (map->p + (offset - map->p_offset));
|
||||
@@ -109,11 +142,17 @@ char *map_ptr(struct map_struct *map,OFF_T offset,int len)
|
||||
void unmap_file(struct map_struct *map)
|
||||
{
|
||||
#ifdef HAVE_MMAP
|
||||
if (map->map)
|
||||
munmap(map->map,map->size);
|
||||
if (map->map) {
|
||||
munmap(map->map,map->p_len);
|
||||
map->map = NULL;
|
||||
}
|
||||
#endif
|
||||
if (map->p) free(map->p);
|
||||
free(map);
|
||||
if (map->p) {
|
||||
free(map->p);
|
||||
map->p = NULL;
|
||||
}
|
||||
memset(map, 0, sizeof(*map));
|
||||
free(map);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user