Blame SOURCES/tar-1.26-large-sparse-file-listing.patch

94b232
From 77cef4ee39ee083838e5cf2137b0f344b49afb6a Mon Sep 17 00:00:00 2001
94b232
From: Pavel Raiskup <praiskup@redhat.com>
94b232
Date: Tue, 29 Jan 2013 10:39:30 +0100
94b232
Subject: [PATCH 1/4] Fix bug in sparse file listing
94b232
94b232
List posix archives containing sparse files >8GB correctly and do not fail.
94b232
This fixes also bug in format of listing for sparse files >8GB - now the
94b232
real size is printed instead of the effective one (this is not strictly
94b232
posix format related).
94b232
94b232
* src/list.c: Remove redundant assignment.
94b232
* src/tar.h: Add new 'real_size' and 'real_size_set' fields in
94b232
  tar_stat_info struct.
94b232
* src/xheader.c: Correctly handle (especially sparse) file sizes directly in
94b232
  xheader_decode().
94b232
---
94b232
 src/list.c    |  1 -
94b232
 src/tar.h     |  4 ++++
94b232
 src/xheader.c | 15 ++++++++++++++-
94b232
 3 files changed, 18 insertions(+), 2 deletions(-)
94b232
94b232
diff --git a/src/list.c b/src/list.c
94b232
index dd501a9..6db36d1 100644
94b232
--- a/src/list.c
94b232
+++ b/src/list.c
94b232
@@ -670,7 +670,6 @@ decode_header (union block *header, struct tar_stat_info *stat_info,
94b232
 	}
94b232
     }
94b232
 
94b232
-  stat_info->archive_file_size = stat_info->stat.st_size;
94b232
   xheader_decode (stat_info);
94b232
 
94b232
   if (sparse_member_p (stat_info))
94b232
diff --git a/src/tar.h b/src/tar.h
94b232
index b181e58..690c146 100644
94b232
--- a/src/tar.h
94b232
+++ b/src/tar.h
94b232
@@ -327,6 +327,10 @@ struct tar_stat_info
94b232
   size_t sparse_map_size;   /* Size of the sparse map */
94b232
   struct sp_array *sparse_map;
94b232
 
94b232
+  off_t real_size;          /* The real size of sparse file */
94b232
+  int   real_size_set;      /* True when GNU.sparse.realsize is set in
94b232
+			       archived file */
94b232
+
94b232
   size_t xattr_map_size;   /* Size of the xattr map */
94b232
   struct xattr_array *xattr_map;
94b232
 
94b232
diff --git a/src/xheader.c b/src/xheader.c
94b232
index be793d4..708aece 100644
94b232
--- a/src/xheader.c
94b232
+++ b/src/xheader.c
94b232
@@ -764,6 +764,16 @@ xheader_decode (struct tar_stat_info *st)
94b232
 	continue;
94b232
     }
94b232
   run_override_list (keyword_override_list, st);
94b232
+
94b232
+  /* The archived (effective) file size is always set directly in tar header
94b232
+     field, possibly overridden by "size" extended header - in both cases,
94b232
+     result is now decoded in st->stat.st_size */
94b232
+  st->archive_file_size = st->stat.st_size;
94b232
+
94b232
+  /* The real file size (given by stat()) may be redefined for sparse
94b232
+     files in "GNU.sparse.realsize" extended header */
94b232
+  if (st->real_size_set)
94b232
+    st->stat.st_size = st->real_size;
94b232
 }
94b232
 
94b232
 static void
