From: Pavel Raiskup <praiskup@redhat.com>
To: bug-tar@gnu.org
Cc: Mark H Weaver <mhw@netris.org>,
linux btrfs <linux-btrfs@vger.kernel.org>
Subject: [PATCH] Re: [Bug-tar] Detection of sparse files is broken on btrfs
Date: Tue, 09 Jan 2018 08:46:36 +0100 [thread overview]
Message-ID: <5923534.bzxSDfjug7@nb.usersys.redhat.com> (raw)
In-Reply-To: <87fu7hccci.fsf@netris.org>
[-- Attachment #1: Type: text/plain, Size: 791 bytes --]
On Monday, January 8, 2018 3:29:17 AM CET Mark H Weaver wrote:
> I propose that we revisit this bug and fix it. We clearly cannot assume that
> st_blocks == 0 implies that the file contains only zeroes.
. only on btrfs, as far as we know, because of some race condition. So
what about special casing that filesystem, where we can lseek() for holes
anyway? Since I would prefer fixing btrfs, I'm CC'ing devels again.
I'm attaching tar patch (public domain, use as you wish) mostly for
discussion about the idea (I can or anybody finalize the ifdef-hell,
etc.). Note this fixes the failing sparse03.at for me (Fedora 27 x86_64 +
btrfs).
references for btrfs guys:
https://www.mail-archive.com/bug-tar@gnu.org/msg05453.html
https://www.spinics.net/lists/linux-btrfs/msg56768.html
Pavel
[-- Attachment #2: btrfs-wholesparse.patch --]
[-- Type: text/x-patch, Size: 2108 bytes --]
diff --git a/src/sparse.c b/src/sparse.c
index d41c0ea..d0a7a55 100644
--- a/src/sparse.c
+++ b/src/sparse.c
@@ -18,6 +18,7 @@
#include <system.h>
#include <inttostr.h>
#include <quotearg.h>
+#include <sys/statfs.h>
#include "common.h"
struct tar_sparse_file;
@@ -261,12 +262,58 @@ sparse_scan_file_raw (struct tar_sparse_file *file)
return tar_sparse_scan (file, scan_end, NULL);
}
+enum sparse_fs_behavior
+ {
+ sparse_fs_behavior_init = 0,
+ sparse_fs_behavior_fine,
+ sparse_fs_behavior_uncertain
+ };
+
+static enum sparse_fs_behavior
+check_sparse_behavior (int fd)
+{
+ struct statfs buf;
+ if (fstatfs (fd, &buf))
+ return sparse_fs_behavior_fine;
+
+ if (buf.f_type == 0x9123683e)
+ return sparse_fs_behavior_uncertain; /* btrfs */
+
+ return sparse_fs_behavior_fine;
+}
+
+static bool
+wholesparse_detection_prohibited (struct tar_stat_info *st)
+{
+ static dev_t cached_device = 0;
+ static enum sparse_fs_behavior behavior;
+
+ if (behavior == sparse_fs_behavior_init
+ || cached_device != st->stat.st_dev)
+ {
+ cached_device = st->stat.st_dev;
+ behavior = check_sparse_behavior (st->fd);
+ }
+
+ return behavior == sparse_fs_behavior_uncertain;
+}
+
+
static bool
sparse_scan_file_wholesparse (struct tar_sparse_file *file)
{
struct tar_stat_info *st = file->stat_info;
struct sp_array sp = {0, 0};
+ /* Some file-systems report st_blksize=0 for files which have some
+ inode-inlined data. This is, per bug-tar@, rather unfortunate
+ behavior, but we need to deal with these filesystems somehow. So,
+ let's prohibit the "wholesparse" detection method for such filesystems,
+ and let's hope that 'SEEK_HOLE/SEEK_DATA' works (if not, we fallback to
+ slow-but-safe 'raw' method anyway). */
+ if (wholesparse_detection_prohibited (file->stat_info))
+ return false;
+
/* Note that this function is called only for truly sparse files of size >= 1
block size (checked via ST_IS_SPARSE before). See the thread
http://www.mail-archive.com/bug-tar@gnu.org/msg04209.html for more info */
next parent reply other threads:[~2018-01-09 7:46 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <87fu7hccci.fsf@netris.org>
2018-01-09 7:46 ` Pavel Raiskup [this message]
2018-01-09 7:59 ` [Bug-tar] [PATCH] Re: Detection of sparse files is broken on btrfs Paul Eggert
2018-01-09 8:25 ` Pavel Raiskup
2018-01-09 10:15 ` Joerg Schilling
2018-01-10 12:00 ` Pavel Raiskup
2018-01-09 10:12 ` Joerg Schilling
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5923534.bzxSDfjug7@nb.usersys.redhat.com \
--to=praiskup@redhat.com \
--cc=bug-tar@gnu.org \
--cc=linux-btrfs@vger.kernel.org \
--cc=mhw@netris.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).