Date: Wed, 1 Dec 2004 02:09:33 +0300 (MSK) From: Sergey Salnikov <serg@citforum.ru> To: FreeBSD-gnats-submit@FreeBSD.org Subject: bin/74567: [patch] [2TB] du doesn't handle sizes >1TB Message-ID: <200411302309.iAUN9XY1038656@ftp.citkit.ru> Resent-Message-ID: <200411302310.iAUNAD2i029754@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 74567 >Category: bin >Synopsis: [patch] [2TB] du doesn't handle sizes >1TB >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Tue Nov 30 23:10:12 GMT 2004 >Closed-Date: >Last-Modified: >Originator: Sergey Salnikov <serg@citforum.ru> >Release: FreeBSD 5.3-RELEASE i386 >Organization: CITForum >Environment: System: FreeBSD ftp.citkit.ru 5.3-RELEASE FreeBSD 5.3-RELEASE #0: Sun Nov 21 02:43:28 MSK 2004 serg@:/usr/obj/usr/src/sys/CITKIT i386 >Description: There is an integer overflow in du when running it on a directory larger than 1TB. >How-To-Repeat: Run du on any >1TB directory on a 32-bit machine. It reports wrong size. >Fix: Here goes the patch. Modified du allocates an int64_t for every subdirectory and stores the size there and not in fts_number. Maybe fts_number just has to be 64-bit? It will make things faster (no need for extra malloc), but involves hacking libc. --- du-2TB-patch begins here --- --- du.c.orig Wed Jul 28 20:03:12 2004 +++ du.c Wed Dec 1 00:20:29 2004 @@ -82,7 +82,8 @@ { FTS *fts; FTSENT *p; - long blocksize, savednumber = 0; + long blocksize; + int64_t savednumber = 0; int ftsoptions; int listall; int depth; @@ -219,24 +220,31 @@ case FTS_D: /* Ignore. */ if (ignorep(p)) fts_set(fts, p, FTS_SKIP); + else { + if ((!p->fts_parent->fts_pointer + && !(p->fts_parent->fts_pointer = calloc(1, sizeof(int64_t)))) + || !(p->fts_pointer = calloc(1, sizeof(int64_t)))) + err(1, "calloc"); + } break; case FTS_DP: if (ignorep(p)) break; - p->fts_parent->fts_number += - p->fts_number += p->fts_statp->st_blocks; + *(int64_t *)p->fts_parent->fts_pointer += + *(int64_t *)p->fts_pointer += p->fts_statp->st_blocks; if (p->fts_level <= depth) { if (hflag) { - (void) prthumanval(howmany(p->fts_number, blocksize)); + (void) prthumanval(howmany(*(int64_t *)p->fts_pointer, blocksize)); (void) printf("\t%s\n", p->fts_path); } else { - (void) printf("%ld\t%s\n", - howmany(p->fts_number, blocksize), + (void) printf("%lld\t%s\n", + howmany(*(int64_t *)p->fts_pointer, blocksize), p->fts_path); } } + free(p->fts_pointer); break; case FTS_DC: /* Ignore. */ break; @@ -265,9 +273,9 @@ } } - p->fts_parent->fts_number += p->fts_statp->st_blocks; + *(int64_t *)p->fts_parent->fts_pointer += p->fts_statp->st_blocks; } - savednumber = p->fts_parent->fts_number; + savednumber = *(int64_t *)p->fts_parent->fts_pointer; } if (errno) @@ -278,7 +286,7 @@ (void) prthumanval(howmany(savednumber, blocksize)); (void) printf("\ttotal\n"); } else { - (void) printf("%ld\ttotal\n", howmany(savednumber, blocksize)); + (void) printf("%lld\ttotal\n", howmany(savednumber, blocksize)); } } --- du-2TB-patch ends here --- >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200411302309.iAUN9XY1038656>