From 053f138daea5d853835ec2fe8c9253a682beef5f Mon Sep 17 00:00:00 2001 From: ws Date: Tue, 7 Sep 1993 15:40:14 +0000 Subject: [PATCH] Changes to VFS readdir semantics NFS changes for better cookie support ISOFS changes for better Rockridge support and support for generation numbers --- sbin/Makefile.inc | 3 +- sbin/mount/mount.c | 7 +- sbin/mount_isofs/Makefile | 3 +- sbin/mount_isofs/mount_isofs.8 | 29 +- sbin/mount_isofs/mount_isofs.c | 17 +- sbin/mount_msdos/mount_msdos.c | 4 +- sbin/mountd/mountd.c | 11 +- sys/isofs/TODO | 39 +- sys/isofs/iso.h | 115 +++- sys/isofs/iso_rrip.h | 40 +- sys/isofs/isofs_bmap.c | 6 +- sys/isofs/isofs_lookup.c | 191 +++--- sys/isofs/isofs_node.c | 450 ++++++++++-- sys/isofs/isofs_node.h | 43 +- sys/isofs/isofs_rrip.c | 1095 +++++++++++++++--------------- sys/isofs/isofs_rrip.h | 24 +- sys/isofs/isofs_util.c | 96 ++- sys/isofs/isofs_vfsops.c | 243 +++---- sys/isofs/isofs_vnops.c | 589 +++++++++++----- sys/kern/dead_vnops.c | 6 +- sys/kern/vfs_cache.c | 11 +- sys/kern/vfs_lookup.c | 2 +- sys/kern/vfs_syscalls.c | 2 +- sys/kern/vfs_vnops.c | 2 +- sys/miscfs/deadfs/dead_vnops.c | 6 +- sys/miscfs/fdesc/fdesc_vnops.c | 16 +- sys/miscfs/fifofs/fifo.h | 6 +- sys/miscfs/kernfs/kernfs_vnops.c | 12 +- sys/miscfs/procfs/pfsnode.h | 6 +- sys/miscfs/procfs/procfs_vnops.c | 22 +- sys/miscfs/specfs/specdev.h | 6 +- sys/msdosfs/denode.h | 6 +- sys/msdosfs/msdosfs_vfsops.c | 19 +- sys/msdosfs/msdosfs_vnops.c | 48 +- sys/nfs/nfs_serv.c | 45 +- sys/nfs/nfs_socket.c | 6 +- sys/nfs/nfs_srvcache.c | 3 +- sys/nfs/nfs_subs.c | 4 +- sys/nfs/nfs_vnops.c | 15 +- sys/nfs/nfsnode.h | 6 +- sys/sys/fifo.h | 6 +- sys/sys/mount.h | 27 +- sys/sys/specdev.h | 6 +- sys/sys/vnode.h | 7 +- sys/ufs/mfsnode.h | 6 +- sys/ufs/ufs_vfsops.c | 2 +- usr.sbin/mountd/mountd.c | 11 +- 47 files changed, 2050 insertions(+), 1269 deletions(-) diff --git a/sbin/Makefile.inc b/sbin/Makefile.inc index 4bb5e980fbfa..de8ead5c8c19 100644 --- a/sbin/Makefile.inc +++ b/sbin/Makefile.inc @@ -1,4 +1,5 @@ # from: @(#)Makefile.inc 5.1 (Berkeley) 5/11/90 -# $Id: Makefile.inc,v 1.4 1993/08/01 05:38:32 mycroft Exp $ +# $Id: Makefile.inc,v 1.5 1993/09/07 15:40:14 ws Exp $ BINDIR?= /sbin +CFLAGS += -I../../sys diff --git a/sbin/mount/mount.c b/sbin/mount/mount.c index 9f98230910ec..6d7ceea28a13 100644 --- a/sbin/mount/mount.c +++ b/sbin/mount/mount.c @@ -39,7 +39,7 @@ char copyright[] = #ifndef lint /*static char sccsid[] = "from: @(#)mount.c 5.44 (Berkeley) 2/26/91";*/ -static char rcsid[] = "$Id: mount.c,v 1.5 1993/08/03 01:25:52 mycroft Exp $"; +static char rcsid[] = "$Id: mount.c,v 1.6 1993/09/07 15:40:25 ws Exp $"; #endif /* not lint */ #include @@ -292,11 +292,6 @@ mountfs(spec, name, flags, type, options, mntopts) if (options) getufsopts(options, &flags); args.fspec = spec; - args.exroot = DEFAULT_ROOTUID; - if (flags & MNT_RDONLY) - args.exflags = MNT_EXRDONLY; - else - args.exflags = 0; argp = (caddr_t)&args; break; diff --git a/sbin/mount_isofs/Makefile b/sbin/mount_isofs/Makefile index 3009257acad4..f05b4b04cbb7 100644 --- a/sbin/mount_isofs/Makefile +++ b/sbin/mount_isofs/Makefile @@ -1,5 +1,6 @@ -# $Id: Makefile,v 1.4 1993/07/28 00:57:07 cgd Exp $ +# $Id: Makefile,v 1.5 1993/09/07 15:40:28 ws Exp $ PROG = mount_isofs +MAN8= ${PROG}.0 .include diff --git a/sbin/mount_isofs/mount_isofs.8 b/sbin/mount_isofs/mount_isofs.8 index aed4bc20d999..79eb3575e9d0 100644 --- a/sbin/mount_isofs/mount_isofs.8 +++ b/sbin/mount_isofs/mount_isofs.8 @@ -27,7 +27,7 @@ .\" (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.2 1993/07/28 00:57:11 cgd Exp $ +.\" $Id: mount_isofs.8,v 1.3 1993/09/07 15:40:29 ws Exp $ .\" .Dd July 19, 1993 .Dt MOUNT_MSDOS 8 @@ -39,6 +39,8 @@ .Nm mount_isofs .Op Fl F Ar fsoptions .Op Fl norrip +.Op Fl gen +.Op Fl extattr .Pa special .Pa node .Sh DESCRIPTION @@ -51,7 +53,7 @@ to the global filesystem namespace at the location indicated by .Pa node . This command is normally executed by -.Xr mount 8 . +.Xr mount 8 at boot time. .Pp If the filesystem includes Rockridge extensions, they are @@ -60,12 +62,28 @@ used unless the 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,7 +94,12 @@ The isofs filesystem should support the original "High Sierra" ("CDROM001") format; it does not. .Pp -POSIX device nodes are currently not supported. +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. diff --git a/sbin/mount_isofs/mount_isofs.c b/sbin/mount_isofs/mount_isofs.c index 336f5e230fc8..b46b9cba0bcb 100644 --- a/sbin/mount_isofs/mount_isofs.c +++ b/sbin/mount_isofs/mount_isofs.c @@ -1,5 +1,5 @@ #ifndef lint -static char rcsid[] = "$Id: mount_isofs.c,v 1.6 1993/08/02 17:51:07 mycroft Exp $"; +static char rcsid[] = "$Id: mount_isofs.c,v 1.7 1993/09/07 15:40:30 ws Exp $"; #endif /* not lint */ #include @@ -21,11 +21,9 @@ char **argv; { char *dev; char *dir; - struct ufs_args args; + struct iso_args args; int c; - int opts; - - opts = MNT_RDONLY; + int opts = 0; argc--; argv++; @@ -37,6 +35,12 @@ char **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(); } @@ -45,8 +49,7 @@ char **argv; dir = argv[1]; args.fspec = dev; - args.exflags = MNT_EXRDONLY | opts; - args.exroot = 0; + args.flags = opts; if (mount (MOUNT_ISOFS, dir, MNT_RDONLY, &args) < 0) { perror ("mount"); diff --git a/sbin/mount_msdos/mount_msdos.c b/sbin/mount_msdos/mount_msdos.c index a84516c96167..9682e03a58d6 100644 --- a/sbin/mount_msdos/mount_msdos.c +++ b/sbin/mount_msdos/mount_msdos.c @@ -3,7 +3,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: mount_msdos.c,v 1.3 1993/08/14 11:05:26 mycroft Exp $"; +static char rcsid[] = "$Id: mount_msdos.c,v 1.4 1993/09/07 15:40:33 ws Exp $"; #endif /* not lint */ #include @@ -53,8 +53,6 @@ char **argv; dir = argv[optind + 1]; args.fspec = dev; - args.exflags = 0; - args.exroot = 0; if (mount (MOUNT_MSDOS, dir, opts, &args) < 0) { perror ("mount"); diff --git a/sbin/mountd/mountd.c b/sbin/mountd/mountd.c index 5f078ee7b050..d5c449b07269 100644 --- a/sbin/mountd/mountd.c +++ b/sbin/mountd/mountd.c @@ -42,7 +42,7 @@ char copyright[] = #ifndef lint /*static char sccsid[] = "from: @(#)mountd.c 5.14 (Berkeley) 2/26/91";*/ -static char rcsid[] = "$Id: mountd.c,v 1.7 1993/08/25 02:42:57 brezak Exp $"; +static char rcsid[] = "$Id: mountd.c,v 1.8 1993/09/07 15:40:37 ws Exp $"; #endif not lint #include @@ -452,7 +452,7 @@ get_exportlist() register struct grouplist *grp; register struct exportlist *ep, *ep2; struct statfs stfsbuf; - struct ufs_args args; + struct export_args args; struct stat sb; FILE *inf; char *cp, *endcp; @@ -618,13 +618,12 @@ get_exportlist() len = endcp - cp; } if (fep == NULL) { - args.fspec = 0; - args.exflags = exflags; args.exroot = rootuid; cp = (char *)0; while (statfs(ep->ex_dirp, &stfsbuf) < 0 || - mount(MOUNT_UFS, ep->ex_dirp, - stfsbuf.f_flags|MNT_UPDATE, &args) < 0) { + mount(MOUNT_EXPORT, ep->ex_dirp, + stfsbuf.f_flags|(MNT_UPDATE|exflags), + &args) < 0) { /* 08 Sep 92*/ if (cp) *cp-- = savedc; else diff --git a/sys/isofs/TODO b/sys/isofs/TODO index 9735320da883..555d26ad7d11 100644 --- a/sys/isofs/TODO +++ b/sys/isofs/TODO @@ -1,4 +1,4 @@ -# $Id: TODO,v 1.3 1993/07/19 13:40:00 cgd Exp $ +# $Id: TODO,v 1.4 1993/09/07 15:40:51 ws Exp $ 1) should understand "older", original High Sierra ("CDROM001") type @@ -13,22 +13,16 @@ o File Attribute o Time stamp o uid, gid + o Devices + o Relocated directories Except follows: - o POSIX device modes + o POSIX device number mapping - I have no idea right now, we should check a REAL implementation - for 386BSD..... + There is some preliminary stuff in there that (ab-)uses the mknod + system call, but this needs a writable filesystem - 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 @@ -48,8 +42,7 @@ 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. + Not yet. 7) ECMA support. @@ -62,5 +55,23 @@ clean. As far as I know, if you export the cdrom by NFS, the client can access the 8 bit clean (ie. Solaris Japanese with EUC code ) + 9) Access checks in isofs_access + + Not yet. + + 10) Support for generation numbers + + Yes. Default is to list only the last file (the one with the highest + generation number). If you mount with -gen, all files are shown with + their generation numbers. In both cases you can specify the generation + number on opening files (if you happen to know it) or leave it off, + when it will again find the last file. + + 11) Support for extended attributes + + Yes. Since this requires an extra block buffer for the attributes + this must be enabled on mounting with the option -extattr. + ---------- Last update July 19, '93 by Atsushi Murai. (amurai@spec.co.jp) +Last update August 19, '93 by Wolfgang Solfrank. (ws@tools.de) diff --git a/sys/isofs/iso.h b/sys/isofs/iso.h index 046cffa12a80..a6e016800404 100644 --- a/sys/isofs/iso.h +++ b/sys/isofs/iso.h @@ -1,5 +1,5 @@ /* - * $Id: iso.h,v 1.4 1993/09/03 04:37:52 cgd Exp $ + * $Id: iso.h,v 1.5 1993/09/07 15:40:52 ws Exp $ */ #define ISODCL(from, to) (to - from + 1) @@ -71,17 +71,40 @@ struct iso_directory_record { of the last entry (34 instead of 33) */ #define ISO_DIRECTORY_RECORD_SIZE 33 -/* CD-ROM Fromat type */ -enum ISO_FTYPE { ISO_FTYPE_9660, ISO_FTYPE_RRIP, ISO_FTYPE_ECMA }; +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]; - int im_ronly; - int im_fmod; struct mount *im_mountp; dev_t im_dev; @@ -93,6 +116,9 @@ struct iso_mnt { 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)) @@ -116,20 +142,77 @@ int 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, char **res, struct buf **bpp)); +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, struct iso_node **ipp, struct iso_directory_record *isodir)); int iso_iput __P((struct iso_node *ip)); int iso_ilock __P((struct iso_node *ip)); int iso_iunlock __P((struct iso_node *ip)); -int isonum_711 __P((unsigned char *p)); -int isonum_712 __P((signed char *p)); -int isonum_721 __P((unsigned char *p)); -int isonum_722 __P((unsigned char *p)); -int isonum_723 __P((unsigned char *p)); -int isonum_731 __P((unsigned char *p)); -int isonum_732 __P((unsigned char *p)); -int isonum_733 __P((unsigned char *p)); int isofs_mountroot __P((void)); -int iso_mountfs __P((struct vnode *devvp, struct mount *mp, struct proc *p)); -int iso_mountedon __P((struct vnode *vp)); + +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 stripgen, int assoc)); + +/* + * Associated files have a trailing '@'. + */ +#define ASSOCCHAR '@' diff --git a/sys/isofs/iso_rrip.h b/sys/isofs/iso_rrip.h index 3f8a0ccb2db7..525f752da1d0 100644 --- a/sys/isofs/iso_rrip.h +++ b/sys/isofs/iso_rrip.h @@ -29,13 +29,11 @@ * SUCH DAMAGE. * * from: @(#)iso_rrip.h - * $Id: iso_rrip.h,v 1.2 1993/08/07 09:32:14 mycroft Exp $ + * $Id: iso_rrip.h,v 1.3 1993/09/07 15:40:53 ws Exp $ */ -#define NOTYET 1 - /* - * Analyze function flag + * Analyze function flag (similar to RR field bits) */ #define ISO_SUSP_ATTR 0x0001 #define ISO_SUSP_DEVICE 0x0002 @@ -46,13 +44,33 @@ #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 +#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 { - 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 )*/ + 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)); diff --git a/sys/isofs/isofs_bmap.c b/sys/isofs/isofs_bmap.c index e3cef837b3b6..85dafe2b1ae8 100644 --- a/sys/isofs/isofs_bmap.c +++ b/sys/isofs/isofs_bmap.c @@ -1,5 +1,5 @@ /* - * $Id: isofs_bmap.c,v 1.3 1993/09/03 04:37:53 cgd Exp $ + * $Id: isofs_bmap.c,v 1.4 1993/09/07 15:40:53 ws Exp $ */ #include "param.h" @@ -17,7 +17,7 @@ struct iso_node *ip; int lblkno; daddr_t *result; { - *result = (ip->iso_extent + lblkno) - * (ip->i_mnt->im_bsize / DEV_BSIZE); + *result = (ip->i_number + lblkno) + * (ip->i_mnt->im_bsize / DEV_BSIZE); return (0); } diff --git a/sys/isofs/isofs_lookup.c b/sys/isofs/isofs_lookup.c index 58f317cb073d..606bfa5099e4 100644 --- a/sys/isofs/isofs_lookup.c +++ b/sys/isofs/isofs_lookup.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)ufs_lookup.c 7.33 (Berkeley) 5/19/91 - * $Id: isofs_lookup.c,v 1.6 1993/09/03 04:37:54 cgd Exp $ + * $Id: isofs_lookup.c,v 1.7 1993/09/07 15:40:54 ws Exp $ */ #include "param.h" @@ -49,13 +49,7 @@ #include "iso_rrip.h" #include "isofs_rrip.h" -#ifdef ISOFS_DEBUG -#define DPRINTF(a) printf a -#else -#define DPRINTF(a) -#endif - -struct nchstats nchstats; +struct nchstats iso_nchstats; /* * Convert a component of a pathname into a pointer to a locked inode. @@ -100,14 +94,9 @@ isofs_lookup(vdp, ndp, p) 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 */ + struct iso_directory_record *ep;/* the current directory entry */ int entryoffsetinblock; /* 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 saveoffset; /* offset of last directory entry in dir */ int numdirpasses; /* strategy for directory search */ int endsearch; /* offset to end directory search */ struct iso_node *pdp; /* saved dp during symlink work */ @@ -116,12 +105,13 @@ isofs_lookup(vdp, ndp, p) int lockparent; /* 1 => lockparent flag is set */ int wantparent; /* 1 => wantparent or lockparent flag */ int error; - + ino_t ino = 0; int reclen; - short namelen; - char altname[251]; - int i; - + u_short namelen; + char altname[NAME_MAX]; + int res; + int assoc, len; + ndp->ni_dvp = vdp; ndp->ni_vp = NULL; dp = VTOI(vdp); @@ -133,11 +123,9 @@ isofs_lookup(vdp, ndp, p) /* * Check accessiblity of directory. */ - if ((dp->iso_flags & 2) == 0) { - DPRINTF(("isofs_lookup: iso_flags = %x, ENOTDIR\n", dp->iso_flags)); - return (ENOTDIR); - } - + if (vdp->v_type != VDIR) + return ENOTDIR; + /* * We now have a segment name to search for, and a directory to search. * @@ -192,7 +180,13 @@ isofs_lookup(vdp, ndp, p) vdp = ITOV(dp); ndp->ni_vp = NULL; } - + + /* + * A traling `@' means, we are looking for an associated file + */ + len = ndp->ni_namelen; + if (assoc = ndp->ni_ptr[len - 1] == ASSOCCHAR) + len--; /* * If there is cached information on a previous search of * this directory, pick up where we last left off. @@ -211,12 +205,11 @@ isofs_lookup(vdp, ndp, p) 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); + if (error = iso_blkatoff(dp,ndp->ni_ufs.ufs_offset,&bp)) + return error; } numdirpasses = 2; - nchstats.ncs_2passes++; + iso_nchstats.ncs_2passes++; } endsearch = roundup(dp->i_size, imp->logical_block_size); @@ -230,9 +223,8 @@ searchloop: 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); + if (error = iso_blkatoff(dp,ndp->ni_ufs.ufs_offset,&bp)) + return error; entryoffsetinblock = 0; } /* @@ -243,7 +235,6 @@ searchloop: (bp->b_un.b_addr + entryoffsetinblock); reclen = isonum_711 (ep->length); - DPRINTF(("isofs_lookup: reclen = %d\n", reclen)); if (reclen == 0) { /* skip to next block, if any */ ndp->ni_ufs.ufs_offset = @@ -252,79 +243,82 @@ searchloop: continue; } - if (reclen < ISO_DIRECTORY_RECORD_SIZE) { - DPRINTF(("isofs_lookup: reclen too small (<%d)\n", - ISO_DIRECTORY_RECORD_SIZE)); + if (reclen < ISO_DIRECTORY_RECORD_SIZE) /* illegal entry, stop */ break; - } - if (entryoffsetinblock + reclen -1 >= imp->logical_block_size) { - DPRINTF(("isofs_lookup: cross-block entry\n")); + 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); - DPRINTF(("isofs_lookup: namelen = %d\n", namelen)); - if (reclen < ISO_DIRECTORY_RECORD_SIZE + namelen) { - DPRINTF(("isofs_lookup: reclen < %d + %d\n", - ISO_DIRECTORY_RECORD_SIZE, namelen)); + if (reclen < ISO_DIRECTORY_RECORD_SIZE + 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 ) { - default: - DPRINTF(("isofs_lookup: unsupported ftype = %x\n", - imp->iso_ftype)); - /* default to iso-mode, any extension should support - iso, not ? */ - /* FALLTHRU */ - - case ISO_FTYPE_9660: - DPRINTF(("isofs_lookup: ftype == ISO\n")); - 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); + switch (imp->iso_ftype) { + default: + if ((!(isonum_711(ep->flags)&4)) == !assoc) { + if ((len == 1 + && ndp->ni_ptr[0] == '.') + || 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. + */ + isofs_defino(ep,&ndp->ni_ufs.ufs_ino); goto found; } - break; - case ISO_FTYPE_RRIP: - DPRINTF(("isofs_lookup: ftype == RRIP\n")); - 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; + if (namelen != 1 + || ep->name[0] != 0) + goto notfound; + } else if (!(res = isofncmp(ndp->ni_ptr,len, + ep->name,namelen))) { + isofs_defino(ep,&ino); + saveoffset = ndp->ni_ufs.ufs_offset; + } else if (ino) + goto foundino; + else if (res < 0) + goto notfound; + else if (res > 0 && numdirpasses == 2) + numdirpasses++; } + break; + case ISO_FTYPE_RRIP: + isofs_rrip_getname(ep,altname,&namelen,&ndp->ni_ufs.ufs_ino,imp); + if (namelen == ndp->ni_namelen + && !bcmp(ndp->ni_ptr,altname,namelen)) + goto found; + break; } ndp->ni_ufs.ufs_offset += reclen; entryoffsetinblock += reclen; } -/* notfound: */ + 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. @@ -345,8 +339,8 @@ searchloop: return (ENOENT); found: - if (numdirpasses == 2) - nchstats.ncs_pass2++; + if (numdirpasses > 1) + iso_nchstats.ncs_pass2++; /* * Found component in pathname. @@ -355,7 +349,6 @@ found: */ 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 @@ -380,6 +373,7 @@ found: if (ndp->ni_isdotdot) { ISO_IUNLOCK(pdp); /* race to get the inode */ if (error = iso_iget(dp, ndp->ni_ufs.ufs_ino, &tdp, ep)) { + brelse(bp); ISO_ILOCK(pdp); return (error); } @@ -390,13 +384,17 @@ found: VREF(vdp); /* we want ourself, ie "." */ ndp->ni_vp = vdp; } else { - if (error = iso_iget(dp, ndp->ni_ufs.ufs_ino, &tdp, ep)) + if (error = iso_iget(dp, ndp->ni_ufs.ufs_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. */ @@ -412,10 +410,9 @@ found: * is non-zero, fill it in with a pointer to the * remaining space in the directory. */ -iso_blkatoff(ip, offset, res, bpp) +iso_blkatoff(ip, offset, bpp) struct iso_node *ip; off_t offset; - char **res; struct buf **bpp; { register struct iso_mnt *imp = ip->i_mnt; @@ -424,14 +421,12 @@ iso_blkatoff(ip, offset, res, bpp) struct buf *bp; int error; - *bpp = 0; if (error = bread(ITOV(ip), lbn, bsize, NOCRED, &bp)) { brelse(bp); - return (error); + *bpp = 0; + return error; } - if (res) - *res = bp->b_un.b_addr + iso_blkoff(imp, offset); *bpp = bp; - return (0); + return 0; } diff --git a/sys/isofs/isofs_node.c b/sys/isofs/isofs_node.c index 53b0275ce8e8..150b3957e5a9 100644 --- a/sys/isofs/isofs_node.c +++ b/sys/isofs/isofs_node.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)isofs_inode.c - * $Id: isofs_node.c,v 1.5 1993/08/01 19:25:52 mycroft Exp $ + * $Id: isofs_node.c,v 1.6 1993/09/07 15:40:55 ws Exp $ */ #include "param.h" @@ -43,11 +43,18 @@ #include "vnode.h" #include "kernel.h" #include "malloc.h" +#include "stat.h" #include "iso.h" #include "isofs_node.h" #include "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))&(INOHSZ-1)) @@ -60,15 +67,32 @@ union iso_ihead { 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))&(DNOHSZ-1)) +#else +#define DNOHASH(dev,ino) (((unsigned)((dev)+(ino)))%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. + * Initialize hash links for inodes and dnodes. */ 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)) @@ -78,8 +102,66 @@ isofs_init() 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. @@ -95,16 +177,18 @@ iso_iget(xp, ino, ipp, isodir) { dev_t dev = xp->i_dev; struct mount *mntp = ITOV(xp)->v_mount; - extern struct vnodeops isofs_vnodeops, spec_inodeops; + 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; - struct dinode *dp; + 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]; @@ -135,8 +219,9 @@ loop: 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->iso_parent_ino = xp->i_number; 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 @@ -148,58 +233,107 @@ loop: 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); + + isofs_defino(isodir,&defino); + if (defino != ino) { + /* + * This is a Rock Ridge relocated directory + * Read the `.' entry out of it. + */ + 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); + + 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); } @@ -210,7 +344,7 @@ FlameOff: iso_iput(ip) register struct iso_node *ip; { - + if ((ip->i_flag & ILOCKED) == 0) panic("iso_iput"); ISO_IUNLOCK(ip); @@ -227,28 +361,17 @@ isofs_inactive(vp, p) { 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; - - /* - * Whenever any inode is registered to HASH by the iso_iget, - * All inode purged here immediately ( v_usecount is 0 ) - * It's too much penalty for cdrom, so I just comment out it. - * (I've confirmed purging them when hash is getting full.) - * - * amurai@spec.co.jp July 22,'93 - */ -#ifdef notdef /* * If we are done with the inode, reclaim it * so that it can be reused immediately. */ - if (vp->v_usecount == 0 /* && ip->i_mode == 0 */) + if (vp->v_usecount == 0 && ip->inode.iso_mode == 0) vgone(vp); -#endif return (error); } @@ -260,7 +383,7 @@ isofs_reclaim(vp) { register struct iso_node *ip = VTOI(vp); int i; - + if (prtactive && vp->v_usecount != 0) vprint("isofs_reclaim: pushing active", vp); /* @@ -287,7 +410,7 @@ isofs_reclaim(vp) iso_ilock(ip) register struct iso_node *ip; { - + while (ip->i_flag & ILOCKED) { ip->i_flag |= IWANT; if (ip->i_spare0 == curproc->p_pid) @@ -316,3 +439,186 @@ iso_iunlock(ip) 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; + inop->inode.iso_links = 2; + } 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->im_bsize,&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->im_bsize,&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); +} diff --git a/sys/isofs/isofs_node.h b/sys/isofs/isofs_node.h index 47c2d5281451..803666dd14e9 100644 --- a/sys/isofs/isofs_node.h +++ b/sys/isofs/isofs_node.h @@ -1,19 +1,33 @@ /* - * $Id: isofs_node.h,v 1.6 1993/08/02 23:04:36 mycroft Exp $ + * $Id: isofs_node.h,v 1.7 1993/09/07 15:40:56 ws Exp $ */ 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 */ + 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 */ @@ -21,6 +35,7 @@ struct iso_node { 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 */ @@ -28,18 +43,19 @@ struct iso_node { long i_spare0; long i_spare1; - + long iso_extent; + long i_size; +#ifdef __notdef__ int iso_reclen; int iso_extlen; - int iso_extent; - int i_size; int iso_flags; - int iso_unit_size; + long iso_unit_size; int iso_interleave_gap; int iso_volume_seq; int iso_namelen; /* ISO9660/RRIP name len */ +#endif int iso_parent; /* byte offset in beginning of dir record */ - int iso_parent_ext; /* block number of dir record */ + long iso_parent_ino; /* ino number of dir */ ISO_RRIP_INODE inode; }; @@ -80,7 +96,7 @@ int isofs_mmap __P((struct vnode *vp, int fflags, struct ucred *cred, int isofs_seek __P((struct vnode *vp, off_t oldoff, off_t newoff, struct ucred *cred)); int isofs_readdir __P((struct vnode *vp, struct uio *uio, struct ucred *cred, - int *eofflagp)); + int *eofflagp, u_int *cookies, int ncookies)); int isofs_abortop __P((struct nameidata *ndp)); int isofs_inactive __P((struct vnode *vp, struct proc *p)); int isofs_reclaim __P((struct vnode *vp)); @@ -89,4 +105,11 @@ int isofs_unlock __P((struct vnode *vp)); 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 diff --git a/sys/isofs/isofs_rrip.c b/sys/isofs/isofs_rrip.c index 0e5e2aae0a88..8eae04989c73 100644 --- a/sys/isofs/isofs_rrip.c +++ b/sys/isofs/isofs_rrip.c @@ -28,7 +28,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: isofs_rrip.c,v 1.2 1993/09/03 04:37:55 cgd Exp $ + * $Id: isofs_rrip.c,v 1.3 1993/09/07 15:40:57 ws Exp $ */ #include "param.h" @@ -38,6 +38,8 @@ #include "vnode.h" #include "mount.h" #include "kernel.h" +#include "stat.h" +#include "types.h" #include "sys/time.h" @@ -46,499 +48,575 @@ #include "isofs_rrip.h" #include "iso_rrip.h" -#include "dirent.h" - -#ifdef ISOFS_DEBUG -#define DPRINTF(a) printf a -#else -#define DPRINTF(a) -#endif - /* * POSIX file attribute */ -static int isofs_rrip_attr( p, ana ) -ISO_RRIP_ATTR *p; -ISO_RRIP_ANALYZE *ana; +static int +isofs_rrip_attr(p,ana) + ISO_RRIP_ATTR *p; + ISO_RRIP_ANALYZE *ana; { - ana->inode.iso_mode = isonum_733(p->mode_l); - ana->inode.iso_uid = (uid_t)isonum_733(p->uid_l); - ana->inode.iso_gid = (gid_t)isonum_733(p->gid_l); -/* ana->inode.iso_links = isonum_733(p->links_l); */ - return; + 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; } -int isofs_rrip_defattr( isodir, ana ) -struct iso_directory_record *isodir; -ISO_RRIP_ANALYZE *ana; +static void +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; -} - -/* - * POSIX device modes - */ -static int isofs_rrip_device( p, ana ) -ISO_RRIP_DEVICE *p; -ISO_RRIP_ANALYZE *ana; -{ -#ifdef NOTYET - 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_733(p->dev_t_high_l), - isonum_733(p->dev_t_low_l) - ); -#endif - return; + /* 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; +static int +isofs_rrip_slink(p,ana) + ISO_RRIP_SLINK *p; + ISO_RRIP_ANALYZE *ana; { - return; + 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 + len; + 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; + return; + } + + 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; +static int +isofs_rrip_altname(p,ana) + ISO_RRIP_ALTNAME *p; + ISO_RRIP_ANALYZE *ana; { - return; + 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; + 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, + 0,isonum_711(isodir->flags)&4); + break; + case 0: + *ana->outlen = 1; + break; + case 1: + *ana->outlen = 2; + break; + } } /* - * Child Link + * Parent or Child Link */ -static int isofs_rrip_clink( p, ana ) -ISO_RRIP_CLINK *p; -ISO_RRIP_ANALYZE *ana; +static int +isofs_rrip_pclink(p,ana) + ISO_RRIP_CLINK *p; + ISO_RRIP_ANALYZE *ana; { -#ifdef NOTYET - 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) - ); -#endif - ana->inode.iso_cln = isonum_733(p->dir_loc); - return; + *ana->inump = isonum_733(p->dir_loc); + ana->fields &= ~(ISO_SUSP_CLINK|ISO_SUSP_PLINK); + return *p->h.type == 'C' ? ISO_SUSP_CLINK : ISO_SUSP_PLINK; } -/* - * Parent Link - */ -static int isofs_rrip_plink( p, ana ) -ISO_RRIP_PLINK *p; -ISO_RRIP_ANALYZE *ana; +void +isofs_defino(isodir,inump) + struct iso_directory_record *isodir; + ino_t *inump; { + *inump = isonum_733(isodir->extent) + isonum_711(isodir->ext_attr_length); +} -#ifdef NOTYET - 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) - ); -#endif - ana->inode.iso_pln = isonum_733(p->dir_loc); - return; +static void +isofs_rrip_defino(isodir,ana) + struct iso_directory_record *isodir; + ISO_RRIP_ANALYZE *ana; +{ + isofs_defino(isodir,ana->inump); } /* * Relocated directory */ -static int isofs_rrip_reldir( p, ana ) -ISO_RRIP_RELDIR *p; -ISO_RRIP_ANALYZE *ana; +static int +isofs_rrip_reldir(p,ana) + ISO_RRIP_RELDIR *p; + ISO_RRIP_ANALYZE *ana; { -#ifdef NOTYET - char buf[3]; + /* 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; +} - buf[0] = p->h.type[0]; - buf[1] = p->h.type[1]; - buf[2] = 0x00; +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; +} - printf("isofs:%s[%d]\n",buf, isonum_711(p->h.length) ); -#endif - return; +static void +isofs_rrip_deftstamp(isodir,ana) + struct iso_directory_record *isodir; + ISO_RRIP_ANALYZE *ana; +{ + isofs_deftstamp(isodir,ana->inop,NULL); } /* - * Time stamp + * POSIX device modes */ -static void isofs_rrip_tstamp_conv7(pi, pu) -char *pi; -struct timeval *pu; +static int +isofs_rrip_device(p,ana) + ISO_RRIP_DEVICE *p; + ISO_RRIP_ANALYZE *ana; { - 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 ); -} + unsigned high, low; -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; + 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 { - 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; + ana->inop->inode.iso_rdev = makedev( high, minor(low) ); } - return; + ana->fields &= ~ISO_SUSP_DEVICE; + return ISO_SUSP_DEVICE; } -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; -} - - /* * Flag indicating - * Nothing to do.... */ -static int isofs_rrip_idflag( p, ana ) -ISO_RRIP_IDFLAG *p; -ISO_RRIP_ANALYZE *ana; +static int +isofs_rrip_idflag(p,ana) + ISO_RRIP_IDFLAG *p; + ISO_RRIP_ANALYZE *ana; { -#ifdef NOTYET - char buf[3]; + 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; +} - buf[0] = p->h.type[0]; - buf[1] = p->h.type[1]; - buf[2] = 0x00; +/* + * 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; +} - printf("isofs:%s[%d] idflag=0x%x\n", - buf, - isonum_711(p->h.length), - p->flags ); -#endif - return; +/* + * System Use end + */ +static int +isofs_rrip_stop(p,ana) + ISO_SUSP_HEADER *p; + ISO_RRIP_ANALYZE *ana; +{ + /* stop analyzing */ + ana->fields = 0; + return ISO_SUSP_STOP; } /* * Extension reference - * Nothing to do.... */ -static int isofs_rrip_exflag( p, ana ) -ISO_RRIP_EXFLAG *p; -ISO_RRIP_ANALYZE *ana; +static int +isofs_rrip_extref(p,ana) + ISO_RRIP_EXTREF *p; + ISO_RRIP_ANALYZE *ana; { -#ifdef NOTYET - 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 ); -#endif - return; -} - -/* - * Unknown ... - * Nothing to do.... - */ -static int isofs_rrip_unknown( p, ana ) -ISO_RRIP_EXFLAG *p; -ISO_RRIP_ANALYZE *ana; -{ - return; + 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)(); - int (*func2)(); - int result; + char type[2]; + int (*func)(); + void (*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 }, - { 'A', 'A', 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; +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; - int found; - int i; - char *pwhead; - int result; - + struct buf *bp = NULL; + int i; + char *pwhead; + int result; + /* - * Note: If name length is odd, + * 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) ); - + 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; - 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 ) { - #ifdef NOTYET - 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 ) ); - #endif - break; - } - + while (1) { + ana->iso_ce_len = 0; /* - * move to next SUSP - */ - phead = (ISO_SUSP_HEADER *) ((unsigned)isonum_711(phead->length) + (char *)phead); + * 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; + } + /* + * 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->im_bsize + || bread(ana->imp->im_devvp, + ana->iso_ce_blk * ana->imp->im_bsize / DEV_BSIZE, + ana->imp->im_bsize,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; } - -setdefault: + if (bp) + brelse(bp); /* * If we don't find the Basic SUSP stuffs, just set default value - * ( attribute/time stamp ) + * ( 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 ); + for (ptable = table; ptable->func2; ptable++) + if (!(ptable->result&result)) + ptable->func2(isodir,ana); + + return result; +} + +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 from 'AL' record - * If either no AL recorde nor 0 lenght, + * If either no AL record or 0 length, * it will be return the translated ISO9660 name, */ -int isofs_rrip_getname( isodir, outbuf, outlen ) -struct iso_directory_record *isodir; -char *outbuf; -short *outlen; +static RRIP_TABLE rrip_table_getname[] = { + { "NM", isofs_rrip_altname, isofs_rrip_defname, ISO_SUSP_ALTNAME }, + { "CL", isofs_rrip_pclink, isofs_rrip_defino, 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_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 ) { - DPRINTF(("isofs_rrip_getname: found NM record\n")); - found = 1; - break; - } - phead = (ISO_SUSP_HEADER *) ((unsigned)isonum_711(phead->length) + (char *)phead); - } + 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++; } - if ( found == 1 ) { - p = (ISO_RRIP_ALTNAME *)phead; - *outlen = isonum_711( p->h.length ) - sizeof( ISO_RRIP_ALTNAME ); - DPRINTF(("isofs_rrip_getname: len = %d, rlen = %d, name = %*.*s\n", - isonum_711(p->h.length), *outlen, - *outlen, *outlen, &p->flags + 1)); - bcopy( (char *)( &p->flags + 1 ), outbuf, *outlen ); - outbuf[*outlen] = 0; - } else { - DPRINTF(("no rrip, name = %s (%08x%08x)\n", - isodir->name, *(long *)isodir->name, *(long *)(isodir->name+4))); - 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 ); + + return isofs_rrip_loop(isodir,&analyze,tab); } /* @@ -546,146 +624,67 @@ short *outlen; * * Note: isodir should contains SL record! */ -int isofs_rrip_getsymname( vp, isodir, outbuf, outlen ) -struct vnode *vp; -struct iso_directory_record *isodir; -char *outbuf; -short *outlen; +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; { - 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)); + ISO_RRIP_ANALYZE analyze; - /* - * 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 ? */ - } + 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; - /* 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 ); + return (isofs_rrip_loop(isodir,&analyze,rrip_table_getsymname)&ISO_SUSP_SLINK); } -#ifdef NOTYET -/* 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"); +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 require 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; } - printf("\n"); + + 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); } -#endif diff --git a/sys/isofs/isofs_rrip.h b/sys/isofs/isofs_rrip.h index e9283d31b14c..5ca34ba38d40 100644 --- a/sys/isofs/isofs_rrip.h +++ b/sys/isofs/isofs_rrip.h @@ -29,7 +29,7 @@ * SUCH DAMAGE. * * from: @(#)isofs_rrip.h - * $Id: isofs_rrip.h,v 1.2 1993/08/01 19:25:53 mycroft Exp $ + * $Id: isofs_rrip.h,v 1.3 1993/09/07 15:40:58 ws Exp $ */ typedef struct { @@ -68,8 +68,9 @@ typedef struct { typedef struct { u_char cflag [ISODCL ( 1, 1)]; u_char clen [ISODCL ( 2, 2)]; - u_char name [ISODCL ( 3, 3)]; + u_char name [0]; } ISO_RRIP_SLINK_COMPONENT; +#define ISO_RRIP_SLSIZ 2 typedef struct { ISO_SUSP_HEADER h; @@ -119,6 +120,21 @@ typedef struct { typedef struct { ISO_SUSP_HEADER h; - unsigned char flags [ISODCL ( 4, 4)]; -} ISO_RRIP_EXFLAG; + 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; diff --git a/sys/isofs/isofs_util.c b/sys/isofs/isofs_util.c index 44af8cbb8a81..738d18697424 100644 --- a/sys/isofs/isofs_util.c +++ b/sys/isofs/isofs_util.c @@ -1,7 +1,6 @@ /* - * $Id: isofs_util.c,v 1.4 1993/09/03 04:37:56 cgd Exp $ + * $Id: isofs_util.c,v 1.5 1993/09/07 15:40:59 ws Exp $ */ - #include "param.h" #include "systm.h" #include "namei.h" @@ -23,6 +22,7 @@ #include "dirent.h" #include "machine/endian.h" +#ifdef __notanymore__ int isonum_711 (p) unsigned char *p; @@ -112,52 +112,86 @@ unsigned char *p; return 0; #endif } +#endif /* __notanymore__ */ /* * translate and compare a filename + * Note: Version number plus ';' may be omitted. */ -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; +int +isofncmp(unsigned char *fn,int fnlen,unsigned char *isofn,int isolen) +{ + int i, j; + char c; + + while (--fnlen >= 0) { + if (--isolen < 0) + return *fn; + if ((c = *isofn++) == ';') { + switch (*fn++) { + default: + return *--fn; + case 0: + return 0; + case ';': + break; + } + for (i = 0; --fnlen >= 0; i = i * 10 + *fn++ - '0') { + if (*fn < '0' || *fn > '9') { + return -1; + } + } + for (j = 0; --isolen >= 0; j = j * 10 + *isofn++ - '0'); + return i - j; } - if (c == ';') - return ((fnidx == fnlen)); - if (c != *fn) - return (0); + if (c != *fn) { + if (c >= 'A' && c <= 'Z') { + if ((c += ('a' - 'A')) != *fn) + return *fn - c; + } else + return *fn - c; + } + fn++; } - return (1); + if (isolen > 0) { + switch (*isofn) { + default: + return -1; + case '.': + if (isofn[1] != ';') + return -1; + case ';': + return 0; + } + } + return 0; } /* * translate a filename */ void -isofntrans(char *infn, int infnlen, char *outfn, short *outfnlen) { +isofntrans(unsigned char *infn,int infnlen, + unsigned char *outfn,unsigned short *outfnlen, + int stripgen,int assoc) +{ 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 + else if (c == '.' && stripgen && *infn == ';') + break; + else if (c == ';' && stripgen) + break; + else *outfn++ = c; } - *outfnlen = infnlen; + if (assoc) { + *outfn = ASSOCCHAR; + fnidx++; + } + *outfnlen = fnidx; } diff --git a/sys/isofs/isofs_vfsops.c b/sys/isofs/isofs_vfsops.c index f9085d434843..55cea2b6148d 100644 --- a/sys/isofs/isofs_vfsops.c +++ b/sys/isofs/isofs_vfsops.c @@ -1,5 +1,5 @@ /* - * $Id: isofs_vfsops.c,v 1.6 1993/09/03 04:37:57 cgd Exp $ + * $Id: isofs_vfsops.c,v 1.7 1993/09/07 15:41:00 ws Exp $ */ #include "param.h" @@ -21,12 +21,6 @@ #include "iso.h" #include "isofs_node.h" -#ifdef ISOFS_DEBUG -#define DPRINTF(a) printf a -#else -#define DPRINTF(a) -#endif - extern int enodev (); struct vfsops isofs_vfsops = { @@ -43,12 +37,14 @@ struct vfsops isofs_vfsops = { }; /* - * Called by vfs_mountroot when ufs is going to be mounted as root. + * 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(); + isofs_mountroot() { register struct mount *mp; @@ -58,14 +54,16 @@ isofs_mountroot() 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 = &isofs_vfsops; + mp->mnt_op = (struct vfsops *)&isofs_vfsops; mp->mnt_flag = MNT_RDONLY; mp->mnt_exroot = 0; mp->mnt_mounth = NULLVP; - error = iso_mountfs(rootvp, mp, p); + args.flags = ISOFSMNT_ROOT; + error = iso_mountfs(rootvp, mp, p, &args); if (error) { free((caddr_t)mp, M_MOUNT); return (error); @@ -110,31 +108,17 @@ isofs_mount(mp, path, data, ndp, p) struct proc *p; { struct vnode *devvp; - struct ufs_args args; + struct iso_args args; u_int size; int error; struct iso_mnt *imp; - if (error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args))) + if (error = copyin(data, (caddr_t)&args, sizeof (struct iso_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. @@ -151,10 +135,8 @@ isofs_mount(mp, path, data, ndp, p) ndp->ni_nameiop = LOOKUP | FOLLOW; ndp->ni_segflg = UIO_USERSPACE; ndp->ni_dirp = args.fspec; - if (error = namei(ndp, p)) { - DPRINTF(("isofs: can't lookup mountpoint\n")); + if (error = namei(ndp, p)) return (error); - } devvp = ndp->ni_vp; if (devvp->v_type != VBLK) { vrele(devvp); @@ -165,15 +147,12 @@ isofs_mount(mp, path, data, ndp, p) return (ENXIO); } - if ((mp->mnt_flag & MNT_UPDATE) == 0) { - error = iso_mountfs(devvp, mp, p); - if (error) - DPRINTF(("isofs: iso_mountfs = %d\n", error)); - } else { - if (devvp != imp->im_devvp) { - DPRINTF(("isofs: devvp != imp->im_devvp")); + if ((mp->mnt_flag & MNT_UPDATE) == 0) + error = iso_mountfs(devvp, mp, p, &args); + else { + if (devvp != imp->im_devvp) error = EINVAL; /* needs translation */ - } else + else vrele(devvp); } if (error) { @@ -182,23 +161,12 @@ isofs_mount(mp, path, data, ndp, p) } imp = VFSTOISOFS(mp); - /* Check the Rock Ridge Extention support */ - if ( args.exflags & ISOFSMNT_NORRIP ) { - imp->iso_ftype = ISO_FTYPE_9660; - mp->mnt_flag |= ISOFSMNT_NORRIP; - } else { - imp->iso_ftype = ISO_FTYPE_RRIP; - mp->mnt_flag &= ~ISOFSMNT_NORRIP; - } - (void) copyinstr(path, imp->im_fsmnt, sizeof(imp->im_fsmnt)-1, &size); - DPRINTF(("isofs: imp->im_fsmnt = %s, size = %d\n", imp->im_fsmnt, 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); - DPRINTF(("isofs: mntfromname = %s, size = %d\n", mp->mnt_stat.f_mntfromname, size)); bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); (void) isofs_statfs(mp, &mp->mnt_stat, p); return (0); @@ -207,10 +175,11 @@ isofs_mount(mp, path, data, ndp, p) /* * Common code for mount and mountroot */ -iso_mountfs(devvp, mp, p) +static iso_mountfs(devvp, mp, p, argp) register struct vnode *devvp; struct mount *mp; struct proc *p; + struct iso_args *argp; { register struct iso_mnt *isomp = (struct iso_mnt *)0; struct buf *bp = NULL; @@ -238,17 +207,13 @@ iso_mountfs(devvp, mp, p) * (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)) { - DPRINTF(("iso_mountfs: iso_mountedon = %d\n", error)); + 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)) { - DPRINTF(("iso_mountfs: VOP_OPEN = %d\n", error)); + 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 @@ -264,15 +229,11 @@ iso_mountfs(devvp, mp, p) vdp = (struct iso_volume_descriptor *)bp->b_un.b_addr; if (bcmp (vdp->id, ISO_STANDARD_ID, sizeof vdp->id) != 0) { - DPRINTF(("isofs: vpd->id == %x != ISO_STANDARD_ID(%x)\n", - vdp->id, ISO_STANDARD_ID)); error = EINVAL; goto out; } if (isonum_711 (vdp->type) == ISO_VD_END) { - DPRINTF(("isofs: vpd->type == %x == ISO_VD_END(%x)\n", - isonum_711 (vdp->type), ISO_VD_END)); error = EINVAL; goto out; } @@ -283,8 +244,6 @@ iso_mountfs(devvp, mp, p) } if (isonum_711 (vdp->type) != ISO_VD_PRIMARY) { - DPRINTF(("isofs: vdp->type == %x != ISO_VD_PRIMARY(%x)\n", - isonum_711 (vdp->type), ISO_VD_PRIMARY)); error = EINVAL; goto out; } @@ -296,7 +255,6 @@ iso_mountfs(devvp, mp, p) if (logical_block_size < DEV_BSIZE || logical_block_size >= MAXBSIZE || (logical_block_size & (logical_block_size - 1)) != 0) { - DPRINTF(("isofs: logical_block_size = %d\n", logical_block_size)); error = EINVAL; goto out; } @@ -315,15 +273,11 @@ iso_mountfs(devvp, mp, p) isomp->im_bshift = 0; while ((1 << isomp->im_bshift) < isomp->im_bsize) isomp->im_bshift++; - - bp->b_flags |= B_INVAL; + + bp->b_flags |= B_AGE; 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; @@ -334,6 +288,43 @@ iso_mountfs(devvp, mp, p) devvp->v_specflags |= SI_MOUNTEDON; + /* Check the Rock Ridge Extention support */ + if (!(argp->flags & ISOFSMNT_NORRIP)) { + if (error = bread (isomp->im_devvp, + (isomp->root_extent + isonum_711(rootp->ext_attr_length)) + * isomp->im_bsize / DEV_BSIZE, + isomp->im_bsize,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) @@ -381,13 +372,16 @@ isofs_unmount(mp, mntflags, p) if (mntinvalbuf(mp)) return (EBUSY); isomp = VFSTOISOFS(mp); - + if (error = vflush(mp, NULLVP, flags)) return (error); - ronly = !isomp->im_ronly; +#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, ronly ? FREAD : FREAD|FWRITE, - NOCRED, p); + 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; @@ -395,28 +389,6 @@ isofs_unmount(mp, mntflags, p) return (error); } -/* - * Check to see if a filesystem is mounted on a block device. - */ -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); -} - /* * Return root of a filesystem */ @@ -429,15 +401,28 @@ isofs_root(mp, vpp) struct vnode tvp; int error; struct iso_mnt *imp = VFSTOISOFS (mp); - + struct iso_directory_record *dp; + struct iso_directory_record dir; + 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); + dp = (struct iso_directory_record *) imp->root; + isofs_defino(dp,&ip->i_number); + /* If we have a rockridge CD, we must use the `.' dir entry */ + if (imp->iso_ftype == ISO_FTYPE_RRIP) { + /* + * With RRIP we must use the `.' entry of the root directory. + * Simply fake it with a different directory record, + * so iget thinks, it's a relocated directory. + */ + dir = *dp; + dp = &dir; + bzero(dp->extent,sizeof(dp->extent)); + } + error = iso_iget(ip, ip->i_number, &nip, dp); if (error) return (error); *vpp = ITOV(nip); @@ -471,6 +456,8 @@ isofs_statfs(mp, sbp, p) bcopy((caddr_t)mp->mnt_stat.f_mntfromname, (caddr_t)&sbp->f_mntfromname[0], MNAMELEN); } + /* Use the first spare for flags: */ + sbp->f_spare[0] = isomp->im_flags; return (0); } @@ -495,7 +482,7 @@ isofs_sync(mp, waitfor) struct ifid { ushort ifid_len; ushort ifid_pad; - int ifid_lbn; + int ifid_parino; int ifid_offset; int ifid_ino; }; @@ -515,7 +502,10 @@ isofs_fhtovp(mp, fhp, vpp) struct iso_directory_record *dirp; struct iso_node *ip, *nip; struct proc *p; - + ino_t ino; + char altname[NAME_MAX]; + u_short namelen; + ifhp = (struct ifid *)fhp; imp = VFSTOISOFS (mp); @@ -524,33 +514,50 @@ isofs_fhtovp(mp, fhp, vpp) ifhp->ifid_lbn, ifhp->ifid_offset, ifhp->ifid_ino); #endif - lbn = ifhp->ifid_lbn; + lbn = ifhp->ifid_parino; off = ifhp->ifid_offset; - ifhp->ifid_lbn += (ifhp->ifid_offset >> 11); - ifhp->ifid_offset &= 0x7ff; + lbn += ifhp->ifid_offset / imp->im_bsize; + off &= (imp->im_bsize - 1); - if (ifhp->ifid_lbn >= imp->volume_space_size) + if (lbn >= imp->volume_space_size) { + printf("fhtovp: lbn exceed volume space %d\n", + lbn ); return (EINVAL); + } - if (ifhp->ifid_offset + ISO_DIRECTORY_RECORD_SIZE >= imp->im_bsize) + if (off + ISO_DIRECTORY_RECORD_SIZE > imp->im_bsize) { + printf("fhtovp: across the block boundary %d\n", + off + ISO_DIRECTORY_RECORD_SIZE ); return (EINVAL); + } if (error = bread (imp->im_devvp, - (ifhp->ifid_lbn * imp->im_bsize / DEV_BSIZE), imp->im_bsize, - NOCRED, &bp)) { + (lbn * imp->im_bsize / DEV_BSIZE), imp->im_bsize, NOCRED, &bp)) { printf("fhtovp: bread error %d\n", error); + brelse(bp); return(EINVAL); } - dirp = (struct iso_directory_record *) - (bp->b_un.b_addr + ifhp->ifid_offset); + dirp = (struct iso_directory_record *)(bp->b_un.b_addr + off); - if (ifhp->ifid_offset + isonum_711 (dirp->length) >= imp->im_bsize) { + if (off + isonum_711 (dirp->length) > imp->im_bsize) { 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) != ifhp->ifid_ino) { + /* Isn't this a bit much for checking stale handles? */ + switch (imp->iso_ftype) { + default: /* ISO_FTYPE_9660 || ISO_FTYPE_DEFAULT */ + isofs_defino(dirp,&ino); + break; + case ISO_FTYPE_RRIP: + isofs_rrip_getname(dirp,altname,&namelen,&ino,imp); + break; + } + if (ino != ifhp->ifid_ino) { brelse(bp); + printf("fhtovp: ino miss %d vs %d\n", ino, ifhp->ifid_ino ); return(EINVAL); } @@ -558,11 +565,12 @@ isofs_fhtovp(mp, fhp, vpp) ip = VTOI(&tvp); ip->i_vnode = &tvp; ip->i_dev = imp->im_dev; - ip->i_diroff = off; - ip->iso_extent = lbn; + ip->i_diroff = ifhp->ifid_offset; + ip->i_number = ifhp->ifid_parino; if (error = iso_iget(ip, ifhp->ifid_ino, &nip, dirp)) { *vpp = NULLVP; brelse (bp); + printf("fhtovp: failed to get ino\n"); return (error); } ip = nip; @@ -586,18 +594,13 @@ isofs_vptofh(vp, fhp) ifhp = (struct ifid *)fhp; ifhp->ifid_len = sizeof(struct ifid); - ifhp->ifid_lbn = ip->iso_parent_ext; + ifhp->ifid_parino = ip->iso_parent_ino; 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); + ifhp->ifid_parino, ifhp->ifid_offset, ifhp->ifid_ino); #endif return (0); } diff --git a/sys/isofs/isofs_vnops.c b/sys/isofs/isofs_vnops.c index cb612c6f0664..dfa1babe0c6d 100644 --- a/sys/isofs/isofs_vnops.c +++ b/sys/isofs/isofs_vnops.c @@ -1,5 +1,5 @@ /* - * $Id: isofs_vnops.c,v 1.7 1993/09/03 04:37:58 cgd Exp $ + * $Id: isofs_vnops.c,v 1.8 1993/09/07 15:41:01 ws Exp $ */ #include "param.h" #include "systm.h" @@ -22,11 +22,60 @@ #include "isofs_node.h" #include "iso_rrip.h" -#ifdef ISOFS_DEBUG -#define DPRINTF(a) printf a +/* + * Mknod vnode call + * Actually remap the device number + */ +/* ARGSUSED */ +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 -#define DPRINTF(a) + 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. @@ -82,29 +131,26 @@ isofs_getattr(vp, vap, cred, p) 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_fsid = ip->i_dev; + vap->va_fileid = ip->i_number; - 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_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_rdev = 0; - vap->va_size = ip->i_size; + vap->va_size = ip->i_size; vap->va_size_rsv = 0; - vap->va_flags = 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 = ip->i_size; vap->va_bytes_rsv = 0; - vap->va_type = vp->v_type; + vap->va_type = vp->v_type; return (0); } @@ -124,14 +170,7 @@ isofs_read(vp, uio, ioflag, cred) 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) @@ -179,6 +218,7 @@ isofs_ioctl(vp, com, data, fflag, cred, p) struct ucred *cred; struct proc *p; { + printf("You did ioctl for isofs !!\n"); return (ENOTTY); } @@ -227,17 +267,111 @@ isofs_seek(vp, oldoff, newoff, cred) return (0); } +/* + * 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; + u_int *cookiep; + int ncookies; + int eof; +}; + +static int +iso_uiodir(idp,dp) + struct isoreaddir *idp; + struct dirent *dp; +{ + 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 (idp->cookiep) { + if (idp->ncookies <= 0) { + idp->eof = 0; + return -1; + } + + *idp->cookiep++ = idp->curroff; + --idp->ncookies; + } + + if (error = uiomove(dp,dp->d_reclen,idp->uio)) + return error; + idp->uio_off = idp->curroff; + return 0; +} + +static int +iso_shipdir(idp) + struct isoreaddir *idp; +{ + struct dirent *dp; + int cl, sl, assoc; + int error; + + cl = idp->current.d_namlen; + if (assoc = cl > 1 && idp->current.d_name[cl - 1] == ASSOCCHAR) + cl--; + + dp = &idp->saveent; + if (!(sl = dp->d_namlen)) { + dp = &idp->assocent; + sl = dp->d_namlen - 1; + } + if (dp->d_namlen) { + if (sl != cl + || bcmp(dp->d_name,idp->current.d_name,sl)) { + if (idp->assocent.d_namlen) { + if (error = iso_uiodir(idp,&idp->assocent,idp->assocoff)) + return error; + idp->uio_off = idp->assocoff; + idp->assocent.d_namlen = 0; + } + if (idp->saveent.d_namlen) { + if (error = iso_uiodir(idp,&idp->saveent,idp->saveoff)) + return error; + idp->uio_off = idp->saveoff; + 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 */ -isofs_readdir(vp, uio, cred, eofflagp) +isofs_readdir(vp, uio, cred, eofflagp, cookies, ncookies) struct vnode *vp; register struct uio *uio; struct ucred *cred; int *eofflagp; + u_int *cookies; + int ncookies; { - struct dirent dirent; - int iso_offset; + struct isoreaddir *idp; int entryoffsetinblock; int error = 0; int endsearch; @@ -246,150 +380,143 @@ isofs_readdir(vp, uio, cred, eofflagp) 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); - DPRINTF(("isofs_readdir: iso_offset = %d, entryoff..=%d\n", - iso_offset, entryoffsetinblock)); + + MALLOC(idp,struct isoreaddir *,sizeof(*idp),M_TEMP,M_WAITOK); + idp->saveent.d_namlen = 0; + idp->assocent.d_namlen = 0; + idp->uio = uio; + idp->cookiep = cookies; + idp->ncookies = ncookies; + idp->curroff = uio->uio_offset; + idp->eof = 1; + + entryoffsetinblock = iso_blkoff(imp, idp->curroff); if (entryoffsetinblock != 0) { - if (error = iso_blkatoff(ip, iso_offset, (char **)0, &bp)) + if (error = iso_blkatoff(ip, idp->curroff, &bp)) { + FREE(idp,M_TEMP); return (error); + } } - + endsearch = ip->i_size; - DPRINTF(("isofs_readdir: endsearch = %d\n", endsearch)); - - while (iso_offset < endsearch && uio->uio_resid > 0) { - DPRINTF(("isooff=%d, entryoff=%d\n", iso_offset, entryoffsetinblock)); + + 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, iso_offset) == 0) { + + if (iso_blkoff(imp, idp->curroff) == 0) { if (bp != NULL) brelse(bp); - if (error = iso_blkatoff(ip, iso_offset, - (char **)0, &bp)) - return (error); + if (error = iso_blkatoff(ip, idp->curroff, &bp)) + break; entryoffsetinblock = 0; - DPRINTF(("new block at iso_offset = %d\n", iso_offset)); } /* * Get pointer to next entry. */ - + ep = (struct iso_directory_record *) (bp->b_un.b_addr + entryoffsetinblock); - + reclen = isonum_711 (ep->length); - DPRINTF(("isofs_readdir: reclen = %d\n", reclen)); if (reclen == 0) { /* skip to next block, if any */ - iso_offset = roundup (iso_offset, - imp->logical_block_size); - DPRINTF(("isofs: skip to next block, if any\n")); + idp->curroff = roundup (idp->curroff, + imp->logical_block_size); continue; } - + if (reclen < ISO_DIRECTORY_RECORD_SIZE) { - DPRINTF(("isofs_readdir: reclen too small!\n")); error = EINVAL; /* illegal entry, stop */ break; } - + if (entryoffsetinblock + reclen -1 >= imp->logical_block_size) { - DPRINTF(("isofs_readdir: entryoffsetinblock + reclen - 1 > lbs\n")); error = EINVAL; /* illegal directory, so stop looking */ break; } + + idp->current.d_namlen = isonum_711 (ep->name_len); - dirent.d_fileno = isonum_733 (ep->extent); - dirent.d_namlen = isonum_711 (ep->name_len); - if (reclen < ISO_DIRECTORY_RECORD_SIZE + dirent.d_namlen) { - error = EINVAL; + if (reclen < ISO_DIRECTORY_RECORD_SIZE + idp->current.d_namlen) { + error = EINVAL; /* illegal entry, stop */ break; - } - + } + + idp->curroff += reclen; /* * */ - switch (ep->name[0]) { + 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); + break; + default: /* ISO_FTYPE_DEFAULT || ISO_FTYPE_9660 */ + idp->current.d_fileno = isonum_733(ep->extent); + strcpy(idp->current.d_name,".."); + switch (ep->name[0]) { case 0: - dirent.d_name[0] = '.'; - dirent.d_namlen = 1; + idp->current.d_namlen = 1; + error = iso_uiodir(idp,&idp->current); break; case 1: - dirent.d_name[0] = '.'; - dirent.d_name[1] = '.'; - dirent.d_namlen = 2; + idp->current.d_namlen = 2; + error = iso_uiodir(idp,&idp->current); break; default: - switch ( imp->iso_ftype ) { - default: - DPRINTF(("isofs_readdir: unknown ftype %x\n", - imp->iso_ftype)); - /* default to iso */ - /* FALLTHRU */ - - case ISO_FTYPE_9660: - DPRINTF(("isofs_readdir: 9660\n")); - isofntrans(ep->name, dirent.d_namlen, dirent.d_name, &dirent.d_namlen); - break; - - case ISO_FTYPE_RRIP: - DPRINTF(("isofs_readdir: RRIP\n")); - isofs_rrip_getname( ep, dirent.d_name, &dirent.d_namlen ); - break; - } + isofntrans(ep->name,idp->current.d_namlen, + idp->current.d_name,&idp->current.d_namlen, + imp->iso_ftype == ISO_FTYPE_DEFAULT, + isonum_711(ep->flags)&4); + if (imp->iso_ftype == ISO_FTYPE_DEFAULT) + error = iso_shipdir(idp); + else + error = iso_uiodir(idp,&idp->current); break; + } } - - dirent.d_name[dirent.d_namlen] = 0; - dirent.d_reclen = DIRSIZ (&dirent); - - DPRINTF(("d_fileno = %d, d_namlen = %d, name = %s (0x%08x%08x)\n", - dirent.d_fileno, dirent.d_namlen, dirent.d_name, - *(unsigned long*)dirent.d_name, - *(unsigned long*)(dirent.d_name+4))); - - if (uio->uio_resid < dirent.d_reclen) + if (error) break; - - if (error = uiomove (&dirent, dirent.d_reclen, uio)) - break; - - iso_offset += reclen; + entryoffsetinblock += reclen; } - - DPRINTF(("isofs_readdir: out of directory scan loop\n")); + + 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); - if (end_flag || (VTOI(vp)->i_size - iso_offset) <= 0) - *eofflagp = 1; - else - *eofflagp = 0; - - uio->uio_offset = iso_offset; - + 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; @@ -399,78 +526,96 @@ 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]; + 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->iso_parent_ino + (ip->iso_parent / imp->im_bsize ) ) + * imp->im_bsize / DEV_BSIZE ), + imp->im_bsize, + NOCRED, + &bp ); + if ( error ) { + brelse(bp); + return( EINVAL ); + } - 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 + */ - /* - * Setup the directory pointer for this inode - */ - - dirp = (ISODIR *)(bp->b_un.b_addr + ( ip->iso_parent & 0x7ff ) ); + dirp = (ISODIR *)(bp->b_un.b_addr + ( ip->iso_parent & (imp->im_bsize - 1) ) ); #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 ); + 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_ino + (ip->iso_parent / imp->im_bsize) ) * imp->im_bsize / DEV_BSIZE ), + ip->iso_parent_ino, + (ip->iso_parent / imp->im_bsize ), + imp->im_bsize, + DEV_BSIZE, + dirp, + bp->b_un.b_addr, + ip->iso_parent, + ip->iso_parent & (imp->im_bsize - 1) ); #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 ) ); + + /* + * Just make sure, we have a right one.... + * 1: Check not cross boundary on block + * 2: Check number of inode + */ + if ( (ip->iso_parent & (imp->im_bsize - 1) ) + isonum_711( dirp->length ) >= + imp->im_bsize ) { + brelse ( bp ); + return( EINVAL ); + } + isofs_defino(dirp,&ino); + if ( ino != ip->i_number ) { + 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; } /* @@ -605,3 +750,77 @@ struct vnodeops isofs_vnodeops = { 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 */ diff --git a/sys/kern/dead_vnops.c b/sys/kern/dead_vnops.c index 41000b964d92..b955d179af08 100644 --- a/sys/kern/dead_vnops.c +++ b/sys/kern/dead_vnops.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)dead_vnops.c 7.13 (Berkeley) 4/15/91 - * $Id: dead_vnops.c,v 1.4 1993/08/01 19:25:58 mycroft Exp $ + * $Id: dead_vnops.c,v 1.5 1993/09/07 15:41:08 ws Exp $ */ #include "param.h" @@ -151,7 +151,9 @@ int dead_select __P(( struct vnode *vp, \ struct uio *uio, \ struct ucred *cred, \ - int *eofflagp))) dead_ebadf) + int *eofflagp, \ + u_int *cookies, \ + int ncookies))) dead_ebadf) #define dead_readlink ((int (*) __P(( \ struct vnode *vp, \ struct uio *uio, \ diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c index 803d1fe13518..b91da7e5d697 100644 --- a/sys/kern/vfs_cache.c +++ b/sys/kern/vfs_cache.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)vfs_cache.c 7.8 (Berkeley) 2/28/91 - * $Id: vfs_cache.c,v 1.2 1993/05/20 02:55:33 cgd Exp $ + * $Id: vfs_cache.c,v 1.3 1993/09/07 15:41:10 ws Exp $ */ #include "param.h" @@ -87,10 +87,11 @@ int doingcache = 1; /* 1 => enable the cache */ * Lookup is called with ni_dvp pointing to the directory to search, * ni_ptr pointing to the name of the entry being sought, ni_namelen * tells the length of the name, and ni_hash contains a hash of - * the name. If the lookup succeeds, the vnode is returned in ni_vp - * and a status of -1 is returned. If the lookup determines that - * the name does not exist (negative cacheing), a status of ENOENT - * is returned. If the lookup fails, a status of zero is returned. + * the name and directory vnode. If the lookup succeeds, the vnode is + * returned in ni_vp and a status of -1 is returned. If the lookup + * determines that the name does not exist (negative cacheing), + * a status of ENOENT is returned. + * If the lookup fails, a status of zero is returned. */ cache_lookup(ndp) register struct nameidata *ndp; diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index 6d9f5eab7a63..0130e1a55e5f 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -1 +1 @@ -revision 1.4 intentionally removed +revision 1.5 intentionally removed diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index a6e3f2871612..37ba0a781f5b 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -1 +1 @@ -revision 1.7 intentionally removed +revision 1.8 intentionally removed diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 6d9f5eab7a63..0130e1a55e5f 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -1 +1 @@ -revision 1.4 intentionally removed +revision 1.5 intentionally removed diff --git a/sys/miscfs/deadfs/dead_vnops.c b/sys/miscfs/deadfs/dead_vnops.c index 41000b964d92..b955d179af08 100644 --- a/sys/miscfs/deadfs/dead_vnops.c +++ b/sys/miscfs/deadfs/dead_vnops.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)dead_vnops.c 7.13 (Berkeley) 4/15/91 - * $Id: dead_vnops.c,v 1.4 1993/08/01 19:25:58 mycroft Exp $ + * $Id: dead_vnops.c,v 1.5 1993/09/07 15:41:08 ws Exp $ */ #include "param.h" @@ -151,7 +151,9 @@ int dead_select __P(( struct vnode *vp, \ struct uio *uio, \ struct ucred *cred, \ - int *eofflagp))) dead_ebadf) + int *eofflagp, \ + u_int *cookies, \ + int ncookies))) dead_ebadf) #define dead_readlink ((int (*) __P(( \ struct vnode *vp, \ struct uio *uio, \ diff --git a/sys/miscfs/fdesc/fdesc_vnops.c b/sys/miscfs/fdesc/fdesc_vnops.c index 116b705f9a75..b64dd0e96f97 100644 --- a/sys/miscfs/fdesc/fdesc_vnops.c +++ b/sys/miscfs/fdesc/fdesc_vnops.c @@ -33,7 +33,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: fdesc_vnops.c,v 1.5 1993/08/02 23:01:49 mycroft Exp $ + * $Id: fdesc_vnops.c,v 1.6 1993/09/07 15:41:18 ws Exp $ */ /* @@ -302,11 +302,13 @@ fdesc_setattr(vp, vap, cred, p) return (error); } -fdesc_readdir(vp, uio, cred, eofflagp) +fdesc_readdir(vp, uio, cred, eofflagp, cookies, ncookies) struct vnode *vp; struct uio *uio; struct ucred *cred; int *eofflagp; + u_int *cookies; + int ncookies; { struct filedesc *fdp; int ind, i; @@ -317,7 +319,7 @@ fdesc_readdir(vp, uio, cred, eofflagp) fdp = uio->uio_procp->p_fd; ind = uio->uio_offset / UIO_MX; error = 0; - while (uio->uio_resid > 0) { + while (uio->uio_resid > 0 && (!cookies || ncookies > 0)) { struct direct d; struct direct *dp = &d; @@ -343,6 +345,10 @@ fdesc_readdir(vp, uio, cred, eofflagp) break; ind++; + if (cookies) { + *cookies++ = ind * UIO_MX; + ncookies--; + } continue; } i = ind - 2; @@ -400,6 +406,10 @@ fdesc_readdir(vp, uio, cred, eofflagp) error = uiomove((caddr_t) dp, UIO_MX, uio); if (error) break; + if (cookies) { + *cookies++ = (ind + 1) * UIO_MX; + ncookies--; + } } ind++; } diff --git a/sys/miscfs/fifofs/fifo.h b/sys/miscfs/fifofs/fifo.h index c0ec71f7b65b..c8b7450bcd64 100644 --- a/sys/miscfs/fifofs/fifo.h +++ b/sys/miscfs/fifofs/fifo.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)fifo.h 7.1 (Berkeley) 4/15/91 - * $Id: fifo.h,v 1.4 1993/06/27 05:59:02 andrew Exp $ + * $Id: fifo.h,v 1.5 1993/09/07 15:41:53 ws Exp $ */ #ifndef _SYS_FIFO_H_ @@ -148,7 +148,9 @@ int fifo_select __P(( struct vnode *vp, \ struct uio *uio, \ struct ucred *cred, \ - int *eofflagp))) fifo_badop) + int *eofflagp, \ + u_int *cookies, \ + int ncookies))) fifo_badop) #define fifo_readlink ((int (*) __P(( \ struct vnode *vp, \ struct uio *uio, \ diff --git a/sys/miscfs/kernfs/kernfs_vnops.c b/sys/miscfs/kernfs/kernfs_vnops.c index bf634d353280..b441dd96370f 100644 --- a/sys/miscfs/kernfs/kernfs_vnops.c +++ b/sys/miscfs/kernfs/kernfs_vnops.c @@ -33,7 +33,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: kernfs_vnops.c,v 1.11 1993/08/02 23:00:57 mycroft Exp $ + * $Id: kernfs_vnops.c,v 1.12 1993/09/07 15:41:21 ws Exp $ */ /* @@ -556,11 +556,13 @@ kernfs_write(vp, uio, ioflag, cred) return (kernfs_xwrite(kt, strbuf, xlen)); } -kernfs_readdir(vp, uio, cred, eofflagp) +kernfs_readdir(vp, uio, cred, eofflagp, cookies, ncookies) struct vnode *vp; struct uio *uio; struct ucred *cred; int *eofflagp; + u_int *cookies; + int ncookies; { struct filedesc *fdp; int i; @@ -568,7 +570,7 @@ kernfs_readdir(vp, uio, cred, eofflagp) i = uio->uio_offset / UIO_MX; error = 0; - while (uio->uio_resid > 0) { + while (uio->uio_resid > 0 && (!cookies || ncookies > 0)) { #ifdef KERNFS_DIAGNOSTIC printf("kernfs_readdir: i = %d\n", i); #endif @@ -601,6 +603,10 @@ kernfs_readdir(vp, uio, cred, eofflagp) error = uiomove((caddr_t) dp, UIO_MX, uio); if (error) break; + if (cookies) { + *cookies = (i + 1) * UIO_MX; + ncookies--; + } } i++; } diff --git a/sys/miscfs/procfs/pfsnode.h b/sys/miscfs/procfs/pfsnode.h index abbf600c1eae..92238aba49d8 100644 --- a/sys/miscfs/procfs/pfsnode.h +++ b/sys/miscfs/procfs/pfsnode.h @@ -27,7 +27,7 @@ * (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: pfsnode.h,v 1.5 1993/08/26 19:01:00 pk Exp $ + * $Id: pfsnode.h,v 1.6 1993/09/07 15:41:24 ws Exp $ */ /* @@ -181,7 +181,9 @@ int pfs_readdir __P(( struct vnode *vp, struct uio *uio, struct ucred *cred, - int *eofflagp)); + int *eofflagp, + u_int *cookies, + int ncookies)); #define pfs_readlink ((int (*) __P(( \ struct vnode *vp, \ struct uio *uio, \ diff --git a/sys/miscfs/procfs/procfs_vnops.c b/sys/miscfs/procfs/procfs_vnops.c index 0aef6c741ffb..85d45179d2e9 100644 --- a/sys/miscfs/procfs/procfs_vnops.c +++ b/sys/miscfs/procfs/procfs_vnops.c @@ -27,7 +27,7 @@ * (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: procfs_vnops.c,v 1.5 1993/08/26 19:01:02 pk Exp $ + * $Id: procfs_vnops.c,v 1.6 1993/09/07 15:41:27 ws Exp $ */ /* @@ -621,11 +621,13 @@ pfs_lookup(vp, ndp, p) } int -pfs_readdir(vp, uio, cred, eofflagp) +pfs_readdir(vp, uio, cred, eofflagp, cookies, ncookies) struct vnode *vp; register struct uio *uio; struct ucred *cred; int *eofflagp; + u_int *cookies; + int ncookies; { int error = 0; int count, lost, pcnt, skipcnt, doingzomb = 0; @@ -660,7 +662,11 @@ pfs_readdir(vp, uio, cred, eofflagp) error = uiomove((char *)&dent, sizeof(struct pfsdent) , uio); if (error) return error; - + if (cookies) { + *cookies++ = sizeof(struct pfsdent); + ncookies--; + } + dent.d_fileno = 2; dent.d_namlen = 2; dent.d_nam[1] = '.'; @@ -668,12 +674,16 @@ pfs_readdir(vp, uio, cred, eofflagp) error = uiomove((char *)&dent, sizeof(struct pfsdent) , uio); if (error) return error; + if (cookies) { + *cookies++ = 2 * sizeof(struct pfsdent); + ncookies--; + } #endif count += 2*dent.d_reclen; } p = allproc; - for (pcnt = 0; p && uio->uio_resid; pcnt++) { + for (pcnt = 0; p && uio->uio_resid && (!cookies || ncookies > 0); pcnt++) { if (pcnt < skipcnt) { p = p->p_nxt; if (p == NULL && doingzomb == 0) { @@ -703,6 +713,10 @@ pfs_readdir(vp, uio, cred, eofflagp) error = uiomove((char *)&dent, dent.d_reclen, uio); if (error) break; + if (cookies) { + *cookies++ = count; + ncookies--; + } } if (count == 0) *eofflagp = 1; diff --git a/sys/miscfs/specfs/specdev.h b/sys/miscfs/specfs/specdev.h index 077024d53160..baa12a0292f9 100644 --- a/sys/miscfs/specfs/specdev.h +++ b/sys/miscfs/specfs/specdev.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)specdev.h 7.4 (Berkeley) 4/19/91 - * $Id: specdev.h,v 1.4 1993/06/27 05:59:07 andrew Exp $ + * $Id: specdev.h,v 1.5 1993/09/07 15:41:56 ws Exp $ */ #ifndef _SYS_SPECDEV_H_ @@ -189,7 +189,9 @@ int spec_select __P(( struct vnode *vp, \ struct uio *uio, \ struct ucred *cred, \ - int *eofflagp))) spec_badop) + int *eofflagp, \ + u_int *cookies, \ + int ncookies))) spec_badop) #define spec_readlink ((int (*) __P(( \ struct vnode *vp, \ struct uio *uio, \ diff --git a/sys/msdosfs/denode.h b/sys/msdosfs/denode.h index a3cfbdf6b027..5994ece4b863 100644 --- a/sys/msdosfs/denode.h +++ b/sys/msdosfs/denode.h @@ -13,7 +13,7 @@ * * October 1992 * - * $Id: denode.h,v 1.1 1993/08/13 11:35:31 cgd Exp $ + * $Id: denode.h,v 1.2 1993/09/07 15:41:31 ws Exp $ */ /* @@ -193,11 +193,7 @@ int msdosfs_rename __P((struct nameidata * fndp, struct nameidata * tdnp, struct int msdosfs_mkdir __P((struct nameidata * ndp, struct vattr * vap, struct proc * p)); int msdosfs_rmdir __P((struct nameidata * ndp, struct proc * p)); int msdosfs_symlink __P((struct nameidata * ndp, struct vattr * vap, char *target, struct proc * p)); -#ifdef __bsdi__ int msdosfs_readdir __P((struct vnode * vp, struct uio * uio, struct ucred * cred, int *eofflagp, u_int * cookies, int ncookies)); -#else -int msdosfs_readdir __P((struct vnode * vp, struct uio * uio, struct ucred * cred, int *eofflagp)); -#endif int msdosfs_readlink __P((struct vnode * vp, struct uio * uio, struct ucred * cred)); int msdosfs_abortop __P((struct nameidata * ndp)); int msdosfs_inactive __P((struct vnode * vp, struct proc * p)); diff --git a/sys/msdosfs/msdosfs_vfsops.c b/sys/msdosfs/msdosfs_vfsops.c index 89f350fc1ba8..86f6d6b2266a 100644 --- a/sys/msdosfs/msdosfs_vfsops.c +++ b/sys/msdosfs/msdosfs_vfsops.c @@ -13,7 +13,7 @@ * * October 1992 * - * $Id: msdosfs_vfsops.c,v 1.1 1993/08/13 11:35:38 cgd Exp $ + * $Id: msdosfs_vfsops.c,v 1.2 1993/09/07 15:41:33 ws Exp $ */ #include "param.h" @@ -62,23 +62,6 @@ msdosfs_mount(mp, path, data, ndp, p) if (error = copyin(data, (caddr_t) & args, sizeof(struct msdosfs_args))) return error; - /* - * Check to see if they want it to be an exportable filesystem via - * nfs. And, if they do, should it be read only, and what uid is - * root to be mapped to. - */ - 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 they just want to update then be sure we can do what is * asked. Can't change a filesystem from read/write to read only. diff --git a/sys/msdosfs/msdosfs_vnops.c b/sys/msdosfs/msdosfs_vnops.c index 95e662d01ba7..75885b608093 100644 --- a/sys/msdosfs/msdosfs_vnops.c +++ b/sys/msdosfs/msdosfs_vnops.c @@ -13,7 +13,7 @@ * * October 1992 * - * $Id: msdosfs_vnops.c,v 1.1 1993/08/13 11:35:40 cgd Exp $ + * msdosfs_vnops.c,v 1.1 1993/08/13 11:35:40 cgd Exp */ #include "param.h" @@ -1264,19 +1264,13 @@ struct dos_dirent { }; int -#ifdef __bsdi__ msdosfs_readdir(vp, uio, cred, eofflagp, cookies, ncookies) -#else -msdosfs_readdir(vp, uio, cred, eofflagp) -#endif struct vnode *vp; struct uio *uio; struct ucred *cred; int *eofflagp; -#ifdef __bsdi__ u_int *cookies; int ncookies; -#endif { int error = 0; int diff; @@ -1298,19 +1292,15 @@ msdosfs_readdir(vp, uio, cred, eofflagp) struct dirent *crnt; u_char dirbuf[512]; /* holds converted dos directories */ int i = 0; -#ifdef __bsdi__ u_int *end_cookies; -#endif #if defined(MSDOSFSDEBUG) printf("msdosfs_readdir(): vp %08x, uio %08x, cred %08x, eofflagp %08x\n", vp, uio, cred, eofflagp); #endif /* defined(MSDOSFSDEBUG) */ -#ifdef __bsdi__ if (cookies) end_cookies = cookies + ncookies; -#endif /* * msdosfs_readdir() won't operate properly on regular files since @@ -1348,13 +1338,25 @@ msdosfs_readdir(vp, uio, cred, eofflagp) */ bias = 2 * sizeof(struct direntry); if (uio->uio_offset < 2 * sizeof(struct direntry)) { - error = uiomove((char *) rootdots + uio->uio_offset, - sizeof rootdots - uio->uio_offset, uio); - if (error) + if (uio->uio_offset + && uio->uio_offset != sizeof(struct direntry)) { + error = EINVAL; goto out; + } + n = 1; + if (!uio->uio_offset) { + n = 2; + *cookies++ = sizeof(struct direntry); + } + if (cookies >= end_cookies) + n--; + else + *cookies++ = 2 * sizeof(struct direntry); + error = uiomove((char *) rootdots + uio->uio_offset, + n * sizeof(struct direntry), uio); } } - do { + while (!error && uio->uio_offset > 0 && cookies < end_cookies) { lbn = (uio->uio_offset - bias) >> pmp->pm_cnshift; on = (uio->uio_offset - bias) & pmp->pm_crbomask; n = MIN((u_long) (pmp->pm_bpcluster - on), uio->uio_resid); @@ -1399,6 +1401,7 @@ msdosfs_readdir(vp, uio, cred, eofflagp) (dentp->deAttributes & ATTR_VOLUME)) { if (prev) { prev->d_reclen += sizeof(struct direntry); + cookies--; } else { prev = crnt; @@ -1442,10 +1445,9 @@ msdosfs_readdir(vp, uio, cred, eofflagp) prev = crnt; } dentp++; -#ifdef __bsdi__ if (cookies) - *cookies++ = (u_int) ((char *) dentp - bp->b_un.b_addr - on) + uio->uio_offset; -#endif + *cookies++ = (u_int)((char *)dentp - bp->b_un.b_addr - on) + + uio->uio_offset; crnt = (struct dirent *) ((char *) crnt + sizeof(struct direntry)); pushout = 1; @@ -1466,10 +1468,8 @@ msdosfs_readdir(vp, uio, cred, eofflagp) prev = 0; crnt = (struct dirent *) dirbuf; } -#ifdef __bsdi__ - if (cookies == end_cookies) + if (cookies >= end_cookies) break; -#endif } if (pushout) { pushout = 0; @@ -1488,11 +1488,9 @@ msdosfs_readdir(vp, uio, cred, eofflagp) bp->b_flags |= B_AGE; #endif /* if 0 */ brelse(bp); -#ifdef __bsdi__ - if (cookies && cookies == end_cookies) + if (n == 0) break; -#endif - } while (error == 0 && uio->uio_resid > 0 && n != 0); + } out: ; uio->uio_resid += lost; diff --git a/sys/nfs/nfs_serv.c b/sys/nfs/nfs_serv.c index 2cdb71c75350..3c669b5aea80 100644 --- a/sys/nfs/nfs_serv.c +++ b/sys/nfs/nfs_serv.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)nfs_serv.c 7.40 (Berkeley) 5/15/91 - * $Id: nfs_serv.c,v 1.7 1993/09/03 23:57:25 jtc Exp $ + * nfs_serv.c,v 1.7 1993/09/03 23:57:25 jtc Exp */ /* @@ -1256,19 +1256,22 @@ nfsrv_readdir(mrep, md, dpos, cred, xid, mrq, repstat, p) int siz, cnt, fullsiz, eofflag; u_long on; char *rbuf; - off_t off, toff; - + off_t off; + u_int *cookiebuf, *cookie; + int ncookies; + fhp = &nfh.fh_generic; nfsm_srvmtofh(fhp); nfsm_disect(tl, u_long *, 2*NFSX_UNSIGNED); - toff = fxdr_unsigned(off_t, *tl++); - off = (toff & ~(NFS_DIRBLKSIZ-1)); - on = (toff & (NFS_DIRBLKSIZ-1)); + off = fxdr_unsigned(off_t, *tl++); + on = off & (NFS_DIRBLKSIZ-1); + off &= ~(NFS_DIRBLKSIZ-1); cnt = fxdr_unsigned(int, *tl); siz = ((cnt+NFS_DIRBLKSIZ-1) & ~(NFS_DIRBLKSIZ-1)); if (cnt > NFS_MAXREADDIR) siz = NFS_MAXREADDIR; fullsiz = siz; + ncookies = siz / 16; /* guess on the number of cookies needed */ if (error = nfsrv_fhtovp(fhp, TRUE, &vp, cred)) nfsm_reply(0); if (error = nfsrv_access(vp, VEXEC, cred, p)) { @@ -1277,6 +1280,7 @@ nfsrv_readdir(mrep, md, dpos, cred, xid, mrq, repstat, p) } VOP_UNLOCK(vp); MALLOC(rbuf, caddr_t, siz, M_TEMP, M_WAITOK); + MALLOC(cookiebuf, u_int *, ncookies * sizeof(u_int), M_TEMP, M_WAITOK); again: iv.iov_base = rbuf; iv.iov_len = fullsiz; @@ -1287,11 +1291,14 @@ again: io.uio_segflg = UIO_SYSSPACE; io.uio_rw = UIO_READ; io.uio_procp = (struct proc *)0; - error = VOP_READDIR(vp, &io, cred, &eofflag); + + error = VOP_READDIR(vp, &io, cred, &eofflag, cookiebuf, ncookies); + cookie = cookiebuf; off = io.uio_offset; if (error) { vrele(vp); free((caddr_t)rbuf, M_TEMP); + free(cookiebuf,M_TEMP); nfsm_reply(0); } if (io.uio_resid) { @@ -1307,6 +1314,7 @@ again: nfsm_build(tl, u_long *, 2*NFSX_UNSIGNED); *tl++ = nfs_false; *tl = nfs_true; + FREE((caddr_t)cookiebuf, M_TEMP); FREE((caddr_t)rbuf, M_TEMP); return (0); } @@ -1316,23 +1324,22 @@ again: * Check for degenerate cases of nothing useful read. * If so go try again */ - cpos = rbuf + on; + cpos = rbuf; cend = rbuf + siz; - dp = (struct direct *)cpos; - while (cpos < cend && dp->d_ino == 0) { - cpos += dp->d_reclen; + while (cpos < cend) { dp = (struct direct *)cpos; + if (cpos < rbuf + on || dp->d_ino == 0) { + cpos += dp->d_reclen; + cookie++; + } else + break; } if (cpos >= cend) { - toff = off; siz = fullsiz; on = 0; goto again; } - cpos = rbuf + on; - cend = rbuf + siz; - dp = (struct direct *)cpos; vrele(vp); len = 3*NFSX_UNSIGNED; /* paranoia, probably can be 0 */ bp = be = (caddr_t)0; @@ -1388,13 +1395,12 @@ again: nfsm_clget; /* Finish off the record */ - toff += dp->d_reclen; - *tl = txdr_unsigned(toff); + *tl = txdr_unsigned(*cookie); bp += NFSX_UNSIGNED; - } else - toff += dp->d_reclen; + } cpos += dp->d_reclen; dp = (struct direct *)cpos; + cookie++; } nfsm_clget; *tl = nfs_false; @@ -1408,6 +1414,7 @@ again: if (bp < be) mp->m_len = bp-mtod(mp, caddr_t); mb->m_next = mp3; + FREE(cookiebuf, M_TEMP); FREE(rbuf, M_TEMP); nfsm_srvdone; } diff --git a/sys/nfs/nfs_socket.c b/sys/nfs/nfs_socket.c index 0369c3ca9fb3..98d355e4745c 100644 --- a/sys/nfs/nfs_socket.c +++ b/sys/nfs/nfs_socket.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)nfs_socket.c 7.23 (Berkeley) 4/20/91 - * $Id: nfs_socket.c,v 1.7 1993/09/06 21:25:20 mycroft Exp $ + * $Id: nfs_socket.c,v 1.8 1993/09/07 15:41:41 ws Exp $ */ /* @@ -957,7 +957,7 @@ nfs_getreq(so, prog, vers, maxproc, nam, mrp, mdp, dposp, retxid, procnum, cr, *wascomp = 0; dpos = mtod(mrep, caddr_t); nfsm_disect(tl, u_long *, 10*NFSX_UNSIGNED); - *retxid = *tl++; + *retxid = fxdr_unsigned(u_long, *tl++); if (*tl++ != rpc_call || *tl++ != rpc_vers) { /* 08 Aug 92*/ *mrp = mrep; *procnum = NFSPROC_NOOP; @@ -1058,7 +1058,7 @@ nfs_rephead(siz, retxid, err, mrq, mbp, bposp) tl = mtod(mreq, u_long *); mreq->m_len = 6*NFSX_UNSIGNED; bpos = ((caddr_t)tl)+mreq->m_len; - *tl++ = retxid; + *tl++ = txdr_unsigned(retxid); *tl++ = rpc_reply; if (err == ERPCMISMATCH) { *tl++ = rpc_msgdenied; diff --git a/sys/nfs/nfs_srvcache.c b/sys/nfs/nfs_srvcache.c index 9af541f0a1bc..c2f8759f4982 100644 --- a/sys/nfs/nfs_srvcache.c +++ b/sys/nfs/nfs_srvcache.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)nfs_srvcache.c 7.11 (Berkeley) 4/16/91 - * $Id: nfs_srvcache.c,v 1.4 1993/05/22 11:43:02 cgd Exp $ + * $Id: nfs_srvcache.c,v 1.5 1993/09/07 15:41:44 ws Exp $ */ /* @@ -215,6 +215,7 @@ loop: rp->rc_state = RC_INPROG; rp->rc_xid = xid; bcopy((caddr_t)nam, (caddr_t)&rp->rc_nam, sizeof (struct mbuf)); + rp->rc_nam.m_data = rp->rc_nam.m_dat; /* for now; hopefully correct? certainly better */ rp->rc_proc = proc; insque(rp, rh); if (mb) diff --git a/sys/nfs/nfs_subs.c b/sys/nfs/nfs_subs.c index 8859f2efeef8..e78f82949183 100644 --- a/sys/nfs/nfs_subs.c +++ b/sys/nfs/nfs_subs.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)nfs_subs.c 7.41 (Berkeley) 5/15/91 - * $Id: nfs_subs.c,v 1.7 1993/08/02 23:11:14 mycroft Exp $ + * $Id: nfs_subs.c,v 1.8 1993/09/07 15:41:45 ws Exp $ */ /* @@ -621,7 +621,6 @@ nfs_namei(ndp, fhp, len, mdp, dposp, p) tocp = ndp->ni_pnbuf; md = *mdp; rem = mtod(md, caddr_t) + md->m_len - fromcp; - ndp->ni_hash = 0; for (i = 0; i < len; i++) { while (rem == 0) { md = md->m_next; @@ -641,7 +640,6 @@ nfs_namei(ndp, fhp, len, mdp, dposp, p) error = EINVAL; goto out; } - ndp->ni_hash += (unsigned char)*fromcp; *tocp++ = *fromcp++; rem--; } diff --git a/sys/nfs/nfs_vnops.c b/sys/nfs/nfs_vnops.c index 1f7786a14f55..460f00866244 100644 --- a/sys/nfs/nfs_vnops.c +++ b/sys/nfs/nfs_vnops.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)nfs_vnops.c 7.60 (Berkeley) 5/24/91 - * $Id: nfs_vnops.c,v 1.10 1993/08/02 23:12:31 mycroft Exp $ + * $Id: nfs_vnops.c,v 1.11 1993/09/07 15:41:46 ws Exp $ */ /* @@ -1192,16 +1192,25 @@ nfs_rmdir(ndp, p) * order so that it looks more sensible. This appears consistent with the * Ultrix implementation of NFS. */ -nfs_readdir(vp, uiop, cred, eofflagp) +nfs_readdir(vp, uiop, cred, eofflagp, cookies, ncookies) register struct vnode *vp; struct uio *uiop; struct ucred *cred; int *eofflagp; + u_int *cookies; + int ncookies; { register struct nfsnode *np = VTONFS(vp); int tresid, error; struct vattr vattr; - + + /* + * Since NFS mounting isn't propagated, + * we don't need to handle cookies here! + */ + if (cookies) + panic("nfs_readdir"); + if (vp->v_type != VDIR) return (EPERM); /* diff --git a/sys/nfs/nfsnode.h b/sys/nfs/nfsnode.h index c4c954357508..29869db739ff 100644 --- a/sys/nfs/nfsnode.h +++ b/sys/nfs/nfsnode.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)nfsnode.h 7.12 (Berkeley) 4/16/91 - * $Id: nfsnode.h,v 1.4 1993/08/02 23:12:32 mycroft Exp $ + * $Id: nfsnode.h,v 1.5 1993/09/07 15:41:48 ws Exp $ */ #ifndef _NFS_NFSNODE_H_ @@ -191,7 +191,9 @@ int nfs_readdir __P(( struct vnode *vp, struct uio *uio, struct ucred *cred, - int *eofflagp)); + int *eofflagp, + u_int *cookies, + int ncookies)); int nfs_readlink __P(( struct vnode *vp, struct uio *uio, diff --git a/sys/sys/fifo.h b/sys/sys/fifo.h index c0ec71f7b65b..c8b7450bcd64 100644 --- a/sys/sys/fifo.h +++ b/sys/sys/fifo.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)fifo.h 7.1 (Berkeley) 4/15/91 - * $Id: fifo.h,v 1.4 1993/06/27 05:59:02 andrew Exp $ + * $Id: fifo.h,v 1.5 1993/09/07 15:41:53 ws Exp $ */ #ifndef _SYS_FIFO_H_ @@ -148,7 +148,9 @@ int fifo_select __P(( struct vnode *vp, \ struct uio *uio, \ struct ucred *cred, \ - int *eofflagp))) fifo_badop) + int *eofflagp, \ + u_int *cookies, \ + int ncookies))) fifo_badop) #define fifo_readlink ((int (*) __P(( \ struct vnode *vp, \ struct uio *uio, \ diff --git a/sys/sys/mount.h b/sys/sys/mount.h index 0396a10b7b90..8a87b323bb1a 100644 --- a/sys/sys/mount.h +++ b/sys/sys/mount.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)mount.h 7.22 (Berkeley) 6/3/91 - * $Id: mount.h,v 1.16 1993/08/24 12:53:50 pk Exp $ + * $Id: mount.h,v 1.17 1993/09/07 15:41:55 ws Exp $ */ #ifndef _SYS_MOUNT_H_ @@ -77,6 +77,7 @@ struct statfs { * File system types. */ #define MOUNT_NONE 0 +#define MOUNT_EXPORT MOUNT_NONE /* use this for export mounting (mountd) */ #define MOUNT_UFS 1 /* UNIX "Fast" Filesystem */ #define MOUNT_NFS 2 /* Network Filesystem */ #define MOUNT_MFS 3 /* Memory Filesystem */ @@ -117,8 +118,6 @@ struct mount { #define MNT_NODEV 0x00000010 /* don't interpret special files */ #define MNT_UNION 0x00000020 /* union with underlying filesysem */ -#define ISOFSMNT_NORRIP 0x00000040 /* disable Rock Ridge Ext.*/ - /* * exported mount flags. */ @@ -210,13 +209,18 @@ struct fhandle { }; typedef struct fhandle fhandle_t; +/* + * Arguments to export mount + */ +struct export_args { + uid_t exroot; /* mapping for root uid */ +}; + /* * Arguments to mount UFS */ struct ufs_args { char *fspec; /* block special device to mount */ - int exflags; /* export related flags */ - uid_t exroot; /* mapping for root uid */ }; /* @@ -269,13 +273,22 @@ struct nfs_args { #define NFSMNT_COMPRESS 0x0800 /* Compress nfs rpc xdr */ #define NFSMNT_LOCKBITS (NFSMNT_SCKLOCK | NFSMNT_WANTSCK) +/* + * 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 */ + /* * Arguments to mount MSDOS filesystems. */ struct msdosfs_args { char *fspec; /* blocks special holding the fs to mount */ - int exflags; /* mount flags */ - uid_t exroot; /* mapping for root uid */ }; #ifdef KERNEL diff --git a/sys/sys/specdev.h b/sys/sys/specdev.h index 077024d53160..baa12a0292f9 100644 --- a/sys/sys/specdev.h +++ b/sys/sys/specdev.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)specdev.h 7.4 (Berkeley) 4/19/91 - * $Id: specdev.h,v 1.4 1993/06/27 05:59:07 andrew Exp $ + * $Id: specdev.h,v 1.5 1993/09/07 15:41:56 ws Exp $ */ #ifndef _SYS_SPECDEV_H_ @@ -189,7 +189,9 @@ int spec_select __P(( struct vnode *vp, \ struct uio *uio, \ struct ucred *cred, \ - int *eofflagp))) spec_badop) + int *eofflagp, \ + u_int *cookies, \ + int ncookies))) spec_badop) #define spec_readlink ((int (*) __P(( \ struct vnode *vp, \ struct uio *uio, \ diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 43b8cc7dc78d..6302b8a256ac 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)vnode.h 7.39 (Berkeley) 6/27/91 - * $Id: vnode.h,v 1.10 1993/08/24 12:53:51 pk Exp $ + * $Id: vnode.h,v 1.11 1993/09/07 15:41:57 ws Exp $ */ #ifndef _SYS_VNODE_H_ @@ -200,7 +200,8 @@ struct vnodeops { int (*vop_symlink) __P((struct nameidata *ndp, struct vattr *vap, char *target, struct proc *p)); int (*vop_readdir) __P((struct vnode *vp, struct uio *uio, - struct ucred *cred, int *eofflagp)); + struct ucred *cred, int *eofflagp, + u_int *cookies, int ncookies)); int (*vop_readlink) __P((struct vnode *vp, struct uio *uio, struct ucred *cred)); int (*vop_abortop) __P((struct nameidata *ndp)); @@ -239,7 +240,7 @@ struct vnodeops { #define VOP_MKDIR(n,a,p) (*((n)->ni_dvp->v_op->vop_mkdir))(n,a,p) #define VOP_RMDIR(n,p) (*((n)->ni_dvp->v_op->vop_rmdir))(n,p) #define VOP_SYMLINK(n,a,m,p) (*((n)->ni_dvp->v_op->vop_symlink))(n,a,m,p) -#define VOP_READDIR(v,u,c,e) (*((v)->v_op->vop_readdir))(v,u,c,e) +#define VOP_READDIR(v,u,c,e,k,n) (*((v)->v_op->vop_readdir))(v,u,c,e,k,n) #define VOP_READLINK(v,u,c) (*((v)->v_op->vop_readlink))(v,u,c) #define VOP_ABORTOP(n) (*((n)->ni_dvp->v_op->vop_abortop))(n) #define VOP_INACTIVE(v,p) (*((v)->v_op->vop_inactive))(v,p) diff --git a/sys/ufs/mfsnode.h b/sys/ufs/mfsnode.h index e0206871c99a..70bb582e059c 100644 --- a/sys/ufs/mfsnode.h +++ b/sys/ufs/mfsnode.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)mfsnode.h 7.3 (Berkeley) 4/16/91 - * $Id: mfsnode.h,v 1.4 1993/08/24 14:54:16 mycroft Exp $ + * $Id: mfsnode.h,v 1.5 1993/09/07 15:42:03 ws Exp $ */ #ifndef _UFS_MFSNODE_H_ @@ -165,7 +165,9 @@ int mfs_ioctl __P(( struct vnode *vp, \ struct uio *uio, \ struct ucred *cred, \ - int *eofflagp))) mfs_badop) + int *eofflagp, + u_int *cookies, + int ncookies))) mfs_badop) #define mfs_readlink ((int (*) __P(( \ struct vnode *vp, \ struct uio *uio, \ diff --git a/sys/ufs/ufs_vfsops.c b/sys/ufs/ufs_vfsops.c index 16dc1f6467d4..063aa4b4b195 100644 --- a/sys/ufs/ufs_vfsops.c +++ b/sys/ufs/ufs_vfsops.c @@ -1 +1 @@ -revision 1.2 intentionally removed +revision 1.3 intentionally removed diff --git a/usr.sbin/mountd/mountd.c b/usr.sbin/mountd/mountd.c index 5f078ee7b050..d5c449b07269 100644 --- a/usr.sbin/mountd/mountd.c +++ b/usr.sbin/mountd/mountd.c @@ -42,7 +42,7 @@ char copyright[] = #ifndef lint /*static char sccsid[] = "from: @(#)mountd.c 5.14 (Berkeley) 2/26/91";*/ -static char rcsid[] = "$Id: mountd.c,v 1.7 1993/08/25 02:42:57 brezak Exp $"; +static char rcsid[] = "$Id: mountd.c,v 1.8 1993/09/07 15:40:37 ws Exp $"; #endif not lint #include @@ -452,7 +452,7 @@ get_exportlist() register struct grouplist *grp; register struct exportlist *ep, *ep2; struct statfs stfsbuf; - struct ufs_args args; + struct export_args args; struct stat sb; FILE *inf; char *cp, *endcp; @@ -618,13 +618,12 @@ get_exportlist() len = endcp - cp; } if (fep == NULL) { - args.fspec = 0; - args.exflags = exflags; args.exroot = rootuid; cp = (char *)0; while (statfs(ep->ex_dirp, &stfsbuf) < 0 || - mount(MOUNT_UFS, ep->ex_dirp, - stfsbuf.f_flags|MNT_UPDATE, &args) < 0) { + mount(MOUNT_EXPORT, ep->ex_dirp, + stfsbuf.f_flags|(MNT_UPDATE|exflags), + &args) < 0) { /* 08 Sep 92*/ if (cp) *cp-- = savedc; else