linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Re: [Bug-tar] Detection of sparse files is broken on btrfs
       [not found] <87fu7hccci.fsf@netris.org>
@ 2018-01-09  7:46 ` Pavel Raiskup
  2018-01-09  7:59   ` [Bug-tar] [PATCH] " Paul Eggert
  0 siblings, 1 reply; 6+ messages in thread
From: Pavel Raiskup @ 2018-01-09  7:46 UTC (permalink / raw)
  To: bug-tar; +Cc: Mark H Weaver, linux btrfs

[-- 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 */

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [Bug-tar] [PATCH] Re: Detection of sparse files is broken on btrfs
  2018-01-09  7:46 ` [PATCH] Re: [Bug-tar] Detection of sparse files is broken on btrfs Pavel Raiskup
@ 2018-01-09  7:59   ` Paul Eggert
  2018-01-09  8:25     ` Pavel Raiskup
  2018-01-09 10:12     ` Joerg Schilling
  0 siblings, 2 replies; 6+ messages in thread
From: Paul Eggert @ 2018-01-09  7:59 UTC (permalink / raw)
  To: Pavel Raiskup, bug-tar; +Cc: Mark H Weaver, linux btrfs

Pavel Raiskup wrote:
> So
> what about special casing that filesystem, where we can lseek() for holes
> anyway?

If we can lseek for holes, then why not just do that? We shouldn't need 
special-case code for btrfs per se. Any filesystem where we can lseek for holes 
should take advantage of that optimization.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Bug-tar] [PATCH] Re: Detection of sparse files is broken on btrfs
  2018-01-09  7:59   ` [Bug-tar] [PATCH] " Paul Eggert
@ 2018-01-09  8:25     ` Pavel Raiskup
  2018-01-09 10:15       ` Joerg Schilling
  2018-01-09 10:12     ` Joerg Schilling
  1 sibling, 1 reply; 6+ messages in thread
From: Pavel Raiskup @ 2018-01-09  8:25 UTC (permalink / raw)
  To: Paul Eggert; +Cc: bug-tar, Mark H Weaver, linux btrfs

On Tuesday, January 9, 2018 8:59:06 AM CET Paul Eggert wrote:
> Pavel Raiskup wrote:
> > So what about special casing that filesystem, where we can lseek() for
> > holes anyway?
> 
> If we can lseek for holes, then why not just do that?

Checking whether lseek() actually works costs some additional syscalls _per
sparse_ file;  checking for ST_NBLOCKS() is without this penalty.

> We shouldn't need special-case code for btrfs per se. Any filesystem
> where we can lseek for holes should take advantage of that optimization.

It is done so actually, the 'wholesparse' is another optimization on top
of that (but usable also in cases where SEEK_HOLE isn't defined at all).

Pavel




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Bug-tar] [PATCH] Re: Detection of sparse files is broken on btrfs
  2018-01-09  7:59   ` [Bug-tar] [PATCH] " Paul Eggert
  2018-01-09  8:25     ` Pavel Raiskup
@ 2018-01-09 10:12     ` Joerg Schilling
  1 sibling, 0 replies; 6+ messages in thread
From: Joerg Schilling @ 2018-01-09 10:12 UTC (permalink / raw)
  To: praiskup, eggert, bug-tar; +Cc: mhw, linux-btrfs

Paul Eggert <eggert@cs.ucla.edu> wrote:

> If we can lseek for holes, then why not just do that? We shouldn't need 
> special-case code for btrfs per se. Any filesystem where we can lseek for holes 
> should take advantage of that optimization.

This is what star uses since 13 years ;-)

Jörg

-- 
 EMail:joerg@schily.net                    (home) Jörg Schilling D-13353 Berlin
    joerg.schilling@fokus.fraunhofer.de (work) Blog: http://schily.blogspot.com/
 URL: http://cdrecord.org/private/ http://sf.net/projects/schilytools/files/'

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Bug-tar] [PATCH] Re: Detection of sparse files is broken on btrfs
  2018-01-09  8:25     ` Pavel Raiskup
@ 2018-01-09 10:15       ` Joerg Schilling
  2018-01-10 12:00         ` Pavel Raiskup
  0 siblings, 1 reply; 6+ messages in thread
From: Joerg Schilling @ 2018-01-09 10:15 UTC (permalink / raw)
  To: praiskup, eggert; +Cc: mhw, linux-btrfs, bug-tar

Pavel Raiskup <praiskup@redhat.com> wrote:

> On Tuesday, January 9, 2018 8:59:06 AM CET Paul Eggert wrote:
> > Pavel Raiskup wrote:
> > > So what about special casing that filesystem, where we can lseek() for
> > > holes anyway?
> > 
> > If we can lseek for holes, then why not just do that?
>
> Checking whether lseek() actually works costs some additional syscalls _per
> sparse_ file;  checking for ST_NBLOCKS() is without this penalty.

Well, star does this since a long time and the penalty is a few microseconds.

"~A

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Bug-tar] [PATCH] Re: Detection of sparse files is broken on btrfs
  2018-01-09 10:15       ` Joerg Schilling
@ 2018-01-10 12:00         ` Pavel Raiskup
  0 siblings, 0 replies; 6+ messages in thread
From: Pavel Raiskup @ 2018-01-10 12:00 UTC (permalink / raw)
  To: bug-tar; +Cc: Joerg Schilling, eggert, mhw, linux-btrfs

On Tuesday, January 9, 2018 11:15:56 AM CET Joerg Schilling wrote:
> Pavel Raiskup <praiskup@redhat.com> wrote:
> 
> > On Tuesday, January 9, 2018 8:59:06 AM CET Paul Eggert wrote:
> > > Pavel Raiskup wrote:
> > > > So what about special casing that filesystem, where we can lseek() for
> > > > holes anyway?
> > > 
> > > If we can lseek for holes, then why not just do that?
> >
> > Checking whether lseek() actually works costs some additional syscalls _per
> > sparse_ file;  checking for ST_NBLOCKS() is without this penalty.
> 
> Well, star does this since a long time and the penalty is a few microseconds.

It would be interesting to see how network filesystems are affected.

Pavel




^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2018-01-10 12:00 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <87fu7hccci.fsf@netris.org>
2018-01-09  7:46 ` [PATCH] Re: [Bug-tar] Detection of sparse files is broken on btrfs Pavel Raiskup
2018-01-09  7:59   ` [Bug-tar] [PATCH] " 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

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).