NAME
file,
closef,
ffree,
FILE_IS_USABLE,
FILE_USE,
FILE_UNUSE,
FILE_SET_MATURE —
operations on file entries
SYNOPSIS
#include <sys/file.h>
int
closef(
struct
file *fp,
struct lwp
*l);
void
ffree(
struct file
*fp);
int
FILE_IS_USABLE(
struct
file *fp);
void
FILE_USE(
struct
file *fp);
void
FILE_UNUSE(
struct
file *fp,
struct lwp
*l);
void
FILE_SET_MATURE(
struct
file *fp);
DESCRIPTION
The file descriptor table of a process references a file entry for each file
used by the kernel. See
filedesc(9) for details of the
file descriptor table. Each file entry is given by:
struct file {
LIST_ENTRY(file) f_list; /* list of active files */
int f_flag;
int f_iflags; /* internal flags */
int f_type; /* descriptor type */
u_int f_count; /* reference count */
u_int f_msgcount; /* message queue references */
int f_usecount; /* number active users */
kauth_cred_t f_cred; /* creds associated with descriptor */
struct fileops {
int (*fo_read)(struct file *fp, off_t *offset,
struct uio *uio, kauth_cred_t cred, int flags);
int (*fo_write)(struct file *fp, off_t *offset,
struct uio *uio, kauth_cred_t cred, int flags);
int (*fo_ioctl)(struct file *fp, u_long com, void *data,
struct lwp *l);
int (*fo_fcntl)(struct file *fp, u_int com, void *data,
struct lwp *l);
int (*fo_poll)(struct file *fp, int events,
struct lwp *l);
int (*fo_stat)(struct file *fp, struct stat *sp,
struct lwp *l);
int (*fo_close)(struct file *fp, struct lwp *l);
} *f_ops;
off_t f_offset;
void *f_data; /* descriptor data */
};
NetBSD treats file entries in an object-oriented fashion
after they are created. Each entry specifies the object type,
f_type, which can have the values
DTYPE_VNODE
,
DTYPE_SOCKET
,
DTYPE_PIPE
and
DTYPE_MISC
. The
file entry also has a pointer to a data structure,
f_data,
that contains information specific to the instance of the underlying object.
The data structure is opaque to the routines that manipulate the file entry.
Each entry also contains an array of function pointers,
f_ops, that translate the generic operations on a file
descriptor into the specific action associated with its type. A reference to
the data structure is passed as the first parameter to a function that
implements a file operation. The operations that must be implemented for each
descriptor type are read, write, ioctl, fcntl, poll, stat, and close. See
vnfileops(9) for an overview
of the vnode file operations. All state associated with an instance of an
object must be stored in that instance's data structure; the underlying
objects are not permitted to manipulate the file entry themselves.
For data files, the file entry points to a
vnode(9) structure. Pipes and
sockets do not have data blocks allocated on the disk and are handled by the
special-device filesystem that calls appropriate drivers to handle I/O for
them. For pipes, the file entry points to a system block that is used during
data transfer. For sockets, the file entry points to a system block that is
used in doing interprocess communications.
The descriptor table of a process (and thus access to the objects to which the
descriptors refer) is inherited from its parent, so several different
processes may reference the same file entry. Thus, each file entry has a
reference count,
f_count. Each time a new reference is
created, the reference count is incremented. When a descriptor is closed, the
reference count is decremented. When the reference count drops to zero, the
file entry is freed.
Some file descriptor semantics can be altered through the
flags argument to the
open(2) system call. These flags
are recorded in
f_flags member of the file entry. For
example, the flags record whether the descriptor is open for reading, writing,
or both reading and writing. The following flags and their corresponding
open(2) flags are:
- FAPPEND
O_APPEND
- FASYNC
O_ASYNC
- O_FSYNC
O_SYNC
- FNDELAY
O_NONBLOCK
- O_NDELAY
O_NONBLOCK
- FNONBLOCK
O_NONBLOCK
- FFSYNC
O_SYNC
- FDSYNC
O_DSYNC
- FRSYNC
O_RSYNC
- FALTIO
O_ALT_IO
Some additional state-specific flags are recorded in the
f_iflags member. Valid values include:
FIF_WANTCLOSE
- If set, then the reference count on the file is zero, but
there were multiple users of the file. This can happen if a file
descriptor table is shared by multiple processes. This flag notifies
potential users that the file is closing and will prevent them from adding
additional uses to the file.
FIF_LARVAL
- The file entry is not fully constructed (mature) and should
not be used.
The
read(2) and
write(2) system calls do not take
an offset in the file as an argument. Instead, each read or write updates the
current file offset,
f_offset in the file according to the
number of bytes transferred. Since more than one process may open the same
file and each needs its own offset in the file, the offset cannot be stored in
the per-object data structure.
FUNCTIONS
-
-
- closef(fp,
l)
- The internal form of
close(2) which decrements the
reference count on file entry fp. The
closef() function release all locks on the file owned by
lwp l, decrements the reference count on the file
entry, and invokes ffree() to free the file entry.
-
-
- ffree(struct
file *fp)
- Free file entry fp. The file entry
was created in
falloc(9).
-
-
- FILE_IS_USABLE(fp)
- Ensure that the file entry is usable by ensuring that
neither the
FIF_WANTCLOSE
flag nor the
FIF_LARVAL
flag is set in
f_iflags.
-
-
- FILE_USE(fp)
- Increment the reference count on file entry
fp.
-
-
- FILE_UNUSE(fp,
l)
- Decrement the reference count on file entry
fp. If the
FIF_WANTCLOSE
flag is set in f_iflags, the file entry is freed.
-
-
- FILE_SET_MATURE(fp)
- Mark the file entry as being fully constructed (mature) by
clearing the
FIF_LARVAL
flag in
f_iflags.
CODE REFERENCES
The framework for file entry handling is implemented within the file
sys/kern/kern_descrip.c.
SEE ALSO
dofileread(9),
filedesc(9),
vnfileops(9),
vnode(9)