next up previous contents
Next: 5. Evaluation Plan Up: 4.10 User Level File Previous: 4.10.1.3 Persistent NFS File

   
4.10.2 Fan-Out in User-Level File Systems

Fan-out defines how many file systems one module can interpose upon. Inside the kernel there is no limit. The interposed vnode pointers are stored inside the interposer's private data field, then accessed as described in Section sec-design-using and depicted in Figure fig-vnode-fanout.


  
Figure: Fan-Out in Stackable Vnode File Systems

Figure: Fan-Out in Stackable Vnode File Systems


/* perform FOO operation on two interposed vnodes */
int
vn_foo(vnode_t *vp, args) {
  vnode_t *hidden_vp1 = vp->v_data->hidden[0];
  vnode_t *hidden_vp2 = vp->v_data->hidden[1];
  int error;

  error = VN_FOO(hidden_vp1, args);

  if (error)
    return(error);

  error = VN_FOO(hidden_vp2, args);

  return(error);
}





3.8in


/* perform FOO operation on two interposed vnodes */
int
vn_foo(vnode_t *vp, args) {
  vnode_t *hidden_vp1 = vp->v_data->hidden[0];
  vnode_t *hidden_vp2 = vp->v_data->hidden[1];
  int error;

  error = VN_FOO(hidden_vp1, args);

  if (error)
    return(error);

  error = VN_FOO(hidden_vp2, args);

  return(error);
}

This code is nice because it does not know about the type of the file systems it interposes upon. This is the result of having an abstract vnode interface in the first place. NFS is not an abstract interface like the vnode interface is. Therefore, an NFS module inside Amd would have to know what type of file system it is accessing:

The generated code must have some hooks that can probe an Amd server at run-time to see if the function it needs to call is local to the running process or not. This is a small complication to the generated code that may make it less clean. For example, the same vnode operation as in Figure fig-vnode-fanout, when generated for the NFS interface, would look much like the code in Figure fig-nfs-fanout.


  
Figure: Fan-Out in Stackable NFS File Systems

Figure: Fan-Out in Stackable NFS File Systems


/* perform FOO operation on two interposed nodes */
int
nfs_foo(fhandle_t *fhp, args)
{
  fhandle_t *hidden_fhp1 = fhp->fh_data->hidden[0];
  fhandle_t *hidden_fhp2 = fhp->fh_data->hidden[1];
  int error;

  /* find type of first handle, and call it */
  if (file_system_local_to_amd(fs_type_of(hidden_fhp1)))
    error = AMD_FOO(hidden_vhp1, args);
  else
    error = syscall(SYS_FOO, hidden_vhp1, args);

  if (error)
    return(error);

  /* find type of second handle, and call it */
  if (file_system_local_to_amd(fs_type_of(hidden_fhp2)))
    error = AMD_FOO(hidden_vhp2, args);
  else
    error = syscall(SYS_FOO, hidden_vhp2, args);

  return(error);
}





4.2in


/* perform FOO operation on two interposed nodes */
int
nfs_foo(fhandle_t *fhp, args)
{
  fhandle_t *hidden_fhp1 = fhp->fh_data->hidden[0];
  fhandle_t *hidden_fhp2 = fhp->fh_data->hidden[1];
  int error;

  /* find type of first handle, and call it */
  if (file_system_local_to_amd(fs_type_of(hidden_fhp1)))
    error = AMD_FOO(hidden_vhp1, args);
  else
    error = syscall(SYS_FOO, hidden_vhp1, args);

  if (error)
    return(error);

  /* find type of second handle, and call it */
  if (file_system_local_to_amd(fs_type_of(hidden_fhp2)))
    error = AMD_FOO(hidden_vhp2, args);
  else
    error = syscall(SYS_FOO, hidden_vhp2, args);

  return(error);
}

Additional and detailed examples of using FiST are included in Appendix sec-appendix-example.


next up previous contents
Next: 5. Evaluation Plan Up: 4.10 User Level File Previous: 4.10.1.3 Persistent NFS File
Erez Zadok
1999-12-07