mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-06 13:09:50 +00:00
Import 4.4BSD-Lite2 onto the vendor branch, note that in the kernel, all
files are off the vendor branch, so this should not change anything. A "U" marker generally means that the file was not changed in between the 4.4Lite and Lite-2 releases, and does not need a merge. "C" generally means that there was a change. [note, new file: cd9660_mount.h]
This commit is contained in:
parent
c2f4655726
commit
f1b74d01b3
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/CSRG/dist/; revision=14553
47
sys/isofs/cd9660/TODO
Normal file
47
sys/isofs/cd9660/TODO
Normal file
@ -0,0 +1,47 @@
|
||||
# $NetBSD: TODO,v 1.4 1994/07/19 11:34:48 mycroft Exp $
|
||||
|
||||
1) should understand "older", original High Sierra ("CDROM001") type
|
||||
|
||||
Not yet. ( I don't have this technical information, yet. )
|
||||
|
||||
2) should understand Rock Ridge
|
||||
|
||||
Yes, we have follows function.
|
||||
|
||||
o Symbolic Link
|
||||
o Real Name(long name)
|
||||
o File Attribute
|
||||
o Time stamp
|
||||
o uid, gid
|
||||
o Devices
|
||||
o Relocated directories
|
||||
|
||||
Except follows:
|
||||
|
||||
o POSIX device number mapping
|
||||
|
||||
There is some preliminary stuff in there that (ab-)uses the mknod
|
||||
system call, but this needs a writable filesystem
|
||||
|
||||
5) should have name translation enabled by mount flag
|
||||
|
||||
Yes. we can disable the Rock Ridge Extension by follows option;
|
||||
|
||||
"mount -t isofs -o -norrip /dev/cd0d /cdrom"
|
||||
|
||||
6) should run as a user process, and not take up kernel space (cdroms
|
||||
are slow)
|
||||
|
||||
Not yet.
|
||||
|
||||
7) ECMA support.
|
||||
|
||||
Not yet. we need not only a technical spec but also ECMA format
|
||||
cd-rom itself!
|
||||
|
||||
8) Character set change by SVD ( multi SVD support )
|
||||
|
||||
Not yet. We should also hack the other part of system as 8 bit
|
||||
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 )
|
||||
|
14
sys/isofs/cd9660/TODO.hibler
Normal file
14
sys/isofs/cd9660/TODO.hibler
Normal file
@ -0,0 +1,14 @@
|
||||
1. Investiate making ISOFS another UFS shared filesystem (ala FFS/MFS/LFS).
|
||||
Since it was modelled after the inode code, we might be able to merge
|
||||
them back. It looks like a seperate (but very similar) lookup routine
|
||||
will be needed due to the associated file stuff.
|
||||
|
||||
2. It would be nice to be able to use the vfs_cluster code.
|
||||
Unfortunately, if the logical block size is smaller than the page size,
|
||||
it won't work. Also, if throughtput is relatively constant for any
|
||||
block size (as it is for the HP drive--150kbs) then clustering may not
|
||||
buy much (or may even hurt when vfs_cluster comes up with a large sync
|
||||
cluster).
|
||||
|
||||
3. Seems like there should be a "notrans" or some such mount option to show
|
||||
filenames as they really are without lower-casing. Does this make sense?
|
102
sys/isofs/cd9660/cd9660_bmap.c
Normal file
102
sys/isofs/cd9660/cd9660_bmap.c
Normal file
@ -0,0 +1,102 @@
|
||||
/*-
|
||||
* Copyright (c) 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley
|
||||
* by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
|
||||
* Support code is derived from software contributed to Berkeley
|
||||
* by Atsushi Murai (amurai@spec.co.jp).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)cd9660_bmap.c 8.4 (Berkeley) 12/5/94
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/namei.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <isofs/cd9660/iso.h>
|
||||
#include <isofs/cd9660/cd9660_node.h>
|
||||
|
||||
/*
|
||||
* Bmap converts a the logical block number of a file to its physical block
|
||||
* number on the disk. The conversion is done by using the logical block
|
||||
* number to index into the data block (extent) for the file.
|
||||
*/
|
||||
int
|
||||
cd9660_bmap(ap)
|
||||
struct vop_bmap_args /* {
|
||||
struct vnode *a_vp;
|
||||
daddr_t a_bn;
|
||||
struct vnode **a_vpp;
|
||||
daddr_t *a_bnp;
|
||||
int *a_runp;
|
||||
} */ *ap;
|
||||
{
|
||||
struct iso_node *ip = VTOI(ap->a_vp);
|
||||
daddr_t lblkno = ap->a_bn;
|
||||
int bshift;
|
||||
|
||||
/*
|
||||
* Check for underlying vnode requests and ensure that logical
|
||||
* to physical mapping is requested.
|
||||
*/
|
||||
if (ap->a_vpp != NULL)
|
||||
*ap->a_vpp = ip->i_devvp;
|
||||
if (ap->a_bnp == NULL)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Compute the requested block number
|
||||
*/
|
||||
bshift = ip->i_mnt->im_bshift;
|
||||
*ap->a_bnp = (ip->iso_start + lblkno) << (bshift - DEV_BSHIFT);
|
||||
|
||||
/*
|
||||
* Determine maximum number of readahead blocks following the
|
||||
* requested block.
|
||||
*/
|
||||
if (ap->a_runp) {
|
||||
int nblk;
|
||||
|
||||
nblk = (ip->i_size >> bshift) - (lblkno + 1);
|
||||
if (nblk <= 0)
|
||||
*ap->a_runp = 0;
|
||||
else if (nblk >= (MAXBSIZE >> bshift))
|
||||
*ap->a_runp = (MAXBSIZE >> bshift) - 1;
|
||||
else
|
||||
*ap->a_runp = nblk;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
488
sys/isofs/cd9660/cd9660_lookup.c
Normal file
488
sys/isofs/cd9660/cd9660_lookup.c
Normal file
@ -0,0 +1,488 @@
|
||||
/*-
|
||||
* Copyright (c) 1989, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley
|
||||
* by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
|
||||
* Support code is derived from software contributed to Berkeley
|
||||
* by Atsushi Murai (amurai@spec.co.jp).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)ufs_lookup.c 7.33 (Berkeley) 5/19/91
|
||||
*
|
||||
* @(#)cd9660_lookup.c 8.7 (Berkeley) 5/27/95
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/namei.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <isofs/cd9660/iso.h>
|
||||
#include <isofs/cd9660/cd9660_node.h>
|
||||
#include <isofs/cd9660/iso_rrip.h>
|
||||
#include <isofs/cd9660/cd9660_rrip.h>
|
||||
|
||||
struct nchstats iso_nchstats;
|
||||
|
||||
/*
|
||||
* Convert a component of a pathname into a pointer to a locked inode.
|
||||
* This is a very central and rather complicated routine.
|
||||
* If the file system is not maintained in a strict tree hierarchy,
|
||||
* this can result in a deadlock situation (see comments in code below).
|
||||
*
|
||||
* The flag argument is LOOKUP, CREATE, RENAME, or DELETE depending on
|
||||
* whether the name is to be looked up, created, renamed, or deleted.
|
||||
* When CREATE, RENAME, or DELETE is specified, information usable in
|
||||
* creating, renaming, or deleting a directory entry may be calculated.
|
||||
* If flag has LOCKPARENT or'ed into it and the target of the pathname
|
||||
* exists, lookup returns both the target and its parent directory locked.
|
||||
* When creating or renaming and LOCKPARENT is specified, the target may
|
||||
* not be ".". When deleting and LOCKPARENT is specified, the target may
|
||||
* be "."., but the caller must check to ensure it does an vrele and iput
|
||||
* instead of two iputs.
|
||||
*
|
||||
* Overall outline of ufs_lookup:
|
||||
*
|
||||
* check accessibility of directory
|
||||
* look for name in cache, if found, then if at end of path
|
||||
* and deleting or creating, drop it, else return name
|
||||
* search for name in directory, to found or notfound
|
||||
* notfound:
|
||||
* if creating, return locked directory, leaving info on available slots
|
||||
* else return error
|
||||
* found:
|
||||
* if at end of path and deleting, return information to allow delete
|
||||
* if at end of path and rewriting (RENAME and LOCKPARENT), lock target
|
||||
* inode and return info to allow rewrite
|
||||
* if not at end, add name to cache; if at end and neither creating
|
||||
* nor deleting, add name to cache
|
||||
*
|
||||
* NOTE: (LOOKUP | LOCKPARENT) currently returns the parent inode unlocked.
|
||||
*/
|
||||
cd9660_lookup(ap)
|
||||
struct vop_lookup_args /* {
|
||||
struct vnode *a_dvp;
|
||||
struct vnode **a_vpp;
|
||||
struct componentname *a_cnp;
|
||||
} */ *ap;
|
||||
{
|
||||
register struct vnode *vdp; /* vnode for directory being searched */
|
||||
register struct iso_node *dp; /* inode for directory being searched */
|
||||
register struct iso_mnt *imp; /* file system that directory is in */
|
||||
struct buf *bp; /* a buffer of directory entries */
|
||||
struct iso_directory_record *ep;/* the current directory entry */
|
||||
int entryoffsetinblock; /* offset of ep in bp's buffer */
|
||||
int saveoffset; /* offset of last directory entry in dir */
|
||||
int numdirpasses; /* strategy for directory search */
|
||||
doff_t endsearch; /* offset to end directory search */
|
||||
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;
|
||||
ino_t ino = 0;
|
||||
int reclen;
|
||||
u_short namelen;
|
||||
char altname[NAME_MAX];
|
||||
int res;
|
||||
int assoc, len;
|
||||
char *name;
|
||||
struct vnode **vpp = ap->a_vpp;
|
||||
struct componentname *cnp = ap->a_cnp;
|
||||
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;
|
||||
vdp = ap->a_dvp;
|
||||
dp = VTOI(vdp);
|
||||
imp = dp->i_mnt;
|
||||
lockparent = flags & LOCKPARENT;
|
||||
wantparent = flags & (LOCKPARENT|WANTPARENT);
|
||||
|
||||
/*
|
||||
* Check accessiblity of directory.
|
||||
*/
|
||||
if (vdp->v_type != VDIR)
|
||||
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.
|
||||
*
|
||||
* Before tediously performing a linear scan of the directory,
|
||||
* check the name cache to see if the directory/name pair
|
||||
* we are looking for is known already.
|
||||
*/
|
||||
if (error = cache_lookup(vdp, vpp, cnp)) {
|
||||
int vpid; /* capability number of vnode */
|
||||
|
||||
if (error == ENOENT)
|
||||
return (error);
|
||||
#ifdef PARANOID
|
||||
if ((vdp->v_flag & VROOT) && (flags & ISDOTDOT))
|
||||
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 = vdp;
|
||||
dp = VTOI(*vpp);
|
||||
vdp = *vpp;
|
||||
vpid = vdp->v_id;
|
||||
if (pdp == vdp) {
|
||||
VREF(vdp);
|
||||
error = 0;
|
||||
} else if (flags & ISDOTDOT) {
|
||||
VOP_UNLOCK(pdp, 0, p);
|
||||
error = vget(vdp, LK_EXCLUSIVE, p);
|
||||
if (!error && lockparent && (flags & ISLASTCN))
|
||||
error = vn_lock(pdp, LK_EXCLUSIVE, p);
|
||||
} else {
|
||||
error = vget(vdp, LK_EXCLUSIVE, p);
|
||||
if (!lockparent || error || !(flags & ISLASTCN))
|
||||
VOP_UNLOCK(pdp, 0, p);
|
||||
}
|
||||
/*
|
||||
* Check that the capability number did not change
|
||||
* while we were waiting for the lock.
|
||||
*/
|
||||
if (!error) {
|
||||
if (vpid == vdp->v_id)
|
||||
return (0);
|
||||
vput(vdp);
|
||||
if (lockparent && pdp != vdp && (flags & ISLASTCN))
|
||||
VOP_UNLOCK(pdp, 0, p);
|
||||
}
|
||||
if (error = vn_lock(pdp, LK_EXCLUSIVE, p))
|
||||
return (error);
|
||||
vdp = pdp;
|
||||
dp = VTOI(pdp);
|
||||
*vpp = NULL;
|
||||
}
|
||||
|
||||
len = cnp->cn_namelen;
|
||||
name = cnp->cn_nameptr;
|
||||
/*
|
||||
* A leading `=' means, we are looking for an associated file
|
||||
*/
|
||||
if (assoc = (imp->iso_ftype != ISO_FTYPE_RRIP && *name == ASSOCCHAR)) {
|
||||
len--;
|
||||
name++;
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is cached information on a previous search of
|
||||
* this directory, pick up where we last left off.
|
||||
* We cache only lookups as these are the most common
|
||||
* and have the greatest payoff. Caching CREATE has little
|
||||
* benefit as it usually must search the entire directory
|
||||
* to determine that the entry does not exist. Caching the
|
||||
* location of the last DELETE or RENAME has not reduced
|
||||
* 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;
|
||||
dp->i_offset = 0;
|
||||
numdirpasses = 1;
|
||||
} else {
|
||||
dp->i_offset = dp->i_diroff;
|
||||
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 = dp->i_size;
|
||||
|
||||
searchloop:
|
||||
while (dp->i_offset < endsearch) {
|
||||
/*
|
||||
* If offset is on a block boundary,
|
||||
* read the next directory block.
|
||||
* Release previous if it exists.
|
||||
*/
|
||||
if ((dp->i_offset & bmask) == 0) {
|
||||
if (bp != NULL)
|
||||
brelse(bp);
|
||||
if (error =
|
||||
VOP_BLKATOFF(vdp, (off_t)dp->i_offset, NULL, &bp))
|
||||
return (error);
|
||||
entryoffsetinblock = 0;
|
||||
}
|
||||
/*
|
||||
* Get pointer to next entry.
|
||||
*/
|
||||
ep = (struct iso_directory_record *)
|
||||
((char *)bp->b_data + entryoffsetinblock);
|
||||
|
||||
reclen = isonum_711(ep->length);
|
||||
if (reclen == 0) {
|
||||
/* skip to next block, if any */
|
||||
dp->i_offset =
|
||||
(dp->i_offset & ~bmask) + imp->logical_block_size;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (reclen < ISO_DIRECTORY_RECORD_SIZE)
|
||||
/* illegal entry, stop */
|
||||
break;
|
||||
|
||||
if (entryoffsetinblock + reclen > imp->logical_block_size)
|
||||
/* entries are not allowed to cross boundaries */
|
||||
break;
|
||||
|
||||
namelen = isonum_711(ep->name_len);
|
||||
|
||||
if (reclen < ISO_DIRECTORY_RECORD_SIZE + namelen)
|
||||
/* illegal entry, stop */
|
||||
break;
|
||||
|
||||
/*
|
||||
* Check for a name match.
|
||||
*/
|
||||
switch (imp->iso_ftype) {
|
||||
default:
|
||||
if ((!(isonum_711(ep->flags)&4)) == !assoc) {
|
||||
if ((len == 1
|
||||
&& *name == '.')
|
||||
|| (flags & ISDOTDOT)) {
|
||||
if (namelen == 1
|
||||
&& ep->name[0] == ((flags & ISDOTDOT) ? 1 : 0)) {
|
||||
/*
|
||||
* Save directory entry's inode number and
|
||||
* release directory buffer.
|
||||
*/
|
||||
dp->i_ino = isodirino(ep, imp);
|
||||
goto found;
|
||||
}
|
||||
if (namelen != 1
|
||||
|| ep->name[0] != 0)
|
||||
goto notfound;
|
||||
} else if (!(res = isofncmp(name,len,
|
||||
ep->name,namelen))) {
|
||||
if (isonum_711(ep->flags)&2)
|
||||
ino = isodirino(ep, imp);
|
||||
else
|
||||
ino = dbtob(bp->b_blkno)
|
||||
+ entryoffsetinblock;
|
||||
saveoffset = dp->i_offset;
|
||||
} else if (ino)
|
||||
goto foundino;
|
||||
#ifdef NOSORTBUG /* On some CDs directory entries are not sorted correctly */
|
||||
else if (res < 0)
|
||||
goto notfound;
|
||||
else if (res > 0 && numdirpasses == 2)
|
||||
numdirpasses++;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case ISO_FTYPE_RRIP:
|
||||
if (isonum_711(ep->flags)&2)
|
||||
ino = isodirino(ep, imp);
|
||||
else
|
||||
ino = dbtob(bp->b_blkno) + entryoffsetinblock;
|
||||
dp->i_ino = ino;
|
||||
cd9660_rrip_getname(ep,altname,&namelen,&dp->i_ino,imp);
|
||||
if (namelen == cnp->cn_namelen
|
||||
&& !bcmp(name,altname,namelen))
|
||||
goto found;
|
||||
ino = 0;
|
||||
break;
|
||||
}
|
||||
dp->i_offset += reclen;
|
||||
entryoffsetinblock += reclen;
|
||||
}
|
||||
if (ino) {
|
||||
foundino:
|
||||
dp->i_ino = ino;
|
||||
if (saveoffset != dp->i_offset) {
|
||||
if (lblkno(imp, dp->i_offset) !=
|
||||
lblkno(imp, saveoffset)) {
|
||||
if (bp != NULL)
|
||||
brelse(bp);
|
||||
if (error = VOP_BLKATOFF(vdp,
|
||||
(off_t)saveoffset, NULL, &bp))
|
||||
return (error);
|
||||
}
|
||||
entryoffsetinblock = saveoffset & bmask;
|
||||
ep = (struct iso_directory_record *)
|
||||
((char *)bp->b_data + entryoffsetinblock);
|
||||
dp->i_offset = saveoffset;
|
||||
}
|
||||
goto found;
|
||||
}
|
||||
notfound:
|
||||
/*
|
||||
* If we started in the middle of the directory and failed
|
||||
* to find our target, we must check the beginning as well.
|
||||
*/
|
||||
if (numdirpasses == 2) {
|
||||
numdirpasses--;
|
||||
dp->i_offset = 0;
|
||||
endsearch = dp->i_diroff;
|
||||
goto searchloop;
|
||||
}
|
||||
if (bp != NULL)
|
||||
brelse(bp);
|
||||
|
||||
/*
|
||||
* Insert name into cache (as non-existent) if appropriate.
|
||||
*/
|
||||
if (cnp->cn_flags & MAKEENTRY)
|
||||
cache_enter(vdp, *vpp, cnp);
|
||||
if (nameiop == CREATE || nameiop == RENAME)
|
||||
return (EROFS);
|
||||
return (ENOENT);
|
||||
|
||||
found:
|
||||
if (numdirpasses == 2)
|
||||
iso_nchstats.ncs_pass2++;
|
||||
|
||||
/*
|
||||
* Found component in pathname.
|
||||
* If the final component of path name, save information
|
||||
* in the cache as to where the entry was found.
|
||||
*/
|
||||
if ((flags & ISLASTCN) && nameiop == LOOKUP)
|
||||
dp->i_diroff = dp->i_offset;
|
||||
|
||||
/*
|
||||
* Step through the translation in the name. We do not `iput' the
|
||||
* directory because we may need it again if a symbolic link
|
||||
* is relative to the current directory. Instead we save it
|
||||
* unlocked as "pdp". We must get the target inode before unlocking
|
||||
* the directory to insure that the inode will not be removed
|
||||
* before we get it. We prevent deadlock by always fetching
|
||||
* inodes from the root, moving down the directory tree. Thus
|
||||
* when following backward pointers ".." we must unlock the
|
||||
* parent directory before getting the requested directory.
|
||||
* There is a potential race condition here if both the current
|
||||
* and parent directories are removed before the `iget' for the
|
||||
* inode associated with ".." returns. We hope that this occurs
|
||||
* infrequently since we cannot avoid this race condition without
|
||||
* implementing a sophisticated deadlock detection algorithm.
|
||||
* Note also that this simple deadlock detection scheme will not
|
||||
* work if the file system has any hard links other than ".."
|
||||
* that point backwards in the directory structure.
|
||||
*/
|
||||
pdp = vdp;
|
||||
/*
|
||||
* If ino is different from dp->i_ino,
|
||||
* it's a relocated directory.
|
||||
*/
|
||||
if (flags & ISDOTDOT) {
|
||||
VOP_UNLOCK(pdp, 0, p); /* race to get the inode */
|
||||
error = cd9660_vget_internal(vdp->v_mount, dp->i_ino, &tdp,
|
||||
dp->i_ino != ino, ep);
|
||||
brelse(bp);
|
||||
if (error) {
|
||||
vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, p);
|
||||
return (error);
|
||||
}
|
||||
if (lockparent && (flags & ISLASTCN) &&
|
||||
(error = vn_lock(pdp, LK_EXCLUSIVE, p))) {
|
||||
vput(tdp);
|
||||
return (error);
|
||||
}
|
||||
*vpp = tdp;
|
||||
} else if (dp->i_number == dp->i_ino) {
|
||||
brelse(bp);
|
||||
VREF(vdp); /* we want ourself, ie "." */
|
||||
*vpp = vdp;
|
||||
} else {
|
||||
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))
|
||||
VOP_UNLOCK(pdp, 0, p);
|
||||
*vpp = tdp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert name into cache if appropriate.
|
||||
*/
|
||||
if (cnp->cn_flags & MAKEENTRY)
|
||||
cache_enter(vdp, *vpp, cnp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
cd9660_blkatoff(ap)
|
||||
struct vop_blkatoff_args /* {
|
||||
struct vnode *a_vp;
|
||||
off_t a_offset;
|
||||
char **a_res;
|
||||
struct buf **a_bpp;
|
||||
} */ *ap;
|
||||
{
|
||||
struct iso_node *ip;
|
||||
register struct iso_mnt *imp;
|
||||
struct buf *bp;
|
||||
daddr_t lbn;
|
||||
int bsize, error;
|
||||
|
||||
ip = VTOI(ap->a_vp);
|
||||
imp = ip->i_mnt;
|
||||
lbn = lblkno(imp, ap->a_offset);
|
||||
bsize = blksize(imp, ip, lbn);
|
||||
|
||||
if (error = bread(ap->a_vp, lbn, bsize, NOCRED, &bp)) {
|
||||
brelse(bp);
|
||||
*ap->a_bpp = NULL;
|
||||
return (error);
|
||||
}
|
||||
if (ap->a_res)
|
||||
*ap->a_res = (char *)bp->b_data + blkoff(imp, ap->a_offset);
|
||||
*ap->a_bpp = bp;
|
||||
return (0);
|
||||
}
|
51
sys/isofs/cd9660/cd9660_mount.h
Normal file
51
sys/isofs/cd9660/cd9660_mount.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 1995
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley
|
||||
* by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
|
||||
* Support code is derived from software contributed to Berkeley
|
||||
* by Atsushi Murai (amurai@spec.co.jp).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)cd9660_mount.h 8.1 (Berkeley) 5/24/95
|
||||
*/
|
||||
|
||||
/*
|
||||
* Arguments to mount ISO 9660 filesystems.
|
||||
*/
|
||||
struct iso_args {
|
||||
char *fspec; /* block special device to mount */
|
||||
struct export_args export; /* network export info */
|
||||
int flags; /* mounting flags, see below */
|
||||
};
|
||||
#define ISOFSMNT_NORRIP 0x00000001 /* disable Rock Ridge Ext.*/
|
||||
#define ISOFSMNT_GENS 0x00000002 /* enable generation numbers */
|
||||
#define ISOFSMNT_EXTATT 0x00000004 /* enable extended attributes */
|
481
sys/isofs/cd9660/cd9660_node.c
Normal file
481
sys/isofs/cd9660/cd9660_node.c
Normal file
@ -0,0 +1,481 @@
|
||||
/*-
|
||||
* 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
|
||||
* by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
|
||||
* Support code is derived from software contributed to Berkeley
|
||||
* by Atsushi Murai (amurai@spec.co.jp).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)cd9660_node.c 8.8 (Berkeley) 5/22/95
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <isofs/cd9660/iso.h>
|
||||
#include <isofs/cd9660/cd9660_node.h>
|
||||
#include <isofs/cd9660/cd9660_mount.h>
|
||||
#include <isofs/cd9660/iso_rrip.h>
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
int prtactive; /* 1 => print out reclaim of active vnodes */
|
||||
|
||||
/*
|
||||
* Initialize hash links for inodes and dnodes.
|
||||
*/
|
||||
cd9660_init(vfsp)
|
||||
struct vfsconf *vfsp;
|
||||
{
|
||||
|
||||
isohashtbl = hashinit(desiredvnodes, M_ISOFSMNT, &isohash);
|
||||
simple_lock_init(&cd9660_ihash_slock);
|
||||
#ifdef ISODEVMAP
|
||||
idvhashtbl = hashinit(desiredvnodes / 8, M_ISOFSMNT, &idvhash);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ISODEVMAP
|
||||
/*
|
||||
* Enter a new node into the device hash list
|
||||
*/
|
||||
struct iso_dnode *
|
||||
iso_dmap(device, inum, create)
|
||||
dev_t device;
|
||||
ino_t inum;
|
||||
int create;
|
||||
{
|
||||
register struct iso_dnode **dpp, *dp, *dq;
|
||||
|
||||
dpp = &idvhashtbl[DNOHASH(device, inum)];
|
||||
for (dp = *dpp;; dp = dp->d_next) {
|
||||
if (dp == NULL)
|
||||
return (NULL);
|
||||
if (inum == dp->i_number && device == dp->i_dev)
|
||||
return (dp);
|
||||
|
||||
if (!create)
|
||||
return (NULL);
|
||||
|
||||
MALLOC(dp, struct iso_dnode *, sizeof(struct iso_dnode), M_CACHE,
|
||||
M_WAITOK);
|
||||
dp->i_dev = dev;
|
||||
dp->i_number = ino;
|
||||
|
||||
if (dq = *dpp)
|
||||
dq->d_prev = dp->d_next;
|
||||
dp->d_next = dq;
|
||||
dp->d_prev = dpp;
|
||||
*dpp = dp;
|
||||
|
||||
return (dp);
|
||||
}
|
||||
|
||||
void
|
||||
iso_dunmap(device)
|
||||
dev_t device;
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
struct vnode *
|
||||
cd9660_ihashget(dev, inum)
|
||||
dev_t dev;
|
||||
ino_t inum;
|
||||
{
|
||||
struct proc *p = curproc; /* XXX */
|
||||
struct iso_node *ip;
|
||||
struct vnode *vp;
|
||||
|
||||
loop:
|
||||
simple_lock(&cd9660_ihash_slock);
|
||||
for (ip = isohashtbl[INOHASH(dev, inum)]; ip; ip = ip->i_next) {
|
||||
if (inum == ip->i_number && dev == ip->i_dev) {
|
||||
vp = ITOV(ip);
|
||||
simple_lock(&vp->v_interlock);
|
||||
simple_unlock(&cd9660_ihash_slock);
|
||||
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p))
|
||||
goto loop;
|
||||
return (vp);
|
||||
}
|
||||
}
|
||||
simple_unlock(&cd9660_ihash_slock);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
simple_unlock(&cd9660_ihash_slock);
|
||||
|
||||
lockmgr(&ip->i_lock, LK_EXCLUSIVE, (struct simplelock *)0, p);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the inode from the hash table.
|
||||
*/
|
||||
void
|
||||
cd9660_ihashrem(ip)
|
||||
register struct iso_node *ip;
|
||||
{
|
||||
register struct iso_node *iq;
|
||||
|
||||
simple_lock(&cd9660_ihash_slock);
|
||||
if (iq = ip->i_next)
|
||||
iq->i_prev = ip->i_prev;
|
||||
*ip->i_prev = iq;
|
||||
#ifdef DIAGNOSTIC
|
||||
ip->i_next = NULL;
|
||||
ip->i_prev = NULL;
|
||||
#endif
|
||||
simple_unlock(&cd9660_ihash_slock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Last reference to an inode, write the inode out and if necessary,
|
||||
* truncate and deallocate the file.
|
||||
*/
|
||||
int
|
||||
cd9660_inactive(ap)
|
||||
struct vop_inactive_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct proc *a_p;
|
||||
} */ *ap;
|
||||
{
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct proc *p = ap->a_p;
|
||||
register struct iso_node *ip = VTOI(vp);
|
||||
int mode, error = 0;
|
||||
|
||||
if (prtactive && vp->v_usecount != 0)
|
||||
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 (ip->inode.iso_mode == 0)
|
||||
vrecycle(vp, (struct simplelock *)0, p);
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reclaim an inode so that it can be used for other purposes.
|
||||
*/
|
||||
int
|
||||
cd9660_reclaim(ap)
|
||||
struct vop_reclaim_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct proc *a_p;
|
||||
} */ *ap;
|
||||
{
|
||||
register struct vnode *vp = ap->a_vp;
|
||||
register struct iso_node *ip = VTOI(vp);
|
||||
int i;
|
||||
|
||||
if (prtactive && vp->v_usecount != 0)
|
||||
vprint("cd9660_reclaim: pushing active", vp);
|
||||
/*
|
||||
* Remove the inode from its hash chain.
|
||||
*/
|
||||
cd9660_ihashrem(ip);
|
||||
/*
|
||||
* Purge old data structures associated with the inode.
|
||||
*/
|
||||
cache_purge(vp);
|
||||
if (ip->i_devvp) {
|
||||
vrele(ip->i_devvp);
|
||||
ip->i_devvp = 0;
|
||||
}
|
||||
FREE(vp->v_data, M_ISOFSNODE);
|
||||
vp->v_data = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* File attributes
|
||||
*/
|
||||
void
|
||||
cd9660_defattr(isodir, inop, bp)
|
||||
struct iso_directory_record *isodir;
|
||||
struct iso_node *inop;
|
||||
struct buf *bp;
|
||||
{
|
||||
struct buf *bp2 = NULL;
|
||||
struct iso_mnt *imp;
|
||||
struct iso_extended_attributes *ap = NULL;
|
||||
int off;
|
||||
|
||||
if (isonum_711(isodir->flags)&2) {
|
||||
inop->inode.iso_mode = S_IFDIR;
|
||||
/*
|
||||
* If we return 2, fts() will assume there are no subdirectories
|
||||
* (just links for the path and .), so instead we return 1.
|
||||
*/
|
||||
inop->inode.iso_links = 1;
|
||||
} else {
|
||||
inop->inode.iso_mode = S_IFREG;
|
||||
inop->inode.iso_links = 1;
|
||||
}
|
||||
if (!bp
|
||||
&& ((imp = inop->i_mnt)->im_flags & ISOFSMNT_EXTATT)
|
||||
&& (off = isonum_711(isodir->ext_attr_length))) {
|
||||
VOP_BLKATOFF(ITOV(inop), (off_t)-(off << imp->im_bshift), NULL,
|
||||
&bp2);
|
||||
bp = bp2;
|
||||
}
|
||||
if (bp) {
|
||||
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;
|
||||
if (!(ap->perm[0]&0x10))
|
||||
inop->inode.iso_mode |= VREAD >> 6;
|
||||
if (!(ap->perm[0]&4))
|
||||
inop->inode.iso_mode |= VEXEC >> 3;
|
||||
if (!(ap->perm[0]&1))
|
||||
inop->inode.iso_mode |= VREAD >> 3;
|
||||
if (!(ap->perm[1]&0x40))
|
||||
inop->inode.iso_mode |= VEXEC;
|
||||
if (!(ap->perm[1]&0x10))
|
||||
inop->inode.iso_mode |= VREAD;
|
||||
inop->inode.iso_uid = isonum_723(ap->owner); /* what about 0? */
|
||||
inop->inode.iso_gid = isonum_723(ap->group); /* what about 0? */
|
||||
} else
|
||||
ap = NULL;
|
||||
}
|
||||
if (!ap) {
|
||||
inop->inode.iso_mode |= VREAD|VEXEC|(VREAD|VEXEC)>>3|(VREAD|VEXEC)>>6;
|
||||
inop->inode.iso_uid = (uid_t)0;
|
||||
inop->inode.iso_gid = (gid_t)0;
|
||||
}
|
||||
if (bp2)
|
||||
brelse(bp2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Time stamps
|
||||
*/
|
||||
void
|
||||
cd9660_deftstamp(isodir,inop,bp)
|
||||
struct iso_directory_record *isodir;
|
||||
struct iso_node *inop;
|
||||
struct buf *bp;
|
||||
{
|
||||
struct buf *bp2 = NULL;
|
||||
struct iso_mnt *imp;
|
||||
struct iso_extended_attributes *ap = NULL;
|
||||
int off;
|
||||
|
||||
if (!bp
|
||||
&& ((imp = inop->i_mnt)->im_flags & ISOFSMNT_EXTATT)
|
||||
&& (off = isonum_711(isodir->ext_attr_length))) {
|
||||
VOP_BLKATOFF(ITOV(inop), (off_t)-(off << imp->im_bshift), NULL,
|
||||
&bp2);
|
||||
bp = bp2;
|
||||
}
|
||||
if (bp) {
|
||||
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))
|
||||
inop->inode.iso_ctime = inop->inode.iso_atime;
|
||||
if (!cd9660_tstamp_conv17(ap->mtime,&inop->inode.iso_mtime))
|
||||
inop->inode.iso_mtime = inop->inode.iso_ctime;
|
||||
} else
|
||||
ap = NULL;
|
||||
}
|
||||
if (!ap) {
|
||||
cd9660_tstamp_conv7(isodir->date,&inop->inode.iso_ctime);
|
||||
inop->inode.iso_atime = inop->inode.iso_ctime;
|
||||
inop->inode.iso_mtime = inop->inode.iso_ctime;
|
||||
}
|
||||
if (bp2)
|
||||
brelse(bp2);
|
||||
}
|
||||
|
||||
int
|
||||
cd9660_tstamp_conv7(pi,pu)
|
||||
u_char *pi;
|
||||
struct timespec *pu;
|
||||
{
|
||||
int i;
|
||||
int crtime, days;
|
||||
int y, m, d, hour, minute, second, tz;
|
||||
|
||||
y = pi[0] + 1900;
|
||||
m = pi[1];
|
||||
d = pi[2];
|
||||
hour = pi[3];
|
||||
minute = pi[4];
|
||||
second = pi[5];
|
||||
tz = pi[6];
|
||||
|
||||
if (y < 1970) {
|
||||
pu->ts_sec = 0;
|
||||
pu->ts_nsec = 0;
|
||||
return 0;
|
||||
} else {
|
||||
#ifdef ORIGINAL
|
||||
/* computes day number relative to Sept. 19th,1989 */
|
||||
/* don't even *THINK* about changing formula. It works! */
|
||||
days = 367*(y-1980)-7*(y+(m+9)/12)/4-3*((y+(m-9)/7)/100+1)/4+275*m/9+d-100;
|
||||
#else
|
||||
/*
|
||||
* Changed :-) to make it relative to Jan. 1st, 1970
|
||||
* and to disambiguate negative division
|
||||
*/
|
||||
days = 367*(y-1960)-7*(y+(m+9)/12)/4-3*((y+(m+9)/12-1)/100+1)/4+275*m/9+d-239;
|
||||
#endif
|
||||
crtime = ((((days * 24) + hour) * 60 + minute) * 60) + second;
|
||||
|
||||
/* timezone offset is unreliable on some disks */
|
||||
if (-48 <= tz && tz <= 52)
|
||||
crtime -= tz * 15 * 60;
|
||||
}
|
||||
pu->ts_sec = crtime;
|
||||
pu->ts_nsec = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static u_int
|
||||
cd9660_chars2ui(begin,len)
|
||||
u_char *begin;
|
||||
int len;
|
||||
{
|
||||
u_int rc;
|
||||
|
||||
for (rc = 0; --len >= 0;) {
|
||||
rc *= 10;
|
||||
rc += *begin++ - '0';
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
cd9660_tstamp_conv17(pi,pu)
|
||||
u_char *pi;
|
||||
struct timespec *pu;
|
||||
{
|
||||
u_char buf[7];
|
||||
|
||||
/* year:"0001"-"9999" -> -1900 */
|
||||
buf[0] = cd9660_chars2ui(pi,4) - 1900;
|
||||
|
||||
/* month: " 1"-"12" -> 1 - 12 */
|
||||
buf[1] = cd9660_chars2ui(pi + 4,2);
|
||||
|
||||
/* day: " 1"-"31" -> 1 - 31 */
|
||||
buf[2] = cd9660_chars2ui(pi + 6,2);
|
||||
|
||||
/* hour: " 0"-"23" -> 0 - 23 */
|
||||
buf[3] = cd9660_chars2ui(pi + 8,2);
|
||||
|
||||
/* minute:" 0"-"59" -> 0 - 59 */
|
||||
buf[4] = cd9660_chars2ui(pi + 10,2);
|
||||
|
||||
/* second:" 0"-"59" -> 0 - 59 */
|
||||
buf[5] = cd9660_chars2ui(pi + 12,2);
|
||||
|
||||
/* difference of GMT */
|
||||
buf[6] = pi[16];
|
||||
|
||||
return cd9660_tstamp_conv7(buf,pu);
|
||||
}
|
||||
|
||||
ino_t
|
||||
isodirino(isodir, imp)
|
||||
struct iso_directory_record *isodir;
|
||||
struct iso_mnt *imp;
|
||||
{
|
||||
ino_t ino;
|
||||
|
||||
ino = (isonum_733(isodir->extent) + isonum_711(isodir->ext_attr_length))
|
||||
<< imp->im_bshift;
|
||||
return (ino);
|
||||
}
|
145
sys/isofs/cd9660/cd9660_node.h
Normal file
145
sys/isofs/cd9660/cd9660_node.h
Normal file
@ -0,0 +1,145 @@
|
||||
/*-
|
||||
* Copyright (c) 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley
|
||||
* by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
|
||||
* Support code is derived from software contributed to Berkeley
|
||||
* by Atsushi Murai (amurai@spec.co.jp).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)cd9660_node.h 8.6 (Berkeley) 5/14/95
|
||||
*/
|
||||
|
||||
/*
|
||||
* Theoretically, directories can be more than 2Gb in length,
|
||||
* however, in practice this seems unlikely. So, we define
|
||||
* the type doff_t as a long to keep down the cost of doing
|
||||
* lookup on a 32-bit machine. If you are porting to a 64-bit
|
||||
* architecture, you should make doff_t the same as off_t.
|
||||
*/
|
||||
#define doff_t long
|
||||
|
||||
typedef struct {
|
||||
struct timespec iso_atime; /* time of last access */
|
||||
struct timespec iso_mtime; /* time of last modification */
|
||||
struct timespec iso_ctime; /* time file changed */
|
||||
u_short iso_mode; /* files access mode and type */
|
||||
uid_t iso_uid; /* owner user id */
|
||||
gid_t iso_gid; /* owner group id */
|
||||
short iso_links; /* links of file */
|
||||
dev_t iso_rdev; /* Major/Minor number for special */
|
||||
} ISO_RRIP_INODE;
|
||||
|
||||
#ifdef ISODEVMAP
|
||||
/*
|
||||
* FOr device# (major,minor) translation table
|
||||
*/
|
||||
struct iso_dnode {
|
||||
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 */
|
||||
};
|
||||
#endif
|
||||
|
||||
struct iso_node {
|
||||
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 */
|
||||
dev_t i_dev; /* device where inode resides */
|
||||
ino_t i_number; /* the identity of the inode */
|
||||
/* we use the actual starting block of the file */
|
||||
struct iso_mnt *i_mnt; /* filesystem associated with this inode */
|
||||
struct lockf *i_lockf; /* head of byte-level lock list */
|
||||
doff_t i_endoff; /* end of useful stuff in directory */
|
||||
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 */
|
||||
struct lock i_lock; /* node lock */
|
||||
|
||||
long iso_extent; /* extent of file */
|
||||
long i_size;
|
||||
long iso_start; /* actual start of data of file (may be different */
|
||||
/* from iso_extent, if file has extended attributes) */
|
||||
ISO_RRIP_INODE inode;
|
||||
};
|
||||
|
||||
#define i_forw i_chain[0]
|
||||
#define i_back i_chain[1]
|
||||
|
||||
/* flags */
|
||||
#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)
|
||||
|
||||
/*
|
||||
* Prototypes for ISOFS vnode operations
|
||||
*/
|
||||
int cd9660_lookup __P((struct vop_lookup_args *));
|
||||
int cd9660_open __P((struct vop_open_args *));
|
||||
int cd9660_close __P((struct vop_close_args *));
|
||||
int cd9660_access __P((struct vop_access_args *));
|
||||
int cd9660_getattr __P((struct vop_getattr_args *));
|
||||
int cd9660_read __P((struct vop_read_args *));
|
||||
int cd9660_ioctl __P((struct vop_ioctl_args *));
|
||||
int cd9660_select __P((struct vop_select_args *));
|
||||
int cd9660_mmap __P((struct vop_mmap_args *));
|
||||
int cd9660_seek __P((struct vop_seek_args *));
|
||||
int cd9660_readdir __P((struct vop_readdir_args *));
|
||||
int cd9660_abortop __P((struct vop_abortop_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_lock __P((struct vop_lock_args *));
|
||||
int cd9660_unlock __P((struct vop_unlock_args *));
|
||||
int cd9660_strategy __P((struct vop_strategy_args *));
|
||||
int cd9660_print __P((struct vop_print_args *));
|
||||
int cd9660_islocked __P((struct vop_islocked_args *));
|
||||
int cd9660_pathconf __P((struct vop_pathconf_args *));
|
||||
int cd9660_blkatoff __P((struct vop_blkatoff_args *));
|
||||
#define cd9660_revoke vop_revoke
|
||||
|
||||
void cd9660_defattr __P((struct iso_directory_record *,
|
||||
struct iso_node *, struct buf *));
|
||||
void cd9660_deftstamp __P((struct iso_directory_record *,
|
||||
struct iso_node *, struct buf *));
|
||||
struct vnode *cd9660_ihashget __P((dev_t, ino_t));
|
||||
void cd9660_ihashins __P((struct iso_node *));
|
||||
void cd9660_ihashrem __P((struct iso_node *));
|
||||
int cd9660_tstamp_conv7 __P((u_char *, struct timespec *));
|
||||
int cd9660_tstamp_conv17 __P((u_char *, struct timespec *));
|
||||
ino_t isodirino __P((struct iso_directory_record *, struct iso_mnt *));
|
||||
#ifdef ISODEVMAP
|
||||
struct iso_dnode *iso_dmap __P((dev_t, ino_t, int));
|
||||
void iso_dunmap __P((dev_t));
|
||||
#endif
|
690
sys/isofs/cd9660/cd9660_rrip.c
Normal file
690
sys/isofs/cd9660/cd9660_rrip.c
Normal file
@ -0,0 +1,690 @@
|
||||
/*-
|
||||
* Copyright (c) 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley
|
||||
* by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
|
||||
* Support code is derived from software contributed to Berkeley
|
||||
* by Atsushi Murai (amurai@spec.co.jp).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)cd9660_rrip.c 8.6 (Berkeley) 12/5/94
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/namei.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <isofs/cd9660/iso.h>
|
||||
#include <isofs/cd9660/cd9660_node.h>
|
||||
#include <isofs/cd9660/cd9660_rrip.h>
|
||||
#include <isofs/cd9660/iso_rrip.h>
|
||||
|
||||
/*
|
||||
* POSIX file attribute
|
||||
*/
|
||||
static int
|
||||
cd9660_rrip_attr(p,ana)
|
||||
ISO_RRIP_ATTR *p;
|
||||
ISO_RRIP_ANALYZE *ana;
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
static void
|
||||
cd9660_rrip_defattr(isodir,ana)
|
||||
struct iso_directory_record *isodir;
|
||||
ISO_RRIP_ANALYZE *ana;
|
||||
{
|
||||
/* But this is a required field! */
|
||||
printf("RRIP without PX field?\n");
|
||||
cd9660_defattr(isodir,ana->inop,NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Symbolic Links
|
||||
*/
|
||||
static int
|
||||
cd9660_rrip_slink(p,ana)
|
||||
ISO_RRIP_SLINK *p;
|
||||
ISO_RRIP_ANALYZE *ana;
|
||||
{
|
||||
register ISO_RRIP_SLINK_COMPONENT *pcomp;
|
||||
register ISO_RRIP_SLINK_COMPONENT *pcompe;
|
||||
int len, wlen, cont;
|
||||
char *outbuf, *inbuf;
|
||||
|
||||
pcomp = (ISO_RRIP_SLINK_COMPONENT *)p->component;
|
||||
pcompe = (ISO_RRIP_SLINK_COMPONENT *)((char *)p + isonum_711(p->h.length));
|
||||
len = *ana->outlen;
|
||||
outbuf = ana->outbuf;
|
||||
cont = ana->cont;
|
||||
|
||||
/*
|
||||
* Gathering a Symbolic name from each component with path
|
||||
*/
|
||||
for (;
|
||||
pcomp < pcompe;
|
||||
pcomp = (ISO_RRIP_SLINK_COMPONENT *)((char *)pcomp + ISO_RRIP_SLSIZ
|
||||
+ isonum_711(pcomp->clen))) {
|
||||
|
||||
if (!cont) {
|
||||
if (len < ana->maxlen) {
|
||||
len++;
|
||||
*outbuf++ = '/';
|
||||
}
|
||||
}
|
||||
cont = 0;
|
||||
|
||||
inbuf = "..";
|
||||
wlen = 0;
|
||||
|
||||
switch (*pcomp->cflag) {
|
||||
|
||||
case ISO_SUSP_CFLAG_CURRENT:
|
||||
/* Inserting Current */
|
||||
wlen = 1;
|
||||
break;
|
||||
|
||||
case ISO_SUSP_CFLAG_PARENT:
|
||||
/* Inserting Parent */
|
||||
wlen = 2;
|
||||
break;
|
||||
|
||||
case ISO_SUSP_CFLAG_ROOT:
|
||||
/* Inserting slash for ROOT */
|
||||
/* start over from beginning(?) */
|
||||
outbuf -= len;
|
||||
len = 0;
|
||||
break;
|
||||
|
||||
case ISO_SUSP_CFLAG_VOLROOT:
|
||||
/* Inserting a mount point i.e. "/cdrom" */
|
||||
/* same as above */
|
||||
outbuf -= len;
|
||||
len = 0;
|
||||
inbuf = ana->imp->im_mountp->mnt_stat.f_mntonname;
|
||||
wlen = strlen(inbuf);
|
||||
break;
|
||||
|
||||
case ISO_SUSP_CFLAG_HOST:
|
||||
/* Inserting hostname i.e. "kurt.tools.de" */
|
||||
inbuf = hostname;
|
||||
wlen = hostnamelen;
|
||||
break;
|
||||
|
||||
case ISO_SUSP_CFLAG_CONTINUE:
|
||||
cont = 1;
|
||||
/* fall thru */
|
||||
case 0:
|
||||
/* Inserting component */
|
||||
wlen = isonum_711(pcomp->clen);
|
||||
inbuf = pcomp->name;
|
||||
break;
|
||||
default:
|
||||
printf("RRIP with incorrect flags?");
|
||||
wlen = ana->maxlen + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (len + wlen > ana->maxlen) {
|
||||
/* indicate error to caller */
|
||||
ana->cont = 1;
|
||||
ana->fields = 0;
|
||||
ana->outbuf -= *ana->outlen;
|
||||
*ana->outlen = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bcopy(inbuf,outbuf,wlen);
|
||||
outbuf += wlen;
|
||||
len += wlen;
|
||||
|
||||
}
|
||||
ana->outbuf = outbuf;
|
||||
*ana->outlen = len;
|
||||
ana->cont = cont;
|
||||
|
||||
if (!isonum_711(p->flags)) {
|
||||
ana->fields &= ~ISO_SUSP_SLINK;
|
||||
return ISO_SUSP_SLINK;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Alternate name
|
||||
*/
|
||||
static int
|
||||
cd9660_rrip_altname(p,ana)
|
||||
ISO_RRIP_ALTNAME *p;
|
||||
ISO_RRIP_ANALYZE *ana;
|
||||
{
|
||||
char *inbuf;
|
||||
int wlen;
|
||||
int cont;
|
||||
|
||||
inbuf = "..";
|
||||
wlen = 0;
|
||||
cont = 0;
|
||||
|
||||
switch (*p->flags) {
|
||||
case ISO_SUSP_CFLAG_CURRENT:
|
||||
/* Inserting Current */
|
||||
wlen = 1;
|
||||
break;
|
||||
|
||||
case ISO_SUSP_CFLAG_PARENT:
|
||||
/* Inserting Parent */
|
||||
wlen = 2;
|
||||
break;
|
||||
|
||||
case ISO_SUSP_CFLAG_HOST:
|
||||
/* Inserting hostname i.e. "kurt.tools.de" */
|
||||
inbuf = hostname;
|
||||
wlen = hostnamelen;
|
||||
break;
|
||||
|
||||
case ISO_SUSP_CFLAG_CONTINUE:
|
||||
cont = 1;
|
||||
/* fall thru */
|
||||
case 0:
|
||||
/* Inserting component */
|
||||
wlen = isonum_711(p->h.length) - 5;
|
||||
inbuf = (char *)p + 5;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("RRIP with incorrect NM flags?\n");
|
||||
wlen = ana->maxlen + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((*ana->outlen += wlen) > ana->maxlen) {
|
||||
/* treat as no name field */
|
||||
ana->fields &= ~ISO_SUSP_ALTNAME;
|
||||
ana->outbuf -= *ana->outlen - wlen;
|
||||
*ana->outlen = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bcopy(inbuf,ana->outbuf,wlen);
|
||||
ana->outbuf += wlen;
|
||||
|
||||
if (!cont) {
|
||||
ana->fields &= ~ISO_SUSP_ALTNAME;
|
||||
return ISO_SUSP_ALTNAME;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
cd9660_rrip_defname(isodir,ana)
|
||||
struct iso_directory_record *isodir;
|
||||
ISO_RRIP_ANALYZE *ana;
|
||||
{
|
||||
strcpy(ana->outbuf,"..");
|
||||
switch (*isodir->name) {
|
||||
default:
|
||||
isofntrans(isodir->name,isonum_711(isodir->name_len),
|
||||
ana->outbuf,ana->outlen,
|
||||
1,isonum_711(isodir->flags)&4);
|
||||
break;
|
||||
case 0:
|
||||
*ana->outlen = 1;
|
||||
break;
|
||||
case 1:
|
||||
*ana->outlen = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Parent or Child Link
|
||||
*/
|
||||
static int
|
||||
cd9660_rrip_pclink(p,ana)
|
||||
ISO_RRIP_CLINK *p;
|
||||
ISO_RRIP_ANALYZE *ana;
|
||||
{
|
||||
*ana->inump = isonum_733(p->dir_loc) << ana->imp->im_bshift;
|
||||
ana->fields &= ~(ISO_SUSP_CLINK|ISO_SUSP_PLINK);
|
||||
return *p->h.type == 'C' ? ISO_SUSP_CLINK : ISO_SUSP_PLINK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Relocated directory
|
||||
*/
|
||||
static int
|
||||
cd9660_rrip_reldir(p,ana)
|
||||
ISO_RRIP_RELDIR *p;
|
||||
ISO_RRIP_ANALYZE *ana;
|
||||
{
|
||||
/* special hack to make caller aware of RE field */
|
||||
*ana->outlen = 0;
|
||||
ana->fields = 0;
|
||||
return ISO_SUSP_RELDIR|ISO_SUSP_ALTNAME|ISO_SUSP_CLINK|ISO_SUSP_PLINK;
|
||||
}
|
||||
|
||||
static int
|
||||
cd9660_rrip_tstamp(p,ana)
|
||||
ISO_RRIP_TSTAMP *p;
|
||||
ISO_RRIP_ANALYZE *ana;
|
||||
{
|
||||
u_char *ptime;
|
||||
|
||||
ptime = p->time;
|
||||
|
||||
/* Check a format of time stamp (7bytes/17bytes) */
|
||||
if (!(*p->flags&ISO_SUSP_TSTAMP_FORM17)) {
|
||||
if (*p->flags&ISO_SUSP_TSTAMP_CREAT)
|
||||
ptime += 7;
|
||||
|
||||
if (*p->flags&ISO_SUSP_TSTAMP_MODIFY) {
|
||||
cd9660_tstamp_conv7(ptime,&ana->inop->inode.iso_mtime);
|
||||
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);
|
||||
ptime += 7;
|
||||
} else
|
||||
ana->inop->inode.iso_atime = ana->inop->inode.iso_mtime;
|
||||
|
||||
if (*p->flags&ISO_SUSP_TSTAMP_ATTR)
|
||||
cd9660_tstamp_conv7(ptime,&ana->inop->inode.iso_ctime);
|
||||
else
|
||||
ana->inop->inode.iso_ctime = ana->inop->inode.iso_mtime;
|
||||
|
||||
} else {
|
||||
if (*p->flags&ISO_SUSP_TSTAMP_CREAT)
|
||||
ptime += 17;
|
||||
|
||||
if (*p->flags&ISO_SUSP_TSTAMP_MODIFY) {
|
||||
cd9660_tstamp_conv17(ptime,&ana->inop->inode.iso_mtime);
|
||||
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;
|
||||
} else
|
||||
ana->inop->inode.iso_atime = ana->inop->inode.iso_mtime;
|
||||
|
||||
if (*p->flags&ISO_SUSP_TSTAMP_ATTR)
|
||||
cd9660_tstamp_conv17(ptime,&ana->inop->inode.iso_ctime);
|
||||
else
|
||||
ana->inop->inode.iso_ctime = ana->inop->inode.iso_mtime;
|
||||
|
||||
}
|
||||
ana->fields &= ~ISO_SUSP_TSTAMP;
|
||||
return ISO_SUSP_TSTAMP;
|
||||
}
|
||||
|
||||
static void
|
||||
cd9660_rrip_deftstamp(isodir,ana)
|
||||
struct iso_directory_record *isodir;
|
||||
ISO_RRIP_ANALYZE *ana;
|
||||
{
|
||||
cd9660_deftstamp(isodir,ana->inop,NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* POSIX device modes
|
||||
*/
|
||||
static int
|
||||
cd9660_rrip_device(p,ana)
|
||||
ISO_RRIP_DEVICE *p;
|
||||
ISO_RRIP_ANALYZE *ana;
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* Flag indicating
|
||||
*/
|
||||
static int
|
||||
cd9660_rrip_idflag(p,ana)
|
||||
ISO_RRIP_IDFLAG *p;
|
||||
ISO_RRIP_ANALYZE *ana;
|
||||
{
|
||||
ana->fields &= isonum_711(p->flags)|~0xff; /* don't touch high bits */
|
||||
/* special handling of RE field */
|
||||
if (ana->fields&ISO_SUSP_RELDIR)
|
||||
return cd9660_rrip_reldir(p,ana);
|
||||
|
||||
return ISO_SUSP_IDFLAG;
|
||||
}
|
||||
|
||||
/*
|
||||
* Continuation pointer
|
||||
*/
|
||||
static int
|
||||
cd9660_rrip_cont(p,ana)
|
||||
ISO_RRIP_CONT *p;
|
||||
ISO_RRIP_ANALYZE *ana;
|
||||
{
|
||||
ana->iso_ce_blk = isonum_733(p->location);
|
||||
ana->iso_ce_off = isonum_733(p->offset);
|
||||
ana->iso_ce_len = isonum_733(p->length);
|
||||
return ISO_SUSP_CONT;
|
||||
}
|
||||
|
||||
/*
|
||||
* System Use end
|
||||
*/
|
||||
static int
|
||||
cd9660_rrip_stop(p,ana)
|
||||
ISO_SUSP_HEADER *p;
|
||||
ISO_RRIP_ANALYZE *ana;
|
||||
{
|
||||
return ISO_SUSP_STOP;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extension reference
|
||||
*/
|
||||
static int
|
||||
cd9660_rrip_extref(p,ana)
|
||||
ISO_RRIP_EXTREF *p;
|
||||
ISO_RRIP_ANALYZE *ana;
|
||||
{
|
||||
if (isonum_711(p->len_id) != 10
|
||||
|| bcmp((char *)p + 8,"RRIP_1991A",10)
|
||||
|| isonum_711(p->version) != 1)
|
||||
return 0;
|
||||
ana->fields &= ~ISO_SUSP_EXTREF;
|
||||
return ISO_SUSP_EXTREF;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
char type[2];
|
||||
int (*func)();
|
||||
void (*func2)();
|
||||
int result;
|
||||
} RRIP_TABLE;
|
||||
|
||||
static int
|
||||
cd9660_rrip_loop(isodir,ana,table)
|
||||
struct iso_directory_record *isodir;
|
||||
ISO_RRIP_ANALYZE *ana;
|
||||
RRIP_TABLE *table;
|
||||
{
|
||||
register RRIP_TABLE *ptable;
|
||||
register ISO_SUSP_HEADER *phead;
|
||||
register ISO_SUSP_HEADER *pend;
|
||||
struct buf *bp = NULL;
|
||||
int i;
|
||||
char *pwhead;
|
||||
int result;
|
||||
|
||||
/*
|
||||
* Note: If name length is odd,
|
||||
* it will be padding 1 byte after the name
|
||||
*/
|
||||
pwhead = isodir->name + isonum_711(isodir->name_len);
|
||||
if (!(isonum_711(isodir->name_len)&1))
|
||||
pwhead++;
|
||||
|
||||
/* If it's not the '.' entry of the root dir obey SP field */
|
||||
if (*isodir->name != 0
|
||||
|| isonum_733(isodir->extent) != ana->imp->root_extent)
|
||||
pwhead += ana->imp->rr_skip;
|
||||
else
|
||||
pwhead += ana->imp->rr_skip0;
|
||||
|
||||
phead = (ISO_SUSP_HEADER *)pwhead;
|
||||
pend = (ISO_SUSP_HEADER *)((char *)isodir + isonum_711(isodir->length));
|
||||
|
||||
result = 0;
|
||||
while (1) {
|
||||
ana->iso_ce_len = 0;
|
||||
/*
|
||||
* Note: "pend" should be more than one SUSP header
|
||||
*/
|
||||
while (pend >= phead + 1) {
|
||||
if (isonum_711(phead->version) == 1) {
|
||||
for (ptable = table; ptable->func; ptable++) {
|
||||
if (*phead->type == *ptable->type
|
||||
&& phead->type[1] == ptable->type[1]) {
|
||||
result |= ptable->func(phead,ana);
|
||||
break;
|
||||
}
|
||||
}
|
||||
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->iso_ce_blk >= ana->imp->volume_space_size
|
||||
|| ana->iso_ce_off + ana->iso_ce_len > ana->imp->logical_block_size
|
||||
|| bread(ana->imp->im_devvp,
|
||||
ana->iso_ce_blk <<
|
||||
(ana->imp->im_bshift - DEV_BSHIFT),
|
||||
ana->imp->logical_block_size, NOCRED, &bp))
|
||||
/* what to do now? */
|
||||
break;
|
||||
phead = (ISO_SUSP_HEADER *)(bp->b_data + ana->iso_ce_off);
|
||||
pend = (ISO_SUSP_HEADER *) ((char *)phead + ana->iso_ce_len);
|
||||
} else
|
||||
break;
|
||||
}
|
||||
if (bp)
|
||||
brelse(bp);
|
||||
/*
|
||||
* If we don't find the Basic SUSP stuffs, just set default value
|
||||
* (attribute/time stamp)
|
||||
*/
|
||||
for (ptable = table; ptable->func2; ptable++)
|
||||
if (!(ptable->result&result))
|
||||
ptable->func2(isodir,ana);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get Attributes.
|
||||
*/
|
||||
static RRIP_TABLE rrip_table_analyze[] = {
|
||||
{ "PX", cd9660_rrip_attr, cd9660_rrip_defattr, ISO_SUSP_ATTR },
|
||||
{ "TF", cd9660_rrip_tstamp, cd9660_rrip_deftstamp, ISO_SUSP_TSTAMP },
|
||||
{ "PN", cd9660_rrip_device, 0, ISO_SUSP_DEVICE },
|
||||
{ "RR", cd9660_rrip_idflag, 0, ISO_SUSP_IDFLAG },
|
||||
{ "CE", cd9660_rrip_cont, 0, ISO_SUSP_CONT },
|
||||
{ "ST", cd9660_rrip_stop, 0, ISO_SUSP_STOP },
|
||||
{ "", 0, 0, 0 }
|
||||
};
|
||||
|
||||
int
|
||||
cd9660_rrip_analyze(isodir,inop,imp)
|
||||
struct iso_directory_record *isodir;
|
||||
struct iso_node *inop;
|
||||
struct iso_mnt *imp;
|
||||
{
|
||||
ISO_RRIP_ANALYZE analyze;
|
||||
|
||||
analyze.inop = inop;
|
||||
analyze.imp = imp;
|
||||
analyze.fields = ISO_SUSP_ATTR|ISO_SUSP_TSTAMP|ISO_SUSP_DEVICE;
|
||||
|
||||
return cd9660_rrip_loop(isodir,&analyze,rrip_table_analyze);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get Alternate Name.
|
||||
*/
|
||||
static RRIP_TABLE rrip_table_getname[] = {
|
||||
{ "NM", cd9660_rrip_altname, cd9660_rrip_defname, ISO_SUSP_ALTNAME },
|
||||
{ "CL", cd9660_rrip_pclink, 0, ISO_SUSP_CLINK|ISO_SUSP_PLINK },
|
||||
{ "PL", cd9660_rrip_pclink, 0, ISO_SUSP_CLINK|ISO_SUSP_PLINK },
|
||||
{ "RE", cd9660_rrip_reldir, 0, ISO_SUSP_RELDIR },
|
||||
{ "RR", cd9660_rrip_idflag, 0, ISO_SUSP_IDFLAG },
|
||||
{ "CE", cd9660_rrip_cont, 0, ISO_SUSP_CONT },
|
||||
{ "ST", cd9660_rrip_stop, 0, ISO_SUSP_STOP },
|
||||
{ "", 0, 0, 0 }
|
||||
};
|
||||
|
||||
int
|
||||
cd9660_rrip_getname(isodir,outbuf,outlen,inump,imp)
|
||||
struct iso_directory_record *isodir;
|
||||
char *outbuf;
|
||||
u_short *outlen;
|
||||
ino_t *inump;
|
||||
struct iso_mnt *imp;
|
||||
{
|
||||
ISO_RRIP_ANALYZE analyze;
|
||||
RRIP_TABLE *tab;
|
||||
|
||||
analyze.outbuf = outbuf;
|
||||
analyze.outlen = outlen;
|
||||
analyze.maxlen = NAME_MAX;
|
||||
analyze.inump = inump;
|
||||
analyze.imp = imp;
|
||||
analyze.fields = ISO_SUSP_ALTNAME|ISO_SUSP_RELDIR|ISO_SUSP_CLINK|ISO_SUSP_PLINK;
|
||||
*outlen = 0;
|
||||
|
||||
tab = rrip_table_getname;
|
||||
if (*isodir->name == 0
|
||||
|| *isodir->name == 1) {
|
||||
cd9660_rrip_defname(isodir,&analyze);
|
||||
|
||||
analyze.fields &= ~ISO_SUSP_ALTNAME;
|
||||
tab++;
|
||||
}
|
||||
|
||||
return cd9660_rrip_loop(isodir,&analyze,tab);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get Symbolic Link.
|
||||
*/
|
||||
static RRIP_TABLE rrip_table_getsymname[] = {
|
||||
{ "SL", cd9660_rrip_slink, 0, ISO_SUSP_SLINK },
|
||||
{ "RR", cd9660_rrip_idflag, 0, ISO_SUSP_IDFLAG },
|
||||
{ "CE", cd9660_rrip_cont, 0, ISO_SUSP_CONT },
|
||||
{ "ST", cd9660_rrip_stop, 0, ISO_SUSP_STOP },
|
||||
{ "", 0, 0, 0 }
|
||||
};
|
||||
|
||||
int
|
||||
cd9660_rrip_getsymname(isodir,outbuf,outlen,imp)
|
||||
struct iso_directory_record *isodir;
|
||||
char *outbuf;
|
||||
u_short *outlen;
|
||||
struct iso_mnt *imp;
|
||||
{
|
||||
ISO_RRIP_ANALYZE analyze;
|
||||
|
||||
analyze.outbuf = outbuf;
|
||||
analyze.outlen = outlen;
|
||||
*outlen = 0;
|
||||
analyze.maxlen = MAXPATHLEN;
|
||||
analyze.cont = 1; /* don't start with a slash */
|
||||
analyze.imp = imp;
|
||||
analyze.fields = ISO_SUSP_SLINK;
|
||||
|
||||
return (cd9660_rrip_loop(isodir,&analyze,rrip_table_getsymname)&ISO_SUSP_SLINK);
|
||||
}
|
||||
|
||||
static RRIP_TABLE rrip_table_extref[] = {
|
||||
{ "ER", cd9660_rrip_extref, 0, ISO_SUSP_EXTREF },
|
||||
{ "CE", cd9660_rrip_cont, 0, ISO_SUSP_CONT },
|
||||
{ "ST", cd9660_rrip_stop, 0, ISO_SUSP_STOP },
|
||||
{ "", 0, 0, 0 }
|
||||
};
|
||||
|
||||
/*
|
||||
* Check for Rock Ridge Extension and return offset of its fields.
|
||||
* Note: We insist on the ER field.
|
||||
*/
|
||||
int
|
||||
cd9660_rrip_offset(isodir,imp)
|
||||
struct iso_directory_record *isodir;
|
||||
struct iso_mnt *imp;
|
||||
{
|
||||
ISO_RRIP_OFFSET *p;
|
||||
ISO_RRIP_ANALYZE analyze;
|
||||
|
||||
imp->rr_skip0 = 0;
|
||||
p = (ISO_RRIP_OFFSET *)(isodir->name + 1);
|
||||
if (bcmp(p,"SP\7\1\276\357",6)) {
|
||||
/* Maybe, it's a CDROM XA disc? */
|
||||
imp->rr_skip0 = 15;
|
||||
p = (ISO_RRIP_OFFSET *)((char *)p + 15);
|
||||
if (bcmp(p,"SP\7\1\276\357",6))
|
||||
return -1;
|
||||
}
|
||||
|
||||
analyze.imp = imp;
|
||||
analyze.fields = ISO_SUSP_EXTREF;
|
||||
if (!(cd9660_rrip_loop(isodir,&analyze,rrip_table_extref)&ISO_SUSP_EXTREF))
|
||||
return -1;
|
||||
|
||||
return isonum_711(p->skip);
|
||||
}
|
140
sys/isofs/cd9660/cd9660_rrip.h
Normal file
140
sys/isofs/cd9660/cd9660_rrip.h
Normal file
@ -0,0 +1,140 @@
|
||||
/*-
|
||||
* Copyright (c) 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley
|
||||
* by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
|
||||
* Support code is derived from software contributed to Berkeley
|
||||
* by Atsushi Murai (amurai@spec.co.jp).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)cd9660_rrip.h 8.2 (Berkeley) 12/5/94
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
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 [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 [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
|
||||
#define ISO_SUSP_CFLAG_ROOT 0x08
|
||||
#define ISO_SUSP_CFLAG_VOLROOT 0x10
|
||||
#define ISO_SUSP_CFLAG_HOST 0x20
|
||||
|
||||
typedef struct {
|
||||
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
|
||||
|
||||
typedef struct {
|
||||
ISO_SUSP_HEADER h;
|
||||
u_char flags [ISODCL ( 4, 4)];
|
||||
u_char component [ISODCL ( 5, 5)];
|
||||
} ISO_RRIP_SLINK;
|
||||
|
||||
typedef struct {
|
||||
ISO_SUSP_HEADER h;
|
||||
char flags [ISODCL ( 4, 4)];
|
||||
} ISO_RRIP_ALTNAME;
|
||||
|
||||
typedef struct {
|
||||
ISO_SUSP_HEADER h;
|
||||
char dir_loc [ISODCL ( 4, 11)]; /* 733 */
|
||||
} ISO_RRIP_CLINK;
|
||||
|
||||
typedef struct {
|
||||
ISO_SUSP_HEADER h;
|
||||
char dir_loc [ISODCL ( 4, 11)]; /* 733 */
|
||||
} ISO_RRIP_PLINK;
|
||||
|
||||
typedef struct {
|
||||
ISO_SUSP_HEADER h;
|
||||
} ISO_RRIP_RELDIR;
|
||||
|
||||
#define ISO_SUSP_TSTAMP_FORM17 0x80
|
||||
#define ISO_SUSP_TSTAMP_FORM7 0x00
|
||||
#define ISO_SUSP_TSTAMP_CREAT 0x01
|
||||
#define ISO_SUSP_TSTAMP_MODIFY 0x02
|
||||
#define ISO_SUSP_TSTAMP_ACCESS 0x04
|
||||
#define ISO_SUSP_TSTAMP_ATTR 0x08
|
||||
#define ISO_SUSP_TSTAMP_BACKUP 0x10
|
||||
#define ISO_SUSP_TSTAMP_EXPIRE 0x20
|
||||
#define ISO_SUSP_TSTAMP_EFFECT 0x40
|
||||
|
||||
typedef struct {
|
||||
ISO_SUSP_HEADER h;
|
||||
u_char flags [ISODCL ( 4, 4)];
|
||||
u_char time [ISODCL ( 5, 5)];
|
||||
} ISO_RRIP_TSTAMP;
|
||||
|
||||
typedef struct {
|
||||
ISO_SUSP_HEADER h;
|
||||
u_char flags [ISODCL ( 4, 4)];
|
||||
} ISO_RRIP_IDFLAG;
|
||||
|
||||
typedef struct {
|
||||
ISO_SUSP_HEADER h;
|
||||
char len_id [ISODCL ( 4, 4)];
|
||||
char len_des [ISODCL ( 5, 5)];
|
||||
char len_src [ISODCL ( 6, 6)];
|
||||
char version [ISODCL ( 7, 7)];
|
||||
} ISO_RRIP_EXTREF;
|
||||
|
||||
typedef struct {
|
||||
ISO_SUSP_HEADER h;
|
||||
char check [ISODCL ( 4, 5)];
|
||||
char skip [ISODCL ( 6, 6)];
|
||||
} ISO_RRIP_OFFSET;
|
||||
|
||||
typedef struct {
|
||||
ISO_SUSP_HEADER h;
|
||||
char location [ISODCL ( 4, 11)];
|
||||
char offset [ISODCL ( 12, 19)];
|
||||
char length [ISODCL ( 20, 27)];
|
||||
} ISO_RRIP_CONT;
|
150
sys/isofs/cd9660/cd9660_util.c
Normal file
150
sys/isofs/cd9660/cd9660_util.c
Normal file
@ -0,0 +1,150 @@
|
||||
/*-
|
||||
* Copyright (c) 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley
|
||||
* by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
|
||||
* Support code is derived from software contributed to Berkeley
|
||||
* by Atsushi Murai (amurai@spec.co.jp).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)cd9660_util.c 8.3 (Berkeley) 12/5/94
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/namei.h>
|
||||
#include <sys/resourcevar.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <miscfs/specfs/specdev.h> /* XXX */
|
||||
#include <miscfs/fifofs/fifo.h> /* XXX */
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/dir.h>
|
||||
|
||||
#include <isofs/cd9660/iso.h>
|
||||
|
||||
/*
|
||||
* translate and compare a filename
|
||||
* Note: Version number plus ';' may be omitted.
|
||||
*/
|
||||
int
|
||||
isofncmp(fn, fnlen, isofn, isolen)
|
||||
u_char *fn, *isofn;
|
||||
int fnlen, isolen;
|
||||
{
|
||||
int i, j;
|
||||
char c;
|
||||
|
||||
while (--fnlen >= 0) {
|
||||
if (--isolen < 0)
|
||||
return *fn;
|
||||
if ((c = *isofn++) == ';') {
|
||||
switch (*fn++) {
|
||||
default:
|
||||
return *--fn;
|
||||
case 0:
|
||||
return 0;
|
||||
case ';':
|
||||
break;
|
||||
}
|
||||
for (i = 0; --fnlen >= 0; i = i * 10 + *fn++ - '0') {
|
||||
if (*fn < '0' || *fn > '9') {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
for (j = 0; --isolen >= 0; j = j * 10 + *isofn++ - '0');
|
||||
return i - j;
|
||||
}
|
||||
if (c != *fn) {
|
||||
if (c >= 'A' && c <= 'Z') {
|
||||
if (c + ('a' - 'A') != *fn) {
|
||||
if (*fn >= 'a' && *fn <= 'z')
|
||||
return *fn - ('a' - 'A') - c;
|
||||
else
|
||||
return *fn - c;
|
||||
}
|
||||
} else
|
||||
return *fn - c;
|
||||
}
|
||||
fn++;
|
||||
}
|
||||
if (isolen > 0) {
|
||||
switch (*isofn) {
|
||||
default:
|
||||
return -1;
|
||||
case '.':
|
||||
if (isofn[1] != ';')
|
||||
return -1;
|
||||
case ';':
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* translate a filename
|
||||
*/
|
||||
void
|
||||
isofntrans(infn, infnlen, outfn, outfnlen, original, assoc)
|
||||
u_char *infn, *outfn;
|
||||
int infnlen;
|
||||
u_short *outfnlen;
|
||||
int original;
|
||||
int assoc;
|
||||
{
|
||||
int fnidx = 0;
|
||||
|
||||
if (assoc) {
|
||||
*outfn++ = ASSOCCHAR;
|
||||
fnidx++;
|
||||
infnlen++;
|
||||
}
|
||||
for (; fnidx < infnlen; fnidx++) {
|
||||
char c = *infn++;
|
||||
|
||||
if (!original && c >= 'A' && c <= 'Z')
|
||||
*outfn++ = c + ('a' - 'A');
|
||||
else if (!original && c == '.' && *infn == ';')
|
||||
break;
|
||||
else if (!original && c == ';')
|
||||
break;
|
||||
else
|
||||
*outfn++ = c;
|
||||
}
|
||||
*outfnlen = fnidx;
|
||||
}
|
800
sys/isofs/cd9660/cd9660_vfsops.c
Normal file
800
sys/isofs/cd9660/cd9660_vfsops.c
Normal file
@ -0,0 +1,800 @@
|
||||
/*-
|
||||
* Copyright (c) 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley
|
||||
* by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
|
||||
* Support code is derived from software contributed to Berkeley
|
||||
* by Atsushi Murai (amurai@spec.co.jp).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)cd9660_vfsops.c 8.18 (Berkeley) 5/22/95
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/namei.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <miscfs/specfs/specdev.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/dkbad.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <isofs/cd9660/iso.h>
|
||||
#include <isofs/cd9660/cd9660_node.h>
|
||||
#include <isofs/cd9660/cd9660_mount.h>
|
||||
|
||||
extern int enodev ();
|
||||
|
||||
struct vfsops cd9660_vfsops = {
|
||||
cd9660_mount,
|
||||
cd9660_start,
|
||||
cd9660_unmount,
|
||||
cd9660_root,
|
||||
cd9660_quotactl,
|
||||
cd9660_statfs,
|
||||
cd9660_sync,
|
||||
cd9660_vget,
|
||||
cd9660_fhtovp,
|
||||
cd9660_vptofh,
|
||||
cd9660_init,
|
||||
cd9660_sysctl
|
||||
};
|
||||
|
||||
/*
|
||||
* Called by vfs_mountroot when iso is going to be mounted as root.
|
||||
*/
|
||||
|
||||
static iso_mountfs();
|
||||
|
||||
cd9660_mountroot()
|
||||
{
|
||||
struct mount *mp;
|
||||
extern struct vnode *rootvp;
|
||||
struct proc *p = curproc; /* XXX */
|
||||
struct iso_args args;
|
||||
int error;
|
||||
|
||||
/*
|
||||
* Get vnodes for swapdev and rootdev.
|
||||
*/
|
||||
if ((error = bdevvp(swapdev, &swapdev_vp)) ||
|
||||
(error = bdevvp(rootdev, &rootvp))) {
|
||||
printf("cd9660_mountroot: can't setup bdevvp's");
|
||||
return (error);
|
||||
}
|
||||
|
||||
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);
|
||||
simple_unlock(&mountlist_slock);
|
||||
(void)cd9660_statfs(mp, &mp->mnt_stat, p);
|
||||
vfs_unbusy(mp, p);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* VFS Operations.
|
||||
*
|
||||
* mount system call
|
||||
*/
|
||||
cd9660_mount(mp, path, data, ndp, p)
|
||||
register struct mount *mp;
|
||||
char *path;
|
||||
caddr_t data;
|
||||
struct nameidata *ndp;
|
||||
struct proc *p;
|
||||
{
|
||||
struct vnode *devvp;
|
||||
struct iso_args args;
|
||||
u_int size;
|
||||
int error;
|
||||
struct iso_mnt *imp;
|
||||
|
||||
if (error = copyin(data, (caddr_t)&args, sizeof (struct iso_args)))
|
||||
return (error);
|
||||
|
||||
if ((mp->mnt_flag & MNT_RDONLY) == 0)
|
||||
return (EROFS);
|
||||
|
||||
/*
|
||||
* If updating, check whether changing from read-only to
|
||||
* read/write; if there is no device name, that's all we do.
|
||||
*/
|
||||
if (mp->mnt_flag & MNT_UPDATE) {
|
||||
imp = VFSTOISOFS(mp);
|
||||
if (args.fspec == 0)
|
||||
return (vfs_export(mp, &imp->im_export, &args.export));
|
||||
}
|
||||
/*
|
||||
* Not an update, or updating the name: look up the name
|
||||
* and verify that it refers to a sensible block device.
|
||||
*/
|
||||
NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p);
|
||||
if (error = namei(ndp))
|
||||
return (error);
|
||||
devvp = ndp->ni_vp;
|
||||
|
||||
if (devvp->v_type != VBLK) {
|
||||
vrele(devvp);
|
||||
return ENOTBLK;
|
||||
}
|
||||
if (major(devvp->v_rdev) >= nblkdev) {
|
||||
vrele(devvp);
|
||||
return ENXIO;
|
||||
}
|
||||
if ((mp->mnt_flag & MNT_UPDATE) == 0)
|
||||
error = iso_mountfs(devvp, mp, p, &args);
|
||||
else {
|
||||
if (devvp != imp->im_devvp)
|
||||
error = EINVAL; /* needs translation */
|
||||
else
|
||||
vrele(devvp);
|
||||
}
|
||||
if (error) {
|
||||
vrele(devvp);
|
||||
return error;
|
||||
}
|
||||
imp = VFSTOISOFS(mp);
|
||||
(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);
|
||||
(void) cd9660_statfs(mp, &mp->mnt_stat, p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Common code for mount and mountroot
|
||||
*/
|
||||
static iso_mountfs(devvp, mp, p, argp)
|
||||
register struct vnode *devvp;
|
||||
struct mount *mp;
|
||||
struct proc *p;
|
||||
struct iso_args *argp;
|
||||
{
|
||||
register struct iso_mnt *isomp = (struct iso_mnt *)0;
|
||||
struct buf *bp = NULL;
|
||||
dev_t dev = devvp->v_rdev;
|
||||
caddr_t base, space;
|
||||
int havepart = 0, blks;
|
||||
int error = EINVAL, i, size;
|
||||
int needclose = 0;
|
||||
int ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
|
||||
extern struct vnode *rootvp;
|
||||
int j;
|
||||
int iso_bsize;
|
||||
int iso_blknum;
|
||||
struct iso_volume_descriptor *vdp;
|
||||
struct iso_primary_descriptor *pri;
|
||||
struct iso_directory_record *rootp;
|
||||
int logical_block_size;
|
||||
|
||||
if (!ronly)
|
||||
return EROFS;
|
||||
|
||||
/*
|
||||
* Disallow multiple mounts of the same device.
|
||||
* Disallow mounting of a device that is currently in use
|
||||
* (except for root, which might share swap device for miniroot).
|
||||
* Flush out any old buffers remaining from a previous use.
|
||||
*/
|
||||
if (error = vfs_mountedon(devvp))
|
||||
return error;
|
||||
if (vcount(devvp) > 1 && devvp != rootvp)
|
||||
return EBUSY;
|
||||
if (error = vinvalbuf(devvp, V_SAVE, p->p_ucred, p, 0, 0))
|
||||
return (error);
|
||||
|
||||
if (error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p))
|
||||
return error;
|
||||
needclose = 1;
|
||||
|
||||
/* This is the "logical sector size". The standard says this
|
||||
* should be 2048 or the physical sector size on the device,
|
||||
* whichever is greater. For now, we'll just use a constant.
|
||||
*/
|
||||
iso_bsize = ISO_DEFAULT_BLOCK_SIZE;
|
||||
|
||||
for (iso_blknum = 16; iso_blknum < 100; iso_blknum++) {
|
||||
if (error = bread(devvp, iso_blknum * btodb(iso_bsize),
|
||||
iso_bsize, NOCRED, &bp))
|
||||
goto out;
|
||||
|
||||
vdp = (struct iso_volume_descriptor *)bp->b_data;
|
||||
if (bcmp (vdp->id, ISO_STANDARD_ID, sizeof vdp->id) != 0) {
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (isonum_711 (vdp->type) == ISO_VD_END) {
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (isonum_711 (vdp->type) == ISO_VD_PRIMARY)
|
||||
break;
|
||||
brelse(bp);
|
||||
}
|
||||
|
||||
if (isonum_711 (vdp->type) != ISO_VD_PRIMARY) {
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
pri = (struct iso_primary_descriptor *)vdp;
|
||||
|
||||
logical_block_size = isonum_723 (pri->logical_block_size);
|
||||
|
||||
if (logical_block_size < DEV_BSIZE || logical_block_size > MAXBSIZE
|
||||
|| (logical_block_size & (logical_block_size - 1)) != 0) {
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rootp = (struct iso_directory_record *)pri->root_directory_record;
|
||||
|
||||
isomp = malloc(sizeof *isomp, M_ISOFSMNT, M_WAITOK);
|
||||
bzero((caddr_t)isomp, sizeof *isomp);
|
||||
isomp->logical_block_size = logical_block_size;
|
||||
isomp->volume_space_size = isonum_733 (pri->volume_space_size);
|
||||
bcopy (rootp, isomp->root, sizeof isomp->root);
|
||||
isomp->root_extent = isonum_733 (rootp->extent);
|
||||
isomp->root_size = isonum_733 (rootp->size);
|
||||
|
||||
isomp->im_bmask = logical_block_size - 1;
|
||||
isomp->im_bshift = 0;
|
||||
while ((1 << isomp->im_bshift) < isomp->logical_block_size)
|
||||
isomp->im_bshift++;
|
||||
|
||||
bp->b_flags |= B_AGE;
|
||||
brelse(bp);
|
||||
bp = NULL;
|
||||
|
||||
mp->mnt_data = (qaddr_t)isomp;
|
||||
mp->mnt_stat.f_fsid.val[0] = (long)dev;
|
||||
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;
|
||||
isomp->im_dev = dev;
|
||||
isomp->im_devvp = devvp;
|
||||
|
||||
devvp->v_specflags |= SI_MOUNTEDON;
|
||||
|
||||
/* 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->im_bshift - DEV_BSHIFT),
|
||||
isomp->logical_block_size, NOCRED, &bp))
|
||||
goto out;
|
||||
|
||||
rootp = (struct iso_directory_record *)bp->b_data;
|
||||
|
||||
if ((isomp->rr_skip = cd9660_rrip_offset(rootp,isomp)) < 0) {
|
||||
argp->flags |= ISOFSMNT_NORRIP;
|
||||
} else {
|
||||
argp->flags &= ~ISOFSMNT_GENS;
|
||||
}
|
||||
|
||||
/*
|
||||
* The contents are valid,
|
||||
* but they will get reread as part of another vnode, so...
|
||||
*/
|
||||
bp->b_flags |= B_AGE;
|
||||
brelse(bp);
|
||||
bp = NULL;
|
||||
}
|
||||
isomp->im_flags = argp->flags&(ISOFSMNT_NORRIP|ISOFSMNT_GENS|ISOFSMNT_EXTATT);
|
||||
switch (isomp->im_flags&(ISOFSMNT_NORRIP|ISOFSMNT_GENS)) {
|
||||
default:
|
||||
isomp->iso_ftype = ISO_FTYPE_DEFAULT;
|
||||
break;
|
||||
case ISOFSMNT_GENS|ISOFSMNT_NORRIP:
|
||||
isomp->iso_ftype = ISO_FTYPE_9660;
|
||||
break;
|
||||
case 0:
|
||||
isomp->iso_ftype = ISO_FTYPE_RRIP;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
out:
|
||||
if (bp)
|
||||
brelse(bp);
|
||||
if (needclose)
|
||||
(void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p);
|
||||
if (isomp) {
|
||||
free((caddr_t)isomp, M_ISOFSMNT);
|
||||
mp->mnt_data = (qaddr_t)0;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make a filesystem operational.
|
||||
* Nothing to do at the moment.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
cd9660_start(mp, flags, p)
|
||||
struct mount *mp;
|
||||
int flags;
|
||||
struct proc *p;
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* unmount system call
|
||||
*/
|
||||
int
|
||||
cd9660_unmount(mp, mntflags, p)
|
||||
struct mount *mp;
|
||||
int mntflags;
|
||||
struct proc *p;
|
||||
{
|
||||
register struct iso_mnt *isomp;
|
||||
int i, error, ronly, flags = 0;
|
||||
|
||||
if (mntflags & MNT_FORCE)
|
||||
flags |= FORCECLOSE;
|
||||
#if 0
|
||||
mntflushbuf(mp, 0);
|
||||
if (mntinvalbuf(mp))
|
||||
return EBUSY;
|
||||
#endif
|
||||
if (error = vflush(mp, NULLVP, flags))
|
||||
return (error);
|
||||
|
||||
isomp = VFSTOISOFS(mp);
|
||||
|
||||
#ifdef ISODEVMAP
|
||||
if (isomp->iso_ftype == ISO_FTYPE_RRIP)
|
||||
iso_dunmap(isomp->im_dev);
|
||||
#endif
|
||||
|
||||
isomp->im_devvp->v_specflags &= ~SI_MOUNTEDON;
|
||||
error = VOP_CLOSE(isomp->im_devvp, FREAD, NOCRED, p);
|
||||
vrele(isomp->im_devvp);
|
||||
free((caddr_t)isomp, M_ISOFSMNT);
|
||||
mp->mnt_data = (qaddr_t)0;
|
||||
mp->mnt_flag &= ~MNT_LOCAL;
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return root of a filesystem
|
||||
*/
|
||||
cd9660_root(mp, vpp)
|
||||
struct mount *mp;
|
||||
struct vnode **vpp;
|
||||
{
|
||||
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 vget, that it's a relocated directory.
|
||||
*/
|
||||
return (cd9660_vget_internal(mp, ino, vpp,
|
||||
imp->iso_ftype == ISO_FTYPE_RRIP, dp));
|
||||
}
|
||||
|
||||
/*
|
||||
* Do operations associated with quotas, not supported
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
cd9660_quotactl(mp, cmd, uid, arg, p)
|
||||
struct mount *mp;
|
||||
int cmd;
|
||||
uid_t uid;
|
||||
caddr_t arg;
|
||||
struct proc *p;
|
||||
{
|
||||
|
||||
return (EOPNOTSUPP);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get file system statistics.
|
||||
*/
|
||||
cd9660_statfs(mp, sbp, p)
|
||||
struct mount *mp;
|
||||
register struct statfs *sbp;
|
||||
struct proc *p;
|
||||
{
|
||||
register struct iso_mnt *isomp;
|
||||
register struct fs *fs;
|
||||
|
||||
isomp = VFSTOISOFS(mp);
|
||||
|
||||
#ifdef COMPAT_09
|
||||
sbp->f_type = 5;
|
||||
#else
|
||||
sbp->f_type = 0;
|
||||
#endif
|
||||
sbp->f_bsize = isomp->logical_block_size;
|
||||
sbp->f_iosize = sbp->f_bsize; /* XXX */
|
||||
sbp->f_blocks = isomp->volume_space_size;
|
||||
sbp->f_bfree = 0; /* total free blocks */
|
||||
sbp->f_bavail = 0; /* blocks free for non superuser */
|
||||
sbp->f_files = 0; /* total files */
|
||||
sbp->f_ffree = 0; /* free file nodes */
|
||||
if (sbp != &mp->mnt_stat) {
|
||||
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;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
cd9660_sync(mp, waitfor, cred, p)
|
||||
struct mount *mp;
|
||||
int waitfor;
|
||||
struct ucred *cred;
|
||||
struct proc *p;
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* File handle to vnode
|
||||
*
|
||||
* Have to be really careful about stale file handles:
|
||||
* - check that the inode number is in range
|
||||
* - call iget() to get the locked inode
|
||||
* - check for an unallocated inode (i_mode == 0)
|
||||
* - check that the generation number matches
|
||||
*/
|
||||
|
||||
struct ifid {
|
||||
ushort ifid_len;
|
||||
ushort ifid_pad;
|
||||
int ifid_ino;
|
||||
long ifid_start;
|
||||
};
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
cd9660_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)
|
||||
register struct mount *mp;
|
||||
struct fid *fhp;
|
||||
struct mbuf *nam;
|
||||
struct vnode **vpp;
|
||||
int *exflagsp;
|
||||
struct ucred **credanonp;
|
||||
{
|
||||
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);
|
||||
|
||||
if (error = VFS_VGET(mp, ifhp->ifid_ino, &nvp)) {
|
||||
*vpp = NULLVP;
|
||||
return (error);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
int
|
||||
cd9660_vget(mp, ino, vpp)
|
||||
struct mount *mp;
|
||||
ino_t ino;
|
||||
struct vnode **vpp;
|
||||
{
|
||||
|
||||
/*
|
||||
* XXXX
|
||||
* It would be nice if we didn't always set the `relocated' flag
|
||||
* and force the extra read, but I don't want to think about fixing
|
||||
* that right now.
|
||||
*/
|
||||
return (cd9660_vget_internal(mp, ino, vpp,
|
||||
#if 0
|
||||
VFSTOISOFS(mp)->iso_ftype == ISO_FTYPE_RRIP,
|
||||
#else
|
||||
0,
|
||||
#endif
|
||||
(struct iso_directory_entry *)0));
|
||||
}
|
||||
|
||||
int
|
||||
cd9660_vget_internal(mp, ino, vpp, relocated, isodir)
|
||||
struct mount *mp;
|
||||
ino_t ino;
|
||||
struct vnode **vpp;
|
||||
int relocated;
|
||||
struct iso_directory_record *isodir;
|
||||
{
|
||||
struct proc *p = curproc; /* XXX */
|
||||
struct iso_mnt *imp;
|
||||
struct iso_node *ip;
|
||||
struct buf *bp;
|
||||
struct vnode *vp, *nvp;
|
||||
dev_t dev;
|
||||
int error;
|
||||
|
||||
imp = VFSTOISOFS(mp);
|
||||
dev = imp->im_dev;
|
||||
if ((*vpp = cd9660_ihashget(dev, ino)) != NULLVP)
|
||||
return (0);
|
||||
|
||||
/* Allocate a new vnode/iso_node. */
|
||||
if (error = getnewvnode(VT_ISOFS, mp, cd9660_vnodeop_p, &vp)) {
|
||||
*vpp = NULLVP;
|
||||
return (error);
|
||||
}
|
||||
MALLOC(ip, struct iso_node *, sizeof(struct iso_node), M_ISOFSNODE,
|
||||
M_WAITOK);
|
||||
bzero((caddr_t)ip, sizeof(struct iso_node));
|
||||
lockinit(&ip->i_lock, PINOD, "isonode", 0, 0);
|
||||
vp->v_data = ip;
|
||||
ip->i_vnode = vp;
|
||||
ip->i_dev = dev;
|
||||
ip->i_number = ino;
|
||||
|
||||
/*
|
||||
* Put it onto its hash chain and lock it so that other requests for
|
||||
* this inode will block if they arrive while we are sleeping waiting
|
||||
* for old data structures to be purged or for the contents of the
|
||||
* disk portion of this inode to be read.
|
||||
*/
|
||||
cd9660_ihashins(ip);
|
||||
|
||||
if (isodir == 0) {
|
||||
int lbn, off;
|
||||
|
||||
lbn = lblkno(imp, ino);
|
||||
if (lbn >= imp->volume_space_size) {
|
||||
vput(vp);
|
||||
printf("fhtovp: lbn exceed volume space %d\n", lbn);
|
||||
return (ESTALE);
|
||||
}
|
||||
|
||||
off = blkoff(imp, ino);
|
||||
if (off + ISO_DIRECTORY_RECORD_SIZE > imp->logical_block_size) {
|
||||
vput(vp);
|
||||
printf("fhtovp: crosses block boundary %d\n",
|
||||
off + ISO_DIRECTORY_RECORD_SIZE);
|
||||
return (ESTALE);
|
||||
}
|
||||
|
||||
error = bread(imp->im_devvp,
|
||||
lbn << (imp->im_bshift - DEV_BSHIFT),
|
||||
imp->logical_block_size, NOCRED, &bp);
|
||||
if (error) {
|
||||
vput(vp);
|
||||
brelse(bp);
|
||||
printf("fhtovp: bread error %d\n",error);
|
||||
return (error);
|
||||
}
|
||||
isodir = (struct iso_directory_record *)(bp->b_data + off);
|
||||
|
||||
if (off + isonum_711(isodir->length) >
|
||||
imp->logical_block_size) {
|
||||
vput(vp);
|
||||
if (bp != 0)
|
||||
brelse(bp);
|
||||
printf("fhtovp: directory crosses block boundary %d[off=%d/len=%d]\n",
|
||||
off +isonum_711(isodir->length), off,
|
||||
isonum_711(isodir->length));
|
||||
return (ESTALE);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (isonum_733(isodir->extent) +
|
||||
isonum_711(isodir->ext_attr_length) != ifhp->ifid_start) {
|
||||
if (bp != 0)
|
||||
brelse(bp);
|
||||
printf("fhtovp: file start miss %d vs %d\n",
|
||||
isonum_733(isodir->extent) + isonum_711(isodir->ext_attr_length),
|
||||
ifhp->ifid_start);
|
||||
return (ESTALE);
|
||||
}
|
||||
#endif
|
||||
} else
|
||||
bp = 0;
|
||||
|
||||
ip->i_mnt = imp;
|
||||
ip->i_devvp = imp->im_devvp;
|
||||
VREF(ip->i_devvp);
|
||||
|
||||
if (relocated) {
|
||||
/*
|
||||
* On relocated directories we must
|
||||
* read the `.' entry out of a dir.
|
||||
*/
|
||||
ip->iso_start = ino >> imp->im_bshift;
|
||||
if (bp != 0)
|
||||
brelse(bp);
|
||||
if (error = VOP_BLKATOFF(vp, (off_t)0, NULL, &bp)) {
|
||||
vput(vp);
|
||||
return (error);
|
||||
}
|
||||
isodir = (struct iso_directory_record *)bp->b_data;
|
||||
}
|
||||
|
||||
ip->iso_extent = isonum_733(isodir->extent);
|
||||
ip->i_size = isonum_733(isodir->size);
|
||||
ip->iso_start = isonum_711(isodir->ext_attr_length) + ip->iso_extent;
|
||||
|
||||
/*
|
||||
* Setup time stamp, attribute
|
||||
*/
|
||||
vp->v_type = VNON;
|
||||
switch (imp->iso_ftype) {
|
||||
default: /* ISO_FTYPE_9660 */
|
||||
{
|
||||
struct buf *bp2;
|
||||
int off;
|
||||
if ((imp->im_flags & ISOFSMNT_EXTATT)
|
||||
&& (off = isonum_711(isodir->ext_attr_length)))
|
||||
VOP_BLKATOFF(vp, (off_t)-(off << imp->im_bshift), NULL,
|
||||
&bp2);
|
||||
else
|
||||
bp2 = NULL;
|
||||
cd9660_defattr(isodir, ip, bp2);
|
||||
cd9660_deftstamp(isodir, ip, bp2);
|
||||
if (bp2)
|
||||
brelse(bp2);
|
||||
break;
|
||||
}
|
||||
case ISO_FTYPE_RRIP:
|
||||
cd9660_rrip_analyze(isodir, ip, imp);
|
||||
break;
|
||||
}
|
||||
|
||||
if (bp != 0)
|
||||
brelse(bp);
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
if (ip->iso_extent == imp->root_extent)
|
||||
vp->v_flag |= VROOT;
|
||||
|
||||
/*
|
||||
* XXX need generation number?
|
||||
*/
|
||||
|
||||
*vpp = vp;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Vnode pointer to File handle
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
cd9660_vptofh(vp, fhp)
|
||||
struct vnode *vp;
|
||||
struct fid *fhp;
|
||||
{
|
||||
register struct iso_node *ip = VTOI(vp);
|
||||
register struct ifid *ifhp;
|
||||
register struct iso_mnt *mp = ip->i_mnt;
|
||||
|
||||
ifhp = (struct ifid *)fhp;
|
||||
ifhp->ifid_len = sizeof(struct ifid);
|
||||
|
||||
ifhp->ifid_ino = ip->i_number;
|
||||
ifhp->ifid_start = ip->iso_start;
|
||||
|
||||
#ifdef ISOFS_DBG
|
||||
printf("vptofh: ino %d, start %ld\n",
|
||||
ifhp->ifid_ino,ifhp->ifid_start);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
1211
sys/isofs/cd9660/cd9660_vnops.c
Normal file
1211
sys/isofs/cd9660/cd9660_vnops.c
Normal file
File diff suppressed because it is too large
Load Diff
268
sys/isofs/cd9660/iso.h
Normal file
268
sys/isofs/cd9660/iso.h
Normal file
@ -0,0 +1,268 @@
|
||||
/*-
|
||||
* Copyright (c) 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley
|
||||
* by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
|
||||
* Support code is derived from software contributed to Berkeley
|
||||
* by Atsushi Murai (amurai@spec.co.jp).
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)iso.h 8.6 (Berkeley) 5/10/95
|
||||
*/
|
||||
|
||||
#define ISODCL(from, to) (to - from + 1)
|
||||
|
||||
struct iso_volume_descriptor {
|
||||
char type[ISODCL(1,1)]; /* 711 */
|
||||
char id[ISODCL(2,6)];
|
||||
char version[ISODCL(7,7)];
|
||||
char data[ISODCL(8,2048)];
|
||||
};
|
||||
|
||||
/* volume descriptor types */
|
||||
#define ISO_VD_PRIMARY 1
|
||||
#define ISO_VD_END 255
|
||||
|
||||
#define ISO_STANDARD_ID "CD001"
|
||||
#define ISO_ECMA_ID "CDW01"
|
||||
|
||||
struct iso_primary_descriptor {
|
||||
char type [ISODCL ( 1, 1)]; /* 711 */
|
||||
char id [ISODCL ( 2, 6)];
|
||||
char version [ISODCL ( 7, 7)]; /* 711 */
|
||||
char unused1 [ISODCL ( 8, 8)];
|
||||
char system_id [ISODCL ( 9, 40)]; /* achars */
|
||||
char volume_id [ISODCL ( 41, 72)]; /* dchars */
|
||||
char unused2 [ISODCL ( 73, 80)];
|
||||
char volume_space_size [ISODCL ( 81, 88)]; /* 733 */
|
||||
char unused3 [ISODCL ( 89, 120)];
|
||||
char volume_set_size [ISODCL (121, 124)]; /* 723 */
|
||||
char volume_sequence_number [ISODCL (125, 128)]; /* 723 */
|
||||
char logical_block_size [ISODCL (129, 132)]; /* 723 */
|
||||
char path_table_size [ISODCL (133, 140)]; /* 733 */
|
||||
char type_l_path_table [ISODCL (141, 144)]; /* 731 */
|
||||
char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */
|
||||
char type_m_path_table [ISODCL (149, 152)]; /* 732 */
|
||||
char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */
|
||||
char root_directory_record [ISODCL (157, 190)]; /* 9.1 */
|
||||
char volume_set_id [ISODCL (191, 318)]; /* dchars */
|
||||
char publisher_id [ISODCL (319, 446)]; /* achars */
|
||||
char preparer_id [ISODCL (447, 574)]; /* achars */
|
||||
char application_id [ISODCL (575, 702)]; /* achars */
|
||||
char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */
|
||||
char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */
|
||||
char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */
|
||||
char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */
|
||||
char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */
|
||||
char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */
|
||||
char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */
|
||||
char file_structure_version [ISODCL (882, 882)]; /* 711 */
|
||||
char unused4 [ISODCL (883, 883)];
|
||||
char application_data [ISODCL (884, 1395)];
|
||||
char unused5 [ISODCL (1396, 2048)];
|
||||
};
|
||||
#define ISO_DEFAULT_BLOCK_SIZE 2048
|
||||
|
||||
struct iso_directory_record {
|
||||
char length [ISODCL (1, 1)]; /* 711 */
|
||||
char ext_attr_length [ISODCL (2, 2)]; /* 711 */
|
||||
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 [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 {
|
||||
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 */
|
||||
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)];
|
||||
u_char len_au [ISODCL (247, 250)]; /* 723 */
|
||||
};
|
||||
|
||||
/* CD-ROM Format type */
|
||||
enum ISO_FTYPE { ISO_FTYPE_DEFAULT, ISO_FTYPE_9660, ISO_FTYPE_RRIP, ISO_FTYPE_ECMA };
|
||||
|
||||
#ifndef ISOFSMNT_ROOT
|
||||
#define ISOFSMNT_ROOT 0
|
||||
#endif
|
||||
|
||||
struct iso_mnt {
|
||||
int im_flags;
|
||||
|
||||
struct mount *im_mountp;
|
||||
dev_t im_dev;
|
||||
struct vnode *im_devvp;
|
||||
|
||||
int logical_block_size;
|
||||
int im_bshift;
|
||||
int im_bmask;
|
||||
|
||||
int volume_space_size;
|
||||
struct netexport im_export;
|
||||
|
||||
char root[ISODCL (157, 190)];
|
||||
int root_extent;
|
||||
int root_size;
|
||||
enum ISO_FTYPE iso_ftype;
|
||||
|
||||
int rr_skip;
|
||||
int rr_skip0;
|
||||
};
|
||||
|
||||
#define VFSTOISOFS(mp) ((struct iso_mnt *)((mp)->mnt_data))
|
||||
|
||||
#define blkoff(imp, loc) ((loc) & (imp)->im_bmask)
|
||||
#define lblktosize(imp, blk) ((blk) << (imp)->im_bshift)
|
||||
#define lblkno(imp, loc) ((loc) >> (imp)->im_bshift)
|
||||
#define blksize(imp, ip, lbn) ((imp)->logical_block_size)
|
||||
|
||||
int cd9660_mount __P((struct mount *,
|
||||
char *, caddr_t, struct nameidata *, struct proc *));
|
||||
int cd9660_start __P((struct mount *, int, struct proc *));
|
||||
int cd9660_unmount __P((struct mount *, int, struct proc *));
|
||||
int cd9660_root __P((struct mount *, struct vnode **));
|
||||
int cd9660_quotactl __P((struct mount *, int, uid_t, caddr_t, struct proc *));
|
||||
int cd9660_statfs __P((struct mount *, struct statfs *, struct proc *));
|
||||
int cd9660_sync __P((struct mount *, int, struct ucred *, struct proc *));
|
||||
int cd9660_vget __P((struct mount *, ino_t, struct vnode **));
|
||||
int cd9660_fhtovp __P((struct mount *, struct fid *, struct mbuf *,
|
||||
struct vnode **, int *, struct ucred **));
|
||||
int cd9660_vptofh __P((struct vnode *, struct fid *));
|
||||
int cd9660_init __P((struct vfsconf *));
|
||||
#define cd9660_sysctl ((int (*) __P((int *, u_int, void *, size_t *, void *, \
|
||||
size_t, struct proc *)))eopnotsupp)
|
||||
|
||||
int cd9660_mountroot __P((void));
|
||||
|
||||
extern int (**cd9660_vnodeop_p)();
|
||||
extern int (**cd9660_specop_p)();
|
||||
#ifdef FIFO
|
||||
extern int (**cd9660_fifoop_p)();
|
||||
#endif
|
||||
|
||||
static __inline int
|
||||
isonum_711(p)
|
||||
u_char *p;
|
||||
{
|
||||
return *p;
|
||||
}
|
||||
|
||||
static __inline int
|
||||
isonum_712(p)
|
||||
char *p;
|
||||
{
|
||||
return *p;
|
||||
}
|
||||
|
||||
#ifndef UNALIGNED_ACCESS
|
||||
|
||||
static __inline int
|
||||
isonum_723(p)
|
||||
u_char *p;
|
||||
{
|
||||
return *p|(p[1] << 8);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
isonum_733(p)
|
||||
u_char *p;
|
||||
{
|
||||
return *p|(p[1] << 8)|(p[2] << 16)|(p[3] << 24);
|
||||
}
|
||||
|
||||
#else /* UNALIGNED_ACCESS */
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
|
||||
static __inline int
|
||||
isonum_723(p)
|
||||
u_char *p
|
||||
{
|
||||
return *(u_int16t *)p;
|
||||
}
|
||||
|
||||
static __inline int
|
||||
isonum_733(p)
|
||||
u_char *p;
|
||||
{
|
||||
return *(u_int32t *)p;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
|
||||
static __inline int
|
||||
isonum_723(p)
|
||||
u_char *p
|
||||
{
|
||||
return *(u_int16t *)(p + 2);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
isonum_733(p)
|
||||
u_char *p;
|
||||
{
|
||||
return *(u_int32t *)(p + 4);
|
||||
}
|
||||
|
||||
#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 '='.
|
||||
*/
|
||||
#define ASSOCCHAR '='
|
Loading…
Reference in New Issue
Block a user