next up previous contents
Next: 8.5 How It All Up: 8. Appendix: Vnode Interface Previous: 8.3 struct vnode

   
8.4 struct vnodeops

An instance of the vnode operations structure (struct vnodeops, listed in Figure fig-vnodeops-h) exists for each different type of file system. For each vnode, the vnode field v_op is set to the pointer of the operations vector of the underlying file system.


  
Figure: SunOS 5.x Vnode Operations Interface

Figure: SunOS 5.x Vnode Operations Interface


typedef struct vnodeops {
  int     (*vop_open)();
  int     (*vop_close)();
  int     (*vop_read)();
  int     (*vop_write)();
  int     (*vop_ioctl)();
  int     (*vop_setfl)();
  int     (*vop_getattr)();
  int     (*vop_setattr)();
  int     (*vop_access)();
  int     (*vop_lookup)();
  int     (*vop_create)();
  int     (*vop_remove)();
  int     (*vop_link)();
  int     (*vop_rename)();
  int     (*vop_mkdir)();
  int     (*vop_rmdir)();
  int     (*vop_readdir)();
  int     (*vop_symlink)();
  int     (*vop_readlink)();
  int     (*vop_fsync)();
  void    (*vop_inactive)();


  int     (*vop_fid)();
  void    (*vop_rwlock)();
  void    (*vop_rwunlock)();
  int     (*vop_seek)();
  int     (*vop_cmp)();
  int     (*vop_frlock)();
  int     (*vop_space)();
  int     (*vop_realvp)();
  int     (*vop_getpage)();
  int     (*vop_putpage)();
  int     (*vop_map)();
  int     (*vop_addmap)();
  int     (*vop_delmap)();
  int     (*vop_poll)();
  int     (*vop_dump)();
  int     (*vop_pathconf)();
  int     (*vop_pageio)();
  int     (*vop_dumpctl)();
  void    (*vop_dispose)();
  int     (*vop_setsecattr)();
  int     (*vop_getsecattr)();
} vnodeops_t;





4.5in


typedef struct vnodeops {
  int     (*vop_open)();
  int     (*vop_close)();
  int     (*vop_read)();
  int     (*vop_write)();
  int     (*vop_ioctl)();
  int     (*vop_setfl)();
  int     (*vop_getattr)();
  int     (*vop_setattr)();
  int     (*vop_access)();
  int     (*vop_lookup)();
  int     (*vop_create)();
  int     (*vop_remove)();
  int     (*vop_link)();
  int     (*vop_rename)();
  int     (*vop_mkdir)();
  int     (*vop_rmdir)();
  int     (*vop_readdir)();
  int     (*vop_symlink)();
  int     (*vop_readlink)();
  int     (*vop_fsync)();
  void    (*vop_inactive)();


  int     (*vop_fid)();
  void    (*vop_rwlock)();
  void    (*vop_rwunlock)();
  int     (*vop_seek)();
  int     (*vop_cmp)();
  int     (*vop_frlock)();
  int     (*vop_space)();
  int     (*vop_realvp)();
  int     (*vop_getpage)();
  int     (*vop_putpage)();
  int     (*vop_map)();
  int     (*vop_addmap)();
  int     (*vop_delmap)();
  int     (*vop_poll)();
  int     (*vop_dump)();
  int     (*vop_pathconf)();
  int     (*vop_pageio)();
  int     (*vop_dumpctl)();
  void    (*vop_dispose)();
  int     (*vop_setsecattr)();
  int     (*vop_getsecattr)();
} vnodeops_t;

Each field of the structure is assigned a pointer to a function that implements a particular operation on the file system in question:

Vnode operations get invoked transparently via macros that dereference the operations vector's field for that operation, and pass along the vnode and the arguments it needs. Each vnode operation has a macro associated with it, located in <sys/vnode.h>. Figure fig-vnode-mac shows as an example, the definitions for some of these calls.


  
Figure: Some Vnode Macros

Figure: Some Vnode Macros


#define VOP_OPEN(vpp, mode, cr)        (*(*(vpp))->v_op->vop_open)(vpp, mode, cr)
#define VOP_CLOSE(vp, f, c, o, cr)     (*(vp)->v_op->vop_close)(vp, f, c, o, cr)
#define VOP_READ(vp, uiop, iof, cr)    (*(vp)->v_op->vop_read)(vp, uiop, iof, cr)
#define VOP_MKDIR(dp, p, vap, vpp, cr) (*(dp)->v_op->vop_mkdir)(dp, p, vap, vpp, cr)
#define VOP_GETATTR(vp, vap, f, cr)    (*(vp)->v_op->vop_getattr)(vp, vap, f, cr)
#define VOP_LOOKUP(vp, cp, vpp, pnp, f, rdir, cr) \
                            (*(vp)->v_op->vop_lookup)(vp, cp, vpp, pnp, f, rdir, cr)
#define VOP_CREATE(dvp, p, vap, ex, mode, vpp, cr) \
                          (*(dvp)->v_op->vop_create)(dvp, p, vap, ex, mode, vpp, cr)





6.3in


#define VOP_OPEN(vpp, mode, cr)        (*(*(vpp))->v_op->vop_open)(vpp, mode, cr)
#define VOP_CLOSE(vp, f, c, o, cr)     (*(vp)->v_op->vop_close)(vp, f, c, o, cr)
#define VOP_READ(vp, uiop, iof, cr)    (*(vp)->v_op->vop_read)(vp, uiop, iof, cr)
#define VOP_MKDIR(dp, p, vap, vpp, cr) (*(dp)->v_op->vop_mkdir)(dp, p, vap, vpp, cr)
#define VOP_GETATTR(vp, vap, f, cr)    (*(vp)->v_op->vop_getattr)(vp, vap, f, cr)
#define VOP_LOOKUP(vp, cp, vpp, pnp, f, rdir, cr) \
                            (*(vp)->v_op->vop_lookup)(vp, cp, vpp, pnp, f, rdir, cr)
#define VOP_CREATE(dvp, p, vap, ex, mode, vpp, cr) \
                          (*(dvp)->v_op->vop_create)(dvp, p, vap, ex, mode, vpp, cr)

When any piece of file system code, that has a handle on a vnode, wants to call a vnode operation on it, it simply dereferences the macro, as depicted in Figure fig-vnode-mac-ex.


  
Figure: Vnode Macros Usage Example

Figure: Vnode Macros Usage Example


int foo(vnode_t *dp, char *name,
        vattr_t *vap, vnode_t **vpp, cred_t *cr)
{
  int error;

  error = VOP_MKDIR(dp, name, vap, vpp, cr);
  if (error)
    return (error);
}





3.5in


int foo(vnode_t *dp, char *name,
        vattr_t *vap, vnode_t **vpp, cred_t *cr)
{
  int error;

  error = VOP_MKDIR(dp, name, vap, vpp, cr);
  if (error)
    return (error);
}


next up previous contents
Next: 8.5 How It All Up: 8. Appendix: Vnode Interface Previous: 8.3 struct vnode
Erez Zadok
1999-12-07