94b232
@@ -1438,7 +1435,10 @@ sparse_size_decoder (struct tar_stat_info *st,
94b232
 {
94b232
   uintmax_t u;
94b232
   if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
94b232
-    st->stat.st_size = u;
94b232
+    {
94b232
+      st->real_size_set = 1;
94b232
+      st->real_size = u;
94b232
+    }
94b232
 }
94b232
 
94b232
 static void
94b232
-- 
94b232
2.13.5
94b232
94b232
94b232
From 198d4621b2a367986c71cd2489c1465ec3be89dc Mon Sep 17 00:00:00 2001
94b232
From: Sergey Poznyakoff <gray@gnu.org>
94b232
Date: Fri, 7 Nov 2014 11:47:44 +0200
94b232
Subject: [PATCH 2/4] Add testcase for the previous commit.
94b232
94b232
* tests/sparse05.at: New file.
94b232
* tests/Makefile.am: Add sparse05.at
94b232
* tests/testsuite.at: Include sparse05.at
94b232
---
94b232
 tests/Makefile.am  |  1 +
94b232
 tests/sparse05.at  | 46 ++++++++++++++++++++++++++++++++++++++++++++++
94b232
 tests/testsuite.at |  1 +
94b232
 3 files changed, 48 insertions(+)
94b232
 create mode 100644 tests/sparse05.at
94b232
94b232
diff --git a/tests/Makefile.am b/tests/Makefile.am
94b232
index 8e1ef8d..094b71c 100644
94b232
--- a/tests/Makefile.am
94b232
+++ b/tests/Makefile.am
94b232
@@ -171,6 +171,7 @@ TESTSUITE_AT = \
94b232
  sparse02.at\
94b232
  sparse03.at\
94b232
  sparse04.at\
94b232
+ sparse05.at\
94b232
  sparsemv.at\
94b232
  sparsemvp.at\
94b232
  spmvp00.at\
94b232
diff --git a/tests/sparse05.at b/tests/sparse05.at
94b232
new file mode 100644
94b232
index 0000000..72f3274
94b232
--- /dev/null
94b232
+++ b/tests/sparse05.at
94b232
@@ -0,0 +1,46 @@
94b232
+# Process this file with autom4te to create testsuite. -*- Autotest -*-
94b232
+#
94b232
+# Test suite for GNU tar.
94b232
+# Copyright 2014 Free Software Foundation, Inc.
94b232
+
94b232
+# This file is part of GNU tar.
94b232
+
94b232
+# GNU tar is free software; you can redistribute it and/or modify
94b232
+# it under the terms of the GNU General Public License as published by
94b232
+# the Free Software Foundation; either version 3 of the License, or
94b232
+# (at your option) any later version.
94b232
+
94b232
+# GNU tar is distributed in the hope that it will be useful,
94b232
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
94b232
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
94b232
+# GNU General Public License for more details.
94b232
+
94b232
+# You should have received a copy of the GNU General Public License
94b232
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
94b232
+
94b232
+AT_SETUP([listing sparse files bigger than 2^33 B])
94b232
+AT_KEYWORDS([sparse sparse05])
94b232
+
94b232
+# Description: If an archive in POSIX.1-2001 archive contained a sparse file
94b232
+# member whose real size (excluding zero blocks) is bigger than 2^33 bytes,
94b232
+# tar 1.28 would incorrectly list the real member size.
94b232
+# Reported by: Pavel Raiskup <praiskup@redhat.com>
94b232
+# References: <1359119879.15037.4.camel@raiskup>,
94b232
+#             http://lists.gnu.org/archive/html/bug-tar/2013-01/msg00001.html
94b232
+
94b232
+AT_TAR_CHECK([
94b232
+(echo 0 =2560
94b232
+for i in `seq 1 999`; do
94b232
+    echo 10M =2560
94b232
+done) | genfile --sparse --file BIGFILE --block-size 4K - || AT_SKIP_TEST
94b232
+tar -f - -c --sparse --posix BIGFILE | tar tvf - | awk '{ print $3, $(NF) }'
94b232
+],
94b232
+[0],
94b232
+[20961034240 BIGFILE
94b232
+],
94b232
+[],
94b232
+[],
94b232
+[],
94b232
+[pax])
94b232
+
94b232
+AT_CLEANUP
94b232
diff --git a/tests/testsuite.at b/tests/testsuite.at
94b232
index 3eb0eee..f7f00ee 100644
94b232
--- a/tests/testsuite.at
94b232
+++ b/tests/testsuite.at
94b232
@@ -308,6 +308,7 @@ m4_include([sparse01.at])
94b232
 m4_include([sparse02.at])
94b232
 m4_include([sparse03.at])
94b232
 m4_include([sparse04.at])
94b232
+m4_include([sparse05.at])
94b232
 m4_include([sparsemv.at])
94b232
 m4_include([spmvp00.at])
94b232
 m4_include([spmvp01.at])
94b232
-- 
94b232
2.13.5
94b232
94b232
94b232
From 8a795036f08bca508c3f3425f41c566562573e5f Mon Sep 17 00:00:00 2001
94b232
From: Sergey Poznyakoff <gray@gnu.org>
94b232
Date: Fri, 7 Nov 2014 11:37:33 +0200
94b232
Subject: [PATCH 3/4] genfile: improve sparse mode
94b232
94b232
Paxutils: 45af1632aa64a5ba1b108e248920e67c180e8485
94b232
94b232
* tests/genfile.c (generate_sparse_file): Handle '-' argument
94b232
(read from stdin);
94b232
If content strings starts with '=', treat it as fragment size and
94b232
use default pattern to fill it.
94b232
* doc/genfile.texi: Document changes to genfile.
94b232
---
94b232
 doc/genfile.texi | 31 +++++++++++++++-------
94b232
 tests/genfile.c  | 79 +++++++++++++++++++++++++++++++++++++++++++++++++-------
94b232
 2 files changed, 91 insertions(+), 19 deletions(-)
94b232
94b232
diff --git a/doc/genfile.texi b/doc/genfile.texi
94b232
index b37e26e..b993b9b 100644
94b232
--- a/doc/genfile.texi
94b232
+++ b/doc/genfile.texi
94b232
@@ -124,9 +124,8 @@ the rest of the command line specifies a so-called @dfn{file map}.
94b232
 descriptors}. Each descriptor is composed of two values: a number,
