* Copyright (c) 1982, 1986, 1989 Regents of the University of California.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 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
#if ((INOHSZ&(INOHSZ-1)) == 0)
#define INOHASH(dev,ino) (((dev)+(ino))&(INOHSZ-1))
#define INOHASH(dev,ino) (((unsigned)((dev)+(ino)))%INOHSZ)
union iso_ihead
*ih_head
[2];
struct iso_node
*ih_chain
[2];
int prtactive
; /* 1 => print out reclaim of active vnodes */
* Initialize hash links for inodes.
register union iso_ihead
*ih
= iso_ihead
;
if (VN_MAXPRIVATE
< sizeof(struct iso_node
))
panic("ihinit: too small");
for (i
= INOHSZ
; --i
>= 0; ih
++) {
* 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
, ipp
, isodir
)
struct iso_directory_record
*isodir
;
struct mount
*mntp
= ITOV(xp
)->v_mount
;
extern struct vnodeops isofs_vnodeops
, spec_inodeops
;
register struct iso_node
*ip
, *iq
;
register struct vnode
*vp
;
ih
= &iso_ihead
[INOHASH(dev
, ino
)];
for (ip
= ih
->ih_chain
[0];
ip
!= (struct iso_node
*)ih
;
if (ino
!= ip
->i_number
|| dev
!= ip
->i_dev
)
if ((ip
->i_flag
&ILOCKED
) != 0) {
sleep((caddr_t
)ip
, PINOD
);
if (error
= getnewvnode(VT_ISOFS
, mntp
, &isofs_vnodeops
, &nvp
)) {
* 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
->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
);
bcopy (isodir
->date
, ip
->iso_time
, sizeof ip
->iso_time
);
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
);
* Initialize the associated vnode
if (ino
== imp
->root_extent
)
* Finish inode initialization.
ip
->i_devvp
= imp
->im_devvp
;
* Unlock and decrement the reference count of an inode structure.
register struct iso_node
*ip
;
if ((ip
->i_flag
& ILOCKED
) == 0)
* Last reference to an inode, write the inode out and if necessary,
* truncate and deallocate the file.
register struct iso_node
*ip
= VTOI(vp
);
if (prtactive
&& vp
->v_usecount
!= 0)
vprint("isofs_inactive: pushing active", vp
);
* 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 */)
* Reclaim an inode so that it can be used for other purposes.
register struct vnode
*vp
;
register struct iso_node
*ip
= VTOI(vp
);
if (prtactive
&& vp
->v_usecount
!= 0)
vprint("isofs_reclaim: pushing active", vp
);
* Remove the inode from its hash chain.
* Purge old data structures associated with the inode.
* Lock an inode. If its already locked, set the WANT bit and sleep.
register struct iso_node
*ip
;
while (ip
->i_flag
& ILOCKED
) {
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_spare0
= curproc
->p_pid
;
* Unlock an inode. If WANT bit is on, wakeup.
register struct iso_node
*ip
;
if ((ip
->i_flag
& ILOCKED
) == 0)
vprint("iso_iunlock: unlocked inode", ITOV(ip
));