From: Paul Eggert Date: Sat, 26 Jan 2013 17:52:55 +0000 (-0800) Subject: tar: fix bug with sparse files with effective size of 8 GiB or more X-Git-Url: https://git.dogcows.com/gitweb?a=commitdiff_plain;h=2f6c03cba298eaa46a6e18500c0ab17d35a00a23;p=chaz%2Ftar tar: fix bug with sparse files with effective size of 8 GiB or more Reported by Pavel Raiskup in . * NEWS: Document the fix. * src/sparse.c (pax_start_header): New function. (pax_dump_header_0, pax_dump_header_1): Use it. --- diff --git a/NEWS b/NEWS index e372663..29b4486 100644 --- a/NEWS +++ b/NEWS @@ -1,9 +1,16 @@ -GNU tar NEWS - User visible changes. 2013-01-01 +GNU tar NEWS - User visible changes. 2013-01-26 Please send GNU tar bug reports to version 1.26.90 (Git) +* Bug fixes + +** Sparse files with large data + +When creating a PAX-format archive, tar no longer arbitrarily restricts +the size of the representation of a sparse file to be less than 8 GiB. + * Quoting In the default C locale, diagnostics and output of 'tar' have been diff --git a/src/sparse.c b/src/sparse.c index b93cdc2..417d4ff 100644 --- a/src/sparse.c +++ b/src/sparse.c @@ -917,6 +917,18 @@ pax_sparse_member_p (struct tar_sparse_file *file) || file->stat_info->sparse_major > 0; } +/* Start a header that uses the effective (shrunken) file size. */ +static union block * +pax_start_header (struct tar_stat_info *st) +{ + off_t realsize = st->stat.st_size; + union block *blk; + st->stat.st_size = st->archive_file_size; + blk = start_header (st); + st->stat.st_size = realsize; + return blk; +} + static bool pax_dump_header_0 (struct tar_sparse_file *file) { @@ -966,9 +978,7 @@ pax_dump_header_0 (struct tar_sparse_file *file) return false; } } - blk = start_header (file->stat_info); - /* Store the effective (shrunken) file size */ - OFF_TO_CHARS (file->stat_info->archive_file_size, blk->header.size); + blk = pax_start_header (file->stat_info); finish_header (file->stat_info, blk, block_ordinal); if (save_file_name) { @@ -1033,9 +1043,7 @@ pax_dump_header_1 (struct tar_sparse_file *file) if (strlen (file->stat_info->file_name) > NAME_FIELD_SIZE) file->stat_info->file_name[NAME_FIELD_SIZE] = 0; - blk = start_header (file->stat_info); - /* Store the effective (shrunken) file size */ - OFF_TO_CHARS (file->stat_info->archive_file_size, blk->header.size); + blk = pax_start_header (file->stat_info); finish_header (file->stat_info, blk, block_ordinal); free (file->stat_info->file_name); file->stat_info->file_name = save_file_name;