Module Name:    src
Committed By:   christos
Date:           Mon Mar 29 15:31:46 UTC 2021

Modified Files:
        src/external/bsd/libarchive/dist/libarchive: archive_read_disk_posix.c

Log Message:
PR/56083: RVP: tar -c hangs when reading from FUSE-ext2 filesystems since
it returns 0 for statvfs members and libarchive handles only -1. Centralize
the transfer setting code.


To generate a diff of this commit:
cvs rdiff -u -r1.1.1.2 -r1.2 \
    src/external/bsd/libarchive/dist/libarchive/archive_read_disk_posix.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/external/bsd/libarchive/dist/libarchive/archive_read_disk_posix.c
diff -u src/external/bsd/libarchive/dist/libarchive/archive_read_disk_posix.c:1.1.1.2 src/external/bsd/libarchive/dist/libarchive/archive_read_disk_posix.c:1.2
--- src/external/bsd/libarchive/dist/libarchive/archive_read_disk_posix.c:1.1.1.2	Wed Jul 24 09:50:23 2019
+++ src/external/bsd/libarchive/dist/libarchive/archive_read_disk_posix.c	Mon Mar 29 11:31:46 2021
@@ -1527,6 +1527,15 @@ get_xfer_size(struct tree *t, int fd, co
 #if defined(HAVE_STATFS) && defined(HAVE_FSTATFS) && defined(MNT_LOCAL) \
 	&& !defined(ST_LOCAL)
 
+static void
+set_transfer_size(struct filesystem *fs, const struct statfs *sfs)
+{
+	fs->xfer_align = sfs->f_bsize > 0 ? (long)sfs->fs_bsize : -1;
+	fs->max_xfer_size = -1;
+	fs->min_xfer_size = sfs->f_iosize > 0 ? (long)sfs->f_iosize : -1;
+	fs->incr_xfer_size = sfs->f_iosize > 0 ? (long)sfs->f_iosize : -1;
+}
+
 /*
  * Gather current filesystem properties on FreeBSD, OpenBSD and Mac OS X.
  */
@@ -1595,10 +1604,7 @@ setup_current_filesystem(struct archive_
 		return (ARCHIVE_FAILED);
 	} else if (xr == 1) {
 		/* pathconf(_PC_REX_*) operations are not supported. */
-		t->current_filesystem->xfer_align = sfs.f_bsize;
-		t->current_filesystem->max_xfer_size = -1;
-		t->current_filesystem->min_xfer_size = sfs.f_iosize;
-		t->current_filesystem->incr_xfer_size = sfs.f_iosize;
+		set_transfer_size(t->current_filesystem, &sfs);
 	}
 	if (sfs.f_flags & MNT_LOCAL)
 		t->current_filesystem->remote = 0;
@@ -1653,6 +1659,20 @@ setup_current_filesystem(struct archive_
 
 #elif (defined(HAVE_STATVFS) || defined(HAVE_FSTATVFS)) && defined(ST_LOCAL)
 
+static void
+set_transfer_size(struct filesystem *fs, const struct statvfs *sfs)
+{
+	fs->xfer_align = sfs->f_frsize > 0 ? (long)sfs->f_frsize : -1;
+	fs->max_xfer_size = -1;
+#if defined(HAVE_STRUCT_STATVFS_F_IOSIZE)
+	fs->min_xfer_size = sfs->f_iosize > 0 ? (long)sfs->f_iosize : -1;
+	fs->incr_xfer_size = sfs->f_iosize > 0 ? (long)sfs->f_iosize : -1;
+#else
+	fs->min_xfer_size = sfs->f_bsize > 0 : (long)sfs->f_bsize : -1;
+	fs->incr_xfer_size = sfs->f_bsize > 0 : (long)sfs->f_bsize : -1;
+#endif
+}
+
 /*
  * Gather current filesystem properties on NetBSD
  */
@@ -1690,15 +1710,7 @@ setup_current_filesystem(struct archive_
 	} else if (xr == 1) {
 		/* Usually come here unless NetBSD supports _PC_REC_XFER_ALIGN
 		 * for pathconf() function. */
-		t->current_filesystem->xfer_align = sfs.f_frsize;
-		t->current_filesystem->max_xfer_size = -1;
-#if defined(HAVE_STRUCT_STATVFS_F_IOSIZE)
-		t->current_filesystem->min_xfer_size = sfs.f_iosize;
-		t->current_filesystem->incr_xfer_size = sfs.f_iosize;
-#else
-		t->current_filesystem->min_xfer_size = sfs.f_bsize;
-		t->current_filesystem->incr_xfer_size = sfs.f_bsize;
-#endif
+		set_transfer_size(t->current_filesystem, &sfs);
 	}
 	if (sfs.f_flag & ST_LOCAL)
 		t->current_filesystem->remote = 0;
@@ -1805,15 +1817,9 @@ setup_current_filesystem(struct archive_
 	} else if (xr == 1) {
 		/* pathconf(_PC_REX_*) operations are not supported. */
 #if defined(HAVE_STATVFS)
-		t->current_filesystem->xfer_align = svfs.f_frsize;
-		t->current_filesystem->max_xfer_size = -1;
-		t->current_filesystem->min_xfer_size = svfs.f_bsize;
-		t->current_filesystem->incr_xfer_size = svfs.f_bsize;
+		set_transfer_size(t->current_filesystem, &svfs);
 #else
-		t->current_filesystem->xfer_align = sfs.f_frsize;
-		t->current_filesystem->max_xfer_size = -1;
-		t->current_filesystem->min_xfer_size = sfs.f_bsize;
-		t->current_filesystem->incr_xfer_size = sfs.f_bsize;
+		set_transfer_size(t->current_filesystem, &sfs);
 #endif
 	}
 	switch (sfs.f_type) {
@@ -1920,10 +1926,7 @@ setup_current_filesystem(struct archive_
 		return (ARCHIVE_FAILED);
 	} else if (xr == 1) {
 		/* pathconf(_PC_REX_*) operations are not supported. */
-		t->current_filesystem->xfer_align = sfs.f_frsize;
-		t->current_filesystem->max_xfer_size = -1;
-		t->current_filesystem->min_xfer_size = sfs.f_bsize;
-		t->current_filesystem->incr_xfer_size = sfs.f_bsize;
+		set_transfer_size(t->current_filesystem, &sfs);
 	}
 
 #if defined(ST_NOATIME)

Reply via email to