From a9895fd20c957ce184091672f1623a5bedd82407 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 24 Aug 2010 17:28:11 -0700 Subject: [PATCH] tar: optimize -c --sparse when file is entirely sparse * src/sparse.c (sparse_scan_file): If the file is entirely sparse, that is, if ST_NBLOCKS is zero, don't bother scanning for nonzero blocks. Idea by Kit Westneat, communicated by Bernd Schubert in . Also, omit unnecessary lseek at start of file. --- src/sparse.c | 54 +++++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/src/sparse.c b/src/sparse.c index 8af4b47..9680b60 100644 --- a/src/sparse.c +++ b/src/sparse.c @@ -217,43 +217,45 @@ sparse_scan_file (struct tar_sparse_file *file) struct tar_stat_info *st = file->stat_info; int fd = file->fd; char buffer[BLOCKSIZE]; - size_t count; + size_t count = 0; off_t offset = 0; struct sp_array sp = {0, 0}; - if (!lseek_or_error (file, 0)) - return false; - st->archive_file_size = 0; - if (!tar_sparse_scan (file, scan_begin, NULL)) - return false; - - while ((count = safe_read (fd, buffer, sizeof buffer)) != 0 - && count != SAFE_READ_ERROR) + if (ST_NBLOCKS (st->stat) == 0) + offset = st->stat.st_size; + else { - /* Analyze the block. */ - if (zero_block_p (buffer, count)) + if (!tar_sparse_scan (file, scan_begin, NULL)) + return false; + + while ((count = safe_read (fd, buffer, sizeof buffer)) != 0 + && count != SAFE_READ_ERROR) { - if (sp.numbytes) + /* Analyze the block. */ + if (zero_block_p (buffer, count)) { - sparse_add_map (st, &sp); - sp.numbytes = 0; - if (!tar_sparse_scan (file, scan_block, NULL)) + if (sp.numbytes) + { + sparse_add_map (st, &sp); + sp.numbytes = 0; + if (!tar_sparse_scan (file, scan_block, NULL)) + return false; + } + } + else + { + if (sp.numbytes == 0) + sp.offset = offset; + sp.numbytes += count; + st->archive_file_size += count; + if (!tar_sparse_scan (file, scan_block, buffer)) return false; } - } - else - { - if (sp.numbytes == 0) - sp.offset = offset; - sp.numbytes += count; - st->archive_file_size += count; - if (!tar_sparse_scan (file, scan_block, buffer)) - return false; - } - offset += count; + offset += count; + } } if (sp.numbytes == 0) -- 2.44.0