94 lines
3.0 KiB
C
94 lines
3.0 KiB
C
/* @(#)rnode.h 1.1 94/10/31 SMI */
|
|
|
|
#ifndef _nfs_rnode_h
|
|
#define _nfs_rnode_h
|
|
|
|
/*
|
|
* Remote file information structure.
|
|
* The rnode is the "inode" for remote files. It contains all the
|
|
* information necessary to handle remote file on the client side.
|
|
*
|
|
* Note on file sizes: we keep two file sizes in the rnode: the size
|
|
* according to the client (r_size) and the size according to the server
|
|
* (r_attr.va_size). They can differ because we modify r_size during a
|
|
* write system call (nfs_rdwr), before the write request goes over the
|
|
* wire (before the file is actually modified on the server). If an OTW
|
|
* request occurs before the cached data is written to the server the file
|
|
* size returned from the server (r_attr.va_size) may not match r_size.
|
|
* r_size is the one we use, in general. r_attr->va_size is only used to
|
|
* determine whether or not our cached data is valid.
|
|
*/
|
|
struct rnode {
|
|
struct rnode *r_freef; /* free list forward pointer */
|
|
struct rnode *r_freeb; /* free list back pointer */
|
|
struct rnode *r_hash; /* rnode hash chain */
|
|
struct vnode r_vnode; /* vnode for remote file */
|
|
fhandle_t r_fh; /* file handle */
|
|
u_short r_flags; /* flags, see below */
|
|
short r_error; /* async write error */
|
|
union {
|
|
daddr_t R_nextr; /* next byte read offset (read-ahead) */
|
|
int R_lastcookie; /* last readdir cookie */
|
|
} r_r;
|
|
#define r_nextr r_r.R_nextr
|
|
#define r_lastcookie r_r.R_lastcookie
|
|
long r_owner; /* proc index for locker of rnode */
|
|
long r_count; /* number of rnode locks for r_owner */
|
|
struct ucred *r_cred; /* current credentials */
|
|
struct ucred *r_unlcred; /* unlinked credentials */
|
|
char *r_unlname; /* unlinked file name */
|
|
struct vnode *r_unldvp; /* parent dir of unlinked file */
|
|
u_long r_size; /* client's view of file size */
|
|
struct vattr r_attr; /* cached vnode attributes */
|
|
struct timeval r_attrtime; /* time attributes become invalid */
|
|
long r_opencnt; /* count of open references */
|
|
};
|
|
|
|
|
|
/*
|
|
* Flags
|
|
*/
|
|
#define RLOCKED 0x01 /* rnode is in use */
|
|
#define RWANT 0x02 /* someone wants a wakeup */
|
|
#define RATTRVALID 0x04 /* Attributes in the rnode are valid */
|
|
#define REOF 0x08 /* EOF encountered on readdir */
|
|
#define RDIRTY 0x10 /* dirty pages from write operation */
|
|
|
|
/*
|
|
* Convert between vnode and rnode
|
|
*/
|
|
#define rtov(rp) (&(rp)->r_vnode)
|
|
#define vtor(vp) ((struct rnode *)((vp)->v_data))
|
|
#define vtofh(vp) (&(vtor(vp)->r_fh))
|
|
#define rtofh(rp) (&(rp)->r_fh)
|
|
|
|
/*
|
|
* Lock and unlock rnodes.
|
|
*/
|
|
#define RLOCK(rp) { \
|
|
while (((rp)->r_flags & RLOCKED) && \
|
|
(rp)->r_owner != uniqpid()) { \
|
|
(rp)->r_flags |= RWANT; \
|
|
(void) sleep((caddr_t)(rp), PINOD); \
|
|
} \
|
|
(rp)->r_owner = uniqpid(); \
|
|
(rp)->r_count++; \
|
|
(rp)->r_flags |= RLOCKED; \
|
|
masterprocp->p_swlocks++; \
|
|
}
|
|
|
|
#define RUNLOCK(rp) { \
|
|
if (--(rp)->r_count < 0) \
|
|
panic("RUNLOCK"); \
|
|
masterprocp->p_swlocks--; \
|
|
if ((rp)->r_count == 0) { \
|
|
(rp)->r_flags &= ~RLOCKED; \
|
|
if ((rp)->r_flags & RWANT) { \
|
|
(rp)->r_flags &= ~RWANT; \
|
|
wakeup((caddr_t)(rp)); \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
#endif /*!_nfs_rnode_h*/
|