Clean up deleted files.
This commit is contained in:
parent
36d501bf10
commit
1968713466
|
@ -1,77 +0,0 @@
|
|||
# $Id: TODO,v 1.4 1993/09/07 15:40:51 ws Exp $
|
||||
|
||||
1) should understand "older", original High Sierra ("CDROM001") type
|
||||
|
||||
Not yet. ( I don't have this technical information, yet. )
|
||||
|
||||
2) should understand Rock Ridge
|
||||
|
||||
Yes, we have follows function.
|
||||
|
||||
o Symbolic Link
|
||||
o Real Name(long name)
|
||||
o File Attribute
|
||||
o Time stamp
|
||||
o uid, gid
|
||||
o Devices
|
||||
o Relocated directories
|
||||
|
||||
Except follows:
|
||||
|
||||
o POSIX device number mapping
|
||||
|
||||
There is some preliminary stuff in there that (ab-)uses the mknod
|
||||
system call, but this needs a writable filesystem
|
||||
|
||||
3) should be called cdfs, as there are other ISO file system soon possible
|
||||
|
||||
Not yet. Probably we should make another file system when the ECMA draft
|
||||
is valid and do it. For doing Rock Ridge Support, I can use almost same
|
||||
code. So I just use the same file system interface...
|
||||
|
||||
4) should have file handles implemented for use with NFS, etc
|
||||
|
||||
Yes. we have already this one, and I based it for this release.
|
||||
|
||||
5) should have name translation enabled by mount flag
|
||||
|
||||
Yes. we can disable the Rock Ridge Extension by follows option;
|
||||
|
||||
"mount -t isofs -o -norrip /dev/cd0d /cdrom"
|
||||
|
||||
6) should run as a user process, and not take up kernel space (cdroms
|
||||
are slow)
|
||||
|
||||
Not yet.
|
||||
|
||||
7) ECMA support.
|
||||
|
||||
Not yet. we need not only a technical spec but also ECMA format
|
||||
cd-rom itself!
|
||||
|
||||
8) Character set change by SVD ( multi SVD support )
|
||||
|
||||
Not yet. We should also hack the other part of system as 8 bit
|
||||
clean. As far as I know, if you export the cdrom by NFS, the client
|
||||
can access the 8 bit clean (ie. Solaris Japanese with EUC code )
|
||||
|
||||
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)
|
217
sys/isofs/iso.h
217
sys/isofs/iso.h
|
@ -1,217 +0,0 @@
|
|||
/*
|
||||
* $Id: iso.h,v 1.6 1993/10/28 17:38:42 ws Exp $
|
||||
*/
|
||||
|
||||
#define ISODCL(from, to) (to - from + 1)
|
||||
|
||||
struct iso_volume_descriptor {
|
||||
char type[ISODCL(1,1)]; /* 711 */
|
||||
char id[ISODCL(2,6)];
|
||||
char version[ISODCL(7,7)];
|
||||
char data[ISODCL(8,2048)];
|
||||
};
|
||||
|
||||
/* volume descriptor types */
|
||||
#define ISO_VD_PRIMARY 1
|
||||
#define ISO_VD_END 255
|
||||
|
||||
#define ISO_STANDARD_ID "CD001"
|
||||
#define ISO_ECMA_ID "CDW01"
|
||||
|
||||
struct iso_primary_descriptor {
|
||||
char type [ISODCL ( 1, 1)]; /* 711 */
|
||||
char id [ISODCL ( 2, 6)];
|
||||
char version [ISODCL ( 7, 7)]; /* 711 */
|
||||
char unused1 [ISODCL ( 8, 8)];
|
||||
char system_id [ISODCL ( 9, 40)]; /* achars */
|
||||
char volume_id [ISODCL ( 41, 72)]; /* dchars */
|
||||
char unused2 [ISODCL ( 73, 80)];
|
||||
char volume_space_size [ISODCL ( 81, 88)]; /* 733 */
|
||||
char unused3 [ISODCL ( 89, 120)];
|
||||
char volume_set_size [ISODCL (121, 124)]; /* 723 */
|
||||
char volume_sequence_number [ISODCL (125, 128)]; /* 723 */
|
||||
char logical_block_size [ISODCL (129, 132)]; /* 723 */
|
||||
char path_table_size [ISODCL (133, 140)]; /* 733 */
|
||||
char type_l_path_table [ISODCL (141, 144)]; /* 731 */
|
||||
char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */
|
||||
char type_m_path_table [ISODCL (149, 152)]; /* 732 */
|
||||
char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */
|
||||
char root_directory_record [ISODCL (157, 190)]; /* 9.1 */
|
||||
char volume_set_id [ISODCL (191, 318)]; /* dchars */
|
||||
char publisher_id [ISODCL (319, 446)]; /* achars */
|
||||
char preparer_id [ISODCL (447, 574)]; /* achars */
|
||||
char application_id [ISODCL (575, 702)]; /* achars */
|
||||
char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */
|
||||
char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */
|
||||
char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */
|
||||
char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */
|
||||
char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */
|
||||
char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */
|
||||
char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */
|
||||
char file_structure_version [ISODCL (882, 882)]; /* 711 */
|
||||
char unused4 [ISODCL (883, 883)];
|
||||
char application_data [ISODCL (884, 1395)];
|
||||
char unused5 [ISODCL (1396, 2048)];
|
||||
};
|
||||
|
||||
struct iso_directory_record {
|
||||
char length [ISODCL (1, 1)]; /* 711 */
|
||||
char ext_attr_length [ISODCL (2, 2)]; /* 711 */
|
||||
unsigned char extent [ISODCL (3, 10)]; /* 733 */
|
||||
unsigned char size [ISODCL (11, 18)]; /* 733 */
|
||||
char date [ISODCL (19, 25)]; /* 7 by 711 */
|
||||
char flags [ISODCL (26, 26)];
|
||||
char file_unit_size [ISODCL (27, 27)]; /* 711 */
|
||||
char interleave [ISODCL (28, 28)]; /* 711 */
|
||||
char volume_sequence_number [ISODCL (29, 32)]; /* 723 */
|
||||
char name_len [ISODCL (33, 33)]; /* 711 */
|
||||
char name [0];
|
||||
};
|
||||
/* can't take sizeof(iso_directory_record), because of possible alignment
|
||||
of the last entry (34 instead of 33) */
|
||||
#define ISO_DIRECTORY_RECORD_SIZE 33
|
||||
|
||||
struct iso_extended_attributes {
|
||||
unsigned char owner [ISODCL (1, 4)]; /* 723 */
|
||||
unsigned char group [ISODCL (5, 8)]; /* 723 */
|
||||
unsigned char perm [ISODCL (9, 10)]; /* 9.5.3 */
|
||||
char ctime [ISODCL (11, 27)]; /* 8.4.26.1 */
|
||||
char mtime [ISODCL (28, 44)]; /* 8.4.26.1 */
|
||||
char xtime [ISODCL (45, 61)]; /* 8.4.26.1 */
|
||||
char ftime [ISODCL (62, 78)]; /* 8.4.26.1 */
|
||||
char recfmt [ISODCL (79, 79)]; /* 711 */
|
||||
char recattr [ISODCL (80, 80)]; /* 711 */
|
||||
unsigned char reclen [ISODCL (81, 84)]; /* 723 */
|
||||
char system_id [ISODCL (85, 116)]; /* achars */
|
||||
char system_use [ISODCL (117, 180)];
|
||||
char version [ISODCL (181, 181)]; /* 711 */
|
||||
char len_esc [ISODCL (182, 182)]; /* 711 */
|
||||
char reserved [ISODCL (183, 246)];
|
||||
unsigned char len_au [ISODCL (247, 250)]; /* 723 */
|
||||
};
|
||||
|
||||
/* CD-ROM Format type */
|
||||
enum ISO_FTYPE { ISO_FTYPE_DEFAULT, ISO_FTYPE_9660, ISO_FTYPE_RRIP, ISO_FTYPE_ECMA };
|
||||
|
||||
#ifndef ISOFSMNT_ROOT
|
||||
#define ISOFSMNT_ROOT 0
|
||||
#endif
|
||||
|
||||
struct iso_mnt {
|
||||
int im_flags;
|
||||
|
||||
int logical_block_size;
|
||||
int volume_space_size;
|
||||
struct vnode *im_devvp;
|
||||
char im_fsmnt[50];
|
||||
|
||||
struct mount *im_mountp;
|
||||
dev_t im_dev;
|
||||
|
||||
int im_bshift;
|
||||
int im_bmask;
|
||||
|
||||
char root[ISODCL (157, 190)];
|
||||
int root_extent;
|
||||
int root_size;
|
||||
enum ISO_FTYPE iso_ftype;
|
||||
|
||||
int rr_skip;
|
||||
int rr_skip0;
|
||||
};
|
||||
|
||||
#define VFSTOISOFS(mp) ((struct iso_mnt *)((mp)->mnt_data))
|
||||
|
||||
#define iso_blkoff(imp, loc) ((loc) & (imp)->im_bmask)
|
||||
#define iso_lblkno(imp, loc) ((loc) >> (imp)->im_bshift)
|
||||
#define iso_blksize(imp, ip, lbn) ((imp)->logical_block_size)
|
||||
#define iso_lblktosize(imp, blk) ((blk) << (imp)->im_bshift)
|
||||
|
||||
|
||||
int isofs_mount __P((struct mount *mp, char *path, caddr_t data,
|
||||
struct nameidata *ndp, struct proc *p));
|
||||
int isofs_start __P((struct mount *mp, int flags, struct proc *p));
|
||||
int isofs_unmount __P((struct mount *mp, int mntflags, struct proc *p));
|
||||
int isofs_root __P((struct mount *mp, struct vnode **vpp));
|
||||
int isofs_statfs __P((struct mount *mp, struct statfs *sbp, struct proc *p));
|
||||
int isofs_sync __P((struct mount *mp, int waitfor));
|
||||
int isofs_fhtovp __P((struct mount *mp, struct fid *fhp, struct vnode **vpp));
|
||||
int isofs_vptofh __P((struct vnode *vp, struct fid *fhp));
|
||||
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, struct buf **bpp));
|
||||
int iso_iget __P((struct iso_node *xp, ino_t ino, int relocated,
|
||||
struct iso_node **ipp, struct iso_directory_record *isodir));
|
||||
int iso_iput __P((struct iso_node *ip));
|
||||
int iso_ilock __P((struct iso_node *ip));
|
||||
int iso_iunlock __P((struct iso_node *ip));
|
||||
int isofs_mountroot __P((void));
|
||||
|
||||
extern inline int
|
||||
isonum_711(p)
|
||||
unsigned char *p;
|
||||
{
|
||||
return *p;
|
||||
}
|
||||
|
||||
extern inline int
|
||||
isonum_712(p)
|
||||
char *p;
|
||||
{
|
||||
return *p;
|
||||
}
|
||||
|
||||
extern inline int
|
||||
isonum_721(p)
|
||||
unsigned char *p;
|
||||
{
|
||||
return *p|((char)p[1] << 8);
|
||||
}
|
||||
|
||||
extern inline int
|
||||
isonum_722(p)
|
||||
unsigned char *p;
|
||||
{
|
||||
return ((char)*p << 8)|p[1];
|
||||
}
|
||||
|
||||
extern inline int
|
||||
isonum_723(p)
|
||||
unsigned char *p;
|
||||
{
|
||||
return isonum_721(p);
|
||||
}
|
||||
|
||||
extern inline int
|
||||
isonum_731(p)
|
||||
unsigned char *p;
|
||||
{
|
||||
return *p|(p[1] << 8)|(p[2] << 16)|(p[3] << 24);
|
||||
}
|
||||
|
||||
extern inline int
|
||||
isonum_732(p)
|
||||
unsigned char *p;
|
||||
{
|
||||
return (*p << 24)|(p[1] << 16)|(p[2] << 8)|p[3];
|
||||
}
|
||||
|
||||
extern inline int
|
||||
isonum_733(p)
|
||||
unsigned char *p;
|
||||
{
|
||||
return isonum_731(p);
|
||||
}
|
||||
|
||||
int isofncmp __P((unsigned char *fn, int fnlen,
|
||||
unsigned char *isofn, int isolen));
|
||||
void isofntrans __P((unsigned char *infn, int infnlen,
|
||||
unsigned char *outfn, unsigned short *outfnlen,
|
||||
int original, int assoc));
|
||||
|
||||
/*
|
||||
* Associated files have a leading '='.
|
||||
*/
|
||||
#define ASSOCCHAR '='
|
|
@ -1,76 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 1993 Atsushi Murai (amurai@spec.co.jp)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY Atsushi Murai(amurai@spec.co.jp)``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)iso_rrip.h
|
||||
* $Id: iso_rrip.h,v 1.3 1993/09/07 15:40:53 ws Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Analyze function flag (similar to RR field bits)
|
||||
*/
|
||||
#define ISO_SUSP_ATTR 0x0001
|
||||
#define ISO_SUSP_DEVICE 0x0002
|
||||
#define ISO_SUSP_SLINK 0x0004
|
||||
#define ISO_SUSP_ALTNAME 0x0008
|
||||
#define ISO_SUSP_CLINK 0x0010
|
||||
#define ISO_SUSP_PLINK 0x0020
|
||||
#define ISO_SUSP_RELDIR 0x0040
|
||||
#define ISO_SUSP_TSTAMP 0x0080
|
||||
#define ISO_SUSP_IDFLAG 0x0100
|
||||
#define ISO_SUSP_EXTREF 0x0200
|
||||
#define ISO_SUSP_CONT 0x0400
|
||||
#define ISO_SUSP_OFFSET 0x0800
|
||||
#define ISO_SUSP_STOP 0x1000
|
||||
#define ISO_SUSP_UNKNOWN 0x8000
|
||||
|
||||
typedef struct {
|
||||
struct iso_node *inop;
|
||||
int fields; /* interesting fields in this analysis */
|
||||
daddr_t iso_ce_blk; /* block of continuation area */
|
||||
off_t iso_ce_off; /* offset of continuation area */
|
||||
int iso_ce_len; /* length of continuation area */
|
||||
struct iso_mnt *imp; /* mount structure */
|
||||
ino_t *inump; /* inode number pointer */
|
||||
char *outbuf; /* name/symbolic link output area */
|
||||
u_short *outlen; /* length of above */
|
||||
u_short maxlen; /* maximum length of above */
|
||||
int cont; /* continuation of above */
|
||||
} ISO_RRIP_ANALYZE;
|
||||
|
||||
int isofs_rrip_analyze __P((struct iso_directory_record *isodir,
|
||||
struct iso_node *inop, struct iso_mnt *imp));
|
||||
int isofs_rrip_getname __P((struct iso_directory_record *isodir,
|
||||
char *outbuf, u_short *outlen,
|
||||
ino_t *inump, struct iso_mnt *imp));
|
||||
int isofs_rrip_getsymname __P((struct iso_directory_record *isodir,
|
||||
char *outbuf, u_short *outlen,
|
||||
struct iso_mnt *imp));
|
||||
int isofs_rrip_offset __P((struct iso_directory_record *isodir,
|
||||
struct iso_mnt *imp));
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
* $Id: isofs_bmap.c,v 1.6 1993/12/18 04:31:28 mycroft Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/namei.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <isofs/iso.h>
|
||||
#include <isofs/isofs_node.h>
|
||||
|
||||
iso_bmap(ip, lblkno, result)
|
||||
struct iso_node *ip;
|
||||
int lblkno;
|
||||
daddr_t *result;
|
||||
{
|
||||
*result = (ip->iso_start + lblkno)
|
||||
* (ip->i_mnt->logical_block_size / DEV_BSIZE);
|
||||
return 0;
|
||||
}
|
|
@ -1,460 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 1989 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Copyright (c) 1983 Atsushi Murai (amurai@spec.co.jp)
|
||||
* All rights reserved for Rock Ridge Extension Support.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)ufs_lookup.c 7.33 (Berkeley) 5/19/91
|
||||
* $Id: isofs_lookup.c,v 1.17 1994/04/25 03:49:27 cgd Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/namei.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <isofs/iso.h>
|
||||
#include <isofs/isofs_node.h>
|
||||
#include <isofs/iso_rrip.h>
|
||||
#include <isofs/isofs_rrip.h>
|
||||
|
||||
struct nchstats iso_nchstats;
|
||||
|
||||
/*
|
||||
* Convert a component of a pathname into a pointer to a locked inode.
|
||||
* This is a very central and rather complicated routine.
|
||||
* If the file system is not maintained in a strict tree hierarchy,
|
||||
* this can result in a deadlock situation (see comments in code below).
|
||||
*
|
||||
* The flag argument is LOOKUP, CREATE, RENAME, or DELETE depending on
|
||||
* whether the name is to be looked up, created, renamed, or deleted.
|
||||
* When CREATE, RENAME, or DELETE is specified, information usable in
|
||||
* creating, renaming, or deleting a directory entry may be calculated.
|
||||
* If flag has LOCKPARENT or'ed into it and the target of the pathname
|
||||
* exists, lookup returns both the target and its parent directory locked.
|
||||
* When creating or renaming and LOCKPARENT is specified, the target may
|
||||
* not be ".". When deleting and LOCKPARENT is specified, the target may
|
||||
* be "."., but the caller must check to ensure it does an vrele and iput
|
||||
* instead of two iputs.
|
||||
*
|
||||
* Overall outline of ufs_lookup:
|
||||
*
|
||||
* check accessibility of directory
|
||||
* look for name in cache, if found, then if at end of path
|
||||
* and deleting or creating, drop it, else return name
|
||||
* search for name in directory, to found or notfound
|
||||
* notfound:
|
||||
* if creating, return locked directory, leaving info on available slots
|
||||
* else return error
|
||||
* found:
|
||||
* if at end of path and deleting, return information to allow delete
|
||||
* if at end of path and rewriting (RENAME and LOCKPARENT), lock target
|
||||
* inode and return info to allow rewrite
|
||||
* if not at end, add name to cache; if at end and neither creating
|
||||
* nor deleting, add name to cache
|
||||
*
|
||||
* NOTE: (LOOKUP | LOCKPARENT) currently returns the parent inode unlocked.
|
||||
*/
|
||||
isofs_lookup(vdp, ndp, p)
|
||||
register struct vnode *vdp;
|
||||
register struct nameidata *ndp;
|
||||
struct proc *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 */
|
||||
struct iso_directory_record *ep;/* the current directory entry */
|
||||
off_t entryoffsetinblock; /* offset of ep in bp's buffer */
|
||||
off_t saveoffset; /* offset of last directory entry in dir */
|
||||
int numdirpasses; /* strategy for directory search */
|
||||
off_t endsearch; /* offset to end directory search */
|
||||
struct iso_node *pdp; /* saved dp during symlink work */
|
||||
struct iso_node *tdp; /* returned by iget */
|
||||
int flag; /* LOOKUP, CREATE, RENAME, or DELETE */
|
||||
int lockparent; /* 1 => lockparent flag is set */
|
||||
int wantparent; /* 1 => wantparent or lockparent flag */
|
||||
int error;
|
||||
ino_t ino = 0;
|
||||
int reclen;
|
||||
u_short namelen;
|
||||
char altname[NAME_MAX];
|
||||
int res;
|
||||
int assoc, len;
|
||||
char *name;
|
||||
|
||||
ndp->ni_dvp = vdp;
|
||||
ndp->ni_vp = NULL;
|
||||
dp = VTOI(vdp);
|
||||
imp = dp->i_mnt;
|
||||
lockparent = ndp->ni_nameiop & LOCKPARENT;
|
||||
flag = ndp->ni_nameiop & OPMASK;
|
||||
wantparent = ndp->ni_nameiop & (LOCKPARENT|WANTPARENT);
|
||||
|
||||
/*
|
||||
* Check accessiblity of directory.
|
||||
*/
|
||||
if (vdp->v_type != VDIR)
|
||||
return ENOTDIR;
|
||||
if (error = isofs_access(vdp, VEXEC, ndp->ni_cred, p))
|
||||
return error;
|
||||
|
||||
/*
|
||||
* We now have a segment name to search for, and a directory to search.
|
||||
*
|
||||
* Before tediously performing a linear scan of the directory,
|
||||
* check the name cache to see if the directory/name pair
|
||||
* we are looking for is known already.
|
||||
*/
|
||||
if (error = cache_lookup(ndp)) {
|
||||
int vpid; /* capability number of vnode */
|
||||
|
||||
if (error == ENOENT)
|
||||
return (error);
|
||||
#ifdef DIAGNOSTIC
|
||||
if (vdp == ndp->ni_rootdir && ndp->ni_isdotdot)
|
||||
panic("ufs_lookup: .. through root");
|
||||
#endif
|
||||
/*
|
||||
* Get the next vnode in the path.
|
||||
* See comment below starting `Step through' for
|
||||
* an explaination of the locking protocol.
|
||||
*/
|
||||
pdp = dp;
|
||||
dp = VTOI(ndp->ni_vp);
|
||||
vdp = ndp->ni_vp;
|
||||
vpid = vdp->v_id;
|
||||
if (pdp == dp) {
|
||||
VREF(vdp);
|
||||
error = 0;
|
||||
} else if (ndp->ni_isdotdot) {
|
||||
ISO_IUNLOCK(pdp);
|
||||
error = vget(vdp, 1);
|
||||
if (!error && lockparent && *ndp->ni_next == '\0')
|
||||
ISO_ILOCK(pdp);
|
||||
} else {
|
||||
error = vget(vdp, 1);
|
||||
if (!lockparent || error || *ndp->ni_next != '\0')
|
||||
ISO_IUNLOCK(pdp);
|
||||
}
|
||||
/*
|
||||
* Check that the capability number did not change
|
||||
* while we were waiting for the lock.
|
||||
*/
|
||||
if (!error) {
|
||||
if (vpid == vdp->v_id)
|
||||
return (0);
|
||||
iso_iput(dp);
|
||||
if (lockparent && pdp != dp && *ndp->ni_next == '\0')
|
||||
ISO_IUNLOCK(pdp);
|
||||
}
|
||||
ISO_ILOCK(pdp);
|
||||
dp = pdp;
|
||||
vdp = ITOV(dp);
|
||||
ndp->ni_vp = NULL;
|
||||
}
|
||||
|
||||
len = ndp->ni_namelen;
|
||||
name = ndp->ni_ptr;
|
||||
/*
|
||||
* A leading `=' means, we are looking for an associated file
|
||||
*/
|
||||
if (assoc = (imp->iso_ftype != ISO_FTYPE_RRIP && *name == ASSOCCHAR)) {
|
||||
len--;
|
||||
name++;
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is cached information on a previous search of
|
||||
* this directory, pick up where we last left off.
|
||||
* We cache only lookups as these are the most common
|
||||
* and have the greatest payoff. Caching CREATE has little
|
||||
* benefit as it usually must search the entire directory
|
||||
* to determine that the entry does not exist. Caching the
|
||||
* location of the last DELETE or RENAME has not reduced
|
||||
* profiling time and hence has been removed in the interest
|
||||
* of simplicity.
|
||||
*/
|
||||
if (flag != LOOKUP || dp->i_diroff == 0 || dp->i_diroff > dp->i_size) {
|
||||
ndp->ni_ufs.ufs_offset = 0;
|
||||
numdirpasses = 1;
|
||||
} else {
|
||||
ndp->ni_ufs.ufs_offset = dp->i_diroff;
|
||||
entryoffsetinblock = iso_blkoff(imp, ndp->ni_ufs.ufs_offset);
|
||||
if (entryoffsetinblock != 0) {
|
||||
if (error = iso_blkatoff(dp,ndp->ni_ufs.ufs_offset,&bp))
|
||||
return error;
|
||||
}
|
||||
numdirpasses = 2;
|
||||
iso_nchstats.ncs_2passes++;
|
||||
}
|
||||
endsearch = roundup(dp->i_size,imp->logical_block_size);
|
||||
|
||||
searchloop:
|
||||
while (ndp->ni_ufs.ufs_offset < endsearch) {
|
||||
/*
|
||||
* If offset is on a block boundary,
|
||||
* read the next directory block.
|
||||
* Release previous if it exists.
|
||||
*/
|
||||
if (iso_blkoff(imp,ndp->ni_ufs.ufs_offset) == 0) {
|
||||
if (bp != NULL)
|
||||
brelse(bp);
|
||||
if (error = iso_blkatoff(dp,ndp->ni_ufs.ufs_offset,&bp))
|
||||
return error;
|
||||
entryoffsetinblock = 0;
|
||||
}
|
||||
/*
|
||||
* Get pointer to next entry.
|
||||
*/
|
||||
|
||||
ep = (struct iso_directory_record *)
|
||||
(bp->b_un.b_addr + entryoffsetinblock);
|
||||
|
||||
reclen = isonum_711 (ep->length);
|
||||
if (reclen == 0) {
|
||||
/* skip to next block, if any */
|
||||
ndp->ni_ufs.ufs_offset =
|
||||
roundup(ndp->ni_ufs.ufs_offset,
|
||||
imp->logical_block_size);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (reclen < ISO_DIRECTORY_RECORD_SIZE)
|
||||
/* illegal entry, stop */
|
||||
break;
|
||||
|
||||
if (entryoffsetinblock + reclen > imp->logical_block_size)
|
||||
/* entries are not allowed to cross boundaries */
|
||||
break;
|
||||
|
||||
/*
|
||||
* Check for a name match.
|
||||
*/
|
||||
namelen = isonum_711(ep->name_len);
|
||||
|
||||
if (reclen < ISO_DIRECTORY_RECORD_SIZE + namelen)
|
||||
/* illegal entry, stop */
|
||||
break;
|
||||
|
||||
switch (imp->iso_ftype) {
|
||||
default:
|
||||
if ((!(isonum_711(ep->flags)&4)) == !assoc) {
|
||||
if ((len == 1
|
||||
&& *name == '.')
|
||||
|| ndp->ni_isdotdot) {
|
||||
if (namelen == 1
|
||||
&& ep->name[0] == (ndp->ni_isdotdot ? 1 : 0)) {
|
||||
/*
|
||||
* Save directory entry's inode number and
|
||||
* reclen in ndp->ni_ufs area, and release
|
||||
* directory buffer.
|
||||
*/
|
||||
isodirino(&ndp->ni_ufs.ufs_ino,ep,imp);
|
||||
goto found;
|
||||
}
|
||||
if (namelen != 1
|
||||
|| ep->name[0] != 0)
|
||||
goto notfound;
|
||||
} else if (!(res = isofncmp(name,len,
|
||||
ep->name,namelen))) {
|
||||
if (isonum_711(ep->flags)&2)
|
||||
isodirino(&ino,ep,imp);
|
||||
else
|
||||
ino = (bp->b_blkno << DEV_BSHIFT)
|
||||
+ entryoffsetinblock;
|
||||
saveoffset = ndp->ni_ufs.ufs_offset;
|
||||
} else if (ino)
|
||||
goto foundino;
|
||||
#ifdef NOSORTBUG /* On some CDs directory entries are not sorted correctly */
|
||||
else if (res < 0)
|
||||
goto notfound;
|
||||
else if (res > 0 && numdirpasses == 2)
|
||||
numdirpasses++;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case ISO_FTYPE_RRIP:
|
||||
if (isonum_711(ep->flags)&2)
|
||||
isodirino(&ino,ep,imp);
|
||||
else
|
||||
ino = (bp->b_blkno << DEV_BSHIFT) + entryoffsetinblock;
|
||||
ndp->ni_ufs.ufs_ino = ino;
|
||||
isofs_rrip_getname(ep,altname,&namelen,&ndp->ni_ufs.ufs_ino,imp);
|
||||
if (namelen == ndp->ni_namelen
|
||||
&& !bcmp(name,altname,namelen))
|
||||
goto found;
|
||||
ino = 0;
|
||||
break;
|
||||
}
|
||||
ndp->ni_ufs.ufs_offset += reclen;
|
||||
entryoffsetinblock += reclen;
|
||||
}
|
||||
if (ino) {
|
||||
foundino:
|
||||
ndp->ni_ufs.ufs_ino = ino;
|
||||
if (saveoffset != ndp->ni_ufs.ufs_offset) {
|
||||
if (iso_lblkno(imp,ndp->ni_ufs.ufs_offset)
|
||||
!= iso_lblkno(imp,saveoffset)) {
|
||||
if (bp != NULL)
|
||||
brelse(bp);
|
||||
if (error = iso_blkatoff(dp,saveoffset,&bp))
|
||||
return error;
|
||||
}
|
||||
ep = (struct iso_directory_record *)(bp->b_un.b_addr
|
||||
+ iso_blkoff(imp,saveoffset));
|
||||
ndp->ni_ufs.ufs_offset = saveoffset;
|
||||
}
|
||||
goto found;
|
||||
}
|
||||
notfound:
|
||||
/*
|
||||
* If we started in the middle of the directory and failed
|
||||
* to find our target, we must check the beginning as well.
|
||||
*/
|
||||
if (numdirpasses == 2) {
|
||||
numdirpasses--;
|
||||
ndp->ni_ufs.ufs_offset = 0;
|
||||
endsearch = dp->i_diroff;
|
||||
goto searchloop;
|
||||
}
|
||||
if (bp != NULL)
|
||||
brelse(bp);
|
||||
/*
|
||||
* Insert name into cache (as non-existent) if appropriate.
|
||||
*/
|
||||
if (ndp->ni_makeentry)
|
||||
cache_enter(ndp);
|
||||
if (flag == CREATE || flag == RENAME)
|
||||
return EJUSTRETURN;
|
||||
return (ENOENT);
|
||||
|
||||
found:
|
||||
if (numdirpasses > 1)
|
||||
iso_nchstats.ncs_pass2++;
|
||||
|
||||
/*
|
||||
* Found component in pathname.
|
||||
* If the final component of path name, save information
|
||||
* in the cache as to where the entry was found.
|
||||
*/
|
||||
if (*ndp->ni_next == '\0' && flag == LOOKUP)
|
||||
dp->i_diroff = ndp->ni_ufs.ufs_offset;
|
||||
|
||||
/*
|
||||
* Step through the translation in the name. We do not `iput' the
|
||||
* directory because we may need it again if a symbolic link
|
||||
* is relative to the current directory. Instead we save it
|
||||
* unlocked as "pdp". We must get the target inode before unlocking
|
||||
* the directory to insure that the inode will not be removed
|
||||
* before we get it. We prevent deadlock by always fetching
|
||||
* inodes from the root, moving down the directory tree. Thus
|
||||
* when following backward pointers ".." we must unlock the
|
||||
* parent directory before getting the requested directory.
|
||||
* There is a potential race condition here if both the current
|
||||
* and parent directories are removed before the `iget' for the
|
||||
* inode associated with ".." returns. We hope that this occurs
|
||||
* infrequently since we cannot avoid this race condition without
|
||||
* implementing a sophisticated deadlock detection algorithm.
|
||||
* Note also that this simple deadlock detection scheme will not
|
||||
* work if the file system has any hard links other than ".."
|
||||
* that point backwards in the directory structure.
|
||||
*/
|
||||
pdp = dp;
|
||||
/*
|
||||
* If ino is different from ndp->ni_ufs.ufs_ino,
|
||||
* it's a relocated directory.
|
||||
*/
|
||||
if (ndp->ni_isdotdot) {
|
||||
ISO_IUNLOCK(pdp); /* race to get the inode */
|
||||
if (error = iso_iget(dp,ndp->ni_ufs.ufs_ino,
|
||||
ndp->ni_ufs.ufs_ino != ino,
|
||||
&tdp,ep)) {
|
||||
brelse(bp);
|
||||
ISO_ILOCK(pdp);
|
||||
return error;
|
||||
}
|
||||
if (lockparent && *ndp->ni_next == '\0')
|
||||
ISO_ILOCK(pdp);
|
||||
ndp->ni_vp = ITOV(tdp);
|
||||
} else if (dp->i_number == ndp->ni_ufs.ufs_ino) {
|
||||
VREF(vdp); /* we want ourself, ie "." */
|
||||
ndp->ni_vp = vdp;
|
||||
} else {
|
||||
if (error = iso_iget(dp,ndp->ni_ufs.ufs_ino,
|
||||
ndp->ni_ufs.ufs_ino != ino,
|
||||
&tdp,ep)) {
|
||||
brelse(bp);
|
||||
return error;
|
||||
}
|
||||
if (!lockparent || *ndp->ni_next != '\0')
|
||||
ISO_IUNLOCK(pdp);
|
||||
ndp->ni_vp = ITOV(tdp);
|
||||
}
|
||||
|
||||
brelse(bp);
|
||||
|
||||
/*
|
||||
* Insert name into cache if appropriate.
|
||||
*/
|
||||
if (ndp->ni_makeentry)
|
||||
cache_enter(ndp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return buffer with contents of block "offset"
|
||||
* from the beginning of directory "ip". If "res"
|
||||
* is non-zero, fill it in with a pointer to the
|
||||
* remaining space in the directory.
|
||||
*/
|
||||
iso_blkatoff(ip, offset, bpp)
|
||||
struct iso_node *ip;
|
||||
off_t offset;
|
||||
struct buf **bpp;
|
||||
{
|
||||
register struct iso_mnt *imp = ip->i_mnt;
|
||||
daddr_t lbn = iso_lblkno(imp,offset);
|
||||
int bsize = iso_blksize(imp,ip,lbn);
|
||||
struct buf *bp;
|
||||
int error;
|
||||
|
||||
if (error = bread(ITOV(ip),lbn,bsize,NOCRED,&bp)) {
|
||||
brelse(bp);
|
||||
*bpp = 0;
|
||||
return error;
|
||||
}
|
||||
*bpp = bp;
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,642 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 1982, 1986, 1989 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)ufs_inode.c (unknown version)
|
||||
* $Id: isofs_node.c,v 1.12 1994/04/25 03:49:30 cgd Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <isofs/iso.h>
|
||||
#include <isofs/isofs_node.h>
|
||||
#include <isofs/iso_rrip.h>
|
||||
|
||||
#define IFTOVT(mode) (iftovt_tab[((mode) & 0170000) >> 12])
|
||||
static enum vtype iftovt_tab[16] = {
|
||||
VNON, VFIFO, VCHR, VNON, VDIR, VNON, VBLK, VNON,
|
||||
VREG, VNON, VLNK, VNON, VSOCK, VNON, VNON, VBAD,
|
||||
};
|
||||
|
||||
#define INOHSZ 512
|
||||
#if ((INOHSZ&(INOHSZ-1)) == 0)
|
||||
#define INOHASH(dev,ino) (((dev)+((ino)>>12))&(INOHSZ-1))
|
||||
#else
|
||||
#define INOHASH(dev,ino) (((unsigned)((dev)+((ino)>>12)))%INOHSZ)
|
||||
#endif
|
||||
|
||||
union iso_ihead {
|
||||
union iso_ihead *ih_head[2];
|
||||
struct iso_node *ih_chain[2];
|
||||
} iso_ihead[INOHSZ];
|
||||
|
||||
#ifdef ISODEVMAP
|
||||
#define DNOHSZ 64
|
||||
#if ((DNOHSZ&(DNOHSZ-1)) == 0)
|
||||
#define DNOHASH(dev,ino) (((dev)+((ino)>>12))&(DNOHSZ-1))
|
||||
#else
|
||||
#define DNOHASH(dev,ino) (((unsigned)((dev)+((ino)>>12)))%DNOHSZ)
|
||||
#endif
|
||||
|
||||
union iso_dhead {
|
||||
union iso_dhead *dh_head[2];
|
||||
struct iso_dnode *dh_chain[2];
|
||||
} iso_dhead[DNOHSZ];
|
||||
#endif
|
||||
|
||||
int prtactive; /* 1 => print out reclaim of active vnodes */
|
||||
|
||||
/*
|
||||
* 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))
|
||||
panic("ihinit: too small");
|
||||
#endif /* not lint */
|
||||
for (i = INOHSZ; --i >= 0; ih++) {
|
||||
ih->ih_head[0] = ih;
|
||||
ih->ih_head[1] = ih;
|
||||
}
|
||||
#ifdef ISODEVMAP
|
||||
for (i = DNOHSZ; --i >= 0; dh++) {
|
||||
dh->dh_head[0] = dh;
|
||||
dh->dh_head[1] = dh;
|
||||
}
|
||||
#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.
|
||||
* If it is in core, wait for the lock bit to clear, then
|
||||
* return the inode locked. Detection and handling of mount
|
||||
* points must be done by the calling routine.
|
||||
*/
|
||||
iso_iget(xp, ino, relocated, ipp, isodir)
|
||||
struct iso_node *xp;
|
||||
ino_t ino;
|
||||
struct iso_node **ipp;
|
||||
struct iso_directory_record *isodir;
|
||||
{
|
||||
dev_t dev = xp->i_dev;
|
||||
struct mount *mntp = ITOV(xp)->v_mount;
|
||||
extern struct vnodeops isofs_vnodeops, isofs_spec_inodeops;
|
||||
register struct iso_node *ip, *iq;
|
||||
register struct vnode *vp;
|
||||
register struct iso_dnode *dp;
|
||||
struct vnode *nvp;
|
||||
struct buf *bp = NULL, *bp2 = NULL;
|
||||
union iso_ihead *ih;
|
||||
union iso_dhead *dh;
|
||||
int i, error, result;
|
||||
struct iso_mnt *imp;
|
||||
ino_t defino;
|
||||
|
||||
ih = &iso_ihead[INOHASH(dev, ino)];
|
||||
loop:
|
||||
for (ip = ih->ih_chain[0];
|
||||
ip != (struct iso_node *)ih;
|
||||
ip = ip->i_forw) {
|
||||
if (ino != ip->i_number || dev != ip->i_dev)
|
||||
continue;
|
||||
if ((ip->i_flag&ILOCKED) != 0) {
|
||||
ip->i_flag |= IWANT;
|
||||
sleep((caddr_t)ip, PINOD);
|
||||
goto loop;
|
||||
}
|
||||
if (vget(ITOV(ip), 1))
|
||||
goto loop;
|
||||
*ipp = ip;
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Allocate a new inode.
|
||||
*/
|
||||
if (error = getnewvnode(VT_ISOFS, mntp, &isofs_vnodeops, &nvp)) {
|
||||
*ipp = 0;
|
||||
return error;
|
||||
}
|
||||
ip = VTOI(nvp);
|
||||
ip->i_vnode = nvp;
|
||||
ip->i_flag = 0;
|
||||
ip->i_devvp = 0;
|
||||
ip->i_diroff = 0;
|
||||
ip->i_lockf = 0;
|
||||
|
||||
/*
|
||||
* Put it onto its hash chain and lock it so that other requests for
|
||||
* this inode will block if they arrive while we are sleeping waiting
|
||||
* for old data structures to be purged or for the contents of the
|
||||
* disk portion of this inode to be read.
|
||||
*/
|
||||
ip->i_dev = dev;
|
||||
ip->i_number = ino;
|
||||
insque(ip, ih);
|
||||
ISO_ILOCK(ip);
|
||||
|
||||
imp = VFSTOISOFS (mntp);
|
||||
ip->i_mnt = imp;
|
||||
ip->i_devvp = imp->im_devvp;
|
||||
VREF(ip->i_devvp);
|
||||
|
||||
if (relocated) {
|
||||
/*
|
||||
* On relocated directories we must
|
||||
* read the `.' entry out of a dir.
|
||||
*/
|
||||
ip->iso_start = ino >> imp->im_bshift;
|
||||
if (error = iso_blkatoff(ip,0,&bp)) {
|
||||
vrele(ip->i_devvp);
|
||||
remque(ip);
|
||||
ip->i_forw = ip;
|
||||
ip->i_back = ip;
|
||||
iso_iput(ip);
|
||||
*ipp = 0;
|
||||
return error;
|
||||
}
|
||||
isodir = (struct iso_directory_record *)bp->b_un.b_addr;
|
||||
}
|
||||
|
||||
ip->iso_extent = isonum_733(isodir->extent);
|
||||
ip->i_size = isonum_733(isodir->size);
|
||||
ip->iso_start = isonum_711(isodir->ext_attr_length) + ip->iso_extent;
|
||||
|
||||
vp = ITOV(ip);
|
||||
|
||||
/*
|
||||
* Setup time stamp, attribute
|
||||
*/
|
||||
vp->v_type = VNON;
|
||||
switch (imp->iso_ftype) {
|
||||
default: /* ISO_FTYPE_9660 */
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unlock and decrement the reference count of an inode structure.
|
||||
*/
|
||||
iso_iput(ip)
|
||||
register struct iso_node *ip;
|
||||
{
|
||||
|
||||
if ((ip->i_flag & ILOCKED) == 0)
|
||||
panic("iso_iput");
|
||||
ISO_IUNLOCK(ip);
|
||||
vrele(ITOV(ip));
|
||||
}
|
||||
|
||||
/*
|
||||
* Last reference to an inode, write the inode out and if necessary,
|
||||
* truncate and deallocate the file.
|
||||
*/
|
||||
isofs_inactive(vp, p)
|
||||
struct vnode *vp;
|
||||
struct proc *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;
|
||||
/*
|
||||
* If we are done with the inode, reclaim it
|
||||
* so that it can be reused immediately.
|
||||
*/
|
||||
if (vp->v_usecount == 0 && ip->inode.iso_mode == 0)
|
||||
vgone(vp);
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reclaim an inode so that it can be used for other purposes.
|
||||
*/
|
||||
isofs_reclaim(vp)
|
||||
register struct vnode *vp;
|
||||
{
|
||||
register struct iso_node *ip = VTOI(vp);
|
||||
int i;
|
||||
|
||||
if (prtactive && vp->v_usecount != 0)
|
||||
vprint("isofs_reclaim: pushing active", vp);
|
||||
/*
|
||||
* Remove the inode from its hash chain.
|
||||
*/
|
||||
remque(ip);
|
||||
ip->i_forw = ip;
|
||||
ip->i_back = ip;
|
||||
/*
|
||||
* Purge old data structures associated with the inode.
|
||||
*/
|
||||
cache_purge(vp);
|
||||
if (ip->i_devvp) {
|
||||
vrele(ip->i_devvp);
|
||||
ip->i_devvp = 0;
|
||||
}
|
||||
ip->i_flag = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Lock an inode. If its already locked, set the WANT bit and sleep.
|
||||
*/
|
||||
iso_ilock(ip)
|
||||
register struct iso_node *ip;
|
||||
{
|
||||
|
||||
while (ip->i_flag & ILOCKED) {
|
||||
ip->i_flag |= IWANT;
|
||||
if (ip->i_spare0 == curproc->p_pid)
|
||||
panic("locking against myself");
|
||||
ip->i_spare1 = curproc->p_pid;
|
||||
(void) sleep((caddr_t)ip, PINOD);
|
||||
}
|
||||
ip->i_spare1 = 0;
|
||||
ip->i_spare0 = curproc->p_pid;
|
||||
ip->i_flag |= ILOCKED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unlock an inode. If WANT bit is on, wakeup.
|
||||
*/
|
||||
iso_iunlock(ip)
|
||||
register struct iso_node *ip;
|
||||
{
|
||||
|
||||
if ((ip->i_flag & ILOCKED) == 0)
|
||||
vprint("iso_iunlock: unlocked inode", ITOV(ip));
|
||||
ip->i_spare0 = 0;
|
||||
ip->i_flag &= ~ILOCKED;
|
||||
if (ip->i_flag&IWANT) {
|
||||
ip->i_flag &= ~IWANT;
|
||||
wakeup((caddr_t)ip);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* File attributes
|
||||
*/
|
||||
void
|
||||
isofs_defattr(isodir,inop,bp)
|
||||
struct iso_directory_record *isodir;
|
||||
struct iso_node *inop;
|
||||
struct buf *bp;
|
||||
{
|
||||
struct buf *bp2 = NULL;
|
||||
struct iso_mnt *imp;
|
||||
struct iso_extended_attributes *ap = NULL;
|
||||
int off;
|
||||
|
||||
if (isonum_711(isodir->flags)&2) {
|
||||
inop->inode.iso_mode = S_IFDIR;
|
||||
/*
|
||||
* If we return 2, fts() will assume there are no subdirectories
|
||||
* (just links for the path and .), so instead we return 1.
|
||||
*/
|
||||
inop->inode.iso_links = 1;
|
||||
} else {
|
||||
inop->inode.iso_mode = S_IFREG;
|
||||
inop->inode.iso_links = 1;
|
||||
}
|
||||
if (!bp
|
||||
&& ((imp = inop->i_mnt)->im_flags&ISOFSMNT_EXTATT)
|
||||
&& (off = isonum_711(isodir->ext_attr_length))) {
|
||||
iso_blkatoff(inop,-off * imp->logical_block_size,&bp2);
|
||||
bp = bp2;
|
||||
}
|
||||
if (bp) {
|
||||
ap = (struct iso_extended_attributes *)bp->b_un.b_addr;
|
||||
|
||||
if (isonum_711(ap->version) == 1) {
|
||||
if (!(ap->perm[0]&0x40))
|
||||
inop->inode.iso_mode |= VEXEC >> 6;
|
||||
if (!(ap->perm[0]&0x10))
|
||||
inop->inode.iso_mode |= VREAD >> 6;
|
||||
if (!(ap->perm[0]&4))
|
||||
inop->inode.iso_mode |= VEXEC >> 3;
|
||||
if (!(ap->perm[0]&1))
|
||||
inop->inode.iso_mode |= VREAD >> 3;
|
||||
if (!(ap->perm[1]&0x40))
|
||||
inop->inode.iso_mode |= VEXEC;
|
||||
if (!(ap->perm[1]&0x10))
|
||||
inop->inode.iso_mode |= VREAD;
|
||||
inop->inode.iso_uid = isonum_723(ap->owner); /* what about 0? */
|
||||
inop->inode.iso_gid = isonum_723(ap->group); /* what about 0? */
|
||||
} else
|
||||
ap = NULL;
|
||||
}
|
||||
if (!ap) {
|
||||
inop->inode.iso_mode |= VREAD|VEXEC|(VREAD|VEXEC)>>3|(VREAD|VEXEC)>>6;
|
||||
inop->inode.iso_uid = (uid_t)0;
|
||||
inop->inode.iso_gid = (gid_t)0;
|
||||
}
|
||||
if (bp2)
|
||||
brelse(bp2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Time stamps
|
||||
*/
|
||||
void
|
||||
isofs_deftstamp(isodir,inop,bp)
|
||||
struct iso_directory_record *isodir;
|
||||
struct iso_node *inop;
|
||||
struct buf *bp;
|
||||
{
|
||||
struct buf *bp2 = NULL;
|
||||
struct iso_mnt *imp;
|
||||
struct iso_extended_attributes *ap = NULL;
|
||||
int off;
|
||||
|
||||
if (!bp
|
||||
&& ((imp = inop->i_mnt)->im_flags&ISOFSMNT_EXTATT)
|
||||
&& (off = isonum_711(isodir->ext_attr_length))) {
|
||||
iso_blkatoff(inop,-off * imp->logical_block_size,&bp2);
|
||||
bp = bp2;
|
||||
}
|
||||
if (bp) {
|
||||
ap = (struct iso_extended_attributes *)bp->b_un.b_addr;
|
||||
|
||||
if (isonum_711(ap->version) == 1) {
|
||||
if (!isofs_tstamp_conv17(ap->ftime,&inop->inode.iso_atime))
|
||||
isofs_tstamp_conv17(ap->ctime,&inop->inode.iso_atime);
|
||||
if (!isofs_tstamp_conv17(ap->ctime,&inop->inode.iso_ctime))
|
||||
inop->inode.iso_ctime = inop->inode.iso_atime;
|
||||
if (!isofs_tstamp_conv17(ap->mtime,&inop->inode.iso_mtime))
|
||||
inop->inode.iso_mtime = inop->inode.iso_ctime;
|
||||
} else
|
||||
ap = NULL;
|
||||
}
|
||||
if (!ap) {
|
||||
isofs_tstamp_conv7(isodir->date,&inop->inode.iso_ctime);
|
||||
inop->inode.iso_atime = inop->inode.iso_ctime;
|
||||
inop->inode.iso_mtime = inop->inode.iso_ctime;
|
||||
}
|
||||
if (bp2)
|
||||
brelse(bp2);
|
||||
}
|
||||
|
||||
int
|
||||
isofs_tstamp_conv7(pi,pu)
|
||||
char *pi;
|
||||
struct timeval *pu;
|
||||
{
|
||||
int i;
|
||||
int crtime, days;
|
||||
int y, m, d, hour, minute, second, tz;
|
||||
|
||||
y = pi[0] + 1900;
|
||||
m = pi[1];
|
||||
d = pi[2];
|
||||
hour = pi[3];
|
||||
minute = pi[4];
|
||||
second = pi[5];
|
||||
tz = pi[6];
|
||||
|
||||
if (y < 1970) {
|
||||
pu->tv_sec = 0;
|
||||
pu->tv_usec = 0;
|
||||
return 0;
|
||||
} else {
|
||||
#ifdef ORIGINAL
|
||||
/* computes day number relative to Sept. 19th,1989 */
|
||||
/* don't even *THINK* about changing formula. It works! */
|
||||
days = 367*(y-1980)-7*(y+(m+9)/12)/4-3*((y+(m-9)/7)/100+1)/4+275*m/9+d-100;
|
||||
#else
|
||||
/*
|
||||
* Changed :-) to make it relative to Jan. 1st, 1970
|
||||
* and to disambiguate negative division
|
||||
*/
|
||||
days = 367*(y-1960)-7*(y+(m+9)/12)/4-3*((y+(m+9)/12-1)/100+1)/4+275*m/9+d-239;
|
||||
#endif
|
||||
crtime = ((((days * 24) + hour) * 60 + minute) * 60) + second;
|
||||
|
||||
/* timezone offset is unreliable on some disks */
|
||||
if (-48 <= tz && tz <= 52)
|
||||
crtime -= tz * 15 * 60;
|
||||
}
|
||||
pu->tv_sec = crtime;
|
||||
pu->tv_usec = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static unsigned
|
||||
isofs_chars2ui(begin,len)
|
||||
unsigned char *begin;
|
||||
int len;
|
||||
{
|
||||
unsigned rc;
|
||||
|
||||
for (rc = 0; --len >= 0;) {
|
||||
rc *= 10;
|
||||
rc += *begin++ - '0';
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
isofs_tstamp_conv17(pi,pu)
|
||||
unsigned char *pi;
|
||||
struct timeval *pu;
|
||||
{
|
||||
unsigned char buf[7];
|
||||
|
||||
/* year:"0001"-"9999" -> -1900 */
|
||||
buf[0] = isofs_chars2ui(pi,4) - 1900;
|
||||
|
||||
/* month: " 1"-"12" -> 1 - 12 */
|
||||
buf[1] = isofs_chars2ui(pi + 4,2);
|
||||
|
||||
/* day: " 1"-"31" -> 1 - 31 */
|
||||
buf[2] = isofs_chars2ui(pi + 6,2);
|
||||
|
||||
/* hour: " 0"-"23" -> 0 - 23 */
|
||||
buf[3] = isofs_chars2ui(pi + 8,2);
|
||||
|
||||
/* minute:" 0"-"59" -> 0 - 59 */
|
||||
buf[4] = isofs_chars2ui(pi + 10,2);
|
||||
|
||||
/* second:" 0"-"59" -> 0 - 59 */
|
||||
buf[5] = isofs_chars2ui(pi + 12,2);
|
||||
|
||||
/* difference of GMT */
|
||||
buf[6] = pi[16];
|
||||
|
||||
return isofs_tstamp_conv7(buf,pu);
|
||||
}
|
||||
|
||||
void
|
||||
isodirino(inump,isodir,imp)
|
||||
ino_t *inump;
|
||||
struct iso_directory_record *isodir;
|
||||
struct iso_mnt *imp;
|
||||
{
|
||||
*inump = (isonum_733(isodir->extent) + isonum_711(isodir->ext_attr_length))
|
||||
* imp->logical_block_size;
|
||||
}
|
Loading…
Reference in New Issue