bin/74567: [patch] [2TB] du doesn't handle sizes >1TB

Sergey Salnikov serg at www1.citforum.ru
Thu Dec 2 13:50:25 PST 2004


The following reply was made to PR bin/74567; it has been noted by GNATS.

From: Sergey Salnikov <serg at www1.citforum.ru>
To: freebsd-gnats-submit at FreeBSD.org
Cc:  
Subject: Re: bin/74567: [patch] [2TB] du doesn't handle sizes >1TB
Date: Fri, 03 Dec 2004 00:41:33 +0300

 I've found a serious bug in my patch - malloc was called in the
 wrong place, and du dumped core when called with no directories, but
 an ordinary file. Corrected.
 
 >It seems like off_t would be more appropriate.
 Really I simply looked at the "prthumanval(int64_t bytes)" line and
 thought that using the same typedef everywhere would be the right
 thing. But off_t is better for that, you're right.
 
 >Have you done any testing to see how expensive this extra malloc is?
 Little. "time du -sm /pub/FreeBSD" on our FTP server showed the same
 times for original and patched du, and 90% is anyway "sys".
 
 It doesn't free fts_number in the virtual top FTS_ENT. It's not a
 problem since the cycle is run just once within a process, but maybe
 that last free() should be added for the sake of cleanlyness.
 
 A new patch follows.
 
 --- du-2TB-patch-v2 begins here ---
 --- du.c.orig   Wed Jul 28 20:03:12 2004
 +++ du.c        Thu Dec  2 00:54:34 2004
 @@ -72,7 +72,7 @@
 
  static int     linkchk(FTSENT *);
  static void    usage(void);
 -void           prthumanval(int64_t);
 +void           prthumanval(off_t);
  void           ignoreadd(const char *);
  void           ignoreclean(void);
  int            ignorep(FTSENT *);
 @@ -82,7 +82,8 @@
  {
         FTS             *fts;
         FTSENT          *p;
 -       long            blocksize, savednumber = 0;
 +       long            blocksize;
 +       off_t           savednumber = 0;
         int             ftsoptions;
         int             listall;
         int             depth;
 @@ -215,8 +216,13 @@
                 err(1, "fts_open");
 
         while ((p = fts_read(fts)) != NULL) {
 +               if ((!p->fts_parent->fts_pointer
 +                    && !(p->fts_parent->fts_pointer = calloc(1, sizeof(off_t)))))
 +                       err(1, "calloc");
                 switch (p->fts_info) {
                         case FTS_D:                     /* Ignore. */
 +                               if (!(p->fts_pointer = calloc(1, sizeof(off_t))))
 +                                       err(1, "calloc");
                                 if (ignorep(p))
                                         fts_set(fts, p, FTS_SKIP);
                                 break;
 @@ -224,19 +230,20 @@
                                 if (ignorep(p))
                                         break;
 
 -                               p->fts_parent->fts_number +=
 -                                   p->fts_number += p->fts_statp->st_blocks;
 +                               *(off_t *)p->fts_parent->fts_pointer +=
 +                                   *(off_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(*(off_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(*(off_t *)p->fts_pointer,
 blocksize),
                                             p->fts_path);
                                         }
                                 }
 +                               free(p->fts_pointer);
                                 break;
                         case FTS_DC:                    /* Ignore. */
                                 break;
 @@ -265,9 +272,9 @@
                                         }
                                 }
 
 -                               p->fts_parent->fts_number +=
 p->fts_statp->st_blocks;
 +                               *(off_t *)p->fts_parent->fts_pointer +=
 p->fts_statp->st_blocks;
                 }
 -               savednumber = p->fts_parent->fts_number;
 +               savednumber = *(off_t *)p->fts_parent->fts_pointer;
         }
 
         if (errno)
 @@ -278,7 +285,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));
                 }
         }
 
 @@ -421,7 +428,7 @@
  }
 
  void
 -prthumanval(int64_t bytes)
 +prthumanval(off_t bytes)
  {
         char buf[5];
 
 --- du-2TB-patch-v2 ends here ---


More information about the freebsd-bugs mailing list