From: Christos Zoulas Date: Mon, 29 Mar 2021 19:32:34 +0000 (-0400) Subject: Extract common transfer setting code for statfs and statvfs. X-Git-Tag: v3.5.2~19^2~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4190194eb8ef375e14897bd7b98db7687b861f43;p=thirdparty%2Flibarchive.git Extract common transfer setting code for statfs and statvfs. 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. --- diff --git a/libarchive/archive_read_disk_posix.c b/libarchive/archive_read_disk_posix.c index 289820695..49631ab0c 100644 --- a/libarchive/archive_read_disk_posix.c +++ b/libarchive/archive_read_disk_posix.c @@ -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)