This is all preliminary.  The question is whether we can cover enough
    bases for this to be viable.

    Here is a proposed struct file.  Make f_data opaque (or more opaque),
    add f_object, extend fileops (see next structure),   Added f_vopflags
    to indicate the presence of a vnode in f_data, allowing extended 
    filesystem ops (e.g. rename, remove, fchown, etc etc etc).

struct file {
        LIST_ENTRY(file) f_list;/* list of active files */
        short   f_flag;         /* see fcntl.h */
        short   f_type;         /* descriptor type */
        short   f_vopflags;     /* extended command set flags */
        short   f_FILLER2;      /* (OLD) references from message queue */
        struct  ucred *f_cred;  /* credentials associated with descriptor */
        struct  fileops *f_ops; /* FILE OPS */
        int     f_seqcount;     /* (sequential heuristic) */
        off_t   f_nextoff;      /* (sequential heuristic) */
        off_t   f_offset;       /* seek position */
        caddr_t f_data;         /* opaque data (was vnode or socket) */
        vm_object_t f_object;   /* VM object if mmapable/cacheable, or NULL */
        int     f_count;        /* reference count */
        int     f_msgcount;     /* reference count from message queue */

        (additional elements required to support devices, maybe just
        a dev_t reference or something like that. I dunno).
};

    Proposed fileops structure (shared):  Remove ucred argument (obtain ucred
    from struct file), add additional functions.  Add cached and uncached
    versions for fo_read() ... all users will use fo_read() but this way you
    can vector fo_read() to a generic VM Object layer which can then call
    fo_readnc() for anything that can't be handled by that layer.  Same
    with fo_write().  Add additional flags to fo_writenc() to handle 
    write behind, notification that a write occured in the VM layer
    (e.g. required by NFS), and other heuristic features.

    Note the lack of any reference to the buffer cache here.  The filesystem
    is responsible for manipulation of the buffer cache if it wants to use
    the buffer cache.

    I've left the uio in for the moment since it's the most generic way
    of passing a buffer.

struct  fileops {
        int     (*fo_read)      (fp, uio, flags, p);    /* cachable */
        int     (*fo_readnc)    (fp, uio, flags, p);    /* uncached */
        int     (*fo_write)     (fp, uio, flags, p);    /* cachable */
        int     (*fo_writenc)   (fp, uio, flags, p);    /* uncached */
        int     (*fo_ioctl)     (fp, com, data, p);
        int     (*fo_poll)      (fp, events, p);
        int     (*fo_kqfilter)  (fp, knote);
        int     (*fo_stat)      (fp, stat, p);
        int     (*fo_close)     (fp, p);
        int     (*fo_mmap)      (fp, mmap_args);
        int     (*fo_dump)      ( ? )
        ... others ...
} *f_ops;

                                            -Matt


To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message

Reply via email to