next up previous contents
Next: 10.2 Gzipfs: An In-Core Up: 10. Extended Examples Using Previous: 10. Extended Examples Using

   
10.1 Crossfs: A Stateless File System

Crossfs is a trivial file system based on my Null file system (Appendix sec-appendix-typical-stateless-nullfs). When a lookup operation crosses into this file system, it performs a simple action such as logging a message on the system console. For all other vnode and vfs operations, it forwards them to the interposed file system. Crossfs keeps no state.

The example of Figure fig-fist-definition-crossfs shows the FiST input for this file system. Specifically, in this implementation I wish to log the user ID and the host from where access to the files originated.


  
Figure: FiST Definition for Crossfs

Figure: FiST Definition for Crossfs


%{
#ifdef HAVE_AC_CONFIG_H
/* include Autoconf-generated header */
# include "config.h"
#endif
%}

%fstype stateless
%filter syslog(%cur_uid, %from_host) $$ vn_lookup {%cur_uid > 999 && %cur_uid != 2301}

%%
  /* Empty FiST rules section */
%%
  /* No additional code needed */





6.5in


%{
#ifdef HAVE_AC_CONFIG_H
/* include Autoconf-generated header */
# include "config.h"
#endif
%}

%fstype stateless
%filter syslog(%cur_uid, %from_host) $$ vn_lookup {%cur_uid > 999 && %cur_uid != 2301}

%%
  /* Empty FiST rules section */
%%
  /* No additional code needed */

The code automatically generated for Crossfs will be identical to Nullfs, with the exception of the lookup function. One possible code for the lookup function is shown in Figure fig-fist-definition-crossfs-code.


  
Figure: Vnode Code Automatically Generated by FiST for Crossfs

Figure: Vnode Code Automatically Generated by FiST for Crossfs


static int
fist_crossfs_lookup( vnode_t *dvp, char *name, vnode_t **vpp,
                     pathname_t *pnp, int flags, vnode_t *rdir, cred_t *cr)
{
  /* check if event should be logged */
  if (u.u_uid > 999 && u.u_uid != 2301)
    kernel_syslog("File %s was accessed at %d by %s@%s.\n",
                  name, curtime, u.u_uid, fist_get_from_host(u));

  /* pass operation to file system, and return status */
  return VOP_LOOKUP(dvp, name, vpp, pnp, flags, rdir, cr);
}





5.5in


static int
fist_crossfs_lookup( vnode_t *dvp, char *name, vnode_t **vpp,
                     pathname_t *pnp, int flags, vnode_t *rdir, cred_t *cr)
{
  /* check if event should be logged */
  if (u.u_uid > 999 && u.u_uid != 2301)
    kernel_syslog("File %s was accessed at %d by %s@%s.\n",
                  name, curtime, u.u_uid, fist_get_from_host(u));

  /* pass operation to file system, and return status */
  return VOP_LOOKUP(dvp, name, vpp, pnp, flags, rdir, cr);
}

This example shows how FiST ``%'' directives get translated into local variables (name), global variables (curtime), or even special functions (fist_get_from_host()).

Figure fig-fist-definition-crossfs-code-4nfs shows the code that would be generated for the NFS version of the same lookup operation.


  
Figure: NFS Code Automatically Generated by FiST for Crossfs

Figure: NFS Code Automatically Generated by FiST for Crossfs


diropres *
nfsproc2_crossfs_lookup( diropargs *argp,
                         struct svc_req *rqstp;
{
  diropres res;
  uid_t uid;
  gid_t gid;
  char host[MAXHOSTNAMELEN];
  time_t tm;

  /* get credentials */
  if (fist_getcreds(rqstp, &uid, &gid, &host) < 0)
    return(NULL);

  /* get time */
  time(&tm);

  /* check if event should be logged */
  if (uid > 999 && uid != 2301)
    syslog("File %s was accessed at %d by %s@%s.\n",
           argp->name, ctime(&tm), uid, host);

  /* perform generic lookup operation, and return status */
  res = fist_nfs_lookup(argp, rqstp);

  return &res;
}





4.3in


diropres *
nfsproc2_crossfs_lookup( diropargs *argp,
                         struct svc_req *rqstp;
{
  diropres res;
  uid_t uid;
  gid_t gid;
  char host[MAXHOSTNAMELEN];
  time_t tm;

  /* get credentials */
  if (fist_getcreds(rqstp, &uid, &gid, &host) < 0)
    return(NULL);

  /* get time */
  time(&tm);

  /* check if event should be logged */
  if (uid > 999 && uid != 2301)
    syslog("File %s was accessed at %d by %s@%s.\n",
           argp->name, ctime(&tm), uid, host);

  /* perform generic lookup operation, and return status */
  res = fist_nfs_lookup(argp, rqstp);

  return &res;
}


next up previous contents
Next: 10.2 Gzipfs: An In-Core Up: 10. Extended Examples Using Previous: 10. Extended Examples Using
Erez Zadok
1999-12-07