diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2008-07-24 18:16:08 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2008-07-24 18:16:08 +0000 |
commit | 3af9cc0f1550e8c882f1a017727d41b54674c2d5 (patch) | |
tree | 0c2e02b402efb2b7cfc81ab5efb1e46b88f41c4c | |
parent | c9a7297a8a135c0afd8f984b91578a822ba3b04c (diff) | |
download | tar-3af9cc0f1550e8c882f1a017727d41b54674c2d5.tar.gz |
Fix multivolume archive creation when volume length=record size.
* src/tar.c (decode_options): Do not allow volume length less
than record size.
* src/buffer.c (_gnu_flush_write): Compensate for the effect
of eventual flush_archive occurring in the middle of buffer
move.
Increment records_written only if _flush_write was able to write
something.
* tests/multiv06.at: New testcase.
* tests/Makefile.am, test/testsuite.at: Add tests/multiv06.at
-rw-r--r-- | ChangeLog | 13 | ||||
-rw-r--r-- | src/buffer.c | 19 | ||||
-rw-r--r-- | src/create.c | 2 | ||||
-rw-r--r-- | src/tar.c | 3 | ||||
-rw-r--r-- | tests/Makefile.am | 1 | ||||
-rw-r--r-- | tests/multiv06.at | 57 | ||||
-rw-r--r-- | tests/testsuite.at | 1 |
7 files changed, 92 insertions, 4 deletions
@@ -1,3 +1,16 @@ +2008-07-24 Sergey Poznyakoff <gray@gnu.org.ua> + + * src/tar.c (decode_options): Do not allow volume length less + than record size. + + * src/buffer.c (_gnu_flush_write): Compensate for the effect + of eventual flush_archive occurring in the middle of buffer + move. + Increment records_written only if _flush_write was able to write + something. + * tests/multiv06.at: New testcase. + * tests/Makefile.am, test/testsuite.at: Add tests/multiv06.at + 2008-06-26 Sergey Poznyakoff <gray@gnu.org.ua> * configure.ac, NEWS: Version 1.20.90 diff --git a/src/buffer.c b/src/buffer.c index be0b3784..e590e128 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -1,7 +1,7 @@ /* Buffer management for tar. Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001, - 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. Written by John Gilmore, on 1985-08-25. @@ -1599,13 +1599,15 @@ _gnu_flush_write (size_t buffer_level) char *copy_ptr; size_t copy_size; size_t bufsize; - + tarlong wrt; + status = _flush_write (); if (status != record_size && !multi_volume_option) archive_write_error (status); else { - records_written++; + if (status) + records_written++; bytes_written += status; } @@ -1654,6 +1656,7 @@ _gnu_flush_write (size_t buffer_level) if (real_s_name) add_chunk_header (); + wrt = bytes_written; header = find_next_block (); bufsize = available_space_after (header); while (bufsize < copy_size) @@ -1668,6 +1671,16 @@ _gnu_flush_write (size_t buffer_level) memcpy (header->buffer, copy_ptr, copy_size); memset (header->buffer + copy_size, 0, bufsize - copy_size); set_next_block_after (header + (copy_size - 1) / BLOCKSIZE); + if (multi_volume_option && wrt < bytes_written) + { + /* The value of bytes_written has changed while moving data; + that means that flush_archive was executed at least once in + between, and, as a consequence, copy_size bytes were not written + to disk. We need to update sizeleft variables to compensate for + that. */ + save_sizeleft += copy_size; + multi_volume_sync (); + } find_next_block (); } diff --git a/src/create.c b/src/create.c index 413115cf..fc26f1ef 100644 --- a/src/create.c +++ b/src/create.c @@ -1041,7 +1041,7 @@ dump_regular_file (int fd, struct tar_stat_info *st) while (size_left > 0) { size_t bufsize, count; - + mv_size_left (size_left); blk = find_next_block (); @@ -2324,6 +2324,9 @@ decode_options (int argc, char **argv) else if (utc_option) verbose_option = 2; + if (tape_length_option && tape_length_option < record_size) + USAGE_ERROR ((0, 0, _("Volume length cannot be less than record size"))); + /* Forbid using -c with no input files whatsoever. Check that `-f -', explicit or implied, is used correctly. */ diff --git a/tests/Makefile.am b/tests/Makefile.am index 729bdd95..263f6eef 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -89,6 +89,7 @@ TESTSUITE_AT = \ multiv03.at\ multiv04.at\ multiv05.at\ + multiv06.at\ old.at\ options.at\ options02.at\ diff --git a/tests/multiv06.at b/tests/multiv06.at new file mode 100644 index 00000000..4df9cd71 --- /dev/null +++ b/tests/multiv06.at @@ -0,0 +1,57 @@ +# Process this file with autom4te to create testsuite. -*- Autotest -*- + +# Test suite for GNU tar. +# Copyright (C) 2008 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# When volume size equals record size, swapping buffers in +# new_volume triggers a call to flush_archive. The size left variables +# must be corrected after that, which was not done in versions <= 1.20. +# Reported by: Marek Kielar <mkielar@go2.pl> +# References: <1907cbb6.79e32b49.48887f09.fd55@o2.pl> + +AT_SETUP([Multivolumes with L=record_size]) +AT_KEYWORDS([multivolume multiv multiv06]) + +m4_define([echo2],[ +echo $* +echo >&2 $* +]) + +AT_TAR_CHECK([ +exec <&- +echo2("Creating file") +genfile --length 20139 --file file +echo2("Creating archive") +tar -c -M -L10 -b20 -farc.1 -farc.2 -farc.3 file +echo2("Testing archive") +tar -t -M -farc.1 -farc.2 -farc.3], +[0], +[Creating file +Creating archive +Testing archive +file +], +[Creating file +Creating archive +Testing archive +], +[],[], +[gnu, pax]) + +AT_CLEANUP + diff --git a/tests/testsuite.at b/tests/testsuite.at index 5b633540..11f108bd 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -155,6 +155,7 @@ m4_include([multiv02.at]) m4_include([multiv03.at]) m4_include([multiv04.at]) m4_include([multiv05.at]) +m4_include([multiv06.at]) m4_include([old.at]) |