pkgsrc-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

pkg/57027: fuse-exfatfs cannot determine disk size



>Number:         57027
>Category:       pkg
>Synopsis:       mkexfatfs fails, unable to determine disk size.
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    pkg-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Sep 27 19:20:00 +0000 2022
>Originator:     Konrad Schroder
>Release:        NetBSD 9.3
>Organization:
	University of Washington
>Environment:
System: NetBSD wood-burner.nano.uw.edu 9.3 NetBSD 9.3 (GENERIC) #0: Thu Aug 4 15:30:37 UTC 2022 mkrepro%mkrepro.NetBSD.org@localhost:/usr/src/sys/arch/amd64/compile/GENERIC amd64
Architecture: x86_64
Machine: amd64
>Description:
	The routine to discover the hard disk size does not work for
	NetBSD, at least with GPT (I didn't try ordinary disklabel'ed disks).
>How-To-Repeat:
	WD=wd1
	DK=/dev/dk6
	gpt destroy $WD
	gpt create $WD
	gpt add -t windows -l export -a 1m -i 1 $WD
	mkexfatfs $DK

	Note that the use of the raw device also does not work.
>Fix:
This patch provides the necessary routine (copied from NetBSD's newfs/fsck)
to discover the partition size, and calls it.  (The source code writes
partial blocks assuming it is working with a block device, so it is
necessary to convert to the raw device name internally rather than
require it on the command line.)

I'll be happy to commit it myself if there are no objections.

Index: Makefile
===================================================================
RCS file: /cvsroot/pkgsrc/filesystems/fuse-exfat/Makefile,v
retrieving revision 1.2
diff -u -r1.2 Makefile
--- Makefile	24 Nov 2020 15:03:22 -0000	1.2
+++ Makefile	27 Sep 2022 17:50:06 -0000
@@ -16,7 +16,7 @@
 GNU_CONFIGURE=	yes
 USE_TOOLS+=	autoheader automake autoreconf gmake pkg-config
 
-post-extract:
+post-patch:
 	cd ${WRKSRC} && autoreconf -fiv
 
 .include "../../mk/fuse.buildlink3.mk"
Index: distinfo
===================================================================
RCS file: /cvsroot/pkgsrc/filesystems/fuse-exfat/distinfo,v
retrieving revision 1.3
diff -u -r1.3 distinfo
--- distinfo	26 Oct 2021 10:25:27 -0000	1.3
+++ distinfo	27 Sep 2022 17:50:06 -0000
@@ -3,3 +3,8 @@
 BLAKE2s (fuse-exfat-1.3.0.tar.gz) = cc38c87a3c600539f3a31d546da4ea743164e6d8aab91939222c6761e7ce39fe
 SHA512 (fuse-exfat-1.3.0.tar.gz) = fa3951e16889db65685e1fb71b0c75fc7014a8025c3442bf6164b94ddd51d282a8ae5e891c46195be53d2a10d62444e2fa1bb3fa3de59c2c3411c6dac363b488
 Size (fuse-exfat-1.3.0.tar.gz) = 57846 bytes
+SHA1 (patch-configure.ac) = 4cf96cdf651c49bc01751d38427a9451b02aeeea
+SHA1 (patch-libexfat__Makefile.am) = a1a4a6c83eac6364fef0ad4fe1fa788feececf91
+SHA1 (patch-libexfat__io.c) = e03d4bf8ae18cb08cab041dce115ffae00d17918
+SHA1 (patch-libexfat__nbpartutil.c) = 24b4062543afc864230e28cd667ada06a3a35052
+SHA1 (patch-libexfat__nbpartutil.h) = 0e87652c054314eabeafc1cbed76cbe0a933735e
Index: patches/patch-configure.ac
===================================================================
RCS file: patches/patch-configure.ac
diff -N patches/patch-configure.ac
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ patches/patch-configure.ac	27 Sep 2022 17:50:06 -0000
@@ -0,0 +1,15 @@
+$NetBSD$
+
+Supply -lutil and -lprop, required for the NetBSD disk size routine.
+
+--- configure.ac	2018-09-14 22:03:24.000000000 -0700
++++ configure.ac	2022-09-27 08:59:46.680435126 -0700
+@@ -38,6 +38,8 @@
+     [Define if block devices are not supported.])
+ ], [:])
+ PKG_CHECK_MODULES([FUSE], [fuse])
++AC_CHECK_LIB(util, opendisk)
++AC_CHECK_LIB(prop, prop_dictionary_get_int64)
+ AC_CONFIG_HEADERS([libexfat/config.h])
+ AC_CONFIG_FILES([
+ 	libexfat/Makefile
Index: patches/patch-libexfat__Makefile.am
===================================================================
RCS file: patches/patch-libexfat__Makefile.am
diff -N patches/patch-libexfat__Makefile.am
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ patches/patch-libexfat__Makefile.am	27 Sep 2022 17:50:06 -0000
@@ -0,0 +1,14 @@
+$NetBSD$
+
+Add new file containing NetBSD disk sizing routine.
+
+--- libexfat/Makefile.am	2022-09-27 10:01:50.915736384 -0700
++++ libexfat/Makefile.am	2022-09-27 10:02:11.320568581 -0700
+@@ -32,6 +32,7 @@
+ 	lookup.c \
+ 	mount.c \
+ 	node.c \
++	nbpartutil.c \
+ 	platform.h \
+ 	repair.c \
+ 	time.c \
Index: patches/patch-libexfat__io.c
===================================================================
RCS file: patches/patch-libexfat__io.c
diff -N patches/patch-libexfat__io.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ patches/patch-libexfat__io.c	27 Sep 2022 17:50:06 -0000
@@ -0,0 +1,46 @@
+$NetBSD$
+
+Add working NetBSD disk sizing.
+
+--- libexfat/io.c	2018-09-14 22:03:24.000000000 -0700
++++ libexfat/io.c	2022-09-27 09:23:55.645533399 -0700
+@@ -35,6 +35,10 @@
+ #include <sys/disklabel.h>
+ #include <sys/dkio.h>
+ #include <sys/ioctl.h>
++#elif defined(__NetBSD__)
++#include <sys/param.h>
++#include <util.h>
++#include "nbpartutil.h"
+ #elif __linux__
+ #include <sys/mount.h>
+ #endif
+@@ -226,6 +230,28 @@
+ 					"you can fix this with fdisk(8)");
+ 	}
+ 	else
++#elif defined(__NetBSD__)
++	if (!S_ISREG(stbuf.st_mode))
++	{
++		if (stbuf.st_size != 0) {
++			dev->size = stbuf.st_size;
++		} else {
++			char device[MAXPATHLEN];
++			u_int secsize;
++			off_t dksize;
++
++			/* mkexfatfs can only use the block device, but */
++			/* getdisksize() needs the raw device name      */
++			getdiskrawname(device, sizeof(device), spec);
++			getdisksize(device, &secsize, &dksize);
++			dev->size = secsize * dksize;
++		}
++		if (dev->size <= 0) {
++			exfat_error("Unable to determine file system size");
++			return NULL;
++		}
++	}
++	else
+ #endif
+ 	{
+ 		/* works for Linux, FreeBSD, Solaris */
Index: patches/patch-libexfat__nbpartutil.c
===================================================================
RCS file: patches/patch-libexfat__nbpartutil.c
diff -N patches/patch-libexfat__nbpartutil.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ patches/patch-libexfat__nbpartutil.c	27 Sep 2022 17:50:06 -0000
@@ -0,0 +1,205 @@
+$NetBSD$
+
+Supply the partition utility code from NetBSD newfs.
+Only compiled if __NetBSD__ is defined.
+
+--- libexfat/nbpartutil.c	2022-09-27 10:20:12.769075968 -0700
++++ libexfat/nbpartutil.c	2022-09-27 10:09:39.285740643 -0700
+@@ -0,0 +1,197 @@
++#ifdef __NetBSD__
++/*	NetBSD: partutil.c,v 1.15.18.2 2021/01/09 19:30:14 martin Exp 	*/
++
++/*-
++ * Copyright (c) 2006 The NetBSD Foundation, Inc.
++ * All rights reserved.
++ *
++ * This code is derived from software contributed to The NetBSD Foundation
++ * by Christos Zoulas.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
++ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
++ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
++ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
++ * POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#include <sys/cdefs.h>
++
++#include <sys/types.h>
++#include <sys/param.h>
++#include <sys/disklabel.h>
++#include <sys/disk.h>
++#include <sys/ioctl.h>
++#include <sys/stat.h>
++
++
++#include <disktab.h>
++#include <err.h>
++#include <errno.h>
++#include <fcntl.h>
++#include <util.h>
++#include <unistd.h>
++#include <stdlib.h>
++#include <string.h>
++
++#include <prop/proplib.h>
++
++#include "nbpartutil.h"
++
++/*
++ * Convert disklabel geometry info to disk_geom.
++ */
++static void
++label2geom(struct disk_geom *geo, const struct disklabel *lp)
++{
++	geo->dg_secperunit = lp->d_secperunit;
++	geo->dg_secsize = lp->d_secsize;
++	geo->dg_nsectors = lp->d_nsectors;
++	geo->dg_ntracks = lp->d_ntracks;
++	geo->dg_ncylinders = lp->d_ncylinders;
++	geo->dg_secpercyl = lp->d_secpercyl;
++	geo->dg_pcylinders = lp->d_ncylinders;
++	geo->dg_sparespertrack = lp->d_sparespertrack;
++	geo->dg_sparespercyl = lp->d_sparespercyl;
++	geo->dg_acylinders = lp->d_acylinders;
++}
++
++/*
++ * Set what we need to know about disk geometry.
++ */
++static void
++dict2geom(struct disk_geom *geo, prop_dictionary_t dict)
++{
++	(void)memset(geo, 0, sizeof(struct disk_geom));
++	prop_dictionary_get_int64(dict, "sectors-per-unit",
++	    &geo->dg_secperunit);
++	prop_dictionary_get_uint32(dict, "sector-size", &geo->dg_secsize);
++	prop_dictionary_get_uint32(dict, "sectors-per-track",
++	    &geo->dg_nsectors);
++	prop_dictionary_get_uint32(dict, "tracks-per-cylinder",
++	    &geo->dg_ntracks);
++	prop_dictionary_get_uint32(dict, "cylinders-per-unit",
++	    &geo->dg_ncylinders);
++}
++
++
++int
++getdiskinfo(const char *s, int fd, const char *dt, struct disk_geom *geo,
++    struct dkwedge_info *dkw)
++{
++	struct disklabel lab;
++	struct disklabel *lp = &lab;
++	prop_dictionary_t disk_dict, geom_dict;
++	struct stat sb;
++	const struct partition *pp;
++	int ptn, error;
++
++	if (dt) {
++		lp = getdiskbyname(dt);
++		if (lp == NULL)
++			errx(1, "unknown disk type `%s'", dt);
++	}
++
++	/* Get disk description dictionary */
++	disk_dict = NULL;
++	error = prop_dictionary_recv_ioctl(fd, DIOCGDISKINFO, &disk_dict);
++
++	/* fail quickly if the device does not exist at all */
++	if (error == ENXIO)
++		return -1;
++
++	if (error) {
++		/*
++		 * Ask for disklabel if DIOCGDISKINFO failed. This is
++		 * compatibility call and can be removed when all devices
++		 * will support DIOCGDISKINFO.
++		 * cgd, ccd pseudo disk drives doesn't support DIOCGDDISKINFO
++		 */
++		if (ioctl(fd, DIOCGDINFO, lp) == -1) {
++			if (errno != ENXIO)
++				warn("DIOCGDINFO on %s failed", s);
++			return -1;
++		}
++		label2geom(geo, lp);
++	} else {
++		geom_dict = prop_dictionary_get(disk_dict, "geometry");
++		dict2geom(geo, geom_dict);
++	}
++	if (disk_dict != NULL)
++		prop_object_release(disk_dict);
++
++	if (dkw == NULL)
++		return 0;
++
++	/* Get info about partition/wedge */
++	if (ioctl(fd, DIOCGWEDGEINFO, dkw) != -1) {
++		/* DIOCGWEDGEINFO didn't fail, we're done */
++		return 0;
++	}
++
++	if (ioctl(fd, DIOCGDINFO, lp) == -1) {
++		err(1, "Please implement DIOCGWEDGEINFO or "
++		    "DIOCGDINFO for disk device %s", s);
++	}
++
++	/* DIOCGDINFO didn't fail */
++	(void)memset(dkw, 0, sizeof(*dkw));
++
++	if (stat(s, &sb) == -1)
++		return 0;
++
++	ptn = strchr(s, '\0')[-1] - 'a';
++	if ((unsigned)ptn >= lp->d_npartitions ||
++	    (devminor_t)ptn != DISKPART(sb.st_rdev))
++		return 0;
++
++	pp = &lp->d_partitions[ptn];
++	if (ptn != getrawpartition()) {
++		dkw->dkw_offset = pp->p_offset;
++		dkw->dkw_size = pp->p_size;
++	} else {
++		dkw->dkw_offset = 0;
++		dkw->dkw_size = geo->dg_secperunit;
++	}
++	dkw->dkw_parent[0] = '*';
++	strlcpy(dkw->dkw_ptype, getfstypename(pp->p_fstype),
++	    sizeof(dkw->dkw_ptype));
++
++	return 0;
++}
++
++int
++getdisksize(const char *name, u_int *secsize, off_t *mediasize)
++{
++	char buf[MAXPATHLEN];
++	struct disk_geom geo;
++	int fd, error;
++
++	if ((fd = opendisk(name, O_RDONLY, buf, sizeof(buf), 0)) == -1)
++		return -1;
++
++	error = getdiskinfo(name, fd, NULL, &geo, NULL);
++	close(fd);
++	if (error)
++		return error;
++
++	*secsize = geo.dg_secsize;
++	*mediasize = geo.dg_secsize * geo.dg_secperunit;
++	return 0;
++}
++#endif /* __NetBSD__ */
Index: patches/patch-libexfat__nbpartutil.h
===================================================================
RCS file: patches/patch-libexfat__nbpartutil.h
diff -N patches/patch-libexfat__nbpartutil.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ patches/patch-libexfat__nbpartutil.h	27 Sep 2022 17:50:06 -0000
@@ -0,0 +1,50 @@
+$NetBSD$
+
+Supply the partition utility code from NetBSD newfs.
+Only compiled if __NetBSD__ is defined.
+
+--- libexfat/nbpartutil.h	2022-09-27 10:20:12.769075968 -0700
++++ libexfat/nbpartutil.h	2022-09-27 10:09:39.310695167 -0700
+@@ -0,0 +1,42 @@
++/*	NetBSD: partutil.h,v 1.3 2014/12/29 16:27:43 christos Exp 	*/
++
++/*-
++ * Copyright (c) 2006 The NetBSD Foundation, Inc.
++ * All rights reserved.
++ *
++ * This code is derived from software contributed to The NetBSD Foundation
++ * by Christos Zoulas.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
++ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
++ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
++ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
++ * POSSIBILITY OF SUCH DAMAGE.
++ */
++#ifndef _PARTUTIL_H_
++#define _PARTUTIL_H_
++
++__BEGIN_DECLS
++struct dkwedge_info;
++struct disk_geom;
++int getdiskinfo(const char *, int, const char *,
++    struct disk_geom *, struct dkwedge_info *);
++int getdisksize(const char *, u_int *, off_t *);
++__END_DECLS
++
++#endif /* _PARTUTIL_H_ */



Home | Main Index | Thread Index | Old Index