[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[coreutils] Re: [Bug-tar] [PATCH] improved sparse file detection
From: |
Paul Eggert |
Subject: |
[coreutils] Re: [Bug-tar] [PATCH] improved sparse file detection |
Date: |
Tue, 24 Aug 2010 17:37:55 -0700 |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.11) Gecko/20100713 Thunderbird/3.0.6 |
> Could we please proceed with the paper work ASAP? For Kit and me please.
Thanks for doing that. Please start on the paperwork anyway,
since it sounds like you'll need to contribute some other code soon.
However, in this particular case the idea is so simple that I coded it
up from scratch myself (see patch below).
> Yes we know about FIEMAP and the Solaris lseek() approch and that should be
> the next step to add.
There are already hooks for that in GNU tar, which are not used yet.
But in the meantime this optimization is a very simple one and should
work everywhere. Thanks again for suggesting this idea.
>> Meanwhile, if you are indeed correct that there are easy ways to detect
>> completely sparse files, even when the ioctl or SEEK_HOLE directives are
>> not present, then the coreutils cp(1) hole iteration routine should
>> probably be taught that corner case to recognize an entirely sparse file
>> as a single hole.
That's a good suggestion; I'll look into that.
Here's the patch I installed. Here I used "diff -b" to avoid
unimportant indentation changes.
From: Paul Eggert <address@hidden>
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
<http://lists.gnu.org/archive/html/bug-tar/2010-08/msg00038.html>.
Also, omit unnecessary lseek at start of file.
diff --git a/src/sparse.c b/src/sparse.c
index 8af4b47..9680b60 100644
--- a/src/sparse.c
+++ b/src/sparse.c
@@ -217,15 +217,16 @@ 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 (ST_NBLOCKS (st->stat) == 0)
+ offset = st->stat.st_size;
+ else
+ {
if (!tar_sparse_scan (file, scan_begin, NULL))
return false;
@@ -255,6 +256,7 @@ sparse_scan_file (struct tar_sparse_file *file)
offset += count;
}
+ }
if (sp.numbytes == 0)
sp.offset = offset;