94b232
 specifying fragment offset from the end of the previous fragment or,
94b232
 for the very first fragment, from the beginning of the file, and
94b232
-@dfn{contents string}, i.e., a string of characters, specifying the
94b232
-pattern to fill the fragment with. File offset can be suffixed with
94b232
-the following quantifiers:
94b232
+@dfn{contents string}, that specifies the pattern to fill the fragment
94b232
+with. File offset can be suffixed with the following quantifiers:
94b232
 
94b232
 @table @samp
94b232
 @item k
94b232
@@ -140,17 +139,29 @@ The number is expressed in megabytes.
94b232
 The number is expressed in gigabytes.
94b232
 @end table
94b232
 
94b232
-    For each letter in contents string @command{genfile} will generate
94b232
-a @dfn{block} of data, filled with this letter and will write it to
94b232
-the fragment. The size of block is given by @option{--block-size}
94b232
-option. It defaults to 512. Thus, if the string consists of @var{n}
94b232
-characters, the resulting file fragment will contain
94b232
-@code{@var{n}*@var{block-size}} of data. 
94b232
+    Contents string can be either a fragment size or a pattern.
94b232
+Fragment size is a decimal number, prefixed with an equals sign.  It
94b232
+can be suffixed with a quantifier, as discussed above.  If fragment
94b232
+size is given, the fragment of that size will be filled with the
94b232
+currently selected pattern (@pxref{Generate Mode, --pattern}) and
94b232
+written to the file.  
94b232
 
94b232
-    Last fragment descriptor can have only file offset part. In this
94b232
+    A pattern is a string of arbitrary ASCII characters.  For each
94b232
+of them, @command{genfile} will generate a @dfn{block} of data,
94b232
+filled with that character and will write it to the fragment. The size
94b232
+of block is given by @option{--block-size} option. It defaults to 512.
94b232
+Thus, if pattern consists of @var{n} characters, the resulting file
94b232
+fragment will contain @code{@var{n}*@var{block-size}} bytes of data.
94b232
+
94b232
+    The last fragment descriptor can have only file offset part. In this
94b232
 case @command{genfile} will create a hole at the end of the file up to
94b232
 the given offset.
94b232
 
94b232
+    A dash appearing as a fragment descriptor instructs
94b232
+@command{genfile} to read file map from the standard input.  Each line
94b232
+of input should consist of fragment offset and contents string,
94b232
+separated by any amount of whitespace.
94b232
+
94b232
     For example, consider the following invocation:
94b232
 
94b232
 @smallexample
94b232
diff --git a/tests/genfile.c b/tests/genfile.c
94b232
index fa480ef..d41336b 100644
94b232
--- a/tests/genfile.c
94b232
+++ b/tests/genfile.c
94b232
@@ -32,6 +32,7 @@
94b232
 #include <inttostr.h>
94b232
 #include <fcntl.h>
94b232
 #include <sys/stat.h>
94b232
+#include <c-ctype.h>
94b232
 #define obstack_chunk_alloc malloc
94b232
 #define obstack_chunk_free free
94b232
 #include <obstack.h>
94b232
@@ -506,6 +507,53 @@ mksparse (int fd, off_t displ, char *marks)
94b232
     }
94b232
 }
94b232
 
