We can dump(8) more than 2TB

2014-06-12 Thread Christian Weisgerber
After writing 2TB (INT_MAX * TP_BSIZE), dump(8) stops reporting
progress because the blockswritten variable has wrapped around to
negative.  It needs to be a larger type like the tapesize variable;
see optr.c:timeest().  This only affects the terminal chatter.  The
actual dump functionality is fine.

ok?

Index: dump.h
===
RCS file: /cvs/src/sbin/dump/dump.h,v
retrieving revision 1.19
diff -u -p -r1.19 dump.h
--- dump.h  24 May 2014 21:49:09 -  1.19
+++ dump.h  12 Jun 2014 11:28:35 -
@@ -73,7 +73,7 @@ int   etapes; /* estimated number of tape
 intnonodump;   /* if set, do not honor UF_NODUMP user flags */
 
 intnotify; /* notify operator flag */
-intblockswritten;  /* number of blocks written on current tape */
+off_t  blockswritten;  /* number of blocks written on current tape */
 inttapeno; /* current tape number */
 time_t tstart_writing; /* when started writing the first tape block */
 long   xferrate;   /* averaged transfer rate of all volumes */
Index: main.c
===
RCS file: /cvs/src/sbin/dump/main.c,v
retrieving revision 1.50
diff -u -p -r1.50 main.c
--- main.c  31 May 2014 08:28:13 -  1.50
+++ main.c  12 Jun 2014 11:29:07 -
@@ -59,7 +59,7 @@
 #include pathnames.h
 
 intnotify = 0; /* notify operator flag */
-intblockswritten = 0;  /* number of blocks written on current tape */
+off_t  blockswritten = 0;  /* number of blocks written on current tape */
 inttapeno = 0; /* current tape number */
 intdensity = 0;/* density in bytes/0.1 */
 intntrec = NTREC;  /* # tape blocks in each tape record */

-- 
Christian naddy Weisgerber  na...@mips.inka.de



Re: We can dump(8) more than 2TB

2014-06-12 Thread Christian Weisgerber
Ted Unangst:

  -intblockswritten;  /* number of blocks written on current tape */
  +off_t  blockswritten;  /* number of blocks written on current tape */
  time_t  tstart_writing; /* when started writing the first tape block */
  longxferrate;   /* averaged transfer rate of all volumes */
 
 I'm not sure off_t is the right semantic type. Perhaps just use int64_t?

I picked off_t for consistency with tapesize, but we could use
int64_t for both.  Not sure about the other off_t's there either.

 (And maybe change xferrate? I'm not sure why that needs to change size
 based on machine, and I can probably assemble an i386 system capable
 of wrapping it. int64_t again.)

I can't get more than 66 MB/s out of my system, so good luck breaking
2 TB/s now, but yes, we can proactively fix that.

-- 
Christian naddy Weisgerber  na...@mips.inka.de



Re: We can dump(8) more than 2TB

2014-06-12 Thread Kenneth Westerback
On 12 June 2014 15:59, Christian Weisgerber na...@mips.inka.de wrote:
 Ted Unangst:

  -intblockswritten;  /* number of blocks written on current tape */
  +off_t  blockswritten;  /* number of blocks written on current tape */
  time_t  tstart_writing; /* when started writing the first tape block */
  longxferrate;   /* averaged transfer rate of all volumes */

 I'm not sure off_t is the right semantic type. Perhaps just use int64_t?

 I picked off_t for consistency with tapesize, but we could use
 int64_t for both.  Not sure about the other off_t's there either.

 (And maybe change xferrate? I'm not sure why that needs to change size
 based on machine, and I can probably assemble an i386 system capable
 of wrapping it. int64_t again.)

 I can't get more than 66 MB/s out of my system, so good luck breaking
 2 TB/s now, but yes, we can proactively fix that.

 --
 Christian naddy Weisgerber  na...@mips.inka.de


I would go with int64_t for blockswritten and anything else that is
counting anything other that characters.

 Ken



Re: We can dump(8) more than 2TB

