summaryrefslogtreecommitdiffstats
path: root/sys/fs/cd9660
diff options
context:
space:
mode:
authordyson <dyson@FreeBSD.org>1997-02-10 02:22:35 +0000
committerdyson <dyson@FreeBSD.org>1997-02-10 02:22:35 +0000
commit10f666af84d48e89e4e2960415c9b616fce4077f (patch)
tree88a944de263165091f0a18abeedbaaccec532407 /sys/fs/cd9660
parent0960d7e91af3428ffba89b42228d82d8afaa0389 (diff)
downloadFreeBSD-src-10f666af84d48e89e4e2960415c9b616fce4077f.zip
FreeBSD-src-10f666af84d48e89e4e2960415c9b616fce4077f.tar.gz
This is the kernel Lite/2 commit. There are some requisite userland
changes, so don't expect to be able to run the kernel as-is (very well) without the appropriate Lite/2 userland changes. The system boots and can mount UFS filesystems. Untested: ext2fs, msdosfs, NFS Known problems: Incorrect Berkeley ID strings in some files. Mount_std mounts will not work until the getfsent library routine is changed. Reviewed by: various people Submitted by: Jeffery Hsu <hsu@freebsd.org>
Diffstat (limited to 'sys/fs/cd9660')
-rw-r--r--sys/fs/cd9660/TODO30
-rw-r--r--sys/fs/cd9660/cd9660_bmap.c12
-rw-r--r--sys/fs/cd9660/cd9660_lookup.c173
-rw-r--r--sys/fs/cd9660/cd9660_node.c462
-rw-r--r--sys/fs/cd9660/cd9660_node.h36
-rw-r--r--sys/fs/cd9660/cd9660_rrip.c76
-rw-r--r--sys/fs/cd9660/cd9660_rrip.h48
-rw-r--r--sys/fs/cd9660/cd9660_util.c107
-rw-r--r--sys/fs/cd9660/cd9660_vfsops.c448
-rw-r--r--sys/fs/cd9660/cd9660_vnops.c721
-rw-r--r--sys/fs/cd9660/iso.h135
11 files changed, 1095 insertions, 1153 deletions
diff --git a/sys/fs/cd9660/TODO b/sys/fs/cd9660/TODO
index eb24a23..71859c7 100644
--- a/sys/fs/cd9660/TODO
+++ b/sys/fs/cd9660/TODO
@@ -25,16 +25,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;
@@ -57,23 +47,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/fs/cd9660/cd9660_bmap.c b/sys/fs/cd9660/cd9660_bmap.c
index 6fffe7a..71dfb9e 100644
--- a/sys/fs/cd9660/cd9660_bmap.c
+++ b/sys/fs/cd9660/cd9660_bmap.c
@@ -67,7 +67,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
@@ -81,8 +81,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
@@ -91,11 +91,11 @@ 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;
}
diff --git a/sys/fs/cd9660/cd9660_lookup.c b/sys/fs/cd9660/cd9660_lookup.c
index 6e85a81..a7e38bb 100644
--- a/sys/fs/cd9660/cd9660_lookup.c
+++ b/sys/fs/cd9660/cd9660_lookup.c
@@ -108,8 +108,9 @@ cd9660_lookup(ap)
int saveoffset = 0; /* 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;
@@ -126,6 +127,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;
@@ -139,13 +141,13 @@ cd9660_lookup(ap)
* Check accessiblity of directory.
*/
if (vdp->v_type != VDIR)
- return (ENOTDIR);
- if ((error = VOP_ACCESS(vdp, VEXEC, cred, cnp->cn_proc)))
+ 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.
*
@@ -160,29 +162,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
@@ -191,13 +193,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;
}
@@ -223,6 +226,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;
@@ -230,16 +234,14 @@ 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) {
/*
@@ -247,10 +249,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;
}
@@ -258,13 +261,13 @@ searchloop:
* 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 */
dp->i_offset =
- roundup(dp->i_offset, imp->logical_block_size);
+ (dp->i_offset & ~bmask) + imp->logical_block_size;
continue;
}
@@ -275,10 +278,7 @@ searchloop:
if (entryoffsetinblock + reclen > imp->logical_block_size)
/* entries are not allowed to cross boundaries */
break;
-
- /*
- * Check for a name match.
- */
+
namelen = isonum_711(ep->name_len);
isoflags = isonum_711(imp->iso_ftype == ISO_FTYPE_HIGH_SIERRA?
&ep->date[6]: ep->flags);
@@ -286,7 +286,10 @@ searchloop:
if (reclen < ISO_DIRECTORY_RECORD_SIZE + namelen)
/* illegal entry, stop */
break;
-
+
+ /*
+ * Check for a name match.
+ */
switch (imp->iso_ftype) {
default:
if (!(isoflags & 4) == !assoc) {
@@ -297,10 +300,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
@@ -308,8 +310,8 @@ searchloop:
goto notfound;
} else if (!(res = isofncmp(name,len,
ep->name,namelen))) {
- if (isoflags & 2)
- isodirino(&ino,ep,imp);
+ if (isonum_711(ep->flags)&2)
+ ino = isodirino(ep, imp);
else
ino = dbtob(bp->b_blkno)
+ entryoffsetinblock;
@@ -326,7 +328,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;
@@ -344,15 +346,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;
@@ -370,6 +374,7 @@ notfound:
}
if (bp != NULL)
brelse(bp);
+
/*
* Insert name into cache (as non-existent) if appropriate.
*/
@@ -382,9 +387,7 @@ notfound:
found:
if (numdirpasses == 2)
iso_nchstats.ncs_pass2++;
- if (bp != NULL)
- brelse(bp);
-
+
/*
* Found component in pathname.
* If the final component of path name, save information
@@ -412,31 +415,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))
- ISO_ILOCK(pdp);
- *vpp = ITOV(tdp);
+ if (lockparent && (flags & ISLASTCN) &&
+ (error = vn_lock(pdp, LK_EXCLUSIVE, p))) {
+ vput(tdp);
+ return (error);
+ }
+ *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;
}
/*
@@ -448,29 +459,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.
*/
int
-iso_blkatoff(ip, offset, bpp)
- struct iso_node *ip;
- doff_t offset;
- struct buf **bpp;
+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;
- if ((error = bread(ITOV(ip),lbn,bsize,NOCRED,&bp))) {
+ ip = VTOI(ap->a_vp);
+ imp = ip->i_mnt;
+ lbn = lblkno(imp, ap->a_offset);
+ bsize = blksize(imp, ip, lbn);
+
+ 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/fs/cd9660/cd9660_node.c b/sys/fs/cd9660/cd9660_node.c
index c3f0911..c726696 100644
--- a/sys/fs/cd9660/cd9660_node.c
+++ b/sys/fs/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
@@ -52,32 +52,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
-
-union iso_dhead {
- union iso_dhead *dh_head[2];
- struct iso_dnode *dh_chain[2];
-} iso_dhead[DNOHSZ];
+/*
+ * 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;
+
+#ifdef ISODEVMAP
+struct iso_node **idvhashtbl;
+u_long idvhash;
+#define DNOHASH(device, inum) (((device) + ((inum)>>12)) & idvhash)
#endif
static unsigned cd9660_chars2ui __P((unsigned char *begin, int len));
@@ -86,73 +75,68 @@ static unsigned cd9660_chars2ui __P((unsigned char *begin, int len));
* Initialize hash links for inodes and dnodes.
*/
int
-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
return (0);
}
-#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;
+ register struct iso_dnode **dpp, *dp, *dq;
- 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;
+ 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;
-
- 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);
+ struct iso_dnode **dpp, *dp, *dq;
+
+ 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);
}
}
}
@@ -160,197 +144,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.
*/
-int
-iso_iget(xp, ino, relocated, ipp, isodir)
- struct iso_node *xp;
- ino_t ino;
- int relocated;
- 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;
-#ifdef ISODEVMAP
- register struct iso_dnode *dp;
-#endif
- struct vnode *nvp;
- struct buf *bp = NULL, *bp2 = NULL;
- union iso_ihead *ih;
- int error, result;
- struct iso_mnt *imp;
+ struct proc *p = curproc; /* XXX */
+ struct iso_node *ip;
+ struct vnode *vp;
- ih = &iso_ihead[INOHASH(dev, ino)];
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;
- (void) tsleep((caddr_t)ip, PINOD, "isoigt", 0);
- goto loop;
- }
- if (vget(ITOV(ip), 1))
- goto loop;
- *ipp = ip;
- return 0;
- }
-
- /*
- * Do the MALLOC before the getnewvnode since doing so afterward
- * might cause a bogus v_data pointer to get dereferenced
- * elsewhere if MALLOC should block.
- */
- MALLOC(ip, struct iso_node *, sizeof(struct iso_node), M_ISOFSNODE, M_WAITOK);
-
- /*
- * Allocate a new vnode/iso_node.
- */
- if ((error = getnewvnode(VT_ISOFS, mntp, cd9660_vnodeop_p, &nvp))) {
- *ipp = NULL;
- FREE(ip, M_ISOFSNODE);
- return error;
- }
- 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);
-
- 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 || ISO_FTYPE_HIGH_SIERRA */
- 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,imp->iso_ftype );
- cd9660_deftstamp(isodir,ip,bp2,imp->iso_ftype );
- 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 ) {
- vp->v_op = cd9660_fifoop_p;
- } else if ( vp->v_type == VCHR || vp->v_type == 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, 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;
+ 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);
}
}
+ simple_unlock(&cd9660_ihash_slock);
+ return (NULL);
+}
- if (ip->iso_extent == imp->root_extent)
- vp->v_flag |= VROOT;
-
+/*
+ * 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;
+
+ 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.
*/
-int
-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));
- return (0);
+ 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);
}
/*
@@ -361,9 +222,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 error = 0;
@@ -371,12 +234,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;
}
@@ -387,6 +251,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;
@@ -397,9 +262,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.
*/
@@ -410,46 +273,6 @@ 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.
- */
-int
-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) tsleep((caddr_t)ip, PINOD, "isoilk", 0);
- }
- ip->i_spare1 = 0;
- ip->i_spare0 = curproc->p_pid;
- ip->i_flag |= ILOCKED;
- return (0);
-}
-
-/*
- * Unlock an inode. If WANT bit is on, wakeup.
- */
-int
-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);
}
@@ -457,7 +280,7 @@ iso_iunlock(ip)
* File attributes
*/
void
-cd9660_defattr(isodir,inop,bp,ftype)
+cd9660_defattr(isodir, inop, bp, ftype)
struct iso_directory_record *isodir;
struct iso_node *inop;
struct buf *bp;
@@ -482,14 +305,15 @@ cd9660_defattr(isodir,inop,bp,ftype)
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))
inop->inode.iso_mode |= VEXEC >> 6;
@@ -533,16 +357,16 @@ cd9660_deftstamp(isodir,inop,bp,ftype)
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;
-
- if (ftype != ISO_FTYPE_HIGH_SIERRA
- && isonum_711(ap->version) == 1) {
+ ap = (struct iso_extended_attributes *)bp->b_data;
+
+ if (isonum_711(ap->version) == 1) {
if (!cd9660_tstamp_conv17(ap->ftime,&inop->inode.iso_atime))
cd9660_tstamp_conv17(ap->ctime,&inop->inode.iso_atime);
if (!cd9660_tstamp_conv17(ap->ctime,&inop->inode.iso_ctime))
@@ -563,9 +387,9 @@ cd9660_deftstamp(isodir,inop,bp,ftype)
int
cd9660_tstamp_conv7(pi,pu,ftype)
-char *pi;
-struct timespec *pu;
-enum ISO_FTYPE ftype;
+ u_char *pi;
+ struct timespec *pu;
+ enum ISO_FTYPE ftype;
{
int crtime, days;
int y, m, d, hour, minute, second, tz;
@@ -609,13 +433,13 @@ enum ISO_FTYPE ftype;
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;
rc += *begin++ - '0';
@@ -625,12 +449,12 @@ cd9660_chars2ui(begin,len)
int
cd9660_tstamp_conv17(pi,pu)
- unsigned char *pi;
+ u_char *pi;
struct timespec *pu;
{
- unsigned char buf[7];
-
- /* year:"0001"-"9999" -> -1900 */
+ u_char buf[7];
+
+ /* year:"0001"-"9999" -> -1900 */
buf[0] = cd9660_chars2ui(pi,4) - 1900;
/* month: " 1"-"12" -> 1 - 12 */
@@ -654,12 +478,14 @@ cd9660_tstamp_conv17(pi,pu)
return cd9660_tstamp_conv7(buf, pu, ISO_FTYPE_DEFAULT);
}
-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/fs/cd9660/cd9660_node.h b/sys/fs/cd9660/cd9660_node.h
index 992f9cb..de538fb 100644
--- a/sys/fs/cd9660/cd9660_node.h
+++ b/sys/fs/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
* $FreeBSD$
*/
@@ -59,22 +59,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 */
@@ -87,8 +85,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;
@@ -101,19 +98,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)
-
-extern vop_t **cd9660_fifoop_p;
-extern vop_t **cd9660_specop_p;
-
/*
* Prototypes for ISOFS vnode operations
*/
@@ -121,14 +110,19 @@ int cd9660_lookup __P((struct vop_lookup_args *));
int cd9660_inactive __P((struct vop_inactive_args *));
int cd9660_reclaim __P((struct vop_reclaim_args *));
int cd9660_bmap __P((struct vop_bmap_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 *, enum ISO_FTYPE));
void cd9660_deftstamp __P((struct iso_directory_record *,
struct iso_node *, struct buf *, enum ISO_FTYPE));
-int cd9660_tstamp_conv7 __P((char *pi, struct timespec *pu, enum ISO_FTYPE));
-int cd9660_tstamp_conv17 __P((unsigned char *pi, struct timespec *pu));
-void isodirino __P((ino_t *inump, struct iso_directory_record *isodir,
- struct iso_mnt *imp));
+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 *, enum ISO_FTYPE));
+int cd9660_tstamp_conv17 __P((u_char *, struct timespec *));
#ifdef ISODEVMAP
struct iso_dnode *iso_dmap __P((dev_t, ino_t, int));
void iso_dunmap __P((dev_t));
diff --git a/sys/fs/cd9660/cd9660_rrip.c b/sys/fs/cd9660/cd9660_rrip.c
index 44d52eb..521094f 100644
--- a/sys/fs/cd9660/cd9660_rrip.c
+++ b/sys/fs/cd9660/cd9660_rrip.c
@@ -35,7 +35,7 @@
* 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
* $FreeBSD$
*/
@@ -104,10 +104,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;
}
@@ -352,8 +352,8 @@ cd9660_rrip_tstamp(p,ana)
ISO_RRIP_TSTAMP *p;
ISO_RRIP_ANALYZE *ana;
{
- unsigned char *ptime;
-
+ u_char *ptime;
+
ptime = p->time;
/* Check a format of time stamp (7bytes/17bytes) */
@@ -367,7 +367,7 @@ cd9660_rrip_tstamp(p,ana)
ptime += 7;
} else
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,
ISO_FTYPE_RRIP);
@@ -390,7 +390,7 @@ cd9660_rrip_tstamp(p,ana)
ptime += 17;
} else
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);
ptime += 17;
@@ -423,16 +423,15 @@ cd9660_rrip_device(p,ana)
ISO_RRIP_DEVICE *p;
ISO_RRIP_ANALYZE *ana;
{
- unsigned high, low;
-
- high = isonum_733(p->dev_t_high_l);
- low = isonum_733(p->dev_t_low_l);
-
- if ( high == 0 ) {
- ana->inop->inode.iso_rdev = makedev( major(low), minor(low) );
- } else {
- ana->inop->inode.iso_rdev = makedev( high, minor(low) );
- }
+ u_int high, low;
+
+ 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));
ana->fields &= ~ISO_SUSP_DEVICE;
return ISO_SUSP_DEVICE;
}
@@ -475,8 +474,6 @@ cd9660_rrip_stop(p,ana)
ISO_SUSP_HEADER *p;
ISO_RRIP_ANALYZE *ana;
{
- /* stop analyzing */
- ana->fields = 0;
return ISO_SUSP_STOP;
}
@@ -545,22 +542,30 @@ 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
*/
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,
- iso_lblktodaddr(ana->imp, ana->iso_ce_blk),
- 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;
@@ -569,7 +574,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))
@@ -579,6 +584,9 @@ cd9660_rrip_loop(isodir,ana,table)
}
/*
+ * Get Attributes.
+ */
+/*
* XXX the casts are bogus but will do for now.
*/
#define BC (rrt_func_t *)
@@ -607,10 +615,8 @@ cd9660_rrip_analyze(isodir,inop,imp)
return cd9660_rrip_loop(isodir,&analyze,rrip_table_analyze);
}
-/*
- * 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", BC cd9660_rrip_altname, cd9660_rrip_defname, ISO_SUSP_ALTNAME },
@@ -654,10 +660,8 @@ cd9660_rrip_getname(isodir,outbuf,outlen,inump,imp)
return cd9660_rrip_loop(isodir,&analyze,tab);
}
-/*
- * Get Symbolic Name from 'SL' record
- *
- * Note: isodir should contains SL record!
+/*
+ * Get Symbolic Link.
*/
static RRIP_TABLE rrip_table_getsymname[] = {
{ "SL", BC cd9660_rrip_slink, 0, ISO_SUSP_SLINK },
@@ -696,7 +700,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/fs/cd9660/cd9660_rrip.h b/sys/fs/cd9660/cd9660_rrip.h
index e65fb3b..cacee39 100644
--- a/sys/fs/cd9660/cd9660_rrip.h
+++ b/sys/fs/cd9660/cd9660_rrip.h
@@ -35,36 +35,30 @@
* 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
- * $FreeBSD$
+ * @(#)cd9660_rrip.h 8.2 (Berkeley) 12/5/94
+ * $Id: cd9660_rrip.h,v 1.3.2000.1 1996/09/30 12:46:48 dfr Exp $
*/
-
+
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
#define ISO_SUSP_CFLAG_CURRENT 0x02
#define ISO_SUSP_CFLAG_PARENT 0x04
@@ -73,9 +67,9 @@ typedef struct {
#define ISO_SUSP_CFLAG_HOST 0x20
typedef struct {
- u_char cflag [ISODCL ( 1, 1)];
- u_char clen [ISODCL ( 2, 2)];
- u_char name [0];
+ u_char cflag [ISODCL ( 1, 1)];
+ u_char clen [ISODCL ( 2, 2)];
+ u_char name [1]; /* XXX */
} ISO_RRIP_SLINK_COMPONENT;
#define ISO_RRIP_SLSIZ 2
@@ -116,13 +110,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/fs/cd9660/cd9660_util.c b/sys/fs/cd9660/cd9660_util.c
index 786d4fd..151d1c3 100644
--- a/sys/fs/cd9660/cd9660_util.c
+++ b/sys/fs/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
* $FreeBSD$
*/
@@ -58,104 +58,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;
unsigned char c;
@@ -211,9 +121,12 @@ 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;
diff --git a/sys/fs/cd9660/cd9660_vfsops.c b/sys/fs/cd9660/cd9660_vfsops.c
index 752a7b4..15eade4 100644
--- a/sys/fs/cd9660/cd9660_vfsops.c
+++ b/sys/fs/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
* $FreeBSD$
*/
@@ -52,10 +52,12 @@
#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/iso_rrip.h>
+#include <isofs/cd9660/cd9660_node.h>
+#include <isofs/cd9660/cd9660_mount.h>
static int cd9660_mount __P((struct mount *,
@@ -84,17 +86,14 @@ static struct vfsops cd9660_vfsops = {
cd9660_vget,
cd9660_fhtovp,
cd9660_vptofh,
- cd9660_init,
+ cd9660_init
};
VFS_SET(cd9660_vfsops, cd9660, MOUNT_CD9660, VFCF_READONLY);
/*
* 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 int iso_mountfs __P((struct vnode *devvp, struct mount *mp,
struct proc *p, struct iso_args *argp));
@@ -102,55 +101,38 @@ static int iso_mountfs __P((struct vnode *devvp, struct mount *mp,
int
cd9660_mountroot()
{
- register struct mount *mp;
+ struct mount *mp;
struct proc *p = curproc; /* XXX */
- struct iso_mnt *imp;
- u_int size;
- int error;
struct iso_args args;
-
+ int error;
+
/*
* Get vnode for rootdev.
*/
- if (bdevvp(rootdev, &rootvp))
- panic("cd9660_mountroot: can't setup bdevvp for rootdev");
-
- 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;
- args.flags = ISOFSMNT_ROOT;
- if ((error = iso_mountfs(rootvp, mp, p, &args))) {
- free(mp, M_MOUNT);
+ if ((error = bdevvp(swapdev, &swapdev_vp)) ||
+ (error = bdevvp(rootdev, &rootvp))) {
+ printf("cd9660_mountroot: can't setup bdevvp's");
return (error);
}
- if ((error = vfs_lock(mp))) {
- (void)cd9660_unmount(mp, 0, p);
+
+ 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);
}
+ simple_lock(&mountlist_slock);
CIRCLEQ_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_unlock(&mountlist_slock);
+ (void)cd9660_statfs(mp, &mp->mnt_stat, p);
+ vfs_unbusy(mp, p);
return (0);
}
/*
- * Flag to allow forcible unmounting.
- */
-static int iso_doforce = 1;
-
-/*
* VFS Operations.
*
* mount system call
@@ -214,10 +196,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);
@@ -277,11 +257,11 @@ 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) {
if (bcmp (vdp->id_sierra, ISO_SIERRA_ID,
sizeof vdp->id) != 0) {
@@ -347,7 +327,7 @@ 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;
@@ -358,14 +338,14 @@ 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;
} else {
@@ -436,12 +416,9 @@ cd9660_unmount(mp, mntflags, p)
{
register struct iso_mnt *isomp;
int error, flags = 0;
-
- if (mntflags & MNT_FORCE) {
- if (!iso_doforce)
- return (EINVAL);
+
+ if (mntflags & MNT_FORCE)
flags |= FORCECLOSE;
- }
#if 0
mntflushbuf(mp, 0);
if (mntinvalbuf(mp))
@@ -474,33 +451,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));
}
/*
@@ -541,10 +502,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;
@@ -563,21 +522,6 @@ cd9660_sync(mp, waitfor, cred, p)
}
/*
- * Flat namespace lookup.
- * Currently unsupported.
- */
-/* ARGSUSED */
-static 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:
@@ -604,92 +548,262 @@ 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);
}
+ *vpp = nvp;
+ *exflagsp = np->netc_exflags;
+ *credanonp = &np->netc_anon;
+ return (0);
+}
- 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);
+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_record *)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 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;
- 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);
+ /*
+ * 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);
+ }
+
+ 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;
}
- if (isonum_733(dirp->extent) + isonum_711(dirp->ext_attr_length) !=
- ifhp->ifid_start) {
- brelse(bp);
- printf("fhtovp: file start miss %d vs %ld\n",
- isonum_733(dirp->extent)+isonum_711(dirp->ext_attr_length),
- ifhp->ifid_start);
- return (ESTALE);
+ 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;
+
+ /*
+ * 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, ISO_FTYPE_9660);
+ cd9660_deftstamp(isodir, ip, bp2, ISO_FTYPE_9660);
+ if (bp2)
+ brelse(bp2);
+ break;
+ }
+ case ISO_FTYPE_RRIP:
+ cd9660_rrip_analyze(isodir, ip, imp);
+ 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);
+ if (bp != 0)
+ brelse(bp);
+
+ /*
+ * 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;
}
- 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/fs/cd9660/cd9660_vnops.c b/sys/fs/cd9660/cd9660_vnops.c
index 88440eb..854d6b5 100644
--- a/sys/fs/cd9660/cd9660_vnops.c
+++ b/sys/fs/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
* $FreeBSD$
*/
@@ -55,6 +55,7 @@
#include <miscfs/fifofs/fifo.h>
#include <sys/malloc.h>
#include <sys/dir.h>
+#include <sys/unistd.h>
#include <isofs/cd9660/iso.h>
#include <isofs/cd9660/cd9660_node.h>
@@ -81,7 +82,6 @@ static int cd9660_lock __P((struct vop_lock_args *));
static int cd9660_unlock __P((struct vop_unlock_args *));
static int cd9660_strategy __P((struct vop_strategy_args *));
static int cd9660_print __P((struct vop_print_args *));
-static int cd9660_enotsupp __P((void));
static int cd9660_islocked __P((struct vop_islocked_args *));
#if 0
@@ -100,7 +100,7 @@ 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;
@@ -116,7 +116,7 @@ cd9660_mknod(ndp, vap, cred, p)
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);
@@ -144,7 +144,7 @@ cd9660_mknod(ndp, vap, cred, p)
/*
* Setattr call. Only allowed for block and character special devices.
*/
-static int
+int
cd9660_setattr(ap)
struct vop_setattr_args /* {
struct vnodeop_desc *a_desc;
@@ -175,7 +175,7 @@ cd9660_setattr(ap)
return (0);
}
}
- return (EOPNOTSUPP);
+ return (0);
}
/*
@@ -229,23 +229,65 @@ cd9660_access(ap)
struct proc *a_p;
} */ *ap;
{
+ 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 on read-only file systems;
- * unless the file is a socket, fifo, or a block or
- * character device resident on the file system.
+ * Disallow write attempts unless the file is a socket,
+ * fifo, or a block or character device resident on the
+ * file system.
*/
- if (ap->a_mode & VWRITE) {
- switch (ap->a_vp->v_type) {
+ if (mode & VWRITE) {
+ switch (vp->v_type) {
case VDIR:
case VLNK:
case VREG:
- if (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY)
- return (EROFS);
- break;
+ return (EROFS);
}
}
- return (0);
+ /* 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);
}
static int
@@ -275,6 +317,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;
@@ -325,31 +390,31 @@ cd9660_read(ap)
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)
- error = cluster_read(vp, ip->i_size,
+ if (lblktosize(imp, rablock) <= ip->i_size)
+ error = cluster_read(vp, (off_t)ip->i_size,
lbn, size, NOCRED, uio->uio_resid,
(ap->a_ioflag >> 16), &bp);
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
@@ -362,7 +427,10 @@ 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;
brelse(bp);
} while (error == 0 && uio->uio_resid > 0 && n != 0);
return (error);
@@ -373,8 +441,8 @@ static int
cd9660_ioctl(ap)
struct vop_ioctl_args /* {
struct vnode *a_vp;
- int a_command;
- caddr_t a_data;
+ u_long a_command;
+ caddr_t a_data;
int a_fflag;
struct ucred *a_cred;
struct proc *a_p;
@@ -452,12 +520,12 @@ 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;
@@ -469,27 +537,27 @@ iso_uiodir(idp,dp,off)
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((caddr_t)dp,dp->d_reclen,idp->uio)))
- return error;
+ if (error = uiomove((caddr_t) dp,dp->d_reclen,idp->uio))
+ return (error);
idp->uio_off = off;
- return 0;
+ return (0);
}
-static int
+int
iso_shipdir(idp)
struct isoreaddir *idp;
{
@@ -517,13 +585,13 @@ assoc = (cl > 1) && (*cname == ASSOCCHAR);
if (sl != cl
|| bcmp(sname,cname,sl)) {
if (idp->assocent.d_namlen) {
- if ((error = iso_uiodir(idp,&idp->assocent,idp->assocoff)))
- return error;
+ if (error = iso_uiodir(idp,&idp->assocent,idp->assocoff))
+ return (error);
idp->assocent.d_namlen = 0;
}
if (idp->saveent.d_namlen) {
- if ((error = iso_uiodir(idp,&idp->saveent,idp->saveoff)))
- return error;
+ if (error = iso_uiodir(idp,&idp->saveent,idp->saveoff))
+ return (error);
idp->saveent.d_namlen = 0;
}
}
@@ -536,13 +604,11 @@ assoc = (cl > 1) && (*cname == ASSOCCHAR);
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.
*/
static int
cd9660_readdir(ap)
@@ -550,54 +616,61 @@ 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 namlen;
int reclen;
- int isoflags;
- struct iso_mnt *imp;
- struct iso_node *ip;
- struct buf *bp = NULL;
- u_short tmplen;
+ u_short namelen;
int ncookies = 0;
- u_int *cookies = NULL;
+ u_long *cookies = NULL;
- ip = VTOI(ap->a_vp);
- imp = ip->i_mnt;
+ 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 = 0;
- idp->assocent.d_namlen = 0;
+ 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 (ap->a_ncookies != NULL) {
+ 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->cookiep = cookies;
+ MALLOC(cookies, u_long *, ncookies * sizeof(u_int), M_TEMP,
+ M_WAITOK);
+ idp->cookies = cookies;
idp->ncookies = ncookies;
- } else
- idp->cookiep = 0;
- idp->eof = 0;
+ }
+ 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) {
/*
@@ -605,26 +678,25 @@ cd9660_readdir(ap)
* 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);
+ ((char *)bp->b_data + entryoffsetinblock);
- reclen = isonum_711 (ep->length);
+ 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;
}
@@ -640,35 +712,27 @@ cd9660_readdir(ap)
break;
}
- namlen = isonum_711 (ep->name_len);
- if (reclen < ISO_DIRECTORY_RECORD_SIZE + namlen) {
+ 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;
}
- /* XXX: be more intelligent if we can */
- idp->current.d_type = DT_UNKNOWN;
-
- idp->current.d_namlen = namlen;
- isoflags = isonum_711(imp->iso_ftype == ISO_FTYPE_HIGH_SIERRA?
- &ep->date[6]: ep->flags);
- if (isoflags & 2)
- isodirino(&idp->current.d_fileno,ep,imp);
+ if (isonum_711(ep->flags)&2)
+ idp->current.d_fileno = isodirino(ep, imp);
else
idp->current.d_fileno = dbtob(bp->b_blkno) +
- idp->curroff;
+ entryoffsetinblock;
idp->curroff += reclen;
- /*
- *
- */
+
switch (imp->iso_ftype) {
case ISO_FTYPE_RRIP:
- cd9660_rrip_getname(ep,idp->current.d_name,
- &tmplen,
+ cd9660_rrip_getname(ep,idp->current.d_name, &namelen,
&idp->current.d_fileno,imp);
- idp->current.d_namlen = tmplen;
+ idp->current.d_namlen = (u_char)namelen;
if (idp->current.d_namlen)
error = iso_uiodir(idp,&idp->current,idp->curroff);
break;
@@ -685,10 +749,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,
- isoflags & 4);
- idp->current.d_namlen = (u_char)elen;
+ isonum_711(ep->flags)&4);
+ idp->current.d_namlen = (u_char)namelen;
if (imp->iso_ftype == ISO_FTYPE_DEFAULT)
error = iso_shipdir(idp);
else
@@ -711,7 +775,7 @@ cd9660_readdir(ap)
if (ap->a_ncookies != NULL) {
if (error)
- FREE(cookies, M_TEMP);
+ free(cookies, M_TEMP);
else {
/*
* Work out the number of cookies actually used.
@@ -725,10 +789,9 @@ cd9660_readdir(ap)
brelse (bp);
uio->uio_offset = idp->uio_off;
- if (ap->a_eofflag)
- *ap->a_eofflag = idp->eof;
+ *ap->a_eofflag = idp->eofflag;
- FREE(idp,M_TEMP);
+ FREE(idp, M_TEMP);
return (error);
}
@@ -754,44 +817,34 @@ cd9660_readlink(ap)
ISODIR *dirp;
ISOMNT *imp;
struct buf *bp;
+ struct uio *uio;
u_short symlen;
int error;
char *symname;
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,
- iso_dblkno(imp, ip->i_number),
- 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....
@@ -800,22 +853,26 @@ cd9660_readlink(ap)
if ((ip->i_number & imp->im_bmask) + isonum_711(dirp->length)
> (unsigned)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 ;-)
@@ -825,11 +882,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);
}
/*
@@ -845,7 +906,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);
}
/*
@@ -855,12 +916,14 @@ static 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));
}
/*
@@ -870,29 +933,14 @@ static 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.
- */
-static 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));
}
/*
@@ -943,102 +991,150 @@ cd9660_print(ap)
struct vnode *a_vp;
} */ *ap;
{
+
printf("tag VT_ISOFS, isofs vnode\n");
- return 0;
+ return (0);
+}
+
+/*
+ * Check for a locked inode.
+ */
+int
+cd9660_islocked(ap)
+ struct vop_islocked_args /* {
+ struct vnode *a_vp;
+ } */ *ap;
+{
+
+ return (lockstatus(&VTOI(ap->a_vp)->i_lock));
}
/*
- * Unsupported operation
+ * Return POSIX pathconf information applicable to cd9660 filesystems.
*/
-static int
-cd9660_enotsupp()
+int
+cd9660_pathconf(ap)
+ struct vop_pathconf_args /* {
+ struct vnode *a_vp;
+ int a_name;
+ register_t *a_retval;
+ } */ *ap;
{
- return (EOPNOTSUPP);
+ 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_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
+#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
*/
vop_t **cd9660_vnodeop_p;
-static struct vnodeopv_entry_desc cd9660_vnodeop_entries[] = {
+struct vnodeopv_entry_desc cd9660_vnodeop_entries[] = {
+
{ &vop_default_desc, (vop_t *)vn_default_error },
- { &vop_lookup_desc, (vop_t *)cd9660_lookup }, /* lookup */
- { &vop_create_desc, (vop_t *)cd9660_create }, /* create */
- { &vop_mknod_desc, (vop_t *)cd9660_mknod }, /* mknod */
- { &vop_open_desc, (vop_t *)cd9660_open }, /* open */
- { &vop_close_desc, (vop_t *)cd9660_close }, /* close */
- { &vop_access_desc, (vop_t *)cd9660_access }, /* access */
- { &vop_getattr_desc, (vop_t *)cd9660_getattr }, /* getattr */
- { &vop_setattr_desc, (vop_t *)cd9660_setattr }, /* setattr */
- { &vop_read_desc, (vop_t *)cd9660_read }, /* read */
- { &vop_write_desc, (vop_t *)cd9660_write }, /* write */
- { &vop_ioctl_desc, (vop_t *)cd9660_ioctl }, /* ioctl */
- { &vop_select_desc, (vop_t *)cd9660_select }, /* select */
- { &vop_mmap_desc, (vop_t *)cd9660_mmap }, /* mmap */
- { &vop_fsync_desc, (vop_t *)cd9660_fsync }, /* fsync */
- { &vop_seek_desc, (vop_t *)cd9660_seek }, /* seek */
- { &vop_remove_desc, (vop_t *)cd9660_remove }, /* remove */
- { &vop_link_desc, (vop_t *)cd9660_link }, /* link */
- { &vop_rename_desc, (vop_t *)cd9660_rename }, /* rename */
- { &vop_mkdir_desc, (vop_t *)cd9660_mkdir }, /* mkdir */
- { &vop_rmdir_desc, (vop_t *)cd9660_rmdir }, /* rmdir */
- { &vop_symlink_desc, (vop_t *)cd9660_symlink }, /* symlink */
- { &vop_readdir_desc, (vop_t *)cd9660_readdir }, /* readdir */
- { &vop_readlink_desc, (vop_t *)cd9660_readlink }, /* readlink */
- { &vop_abortop_desc, (vop_t *)cd9660_abortop }, /* abortop */
- { &vop_inactive_desc, (vop_t *)cd9660_inactive }, /* inactive */
- { &vop_reclaim_desc, (vop_t *)cd9660_reclaim }, /* reclaim */
- { &vop_lock_desc, (vop_t *)cd9660_lock }, /* lock */
- { &vop_unlock_desc, (vop_t *)cd9660_unlock }, /* unlock */
- { &vop_bmap_desc, (vop_t *)cd9660_bmap }, /* bmap */
- { &vop_strategy_desc, (vop_t *)cd9660_strategy }, /* strategy */
- { &vop_print_desc, (vop_t *)cd9660_print }, /* print */
- { &vop_islocked_desc, (vop_t *)cd9660_islocked }, /* islocked */
- { &vop_pathconf_desc, (vop_t *)cd9660_pathconf }, /* pathconf */
- { &vop_advlock_desc, (vop_t *)cd9660_advlock }, /* advlock */
- { &vop_blkatoff_desc, (vop_t *)cd9660_blkatoff }, /* blkatoff */
- { &vop_valloc_desc, (vop_t *)cd9660_valloc }, /* valloc */
- { &vop_vfree_desc, (vop_t *)cd9660_vfree }, /* vfree */
- { &vop_truncate_desc, (vop_t *)cd9660_truncate }, /* truncate */
- { &vop_update_desc, (vop_t *)cd9660_update }, /* update */
- { &vop_bwrite_desc, (vop_t *)vn_bwrite }, /* bwrite */
+ { &vop_lookup_desc, (vop_t *)cd9660_lookup }, /* lookup */
+ { &vop_create_desc, (vop_t *)cd9660_create }, /* create */
+ { &vop_mknod_desc, (vop_t *)cd9660_mknod }, /* mknod */
+ { &vop_open_desc, (vop_t *)cd9660_open }, /* open */
+ { &vop_close_desc, (vop_t *)cd9660_close }, /* close */
+ { &vop_access_desc, (vop_t *)cd9660_access }, /* access */
+ { &vop_getattr_desc, (vop_t *)cd9660_getattr }, /* getattr */
+ { &vop_setattr_desc, (vop_t *)cd9660_setattr }, /* setattr */
+ { &vop_read_desc, (vop_t *)cd9660_read }, /* read */
+ { &vop_write_desc, (vop_t *)cd9660_write }, /* write */
+ { &vop_lease_desc, (vop_t *)cd9660_lease_check },/* lease */
+ { &vop_ioctl_desc, (vop_t *)cd9660_ioctl }, /* ioctl */
+ { &vop_select_desc, (vop_t *)cd9660_select }, /* select */
+ { &vop_revoke_desc, (vop_t *)cd9660_revoke }, /* revoke */
+ { &vop_mmap_desc, (vop_t *)cd9660_mmap }, /* mmap */
+ { &vop_fsync_desc, (vop_t *)cd9660_fsync }, /* fsync */
+ { &vop_seek_desc, (vop_t *)cd9660_seek }, /* seek */
+ { &vop_remove_desc, (vop_t *)cd9660_remove }, /* remove */
+ { &vop_link_desc, (vop_t *)cd9660_link }, /* link */
+ { &vop_rename_desc, (vop_t *)cd9660_rename }, /* rename */
+ { &vop_mkdir_desc, (vop_t *)cd9660_mkdir }, /* mkdir */
+ { &vop_rmdir_desc, (vop_t *)cd9660_rmdir }, /* rmdir */
+ { &vop_symlink_desc, (vop_t *)cd9660_symlink }, /* symlink */
+ { &vop_readdir_desc, (vop_t *)cd9660_readdir }, /* readdir */
+ { &vop_readlink_desc, (vop_t *)cd9660_readlink },/* readlink */
+ { &vop_abortop_desc, (vop_t *)cd9660_abortop }, /* abortop */
+ { &vop_inactive_desc, (vop_t *)cd9660_inactive },/* inactive */
+ { &vop_reclaim_desc, (vop_t *)cd9660_reclaim }, /* reclaim */
+ { &vop_lock_desc, (vop_t *)cd9660_lock }, /* lock */
+ { &vop_unlock_desc, (vop_t *)cd9660_unlock }, /* unlock */
+ { &vop_bmap_desc, (vop_t *)cd9660_bmap }, /* bmap */
+ { &vop_strategy_desc, (vop_t *)cd9660_strategy },/* strategy */
+ { &vop_print_desc, (vop_t *)cd9660_print }, /* print */
+ { &vop_islocked_desc, (vop_t *)cd9660_islocked },/* islocked */
+ { &vop_pathconf_desc, (vop_t *)cd9660_pathconf },/* pathconf */
+ { &vop_advlock_desc, (vop_t *)cd9660_advlock }, /* advlock */
+ { &vop_blkatoff_desc, (vop_t *)cd9660_blkatoff },/* blkatoff */
+ { &vop_valloc_desc, (vop_t *)cd9660_valloc }, /* valloc */
+ { &vop_vfree_desc, (vop_t *)cd9660_vfree }, /* vfree */
+ { &vop_truncate_desc, (vop_t *)cd9660_truncate },/* truncate */
+ { &vop_update_desc, (vop_t *)cd9660_update }, /* update */
+ { &vop_bwrite_desc, (vop_t *)vn_bwrite },
{ NULL, NULL }
};
static struct vnodeopv_desc cd9660_vnodeop_opv_desc =
@@ -1049,101 +1145,106 @@ VNODEOP_SET(cd9660_vnodeop_opv_desc);
* Special device vnode ops
*/
vop_t **cd9660_specop_p;
-static struct vnodeopv_entry_desc cd9660_specop_entries[] = {
+struct vnodeopv_entry_desc cd9660_specop_entries[] = {
{ &vop_default_desc, (vop_t *)vn_default_error },
- { &vop_lookup_desc, (vop_t *)spec_lookup }, /* lookup */
- { &vop_create_desc, (vop_t *)cd9660_create }, /* create */
- { &vop_mknod_desc, (vop_t *)cd9660_mknod }, /* mknod */
- { &vop_open_desc, (vop_t *)spec_open }, /* open */
- { &vop_close_desc, (vop_t *)spec_close }, /* close */
- { &vop_access_desc, (vop_t *)cd9660_access }, /* access */
- { &vop_getattr_desc, (vop_t *)cd9660_getattr }, /* getattr */
- { &vop_setattr_desc, (vop_t *)cd9660_setattr }, /* setattr */
- { &vop_read_desc, (vop_t *)spec_read }, /* read */
- { &vop_write_desc, (vop_t *)spec_write }, /* write */
- { &vop_ioctl_desc, (vop_t *)spec_ioctl }, /* ioctl */
- { &vop_select_desc, (vop_t *)spec_select }, /* select */
- { &vop_mmap_desc, (vop_t *)spec_mmap }, /* mmap */
- { &vop_fsync_desc, (vop_t *)spec_fsync }, /* fsync */
- { &vop_seek_desc, (vop_t *)spec_seek }, /* seek */
- { &vop_remove_desc, (vop_t *)cd9660_remove }, /* remove */
- { &vop_link_desc, (vop_t *)cd9660_link }, /* link */
- { &vop_rename_desc, (vop_t *)cd9660_rename }, /* rename */
- { &vop_mkdir_desc, (vop_t *)cd9660_mkdir }, /* mkdir */
- { &vop_rmdir_desc, (vop_t *)cd9660_rmdir }, /* rmdir */
- { &vop_symlink_desc, (vop_t *)cd9660_symlink }, /* symlink */
- { &vop_readdir_desc, (vop_t *)spec_readdir }, /* readdir */
- { &vop_readlink_desc, (vop_t *)spec_readlink }, /* readlink */
- { &vop_abortop_desc, (vop_t *)spec_abortop }, /* abortop */
- { &vop_inactive_desc, (vop_t *)cd9660_inactive }, /* inactive */
- { &vop_reclaim_desc, (vop_t *)cd9660_reclaim }, /* reclaim */
- { &vop_lock_desc, (vop_t *)cd9660_lock }, /* lock */
- { &vop_unlock_desc, (vop_t *)cd9660_unlock }, /* unlock */
- { &vop_bmap_desc, (vop_t *)spec_bmap }, /* bmap */
- { &vop_strategy_desc, (vop_t *)spec_strategy }, /* strategy */
- { &vop_print_desc, (vop_t *)cd9660_print }, /* print */
- { &vop_islocked_desc, (vop_t *)cd9660_islocked }, /* islocked */
- { &vop_pathconf_desc, (vop_t *)spec_pathconf }, /* pathconf */
- { &vop_advlock_desc, (vop_t *)spec_advlock }, /* advlock */
- { &vop_blkatoff_desc, (vop_t *)spec_blkatoff }, /* blkatoff */
- { &vop_valloc_desc, (vop_t *)spec_valloc }, /* valloc */
- { &vop_vfree_desc, (vop_t *)spec_vfree }, /* vfree */
- { &vop_truncate_desc, (vop_t *)spec_truncate }, /* truncate */
- { &vop_update_desc, (vop_t *)cd9660_update }, /* update */
- { &vop_getpages_desc, (vop_t *)spec_getpages}, /* getpages */
- { &vop_bwrite_desc, (vop_t *)vn_bwrite }, /* bwrite */
+ { &vop_lookup_desc, (vop_t *)spec_lookup }, /* lookup */
+ { &vop_create_desc, (vop_t *)spec_create }, /* create */
+ { &vop_mknod_desc, (vop_t *)spec_mknod }, /* mknod */
+ { &vop_open_desc, (vop_t *)spec_open }, /* open */
+ { &vop_close_desc, (vop_t *)spec_close }, /* close */
+ { &vop_access_desc, (vop_t *)cd9660_access }, /* access */
+ { &vop_getattr_desc, (vop_t *)cd9660_getattr }, /* getattr */
+ { &vop_setattr_desc, (vop_t *)cd9660_setattr }, /* setattr */
+ { &vop_read_desc, (vop_t *)spec_read }, /* read */
+ { &vop_write_desc, (vop_t *)spec_write }, /* write */
+ { &vop_lease_desc, (vop_t *)spec_lease_check }, /* lease */
+ { &vop_ioctl_desc, (vop_t *)spec_ioctl }, /* ioctl */
+ { &vop_select_desc, (vop_t *)spec_select }, /* select */
+ { &vop_revoke_desc, (vop_t *)spec_revoke }, /* revoke */
+ { &vop_mmap_desc, (vop_t *)spec_mmap }, /* mmap */
+ { &vop_fsync_desc, (vop_t *)spec_fsync }, /* fsync */
+ { &vop_seek_desc, (vop_t *)spec_seek }, /* seek */
+ { &vop_remove_desc, (vop_t *)spec_remove }, /* remove */
+ { &vop_link_desc, (vop_t *)spec_link }, /* link */
+ { &vop_rename_desc, (vop_t *)spec_rename }, /* rename */
+ { &vop_mkdir_desc, (vop_t *)spec_mkdir }, /* mkdir */
+ { &vop_rmdir_desc, (vop_t *)spec_rmdir }, /* rmdir */
+ { &vop_symlink_desc, (vop_t *)spec_symlink }, /* symlink */
+ { &vop_readdir_desc, (vop_t *)spec_readdir }, /* readdir */
+ { &vop_readlink_desc, (vop_t *)spec_readlink }, /* readlink */
+ { &vop_abortop_desc, (vop_t *)spec_abortop }, /* abortop */
+ { &vop_inactive_desc, (vop_t *)cd9660_inactive },/* inactive */
+ { &vop_reclaim_desc, (vop_t *)cd9660_reclaim }, /* reclaim */
+ { &vop_lock_desc, (vop_t *)cd9660_lock }, /* lock */
+ { &vop_unlock_desc, (vop_t *)cd9660_unlock }, /* unlock */
+ { &vop_bmap_desc, (vop_t *)spec_bmap }, /* bmap */
+ { &vop_strategy_desc, (vop_t *)spec_strategy }, /* strategy */
+ { &vop_print_desc, (vop_t *)cd9660_print }, /* print */
+ { &vop_islocked_desc, (vop_t *)cd9660_islocked },/* islocked */
+ { &vop_pathconf_desc, (vop_t *)spec_pathconf }, /* pathconf */
+ { &vop_advlock_desc, (vop_t *)spec_advlock }, /* advlock */
+ { &vop_blkatoff_desc, (vop_t *)spec_blkatoff }, /* blkatoff */
+ { &vop_valloc_desc, (vop_t *)spec_valloc }, /* valloc */
+ { &vop_vfree_desc, (vop_t *)spec_vfree }, /* vfree */
+ { &vop_truncate_desc, (vop_t *)spec_truncate }, /* truncate */
+ { &vop_update_desc, (vop_t *)cd9660_update }, /* update */
+ { &vop_bwrite_desc, (vop_t *)vn_bwrite },
{ NULL, NULL }
};
static struct vnodeopv_desc cd9660_specop_opv_desc =
{ &cd9660_specop_p, cd9660_specop_entries };
VNODEOP_SET(cd9660_specop_opv_desc);
+#ifdef FIFO
vop_t **cd9660_fifoop_p;
-static struct vnodeopv_entry_desc cd9660_fifoop_entries[] = {
+struct vnodeopv_entry_desc cd9660_fifoop_entries[] = {
{ &vop_default_desc, (vop_t *)vn_default_error },
- { &vop_lookup_desc, (vop_t *)fifo_lookup }, /* lookup */
- { &vop_create_desc, (vop_t *)cd9660_create }, /* create */
- { &vop_mknod_desc, (vop_t *)cd9660_mknod }, /* mknod */
- { &vop_open_desc, (vop_t *)fifo_open }, /* open */
- { &vop_close_desc, (vop_t *)fifo_close }, /* close */
- { &vop_access_desc, (vop_t *)cd9660_access }, /* access */
- { &vop_getattr_desc, (vop_t *)cd9660_getattr }, /* getattr */
- { &vop_setattr_desc, (vop_t *)cd9660_setattr }, /* setattr */
- { &vop_read_desc, (vop_t *)fifo_read }, /* read */
- { &vop_write_desc, (vop_t *)fifo_write }, /* write */
- { &vop_ioctl_desc, (vop_t *)fifo_ioctl }, /* ioctl */
- { &vop_select_desc, (vop_t *)fifo_select }, /* select */
- { &vop_mmap_desc, (vop_t *)fifo_mmap }, /* mmap */
- { &vop_fsync_desc, (vop_t *)fifo_fsync }, /* fsync */
- { &vop_seek_desc, (vop_t *)fifo_seek }, /* seek */
- { &vop_remove_desc, (vop_t *)cd9660_remove }, /* remove */
- { &vop_link_desc, (vop_t *)cd9660_link }, /* link */
- { &vop_rename_desc, (vop_t *)cd9660_rename }, /* rename */
- { &vop_mkdir_desc, (vop_t *)cd9660_mkdir }, /* mkdir */
- { &vop_rmdir_desc, (vop_t *)cd9660_rmdir }, /* rmdir */
- { &vop_symlink_desc, (vop_t *)cd9660_symlink }, /* symlink */
- { &vop_readdir_desc, (vop_t *)fifo_readdir }, /* readdir */
- { &vop_readlink_desc, (vop_t *)fifo_readlink }, /* readlink */
- { &vop_abortop_desc, (vop_t *)fifo_abortop }, /* abortop */
- { &vop_inactive_desc, (vop_t *)cd9660_inactive }, /* inactive */
- { &vop_reclaim_desc, (vop_t *)cd9660_reclaim }, /* reclaim */
- { &vop_lock_desc, (vop_t *)cd9660_lock }, /* lock */
- { &vop_unlock_desc, (vop_t *)cd9660_unlock }, /* unlock */
- { &vop_bmap_desc, (vop_t *)fifo_bmap }, /* bmap */
- { &vop_strategy_desc, (vop_t *)fifo_badop }, /* strategy */
- { &vop_print_desc, (vop_t *)cd9660_print }, /* print */
- { &vop_islocked_desc, (vop_t *)cd9660_islocked }, /* islocked */
- { &vop_pathconf_desc, (vop_t *)fifo_pathconf }, /* pathconf */
- { &vop_advlock_desc, (vop_t *)fifo_advlock }, /* advlock */
- { &vop_blkatoff_desc, (vop_t *)fifo_blkatoff }, /* blkatoff */
- { &vop_valloc_desc, (vop_t *)fifo_valloc }, /* valloc */
- { &vop_vfree_desc, (vop_t *)fifo_vfree }, /* vfree */
- { &vop_truncate_desc, (vop_t *)fifo_truncate }, /* truncate */
- { &vop_update_desc, (vop_t *)cd9660_update }, /* update */
- { &vop_bwrite_desc, (vop_t *)vn_bwrite }, /* bwrite */
+ { &vop_lookup_desc, (vop_t *)fifo_lookup }, /* lookup */
+ { &vop_create_desc, (vop_t *)fifo_create }, /* create */
+ { &vop_mknod_desc, (vop_t *)fifo_mknod }, /* mknod */
+ { &vop_open_desc, (vop_t *)fifo_open }, /* open */
+ { &vop_close_desc, (vop_t *)fifo_close }, /* close */
+ { &vop_access_desc, (vop_t *)cd9660_access }, /* access */
+ { &vop_getattr_desc, (vop_t *)cd9660_getattr }, /* getattr */
+ { &vop_setattr_desc, (vop_t *)cd9660_setattr }, /* setattr */
+ { &vop_read_desc, (vop_t *)fifo_read }, /* read */
+ { &vop_write_desc, (vop_t *)fifo_write }, /* write */
+ { &vop_lease_desc, (vop_t *)fifo_lease_check }, /* lease */
+ { &vop_ioctl_desc, (vop_t *)fifo_ioctl }, /* ioctl */
+ { &vop_select_desc, (vop_t *)fifo_select }, /* select */
+ { &vop_revoke_desc, (vop_t *)fifo_revoke }, /* revoke */
+ { &vop_mmap_desc, (vop_t *)fifo_mmap }, /* mmap */
+ { &vop_fsync_desc, (vop_t *)fifo_fsync }, /* fsync */
+ { &vop_seek_desc, (vop_t *)fifo_seek }, /* seek */
+ { &vop_remove_desc, (vop_t *)fifo_remove }, /* remove */
+ { &vop_link_desc, (vop_t *)fifo_link } , /* link */
+ { &vop_rename_desc, (vop_t *)fifo_rename }, /* rename */
+ { &vop_mkdir_desc, (vop_t *)fifo_mkdir }, /* mkdir */
+ { &vop_rmdir_desc, (vop_t *)fifo_rmdir }, /* rmdir */
+ { &vop_symlink_desc, (vop_t *)fifo_symlink }, /* symlink */
+ { &vop_readdir_desc, (vop_t *)fifo_readdir }, /* readdir */
+ { &vop_readlink_desc, (vop_t *)fifo_readlink }, /* readlink */
+ { &vop_abortop_desc, (vop_t *)fifo_abortop }, /* abortop */
+ { &vop_inactive_desc, (vop_t *)cd9660_inactive },/* inactive */
+ { &vop_reclaim_desc, (vop_t *)cd9660_reclaim }, /* reclaim */
+ { &vop_lock_desc, (vop_t *)cd9660_lock }, /* lock */
+ { &vop_unlock_desc, (vop_t *)cd9660_unlock }, /* unlock */
+ { &vop_bmap_desc, (vop_t *)fifo_bmap }, /* bmap */
+ { &vop_strategy_desc, (vop_t *)fifo_strategy }, /* strategy */
+ { &vop_print_desc, (vop_t *)cd9660_print }, /* print */
+ { &vop_islocked_desc, (vop_t *)cd9660_islocked },/* islocked */
+ { &vop_pathconf_desc, (vop_t *)fifo_pathconf }, /* pathconf */
+ { &vop_advlock_desc, (vop_t *)fifo_advlock }, /* advlock */
+ { &vop_blkatoff_desc, (vop_t *)fifo_blkatoff }, /* blkatoff */
+ { &vop_valloc_desc, (vop_t *)fifo_valloc }, /* valloc */
+ { &vop_vfree_desc, (vop_t *)fifo_vfree }, /* vfree */
+ { &vop_truncate_desc, (vop_t *)fifo_truncate }, /* truncate */
+ { &vop_update_desc, (vop_t *)cd9660_update }, /* update */
+ { &vop_bwrite_desc, (vop_t *)vn_bwrite },
{ NULL, NULL }
};
static struct vnodeopv_desc cd9660_fifoop_opv_desc =
{ &cd9660_fifoop_p, cd9660_fifoop_entries };
VNODEOP_SET(cd9660_fifoop_opv_desc);
+#endif /* FIFO */
diff --git a/sys/fs/cd9660/iso.h b/sys/fs/cd9660/iso.h
index 1656c23..e2a7779 100644
--- a/sys/fs/cd9660/iso.h
+++ b/sys/fs/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
* $FreeBSD$
*/
@@ -138,37 +138,37 @@ struct iso_sierra_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 */
@@ -191,7 +191,6 @@ struct iso_mnt {
int im_bmask;
int volume_space_size;
- char im_fsmnt[50];
struct netexport im_export;
char root[ISODCL (157, 190)];
@@ -205,94 +204,102 @@ 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 iso_lblktodaddr(imp, lbn) btodb(iso_lblktosize(imp, lbn))
-#define iso_dblkinc(imp, lbn) ((lbn) + iso_lblktodaddr(imp, 1))
-#define iso_dblkno(imp, loc) iso_lblktodaddr(imp, iso_lblkno(imp, loc))
-int cd9660_init __P((void));
-
-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_mountroot __P((void));
+#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_vget_internal __P((struct mount *, ino_t, struct vnode **, int,
+ struct iso_directory_record *));
+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 vop_t **cd9660_vnodeop_p;
+extern vop_t **cd9660_specop_p;
+#ifdef FIFO
+extern vop_t **cd9660_fifoop_p;
+#endif
-static int isonum_711 __P((unsigned char *p));
-static int isonum_712 __P((char *p));
-static int isonum_721 __P((unsigned char *p));
-static int isonum_722 __P((unsigned char *p));
-static int isonum_723 __P((unsigned char *p));
-static int isonum_731 __P((unsigned char *p));
-static int isonum_732 __P((unsigned char *p));
-static int isonum_733 __P((unsigned char *p));
-
-static inline int
+static __inline int isonum_711 __P((u_char *));
+static __inline int
isonum_711(p)
- unsigned char *p;
+ u_char *p;
{
return *p;
}
-static inline int
+static __inline int isonum_712 __P((char *));
+static __inline int
isonum_712(p)
char *p;
{
return *p;
}
-static inline int
-isonum_721(p)
- unsigned char *p;
+#ifndef UNALIGNED_ACCESS
+
+static __inline int isonum_723 __P((u_char *));
+static __inline int
+isonum_723(p)
+ u_char *p;
{
- return *p|((char)p[1] << 8);
+ return *p|(p[1] << 8);
}
-static inline int
-isonum_722(p)
- unsigned char *p;
+static __inline int isonum_733 __P((u_char *));
+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);
}
-static 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;
}
-static 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;
}
-static 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);
}
-static 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