Date: Wed, 20 Mar 2002 11:33:59 +0200 From: Ruslan Ermilov <ru@FreeBSD.org> To: Dag-Erling Smorgrav <des@FreeBSD.org> Cc: Bruce Evans <bde@FreeBSD.org>, current@FreeBSD.org Subject: Re: cvs commit: src/usr.bin/xinstall xinstall.c Message-ID: <20020320093359.GB2503@sunbay.com> In-Reply-To: <200203182326.g2INQDb71549@freefall.freebsd.org> References: <200203182326.g2INQDb71549@freefall.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, Mar 18, 2002 at 03:26:13PM -0800, Dag-Erling Smorgrav wrote: > des 2002/03/18 15:26:13 PST > > Modified files: > usr.bin/xinstall xinstall.c > Log: > Bump the cutoff mark for comparing files from 8 MB to 16 MB. > > Revision Changes Path > 1.48 +3 -1 src/usr.bin/xinstall/xinstall.c > OK, I think it's finally the time to borrow mmap(2) comparison in chunks from OpenBSD (better viewed as -w diff): %%% Index: xinstall.c =================================================================== RCS file: /home/ncvs/src/usr.bin/xinstall/xinstall.c,v retrieving revision 1.48 diff -u -p -r1.48 xinstall.c --- xinstall.c 18 Mar 2002 23:26:13 -0000 1.48 +++ xinstall.c 20 Mar 2002 09:26:11 -0000 @@ -74,12 +74,11 @@ static const char sccsid[] = "From: @(#) #define MAP_FAILED ((void *)-1) /* from <sys/mman.h> */ #endif -#define MAX_CMP_SIZE (16 * 1024 * 1024) - #define DIRECTORY 0x01 /* Tell install it's a directory. */ #define SETFLAGS 0x02 /* Tell install to set flags. */ #define NOCHANGEBITS (UF_IMMUTABLE | UF_APPEND | SF_IMMUTABLE | SF_APPEND) #define BACKUP_SUFFIX ".old" +#define MAX_CMP_SIZE (16 * 1024 * 1024) struct passwd *pp; struct group *gp; @@ -523,6 +522,8 @@ compare(int from_fd, const char *from_na int to_fd, const char *to_name __unused, size_t to_len) { char *p, *q; + size_t len, remainder; + off_t from_off, to_off; int rv; int done_compare; @@ -530,48 +531,60 @@ compare(int from_fd, const char *from_na if (from_len != to_len) return 1; - if (from_len <= MAX_CMP_SIZE) { - done_compare = 0; - if (trymmap(from_fd) && trymmap(to_fd)) { - p = mmap(NULL, from_len, PROT_READ, MAP_SHARED, from_fd, (off_t)0); + done_compare = 0; + if (trymmap(from_fd) && trymmap(to_fd)) { + /* + * Compare two files being careful not to mmap + * more than 8M at a time. + */ + from_off = to_off = (off_t)0; + remainder = from_len; + while (!rv && remainder > 0) { + len = MIN(remainder, 8 * 1024 * 1024); + + p = mmap(NULL, len, PROT_READ, MAP_SHARED, from_fd, from_off); if (p == (char *)MAP_FAILED) goto out; - q = mmap(NULL, from_len, PROT_READ, MAP_SHARED, to_fd, (off_t)0); + q = mmap(NULL, len, PROT_READ, MAP_SHARED, to_fd, to_off); if (q == (char *)MAP_FAILED) { - munmap(p, from_len); + munmap(p, len); goto out; } - rv = memcmp(p, q, from_len); - munmap(p, from_len); - munmap(q, from_len); - done_compare = 1; - } - out: - if (!done_compare) { - char buf1[MAXBSIZE]; - char buf2[MAXBSIZE]; - int n1, n2; - - rv = 0; - lseek(from_fd, 0, SEEK_SET); - lseek(to_fd, 0, SEEK_SET); - while (rv == 0) { - n1 = read(from_fd, buf1, sizeof(buf1)); - if (n1 == 0) - break; /* EOF */ - else if (n1 > 0) { - n2 = read(to_fd, buf2, n1); - if (n2 == n1) - rv = memcmp(buf1, buf2, n1); - else - rv = 1; /* out of sync */ - } else - rv = 1; /* read failure */ - } - lseek(from_fd, 0, SEEK_SET); - lseek(to_fd, 0, SEEK_SET); + rv = memcmp(p, q, len); + munmap(p, len); + munmap(q, len); + + from_off += len; + to_off += len; + remainder -= len; + } + done_compare = 1; + } +out: + if (!done_compare && from_len <= MAX_CMP_SIZE) { + char buf1[MAXBSIZE]; + char buf2[MAXBSIZE]; + int n1, n2; + + rv = 0; + lseek(from_fd, 0, SEEK_SET); + lseek(to_fd, 0, SEEK_SET); + while (rv == 0) { + n1 = read(from_fd, buf1, sizeof(buf1)); + if (n1 == 0) + break; /* EOF */ + else if (n1 > 0) { + n2 = read(to_fd, buf2, n1); + if (n2 == n1) + rv = memcmp(buf1, buf2, n1); + else + rv = 1; /* out of sync */ + } else + rv = 1; /* read failure */ } + lseek(from_fd, 0, SEEK_SET); + lseek(to_fd, 0, SEEK_SET); } else rv = 1; /* don't bother in this case */ %%% Cheers, -- Ruslan Ermilov Sysadmin and DBA, ru@sunbay.com Sunbay Software AG, ru@FreeBSD.org FreeBSD committer, +380.652.512.251 Simferopol, Ukraine http://www.FreeBSD.org The Power To Serve http://www.oracle.com Enabling The Information Age To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020320093359.GB2503>