2014-06-12 Thread Mark Kettenis
 Date: Thu, 12 Jun 2014 15:14:29 -0400
 From: Ted Unangst t...@tedunangst.com
 
 On Thu, Jun 12, 2014 at 21:07, Christian Weisgerber wrote:
  After writing 2TB (INT_MAX * TP_BSIZE), dump(8) stops reporting
  progress because the blockswritten variable has wrapped around to
  negative.  It needs to be a larger type like the tapesize variable;
  see optr.c:timeest().  This only affects the terminal chatter.  The
  actual dump functionality is fine.
 
  int notify; /* notify operator flag */
  -intblockswritten;  /* number of blocks written on current tape */
  +off_t  blockswritten;  /* number of blocks written on current tape */
  int tapeno; /* current tape number */
  time_t  tstart_writing; /* when started writing the first tape block */
  longxferrate;   /* averaged transfer rate of all volumes */
 
 I'm not sure off_t is the right semantic type. Perhaps just use int64_t?

int64_t is what we use in struct stat.

That said, there is existing off_t abuse in dump.



Re: We can dump(8) more than 2TB

2014-06-12 Thread Theo de Raadt
  Date: Thu, 12 Jun 2014 15:14:29 -0400
  From: Ted Unangst t...@tedunangst.com
  
  On Thu, Jun 12, 2014 at 21:07, Christian Weisgerber wrote:
   After writing 2TB (INT_MAX * TP_BSIZE), dump(8) stops reporting
   progress because the blockswritten variable has wrapped around to
   negative.  It needs to be a larger type like the tapesize variable;
   see optr.c:timeest().  This only affects the terminal chatter.  The
   actual dump functionality is fine.
  
   int   notify; /* notify operator flag */
   -int  blockswritten;  /* number of blocks written on current tape */
   +off_tblockswritten;  /* number of blocks written on current tape */
   int   tapeno; /* current tape number */
   time_ttstart_writing; /* when started writing the first tape block */
   long  xferrate;   /* averaged transfer rate of all volumes */
  
  I'm not sure off_t is the right semantic type. Perhaps just use int64_t?
 
 int64_t is what we use in struct stat.
 
 That said, there is existing off_t abuse in dump.

I seperately pointed out to naddy that blocksperfile is also mishandled;
it will also overflow.  It is printed with a %ld somewhere, so fix that
too.



Re: We can dump(8) more than 2TB

2014-06-12 Thread Christian Weisgerber
New diff.

* Move all off_t variables that don't look like file sizes to
  int64_t.
* Switch blockswritten to int64_t, so it won't wrap at 2TB.
* Same for blocksthisvol (deraadt@).
* Switch xferrate (tedu@) and blocksperfile from long to uint64_t.
* Since blocksperfile can be set with -B, move numarg() from long
  to long long and don't mark small integer constant arguments with
  'L'.

Index: dump.h
===
RCS file: /cvs/src/sbin/dump/dump.h,v
retrieving revision 1.19
diff -u -p -r1.19 dump.h
--- dump.h  24 May 2014 21:49:09 -  1.19
+++ dump.h  12 Jun 2014 21:02:32 -
@@ -65,15 +65,15 @@ int pipeout;/* true = output to standa
 ino_t  curino; /* current inumber; used globally */
 intnewtape;/* new tape flag */
 intdensity;/* density in 0.1 units */
-off_t  tapesize;   /* estimated tape size, blocks */
-off_t  tsize;  /* tape size in 0.1 units */
+int64_ttapesize;   /* estimated tape size, blocks */
+int64_ttsize;  /* tape size in 0.1 units */
 intunlimited;  /* if set, write to end of medium */
-off_t  asize;  /* number of 0.1 units written on current tape */
+int64_tasize;  /* number of 0.1 units written on current tape 
*/
 intetapes; /* estimated number of tapes */
 intnonodump;   /* if set, do not honor UF_NODUMP user flags */
 
 intnotify; /* notify operator flag */