94b232
+static int
94b232
+make_fragment (int fd, char *offstr, char *mapstr)
94b232
+{
94b232
+  int i;
94b232
+  off_t displ = get_size (offstr, 1);
94b232
+
94b232
+  file_length += displ;
94b232
+
94b232
+  if (!mapstr || !*mapstr)
94b232
+    {
94b232
+      mkhole (fd, displ);
94b232
+      return 1;
94b232
+    }
94b232
+  else if (*mapstr == '=')
94b232
+    {
94b232
+      off_t n = get_size (mapstr + 1, 1);
94b232
+
94b232
+      switch (pattern)
94b232
+	{
94b232
+	case DEFAULT_PATTERN:
94b232
+	  for (i = 0; i < block_size; i++)
94b232
+	    buffer[i] = i & 255;
94b232
+	  break;
94b232
+	  
94b232
+	case ZEROS_PATTERN:
94b232
+	  memset (buffer, 0, block_size);
94b232
+	  break;
94b232
+	}
94b232
+
94b232
+      if (lseek (fd, displ, SEEK_CUR) == -1)
94b232
+	error (EXIT_FAILURE, errno, "lseek");
94b232
+      
94b232
+      for (; n; n--)
94b232
+	{
94b232
+	  if (write (fd, buffer, block_size) != block_size)
94b232
+	    error (EXIT_FAILURE, errno, "write");
94b232
+	  file_length += block_size;
94b232
+	}
94b232
+    }
94b232
+  else
94b232
+    {
94b232
+      file_length += block_size * strlen (mapstr);
94b232
+      mksparse (fd, displ, mapstr);
94b232
+    }
94b232
+  return 0;
94b232
+}
94b232
+
94b232
 static void
94b232
 generate_sparse_file (int argc, char **argv)
94b232
 {
94b232
@@ -526,20 +574,33 @@ generate_sparse_file (int argc, char **argv)
94b232
 
94b232
   file_length = 0;
94b232
 
94b232
-  for (i = 0; i < argc; i += 2)
94b232
+  while (argc)
94b232
     {
94b232
-      off_t displ = get_size (argv[i], 1);
94b232
-      file_length += displ;
94b232
+      if (argv[0][0] == '-' && argv[0][1] == 0)
94b232
+	{
94b232
+	  char buf[256];
94b232
+	  while (fgets (buf, sizeof (buf), stdin))
94b232
+	    {
94b232
+	      size_t n = strlen (buf);
94b232
 
94b232
-      if (i == argc-1)
94b232
-	{
94b232
-	  mkhole (fd, displ);
94b232
-	  break;
94b232
+	      while (n > 0 && c_isspace (buf[n-1]))
94b232
+		buf[--n] = 0;
94b232
+	      
94b232
+	      n = strcspn (buf, " \t");
94b232
+	      buf[n++] = 0;
94b232
+	      while (buf[n] && c_isblank (buf[n]))
94b232
+		++n;
94b232
+	      make_fragment (fd, buf, buf + n);
94b232
+	    }
94b232
+	  ++argv;
94b232
+	  --argc;
94b232
 	}
94b232
       else
94b232
 	{
94b232
-	  file_length += block_size * strlen (argv[i+1]);
94b232
-	  mksparse (fd, displ, argv[i+1]);
94b232
+	  if (make_fragment (fd, argv[0], argv[1]))
94b232
+	    break;
94b232
+	  argc -= 2;
94b232
+	  argv += 2;
94b232
 	}
94b232
     }
94b232
 
94b232
-- 
94b232
2.13.5
94b232
94b232
94b232
From 29e35df407d6c7b1e1ff57f7ef2030a253132a8a Mon Sep 17 00:00:00 2001
94b232
From: Pavel Raiskup <praiskup@redhat.com>
94b232
Date: Fri, 4 Dec 2015 19:36:14 +0100
94b232
Subject: [PATCH 4/4] genfile: remove unused variable
94b232
94b232
paxutils: 58b8ac114790e2de7992db1a387ec14238783f39
94b232
94b232
* tests/genfile.c (generate_sparse_file): Remove unused 'i'.
94b232
---
94b232
 tests/genfile.c | 1 -
94b232
 1 file changed, 1 deletion(-)
94b232
94b232
diff --git a/tests/genfile.c b/tests/genfile.c
94b232
index d41336b..4699d21 100644
94b232
--- a/tests/genfile.c
94b232
+++ b/tests/genfile.c
94b232
@@ -557,7 +557,6 @@ make_fragment (int fd, char *offstr, char *mapstr)
94b232
 static void
94b232
 generate_sparse_file (int argc, char **argv)
94b232
 {
94b232
-  int i;
94b232
   int fd;
94b232
   int flags = O_CREAT | O_RDWR | O_BINARY;
94b232
 
94b232
-- 
94b232
2.13.5
94b232