NetBSD Problem Report #48808
From www@NetBSD.org Wed May 14 08:32:06 2014
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [149.20.53.66])
(using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits))
(Client CN "mail.netbsd.org", Issuer "Postmaster NetBSD.org" (verified OK))
by mollari.NetBSD.org (Postfix) with ESMTPS id 4B424A5813
for <gnats-bugs@gnats.NetBSD.org>; Wed, 14 May 2014 08:32:06 +0000 (UTC)
Message-Id: <20140514083202.54F2BA5856@mollari.NetBSD.org>
Date: Wed, 14 May 2014 08:32:01 +0000 (UTC)
From: scdbackup@gmx.net
Reply-To: scdbackup@gmx.net
To: gnats-bugs@NetBSD.org
Subject: Enhance mount_cd9660 by option -s like in other BSDs
X-Send-Pr-Version: www-1.0
>Number: 48808
>Category: kern
>Synopsis: Enhance mount_cd9660 by option -s like in other BSDs
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Wed May 14 08:35:00 +0000 2014
>Last-Modified: Sun Jun 01 15:05:01 +0000 2014
>Originator: Thomas Schmitt
>Release: 6.99.40 as of early may 2014, with kern/48787
>Organization:
>Environment:
NetBSD netbsd 6.99.40 NetBSD 6.99.40 (GENERIC) #65: Tue May 13 20:39:35 UTC 2014 thomas@netbsd:/usr/obj/sys/arch/i386/compile/GENERIC i386
>Description:
I have running on my modified 6.99.40 kernel a /sbin/mount_cd9660
which knows option -s to address an ISO 9660 superblock other than
the ones pointed to by /dev/cd0a or /dev/cd0d.
struct iso_args as of /usr/include/isofs/cd9660/mount_cd9660.h
has been enhanced with special care to maintain API and ABI
compatibility for older userland and kernels.
My addition to man 8 mount_cd9660 says:
[ The options are as follows:]
[...]
[ -o Options are specified with a -o flag followed by a comma]
[...]
ssector
Is ignored as input option but reported by getargs if
option -s is in effect.
-s block_offset
Read the superblock from a block address, which is computed by
adding block_offset to the partition offset implied by the choice
of the device file. With /dev/cdXd this partition offset is 0,
which leads to the first and oldest ISO-9660 session on the
medium. /dev/cdXa has the offset of the last and youngest
recognized medium partition. Other sessions may be reached from
/dev/cdXd by -s with a block_offset which can be obtained from
burn software for optical media. The block size is 2048 bytes.
/dev/cdX partitions are recognized from logical tracks of
unformatted optical media. Formatted media appear as a single
partition. Nevertheless they may bear several ISO-9660 sessions.
Refer to their ISO-9660 producer for offset info.
Compatibility between old/new kernel and new/old userland:
/sbin/mount_cd9660 will not offer option -s if not ISOFSMNT_SSECTOR
was defined in /usr/include/isofs/cd9660/cd9660_mount.h at compile
time.
Such a binary will react on -s like the current /sbin/mount_cd9660:
netbsd# mount_cd9660 -s 8768 /dev/cd0d /mnt/iso
mount_cd9660: unknown option -- s
usage: mount_cd9660 [-o options] special node
If -s is enabled and gets used with a non-zero value, then
mount_cd9660 will check after successful mounting, whether the kernel
seems to have expected the old struct iso_args and thus must have
ignored ISOFSMNT_SSECTOR and iso_args.ssector.
It will then unmount(2) the freshly but wrongly mounted ISO.
On a kernel with old struct iso_args this yields
netbsd# mount_cd9660 -s 8768 /dev/cd0d /mnt/iso
mount_cd9660 : Kernel ignored option -s.
mount_cd9660 : Had to revoke mount attempt with option -s
netbsd# mount | grep cd0d
netbsd#
netbsd# mount_cd9660 /dev/cd0d /mnt/iso
netbsd# mount | grep cd0d
/dev/cd0d on /mnt/iso type cd9660 (read-only, local)
On a kernel with new struct iso_args, both are supposed to work
netbsd# mount_cd9660 -s 8768 /dev/cd0d /mnt/iso
netbsd# mount | grep cd0d
/dev/cd0d on /mnt/iso type cd9660 (read-only, local)
The inquiry by MNT_GETARGS will report non-zero -s values
netbsd# mount_cd9660 -o getargs /dev/cd0d /mnt/iso
0x40<ssector>
-s 8768
Old mount_9660 on a new kernel works (without -s, of course).
Some background about the number used:
Session start block numbers for the ISO filesystem are learned from
netbsd$ xorriso -indev /dev/rcd0d -toc
...
TOC layout : Idx , sbsector , Size , Volume Id
ISO session : 1 , 32 , 24s , ISOIMAGE
ISO session : 2 , 64 , 8695s , ISOIMAGE
ISO session : 3 , 8768 , 7936s , ISOIMAGE
ISO session : 4 , 16704 , 2097240s , ISOIMAGE
ISO session : 5 , 2113952 , 7883s , ISOIMAGE
The numbers underneath "sbsector" are valid parameters for -s.
cd0d and cd0a both are session 5, pointed to by the default
superblock at offset 0. (The other superblocks form a chain
by starting at the next 32-blocks-aligned address after the
previous image end.)
Above -toc is from a virtual CD-ROM drive, behaving like a DVD+RW
(i.e. formatted medium) in a read-only drive. Real multi-session media,
e.g. BD-R have their first session at block 0, and there would be a
difference between cd0a and cd0d:
ISO session : 1 , 0 , 1452463s , HOME_2014_04_20_120026
ISO session : 2 , 1452640 , 37251s , HOME_2014_04_21_123352
...
ISO session : 23 , 2508608 , 54916s , HOME_2014_05_12_115406
ISO session : 24 , 2563680 , 54686s , HOME_2014_05_13_111159
cd0d is then session 1. cd0a is (supposed to be) session 24.
The sessions inbetween are now reachable by -s.
They then provide daily snapshots of $HOME from my real computer.
I hope to use this BD-R for another half year of backups.
Somehwere between session 200 and 300 it will go on strike
if it is not full before. All snapshots will still be readable
then, only writing will not work any more.
Important notice for all reviewers:
The kernel patch proposal contains the termination of publishing
all cd9660 header files, except
/usr/include/isofs/cd9660/mount_cd9660.h
which is public for usage with mount(2).
A discussion on tech-kern did not yield objections up to now. See
http://mail-index.netbsd.org/tech-kern/2014/05/13/msg017048.html
and follow-ups.
The public exposure of the then private headers makes it nearly
impossible to augment the implementation without disturbing
potential undue includers.
I hope there are none, or that they show up and start discussing.
>How-To-Repeat:
Test ISO image is once again
http://scdbackup.webframe.org/large.iso.bz2
4470 bytes, MD5 7d78dc3efaec8ea3f1801335329f410d.
It inflates to 4,329,897,984 bytes.
Do this only if the fix of kern/48787 is applied.
If not, you will not get rid of the /mnt/iso mount point until reboot !
It bears two sessions. Number 2 is mounted by default:
TOC layout : Idx , sbsector , Size , Volume Id
ISO session : 1 , 32 , 2113977s , ISOIMAGE
ISO session : 2 , 2114016 , 25s , ISOIMAGE
If the ISO is submitted as /dev/cd0, do:
mount_cd9660 -s 32 /dev/cd0d /mnt/iso
ls -l /mnt/iso
which should show only one file in the ISO root (containing a
large file which triggers an interesting bug):
drwxr-xr-x 1 thomas dbus 2048 May 6 15:30 my
Now for session 2 which is default:
umount /mnt/iso
mount_cd9660 /dev/cd0d /mnt/iso
ls -l /mnt/iso
should show two files in the ISO root:
drwxr-xr-x 1 thomas dbus 2048 May 6 15:30 my
-rw-r--r-- 1 thomas dbus 6 May 6 15:34 small_file
(Actually user id 1000, group id 1000)
>Fix:
I will propose three patches.
One for sys/fs/cd9660, one for sbin/mount_cd9660, and one for
/usr/src/distrib/sets/lists/comp/mi, where the now private header
files are currently listed as "comp-c-include".
The kernel patch proposal still contains open questions, marked by "XXX":
- There is a very peculiar "partition" semantic with /dev/cd*.
The position of the superblock is taken from a partition offset.
cd9660_vfsops.c:
sess = label.d_partitions[DISKPART(dev)].p_cdsession;
Nevertheless the block addressing is done relative to the base device
/dev/cdXd. This is indeed appropriate for ISO 9660 multi-session, but
hardly for partitions.
I still have to explore the effect of above code line with partitioned
hard disk media. Does .p_cdsession show non-zero values there ?
Do the bread() operations work relative to the partition start ?
- I allocate a struct iso_args as local variable on the stack.
Size is 120 bytes on i386. Is there a rigid stack dscipline which
would demand malloc() and free() for larger objects ?
- The old kernels silently ignore my new flags bit ISOFSMNT_SSECTOR.
This makes necessary in sbin/mount_cd9660 a cumbersome check after
mount(2) and eventually revocation of the misdirected mount by
unmount(2).
I would like to avoid this with future changes.
Therefore i want to throw EINVAL on unknown flags bits.
Martin Husemann stated to me, that struct iso_arg is supposed
to be submitted properly zeroized in all unused bits and bytes.
- I see flags bit ISOFSMNT_NOCASETRANS missing in the statement which
memorizes the options for inquiry by mount(2) MNT_GETARGS.
Can this be intentional ? Why ?
None of these is essential for the desired mount feature.
But they need to be decided for getting a neat patch.
>Audit-Trail:
From: Martin Husemann <martin@duskware.de>
To: gnats-bugs@NetBSD.org
Cc: kern-bug-people@netbsd.org, gnats-admin@netbsd.org,
netbsd-bugs@netbsd.org
Subject: Re: kern/48808: Enhance mount_cd9660 by option -s like in other BSDs
Date: Wed, 14 May 2014 10:45:52 +0200
On Wed, May 14, 2014 at 08:35:00AM +0000, scdbackup@gmx.net wrote:
> If -s is enabled and gets used with a non-zero value, then
> mount_cd9660 will check after successful mounting, whether the kernel
> seems to have expected the old struct iso_args and thus must have
> ignored ISOFSMNT_SSECTOR and iso_args.ssector.
> It will then unmount(2) the freshly but wrongly mounted ISO.
Forward binary compat like this is not needed - a new mount_cd9660 binary
can expect a new kernel always.
Martin
From: "Thomas Schmitt" <scdbackup@gmx.net>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: kern/48808
Date: Wed, 14 May 2014 10:58:22 +0200
--- sys/fs/cd9660/Makefile.orig 2002-12-23 17:52:08.000000000 +0000
+++ sys/fs/cd9660/Makefile 2014-05-13 21:41:50.000000000 +0000
@@ -2,7 +2,6 @@
INCSDIR= /usr/include/isofs/cd9660
-INCS= cd9660_extern.h cd9660_mount.h cd9660_node.h cd9660_rrip.h iso.h \
- iso_rrip.h
+INCS= cd9660_mount.h
.include <bsd.kinc.mk>
--- sys/fs/cd9660/cd9660_extern.h.orig 2013-06-23 07:28:36.000000000 +0000
+++ sys/fs/cd9660/cd9660_extern.h 2014-05-13 21:18:11.000000000 +0000
@@ -72,15 +72,17 @@ struct iso_mnt {
int im_bshift;
int im_bmask;
- int volume_space_size;
+ uint32_t volume_space_size;
char root[ISODCL (157, 190)];
- int root_extent;
- int root_size;
+ uint32_t root_extent;
+ uint32_t root_size;
enum ISO_FTYPE iso_ftype;
int rr_skip;
int rr_skip0;
+
+ uint32_t im_ssector;
};
#define VFSTOISOFS(mp) ((struct iso_mnt *)((mp)->mnt_data))
--- sys/fs/cd9660/cd9660_mount.h.orig 2005-12-03 17:34:43.000000000 +0000
+++ sys/fs/cd9660/cd9660_mount.h 2014-05-13 20:38:41.000000000 +0000
@@ -38,6 +38,8 @@
#ifndef _ISOFS_CD9660_CD9660_MOUNT_H_
#define _ISOFS_CD9660_CD9660_MOUNT_H_
+#include <sys/types.h>
+
/*
* Arguments to mount ISO 9660 filesystems.
*/
@@ -45,6 +47,18 @@ struct iso_args {
const char *fspec; /* block special device to mount */
struct export_args30 _pad1; /* compat with old userland tools */
int flags; /* mounting flags, see below */
+ uint32_t ssector; /* start sector of session (relative to
+ * the partition offset of fspec),
+ * if flags & ISOFSMNT_SSECTOR
+ */
+ /* XXX
+ * Up to now the effect of ssector could be tested only with devices
+ * which have partition offset 0. Like /dev/cd0d (or cd0a on CD-ROM).
+ * It is supposed to get added to the partition offset of fspec.
+ * XXX ???
+ * Would completely overriding the partition offset work at all ?
+ * Are there cases with no device file with offset 0 ?
+ */
};
#define ISOFSMNT_NORRIP 0x00000001 /* disable Rock Ridge Ext.*/
#define ISOFSMNT_GENS 0x00000002 /* enable generation numbers */
@@ -52,8 +66,32 @@ struct iso_args {
#define ISOFSMNT_NOJOLIET 0x00000008 /* disable Joliet extensions */
#define ISOFSMNT_NOCASETRANS 0x00000010 /* do not make names lower case */
#define ISOFSMNT_RRCASEINS 0x00000020 /* case insensitive Rock Ridge */
+#define ISOFSMNT_SSECTOR 0x00000040 /* add ssector to the partition
+ * offset of fspec
+ */
#define ISOFSMNT_BITS "\177\20" \
"b\00norrip\0b\01gens\0b\02extatt\0b\03nojoliet\0" \
- "b\04nocasetrans\0b\05rrcaseins\0"
+ "b\04nocasetrans\0b\05rrcaseins\0b\06ssector\0"
+
+
+/* Compatibility precaution:
+ *
+ * struct old_iso_args_v_1_6 is the definition of struct iso_args before
+ * may 2014. Such structs are still accepted by mount(2) and will be defaulted
+ * to (flags & ~ISOFSMNT_SSECTOR).
+ *
+ * The old struct is exposed here to serve as size benchmark for the reply
+ * of mount(2) with ISOFSMNT_SSECTOR. If after successful mount(2), the inquiry
+ * by MNT_GETARGS yields sizeof(struct old_iso_args_v_1_6) then the
+ * kernel was built with the old struct iso_args. In this case it silently
+ * ignored ISOFSMNT_SSECTOR and iso_args.ssector.
+ * This test can be done only after mounting, because else -1 gets returned.
+ */
+struct old_iso_args_v_1_6 {
+ const char *fspec;
+ struct export_args30 _pad1;
+ int flags;
+};
+
#endif /* _ISOFS_CD9660_CD9660_MOUNT_H_ */
--- sys/fs/cd9660/cd9660_vfsops.c.patch_006 2014-05-11 10:02:49.000000000 +0000
+++ sys/fs/cd9660/cd9660_vfsops.c 2014-05-13 20:39:31.000000000 +0000
@@ -216,20 +216,47 @@ cd9660_mount(struct mount *mp, const cha
int error;
struct iso_mnt *imp = VFSTOISOFS(mp);
+ /* XXX do i have to malloc this memory and free it on exit ? */
+ struct iso_args defaulted_iso_args;
+
if (args == NULL)
return EINVAL;
- if (*data_len < sizeof *args)
- return EINVAL;
+ if (*data_len < sizeof *args) {
+ if (*data_len < sizeof (struct old_iso_args_v_1_6))
+ return EINVAL; /* Too small even for old iso_args */
+ if (!(mp->mnt_flag & MNT_GETARGS)) {
+ /* Upgrade old struct by defaults */
+ args = &defaulted_iso_args;
+ memset(args, 0, sizeof *args);
+ memcpy(args, data, sizeof (struct old_iso_args_v_1_6));
+ args->flags &= ~ISOFSMNT_SSECTOR;
+ printf("cd9660_mount: Upgraded old struct iso_args\n");
+ }
+ }
if (mp->mnt_flag & MNT_GETARGS) {
if (imp == NULL)
return EIO;
args->fspec = NULL;
args->flags = imp->im_flags;
- *data_len = sizeof (*args);
+ if (*data_len >= sizeof *args) {
+ args->ssector = imp->im_ssector;
+ *data_len = sizeof (*args);
+ } else {
+ *data_len = sizeof (struct old_iso_args_v_1_6);
+ }
return 0;
}
+ /* XXX Check for any unknown flags and eventually throw EINVAL ?
+ * This would allow future extensions to fail on old kernels
+ * rather than to be silently ignored, which causes the need
+ * to verify their effectiveness.
+ * See cd9660_mount.h: struct old_iso_args_v_1_6
+ * (One cannot use *data_len as indicator for undue demands.
+ * A newer iso_args may well express old fulfillable wishes.)
+ */
+
if ((mp->mnt_flag & MNT_RDONLY) == 0)
return (EROFS);
@@ -277,6 +304,11 @@ cd9660_mount(struct mount *mp, const cha
VOP_UNLOCK(devvp);
/* reference to devvp is donated through iso_mountfs */
} else {
+ if ((imp->im_flags & ISOFSMNT_SSECTOR ? imp->im_ssector : 0) !=
+ (args->flags & ISOFSMNT_SSECTOR ? args->ssector : 0)) {
+ error = EINVAL; /* wish to change superblock */
+ goto fail;
+ }
if (devvp != imp->im_devvp &&
devvp->v_rdev != imp->im_devvp->v_rdev) {
error = EINVAL; /* needs translation */
@@ -345,11 +377,11 @@ iso_mountfs(struct vnode *devvp, struct
int error = EINVAL;
int ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
int iso_bsize;
- int iso_blknum;
+ uint32_t iso_blknum;
int joliet_level;
struct iso_volume_descriptor *vdp;
struct iso_supplementary_descriptor *sup;
- int sess = 0;
+ uint32_t sess = 0;
int ext_attr_length;
struct disklabel label;
@@ -376,12 +408,15 @@ iso_mountfs(struct vnode *devvp, struct
if (error)
sess = 0; /* never mind */
}
+ if (argp->flags & ISOFSMNT_SSECTOR)
+ sess += argp->ssector;
#ifdef ISO_DEBUG
printf("isofs: session offset (part %"PRId32") %d\n", DISKPART(dev), sess);
#endif
for (iso_blknum = 16; iso_blknum < 100; iso_blknum++) {
- if ((error = bread(devvp, (iso_blknum+sess) * btodb(iso_bsize),
+ if ((error = bread(devvp, ((daddr_t) iso_blknum + sess)
+ * btodb(iso_bsize),
iso_bsize, NOCRED, 0, &bp)) != 0)
goto out;
@@ -434,6 +469,8 @@ iso_mountfs(struct vnode *devvp, struct
goto out;
}
+ if (argp->flags & ISOFSMNT_SSECTOR)
+ isomp->im_ssector = argp->ssector;
isomp->volume_space_size += sess;
brelse(pribp, BC_AGE);
@@ -478,8 +515,14 @@ iso_mountfs(struct vnode *devvp, struct
brelse(bp, BC_AGE);
bp = NULL;
}
+
+ /* XXX Why is ISOFSMNT_NOCASETRANS missing here ?
+ * Is it because man mount_cd9660 prefers "nomaplcase" whereas
+ * the macro ISOFSMNT_BITS in cd9660_mount.h says "nocasetrans" ?
+ */
isomp->im_flags = argp->flags & (ISOFSMNT_NORRIP | ISOFSMNT_GENS |
- ISOFSMNT_EXTATT | ISOFSMNT_NOJOLIET | ISOFSMNT_RRCASEINS);
+ ISOFSMNT_EXTATT | ISOFSMNT_NOJOLIET | ISOFSMNT_RRCASEINS |
+ ISOFSMNT_SSECTOR);
if (isomp->im_flags & ISOFSMNT_GENS)
isomp->iso_ftype = ISO_FTYPE_9660;
From: "Thomas Schmitt" <scdbackup@gmx.net>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: kern/48808
Date: Wed, 14 May 2014 11:04:44 +0200
--- sbin/mount_cd9660/mount_cd9660.c.orig 2011-08-29 14:35:00.000000000 +0000
+++ sbin/mount_cd9660/mount_cd9660.c 2014-05-13 19:09:42.000000000 +0000
@@ -59,6 +59,7 @@ __RCSID("$NetBSD: mount_cd9660.c,v 1.32
#include <string.h>
#include <unistd.h>
#include <util.h>
+#include <errno.h>
#include <isofs/cd9660/cd9660_mount.h>
@@ -79,6 +80,7 @@ static const struct mntopt mopts[] = {
{ "rrip", 1, ISOFSMNT_NORRIP, 1 },
{ "joliet", 1, ISOFSMNT_NOJOLIET, 1 },
{ "rrcaseins", 0, ISOFSMNT_RRCASEINS, 1 },
+ { "ssector", 0, 0, 1 }, /* not setable, only for info via getargs */
MOPT_NULL,
};
@@ -102,11 +104,15 @@ mount_cd9660_parseargs(int argc, char **
int ch, opts;
mntoptparse_t mp;
char *dev, *dir;
+#ifdef ISOFSMNT_SSECTOR
+ char *ep;
+ long long int llnum;
+#endif
memset(args, 0, sizeof(*args));
*mntflags = opts = 0;
optind = optreset = 1;
- while ((ch = getopt(argc, argv, "egijo:r")) != -1)
+ while ((ch = getopt(argc, argv, "egijo:rs:")) != -1)
switch (ch) {
case 'e':
/* obsolete, retained for compatibility only, use
@@ -134,6 +140,23 @@ mount_cd9660_parseargs(int argc, char **
* -o norrip */
opts |= ISOFSMNT_NORRIP;
break;
+ case 's':
+#ifdef ISOFSMNT_SSECTOR
+ /* learned from mount/fattr.c : a_num() */
+ llnum = strtoll(optarg, &ep, 0);
+ if (*ep || optarg == ep || llnum < 0 ||
+ llnum > (long long int) 0xffffff00) {
+ (void)fprintf(stderr,
+ "%s : unusable parameter with option -s\n",
+ getprogname());
+ usage();
+ }
+ args->ssector = llnum;
+ opts |= ISOFSMNT_SSECTOR;
+ break;
+#else
+ usage();
+#endif
case '?':
default:
usage();
@@ -161,6 +184,38 @@ mount_cd9660_parseargs(int argc, char **
args->flags = opts;
}
+#ifdef ISOFSMNT_SSECTOR
+
+/* Inquire after mount whether the running kernel knows iso_args.ssector.
+ * This cannot be done before mount(2), because then MNT_GETARGS will yield
+ * no result. Afterwards, the size of the MNT_GETARGS reply can tell.
+ */
+static int
+kernel_has_args_ssector(char *canon_dir)
+{
+ struct iso_args args;
+ int mntflags = MNT_GETARGS, kernel_args_size;
+
+ kernel_args_size = mount(MOUNT_CD9660, canon_dir, mntflags,
+ &args, sizeof args);
+ if (kernel_args_size == -1) {
+ (void)fprintf(stderr,
+ "%s : Error when inquiring success of option -s : %s\n",
+ getprogname(),
+ errno != 0 ? strerror(errno) : "unrecognizable error");
+ return 0;
+ }
+ if (kernel_args_size < (int) (sizeof (struct old_iso_args_v_1_6) +
+ sizeof (unsigned long int))) {
+ (void)fprintf(stderr, "%s : Kernel ignored option -s\n",
+ getprogname());
+ return 0;
+ }
+ return (1);
+}
+
+#endif /* ISOFSMNT_SSECTOR */
+
int
mount_cd9660(int argc, char **argv)
{
@@ -177,6 +232,20 @@ mount_cd9660(int argc, char **argv)
char buf[2048];
(void)snprintb(buf, sizeof(buf), ISOFSMNT_BITS, args.flags);
printf("%s\n", buf);
+
+#ifdef ISOFSMNT_SSECTOR
+
+ if (args.flags & ISOFSMNT_SSECTOR)
+ printf("-s %lu\n", args.ssector);
+ } else if ((args.flags & ISOFSMNT_SSECTOR) && args.ssector > 0) {
+ if (!kernel_has_args_ssector(canon_dir)) {
+ if (unmount(canon_dir, 0) == 0)
+ (void)fprintf(stderr,
+ "%s : Had to revoke mount attempt with option -s\n",
+ getprogname());
+ exit(1);
+ }
+#endif
}
exit(0);
@@ -185,7 +254,13 @@ mount_cd9660(int argc, char **argv)
static void
usage(void)
{
+#ifdef ISOFSMNT_SSECTOR
+ (void)fprintf(stderr,
+ "usage: %s [-o options | -s block_offset] special node\n",
+ getprogname());
+#else
(void)fprintf(stderr,
"usage: %s [-o options] special node\n", getprogname());
+#endif
exit(1);
}
--- sbin/mount_cd9660/mount_cd9660.8.orig 2009-01-03 22:56:23.000000000 +0000
+++ sbin/mount_cd9660/mount_cd9660.8 2014-05-13 18:34:13.000000000 +0000
@@ -57,7 +57,7 @@
.\"
.\" @(#)mount_cd9660.8 8.3 (Berkeley) 3/27/94
.\"
-.Dd January 3, 2009
+.Dd May, 12, 2014
.Dt MOUNT_CD9660 8
.Os
.Sh NAME
@@ -66,6 +66,7 @@
.Sh SYNOPSIS
.Nm
.Op Fl o Ar options
+.Op Fl s Ar block_offset
.Ar special node
.Sh DESCRIPTION
The
@@ -130,8 +131,35 @@ For compatibility with Solaris only.
.It Cm rrcaseins
Makes all lookups case-insensitive even for CD-ROMs with Rock-Ridge
extensions (for Rock-Ridge, default is case-sensitive lookup).
+.It Cm ssector
+Is ignored as input option but reported by
+.Cm getargs
+if option
+.Cm Fl s
+is in effect.
.El
.El
+.Bl -tag -width indent
+.It Fl s Ar block_offset
+Read the superblock from a block address, which is computed by adding
+.Ar block_offset
+to the partition offset implied by the choice of the device file.
+With /dev/cdXd this partition offset is 0,
+which leads to the first and oldest ISO-9660 session on the medium.
+/dev/cdXa has the offset of the last and youngest recognized medium
+partition.
+Other sessions may be reached from /dev/cdXd by
+.Fl s
+with a
+.Ar block_offset
+which can be obtained from burn software for optical media.
+The block size is 2048 bytes.
+.Pp
+/dev/cdX partitions are recognized from logical tracks of unformatted
+optical media.
+Formatted media appear as a single partition. Nevertheless they may bear
+several ISO-9660 sessions. Refer to their ISO-9660 producer for offset info.
+.El
.Pp
For compatibility with previous releases, following obsolete flags are
still recognized:
From: "Thomas Schmitt" <scdbackup@gmx.net>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: kern/48808
Date: Wed, 14 May 2014 11:15:36 +0200
--- distrib/sets/lists/comp/mi.orig 2014-04-25 00:24:39.000000000 +0000
+++ distrib/sets/lists/comp/mi 2014-05-14 07:12:18.000000000 +0000
@@ -2356,12 +2356,12 @@
./usr/include/isns.h comp-c-include
./usr/include/isns_defs.h comp-c-include
./usr/include/iso646.h comp-c-include
-./usr/include/isofs/cd9660/cd9660_extern.h comp-c-include
+./usr/include/isofs/cd9660/cd9660_extern.h comp-obsolete obsolete
./usr/include/isofs/cd9660/cd9660_mount.h comp-c-include
-./usr/include/isofs/cd9660/cd9660_node.h comp-c-include
-./usr/include/isofs/cd9660/cd9660_rrip.h comp-c-include
-./usr/include/isofs/cd9660/iso.h comp-c-include
-./usr/include/isofs/cd9660/iso_rrip.h comp-c-include
+./usr/include/isofs/cd9660/cd9660_node.h comp-obsolete obsolete
+./usr/include/isofs/cd9660/cd9660_rrip.h comp-obsolete obsolete
+./usr/include/isofs/cd9660/iso.h comp-obsolete obsolete
+./usr/include/isofs/cd9660/iso_rrip.h comp-obsolete obsolete
./usr/include/kadm5/admin.h comp-krb5-include kerberos
./usr/include/kadm5/kadm5-private.h comp-krb5-include kerberos
./usr/include/kadm5/kadm5-protos.h comp-krb5-include kerberos
From: "Thomas Schmitt" <scdbackup@gmx.net>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: kern/48808
Date: Wed, 14 May 2014 11:26:40 +0200
Martin Husemann:
> Forward binary compat like this is not needed - a new mount_cd9660 binary
> can expect a new kernel always.
mount_cd9660(8) is not the exclusive caller of mount(2) with
struct iso_args. So i felt obliged to provide a detection method
in mount_cd9660.h (struct old_iso_args_v_1_6).
I'm a userlander and not far from calling mount(2) in own software.
It would be decisive for me to know whether my args.ssector was
taken into respect.
Next i (in my new role as kernel hacker) had to test whether this
distinction works. This was most easy to do in mount_cd9660(8).
We can tear down all ifdef ISOFSMNT_SSECTOR in mount_cd9660(8)
if they are deemed too ugly.
But they are of educational use for anybody who wants to learn
about this revolution after 20 years of stability.
Errata:
* The old struct is exposed here to serve as size benchmark for the reply
- * of mount(2) with ISOFSMNT_SSECTOR. If after successful mount(2), the inquiry
+ * of mount(2) with MNT_GETARGS. If after successful mount(2), the inquiry
* by MNT_GETARGS yields sizeof(struct old_iso_args_v_1_6) then the
From: "Thomas Schmitt" <scdbackup@gmx.net>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: kern/48808
Date: Wed, 14 May 2014 18:17:03 +0200
I can now answer the question about partitioned devices, which
are not cd but rather wd (XXX in cd9660_mount.h):
Mounting of /dev/wdX? is indeed handled by cd9660_vfsops.c
differently than with /dev/cdX?.
A hard disk partition is used with its own block addressing
which starts by 0.
A cd "partition" is used with the block addressing of the
base device /dev/cdXd and a superblock offset given by the
cd "partition" start.
I will have to clarify the man page.
Not easy to explain ... would this text be understandable ?
------------------------------------------------------------------
-s block_offset
Read the superblock from a block address, which is computed by
adding block_offset to the default superblock offset implied by
the choice of the device file. The block size is 2048 bytes.
Optical drives /dev/cd* with unformatted media are handled
differently than other storage partitions. /dev/cd?d points to
the start of the first and oldest logical track on the loaded
medium. /dev/cd?a points to the last and youngest logical track.
Nevertheless all block addressing is done relative to /dev/cd?d.
Only the default offset is taken from /dev/cd?a, if that one is
used. This matches the needs of ISO-9660 multisession on
unformatted optical media.
Formatted optical media and other kinds of storage partitions
show no such default superblock offsets. Nevertheless they may
bear several ISO-9660 sessions. Usually the superblock at offset
0 leads to the youngest session.
Other ISO-9660 sessions can be mounted by help of option -s with
a block_offset which can be obtained from burn software for
optical media. Among the /dev/cd* devices, use /dev/cd?d for this
purpose.
------------------------------------------------------------------
I have to stress that this situation is not created by my new option.
It just adds a user-defined offset to the mess described above.
------------------------------------------------------------------
My experiment:
------------------------------------------------------------------
(Thanks to https://www.netbsd.org/docs/guide/en/chap-rmmedia.html)
disklabel wd1 reports about my virtual MBR-formatted USB stick:
# size offset fstype [fsize bsize cpg/sgs]
d: 10485760 0 unused 0 0 # ...
e: 1606437 63 Linux Ext2 0 0 # ...
f: 8867880 1606500 Linux Ext2 0 0 # ...
Permissions are set quite liberally
brw-r--r-- 1 root operator 0, 11 Feb 7 18:01 /dev/wd1d
brw-rw-rw- 1 root operator 0, 12 Feb 4 17:37 /dev/wd1e
brw-rw-rw- 1 root operator 0, 13 Feb 4 17:37 /dev/wd1f
I write an ISO image into partition 1
xorriso -outdev stdio:/dev/wd1e \
-blank as_needed \
-map libisofs-1.3.6 /libisofs-1.3.6
xorriso can load the result and report about its files.
Inspection with a hex dumper shows that the ISO 9660 Primary
Volume Descriptor indeed is stored 63 * 512 + 16 * 2048 bytes
after start of /dev/wd1d. All as expected for a partition
with start at 512-block 63.
So if partition /dev/wd1e can be mounted, then not with block
addresses relative to /dev/wd1d (as would be done with with
/dev/cd0a and /dev/cd0d). The offset of 63 * 512 would disalign
all block addresses of the ISO which counts 2048-blocks.
Well, mounting works fine:
mount_cd9660 /dev/wd1e /mnt/iso
ls -l /mnt/iso
find /mnt/iso | less
From: "Thomas Schmitt" <scdbackup@gmx.net>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: kern/48808
Date: Wed, 14 May 2014 19:51:21 +0200
It seems clearer to document and more similar to the behavior
of other operating systems, if -s overrides the offset of /dev/cd0a
rather than adding to it.
cd9660_vfsops.c:
if (argp->flags & ISOFSMNT_SSECTOR)
- sess += argp->ssector;
+ sess = argp->ssector;
#ifdef ISO_DEBUG
From: "Thomas Schmitt" <scdbackup@gmx.net>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: kern/48808
Date: Thu, 15 May 2014 09:37:24 +0200
I overhauled the man page description of the new option.
The main problem is that several device models meet at this
topic.
There is NetBSD CD partitioning, which might surprise even
experienced users, when they encounter it for the first time.
http://www.netbsd.org/docs/guide/en/chap-rmmedia.html#multisession
It reflects the device model of SCSI/MMC which distinguishes
two large families of media capabilities:
Sequential, which get shown partitioned by NetBSD.
Overwritable, which get shown like a hard disk with a single partition.
Both under the device name cd.
These are not really media families, because DVD-RW and BD-R media
can play on both fields.
I may not even distinguish the families by "formatted" and
"unformatted", because one of the three BD-R personalities is
formatted and sequential at the same time.
This has to be explained to a person who might assume the normal
VFS device model of partitions and filesystems.
Well, did i succeed with the following text ?
--------------------------------------------------------------------
-s block_offset
Read the superblock from block address block_offset rather than
from the default position implied by the choice of the device
file. The block size is 2048 bytes.
Optical drives /dev/cd* with multi-session media are handled
differently than other storage partitions. /dev/cd?d points to
the start of the first and oldest logical track on the loaded
medium. /dev/cd?a points to the last and youngest logical track.
Nevertheless all block addressing is done relative to /dev/cd?d.
Only the default offset is taken from /dev/cd?a, if that one is
used. This matches the needs of ISO-9660 multisession on such
optical media.
Optical media, which are formatted to support random read-write
access, as well as other kinds of storage partitions show no such
default superblock offsets. Nevertheless they may bear several
ISO-9660 sessions. The default superblock is at offset 0 and
usually leads to the youngest session.
Other ISO-9660 sessions can be mounted by help of option -s with
a block_offset which can be obtained from burn software for
optical media.
----------------------------------------------------------------------
From: "Thomas Schmitt" <scdbackup@gmx.net>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: kern/48808
Date: Thu, 15 May 2014 12:19:20 +0200
Or maybe i should just point to mscdlabel(8), and give a modest
hint why it is not able to do what mount_cd9660 -s can do:
--------------------------------------------------------------------
-s block_offset
Read the superblock from block address block_offset rather than
from the default position implied by the choice of the device
file. The block size is 2048 bytes.
Command mscdlabel(8) may have connected some /dev/cd* files to
logical tracks of an optical multi-session medium, giving the
device files the matching superblock positions for the recognized
ISO-9660 filesystems. Such a default offset will be overridden
by option -s so that all /dev/cd* will behave like /dev/cd*d.
mscdlabel(8) has limitations with finding all ISO-9660 sessions
which are accessible via a storage device. The burn software
suite which produced the ISO-9660 filesystem should be able to
tell all suitable block_offset values.
--------------------------------------------------------------------
Actually the limitations of mscdlabel(8) applies even to CD media:
How to represent the about 40 sessions which i could squeeze on a
CD-R ? (Despite the wasted MBs between CD sessions.)
How to represent a DVD+R with up to 150 sessions or a multi-session
BD-R with up to 300 sessions ?
Nevertheless, mscdlabel(8) could become a tool which tells block_offset
values for mount_cd9660 -s. I will have a look at it ... later.
From: "Thomas Schmitt" <scdbackup@gmx.net>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: kern/48808
Date: Fri, 16 May 2014 08:31:24 +0200
I finished my tests of the new mount_c9660 without finding
problems, which were not present before.
The test with mount(2) option MNT_UPDATE works insofar that the
kernel refuses on the request to change the superblock offset
(as i told it to do).
But the usefulness of MNT_UPDATE resp -o update with the current
implementation is questionable, because it seems to do nothing.
A change from default rrip,joliet,maplcase by
mount_cd9660 -o norrip,nojoliet,nomaplcase /dev/cd0a /mnt/iso
would make sense.
Among other things it would change
-rw-r--r-- 1 thomas dbus 4294965248 Jun 23 2012 powerpc.img
-rw-r--r-- 1 thomas dbus 4294965248 Jun 23 2012 powerpc.img
to
-r-xr-xr-x 1 root wheel 2048 Jun 23 2012 POWERPC.IMG
which is at least educational. (.. and would allow to concatenate
the true 4 GiB file from both faulty representations. :))
The implementation seems tricky, because parts of iso_mountfs()
would have to be performed to verify the validity of the new
options. Also i am uncertain about the impact on existing iso_node
objects if mount flags get changed.
UDF simply throws EOPNOTSUPP on MNT_UPDATE. But it also does it
on udf_mountroot() which serves as struct vfsops.vfs_mountroot().
From: Julian Coleman <jdc@coris.org.uk>
To: gnats-bugs@NetBSD.org, scdbackup@gmx.net
Cc:
Subject: Re: kern/48808: Enhance mount_cd9660 by option -s like in other BSDs
Date: Fri, 16 May 2014 10:36:17 +0100
Hi,
> -s block_offset
> of the device file. With /dev/cdXd this partition offset is 0,
A couple of notes:
cdXd is only the raw partition on some ports, it will be cdXc on others
(e.g. see the BUGS section of disklabel(8)), so that should be noted
somewhere - I don't think that we have a good way of doing that though.
how likely are we to crash if the block_offset isn't a superblock?
Thanks,
J
--
NetBSD: simple; works; documented / Sailing at Newbiggin
http://www.netbsd.org/ / http://www.newbigginsailingclub.org/
From: "Thomas Schmitt" <scdbackup@gmx.net>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: kern/48808
Date: Fri, 16 May 2014 12:52:56 +0200
Hi,
> cdXd is only the raw partition on some ports, it will be cdXc on others
> (e.g. see the BUGS section of disklabel(8)), so that should be noted
> somewhere - I don't think that we have a good way of doing that though.
It's indeed mentionen in man 8 mscdlabel:
"The raw partition (typically partition c, but d on i386 and some other
platforms) is left alone during this process."
I change the man page proposal of mount_cd9660:
Such a default offset will be overridden by option
.Fl s
- so that all /dev/cd* will behave like /dev/cd*d.
+ so that all /dev/cd* will behave like the raw partition device /dev/cd*d
+ resp. /dev/cd*c.
.Pp
.Xr mscdlabel 8
> how likely are we to crash if the block_offset isn't a superblock?
To my estimation not more than with a user applying
mount -t 9660
to a not suitable device rep. medium.
I tried unsuitable offsets already (sorry for not reporting):
netbsd# mount_cd9660 -s 12345 /dev/cd0a /mnt/iso
mount_cd9660: /dev/cd0a on /mnt/iso: Invalid argument
With unsuitable medium content i get the same
netbsd# mount_cd9660 /dev/wd1f /mnt/iso
mount_cd9660: /dev/wd1f on /mnt/iso: Invalid argument
Existing precautions in cd9660:
In sys/fs/cd9660/cd9660_vfsops.c the loop
for (iso_blknum = 16; iso_blknum < 100; iso_blknum++) {
is searching for ISO 9660 Volume Descriptors.
If it does not find one, then it throws the error
if (pribp == NULL) {
error = EINVAL;
goto out;
}
The loop ends on the first block that does not look like
a ISO 9660 volume descriptor.
if (memcmp(vdp->id, ISO_STANDARD_ID, sizeof(vdp->id)) != 0) {
It could be made a notch sharper by demanding a Primary Volume
Descriptor (case ISO_VD_PRIMARY:) in the first block that is
examined by the loop.
(The macros are defined in iso.h and match my knowledge about
ISO 9660.)
From: Julian Coleman <jdc@coris.org.uk>
To: gnats-bugs@NetBSD.org, Thomas Schmitt <scdbackup@gmx.net>
Cc:
Subject: Re: kern/48808
Date: Fri, 16 May 2014 12:38:46 +0100
Hi,
> I change the man page proposal of mount_cd9660:
That looks good to me.
> To my estimation not more than with a user applying
> mount -t 9660
> to a not suitable device rep. medium.
Thanks for the details. This sounds fine (and we also have rump_cd9660
available for really untrusted media).
Thanks,
J
--
NetBSD: simple; works; documented / Sailing at Newbiggin
http://www.netbsd.org/ / http://www.newbigginsailingclub.org/
From: matthew green <mrg@eterna.com.au>
To: gnats-bugs@NetBSD.org
Cc: kern-bug-people@netbsd.org, gnats-admin@netbsd.org,
netbsd-bugs@netbsd.org, scdbackup@gmx.net
Subject: re: kern/48808
Date: Sat, 17 May 2014 04:22:16 +1000
some minor mdoc issues below. thanks.
> It's indeed mentionen in man 8 mscdlabel:
> "The raw partition (typically partition c, but d on i386 and some other
> platforms) is left alone during this process."
>
> I change the man page proposal of mount_cd9660:
>
> Such a default offset will be overridden by option
> .Fl s
> - so that all /dev/cd* will behave like /dev/cd*d.
> + so that all /dev/cd* will behave like the raw partition device /dev/cd*d
> + resp. /dev/cd*c.
> .Pp
> .Xr mscdlabel 8
all pathnames should be written with ".Pa" macro. also, i'd
reference sysctl kern.rawpartition -- 'a' + that is the name
you'll see in /dev. ie, value '2' and '3' are common. eg:
so that all
.Pa /dev/cd*
will behave like the raw partition device.
See
.Xr sysctl 7
kern.rawpartition value to determine the raw partition, usually
.Pa /dev/cd0c
or
.Pa /dev/cd0d .
.mrg.
From: "Thomas Schmitt" <scdbackup@gmx.net>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: kern/48808
Date: Fri, 16 May 2014 21:01:25 +0200
Actually it does not matter which device is the raw partition.
All cd partition devices will behave the same as soon as -s is
present.
A hint about sysctl kern.rawpartition would rather be appropriate
for the man page of mscdlabel(8).
So how about just not talking about "c", "d", "cd0", or "cd1" ?
-----------------------------------------------------------------
Such a default offset will be overridden by option
.Fl s
- so that all /dev/cd* will behave like the raw partition device /dev/cd*d
- resp. /dev/cd*c.
+ so that all
+ .Pa /dev/cd*
+ will behave like raw partition devices.
.Pp
.Xr mscdlabel 8
-----------------------------------------------------------------
The explanation of "raw partition device" can be found by following
the now many references to mscdlabel(8).
In context this would state
----------------------------------------------------------------
Command mscdlabel(8) may have connected some /dev/cd* files to
logical tracks of an optical multi-session medium, giving the
device files the matching superblock positions for the recognized
ISO-9660 filesystems. Such a default offset will be overridden
by option -s so that all /dev/cd* will behave like raw partition
devices.
----------------------------------------------------------------
From: "Thomas Schmitt" <scdbackup@gmx.net>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: kern/48808
Date: Sun, 18 May 2014 16:25:43 +0200
I answered to myself the rest of the XXX questions.
- Nobody objected adding 120 bytes on the stack. So it stays
this way. No clean-up code against memory leaks is needed.
- I will submit the proposal to reject unknown ISOFSMNT_* flags
as a separate PR. The comment is still in my proposed change.
- I leave the remarks about the non-operation of MNT_UPDATE
for somebody who has more clue about how this is supposed to
work. Currently and after my change, it silently does nothing.
- I added ISOFSMNT_NOCASETRANS to the memorized mount flags in
struct iso_mnt.im_flags.
Further i adapted ISOFSMNT_BITS to the "new formatting style" example
in man 9 snprintb. (It does not solve the ugly output "0x0>"
of -o getargs on a default mount.)
------------------------------------------------------------------------
To Martin Husemann:
> Forward binary compat like this is not needed - a new mount_cd9660 binary
> can expect a new kernel always.
Shall i understand "is not needed" as "is not desirable" and remove
the after-mount test in mount_cd9660(8) ?
To other commenters:
If you are not satisfied with my reactions, then please tell.
------------------------------------------------------------------------
I will now send two refurbished change proposals for sys/fs/cd9660
and sbin/mount_9660. I deem them ready for committer review.
The patch proposal
Date: Wed, 14 May 2014 11:15:36 +0200
for
distrib/sets/lists/comp/mi
stays valid.
From: "Thomas Schmitt" <scdbackup@gmx.net>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: kern/48808
Date: Sun, 18 May 2014 16:31:30 +0200
--- sys/fs/cd9660/Makefile.orig 2002-12-23 17:52:08.000000000 +0000
+++ sys/fs/cd9660/Makefile 2014-05-13 21:41:50.000000000 +0000
@@ -2,7 +2,6 @@
INCSDIR= /usr/include/isofs/cd9660
-INCS= cd9660_extern.h cd9660_mount.h cd9660_node.h cd9660_rrip.h iso.h \
- iso_rrip.h
+INCS= cd9660_mount.h
.include <bsd.kinc.mk>
--- sys/fs/cd9660/cd9660_extern.h.orig 2013-06-23 07:28:36.000000000 +0000
+++ sys/fs/cd9660/cd9660_extern.h 2014-05-13 21:18:11.000000000 +0000
@@ -72,15 +72,17 @@ struct iso_mnt {
int im_bshift;
int im_bmask;
- int volume_space_size;
+ uint32_t volume_space_size;
char root[ISODCL (157, 190)];
- int root_extent;
- int root_size;
+ uint32_t root_extent;
+ uint32_t root_size;
enum ISO_FTYPE iso_ftype;
int rr_skip;
int rr_skip0;
+
+ uint32_t im_ssector;
};
#define VFSTOISOFS(mp) ((struct iso_mnt *)((mp)->mnt_data))
--- sys/fs/cd9660/cd9660_mount.h.orig 2005-12-03 17:34:43.000000000 +0000
+++ sys/fs/cd9660/cd9660_mount.h 2014-05-18 12:41:55.000000000 +0000
@@ -38,6 +38,8 @@
#ifndef _ISOFS_CD9660_CD9660_MOUNT_H_
#define _ISOFS_CD9660_CD9660_MOUNT_H_
+#include <sys/types.h>
+
/*
* Arguments to mount ISO 9660 filesystems.
*/
@@ -45,6 +47,9 @@ struct iso_args {
const char *fspec; /* block special device to mount */
struct export_args30 _pad1; /* compat with old userland tools */
int flags; /* mounting flags, see below */
+ uint32_t ssector; /* start sector of session,
+ * if flags & ISOFSMNT_SSECTOR
+ */
};
#define ISOFSMNT_NORRIP 0x00000001 /* disable Rock Ridge Ext.*/
#define ISOFSMNT_GENS 0x00000002 /* enable generation numbers */
@@ -52,8 +57,30 @@ struct iso_args {
#define ISOFSMNT_NOJOLIET 0x00000008 /* disable Joliet extensions */
#define ISOFSMNT_NOCASETRANS 0x00000010 /* do not make names lower case */
#define ISOFSMNT_RRCASEINS 0x00000020 /* case insensitive Rock Ridge */
+#define ISOFSMNT_SSECTOR 0x00000040 /* use ssector as session start */
-#define ISOFSMNT_BITS "\177\20" \
+#define ISOFSMNT_BITS "\177\020" \
"b\00norrip\0b\01gens\0b\02extatt\0b\03nojoliet\0" \
- "b\04nocasetrans\0b\05rrcaseins\0"
+ "b\04nocasetrans\0b\05rrcaseins\0b\06ssector\0\0"
+
+
+/* Compatibility precaution:
+ *
+ * struct old_iso_args_v_1_6 is the definition of struct iso_args before
+ * may 2014. Such structs are still accepted by mount(2) and will be defaulted
+ * to (flags & ~ISOFSMNT_SSECTOR).
+ *
+ * The old struct is exposed here to serve as size benchmark for the reply
+ * of mount(2) with MNT_GETARGS. If after successful mount(2), the inquiry
+ * by MNT_GETARGS yields sizeof(struct old_iso_args_v_1_6) then the
+ * kernel was built with the old struct iso_args. In this case it silently
+ * ignored ISOFSMNT_SSECTOR and iso_args.ssector.
+ * This test can be done only after mounting, because else -1 gets returned.
+ */
+struct old_iso_args_v_1_6 {
+ const char *fspec;
+ struct export_args30 _pad1;
+ int flags;
+};
+
#endif /* _ISOFS_CD9660_CD9660_MOUNT_H_ */
--- sys/fs/cd9660/cd9660_vfsops.c.patch_006 2014-05-11 10:02:49.000000000 +0000
+++ sys/fs/cd9660/cd9660_vfsops.c 2014-05-18 12:42:37.000000000 +0000
@@ -215,21 +215,45 @@ cd9660_mount(struct mount *mp, const cha
struct iso_args *args = data;
int error;
struct iso_mnt *imp = VFSTOISOFS(mp);
+ struct iso_args defaulted_iso_args;
if (args == NULL)
return EINVAL;
- if (*data_len < sizeof *args)
- return EINVAL;
-
+ if (*data_len < sizeof *args) {
+ if (*data_len < sizeof (struct old_iso_args_v_1_6))
+ return EINVAL; /* Too small even for old iso_args */
+ if (!(mp->mnt_flag & MNT_GETARGS)) {
+ /* Upgrade old struct by defaults */
+ args = &defaulted_iso_args;
+ memset(args, 0, sizeof *args);
+ memcpy(args, data, sizeof (struct old_iso_args_v_1_6));
+ args->flags &= ~ISOFSMNT_SSECTOR;
+ printf("cd9660_mount: Upgraded old struct iso_args\n");
+ }
+ }
if (mp->mnt_flag & MNT_GETARGS) {
if (imp == NULL)
return EIO;
args->fspec = NULL;
args->flags = imp->im_flags;
- *data_len = sizeof (*args);
+ if (*data_len >= sizeof *args) {
+ args->ssector = imp->im_ssector;
+ *data_len = sizeof (*args);
+ } else {
+ *data_len = sizeof (struct old_iso_args_v_1_6);
+ }
return 0;
}
+ /* XXX Check for any unknown flags and eventually throw EINVAL ?
+ * This would allow future extensions to fail on old kernels
+ * rather than to be silently ignored, which causes the need
+ * to verify their effectiveness.
+ * See cd9660_mount.h: struct old_iso_args_v_1_6
+ * (One cannot use *data_len as indicator for undue demands.
+ * A newer iso_args may well express old fulfillable wishes.)
+ */
+
if ((mp->mnt_flag & MNT_RDONLY) == 0)
return (EROFS);
@@ -244,7 +268,6 @@ cd9660_mount(struct mount *mp, const cha
NSM_FOLLOW_NOEMULROOT, &devvp);
if (error != 0)
return (error);
-
if (devvp->v_type != VBLK) {
vrele(devvp);
return ENOTBLK;
@@ -277,11 +300,22 @@ cd9660_mount(struct mount *mp, const cha
VOP_UNLOCK(devvp);
/* reference to devvp is donated through iso_mountfs */
} else {
+ if ((imp->im_flags & ISOFSMNT_SSECTOR ? imp->im_ssector : 0) !=
+ (args->flags & ISOFSMNT_SSECTOR ? args->ssector : 0)) {
+ error = EINVAL; /* wish to change superblock */
+ goto fail;
+ }
if (devvp != imp->im_devvp &&
devvp->v_rdev != imp->im_devvp->v_rdev) {
error = EINVAL; /* needs translation */
goto fail;
}
+
+ /* XXX Should not something be done here ?
+ norrip, nojoliet, nomaplcase, ... ?
+ */
+ /* XXX UDF throws EOPNOTSUPP instead of silently ignoring */
+
VOP_UNLOCK(devvp);
vrele(devvp);
}
@@ -345,11 +379,11 @@ iso_mountfs(struct vnode *devvp, struct
int error = EINVAL;
int ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
int iso_bsize;
- int iso_blknum;
+ uint32_t iso_blknum;
int joliet_level;
struct iso_volume_descriptor *vdp;
struct iso_supplementary_descriptor *sup;
- int sess = 0;
+ uint32_t sess = 0;
int ext_attr_length;
struct disklabel label;
@@ -376,12 +410,15 @@ iso_mountfs(struct vnode *devvp, struct
if (error)
sess = 0; /* never mind */
}
+ if (argp->flags & ISOFSMNT_SSECTOR)
+ sess = argp->ssector;
#ifdef ISO_DEBUG
printf("isofs: session offset (part %"PRId32") %d\n", DISKPART(dev), sess);
#endif
for (iso_blknum = 16; iso_blknum < 100; iso_blknum++) {
- if ((error = bread(devvp, (iso_blknum+sess) * btodb(iso_bsize),
+ if ((error = bread(devvp, ((daddr_t) iso_blknum + sess)
+ * btodb(iso_bsize),
iso_bsize, NOCRED, 0, &bp)) != 0)
goto out;
@@ -434,6 +471,8 @@ iso_mountfs(struct vnode *devvp, struct
goto out;
}
+ if (argp->flags & ISOFSMNT_SSECTOR)
+ isomp->im_ssector = argp->ssector;
isomp->volume_space_size += sess;
brelse(pribp, BC_AGE);
@@ -479,7 +518,8 @@ iso_mountfs(struct vnode *devvp, struct
bp = NULL;
}
isomp->im_flags = argp->flags & (ISOFSMNT_NORRIP | ISOFSMNT_GENS |
- ISOFSMNT_EXTATT | ISOFSMNT_NOJOLIET | ISOFSMNT_RRCASEINS);
+ ISOFSMNT_EXTATT | ISOFSMNT_NOJOLIET | ISOFSMNT_NOCASETRANS |
+ ISOFSMNT_RRCASEINS | ISOFSMNT_SSECTOR);
if (isomp->im_flags & ISOFSMNT_GENS)
isomp->iso_ftype = ISO_FTYPE_9660;
From: "Thomas Schmitt" <scdbackup@gmx.net>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: kern/48808
Date: Sun, 18 May 2014 16:39:13 +0200
--- sbin/mount_cd9660/mount_cd9660.c.orig 2011-08-29 14:35:00.000000000 +0000
+++ sbin/mount_cd9660/mount_cd9660.c 2014-05-18 13:59:46.000000000 +0000
@@ -59,6 +59,7 @@ __RCSID("$NetBSD: mount_cd9660.c,v 1.32
#include <string.h>
#include <unistd.h>
#include <util.h>
+#include <errno.h>
#include <isofs/cd9660/cd9660_mount.h>
@@ -79,6 +80,7 @@ static const struct mntopt mopts[] = {
{ "rrip", 1, ISOFSMNT_NORRIP, 1 },
{ "joliet", 1, ISOFSMNT_NOJOLIET, 1 },
{ "rrcaseins", 0, ISOFSMNT_RRCASEINS, 1 },
+ { "ssector", 0, 0, 1 }, /* not setable, only for info via getargs */
MOPT_NULL,
};
@@ -102,11 +104,15 @@ mount_cd9660_parseargs(int argc, char **
int ch, opts;
mntoptparse_t mp;
char *dev, *dir;
+#ifdef ISOFSMNT_SSECTOR
+ char *ep;
+ long long int llnum;
+#endif
memset(args, 0, sizeof(*args));
*mntflags = opts = 0;
optind = optreset = 1;
- while ((ch = getopt(argc, argv, "egijo:r")) != -1)
+ while ((ch = getopt(argc, argv, "egijo:rs:")) != -1)
switch (ch) {
case 'e':
/* obsolete, retained for compatibility only, use
@@ -134,6 +140,23 @@ mount_cd9660_parseargs(int argc, char **
* -o norrip */
opts |= ISOFSMNT_NORRIP;
break;
+ case 's':
+#ifdef ISOFSMNT_SSECTOR
+ /* learned from mount/fattr.c : a_num() */
+ llnum = strtoll(optarg, &ep, 0);
+ if (*ep || optarg == ep || llnum < 0 ||
+ llnum > (long long int) 0xffffff00) {
+ (void)fprintf(stderr,
+ "%s : unusable parameter with option -s\n",
+ getprogname());
+ usage();
+ }
+ args->ssector = llnum;
+ opts |= ISOFSMNT_SSECTOR;
+ break;
+#else
+ usage();
+#endif
case '?':
default:
usage();
@@ -161,6 +184,38 @@ mount_cd9660_parseargs(int argc, char **
args->flags = opts;
}
+#ifdef ISOFSMNT_SSECTOR
+
+/* Inquire after mount whether the running kernel knows iso_args.ssector.
+ * This cannot be done before mount(2), because then MNT_GETARGS will yield
+ * no result. Afterwards, the size of the MNT_GETARGS reply can tell.
+ */
+static int
+kernel_has_args_ssector(char *canon_dir)
+{
+ struct iso_args args;
+ int mntflags = MNT_GETARGS, kernel_args_size;
+
+ kernel_args_size = mount(MOUNT_CD9660, canon_dir, mntflags,
+ &args, sizeof args);
+ if (kernel_args_size == -1) {
+ (void)fprintf(stderr,
+ "%s : Error when inquiring success of option -s : %s\n",
+ getprogname(),
+ errno != 0 ? strerror(errno) : "unrecognizable error");
+ return 0;
+ }
+ if (kernel_args_size < (int) (sizeof (struct old_iso_args_v_1_6) +
+ sizeof (unsigned long int))) {
+ (void)fprintf(stderr, "%s : Kernel ignored option -s\n",
+ getprogname());
+ return 0;
+ }
+ return (1);
+}
+
+#endif /* ISOFSMNT_SSECTOR */
+
int
mount_cd9660(int argc, char **argv)
{
@@ -177,6 +232,20 @@ mount_cd9660(int argc, char **argv)
char buf[2048];
(void)snprintb(buf, sizeof(buf), ISOFSMNT_BITS, args.flags);
printf("%s\n", buf);
+
+#ifdef ISOFSMNT_SSECTOR
+
+ if (args.flags & ISOFSMNT_SSECTOR)
+ printf("-s %"PRIu32"\n", args.ssector);
+ } else if ((args.flags & ISOFSMNT_SSECTOR) && args.ssector > 0) {
+ if (!kernel_has_args_ssector(canon_dir)) {
+ if (unmount(canon_dir, 0) == 0)
+ (void)fprintf(stderr,
+ "%s : Had to revoke mount attempt with option -s\n",
+ getprogname());
+ exit(1);
+ }
+#endif
}
exit(0);
@@ -185,7 +254,13 @@ mount_cd9660(int argc, char **argv)
static void
usage(void)
{
+#ifdef ISOFSMNT_SSECTOR
+ (void)fprintf(stderr,
+ "usage: %s [-o options | -s block_offset] special node\n",
+ getprogname());
+#else
(void)fprintf(stderr,
"usage: %s [-o options] special node\n", getprogname());
+#endif
exit(1);
}
--- sbin/mount_cd9660/mount_cd9660.8.orig 2009-01-03 22:56:23.000000000 +0000
+++ sbin/mount_cd9660/mount_cd9660.8 2014-05-16 19:49:05.000000000 +0000
@@ -57,7 +57,7 @@
.\"
.\" @(#)mount_cd9660.8 8.3 (Berkeley) 3/27/94
.\"
-.Dd January 3, 2009
+.Dd May, 16, 2014
.Dt MOUNT_CD9660 8
.Os
.Sh NAME
@@ -66,6 +66,7 @@
.Sh SYNOPSIS
.Nm
.Op Fl o Ar options
+.Op Fl s Ar block_offset
.Ar special node
.Sh DESCRIPTION
The
@@ -130,8 +131,41 @@ For compatibility with Solaris only.
.It Cm rrcaseins
Makes all lookups case-insensitive even for CD-ROMs with Rock-Ridge
extensions (for Rock-Ridge, default is case-sensitive lookup).
+.It Cm ssector
+Is ignored as input option but reported by
+.Cm getargs
+if option
+.Cm Fl s
+is in effect.
.El
.El
+.Bl -tag -width indent
+.It Fl s Ar block_offset
+Read the superblock from block address
+.Ar block_offset
+rather than from the default position implied by the choice of the device file.
+The block size is 2048 bytes.
+.Pp
+Command
+.Xr mscdlabel 8
+may have connected some
+.Pa /dev/cd*
+files to logical tracks of an optical
+multi-session medium, giving the device files the matching superblock
+positions for the recognized ISO-9660 filesystems.
+Such a default offset will be overridden by option
+.Fl s
+so that all
+.Pa /dev/cd*
+will behave like raw partition devices.
+.Pp
+.Xr mscdlabel 8
+has limitations with finding all ISO-9660 sessions which are accessible via
+a storage device. The burn software suite which produced the ISO-9660
+filesystem should be able to tell all suitable
+.Ar block_offset
+values.
+.El
.Pp
For compatibility with previous releases, following obsolete flags are
still recognized:
From: "Thomas Schmitt" <scdbackup@gmx.net>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: kern/48808
Date: Mon, 19 May 2014 23:24:54 +0200
I see in the patch text that i forgot to adapt the debugging code
to the new data type of variable "sess".
For review, please virtually apply this change to the patch for
sys/fs/cd9660/cd9660_vfsops.c:
#ifdef ISO_DEBUG
- printf("isofs: session offset (part %"PRId32") %d\n", DISKPART(dev), sess);
+ printf("isofs: session offset (part %"PRIu32") %d\n", DISKPART(dev), sess);
#endif
From: "Thomas Schmitt" <scdbackup@gmx.net>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: kern/48808
Date: Tue, 20 May 2014 07:34:28 +0200
Another attempt to get that debugging line right
#ifdef ISO_DEBUG
- printf("isofs: session offset (part %"PRId32") %d\n", DISKPART(dev), sess);
+ printf("isofs: session offset (part %"PRId32") %"PRIu32"\n", DISKPART(dev), sess);
#endif
From: "Thomas Schmitt" <scdbackup@gmx.net>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: kern/48808
Date: Sun, 25 May 2014 09:26:43 +0200
I have to retract the proposal to remove most of the .h files
from /usr/include/isofs/cd9660.
As reported in
http://mail-index.netbsd.org/tech-kern/2014/05/24/msg017141.html
http://mail-index.netbsd.org/tech-kern/2014/05/25/msg017143.html
there are indeed includers of these files:
fstat(1), pmap(1), makefs(8)
None of them is affected by the header changes proposed in this
PR kern/48808.
(There will be API/ABI problems with fstat(1) if struct iso_node
gets changed to support files of 4 GiB or larger.)
From: "Thomas Schmitt" <scdbackup@gmx.net>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: kern/48808
Date: Sun, 01 Jun 2014 16:50:16 +0200
Hi,
after counselling by Martin Husemann: new patch proposals.
The patch for distrib/sets/lists/comp/mi.orig is now retracted.
The patch for sys/fs/cd9660 is slightley modified to reflect
my grown deference towards the semi-public API/ABI of cd9660.
cd9660_extern.h will not have (uint32_t) as replacement of
inappropriate (int), but rather (unsigned int).
I expect 16 bit int to fail miserably anyway, so it is only
about not breaking the ABI for machines with 64 bit (int).
The change of signedness can hardly affect existing ISO 9660
filesystems, because it shows up only above 4 TiB size.
The patch for sbin/mount_cd9660 was shrunk by the assumption
that new /sbin/mount_cd9660 will always be compiled in a *.h
environment and run on a kernel which implement the new session
offset feature from the sys/fs/cd9660 patch.
I considered to remove only the after-mount test for success of
the new option. But actually it makes few sense to allow an
old kernel header environment at compile time, but to assume a
new kernel at run time.
So there are two alternative patches for choice:
- The older one, ready for old and new kernels.
Date: Sun, 18 May 2014 16:39:13 +0200
- The new one, ready only for new kernels.
The new patches are tested by the ISO filesystem which also
serves for the upcomming large file patch. All seems well,
except of course 2 failed large file tests.
Have a nice day :)
Thomas
From: "Thomas Schmitt" <scdbackup@gmx.net>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: kern/48808
Date: Sun, 01 Jun 2014 16:56:46 +0200
--- sys/fs/cd9660/cd9660_extern.h.orig 2013-06-23 07:28:36.000000000 +0000
+++ sys/fs/cd9660/cd9660_extern.h 2014-06-01 13:21:20.000000000 +0000
@@ -72,15 +72,17 @@ struct iso_mnt {
int im_bshift;
int im_bmask;
- int volume_space_size;
+ unsigned int volume_space_size;
char root[ISODCL (157, 190)];
- int root_extent;
- int root_size;
+ unsigned int root_extent;
+ unsigned int root_size;
enum ISO_FTYPE iso_ftype;
int rr_skip;
int rr_skip0;
+
+ unsigned int im_ssector;
};
#define VFSTOISOFS(mp) ((struct iso_mnt *)((mp)->mnt_data))
--- sys/fs/cd9660/cd9660_mount.h.orig 2005-12-03 17:34:43.000000000 +0000
+++ sys/fs/cd9660/cd9660_mount.h 2014-06-01 13:04:55.000000000 +0000
@@ -38,6 +38,8 @@
#ifndef _ISOFS_CD9660_CD9660_MOUNT_H_
#define _ISOFS_CD9660_CD9660_MOUNT_H_
+#include <sys/types.h>
+
/*
* Arguments to mount ISO 9660 filesystems.
*/
@@ -45,6 +47,9 @@ struct iso_args {
const char *fspec; /* block special device to mount */
struct export_args30 _pad1; /* compat with old userland tools */
int flags; /* mounting flags, see below */
+ uint32_t ssector; /* start sector of session,
+ * if flags & ISOFSMNT_SSECTOR
+ */
};
#define ISOFSMNT_NORRIP 0x00000001 /* disable Rock Ridge Ext.*/
#define ISOFSMNT_GENS 0x00000002 /* enable generation numbers */
@@ -52,8 +57,30 @@ struct iso_args {
#define ISOFSMNT_NOJOLIET 0x00000008 /* disable Joliet extensions */
#define ISOFSMNT_NOCASETRANS 0x00000010 /* do not make names lower case */
#define ISOFSMNT_RRCASEINS 0x00000020 /* case insensitive Rock Ridge */
+#define ISOFSMNT_SSECTOR 0x00000040 /* use ssector as session start */
-#define ISOFSMNT_BITS "\177\20" \
+#define ISOFSMNT_BITS "\177\020" \
"b\00norrip\0b\01gens\0b\02extatt\0b\03nojoliet\0" \
- "b\04nocasetrans\0b\05rrcaseins\0"
+ "b\04nocasetrans\0b\05rrcaseins\0b\06ssector\0\0"
+
+
+/* Compatibility precaution:
+ *
+ * struct old_iso_args_v_1_6 is the definition of struct iso_args before
+ * may 2014. Such structs are still accepted by mount(2) and will be defaulted
+ * to (flags & ~ISOFSMNT_SSECTOR).
+ *
+ * The old struct is exposed here to serve as size benchmark for the reply
+ * of mount(2) with MNT_GETARGS. If after successful mount(2), the inquiry
+ * by MNT_GETARGS yields sizeof(struct old_iso_args_v_1_6) then the
+ * kernel was built with the old struct iso_args. In this case it silently
+ * ignored ISOFSMNT_SSECTOR and iso_args.ssector.
+ * This test can be done only after mounting, because else -1 gets returned.
+ */
+struct old_iso_args_v_1_6 {
+ const char *fspec;
+ struct export_args30 _pad1;
+ int flags;
+};
+
#endif /* _ISOFS_CD9660_CD9660_MOUNT_H_ */
--- sys/fs/cd9660/cd9660_vfsops.c.patch_006 2014-06-01 13:16:27.000000000 +0000
+++ sys/fs/cd9660/cd9660_vfsops.c 2014-06-01 13:04:55.000000000 +0000
@@ -215,21 +215,45 @@ cd9660_mount(struct mount *mp, const cha
struct iso_args *args = data;
int error;
struct iso_mnt *imp = VFSTOISOFS(mp);
+ struct iso_args defaulted_iso_args;
if (args == NULL)
return EINVAL;
- if (*data_len < sizeof *args)
- return EINVAL;
-
+ if (*data_len < sizeof *args) {
+ if (*data_len < sizeof (struct old_iso_args_v_1_6))
+ return EINVAL; /* Too small even for old iso_args */
+ if (!(mp->mnt_flag & MNT_GETARGS)) {
+ /* Upgrade old struct by defaults */
+ args = &defaulted_iso_args;
+ memset(args, 0, sizeof *args);
+ memcpy(args, data, sizeof (struct old_iso_args_v_1_6));
+ args->flags &= ~ISOFSMNT_SSECTOR;
+ printf("cd9660_mount: Upgraded old struct iso_args\n");
+ }
+ }
if (mp->mnt_flag & MNT_GETARGS) {
if (imp == NULL)
return EIO;
args->fspec = NULL;
args->flags = imp->im_flags;
- *data_len = sizeof (*args);
+ if (*data_len >= sizeof *args) {
+ args->ssector = imp->im_ssector;
+ *data_len = sizeof (*args);
+ } else {
+ *data_len = sizeof (struct old_iso_args_v_1_6);
+ }
return 0;
}
+ /* XXX Check for any unknown flags and eventually throw EINVAL ?
+ * This would allow future extensions to fail on old kernels
+ * rather than to be silently ignored, which causes the need
+ * to verify their effectiveness.
+ * See cd9660_mount.h: struct old_iso_args_v_1_6
+ * (One cannot use *data_len as indicator for undue demands.
+ * A newer iso_args may well express old fulfillable wishes.)
+ */
+
if ((mp->mnt_flag & MNT_RDONLY) == 0)
return (EROFS);
@@ -244,7 +268,6 @@ cd9660_mount(struct mount *mp, const cha
NSM_FOLLOW_NOEMULROOT, &devvp);
if (error != 0)
return (error);
-
if (devvp->v_type != VBLK) {
vrele(devvp);
return ENOTBLK;
@@ -277,11 +300,22 @@ cd9660_mount(struct mount *mp, const cha
VOP_UNLOCK(devvp);
/* reference to devvp is donated through iso_mountfs */
} else {
+ if ((imp->im_flags & ISOFSMNT_SSECTOR ? imp->im_ssector : 0) !=
+ (args->flags & ISOFSMNT_SSECTOR ? args->ssector : 0)) {
+ error = EINVAL; /* wish to change superblock */
+ goto fail;
+ }
if (devvp != imp->im_devvp &&
devvp->v_rdev != imp->im_devvp->v_rdev) {
error = EINVAL; /* needs translation */
goto fail;
}
+
+ /* XXX Should not something be done here ?
+ norrip, nojoliet, nomaplcase, ... ?
+ */
+ /* XXX UDF throws EOPNOTSUPP instead of silently ignoring */
+
VOP_UNLOCK(devvp);
vrele(devvp);
}
@@ -345,11 +379,11 @@ iso_mountfs(struct vnode *devvp, struct
int error = EINVAL;
int ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
int iso_bsize;
- int iso_blknum;
+ uint32_t iso_blknum;
int joliet_level;
struct iso_volume_descriptor *vdp;
struct iso_supplementary_descriptor *sup;
- int sess = 0;
+ uint32_t sess = 0;
int ext_attr_length;
struct disklabel label;
@@ -376,12 +410,15 @@ iso_mountfs(struct vnode *devvp, struct
if (error)
sess = 0; /* never mind */
}
+ if (argp->flags & ISOFSMNT_SSECTOR)
+ sess = argp->ssector;
#ifdef ISO_DEBUG
- printf("isofs: session offset (part %"PRId32") %d\n", DISKPART(dev), sess);
+ printf("isofs: session offset (part %"PRId32") %"PRIu32"\n", DISKPART(dev), sess);
#endif
for (iso_blknum = 16; iso_blknum < 100; iso_blknum++) {
- if ((error = bread(devvp, (iso_blknum+sess) * btodb(iso_bsize),
+ if ((error = bread(devvp, ((daddr_t) iso_blknum + sess)
+ * btodb(iso_bsize),
iso_bsize, NOCRED, 0, &bp)) != 0)
goto out;
@@ -434,6 +471,8 @@ iso_mountfs(struct vnode *devvp, struct
goto out;
}
+ if (argp->flags & ISOFSMNT_SSECTOR)
+ isomp->im_ssector = argp->ssector;
isomp->volume_space_size += sess;
brelse(pribp, BC_AGE);
@@ -479,7 +518,8 @@ iso_mountfs(struct vnode *devvp, struct
bp = NULL;
}
isomp->im_flags = argp->flags & (ISOFSMNT_NORRIP | ISOFSMNT_GENS |
- ISOFSMNT_EXTATT | ISOFSMNT_NOJOLIET | ISOFSMNT_RRCASEINS);
+ ISOFSMNT_EXTATT | ISOFSMNT_NOJOLIET | ISOFSMNT_NOCASETRANS |
+ ISOFSMNT_RRCASEINS | ISOFSMNT_SSECTOR);
if (isomp->im_flags & ISOFSMNT_GENS)
isomp->iso_ftype = ISO_FTYPE_9660;
From: "Thomas Schmitt" <scdbackup@gmx.net>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: kern/48808
Date: Sun, 01 Jun 2014 17:03:09 +0200
--- sbin/mount_cd9660/mount_cd9660.c.orig 2011-08-29 14:35:00.000000000 +0000
+++ sbin/mount_cd9660/mount_cd9660.c 2014-06-01 13:56:09.000000000 +0000
@@ -79,6 +79,7 @@ static const struct mntopt mopts[] = {
{ "rrip", 1, ISOFSMNT_NORRIP, 1 },
{ "joliet", 1, ISOFSMNT_NOJOLIET, 1 },
{ "rrcaseins", 0, ISOFSMNT_RRCASEINS, 1 },
+ { "ssector", 0, 0, 1 }, /* not setable, only for info via getargs */
MOPT_NULL,
};
@@ -102,11 +103,13 @@ mount_cd9660_parseargs(int argc, char **
int ch, opts;
mntoptparse_t mp;
char *dev, *dir;
+ char *ep;
+ long long int llnum;
memset(args, 0, sizeof(*args));
*mntflags = opts = 0;
optind = optreset = 1;
- while ((ch = getopt(argc, argv, "egijo:r")) != -1)
+ while ((ch = getopt(argc, argv, "egijo:rs:")) != -1)
switch (ch) {
case 'e':
/* obsolete, retained for compatibility only, use
@@ -134,6 +137,19 @@ mount_cd9660_parseargs(int argc, char **
* -o norrip */
opts |= ISOFSMNT_NORRIP;
break;
+ case 's':
+ /* learned from mount/fattr.c : a_num() */
+ llnum = strtoll(optarg, &ep, 0);
+ if (*ep || optarg == ep || llnum < 0 ||
+ llnum > (long long int) 0xffffff00) {
+ (void)fprintf(stderr,
+ "%s : unusable parameter with option -s\n",
+ getprogname());
+ usage();
+ }
+ args->ssector = llnum;
+ opts |= ISOFSMNT_SSECTOR;
+ break;
case '?':
default:
usage();
@@ -177,6 +193,8 @@ mount_cd9660(int argc, char **argv)
char buf[2048];
(void)snprintb(buf, sizeof(buf), ISOFSMNT_BITS, args.flags);
printf("%s\n", buf);
+ if (args.flags & ISOFSMNT_SSECTOR)
+ printf("-s %"PRIu32"\n", args.ssector);
}
exit(0);
@@ -186,6 +204,7 @@ static void
usage(void)
{
(void)fprintf(stderr,
- "usage: %s [-o options] special node\n", getprogname());
+ "usage: %s [-o options | -s block_offset] special node\n",
+ getprogname());
exit(1);
}
--- sbin/mount_cd9660/mount_cd9660.8.orig 2009-01-03 22:56:23.000000000 +0000
+++ sbin/mount_cd9660/mount_cd9660.8 2014-05-16 19:49:05.000000000 +0000
@@ -57,7 +57,7 @@
.\"
.\" @(#)mount_cd9660.8 8.3 (Berkeley) 3/27/94
.\"
-.Dd January 3, 2009
+.Dd May, 16, 2014
.Dt MOUNT_CD9660 8
.Os
.Sh NAME
@@ -66,6 +66,7 @@
.Sh SYNOPSIS
.Nm
.Op Fl o Ar options
+.Op Fl s Ar block_offset
.Ar special node
.Sh DESCRIPTION
The
@@ -130,8 +131,41 @@ For compatibility with Solaris only.
.It Cm rrcaseins
Makes all lookups case-insensitive even for CD-ROMs with Rock-Ridge
extensions (for Rock-Ridge, default is case-sensitive lookup).
+.It Cm ssector
+Is ignored as input option but reported by
+.Cm getargs
+if option
+.Cm Fl s
+is in effect.
.El
.El
+.Bl -tag -width indent
+.It Fl s Ar block_offset
+Read the superblock from block address
+.Ar block_offset
+rather than from the default position implied by the choice of the device file.
+The block size is 2048 bytes.
+.Pp
+Command
+.Xr mscdlabel 8
+may have connected some
+.Pa /dev/cd*
+files to logical tracks of an optical
+multi-session medium, giving the device files the matching superblock
+positions for the recognized ISO-9660 filesystems.
+Such a default offset will be overridden by option
+.Fl s
+so that all
+.Pa /dev/cd*
+will behave like raw partition devices.
+.Pp
+.Xr mscdlabel 8
+has limitations with finding all ISO-9660 sessions which are accessible via
+a storage device. The burn software suite which produced the ISO-9660
+filesystem should be able to tell all suitable
+.Ar block_offset
+values.
+.El
.Pp
For compatibility with previous releases, following obsolete flags are
still recognized:
(Contact us)
$NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.