]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Extract common transfer setting code for statfs and statvfs.
authorChristos Zoulas <christos@zoulas.com>
Mon, 29 Mar 2021 19:32:34 +0000 (15:32 -0400)
committerChristos Zoulas <christos@zoulas.com>
Mon, 29 Mar 2021 19:32:34 +0000 (15:32 -0400)
1. Makes detection of f_iosize constent.
2. Avoid infinite loops by detecting 0 sizes and converting to -1.
   This happens with FUSE. NetBSD PR/56083.

libarchive/archive_read_disk_posix.c

index 2898206951d54f7a6e9c955ba8b74dd9e6cc6ef7..49631ab0c4d47136dad39ceb60d01e1f8546a629 100644 (file)
@@ -1525,6 +1525,15 @@ get_xfer_size(struct tree *t, int fd, const char *path)
 #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.
  */
@@ -1593,10 +1602,7 @@ setup_current_filesystem(struct archive_read_disk *a)
                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;
@@ -1651,6 +1657,20 @@ setup_current_filesystem(struct archive_read_disk *a)
 
 #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
  */
@@ -1688,15 +1708,7 @@ setup_current_filesystem(struct archive_read_disk *a)
        } else if (xr == 1) {
                /* Usually come here unless NetBSD supports _PC_REC_XFER_ALIGN
                 * for pathconf() function. */
-               t->current_filesystem->xfer_align = svfs.f_frsize;
-               t->current_filesystem->max_xfer_size = -1;
-#if defined(HAVE_STRUCT_STATVFS_F_IOSIZE)
-               t->current_filesystem->min_xfer_size = svfs.f_iosize;
-               t->current_filesystem->incr_xfer_size = svfs.f_iosize;
-#else
-               t->current_filesystem->min_xfer_size = svfs.f_bsize;
-               t->current_filesystem->incr_xfer_size = svfs.f_bsize;
-#endif
+               set_transfer_size(t->current_filesystem, &sfs);
        }
        if (svfs.f_flag & ST_LOCAL)
                t->current_filesystem->remote = 0;
@@ -1803,15 +1815,9 @@ setup_current_filesystem(struct archive_read_disk *a)
        } 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) {
@@ -1918,10 +1924,7 @@ setup_current_filesystem(struct archive_read_disk *a)
                return (ARCHIVE_FAILED);
        } else if (xr == 1) {
                /* pathconf(_PC_REX_*) operations are not supported. */
-               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, &sfs);
        }
 
 #if defined(ST_NOATIME)