From owner-freebsd-bugs@FreeBSD.ORG Wed Sep 25 00:00:00 2013 Return-Path: Delivered-To: freebsd-bugs@smarthost.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id E36736D5 for ; Wed, 25 Sep 2013 00:00:00 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:1900:2254:206c::16:87]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id C33D22528 for ; Wed, 25 Sep 2013 00:00:00 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.7/8.14.7) with ESMTP id r8P000bP015208 for ; Wed, 25 Sep 2013 00:00:00 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.7/8.14.7/Submit) id r8P000Bw015206; Wed, 25 Sep 2013 00:00:00 GMT (envelope-from gnats) Resent-Date: Wed, 25 Sep 2013 00:00:00 GMT Resent-Message-Id: <201309250000.r8P000Bw015206@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, John-Mark Gurney Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id DAD605C2 for ; Tue, 24 Sep 2013 23:58:19 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from oldred.freebsd.org (oldred.freebsd.org [8.8.178.121]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id B67E2250E for ; Tue, 24 Sep 2013 23:58:19 +0000 (UTC) Received: from oldred.freebsd.org ([127.0.1.6]) by oldred.freebsd.org (8.14.5/8.14.7) with ESMTP id r8ONwJtX000381 for ; Tue, 24 Sep 2013 23:58:19 GMT (envelope-from nobody@oldred.freebsd.org) Received: (from nobody@localhost) by oldred.freebsd.org (8.14.5/8.14.5/Submit) id r8ONwJRT000378; Tue, 24 Sep 2013 23:58:19 GMT (envelope-from nobody) Message-Id: <201309242358.r8ONwJRT000378@oldred.freebsd.org> Date: Tue, 24 Sep 2013 23:58:19 GMT From: John-Mark Gurney To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Subject: bin/182362: bsdpatch fails to apply patch when you say yes X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 25 Sep 2013 00:00:01 -0000 >Number: 182362 >Category: bin >Synopsis: bsdpatch fails to apply patch when you say yes >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Wed Sep 25 00:00:00 UTC 2013 >Closed-Date: >Last-Modified: >Originator: John-Mark Gurney >Release: FreeBSD 10.0-ALPHA3 >Organization: >Environment: FreeBSD carbon.funkthat.com 10.0-ALPHA3 FreeBSD 10.0-ALPHA3 #1 r255861M: Tue Sep 24 13:36:04 PDT 2013 jmg@carbon.funkthat.com:/usr/src/sys/amd64/compile/lockprof amd64 >Description: Extract attached shar archive and do: [jmg@carbon /tmp/wo]$ patch < cd9660.patch Hmm... Looks like a unified diff to me... The text leading up to this was: -------------------------- |Index: cd9660_vfsops.c |=================================================================== |--- cd9660_vfsops.c (revision 255707) |+++ cd9660_vfsops.c (working copy) -------------------------- Patching file cd9660_vfsops.c using Plan A... Reversed (or previously applied) patch detected! Assume -R? [y] n Apply anyway? [n] y Reversed (or previously applied) patch detected! Assume -R? [y] n Apply anyway? [n] y Reversed (or previously applied) patch detected! Assume -R? [y] n Apply anyway? [n] y Hunk #1 failed at 214. Hunk #2 succeeded at 369. Hunk #3 succeeded at 393 (offset -1 lines). Hunk #4 succeeded at 414 (offset -1 lines). Hunk #5 succeeded at 469 (offset -1 lines). 1 out of 5 hunks failed--saving rejects to cd9660_vfsops.c.rej done Do I really need to answer the question three times that Yes, I really do want to apply the patch? I have verified that gnupatch does not do this. >How-To-Repeat: see above. >Fix: Patch attached with submission follows: # This is a shell archive. Save it in a file, remove anything before # this line, and then unpack it by entering "sh file". Note, it may # create directories; files and directories will be owned by you and # have default permissions. # # This archive contains: # # cd9660.patch # cd9660_vfsops.c # echo x - cd9660.patch sed 's/^X//' >cd9660.patch << '4af2b3683126871a553b80884bd87b50' XIndex: cd9660_vfsops.c X=================================================================== X--- cd9660_vfsops.c (revision 255707) X+++ cd9660_vfsops.c (working copy) X@@ -214,7 +214,7 @@ X int iso_bsize; X int iso_blknum; X int joliet_level; X- struct iso_volume_descriptor *vdp = 0; X+ struct iso_volume_descriptor *vdp = NULL; X struct iso_primary_descriptor *pri = NULL; X struct iso_sierra_primary_descriptor *pri_sierra = NULL; X struct iso_supplementary_descriptor *sup = NULL; X@@ -369,6 +369,9 @@ X pribp->b_flags |= B_AGE; X brelse(pribp); X pribp = NULL; X+ rootp = NULL; X+ pri = NULL; X+ pri_sierra = NULL; X X mp->mnt_data = isomp; X mp->mnt_stat.f_fsid.val[0] = dev2udev(dev); X@@ -391,11 +394,11 @@ X X /* Check the Rock Ridge Extension support */ X if (!(isomp->im_flags & ISOFSMNT_NORRIP)) { X- if ((error = bread(isomp->im_devvp, X- (isomp->root_extent + isonum_711(rootp->ext_attr_length)) << X- (isomp->im_bshift - DEV_BSHIFT), X- isomp->logical_block_size, NOCRED, &bp)) != 0) X- goto out; X+ if ((error = bread(isomp->im_devvp, (isomp->root_extent + X+ isonum_711(((struct iso_directory_record *)isomp->root)-> X+ ext_attr_length)) << (isomp->im_bshift - DEV_BSHIFT), X+ isomp->logical_block_size, NOCRED, &bp)) != 0) X+ goto out; X X rootp = (struct iso_directory_record *)bp->b_data; X X@@ -412,6 +415,7 @@ X bp->b_flags |= B_AGE; X brelse(bp); X bp = NULL; X+ rootp = NULL; X } X X if (isomp->im_flags & ISOFSMNT_KICONV && cd9660_iconv) { X@@ -466,6 +470,7 @@ X if (supbp) { X brelse(supbp); X supbp = NULL; X+ sup = NULL; X } X X return 0; 4af2b3683126871a553b80884bd87b50 echo x - cd9660_vfsops.c sed 's/^X//' >cd9660_vfsops.c << '6e65c262c71a183b9a224cc8a47ecdb1' X/*- X * Copyright (c) 1994 X * The Regents of the University of California. All rights reserved. X * X * This code is derived from software contributed to Berkeley X * by Pace Willisson (pace@blitz.com). The Rock Ridge Extension X * Support code is derived from software contributed to Berkeley X * by Atsushi Murai (amurai@spec.co.jp). X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * 4. Neither the name of the University nor the names of its contributors X * may be used to endorse or promote products derived from this software X * without specific prior written permission. X * X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE X * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF X * SUCH DAMAGE. X * X * @(#)cd9660_vfsops.c 8.18 (Berkeley) 5/22/95 X */ X X#include X__FBSDID("$FreeBSD: head/sys/fs/cd9660/cd9660_vfsops.c 242833 2012-11-09 18:02:25Z attilio $"); X X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X X#include X#include X#include X#include X X#include X#include X XMALLOC_DEFINE(M_ISOFSMNT, "isofs_mount", "ISOFS mount structure"); XMALLOC_DEFINE(M_ISOFSNODE, "isofs_node", "ISOFS vnode private part"); X Xstruct iconv_functions *cd9660_iconv = NULL; X Xstatic vfs_mount_t cd9660_mount; Xstatic vfs_cmount_t cd9660_cmount; Xstatic vfs_unmount_t cd9660_unmount; Xstatic vfs_root_t cd9660_root; Xstatic vfs_statfs_t cd9660_statfs; Xstatic vfs_vget_t cd9660_vget; Xstatic vfs_fhtovp_t cd9660_fhtovp; X Xstatic struct vfsops cd9660_vfsops = { X .vfs_fhtovp = cd9660_fhtovp, X .vfs_mount = cd9660_mount, X .vfs_cmount = cd9660_cmount, X .vfs_root = cd9660_root, X .vfs_statfs = cd9660_statfs, X .vfs_unmount = cd9660_unmount, X .vfs_vget = cd9660_vget, X}; XVFS_SET(cd9660_vfsops, cd9660, VFCF_READONLY); XMODULE_VERSION(cd9660, 1); X Xstatic int iso_mountfs(struct vnode *devvp, struct mount *mp); X X/* X * VFS Operations. X */ X Xstatic int Xcd9660_cmount(struct mntarg *ma, void *data, uint64_t flags) X{ X struct iso_args args; X struct export_args exp; X int error; X X error = copyin(data, &args, sizeof args); X if (error) X return (error); X vfs_oexport_conv(&args.export, &exp); X X ma = mount_argsu(ma, "from", args.fspec, MAXPATHLEN); X ma = mount_arg(ma, "export", &exp, sizeof(exp)); X ma = mount_argsu(ma, "cs_disk", args.cs_disk, 64); X ma = mount_argsu(ma, "cs_local", args.cs_local, 64); X ma = mount_argf(ma, "ssector", "%u", args.ssector); X ma = mount_argb(ma, !(args.flags & ISOFSMNT_NORRIP), "norrip"); X ma = mount_argb(ma, args.flags & ISOFSMNT_GENS, "nogens"); X ma = mount_argb(ma, args.flags & ISOFSMNT_EXTATT, "noextatt"); X ma = mount_argb(ma, !(args.flags & ISOFSMNT_NOJOLIET), "nojoliet"); X ma = mount_argb(ma, X args.flags & ISOFSMNT_BROKENJOLIET, "nobrokenjoliet"); X ma = mount_argb(ma, args.flags & ISOFSMNT_KICONV, "nokiconv"); X X error = kernel_mount(ma, flags); X X return (error); X} X Xstatic int Xcd9660_mount(struct mount *mp) X{ X struct vnode *devvp; X struct thread *td; X char *fspec; X int error; X accmode_t accmode; X struct nameidata ndp; X struct iso_mnt *imp = NULL; X X td = curthread; X X /* X * Unconditionally mount as read-only. X */ X MNT_ILOCK(mp); X mp->mnt_flag |= MNT_RDONLY; X MNT_IUNLOCK(mp); X X fspec = vfs_getopts(mp->mnt_optnew, "from", &error); X if (error) X return (error); X X imp = VFSTOISOFS(mp); X X if (mp->mnt_flag & MNT_UPDATE) { X if (vfs_flagopt(mp->mnt_optnew, "export", NULL, 0)) X return (0); X } X /* X * Not an update, or updating the name: look up the name X * and verify that it refers to a sensible block device. X */ X NDINIT(&ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, fspec, td); X if ((error = namei(&ndp))) X return (error); X NDFREE(&ndp, NDF_ONLY_PNBUF); X devvp = ndp.ni_vp; X X if (!vn_isdisk(devvp, &error)) { X vput(devvp); X return (error); X } X X /* X * Verify that user has necessary permissions on the device, X * or has superuser abilities X */ X accmode = VREAD; X error = VOP_ACCESS(devvp, accmode, td->td_ucred, td); X if (error) X error = priv_check(td, PRIV_VFS_MOUNT_PERM); X if (error) { X vput(devvp); X return (error); X } X X if ((mp->mnt_flag & MNT_UPDATE) == 0) { X error = iso_mountfs(devvp, mp); X if (error) X vrele(devvp); X } else { X if (devvp != imp->im_devvp) X error = EINVAL; /* needs translation */ X vput(devvp); X } X if (error) X return (error); X vfs_mountedfrom(mp, fspec); X return (0); X} X X/* X * Common code for mount and mountroot X */ Xstatic int Xiso_mountfs(devvp, mp) X struct vnode *devvp; X struct mount *mp; X{ X struct iso_mnt *isomp = NULL; X struct buf *bp = NULL; X struct buf *pribp = NULL, *supbp = NULL; X struct cdev *dev; X int error = EINVAL; X int high_sierra = 0; X int iso_bsize; X int iso_blknum; X int joliet_level; X struct iso_volume_descriptor *vdp = NULL; X struct iso_primary_descriptor *pri = NULL; X struct iso_sierra_primary_descriptor *pri_sierra = NULL; X struct iso_supplementary_descriptor *sup = NULL; X struct iso_directory_record *rootp; X int logical_block_size, ssector; X struct g_consumer *cp; X struct bufobj *bo; X char *cs_local, *cs_disk; X X dev = devvp->v_rdev; X dev_ref(dev); X DROP_GIANT(); X g_topology_lock(); X error = g_vfs_open(devvp, &cp, "cd9660", 0); X g_topology_unlock(); X PICKUP_GIANT(); X VOP_UNLOCK(devvp, 0); X if (error) X goto out; X if (devvp->v_rdev->si_iosize_max != 0) X mp->mnt_iosize_max = devvp->v_rdev->si_iosize_max; X if (mp->mnt_iosize_max > MAXPHYS) X mp->mnt_iosize_max = MAXPHYS; X X bo = &devvp->v_bufobj; X X /* This is the "logical sector size". The standard says this X * should be 2048 or the physical sector size on the device, X * whichever is greater. X */ X if ((ISO_DEFAULT_BLOCK_SIZE % cp->provider->sectorsize) != 0) { X error = EINVAL; X goto out; X } X X iso_bsize = cp->provider->sectorsize; X X joliet_level = 0; X if (1 != vfs_scanopt(mp->mnt_optnew, "ssector", "%d", &ssector)) X ssector = 0; X for (iso_blknum = 16 + ssector; X iso_blknum < 100 + ssector; X iso_blknum++) { X if ((error = bread(devvp, iso_blknum * btodb(ISO_DEFAULT_BLOCK_SIZE), X iso_bsize, NOCRED, &bp)) != 0) X goto out; X X vdp = (struct iso_volume_descriptor *)bp->b_data; X if (bcmp (vdp->id, ISO_STANDARD_ID, sizeof vdp->id) != 0) { X if (bcmp (vdp->id_sierra, ISO_SIERRA_ID, X sizeof vdp->id_sierra) != 0) { X error = EINVAL; X goto out; X } else X high_sierra = 1; X } X switch (isonum_711 (high_sierra? vdp->type_sierra: vdp->type)){ X case ISO_VD_PRIMARY: X if (pribp == NULL) { X pribp = bp; X bp = NULL; X pri = (struct iso_primary_descriptor *)vdp; X pri_sierra = X (struct iso_sierra_primary_descriptor *)vdp; X } X break; X X case ISO_VD_SUPPLEMENTARY: X if (supbp == NULL) { X supbp = bp; X bp = NULL; X sup = (struct iso_supplementary_descriptor *)vdp; X X if (!vfs_flagopt(mp->mnt_optnew, "nojoliet", NULL, 0)) { X if (bcmp(sup->escape, "%/@", 3) == 0) X joliet_level = 1; X if (bcmp(sup->escape, "%/C", 3) == 0) X joliet_level = 2; X if (bcmp(sup->escape, "%/E", 3) == 0) X joliet_level = 3; X X if ((isonum_711 (sup->flags) & 1) && X !vfs_flagopt(mp->mnt_optnew, "brokenjoliet", NULL, 0)) X joliet_level = 0; X } X } X break; X X case ISO_VD_END: X goto vd_end; X X default: X break; X } X if (bp) { X brelse(bp); X bp = NULL; X } X } X vd_end: X if (bp) { X brelse(bp); X bp = NULL; X } X X if (pri == NULL) { X error = EINVAL; X goto out; X } X X logical_block_size = X isonum_723 (high_sierra? X pri_sierra->logical_block_size: X pri->logical_block_size); X X if (logical_block_size < DEV_BSIZE || logical_block_size > MAXBSIZE X || (logical_block_size & (logical_block_size - 1)) != 0) { X error = EINVAL; X goto out; X } X X rootp = (struct iso_directory_record *) X (high_sierra? X pri_sierra->root_directory_record: X pri->root_directory_record); X X isomp = malloc(sizeof *isomp, M_ISOFSMNT, M_WAITOK | M_ZERO); X isomp->im_cp = cp; X isomp->im_bo = bo; X isomp->logical_block_size = logical_block_size; X isomp->volume_space_size = X isonum_733 (high_sierra? X pri_sierra->volume_space_size: X pri->volume_space_size); X isomp->joliet_level = 0; X /* X * Since an ISO9660 multi-session CD can also access previous X * sessions, we have to include them into the space consider- X * ations. This doesn't yield a very accurate number since X * parts of the old sessions might be inaccessible now, but we X * can't do much better. This is also important for the NFS X * filehandle validation. X */ X isomp->volume_space_size += ssector; X bcopy (rootp, isomp->root, sizeof isomp->root); X isomp->root_extent = isonum_733 (rootp->extent); X isomp->root_size = isonum_733 (rootp->size); X X isomp->im_bmask = logical_block_size - 1; X isomp->im_bshift = ffs(logical_block_size) - 1; X X pribp->b_flags |= B_AGE; X brelse(pribp); X pribp = NULL; X X mp->mnt_data = isomp; X mp->mnt_stat.f_fsid.val[0] = dev2udev(dev); X mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum; X mp->mnt_maxsymlinklen = 0; X MNT_ILOCK(mp); X mp->mnt_flag |= MNT_LOCAL; X mp->mnt_kern_flag |= MNTK_LOOKUP_SHARED | MNTK_EXTENDED_SHARED; X MNT_IUNLOCK(mp); X isomp->im_mountp = mp; X isomp->im_dev = dev; X isomp->im_devvp = devvp; X X vfs_flagopt(mp->mnt_optnew, "norrip", &isomp->im_flags, ISOFSMNT_NORRIP); X vfs_flagopt(mp->mnt_optnew, "gens", &isomp->im_flags, ISOFSMNT_GENS); X vfs_flagopt(mp->mnt_optnew, "extatt", &isomp->im_flags, ISOFSMNT_EXTATT); X vfs_flagopt(mp->mnt_optnew, "nojoliet", &isomp->im_flags, ISOFSMNT_NOJOLIET); X vfs_flagopt(mp->mnt_optnew, "kiconv", &isomp->im_flags, ISOFSMNT_KICONV); X X /* Check the Rock Ridge Extension support */ X if (!(isomp->im_flags & ISOFSMNT_NORRIP)) { X if ((error = bread(isomp->im_devvp, X (isomp->root_extent + isonum_711(rootp->ext_attr_length)) << X (isomp->im_bshift - DEV_BSHIFT), X isomp->logical_block_size, NOCRED, &bp)) != 0) X goto out; X X rootp = (struct iso_directory_record *)bp->b_data; X X if ((isomp->rr_skip = cd9660_rrip_offset(rootp,isomp)) < 0) { X isomp->im_flags |= ISOFSMNT_NORRIP; X } else { X isomp->im_flags &= ~ISOFSMNT_GENS; X } X X /* X * The contents are valid, X * but they will get reread as part of another vnode, so... X */ X bp->b_flags |= B_AGE; X brelse(bp); X bp = NULL; X } X X if (isomp->im_flags & ISOFSMNT_KICONV && cd9660_iconv) { X cs_local = vfs_getopts(mp->mnt_optnew, "cs_local", &error); X if (error) X goto out; X cs_disk = vfs_getopts(mp->mnt_optnew, "cs_disk", &error); X if (error) X goto out; X cd9660_iconv->open(cs_local, cs_disk, &isomp->im_d2l); X cd9660_iconv->open(cs_disk, cs_local, &isomp->im_l2d); X } else { X isomp->im_d2l = NULL; X isomp->im_l2d = NULL; X } X X if (high_sierra) { X /* this effectively ignores all the mount flags */ X if (bootverbose) X log(LOG_INFO, "cd9660: High Sierra Format\n"); X isomp->iso_ftype = ISO_FTYPE_HIGH_SIERRA; X } else X switch (isomp->im_flags&(ISOFSMNT_NORRIP|ISOFSMNT_GENS)) { X default: X isomp->iso_ftype = ISO_FTYPE_DEFAULT; X break; X case ISOFSMNT_GENS|ISOFSMNT_NORRIP: X isomp->iso_ftype = ISO_FTYPE_9660; X break; X case 0: X if (bootverbose) X log(LOG_INFO, "cd9660: RockRidge Extension\n"); X isomp->iso_ftype = ISO_FTYPE_RRIP; X break; X } X X /* Decide whether to use the Joliet descriptor */ X X if (isomp->iso_ftype != ISO_FTYPE_RRIP && joliet_level) { X if (bootverbose) X log(LOG_INFO, "cd9660: Joliet Extension (Level %d)\n", X joliet_level); X rootp = (struct iso_directory_record *) X sup->root_directory_record; X bcopy (rootp, isomp->root, sizeof isomp->root); X isomp->root_extent = isonum_733 (rootp->extent); X isomp->root_size = isonum_733 (rootp->size); X isomp->joliet_level = joliet_level; X supbp->b_flags |= B_AGE; X } X X if (supbp) { X brelse(supbp); X supbp = NULL; X } X X return 0; Xout: X if (bp) X brelse(bp); X if (pribp) X brelse(pribp); X if (supbp) X brelse(supbp); X if (cp != NULL) { X DROP_GIANT(); X g_topology_lock(); X g_vfs_close(cp); X g_topology_unlock(); X PICKUP_GIANT(); X } X if (isomp) { X free(isomp, M_ISOFSMNT); X mp->mnt_data = NULL; X } X dev_rel(dev); X return error; X} X X/* X * unmount system call X */ Xstatic int Xcd9660_unmount(mp, mntflags) X struct mount *mp; X int mntflags; X{ X struct iso_mnt *isomp; X int error, flags = 0; X X if (mntflags & MNT_FORCE) X flags |= FORCECLOSE; X if ((error = vflush(mp, 0, flags, curthread))) X return (error); X X isomp = VFSTOISOFS(mp); X X if (isomp->im_flags & ISOFSMNT_KICONV && cd9660_iconv) { X if (isomp->im_d2l) X cd9660_iconv->close(isomp->im_d2l); X if (isomp->im_l2d) X cd9660_iconv->close(isomp->im_l2d); X } X DROP_GIANT(); X g_topology_lock(); X g_vfs_close(isomp->im_cp); X g_topology_unlock(); X PICKUP_GIANT(); X vrele(isomp->im_devvp); X dev_rel(isomp->im_dev); X free(isomp, M_ISOFSMNT); X mp->mnt_data = NULL; X MNT_ILOCK(mp); X mp->mnt_flag &= ~MNT_LOCAL; X MNT_IUNLOCK(mp); X return (error); X} X X/* X * Return root of a filesystem X */ Xstatic int Xcd9660_root(mp, flags, vpp) X struct mount *mp; X int flags; X struct vnode **vpp; X{ X struct iso_mnt *imp = VFSTOISOFS(mp); X struct iso_directory_record *dp = X (struct iso_directory_record *)imp->root; X ino_t ino = isodirino(dp, imp); X X /* X * With RRIP we must use the `.' entry of the root directory. X * Simply tell vget, that it's a relocated directory. X */ X return (cd9660_vget_internal(mp, ino, flags, vpp, X imp->iso_ftype == ISO_FTYPE_RRIP, dp)); X} X X/* X * Get filesystem statistics. X */ Xstatic int Xcd9660_statfs(mp, sbp) X struct mount *mp; X struct statfs *sbp; X{ X struct iso_mnt *isomp; X X isomp = VFSTOISOFS(mp); X X sbp->f_bsize = isomp->logical_block_size; X sbp->f_iosize = sbp->f_bsize; /* XXX */ X sbp->f_blocks = isomp->volume_space_size; X sbp->f_bfree = 0; /* total free blocks */ X sbp->f_bavail = 0; /* blocks free for non superuser */ X sbp->f_files = 0; /* total files */ X sbp->f_ffree = 0; /* free file nodes */ X return 0; X} X X/* X * File handle to vnode X * X * Have to be really careful about stale file handles: X * - check that the inode number is in range X * - call iget() to get the locked inode X * - check for an unallocated inode (i_mode == 0) X * - check that the generation number matches X */ X X/* ARGSUSED */ Xstatic int Xcd9660_fhtovp(mp, fhp, flags, vpp) X struct mount *mp; X struct fid *fhp; X int flags; X struct vnode **vpp; X{ X struct ifid ifh; X struct iso_node *ip; X struct vnode *nvp; X int error; X X memcpy(&ifh, fhp, sizeof(ifh)); X X#ifdef ISOFS_DBG X printf("fhtovp: ino %d, start %ld\n", X ifh.ifid_ino, ifh.ifid_start); X#endif X X if ((error = VFS_VGET(mp, ifh.ifid_ino, LK_EXCLUSIVE, &nvp)) != 0) { X *vpp = NULLVP; X return (error); X } X ip = VTOI(nvp); X if (ip->inode.iso_mode == 0) { X vput(nvp); X *vpp = NULLVP; X return (ESTALE); X } X *vpp = nvp; X vnode_create_vobject(*vpp, ip->i_size, curthread); X return (0); X} X Xstatic int Xcd9660_vget(mp, ino, flags, vpp) X struct mount *mp; X ino_t ino; X int flags; X struct vnode **vpp; X{ X X /* X * XXXX X * It would be nice if we didn't always set the `relocated' flag X * and force the extra read, but I don't want to think about fixing X * that right now. X */ X return (cd9660_vget_internal(mp, ino, flags, vpp, X#if 0 X VFSTOISOFS(mp)->iso_ftype == ISO_FTYPE_RRIP, X#else X 0, X#endif X (struct iso_directory_record *)0)); X} X Xint Xcd9660_vget_internal(mp, ino, flags, vpp, relocated, isodir) X struct mount *mp; X ino_t ino; X int flags; X struct vnode **vpp; X int relocated; X struct iso_directory_record *isodir; X{ X struct iso_mnt *imp; X struct iso_node *ip; X struct buf *bp; X struct vnode *vp; X struct cdev *dev; X int error; X struct thread *td; X X td = curthread; X error = vfs_hash_get(mp, ino, flags, td, vpp, NULL, NULL); X if (error || *vpp != NULL) X return (error); X X /* X * We must promote to an exclusive lock for vnode creation. This X * can happen if lookup is passed LOCKSHARED. X */ X if ((flags & LK_TYPE_MASK) == LK_SHARED) { X flags &= ~LK_TYPE_MASK; X flags |= LK_EXCLUSIVE; X } X X /* X * We do not lock vnode creation as it is believed to be too X * expensive for such rare case as simultaneous creation of vnode X * for same ino by different processes. We just allow them to race X * and check later to decide who wins. Let the race begin! X */ X X imp = VFSTOISOFS(mp); X dev = imp->im_dev; X X /* Allocate a new vnode/iso_node. */ X if ((error = getnewvnode("isofs", mp, &cd9660_vnodeops, &vp)) != 0) { X *vpp = NULLVP; X return (error); X } X ip = malloc(sizeof(struct iso_node), M_ISOFSNODE, X M_WAITOK | M_ZERO); X vp->v_data = ip; X ip->i_vnode = vp; X ip->i_number = ino; X X lockmgr(vp->v_vnlock, LK_EXCLUSIVE, NULL); X error = insmntque(vp, mp); X if (error != 0) { X free(ip, M_ISOFSNODE); X *vpp = NULLVP; X return (error); X } X error = vfs_hash_insert(vp, ino, flags, td, vpp, NULL, NULL); X if (error || *vpp != NULL) X return (error); X X if (isodir == 0) { X int lbn, off; X X lbn = lblkno(imp, ino); X if (lbn >= imp->volume_space_size) { X vput(vp); X printf("fhtovp: lbn exceed volume space %d\n", lbn); X return (ESTALE); X } X X off = blkoff(imp, ino); X if (off + ISO_DIRECTORY_RECORD_SIZE > imp->logical_block_size) { X vput(vp); X printf("fhtovp: crosses block boundary %d\n", X off + ISO_DIRECTORY_RECORD_SIZE); X return (ESTALE); X } X X error = bread(imp->im_devvp, X lbn << (imp->im_bshift - DEV_BSHIFT), X imp->logical_block_size, NOCRED, &bp); X if (error) { X vput(vp); X brelse(bp); X printf("fhtovp: bread error %d\n",error); X return (error); X } X isodir = (struct iso_directory_record *)(bp->b_data + off); X X if (off + isonum_711(isodir->length) > X imp->logical_block_size) { X vput(vp); X if (bp != 0) X brelse(bp); X printf("fhtovp: directory crosses block boundary %d[off=%d/len=%d]\n", X off +isonum_711(isodir->length), off, X isonum_711(isodir->length)); X return (ESTALE); X } X X#if 0 X if (isonum_733(isodir->extent) + X isonum_711(isodir->ext_attr_length) != ifhp->ifid_start) { X if (bp != 0) X brelse(bp); X printf("fhtovp: file start miss %d vs %d\n", X isonum_733(isodir->extent) + isonum_711(isodir->ext_attr_length), X ifhp->ifid_start); X return (ESTALE); X } X#endif X } else X bp = 0; X X ip->i_mnt = imp; X X if (relocated) { X /* X * On relocated directories we must X * read the `.' entry out of a dir. X */ X ip->iso_start = ino >> imp->im_bshift; X if (bp != 0) X brelse(bp); X if ((error = cd9660_blkatoff(vp, (off_t)0, NULL, &bp)) != 0) { X vput(vp); X return (error); X } X isodir = (struct iso_directory_record *)bp->b_data; X } X X ip->iso_extent = isonum_733(isodir->extent); X ip->i_size = isonum_733(isodir->size); X ip->iso_start = isonum_711(isodir->ext_attr_length) + ip->iso_extent; X X /* X * Setup time stamp, attribute X */ X vp->v_type = VNON; X switch (imp->iso_ftype) { X default: /* ISO_FTYPE_9660 */ X { X struct buf *bp2; X int off; X if ((imp->im_flags & ISOFSMNT_EXTATT) X && (off = isonum_711(isodir->ext_attr_length))) X cd9660_blkatoff(vp, (off_t)-(off << imp->im_bshift), NULL, X &bp2); X else X bp2 = NULL; X cd9660_defattr(isodir, ip, bp2, ISO_FTYPE_9660); X cd9660_deftstamp(isodir, ip, bp2, ISO_FTYPE_9660); X if (bp2) X brelse(bp2); X break; X } X case ISO_FTYPE_RRIP: X cd9660_rrip_analyze(isodir, ip, imp); X break; X } X X if (bp != 0) X brelse(bp); X X /* X * Initialize the associated vnode X */ X switch (vp->v_type = IFTOVT(ip->inode.iso_mode)) { X case VFIFO: X vp->v_op = &cd9660_fifoops; X break; X default: X VN_LOCK_ASHARE(vp); X break; X } X X if (ip->iso_extent == imp->root_extent) X vp->v_vflag |= VV_ROOT; X X /* X * XXX need generation number? X */ X X *vpp = vp; X return (0); X} 6e65c262c71a183b9a224cc8a47ecdb1 exit >Release-Note: >Audit-Trail: >Unformatted: