Files
Arquivotheca.SunOS-4.1.4/sys/specfs/snode.h
seta75D ff309bfe1c Init
2021-10-11 18:37:13 -03:00

124 lines
3.7 KiB
C

/* @(#)snode.h 1.1 94/10/31 SMI */
#ifndef _specfs_snode_h
#define _specfs_snode_h
/*
* Copyright (c) 1987 by Sun Microsystems, Inc.
*/
/*
* The SNODE represents a special file in any filesystem. There is
* one snode for each active special file. Filesystems which support
* special files use specvp(vp, dev) to convert a normal vnode to a
* special vnode in the ops create, mkdir, and lookup.
*
* To handle having multiple snodes which represent the same
* underlying block device vnode without cache aliasing problems,
* the s_bdevvp is used to point to the "common" vnode used for
* caching data. If an snode is created internally by the kernel,
* then the s_realvp field is NULL and s_bdevvp points to s_vnode.
* The other snodes which are created as a result of a lookup of a
* device in a file system have s_realvp pointing to the vp which
* represents the device in the file system while the s_bdevvp points
* into the "common" vnode for the block device in another snode.
*/
struct snode {
struct snode *s_next; /* must be first */
struct vnode s_vnode; /* vnode associated with this snode */
struct vnode *s_realvp; /* vnode for the fs entry (if any) */
struct vnode *s_bdevvp; /* blk device vnode (for caching) */
u_short s_flag; /* flags, see below */
dev_t s_dev; /* device the snode represents */
daddr_t s_nextr; /* next byte read offset (read-ahead) */
daddr_t s_size; /* block device size in bytes */
struct timeval s_atime; /* time of last access */
struct timeval s_mtime; /* time of last modification */
struct timeval s_ctime; /* time of last attributes change */
int s_count; /* count of opened references */
long s_owner; /* index of process locking snode */
long s_lckcnt; /* number of processes locking snode */
};
/* flags */
#define SLOCKED 0x01 /* snode is locked */
#define SUPD 0x02 /* update device access time */
#define SACC 0x04 /* update device modification time */
#define SCLOSING 0x08 /* device is being closed */
#define SWANT 0x10 /* some process waiting on lock */
#define SCHG 0x40 /* update device change time */
/*
* Convert between vnode and snode
*/
#define VTOS(vp) ((struct snode *)((vp)->v_data))
#define STOV(sp) (&(sp)->s_vnode)
#ifdef KERNEL
/*
* Lock and unlock snodes.
*/
#define SNLOCK(sp) { \
while (((sp)->s_flag & SLOCKED) && \
(sp)->s_owner != uniqpid()) { \
(sp)->s_flag |= SWANT; \
(void) sleep((caddr_t)(sp), PINOD); \
} \
(sp)->s_owner = uniqpid(); \
(sp)->s_lckcnt++; \
(sp)->s_flag |= SLOCKED; \
masterprocp->p_swlocks++; \
}
#define SNUNLOCK(sp) { \
if (--(sp)->s_lckcnt < 0) \
panic("SNUNLOCK"); \
masterprocp->p_swlocks--; \
if ((sp)->s_lckcnt == 0) { \
(sp)->s_flag &= ~SLOCKED; \
if ((sp)->s_flag & SWANT) { \
(sp)->s_flag &= ~SWANT; \
wakeup((caddr_t)(sp)); \
} \
} \
}
/*
* Construct a spec vnode for a given device that shadows a particular
* "real" vnode.
*/
extern struct vnode *specvp();
/*
* Construct a spec vnode for a given device that shadows nothing.
*/
extern struct vnode *makespecvp();
/*
* Find any other spec vnode that refers to the same device as another vnode.
*/
extern struct vnode *other_specvp();
/*
* Find and hold the spec vnode that refers to the given device.
*/
extern struct vnode *slookup();
/*
* Snode lookup stuff.
* These routines maintain a table of snodes hashed by dev so
* that the snode for an dev can be found if it already exists.
* NOTE: STABLESIZE must be a power of 2 for STABLEHASH to work!
*/
#define STABLESIZE 16
#define STABLEHASH(dev) ((major(dev) + minor(dev)) & (STABLESIZE - 1))
extern struct snode *stable[];
extern struct vnodeops spec_vnodeops;
#endif KERNEL
#endif /*!_specfs_snode_h*/