diff options
author | 2019-08-26 22:22:14 +0000 | |
---|---|---|
committer | 2019-08-26 22:22:14 +0000 | |
commit | c314c8030071bec0bc321323addce2d5bc49acf4 (patch) | |
tree | 22582eddbbbe90ad4132ac37c5d70df7bfb679c1 | |
parent | sync (diff) | |
download | wireguard-openbsd-c314c8030071bec0bc321323addce2d5bc49acf4.tar.xz wireguard-openbsd-c314c8030071bec0bc321323addce2d5bc49acf4.zip |
replace a mmap() with pread(). The mmap() is not needed, the file is
read sequentially anyway, (hash-sized) block by block. This avoids
counting potentially large files against the memory limits of the
process. Problem reported by Jan Stary, thanks.
ok deraadt@
-rw-r--r-- | usr.bin/rsync/uploader.c | 52 |
1 files changed, 32 insertions, 20 deletions
diff --git a/usr.bin/rsync/uploader.c b/usr.bin/rsync/uploader.c index fd07b22caeb..38d5d24fcc7 100644 --- a/usr.bin/rsync/uploader.c +++ b/usr.bin/rsync/uploader.c @@ -1,4 +1,4 @@ -/* $Id: uploader.c,v 1.22 2019/05/08 21:30:11 benno Exp $ */ +/* $Id: uploader.c,v 1.23 2019/08/26 22:22:14 benno Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2019 Florian Obser <florian@openbsd.org> @@ -158,8 +158,8 @@ init_blk(struct blk *p, const struct blkset *set, off_t offs, p->len = idx < set->blksz - 1 ? set->len : set->rem; p->offs = offs; - p->chksum_short = hash_fast(map + offs, p->len); - hash_slow(map + offs, p->len, p->chksum_long, sess); + p->chksum_short = hash_fast(map, p->len); + hash_slow(map, p->len, p->chksum_long, sess); } /* @@ -741,8 +741,9 @@ rsync_uploader(struct upload *u, int *fileinfd, { struct blkset blk; struct stat st; - void *map, *bufp; - size_t i, mapsz, pos, sz; + void *mbuf, *bufp; + ssize_t msz; + size_t i, pos, sz; off_t offs; int c; const struct flist *f; @@ -909,35 +910,46 @@ rsync_uploader(struct upload *u, int *fileinfd, blk.csum = u->csumlen; if (*fileinfd != -1 && st.st_size > 0) { - mapsz = st.st_size; - map = mmap(NULL, mapsz, PROT_READ, MAP_SHARED, *fileinfd, 0); - if (map == MAP_FAILED) { - ERR("%s: mmap", u->fl[u->idx].path); - close(*fileinfd); - *fileinfd = -1; - return -1; - } - init_blkset(&blk, st.st_size); assert(blk.blksz); blk.blks = calloc(blk.blksz, sizeof(struct blk)); if (blk.blks == NULL) { ERR("calloc"); - munmap(map, mapsz); + close(*fileinfd); + *fileinfd = -1; + return -1; + } + + if ((mbuf = calloc(1, blk.len)) == NULL) { + ERR("calloc"); close(*fileinfd); *fileinfd = -1; return -1; } offs = 0; - for (i = 0; i < blk.blksz; i++) { - init_blk(&blk.blks[i], - &blk, offs, i, map, sess); + i = 0; + do { + msz = pread(*fileinfd, mbuf, blk.len, offs); + if (msz < 0) { + ERR("pread"); + close(*fileinfd); + *fileinfd = -1; + return -1; + } + if ((size_t)msz != blk.len && (size_t)msz != blk.rem) { + /* short read, try again */ + continue; + } + init_blk(&blk.blks[i], &blk, offs, i, mbuf, sess); offs += blk.len; - } + LOG3( + "i=%ld, offs=%lld, msz=%ld, blk.len=%lu, blk.rem=%lu", + i, offs, msz, blk.len, blk.rem); + i++; + } while (i < blk.blksz); - munmap(map, mapsz); close(*fileinfd); *fileinfd = -1; LOG3("%s: mapped %jd B with %zu blocks", |