-intblockswritten;  /* number of blocks written on current tape */
+int64_tblockswritten;  /* number of blocks written on current tape */
 inttapeno; /* current tape number */
 time_t tstart_writing; /* when started writing the first tape block */
 long   xferrate;   /* averaged transfer rate of all volumes */
@@ -96,10 +96,11 @@ voidtimeest(void);
 
 /* mapping routines */
 union  dinode;
-off_t  blockest(union dinode *dp);
-void   mapfileino(ino_t, off_t *, int *);
-intmapfiles(ino_t maxino, off_t *tapesize, char *disk, char * const *dirv);
-intmapdirs(ino_t maxino, off_t *tapesize);
+int64_tblockest(union dinode *dp);
+void   mapfileino(ino_t, int64_t *, int *);
+intmapfiles(ino_t maxino, int64_t *tapesize, char *disk,
+   char * const *dirv);
+intmapdirs(ino_t maxino, int64_t *tapesize);
 
 /* file dumping routines */
 void   ufs1_blksout(int32_t *blkp, int frags, ino_t ino);
Index: main.c
===
RCS file: /cvs/src/sbin/dump/main.c,v
retrieving revision 1.50
diff -u -p -r1.50 main.c
--- main.c  31 May 2014 08:28:13 -  1.50
+++ main.c  12 Jun 2014 21:19:18 -
@@ -59,12 +59,12 @@
 #include pathnames.h
 
 intnotify = 0; /* notify operator flag */
-intblockswritten = 0;  /* number of blocks written on current tape */
+int64_tblockswritten = 0;  /* number of blocks written on current 
tape */
 inttapeno = 0; /* current tape number */
 intdensity = 0;/* density in bytes/0.1 */
 intntrec = NTREC;  /* # tape blocks in each tape record */
 intcartridge = 0;  /* Assume non-cartridge tape */
-long   blocksperfile;  /* output blocks per file */
+int64_tblocksperfile;  /* output blocks per file */
 char   *host = NULL;   /* remote host (if any) */
 intmaxbsize = 64*1024; /* XXX MAXBSIZE from sys/param.h */
 
@@ -75,7 +75,7 @@ struct disklabel lab;
  */
 static int sblock_try[] = SBLOCKSEARCH;
 
-static long numarg(char *, long, long);
+static long long numarg(char *, long long, long long);
 static void obsolete(int *, char **[]);
 static void usage(void);
 
@@ -121,11 +121,11 @@ main(int argc, char *argv[])
break;
 
case 'B':   /* blocks per output file */
-   blocksperfile = numarg(blocks per file, 1L, 0L);
+   blocksperfile = numarg(blocks per file, 1, 0);
break;
 
case 'b':   /* blocks per tape write */
-   ntrec = numarg(blocks per write, 1L, 1000L);
+   ntrec = numarg(blocks per write, 1, 1000);
if (ntrec  maxbsize/1024) {
msg(Please choose a blocksize = %dKB\n,
maxbsize/1024);
@@ -139,7 +139,7 @@ main(int argc, char *argv[])
break;
 
case 'd':   /* density, in bits per inch */
-   density = numarg(density, 10L, 327670L) / 10;
+   density = numarg(density, 10, 327670) / 10;
if (density = 625  !bflag)
ntrec = HIGHDENSITYTREC;
break;
@@ -149,7 +149,7 @@ main(int argc, char *argv[])
break;
 
case 'h':
-   honorlevel 

Re: We can dump(8) more than 2TB

2014-06-12 Thread Ted Unangst
On Thu, Jun 12, 2014 at 21:30, Christian Weisgerber wrote:
 New diff.
 
 * Move all off_t variables that don't look like file sizes to
 int64_t.
 * Switch blockswritten to int64_t, so it won't wrap at 2TB.
 * Same for blocksthisvol (deraadt@).
 * Switch xferrate (tedu@) and blocksperfile from long to uint64_t.
 * Since blocksperfile can be set with -B, move numarg() from long
 to long long and don't mark small integer constant arguments with
 'L'.

I myself am not a dump fiend, but it all looks reasonable.