summaryrefslogtreecommitdiffstats
path: root/sys/isofs
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1996-03-11 19:20:10 +0000
committerpeter <peter@FreeBSD.org>1996-03-11 19:20:10 +0000
commitfb94bd994ea4d676da6057ac5e34a4883aa9cafe (patch)
treef885b168318e77ea02de6dbd959c671d557cebb0 /sys/isofs
parent51afe267439297a3099fc177d1f82e93c3b34fb4 (diff)
downloadFreeBSD-src-fb94bd994ea4d676da6057ac5e34a4883aa9cafe.zip
FreeBSD-src-fb94bd994ea4d676da6057ac5e34a4883aa9cafe.tar.gz
Import 4.4BSD-Lite2 onto the vendor branch, note that in the kernel, all
files are off the vendor branch, so this should not change anything. A "U" marker generally means that the file was not changed in between the 4.4Lite and Lite-2 releases, and does not need a merge. "C" generally means that there was a change. [note, new file: cd9660_mount.h]
Diffstat (limited to 'sys/isofs')
-rw-r--r--sys/isofs/cd9660/TODO32
-rw-r--r--sys/isofs/cd9660/TODO.hibler14
-rw-r--r--sys/isofs/cd9660/cd9660_bmap.c16
-rw-r--r--sys/isofs/cd9660/cd9660_lookup.c165
-rw-r--r--sys/isofs/cd9660/cd9660_mount.h51
-rw-r--r--sys/isofs/cd9660/cd9660_node.c457
-rw-r--r--sys/isofs/cd9660/cd9660_node.h30
-rw-r--r--sys/isofs/cd9660/cd9660_rrip.c65
-rw-r--r--sys/isofs/cd9660/cd9660_rrip.h34
-rw-r--r--sys/isofs/cd9660/cd9660_util.c108
-rw-r--r--sys/isofs/cd9660/cd9660_vfsops.c441
-rw-r--r--sys/isofs/cd9660/cd9660_vnops.c599
-rw-r--r--sys/isofs/cd9660/iso.h114
13 files changed, 1107 insertions, 1019 deletions
diff --git a/sys/isofs/cd9660/TODO b/sys/isofs/cd9660/TODO
index 555d26a..7951ff8 100644
--- a/sys/isofs/cd9660/TODO
+++ b/sys/isofs/cd9660/TODO
@@ -1,4 +1,4 @@
-# $Id: TODO,v 1.4 1993/09/07 15:40:51 ws Exp $
+# $NetBSD: TODO,v 1.4 1994/07/19 11:34:48 mycroft Exp $
1) should understand "older", original High Sierra ("CDROM001") type
@@ -23,16 +23,6 @@
There is some preliminary stuff in there that (ab-)uses the mknod
system call, but this needs a writable filesystem
- 3) should be called cdfs, as there are other ISO file system soon possible
-
- Not yet. Probably we should make another file system when the ECMA draft
- is valid and do it. For doing Rock Ridge Support, I can use almost same
- code. So I just use the same file system interface...
-
- 4) should have file handles implemented for use with NFS, etc
-
- Yes. we have already this one, and I based it for this release.
-
5) should have name translation enabled by mount flag
Yes. we can disable the Rock Ridge Extension by follows option;
@@ -55,23 +45,3 @@
clean. As far as I know, if you export the cdrom by NFS, the client
can access the 8 bit clean (ie. Solaris Japanese with EUC code )
- 9) Access checks in isofs_access
-
- Not yet.
-
- 10) Support for generation numbers
-
- Yes. Default is to list only the last file (the one with the highest
- generation number). If you mount with -gen, all files are shown with
- their generation numbers. In both cases you can specify the generation
- number on opening files (if you happen to know it) or leave it off,
- when it will again find the last file.
-
- 11) Support for extended attributes
-
- Yes. Since this requires an extra block buffer for the attributes
- this must be enabled on mounting with the option -extattr.
-
-----------
-Last update July 19, '93 by Atsushi Murai. (amurai@spec.co.jp)
-Last update August 19, '93 by Wolfgang Solfrank. (ws@tools.de)
diff --git a/sys/isofs/cd9660/TODO.hibler b/sys/isofs/cd9660/TODO.hibler
index 3501aa2..660b268 100644
--- a/sys/isofs/cd9660/TODO.hibler
+++ b/sys/isofs/cd9660/TODO.hibler
@@ -3,20 +3,12 @@
them back. It looks like a seperate (but very similar) lookup routine
will be needed due to the associated file stuff.
-2. Make filesystem exportable. This comes for free if stacked with UFS.
- Otherwise, the ufs_export routines need to be elevated to vfs_* routines.
- [ DONE - hibler ]
-
-3. If it can't be merged with UFS, at least get them in sync. For example,
- it could use the same style hashing routines as in ufs/ufs_ihash.c
-
-4. It would be nice to be able to use the vfs_cluster code.
+2. It would be nice to be able to use the vfs_cluster code.
Unfortunately, if the logical block size is smaller than the page size,
it won't work. Also, if throughtput is relatively constant for any
block size (as it is for the HP drive--150kbs) then clustering may not
buy much (or may even hurt when vfs_cluster comes up with a large sync
cluster).
-5. Seems like there should be a "notrans" or some such mount option to show
- filenames as they really are without lower-casing, stripping of version
- numbers, etc. Does this make sense?
+3. Seems like there should be a "notrans" or some such mount option to show
+ filenames as they really are without lower-casing. Does this make sense?
diff --git a/sys/isofs/cd9660/cd9660_bmap.c b/sys/isofs/cd9660/cd9660_bmap.c
index 911eedf..3eeda7d 100644
--- a/sys/isofs/cd9660/cd9660_bmap.c
+++ b/sys/isofs/cd9660/cd9660_bmap.c
@@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)cd9660_bmap.c 8.3 (Berkeley) 1/23/94
+ * @(#)cd9660_bmap.c 8.4 (Berkeley) 12/5/94
*/
#include <sys/param.h>
@@ -65,7 +65,7 @@ cd9660_bmap(ap)
{
struct iso_node *ip = VTOI(ap->a_vp);
daddr_t lblkno = ap->a_bn;
- long bsize;
+ int bshift;
/*
* Check for underlying vnode requests and ensure that logical
@@ -79,8 +79,8 @@ cd9660_bmap(ap)
/*
* Compute the requested block number
*/
- bsize = ip->i_mnt->logical_block_size;
- *ap->a_bnp = (ip->iso_start + lblkno) * btodb(bsize);
+ bshift = ip->i_mnt->im_bshift;
+ *ap->a_bnp = (ip->iso_start + lblkno) << (bshift - DEV_BSHIFT);
/*
* Determine maximum number of readahead blocks following the
@@ -89,14 +89,14 @@ cd9660_bmap(ap)
if (ap->a_runp) {
int nblk;
- nblk = (ip->i_size - (lblkno + 1) * bsize) / bsize;
+ nblk = (ip->i_size >> bshift) - (lblkno + 1);
if (nblk <= 0)
*ap->a_runp = 0;
- else if (nblk >= MAXBSIZE/bsize)
- *ap->a_runp = MAXBSIZE/bsize - 1;
+ else if (nblk >= (MAXBSIZE >> bshift))
+ *ap->a_runp = (MAXBSIZE >> bshift) - 1;
else
*ap->a_runp = nblk;
}
- return 0;
+ return (0);
}
diff --git a/sys/isofs/cd9660/cd9660_lookup.c b/sys/isofs/cd9660/cd9660_lookup.c
index 62d1d3f..a045a8c 100644
--- a/sys/isofs/cd9660/cd9660_lookup.c
+++ b/sys/isofs/cd9660/cd9660_lookup.c
@@ -37,7 +37,7 @@
*
* from: @(#)ufs_lookup.c 7.33 (Berkeley) 5/19/91
*
- * @(#)cd9660_lookup.c 8.2 (Berkeley) 1/23/94
+ * @(#)cd9660_lookup.c 8.7 (Berkeley) 5/27/95
*/
#include <sys/param.h>
@@ -105,8 +105,9 @@ cd9660_lookup(ap)
int saveoffset; /* offset of last directory entry in dir */
int numdirpasses; /* strategy for directory search */
doff_t endsearch; /* offset to end directory search */
- struct iso_node *pdp; /* saved dp during symlink work */
- struct iso_node *tdp; /* returned by iget */
+ struct vnode *pdp; /* saved dp during symlink work */
+ struct vnode *tdp; /* returned by cd9660_vget_internal */
+ u_long bmask; /* block offset mask */
int lockparent; /* 1 => lockparent flag is set */
int wantparent; /* 1 => wantparent or lockparent flag */
int error;
@@ -122,6 +123,7 @@ cd9660_lookup(ap)
struct ucred *cred = cnp->cn_cred;
int flags = cnp->cn_flags;
int nameiop = cnp->cn_nameiop;
+ struct proc *p = cnp->cn_proc;
bp = NULL;
*vpp = NULL;
@@ -135,9 +137,12 @@ cd9660_lookup(ap)
* Check accessiblity of directory.
*/
if (vdp->v_type != VDIR)
- return (ENOTDIR);
+ return (ENOTDIR);
if (error = VOP_ACCESS(vdp, VEXEC, cred, cnp->cn_proc))
return (error);
+ if ((flags & ISLASTCN) && (vdp->v_mount->mnt_flag & MNT_RDONLY) &&
+ (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
+ return (EROFS);
/*
* We now have a segment name to search for, and a directory to search.
@@ -153,29 +158,29 @@ cd9660_lookup(ap)
return (error);
#ifdef PARANOID
if ((vdp->v_flag & VROOT) && (flags & ISDOTDOT))
- panic("ufs_lookup: .. through root");
+ panic("cd9660_lookup: .. through root");
#endif
/*
* Get the next vnode in the path.
* See comment below starting `Step through' for
* an explaination of the locking protocol.
*/
- pdp = dp;
+ pdp = vdp;
dp = VTOI(*vpp);
vdp = *vpp;
vpid = vdp->v_id;
- if (pdp == dp) {
+ if (pdp == vdp) {
VREF(vdp);
error = 0;
} else if (flags & ISDOTDOT) {
- ISO_IUNLOCK(pdp);
- error = vget(vdp, 1);
+ VOP_UNLOCK(pdp, 0, p);
+ error = vget(vdp, LK_EXCLUSIVE, p);
if (!error && lockparent && (flags & ISLASTCN))
- ISO_ILOCK(pdp);
+ error = vn_lock(pdp, LK_EXCLUSIVE, p);
} else {
- error = vget(vdp, 1);
+ error = vget(vdp, LK_EXCLUSIVE, p);
if (!lockparent || error || !(flags & ISLASTCN))
- ISO_IUNLOCK(pdp);
+ VOP_UNLOCK(pdp, 0, p);
}
/*
* Check that the capability number did not change
@@ -184,13 +189,14 @@ cd9660_lookup(ap)
if (!error) {
if (vpid == vdp->v_id)
return (0);
- iso_iput(dp);
- if (lockparent && pdp != dp && (flags & ISLASTCN))
- ISO_IUNLOCK(pdp);
+ vput(vdp);
+ if (lockparent && pdp != vdp && (flags & ISLASTCN))
+ VOP_UNLOCK(pdp, 0, p);
}
- ISO_ILOCK(pdp);
- dp = pdp;
- vdp = ITOV(dp);
+ if (error = vn_lock(pdp, LK_EXCLUSIVE, p))
+ return (error);
+ vdp = pdp;
+ dp = VTOI(pdp);
*vpp = NULL;
}
@@ -215,6 +221,7 @@ cd9660_lookup(ap)
* profiling time and hence has been removed in the interest
* of simplicity.
*/
+ bmask = imp->im_bmask;
if (nameiop != LOOKUP || dp->i_diroff == 0 ||
dp->i_diroff > dp->i_size) {
entryoffsetinblock = 0;
@@ -222,15 +229,13 @@ cd9660_lookup(ap)
numdirpasses = 1;
} else {
dp->i_offset = dp->i_diroff;
- entryoffsetinblock = iso_blkoff(imp, dp->i_offset);
- if (entryoffsetinblock != 0) {
- if (error = iso_blkatoff(dp, dp->i_offset, &bp))
+ if ((entryoffsetinblock = dp->i_offset & bmask) &&
+ (error = VOP_BLKATOFF(vdp, (off_t)dp->i_offset, NULL, &bp)))
return (error);
- }
numdirpasses = 2;
iso_nchstats.ncs_2passes++;
}
- endsearch = roundup(dp->i_size, imp->logical_block_size);
+ endsearch = dp->i_size;
searchloop:
while (dp->i_offset < endsearch) {
@@ -239,10 +244,11 @@ searchloop:
* read the next directory block.
* Release previous if it exists.
*/
- if (iso_blkoff(imp, dp->i_offset) == 0) {
+ if ((dp->i_offset & bmask) == 0) {
if (bp != NULL)
brelse(bp);
- if (error = iso_blkatoff(dp, dp->i_offset, &bp))
+ if (error =
+ VOP_BLKATOFF(vdp, (off_t)dp->i_offset, NULL, &bp))
return (error);
entryoffsetinblock = 0;
}
@@ -250,13 +256,13 @@ searchloop:
* Get pointer to next entry.
*/
ep = (struct iso_directory_record *)
- (bp->b_un.b_addr + entryoffsetinblock);
+ ((char *)bp->b_data + entryoffsetinblock);
- reclen = isonum_711 (ep->length);
+ reclen = isonum_711(ep->length);
if (reclen == 0) {
/* skip to next block, if any */
dp->i_offset =
- roundup(dp->i_offset, imp->logical_block_size);
+ (dp->i_offset & ~bmask) + imp->logical_block_size;
continue;
}
@@ -268,15 +274,15 @@ searchloop:
/* entries are not allowed to cross boundaries */
break;
- /*
- * Check for a name match.
- */
namelen = isonum_711(ep->name_len);
if (reclen < ISO_DIRECTORY_RECORD_SIZE + namelen)
/* illegal entry, stop */
break;
+ /*
+ * Check for a name match.
+ */
switch (imp->iso_ftype) {
default:
if ((!(isonum_711(ep->flags)&4)) == !assoc) {
@@ -287,10 +293,9 @@ searchloop:
&& ep->name[0] == ((flags & ISDOTDOT) ? 1 : 0)) {
/*
* Save directory entry's inode number and
- * reclen in ndp->ni_ufs area, and release
- * directory buffer.
+ * release directory buffer.
*/
- isodirino(&dp->i_ino,ep,imp);
+ dp->i_ino = isodirino(ep, imp);
goto found;
}
if (namelen != 1
@@ -299,7 +304,7 @@ searchloop:
} else if (!(res = isofncmp(name,len,
ep->name,namelen))) {
if (isonum_711(ep->flags)&2)
- isodirino(&ino,ep,imp);
+ ino = isodirino(ep, imp);
else
ino = dbtob(bp->b_blkno)
+ entryoffsetinblock;
@@ -316,7 +321,7 @@ searchloop:
break;
case ISO_FTYPE_RRIP:
if (isonum_711(ep->flags)&2)
- isodirino(&ino,ep,imp);
+ ino = isodirino(ep, imp);
else
ino = dbtob(bp->b_blkno) + entryoffsetinblock;
dp->i_ino = ino;
@@ -334,15 +339,17 @@ searchloop:
foundino:
dp->i_ino = ino;
if (saveoffset != dp->i_offset) {
- if (iso_lblkno(imp,dp->i_offset)
- != iso_lblkno(imp,saveoffset)) {
+ if (lblkno(imp, dp->i_offset) !=
+ lblkno(imp, saveoffset)) {
if (bp != NULL)
brelse(bp);
- if (error = iso_blkatoff(dp, saveoffset, &bp))
+ if (error = VOP_BLKATOFF(vdp,
+ (off_t)saveoffset, NULL, &bp))
return (error);
}
- ep = (struct iso_directory_record *)(bp->b_un.b_addr
- + iso_blkoff(imp,saveoffset));
+ entryoffsetinblock = saveoffset & bmask;
+ ep = (struct iso_directory_record *)
+ ((char *)bp->b_data + entryoffsetinblock);
dp->i_offset = saveoffset;
}
goto found;
@@ -360,20 +367,19 @@ notfound:
}
if (bp != NULL)
brelse(bp);
+
/*
* Insert name into cache (as non-existent) if appropriate.
*/
if (cnp->cn_flags & MAKEENTRY)
cache_enter(vdp, *vpp, cnp);
if (nameiop == CREATE || nameiop == RENAME)
- return (EJUSTRETURN);
+ return (EROFS);
return (ENOENT);
found:
if (numdirpasses == 2)
iso_nchstats.ncs_pass2++;
- if (bp != NULL)
- brelse(bp);
/*
* Found component in pathname.
@@ -402,31 +408,39 @@ found:
* work if the file system has any hard links other than ".."
* that point backwards in the directory structure.
*/
- pdp = dp;
+ pdp = vdp;
/*
* If ino is different from dp->i_ino,
* it's a relocated directory.
*/
if (flags & ISDOTDOT) {
- ISO_IUNLOCK(pdp); /* race to get the inode */
- if (error = iso_iget(dp,dp->i_ino,
- dp->i_ino != ino,
- &tdp,ep)) {
- ISO_ILOCK(pdp);
+ VOP_UNLOCK(pdp, 0, p); /* race to get the inode */
+ error = cd9660_vget_internal(vdp->v_mount, dp->i_ino, &tdp,
+ dp->i_ino != ino, ep);
+ brelse(bp);
+ if (error) {
+ vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, p);
+ return (error);
+ }
+ if (lockparent && (flags & ISLASTCN) &&
+ (error = vn_lock(pdp, LK_EXCLUSIVE, p))) {
+ vput(tdp);
return (error);
}
- if (lockparent && (flags & ISLASTCN))
- ISO_ILOCK(pdp);
- *vpp = ITOV(tdp);
+ *vpp = tdp;
} else if (dp->i_number == dp->i_ino) {
+ brelse(bp);
VREF(vdp); /* we want ourself, ie "." */
*vpp = vdp;
} else {
- if (error = iso_iget(dp,dp->i_ino,dp->i_ino!=ino,&tdp,ep))
+ error = cd9660_vget_internal(vdp->v_mount, dp->i_ino, &tdp,
+ dp->i_ino != ino, ep);
+ brelse(bp);
+ if (error)
return (error);
if (!lockparent || !(flags & ISLASTCN))
- ISO_IUNLOCK(pdp);
- *vpp = ITOV(tdp);
+ VOP_UNLOCK(pdp, 0, p);
+ *vpp = tdp;
}
/*
@@ -438,28 +452,37 @@ found:
}
/*
- * Return buffer with contents of block "offset"
- * from the beginning of directory "ip". If "res"
- * is non-zero, fill it in with a pointer to the
+ * Return buffer with the contents of block "offset" from the beginning of
+ * directory "ip". If "res" is non-zero, fill it in with a pointer to the
* remaining space in the directory.
*/
-iso_blkatoff(ip, offset, bpp)
- struct iso_node *ip;
- doff_t offset;
- struct buf **bpp;
+int
+cd9660_blkatoff(ap)
+ struct vop_blkatoff_args /* {
+ struct vnode *a_vp;
+ off_t a_offset;
+ char **a_res;
+ struct buf **a_bpp;
+ } */ *ap;
{
- register struct iso_mnt *imp = ip->i_mnt;
- daddr_t lbn = iso_lblkno(imp,offset);
- int bsize = iso_blksize(imp,ip,lbn);
+ struct iso_node *ip;
+ register struct iso_mnt *imp;
struct buf *bp;
- int error;
+ daddr_t lbn;
+ int bsize, error;
+
+ ip = VTOI(ap->a_vp);
+ imp = ip->i_mnt;
+ lbn = lblkno(imp, ap->a_offset);
+ bsize = blksize(imp, ip, lbn);
- if (error = bread(ITOV(ip),lbn,bsize,NOCRED,&bp)) {
+ if (error = bread(ap->a_vp, lbn, bsize, NOCRED, &bp)) {
brelse(bp);
- *bpp = 0;
+ *ap->a_bpp = NULL;
return (error);
}
- *bpp = bp;
-
+ if (ap->a_res)
+ *ap->a_res = (char *)bp->b_data + blkoff(imp, ap->a_offset);
+ *ap->a_bpp = bp;
return (0);
}
diff --git a/sys/isofs/cd9660/cd9660_mount.h b/sys/isofs/cd9660/cd9660_mount.h
new file mode 100644
index 0000000..ea6ecaa
--- /dev/null
+++ b/sys/isofs/cd9660/cd9660_mount.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1995
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley
+ * by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
+ * Support code is derived from software contributed to Berkeley
+ * by Atsushi Murai (amurai@spec.co.jp).
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)cd9660_mount.h 8.1 (Berkeley) 5/24/95
+ */
+
+/*
+ * Arguments to mount ISO 9660 filesystems.
+ */
+struct iso_args {
+ char *fspec; /* block special device to mount */
+ struct export_args export; /* network export info */
+ int flags; /* mounting flags, see below */
+};
+#define ISOFSMNT_NORRIP 0x00000001 /* disable Rock Ridge Ext.*/
+#define ISOFSMNT_GENS 0x00000002 /* enable generation numbers */
+#define ISOFSMNT_EXTATT 0x00000004 /* enable extended attributes */
diff --git a/sys/isofs/cd9660/cd9660_node.c b/sys/isofs/cd9660/cd9660_node.c
index d83a7a6..056e7d2 100644
--- a/sys/isofs/cd9660/cd9660_node.c
+++ b/sys/isofs/cd9660/cd9660_node.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1982, 1986, 1989, 1994
+ * Copyright (c) 1982, 1986, 1989, 1994, 1995
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley
@@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)cd9660_node.c 8.2 (Berkeley) 1/23/94
+ * @(#)cd9660_node.c 8.8 (Berkeley) 5/22/95
*/
#include <sys/param.h>
@@ -51,32 +51,21 @@
#include <isofs/cd9660/iso.h>
#include <isofs/cd9660/cd9660_node.h>
+#include <isofs/cd9660/cd9660_mount.h>
#include <isofs/cd9660/iso_rrip.h>
-#define INOHSZ 512
-#if ((INOHSZ&(INOHSZ-1)) == 0)
-#define INOHASH(dev,ino) (((dev)+((ino)>>12))&(INOHSZ-1))
-#else
-#define INOHASH(dev,ino) (((unsigned)((dev)+((ino)>>12)))%INOHSZ)
-#endif
-
-union iso_ihead {
- union iso_ihead *ih_head[2];
- struct iso_node *ih_chain[2];
-} iso_ihead[INOHSZ];
-
-#ifdef ISODEVMAP
-#define DNOHSZ 64
-#if ((DNOHSZ&(DNOHSZ-1)) == 0)
-#define DNOHASH(dev,ino) (((dev)+((ino)>>12))&(DNOHSZ-1))
-#else
-#define DNOHASH(dev,ino) (((unsigned)((dev)+((ino)>>12)))%DNOHSZ)
-#endif
+/*
+ * Structures associated with iso_node caching.
+ */
+struct iso_node **isohashtbl;
+u_long isohash;
+#define INOHASH(device, inum) (((device) + ((inum)>>12)) & isohash)
+struct simplelock cd9660_ihash_slock;
-union iso_dhead {
- union iso_dhead *dh_head[2];
- struct iso_dnode *dh_chain[2];
-} iso_dhead[DNOHSZ];
+#ifdef ISODEVMAP
+struct iso_node **idvhashtbl;
+u_long idvhash;
+#define DNOHASH(device, inum) (((device) + ((inum)>>12)) & idvhash)
#endif
int prtactive; /* 1 => print out reclaim of active vnodes */
@@ -84,72 +73,67 @@ int prtactive; /* 1 => print out reclaim of active vnodes */
/*
* Initialize hash links for inodes and dnodes.
*/
-cd9660_init()
+cd9660_init(vfsp)
+ struct vfsconf *vfsp;
{
- register int i;
- register union iso_ihead *ih = iso_ihead;
-#ifdef ISODEVMAP
- register union iso_dhead *dh = iso_dhead;
-#endif
- for (i = INOHSZ; --i >= 0; ih++) {
- ih->ih_head[0] = ih;
- ih->ih_head[1] = ih;
- }
-#ifdef ISODEVMAP
- for (i = DNOHSZ; --i >= 0; dh++) {
- dh->dh_head[0] = dh;
- dh->dh_head[1] = dh;
- }
+ isohashtbl = hashinit(desiredvnodes, M_ISOFSMNT, &isohash);
+ simple_lock_init(&cd9660_ihash_slock);
+#ifdef ISODEVMAP
+ idvhashtbl = hashinit(desiredvnodes / 8, M_ISOFSMNT, &idvhash);
#endif
}
-#ifdef ISODEVMAP
+#ifdef ISODEVMAP
/*
* Enter a new node into the device hash list
*/
struct iso_dnode *
-iso_dmap(dev,ino,create)
- dev_t dev;
- ino_t ino;
+iso_dmap(device, inum, create)
+ dev_t device;
+ ino_t inum;
int create;
{
- struct iso_dnode *dp;
- union iso_dhead *dh;
-
- dh = &iso_dhead[DNOHASH(dev, ino)];
- for (dp = dh->dh_chain[0];
- dp != (struct iso_dnode *)dh;
- dp = dp->d_forw)
- if (ino == dp->i_number && dev == dp->i_dev)
- return dp;
+ register struct iso_dnode **dpp, *dp, *dq;
+
+ dpp = &idvhashtbl[DNOHASH(device, inum)];
+ for (dp = *dpp;; dp = dp->d_next) {
+ if (dp == NULL)
+ return (NULL);
+ if (inum == dp->i_number && device == dp->i_dev)
+ return (dp);
if (!create)
- return (struct iso_dnode *)0;
+ return (NULL);
- MALLOC(dp,struct iso_dnode *,sizeof(struct iso_dnode),M_CACHE,M_WAITOK);
+ MALLOC(dp, struct iso_dnode *, sizeof(struct iso_dnode), M_CACHE,
+ M_WAITOK);
dp->i_dev = dev;
dp->i_number = ino;
- insque(dp,dh);
-
- return dp;
+
+ if (dq = *dpp)
+ dq->d_prev = dp->d_next;
+ dp->d_next = dq;
+ dp->d_prev = dpp;
+ *dpp = dp;
+
+ return (dp);
}
void
-iso_dunmap(dev)
- dev_t dev;
+iso_dunmap(device)
+ dev_t device;
{
- struct iso_dnode *dp, *dq;
- union iso_dhead *dh;
+ struct iso_dnode **dpp, *dp, *dq;
- for (dh = iso_dhead; dh < iso_dhead + DNOHSZ; dh++) {
- for (dp = dh->dh_chain[0];
- dp != (struct iso_dnode *)dh;
- dp = dq) {
- dq = dp->d_forw;
- if (dev == dp->i_dev) {
- remque(dp);
- FREE(dp,M_CACHE);
+ for (dpp = idvhashtbl; dpp <= idvhashtbl + idvhash; dpp++) {
+ for (dp = *dpp; dp != NULL; dp = dq)
+ dq = dp->d_next;
+ if (device == dp->i_dev) {
+ if (dq)
+ dq->d_prev = dp->d_prev;
+ *dp->d_prev = dq;
+ FREE(dp, M_CACHE);
}
}
}
@@ -157,195 +141,74 @@ iso_dunmap(dev)
#endif
/*
- * Look up a ISOFS dinode number to find its incore vnode.
- * If it is not in core, read it in from the specified device.
- * If it is in core, wait for the lock bit to clear, then
- * return the inode locked. Detection and handling of mount
- * points must be done by the calling routine.
+ * Use the device/inum pair to find the incore inode, and return a pointer
+ * to it. If it is in core, but locked, wait for it.
*/
-iso_iget(xp, ino, relocated, ipp, isodir)
- struct iso_node *xp;
- ino_t ino;
- struct iso_node **ipp;
- struct iso_directory_record *isodir;
+struct vnode *
+cd9660_ihashget(dev, inum)
+ dev_t dev;
+ ino_t inum;
{
- dev_t dev = xp->i_dev;
- struct mount *mntp = ITOV(xp)->v_mount;
- register struct iso_node *ip, *iq;
- register struct vnode *vp;
- register struct iso_dnode *dp;
- struct vnode *nvp;
- struct buf *bp = NULL, *bp2 = NULL;
- union iso_ihead *ih;
- union iso_dhead *dh;
- int i, error, result;
- struct iso_mnt *imp;
- ino_t defino;
-
- ih = &iso_ihead[INOHASH(dev, ino)];
+ struct proc *p = curproc; /* XXX */
+ struct iso_node *ip;
+ struct vnode *vp;
+
loop:
- for (ip = ih->ih_chain[0];
- ip != (struct iso_node *)ih;
- ip = ip->i_forw) {
- if (ino != ip->i_number || dev != ip->i_dev)
- continue;
- if ((ip->i_flag&ILOCKED) != 0) {
- ip->i_flag |= IWANT;
- sleep((caddr_t)ip, PINOD);
- goto loop;
+ simple_lock(&cd9660_ihash_slock);
+ for (ip = isohashtbl[INOHASH(dev, inum)]; ip; ip = ip->i_next) {
+ if (inum == ip->i_number && dev == ip->i_dev) {
+ vp = ITOV(ip);
+ simple_lock(&vp->v_interlock);
+ simple_unlock(&cd9660_ihash_slock);
+ if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p))
+ goto loop;
+ return (vp);
}
- if (vget(ITOV(ip), 1))
- goto loop;
- *ipp = ip;
- return 0;
- }
- /*
- * Allocate a new vnode/iso_node.
- */
- if (error = getnewvnode(VT_ISOFS, mntp, cd9660_vnodeop_p, &nvp)) {
- *ipp = 0;
- return error;
}
- MALLOC(ip, struct iso_node *, sizeof(struct iso_node),
- M_ISOFSNODE, M_WAITOK);
- bzero((caddr_t)ip, sizeof(struct iso_node));
- nvp->v_data = ip;
- ip->i_vnode = nvp;
- ip->i_flag = 0;
- ip->i_devvp = 0;
- ip->i_diroff = 0;
- ip->i_lockf = 0;
-
- /*
- * Put it onto its hash chain and lock it so that other requests for
- * this inode will block if they arrive while we are sleeping waiting
- * for old data structures to be purged or for the contents of the
- * disk portion of this inode to be read.
- */
- ip->i_dev = dev;
- ip->i_number = ino;
- insque(ip, ih);
- ISO_ILOCK(ip);
+ simple_unlock(&cd9660_ihash_slock);
+ return (NULL);
+}
- imp = VFSTOISOFS (mntp);
- ip->i_mnt = imp;
- ip->i_devvp = imp->im_devvp;
- VREF(ip->i_devvp);
-
- if (relocated) {
- /*
- * On relocated directories we must
- * read the `.' entry out of a dir.
- */
- ip->iso_start = ino >> imp->im_bshift;
- if (error = iso_blkatoff(ip,0,&bp)) {
- vrele(ip->i_devvp);
- remque(ip);
- ip->i_forw = ip;
- ip->i_back = ip;
- iso_iput(ip);
- *ipp = 0;
- return error;
- }
- isodir = (struct iso_directory_record *)bp->b_un.b_addr;
- }
-
- ip->iso_extent = isonum_733(isodir->extent);
- ip->i_size = isonum_733(isodir->size);
- ip->iso_start = isonum_711(isodir->ext_attr_length) + ip->iso_extent;
-
- vp = ITOV(ip);
-
- /*
- * Setup time stamp, attribute
- */
- vp->v_type = VNON;
- switch (imp->iso_ftype) {
- default: /* ISO_FTYPE_9660 */
- if ((imp->im_flags&ISOFSMNT_EXTATT)
- && isonum_711(isodir->ext_attr_length))
- iso_blkatoff(ip,-isonum_711(isodir->ext_attr_length),
- &bp2);
- cd9660_defattr(isodir,ip,bp2 );
- cd9660_deftstamp(isodir,ip,bp2 );
- break;
- case ISO_FTYPE_RRIP:
- result = cd9660_rrip_analyze(isodir,ip,imp);
- break;
- }
- if (bp2)
- brelse(bp2);
- if (bp)
- brelse(bp);
-
- /*
- * Initialize the associated vnode
- */
- vp->v_type = IFTOVT(ip->inode.iso_mode);
-
- if ( vp->v_type == VFIFO ) {
-#ifdef FIFO
- extern int (**cd9660_fifoop_p)();
- vp->v_op = cd9660_fifoop_p;
-#else
- iso_iput(ip);
- *ipp = 0;
- return EOPNOTSUPP;
-#endif /* FIFO */
- } else if ( vp->v_type == VCHR || vp->v_type == VBLK ) {
- extern int (**cd9660_specop_p)();
+/*
+ * Insert the inode into the hash table, and return it locked.
+ */
+void
+cd9660_ihashins(ip)
+ struct iso_node *ip;
+{
+ struct proc *p = curproc; /* XXX */
+ struct iso_node **ipp, *iq;
- /*
- * if device, look at device number table for translation
- */
-#ifdef ISODEVMAP
- if (dp = iso_dmap(dev,ino,0))
- ip->inode.iso_rdev = dp->d_dev;
-#endif
- vp->v_op = cd9660_specop_p;
- if (nvp = checkalias(vp, ip->inode.iso_rdev, mntp)) {
- /*
- * Reinitialize aliased inode.
- */
- vp = nvp;
- iq = VTOI(vp);
- iq->i_vnode = vp;
- iq->i_flag = 0;
- ISO_ILOCK(iq);
- iq->i_dev = dev;
- iq->i_number = ino;
- iq->i_mnt = ip->i_mnt;
- bcopy(&ip->iso_extent,&iq->iso_extent,
- (char *)(ip + 1) - (char *)&ip->iso_extent);
- insque(iq, ih);
- /*
- * Discard unneeded vnode
- * (This introduces the need of INACTIVE modification)
- */
- ip->inode.iso_mode = 0;
- iso_iput(ip);
- ip = iq;
- }
- }
-
- if (ip->iso_extent == imp->root_extent)
- vp->v_flag |= VROOT;
-
+ simple_lock(&cd9660_ihash_slock);
+ ipp = &isohashtbl[INOHASH(ip->i_dev, ip->i_number)];
+ if (iq = *ipp)
+ iq->i_prev = &ip->i_next;
+ ip->i_next = iq;
+ ip->i_prev = ipp;
*ipp = ip;
- return 0;
+ simple_unlock(&cd9660_ihash_slock);
+
+ lockmgr(&ip->i_lock, LK_EXCLUSIVE, (struct simplelock *)0, p);
}
/*
- * Unlock and decrement the reference count of an inode structure.
+ * Remove the inode from the hash table.
*/
-iso_iput(ip)
+void
+cd9660_ihashrem(ip)
register struct iso_node *ip;
{
-
- if ((ip->i_flag & ILOCKED) == 0)
- panic("iso_iput");
- ISO_IUNLOCK(ip);
- vrele(ITOV(ip));
+ register struct iso_node *iq;
+
+ simple_lock(&cd9660_ihash_slock);
+ if (iq = ip->i_next)
+ iq->i_prev = ip->i_prev;
+ *ip->i_prev = iq;
+#ifdef DIAGNOSTIC
+ ip->i_next = NULL;
+ ip->i_prev = NULL;
+#endif
+ simple_unlock(&cd9660_ihash_slock);
}
/*
@@ -356,9 +219,11 @@ int
cd9660_inactive(ap)
struct vop_inactive_args /* {
struct vnode *a_vp;
+ struct proc *a_p;
} */ *ap;
{
struct vnode *vp = ap->a_vp;
+ struct proc *p = ap->a_p;
register struct iso_node *ip = VTOI(vp);
int mode, error = 0;
@@ -366,12 +231,13 @@ cd9660_inactive(ap)
vprint("cd9660_inactive: pushing active", vp);
ip->i_flag = 0;
+ VOP_UNLOCK(vp, 0, p);
/*
* If we are done with the inode, reclaim it
* so that it can be reused immediately.
*/
- if (vp->v_usecount == 0 && ip->inode.iso_mode == 0)
- vgone(vp);
+ if (ip->inode.iso_mode == 0)
+ vrecycle(vp, (struct simplelock *)0, p);
return error;
}
@@ -382,6 +248,7 @@ int
cd9660_reclaim(ap)
struct vop_reclaim_args /* {
struct vnode *a_vp;
+ struct proc *a_p;
} */ *ap;
{
register struct vnode *vp = ap->a_vp;
@@ -393,9 +260,7 @@ cd9660_reclaim(ap)
/*
* Remove the inode from its hash chain.
*/
- remque(ip);
- ip->i_forw = ip;
- ip->i_back = ip;
+ cd9660_ihashrem(ip);
/*
* Purge old data structures associated with the inode.
*/
@@ -406,50 +271,14 @@ cd9660_reclaim(ap)
}
FREE(vp->v_data, M_ISOFSNODE);
vp->v_data = NULL;
- return 0;
-}
-
-/*
- * Lock an inode. If its already locked, set the WANT bit and sleep.
- */
-iso_ilock(ip)
- register struct iso_node *ip;
-{
-
- while (ip->i_flag & ILOCKED) {
- ip->i_flag |= IWANT;
- if (ip->i_spare0 == curproc->p_pid)
- panic("locking against myself");
- ip->i_spare1 = curproc->p_pid;
- (void) sleep((caddr_t)ip, PINOD);
- }
- ip->i_spare1 = 0;
- ip->i_spare0 = curproc->p_pid;
- ip->i_flag |= ILOCKED;
-}
-
-/*
- * Unlock an inode. If WANT bit is on, wakeup.
- */
-iso_iunlock(ip)
- register struct iso_node *ip;
-{
-
- if ((ip->i_flag & ILOCKED) == 0)
- vprint("iso_iunlock: unlocked inode", ITOV(ip));
- ip->i_spare0 = 0;
- ip->i_flag &= ~ILOCKED;
- if (ip->i_flag&IWANT) {
- ip->i_flag &= ~IWANT;
- wakeup((caddr_t)ip);
- }
+ return (0);
}
/*
* File attributes
*/
void
-cd9660_defattr(isodir,inop,bp)
+cd9660_defattr(isodir, inop, bp)
struct iso_directory_record *isodir;
struct iso_node *inop;
struct buf *bp;
@@ -471,13 +300,14 @@ cd9660_defattr(isodir,inop,bp)
inop->inode.iso_links = 1;
}
if (!bp
- && ((imp = inop->i_mnt)->im_flags&ISOFSMNT_EXTATT)
+ && ((imp = inop->i_mnt)->im_flags & ISOFSMNT_EXTATT)
&& (off = isonum_711(isodir->ext_attr_length))) {
- iso_blkatoff(inop,-off * imp->logical_block_size,&bp2);
+ VOP_BLKATOFF(ITOV(inop), (off_t)-(off << imp->im_bshift), NULL,
+ &bp2);
bp = bp2;
}
if (bp) {
- ap = (struct iso_extended_attributes *)bp->b_un.b_addr;
+ ap = (struct iso_extended_attributes *)bp->b_data;
if (isonum_711(ap->version) == 1) {
if (!(ap->perm[0]&0x40))
@@ -521,13 +351,14 @@ cd9660_deftstamp(isodir,inop,bp)
int off;
if (!bp
- && ((imp = inop->i_mnt)->im_flags&ISOFSMNT_EXTATT)
+ && ((imp = inop->i_mnt)->im_flags & ISOFSMNT_EXTATT)
&& (off = isonum_711(isodir->ext_attr_length))) {
- iso_blkatoff(inop,-off * imp->logical_block_size,&bp2);
+ VOP_BLKATOFF(ITOV(inop), (off_t)-(off << imp->im_bshift), NULL,
+ &bp2);
bp = bp2;
}
if (bp) {
- ap = (struct iso_extended_attributes *)bp->b_un.b_addr;
+ ap = (struct iso_extended_attributes *)bp->b_data;
if (isonum_711(ap->version) == 1) {
if (!cd9660_tstamp_conv17(ap->ftime,&inop->inode.iso_atime))
@@ -550,8 +381,8 @@ cd9660_deftstamp(isodir,inop,bp)
int
cd9660_tstamp_conv7(pi,pu)
-char *pi;
-struct timeval *pu;
+ u_char *pi;
+ struct timespec *pu;
{
int i;
int crtime, days;
@@ -566,8 +397,8 @@ struct timeval *pu;
tz = pi[6];
if (y < 1970) {
- pu->tv_sec = 0;
- pu->tv_usec = 0;
+ pu->ts_sec = 0;
+ pu->ts_nsec = 0;
return 0;
} else {
#ifdef ORIGINAL
@@ -585,19 +416,19 @@ struct timeval *pu;
/* timezone offset is unreliable on some disks */
if (-48 <= tz && tz <= 52)
- crtime += tz * 15 * 60;
+ crtime -= tz * 15 * 60;
}
- pu->tv_sec = crtime;
- pu->tv_usec = 0;
+ pu->ts_sec = crtime;
+ pu->ts_nsec = 0;
return 1;
}
-static unsigned
+static u_int
cd9660_chars2ui(begin,len)
- unsigned char *begin;
+ u_char *begin;
int len;
{
- unsigned rc;
+ u_int rc;
for (rc = 0; --len >= 0;) {
rc *= 10;
@@ -608,10 +439,10 @@ cd9660_chars2ui(begin,len)
int
cd9660_tstamp_conv17(pi,pu)
- unsigned char *pi;
- struct timeval *pu;
+ u_char *pi;
+ struct timespec *pu;
{
- unsigned char buf[7];
+ u_char buf[7];
/* year:"0001"-"9999" -> -1900 */
buf[0] = cd9660_chars2ui(pi,4) - 1900;
@@ -637,12 +468,14 @@ cd9660_tstamp_conv17(pi,pu)
return cd9660_tstamp_conv7(buf,pu);
}
-void
-isodirino(inump,isodir,imp)
- ino_t *inump;
+ino_t
+isodirino(isodir, imp)
struct iso_directory_record *isodir;
struct iso_mnt *imp;
{
- *inump = (isonum_733(isodir->extent) + isonum_711(isodir->ext_attr_length))
- * imp->logical_block_size;
+ ino_t ino;
+
+ ino = (isonum_733(isodir->extent) + isonum_711(isodir->ext_attr_length))
+ << imp->im_bshift;
+ return (ino);
}
diff --git a/sys/isofs/cd9660/cd9660_node.h b/sys/isofs/cd9660/cd9660_node.h
index 45de67f..ad36292 100644
--- a/sys/isofs/cd9660/cd9660_node.h
+++ b/sys/isofs/cd9660/cd9660_node.h
@@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)cd9660_node.h 8.2 (Berkeley) 1/23/94
+ * @(#)cd9660_node.h 8.6 (Berkeley) 5/14/95
*/
/*
@@ -58,22 +58,20 @@ typedef struct {
dev_t iso_rdev; /* Major/Minor number for special */
} ISO_RRIP_INODE;
-#ifdef ISODEVMAP
+#ifdef ISODEVMAP
/*
* FOr device# (major,minor) translation table
*/
struct iso_dnode {
- struct iso_dnode *d_chain[2]; /* hash chain, MUST be first */
+ struct iso_dnode *d_next, **d_prev; /* hash chain */
dev_t i_dev; /* device where dnode resides */
ino_t i_number; /* the identity of the inode */
dev_t d_dev; /* device # for translation */
};
-#define d_forw d_chain[0]
-#define d_back d_chain[1]
#endif
struct iso_node {
- struct iso_node *i_chain[2]; /* hash chain, MUST be first */
+ struct iso_node *i_next, **i_prev; /* hash chain */
struct vnode *i_vnode; /* vnode associated with this inode */
struct vnode *i_devvp; /* vnode for block I/O */
u_long i_flag; /* see below */
@@ -86,8 +84,7 @@ struct iso_node {
doff_t i_diroff; /* offset in dir, where we found last entry */
doff_t i_offset; /* offset of free space in directory */
ino_t i_ino; /* inode number of found directory */
- long i_spare0;
- long i_spare1;
+ struct lock i_lock; /* node lock */
long iso_extent; /* extent of file */
long i_size;
@@ -100,16 +97,11 @@ struct iso_node {
#define i_back i_chain[1]
/* flags */
-#define ILOCKED 0x0001 /* inode is locked */
-#define IWANT 0x0002 /* some process waiting on lock */
-#define IACC 0x0020 /* inode access time to be updated */
+#define IN_ACCESS 0x0020 /* inode access time to be updated */
#define VTOI(vp) ((struct iso_node *)(vp)->v_data)
#define ITOV(ip) ((ip)->i_vnode)
-#define ISO_ILOCK(ip) iso_ilock(ip)
-#define ISO_IUNLOCK(ip) iso_iunlock(ip)
-
/*
* Prototypes for ISOFS vnode operations
*/
@@ -133,10 +125,20 @@ int cd9660_unlock __P((struct vop_unlock_args *));
int cd9660_strategy __P((struct vop_strategy_args *));
int cd9660_print __P((struct vop_print_args *));
int cd9660_islocked __P((struct vop_islocked_args *));
+int cd9660_pathconf __P((struct vop_pathconf_args *));
+int cd9660_blkatoff __P((struct vop_blkatoff_args *));
+#define cd9660_revoke vop_revoke
+
void cd9660_defattr __P((struct iso_directory_record *,
struct iso_node *, struct buf *));
void cd9660_deftstamp __P((struct iso_directory_record *,
struct iso_node *, struct buf *));
+struct vnode *cd9660_ihashget __P((dev_t, ino_t));
+void cd9660_ihashins __P((struct iso_node *));
+void cd9660_ihashrem __P((struct iso_node *));
+int cd9660_tstamp_conv7 __P((u_char *, struct timespec *));
+int cd9660_tstamp_conv17 __P((u_char *, struct timespec *));
+ino_t isodirino __P((struct iso_directory_record *, struct iso_mnt *));
#ifdef ISODEVMAP
struct iso_dnode *iso_dmap __P((dev_t, ino_t, int));
void iso_dunmap __P((dev_t));
diff --git a/sys/isofs/cd9660/cd9660_rrip.c b/sys/isofs/cd9660/cd9660_rrip.c
index 0923fa0..cd7292c 100644
--- a/sys/isofs/cd9660/cd9660_rrip.c
+++ b/sys/isofs/cd9660/cd9660_rrip.c
@@ -35,10 +35,11 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)cd9660_rrip.c 8.2 (Berkeley) 1/23/94
+ * @(#)cd9660_rrip.c 8.6 (Berkeley) 12/5/94
*/
#include <sys/param.h>
+#include <sys/systm.h>
#include <sys/namei.h>
#include <sys/buf.h>
#include <sys/file.h>
@@ -63,10 +64,10 @@ cd9660_rrip_attr(p,ana)
ISO_RRIP_ATTR *p;
ISO_RRIP_ANALYZE *ana;
{
- ana->inop->inode.iso_mode = isonum_731(p->mode_l);
- ana->inop->inode.iso_uid = (uid_t)isonum_731(p->uid_l);
- ana->inop->inode.iso_gid = (gid_t)isonum_731(p->gid_l);
- ana->inop->inode.iso_links = isonum_731(p->links_l);
+ ana->inop->inode.iso_mode = isonum_733(p->mode);
+ ana->inop->inode.iso_uid = isonum_733(p->uid);
+ ana->inop->inode.iso_gid = isonum_733(p->gid);
+ ana->inop->inode.iso_links = isonum_733(p->links);
ana->fields &= ~ISO_SUSP_ATTR;
return ISO_SUSP_ATTR;
}
@@ -311,7 +312,7 @@ cd9660_rrip_tstamp(p,ana)
ISO_RRIP_TSTAMP *p;
ISO_RRIP_ANALYZE *ana;
{
- unsigned char *ptime;
+ u_char *ptime;
ptime = p->time;
@@ -324,7 +325,7 @@ cd9660_rrip_tstamp(p,ana)
cd9660_tstamp_conv7(ptime,&ana->inop->inode.iso_mtime);
ptime += 7;
} else
- bzero(&ana->inop->inode.iso_mtime,sizeof(struct timeval));
+ bzero(&ana->inop->inode.iso_mtime,sizeof(struct timespec));
if (*p->flags&ISO_SUSP_TSTAMP_ACCESS) {
cd9660_tstamp_conv7(ptime,&ana->inop->inode.iso_atime);
@@ -345,7 +346,7 @@ cd9660_rrip_tstamp(p,ana)
cd9660_tstamp_conv17(ptime,&ana->inop->inode.iso_mtime);
ptime += 17;
} else
- bzero(&ana->inop->inode.iso_mtime,sizeof(struct timeval));
+ bzero(&ana->inop->inode.iso_mtime,sizeof(struct timespec));
if (*p->flags&ISO_SUSP_TSTAMP_ACCESS) {
cd9660_tstamp_conv17(ptime,&ana->inop->inode.iso_atime);
@@ -379,16 +380,15 @@ cd9660_rrip_device(p,ana)
ISO_RRIP_DEVICE *p;
ISO_RRIP_ANALYZE *ana;
{
- unsigned high, low;
+ u_int high, low;
- high = isonum_733(p->dev_t_high_l);
- low = isonum_733(p->dev_t_low_l);
+ high = isonum_733(p->dev_t_high);
+ low = isonum_733(p->dev_t_low);
- if ( high == 0 ) {
- ana->inop->inode.iso_rdev = makedev( major(low), minor(low) );
- } else {
- ana->inop->inode.iso_rdev = makedev( high, minor(low) );
- }
+ if (high == 0)
+ ana->inop->inode.iso_rdev = makedev(major(low), minor(low));
+ else
+ ana->inop->inode.iso_rdev = makedev(high, minor(low));
ana->fields &= ~ISO_SUSP_DEVICE;
return ISO_SUSP_DEVICE;
}
@@ -431,8 +431,6 @@ cd9660_rrip_stop(p,ana)
ISO_SUSP_HEADER *p;
ISO_RRIP_ANALYZE *ana;
{
- /* stop analyzing */
- ana->fields = 0;
return ISO_SUSP_STOP;
}
@@ -509,6 +507,13 @@ cd9660_rrip_loop(isodir,ana,table)
if (!ana->fields)
break;
}
+ if (result&ISO_SUSP_STOP) {
+ result &= ~ISO_SUSP_STOP;
+ break;
+ }
+ /* plausibility check */
+ if (isonum_711(phead->length) < sizeof(*phead))
+ break;
/*
* move to next SUSP
* Hopefully this works with newer versions, too
@@ -516,15 +521,16 @@ cd9660_rrip_loop(isodir,ana,table)
phead = (ISO_SUSP_HEADER *)((char *)phead + isonum_711(phead->length));
}
- if ( ana->fields && ana->iso_ce_len ) {
+ if (ana->fields && ana->iso_ce_len) {
if (ana->iso_ce_blk >= ana->imp->volume_space_size
|| ana->iso_ce_off + ana->iso_ce_len > ana->imp->logical_block_size
|| bread(ana->imp->im_devvp,
- ana->iso_ce_blk * ana->imp->logical_block_size / DEV_BSIZE,
- ana->imp->logical_block_size,NOCRED,&bp))
+ ana->iso_ce_blk <<
+ (ana->imp->im_bshift - DEV_BSHIFT),
+ ana->imp->logical_block_size, NOCRED, &bp))
/* what to do now? */
break;
- phead = (ISO_SUSP_HEADER *)(bp->b_un.b_addr + ana->iso_ce_off);
+ phead = (ISO_SUSP_HEADER *)(bp->b_data + ana->iso_ce_off);
pend = (ISO_SUSP_HEADER *) ((char *)phead + ana->iso_ce_len);
} else
break;
@@ -533,7 +539,7 @@ cd9660_rrip_loop(isodir,ana,table)
brelse(bp);
/*
* If we don't find the Basic SUSP stuffs, just set default value
- * ( attribute/time stamp )
+ * (attribute/time stamp)
*/
for (ptable = table; ptable->func2; ptable++)
if (!(ptable->result&result))
@@ -542,6 +548,9 @@ cd9660_rrip_loop(isodir,ana,table)
return result;
}
+/*
+ * Get Attributes.
+ */
static RRIP_TABLE rrip_table_analyze[] = {
{ "PX", cd9660_rrip_attr, cd9660_rrip_defattr, ISO_SUSP_ATTR },
{ "TF", cd9660_rrip_tstamp, cd9660_rrip_deftstamp, ISO_SUSP_TSTAMP },
@@ -568,9 +577,7 @@ cd9660_rrip_analyze(isodir,inop,imp)
}
/*
- * Get Alternate Name from 'AL' record
- * If either no AL record or 0 length,
- * it will be return the translated ISO9660 name,
+ * Get Alternate Name.
*/
static RRIP_TABLE rrip_table_getname[] = {
{ "NM", cd9660_rrip_altname, cd9660_rrip_defname, ISO_SUSP_ALTNAME },
@@ -615,9 +622,7 @@ cd9660_rrip_getname(isodir,outbuf,outlen,inump,imp)
}
/*
- * Get Symbolic Name from 'SL' record
- *
- * Note: isodir should contains SL record!
+ * Get Symbolic Link.
*/
static RRIP_TABLE rrip_table_getsymname[] = {
{ "SL", cd9660_rrip_slink, 0, ISO_SUSP_SLINK },
@@ -656,7 +661,7 @@ static RRIP_TABLE rrip_table_extref[] = {
/*
* Check for Rock Ridge Extension and return offset of its fields.
- * Note: We require the ER field.
+ * Note: We insist on the ER field.
*/
int
cd9660_rrip_offset(isodir,imp)
diff --git a/sys/isofs/cd9660/cd9660_rrip.h b/sys/isofs/cd9660/cd9660_rrip.h
index b401728..c1e2a04 100644
--- a/sys/isofs/cd9660/cd9660_rrip.h
+++ b/sys/isofs/cd9660/cd9660_rrip.h
@@ -35,33 +35,27 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)cd9660_rrip.h 8.1 (Berkeley) 1/21/94
+ * @(#)cd9660_rrip.h 8.2 (Berkeley) 12/5/94
*/
typedef struct {
- char type [ISODCL ( 0, 1)];
- unsigned char length [ISODCL ( 2, 2)]; /* 711 */
- unsigned char version [ISODCL ( 3, 3)];
+ char type [ISODCL ( 0, 1)];
+ u_char length [ISODCL ( 2, 2)]; /* 711 */
+ u_char version [ISODCL ( 3, 3)];
} ISO_SUSP_HEADER;
typedef struct {
ISO_SUSP_HEADER h;
- char mode_l [ISODCL ( 4, 7)]; /* 731 */
- char mode_m [ISODCL ( 8, 11)]; /* 732 */
- char links_l [ISODCL ( 12, 15)]; /* 731 */
- char links_m [ISODCL ( 16, 19)]; /* 732 */
- char uid_l [ISODCL ( 20, 23)]; /* 731 */
- char uid_m [ISODCL ( 24, 27)]; /* 732 */
- char gid_l [ISODCL ( 28, 31)]; /* 731 */
- char gid_m [ISODCL ( 32, 35)]; /* 732 */
+ char mode [ISODCL ( 4, 11)]; /* 733 */
+ char links [ISODCL ( 12, 19)]; /* 733 */
+ char uid [ISODCL ( 20, 27)]; /* 733 */
+ char gid [ISODCL ( 28, 35)]; /* 733 */
} ISO_RRIP_ATTR;
typedef struct {
ISO_SUSP_HEADER h;
- char dev_t_high_l [ISODCL ( 4, 7)]; /* 731 */
- char dev_t_high_m [ISODCL ( 8, 11)]; /* 732 */
- char dev_t_low_l [ISODCL ( 12, 15)]; /* 731 */
- char dev_t_low_m [ISODCL ( 16, 19)]; /* 732 */
+ char dev_t_high [ISODCL ( 4, 11)]; /* 733 */
+ char dev_t_low [ISODCL ( 12, 19)]; /* 733 */
} ISO_RRIP_DEVICE;
#define ISO_SUSP_CFLAG_CONTINUE 0x01
@@ -74,7 +68,7 @@ typedef struct {
typedef struct {
u_char cflag [ISODCL ( 1, 1)];
u_char clen [ISODCL ( 2, 2)];
- u_char name [0];
+ u_char name [1]; /* XXX */
} ISO_RRIP_SLINK_COMPONENT;
#define ISO_RRIP_SLSIZ 2
@@ -115,13 +109,13 @@ typedef struct {
typedef struct {
ISO_SUSP_HEADER h;
- unsigned char flags [ISODCL ( 4, 4)];
- unsigned char time [ISODCL ( 5, 5)];
+ u_char flags [ISODCL ( 4, 4)];
+ u_char time [ISODCL ( 5, 5)];
} ISO_RRIP_TSTAMP;
typedef struct {
ISO_SUSP_HEADER h;
- unsigned char flags [ISODCL ( 4, 4)];
+ u_char flags [ISODCL ( 4, 4)];
} ISO_RRIP_IDFLAG;
typedef struct {
diff --git a/sys/isofs/cd9660/cd9660_util.c b/sys/isofs/cd9660/cd9660_util.c
index f74f051..003a3ad 100644
--- a/sys/isofs/cd9660/cd9660_util.c
+++ b/sys/isofs/cd9660/cd9660_util.c
@@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)cd9660_util.c 8.1 (Berkeley) 1/21/94
+ * @(#)cd9660_util.c 8.3 (Berkeley) 12/5/94
*/
#include <sys/param.h>
@@ -57,104 +57,14 @@
#include <isofs/cd9660/iso.h>
-#ifdef __notanymore__
-int
-isonum_711 (p)
-unsigned char *p;
-{
- return (*p);
-}
-
-int
-isonum_712 (p)
-signed char *p;
-{
- return (*p);
-}
-
-int
-isonum_721 (p)
-unsigned char *p;
-{
- /* little endian short */
-#if BYTE_ORDER != LITTLE_ENDIAN
- printf ("isonum_721 called on non little-endian machine!\n");
-#endif
-
- return *(short *)p;
-}
-
-int
-isonum_722 (p)
-unsigned char *p;
-{
- /* big endian short */
-#if BYTE_ORDER != BIG_ENDIAN
- printf ("isonum_722 called on non big-endian machine!\n");
-#endif
-
- return *(short *)p;
-}
-
-int
-isonum_723 (p)
-unsigned char *p;
-{
-#if BYTE_ORDER == BIG_ENDIAN
- return isonum_722 (p + 2);
-#elif BYTE_ORDER == LITTLE_ENDIAN
- return isonum_721 (p);
-#else
- printf ("isonum_723 unsupported byte order!\n");
- return 0;
-#endif
-}
-
-int
-isonum_731 (p)
-unsigned char *p;
-{
- /* little endian long */
-#if BYTE_ORDER != LITTLE_ENDIAN
- printf ("isonum_731 called on non little-endian machine!\n");
-#endif
-
- return *(long *)p;
-}
-
-int
-isonum_732 (p)
-unsigned char *p;
-{
- /* big endian long */
-#if BYTE_ORDER != BIG_ENDIAN
- printf ("isonum_732 called on non big-endian machine!\n");
-#endif
-
- return *(long *)p;
-}
-
-int
-isonum_733 (p)
-unsigned char *p;
-{
-#if BYTE_ORDER == BIG_ENDIAN
- return isonum_732 (p + 4);
-#elif BYTE_ORDER == LITTLE_ENDIAN
- return isonum_731 (p);
-#else
- printf ("isonum_733 unsupported byte order!\n");
- return 0;
-#endif
-}
-#endif /* __notanymore__ */
-
/*
* translate and compare a filename
* Note: Version number plus ';' may be omitted.
*/
int
-isofncmp(unsigned char *fn,int fnlen,unsigned char *isofn,int isolen)
+isofncmp(fn, fnlen, isofn, isolen)
+ u_char *fn, *isofn;
+ int fnlen, isolen;
{
int i, j;
char c;
@@ -210,15 +120,19 @@ isofncmp(unsigned char *fn,int fnlen,unsigned char *isofn,int isolen)
* translate a filename
*/
void
-isofntrans(unsigned char *infn,int infnlen,
- unsigned char *outfn,unsigned short *outfnlen,
- int original,int assoc)
+isofntrans(infn, infnlen, outfn, outfnlen, original, assoc)
+ u_char *infn, *outfn;
+ int infnlen;
+ u_short *outfnlen;
+ int original;
+ int assoc;
{
int fnidx = 0;
if (assoc) {
*outfn++ = ASSOCCHAR;
fnidx++;
+ infnlen++;
}
for (; fnidx < infnlen; fnidx++) {
char c = *infn++;
diff --git a/sys/isofs/cd9660/cd9660_vfsops.c b/sys/isofs/cd9660/cd9660_vfsops.c
index 02dd92a..e242946 100644
--- a/sys/isofs/cd9660/cd9660_vfsops.c
+++ b/sys/isofs/cd9660/cd9660_vfsops.c
@@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)cd9660_vfsops.c 8.3 (Berkeley) 1/31/94
+ * @(#)cd9660_vfsops.c 8.18 (Berkeley) 5/22/95
*/
#include <sys/param.h>
@@ -53,9 +53,11 @@
#include <sys/ioctl.h>
#include <sys/errno.h>
#include <sys/malloc.h>
+#include <sys/stat.h>
#include <isofs/cd9660/iso.h>
#include <isofs/cd9660/cd9660_node.h>
+#include <isofs/cd9660/cd9660_mount.h>
extern int enodev ();
@@ -71,70 +73,50 @@ struct vfsops cd9660_vfsops = {
cd9660_fhtovp,
cd9660_vptofh,
cd9660_init,
+ cd9660_sysctl
};
/*
* Called by vfs_mountroot when iso is going to be mounted as root.
- *
- * Name is updated by mount(8) after booting.
*/
-#define ROOTNAME "root_device"
static iso_mountfs();
cd9660_mountroot()
{
- register struct mount *mp;
+ struct mount *mp;
extern struct vnode *rootvp;
struct proc *p = curproc; /* XXX */
- struct iso_mnt *imp;
- register struct fs *fs;
- u_int size;
- int error;
struct iso_args args;
+ int error;
/*
* Get vnodes for swapdev and rootdev.
*/
- if (bdevvp(swapdev, &swapdev_vp) || bdevvp(rootdev, &rootvp))
- panic("cd9660_mountroot: can't setup bdevvp's");
+ if ((error = bdevvp(swapdev, &swapdev_vp)) ||
+ (error = bdevvp(rootdev, &rootvp))) {
+ printf("cd9660_mountroot: can't setup bdevvp's");
+ return (error);
+ }
- mp = malloc((u_long)sizeof(struct mount), M_MOUNT, M_WAITOK);
- bzero((char *)mp, (u_long)sizeof(struct mount));
- mp->mnt_op = &cd9660_vfsops;
- mp->mnt_flag = MNT_RDONLY;
+ if (error = vfs_rootmountalloc("cd9660", "root_device", &mp))
+ return (error);
args.flags = ISOFSMNT_ROOT;
if (error = iso_mountfs(rootvp, mp, p, &args)) {
+ mp->mnt_vfc->vfc_refcount--;
+ vfs_unbusy(mp, p);
free(mp, M_MOUNT);
return (error);
}
- if (error = vfs_lock(mp)) {
- (void)cd9660_unmount(mp, 0, p);
- free(mp, M_MOUNT);
- return (error);
- }
- TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list);
- mp->mnt_flag |= MNT_ROOTFS;
- mp->mnt_vnodecovered = NULLVP;
- imp = VFSTOISOFS(mp);
- bzero(imp->im_fsmnt, sizeof(imp->im_fsmnt));
- imp->im_fsmnt[0] = '/';
- bcopy((caddr_t)imp->im_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname,
- MNAMELEN);
- (void) copystr(ROOTNAME, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
- &size);
- bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
- (void) cd9660_statfs(mp, &mp->mnt_stat, p);
- vfs_unlock(mp);
+ simple_lock(&mountlist_slock);
+ CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
+ simple_unlock(&mountlist_slock);
+ (void)cd9660_statfs(mp, &mp->mnt_stat, p);
+ vfs_unbusy(mp, p);
return (0);
}
/*
- * Flag to allow forcible unmounting.
- */
-int iso_doforce = 1;
-
-/*
* VFS Operations.
*
* mount system call
@@ -197,10 +179,8 @@ cd9660_mount(mp, path, data, ndp, p)
return error;
}
imp = VFSTOISOFS(mp);
- (void) copyinstr(path, imp->im_fsmnt, sizeof(imp->im_fsmnt)-1, &size);
- bzero(imp->im_fsmnt + size, sizeof(imp->im_fsmnt) - size);
- bcopy((caddr_t)imp->im_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname,
- MNAMELEN);
+ (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
+ bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
(void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
&size);
bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
@@ -261,11 +241,11 @@ static iso_mountfs(devvp, mp, p, argp)
iso_bsize = ISO_DEFAULT_BLOCK_SIZE;
for (iso_blknum = 16; iso_blknum < 100; iso_blknum++) {
- if (error = bread (devvp, btodb(iso_blknum * iso_bsize),
- iso_bsize, NOCRED, &bp))
+ if (error = bread(devvp, iso_blknum * btodb(iso_bsize),
+ iso_bsize, NOCRED, &bp))
goto out;
- vdp = (struct iso_volume_descriptor *)bp->b_un.b_addr;
+ vdp = (struct iso_volume_descriptor *)bp->b_data;
if (bcmp (vdp->id, ISO_STANDARD_ID, sizeof vdp->id) != 0) {
error = EINVAL;
goto out;
@@ -317,7 +297,7 @@ static iso_mountfs(devvp, mp, p, argp)
mp->mnt_data = (qaddr_t)isomp;
mp->mnt_stat.f_fsid.val[0] = (long)dev;
- mp->mnt_stat.f_fsid.val[1] = MOUNT_CD9660;
+ mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
mp->mnt_maxsymlinklen = 0;
mp->mnt_flag |= MNT_LOCAL;
isomp->im_mountp = mp;
@@ -328,13 +308,13 @@ static iso_mountfs(devvp, mp, p, argp)
/* Check the Rock Ridge Extention support */
if (!(argp->flags & ISOFSMNT_NORRIP)) {
- if (error = bread (isomp->im_devvp,
- (isomp->root_extent + isonum_711(rootp->ext_attr_length))
- * isomp->logical_block_size / DEV_BSIZE,
- isomp->logical_block_size,NOCRED,&bp))
+ if (error = bread(isomp->im_devvp,
+ (isomp->root_extent + isonum_711(rootp->ext_attr_length)) <<
+ (isomp->im_bshift - DEV_BSHIFT),
+ isomp->logical_block_size, NOCRED, &bp))
goto out;
- rootp = (struct iso_directory_record *)bp->b_un.b_addr;
+ rootp = (struct iso_directory_record *)bp->b_data;
if ((isomp->rr_skip = cd9660_rrip_offset(rootp,isomp)) < 0) {
argp->flags |= ISOFSMNT_NORRIP;
@@ -401,11 +381,8 @@ cd9660_unmount(mp, mntflags, p)
register struct iso_mnt *isomp;
int i, error, ronly, flags = 0;
- if (mntflags & MNT_FORCE) {
- if (!iso_doforce || (mp->mnt_flag & MNT_ROOTFS))
- return (EINVAL);
+ if (mntflags & MNT_FORCE)
flags |= FORCECLOSE;
- }
#if 0
mntflushbuf(mp, 0);
if (mntinvalbuf(mp))
@@ -437,33 +414,17 @@ cd9660_root(mp, vpp)
struct mount *mp;
struct vnode **vpp;
{
- register struct iso_node *ip;
- struct iso_node tip, *nip;
- struct vnode tvp;
- int error;
- struct iso_mnt *imp = VFSTOISOFS (mp);
- struct iso_directory_record *dp;
-
- tvp.v_mount = mp;
- tvp.v_data = &tip;
- ip = VTOI(&tvp);
- ip->i_vnode = &tvp;
- ip->i_dev = imp->im_dev;
- ip->i_diroff = 0;
- dp = (struct iso_directory_record *)imp->root;
- isodirino(&ip->i_number,dp,imp);
+ struct iso_mnt *imp = VFSTOISOFS(mp);
+ struct iso_directory_record *dp =
+ (struct iso_directory_record *)imp->root;
+ ino_t ino = isodirino(dp, imp);
/*
* With RRIP we must use the `.' entry of the root directory.
- * Simply tell iget, that it's a relocated directory.
+ * Simply tell vget, that it's a relocated directory.
*/
- error = iso_iget(ip,ip->i_number,
- imp->iso_ftype == ISO_FTYPE_RRIP,
- &nip,dp);
- if (error)
- return error;
- *vpp = ITOV(nip);
- return 0;
+ return (cd9660_vget_internal(mp, ino, vpp,
+ imp->iso_ftype == ISO_FTYPE_RRIP, dp));
}
/*
@@ -494,8 +455,12 @@ cd9660_statfs(mp, sbp, p)
register struct fs *fs;
isomp = VFSTOISOFS(mp);
-
- sbp->f_type = MOUNT_CD9660;
+
+#ifdef COMPAT_09
+ sbp->f_type = 5;
+#else
+ sbp->f_type = 0;
+#endif
sbp->f_bsize = isomp->logical_block_size;
sbp->f_iosize = sbp->f_bsize; /* XXX */
sbp->f_blocks = isomp->volume_space_size;
@@ -504,10 +469,8 @@ cd9660_statfs(mp, sbp, p)
sbp->f_files = 0; /* total files */
sbp->f_ffree = 0; /* free file nodes */
if (sbp != &mp->mnt_stat) {
- bcopy((caddr_t)mp->mnt_stat.f_mntonname,
- (caddr_t)&sbp->f_mntonname[0], MNAMELEN);
- bcopy((caddr_t)mp->mnt_stat.f_mntfromname,
- (caddr_t)&sbp->f_mntfromname[0], MNAMELEN);
+ bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
+ bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
}
/* Use the first spare for flags: */
sbp->f_spare[0] = isomp->im_flags;
@@ -526,21 +489,6 @@ cd9660_sync(mp, waitfor, cred, p)
}
/*
- * Flat namespace lookup.
- * Currently unsupported.
- */
-/* ARGSUSED */
-int
-cd9660_vget(mp, ino, vpp)
- struct mount *mp;
- ino_t ino;
- struct vnode **vpp;
-{
-
- return (EOPNOTSUPP);
-}
-
-/*
* File handle to vnode
*
* Have to be really careful about stale file handles:
@@ -567,92 +515,263 @@ cd9660_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)
int *exflagsp;
struct ucred **credanonp;
{
- struct vnode tvp;
- int error;
- int lbn, off;
- struct ifid *ifhp;
- struct iso_mnt *imp;
- struct buf *bp;
- struct iso_directory_record *dirp;
- struct iso_node tip, *ip, *nip;
- struct netcred *np;
-
- imp = VFSTOISOFS (mp);
- ifhp = (struct ifid *)fhp;
+ struct ifid *ifhp = (struct ifid *)fhp;
+ register struct iso_node *ip;
+ register struct netcred *np;
+ register struct iso_mnt *imp = VFSTOISOFS(mp);
+ struct vnode *nvp;
+ int error;
#ifdef ISOFS_DBG
printf("fhtovp: ino %d, start %ld\n",
ifhp->ifid_ino, ifhp->ifid_start);
#endif
+ /*
+ * Get the export permission structure for this <mp, client> tuple.
+ */
np = vfs_export_lookup(mp, &imp->im_export, nam);
if (np == NULL)
return (EACCES);
- lbn = iso_lblkno(imp, ifhp->ifid_ino);
- if (lbn >= imp->volume_space_size) {
- printf("fhtovp: lbn exceed volume space %d\n", lbn);
- return (ESTALE);
+ if (error = VFS_VGET(mp, ifhp->ifid_ino, &nvp)) {
+ *vpp = NULLVP;
+ return (error);
}
-
- off = iso_blkoff(imp, ifhp->ifid_ino);
- if (off + ISO_DIRECTORY_RECORD_SIZE > imp->logical_block_size) {
- printf("fhtovp: crosses block boundary %d\n",
- off + ISO_DIRECTORY_RECORD_SIZE);
+ ip = VTOI(nvp);
+ if (ip->inode.iso_mode == 0) {
+ vput(nvp);
+ *vpp = NULLVP;
return (ESTALE);
}
-
- error = bread(imp->im_devvp, btodb(lbn * imp->logical_block_size),
- imp->logical_block_size, NOCRED, &bp);
- if (error) {
- printf("fhtovp: bread error %d\n",error);
- brelse(bp);
+ *vpp = nvp;
+ *exflagsp = np->netc_exflags;
+ *credanonp = &np->netc_anon;
+ return (0);
+}
+
+int
+cd9660_vget(mp, ino, vpp)
+ struct mount *mp;
+ ino_t ino;
+ struct vnode **vpp;
+{
+
+ /*
+ * XXXX
+ * It would be nice if we didn't always set the `relocated' flag
+ * and force the extra read, but I don't want to think about fixing
+ * that right now.
+ */
+ return (cd9660_vget_internal(mp, ino, vpp,
+#if 0
+ VFSTOISOFS(mp)->iso_ftype == ISO_FTYPE_RRIP,
+#else
+ 0,
+#endif
+ (struct iso_directory_entry *)0));
+}
+
+int
+cd9660_vget_internal(mp, ino, vpp, relocated, isodir)
+ struct mount *mp;
+ ino_t ino;
+ struct vnode **vpp;
+ int relocated;
+ struct iso_directory_record *isodir;
+{
+ struct proc *p = curproc; /* XXX */
+ struct iso_mnt *imp;
+ struct iso_node *ip;
+ struct buf *bp;
+ struct vnode *vp, *nvp;
+ dev_t dev;
+ int error;
+
+ imp = VFSTOISOFS(mp);
+ dev = imp->im_dev;
+ if ((*vpp = cd9660_ihashget(dev, ino)) != NULLVP)
+ return (0);
+
+ /* Allocate a new vnode/iso_node. */
+ if (error = getnewvnode(VT_ISOFS, mp, cd9660_vnodeop_p, &vp)) {
+ *vpp = NULLVP;
return (error);
}
+ MALLOC(ip, struct iso_node *, sizeof(struct iso_node), M_ISOFSNODE,
+ M_WAITOK);
+ bzero((caddr_t)ip, sizeof(struct iso_node));
+ lockinit(&ip->i_lock, PINOD, "isonode", 0, 0);
+ vp->v_data = ip;
+ ip->i_vnode = vp;
+ ip->i_dev = dev;
+ ip->i_number = ino;
+
+ /*
+ * Put it onto its hash chain and lock it so that other requests for
+ * this inode will block if they arrive while we are sleeping waiting
+ * for old data structures to be purged or for the contents of the
+ * disk portion of this inode to be read.
+ */
+ cd9660_ihashins(ip);
+
+ if (isodir == 0) {
+ int lbn, off;
+
+ lbn = lblkno(imp, ino);
+ if (lbn >= imp->volume_space_size) {
+ vput(vp);
+ printf("fhtovp: lbn exceed volume space %d\n", lbn);
+ return (ESTALE);
+ }
- dirp = (struct iso_directory_record *)(bp->b_un.b_addr + off);
- if (off + isonum_711(dirp->length) > imp->logical_block_size) {
- brelse(bp);
- printf("fhtovp: directory crosses block boundary %d[off=%d/len=%d]\n",
- off+isonum_711(dirp->length), off,
- isonum_711(dirp->length));
- return (ESTALE);
+ off = blkoff(imp, ino);
+ if (off + ISO_DIRECTORY_RECORD_SIZE > imp->logical_block_size) {
+ vput(vp);
+ printf("fhtovp: crosses block boundary %d\n",
+ off + ISO_DIRECTORY_RECORD_SIZE);
+ return (ESTALE);
+ }
+
+ error = bread(imp->im_devvp,
+ lbn << (imp->im_bshift - DEV_BSHIFT),
+ imp->logical_block_size, NOCRED, &bp);
+ if (error) {
+ vput(vp);
+ brelse(bp);
+ printf("fhtovp: bread error %d\n",error);
+ return (error);
+ }
+ isodir = (struct iso_directory_record *)(bp->b_data + off);
+
+ if (off + isonum_711(isodir->length) >
+ imp->logical_block_size) {
+ vput(vp);
+ if (bp != 0)
+ brelse(bp);
+ printf("fhtovp: directory crosses block boundary %d[off=%d/len=%d]\n",
+ off +isonum_711(isodir->length), off,
+ isonum_711(isodir->length));
+ return (ESTALE);
+ }
+
+#if 0
+ if (isonum_733(isodir->extent) +
+ isonum_711(isodir->ext_attr_length) != ifhp->ifid_start) {
+ if (bp != 0)
+ brelse(bp);
+ printf("fhtovp: file start miss %d vs %d\n",
+ isonum_733(isodir->extent) + isonum_711(isodir->ext_attr_length),
+ ifhp->ifid_start);
+ return (ESTALE);
+ }
+#endif
+ } else
+ bp = 0;
+
+ ip->i_mnt = imp;
+ ip->i_devvp = imp->im_devvp;
+ VREF(ip->i_devvp);
+
+ if (relocated) {
+ /*
+ * On relocated directories we must
+ * read the `.' entry out of a dir.
+ */
+ ip->iso_start = ino >> imp->im_bshift;
+ if (bp != 0)
+ brelse(bp);
+ if (error = VOP_BLKATOFF(vp, (off_t)0, NULL, &bp)) {
+ vput(vp);
+ return (error);
+ }
+ isodir = (struct iso_directory_record *)bp->b_data;
}
+
+ ip->iso_extent = isonum_733(isodir->extent);
+ ip->i_size = isonum_733(isodir->size);
+ ip->iso_start = isonum_711(isodir->ext_attr_length) + ip->iso_extent;
- if (isonum_733(dirp->extent) + isonum_711(dirp->ext_attr_length) !=
- ifhp->ifid_start) {
+ /*
+ * Setup time stamp, attribute
+ */
+ vp->v_type = VNON;
+ switch (imp->iso_ftype) {
+ default: /* ISO_FTYPE_9660 */
+ {
+ struct buf *bp2;
+ int off;
+ if ((imp->im_flags & ISOFSMNT_EXTATT)
+ && (off = isonum_711(isodir->ext_attr_length)))
+ VOP_BLKATOFF(vp, (off_t)-(off << imp->im_bshift), NULL,
+ &bp2);
+ else
+ bp2 = NULL;
+ cd9660_defattr(isodir, ip, bp2);
+ cd9660_deftstamp(isodir, ip, bp2);
+ if (bp2)
+ brelse(bp2);
+ break;
+ }
+ case ISO_FTYPE_RRIP:
+ cd9660_rrip_analyze(isodir, ip, imp);
+ break;
+ }
+
+ if (bp != 0)
brelse(bp);
- printf("fhtovp: file start miss %d vs %d\n",
- isonum_733(dirp->extent)+isonum_711(dirp->ext_attr_length),
- ifhp->ifid_start);
- return (ESTALE);
+
+ /*
+ * Initialize the associated vnode
+ */
+ switch (vp->v_type = IFTOVT(ip->inode.iso_mode)) {
+ case VFIFO:
+#ifdef FIFO
+ vp->v_op = cd9660_fifoop_p;
+ break;
+#else
+ vput(vp);
+ return (EOPNOTSUPP);
+#endif /* FIFO */
+ case VCHR:
+ case VBLK:
+ /*
+ * if device, look at device number table for translation
+ */
+#ifdef ISODEVMAP
+ if (dp = iso_dmap(dev, ino, 0))
+ ip->inode.iso_rdev = dp->d_dev;
+#endif
+ vp->v_op = cd9660_specop_p;
+ if (nvp = checkalias(vp, ip->inode.iso_rdev, mp)) {
+ /*
+ * Discard unneeded vnode, but save its iso_node.
+ * Note that the lock is carried over in the iso_node
+ * to the replacement vnode.
+ */
+ nvp->v_data = vp->v_data;
+ vp->v_data = NULL;
+ vp->v_op = spec_vnodeop_p;
+ vrele(vp);
+ vgone(vp);
+ /*
+ * Reinitialize aliased inode.
+ */
+ vp = nvp;
+ ip->i_vnode = vp;
+ }
+ break;
}
- brelse(bp);
- ip = &tip;
- tvp.v_mount = mp;
- tvp.v_data = ip;
- ip->i_vnode = &tvp;
- ip->i_dev = imp->im_dev;
- if (error = iso_iget(ip, ifhp->ifid_ino, 0, &nip, dirp)) {
- *vpp = NULLVP;
- printf("fhtovp: failed to get inode\n");
- return (error);
- }
- ip = nip;
+ if (ip->iso_extent == imp->root_extent)
+ vp->v_flag |= VROOT;
+
/*
* XXX need generation number?
*/
- if (ip->inode.iso_mode == 0) {
- iso_iput(ip);
- *vpp = NULLVP;
- printf("fhtovp: inode mode == 0\n");
- return (ESTALE);
- }
- *vpp = ITOV(ip);
- *exflagsp = np->netc_exflags;
- *credanonp = &np->netc_anon;
- return 0;
+
+ *vpp = vp;
+ return (0);
}
/*
diff --git a/sys/isofs/cd9660/cd9660_vnops.c b/sys/isofs/cd9660/cd9660_vnops.c
index 59f5a73..858f2b8 100644
--- a/sys/isofs/cd9660/cd9660_vnops.c
+++ b/sys/isofs/cd9660/cd9660_vnops.c
@@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)cd9660_vnops.c 8.3 (Berkeley) 1/23/94
+ * @(#)cd9660_vnops.c 8.19 (Berkeley) 5/27/95
*/
#include <sys/param.h>
@@ -74,25 +74,25 @@ cd9660_mknod(ndp, vap, cred, p)
free(ndp->ni_pnbuf, M_NAMEI);
vput(ndp->ni_dvp);
vput(ndp->ni_vp);
- return EINVAL;
+ return (EINVAL);
#else
register struct vnode *vp;
struct iso_node *ip;
struct iso_dnode *dp;
int error;
-
+
vp = ndp->ni_vp;
ip = VTOI(vp);
-
+
if (ip->i_mnt->iso_ftype != ISO_FTYPE_RRIP
|| vap->va_type != vp->v_type
|| (vap->va_type != VCHR && vap->va_type != VBLK)) {
free(ndp->ni_pnbuf, M_NAMEI);
vput(ndp->ni_dvp);
vput(ndp->ni_vp);
- return EINVAL;
+ return (EINVAL);
}
-
+
dp = iso_dmap(ip->i_dev,ip->i_number,1);
if (ip->inode.iso_rdev == vap->va_rdev || vap->va_rdev == VNOVAL) {
/* same as the unmapped one, delete the mapping */
@@ -101,7 +101,7 @@ cd9660_mknod(ndp, vap, cred, p)
} else
/* enter new mapping */
dp->d_dev = vap->va_rdev;
-
+
/*
* Remove inode so that it will be reloaded by iget and
* checked to see if it is an alias of an existing entry
@@ -116,6 +116,42 @@ cd9660_mknod(ndp, vap, cred, p)
#endif
/*
+ * Setattr call. Only allowed for block and character special devices.
+ */
+int
+cd9660_setattr(ap)
+ struct vop_setattr_args /* {
+ struct vnodeop_desc *a_desc;
+ struct vnode *a_vp;
+ struct vattr *a_vap;
+ struct ucred *a_cred;
+ struct proc *a_p;
+ } */ *ap;
+{
+ struct vnode *vp = ap->a_vp;
+ struct vattr *vap = ap->a_vap;
+
+ if (vap->va_flags != VNOVAL || vap->va_uid != (uid_t)VNOVAL ||
+ vap->va_gid != (gid_t)VNOVAL || vap->va_atime.ts_sec != VNOVAL ||
+ vap->va_mtime.ts_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL)
+ return (EROFS);
+ if (vap->va_size != VNOVAL) {
+ switch (vp->v_type) {
+ case VDIR:
+ return (EISDIR);
+ case VLNK:
+ case VREG:
+ return (EROFS);
+ case VCHR:
+ case VBLK:
+ case VSOCK:
+ case VFIFO:
+ return (0);
+ }
+ }
+}
+
+/*
* Open called.
*
* Nothing to do.
@@ -165,7 +201,65 @@ cd9660_access(ap)
struct proc *a_p;
} */ *ap;
{
- return (0);
+ struct vnode *vp = ap->a_vp;
+ struct iso_node *ip = VTOI(vp);
+ struct ucred *cred = ap->a_cred;
+ mode_t mask, mode = ap->a_mode;
+ gid_t *gp;
+ int i;
+
+ /*
+ * Disallow write attempts unless the file is a socket,
+ * fifo, or a block or character device resident on the
+ * file system.
+ */
+ if (mode & VWRITE) {
+ switch (vp->v_type) {
+ case VDIR:
+ case VLNK:
+ case VREG:
+ return (EROFS);
+ }
+ }
+
+ /* User id 0 always gets access. */
+ if (cred->cr_uid == 0)
+ return (0);
+
+ mask = 0;
+
+ /* Otherwise, check the owner. */
+ if (cred->cr_uid == ip->inode.iso_uid) {
+ if (mode & VEXEC)
+ mask |= S_IXUSR;
+ if (mode & VREAD)
+ mask |= S_IRUSR;
+ if (mode & VWRITE)
+ mask |= S_IWUSR;
+ return ((ip->inode.iso_mode & mask) == mask ? 0 : EACCES);
+ }
+
+ /* Otherwise, check the groups. */
+ for (i = 0, gp = cred->cr_groups; i < cred->cr_ngroups; i++, gp++)
+ if (ip->inode.iso_gid == *gp) {
+ if (mode & VEXEC)
+ mask |= S_IXGRP;
+ if (mode & VREAD)
+ mask |= S_IRGRP;
+ if (mode & VWRITE)
+ mask |= S_IWGRP;
+ return ((ip->inode.iso_mode & mask) == mask ?
+ 0 : EACCES);
+ }
+
+ /* Otherwise, check everyone else. */
+ if (mode & VEXEC)
+ mask |= S_IXOTH;
+ if (mode & VREAD)
+ mask |= S_IROTH;
+ if (mode & VWRITE)
+ mask |= S_IWOTH;
+ return ((ip->inode.iso_mode & mask) == mask ? 0 : EACCES);
}
cd9660_getattr(ap)
@@ -195,6 +289,29 @@ cd9660_getattr(ap)
vap->va_rdev = ip->inode.iso_rdev;
vap->va_size = (u_quad_t) ip->i_size;
+ if (ip->i_size == 0 && (vap->va_mode & S_IFMT) == S_IFLNK) {
+ struct vop_readlink_args rdlnk;
+ struct iovec aiov;
+ struct uio auio;
+ char *cp;
+
+ MALLOC(cp, char *, MAXPATHLEN, M_TEMP, M_WAITOK);
+ aiov.iov_base = cp;
+ aiov.iov_len = MAXPATHLEN;
+ auio.uio_iov = &aiov;
+ auio.uio_iovcnt = 1;
+ auio.uio_offset = 0;
+ auio.uio_rw = UIO_READ;
+ auio.uio_segflg = UIO_SYSSPACE;
+ auio.uio_procp = ap->a_p;
+ auio.uio_resid = MAXPATHLEN;
+ rdlnk.a_uio = &auio;
+ rdlnk.a_vp = ap->a_vp;
+ rdlnk.a_cred = ap->a_cred;
+ if (cd9660_readlink(&rdlnk) == 0)
+ vap->va_size = MAXPATHLEN - auio.uio_resid;
+ FREE(cp, M_TEMP);
+ }
vap->va_flags = 0;
vap->va_gen = 1;
vap->va_blocksize = ip->i_mnt->logical_block_size;
@@ -234,35 +351,35 @@ cd9660_read(ap)
off_t diff;
int rasize, error = 0;
long size, n, on;
-
+
if (uio->uio_resid == 0)
return (0);
if (uio->uio_offset < 0)
return (EINVAL);
- ip->i_flag |= IACC;
+ ip->i_flag |= IN_ACCESS;
imp = ip->i_mnt;
do {
- lbn = iso_lblkno(imp, uio->uio_offset);
- on = iso_blkoff(imp, uio->uio_offset);
- n = min((unsigned)(imp->logical_block_size - on),
+ lbn = lblkno(imp, uio->uio_offset);
+ on = blkoff(imp, uio->uio_offset);
+ n = min((u_int)(imp->logical_block_size - on),
uio->uio_resid);
diff = (off_t)ip->i_size - uio->uio_offset;
if (diff <= 0)
return (0);
if (diff < n)
n = diff;
- size = iso_blksize(imp, ip, lbn);
+ size = blksize(imp, ip, lbn);
rablock = lbn + 1;
if (doclusterread) {
- if (iso_lblktosize(imp, rablock) <= ip->i_size)
+ if (lblktosize(imp, rablock) <= ip->i_size)
error = cluster_read(vp, (off_t)ip->i_size,
lbn, size, NOCRED, &bp);
- else
+ else
error = bread(vp, lbn, size, NOCRED, &bp);
} else {
if (vp->v_lastr + 1 == lbn &&
- iso_lblktosize(imp, rablock) < ip->i_size) {
- rasize = iso_blksize(imp, ip, rablock);
+ lblktosize(imp, rablock) < ip->i_size) {
+ rasize = blksize(imp, ip, rablock);
error = breadn(vp, lbn, size, &rablock,
&rasize, 1, NOCRED, &bp);
} else
@@ -275,7 +392,7 @@ cd9660_read(ap)
return (error);
}
- error = uiomove(bp->b_un.b_addr + on, (int)n, uio);
+ error = uiomove(bp->b_data + on, (int)n, uio);
if (n + on == imp->logical_block_size ||
uio->uio_offset == (off_t)ip->i_size)
bp->b_flags |= B_AGE;
@@ -289,7 +406,7 @@ int
cd9660_ioctl(ap)
struct vop_ioctl_args /* {
struct vnode *a_vp;
- int a_command;
+ u_long a_command;
caddr_t a_data;
int a_fflag;
struct ucred *a_cred;
@@ -368,44 +485,44 @@ struct isoreaddir {
off_t curroff;
struct uio *uio;
off_t uio_off;
- u_int *cookiep;
+ int eofflag;
+ u_long *cookies;
int ncookies;
- int eof;
};
-static int
+int
iso_uiodir(idp,dp,off)
struct isoreaddir *idp;
struct dirent *dp;
off_t off;
{
int error;
-
+
dp->d_name[dp->d_namlen] = 0;
dp->d_reclen = DIRSIZ(dp);
-
+
if (idp->uio->uio_resid < dp->d_reclen) {
- idp->eof = 0;
- return -1;
+ idp->eofflag = 0;
+ return (-1);
}
-
- if (idp->cookiep) {
+
+ if (idp->cookies) {
if (idp->ncookies <= 0) {
- idp->eof = 0;
- return -1;
+ idp->eofflag = 0;
+ return (-1);
}
-
- *idp->cookiep++ = off;
+
+ *idp->cookies++ = off;
--idp->ncookies;
}
-
+
if (error = uiomove(dp,dp->d_reclen,idp->uio))
- return error;
+ return (error);
idp->uio_off = off;
- return 0;
+ return (0);
}
-static int
+int
iso_shipdir(idp)
struct isoreaddir *idp;
{
@@ -413,14 +530,14 @@ iso_shipdir(idp)
int cl, sl, assoc;
int error;
char *cname, *sname;
-
+
cl = idp->current.d_namlen;
cname = idp->current.d_name;
if (assoc = cl > 1 && *cname == ASSOCCHAR) {
cl--;
cname++;
}
-
+
dp = &idp->saveent;
sname = dp->d_name;
if (!(sl = dp->d_namlen)) {
@@ -433,12 +550,12 @@ iso_shipdir(idp)
|| bcmp(sname,cname,sl)) {
if (idp->assocent.d_namlen) {
if (error = iso_uiodir(idp,&idp->assocent,idp->assocoff))
- return error;
+ return (error);
idp->assocent.d_namlen = 0;
}
if (idp->saveent.d_namlen) {
if (error = iso_uiodir(idp,&idp->saveent,idp->saveoff))
- return error;
+ return (error);
idp->saveent.d_namlen = 0;
}
}
@@ -451,13 +568,11 @@ iso_shipdir(idp)
idp->saveoff = idp->curroff;
bcopy(&idp->current,&idp->saveent,idp->current.d_reclen);
}
- return 0;
+ return (0);
}
/*
* Vnode op for readdir
- * XXX make sure everything still works now that eofflagp and cookiep
- * are no longer args.
*/
int
cd9660_readdir(ap)
@@ -465,109 +580,123 @@ cd9660_readdir(ap)
struct vnode *a_vp;
struct uio *a_uio;
struct ucred *a_cred;
+ int *a_eofflag;
+ int *a_ncookies;
+ u_long *a_cookies;
} */ *ap;
{
register struct uio *uio = ap->a_uio;
struct isoreaddir *idp;
+ struct vnode *vdp = ap->a_vp;
+ struct iso_node *dp;
+ struct iso_mnt *imp;
+ struct buf *bp = NULL;
+ struct iso_directory_record *ep;
int entryoffsetinblock;
+ doff_t endsearch;
+ u_long bmask;
int error = 0;
- int endsearch;
- struct iso_directory_record *ep;
- u_short elen;
int reclen;
- struct iso_mnt *imp;
- struct iso_node *ip;
- struct buf *bp = NULL;
-
- ip = VTOI(ap->a_vp);
- imp = ip->i_mnt;
-
- MALLOC(idp,struct isoreaddir *,sizeof(*idp),M_TEMP,M_WAITOK);
- idp->saveent.d_namlen = 0;
- idp->assocent.d_namlen = 0;
+ u_short namelen;
+ int ncookies = 0;
+ u_long *cookies = NULL;
+
+ dp = VTOI(vdp);
+ imp = dp->i_mnt;
+ bmask = imp->im_bmask;
+
+ MALLOC(idp, struct isoreaddir *, sizeof(*idp), M_TEMP, M_WAITOK);
+ idp->saveent.d_namlen = idp->assocent.d_namlen = 0;
+ /*
+ * XXX
+ * Is it worth trying to figure out the type?
+ */
+ idp->saveent.d_type = idp->assocent.d_type = idp->current.d_type =
+ DT_UNKNOWN;
idp->uio = uio;
-#if 0
- idp->cookiep = cookies;
- idp->ncookies = ncookies;
- idp->eof = 1;
-#else
- idp->cookiep = 0;
-#endif
+ if (ap->a_ncookies == NULL) {
+ idp->cookies = NULL;
+ } else {
+ /*
+ * Guess the number of cookies needed.
+ */
+ ncookies = uio->uio_resid / 16;
+ MALLOC(cookies, u_int *, ncookies * sizeof(u_int), M_TEMP,
+ M_WAITOK);
+ idp->cookies = cookies;
+ idp->ncookies = ncookies;
+ }
+ idp->eofflag = 1;
idp->curroff = uio->uio_offset;
-
- entryoffsetinblock = iso_blkoff(imp, idp->curroff);
- if (entryoffsetinblock != 0) {
- if (error = iso_blkatoff(ip, idp->curroff, &bp)) {
- FREE(idp,M_TEMP);
- return (error);
- }
+
+ if ((entryoffsetinblock = idp->curroff & bmask) &&
+ (error = VOP_BLKATOFF(vdp, (off_t)idp->curroff, NULL, &bp))) {
+ FREE(idp, M_TEMP);
+ return (error);
}
-
- endsearch = ip->i_size;
-
+ endsearch = dp->i_size;
+
while (idp->curroff < endsearch) {
/*
* If offset is on a block boundary,
* read the next directory block.
* Release previous if it exists.
*/
-
- if (iso_blkoff(imp, idp->curroff) == 0) {
+ if ((idp->curroff & bmask) == 0) {
if (bp != NULL)
brelse(bp);
- if (error = iso_blkatoff(ip, idp->curroff, &bp))
+ if (error =
+ VOP_BLKATOFF(vdp, (off_t)idp->curroff, NULL, &bp))
break;
entryoffsetinblock = 0;
}
/*
* Get pointer to next entry.
*/
-
ep = (struct iso_directory_record *)
- (bp->b_un.b_addr + entryoffsetinblock);
-
- reclen = isonum_711 (ep->length);
+ ((char *)bp->b_data + entryoffsetinblock);
+
+ reclen = isonum_711(ep->length);
if (reclen == 0) {
/* skip to next block, if any */
- idp->curroff = roundup (idp->curroff,
- imp->logical_block_size);
+ idp->curroff =
+ (idp->curroff & ~bmask) + imp->logical_block_size;
continue;
}
-
+
if (reclen < ISO_DIRECTORY_RECORD_SIZE) {
error = EINVAL;
/* illegal entry, stop */
break;
}
-
+
if (entryoffsetinblock + reclen > imp->logical_block_size) {
error = EINVAL;
/* illegal directory, so stop looking */
break;
}
-
- idp->current.d_namlen = isonum_711 (ep->name_len);
- if (isonum_711(ep->flags)&2)
- isodirino(&idp->current.d_fileno,ep,imp);
- else
- idp->current.d_fileno = dbtob(bp->b_blkno) +
- idp->curroff;
-
+
+ idp->current.d_namlen = isonum_711(ep->name_len);
+
if (reclen < ISO_DIRECTORY_RECORD_SIZE + idp->current.d_namlen) {
error = EINVAL;
/* illegal entry, stop */
break;
}
-
+
+ if (isonum_711(ep->flags)&2)
+ idp->current.d_fileno = isodirino(ep, imp);
+ else
+ idp->current.d_fileno = dbtob(bp->b_blkno) +
+ entryoffsetinblock;
+
idp->curroff += reclen;
- /*
- *
- */
+
switch (imp->iso_ftype) {
case ISO_FTYPE_RRIP:
- cd9660_rrip_getname(ep,idp->current.d_name,
- (u_short *)&idp->current.d_namlen,
+ cd9660_rrip_getname(ep,idp->current.d_name, &namelen,
&idp->current.d_fileno,imp);
+ idp->current.d_namlen = (u_char)namelen;
if (idp->current.d_namlen)
error = iso_uiodir(idp,&idp->current,idp->curroff);
break;
@@ -584,10 +713,10 @@ cd9660_readdir(ap)
break;
default:
isofntrans(ep->name,idp->current.d_namlen,
- idp->current.d_name, &elen,
+ idp->current.d_name, &namelen,
imp->iso_ftype == ISO_FTYPE_9660,
isonum_711(ep->flags)&4);
- idp->current.d_namlen = (u_char)elen;
+ idp->current.d_namlen = (u_char)namelen;
if (imp->iso_ftype == ISO_FTYPE_DEFAULT)
error = iso_shipdir(idp);
else
@@ -597,27 +726,37 @@ cd9660_readdir(ap)
}
if (error)
break;
-
+
entryoffsetinblock += reclen;
}
-
+
if (!error && imp->iso_ftype == ISO_FTYPE_DEFAULT) {
idp->current.d_namlen = 0;
error = iso_shipdir(idp);
}
if (error < 0)
error = 0;
-
+
+ if (ap->a_ncookies != NULL) {
+ if (error)
+ free(cookies, M_TEMP);
+ else {
+ /*
+ * Work out the number of cookies actually used.
+ */
+ *ap->a_ncookies = ncookies - idp->ncookies;
+ *ap->a_cookies = cookies;
+ }
+ }
+
if (bp)
brelse (bp);
uio->uio_offset = idp->uio_off;
-#if 0
- *eofflagp = idp->eof;
-#endif
-
- FREE(idp,M_TEMP);
-
+ *ap->a_eofflag = idp->eofflag;
+
+ FREE(idp, M_TEMP);
+
return (error);
}
@@ -639,49 +778,39 @@ cd9660_readlink(ap)
} */ *ap;
{
ISONODE *ip;
- ISODIR *dirp;
+ ISODIR *dirp;
ISOMNT *imp;
struct buf *bp;
+ struct uio *uio;
u_short symlen;
int error;
char *symname;
ino_t ino;
-
+
ip = VTOI(ap->a_vp);
imp = ip->i_mnt;
-
+ uio = ap->a_uio;
+
if (imp->iso_ftype != ISO_FTYPE_RRIP)
- return EINVAL;
-
+ return (EINVAL);
+
/*
* Get parents directory record block that this inode included.
*/
error = bread(imp->im_devvp,
- (daddr_t)(ip->i_number / DEV_BSIZE),
- imp->logical_block_size,
- NOCRED,
- &bp);
+ (ip->i_number >> imp->im_bshift) <<
+ (imp->im_bshift - DEV_BSHIFT),
+ imp->logical_block_size, NOCRED, &bp);
if (error) {
brelse(bp);
- return EINVAL;
+ return (EINVAL);
}
/*
* Setup the directory pointer for this inode
*/
- dirp = (ISODIR *)(bp->b_un.b_addr + (ip->i_number & imp->im_bmask));
-#ifdef DEBUG
- printf("lbn=%d,off=%d,bsize=%d,DEV_BSIZE=%d, dirp= %08x, b_addr=%08x, offset=%08x(%08x)\n",
- (daddr_t)(ip->i_number >> imp->im_bshift),
- ip->i_number & imp->im_bmask,
- imp->logical_block_size,
- DEV_BSIZE,
- dirp,
- bp->b_un.b_addr,
- ip->i_number,
- ip->i_number & imp->im_bmask );
-#endif
-
+ dirp = (ISODIR *)(bp->b_data + (ip->i_number & imp->im_bmask));
+
/*
* Just make sure, we have a right one....
* 1: Check not cross boundary on block
@@ -689,22 +818,26 @@ cd9660_readlink(ap)
if ((ip->i_number & imp->im_bmask) + isonum_711(dirp->length)
> imp->logical_block_size) {
brelse(bp);
- return EINVAL;
+ return (EINVAL);
}
-
+
/*
* Now get a buffer
* Abuse a namei buffer for now.
*/
- MALLOC(symname,char *,MAXPATHLEN,M_NAMEI,M_WAITOK);
+ if (uio->uio_segflg == UIO_SYSSPACE)
+ symname = uio->uio_iov->iov_base;
+ else
+ MALLOC(symname, char *, MAXPATHLEN, M_NAMEI, M_WAITOK);
/*
* Ok, we just gathering a symbolic name in SL record.
*/
- if (cd9660_rrip_getsymname(dirp,symname,&symlen,imp) == 0) {
- FREE(symname,M_NAMEI);
+ if (cd9660_rrip_getsymname(dirp, symname, &symlen, imp) == 0) {
+ if (uio->uio_segflg != UIO_SYSSPACE)
+ FREE(symname, M_NAMEI);
brelse(bp);
- return EINVAL;
+ return (EINVAL);
}
/*
* Don't forget before you leave from home ;-)
@@ -714,11 +847,15 @@ cd9660_readlink(ap)
/*
* return with the symbolic name to caller's.
*/
- error = uiomove(symname,symlen,ap->a_uio);
-
- FREE(symname,M_NAMEI);
-
- return error;
+ if (uio->uio_segflg != UIO_SYSSPACE) {
+ error = uiomove(symname, symlen, uio);
+ FREE(symname, M_NAMEI);
+ return (error);
+ }
+ uio->uio_resid -= symlen;
+ uio->uio_iov->iov_base += symlen;
+ uio->uio_iov->iov_len -= symlen;
+ return (0);
}
/*
@@ -734,7 +871,7 @@ cd9660_abortop(ap)
{
if ((ap->a_cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF)
FREE(ap->a_cnp->cn_pnbuf, M_NAMEI);
- return 0;
+ return (0);
}
/*
@@ -744,12 +881,14 @@ int
cd9660_lock(ap)
struct vop_lock_args /* {
struct vnode *a_vp;
+ int a_flags;
+ struct proc *a_p;
} */ *ap;
{
- register struct iso_node *ip = VTOI(ap->a_vp);
+ struct vnode *vp = ap->a_vp;
- ISO_ILOCK(ip);
- return 0;
+ return (lockmgr(&VTOI(vp)->i_lock, ap->a_flags, &vp->v_interlock,
+ ap->a_p));
}
/*
@@ -759,29 +898,14 @@ int
cd9660_unlock(ap)
struct vop_unlock_args /* {
struct vnode *a_vp;
+ int a_flags;
+ struct proc *a_p;
} */ *ap;
{
- register struct iso_node *ip = VTOI(ap->a_vp);
-
- if (!(ip->i_flag & ILOCKED))
- panic("cd9660_unlock NOT LOCKED");
- ISO_IUNLOCK(ip);
- return 0;
-}
-
-/*
- * Check for a locked inode.
- */
-int
-cd9660_islocked(ap)
- struct vop_islocked_args /* {
- struct vnode *a_vp;
- } */ *ap;
-{
+ struct vnode *vp = ap->a_vp;
- if (VTOI(ap->a_vp)->i_flag & ILOCKED)
- return 1;
- return 0;
+ return (lockmgr(&VTOI(vp)->i_lock, ap->a_flags | LK_RELEASE,
+ &vp->v_interlock, ap->a_p));
}
/*
@@ -832,60 +956,104 @@ cd9660_print(ap)
struct vnode *a_vp;
} */ *ap;
{
+
printf("tag VT_ISOFS, isofs vnode\n");
- return 0;
+ return (0);
}
/*
- * Unsupported operation
+ * Check for a locked inode.
*/
int
-cd9660_enotsupp()
+cd9660_islocked(ap)
+ struct vop_islocked_args /* {
+ struct vnode *a_vp;
+ } */ *ap;
{
- return (EOPNOTSUPP);
+ return (lockstatus(&VTOI(ap->a_vp)->i_lock));
+}
+
+/*
+ * Return POSIX pathconf information applicable to cd9660 filesystems.
+ */
+int
+cd9660_pathconf(ap)
+ struct vop_pathconf_args /* {
+ struct vnode *a_vp;
+ int a_name;
+ register_t *a_retval;
+ } */ *ap;
+{
+
+ switch (ap->a_name) {
+ case _PC_LINK_MAX:
+ *ap->a_retval = 1;
+ return (0);
+ case _PC_NAME_MAX:
+ if (VTOI(ap->a_vp)->i_mnt->iso_ftype == ISO_FTYPE_RRIP)
+ *ap->a_retval = NAME_MAX;
+ else
+ *ap->a_retval = 37;
+ return (0);
+ case _PC_PATH_MAX:
+ *ap->a_retval = PATH_MAX;
+ return (0);
+ case _PC_PIPE_BUF:
+ *ap->a_retval = PIPE_BUF;
+ return (0);
+ case _PC_CHOWN_RESTRICTED:
+ *ap->a_retval = 1;
+ return (0);
+ case _PC_NO_TRUNC:
+ *ap->a_retval = 1;
+ return (0);
+ default:
+ return (EINVAL);
+ }
+ /* NOTREACHED */
}
/*
* Global vfs data structures for isofs
*/
#define cd9660_create \
- ((int (*) __P((struct vop_create_args *)))cd9660_enotsupp)
-#define cd9660_mknod ((int (*) __P((struct vop_mknod_args *)))cd9660_enotsupp)
-#define cd9660_setattr \
- ((int (*) __P((struct vop_setattr_args *)))cd9660_enotsupp)
-#define cd9660_write ((int (*) __P((struct vop_write_args *)))cd9660_enotsupp)
+ ((int (*) __P((struct vop_create_args *)))eopnotsupp)
+#define cd9660_mknod ((int (*) __P((struct vop_mknod_args *)))eopnotsupp)
+#define cd9660_write ((int (*) __P((struct vop_write_args *)))eopnotsupp)
+#ifdef NFS
+int lease_check __P((struct vop_lease_args *));
+#define cd9660_lease_check lease_check
+#else
+#define cd9660_lease_check ((int (*) __P((struct vop_lease_args *)))nullop)
+#endif
#define cd9660_fsync ((int (*) __P((struct vop_fsync_args *)))nullop)
#define cd9660_remove \
- ((int (*) __P((struct vop_remove_args *)))cd9660_enotsupp)
-#define cd9660_link ((int (*) __P((struct vop_link_args *)))cd9660_enotsupp)
+ ((int (*) __P((struct vop_remove_args *)))eopnotsupp)
+#define cd9660_link ((int (*) __P((struct vop_link_args *)))eopnotsupp)
#define cd9660_rename \
- ((int (*) __P((struct vop_rename_args *)))cd9660_enotsupp)
-#define cd9660_mkdir ((int (*) __P((struct vop_mkdir_args *)))cd9660_enotsupp)
-#define cd9660_rmdir ((int (*) __P((struct vop_rmdir_args *)))cd9660_enotsupp)
+ ((int (*) __P((struct vop_rename_args *)))eopnotsupp)
+#define cd9660_mkdir ((int (*) __P((struct vop_mkdir_args *)))eopnotsupp)
+#define cd9660_rmdir ((int (*) __P((struct vop_rmdir_args *)))eopnotsupp)
#define cd9660_symlink \
- ((int (*) __P((struct vop_symlink_args *)))cd9660_enotsupp)
-#define cd9660_pathconf \
- ((int (*) __P((struct vop_pathconf_args *)))cd9660_enotsupp)
+ ((int (*) __P((struct vop_symlink_args *)))eopnotsupp)
#define cd9660_advlock \
- ((int (*) __P((struct vop_advlock_args *)))cd9660_enotsupp)
-#define cd9660_blkatoff \
- ((int (*) __P((struct vop_blkatoff_args *)))cd9660_enotsupp)
+ ((int (*) __P((struct vop_advlock_args *)))eopnotsupp)
#define cd9660_valloc ((int(*) __P(( \
struct vnode *pvp, \
int mode, \
struct ucred *cred, \
- struct vnode **vpp))) cd9660_enotsupp)
-#define cd9660_vfree ((int (*) __P((struct vop_vfree_args *)))cd9660_enotsupp)
+ struct vnode **vpp))) eopnotsupp)
+#define cd9660_vfree ((int (*) __P((struct vop_vfree_args *)))eopnotsupp)
#define cd9660_truncate \
- ((int (*) __P((struct vop_truncate_args *)))cd9660_enotsupp)
+ ((int (*) __P((struct vop_truncate_args *)))eopnotsupp)
#define cd9660_update \
- ((int (*) __P((struct vop_update_args *)))cd9660_enotsupp)
+ ((int (*) __P((struct vop_update_args *)))eopnotsupp)
#define cd9660_bwrite \
- ((int (*) __P((struct vop_bwrite_args *)))cd9660_enotsupp)
+ ((int (*) __P((struct vop_bwrite_args *)))eopnotsupp)
/*
- * Global vfs data structures for nfs
+ * Global vfs data structures for cd9660
*/
int (**cd9660_vnodeop_p)();
struct vnodeopv_entry_desc cd9660_vnodeop_entries[] = {
@@ -900,8 +1068,10 @@ struct vnodeopv_entry_desc cd9660_vnodeop_entries[] = {
{ &vop_setattr_desc, cd9660_setattr }, /* setattr */
{ &vop_read_desc, cd9660_read }, /* read */
{ &vop_write_desc, cd9660_write }, /* write */
+ { &vop_lease_desc, cd9660_lease_check },/* lease */
{ &vop_ioctl_desc, cd9660_ioctl }, /* ioctl */
{ &vop_select_desc, cd9660_select }, /* select */
+ { &vop_revoke_desc, cd9660_revoke }, /* revoke */
{ &vop_mmap_desc, cd9660_mmap }, /* mmap */
{ &vop_fsync_desc, cd9660_fsync }, /* fsync */
{ &vop_seek_desc, cd9660_seek }, /* seek */
@@ -942,8 +1112,8 @@ int (**cd9660_specop_p)();
struct vnodeopv_entry_desc cd9660_specop_entries[] = {
{ &vop_default_desc, vn_default_error },
{ &vop_lookup_desc, spec_lookup }, /* lookup */
- { &vop_create_desc, cd9660_create }, /* create */
- { &vop_mknod_desc, cd9660_mknod }, /* mknod */
+ { &vop_create_desc, spec_create }, /* create */
+ { &vop_mknod_desc, spec_mknod }, /* mknod */
{ &vop_open_desc, spec_open }, /* open */
{ &vop_close_desc, spec_close }, /* close */
{ &vop_access_desc, cd9660_access }, /* access */
@@ -951,17 +1121,19 @@ struct vnodeopv_entry_desc cd9660_specop_entries[] = {
{ &vop_setattr_desc, cd9660_setattr }, /* setattr */
{ &vop_read_desc, spec_read }, /* read */
{ &vop_write_desc, spec_write }, /* write */
+ { &vop_lease_desc, spec_lease_check }, /* lease */
{ &vop_ioctl_desc, spec_ioctl }, /* ioctl */
{ &vop_select_desc, spec_select }, /* select */
+ { &vop_revoke_desc, spec_revoke }, /* revoke */
{ &vop_mmap_desc, spec_mmap }, /* mmap */
{ &vop_fsync_desc, spec_fsync }, /* fsync */
{ &vop_seek_desc, spec_seek }, /* seek */
- { &vop_remove_desc, cd9660_remove }, /* remove */
- { &vop_link_desc, cd9660_link }, /* link */
- { &vop_rename_desc, cd9660_rename }, /* rename */
- { &vop_mkdir_desc, cd9660_mkdir }, /* mkdir */
- { &vop_rmdir_desc, cd9660_rmdir }, /* rmdir */
- { &vop_symlink_desc, cd9660_symlink }, /* symlink */
+ { &vop_remove_desc, spec_remove }, /* remove */
+ { &vop_link_desc, spec_link }, /* link */
+ { &vop_rename_desc, spec_rename }, /* rename */
+ { &vop_mkdir_desc, spec_mkdir }, /* mkdir */
+ { &vop_rmdir_desc, spec_rmdir }, /* rmdir */
+ { &vop_symlink_desc, spec_symlink }, /* symlink */
{ &vop_readdir_desc, spec_readdir }, /* readdir */
{ &vop_readlink_desc, spec_readlink }, /* readlink */
{ &vop_abortop_desc, spec_abortop }, /* abortop */
@@ -970,8 +1142,7 @@ struct vnodeopv_entry_desc cd9660_specop_entries[] = {
{ &vop_lock_desc, cd9660_lock }, /* lock */
{ &vop_unlock_desc, cd9660_unlock }, /* unlock */
{ &vop_bmap_desc, spec_bmap }, /* bmap */
- /* XXX strategy: panics, should be notsupp instead? */
- { &vop_strategy_desc, cd9660_strategy },/* strategy */
+ { &vop_strategy_desc, spec_strategy }, /* strategy */
{ &vop_print_desc, cd9660_print }, /* print */
{ &vop_islocked_desc, cd9660_islocked },/* islocked */
{ &vop_pathconf_desc, spec_pathconf }, /* pathconf */
@@ -992,8 +1163,8 @@ int (**cd9660_fifoop_p)();
struct vnodeopv_entry_desc cd9660_fifoop_entries[] = {
{ &vop_default_desc, vn_default_error },
{ &vop_lookup_desc, fifo_lookup }, /* lookup */
- { &vop_create_desc, cd9660_create }, /* create */
- { &vop_mknod_desc, cd9660_mknod }, /* mknod */
+ { &vop_create_desc, fifo_create }, /* create */
+ { &vop_mknod_desc, fifo_mknod }, /* mknod */
{ &vop_open_desc, fifo_open }, /* open */
{ &vop_close_desc, fifo_close }, /* close */
{ &vop_access_desc, cd9660_access }, /* access */
@@ -1001,17 +1172,19 @@ struct vnodeopv_entry_desc cd9660_fifoop_entries[] = {
{ &vop_setattr_desc, cd9660_setattr }, /* setattr */
{ &vop_read_desc, fifo_read }, /* read */
{ &vop_write_desc, fifo_write }, /* write */
+ { &vop_lease_desc, fifo_lease_check }, /* lease */
{ &vop_ioctl_desc, fifo_ioctl }, /* ioctl */
{ &vop_select_desc, fifo_select }, /* select */
+ { &vop_revoke_desc, fifo_revoke }, /* revoke */
{ &vop_mmap_desc, fifo_mmap }, /* mmap */
{ &vop_fsync_desc, fifo_fsync }, /* fsync */
{ &vop_seek_desc, fifo_seek }, /* seek */
- { &vop_remove_desc, cd9660_remove }, /* remove */
- { &vop_link_desc, cd9660_link }, /* link */
- { &vop_rename_desc, cd9660_rename }, /* rename */
- { &vop_mkdir_desc, cd9660_mkdir }, /* mkdir */
- { &vop_rmdir_desc, cd9660_rmdir }, /* rmdir */
- { &vop_symlink_desc, cd9660_symlink }, /* symlink */
+ { &vop_remove_desc, fifo_remove }, /* remove */
+ { &vop_link_desc, fifo_link } , /* link */
+ { &vop_rename_desc, fifo_rename }, /* rename */
+ { &vop_mkdir_desc, fifo_mkdir }, /* mkdir */
+ { &vop_rmdir_desc, fifo_rmdir }, /* rmdir */
+ { &vop_symlink_desc, fifo_symlink }, /* symlink */
{ &vop_readdir_desc, fifo_readdir }, /* readdir */
{ &vop_readlink_desc, fifo_readlink }, /* readlink */
{ &vop_abortop_desc, fifo_abortop }, /* abortop */
@@ -1020,7 +1193,7 @@ struct vnodeopv_entry_desc cd9660_fifoop_entries[] = {
{ &vop_lock_desc, cd9660_lock }, /* lock */
{ &vop_unlock_desc, cd9660_unlock }, /* unlock */
{ &vop_bmap_desc, fifo_bmap }, /* bmap */
- { &vop_strategy_desc, fifo_badop }, /* strategy */
+ { &vop_strategy_desc, fifo_strategy }, /* strategy */
{ &vop_print_desc, cd9660_print }, /* print */
{ &vop_islocked_desc, cd9660_islocked },/* islocked */
{ &vop_pathconf_desc, fifo_pathconf }, /* pathconf */
diff --git a/sys/isofs/cd9660/iso.h b/sys/isofs/cd9660/iso.h
index e356706..c42bc08 100644
--- a/sys/isofs/cd9660/iso.h
+++ b/sys/isofs/cd9660/iso.h
@@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#)iso.h 8.2 (Berkeley) 1/23/94
+ * @(#)iso.h 8.6 (Berkeley) 5/10/95
*/
#define ISODCL(from, to) (to - from + 1)
@@ -94,37 +94,37 @@ struct iso_primary_descriptor {
struct iso_directory_record {
char length [ISODCL (1, 1)]; /* 711 */
char ext_attr_length [ISODCL (2, 2)]; /* 711 */
- unsigned char extent [ISODCL (3, 10)]; /* 733 */
- unsigned char size [ISODCL (11, 18)]; /* 733 */
+ u_char extent [ISODCL (3, 10)]; /* 733 */
+ u_char size [ISODCL (11, 18)]; /* 733 */
char date [ISODCL (19, 25)]; /* 7 by 711 */
char flags [ISODCL (26, 26)];
char file_unit_size [ISODCL (27, 27)]; /* 711 */
char interleave [ISODCL (28, 28)]; /* 711 */
char volume_sequence_number [ISODCL (29, 32)]; /* 723 */
char name_len [ISODCL (33, 33)]; /* 711 */
- char name [0];
+ char name [1]; /* XXX */
};
/* can't take sizeof(iso_directory_record), because of possible alignment
of the last entry (34 instead of 33) */
#define ISO_DIRECTORY_RECORD_SIZE 33
struct iso_extended_attributes {
- unsigned char owner [ISODCL (1, 4)]; /* 723 */
- unsigned char group [ISODCL (5, 8)]; /* 723 */
- unsigned char perm [ISODCL (9, 10)]; /* 9.5.3 */
+ u_char owner [ISODCL (1, 4)]; /* 723 */
+ u_char group [ISODCL (5, 8)]; /* 723 */
+ u_char perm [ISODCL (9, 10)]; /* 9.5.3 */
char ctime [ISODCL (11, 27)]; /* 8.4.26.1 */
char mtime [ISODCL (28, 44)]; /* 8.4.26.1 */
char xtime [ISODCL (45, 61)]; /* 8.4.26.1 */
char ftime [ISODCL (62, 78)]; /* 8.4.26.1 */
char recfmt [ISODCL (79, 79)]; /* 711 */
char recattr [ISODCL (80, 80)]; /* 711 */
- unsigned char reclen [ISODCL (81, 84)]; /* 723 */
+ u_char reclen [ISODCL (81, 84)]; /* 723 */
char system_id [ISODCL (85, 116)]; /* achars */
char system_use [ISODCL (117, 180)];
char version [ISODCL (181, 181)]; /* 711 */
char len_esc [ISODCL (182, 182)]; /* 711 */
char reserved [ISODCL (183, 246)];
- unsigned char len_au [ISODCL (247, 250)]; /* 723 */
+ u_char len_au [ISODCL (247, 250)]; /* 723 */
};
/* CD-ROM Format type */
@@ -146,7 +146,6 @@ struct iso_mnt {
int im_bmask;
int volume_space_size;
- char im_fsmnt[50];
struct netexport im_export;
char root[ISODCL (157, 190)];
@@ -160,10 +159,10 @@ struct iso_mnt {
#define VFSTOISOFS(mp) ((struct iso_mnt *)((mp)->mnt_data))
-#define iso_blkoff(imp, loc) ((loc) & (imp)->im_bmask)
-#define iso_lblkno(imp, loc) ((loc) >> (imp)->im_bshift)
-#define iso_blksize(imp, ip, lbn) ((imp)->logical_block_size)
-#define iso_lblktosize(imp, blk) ((blk) << (imp)->im_bshift)
+#define blkoff(imp, loc) ((loc) & (imp)->im_bmask)
+#define lblktosize(imp, blk) ((blk) << (imp)->im_bshift)
+#define lblkno(imp, loc) ((loc) >> (imp)->im_bshift)
+#define blksize(imp, ip, lbn) ((imp)->logical_block_size)
int cd9660_mount __P((struct mount *,
char *, caddr_t, struct nameidata *, struct proc *));
@@ -177,78 +176,91 @@ int cd9660_vget __P((struct mount *, ino_t, struct vnode **));
int cd9660_fhtovp __P((struct mount *, struct fid *, struct mbuf *,
struct vnode **, int *, struct ucred **));
int cd9660_vptofh __P((struct vnode *, struct fid *));
-int cd9660_init __P(());
-
-struct iso_node;
-int iso_blkatoff __P((struct iso_node *ip, long offset, struct buf **bpp));
-int iso_iget __P((struct iso_node *xp, ino_t ino, int relocated,
- struct iso_node **ipp, struct iso_directory_record *isodir));
-int iso_iput __P((struct iso_node *ip));
-int iso_ilock __P((struct iso_node *ip));
-int iso_iunlock __P((struct iso_node *ip));
+int cd9660_init __P((struct vfsconf *));
+#define cd9660_sysctl ((int (*) __P((int *, u_int, void *, size_t *, void *, \
+ size_t, struct proc *)))eopnotsupp)
+
int cd9660_mountroot __P((void));
extern int (**cd9660_vnodeop_p)();
+extern int (**cd9660_specop_p)();
+#ifdef FIFO
+extern int (**cd9660_fifoop_p)();
+#endif
-extern inline int
+static __inline int
isonum_711(p)
- unsigned char *p;
+ u_char *p;
{
return *p;
}
-extern inline int
+static __inline int
isonum_712(p)
char *p;
{
return *p;
}
-extern inline int
-isonum_721(p)
- unsigned char *p;
+#ifndef UNALIGNED_ACCESS
+
+static __inline int
+isonum_723(p)
+ u_char *p;
{
- return *p|((char)p[1] << 8);
+ return *p|(p[1] << 8);
}
-extern inline int
-isonum_722(p)
- unsigned char *p;
+static __inline int
+isonum_733(p)
+ u_char *p;
{
- return ((char)*p << 8)|p[1];
+ return *p|(p[1] << 8)|(p[2] << 16)|(p[3] << 24);
}
-extern inline int
+#else /* UNALIGNED_ACCESS */
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+
+static __inline int
isonum_723(p)
- unsigned char *p;
+ u_char *p
{
- return isonum_721(p);
+ return *(u_int16t *)p;
}
-extern inline int
-isonum_731(p)
- unsigned char *p;
+static __inline int
+isonum_733(p)
+ u_char *p;
{
- return *p|(p[1] << 8)|(p[2] << 16)|(p[3] << 24);
+ return *(u_int32t *)p;
}
-extern inline int
-isonum_732(p)
- unsigned char *p;
+#endif
+
+#if BYTE_ORDER == BIG_ENDIAN
+
+static __inline int
+isonum_723(p)
+ u_char *p
{
- return (*p << 24)|(p[1] << 16)|(p[2] << 8)|p[3];
+ return *(u_int16t *)(p + 2);
}
-extern inline int
+static __inline int
isonum_733(p)
- unsigned char *p;
+ u_char *p;
{
- return isonum_731(p);
+ return *(u_int32t *)(p + 4);
}
-int isofncmp __P((unsigned char *, int, unsigned char *, int));
-void isofntrans __P((unsigned char *, int, unsigned char *, unsigned short *,
- int, int));
+#endif
+
+#endif /* UNALIGNED_ACCESS */
+
+int isofncmp __P((u_char *, int, u_char *, int));
+void isofntrans __P((u_char *, int, u_char *, u_short *, int, int));
+ino_t isodirino __P((struct iso_directory_record *, struct iso_mnt *));
/*
* Associated files have a leading '='.
OpenPOWER on IntegriCloud