Return to BSD News archive
Path: sserve!newshost.anu.edu.au!munnari.oz.au!spool.mu.edu!howland.reston.ans.net!EU.net!ieunet!news.ieunet.ie!jkh From: jkh@whisker.hubbard.ie (Jordan K. Hubbard) Newsgroups: comp.os.386bsd.bugs Subject: Re: ISOFS with RockRidge Date: 04 Jun 1994 11:58:36 GMT Organization: Jordan Hubbard Lines: 6169 Message-ID: <JKH.94Jun4115837@whisker.hubbard.ie> References: <DFR.94Jun3104518@minnow.render.com> NNTP-Posting-Host: whisker.hubbard.ie In-reply-to: dfr@render.com's message of 03 Jun 1994 09:45:18 GMT In article <DFR.94Jun3104518@minnow.render.com> dfr@render.com (Doug Rabson) writes: It appears that in RockRidge, deeply nested directories need to be renamed due to some kind of limitation in the ISO format. in particular, 'R6untarred/xc/programs/Xserver/PEX5/ddpex/mi/include' (among others) was renamed to 'R6untarred/xc/programs/Xserver/PEX5/ddpex/mi/../../../../../../../RR_MOVED/INCLUDE0' Known problem - anyone care to give the following a try and report back to freebsd-hackers@freefall.cdrom.com? Do NOT reply to me here as I'll be at USENIX and won't have a chance to read mail sent here for a couple of weeks, starting Monday. Jordan From: Brian Childs <brian@claremont.com> Received: by claremont.com (4.1/3.1.090690-Claremont Systems Inc.) id AA24506; Fri, 3 Jun 94 13:16:18 EDT Message-Id: <9406031716.AA24506@claremont.com> Subject: isofs mishandles relocated dirs, and all special files Index: sys/isofs FreeBSD-1.1 Apparently-To: FreeBSD-bugfiler@freefall.cdrom.com Sender: freebsd-bugs-owner@freefall.cdrom.com Precedence: bulk Description: isofs mishandles relocated directories, and all special files including block, char, symbolic links, and fifo's. It sort of handles symlinks, they don't show up when you just enter 'ls' in a dir, you have to enter 'ls -l symlink-file'. Also, when mounted with -norrip mount flag, isofs still uses posix filenames instead of ISO9660. Repeat-By: mounting an isofs with relocated dirs & special files, and doing some 'ls'ing. if you don't have an isofs with these characteristics, then get a hold of tsx-11.mit.edu:/pub/linux/BETA/cdrom/mkisofs-1.01.tar.gz, compile it, put it in your path, and run the following shell script, and then run 'mount -rt isofs /dev/fd0a /mnt' ---BEGIN---8<---BEGIN---8<---BEGIN---8<---BEGIN---8<---BEGIN---8<---BEGIN--- #!/bin/sh echo -n "insert a scratch floppy in fd0: <PRESS RETURN>" read junk fdformat /dev/rfd0 cd /tmp topdir=`pwd` if [ -d rrip ]; then rm -rf rrip fi # Make a really deep dir structure mkdir rrip dir="rrip" for subdir in sub1 sub2 sub3 sub4 sub5 sub6 sub7 sub8 sub9 sub10; do dir="$dir/$subdir" mkdir $dir done # Create a dummy file cd rrip testfile="sub1/sub2/sub3/sub4/sub5/sub6/sub7/sub8/sub9/sub10/Testfile" echo "This is a stupid test file" > $testfile # Create a symlink to our dummy file ln -s $testfile # Create some special files mknod Pipe p mknod fd0 b 2 0 mknod rfd0 c 9 0 cd $topdir mkisofs -RT -o /dev/rfd0 rrip ---*END*---8<---*END*---8<---*END*---8<---*END*---8<---*END*---8<---*END*--- Fix: This is a port of NetBSD's isofs to FreeBSD. The following files are patched: /usr/src/sys/sys/mount.h /usr/src/sys/isofs/* /usr/src/sbin/mount_isofs/* The new functionality includes: - the -norrip mount flag now ignores posix filenames. - symbolic links now appear when 'ls' is run - FIFO's are supported - posix device nodes are now supported - relocated directories are handled properly. Allowing directories to be nested more than 8 levels. isofs_lookup.c is the only file which generates warnings, it generates: ../../isofs/isofs_lookup.c:99: warning: `ep' may be used uninitialized in this function ../../isofs/isofs_lookup.c:246: warning: `p' may be used uninitialized in this function The two are really the same problem, namely 'ep' is possibly uninitialized. I couldn't decide what a good initializer would be, so instead of masking a potential bug, I left in the warning. This is a VERY big patch, let me know if you dont get it all. The cksum for the patch alone is: 2391581647 149171 isofs.patch ---BEGIN---8<---BEGIN---8<---BEGIN---8<---BEGIN---8<---BEGIN---8<---BEGIN--- *** sys/sys/mount.h-orig Wed Jun 1 22:17:05 1994 --- sys/sys/mount.h Wed Jun 1 22:19:44 1994 *************** *** 285,290 **** --- 285,304 ---- }; #endif /* PCFS */ + #ifdef ISOFS + /* + * Arguments to mount ISO 9660 filesystems. + */ + struct iso_args { + char *fspec; /* block special holding the fs to mount */ + int flags; /* mounting flags, see below */ + }; + #define ISOFSMNT_NORRIP 0x00000001 /* disable Rock Ridge Ext.*/ + #define ISOFSMNT_GENS 0x00000002 /* enable usage of generation numbers */ + #define ISOFSMNT_EXTATT 0x00000004 /* enable usage of extended attributes */ + #endif /* ISOFS */ + + #ifdef KERNEL /* * exported vnode operations *** sys/isofs-old/TODO Wed Jun 1 03:02:32 1994 --- sys/isofs/TODO Mon May 30 08:55:55 1994 *************** *** 1,4 **** ! # $Id: TODO,v 1.2 1993/07/20 03:27:21 jkh Exp $ 1) should understand "older", original High Sierra ("CDROM001") type --- 1,4 ---- ! # $Id: TODO,v 1.4 1993/09/07 15:40:51 ws Exp $ 1) should understand "older", original High Sierra ("CDROM001") type *************** *** 13,34 **** o File Attribute o Time stamp o uid, gid Except follows: ! o POSIX device modes ! I have no idea right now, we should check a REAL implementation ! for 386BSD..... - o Limitation of 8 level directory( ISO9660 limitation ) - - Rock Ridge Extension are defined with the "CL/PL/RE" for getting - rid of this limitation. But as far as I test the cdroms,I'v never - seen this definition and we can access the over 8 level without - it. (Another word, this limitation is NOT physical ISO9660's - FORMAT limitation for unix stuffs.... I believe... ) - 3) should be called cdfs, as there are other ISO file system soon possible Not yet. Probably we should make another file system when the ECMA draft --- 13,28 ---- 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 3) should be called cdfs, as there are other ISO file system soon possible Not yet. Probably we should make another file system when the ECMA draft *************** *** 48,55 **** 6) should run as a user process, and not take up kernel space (cdroms are slow) ! Not yet. And addition, we should try to avoid a long seek by a absolute path ! with using the PATH TABLE or other method. 7) ECMA support. --- 42,48 ---- 6) should run as a user process, and not take up kernel space (cdroms are slow) ! Not yet. 7) ECMA support. *************** *** 62,66 **** --- 55,77 ---- clean. As far as I know, if you export the cdrom by NFS, the client can access the 8 bit clean (ie. Solaris Japanese with EUC code ) + 9) Access checks in isofs_access + + Not yet. + + 10) Support for generation numbers + + Yes. Default is to list only the last file (the one with the highest + generation number). If you mount with -gen, all files are shown with + their generation numbers. In both cases you can specify the generation + number on opening files (if you happen to know it) or leave it off, + when it will again find the last file. + + 11) Support for extended attributes + + Yes. Since this requires an extra block buffer for the attributes + this must be enabled on mounting with the option -extattr. + ---------- Last update July 19, '93 by Atsushi Murai. (amurai@spec.co.jp) + Last update August 19, '93 by Wolfgang Solfrank. (ws@tools.de) + Ported to FreeBSD-1.1 June 2, '94 by Brian Childs. (brian@claremont.com) *** sys/isofs-old/iso.h Wed Jun 1 03:02:32 1994 --- sys/isofs/iso.h Wed Jun 1 23:15:56 1994 *************** *** 1,5 **** /* ! * $Id: iso.h,v 1.5 1993/12/19 00:51:02 wollman Exp $ */ #ifndef _ISOFS_ISO_H_ --- 1,5 ---- /* ! * $Id: iso.h,v 1.6 1993/10/28 17:38:42 ws Exp $ */ #ifndef _ISOFS_ISO_H_ *************** *** 70,105 **** char name_len [ISODCL (33, 33)]; /* 711 */ char name [0]; }; ! /* CD-ROM Fromat type */ ! enum ISO_FTYPE { ISO_FTYPE_9660, ISO_FTYPE_RRIP, ISO_FTYPE_ECMA }; struct iso_mnt { int logical_block_size; int volume_space_size; struct vnode *im_devvp; char im_fsmnt[50]; - int im_ronly; - int im_fmod; struct mount *im_mountp; dev_t im_dev; ! int im_bshift; int im_bmask; ! int im_bsize; ! char root[ISODCL (157, 190)]; int root_extent; int root_size; enum ISO_FTYPE iso_ftype; }; #define VFSTOISOFS(mp) ((struct iso_mnt *)((mp)->mnt_data)) ! #define iso_blkoff(imp, loc) ((loc) & ~(imp)->im_bmask) #define iso_lblkno(imp, loc) ((loc) >> (imp)->im_bshift) ! #define iso_blksize(imp, ip, lbn) ((imp)->im_bsize) #define iso_lblktosize(imp, blk) ((blk) << (imp)->im_bshift) --- 70,133 ---- char name_len [ISODCL (33, 33)]; /* 711 */ char name [0]; }; + /* can't take sizeof(iso_directory_record), because of possible alignment + of the last entry (34 instead of 33) */ + #define ISO_DIRECTORY_RECORD_SIZE 33 + + struct iso_extended_attributes { + unsigned char owner [ISODCL (1, 4)]; /* 723 */ + unsigned char group [ISODCL (5, 8)]; /* 723 */ + unsigned char perm [ISODCL (9, 10)]; /* 9.5.3 */ + char ctime [ISODCL (11, 27)]; /* 8.4.26.1 */ + char mtime [ISODCL (28, 44)]; /* 8.4.26.1 */ + char xtime [ISODCL (45, 61)]; /* 8.4.26.1 */ + char ftime [ISODCL (62, 78)]; /* 8.4.26.1 */ + char recfmt [ISODCL (79, 79)]; /* 711 */ + char recattr [ISODCL (80, 80)]; /* 711 */ + unsigned char reclen [ISODCL (81, 84)]; /* 723 */ + char system_id [ISODCL (85, 116)]; /* achars */ + char system_use [ISODCL (117, 180)]; + char version [ISODCL (181, 181)]; /* 711 */ + char len_esc [ISODCL (182, 182)]; /* 711 */ + char reserved [ISODCL (183, 246)]; + unsigned char len_au [ISODCL (247, 250)]; /* 723 */ + }; + + /* 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; + int logical_block_size; int volume_space_size; struct vnode *im_devvp; char im_fsmnt[50]; struct mount *im_mountp; dev_t im_dev; ! int im_bshift; int im_bmask; ! 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 iso_blkoff(imp, loc) ((loc) & (imp)->im_bmask) #define iso_lblkno(imp, loc) ((loc) >> (imp)->im_bshift) ! #define iso_blksize(imp, ip, lbn) ((imp)->logical_block_size) #define iso_lblktosize(imp, blk) ((blk) << (imp)->im_bshift) *************** *** 112,129 **** int isofs_sync __P((struct mount *mp, int waitfor)); int isofs_fhtovp __P((struct mount *mp, struct fid *fhp, struct vnode **vpp)); int isofs_vptofh __P((struct vnode *vp, struct fid *fhp)); ! void isofs_init __P((void)); ! /* From isofs_util.c: */ ! extern int isonum_711(char *); ! extern int isonum_712(char *); ! extern int isonum_721(char *); ! extern int isonum_722(char *); ! extern int isonum_723(char *); ! extern int isonum_731(u_char *); ! extern int isonum_732(u_char *); ! extern int isonum_733(u_char *); ! extern int isofncmp(char *, int, char *, int); ! extern void isofntrans(char *, int, char *, int *); #endif /* _ISOFS_ISO_H_ */ --- 140,222 ---- int isofs_sync __P((struct mount *mp, int waitfor)); int isofs_fhtovp __P((struct mount *mp, struct fid *fhp, struct vnode **vpp)); int isofs_vptofh __P((struct vnode *vp, struct fid *fhp)); ! void isofs_init __P(()); ! struct iso_node; ! int iso_bmap __P((struct iso_node *ip, int lblkno, daddr_t *result)); ! int iso_blkatoff __P((struct iso_node *ip, off_t offset, struct buf **bpp)); ! int iso_iget __P((struct iso_node *xp, ino_t ino, int relocated, ! struct iso_node **ipp, struct iso_directory_record *isodir)); ! void iso_iput __P((struct iso_node *ip)); ! void iso_ilock __P((struct iso_node *ip)); ! void iso_iunlock __P((struct iso_node *ip)); ! int isofs_mountroot __P((void)); ! ! extern inline int ! isonum_711(p) ! unsigned char *p; ! { ! return *p; ! } ! ! extern inline int ! isonum_712(p) ! char *p; ! { ! return *p; ! } ! ! extern inline int ! isonum_721(p) ! unsigned char *p; ! { ! return *p|((char)p[1] << 8); ! } ! ! extern inline int ! isonum_722(p) ! unsigned char *p; ! { ! return ((char)*p << 8)|p[1]; ! } ! ! extern inline int ! isonum_723(p) ! unsigned char *p; ! { ! return isonum_721(p); ! } ! ! extern inline int ! isonum_731(p) ! unsigned char *p; ! { ! return *p|(p[1] << 8)|(p[2] << 16)|(p[3] << 24); ! } ! ! extern inline int ! isonum_732(p) ! unsigned char *p; ! { ! return (*p << 24)|(p[1] << 16)|(p[2] << 8)|p[3]; ! } ! ! extern inline int ! isonum_733(p) ! unsigned char *p; ! { ! return isonum_731(p); ! } ! ! int isofncmp __P((unsigned char *fn, int fnlen, ! unsigned char *isofn, int isolen)); ! void isofntrans __P((unsigned char *infn, int infnlen, ! unsigned char *outfn, unsigned short *outfnlen, ! int original, int assoc)); ! ! /* ! * Associated files have a leading '='. ! */ ! #define ASSOCCHAR '=' #endif /* _ISOFS_ISO_H_ */ *** sys/isofs-old/iso_rrip.h Wed Jun 1 03:02:32 1994 --- sys/isofs/iso_rrip.h Wed Jun 1 23:15:26 1994 *************** *** 29,42 **** * SUCH DAMAGE. * * from: @(#)iso_rrip.h ! * $Id: iso_rrip.h,v 1.4 1993/11/07 17:46:03 wollman Exp $ */ #ifndef _ISOFS_ISO_RRIP_H_ #define _ISOFS_ISO_RRIP_H_ 1 /* ! * Analyze function flag */ #define ISO_SUSP_ATTR 0x0001 #define ISO_SUSP_DEVICE 0x0002 --- 29,42 ---- * SUCH DAMAGE. * * from: @(#)iso_rrip.h ! * $Id: iso_rrip.h,v 1.3 1993/09/07 15:40:53 ws Exp $ */ #ifndef _ISOFS_ISO_RRIP_H_ #define _ISOFS_ISO_RRIP_H_ 1 /* ! * Analyze function flag (similar to RR field bits) */ #define ISO_SUSP_ATTR 0x0001 #define ISO_SUSP_DEVICE 0x0002 *************** *** 47,60 **** #define ISO_SUSP_RELDIR 0x0040 #define ISO_SUSP_TSTAMP 0x0080 #define ISO_SUSP_IDFLAG 0x0100 ! #define ISO_SUSP_EXFLAG 0x0200 ! #define ISO_SUSP_UNKNOWN 0x0400 typedef struct { ! ISO_RRIP_INODE inode; ! u_short iso_altlen; /* Alt Name length */ ! u_short iso_symlen; /* Symbol Name length */ ! char *iso_altname; /* Alt Name (no Null terminated ) */ ! char *iso_symname; /* Symbol Name (no NULL termninated )*/ } ISO_RRIP_ANALYZE; #endif /* _ISOFS_ISO_RRIP_H_ */ --- 47,81 ---- #define ISO_SUSP_RELDIR 0x0040 #define ISO_SUSP_TSTAMP 0x0080 #define ISO_SUSP_IDFLAG 0x0100 ! #define ISO_SUSP_EXTREF 0x0200 ! #define ISO_SUSP_CONT 0x0400 ! #define ISO_SUSP_OFFSET 0x0800 ! #define ISO_SUSP_STOP 0x1000 ! #define ISO_SUSP_UNKNOWN 0x8000 typedef struct { ! struct iso_node *inop; ! int fields; /* interesting fields in this analysis */ ! daddr_t iso_ce_blk; /* block of continuation area */ ! off_t iso_ce_off; /* offset of continuation area */ ! int iso_ce_len; /* length of continuation area */ ! struct iso_mnt *imp; /* mount structure */ ! ino_t *inump; /* inode number pointer */ ! char *outbuf; /* name/symbolic link output area */ ! u_short *outlen; /* length of above */ ! u_short maxlen; /* maximum length of above */ ! int cont; /* continuation of above */ } ISO_RRIP_ANALYZE; + + int isofs_rrip_analyze __P((struct iso_directory_record *isodir, + struct iso_node *inop, struct iso_mnt *imp)); + int isofs_rrip_getname __P((struct iso_directory_record *isodir, + char *outbuf, u_short *outlen, + ino_t *inump, struct iso_mnt *imp)); + int isofs_rrip_getsymname __P((struct iso_directory_record *isodir, + char *outbuf, u_short *outlen, + struct iso_mnt *imp)); + int isofs_rrip_offset __P((struct iso_directory_record *isodir, + struct iso_mnt *imp)); + #endif /* _ISOFS_ISO_RRIP_H_ */ *** sys/isofs-old/isofs_bmap.c Wed Jun 1 03:02:32 1994 --- sys/isofs/isofs_bmap.c Mon May 30 12:23:28 1994 *************** *** 1,25 **** /* ! * $Id: isofs_bmap.c,v 1.4 1993/12/19 00:51:03 wollman Exp $ */ ! #include "param.h" ! #include "systm.h" ! #include "namei.h" ! #include "buf.h" ! #include "file.h" ! #include "vnode.h" ! #include "mount.h" ! #include "iso.h" ! #include "isofs_node.h" int iso_bmap(ip, lblkno, result) ! struct iso_node *ip; ! int lblkno; ! int *result; { ! *result = (ip->iso_extent + lblkno) ! * (ip->i_mnt->im_bsize / DEV_BSIZE); ! return (0); } --- 1,24 ---- /* ! * $Id: isofs_bmap.c,v 1.6 1993/12/18 04:31:28 mycroft Exp $ */ ! #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/iso.h> ! #include <isofs/isofs_node.h> int iso_bmap(ip, lblkno, result) ! struct iso_node *ip; ! int lblkno; ! daddr_t *result; { ! *result = (ip->iso_start + lblkno) ! * (ip->i_mnt->logical_block_size / DEV_BSIZE); ! return 0; } *** sys/isofs-old/isofs_lookup.c Wed Jun 1 03:02:32 1994 --- sys/isofs/isofs_lookup.c Wed Jun 1 23:12:33 1994 *************** *** 34,56 **** * SUCH DAMAGE. * * from: @(#)ufs_lookup.c 7.33 (Berkeley) 5/19/91 ! * $Id: isofs_lookup.c,v 1.5 1993/11/25 01:32:22 wollman Exp $ */ ! #include "param.h" ! #include "systm.h" ! #include "namei.h" ! #include "buf.h" ! #include "file.h" ! #include "vnode.h" ! #include "mount.h" ! #include "iso.h" ! #include "isofs_node.h" ! #include "iso_rrip.h" ! #include "isofs_rrip.h" ! ! struct nchstats nchstats; /* * Convert a component of a pathname into a pointer to a locked inode. --- 34,56 ---- * SUCH DAMAGE. * * from: @(#)ufs_lookup.c 7.33 (Berkeley) 5/19/91 ! * $Id: isofs_lookup.c,v 1.17 1994/04/25 03:49:27 cgd Exp $ */ ! #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 <isofs/iso.h> ! #include <isofs/isofs_node.h> ! #include <isofs/iso_rrip.h> ! #include <isofs/isofs_rrip.h> ! struct nchstats iso_nchstats; /* * Convert a component of a pathname into a pointer to a locked inode. *************** *** 96,123 **** register struct iso_node *dp; /* the directory we are searching */ register struct iso_mnt *imp; /* file system that directory is in */ struct buf *bp = 0; /* a buffer of directory entries */ ! register struct iso_directory_record *ep; ! /* the current directory entry */ ! int entryoffsetinblock = 0; /* offset of ep in bp's buffer */ ! enum {NONE, COMPACT, FOUND} slotstatus; ! int slotoffset = -1; /* offset of area with free space */ ! int slotsize; /* size of area at slotoffset */ ! int slotfreespace; /* amount of space free in slot */ ! int slotneeded; /* size of the entry we're seeking */ int numdirpasses; /* strategy for directory search */ ! int endsearch; /* offset to end directory search */ struct iso_node *pdp; /* saved dp during symlink work */ struct iso_node *tdp; /* returned by iget */ int flag; /* LOOKUP, CREATE, RENAME, or DELETE */ int lockparent; /* 1 => lockparent flag is set */ int wantparent; /* 1 => wantparent or lockparent flag */ int error; ! int reclen; ! int namelen; ! char altname[251]; ! int i; ! ndp->ni_dvp = vdp; ndp->ni_vp = NULL; dp = VTOI(vdp); --- 96,120 ---- register struct iso_node *dp; /* the directory we are searching */ register struct iso_mnt *imp; /* file system that directory is in */ struct buf *bp = 0; /* a buffer of directory entries */ ! struct iso_directory_record *ep;/* the current directory entry */ ! off_t entryoffsetinblock = 0; /* offset of ep in bp's buffer */ ! off_t saveoffset = 0; /* offset of last directory entry in dir */ int numdirpasses; /* strategy for directory search */ ! off_t endsearch; /* offset to end directory search */ struct iso_node *pdp; /* saved dp during symlink work */ struct iso_node *tdp; /* returned by iget */ int flag; /* LOOKUP, CREATE, RENAME, or DELETE */ 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; ! ndp->ni_dvp = vdp; ndp->ni_vp = NULL; dp = VTOI(vdp); *************** *** 125,137 **** lockparent = ndp->ni_nameiop & LOCKPARENT; flag = ndp->ni_nameiop & OPMASK; wantparent = ndp->ni_nameiop & (LOCKPARENT|WANTPARENT); ! /* * Check accessiblity of directory. */ ! if ((dp->iso_flags & 2) == 0) ! return (ENOTDIR); ! /* * We now have a segment name to search for, and a directory to search. * --- 122,136 ---- lockparent = ndp->ni_nameiop & LOCKPARENT; flag = ndp->ni_nameiop & OPMASK; wantparent = ndp->ni_nameiop & (LOCKPARENT|WANTPARENT); ! /* * Check accessiblity of directory. */ ! if (vdp->v_type != VDIR) ! return ENOTDIR; ! if (error = isofs_access(vdp, VEXEC, ndp->ni_cred, p)) ! return error; ! /* * We now have a segment name to search for, and a directory to search. * *************** *** 141,150 **** */ if (error = cache_lookup(ndp)) { int vpid; /* capability number of vnode */ ! if (error == ENOENT) return (error); ! #ifdef PARANOID if (vdp == ndp->ni_rootdir && ndp->ni_isdotdot) panic("ufs_lookup: .. through root"); #endif --- 140,149 ---- */ if (error = cache_lookup(ndp)) { int vpid; /* capability number of vnode */ ! if (error == ENOENT) return (error); ! #ifdef DIAGNOSTIC if (vdp == ndp->ni_rootdir && ndp->ni_isdotdot) panic("ufs_lookup: .. through root"); #endif *************** *** 186,192 **** vdp = ITOV(dp); ndp->ni_vp = NULL; } ! /* * If there is cached information on a previous search of * this directory, pick up where we last left off. --- 185,201 ---- vdp = ITOV(dp); ndp->ni_vp = NULL; } ! ! len = ndp->ni_namelen; ! name = ndp->ni_ptr; ! /* ! * 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. *************** *** 205,219 **** ndp->ni_ufs.ufs_offset = dp->i_diroff; entryoffsetinblock = iso_blkoff(imp, ndp->ni_ufs.ufs_offset); if (entryoffsetinblock != 0) { ! if (error = iso_blkatoff(dp, ndp->ni_ufs.ufs_offset, ! (char **)0, &bp)) ! return (error); } numdirpasses = 2; ! nchstats.ncs_2passes++; } ! endsearch = roundup(dp->i_size, imp->logical_block_size); ! searchloop: while (ndp->ni_ufs.ufs_offset < endsearch) { /* --- 214,227 ---- ndp->ni_ufs.ufs_offset = dp->i_diroff; entryoffsetinblock = iso_blkoff(imp, ndp->ni_ufs.ufs_offset); if (entryoffsetinblock != 0) { ! if (error = iso_blkatoff(dp,ndp->ni_ufs.ufs_offset,&bp)) ! return error; } numdirpasses = 2; ! iso_nchstats.ncs_2passes++; } ! endsearch = roundup(dp->i_size,imp->logical_block_size); ! searchloop: while (ndp->ni_ufs.ufs_offset < endsearch) { /* *************** *** 221,307 **** * read the next directory block. * Release previous if it exists. */ ! if (iso_blkoff(imp, ndp->ni_ufs.ufs_offset) == 0) { if (bp != NULL) brelse(bp); ! if (error = iso_blkatoff(dp, ndp->ni_ufs.ufs_offset, ! (char **)0, &bp)) ! return (error); entryoffsetinblock = 0; } /* * Get pointer to next entry. */ ! ep = (struct iso_directory_record *) (bp->b_un.b_addr + entryoffsetinblock); ! reclen = isonum_711 (ep->length); if (reclen == 0) { /* skip to next block, if any */ ndp->ni_ufs.ufs_offset = ! roundup (ndp->ni_ufs.ufs_offset, ! imp->logical_block_size); continue; } ! ! if (reclen < sizeof (struct iso_directory_record)) /* illegal entry, stop */ break; ! ! /* 10 Aug 92*/ if (entryoffsetinblock + reclen -1 >= imp->logical_block_size) /* entries are not allowed to cross boundaries */ break; ! /* * Check for a name match. */ ! namelen = isonum_711 (ep->name_len); ! ! if (reclen < sizeof (struct iso_directory_record) + namelen) /* illegal entry, stop */ break; ! ! if (namelen == 1 ! && ((ndp->ni_namelen == 1 ! && ndp->ni_ptr[0] == '.' ! && ep->name[0] == 0) ! || (ndp->ni_isdotdot && ep->name[0] == 1))) { ! /* ! * Save directory entry's inode number and ! * reclen in ndp->ni_ufs area, and release ! * directory buffer. ! */ ! ndp->ni_ufs.ufs_ino = isonum_733 (ep->extent); ! brelse(bp); ! goto found; ! } else { ! switch ( imp->iso_ftype ) { ! case ISO_FTYPE_9660: ! if( ( namelen >= ndp->ni_namelen ) && ! ( isofncmp( ndp->ni_ptr, ndp->ni_namelen, ep->name, namelen ) ) ) { ! ndp->ni_ufs.ufs_ino = isonum_733 (ep->extent); ! brelse(bp); ! goto found; ! } ! break; ! case ISO_FTYPE_RRIP: ! isofs_rrip_getname( ep, altname, &namelen ); ! if ( ( namelen == ndp->ni_namelen ) && ! ( !bcmp( ndp->ni_ptr, altname, ndp->ni_namelen ) ) ) { ! ndp->ni_ufs.ufs_ino = isonum_733 (ep->extent); ! brelse(bp); goto found; } ! break; ! default: ! break; } } ndp->ni_ufs.ufs_offset += reclen; entryoffsetinblock += reclen; } ! /* notfound: */ /* * If we started in the middle of the directory and failed * to find our target, we must check the beginning as well. --- 229,345 ---- * read the next directory block. * Release previous if it exists. */ ! if (iso_blkoff(imp,ndp->ni_ufs.ufs_offset) == 0) { if (bp != NULL) brelse(bp); ! if (error = iso_blkatoff(dp,ndp->ni_ufs.ufs_offset,&bp)) ! return error; entryoffsetinblock = 0; } /* * Get pointer to next entry. */ ! ep = (struct iso_directory_record *) (bp->b_un.b_addr + entryoffsetinblock); ! reclen = isonum_711 (ep->length); if (reclen == 0) { /* skip to next block, if any */ ndp->ni_ufs.ufs_offset = ! roundup(ndp->ni_ufs.ufs_offset, ! 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; ! /* * Check for a name match. */ ! namelen = isonum_711(ep->name_len); ! ! if (reclen < ISO_DIRECTORY_RECORD_SIZE + namelen) /* illegal entry, stop */ break; ! ! switch (imp->iso_ftype) { ! default: ! if ((!(isonum_711(ep->flags)&4)) == !assoc) { ! if ((len == 1 ! && *name == '.') ! || ndp->ni_isdotdot) { ! if (namelen == 1 ! && ep->name[0] == (ndp->ni_isdotdot ? 1 : 0)) { ! /* ! * Save directory entry's inode number and ! * reclen in ndp->ni_ufs area, and release ! * directory buffer. ! */ ! isodirino(&ndp->ni_ufs.ufs_ino,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) ! isodirino(&ino,ep,imp); ! else ! ino = (bp->b_blkno << DEV_BSHIFT) ! + entryoffsetinblock; ! saveoffset = ndp->ni_ufs.ufs_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) + isodirino(&ino,ep,imp); + else + ino = (bp->b_blkno << DEV_BSHIFT) + entryoffsetinblock; + ndp->ni_ufs.ufs_ino = ino; + isofs_rrip_getname(ep,altname,&namelen,&ndp->ni_ufs.ufs_ino,imp); + if (namelen == ndp->ni_namelen + && !bcmp(name,altname,namelen)) + goto found; + ino = 0; + break; } ndp->ni_ufs.ufs_offset += reclen; entryoffsetinblock += reclen; } ! if (ino) { ! foundino: ! ndp->ni_ufs.ufs_ino = ino; ! if (saveoffset != ndp->ni_ufs.ufs_offset) { ! if (iso_lblkno(imp,ndp->ni_ufs.ufs_offset) ! != iso_lblkno(imp,saveoffset)) { ! if (bp != NULL) ! brelse(bp); ! if (error = iso_blkatoff(dp,saveoffset,&bp)) ! return error; ! } ! ep = (struct iso_directory_record *)(bp->b_un.b_addr ! + iso_blkoff(imp,saveoffset)); ! ndp->ni_ufs.ufs_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. *************** *** 319,330 **** */ if (ndp->ni_makeentry) cache_enter(ndp); return (ENOENT); ! found: ! if (numdirpasses == 2) ! nchstats.ncs_pass2++; ! /* * Found component in pathname. * If the final component of path name, save information --- 357,370 ---- */ if (ndp->ni_makeentry) cache_enter(ndp); + if (flag == CREATE || flag == RENAME) + return EJUSTRETURN; return (ENOENT); ! found: ! if (numdirpasses > 1) ! iso_nchstats.ncs_pass2++; ! /* * Found component in pathname. * If the final component of path name, save information *************** *** 332,339 **** */ if (*ndp->ni_next == '\0' && flag == LOOKUP) dp->i_diroff = ndp->ni_ufs.ufs_offset; ! /* &~ (imp->logical_block_size - 1); */ ! /* * Step through the translation in the name. We do not `iput' the * directory because we may need it again if a symbolic link --- 372,378 ---- */ if (*ndp->ni_next == '\0' && flag == LOOKUP) dp->i_diroff = ndp->ni_ufs.ufs_offset; ! /* * Step through the translation in the name. We do not `iput' the * directory because we may need it again if a symbolic link *************** *** 354,364 **** * that point backwards in the directory structure. */ pdp = dp; if (ndp->ni_isdotdot) { ISO_IUNLOCK(pdp); /* race to get the inode */ ! if (error = iso_iget(dp, ndp->ni_ufs.ufs_ino, &tdp, ep)) { ISO_ILOCK(pdp); ! return (error); } if (lockparent && *ndp->ni_next == '\0') ISO_ILOCK(pdp); --- 393,410 ---- * that point backwards in the directory structure. */ pdp = dp; + /* + * If ino is different from ndp->ni_ufs.ufs_ino, + * it's a relocated directory. + */ if (ndp->ni_isdotdot) { ISO_IUNLOCK(pdp); /* race to get the inode */ ! if (error = iso_iget(dp,ndp->ni_ufs.ufs_ino, ! ndp->ni_ufs.ufs_ino != ino, ! &tdp,ep)) { ! brelse(bp); ISO_ILOCK(pdp); ! return error; } if (lockparent && *ndp->ni_next == '\0') ISO_ILOCK(pdp); *************** *** 367,388 **** VREF(vdp); /* we want ourself, ie "." */ ndp->ni_vp = vdp; } else { ! if (error = iso_iget(dp, ndp->ni_ufs.ufs_ino, &tdp, ep)) ! return (error); if (!lockparent || *ndp->ni_next != '\0') ISO_IUNLOCK(pdp); ndp->ni_vp = ITOV(tdp); } ! /* * Insert name into cache if appropriate. */ if (ndp->ni_makeentry) cache_enter(ndp); ! return (0); } - /* * Return buffer with contents of block "offset" * from the beginning of directory "ip". If "res" --- 413,439 ---- VREF(vdp); /* we want ourself, ie "." */ ndp->ni_vp = vdp; } else { ! if (error = iso_iget(dp,ndp->ni_ufs.ufs_ino, ! ndp->ni_ufs.ufs_ino != ino, ! &tdp,ep)) { ! brelse(bp); ! return error; ! } if (!lockparent || *ndp->ni_next != '\0') ISO_IUNLOCK(pdp); ndp->ni_vp = ITOV(tdp); } ! ! brelse(bp); ! /* * Insert name into cache if appropriate. */ if (ndp->ni_makeentry) cache_enter(ndp); ! return 0; } /* * Return buffer with contents of block "offset" * from the beginning of directory "ip". If "res" *************** *** 390,415 **** * remaining space in the directory. */ int ! iso_blkatoff(ip, offset, res, bpp) struct iso_node *ip; off_t offset; - char **res; struct buf **bpp; { register struct iso_mnt *imp = ip->i_mnt; ! daddr_t lbn = iso_lblkno (imp, offset); ! int bsize = iso_blksize (imp, ip, lbn); struct buf *bp; int error; ! ! *bpp = 0; ! if (error = bread(ITOV(ip), lbn, bsize, NOCRED, &bp)) { brelse(bp); ! return (error); } - if (res) - *res = bp->b_un.b_addr + iso_blkoff(imp, offset); *bpp = bp; ! ! return (0); } --- 441,463 ---- * remaining space in the directory. */ int ! iso_blkatoff(ip, offset, bpp) struct iso_node *ip; off_t offset; struct buf **bpp; { register struct iso_mnt *imp = ip->i_mnt; ! daddr_t lbn = iso_lblkno(imp,offset); ! int bsize = iso_blksize(imp,ip,lbn); struct buf *bp; int error; ! ! if (error = bread(ITOV(ip),lbn,bsize,NOCRED,&bp)) { brelse(bp); ! *bpp = 0; ! return error; } *bpp = bp; ! ! return 0; } *** sys/isofs-old/isofs_node.c Wed Jun 1 03:02:32 1994 --- sys/isofs/isofs_node.c Wed Jun 1 22:28:04 1994 *************** *** 30,58 **** * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ! * from: @(#)isofs_inode.c ! * $Id: isofs_node.c,v 1.6 1993/11/25 01:32:23 wollman Exp $ */ ! #include "param.h" ! #include "systm.h" ! #include "mount.h" ! #include "proc.h" ! #include "file.h" ! #include "buf.h" ! #include "vnode.h" ! #include "kernel.h" ! #include "malloc.h" ! ! #include "iso.h" ! #include "isofs_node.h" ! #include "iso_rrip.h" #define INOHSZ 512 #if ((INOHSZ&(INOHSZ-1)) == 0) ! #define INOHASH(dev,ino) (((dev)+(ino))&(INOHSZ-1)) #else ! #define INOHASH(dev,ino) (((unsigned)((dev)+(ino)))%INOHSZ) #endif union iso_ihead { --- 30,65 ---- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ! * from: @(#)ufs_inode.c (unknown version) ! * $Id: isofs_node.c,v 1.12 1994/04/25 03:49:30 cgd Exp $ */ ! #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/iso.h> ! #include <isofs/isofs_node.h> ! #include <isofs/iso_rrip.h> ! ! #define IFTOVT(mode) (iftovt_tab[((mode) & 0170000) >> 12]) ! static enum vtype iftovt_tab[16] = { ! VNON, VFIFO, VCHR, VNON, VDIR, VNON, VBLK, VNON, ! VREG, VNON, VLNK, VNON, VSOCK, VNON, VNON, VBAD, ! }; #define INOHSZ 512 #if ((INOHSZ&(INOHSZ-1)) == 0) ! #define INOHASH(dev,ino) (((dev)+((ino)>>12))&(INOHSZ-1)) #else ! #define INOHASH(dev,ino) (((unsigned)((dev)+((ino)>>12)))%INOHSZ) #endif union iso_ihead { *************** *** 60,75 **** struct iso_node *ih_chain[2]; } iso_ihead[INOHSZ]; int prtactive; /* 1 => print out reclaim of active vnodes */ /* ! * Initialize hash links for inodes. */ void isofs_init() { register int i; register union iso_ihead *ih = iso_ihead; #ifndef lint if (VN_MAXPRIVATE < sizeof(struct iso_node)) --- 67,99 ---- struct iso_node *ih_chain[2]; } iso_ihead[INOHSZ]; + #ifdef ISODEVMAP + #define DNOHSZ 64 + #if ((DNOHSZ&(DNOHSZ-1)) == 0) + #define DNOHASH(dev,ino) (((dev)+((ino)>>12))&(DNOHSZ-1)) + #else + #define DNOHASH(dev,ino) (((unsigned)((dev)+((ino)>>12)))%DNOHSZ) + #endif + + union iso_dhead { + union iso_dhead *dh_head[2]; + struct iso_dnode *dh_chain[2]; + } iso_dhead[DNOHSZ]; + #endif + int prtactive; /* 1 => print out reclaim of active vnodes */ /* ! * Initialize hash links for inodes and dnodes. */ void isofs_init() { register int i; register union iso_ihead *ih = iso_ihead; + #ifdef ISODEVMAP + register union iso_dhead *dh = iso_dhead; + #endif #ifndef lint if (VN_MAXPRIVATE < sizeof(struct iso_node)) *************** *** 79,86 **** --- 103,168 ---- ih->ih_head[0] = ih; ih->ih_head[1] = ih; } + #ifdef ISODEVMAP + for (i = DNOHSZ; --i >= 0; dh++) { + dh->dh_head[0] = dh; + dh->dh_head[1] = dh; + } + #endif } + #ifdef ISODEVMAP + /* + * Enter a new node into the device hash list + */ + struct iso_dnode * + iso_dmap(dev,ino,create) + dev_t dev; + ino_t ino; + int create; + { + struct iso_dnode *dp; + union iso_dhead *dh; + + dh = &iso_dhead[DNOHASH(dev, ino)]; + for (dp = dh->dh_chain[0]; + dp != (struct iso_dnode *)dh; + dp = dp->d_forw) + if (ino == dp->i_number && dev == dp->i_dev) + return dp; + + if (!create) + return (struct iso_dnode *)0; + + MALLOC(dp,struct iso_dnode *,sizeof(struct iso_dnode),M_CACHE,M_WAITOK); + dp->i_dev = dev; + dp->i_number = ino; + insque(dp,dh); + + return dp; + } + + void + iso_dunmap(dev) + dev_t dev; + { + struct iso_dnode *dp, *dq; + union iso_dhead *dh; + + for (dh = iso_dhead; dh < iso_dhead + DNOHSZ; dh++) { + for (dp = dh->dh_chain[0]; + dp != (struct iso_dnode *)dh; + dp = dq) { + dq = dp->d_forw; + if (dev == dp->i_dev) { + remque(dp); + FREE(dp,M_CACHE); + } + } + } + } + #endif + /* * Look up a ISOFS dinode number to find its incore vnode. * If it is not in core, read it in from the specified device. *************** *** 89,112 **** * points must be done by the calling routine. */ int ! iso_iget(xp, ino, ipp, isodir) struct iso_node *xp; ino_t ino; struct iso_node **ipp; struct iso_directory_record *isodir; { dev_t dev = xp->i_dev; struct mount *mntp = ITOV(xp)->v_mount; ! extern struct vnodeops isofs_vnodeops, spec_inodeops; register struct iso_node *ip, *iq; register struct vnode *vp; struct vnode *nvp; ! struct buf *bp; ! struct dinode *dp; union iso_ihead *ih; ! int i, error, result = 0; struct iso_mnt *imp; ! ih = &iso_ihead[INOHASH(dev, ino)]; loop: for (ip = ih->ih_chain[0]; --- 171,197 ---- * points must be done by the calling routine. */ int ! iso_iget(xp, ino, relocated, ipp, isodir) struct iso_node *xp; ino_t ino; + int relocated; struct iso_node **ipp; struct iso_directory_record *isodir; { dev_t dev = xp->i_dev; struct mount *mntp = ITOV(xp)->v_mount; ! extern struct vnodeops isofs_vnodeops, isofs_spec_inodeops; register struct iso_node *ip, *iq; register struct vnode *vp; + register struct iso_dnode *dp; struct vnode *nvp; ! struct buf *bp = NULL, *bp2 = NULL; union iso_ihead *ih; ! union iso_dhead *dh; ! int i, error, result; struct iso_mnt *imp; ! ino_t defino; ! ih = &iso_ihead[INOHASH(dev, ino)]; loop: for (ip = ih->ih_chain[0]; *************** *** 116,144 **** continue; if ((ip->i_flag&ILOCKED) != 0) { ip->i_flag |= IWANT; ! tsleep((caddr_t)ip, PINOD, "isoiget", 0); goto loop; } if (vget(ITOV(ip))) goto loop; *ipp = ip; ! return(0); } /* * Allocate a new inode. */ if (error = getnewvnode(VT_ISOFS, mntp, &isofs_vnodeops, &nvp)) { *ipp = 0; ! return (error); } ip = VTOI(nvp); ip->i_vnode = nvp; ip->i_flag = 0; ip->i_devvp = 0; ip->i_diroff = 0; - ip->iso_parent = xp->i_diroff; /* Parent directory's */ - ip->iso_parent_ext = xp->iso_extent; ip->i_lockf = 0; /* * Put it onto its hash chain and lock it so that other requests for * this inode will block if they arrive while we are sleeping waiting --- 201,228 ---- continue; if ((ip->i_flag&ILOCKED) != 0) { ip->i_flag |= IWANT; ! sleep((caddr_t)ip, PINOD); goto loop; } if (vget(ITOV(ip))) goto loop; *ipp = ip; ! return 0; } /* * Allocate a new inode. */ if (error = getnewvnode(VT_ISOFS, mntp, &isofs_vnodeops, &nvp)) { *ipp = 0; ! return error; } ip = VTOI(nvp); ip->i_vnode = nvp; ip->i_flag = 0; ip->i_devvp = 0; ip->i_diroff = 0; ip->i_lockf = 0; + /* * Put it onto its hash chain and lock it so that other requests for * this inode will block if they arrive while we are sleeping waiting *************** *** 150,209 **** insque(ip, ih); ISO_ILOCK(ip); - ip->iso_reclen = isonum_711 (isodir->length); - ip->iso_extlen = isonum_711 (isodir->ext_attr_length); - ip->iso_extent = isonum_733 (isodir->extent); - ip->i_size = isonum_733 (isodir->size); - ip->iso_flags = isonum_711 (isodir->flags); - ip->iso_unit_size = isonum_711 (isodir->file_unit_size); - ip->iso_interleave_gap = isonum_711 (isodir->interleave); - ip->iso_volume_seq = isonum_723 (isodir->volume_sequence_number); - ip->iso_namelen = isonum_711 (isodir->name_len); - imp = VFSTOISOFS (mntp); vp = ITOV(ip); /* ! * Setup time stamp, attribute , if CL or PL, set loc but not yet.. */ ! switch ( imp->iso_ftype ) { ! case ISO_FTYPE_9660: ! isofs_rrip_defattr ( isodir, &(ip->inode) ); ! isofs_rrip_deftstamp( isodir, &(ip->inode) ); ! goto FlameOff; ! break; ! case ISO_FTYPE_RRIP: ! result = isofs_rrip_analyze( isodir, &(ip->inode) ); ! break; ! default: ! printf("unknown iso_ftype.. %d\n", imp->iso_ftype ); ! break; } /* * Initialize the associated vnode */ ! if ( result & ISO_SUSP_SLINK ) { ! vp->v_type = VLNK; /* Symbolic Link */ ! } else { ! FlameOff: ! if (ip->iso_flags & 2) { ! vp->v_type = VDIR; ! } else { ! vp->v_type = VREG; } } ! ! imp = VFSTOISOFS (mntp); ! ! if (ino == imp->root_extent) vp->v_flag |= VROOT; ! /* ! * Finish inode initialization. ! */ ! ip->i_mnt = imp; ! ip->i_devvp = imp->im_devvp; ! VREF(ip->i_devvp); *ipp = ip; ! return (0); } /* --- 234,343 ---- insque(ip, ih); ISO_ILOCK(ip); imp = VFSTOISOFS (mntp); + ip->i_mnt = imp; + ip->i_devvp = imp->im_devvp; + VREF(ip->i_devvp); + + if (relocated) { + /* + * On relocated directories we must + * read the `.' entry out of a dir. + */ + ip->iso_start = ino >> imp->im_bshift; + if (error = iso_blkatoff(ip,0,&bp)) { + vrele(ip->i_devvp); + remque(ip); + ip->i_forw = ip; + ip->i_back = ip; + iso_iput(ip); + *ipp = 0; + return error; + } + isodir = (struct iso_directory_record *)bp->b_un.b_addr; + } + + ip->iso_extent = isonum_733(isodir->extent); + ip->i_size = isonum_733(isodir->size); + ip->iso_start = isonum_711(isodir->ext_attr_length) + ip->iso_extent; + vp = ITOV(ip); + /* ! * Setup time stamp, attribute */ ! vp->v_type = VNON; ! switch (imp->iso_ftype) { ! default: /* ISO_FTYPE_9660 */ ! if ((imp->im_flags&ISOFSMNT_EXTATT) ! && isonum_711(isodir->ext_attr_length)) ! iso_blkatoff(ip,-isonum_711(isodir->ext_attr_length), ! &bp2); ! isofs_defattr(isodir,ip,bp2 ); ! isofs_deftstamp(isodir,ip,bp2 ); ! break; ! case ISO_FTYPE_RRIP: ! result = isofs_rrip_analyze(isodir,ip,imp); ! break; } + if (bp2) + brelse(bp2); + if (bp) + brelse(bp); + /* * Initialize the associated vnode */ ! vp->v_type = IFTOVT(ip->inode.iso_mode); ! ! if ( vp->v_type == VFIFO ) { ! #ifdef FIFO ! extern struct vnodeops isofs_fifo_inodeops; ! vp->v_op = &isofs_fifo_inodeops; ! #else ! iso_iput(ip); ! *ipp = 0; ! return EOPNOTSUPP; ! #endif /* FIFO */ ! } else if ( vp->v_type == VCHR || vp->v_type == VBLK ) { ! /* ! * if device, look at device number table for translation ! */ ! #ifdef ISODEVMAP ! if (dp = iso_dmap(dev,ino,0)) ! ip->inode.iso_rdev = dp->d_dev; ! #endif ! vp->v_op = &isofs_spec_inodeops; ! if (nvp = checkalias(vp, ip->inode.iso_rdev, mntp)) { ! /* ! * Reinitialize aliased inode. ! */ ! vp = nvp; ! iq = VTOI(vp); ! iq->i_vnode = vp; ! iq->i_flag = 0; ! ISO_ILOCK(iq); ! iq->i_dev = dev; ! iq->i_number = ino; ! iq->i_mnt = ip->i_mnt; ! bcopy(&ip->iso_extent,&iq->iso_extent, ! (char *)(ip + 1) - (char *)&ip->iso_extent); ! insque(iq, ih); ! /* ! * Discard unneeded vnode ! * (This introduces the need of INACTIVE modification) ! */ ! ip->inode.iso_mode = 0; ! iso_iput(ip); ! ip = iq; } } ! ! if (ip->iso_extent == imp->root_extent) vp->v_flag |= VROOT; ! *ipp = ip; ! return 0; } /* *************** *** 213,219 **** iso_iput(ip) register struct iso_node *ip; { ! if ((ip->i_flag & ILOCKED) == 0) panic("iso_iput"); ISO_IUNLOCK(ip); --- 347,353 ---- iso_iput(ip) register struct iso_node *ip; { ! if ((ip->i_flag & ILOCKED) == 0) panic("iso_iput"); ISO_IUNLOCK(ip); *************** *** 231,256 **** { register struct iso_node *ip = VTOI(vp); int mode, error = 0; ! if (prtactive && vp->v_usecount != 0) vprint("isofs_inactive: pushing active", vp); ! ip->i_flag = 0; /* * If we are done with the inode, reclaim it * so that it can be reused immediately. */ ! ! /* ! * Purge symlink entries since they cause problems ! * when cached. Leave other entries alone since flushing ! * them every time is a major performance hit. ! */ ! if (vp->v_usecount == 0 && vp->v_type == VLNK) { ! /* printf("Flushing symlink entry\n");*/ vgone(vp); ! } ! return (error); } /* --- 365,382 ---- { register struct iso_node *ip = VTOI(vp); int mode, error = 0; ! if (prtactive && vp->v_usecount != 0) vprint("isofs_inactive: pushing active", vp); ! ip->i_flag = 0; /* * If we are done with the inode, reclaim it * so that it can be reused immediately. */ ! if (vp->v_usecount == 0 && ip->inode.iso_mode == 0) vgone(vp); ! return error; } /* *************** *** 262,268 **** { register struct iso_node *ip = VTOI(vp); int i; ! if (prtactive && vp->v_usecount != 0) vprint("isofs_reclaim: pushing active", vp); /* --- 388,394 ---- { register struct iso_node *ip = VTOI(vp); int i; ! if (prtactive && vp->v_usecount != 0) vprint("isofs_reclaim: pushing active", vp); /* *************** *** 280,286 **** ip->i_devvp = 0; } ip->i_flag = 0; ! return (0); } /* --- 406,412 ---- ip->i_devvp = 0; } ip->i_flag = 0; ! return 0; } /* *************** *** 290,302 **** iso_ilock(ip) register struct iso_node *ip; { ! while (ip->i_flag & ILOCKED) { ip->i_flag |= IWANT; if (ip->i_spare0 == curproc->p_pid) panic("locking against myself"); ip->i_spare1 = curproc->p_pid; ! (void) tsleep((caddr_t)ip, PINOD, "isoilck", 0); } ip->i_spare1 = 0; ip->i_spare0 = curproc->p_pid; --- 416,428 ---- iso_ilock(ip) register struct iso_node *ip; { ! while (ip->i_flag & ILOCKED) { ip->i_flag |= IWANT; if (ip->i_spare0 == curproc->p_pid) panic("locking against myself"); ip->i_spare1 = curproc->p_pid; ! (void) sleep((caddr_t)ip, PINOD); } ip->i_spare1 = 0; ip->i_spare0 = curproc->p_pid; *************** *** 319,322 **** --- 445,650 ---- ip->i_flag &= ~IWANT; wakeup((caddr_t)ip); } + } + + /* + * File attributes + */ + void + isofs_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))) { + iso_blkatoff(inop,-off * imp->logical_block_size,&bp2); + bp = bp2; + } + if (bp) { + ap = (struct iso_extended_attributes *)bp->b_un.b_addr; + + 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 + isofs_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))) { + iso_blkatoff(inop,-off * imp->logical_block_size,&bp2); + bp = bp2; + } + if (bp) { + ap = (struct iso_extended_attributes *)bp->b_un.b_addr; + + if (isonum_711(ap->version) == 1) { + if (!isofs_tstamp_conv17(ap->ftime,&inop->inode.iso_atime)) + isofs_tstamp_conv17(ap->ctime,&inop->inode.iso_atime); + if (!isofs_tstamp_conv17(ap->ctime,&inop->inode.iso_ctime)) + inop->inode.iso_ctime = inop->inode.iso_atime; + if (!isofs_tstamp_conv17(ap->mtime,&inop->inode.iso_mtime)) + inop->inode.iso_mtime = inop->inode.iso_ctime; + } else + ap = NULL; + } + if (!ap) { + isofs_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 + isofs_tstamp_conv7(pi,pu) + char *pi; + struct timeval *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->tv_sec = 0; + pu->tv_usec = 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->tv_sec = crtime; + pu->tv_usec = 0; + return 1; + } + + static unsigned + isofs_chars2ui(begin,len) + unsigned char *begin; + int len; + { + unsigned rc; + + for (rc = 0; --len >= 0;) { + rc *= 10; + rc += *begin++ - '0'; + } + return rc; + } + + int + isofs_tstamp_conv17(pi,pu) + unsigned char *pi; + struct timeval *pu; + { + unsigned char buf[7]; + + /* year:"0001"-"9999" -> -1900 */ + buf[0] = isofs_chars2ui(pi,4) - 1900; + + /* month: " 1"-"12" -> 1 - 12 */ + buf[1] = isofs_chars2ui(pi + 4,2); + + /* day: " 1"-"31" -> 1 - 31 */ + buf[2] = isofs_chars2ui(pi + 6,2); + + /* hour: " 0"-"23" -> 0 - 23 */ + buf[3] = isofs_chars2ui(pi + 8,2); + + /* minute:" 0"-"59" -> 0 - 59 */ + buf[4] = isofs_chars2ui(pi + 10,2); + + /* second:" 0"-"59" -> 0 - 59 */ + buf[5] = isofs_chars2ui(pi + 12,2); + + /* difference of GMT */ + buf[6] = pi[16]; + + return isofs_tstamp_conv7(buf,pu); + } + + void + isodirino(inump,isodir,imp) + ino_t *inump; + struct iso_directory_record *isodir; + struct iso_mnt *imp; + { + *inump = (isonum_733(isodir->extent) + isonum_711(isodir->ext_attr_length)) + * imp->logical_block_size; } *** sys/isofs-old/isofs_node.h Wed Jun 1 03:02:33 1994 --- sys/isofs/isofs_node.h Wed Jun 1 23:14:43 1994 *************** *** 1,22 **** /* ! * $Id: isofs_node.h,v 1.5 1993/12/19 00:51:04 wollman Exp $ */ #ifndef _ISOFS_ISOFS_NODE_H_ #define _ISOFS_ISOFS_NODE_H_ 1 - typedef struct { - unsigned iso_cln; /* Child link */ - unsigned iso_pln; /* Parents link */ struct timeval iso_atime; /* time of last access */ struct timeval iso_mtime; /* time of last modification */ struct timeval 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 */ } ISO_RRIP_INODE; struct iso_node { struct iso_node *i_chain[2]; /* hash chain, MUST be first */ struct vnode *i_vnode; /* vnode associated with this inode */ --- 1,35 ---- /* ! * $Id: isofs_node.h,v 1.9 1993/12/23 07:37:42 cgd Exp $ */ #ifndef _ISOFS_ISOFS_NODE_H_ #define _ISOFS_ISOFS_NODE_H_ 1 typedef struct { struct timeval iso_atime; /* time of last access */ struct timeval iso_mtime; /* time of last modification */ struct timeval 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_chain[2]; /* hash chain, MUST be first */ + dev_t i_dev; /* device where dnode resides */ + ino_t i_number; /* the identity of the inode */ + dev_t d_dev; /* device # for translation */ + }; + #define d_forw d_chain[0] + #define d_back d_chain[1] + #endif + struct iso_node { struct iso_node *i_chain[2]; /* hash chain, MUST be first */ struct vnode *i_vnode; /* vnode associated with this inode */ *************** *** 24,29 **** --- 37,43 ---- 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 */ long i_diroff; /* offset in dir, where we found last entry */ *************** *** 31,48 **** long i_spare0; long i_spare1; ! ! int iso_reclen; ! int iso_extlen; ! int iso_extent; ! int i_size; ! int iso_flags; ! int iso_unit_size; ! int iso_interleave_gap; ! int iso_volume_seq; ! int iso_namelen; /* ISO9660/RRIP name len */ ! int iso_parent; /* byte offset in beginning of dir record */ ! int iso_parent_ext; /* block number of dir record */ ISO_RRIP_INODE inode; }; --- 45,54 ---- long i_spare0; long i_spare1; ! 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; }; *************** *** 92,108 **** int isofs_strategy __P((struct buf *bp)); void isofs_print __P((struct vnode *vp)); int isofs_islocked __P((struct vnode *vp)); ! ! /* From isofs_node.c: */ ! struct iso_directory_record; ! extern void isofs_init(void); ! extern int iso_iget(struct iso_node *, ino_t, struct iso_node **, ! struct iso_directory_record *); ! extern void iso_iput(struct iso_node *); ! extern void iso_ilock(struct iso_node *); ! extern void iso_iunlock(struct iso_node *); ! ! ! extern int iso_blkatoff(struct iso_node *, off_t, char **, struct buf **); #endif /* _ISOFS_ISOFS_NODE_H_ */ --- 98,110 ---- int isofs_strategy __P((struct buf *bp)); void isofs_print __P((struct vnode *vp)); int isofs_islocked __P((struct vnode *vp)); ! void isofs_defattr __P((struct iso_directory_record *isodir, ! struct iso_node *inop, struct buf *bp)); ! void isofs_deftstamp __P((struct iso_directory_record *isodir, ! struct iso_node *inop, struct buf *bp)); ! #ifdef ISODEVMAP ! struct iso_dnode *iso_dmap __P((dev_t dev, ino_t ino, int create)); ! void iso_dunmap __P((dev_t dev)); ! #endif #endif /* _ISOFS_ISOFS_NODE_H_ */ *** sys/isofs-old/isofs_rrip.c Wed Jun 1 03:02:33 1994 --- sys/isofs/isofs_rrip.c Wed Jun 1 23:11:05 1994 *************** *** 28,663 **** * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ! * $Id: isofs_rrip.c,v 1.5 1993/12/19 00:51:05 wollman Exp $ */ ! #include "param.h" ! #include "systm.h" ! #include "namei.h" ! #include "buf.h" ! #include "file.h" ! #include "vnode.h" ! #include "mount.h" ! #include "kernel.h" ! ! #include "sys/time.h" ! ! #include "iso.h" ! #include "isofs_node.h" ! #include "isofs_rrip.h" ! #include "iso_rrip.h" /* * POSIX file attribute */ ! static int isofs_rrip_attr( p, ana ) ! ISO_RRIP_ATTR *p; ISO_RRIP_ANALYZE *ana; { ! ana->inode.iso_mode = isonum_731(p->mode_l); ! ana->inode.iso_uid = (uid_t)isonum_731(p->uid_l); ! ana->inode.iso_gid = (gid_t)isonum_731(p->gid_l); ! /* ana->inode.iso_links = isonum_731(p->links_l); */ ! return 0; ! } ! ! int isofs_rrip_defattr( isodir, ana ) ! struct iso_directory_record *isodir; ! ISO_RRIP_ANALYZE *ana; ! { ! ana->inode.iso_mode = (VREAD|VEXEC|(VREAD|VEXEC)>>3|(VREAD|VEXEC)>>6); ! ana->inode.iso_uid = (uid_t)0; ! ana->inode.iso_gid = (gid_t)0; ! return 0; } ! /* ! * POSIX device modes ! */ ! static int isofs_rrip_device( p, ana ) ! ISO_RRIP_DEVICE *p; ISO_RRIP_ANALYZE *ana; { ! char buf[3]; ! ! buf[0] = p->h.type[0]; ! buf[1] = p->h.type[1]; ! buf[2] = 0x00; ! ! printf("isofs:%s[%d] high=0x%08x, low=0x%08x\n", ! buf, ! isonum_711(p->h.length), ! isonum_731(p->dev_t_high_l), ! isonum_731(p->dev_t_low_l) ! ); ! return 0; } /* * Symbolic Links */ ! static int isofs_rrip_slink( p, ana ) ISO_RRIP_SLINK *p; ISO_RRIP_ANALYZE *ana; { return 0; } /* * Alternate name */ ! static int isofs_rrip_altname( p, ana ) ISO_RRIP_ALTNAME *p; ISO_RRIP_ANALYZE *ana; { return 0; } ! /* ! * Child Link ! */ ! static int isofs_rrip_clink( p, ana ) ! ISO_RRIP_CLINK *p; ISO_RRIP_ANALYZE *ana; { ! char buf[3]; ! buf[0] = p->h.type[0]; ! buf[1] = p->h.type[1]; ! buf[2] = 0x00; ! printf("isofs:%s[%d] loc=%d\n", ! buf, ! isonum_711(p->h.length), ! isonum_733(p->dir_loc) ! ); ! ana->inode.iso_cln = isonum_733(p->dir_loc); ! return 0; } /* ! * Parent Link */ ! static int isofs_rrip_plink( p, ana ) ! ISO_RRIP_PLINK *p; ! ISO_RRIP_ANALYZE *ana; ! { ! ! char buf[3]; ! buf[0] = p->h.type[0]; ! buf[1] = p->h.type[1]; ! buf[2] = 0x00; ! printf("isofs:%s[%d] loc=%d\n", ! buf, ! isonum_711(p->h.length), ! isonum_733(p->dir_loc) ! ); ! ana->inode.iso_pln = isonum_733(p->dir_loc); ! return 0; } /* * Relocated directory */ ! static int isofs_rrip_reldir( p, ana ) ! ISO_RRIP_RELDIR *p; ! ISO_RRIP_ANALYZE *ana; { ! char buf[3]; ! ! buf[0] = p->h.type[0]; ! buf[1] = p->h.type[1]; ! buf[2] = 0x00; ! ! printf("isofs:%s[%d]\n",buf, isonum_711(p->h.length) ); ! return 0; } ! /* ! * Time stamp ! */ ! static void isofs_rrip_tstamp_conv7(pi, pu) ! char *pi; ! struct timeval *pu; ! { ! int i; ! int crtime,days; ! int year,month,day,hour,minute,second,tz; ! ! year = pi[0] - 70; ! month = pi[1]; ! day = pi[2]; ! hour = pi[3]; ! minute = pi[4]; ! second = pi[5]; ! tz = pi[6]; ! ! if (year < 0) { ! crtime = 0; ! } else { ! int monlen[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; ! days = year * 365; ! if (year > 2) ! days += (year+2) / 4; ! for (i = 1; i < month; i++) ! days += monlen[i-1]; ! if (((year+2) % 4) == 0 && month > 2) ! days++; ! days += day - 1; ! crtime = ((((days * 24) + hour) * 60 + minute) * 60) ! + second; ! ! /* sign extend */ ! if (tz & 0x80) ! tz |= (-1 << 8); ! ! /* timezone offset is unreliable on some disks */ ! if (-48 <= tz && tz <= 52) ! crtime += tz * 15 * 60; ! } ! pu->tv_sec = crtime; ! pu->tv_usec = 0; ! } ! ! ! static unsigned isofs_chars2ui( begin, end ) ! unsigned char *begin; ! unsigned char *end; { ! unsigned rc=0; ! int len; ! int wlen; ! static int pow[]={ 1, 10, 100, 1000 }; ! ! len = end - begin; ! wlen= len; ! for (; len >= 0; len -- ) { ! rc += ( *(begin+len) * pow[wlen - len] ); ! } ! return( rc ); ! } - static void isofs_rrip_tstamp_conv17(pi, pu) - unsigned char *pi; - struct timeval *pu; - { - unsigned char buf[7]; - - /* year:"0001"-"9999" -> -1900 */ - buf[0] = (unsigned char)(isofs_chars2ui( &pi[0], &pi[3]) - 1900 ); - - /* month: " 1"-"12" -> 1 - 12 */ - buf[1] = (unsigned char)isofs_chars2ui( &pi[4], &pi[5]); - - /* day: " 1"-"31" -> 1 - 31 */ - buf[2] = isofs_chars2ui( &pi[6], &pi[7]); - - /* hour: " 0"-"23" -> 0 - 23 */ - buf[3] = isofs_chars2ui( &pi[8], &pi[9]); - - /* minute:" 0"-"59" -> 0 - 59 */ - buf[4] = isofs_chars2ui( &pi[10], &pi[11] ); - - /* second:" 0"-"59" -> 0 - 59 */ - buf[5] = isofs_chars2ui( &pi[12], &pi[13] ); - - /* difference of GMT */ - buf[6] = pi[16]; - - isofs_rrip_tstamp_conv7(buf, pu); - } - - static int isofs_rrip_tstamp( p, ana ) - ISO_RRIP_TSTAMP *p; - ISO_RRIP_ANALYZE *ana; - { - unsigned char *ptime; - ptime = p->time; ! /* Check a format of time stamp (7bytes/17bytes) */ ! if ( !(*p->flags & ISO_SUSP_TSTAMP_FORM17 ) ) { ! isofs_rrip_tstamp_conv7(ptime, &ana->inode.iso_ctime ); ! ! if ( *p->flags & ISO_SUSP_TSTAMP_MODIFY ) ! isofs_rrip_tstamp_conv7(ptime+7, &ana->inode.iso_mtime ); ! else ! ana->inode.iso_mtime = ana->inode.iso_ctime; ! ! if ( *p->flags & ISO_SUSP_TSTAMP_ACCESS ) ! isofs_rrip_tstamp_conv7(ptime+14, &ana->inode.iso_atime ); ! else ! ana->inode.iso_atime = ana->inode.iso_ctime; } else { ! isofs_rrip_tstamp_conv17(ptime, &ana->inode.iso_ctime ); ! ! if ( *p->flags & ISO_SUSP_TSTAMP_MODIFY ) ! isofs_rrip_tstamp_conv17(ptime+17, &ana->inode.iso_mtime ); ! else ! ana->inode.iso_mtime = ana->inode.iso_ctime; ! ! if ( *p->flags & ISO_SUSP_TSTAMP_ACCESS ) ! isofs_rrip_tstamp_conv17(ptime+34, &ana->inode.iso_atime ); ! else ! ana->inode.iso_atime = ana->inode.iso_ctime; } ! return 0; } ! int isofs_rrip_deftstamp( isodir, ana ) struct iso_directory_record *isodir; ISO_RRIP_ANALYZE *ana; { ! isofs_rrip_tstamp_conv7(isodir->date, &ana->inode.iso_ctime ); ! ana->inode.iso_atime = ana->inode.iso_ctime; ! ana->inode.iso_mtime = ana->inode.iso_ctime; ! return 0; } /* * Flag indicating - * Nothing to do.... */ ! static int isofs_rrip_idflag( p, ana ) ! ISO_RRIP_IDFLAG *p; ! ISO_RRIP_ANALYZE *ana; ! { ! char buf[3]; ! ! buf[0] = p->h.type[0]; ! buf[1] = p->h.type[1]; ! buf[2] = 0x00; ! ! printf("isofs:%s[%d] idflag=0x%x\n", ! buf, ! isonum_711(p->h.length), ! p->flags ); ! return 0; } /* ! * Extension reference ! * Nothing to do.... */ ! static int isofs_rrip_exflag( p, ana ) ! ISO_RRIP_EXFLAG *p; ! ISO_RRIP_ANALYZE *ana; ! { ! char buf[3]; ! ! buf[0] = p->h.type[0]; ! buf[1] = p->h.type[1]; ! buf[2] = 0x00; ! ! printf("isofs:%s[%d] exflag=0x%x", ! buf, ! isonum_711(p->h.length), ! p->flags ); ! return 0; } /* ! * Unknown ... ! * Nothing to do.... */ ! static int isofs_rrip_unknown( p, ana ) ! ISO_RRIP_EXFLAG *p; ISO_RRIP_ANALYZE *ana; { ! return 0; } typedef struct { ! char type[2]; ! int (*func)(); ! int (*func2)(); ! int result; } RRIP_TABLE; ! static RRIP_TABLE rrip_table [] = { ! { 'P', 'X', isofs_rrip_attr, isofs_rrip_defattr, ISO_SUSP_ATTR }, ! { 'T', 'F', isofs_rrip_tstamp, isofs_rrip_deftstamp, ISO_SUSP_TSTAMP }, ! { 'N', 'M', isofs_rrip_altname,0, ISO_SUSP_ALTNAME }, ! { 'C', 'L', isofs_rrip_clink, 0, ISO_SUSP_CLINK }, ! { 'P', 'L', isofs_rrip_plink, 0, ISO_SUSP_PLINK }, ! { 'S', 'L', isofs_rrip_slink, 0, ISO_SUSP_SLINK }, ! { 'R', 'E', isofs_rrip_reldir, 0, ISO_SUSP_RELDIR }, ! { 'P', 'N', isofs_rrip_device, 0, ISO_SUSP_DEVICE }, ! { 'R', 'R', isofs_rrip_idflag, 0, ISO_SUSP_IDFLAG }, ! { 'E', 'R', isofs_rrip_exflag, 0, ISO_SUSP_EXFLAG }, ! { 'S', 'P', isofs_rrip_unknown,0, ISO_SUSP_UNKNOWN }, ! { 'C', 'E', isofs_rrip_unknown,0, ISO_SUSP_UNKNOWN } ! }; ! ! int isofs_rrip_analyze ( isodir, analyze ) ! struct iso_directory_record *isodir; ! ISO_RRIP_ANALYZE *analyze; ! { ! register RRIP_TABLE *ptable; register ISO_SUSP_HEADER *phead; register ISO_SUSP_HEADER *pend; ! int found; ! 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) & 0x0001) ) ! pwhead ++; ! phead = (ISO_SUSP_HEADER *)pwhead; ! pend = (ISO_SUSP_HEADER *)( (char *)isodir + isonum_711(isodir->length) ); ! result = 0; ! if ( pend == phead ) { ! goto setdefault; ! } ! /* ! * Note: "pend" should be more than one SUSP header ! */ ! while ( pend >= phead + 1) { ! found = 0; ! for ( ptable=&rrip_table[0];ptable < &rrip_table[sizeof(rrip_table)/sizeof(RRIP_TABLE)]; ptable ++) { ! if ( bcmp( phead->type, ptable->type, 2 ) == 0 ) { ! found = 1; ! ptable->func( phead, analyze ); ! result |= ptable->result; ! break; } ! } ! if ( found == 0 ) { ! printf("isofs: name '"); ! for ( i =0; i < isonum_711(isodir->name_len) ;i++) { ! printf("%c", *(isodir->name + i) ); } ! printf("'"); ! printf(" - type %c%c [%08x/%08x]...not found\n", ! phead->type[0], phead->type[1], phead, pend ); ! isofs_hexdump( phead, (int)( (char *)pend - (char *)phead ) ); ! break; ! } ! ! /* ! * move to next SUSP ! */ ! phead = (ISO_SUSP_HEADER *) ((unsigned)isonum_711(phead->length) + (char *)phead); } ! ! setdefault: /* * If we don't find the Basic SUSP stuffs, just set default value ! * ( attribute/time stamp ) */ ! for ( ptable=&rrip_table[0];ptable < &rrip_table[2]; ptable ++) { ! if ( ptable->func2 != 0 && !(ptable->result & result) ) { ! ptable->func2( isodir, analyze ); ! } ! } ! return ( result ); } ! /* ! * Get Alternate Name from 'AL' record ! * If either no AL record nor 0 lenght, ! * it will be return the translated ISO9660 name, */ ! int isofs_rrip_getname( isodir, outbuf, outlen ) struct iso_directory_record *isodir; ! char *outbuf; ! int *outlen; { ! ISO_SUSP_HEADER *phead, *pend; ! ISO_RRIP_ALTNAME *p; ! char *pwhead; ! int found; ! ! /* ! * 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) & 0x0001) ) ! pwhead ++; ! phead = (ISO_SUSP_HEADER *)pwhead; ! pend = (ISO_SUSP_HEADER *)( (char *)isodir + isonum_711(isodir->length) ); ! ! found = 0; ! if ( pend != phead ) { ! while ( pend >= phead + 1) { ! if ( bcmp( phead->type, "NM", 2 ) == 0 ) { ! found = 1; ! break; ! } ! phead = (ISO_SUSP_HEADER *) ((unsigned)isonum_711(phead->length) + (char *)phead); ! } ! } ! if ( found == 1 ) { ! p = (ISO_RRIP_ALTNAME *)phead; ! *outlen = isonum_711( p->h.length ) - sizeof( ISO_RRIP_ALTNAME ); ! bcopy( (char *)( &p->flags + 1 ), outbuf, *outlen ); ! } else { ! isofntrans(isodir->name, isonum_711(isodir->name_len), outbuf, outlen ); ! if ( *outlen == 1) { ! switch ( outbuf[0] ) { ! case 0: ! outbuf[0] = '.'; ! break; ! case 1: ! outbuf[0] = '.'; ! outbuf[1] = '.'; ! *outlen = 2; ! } ! } ! } ! return( found ); } /* ! * Get Symbolic Name from 'SL' record ! * ! * Note: isodir should contains SL record! ! */ ! int isofs_rrip_getsymname( vp, isodir, outbuf, outlen ) ! struct vnode *vp; ! struct iso_directory_record *isodir; ! char *outbuf; ! int *outlen; ! { ! register ISO_RRIP_SLINK_COMPONENT *pcomp; ! register ISO_SUSP_HEADER *phead, *pend; ! register ISO_RRIP_SLINK_COMPONENT *pcompe; ! ISO_RRIP_SLINK *p; ! char *pwhead; ! int found; ! int slash; ! int wlen; ! /* ! * 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) & 0x0001) ) ! pwhead ++; ! phead = (ISO_SUSP_HEADER *)pwhead; ! pend = (ISO_SUSP_HEADER *)( (char *)isodir + isonum_711(isodir->length) ); ! ! found = 0; ! if ( pend != phead ) { ! while ( pend >= phead + 1) { ! if ( bcmp( phead->type, "SL", 2 ) == 0 ) { ! found = 1; ! break; ! } ! phead = (ISO_SUSP_HEADER *) ((unsigned)isonum_711(phead->length) + (char *)phead); ! } } - if ( found == 0 ) { - *outlen = 0; - return( found ); - } - - p = (ISO_RRIP_SLINK *)phead; - pcomp = (ISO_RRIP_SLINK_COMPONENT *)p->component; - pcompe = (ISO_RRIP_SLINK_COMPONENT *)((char *)p + isonum_711(p->h.length)); ! /* ! * Gathering a Symbolic name from each component with path ! */ ! *outlen = 0; ! slash = 0; ! while ( pcomp < pcompe ) { ! ! /* Inserting Current */ ! if ( pcomp->cflag[0] & ISO_SUSP_CFLAG_CURRENT ) { ! bcopy("./", outbuf+*outlen, 2); ! *outlen += 2; ! slash = 0; ! } ! /* Inserting Parent */ ! if ( pcomp->cflag[0] & ISO_SUSP_CFLAG_PARENT ) { ! bcopy("../", outbuf+*outlen, 3); ! *outlen += 3; ! slash = 0; ! } ! /* Inserting slash for ROOT */ ! if ( pcomp->cflag[0] & ISO_SUSP_CFLAG_ROOT ) { ! bcopy("/", outbuf+*outlen, 1); ! *outlen += 1; ! slash = 0; ! } ! /* Inserting a mount point i.e. "/cdrom" */ ! if ( pcomp->cflag[0] & ISO_SUSP_CFLAG_VOLROOT ) { ! wlen = strlen(vp->v_mount->mnt_stat.f_mntonname); ! bcopy(vp->v_mount->mnt_stat.f_mntonname,outbuf+*outlen, wlen); ! *outlen += wlen; ! slash = 1; ! } ! /* Inserting hostname i.e. "tama:" */ ! if ( pcomp->cflag[0] & ISO_SUSP_CFLAG_HOST ) { ! bcopy(hostname, outbuf+*outlen, hostnamelen); ! *(outbuf+hostnamelen) = ':'; ! *outlen += (hostnamelen + 1); ! slash = 0; /* Uuum Should we insert a slash ? */ ! } ! /* Inserting slash for next component */ ! if ( slash == 1 ) { ! outbuf[*outlen] = '/'; ! *outlen += 1; ! slash = 0; ! } ! ! /* Inserting component */ ! wlen = isonum_711(pcomp->clen); ! if ( wlen != 0 ) { ! bcopy( pcomp->name, outbuf + *outlen, wlen ); ! *outlen += wlen; ! slash = 1; ! } ! ! /* ! * Move to next component... ! */ ! pcomp = (ISO_RRIP_SLINK_COMPONENT *)((char *)pcomp ! + sizeof(ISO_RRIP_SLINK_COMPONENT) - 1 ! + isonum_711(pcomp->clen)); ! } ! return( found ); ! } ! /* Hexdump routine for debug*/ ! int isofs_hexdump( p, size ) ! unsigned char *p; ! int size; ! { ! int i,j,k; ! unsigned char *wp; ! ! for ( i = 0; i < size; i += 16 ) { ! printf("isofs: "); ! wp = p; ! k = ( (size - i) > 16 ? 16 : size - i ); ! for ( j =0; j < k; j ++ ){ ! printf("%02x ", *p ); ! p++; ! } ! printf(" : "); ! p = wp; ! for ( j =0; j < k; j ++ ){ ! if ( (*p > 0x20) && (*p < 0x7f) ) ! printf("%c", *p ); ! else ! printf(" "); ! p++; ! } ! printf("\n"); } ! printf("\n"); ! return 0; } --- 28,681 ---- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ! * $Id: isofs_rrip.c,v 1.8 1994/03/13 17:24:23 ws Exp $ */ ! #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/iso.h> ! #include <isofs/isofs_node.h> ! #include <isofs/isofs_rrip.h> ! #include <isofs/iso_rrip.h> /* * POSIX file attribute */ ! static int ! isofs_rrip_attr(p,ana) ! ISO_RRIP_ATTR *p; ISO_RRIP_ANALYZE *ana; { ! ana->inop->inode.iso_mode = isonum_731(p->mode_l); ! ana->inop->inode.iso_uid = (uid_t)isonum_731(p->uid_l); ! ana->inop->inode.iso_gid = (gid_t)isonum_731(p->gid_l); ! ana->inop->inode.iso_links = isonum_731(p->links_l); ! ana->fields &= ~ISO_SUSP_ATTR; ! return ISO_SUSP_ATTR; } ! static void ! isofs_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"); ! isofs_defattr(isodir,ana->inop,NULL); } /* * Symbolic Links */ ! static int ! isofs_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 ! isofs_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 ! isofs_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 ! isofs_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 ! isofs_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 ! isofs_rrip_tstamp(p,ana) ! ISO_RRIP_TSTAMP *p; ! ISO_RRIP_ANALYZE *ana; { ! unsigned 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) { ! isofs_tstamp_conv7(ptime,&ana->inop->inode.iso_mtime); ! ptime += 7; ! } else ! bzero(&ana->inop->inode.iso_mtime,sizeof(struct timeval)); ! ! if (*p->flags&ISO_SUSP_TSTAMP_ACCESS) { ! isofs_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) ! isofs_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) { ! isofs_tstamp_conv17(ptime,&ana->inop->inode.iso_mtime); ! ptime += 17; ! } else ! bzero(&ana->inop->inode.iso_mtime,sizeof(struct timeval)); ! ! if (*p->flags&ISO_SUSP_TSTAMP_ACCESS) { ! isofs_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) ! isofs_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 ! isofs_rrip_deftstamp(isodir,ana) struct iso_directory_record *isodir; ISO_RRIP_ANALYZE *ana; { ! isofs_deftstamp(isodir,ana->inop,NULL); } + /* + * POSIX device modes + */ + static int + isofs_rrip_device(p,ana) + ISO_RRIP_DEVICE *p; + ISO_RRIP_ANALYZE *ana; + { + unsigned high, low; + + high = isonum_733(p->dev_t_high_l); + low = isonum_733(p->dev_t_low_l); + + if (high == 0) + ana->inop->inode.iso_rdev = makedev(major(low),minor(low)); + else + ana->inop->inode.iso_rdev = makedev(high,minor(low)); + ana->fields &= ~ISO_SUSP_DEVICE; + return ISO_SUSP_DEVICE; + } /* * Flag indicating */ ! static int ! isofs_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 isofs_rrip_reldir(p,ana); ! ! return ISO_SUSP_IDFLAG; } /* ! * Continuation pointer */ ! static int ! isofs_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 ! isofs_rrip_stop(p,ana) ! ISO_SUSP_HEADER *p; ISO_RRIP_ANALYZE *ana; { ! return ISO_SUSP_STOP; ! } ! ! /* ! * Extension reference ! */ ! static int ! isofs_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 ! isofs_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->logical_block_size / DEV_BSIZE, ! ana->imp->logical_block_size,NOCRED,&bp)) ! /* what to do now? */ ! break; ! phead = (ISO_SUSP_HEADER *)(bp->b_un.b_addr + ana->iso_ce_off); ! 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", isofs_rrip_attr, isofs_rrip_defattr, ISO_SUSP_ATTR }, ! { "TF", isofs_rrip_tstamp, isofs_rrip_deftstamp, ISO_SUSP_TSTAMP }, ! { "PN", isofs_rrip_device, 0, ISO_SUSP_DEVICE }, ! { "RR", isofs_rrip_idflag, 0, ISO_SUSP_IDFLAG }, ! { "CE", isofs_rrip_cont, 0, ISO_SUSP_CONT }, ! { "ST", isofs_rrip_stop, 0, ISO_SUSP_STOP }, ! { "", 0, 0, 0 } ! }; ! ! int ! isofs_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 isofs_rrip_loop(isodir,&analyze,rrip_table_analyze); } /* ! * Get Alternate Name. ! */ ! static RRIP_TABLE rrip_table_getname[] = { ! { "NM", isofs_rrip_altname, isofs_rrip_defname, ISO_SUSP_ALTNAME }, ! { "CL", isofs_rrip_pclink, 0, ISO_SUSP_CLINK|ISO_SUSP_PLINK }, ! { "PL", isofs_rrip_pclink, 0, ISO_SUSP_CLINK|ISO_SUSP_PLINK }, ! { "RE", isofs_rrip_reldir, 0, ISO_SUSP_RELDIR }, ! { "RR", isofs_rrip_idflag, 0, ISO_SUSP_IDFLAG }, ! { "CE", isofs_rrip_cont, 0, ISO_SUSP_CONT }, ! { "ST", isofs_rrip_stop, 0, ISO_SUSP_STOP }, ! { "", 0, 0, 0 } ! }; ! int ! isofs_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) { ! isofs_rrip_defname(isodir,&analyze); ! ! analyze.fields &= ~ISO_SUSP_ALTNAME; ! tab++; } ! return isofs_rrip_loop(isodir,&analyze,tab); ! } ! /* ! * Get Symbolic Link. ! */ ! static RRIP_TABLE rrip_table_getsymname[] = { ! { "SL", isofs_rrip_slink, 0, ISO_SUSP_SLINK }, ! { "RR", isofs_rrip_idflag, 0, ISO_SUSP_IDFLAG }, ! { "CE", isofs_rrip_cont, 0, ISO_SUSP_CONT }, ! { "ST", isofs_rrip_stop, 0, ISO_SUSP_STOP }, ! { "", 0, 0, 0 } ! }; ! int ! isofs_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 (isofs_rrip_loop(isodir,&analyze,rrip_table_getsymname)&ISO_SUSP_SLINK); ! } ! static RRIP_TABLE rrip_table_extref[] = { ! { "ER", isofs_rrip_extref, 0, ISO_SUSP_EXTREF }, ! { "CE", isofs_rrip_cont, 0, ISO_SUSP_CONT }, ! { "ST", isofs_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 ! isofs_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 (!(isofs_rrip_loop(isodir,&analyze,rrip_table_extref)&ISO_SUSP_EXTREF)) ! return -1; ! ! return isonum_711(p->skip); } *** sys/isofs-old/isofs_rrip.h Wed Jun 1 03:02:33 1994 --- sys/isofs/isofs_rrip.h Wed Jun 1 23:13:54 1994 *************** *** 29,35 **** * SUCH DAMAGE. * * from: @(#)isofs_rrip.h ! * $Id: isofs_rrip.h,v 1.3 1993/11/07 17:46:05 wollman Exp $ */ #ifndef _ISOFS_ISOFS_RRIP_H_ --- 29,35 ---- * SUCH DAMAGE. * * from: @(#)isofs_rrip.h ! * $Id: isofs_rrip.h,v 1.3 1993/09/07 15:40:58 ws Exp $ */ #ifndef _ISOFS_ISOFS_RRIP_H_ *************** *** 71,78 **** typedef struct { u_char cflag [ISODCL ( 1, 1)]; u_char clen [ISODCL ( 2, 2)]; ! u_char name [ISODCL ( 3, 3)]; } ISO_RRIP_SLINK_COMPONENT; typedef struct { ISO_SUSP_HEADER h; --- 71,79 ---- typedef struct { u_char cflag [ISODCL ( 1, 1)]; u_char clen [ISODCL ( 2, 2)]; ! u_char name [0]; } ISO_RRIP_SLINK_COMPONENT; + #define ISO_RRIP_SLSIZ 2 typedef struct { ISO_SUSP_HEADER h; *************** *** 122,128 **** typedef struct { ISO_SUSP_HEADER h; ! unsigned char flags [ISODCL ( 4, 4)]; ! } ISO_RRIP_EXFLAG; #endif /* _ISOFS_ISOFS_RRIP_H_ */ --- 123,145 ---- 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; #endif /* _ISOFS_ISOFS_RRIP_H_ */ *** sys/isofs-old/isofs_util.c Wed Jun 1 03:02:33 1994 --- sys/isofs/isofs_util.c Mon May 30 22:55:55 1994 *************** *** 1,139 **** /* ! * $Id: isofs_util.c,v 1.4 1993/12/19 00:51:06 wollman Exp $ */ ! #include "param.h" ! #include "systm.h" int isonum_711 (p) ! char *p; { ! return (*p & 0xff); } int isonum_712 (p) ! char *p; { ! int val; ! ! val = *p; ! if (val & 0x80) ! val |= ~0xff; ! return (val); } int isonum_721 (p) ! char *p; { ! return ((p[0] & 0xff) | ((p[1] & 0xff) << 8)); } int isonum_722 (p) ! char *p; { ! return (((p[0] & 0xff) << 8) | (p[1] & 0xff)); } int isonum_723 (p) ! char *p; { ! #if 0 ! if (p[0] != p[3] || p[1] != p[2]) { ! fprintf (stderr, "invalid format 7.2.3 number\n"); ! exit (1); ! } #endif - return (isonum_721 (p)); } int isonum_731 (p) unsigned char *p; { ! return ((p[0] & 0xff) ! | ((p[1] & 0xff) << 8) ! | ((p[2] & 0xff) << 16) ! | ((p[3] & 0xff) << 24)); } int isonum_732 (p) unsigned char *p; { ! return (((p[0] & 0xff) << 24) ! | ((p[1] & 0xff) << 16) ! | ((p[2] & 0xff) << 8) ! | (p[3] & 0xff)); } int isonum_733 (p) unsigned char *p; { ! int i; ! ! #if 0 ! for (i = 0; i < 4; i++) { ! if (p[i] != p[7-i]) { ! fprintf (stderr, "bad format 7.3.3 number\n"); ! exit (1); ! } ! } #endif - return (isonum_731 (p)); } /* * translate and compare a filename */ int ! isofncmp(char *fn, int fnlen, char *isofn, int isolen) { ! int fnidx; ! ! fnidx = 0; ! for (fnidx = 0; fnidx < isolen; fnidx++, fn++) { ! char c = *isofn++; ! ! if (fnidx > fnlen) ! return (0); ! ! if (c >= 'A' && c <= 'Z') { ! if (c + ('a' - 'A') != *fn) ! return(0); ! else ! continue; } - if (c == ';') - return ((fnidx == fnlen)); - if (c != *fn) - return (0); } ! return (1); } /* * translate a filename */ void ! isofntrans(char *infn, int infnlen, char *outfn, short *outfnlen) { ! int fnidx; ! ! fnidx = 0; ! for (fnidx = 0; fnidx < infnlen; fnidx++) { char c = *infn++; ! ! if (c >= 'A' && c <= 'Z') *outfn++ = c + ('a' - 'A'); ! else if (c == ';') { ! *outfnlen = fnidx; ! return; ! } else *outfn++ = c; } ! *outfnlen = infnlen; } --- 1,203 ---- /* ! * $Id: isofs_util.c,v 1.10 1994/05/07 01:22:26 cgd Exp $ */ ! #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 <sys/malloc.h> ! #include <sys/dir.h> + #include <sys/specdev.h> /* XXX */ + #include <sys/fifo.h> /* XXX */ + + #include <isofs/iso.h> + + #include <machine/endian.h> + + #ifdef __notanymore__ int isonum_711 (p) ! unsigned char *p; { ! return (*p); } int isonum_712 (p) ! signed char *p; { ! return (*p); } int isonum_721 (p) ! unsigned char *p; { ! /* little endian short */ ! #if BYTE_ORDER != LITTLE_ENDIAN ! printf ("isonum_721 called on non little-endian machine!\n"); ! #endif ! ! return *(short *)p; } int isonum_722 (p) ! unsigned char *p; { ! /* big endian short */ ! #if BYTE_ORDER != BIG_ENDIAN ! printf ("isonum_722 called on non big-endian machine!\n"); ! #endif ! ! return *(short *)p; } int isonum_723 (p) ! unsigned char *p; { ! #if BYTE_ORDER == BIG_ENDIAN ! return isonum_722 (p + 2); ! #elif BYTE_ORDER == LITTLE_ENDIAN ! return isonum_721 (p); ! #else ! printf ("isonum_723 unsupported byte order!\n"); ! return 0; #endif } int isonum_731 (p) unsigned char *p; { ! /* little endian long */ ! #if BYTE_ORDER != LITTLE_ENDIAN ! printf ("isonum_731 called on non little-endian machine!\n"); ! #endif ! ! return *(long *)p; } int isonum_732 (p) unsigned char *p; { ! /* big endian long */ ! #if BYTE_ORDER != BIG_ENDIAN ! printf ("isonum_732 called on non big-endian machine!\n"); ! #endif ! ! return *(long *)p; } int isonum_733 (p) unsigned char *p; { ! #if BYTE_ORDER == BIG_ENDIAN ! return isonum_732 (p + 4); ! #elif BYTE_ORDER == LITTLE_ENDIAN ! return isonum_731 (p); ! #else ! printf ("isonum_733 unsupported byte order!\n"); ! return 0; #endif } + #endif /* __notanymore__ */ /* * translate and compare a filename + * Note: Version number plus ';' may be omitted. */ int ! isofncmp(unsigned char *fn,int fnlen,unsigned char *isofn,int isolen) ! { ! int i, j; ! unsigned 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(unsigned char *infn,int infnlen, ! unsigned char *outfn,unsigned short *outfnlen, ! int original,int assoc) ! { ! int fnidx = 0; ! ! if (assoc) { ! *outfn++ = ASSOCCHAR; ! fnidx++; ! } ! 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; } *** sys/isofs-old/isofs_vfsops.c Wed Jun 1 03:02:33 1994 --- sys/isofs/isofs_vfsops.c Wed Jun 1 22:50:33 1994 *************** *** 1,25 **** /* ! * $Id: isofs_vfsops.c,v 1.5 1993/12/19 00:51:07 wollman Exp $ */ ! #include "param.h" ! #include "systm.h" ! #include "namei.h" ! #include "proc.h" ! #include "kernel.h" ! #include "vnode.h" ! #include "specdev.h" ! #include "mount.h" ! #include "buf.h" ! #include "file.h" ! #include "dkbad.h" ! #include "disklabel.h" ! #include "ioctl.h" ! #include "errno.h" ! #include "malloc.h" ! #include "iso.h" ! #include "isofs_node.h" extern int enodev (); --- 1,26 ---- /* ! * $Id: isofs_vfsops.c,v 1.13 1994/04/23 07:54:38 cgd Exp $ */ ! #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 <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/specdev.h> /* XXX */ ! ! #include <isofs/iso.h> ! #include <isofs/isofs_node.h> extern int enodev (); *************** *** 37,49 **** }; /* ! * Called by vfs_mountroot when ufs is going to be mounted as root. * * Name is updated by mount(8) after booting. */ #define ROOTNAME "root_device" ! static int iso_mountfs(struct vnode *, struct mount *, struct proc *); int isofs_mountroot() --- 38,50 ---- }; /* ! * Called by vfs_mountroot when iso is going to be mounted as root. * * Name is updated by mount(8) after booting. */ #define ROOTNAME "root_device" ! static iso_mountfs(); int isofs_mountroot() *************** *** 55,76 **** register struct fs *fs; u_int size; int error; ! mp = (struct mount *)malloc((u_long)sizeof(struct mount), M_MOUNT, M_WAITOK); ! mp->mnt_op = &isofs_vfsops; mp->mnt_flag = MNT_RDONLY; mp->mnt_exroot = 0; mp->mnt_mounth = NULLVP; ! error = iso_mountfs(rootvp, mp, p); if (error) { free((caddr_t)mp, M_MOUNT); ! return (error); } if (error = vfs_lock(mp)) { (void)isofs_unmount(mp, 0, p); free((caddr_t)mp, M_MOUNT); ! return (error); } rootfs = mp; mp->mnt_next = mp; --- 56,79 ---- register struct fs *fs; u_int size; int error; ! struct iso_args args; ! mp = (struct mount *)malloc((u_long)sizeof(struct mount), M_MOUNT, M_WAITOK); ! mp->mnt_op = (struct vfsops *)&isofs_vfsops; mp->mnt_flag = MNT_RDONLY; mp->mnt_exroot = 0; mp->mnt_mounth = NULLVP; ! args.flags = ISOFSMNT_ROOT; ! error = iso_mountfs(rootvp, mp, p, &args); if (error) { free((caddr_t)mp, M_MOUNT); ! return error; } if (error = vfs_lock(mp)) { (void)isofs_unmount(mp, 0, p); free((caddr_t)mp, M_MOUNT); ! return error; } rootfs = mp; mp->mnt_next = mp; *************** *** 86,101 **** bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); (void) isofs_statfs(mp, &mp->mnt_stat, p); vfs_unlock(mp); ! return (0); } /* ! * Flag to allow forcible unmounting. */ int iso_doforce = 1; /* ! * VFS Operations. * * mount system call */ --- 89,105 ---- bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); (void) isofs_statfs(mp, &mp->mnt_stat, p); vfs_unlock(mp); ! return 0; } + /* ! * flag to allow forcible unmounting. */ int iso_doforce = 1; /* ! * vfs operations. * * mount system call */ *************** *** 108,146 **** struct proc *p; { struct vnode *devvp; ! struct ufs_args args; u_int size; int error; ! struct iso_mnt *imp = 0; ! ! if (error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args))) ! return (error); ! if ((mp->mnt_flag & MNT_RDONLY) == 0) ! return (EROFS); ! ! /* ! * Process export requests. ! */ ! if ((args.exflags & MNT_EXPORTED) || (mp->mnt_flag & MNT_EXPORTED)) { ! if (args.exflags & MNT_EXPORTED) ! mp->mnt_flag |= MNT_EXPORTED; ! else ! mp->mnt_flag &= ~MNT_EXPORTED; ! if (args.exflags & MNT_EXRDONLY) ! mp->mnt_flag |= MNT_EXRDONLY; ! else ! mp->mnt_flag &= ~MNT_EXRDONLY; ! mp->mnt_exroot = args.exroot; ! } /* * 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 (0); } /* * Not an update, or updating the name: look up the name --- 112,135 ---- 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) { if (args.fspec == 0) ! return 0; } /* * Not an update, or updating the name: look up the name *************** *** 150,169 **** ndp->ni_segflg = UIO_USERSPACE; ndp->ni_dirp = args.fspec; if (error = namei(ndp, p)) ! 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); ! else { if (devvp != imp->im_devvp) error = EINVAL; /* needs translation */ else --- 139,159 ---- ndp->ni_segflg = UIO_USERSPACE; ndp->ni_dirp = args.fspec; if (error = namei(ndp, p)) ! 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 { ! imp = VFSTOISOFS(mp); if (devvp != imp->im_devvp) error = EINVAL; /* needs translation */ else *************** *** 171,208 **** } if (error) { vrele(devvp); ! return (error); } imp = VFSTOISOFS(mp); ! ! /* Check the Rock Ridge Extention support */ ! if ( args.exflags & MNT_NORRIP ) { ! imp->iso_ftype = ISO_FTYPE_9660; ! mp->mnt_flag |= MNT_NORRIP; ! } else { ! imp->iso_ftype = ISO_FTYPE_RRIP; ! mp->mnt_flag &= ~MNT_NORRIP; ! } ! (void) copyinstr(path, imp->im_fsmnt, sizeof(imp->im_fsmnt)-1, &size); bzero(imp->im_fsmnt + size, sizeof(imp->im_fsmnt) - size); bcopy((caddr_t)imp->im_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname, MNAMELEN); ! (void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, &size); bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); (void) isofs_statfs(mp, &mp->mnt_stat, p); ! return (0); } /* * Common code for mount and mountroot */ ! static int ! iso_mountfs(devvp, mp, p) register struct vnode *devvp; struct mount *mp; struct proc *p; { register struct iso_mnt *isomp = (struct iso_mnt *)0; struct buf *bp = NULL; --- 161,189 ---- } if (error) { vrele(devvp); ! return error; } imp = VFSTOISOFS(mp); ! (void) copyinstr(path, imp->im_fsmnt, sizeof(imp->im_fsmnt)-1, &size); bzero(imp->im_fsmnt + size, sizeof(imp->im_fsmnt) - size); bcopy((caddr_t)imp->im_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname, MNAMELEN); ! (void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, &size); bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); (void) isofs_statfs(mp, &mp->mnt_stat, p); ! return 0; } /* * Common code for mount and mountroot */ ! static int 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; *************** *** 220,310 **** 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 = iso_mountedon(devvp)) ! return (error); if (vcount(devvp) > 1 && devvp != rootvp) ! return (EBUSY); vinvalbuf(devvp, 1); if (error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, 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 = 2048; ! for (iso_blknum = 16; iso_blknum < 100; iso_blknum++) { if (error = bread (devvp, iso_blknum * iso_bsize / DEV_BSIZE, iso_bsize, NOCRED, &bp)) goto out; ! vdp = (struct iso_volume_descriptor *)bp->b_un.b_addr; 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 = (struct iso_mnt *)malloc(sizeof *isomp,M_ISOFSMNT,M_WAITOK); 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_bsize = logical_block_size; ! isomp->im_bmask = ~(isomp->im_bsize - 1); isomp->im_bshift = 0; ! while ((1 << isomp->im_bshift) < isomp->im_bsize) isomp->im_bshift++; ! ! bp->b_flags |= B_INVAL; brelse(bp); bp = NULL; ! ! isomp->im_ronly = ronly; ! if (ronly == 0) ! isomp->im_fmod = 1; ! mp->mnt_data = (qaddr_t)isomp; mp->mnt_stat.f_fsid.val[0] = (long)dev; mp->mnt_stat.f_fsid.val[1] = MOUNT_ISOFS; --- 201,286 ---- 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 = mountedon(devvp)) ! return error; if (vcount(devvp) > 1 && devvp != rootvp) ! return EBUSY; vinvalbuf(devvp, 1); if (error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, 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 = 2048; ! for (iso_blknum = 16; iso_blknum < 100; iso_blknum++) { if (error = bread (devvp, iso_blknum * iso_bsize / DEV_BSIZE, iso_bsize, NOCRED, &bp)) goto out; ! vdp = (struct iso_volume_descriptor *)bp->b_un.b_addr; 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 = (struct iso_mnt *)malloc(sizeof *isomp,M_ISOFSMNT,M_WAITOK); 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] = MOUNT_ISOFS; *************** *** 312,321 **** isomp->im_mountp = mp; isomp->im_dev = dev; isomp->im_devvp = devvp; ! devvp->v_specflags |= SI_MOUNTEDON; ! ! return (0); out: if (bp) brelse(bp); --- 288,334 ---- 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->logical_block_size / DEV_BSIZE, ! isomp->logical_block_size,NOCRED,&bp)) ! goto out; ! ! rootp = (struct iso_directory_record *)bp->b_un.b_addr; ! ! if ((isomp->rr_skip = isofs_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); *************** *** 325,331 **** free((caddr_t)isomp, M_ISOFSMNT); mp->mnt_data = (qaddr_t)0; } ! return (error); } /* --- 338,344 ---- free((caddr_t)isomp, M_ISOFSMNT); mp->mnt_data = (qaddr_t)0; } ! return error; } /* *************** *** 339,346 **** int flags; struct proc *p; { ! ! return (0); } /* --- 352,358 ---- int flags; struct proc *p; { ! return 0; } /* *************** *** 354,404 **** { register struct iso_mnt *isomp; int i, error, ronly, flags = 0; ! if (mntflags & MNT_FORCE) { if (!iso_doforce || mp == rootfs) ! return (EINVAL); flags |= FORCECLOSE; } mntflushbuf(mp, 0); if (mntinvalbuf(mp)) ! return (EBUSY); isomp = VFSTOISOFS(mp); ! if (error = vflush(mp, NULLVP, flags)) ! return (error); ! ronly = !isomp->im_ronly; isomp->im_devvp->v_specflags &= ~SI_MOUNTEDON; ! error = VOP_CLOSE(isomp->im_devvp, ronly ? FREAD : FREAD|FWRITE, ! 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); ! } ! ! /* ! * Check to see if a filesystem is mounted on a block device. ! */ ! int ! iso_mountedon(vp) ! register struct vnode *vp; ! { ! register struct vnode *vq; ! ! if (vp->v_specflags & SI_MOUNTEDON) ! return (EBUSY); ! if (vp->v_flag & VALIASED) { ! for (vq = *vp->v_hashchain; vq; vq = vq->v_specnext) { ! if (vq->v_rdev != vp->v_rdev || ! vq->v_type != vp->v_type) ! continue; ! if (vq->v_specflags & SI_MOUNTEDON) ! return (EBUSY); ! } ! } ! return (0); } /* --- 366,396 ---- { register struct iso_mnt *isomp; int i, error, ronly, flags = 0; ! if (mntflags & MNT_FORCE) { if (!iso_doforce || mp == rootfs) ! return EINVAL; flags |= FORCECLOSE; } mntflushbuf(mp, 0); if (mntinvalbuf(mp)) ! return EBUSY; isomp = VFSTOISOFS(mp); ! if (error = vflush(mp, NULLVP, flags)) ! return error; ! #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; } /* *************** *** 414,432 **** struct vnode tvp; int error; struct iso_mnt *imp = VFSTOISOFS (mp); ! tvp.v_mount = mp; ip = VTOI(&tvp); ip->i_vnode = &tvp; ip->i_dev = imp->im_dev; ip->i_diroff = 0; ! ip->iso_extent = imp->root_extent; ! error = iso_iget(ip, imp->root_extent, &nip, ! (struct iso_directory_record *) imp->root); if (error) ! return (error); *vpp = ITOV(nip); ! return (0); } /* --- 406,432 ---- struct vnode tvp; int error; struct iso_mnt *imp = VFSTOISOFS (mp); ! struct iso_directory_record *dp; ! tvp.v_mount = mp; ip = VTOI(&tvp); ip->i_vnode = &tvp; ip->i_dev = imp->im_dev; ip->i_diroff = 0; ! dp = (struct iso_directory_record *)imp->root; ! isodirino(&ip->i_number,dp,imp); ! ! /* ! * With RRIP we must use the `.' entry of the root directory. ! * Simply tell iget, that it's a relocated directory. ! */ ! error = iso_iget(ip,ip->i_number, ! imp->iso_ftype == ISO_FTYPE_RRIP, ! &nip,dp); if (error) ! return error; *vpp = ITOV(nip); ! return 0; } /* *************** *** 457,463 **** bcopy((caddr_t)mp->mnt_stat.f_mntfromname, (caddr_t)&sbp->f_mntfromname[0], MNAMELEN); } ! return (0); } int --- 457,467 ---- bcopy((caddr_t)mp->mnt_stat.f_mntfromname, (caddr_t)&sbp->f_mntfromname[0], MNAMELEN); } ! #if 0 ! /* Use the first spare for flags: */ ! sbp->f_spare[0] = isomp->im_flags; ! #endif ! return 0; } int *************** *** 465,471 **** struct mount *mp; int waitfor; { ! return (0); } /* --- 469,475 ---- struct mount *mp; int waitfor; { ! return 0; } /* *************** *** 478,490 **** * - check that the generation number matches */ - struct ifid { ushort ifid_len; ushort ifid_pad; - int ifid_lbn; - int ifid_offset; int ifid_ino; }; int --- 482,492 ---- * - check that the generation number matches */ struct ifid { ushort ifid_len; ushort ifid_pad; int ifid_ino; + off_t ifid_start; }; int *************** *** 502,563 **** struct buf *bp; struct iso_directory_record *dirp; struct iso_node *ip, *nip; ! struct proc *p; ! ifhp = (struct ifid *)fhp; imp = VFSTOISOFS (mp); ! #ifdef ISOFS_DBG ! printf("fhtovp: lbn %d, off %d, ino %d\n", ! ifhp->ifid_lbn, ifhp->ifid_offset, ifhp->ifid_ino); #endif ! ! lbn = ifhp->ifid_lbn; ! off = ifhp->ifid_offset; ! ifhp->ifid_lbn += (ifhp->ifid_offset >> 11); ! ifhp->ifid_offset &= 0x7ff; ! ! if (ifhp->ifid_lbn >= imp->volume_space_size) ! return (EINVAL); ! ! if (ifhp->ifid_offset + sizeof (struct iso_directory_record) ! >= imp->im_bsize) ! return (EINVAL); ! ! if (error = bread (imp->im_devvp, ! (ifhp->ifid_lbn * imp->im_bsize / DEV_BSIZE), imp->im_bsize, ! NOCRED, &bp)) { ! printf("fhtovp: bread error %d\n", error); ! return(EINVAL); } ! ! dirp = (struct iso_directory_record *) ! (bp->b_un.b_addr + ifhp->ifid_offset); ! ! if (ifhp->ifid_offset + isonum_711 (dirp->length) >= imp->im_bsize) { ! brelse (bp); ! return (EINVAL); } ! if (isonum_733(dirp->extent) != ifhp->ifid_ino) { brelse(bp); ! return(EINVAL); } ! tvp.v_mount = mp; ip = VTOI(&tvp); ip->i_vnode = &tvp; ip->i_dev = imp->im_dev; ! ip->i_diroff = off; ! ip->iso_extent = lbn; ! if (error = iso_iget(ip, ifhp->ifid_ino, &nip, dirp)) { *vpp = NULLVP; ! brelse (bp); ! return (error); } ip = nip; *vpp = ITOV(ip); ! brelse (bp); ! return (0); } /* --- 504,572 ---- struct buf *bp; struct iso_directory_record *dirp; struct iso_node *ip, *nip; ! ifhp = (struct ifid *)fhp; imp = VFSTOISOFS (mp); ! #ifdef ISOFS_DBG ! printf("fhtovp: ino %d, start %ld\n",ifhp->ifid_ino,ifhp->ifid_start); #endif ! ! lbn = ifhp->ifid_ino >> imp->im_bshift; ! off = ifhp->ifid_ino & imp->im_bmask; ! ! if (lbn >= imp->volume_space_size) { ! printf("fhtovp: lbn exceed volume space %d\n",lbn); ! return EINVAL; } ! ! if (off + ISO_DIRECTORY_RECORD_SIZE > imp->logical_block_size) { ! printf("fhtovp: across the block boundary %d\n", ! off + ISO_DIRECTORY_RECORD_SIZE); ! return EINVAL; } ! ! if (error = bread(imp->im_devvp, ! lbn * imp->logical_block_size / DEV_BSIZE, ! imp->logical_block_size, ! NOCRED,&bp)) { ! printf("fhtovp: bread error %d\n",error); brelse(bp); ! return EINVAL; } ! ! dirp = (struct iso_directory_record *)(bp->b_un.b_addr + off); ! ! if (off + isonum_711(dirp->length) > imp->logical_block_size) { ! brelse(bp); ! printf("fhtovp: directory across the block boundary %d[off=%d/len=%d]\n", ! off + isonum_711(dirp->length),off,isonum_711(dirp->length)); ! return EINVAL; ! } ! ! if (isonum_733(dirp->extent) + isonum_711(dirp->ext_attr_length) ! != ifhp->ifid_start) { ! brelse(bp); ! printf("fhtovp: file start miss %d vs %d\n", ! isonum_733(dirp->extent) + isonum_711(dirp->ext_attr_length), ! ifhp->ifid_start); ! return EINVAL; ! } ! tvp.v_mount = mp; ip = VTOI(&tvp); ip->i_vnode = &tvp; ip->i_dev = imp->im_dev; ! if (error = iso_iget(ip,ifhp->ifid_ino,0,&nip,dirp)) { *vpp = NULLVP; ! brelse(bp); ! printf("fhtovp: failed to get ino\n"); ! return error; } ip = nip; *vpp = ITOV(ip); ! brelse(bp); ! return 0; } /* *************** *** 572,593 **** 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_lbn = ip->iso_parent_ext; ! ifhp->ifid_offset = ip->iso_parent; ifhp->ifid_ino = ip->i_number; ! ! if(ip->i_number == mp->root_extent) { ! ifhp->ifid_lbn = ip->i_number; ! ifhp->ifid_offset = 0; ! } ! #ifdef ISOFS_DBG ! printf("vptofh: lbn %d, off %d, ino %d\n", ! ifhp->ifid_lbn, ifhp->ifid_offset, ifhp->ifid_ino); #endif ! return (0); } --- 581,596 ---- 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; } *** sys/isofs-old/isofs_vnops.c Wed Jun 1 03:02:33 1994 --- sys/isofs/isofs_vnops.c Wed Jun 1 01:36:09 1994 *************** *** 1,26 **** /* ! * $Id: isofs_vnops.c,v 1.4 1993/12/19 00:51:08 wollman Exp $ */ ! #include "param.h" ! #include "systm.h" ! #include "namei.h" ! #include "resourcevar.h" ! #include "kernel.h" ! #include "file.h" ! #include "stat.h" ! #include "buf.h" ! #include "proc.h" ! #include "conf.h" ! #include "mount.h" ! #include "vnode.h" ! #include "specdev.h" ! #include "fifo.h" ! #include "malloc.h" ! #include "dir.h" ! ! #include "iso.h" ! #include "isofs_node.h" ! #include "iso_rrip.h" /* * Open called. --- 1,84 ---- /* ! * $Id: isofs_vnops.c,v 1.18 1994/05/24 02:38:39 cgd Exp $ */ ! ! #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 <sys/malloc.h> ! #include <sys/dir.h> ! ! #include <sys/specdev.h> /* XXX */ ! #include <sys/fifo.h> /* XXX */ ! ! #include <isofs/iso.h> ! #include <isofs/isofs_node.h> ! #include <isofs/iso_rrip.h> ! ! /* ! * Mknod vnode call ! * Actually remap the device number ! */ ! /* ARGSUSED */ ! int ! isofs_mknod(ndp, vap, cred, p) ! struct nameidata *ndp; ! struct ucred *cred; ! struct vattr *vap; ! struct proc *p; ! { ! #ifndef ISODEVMAP ! free(ndp->ni_pnbuf, M_NAMEI); ! vput(ndp->ni_dvp); ! vput(ndp->ni_vp); ! return EINVAL; ! #else ! register struct vnode *vp; ! struct iso_node *ip; ! struct iso_dnode *dp; ! int error; ! ! vp = ndp->ni_vp; ! ip = VTOI(vp); ! ! if (ip->i_mnt->iso_ftype != ISO_FTYPE_RRIP ! || vap->va_type != vp->v_type ! || (vap->va_type != VCHR && vap->va_type != VBLK)) { ! free(ndp->ni_pnbuf, M_NAMEI); ! vput(ndp->ni_dvp); ! vput(ndp->ni_vp); ! return EINVAL; ! } ! ! dp = iso_dmap(ip->i_dev,ip->i_number,1); ! if (ip->inode.iso_rdev == vap->va_rdev || vap->va_rdev == VNOVAL) { ! /* same as the unmapped one, delete the mapping */ ! remque(dp); ! FREE(dp,M_CACHE); ! } else ! /* enter new mapping */ ! dp->d_dev = vap->va_rdev; ! ! /* ! * Remove inode so that it will be reloaded by iget and ! * checked to see if it is an alias of an existing entry ! * in the inode cache. ! */ ! vput(vp); ! vp->v_type = VNON; ! vgone(vp); ! return (0); ! #endif ! } /* * Open called. *************** *** 66,72 **** struct ucred *cred; struct proc *p; { ! return (0); } /* ARGSUSED */ --- 124,146 ---- struct ucred *cred; struct proc *p; { ! register struct iso_node *ip = VTOI(vp); ! register gid_t *gp; ! int i; ! ! if (cred->cr_uid == 0) ! return 0; ! if (cred->cr_uid != ip->inode.iso_uid) { ! mode >>= 3; ! gp = cred->cr_groups; ! for (i = 0; i < cred->cr_ngroups; i++, gp++) ! if (ip->inode.iso_gid == *gp) ! goto found; ! mode >>= 3; ! found: ! ; ! } ! return (ip->inode.iso_mode & mode) == mode ? 0 : EACCES; } /* ARGSUSED */ *************** *** 80,108 **** register struct iso_node *ip = VTOI(vp); int i; ! vap->va_fsid = ip->i_dev; ! vap->va_fileid = ip->i_number; ! if (vp->v_type == VDIR) ! vap->va_nlink = 2; ! else ! vap->va_nlink = 1; ! ! vap->va_mode = ip->inode.iso_mode; ! vap->va_uid = ip->inode.iso_uid; ! vap->va_gid = ip->inode.iso_gid; vap->va_atime= ip->inode.iso_atime; vap->va_mtime= ip->inode.iso_mtime; vap->va_ctime= ip->inode.iso_ctime; ! vap->va_rdev = 0; ! vap->va_size = ip->i_size; ! vap->va_size_rsv = 0; ! vap->va_flags = 0; vap->va_gen = 1; vap->va_blocksize = ip->i_mnt->logical_block_size; ! vap->va_bytes = ip->i_size; ! vap->va_bytes_rsv = 0; ! vap->va_type = vp->v_type; return (0); } --- 154,178 ---- register struct iso_node *ip = VTOI(vp); int i; ! vap->va_fsid = ip->i_dev; ! vap->va_fileid = ip->i_number; ! ! vap->va_mode = ip->inode.iso_mode; ! vap->va_nlink = ip->inode.iso_links; ! vap->va_uid = ip->inode.iso_uid; ! vap->va_gid = ip->inode.iso_gid; ! vap->va_atime= ip->inode.iso_atime; vap->va_mtime= ip->inode.iso_mtime; vap->va_ctime= ip->inode.iso_ctime; ! vap->va_rdev = ip->inode.iso_rdev; ! vap->va_size = ip->i_size; ! vap->va_flags = 0; vap->va_gen = 1; vap->va_blocksize = ip->i_mnt->logical_block_size; ! vap->va_bytes = ip->i_size; ! vap->va_type = vp->v_type; return (0); } *************** *** 123,136 **** daddr_t lbn, bn, rablock; int size, diff, error = 0; long n, on, type; ! ! #ifdef DIAGNOSTICx ! if (uio->uio_rw != UIO_READ) ! panic("isofs_read mode"); ! type = ip->i_mode & IFMT; ! if (type != IFDIR && type != IFREG && type != IFLNK) ! panic("isofs_read type"); ! #endif if (uio->uio_resid == 0) return (0); if (uio->uio_offset < 0) --- 193,199 ---- daddr_t lbn, bn, rablock; int size, diff, error = 0; long n, on, type; ! if (uio->uio_resid == 0) return (0); if (uio->uio_offset < 0) *************** *** 140,146 **** do { lbn = iso_lblkno(imp, uio->uio_offset); on = iso_blkoff(imp, uio->uio_offset); ! n = MIN((unsigned)(imp->im_bsize - on), uio->uio_resid); diff = ip->i_size - uio->uio_offset; if (diff <= 0) return (0); --- 203,209 ---- do { lbn = iso_lblkno(imp, uio->uio_offset); on = iso_blkoff(imp, uio->uio_offset); ! n = min((unsigned)(imp->logical_block_size - on), uio->uio_resid); diff = ip->i_size - uio->uio_offset; if (diff <= 0) return (0); *************** *** 155,168 **** else error = bread(ITOV(ip), lbn, size, NOCRED, &bp); vp->v_lastr = lbn; ! n = MIN(n, size - bp->b_resid); if (error) { brelse(bp); return (error); } error = uiomove(bp->b_un.b_addr + on, (int)n, uio); ! if (n + on == imp->im_bsize || uio->uio_offset == ip->i_size) bp->b_flags |= B_AGE; brelse(bp); } while (error == 0 && uio->uio_resid > 0 && n != 0); --- 218,231 ---- else error = bread(ITOV(ip), lbn, size, NOCRED, &bp); vp->v_lastr = lbn; ! n = min(n, size - bp->b_resid); if (error) { brelse(bp); return (error); } error = uiomove(bp->b_un.b_addr + on, (int)n, uio); ! if (n + on == imp->logical_block_size || uio->uio_offset == ip->i_size) bp->b_flags |= B_AGE; brelse(bp); } while (error == 0 && uio->uio_resid > 0 && n != 0); *************** *** 179,184 **** --- 242,248 ---- struct ucred *cred; struct proc *p; { + printf("You did ioctl for isofs !!\n"); return (ENOTTY); } *************** *** 231,236 **** --- 295,386 ---- } /* + * Structure for reading directories + */ + struct isoreaddir { + struct dirent saveent; + struct dirent assocent; + struct dirent current; + off_t saveoff; + off_t assocoff; + off_t curroff; + struct uio *uio; + off_t uio_off; + int eof; + }; + + static int + iso_uiodir(idp,dp,off) + struct isoreaddir *idp; + struct dirent *dp; + off_t off; + { + int error; + + dp->d_name[dp->d_namlen] = 0; + dp->d_reclen = DIRSIZ(dp); + + if (idp->uio->uio_resid < dp->d_reclen) { + idp->eof = 0; + return -1; + } + + if (error = uiomove(dp,dp->d_reclen,idp->uio)) + return error; + idp->uio_off = off; + return 0; + } + + static int + iso_shipdir(idp) + struct isoreaddir *idp; + { + struct dirent *dp; + int cl, sl, assoc; + int error; + char *cname, *sname; + + cl = idp->current.d_namlen; + cname = idp->current.d_name; + if (assoc = cl > 1 && *cname == ASSOCCHAR) { + cl--; + cname++; + } + + dp = &idp->saveent; + sname = dp->d_name; + if (!(sl = dp->d_namlen)) { + dp = &idp->assocent; + sname = dp->d_name + 1; + sl = dp->d_namlen - 1; + } + if (sl > 0) { + if (sl != cl + || bcmp(sname,cname,sl)) { + if (idp->assocent.d_namlen) { + if (error = iso_uiodir(idp,&idp->assocent,idp->assocoff)) + return error; + idp->assocent.d_namlen = 0; + } + if (idp->saveent.d_namlen) { + if (error = iso_uiodir(idp,&idp->saveent,idp->saveoff)) + return error; + idp->saveent.d_namlen = 0; + } + } + } + idp->current.d_reclen = DIRSIZ(&idp->current); + if (assoc) { + idp->assocoff = idp->curroff; + bcopy(&idp->current,&idp->assocent,idp->current.d_reclen); + } else { + idp->saveoff = idp->curroff; + bcopy(&idp->current,&idp->saveent,idp->current.d_reclen); + } + return 0; + } + + /* * Vnode op for readdir */ int *************** *** 240,247 **** struct ucred *cred; int *eofflagp; { ! struct dirent dirent; ! int iso_offset; int entryoffsetinblock; int error = 0; int endsearch; --- 390,396 ---- struct ucred *cred; int *eofflagp; { ! struct isoreaddir *idp; int entryoffsetinblock; int error = 0; int endsearch; *************** *** 250,459 **** struct iso_mnt *imp; struct iso_node *ip; struct buf *bp = NULL; ! int i; ! int end_flag = 0; ! ISO_RRIP_ANALYZE ana; ! ip = VTOI (vp); imp = ip->i_mnt; ! ! iso_offset = uio->uio_offset; ! ! entryoffsetinblock = iso_blkoff(imp, iso_offset); if (entryoffsetinblock != 0) { ! if (error = iso_blkatoff(ip, iso_offset, (char **)0, &bp)) return (error); } ! endsearch = ip->i_size; ! ! while (iso_offset < endsearch && uio->uio_resid > 0) { /* * If offset is on a block boundary, * read the next directory block. * Release previous if it exists. */ ! ! if (iso_blkoff(imp, iso_offset) == 0) { if (bp != NULL) brelse(bp); ! if (error = iso_blkatoff(ip, iso_offset, ! (char **)0, &bp)) ! return (error); entryoffsetinblock = 0; } /* * Get pointer to next entry. */ ! ep = (struct iso_directory_record *) (bp->b_un.b_addr + entryoffsetinblock); ! reclen = isonum_711 (ep->length); if (reclen == 0) { /* skip to next block, if any */ ! iso_offset = roundup (iso_offset, ! imp->logical_block_size); continue; } ! ! if (reclen < sizeof (struct iso_directory_record)) /* illegal entry, stop */ break; ! ! /* 10 Aug 92*/ if (entryoffsetinblock + reclen -1 >= imp->logical_block_size) /* illegal directory, so stop looking */ break; ! ! dirent.d_fileno = isonum_733 (ep->extent); ! dirent.d_namlen = isonum_711 (ep->name_len); ! ! if (reclen < sizeof (struct iso_directory_record) ! + dirent.d_namlen) /* illegal entry, stop */ break; ! /* * */ ! switch (ep->name[0]) { ! case 0: ! dirent.d_name[0] = '.'; ! dirent.d_namlen = 1; break; ! case 1: ! dirent.d_name[0] = '.'; ! dirent.d_name[1] = '.'; ! dirent.d_namlen = 2; ! break; ! default: ! switch ( imp->iso_ftype ) { ! case ISO_FTYPE_RRIP: ! isofs_rrip_getname( ep, dirent.d_name, &dirent.d_namlen ); break; ! case ISO_FTYPE_9660: ! { ! int namelen = dirent.d_namlen; ! isofntrans(ep->name, dirent.d_namlen, ! dirent.d_name, &namelen); ! dirent.d_namlen = namelen; break; - } default: break; } - break; } ! ! dirent.d_name[dirent.d_namlen] = 0; ! dirent.d_reclen = DIRSIZ (&dirent); ! ! if (uio->uio_resid < dirent.d_reclen) break; ! ! if (error = uiomove (&dirent, dirent.d_reclen, uio)) ! break; ! ! iso_offset += reclen; entryoffsetinblock += reclen; } ! if (bp) brelse (bp); ! if (end_flag || (VTOI(vp)->i_size - iso_offset) <= 0) ! *eofflagp = 1; ! else ! *eofflagp = 0; ! ! uio->uio_offset = iso_offset; ! return (error); } /* * Return target name of a symbolic link */ typedef struct iso_directory_record ISODIR; typedef struct iso_node ISONODE; typedef struct iso_mnt ISOMNT; int isofs_readlink(vp, uio, cred) ! struct vnode *vp; ! struct uio *uio; ! struct ucred *cred; ! { ! ISONODE *ip; ! ISODIR *dirp; ! ISOMNT *imp; ! struct buf *bp; ! int symlen; ! int error; ! char symname[NAME_MAX]; ! ! ip = VTOI( vp ); ! imp = ip->i_mnt; ! /* ! * Get parents directory record block that this inode included. ! */ ! error = bread( imp->im_devvp, ! (daddr_t)(( ip->iso_parent_ext + (ip->iso_parent >> 11 ) ) ! * imp->im_bsize / DEV_BSIZE ), ! imp->im_bsize, ! NOCRED, ! &bp ); ! if ( error ) { ! return( EINVAL ); ! } ! ! /* ! * Setup the directory pointer for this inode ! */ ! dirp = (ISODIR *)(bp->b_un.b_addr + ( ip->iso_parent & 0x7ff ) ); #ifdef DEBUG ! printf("lbn=%d[base=%d,off=%d,bsize=%d,DEV_BSIZE=%d], dirp= %08x, b_addr=%08x, offset=%08x(%08x)\n", ! (daddr_t)(( ip->iso_parent_ext + (ip->iso_parent >> 12 ) ) * imp->im_bsize / DEV_BSIZE ), ! ip->iso_parent_ext, ! (ip->iso_parent >> 11 ), ! imp->im_bsize, ! DEV_BSIZE, ! dirp, ! bp->b_un.b_addr, ! ip->iso_parent, ! ip->iso_parent & 0x7ff ); #endif ! ! /* ! * Just make sure, we have a right one.... ! * 1: Check not cross boundary on block ! * 2: Check number of inode ! */ ! if ( (ip->iso_parent & 0x7ff) + isonum_711( dirp->length ) >= ! imp->im_bsize ) { ! brelse ( bp ); ! return( EINVAL ); ! } ! if ( isonum_733(dirp->extent) != ip->i_number ) { ! brelse ( bp ); ! return( EINVAL ); ! } ! ! /* ! * Ok, we just gathering a Symbolick name in SL record. ! */ ! if ( isofs_rrip_getsymname( vp, dirp, symname, &symlen ) == 0 ) { ! brelse ( bp ); ! return( EINVAL ); ! } ! /* ! * Don't forget before you leave from home ;-) ! */ ! brelse( bp ); ! ! /* ! * return with the Symbolick name to caller's. ! */ ! return ( uiomove( symname, symlen, uio ) ); } /* --- 399,632 ---- struct iso_mnt *imp; struct iso_node *ip; struct buf *bp = NULL; ! ip = VTOI (vp); imp = ip->i_mnt; ! ! MALLOC(idp,struct isoreaddir *,sizeof(*idp),M_TEMP,M_WAITOK); ! idp->saveent.d_namlen = 0; ! idp->assocent.d_namlen = 0; ! idp->uio = uio; ! idp->curroff = uio->uio_offset; ! idp->eof = 1; ! ! entryoffsetinblock = iso_blkoff(imp, idp->curroff); if (entryoffsetinblock != 0) { ! if (error = iso_blkatoff(ip, idp->curroff, &bp)) { ! FREE(idp,M_TEMP); return (error); + } } ! endsearch = ip->i_size; ! ! while (idp->curroff < endsearch) { /* * If offset is on a block boundary, * read the next directory block. * Release previous if it exists. */ ! ! if (iso_blkoff(imp, idp->curroff) == 0) { if (bp != NULL) brelse(bp); ! if (error = iso_blkatoff(ip, idp->curroff, &bp)) ! break; entryoffsetinblock = 0; } /* * Get pointer to next entry. */ ! ep = (struct iso_directory_record *) (bp->b_un.b_addr + entryoffsetinblock); ! reclen = isonum_711 (ep->length); if (reclen == 0) { /* skip to next block, if any */ ! idp->curroff = roundup (idp->curroff, ! imp->logical_block_size); continue; } ! ! if (reclen < ISO_DIRECTORY_RECORD_SIZE) { ! error = EINVAL; /* illegal entry, stop */ break; ! } ! ! if (entryoffsetinblock + reclen > imp->logical_block_size) { ! error = EINVAL; /* illegal directory, so stop looking */ break; ! } ! ! idp->current.d_namlen = isonum_711 (ep->name_len); ! if (isonum_711(ep->flags)&2) ! isodirino(&idp->current.d_fileno,ep,imp); ! else ! idp->current.d_fileno = (bp->b_blkno << DEV_BSHIFT) + idp->curroff; ! ! if (reclen < ISO_DIRECTORY_RECORD_SIZE + idp->current.d_namlen) { ! error = EINVAL; /* illegal entry, stop */ break; ! } ! ! idp->curroff += reclen; /* * */ ! switch (imp->iso_ftype) { ! case ISO_FTYPE_RRIP: ! isofs_rrip_getname(ep,idp->current.d_name, ! &idp->current.d_namlen, ! &idp->current.d_fileno,imp); ! if (idp->current.d_namlen) ! error = iso_uiodir(idp,&idp->current,idp->curroff); break; ! default: /* ISO_FTYPE_DEFAULT || ISO_FTYPE_9660 */ ! strcpy(idp->current.d_name,".."); ! switch (ep->name[0]) { ! case 0: ! idp->current.d_namlen = 1; ! error = iso_uiodir(idp,&idp->current,idp->curroff); break; ! case 1: ! idp->current.d_namlen = 2; ! error = iso_uiodir(idp,&idp->current,idp->curroff); break; default: + isofntrans(ep->name,idp->current.d_namlen, + idp->current.d_name,&idp->current.d_namlen, + imp->iso_ftype == ISO_FTYPE_9660, + isonum_711(ep->flags)&4); + if (imp->iso_ftype == ISO_FTYPE_DEFAULT) + error = iso_shipdir(idp); + else + error = iso_uiodir(idp,&idp->current,idp->curroff); break; } } ! if (error) break; ! entryoffsetinblock += reclen; } ! ! if (!error && imp->iso_ftype == ISO_FTYPE_DEFAULT) { ! idp->current.d_namlen = 0; ! error = iso_shipdir(idp); ! } ! if (error < 0) ! error = 0; ! if (bp) brelse (bp); ! uio->uio_offset = idp->uio_off; ! *eofflagp = idp->eof; ! ! FREE(idp,M_TEMP); ! return (error); } /* * Return target name of a symbolic link + * Shouldn't we get the parent vnode and read the data from there? + * This could eventually result in deadlocks in isofs_lookup. + * But otherwise the block read here is in the block buffer two times. */ typedef struct iso_directory_record ISODIR; typedef struct iso_node ISONODE; typedef struct iso_mnt ISOMNT; int isofs_readlink(vp, uio, cred) ! struct vnode *vp; ! struct uio *uio; ! struct ucred *cred; ! { ! ISONODE *ip; ! ISODIR *dirp; ! ISOMNT *imp; ! struct buf *bp; ! u_short symlen; ! int error; ! char *symname; ! ino_t ino; ! ! ip = VTOI(vp); ! imp = ip->i_mnt; ! ! if (imp->iso_ftype != ISO_FTYPE_RRIP) ! return EINVAL; ! ! /* ! * Get parents directory record block that this inode included. ! */ ! error = bread(imp->im_devvp, ! (daddr_t)((ip->i_number&~imp->im_bmask) / DEV_BSIZE), ! imp->logical_block_size, ! NOCRED, ! &bp); ! if (error) { ! brelse(bp); ! return EINVAL; ! } ! /* ! * Setup the directory pointer for this inode ! */ ! dirp = (ISODIR *)(bp->b_un.b_addr + (ip->i_number & imp->im_bmask)); #ifdef DEBUG ! printf("lbn=%d,off=%d,bsize=%d,DEV_BSIZE=%d, dirp= %08x, b_addr=%08x, offset=%08x(%08x)\n", ! (daddr_t)(ip->i_number >> imp->im_bshift), ! ip->i_number & imp->im_bmask, ! imp->logical_block_size, ! DEV_BSIZE, ! dirp, ! bp->b_un.b_addr, ! ip->i_number, ! ip->i_number & imp->im_bmask ); #endif ! ! /* ! * Just make sure, we have a right one.... ! * 1: Check not cross boundary on block ! */ ! if ((ip->i_number & imp->im_bmask) + isonum_711(dirp->length) ! > imp->logical_block_size) { ! brelse(bp); ! return EINVAL; ! } ! ! /* ! * Now get a buffer ! * Abuse a namei buffer for now. ! */ ! MALLOC(symname,char *,MAXPATHLEN,M_NAMEI,M_WAITOK); ! ! /* ! * Ok, we just gathering a symbolic name in SL record. ! */ ! if (isofs_rrip_getsymname(dirp,symname,&symlen,imp) == 0) { ! FREE(symname,M_NAMEI); ! brelse(bp); ! return EINVAL; ! } ! /* ! * Don't forget before you leave from home ;-) ! */ ! brelse(bp); ! ! /* ! * return with the symbolic name to caller's. ! */ ! error = uiomove(symname,symlen,uio); ! ! FREE(symname,M_NAMEI); ! ! return error; } /* *************** *** 468,474 **** if ((ndp->ni_nameiop & (HASBUF | SAVESTART)) == HASBUF) FREE(ndp->ni_pnbuf, M_NAMEI); ! return (0); } /* --- 641,647 ---- if ((ndp->ni_nameiop & (HASBUF | SAVESTART)) == HASBUF) FREE(ndp->ni_pnbuf, M_NAMEI); ! return 0; } /* *************** *** 481,487 **** register struct iso_node *ip = VTOI(vp); ISO_ILOCK(ip); ! return (0); } /* --- 654,660 ---- register struct iso_node *ip = VTOI(vp); ISO_ILOCK(ip); ! return 0; } /* *************** *** 496,502 **** if (!(ip->i_flag & ILOCKED)) panic("isofs_unlock NOT LOCKED"); ISO_IUNLOCK(ip); ! return (0); } /* --- 669,675 ---- if (!(ip->i_flag & ILOCKED)) panic("isofs_unlock NOT LOCKED"); ISO_IUNLOCK(ip); ! return 0; } /* *************** *** 508,515 **** { if (VTOI(vp)->i_flag & ILOCKED) ! return (1); ! return (0); } /* --- 681,688 ---- { if (VTOI(vp)->i_flag & ILOCKED) ! return 1; ! return 0; } /* *************** *** 529,546 **** panic("isofs_strategy: spec"); if (bp->b_blkno == bp->b_lblkno) { if (error = iso_bmap(ip, bp->b_lblkno, &bp->b_blkno)) ! return (error); if ((long)bp->b_blkno == -1) clrbuf(bp); } if ((long)bp->b_blkno == -1) { biodone(bp); ! return (0); } vp = ip->i_devvp; bp->b_dev = vp->v_rdev; (*(vp->v_op->vop_strategy))(bp); ! return (0); } /* --- 702,719 ---- panic("isofs_strategy: spec"); if (bp->b_blkno == bp->b_lblkno) { if (error = iso_bmap(ip, bp->b_lblkno, &bp->b_blkno)) ! return error; if ((long)bp->b_blkno == -1) clrbuf(bp); } if ((long)bp->b_blkno == -1) { biodone(bp); ! return 0; } vp = ip->i_devvp; bp->b_dev = vp->v_rdev; (*(vp->v_op->vop_strategy))(bp); ! return 0; } /* *************** *** 550,556 **** isofs_print(vp) struct vnode *vp; { ! printf ("tag VT_ISOFS, isofs vnode\n"); } extern int enodev (); --- 723,729 ---- isofs_print(vp) struct vnode *vp; { ! printf("tag VT_ISOFS, isofs vnode\n"); } extern int enodev (); *************** *** 593,595 **** --- 766,842 ---- isofs_islocked, /* islocked */ (void *)enodev, /* advlock */ }; + + struct vnodeops isofs_spec_inodeops = { + spec_lookup, /* lookup */ + (void *)enodev, /* create */ + (void *)enodev, /* mknod */ + spec_open, /* open */ + spec_close, /* close */ + isofs_access, /* access */ + isofs_getattr, /* getattr */ + (void *)enodev, /* setattr */ + spec_read, /* read */ + spec_write, /* write */ + spec_ioctl, /* ioctl */ + spec_select, /* select */ + spec_mmap, /* mmap */ + spec_fsync, /* fsync */ + spec_seek, /* seek */ + (void *)enodev, /* remove */ + (void *)enodev, /* link */ + (void *)enodev, /* rename */ + (void *)enodev, /* mkdir */ + (void *)enodev, /* rmdir */ + (void *)enodev, /* symlink */ + spec_readdir, /* readdir */ + spec_readlink, /* readlink */ + spec_abortop, /* abortop */ + isofs_inactive, /* inactive */ + isofs_reclaim, /* reclaim */ + isofs_lock, /* lock */ + isofs_unlock, /* unlock */ + (void *)enodev, /* bmap */ + spec_strategy, /* strategy */ + isofs_print, /* print */ + isofs_islocked, /* islocked */ + spec_advlock, /* advlock */ + }; + + #ifdef FIFO + struct vnodeops isofs_fifo_inodeops = { + fifo_lookup, /* lookup */ + (void *)enodev, /* create */ + (void *)enodev, /* mknod */ + fifo_open, /* open */ + fifo_close, /* close */ + isofs_access, /* access */ + isofs_getattr, /* getattr */ + (void *)enodev, /* setattr */ + fifo_read, /* read */ + fifo_write, /* write */ + fifo_ioctl, /* ioctl */ + fifo_select, /* select */ + fifo_mmap, /* mmap */ + fifo_fsync, /* fsync */ + fifo_seek, /* seek */ + (void *)enodev, /* remove */ + (void *)enodev, /* link */ + (void *)enodev, /* rename */ + (void *)enodev, /* mkdir */ + (void *)enodev, /* rmdir */ + (void *)enodev, /* symlink */ + fifo_readdir, /* readdir */ + fifo_readlink, /* readlink */ + fifo_abortop, /* abortop */ + isofs_inactive, /* inactive */ + isofs_reclaim, /* reclaim */ + isofs_lock, /* lock */ + isofs_unlock, /* unlock */ + (void *)enodev, /* bmap */ + fifo_strategy, /* strategy */ + isofs_print, /* print */ + isofs_islocked, /* islocked */ + fifo_advlock, /* advlock */ + }; + #endif /* FIFO */ *** sbin/mount_isofs-old/Makefile Wed Jul 21 17:57:15 1993 --- sbin/mount_isofs/Makefile Wed Jun 1 22:24:25 1994 *************** *** 1,4 **** ! # $Id: Makefile,v 1.3 1993/07/21 21:57:33 rgrimes Exp $ PROG = mount_isofs MAN8 = mount_isofs.8 --- 1,4 ---- ! # $Id: Makefile,v 1.5 1993/09/07 15:40:28 ws Exp $ PROG = mount_isofs MAN8 = mount_isofs.8 *** sbin/mount_isofs-old/mount_isofs.8 Sun Feb 6 21:47:38 1994 --- sbin/mount_isofs/mount_isofs.8 Wed Jun 1 22:22:25 1994 *************** *** 14,20 **** .\" must display the following acknowledgement: .\" This product includes software developed by Christopher G. Demetriou. .\" 3. The name of the author may not be used to endorse or promote products ! .\" derived from this software withough specific prior written permission .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES --- 14,20 ---- .\" must display the following acknowledgement: .\" This product includes software developed by Christopher G. Demetriou. .\" 3. The name of the author may not be used to endorse or promote products ! .\" derived from this software without specific prior written permission .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES *************** *** 27,37 **** .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" ! .\" $Id: mount_isofs.8,v 1.5 1994/02/07 02:47:56 rgrimes Exp $ .\" .Dd July 19, 1993 .Dt MOUNT_ISOFS 8 ! .Os .Sh NAME .Nm mount_isofs .Nd mount an ISO-9660 filesystem --- 27,37 ---- .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" ! .\" $Id: mount_isofs.8,v 1.5 1994/01/29 01:43:37 jtc Exp $ .\" .Dd July 19, 1993 .Dt MOUNT_ISOFS 8 ! .Os NetBSD 0.9 .Sh NAME .Nm mount_isofs .Nd mount an ISO-9660 filesystem *************** *** 39,44 **** --- 39,46 ---- .Nm mount_isofs .Op Fl F Ar fsoptions .Op Fl norrip + .Op Fl gen + .Op Fl extattr .Pa special .Pa node .Sh DESCRIPTION *************** *** 51,57 **** indicated by .Pa node . This command is normally executed by ! .Xr mount 8 . at boot time. .Pp If the filesystem includes Rockridge extensions, they are --- 53,59 ---- indicated by .Pa node . This command is normally executed by ! .Xr mount 8 at boot time. .Pp If the filesystem includes Rockridge extensions, they are *************** *** 60,71 **** flag is used. If that option is given to .Nm then the Rockridge extensions will be ignored. .Sh EXAMPLES .Bd -literal -offset indent -compact ! mount_isofs /dev/cd0a /cdrom ! mount_isofs \-norrip /dev/cd0a /cdrom ! mount \-t isofs /dev/cd0a /cdrom ! mount \-t isofs \-o \-norrip /dev/cd0a /cdrom .Ed .Sh SEE ALSO .Xr mount 2 , --- 62,89 ---- flag is used. If that option is given to .Nm then the Rockridge extensions will be ignored. + .Pp + Version numbers on files are normally stripped on directory listings. + If you want to see those, use the + .Fl gen + flag. + Otherwise, if there are files with different version numbers on the disk, + only the last one will be listed. + In either case, you may open a file with or without explicitly stating the + version number. + .Pp + If a disk contains extended attributes, they are normally ignored. + You can enable the usage of extended attributes with the + .Fl extattr + flag. .Sh EXAMPLES .Bd -literal -offset indent -compact ! mount_isofs /dev/cd0d /cdrom ! mount_isofs \-norrip /dev/cd0d /cdrom ! mount_isofs \-norrip \-gen /dev/cd0d /cdrom ! mount \-t isofs /dev/cd0d /cdrom ! mount \-t isofs \-o \-norrip /dev/cd0d /cdrom ! mount \-t isofs \-o \-gen,\-extattr /dev/cd0d /cdrom .Ed .Sh SEE ALSO .Xr mount 2 , *************** *** 76,82 **** ("CDROM001") format; it does not. .Pp ! POSIX device nodes are currently not supported. .Pp The filesystem name might need some rethinking, and some would say it should run as a user process. --- 94,105 ---- ("CDROM001") format; it does not. .Pp ! POSIX device node mapping is currently not supported. ! .Pp ! Version numbers are not stripped if Rockridge extensions are in use. ! In this case, accessing files that don't have Rockridge names without ! version numbers gets the one with the lowest version number and not ! the one with the highest. .Pp The filesystem name might need some rethinking, and some would say it should run as a user process. *** sbin/mount_isofs-old/mount_isofs.c Sun Oct 24 00:29:50 1993 --- sbin/mount_isofs/mount_isofs.c Wed Jun 1 22:22:25 1994 *************** *** 1,9 **** #ifndef lint ! static char rcsid[] = "$Header: /home/cvs/386BSD/src/sbin/mount_isofs/mount_isofs.c,v 1.3 1993/10/24 04:30:08 rgrimes Exp $"; ! #endif #include <stdio.h> #include <sys/types.h> #include <sys/mount.h> void --- 1,10 ---- #ifndef lint ! static char rcsid[] = "$Id: mount_isofs.c,v 1.8 1993/10/20 19:53:36 cgd Exp $"; ! #endif /* not lint */ #include <stdio.h> #include <sys/types.h> + #define ISOFS #include <sys/mount.h> void *************** *** 20,40 **** { char *dev; char *dir; ! struct ufs_args args; int c; ! int opts; ! ! opts = MNT_RDONLY; argc--; argv++; while (argc > 2) { if (!strcmp("-F", argv[0])) { argc--; argv++; ! opts |= atoi(argv[0]); argc--; argv++; } else if (!strcmp(argv[0], "-norrip")) { ! opts |= MNT_NORRIP; argc--; argv++; } else usage(); --- 21,45 ---- { char *dev; char *dir; ! struct iso_args args; int c; ! int opts = 0, mntflags = 0; argc--; argv++; while (argc > 2) { if (!strcmp("-F", argv[0])) { argc--; argv++; ! mntflags |= atoi(argv[0]); argc--; argv++; } else if (!strcmp(argv[0], "-norrip")) { ! opts |= ISOFSMNT_NORRIP; ! argc--; argv++; ! } else if (!strcmp(argv[0], "-gen")) { ! opts |= ISOFSMNT_GENS; ! argc--; argv++; ! } else if (!strcmp(argv[0], "-extattr")) { ! opts |= ISOFSMNT_EXTATT; argc--; argv++; } else usage(); *************** *** 44,53 **** dir = argv[1]; args.fspec = dev; ! args.exflags = MNT_EXRDONLY | opts; ! args.exroot = 0; ! if (mount (MOUNT_ISOFS, dir, MNT_RDONLY, &args) < 0) { perror ("mount"); exit (1); } --- 49,57 ---- dir = argv[1]; args.fspec = dev; ! args.flags = opts; ! if (mount (MOUNT_ISOFS, dir, mntflags, &args) < 0) { perror ("mount"); exit (1); } ---*END*---8<---*END*---8<---*END*---8<---*END*---8<---*END*---8<---*END*--- -- Jordan K. Hubbard FreeBSD core team Friend to mollusks