public inbox for systemtap@sourceware.org
 help / color / mirror / Atom feed
* Re: [ltc-perf]  draft of nfs event hook
       [not found] <OF053E04B8.D96A9ADC-ON482571B7.0031B2AD-482571B7.00323E27@cn.ibm.com>
@ 2006-07-27 13:56 ` Li Guanglei
  2006-07-27 15:29   ` [NFS] " Chuck Lever
  2006-08-11  1:59   ` Xue Peng Li
  0 siblings, 2 replies; 8+ messages in thread
From: Li Guanglei @ 2006-07-27 13:56 UTC (permalink / raw)
  To: systemtap, nfs

Hi,

   The NFS trace hooks we are working on will be part of the trace 
hooks of LKET, which is a system trace tool and we mainly use it for 
performance analysis.

   LKET is a dynamic trace facility based on SystemTap. It is actually 
implemented as SystemTap's tapsets library and it has been integrated 
into SystemTap already. For more info of LKET, you can refer to:

http://sourceware.org/systemtap/man5/lket.5.html

   When we started working on NFS trace hooks, we realized it is not 
an easy task. Although we use NFS in daily work but we don't have much 
knowledge about the NFS protocol details and its implementation inside 
the Kernel. So I divided the work into two steps. At the first step I 
need get a list of trace points. And at the second step I need to make 
sure what trace data is available for each trace hook. In a short, the 
trace data available for each hook will be derived from the arguments 
of the kernel functions being probed.

   We read through the Kernel source code and chose some functions to 
be instrumented. We will trace the entry of these functions and if 
necessary, the return of them will also be traced. The following is 
the list of these functions, please take a review:

==================== Client Side ==========================

<1> nfs directory operations

      All functions from nfs_dir_operations:

       const struct file_operations nfs_dir_operations = {
         .llseek         = nfs_llseek_dir,
         .read           = generic_read_dir,
         .readdir        = nfs_readdir,
         .open           = nfs_opendir,
         .release        = nfs_release,
         .fsync          = nfs_fsync_dir,
};

<2> nfs file operations

     All functions from nfs_file_operations:

     const struct file_operations nfs_file_operations = {
         .llseek         = nfs_file_llseek,
         .read           = do_sync_read,
         .write          = do_sync_write,
         .aio_read               = nfs_file_read,
         .aio_write              = nfs_file_write,
         .mmap           = nfs_file_mmap,
         .open           = nfs_file_open,
         .flush          = nfs_file_flush,
         .release        = nfs_file_release,
         .fsync          = nfs_fsync,
         .lock           = nfs_lock,
         .flock          = nfs_flock,
         .sendfile       = nfs_file_sendfile,
         .check_flags    = nfs_check_flags,
};

<3> nfs address space operations:
     All functions from nfs_file_aops:

       struct address_space_operations nfs_file_aops = {
         .readpage = nfs_readpage,
         .readpages = nfs_readpages,
         .set_page_dirty = __set_page_dirty_nobuffers,
         .writepage = nfs_writepage,
         .writepages = nfs_writepages,
         .prepare_write = nfs_prepare_write,
         .commit_write = nfs_commit_write,
         .invalidatepage = nfs_invalidate_page,
         .releasepage = nfs_release_page,
#ifdef CONFIG_NFS_DIRECTIO
         .direct_IO = nfs_direct_IO,
#endif
      };

<4> NFS RPC procedures:

    All functions from nfs_v[2,3,4]_clientops:
     I only list the nfs_v3 rpc procedures:
      struct nfs_rpc_ops      nfs_v3_clientops = {
         .version        = 3,                    /* protocol version */
         .dentry_ops     = &nfs_dentry_operations,
         .dir_inode_ops  = &nfs3_dir_inode_operations,
         .file_inode_ops = &nfs3_file_inode_operations,
         .getroot        = nfs3_proc_get_root,
         .getattr        = nfs3_proc_getattr,
         .setattr        = nfs3_proc_setattr,
         .lookup         = nfs3_proc_lookup,
         .access         = nfs3_proc_access,
         .readlink       = nfs3_proc_readlink,
         .read           = nfs3_proc_read,
         .write          = nfs3_proc_write,
         .commit         = nfs3_proc_commit,
         .create         = nfs3_proc_create,
         .remove         = nfs3_proc_remove,
         .unlink_setup   = nfs3_proc_unlink_setup,
         .unlink_done    = nfs3_proc_unlink_done,
         .rename         = nfs3_proc_rename,
         .link           = nfs3_proc_link,
         .symlink        = nfs3_proc_symlink,
         .mkdir          = nfs3_proc_mkdir,
         .rmdir          = nfs3_proc_rmdir,
         .readdir        = nfs3_proc_readdir,
         .mknod          = nfs3_proc_mknod,
         .statfs         = nfs3_proc_statfs,
         .fsinfo         = nfs3_proc_fsinfo,
         .pathconf       = nfs3_proc_pathconf,
         .decode_dirent  = nfs3_decode_dirent,
         .read_setup     = nfs3_proc_read_setup,
         .read_done      = nfs3_read_done,
         .write_setup    = nfs3_proc_write_setup,
         .write_done     = nfs3_write_done,
         .commit_setup   = nfs3_proc_commit_setup,
         .commit_done    = nfs3_commit_done,
         .file_open      = nfs_open,
         .file_release   = nfs_release,
         .lock           = nfs3_proc_lock,
         .clear_acl_cache = nfs3_forget_cached_acls,
     };

   The LKET already has syscall and iosyscall trace hooks. So with the 
above trace hooks, LKET could trace different layer of NFS operations:
    --> Syscall
       --> struct file_operations
           --> struct address_space_operations
                --> struct nfs_rpc_ops

======================= Server Side =============================

<1> nfsd_dispatch
    This is the NFS dispatching function sit on top of RPC.

<2> NFS RPC procedures:

     For NFSv4, it will be nfsd4_proc_compound

     For NFSv2, NFSv3, it will be the functions from nfsd_procedures[2,3]

     Here is a list for NFSv3, NFSv2 are almost the same:
       nfsd3_proc_null,
       nfsd3_proc_getattr,
       nfsd3_proc_setattr,
       nfsd3_proc_lookup,
       nfsd3_proc_access,
       nfsd3_proc_readlink,
       nfsd3_proc_read,
       nfsd3_proc_write,
       nfsd3_proc_create,
       nfsd3_proc_mkdir,
       nfsd3_proc_symlink,
       nfsd3_proc_mknod,
       nfsd3_proc_remove,
       nfsd3_proc_rmdir,
       nfsd3_proc_rename,
       nfsd3_proc_link,
       nfsd3_proc_readdir,
       nfsd3_proc_readdirplus,readdirplus,
       nfsd3_proc_fsstat,
       nfsd3_proc_fsinfo,
       nfsd3_proc_pathconf,
       nfsd3_proc_commit,

<3> NFSD file VFS operations

      The functions nfsd_xxx from "fs/nfsd/vfs.c"

With the above server side trace hooks, LKET could trace NFS 
operations at different layer:

      nfsd_dispatch -->
         --> NFS RPC Procedures
            --> NFS VFS file operations


   What I didn't list about NFS operations includes authentication, 
NFSv4 callback and RPC(I prefer to use a separate set of trace hooks 
for RPC). I am not sure if these operations are also required to be 
traced. If I missed some important functions or I listed some 
redundant functions, please feel free to let me know. Any comments 
will be highly appreciated.

   Thanks.

The following is from Li Xuepeng posted on nfs@lists.sourceforge.net 
which involved some implementations details and its trace point lists 
is a subset of the above.

- Guanglei

Xue Peng Li ??:
> Hi folks,
> 
> I am working on NFS trace hooks for SystemTap/LKET. These trace
> hooks could be used for performance analyzing which will trace both
> NFS client and server side activities.
> 
> At the first step I need make sure that the trace hooks I defined
> are appropriate and every trace hook probes the right places inside
> the Kernel. So I will be appreciated if you could help me review the
> following trace hooks.
> 
> 
> Thanks
> 
> ======================== NFS Client Side Trace Hooks =================
> 
> The following event hooks are used to trace nfs client activities.
> These event hooks are divided into two groups. Probe Point and
> Description is given for each event hook.
> 
> Group1:
> It contains 15 event hooks, which are used to probe Client-side
> NFS procedures.
> ---------------------------------------------------------------------
> addevent.nfs.proc.read_setup
> Probe Point:
> nfs_proc_read_setup,nfs3_proc_read_setup, nfs4_proc_read_setup
> Description:
> Setup a rpc task to prepare for reading
> ---------------------------------------------------------------------
> addevent.nfs.proc.read_done
> Probe Point:
> nfs_proc_read_done,nfs3_proc_read_done,
> nfs4_proc_read_done
> Description:
> Fires when receive a read reply from server,it is used to
> refresh the inode on client
> ---------------------------------------------------------------------
> addevnet.nfs.proc.read
> Probe Point:
> nfs_proc_read,nfs3_proc_read,nfs4_proc_read
> Description:
> Send a read operation to server,and refresh local inode after
> receive reply from server
> ---------------------------------------------------------------------
> addevent.nfs.proc.write_setup
> Probe Point:
> nfs_proc_write_setup,nfs3_proc_write_setup,nfs4_proc_write_setup
> Description:
> ---------------------------------------------------------------------
> addevent.nfs.proc.write
> Probe Point:
> nfs_proc_write,nfs3_proc_write,nfs4_proc_write
> Description:
> Send a write operation to server
> ---------------------------------------------------------------------
> addevent.nfs.proc.write_done
> Probe Point:
> nfs_write_done,nfs3_write_done,nfs4_write_done
> Description:
> Fires when receive a write reply from server,it is used to
> refresh the inode on client
> ---------------------------------------------------------------------
> addevent.nfs.proc.open
> Probe Point:
> nfs_open
> Description:
> Allocate file read/write context information
> ---------------------------------------------------------------------
> addevent.nfs.proc.release
> Probe Point:
> nfs_release
> Description:
> Release file read/write context information
> ---------------------------------------------------------------------
> addevent.nfs.proc.create
> Probe Point:
> nfs_create
> Description:
> Create a new file or dir on server
> _____________________________________________________________________
> 
> Group2:
> This group includes the event hooks which probe NFS address space
> operation related function.All the functions are common in NFSV2,
> NFSV3,NFSV4.
> ---------------------------------------------------------------------
> addevent.nfs.aops.readpage
> Probe Point:
> nfs_readpage
> Description :
> Read the page ,only fires when a previous async read operation
> failed
> ---------------------------------------------------------------------
> addevent.nfs.aops.readpages
> Probe Point:
> nfs_readpages
> Description:
> Fires when in readahead way,read several pages once
> ---------------------------------------------------------------------
> addevent.nfs.aops.writepage
> Probe Point:
> nfs_writepage
> Description:
> Write an mapped page to the server
> ---------------------------------------------------------------------
> addevent.nfs.aops.writepages
> Probe Point:
> nfs_writepages
> Description:
> Write several dirty pages to the serve once
> ---------------------------------------------------------------------
> addevent.nfs.aops.prepare_write
> Probe Point:
> prepare_write
> Description:
> Prepare a page for writing. Look for a request corresponding
> to the page. If there is one, and it belongs to another aops,
> we flush it out before we try to copy anything into the page.
> Also do the same if we find a request from an existing
> dropped page.
> ---------------------------------------------------------------------
> addevent.nfs.aops.commit_write
> Probe Point:
> nfs_commit_write
> Description :
> Update and possibly write a cached page of an NFS aops
> _____________________________________________________________________
> 
> 
> ====================== NFS Server Side Trace Hooks ==================
> 
> The following event hooks are used to traced nfs server activities.
> The event hooks are divided into three group.
> 
> Group1:
> It contains one event hook,which probes nfsd_dispatch
> ---------------------------------------------------------------------
> addevent.nfsd.dispatch
> Probe Point:
> nfsd_dispatch
> Description:
> Decode the arguments received from client,call the procedure
> handler,encode the result
> ______________________________________________________________________
> Group2:
> It contains three event hooks.The functions probed will be called
> by related procedure handler. All the functions are common in NFSV2,
> NFSV3,NFSV4
> ---------------------------------------------------------------------
> addevent.nfsd.read
> Probe Point:
> nfsd_read
> Description:
> It does the "real" work of read
> ---------------------------------------------------------------------
> addevent.nfsd.write
> Probe Point:
> nfsd_write
> Description:
> It does the "real " work of write
> ---------------------------------------------------------------------
> addevent.nfsd.open
> Probe Point:
> nfsd_open
> Description:
> Open an existing file or directory.
> ---------------------------------------------------------------------
> addevent.nfsd.close
> Probe Point:
> nfsd_close
> Description:
> Close an existing file or directory
> _____________________________________________________________________
> Group3:
> It contains eight event hooks,which probe procedure handlers.
> ---------------------------------------------------------------------
> addevent.nfsd.proc2.read
> Probe Point:
> nfsd_proc_read
> Description:
> Read data from file (NFSV2)
> ---------------------------------------------------------------------
> addevent.nfsd.proc3.read
> Probe Point:
> nfsd3_proc_read
> Description:
> Read data from file (NFSV3)
> ---------------------------------------------------------------------
> addevent.nfsd.proc4.read
> Probe Point:
> nfsd4_read
> Description:
> Check stateid and prepare for reading
> ---------------------------------------------------------------------
> addevent.nfsd.proc2.write
> Probe Point:
> nfsd_proc_write
> Description:
> Write data to file (NFSV2)
> ---------------------------------------------------------------------
> addevent.nfsd.pro3.write
> Probe Point:
> nfsd3_proc_write
> Description:
> Write data to file (NFSV3)
> ---------------------------------------------------------------------
> addevent.nfsd.proc4.write
> Probe Point:
> nfsd4_write
> Description:
> Check stateid and write data to file
> ---------------------------------------------------------------------
> addevent.nfsd.proc4.open
> Probe Point:
> nfsd4_open
> Description:
> Check stateid and open file
> ---------------------------------------------------------------------
> addevent.nfsd.proc4.compound
> Probe Point:
> nfsd4_proc_compound
> Description:
> Call different procedures according to client request
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> ltc-perf mailing list
> ltc-perf@linux.ibm.com
> http://linux.ibm.com/mailman/listinfo/ltc-perf


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [NFS] [ltc-perf] draft of nfs event hook
  2006-07-27 13:56 ` [ltc-perf] draft of nfs event hook Li Guanglei
@ 2006-07-27 15:29   ` Chuck Lever
  2006-07-27 17:01     ` Jose R. Santos
  2006-07-27 22:46     ` Li Guanglei
  2006-08-11  1:59   ` Xue Peng Li
  1 sibling, 2 replies; 8+ messages in thread
From: Chuck Lever @ 2006-07-27 15:29 UTC (permalink / raw)
  To: Li Guanglei; +Cc: systemtap, nfs

On 7/27/06, Li Guanglei <guanglei@cn.ibm.com> wrote:
>    When we started working on NFS trace hooks, we realized it is not
> an easy task. Although we use NFS in daily work but we don't have much
> knowledge about the NFS protocol details and its implementation inside
> the Kernel. So I divided the work into two steps. At the first step I
> need get a list of trace points. And at the second step I need to make
> sure what trace data is available for each trace hook. In a short, the
> trace data available for each hook will be derived from the arguments
> of the kernel functions being probed.
>
>    We read through the Kernel source code and chose some functions to
> be instrumented. We will trace the entry of these functions and if
> necessary, the return of them will also be traced. The following is
> the list of these functions, please take a review:

Have you done this with a local file system?  I assume yes, and that
you just described the general approach you have taken with other file
systems.  I think getting the same kind of data and trace points from
the NFS client as you added to local file systems would be good.

Capturing VFS and address space entry points is definitely useful and
is similar to local file systems.  At the bottom of the NFS client is
the RPC client, and it acts just like the block I/O layer does for
local file systems.  Would you consider adding trace points in the
LKET for the RPC client and server?




> ==================== Client Side ==========================
>
> <1> nfs directory operations
>
>       All functions from nfs_dir_operations:
>
>        const struct file_operations nfs_dir_operations = {
>          .llseek         = nfs_llseek_dir,
>          .read           = generic_read_dir,
>          .readdir        = nfs_readdir,
>          .open           = nfs_opendir,
>          .release        = nfs_release,
>          .fsync          = nfs_fsync_dir,
> };
>
> <2> nfs file operations
>
>      All functions from nfs_file_operations:
>
>      const struct file_operations nfs_file_operations = {
>          .llseek         = nfs_file_llseek,
>          .read           = do_sync_read,
>          .write          = do_sync_write,
>          .aio_read               = nfs_file_read,
>          .aio_write              = nfs_file_write,
>          .mmap           = nfs_file_mmap,
>          .open           = nfs_file_open,
>          .flush          = nfs_file_flush,
>          .release        = nfs_file_release,
>          .fsync          = nfs_fsync,
>          .lock           = nfs_lock,
>          .flock          = nfs_flock,
>          .sendfile       = nfs_file_sendfile,
>          .check_flags    = nfs_check_flags,
> };
>
> <3> nfs address space operations:
>      All functions from nfs_file_aops:
>
>        struct address_space_operations nfs_file_aops = {
>          .readpage = nfs_readpage,
>          .readpages = nfs_readpages,
>          .set_page_dirty = __set_page_dirty_nobuffers,
>          .writepage = nfs_writepage,
>          .writepages = nfs_writepages,
>          .prepare_write = nfs_prepare_write,
>          .commit_write = nfs_commit_write,
>          .invalidatepage = nfs_invalidate_page,
>          .releasepage = nfs_release_page,
> #ifdef CONFIG_NFS_DIRECTIO
>          .direct_IO = nfs_direct_IO,
> #endif
>       };
>
> <4> NFS RPC procedures:
>
>     All functions from nfs_v[2,3,4]_clientops:
>      I only list the nfs_v3 rpc procedures:
>       struct nfs_rpc_ops      nfs_v3_clientops = {
>          .version        = 3,                    /* protocol version */
>          .dentry_ops     = &nfs_dentry_operations,
>          .dir_inode_ops  = &nfs3_dir_inode_operations,
>          .file_inode_ops = &nfs3_file_inode_operations,
>          .getroot        = nfs3_proc_get_root,
>          .getattr        = nfs3_proc_getattr,
>          .setattr        = nfs3_proc_setattr,
>          .lookup         = nfs3_proc_lookup,
>          .access         = nfs3_proc_access,
>          .readlink       = nfs3_proc_readlink,
>          .read           = nfs3_proc_read,
>          .write          = nfs3_proc_write,
>          .commit         = nfs3_proc_commit,
>          .create         = nfs3_proc_create,
>          .remove         = nfs3_proc_remove,
>          .unlink_setup   = nfs3_proc_unlink_setup,
>          .unlink_done    = nfs3_proc_unlink_done,
>          .rename         = nfs3_proc_rename,
>          .link           = nfs3_proc_link,
>          .symlink        = nfs3_proc_symlink,
>          .mkdir          = nfs3_proc_mkdir,
>          .rmdir          = nfs3_proc_rmdir,
>          .readdir        = nfs3_proc_readdir,
>          .mknod          = nfs3_proc_mknod,
>          .statfs         = nfs3_proc_statfs,
>          .fsinfo         = nfs3_proc_fsinfo,
>          .pathconf       = nfs3_proc_pathconf,
>          .decode_dirent  = nfs3_decode_dirent,
>          .read_setup     = nfs3_proc_read_setup,
>          .read_done      = nfs3_read_done,
>          .write_setup    = nfs3_proc_write_setup,
>          .write_done     = nfs3_write_done,
>          .commit_setup   = nfs3_proc_commit_setup,
>          .commit_done    = nfs3_commit_done,
>          .file_open      = nfs_open,
>          .file_release   = nfs_release,
>          .lock           = nfs3_proc_lock,
>          .clear_acl_cache = nfs3_forget_cached_acls,
>      };
>
>    The LKET already has syscall and iosyscall trace hooks. So with the
> above trace hooks, LKET could trace different layer of NFS operations:
>     --> Syscall
>        --> struct file_operations
>            --> struct address_space_operations
>                 --> struct nfs_rpc_ops
>
> ======================= Server Side =============================
>
> <1> nfsd_dispatch
>     This is the NFS dispatching function sit on top of RPC.
>
> <2> NFS RPC procedures:
>
>      For NFSv4, it will be nfsd4_proc_compound
>
>      For NFSv2, NFSv3, it will be the functions from nfsd_procedures[2,3]
>
>      Here is a list for NFSv3, NFSv2 are almost the same:
>        nfsd3_proc_null,
>        nfsd3_proc_getattr,
>        nfsd3_proc_setattr,
>        nfsd3_proc_lookup,
>        nfsd3_proc_access,
>        nfsd3_proc_readlink,
>        nfsd3_proc_read,
>        nfsd3_proc_write,
>        nfsd3_proc_create,
>        nfsd3_proc_mkdir,
>        nfsd3_proc_symlink,
>        nfsd3_proc_mknod,
>        nfsd3_proc_remove,
>        nfsd3_proc_rmdir,
>        nfsd3_proc_rename,
>        nfsd3_proc_link,
>        nfsd3_proc_readdir,
>        nfsd3_proc_readdirplus,readdirplus,
>        nfsd3_proc_fsstat,
>        nfsd3_proc_fsinfo,
>        nfsd3_proc_pathconf,
>        nfsd3_proc_commit,
>
> <3> NFSD file VFS operations
>
>       The functions nfsd_xxx from "fs/nfsd/vfs.c"
>
> With the above server side trace hooks, LKET could trace NFS
> operations at different layer:
>
>       nfsd_dispatch -->
>          --> NFS RPC Procedures
>             --> NFS VFS file operations
>
>
>    What I didn't list about NFS operations includes authentication,
> NFSv4 callback and RPC(I prefer to use a separate set of trace hooks
> for RPC). I am not sure if these operations are also required to be
> traced. If I missed some important functions or I listed some
> redundant functions, please feel free to let me know. Any comments
> will be highly appreciated.
>
>    Thanks.
>
> The following is from Li Xuepeng posted on nfs@lists.sourceforge.net
> which involved some implementations details and its trace point lists
> is a subset of the above.
>
> - Guanglei
>
> Xue Peng Li ??:
> > Hi folks,
> >
> > I am working on NFS trace hooks for SystemTap/LKET. These trace
> > hooks could be used for performance analyzing which will trace both
> > NFS client and server side activities.
> >
> > At the first step I need make sure that the trace hooks I defined
> > are appropriate and every trace hook probes the right places inside
> > the Kernel. So I will be appreciated if you could help me review the
> > following trace hooks.
> >
> >
> > Thanks
> >
> > ======================== NFS Client Side Trace Hooks =================
> >
> > The following event hooks are used to trace nfs client activities.
> > These event hooks are divided into two groups. Probe Point and
> > Description is given for each event hook.
> >
> > Group1:
> > It contains 15 event hooks, which are used to probe Client-side
> > NFS procedures.
> > ---------------------------------------------------------------------
> > addevent.nfs.proc.read_setup
> > Probe Point:
> > nfs_proc_read_setup,nfs3_proc_read_setup, nfs4_proc_read_setup
> > Description:
> > Setup a rpc task to prepare for reading
> > ---------------------------------------------------------------------
> > addevent.nfs.proc.read_done
> > Probe Point:
> > nfs_proc_read_done,nfs3_proc_read_done,
> > nfs4_proc_read_done
> > Description:
> > Fires when receive a read reply from server,it is used to
> > refresh the inode on client
> > ---------------------------------------------------------------------
> > addevnet.nfs.proc.read
> > Probe Point:
> > nfs_proc_read,nfs3_proc_read,nfs4_proc_read
> > Description:
> > Send a read operation to server,and refresh local inode after
> > receive reply from server
> > ---------------------------------------------------------------------
> > addevent.nfs.proc.write_setup
> > Probe Point:
> > nfs_proc_write_setup,nfs3_proc_write_setup,nfs4_proc_write_setup
> > Description:
> > ---------------------------------------------------------------------
> > addevent.nfs.proc.write
> > Probe Point:
> > nfs_proc_write,nfs3_proc_write,nfs4_proc_write
> > Description:
> > Send a write operation to server
> > ---------------------------------------------------------------------
> > addevent.nfs.proc.write_done
> > Probe Point:
> > nfs_write_done,nfs3_write_done,nfs4_write_done
> > Description:
> > Fires when receive a write reply from server,it is used to
> > refresh the inode on client
> > ---------------------------------------------------------------------
> > addevent.nfs.proc.open
> > Probe Point:
> > nfs_open
> > Description:
> > Allocate file read/write context information
> > ---------------------------------------------------------------------
> > addevent.nfs.proc.release
> > Probe Point:
> > nfs_release
> > Description:
> > Release file read/write context information
> > ---------------------------------------------------------------------
> > addevent.nfs.proc.create
> > Probe Point:
> > nfs_create
> > Description:
> > Create a new file or dir on server
> > _____________________________________________________________________
> >
> > Group2:
> > This group includes the event hooks which probe NFS address space
> > operation related function.All the functions are common in NFSV2,
> > NFSV3,NFSV4.
> > ---------------------------------------------------------------------
> > addevent.nfs.aops.readpage
> > Probe Point:
> > nfs_readpage
> > Description :
> > Read the page ,only fires when a previous async read operation
> > failed
> > ---------------------------------------------------------------------
> > addevent.nfs.aops.readpages
> > Probe Point:
> > nfs_readpages
> > Description:
> > Fires when in readahead way,read several pages once
> > ---------------------------------------------------------------------
> > addevent.nfs.aops.writepage
> > Probe Point:
> > nfs_writepage
> > Description:
> > Write an mapped page to the server
> > ---------------------------------------------------------------------
> > addevent.nfs.aops.writepages
> > Probe Point:
> > nfs_writepages
> > Description:
> > Write several dirty pages to the serve once
> > ---------------------------------------------------------------------
> > addevent.nfs.aops.prepare_write
> > Probe Point:
> > prepare_write
> > Description:
> > Prepare a page for writing. Look for a request corresponding
> > to the page. If there is one, and it belongs to another aops,
> > we flush it out before we try to copy anything into the page.
> > Also do the same if we find a request from an existing
> > dropped page.
> > ---------------------------------------------------------------------
> > addevent.nfs.aops.commit_write
> > Probe Point:
> > nfs_commit_write
> > Description :
> > Update and possibly write a cached page of an NFS aops
> > _____________________________________________________________________
> >
> >
> > ====================== NFS Server Side Trace Hooks ==================
> >
> > The following event hooks are used to traced nfs server activities.
> > The event hooks are divided into three group.
> >
> > Group1:
> > It contains one event hook,which probes nfsd_dispatch
> > ---------------------------------------------------------------------
> > addevent.nfsd.dispatch
> > Probe Point:
> > nfsd_dispatch
> > Description:
> > Decode the arguments received from client,call the procedure
> > handler,encode the result
> > ______________________________________________________________________
> > Group2:
> > It contains three event hooks.The functions probed will be called
> > by related procedure handler. All the functions are common in NFSV2,
> > NFSV3,NFSV4
> > ---------------------------------------------------------------------
> > addevent.nfsd.read
> > Probe Point:
> > nfsd_read
> > Description:
> > It does the "real" work of read
> > ---------------------------------------------------------------------
> > addevent.nfsd.write
> > Probe Point:
> > nfsd_write
> > Description:
> > It does the "real " work of write
> > ---------------------------------------------------------------------
> > addevent.nfsd.open
> > Probe Point:
> > nfsd_open
> > Description:
> > Open an existing file or directory.
> > ---------------------------------------------------------------------
> > addevent.nfsd.close
> > Probe Point:
> > nfsd_close
> > Description:
> > Close an existing file or directory
> > _____________________________________________________________________
> > Group3:
> > It contains eight event hooks,which probe procedure handlers.
> > ---------------------------------------------------------------------
> > addevent.nfsd.proc2.read
> > Probe Point:
> > nfsd_proc_read
> > Description:
> > Read data from file (NFSV2)
> > ---------------------------------------------------------------------
> > addevent.nfsd.proc3.read
> > Probe Point:
> > nfsd3_proc_read
> > Description:
> > Read data from file (NFSV3)
> > ---------------------------------------------------------------------
> > addevent.nfsd.proc4.read
> > Probe Point:
> > nfsd4_read
> > Description:
> > Check stateid and prepare for reading
> > ---------------------------------------------------------------------
> > addevent.nfsd.proc2.write
> > Probe Point:
> > nfsd_proc_write
> > Description:
> > Write data to file (NFSV2)
> > ---------------------------------------------------------------------
> > addevent.nfsd.pro3.write
> > Probe Point:
> > nfsd3_proc_write
> > Description:
> > Write data to file (NFSV3)
> > ---------------------------------------------------------------------
> > addevent.nfsd.proc4.write
> > Probe Point:
> > nfsd4_write
> > Description:
> > Check stateid and write data to file
> > ---------------------------------------------------------------------
> > addevent.nfsd.proc4.open
> > Probe Point:
> > nfsd4_open
> > Description:
> > Check stateid and open file
> > ---------------------------------------------------------------------
> > addevent.nfsd.proc4.compound
> > Probe Point:
> > nfsd4_proc_compound
> > Description:
> > Call different procedures according to client request
> >
> >
> > ------------------------------------------------------------------------
> >
> > _______________________________________________
> > ltc-perf mailing list
> > ltc-perf@linux.ibm.com
> > http://linux.ibm.com/mailman/listinfo/ltc-perf
>
>
>
> -------------------------------------------------------------------------
> Take Surveys. Earn Cash. Influence the Future of IT
> Join SourceForge.net's Techsay panel and you'll get the chance to share your
> opinions on IT & business topics through brief surveys -- and earn cash
> http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
> _______________________________________________
> NFS maillist  -  NFS@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/nfs
>


-- 
"We who cut mere stones must always be envisioning cathedrals"
   -- Quarry worker's creed

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [NFS] [ltc-perf] draft of nfs event hook
  2006-07-27 15:29   ` [NFS] " Chuck Lever
@ 2006-07-27 17:01     ` Jose R. Santos
  2006-07-27 22:46     ` Li Guanglei
  1 sibling, 0 replies; 8+ messages in thread
From: Jose R. Santos @ 2006-07-27 17:01 UTC (permalink / raw)
  To: Chuck Lever; +Cc: Li Guanglei, systemtap, nfs

Chuck Lever wrote:
> On 7/27/06, Li Guanglei <guanglei@cn.ibm.com> wrote:
>>    When we started working on NFS trace hooks, we realized it is not
>> an easy task. Although we use NFS in daily work but we don't have much
>> knowledge about the NFS protocol details and its implementation inside
>> the Kernel. So I divided the work into two steps. At the first step I
>> need get a list of trace points. And at the second step I need to make
>> sure what trace data is available for each trace hook. In a short, the
>> trace data available for each hook will be derived from the arguments
>> of the kernel functions being probed.
>>
>>    We read through the Kernel source code and chose some functions to
>> be instrumented. We will trace the entry of these functions and if
>> necessary, the return of them will also be traced. The following is
>> the list of these functions, please take a review:
>
> Have you done this with a local file system?  I assume yes, and that
> you just described the general approach you have taken with other file
> systems.  I think getting the same kind of data and trace points from
> the NFS client as you added to local file systems would be good.

There is someone already working on a tapset for ext3 and we are waiting 
for that tapset to be available before we go into looking how to add 
trace hooks to ext3.  We plan to have a similar approach to the NFS hooks.
>
> Capturing VFS and address space entry points is definitely useful and
> is similar to local file systems.  At the bottom of the NFS client is
> the RPC client, and it acts just like the block I/O layer does for
> local file systems.  Would you consider adding trace points in the
> LKET for the RPC client and server?

Definitely.  We've already added a trace hook on the NFS server dispatch 
entry and exit and we are looking at adding even more.  While our focus 
has mostly been adding hooks that would assist in performance analysis, 
the tool can also be used for the purposes of debugging as well.  If you 
have specific places where you would like to see trace hook inserted, we 
are definitely interested.

-JRS

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [NFS] [ltc-perf] draft of nfs event hook
  2006-07-27 15:29   ` [NFS] " Chuck Lever
  2006-07-27 17:01     ` Jose R. Santos
@ 2006-07-27 22:46     ` Li Guanglei
       [not found]       ` <001301c6b1e8$bd7cf590$160b0a0a@ict25eacacc325>
  1 sibling, 1 reply; 8+ messages in thread
From: Li Guanglei @ 2006-07-27 22:46 UTC (permalink / raw)
  To: Chuck Lever; +Cc: systemtap, nfs

> 
> Have you done this with a local file system?  I assume yes, and that
> you just described the general approach you have taken with other file
> systems.  I think getting the same kind of data and trace points from
> the NFS client as you added to local file systems would be good.
> 
> Capturing VFS and address space entry points is definitely useful and
> is similar to local file systems.  At the bottom of the NFS client is
> the RPC client, and it acts just like the block I/O layer does for
> local file systems.  Would you consider adding trace points in the
> LKET for the RPC client and server?
> 
>>
>>    What I didn't list about NFS operations includes authentication,
>> NFSv4 callback and RPC(I prefer to use a separate set of trace hooks
>> for RPC). I am not sure if these operations are also required to be
>> traced. If I missed some important functions or I listed some
>> redundant functions, please feel free to let me know. Any comments
>> will be highly appreciated.
>>

I didn't list RPC here because I think RPC is not only used by NFS and 
I need another set of RPC trace hooks to address the RPC server and 
client side operations. That will be my plan of the next set of trace 
hooks.

- Guanglei

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [NFS] [ltc-perf] draft of nfs event hook
       [not found]       ` <001301c6b1e8$bd7cf590$160b0a0a@ict25eacacc325>
@ 2006-07-28  2:03         ` Li Guanglei
  0 siblings, 0 replies; 8+ messages in thread
From: Li Guanglei @ 2006-07-28  2:03 UTC (permalink / raw)
  To: ZhaoYi; +Cc: systemtap, nfs

ZhaoYi ??:
> I think RPC is also needed to be listed, because in the current implementation of Linux NFS, RPC in the kernel is used by nfs only.

Although RPC is only used by NFS inside Kernel, I think NFS and RPC 
fall into two different categories. A separate set of trace hooks for 
RPC should be better.

- Guanglei

> ----- Original Message ----- 
> From: "Li Guanglei" <guanglei@cn.ibm.com>
> To: "Chuck Lever" <chucklever@gmail.com>
> Cc: <nfs@lists.sourceforge.net>; <systemtap@sourceware.org>
> Sent: Friday, July 28, 2006 6:47 AM
> Subject: Re: [NFS] [ltc-perf] draft of nfs event hook
> 
> 
>>> Have you done this with a local file system?  I assume yes, and that
>>> you just described the general approach you have taken with other file
>>> systems.  I think getting the same kind of data and trace points from
>>> the NFS client as you added to local file systems would be good.
>>>
>>> Capturing VFS and address space entry points is definitely useful and
>>> is similar to local file systems.  At the bottom of the NFS client is
>>> the RPC client, and it acts just like the block I/O layer does for
>>> local file systems.  Would you consider adding trace points in the
>>> LKET for the RPC client and server?
>>>
>>>>    What I didn't list about NFS operations includes authentication,
>>>> NFSv4 callback and RPC(I prefer to use a separate set of trace hooks
>>>> for RPC). I am not sure if these operations are also required to be
>>>> traced. If I missed some important functions or I listed some
>>>> redundant functions, please feel free to let me know. Any comments
>>>> will be highly appreciated.
>>>>
>> I didn't list RPC here because I think RPC is not only used by NFS and 
>> I need another set of RPC trace hooks to address the RPC server and 
>> client side operations. That will be my plan of the next set of trace 
>> hooks.
>>
>> - Guanglei
>>
>>
>> -------------------------------------------------------------------------
>> Take Surveys. Earn Cash. Influence the Future of IT
>> Join SourceForge.net's Techsay panel and you'll get the chance to share your
>> opinions on IT & business topics through brief surveys -- and earn cash
>> http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
>> _______________________________________________
>> NFS maillist  -  NFS@lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/nfs
>>


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [ltc-perf]  draft of nfs event hook
  2006-07-27 13:56 ` [ltc-perf] draft of nfs event hook Li Guanglei
  2006-07-27 15:29   ` [NFS] " Chuck Lever
@ 2006-08-11  1:59   ` Xue Peng Li
  2006-08-16  8:53     ` Xue Peng Li
  1 sibling, 1 reply; 8+ messages in thread
From: Xue Peng Li @ 2006-08-11  1:59 UTC (permalink / raw)
  To: systemtap, nfs

[-- Attachment #1: Type: text/plain, Size: 8383 bytes --]

Hi folks,

    I am working on NFS tapsets recently which could be able to probe 
both NFS server side and client side operations. As the first step, I am 
working on tapsets about NFS client side. This tapset includes three 
levels, i.e. file operation, address space operation, client-side 
procedures stubs(nfs_proc function). I have finished the tapset about 
fop(file operation) and aop (address space operation). I resues the 
Tom's vfs.stp to avoid duplicate work.

    I will be very happy if you can take a look at it. Feel free to tell 
me if you have any questions/suggestions/comments.

    Thanks.

Li Guanglei wrote:
> Hi,
> 
>   The NFS trace hooks we are working on will be part of the trace hooks 
> of LKET, which is a system trace tool and we mainly use it for 
> performance analysis.
> 
>   LKET is a dynamic trace facility based on SystemTap. It is actually 
> implemented as SystemTap's tapsets library and it has been integrated 
> into SystemTap already. For more info of LKET, you can refer to:
> 
> http://sourceware.org/systemtap/man5/lket.5.html
> 
>   When we started working on NFS trace hooks, we realized it is not an 
> easy task. Although we use NFS in daily work but we don't have much 
> knowledge about the NFS protocol details and its implementation inside 
> the Kernel. So I divided the work into two steps. At the first step I 
> need get a list of trace points. And at the second step I need to make 
> sure what trace data is available for each trace hook. In a short, the 
> trace data available for each hook will be derived from the arguments of 
> the kernel functions being probed.
> 
>   We read through the Kernel source code and chose some functions to be 
> instrumented. We will trace the entry of these functions and if 
> necessary, the return of them will also be traced. The following is the 
> list of these functions, please take a review:
> 
> ==================== Client Side ==========================
> 
> <1> nfs directory operations
> 
>      All functions from nfs_dir_operations:
> 
>       const struct file_operations nfs_dir_operations = {
>         .llseek         = nfs_llseek_dir,
>         .read           = generic_read_dir,
>         .readdir        = nfs_readdir,
>         .open           = nfs_opendir,
>         .release        = nfs_release,
>         .fsync          = nfs_fsync_dir,
> };
> 
> <2> nfs file operations
> 
>     All functions from nfs_file_operations:
> 
>     const struct file_operations nfs_file_operations = {
>         .llseek         = nfs_file_llseek,
>         .read           = do_sync_read,
>         .write          = do_sync_write,
>         .aio_read               = nfs_file_read,
>         .aio_write              = nfs_file_write,
>         .mmap           = nfs_file_mmap,
>         .open           = nfs_file_open,
>         .flush          = nfs_file_flush,
>         .release        = nfs_file_release,
>         .fsync          = nfs_fsync,
>         .lock           = nfs_lock,
>         .flock          = nfs_flock,
>         .sendfile       = nfs_file_sendfile,
>         .check_flags    = nfs_check_flags,
> };
> 
> <3> nfs address space operations:
>     All functions from nfs_file_aops:
> 
>       struct address_space_operations nfs_file_aops = {
>         .readpage = nfs_readpage,
>         .readpages = nfs_readpages,
>         .set_page_dirty = __set_page_dirty_nobuffers,
>         .writepage = nfs_writepage,
>         .writepages = nfs_writepages,
>         .prepare_write = nfs_prepare_write,
>         .commit_write = nfs_commit_write,
>         .invalidatepage = nfs_invalidate_page,
>         .releasepage = nfs_release_page,
> #ifdef CONFIG_NFS_DIRECTIO
>         .direct_IO = nfs_direct_IO,
> #endif
>      };
> 
> <4> NFS RPC procedures:
> 
>    All functions from nfs_v[2,3,4]_clientops:
>     I only list the nfs_v3 rpc procedures:
>      struct nfs_rpc_ops      nfs_v3_clientops = {
>         .version        = 3,                    /* protocol version */
>         .dentry_ops     = &nfs_dentry_operations,
>         .dir_inode_ops  = &nfs3_dir_inode_operations,
>         .file_inode_ops = &nfs3_file_inode_operations,
>         .getroot        = nfs3_proc_get_root,
>         .getattr        = nfs3_proc_getattr,
>         .setattr        = nfs3_proc_setattr,
>         .lookup         = nfs3_proc_lookup,
>         .access         = nfs3_proc_access,
>         .readlink       = nfs3_proc_readlink,
>         .read           = nfs3_proc_read,
>         .write          = nfs3_proc_write,
>         .commit         = nfs3_proc_commit,
>         .create         = nfs3_proc_create,
>         .remove         = nfs3_proc_remove,
>         .unlink_setup   = nfs3_proc_unlink_setup,
>         .unlink_done    = nfs3_proc_unlink_done,
>         .rename         = nfs3_proc_rename,
>         .link           = nfs3_proc_link,
>         .symlink        = nfs3_proc_symlink,
>         .mkdir          = nfs3_proc_mkdir,
>         .rmdir          = nfs3_proc_rmdir,
>         .readdir        = nfs3_proc_readdir,
>         .mknod          = nfs3_proc_mknod,
>         .statfs         = nfs3_proc_statfs,
>         .fsinfo         = nfs3_proc_fsinfo,
>         .pathconf       = nfs3_proc_pathconf,
>         .decode_dirent  = nfs3_decode_dirent,
>         .read_setup     = nfs3_proc_read_setup,
>         .read_done      = nfs3_read_done,
>         .write_setup    = nfs3_proc_write_setup,
>         .write_done     = nfs3_write_done,
>         .commit_setup   = nfs3_proc_commit_setup,
>         .commit_done    = nfs3_commit_done,
>         .file_open      = nfs_open,
>         .file_release   = nfs_release,
>         .lock           = nfs3_proc_lock,
>         .clear_acl_cache = nfs3_forget_cached_acls,
>     };
> 
>   The LKET already has syscall and iosyscall trace hooks. So with the 
> above trace hooks, LKET could trace different layer of NFS operations:
>    --> Syscall
>       --> struct file_operations
>           --> struct address_space_operations
>                --> struct nfs_rpc_ops
> 
> ======================= Server Side =============================
> 
> <1> nfsd_dispatch
>    This is the NFS dispatching function sit on top of RPC.
> 
> <2> NFS RPC procedures:
> 
>     For NFSv4, it will be nfsd4_proc_compound
> 
>     For NFSv2, NFSv3, it will be the functions from nfsd_procedures[2,3]
> 
>     Here is a list for NFSv3, NFSv2 are almost the same:
>       nfsd3_proc_null,
>       nfsd3_proc_getattr,
>       nfsd3_proc_setattr,
>       nfsd3_proc_lookup,
>       nfsd3_proc_access,
>       nfsd3_proc_readlink,
>       nfsd3_proc_read,
>       nfsd3_proc_write,
>       nfsd3_proc_create,
>       nfsd3_proc_mkdir,
>       nfsd3_proc_symlink,
>       nfsd3_proc_mknod,
>       nfsd3_proc_remove,
>       nfsd3_proc_rmdir,
>       nfsd3_proc_rename,
>       nfsd3_proc_link,
>       nfsd3_proc_readdir,
>       nfsd3_proc_readdirplus,readdirplus,
>       nfsd3_proc_fsstat,
>       nfsd3_proc_fsinfo,
>       nfsd3_proc_pathconf,
>       nfsd3_proc_commit,
> 
> <3> NFSD file VFS operations
> 
>      The functions nfsd_xxx from "fs/nfsd/vfs.c"
> 
> With the above server side trace hooks, LKET could trace NFS operations 
> at different layer:
> 
>      nfsd_dispatch -->
>         --> NFS RPC Procedures
>            --> NFS VFS file operations
> 
> 
>   What I didn't list about NFS operations includes authentication, NFSv4 
> callback and RPC(I prefer to use a separate set of trace hooks for RPC). 
> I am not sure if these operations are also required to be traced. If I 
> missed some important functions or I listed some redundant functions, 
> please feel free to let me know. Any comments will be highly appreciated.
> 
>   Thanks.
> 
> The following is from Li Xuepeng posted on nfs@lists.sourceforge.net 
> which involved some implementations details and its trace point lists is 
> a subset of the above.
> 
> - Guanglei
> 
> Xue Peng Li ??:
>> Hi folks,
>>
>> I am working on NFS trace hooks for SystemTap/LKET. These trace
>> hooks could be used for performance analyzing which will trace both
>> NFS client and server side activities.
>>
>> At the first step I need make sure that the trace hooks I defined
>> are appropriate and every trace hook probes the right places inside
>> the Kernel. So I will be appreciated if you could help me review the
>> following trace hooks.
>>
>>
>> Thanks

[-- Attachment #2: nfs.stp --]
[-- Type: text/plain, Size: 29124 bytes --]

%{
#include <linux/kernel.h>
#include <linux/nfs_fs.h>
%}
/*Get struct nfs_inode from struct inode*/
%{ 
  struct nfs_inode * __nfs_i (struct inode *inode)
  {
    struct nfs_inode * nfsi = NFS_I(inode);

    return (nfsi);
  }
%}

/*Get cache_validity flag from struct inode*/
function __nfsi_cache_valid:long(inode:long)
%{
    struct inode * inode = (struct inode *)(THIS->inode);
    struct nfs_inode * nfsi;
  
    nfsi = __nfs_i(inode);
    THIS->__retvalue = nfsi->cache_validity;
%}

/*Get read_cache_jiffies from struct inode*/
function __nfsi_rcache_time :long (inode:long)
%{
    struct inode * inode = (struct inode *)(THIS->inode);
    struct nfs_inode * nfsi = (struct nfs_inode *) __nfs_i(inode);

    THIS->__retvalue = nfsi->read_cache_jiffies;
%}

/*Get attrtimeo from struct inode*/
function __nfsi_attr_time :long (inode:long)
%{
    struct inode * inode = (struct inode *)(THIS->inode);
    struct nfs_inode * nfsi = (struct nfs_inode *) __nfs_i(inode);

    THIS->__retvalue = nfsi->attrtimeo;
%}

/*Get ndirty from struct inode*/
function __nfsi_ndirty:long (inode:long)
%{
      struct inode *inode = (struct inode *)(THIS->inode);
      struct nfs_inode *nfsi = NFS_I(inode);
 
      THIS->__retvalue = nfsi->ndirty;
%}

/*Get rsize from struct inode*/
function __nfs_server_rsize:long (inode:long)
%{
       struct inode * inode = (struct inode *)(THIS->inode);

       THIS->__retvalue = NFS_SERVER(inode)->rsize;
%}

/*Get wsize from struct inode*/
function __nfs_server_wsize:long (inode:long)
%{
       struct inode * inode = (struct inode *)(THIS->inode);

       THIS->__retvalue = NFS_SERVER(inode)->wsize;
%}

/*Get rpages from struct inode*/
function __nfs_rpages:long (inode:long)
%{
       struct inode * inode = (struct inode *)(THIS->inode);

       THIS->__retvalue = NFS_SERVER(inode)->rpages;
%}

/*Get wpages from struct inode*/
function __nfs_wpages:long(inode:long)
%{
      struct inode *inode = (struct inode*)(THIS->inode);
      THIS->__retvalue = NFS_SERVER(inode)->wpages;
%}

/*Get struct inode from struct page*/
function __p2i :long(page:long)
%{
      struct page *page = (struct page *)(THIS->page);
      THIS->__retvalue = (long)page->mapping->host;
%}

/*Get i_flags from struct page*/
function __p2i_flag : long (page:long)
%{
      struct page *page = (struct page *) (THIS->page);
      THIS->__retvalue = page->mapping->host->i_flags;
%}

/*Get i_state from struct page*/
function __p2i_state :long (page:long)
%{
      struct page *page = (struct page *) (THIS->page);
      THIS->__retvalue = page->mapping->host->i_state;
%}

/*Get i_size from struct page*/
function __p2i_size :long (page:long)
%{
      struct page *page = (struct page *) (THIS->page);
      THIS->__retvalue = page->mapping->host->i_size;
%}

/*Get s_flags from struct page*/
function __p2sb_flag:long (page:long)
%{
      struct page *page = (struct page *)(THIS->page);
      THIS->__retvalue = page->mapping->host->i_sb->s_flags;
%}

function __d_loff_t :long (ppos :long)
%{
     loff_t * ppos = (loff_t *) (THIS->ppos);
     
     THIS->__retvalue =(long) *ppos;
%}

probe nfs.fop.entries = nfs.fop.llseek,
                        nfs.fop.read,
                        nfs.fop.write,
                        nfs.fop.aio_read,
                        nfs.fop.aio_write,
                        nfs.fop.mmap,
                        nfs.fop.open,
                        nfs.fop.flush,
                        nfs.fop.release,
                        nfs.fop.fsync,
                        nfs.fop.lock,
                        nfs.fop.sendfile
{
}

probe nfs.fop.entries.return = nfs.fop.llseek.return,
                        nfs.fop.read.return,
                        nfs.fop.write.return,
                        nfs.fop.aio_read.return,
                        nfs.fop.aio_write.return,
                        nfs.fop.mmap.return,
                        nfs.fop.open.return,
                        nfs.fop.flush.return,
                        nfs.fop.release.return,
                        nfs.fop.fsync.return,
                        nfs.fop.lock.return,
                        nfs.fop.sendfile.return
{
}

/*probe nfs.fop.llseek
 *
 *  Fires when do a llseek operation on nfs,it probes
 *  llseek file operation of nfs
 *
 *  Arguments:
 *     dev : device identifier
 *     ino : inode number
 *     offset : the offset of the file will be repositioned
 *     origin : the original position. The possible value could be:
 *         SEEK_SET
 *               The offset is set to offset bytes.
 *         SEEK_CUR
 *               The offset is set to its current location plus offset bytes.
 *         SEEK_END
 *               The offset is set to the size of the file plus offset bytes.
 *
*/
probe nfs.fop.llseek = kernel.function ("nfs_file_llseek") ?,
                       module("nfs").function("nfs_file_llseek") ?
{
        dev = $filp->f_dentry->d_inode->i_sb->s_dev
        ino = $filp->f_dentry->d_inode->i_ino
        maxbyte = $filp->f_dentry->d_inode->i_sb->s_maxbytes
        offset = $offset
        origin = $origin

        name = "nfs.fop.llseek"
        argstr = sprintf("%d, %d", offset, origin)
}

probe nfs.fop.llseek.return = kernel.function ("nfs_file_llseek").return ?,
                              module("nfs").function("nfs_file_llseek").return ?
{
        name = "nfs.fop.llseek.return"
        retstr = sprintf("%d", $return)
}
/*probe nfs.fop.read
 *
 * Fires when do a read operation on nfs,it probes
 * read file operation of nfs
 * 
 * Arguments:
 *        
 *
*/
probe nfs.fop.read = vfs.do_sync_read
{
        name = "nfs.fop.read"
}

probe nfs.fop.read.return = vfs.do_sync_read.return
{
        name = "nfs.fop.read.return"
}

/*probe nfs.fop.write
 *
 * Fires when do a write operation on nfs,it probes
 * write file operation of nfs
 * 
 * Arguments:
 *        
 *
*/

probe nfs.fop.write = vfs.do_sync_write
{
        name = "nfs.fop.write"
}

probe nfs.fop.write.return = vfs.do_sync_write.return
{
        name = "nfs.fop.write.return"
}

/*probe nfs.fop.aio_read
 *
 * It probes aio_read file operation of nfs
 * 
 * Arguments:
 *    dev : device identifier
 *    ino : inode number        
 *    count : read bytes
 *    pos   : current position of file   
 *    buf   : the address of buf in user space
 *    parent_name : parent dir name
 *    file_name : file name
 *    cache_valid : cache related bit mask flag
 *    cache_time : when we started read-caching this inode
 *    attrtimeo :  how long the cached information is assumed
 *                 to be valid.
 *   We need to revalidate the cached attrs for this inode if
 *
 *      jiffies - read_cache_jiffies > attrtimeo
*/
probe nfs.fop.aio_read = kernel.function ("nfs_file_read") ?,
                       module("nfs").function("nfs_file_read") ?
{
        dev = $iocb->ki_filp->f_dentry->d_inode->i_sb->s_dev
        ino = $iocb->ki_filp->f_dentry->d_inode->i_ino

        count = $count
        pos = $pos
        buf = $buf

        parent_name = kernel_string($iocb->ki_filp->f_dentry->d_parent->d_name->name)
        file_name = kernel_string($iocb->ki_filp->f_dentry->d_name->name)


        cache_valid = __nfsi_cache_valid($iocb->ki_filp->f_dentry->d_inode)
        cache_time  = __nfsi_rcache_time($iocb->ki_filp->f_dentry->d_inode)
        attr_time   = __nfsi_attr_time($iocb->ki_filp->f_dentry->d_inode)

        flag =  $iocb->ki_filp->f_flags

        name = "nfs.fop.aio_read"
        argstr = sprintf("%p,%d, %d",buf,count, pos)

        size = count
        units = "bytes"
}


probe nfs.fop.aio_read.return = kernel.function ("nfs_file_read").return ?,
                                module("nfs").function("nfs_file_read").return ?
{
        name = "nfs.fop.aio_read.return"
        retstr = sprintf("%d", $return)

        if ($return > 0) {
                size = $return
                units = "bytes"
        }
}

/*probe nfs.fop.aio_write
 *
 * It probes aio_write file operation of nfs
 * 
 * Arguments:
 *    dev : device identifier
 *    ino : inode number        
 *    count : read bytes
 *    pos   : offset of the file 
 *    buf   : the address of buf in user space
 *    parent_name : parent dir name
 *    file_name : file name
 *
*/
probe nfs.fop.aio_write = kernel.function("nfs_file_write") ?,
                          module("nfs").function("nfs_file_write") ?
{
        dev = $iocb->ki_filp->f_dentry->d_inode->i_sb->s_dev
        ino = $iocb->ki_filp->f_dentry->d_inode->i_ino

        count = $count
        pos = $pos
        buf = $buf
               
        parent_name = kernel_string($iocb->ki_filp->f_dentry->d_parent->d_name->name)
        file_name = kernel_string($iocb->ki_filp->f_dentry->d_name->name)

        name = "nfs.fop.aio.write"
        argstr = sprintf("%p, %d, %d", buf, count, pos)

        size = count
        units = "bytes"
}

probe nfs.fop.aio_write.return =  kernel.function("nfs_file_write").return ?,
                          module("nfs").function("nfs_file_write").return ?
{
        name = "nfs.fop.aio_write.return"
        retstr = sprintf("%d", $return)

        if ($return > 0) {
                size = $return
                units = "bytes"
        }
}

/*probe nfs.fop.mmap
 *
 * Fires when do an mmap operation on nfs,
 * it probes mmap operation of nfs
 * 
 * Arguments:
 *    dev : device identifier
 *    ino : inode number        
 *    vm_start :  start address within vm_mm 
 *    vm_end   :  the first byte after end address within vm_mm
 *    vm_flag  :  vm flags
 *    buf   : the address of buf in user space
 *    parent_name : parent dir name
 *    file_name : file name
 *    cache_valid : cache related bit mask flag
 *    cache_time : when we started read-caching this inode
 *    attrtimeo :  how long the cached information is assumed
 *                 to be valid.
 *   We need to revalidate the cached attrs for this inode if
 *
 *      jiffies - read_cache_jiffies > attrtimeo
*/
probe nfs.fop.mmap = kernel.function("nfs_file_mmap") ?,
                     module("nfs").function("nfs_file_mmap") ?
{
        dev = $file->f_dentry->d_inode->i_sb->s_dev
        ino = $file->f_dentry->d_inode->i_ino

        vm_start = $vma->vm_start
        vm_end = $vma->vm_end
        vm_flags = $vma->vm_flags

        parent_name = kernel_string($file->f_dentry->d_parent->d_name->name)
        file_name = kernel_string($file->f_dentry->d_name->name)

        cache_valid = __nfsi_cache_valid($file->f_dentry->d_inode)
        cache_time  = __nfsi_rcache_time($file->f_dentry->d_inode)
        attr_time   = __nfsi_attr_time($file->f_dentry->d_inode)

        name = "nfs.fop.mmap"
        argstr = sprintf("0x%x, 0x%x, 0x%x", vm_start, vm_end, vm_flags)
}

probe nfs.fop.mmap.return = kernel.function("nfs_file_mmap").return ?,
                     module("nfs").function("nfs_file_mmap").return ?
{
        name = "nfs.fop.mmap.return"
        retstr = sprintf("%d", $return)
}

/*probe nfs.fop.open
 *
 * Fires when do an open operation on nfs,
 * it probes open file operation of nfs
 * 
 * Arguments:
 *    dev : device identifier
 *    ino : inode number        
 *    file_name : file name
 *    flag : file flag
 *    i_size : file length in bytes 
*/
probe nfs.fop.open = kernel.function("nfs_file_open") ?,
                     module("nfs").function("nfs_file_open") ?
{
        dev = $filp->f_dentry->d_inode->i_sb->s_dev
        ino = $inode->i_ino

        filename = kernel_string($filp->f_dentry->d_name->name)
        flag = $filp->f_flags   

        i_size = $inode->i_size
   
        name = "nfs.fop.open"
        argstr = sprintf("%d,%d, %s", flag, ino, filename)
}

probe nfs.fop.open.return = kernel.function("nfs_file_open").return ?,
                            module("nfs").function("nfs_file_open").return ?
{
        name = "nfs.fop.open.return"
        retstr = sprintf("%d", $return)        
}

/*probe nfs.fop.flush
 *
 * Fires when do a flush file operation on nfs,
 * it probes flush file operation of nfs
 * 
 * Arguments:
 *    dev : device identifier
 *    ino : inode number        
 *    mode : file mode
 *    ndirty : number of dirty page
*/
probe nfs.fop.flush = kernel.function("nfs_file_flush") ?,
                      module("nfs").function("nfs_file_flush") ?
{
        dev = $file->f_dentry->d_inode->i_sb->s_dev
        ino = $file->f_dentry->d_inode->i_ino;

        mode = $file->f_mode
        ndirty = __nfsi_ndirty($file->f_dentry->d_inode)

        name = "nfs.fop.flush"
        argstr = sprintf("%d",ino)
}

probe nfs.fop.flush.return = kernel.function("nfs_file_flush").return ?,
                      module("nfs").function("nfs_file_flush").return ?
{
        name = "nfs.fop.flush.return"
        retstr = sprintf("%d",$return)
}

/*probe nfs.fop.release
 *
 * Fires when do a release page operation on nfs,
 * it probes release file operation of nfs
 * 
 * Arguments:
 *    dev : device identifier
 *    ino : inode number        
 *    mode : file mode
*/
probe nfs.fop.release = kernel.function("nfs_file_release") ?,
                      module("nfs").function("nfs_file_release") ?
{
        dev = $filp->f_dentry->d_inode->i_sb->s_dev
        ino = $inode->i_ino

        mode = $filp->f_mode

        name = "nfs.fop.release"
        argstr = sprintf("%d" , ino)
}

probe nfs.fop.release.return = kernel.function("nfs_file_release").return ?,
                               module("nfs").function("nfs_file_release").return ?
{
        name = "nfs.fop.release.return"
        retstr = sprintf("%d", $return)
}

/*probe nfs.fop.fsync
 *
 * Fires when do a fsync operation on nfs,
 * it probes fsync file operation of nfs
 * 
 * Arguments:
 *    dev : device identifier
 *    ino : inode number       
 *    ndirty : number of dirty pages 
*/
probe nfs.fop.fsync = kernel.function("nfs_fsync") ?,
                      module("nfs").function("nfs_fsync") ?
{
        dev = $file->f_dentry->d_inode->i_sb->s_dev
        ino = $file->f_dentry->d_inode->i_ino

        ndirty = __nfsi_ndirty($file->f_dentry->d_inode)

        name = "nfs.fop.fsync"
	argstr = sprintf("%d",ino)  
}

probe nfs.fop.fsync.return = kernel.function("nfs_fsync").return ?,
                             module("nfs").function("nfs_fsync").return ?
{
        name = "nfs.fop.fsync.return"
        retstr = sprintf("%d", $return)
}

/*probe nfs.fop.lock
 *
 * Fires when do a file lock operation on nfs,
 * it probes lock file operation of nfs
 * 
 * Arguments:
 *    dev : device identifier
 *    ino : inode number      
 *    i_mode : file type and access rights
 *    cmd : cmd arguments
 *    fl_type :lock type
 *    fl_flag : lock flags
 *    fl_start : starting offset of locked region 
 *    fl_end   : ending offset of locked region  
*/
probe nfs.fop.lock = kernel.function("nfs_lock") ?,
                     module("nfs").function("nfs_lock") ?
{
        dev = $filp->f_dentry->d_inode->i_sb->s_dev
        ino = $filp->f_dentry->d_inode->i_ino
 
        i_mode = $filp->f_dentry->d_inode->i_mode
        cmd = $cmd
 
        fl_type = $fl->fl_type
        fl_flag = $fl->fl_flags
        fl_start = $fl->fl_start
        fl_end  = $fl->fl_end

        name = "nfs.fop.lock"
        argstr = sprintf("%d,%d",cmd,i_mode)
}

probe nfs.fop.lock.return = kernel.function("nfs_lock").return ?,
                             module("nfs").function("nfs_lock").return ?
{
         name = "nfs.fop.lock.return"
         retstr = sprintf("%d",$return)
}


/*probe nfs.fop.sendfile
 *
 * Fires when do a send file  operation on nfs,
 * it probes sendfile file operation of nfs
 * 
 * Arguments:
 *    dev : device identifier
 *    ino : inode number     
 *    count : read bytes
 *    ppos : current position of file
 *    cache_valid : cache related bit mask flag
 *    cache_time : when we started read-caching this inode
 *    attrtimeo :  how long the cached information is assumed
 *                 to be valid.
 *   We need to revalidate the cached attrs for this inode if
 *
 *      jiffies - read_cache_jiffies > attrtimeo
*/
probe nfs.fop.sendfile = kernel.function("nfs_file_sendfile") ?,
                              module("nfs").function("nfs_file_sendfile") ?
{

        dev = $filp->f_dentry->d_inode->i_sb->s_dev
        ino = $filp->f_dentry->d_inode->i_ino

        count = $count
        ppos  = __d_loff_t($ppos)

        cache_valid = __nfsi_cache_valid($filp->f_dentry->d_inode)
        cache_time  = __nfsi_rcache_time($filp->f_dentry->d_inode)
        attr_time   = __nfsi_attr_time($filp->f_dentry->d_inode)


        name = "nfs.fop.sendfile"
        argstr = sprintf("%d,%d", count,ppos)

        size = count
        units = "bytes"
}

probe nfs.fop.sendfile.return = kernel.function("nfs_file_sendfile").return ?,
                              module("nfs").function("nfs_file_sendfile").return ?
{
        name = "nfs.fopsendfile.return"
        retstr = sprintf("%d", $return)

        if ($return > 0) {
                size = $return
                units = "bytes"
        }
}

/*probe nfs.fop.check_flags
 *
 * Fires when do a checking flag  operation on nfs,
 * it probes check_flag file operation of nfs
 * 
 * Arguments:
 *    flag : file flag
*/
probe nfs.fop.check_flags =  kernel.function("nfs_check_flags") ?,
                             module("nfs").function("nfs_check_flags") ?
{
        flag = $flags
        
        name = "nfs.fop.check_flags"
        argstr = sprintf("%d",flag)
}

probe nfs.fop.check_flags.return =  kernel.function("nfs_check_flags").return ?,
                             module("nfs").function("nfs_check_flags").return ?
{
        name = "nfs.fop.check_flags.return"
        retstr = sprintf("%d",$return)
}

probe nfs.aop.entries = nfs.aop.readpage,
                        nfs.aop.readpages,
                        nfs.aop.writepage,
                        nfs.aop.writepages,
                        nfs.aop.prepare_write,
                        nfs.aop.commit_write,
                        nfs.aop.release_page
{
}
 
probe nfs.aop.entries.return = nfs.aop.readpage.return,
                        nfs.aop.readpages.return,
                        nfs.aop.writepage.return,
                        nfs.aop.writepages.return,
                        nfs.aop.prepare_write.return,
                        nfs.aop.commit_write.return,
                        nfs.aop.release_page.return
{
}

/* probe nfs.aop.readpage
 *
 *   Read the page ,only fies when a previous async
 *   read operation failed
 *
 * Arguments:
 *   __page : the address of page
 *   dev : device identifier
 *   ino : inode number    
 *   i_flag : file flags
 *   i_size : file length in bytes
 *   sb_flag : super block flags
 *   file  : file argument
 *   page_index : offset within mapping, can used a 
                  page identifier and position identifier
                  in the page frame
 *   rsize :  read size  (in bytes)
 *   size :  number of pages to be read in this execution 
 */
probe nfs.aop.readpage = kernel.function ("nfs_readpage") ?,
        module("nfs").function ("nfs_readpage") ?
{
        __page = $page
        dev = __page_dev(__page)
        ino = __page_ino(__page)

        i_flag = __p2i_flag($page) 
        i_size = __p2i_size($page)
 
        sb_flag = __p2sb_flag($page) 

        file = $file
        page_index = $page->index
        
        __inode = __p2i($page) 
        rsize = __nfs_server_rsize(__inode)

        name = "nfs.aop.readpage"
        argstr = sprintf("%d,%d" , page_index,r_size)

        size = 1
        units = "pages"
}

probe nfs.aop.readpage.return = kernel.function ("nfs_readpage").return ?,
        module("nfs").function ("nfs_readpage").return ?
{
        name = "nfs.aop.readpage.return"
        retstr = sprintf("%d", $return)

        size = 1
        units = "pages"
}

/* probe nfs.aop.readpages
 *
 * Fies when in readahead way,read several pages once
 * Arguments:
 *   dev : device identifier
 *   ino : inode number   
 *   nr_pages :  number of pages to be read in this execution 
 *   file : filp argument
 *   rpages : read size (in pages) 
 *   rsize  : read size (in bytes)
 *   size :  number of pages to be read in this execution 
 */
probe nfs.aop.readpages =  kernel.function ("nfs_readpages") ?,
        module("nfs").function ("nfs_readpages") ?
{
        dev = $mapping->host->i_sb->s_dev
        ino = $mapping->host->i_ino

        nr_pages = $nr_pages
        file = $filp

        rpages = __nfs_rpages($mapping->host)
        rsize  = __nfs_server_rsize($mapping->host)

        name = "nfs.aop.readpages"
        argstr = sprintf("%d" , nr_pages)

        size = nr_pages
        units = "pages"
}

probe nfs.aop.readpages.return = kernel.function ("nfs_readpages").return ?,
        module("nfs").function ("nfs_readpages").return ?
{
        name = "nfs.aop.readpages.return"
        retstr = sprintf("%d", $return)


        if($return > 0 )
        {
            size = retstr
        }
        units = "pages"
}
/*probe nfs.aop.set_page_dirty
 *
 *   __set_page_dirty_nobuffers is used to set a page dirty,but
 *   not all the buffers.
 *
 *  Arguments:
 *     __page : the address of page
 *      page_flag : page flags
*/
probe nfs.aop.set_page_dirty =
            kernel.function ("__set_page_dirty_nobuffers") ?,
             module("nfs").function ("__set_page_dirty_nobuffers") ?
{
 /*       dev = $mapping->host->i_sb->s_dev
        devname = __find_bdevname(dev, $mapping->host->i_sb->s_bdev)
        ino = $mapping->host->i_ino
*/
        __page = $page
        page_flag = $page->flags

        name = "nfs.aop.set_page_dirty"
        argstr = sprintf("%d",flag)
}

probe nfs.aop.set_page_dirty.return =
            kernel.function ("__set_page_dirty_nobuffers") .return?,
            module("nfs").function ("__set_page_dirty_nobuffers").return ?
{
        name = "nfs.aop.set_page_dirty.return"
        retstr = sprintf("%d", $return)
}

/*probe nfs.aop.writepage
 *
 *   Write an mapped page to the server
 *
 *  Arguments:
 *     __page : the address of page
 *     dev : device identifier
 *     ino : inode number  
 *     for_reclaim : a flag of writeback_control, indicates if it's invoked from the page allocator 
 *     for_kupdate : a flag of writeback_control, indicates if it's a kupdate writeback
 *      The priority of wb is decided by above two flags
 *     i_flag : file flags
 *     i_size : file length in bytes
 *     i_state : inode state flags
 *     sb_flag : super block flags
 *     page_index : offset within mapping, can used a 
                    page identifier and position identifier
                    in the page frame
 *     wsize :  write size
 *     size  :  number of pages to be written in this execution 
*/
probe nfs.aop.writepage =  kernel.function ("nfs_writepage") ?,
             module("nfs").function ("nfs_writepage") ?
{
        __page = $page
        dev = __page_dev(__page)
        ino = __page_ino(__page)
        

        for_reclaim = $wbc->for_reclaim
        for_kupdate = $wbc->for_kupdate

        i_flag = __p2i_flag($page) 
        i_state = __p2i_state($page)
        i_size = __p2i_size($page)

        sb_flag = __p2sb_flag($page) 


        page_index = $page->index

        __inode = __p2i($page)
        wsize = __nfs_server_wsize(__inode)            
 
        name = "nfs.aop.writepage"
        argstr = sprintf("%d",page_index)

        size = 1
        units = "pages"
}

probe nfs.aop.writepage.return =  kernel.function ("nfs_writepage").return ?,
             module("nfs").function ("nfs_writepage").return ?
{
        name = "nfs.aop.writepage.return"
        retstr = sprintf("%d", $return)
}

/*probe nfs.aop.writepages
 *  Write several dirty pages to the serve
 *Arguments:
 *     dev : device identifier
 *     ino : inode number  
 *     for_reclaim : a flag of writeback_control, indicates if it's invoked from the page allocator 
 *     for_kupdate : a flag of writeback_control, indicates if it's a kupdate writeback
 *      The priority of wb is decided by above two flags
 *      wsize :  write size
 *      wpages : write size (in pages)
 *      nr_to_write : number of pages to be written in this execution  
 *      size : number of pages to be written in this execution  
*/
probe nfs.aop.writepages =  kernel.function ("nfs_writepages") ?,
             module("nfs").function ("nfs_writepages") ?
{
        dev = $mapping->host->i_sb->s_dev
        ino = $mapping->host->i_ino

        for_reclaim = $wbc->for_reclaim
        for_kupdate = $wbc->for_kupdate
        nr_to_write = $wbc->nr_to_write

        wsize = __nfs_server_wsize($mapping->host)
        wpages = __nfs_wpages($mapping->host)

        name = "nfs.aop.writepages"
        argstr = sprintf("%d",nr_to_write)

        size = nr_to_write
        units = "pages"         
}

probe nfs.aop.writepages.return =  kernel.function ("nfs_writepages").return ?,
             module("nfs").function ("nfs_writepages").return ?
{
        name = "nfs.aop.writepages.return"
        retstr = sprintf("%d", $return)
}
/*probe nfs.aop.prepare_write
 *  Fires when do write operation on nfs.
 *     Prepare a page for writing
 *     Look for a request corresponding to the page. If there
 *     is one, and it belongs to another file, we flush it out
 *     before we try to copy anything into the page. 
 *     Also do the same if we find a request from an existing
 *     dropped page
 *
 *  Arguments:
 *     __page : the address of page
 *     dev : device identifier
 *     ino : inode number 
 *     offset : start address of this write operation 
 *     to     : end address of this write operation 
 *     page_index : offset within mapping, can used a 
                     page identifier and position identifier
                     in the page frame
 *     size   : read bytes
*/
probe nfs.aop.prepare_write=  kernel.function ("nfs_prepare_write") ?,
             module("nfs").function ("nfs_prepare_write") ?
{
        dev = __page_dev(__page)
        devname = __find_bdevname(dev, __page_bdev(__page))
        ino = __page_ino(__page)      
  
        offset = $offset
        to = $to
       
        page_index = $page->index
        __page = $page

        name = "nfs.aop.prepare_write"
        argstr = sprintf("%d", page_index)

        size = to - offset
        units = "bytes"        
}

probe nfs.aop.prepare_write.return = 
                 kernel.function ("nfs_prepare_write").return ?,
                 module("nfs").function ("nfs_prepare_write").return ?
{
        name = "nfs.aop.nfs_prepare_write.return"
        retstr = sprintf("%d", $return)
}

/*probe nfs.aop.commit_write
 *  Fires when do a write operation on nfs,
 *  often after prepare_write
 *
 *  Update and possibly write a cached page of an NFS file
 *
 *  Arguments:
 *     __page : the address of page
 *     dev : device identifier
 *     ino : inode number
 *     offset : start address of this write operation 
 *     to     : end address of this write operation
 *     i_flag : file flags
 *     i_size : file length in bytes
 *     sb_flag : super block flags
 *     page_index : offset within mapping, can used a 
                    page identifier and position identifier
                    in the page frame
 *     size   : read bytes
 */ 
probe nfs.aop.commit_write=  kernel.function ("nfs_commit_write") ?,
             module("nfs").function ("nfs_commit_write") ?
{
         __page = $page
        dev = __page_dev(__page)
        ino = __page_ino(__page)

        offset = $offset
        to = $to
      

        i_flag = __p2i_flag($page) 
        i_size = __p2i_size($page)

        sb_flag = __p2sb_flag($page) 

        page_index = $page->index
     
        name = "nfs.aop.commit_write"
        argstr = sprintf("%d, %d",offset , to)

        size = to - offset
        units = "bytes"
}


probe nfs.aop.commit_write.return=  
             kernel.function ("nfs_commit_write").return ?,
             module("nfs").function ("nfs_commit_write").return? 
{
        name = "nfs.aop.nfs_commit_write.return"
        retstr = sprintf("%d", $return)
}

/*probe nfs.aop.release_page
 *  Fires when do a release operation on nfs,
 *  
 *
 *  Arguments:
 *     __page : the address of page
 *     dev : device identifier
 *     ino : inode number
 *     page_index : offset within mapping, can used a 
                    page identifier and position identifier
                    in the page frame
 *     size : release pages
*/
probe nfs.aop.release_page =  kernel.function ("nfs_release_page") ?,
             module("nfs").function ("nfs_release_page")?
{
        __page = $page
        dev = __page_dev(__page)
        ino = __page_ino(__page)

//        gfp = $gfp
        page_index = $page->index

        name = "nfs.aop.releasepage"
        argstr = sprintf("%d", page_index)

        size = 1
        units = "pages"

}  

probe nfs.aop.release_page.return =  kernel.function ("nfs_release_page").return ?,
             module("nfs").function ("nfs_release_page").return?
{
        name = "nfs.aop.nfs_release_page.return"
        retstr = sprintf("%d", $return)
}


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [ltc-perf]  draft of nfs event hook
  2006-08-11  1:59   ` Xue Peng Li
@ 2006-08-16  8:53     ` Xue Peng Li
  2006-08-22 10:06       ` Xue Peng Li
  0 siblings, 1 reply; 8+ messages in thread
From: Xue Peng Li @ 2006-08-16  8:53 UTC (permalink / raw)
  To: systemtap; +Cc: nfs

[-- Attachment #1: Type: text/plain, Size: 228 bytes --]

Hi folks
    This is another nfs tapset about nfs procedures stubs on client side. 
 And I will write nfs procedures stubs on server side at next step.

    If you have any questions/suggestions/comments,pls tell me
 


Thanks 

[-- Attachment #2: nfs_proc.stp --]
[-- Type: application/octet-stream, Size: 30450 bytes --]

%{
	#include <linux/nfs_fs.h>
%}

%{
/*Get ip address from a rpc_task*/
	__u32 get_ip(struct rpc_task *);
/*Get protocol types from a rpc_task*/
	int get_prot(struct rpc_task *);
%}
%{
     __u32 get_ip(struct rpc_task * task)
     {
        struct rpc_clnt * tk_client;
        struct rpc_xprt * cl_xprt;
        tk_client = task->tk_client;
        cl_xprt= tk_client->cl_xprt;

        return cl_xprt->addr.sin_addr.s_addr;
     }
     int get_prot(struct rpc_task * task)
     {
        struct rpc_clnt * tk_client;
        struct rpc_xprt * cl_xprt;
        tk_client = task->tk_client;
        cl_xprt= tk_client->cl_xprt;

        return cl_xprt->prot;
    }
%}
/*
  0:get ip address
  1:get proto
*/
function __i2n_ip_proto :long(dir:long,index:long)
%{
	int index = (int) (THIS->index);
	struct inode * dir = (struct inode *)(THIS->dir);
        struct rpc_clnt * clnt = NFS_CLIENT(dir);
        struct rpc_xprt * cl_xprt = clnt->cl_xprt;
        struct sockaddr_in * addr = &(cl_xprt->addr);

        if(index == 0)
		THIS->__retvalue = addr->sin_addr.s_addr;
        else
		THIS->__retvalue = cl_xprt->prot;
%}

/*
  0:get ip address
  1:get proto
*/
function __nfs_data_ip_proto:long (rdata :long,index :long)
%{
        int index = (int)(THIS->index);
        struct nfs_read_data * rdata = (struct nfs_read_data *)(THIS->rdata);
	struct rpc_task    *task = &(rdata->task);

	if(index == 0)
		THIS->__retvalue = get_ip(task);
	else
		THIS->__retvalue = get_prot(task);
%}

function __nfsv4_bitmask :long(dir:long,i:long)
%{
        int i = (int) (THIS->i);
	struct inode * dir = (struct inode *)(THIS->dir);
        struct nfs_server * server = NFS_SERVER(dir);

        THIS->__retvalue = server->attr_bitmask[i];

%}

probe nfs.proc.entries = nfs.proc.lookup,
			nfs.proc.read,
			nfs.proc.write,
			nfs.proc.commit,
			nfs.proc.read_setup,
			nfs.proc.write_setup,
			nfs.proc.commit_setup,
			nfs.proc.read_done,
			nfs.proc.write_done,
			nfs.proc.commit_done,
			nfs.proc.open,
			nfs.proc.release
{
}


probe nfs.proc.return = nfs.proc.lookup.return,
			nfs.proc.read.return,
			nfs.proc.write.return,
			nfs.proc.commit.return,
			nfs.proc.read_done.return,
			nfs.proc.write_done.return,
			nfs.proc.commit_done.return,
			nfs.proc.open.return,
			nfs.proc.release.return  
{
}

/*
*probe nfs.proc.lookup
*
* Fires when client opens/searchs a file on server
*
* Arguments:
*   server_ip : ip address of server
*   prot  : transfer protocol
*   version : nfs version
*   filename : the name of  file which client opens/searchs on server
*   name_len : the length of file name
*   bitmask0:
*   bitmask1 :V4 bitmask representing the set of attributes 
*             supported on this filesystem (only in probe nfs.proc4.lookup)
* 
*/
probe nfs.proc.lookup = nfs.proc2.lookup,
                        nfs.proc3.lookup,
                        nfs.proc4.lookup
{
}

probe nfs.proc.lookup.return = nfs.proc2.lookup.return,
                               nfs.proc3.lookup.return,
                               nfs.proc4.lookup.return
{}

probe nfs.proc2.lookup = kernel.function("nfs_proc_lookup")?,
                         module("nfs").function("nfs_proc_lookup")?
{
	server_ip = __i2n_ip_proto($dir,0)
        prot   = __i2n_ip_proto($dir,1)
        version = "NFSV2"

	filename = kernel_string($name->name)
        name_len = $name->len

        name = "nfs.proc2.lookup"
        argstr = sprintf("%s",filename) 
}

probe nfs.proc2.lookup.return = kernel.function("nfs_proc_lookup").return?,
                                module("nfs").function("nfs_proc_lookup").return?
{
        version = "NFSV2"
	name = "nfs.proc2.lookup.return"
	retstr = sprintf("%d", $return)
}

probe nfs.proc3.lookup = kernel.function("nfs3_proc_lookup")?,
                         module("nfs").function("nfs3_proc_lookup")?
{

	server_ip = __i2n_ip_proto($dir,0)
        prot   = __i2n_ip_proto($dir,1)
        version = "NFSV3"

	filename = kernel_string($name->name)
        name_len = $name->len

        name = "nfs.proc3.lookup"
        argstr = sprintf("%s",filename) 
}


probe nfs.proc3.lookup.return = kernel.function("nfs3_proc_lookup").return?,
                                module("nfs").function("nfs3_proc_lookup").return?
{
        version = "NFSV3"
	name = "nfs.proc3.lookup.return"
	retstr = sprintf("%d", $return)
}

probe nfs.proc4.lookup = kernel.function("nfs4_proc_lookup")?,
                         module("nfs").function("nfs4_proc_lookup")?
{

	server_ip = __i2n_ip_proto($dir,0)
        prot   = __i2n_ip_proto($dir,1)
        version = "NFSV4"

	filename = kernel_string($name->name)
        name_len = $name->len
        bitmask0 = __nfsv4_bitmask($dir,0)
        bitmask1 = __nfsv4_bitmask($dir,1)

        name = "nfs.proc4.lookup"
        argstr = sprintf("%s",filename) 
}

probe nfs.proc4.lookup.return = kernel.function("nfs4_proc_lookup").return?,
                                module("nfs").function("nfs4_proc_lookup").return?
{
        version = "NFSV4"
	name = "nfs.proc4.lookup.return"
	retstr = sprintf("%d", $return)
}

/*
*probe nfs.proc.read
*
* Fires when client synchronously reads file from server 
*
* Arguments:
*   server_ip : ip address of server
*   prot  : transfer protocol
*   version : nfs version
*   flags  : used to set task->tk_flags in rpc_init_task function
*   size:
*   count : read bytes in this execution
*   offset : the file offset
* 
*/
probe nfs.proc.read = nfs.proc2.read ,
                      nfs.proc3.read ,
                      nfs.proc4.read 
{}


probe nfs.proc.read.return = nfs.proc2.read.return ,
                      nfs.proc3.read.return ,
                      nfs.proc4.read.return 
{
}

probe nfs.proc2.read = kernel.function("nfs_proc_read") ?,
                       module("nfs").function("nfs_proc_read")?
{
	server_ip = __nfs_data_ip_proto($rdata,0)
        prot = __nfs_data_ip_proto($rdata,1)
        version = "NFSV2"

	flags = $rdata->flags
        count = $rdata->args->count
        offset = $rdata->args->offset

	name = "nfs.proc2.read"
	argstr = sprintf("%d,%d",count,offset)

        size = count
        units = "bytes"
}

probe nfs.proc2.read.return = kernel.function("nfs_proc_read").return ?,
                       module("nfs").function("nfs_proc_read").return?
{
        version = "NFSV2"
	name = "nfs.proc2.read.return"
	retstr = sprintf("%d", $return)
       
        if(retsrt >= 0)
        {  
        	size = retstr
	        units = "bytes"
	}
}

probe nfs.proc3.read = kernel.function("nfs3_proc_read") ?,
                       module("nfs").function("nfs3_proc_read")?
{
	server_ip = __nfs_data_ip_proto($rdata,0)
        prot = __nfs_data_ip_proto($rdata,1)
        version = "NFSV3"

	flags = $rdata->flags
        count = $rdata->args->count
        offset = $rdata->args->offset

	name = "nfs.proc3.read"
	argstr = sprintf("%d,%d",count,offset)

        size = count
        units = "bytes"
}


probe nfs.proc3.read.return = kernel.function("nfs3_proc_read").return ?,
                       module("nfs").function("nfs3_proc_read").return?
{
        version = "NFSV3"
	name = "nfs.proc3.read.return"
	retstr = sprintf("%d", $return)

        if(retsrt >= 0)
        {  
        	size = retstr
	        units = "bytes"
	}
}


probe nfs.proc4.read = kernel.function("nfs4_proc_read") ?,
                       module("nfs").function("nfs4_proc_read")?
{
	server_ip = __nfs_data_ip_proto($rdata,0)
        prot = __nfs_data_ip_proto($rdata,1)
        version = "NFSV4"

	flags = $rdata->flags
        count = $rdata->args->count
        offset = $rdata->args->offset

	name = "nfs.proc4.read"
	argstr = sprintf("%d,%d",count,offset)

        size = count
        units = "bytes"
}


probe nfs.proc4.read.return = kernel.function("nfs4_proc_read").return ?,
                       module("nfs").function("nfs4_proc_read").return?
{
        version = "NFSV4"
	name = "nfs.proc4.read.return"
	retstr = sprintf("%d", $return)
        
        if(retsrt >= 0)
        {  
        	size = retstr
	        units = "bytes"
	}
}


/*
*probe nfs.proc.write
*
* Fires when client synchronously writes file to server 
*
* Arguments:
*   server_ip : ip address of server
*   prot  : transfer protocol
*   version : nfs version
*   flags  : used to set task->tk_flags in rpc_init_task function
*   count :
*   size  : read bytes in this execution
*   offset : the file offset
*   bitmask0:
*   bitmask1 :V4 bitmask representing the set of attributes 
*             supported on this filesystem (only in probe nfs.proc4.lookup)
*/

probe nfs.proc.write = nfs.proc2.write ,
                      nfs.proc3.write ,
                      nfs.proc4.write 
{}


probe nfs.proc.write.return = nfs.proc2.write.return ,
                      nfs.proc3.write.return ,
                      nfs.proc4.write.return 
{}

probe nfs.proc2.write = kernel.function("nfs_proc_write")?,
                        module("nfs").function("nfs_proc_write")
{
      
	server_ip = __nfs_data_ip_proto($wdata,0)
        prot = __nfs_data_ip_proto($wdata,1)
        version = "NFSV2"

	flags = $wdata->flags
        count = $wdata->args->count
        offset = $wdata->args->offset

	name = "nfs.proc2.write"
	argstr = sprintf("%d,%d",count,offset)

        size = count
        units = "bytes"
}


probe nfs.proc2.write.return = kernel.function("nfs_proc_write").return ?,
                       module("nfs").function("nfs_proc_write").return?
{
        version = "NFSV2"
	name = "nfs.proc2.write.return"
	retstr = sprintf("%d", $return)
        
        if(retsrt >= 0)
        {  
        	size = retstr
	        units = "bytes"
	}
}


probe nfs.proc3.write = kernel.function("nfs3_proc_write")?,
                        module("nfs").function("nfs3_proc_write")
{
      
	server_ip = __nfs_data_ip_proto($wdata,0)
        prot = __nfs_data_ip_proto($wdata,1)
        version = "NFSV3"

	flags = $wdata->flags
        count = $wdata->args->count
        offset = $wdata->args->offset

	name = "nfs.proc3.write"
	argstr = sprintf("%d,%d",count,offset)

        size = count
        units = "bytes"
}


probe nfs.proc3.write.return = kernel.function("nfs3_proc_write").return ?,
                       module("nfs").function("nfs3_proc_write").return?
{
        version = "NFSV3"
	name = "nfs.proc3.write.return"
	retstr = sprintf("%d", $return)
        
        if(retsrt >= 0)
        {  
        	size = retstr
	        units = "bytes"
	}
}


probe nfs.proc4.write = kernel.function("nfs4_proc_write")?,
                        module("nfs").function("nfs4_proc_write")
{
      
	server_ip = __nfs_data_ip_proto($wdata,0)
        prot = __nfs_data_ip_proto($wdata,1)
        version = "NFSV4"

	flags = $wdata->flags
        count = $wdata->args->count
        offset = $wdata->args->offset
        bitmask0 = __nfsv4_bitmask($wdata->inode,0)
        bitmask1 = __nfsv4_bitmask($wdata->inode,1)

	name = "nfs.proc4.write"
	argstr = sprintf("%d,%d",count,offset)

        size = count
        units = "bytes"
}


probe nfs.proc4.write.return = kernel.function("nfs4_proc_write").return ?,
                       module("nfs").function("nfs4_proc_write").return?
{
        version = "NFSV4"
	name = "nfs.proc4.write.return"
	retstr = sprintf("%d", $return)
        
        if(retsrt >= 0)
        {  
        	size = retstr
	        units = "bytes"
	}
}

/*
*probe nfs.proc.commit
*
* Fires when client writes the buffered data to disk,the buffered 
* data is asynchronously written by client before
* The commit function works in sync way,not exist in NFSV2
*
* Arguments:
*   server_ip : ip address of server
*   prot  : transfer protocol
*   version : nfs version
*   flags  : used to set task->tk_flags in rpc_init_task function
*   count :
*   size  : read bytes in this execution
*   offset : the file offset
*   bitmask0:
*   bitmask1 :V4 bitmask representing the set of attributes 
*             supported on this filesystem (only in probe nfs.proc4.lookup)
*/
probe nfs.proc.commit = nfs.proc3.commit,
                        nfs.proc4.commit
{}

probe nfs.proc.commit.return = nfs.proc3.commit.return,
                               nfs.proc4.commit.return
{}

probe nfs.proc3.commit = kernel.function ("nfs3_proc_commit")?,
                         module("nfs").function("nfs3_proc_commit")?
{
	server_ip = __nfs_data_ip_proto($cdata,0)
        prot = __nfs_data_ip_proto($cdata,1)
        version = "NFSV3"

        count = $cdata->args->count
        offset = $cdata->args->offset

	name = "nfs.proc3.commit"
	argstr = sprintf("%d,%d",count,offset)

        size = count
        units = "bytes"
}

probe nfs.proc3.commit.return = kernel.function ("nfs3_proc_commit").return?,
                         module("nfs").function("nfs3_proc_commit").return?
{
        version = "NFSV3"
	name = "nfs.proc3.commit.return"
	retstr = sprintf("%d", $return)
        
        if(retsrt >= 0)
        {  
        	size = retstr
	        units = "bytes"
	}
}


probe nfs.proc4.commit = kernel.function ("nfs4_proc_commit")?,
                         module("nfs").function("nfs4_proc_commit")?
{
	server_ip = __nfs_data_ip_proto($cdata,0)
        prot = __nfs_data_ip_proto($cdata,1)
        version = "NFSV4"

        count = $cdata->args->count
        offset = $cdata->args->offset
        bitmask0 = __nfsv4_bitmask($cdata->inode,0)
        bitmask1 = __nfsv4_bitmask($cdata->inode,1)

	name = "nfs.proc4.commit"
	argstr = sprintf("%d,%d",count,offset)

        size = count
        units = "bytes"
}

probe nfs.proc4.commit.return = kernel.function ("nfs4_proc_commit").return?,
                         module("nfs").function("nfs4_proc_commit").return?
{
        version = "NFSV4"
	name = "nfs.proc4.commit.return"
	retstr = sprintf("%d", $return)
        
        if(retsrt >= 0)
        {  
        	size = retstr
	        units = "bytes"
	}
}

/*
*probe nfs.proc.read_setup
*
* The read_setup function is used to setup a read rpc task,not do
* a real read operation.
*
* Arguments:
*   server_ip : ip address of server
*   prot  : transfer protocol
*   version : nfs version
*   count :
*   size  : read bytes in this execution
*   offset : the file offset 
*/
probe nfs.proc.read_setup = nfs.proc2.read_setup ,
                      nfs.proc3.read_setup ,
                      nfs.proc4.read_setup 
{}



probe nfs.proc2.read_setup = kernel.function("nfs_proc_read_setup") ?,
                       module("nfs").function("nfs_proc_read_setup")?
{
	server_ip = __nfs_data_ip_proto($data,0)
        prot = __nfs_data_ip_proto($data,1)
        version = "NFSV2"

        count = $data->args->count
        offset = $data->args->offset

	name = "nfs.proc2.read_setup"
	argstr = sprintf("%d,%d",count,offset)

        size = count
        units = "bytes"
}


probe nfs.proc3.read_setup = kernel.function("nfs3_proc_read_setup") ?,
                       module("nfs").function("nfs3_proc_read_setup")?
{
	server_ip = __nfs_data_ip_proto($data,0)
        prot = __nfs_data_ip_proto($data,1)
        version = "NFSV3"

        count = $data->args->count
        offset = $data->args->offset

	name = "nfs.proc3.read_setup"
	argstr = sprintf("%d,%d",count,offset)

        size = count
        units = "bytes"
}




probe nfs.proc4.read_setup = kernel.function("nfs4_proc_read_setup") ?,
                       module("nfs").function("nfs4_proc_read_setup")?
{
	server_ip = __nfs_data_ip_proto($data,0)
        prot = __nfs_data_ip_proto($data,1)
        version = "NFSV4"

        count = $data->args->count
        offset = $data->args->offset
	//timestamp = $jiffies

	name = "nfs.proc4.read_setup"
	argstr = sprintf("%d,%d",count,offset)

        size = count
        units = "bytes"
}


/*probe nfs.proc.read_done
*
* Fires when a read reply is received or some read error occur
* (timeout or socket shutdown)
*
* Arguments:
*   server_ip : ip address of server
*   prot  : transfer protocol
*   version : nfs version
*   status : result of last operation
*   count  : read size of last operation
*   offset : the file offset of last operation
*   timestamp : time stamp ,which is used for lease renewal (only
    in nfs.proc4.read_done)
*/
probe nfs.proc.read_done = nfs.proc2.read_done,
                           nfs.proc3.read_done,
                           nfs.proc4.read_done
{}

probe nfs.proc.read_done.return = nfs.proc2.read_done.return,
                           nfs.proc3.read_done.return,
                           nfs.proc4.read_done.return
{}

probe nfs.proc2.read_done = kernel.function("nfs_read_done")?,
                            module("nfs").function("nfs_read_done")?
{
	server_ip = __nfs_data_ip_proto($data,0)
        prot = __nfs_data_ip_proto($data,1)
        version = "NFSV2"

	status = $task->tk_status
	offset = $data->args->offset
	count = $data->args->count

	name = "nfs.proc2.read_done"
        argstr = sprintf("%d",status)

}

probe nfs.proc2.read_done.return = kernel.function("nfs_read_done").return?,
                            module("nfs").function("nfs_read_done").return?
{
        version = "NFSV2"
	name = "nfs.proc2.read_done.return"
	retstr = sprintf("%d", $return)
}


probe nfs.proc3.read_done = kernel.function("nfs3_read_done")?,
                            module("nfs").function("nfs3_read_done")?
{
	server_ip = __nfs_data_ip_proto($data,0)
        prot = __nfs_data_ip_proto($data,1)
        version = "NFSV3"

	status = $task->tk_status
	offset = $data->args->offset
	count = $data->args->count

	name = "nfs.proc3.read_done"
        argstr = sprintf("%d",status)

}

probe nfs.proc3.read_done.return = kernel.function("nfs3_read_done").return?,
                            module("nfs").function("nfs3_read_done").return?
{
        version = "NFSV3"
	name = "nfs.proc3.read_done.return"
	retstr = sprintf("%d", $return)
}


probe nfs.proc4.read_done = kernel.function("nfs4_read_done")?,
                            module("nfs").function("nfs4_read_done")?
{
	server_ip = __nfs_data_ip_proto($data,0)
        prot = __nfs_data_ip_proto($data,1)
        version = "NFSV4"

	status = $task->tk_status
	offset = $data->args->offset
	count = $data->args->count
        timestamp = $data->timestamp

	name = "nfs.proc4.read_done"
        argstr = sprintf("%d",status)

}

probe nfs.proc4.read_done.return = kernel.function("nfs4_read_done").return?,
                            module("nfs").function("nfs4_read_done").return?
{
        version = "NFSV4"
	name = "nfs.proc4.read_done.return"
	retstr = sprintf("%d", $return)
}

/*probe nfs.proc.write_setup
*
* The write_setup function is used to setup a write rpc task,not do
* a real write operation.
*
* Arguments:
*   server_ip : ip address of server
*   prot  : transfer protocol
*   version : nfs version
*   size :
*   count : read bytes in this execution
*   offset : the file offset
*   how : used to set args.stable.
*         The stable value could be:
*         NFS_UNSTABLE,NFS_DATA_SYNC,NFS_FILE_SYNC(in nfs.proc3.write_setup and nfs.proc4.write_setup)
*   bitmask0:
*   bitmask1 :V4 bitmask representing the set of attributes 
*             supported on this filesystem (only in probe nfs.proc4.lookup)
*/

probe nfs.proc.write_setup = nfs.proc2.write_setup,
                             nfs.proc3.write_setup,
                             nfs.proc4.write_setup
{}


probe nfs.proc2.write_setup = kernel.function("nfs_proc_write_setup") ?,
                              module("nfs").function("nfs_proc_write_setup") ?
{
	server_ip = __nfs_data_ip_proto($data,0)
        prot = __nfs_data_ip_proto($data,1)
        version = "NFSV2"

        count = $data->args->count
        offset = $data->args->offset

	name = "nfs.proc2.write_setup"
	argstr = sprintf("%d,%d",count,offset)

        size = count
        units = "bytes"
}


probe nfs.proc3.write_setup = kernel.function("nfs3_proc_write_setup") ?,
                              module("nfs").function("nfs3_proc_write_setup") ?
{
	server_ip = __nfs_data_ip_proto($data,0)
        prot = __nfs_data_ip_proto($data,1)
        version = "NFSV3"

        count = $data->args->count
        offset = $data->args->offset
	how = $how

	name = "nfs.proc3.write_setup"
	argstr = sprintf("%d,%d,%d",count,offset,how)

        size = count
        units = "bytes"
}

probe nfs.proc4.write_setup = kernel.function("nfs4_proc_write_setup") ?,
                              module("nfs").function("nfs4_proc_write_setup") ?
{
	server_ip = __nfs_data_ip_proto($data,0)
        prot = __nfs_data_ip_proto($data,1)
        version = "NFSV4"

        count = $data->args->count
        offset = $data->args->offset
	how = $how
        bitmask0 = __nfsv4_bitmask($data->inode,0)
        bitmask1 = __nfsv4_bitmask($data->inode,1)
	//timestamp = $jiffies
	
	name = "nfs.proc4.write_setup"
	argstr = sprintf("%d,%d,%d",count,offset,how)

        size = count
        units = "bytes"
}


/*probe nfs.proc.write_done
*
* Fires when a write reply is received or some write error occur
* (timeout or socket shutdown)
*
* Arguments:
*   server_ip : ip address of server
*   prot  : transfer protocol
*   version : nfs version
*   status : result of last operation
*   valid  : fattr->valid ,indicates which fields are valid 
*   count  : read size of last operation
*   offset : the file offset of last operation
*   timestamp : time stamp ,which is used for lease renewal (only
    in nfs.proc4.write_done)
*/
probe nfs.proc.write_done = nfs.proc2.write_done,
                            nfs.proc3.write_done,
                            nfs.proc4.write_done 
{}

probe nfs.proc.write_done.return = nfs.proc2.write_done.return,
                            nfs.proc3.write_done.return,
                            nfs.proc4.write_done.return 
{}

probe nfs.proc2.write_done = kernel.function("nfs_write_done") ?,
                             module("nfs").function("nfs_write_done") ?
{
	server_ip = __nfs_data_ip_proto($data,0)
        prot = __nfs_data_ip_proto($data,1)
        version = "NFSV2"

	status = $task->tk_status
	valid = $data->res->fattr->valid
	offset = $data->args->offset
	count = $data->args->count

	name = "nfs.proc2.write_done"
	argstr = sprintf("%d",status)
}

probe nfs.proc2.write_done.return = kernel.function("nfs_write_done").return ?,
                             module("nfs").function("nfs_write_done").return ?
{
        version = "NFSV2"
	name = "nfs.proc2.write_done.return"
	retstr = sprintf("%d", $return)
}

probe nfs.proc3.write_done = kernel.function("nfs3_write_done") ?,
                             module("nfs").function("nfs3_write_done") ?
{
	server_ip = __nfs_data_ip_proto($data,0)
        prot = __nfs_data_ip_proto($data,1)
        version = "NFSV3"

	status = $task->tk_status
	valid = $data->res->fattr->valid
	offset = $data->args->offset
	count = $data->args->count

	name = "nfs.proc3.write_done"
	argstr = sprintf("%d",status)
}

probe nfs.proc3.write_done.return = kernel.function("nfs3_write_done").return ?,
                             module("nfs").function("nfs3_write_done").return ?
{
        version = "NFSV3"
	name = "nfs.proc3.write_done.return"
	retstr = sprintf("%d", $return)
}

probe nfs.proc4.write_done = kernel.function("nfs4_write_done") ?,
                             module("nfs").function("nfs4_write_done") ?
{
	server_ip = __nfs_data_ip_proto($data,0)
        prot = __nfs_data_ip_proto($data,1)
        version = "NFSV4"

	status = $task->tk_status
	valid = $data->res->fattr->valid
	offset = $data->args->offset
	count = $data->args->count
	timestamp = $data->timestamp

	name = "nfs.proc4.write_done"
	argstr = sprintf("%d",status)
}

probe nfs.proc4.write_done.return = kernel.function("nfs4_write_done").return ?,
                             module("nfs").function("nfs4_write_done").return ?
{
        version = "NFSV4"
	name = "nfs.proc4.write_done.return"
	retstr = sprintf("%d", $return)
}


/*probe nfs.proc.commit_setup
*
* The commit_setup function is used to setup a commit rpc task,not do
* a real commit operation.It is not exist in NFSV2
*
* Arguments:
*   server_ip : ip address of server
*   prot  : transfer protocol
*   version : nfs version
*   size :
*   count : read bytes in this execution
*   offset : the file offset
*   bitmask0:
*   bitmask1 :V4 bitmask representing the set of attributes 
*             supported on this filesystem (only in probe nfs.proc4.lookup)
*/

probe nfs.proc.commit_setup =nfs.proc3.commit_setup,
                             nfs.proc4.commit_setup
{}


probe nfs.proc3.commit_setup = kernel.function("nfs3_proc_commit_setup") ?,
                              module("nfs").function("nfs3_proc_commit_setup") ?
{
	server_ip = __nfs_data_ip_proto($data,0)
        prot = __nfs_data_ip_proto($data,1)
        version = "NFSV3"

        count = $data->args->count
        offset = $data->args->offset

	name = "nfs.proc3.commit_setup"
	argstr = sprintf("%d,%d,%d",count,offset,how)

        size = count
        units = "bytes"
}

probe nfs.proc4.commit_setup = kernel.function("nfs4_proc_commit_setup") ?,
                              module("nfs").function("nfs4_proc_commit_setup") ?
{
	server_ip = __nfs_data_ip_proto($data,0)
        prot = __nfs_data_ip_proto($data,1)
        version = "NFSV4"

        count = $data->args->count
        offset = $data->args->offset
        bitmask0 = __nfsv4_bitmask($data->inode,0)
        bitmask1 = __nfsv4_bitmask($data->inode,1)
	//timestamp = $jiffies
	
	name = "nfs.proc4.commit_setup"
	argstr = sprintf("%d,%d,%d",count,offset,how)

        size = count
        units = "bytes"
}


/*probe nfs.proc.commit_done
*
* Fires when a commit reply is received or some commit operation error occur
* (timeout or socket shutdown)
*
* Arguments:
*   server_ip : ip address of server
*   prot  : transfer protocol
*   version : nfs version
*   status : result of last operation
*   valid  : fattr->valid ,indicates which fields are valid 
*   count  : read size of last operation
*   offset : the file offset of last operation
*   timestamp : time stamp ,which is used for lease renewal (only
    in nfs.proc4.commit_done)
*/
probe nfs.proc.commit_done = 
                            nfs.proc3.commit_done,
                            nfs.proc4.commit_done 
{}

probe nfs.proc.commit_done.return = 
                            nfs.proc3.commit_done.return,
                            nfs.proc4.commit_done.return 
{}


probe nfs.proc3.commit_done = kernel.function("nfs3_commit_done") ?,
                             module("nfs").function("nfs3_commit_done") ?
{
	server_ip = __nfs_data_ip_proto($data,0)
        prot = __nfs_data_ip_proto($data,1)
        version = "NFSV3"

	status = $task->tk_status
        count = $data->args->count
        offset = $data->args->offset
	valid = $data->res->fattr->valid

	name = "nfs.proc3.commit_done"
	argstr = sprintf("%d",status)
}

probe nfs.proc3.commit_done.return = kernel.function("nfs3_commit_done").return ?,
                             module("nfs").function("nfs3_commit_done").return ?
{
        version = "NFSV3"
	name = "nfs.proc3.commit_done.return"
	retstr = sprintf("%d", $return)
}

probe nfs.proc4.commit_done = kernel.function("nfs4_commit_done") ?,
                             module("nfs").function("nfs4_commit_done") ?
{
	server_ip = __nfs_data_ip_proto($data,0)
        prot = __nfs_data_ip_proto($data,1)
        version = "NFSV4"

	status = $task->tk_status
        count = $data->args->count
        offset = $data->args->offset
	valid = $data->res->fattr->valid
	timestamp = $data->timestamp

	name = "nfs.proc4.commit_done"
	argstr = sprintf("%d",status)
}

probe nfs.proc4.commit_done.return = kernel.function("nfs4_commit_done").return ?,
                             module("nfs").function("nfs4_commit_done").return ?
{
        version = "NFSV4"
	name = "nfs.proc4.commit_done.return"
	retstr = sprintf("%d", $return)
}
/*probe nfs.proc.open
*
*  Allocate file read/write context information
*
* Arguments:
*   server_ip : ip address of server
*   prot  : transfer protocol
*   version : nfs version(the function is used for all NFS version)
*   filename : file name opened on server side
*   flag   : file flag
*   mode   : file  mode
*/

probe nfs.proc.open = kernel.function("nfs_open") ?,
                      module("nfs").function("nfs_open") ?
{
	server_ip = __i2n_ip_proto($inode,0)
	prot = __i2n_ip_proto($inode,1)  	
	version = "NFS"

	filename = kernel_string($filp->f_dentry->d_name->name)
	flag = $filp->f_flags
	mode = $filp->f_mode

	name = "nfs.proc.open"
	argstr = sprintf("%s,%d,%d",filename,flag,mode)
}

probe nfs.proc.open.return = kernel.function("nfs_open").return ?,
                      module("nfs").function("nfs_open").return ?
{
	version = "NFS"
	name = "nfs.proc.open.return"
	retstr = sprintf("%d", $return)
}

/*probe nfs.proc.release
*
*  Release file read/write context information
*
* Arguments:
*   server_ip : ip address of server
*   prot  : transfer protocol
*   version : nfs version(the function is used for all NFS version)
*   filename : file name opened on server side
*   flag   : file flag
*   mode   : file  mode
*/
probe nfs.proc.release= kernel.function("nfs_release") ?,
                      module("nfs").function("nfs_release") ?
{
	server_ip = __i2n_ip_proto($inode,0)
	prot = __i2n_ip_proto($inode,1)  	
	version = "NFS"

	filename = kernel_string($filp->f_dentry->d_name->name)
	flag = $filp->f_flags
	mode = $filp->f_mode

	name = "nfs.proc.release"
	argstr = sprintf("%s,%d,%d",filename,flag,mode)
}

probe nfs.proc.release.return = kernel.function("nfs_release").return ?,
                      module("nfs").function("nfs_release").return ?
{
	version = "NFS"
	name = "nfs.proc.release.return"
	retstr = sprintf("%d", $return)
}
/*
*probe nfs.proc4.hadle_exception (only for NFSV4)
* This is the error handling routine for processes for nfsv4
*
* Arguments:
*  errorcode : indicates the type of error
*/
probe nfs.proc4.handle_exception = kernel.function("nfs4_handle_exception") ?,
                               module("nfs").function("nfs4_handle_exception")?
{
	version = "NFSV4"
	
        errorcode = $errorcode

        name = "nfs.proc4.handle_exception"
        argstr =  sprintf("%d",errorcode)
}

probe nfs.proc4.handle_exception.return = kernel.function("nfs4_handle_exception").return ?,
                               module("nfs").function("nfs4_handle_exception").return?
{
        name = "nfs.proc4.handle_exception.return"
        retstr =  sprintf("%d",$return)
}


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [ltc-perf]  draft of nfs event hook
  2006-08-16  8:53     ` Xue Peng Li
@ 2006-08-22 10:06       ` Xue Peng Li
  0 siblings, 0 replies; 8+ messages in thread
From: Xue Peng Li @ 2006-08-22 10:06 UTC (permalink / raw)
  To: systemtap; +Cc: nfs

[-- Attachment #1: Type: text/plain, Size: 1353 bytes --]

Hi folks,
    This is nfsd tapset ,which includes nfsd procedures stubs on server 
side and nfsd functions called by corresponding procedures stubs.
In this tapset , I only probes some procedures stubs and nfsd functions 
not all of them .And this is the last nfs tapset,
I have sent out all nfs tapsets yet.

    Not like NFSV2 and NFSV3,there is just one procedure stub for 
NFSV4,nfsd4_proc_compound ,which will call difference function 
according to RPC request.So there is only one probe point at proc level 
for NFSV4.Some nfsd functions for NFSV4 like nfsd4_read,
nfsd4_write etc,are static inline functions,can't be probed.

    tell me if you have any questions/comments 

    BTW: My kernel is 2.6.17.2,could anyone tell me the NFSV4 of this 
kernel is  available?



Thanks.
Best Regards,

Li Xuepeng  (李雪鹏)

Linux Performance, China Systems & Technology Lab
China Development Labs, Beijing
Email: xuepengl@cn.ibm.com

systemtap-owner@sourceware.org wrote on 2006-08-16 16:56:32:

> Hi folks
>     This is another nfs tapset about nfs procedures stubs on client 
side. 
>  And I will write nfs procedures stubs on server side at next step.
> 
>     If you have any questions/suggestions/comments,pls tell me
> 
> 
> 
> Thanks 
> [attachment "nfs_proc.stp" deleted by Xue Peng Li/China/Contr/IBM] 

[-- Attachment #2: nfsd.stp --]
[-- Type: application/octet-stream, Size: 27619 bytes --]

%{
#include <linux/sunrpc/svc.h>
#include <linux/nfsd/nfsd.h>
#include <linux/nfsd/cache.h>
#include <linux/nfsd/xdr.h>
#include <linux/nfsd/xdr3.h>
%}

%{
/*Get file handle from struct svc_fh */
	char * fh_fmt(struct svc_fh * fhp)
	{
		 struct knfsd_fh *fh = &fhp->fh_handle;

        	static char buf[80];
	        sprintf(buf, "%d: %08x %08x %08x %08x %08x %08x",
        	        fh->fh_size,
                	fh->fh_base.fh_pad[0],
	                fh->fh_base.fh_pad[1],
        	        fh->fh_base.fh_pad[2],
	                fh->fh_base.fh_pad[3],
        	        fh->fh_base.fh_pad[4],
	                fh->fh_base.fh_pad[5]);
	        return buf;
	}
%}
/*
*1 : nfsd.proc2.lookup
*2 : nfsd.proc3.lookup
*3 : nfsd.proc2.read
*4 : nfsd.proc3.read
*5 : nfsd.proc2.write
*6 : nfsd.proc3.write
*7 : nfsd.proc3.commit
*8 : nfsd.proc2.create
*9 : nfsd.proc3.create
*10: nfsd.proc2.remove
*11: nfsd.proc3.remove
*12 :nfsd.proc2.rename.ffh
*13 :nfsd.proc2.rename.tfh
*14 :nfsd.proc3.rename.ffh
*15 :nfsd.proc3.rename.tfh
*/

/*Get file handler from argp,the index indicates the type of argp*/
function __get_fh:string (argp:long,index:long)
%{
	int index = (int)(THIS->index);
	struct nfsd_diropargs * argp = NULL ;
	struct nfsd3_diropargs * argp3 = NULL ;
	struct nfsd_readargs * argpr = NULL;
	struct nfsd3_readargs * argpr3 = NULL;
	struct nfsd_writeargs * argpw = NULL;
	struct nfsd3_writeargs * argpw3 = NULL;
	struct nfsd3_commitargs * argpc3 = NULL;
	struct nfsd_createargs *argpcr = NULL;
	struct nfsd3_createargs *argpcr3 = NULL;
	struct nfsd_diropargs *argpre = NULL;
	struct nfsd3_diropargs *argpre3 = NULL;
	struct nfsd_renameargs *argpren = NULL;
	struct nfsd3_renameargs *argpren3 = NULL;
	struct svc_fh * fhp = NULL;
	char * buf;

	switch(index)
	{
	case 1: argp = (struct nfsd_diropargs *)THIS->argp;
		fhp = &argp->fh;
		break;
	case 2: argp3 = (struct nfsd3_diropargs *)THIS->argp;
		fhp = &argp3->fh;
		break;
	case 3: argpr = (struct nfsd_readargs * )THIS->argp;
		fhp = &argpr->fh;
		break;
	case 4: argpr3 = (struct nfsd3_readargs * )THIS->argp;
		fhp = &argpr3->fh;
		break;
	case 5: argpw = (struct nfsd_writeargs * )THIS->argp;
		fhp = &argpw->fh;
		break;
	case 6: argpw3 = (struct nfsd3_writeargs * )THIS->argp;
		fhp = &argpw3->fh;
		break;
	case 7: argpc3 = (struct nfsd3_commitargs * )THIS->argp;
		fhp = &argpc3->fh;
		break;
	case 8: argpcr = (struct nfsd_createargs * )THIS->argp;
		fhp = &argpcr->fh;
		break;
	case 9: argpcr3 = (struct nfsd3_createargs * )THIS->argp;
		fhp = &argpcr3->fh;
		break;
	case 10: argpre = (struct nfsd_diropargs * )THIS->argp;
		fhp = &argpre->fh;
		break;
	case 11: argpre3 = (struct nfsd3_diropargs * )THIS->argp;
		fhp = &argpre3->fh;
		break;
	case 12: argpren = (struct nfsd_renameargs * )THIS->argp;
		fhp = &argpren->ffh;
		break;
	case 13: argpren = (struct nfsd_renameargs * )THIS->argp;
		fhp = &argpren->tfh;
		break;
	case 14: argpren3 = (struct nfsd3_renameargs * )THIS->argp;
		fhp = &argpren3->ffh;
		break;
	case 15: argpren3 = (struct nfsd3_renameargs * )THIS->argp;
		fhp = &argpren3->tfh;
		break;
	}
	
	if(fhp == NULL)
	{
		_stp_printf("the fhp is NULL");
	}
	else
	{
		buf = fh_fmt(fhp);
//	_stp_printf("%s:\n",buf);
		strlcpy (THIS->__retvalue,buf,80);
	}
%}
/*Get file handler from struct svc_fh , it will call
fh_fmt function*/
function __svc_fh:string(fh :long)
%{
	struct svc_fh * fhp = (struct svc_fh *) (THIS->fh);
	char * buf ;
	
	buf =  fh_fmt(fhp); 	
	strlcpy (THIS->__retvalue,buf,80);
%}

function p_long:long(cnt:long)
%{
	unsigned long * count = (unsigned long *)(THIS->cnt);
	
	THIS->__retvalue = *count;
%}
/*
*probe nfsd.dispatch
*  Fires when server receives a NFS operation from client 
*
*Arguments:
*  client_ip : the ip address of client
*  proto : transfer protocol
*  version : nfs version
*  xid : transmission id
*  prog : program number
*  proc : procedure number
*/
probe nfsd.dispatch = kernel.function("nfsd_dispatch")?,
                      module("nfsd").function("nfsd_dispatch") ?
{
	client_ip = $rqstp->rq_addr->sin_addr->s_addr
	proto = $rqstp->rq_prot
	version = $rqstp->rq_vers

	xid = $rqstp->rq_xid
	prog = $rqstp->rq_prog
	proc = $rqstp->rq_proc

	name = "nfsd.dispatch"
	argstr = sprintf("%d,%d",version,proto)
}

probe nfsd.dispatch.return = kernel.function("nfsd_dispatch").return?,
                      module("nfsd").function("nfsd_dispatch").return ?
{
	name = "nfsd.dispatch.return"
	retstr = sprintf("%d",$return)
}

probe nfsd.proc.entries = nfsd.proc.lookup,
                          nfsd.proc.read,
                          nfsd.proc.write,
                          nfsd.proc.commit,
                          nfsd.proc.compound,
                          nfsd.proc.rename,
			  nfsd.proc.create
{} 

probe nfsd.proc.return = nfsd.proc.lookup.return,
                          nfsd.proc.read.return,
                          nfsd.proc.write.return,
                          nfsd.proc.commit.return,
                          nfsd.proc.compound.return,
                          nfsd.proc.rename.return,
                          nfsd.proc.create.return
{} 

/*
*probe nfsd.proc.lookup
*  Fires when client opens/searchs file on server
*
*Arguments:
*  client_ip : the ip address of client
*  proto : transfer protocol
*  version : nfs version
*  fh  : file handle of parent dir (the first part is the length of the file handle)
*  filename : file name 
*  filelen  : the length of file name
*/
probe nfsd.proc.lookup = nfsd.proc2.lookup,
                         nfsd.proc3.lookup
{}

probe nfsd.proc.lookup.return = nfsd.proc2.lookup.return,
                         nfsd.proc3.lookup.return
{}

probe nfsd.proc2.lookup = kernel.function("nfsd_proc_lookup") ?,
                          module("nfsd").function("nfsd_proc_lookup") ?
{
	client_ip = $rqstp->rq_addr->sin_addr->s_addr
	proto = $rqstp->rq_prot
        version = "NFSV2"
	fh = __get_fh($argp,1)

	filename = kernel_string($argp->name)
	filelen = $argp->len

	name = "nfsd.proc2.lookup"
	argstr = sprintf("%s",filename)
}

 
probe nfsd.proc2.lookup.return = kernel.function("nfsd_proc_lookup").return ?,
                          module("nfsd").function("nfsd_proc_lookup").return ?
{
	name = "nfsd.proc2.lookup.return"
	version = "NFSV2"
	retstr = sprintf("%d",$return)
}

probe nfsd.proc3.lookup = kernel.function("nfsd3_proc_lookup") ?,
                          module("nfsd").function("nfsd3_proc_lookup") ?
{
	client_ip = $rqstp->rq_addr->sin_addr->s_addr
	proto = $rqstp->rq_prot
        version = "NFSV3"
	fh = __get_fh($argp,1)

	filename = kernel_string($argp->name)
	filelen = $argp->len

	name = "nfsd.proc3.lookup"
	argstr = sprintf("%s",filename)
} 

probe nfsd.proc3.lookup.return = kernel.function("nfsd3_proc_lookup").return ?,
                          module("nfsd").function("nfsd3_proc_lookup").return ?
{
	name = "nfsd.proc3.lookup.return"
	version = "NFSV3"
	retstr = sprintf("%d",$return)
}


/*
*probe nfsd.proc.read
*  Fires when client read file on server
*
*Arguments:
*  client_ip : the ip address of client
*  proto : transfer protocol
*  version : nfs version
*  fh  : file handle (the first part is the length of the file handle)
*  size:
*  count : read bytes
*  offset : the offset of file 
*  vec : struct kvec ,includes buf address in kernel address
         and length of each buffer
*  vlen : read blocks 
*/
probe nfsd.proc.read = nfsd.proc2.read,
                       nfsd.proc3.read
{}

probe nfsd.proc.read.return = nfsd.proc2.read.return,
                       nfsd.proc3.read.return
{

}

probe nfsd.proc2.read = kernel.function("nfsd_proc_read")?,
                        module("nfsd").function("nfsd_proc_read")?
{
	client_ip = $rqstp->rq_addr->sin_addr->s_addr
	proto = $rqstp->rq_prot
        version = "NFSV2"
	fh = __get_fh($argp,3)

	count = $argp->count 
	offset = $argp->offset 
	vec = $argp->vec
	vlen = $argp->vlen

	name = "nfsd.proc2.read"
	argstr = sprintf("%d,%d",count,offset)

        size = count
        units = "bytes"
}

 
probe nfsd.proc2.read.return = kernel.function("nfsd_proc_read").return?,
                        module("nfsd").function("nfsd_proc_read").return?
{
	name = "nfsd.proc2.read.return"
	version = "NFSV2"
	retstr = sprintf("%d",$return)
}

probe nfsd.proc3.read = kernel.function("nfsd3_proc_read")?,
                        module("nfsd").function("nfsd3_proc_read")?
{
	client_ip = $rqstp->rq_addr->sin_addr->s_addr
	proto = $rqstp->rq_prot
        version = "NFSV3"
	fh = __get_fh($argp,4)

	count = $argp->count 
	offset = $argp->offset 
	vec = $argp->vec
	vlen = $argp->vlen

	name = "nfsd.proc3.read"
	argstr = sprintf("%d,%d",count,offset)

        size = count
        units = "bytes"
}

 
probe nfsd.proc3.read.return = kernel.function("nfsd3_proc_read").return?,
                        module("nfsd").function("nfsd3_proc_read").return?
{
	name = "nfsd.proc3.read.return"
	version = "NFSV3"
	retstr = sprintf("%d",$return)
}

/*
*probe nfsd.proc.write
*  Fires when client writes data to  file on server
*
*Arguments:
*  client_ip : the ip address of client
*  proto : transfer protocol
*  version : nfs version
*  fh  : file handle (the first part is the length of the file handle)
*  size:
*  count : read bytes
*  offset : the offset of file 
*  vec : struct kvec ,includes buf address in kernel address
         and length of each buffer
*  vlen : read blocks 
*  stable : argp->stable(only in nfs.proc3.write)
*/
probe nfsd.proc.write = nfsd.proc2.write,
                       nfsd.proc3.write
{}

probe nfsd.proc.write.return = nfsd.proc2.write.return,
                       nfsd.proc3.write.return
{

}

probe nfsd.proc2.write = kernel.function("nfsd_proc_write")?,
                        module("nfsd").function("nfsd_proc_write")?
{
	client_ip = $rqstp->rq_addr->sin_addr->s_addr
	proto = $rqstp->rq_prot
        version = "NFSV2"
	fh = __get_fh($argp,5)

	count = $argp->len
	offset = $argp->offset 
	vec = $argp->vec
	vlen = $argp->vlen

	name = "nfsd.proc2.write"
	argstr = sprintf("%d,%d",count,offset)

        size = count
        units = "bytes"
}

 
probe nfsd.proc2.write.return = kernel.function("nfsd_proc_write").return?,
                        module("nfsd").function("nfsd_proc_write").return?
{
	name = "nfsd.proc2.write.return"
	version = "NFSV2"
	retstr = sprintf("%d",$return)
}

probe nfsd.proc3.write = kernel.function("nfsd3_proc_write")?,
                        module("nfsd").function("nfsd3_proc_write")?
{
	client_ip = $rqstp->rq_addr->sin_addr->s_addr
	proto = $rqstp->rq_prot
        version = "NFSV3"
	fh = __get_fh($argp,6)

	count = $argp->count 
	offset = $argp->offset 
	vec = $argp->vec
	vlen = $argp->vlen
	stable = $argp->stable

	name = "nfsd.proc3.write"
	argstr = sprintf("%d,%d",count,offset)

        size = count
        units = "bytes"
}

 
probe nfsd.proc3.write.return = kernel.function("nfsd3_proc_write").return?,
                        module("nfsd").function("nfsd3_proc_write").return?
{
	name = "nfsd.proc3.write.return"
	version = "NFSV3"
	retstr = sprintf("%d",$return)
}

/*
*probe nfsd.proc.commit
*  Fires when client does a commit operation,which is
*  used to flush the data written by async operation before
*  to disk
*
*Arguments:
*  client_ip : the ip address of client
*  proto : transfer protocol
*  version : nfs version
*  fh  : file handle (the first part is the length of the file handle)
*  size:
*  count : read bytes
*  offset : the offset of file 
*/
probe nfsd.proc.commit =  nfsd.proc3.commit
{}

probe nfsd.proc.commit.return = nfsd.proc3.commit.return
{

}

probe nfsd.proc3.commit = kernel.function("nfsd3_proc_commit")?,
                        module("nfsd").function("nfsd3_proc_commit")?
{
	client_ip = $rqstp->rq_addr->sin_addr->s_addr
	proto = $rqstp->rq_prot
        version = "NFSV3"
	fh = __get_fh($argp,7) 

	count = $argp->count 
	offset = $argp->offset 

	name = "nfsd.proc3.commit"
	argstr = sprintf("%d,%d",count,offset)

        size = count
        units = "bytes"
}

probe nfsd.proc3.commit.return = kernel.function("nfsd3_proc_commit").return?,
                        module("nfsd").function("nfsd3_proc_commit").return?
{
	name = "nfsd.proc3.commit.return"
	version = "NFSV3"
	retstr = sprintf("%d",$return)
}

/*
*probe nfsd.proc.create
* Fires when clients create a file on server side.
*
* Arguments:
*  client_ip : the ip address of client
*  proto : transfer protocol
*  version : nfs version
*  fh  : file handle (the first part is the length of the file handle)
*  filename : file name
*  filelen : length of file name
*/
probe nfsd.proc.create = nfsd.proc2.create,
                         nfsd.proc3.create
{}
probe nfsd.proc.create.return = nfsd.proc2.create.return,
                                nfsd.proc3.create.return
{}

probe nfsd.proc2.create = kernel.function("nfsd_proc_create")?,
                         module("nfsd").function("nfsd_proc_create")
{
	client_ip = $rqstp->rq_addr->sin_addr->s_addr
	proto = $rqstp->rq_prot
        version = "NFSV2"
	fh = __get_fh($argp,8)

	filename  = kernel_string($argp->name) 
	filelen = $argp->len

	name = "nfsd.proc2.create"
	argstr = sprintf("%s",filename)
}

probe nfsd.proc2.create.return =  kernel.function("nfsd_proc_create").return?,
                                 module("nfsd").function("nfsd_proc_create").return
{
	name = "nfsd.proc2.create.return"
	version = "NFSV2"
	retstr = sprintf("%d",$return)
}

probe nfsd.proc3.create = kernel.function("nfsd3_proc_create")?,
                         module("nfsd").function("nfsd3_proc_create")
{
	client_ip = $rqstp->rq_addr->sin_addr->s_addr
	proto = $rqstp->rq_prot
        version = "NFSV3"
	fh = __get_fh($argp,9)

	filename  = kernel_string($argp->name) 
	filelen = $argp->len
	
	name = "nfsd.proc3.create"
	argstr = sprintf("%s",filename)
}

probe nfsd.proc3.create.return =  kernel.function("nfsd3_proc_create").return?,
                                 module("nfsd").function("nfsd3_proc_create").return
{
	name = "nfsd.proc3.create.return"
	version = "NFSV3"
	retstr = sprintf("%d",$return)
}

/*
*probe nfsd.proc.remove
* Fires when clients removes a file on server side.
*
* Arguments:
*  client_ip : the ip address of client
*  proto : transfer protocol
*  version : nfs version
*  fh  : file handle (the first part is the length of the file handle)
*  filename : file name
*  filelen : length of file name
*/
probe nfsd.proc.remove = nfsd.proc2.remove,
                         nfsd.proc3.remove
{}
probe nfsd.proc.remove.return = nfsd.proc2.remove.return,
                                nfsd.proc3.remove.return
{}

probe nfsd.proc2.remove = kernel.function("nfsd_proc_remove")?,
                         module("nfsd").function("nfsd_proc_remove")
{
	client_ip = $rqstp->rq_addr->sin_addr->s_addr
	proto = $rqstp->rq_prot
        version = "NFSV2"
	fh = __get_fh($argp,10)

	filename  = kernel_string($argp->name) 
	filelen = $argp->len

	name = "nfsd.proc2.remove"
	argstr = sprintf("%s",filename)
}

probe nfsd.proc2.remove.return =  kernel.function("nfsd_proc_remove").return?,
                                 module("nfsd").function("nfsd_proc_remove").return
{
	name = "nfsd.proc2.remove.return"
	version = "NFSV2"
	retstr = sprintf("%d",$return)
}

probe nfsd.proc3.remove = kernel.function("nfsd3_proc_remove")?,
                         module("nfsd").function("nfsd3_proc_remove")
{
	client_ip = $rqstp->rq_addr->sin_addr->s_addr
	proto = $rqstp->rq_prot
        version = "NFSV3"
	fh = __get_fh($argp,11)

	filename  = kernel_string($argp->name) 
	filelen = $argp->len
	
	name = "nfsd.proc3.remove"
	argstr = sprintf("%s",filename)
}

probe nfsd.proc3.remove.return =  kernel.function("nfsd3_proc_remove").return?,
                                 module("nfsd").function("nfsd3_proc_remove").return?
{
	name = "nfsd.proc3.remove.return"
	version = "NFSV3"
	retstr = sprintf("%d",$return)
}

/*
* probe nfsd.proc.rename
*  Fires when clients rename a file on server side
*
* Arguments:
*   fh : file handler of old path
*   tfh : file handler of new path
*   filename : old file name 
*   tname : new file name
*   flen : length of old file name 
*   tlen : length of new file name
*/
probe nfsd.proc.rename = nfsd.proc2.rename,
                         nfsd.proc3.rename
{}

probe nfsd.proc.rename.return = nfsd.proc2.rename.return,
                         nfsd.proc3.rename.return
{}

probe nfsd.proc2.rename =  kernel.function("nfsd_proc_rename")?,
                           module("nfsd").function("nfsd_proc_rename")?
{
	client_ip = $rqstp->rq_addr->sin_addr->s_addr
	proto = $rqstp->rq_prot
        version = "NFSV2"
	fh = __get_fh($argp,12)
	tfh = __get_fh($argp,13)

	filename  = kernel_string($argp->fname) 
	filelen = $argp->flen
	tname = kernel_string($argp->tname)
	tlen = $argp->tlen

	name = "nfsd.proc2.rename"
	argstr = sprintf("%s,%s",filename,tname)
}

probe nfsd.proc2.rename.return =  kernel.function("nfsd2_proc_rename").return?,
                           module("nfsd").function("nfsd2_proc_rename").return?
{
	name = "nfsd.proc2.rename.return"
	version = "NFSV2"
	retstr = sprintf("%d",$return)
}

probe nfsd.proc3.rename =  kernel.function("nfsd3_proc_rename")?,
                           module("nfsd").function("nfsd3_proc_rename")?
{
	client_ip = $rqstp->rq_addr->sin_addr->s_addr
	proto = $rqstp->rq_prot
        version = "NFSV3"
	fh = __get_fh($argp,14)
	tfh = __get_fh($argp,15)

	filename  = kernel_string($argp->fname) 
	filelen = $argp->flen
	tname = kernel_string($argp->tname)
	tlen = $argp->tlen

	name = "nfsd.proc3.rename"
	argstr = sprintf("%s,%s",filename,tname)
}

probe nfsd.proc3.rename.return =  kernel.function("nfsd3_proc_rename").return?,
                           module("nfsd").function("nfsd3_proc_rename").return?
{
	name = "nfsd.proc3.rename.return"
	version = "NFSV3"
	retstr = sprintf("%d",$return)
}
/*
*probe nfsd.proc.compound
*   Fires when the server received a NFSV4 operation from client
*
*Arguments:
*  client_ip : the ip address of client
*  proto : transfer protocol
*  version : nfs version
*  num : number of file operation in this RPC operation 
*  op : head of operation list in this compound execution
*/
probe nfsd.proc.compound = nfsd.proc4.compound
{}

probe nfsd.proc.compound.return = nfsd.proc4.compound.return
{}

probe nfsd.proc4.compound = kernel.function("nfsd4_proc_compound")?,
                            module("nfsd").function("nfsd4_proc_compound")
{
	client_ip = $rqstp->rq_addr->sin_addr->s_addr
	proto = $rqstp->rq_prot
        version = "NFSV4"

	num = $args->opcnt
	op = $args->ops
	
	name = "nfsd.proc4.cmpound"
	argstr = sprintf("%d",num)
}

probe nfsd.proc4.compound.return = kernel.function("nfsd4_proc_compound").return?,
                            module("nfsd").function("nfsd4_proc_compound").return
{
	name = "nfsd.proc4.compound.return"
	version = "NFSV4"
	retstr = sprintf("%d",$return)
}

probe nfsd.entries = nfsd.open,
	             nfsd.read,
                     nfsd.write,
                     nfsd.lookup,
                     nfsd.commit,
                     nfsd.create,
                     nfsd.createv3,
                     nfsd.unlink,
                     nfsd.rename,
                     nfsd.close
{}

probe nfsd.return= nfsd.open.return,
	             nfsd.read.return,
                     nfsd.write.return,
                     nfsd.lookup.return,
                     nfsd.commit.return,
                     nfsd.create.return,
                     nfsd.createv3.return,
                     nfsd.unlink.return,
                     nfsd.rename,return,
                     nfsd.close.return
{}
/*probe nfsd.open
*  Fires when server opens a file
*
* Arguments:
*  fh  : file handle (the first part is the length of the file handle)
*  access : indicates the type of open(read/write/commit/readdir...) 
*  type : type of file(regular file or dir)
*/
probe nfsd.open = kernel.function("nfsd_open") ?,
                  module("nfsd").function("nfsd_open")
{
	fh = __svc_fh($fhp)

	access = $access
	type = $type

	name = "nfsd.open"
	argstr = sprintf("%d",access)
}

probe nfsd.open.return = kernel.function("nfsd_open").return ?,
                  module("nfsd").function("nfsd_open").return
{
	name = "nfsd.open.return"
	retstr = sprintf("%d",$return)
}

/*probe nfsd.close
*  Fires when server closes a file
*
* Arguments:
* filename : file name
*/
probe nfsd.close = kernel.function("nfsd_close")?,
                   module("nfsd").function("nfsd_close")?
{
	filename = kernel_string($filp->f_dentry->d_name->name)

	name = "nfsd.close"
	argstr = sprintf("%s",filename)
}
/*probe nfsd.read
*  Fires when server reads data from a file
*
* Arguments:
*  fh  : file handle (the first part is the length of the file handle)
*  file : argument file,indicates if the file has been opened.
*  size:
*  count : read bytes
*  offset : the offset of file 
*  vec : struct kvec ,includes buf address in kernel address
         and length of each buffer
*  vlen : read blocks 
*/
probe nfsd.read = kernel.function("nfsd_read") ?,
                  module("nfsd").function("nfsd_read")?
{
	fh = __svc_fh($fhp)

	file = $file
	count = p_long($count)
	offset = $offset
	vec = $vec
	vlen = $vlen

	name = "nfsd.read"
	argstr = sprintf("%d,%d",count,offsee)

	size = count
	units = "bytes"
} 

probe nfsd.read.return = kernel.function("nfsd_read").return ?,
                  module("nfsd").function("nfsd_read").return?
{
	name = "nfsd.read.return"
	retstr = sprintf("%d",$return)
}

/*probe nfsd.write
*  Fires when server writes data to a file
*
* Arguments:
*  fh  : file handle (the first part is the length of the file handle)
*  file : argument file,indicates if the file has been opened.
*  size:
*  count : read bytes
*  offset : the offset of file 
*  vec : struct kvec ,includes buf address in kernel address
         and length of each buffer
*  vlen : read blocks 
*/
probe nfsd.write = kernel.function("nfsd_write")?,
                   module("nfsd").function("nfsd_write")?
{
	fh = __svc_fh($fhp)

	file = $file
	count = $cnt
	offset = $offset
	vec = $vec
	vlen = $vlen

	name = "nfsd.write"
	argstr = sprintf("%d,%d",count,offsee)

	size = count
	units = "bytes"
}

probe nfsd.write.return = kernel.function("nfsd_write").return?,
                   module("nfsd").function("nfsd_write").return?
{
	name = "nfsd.write.return"
	retstr = sprintf("%d",$return)
}

/*probe nfsd.commit
*  Fires when server commits all pending writes to stable storage.  
*
* Arguments:
*  fh  : file handle (the first part is the length of the file handle)
*  flag : indicates whether this execution is a sync operation
*  size:
*  count : read bytes
*  offset : the offset of file
*/
probe nfsd.commit = kernel.function("nfsd_commit")?,
                    module("nfsd").function("nfsd_commit")?
{
	fh = __svc_fh($fhp)

	count = $count
	offset = $offset
	flag = $fhp->fh_export->ex_flags

	name = "nfsd.commit"
	argstr = sprintf("%d,%d",count,offset)

	size = count 
	units = "bytes"
}

probe nfsd.commit.return = kernel.function("nfsd_commit").return?,
                    module("nfsd").function("nfsd_commit").return ?
{
	name = "nfsd.commit.return"
	retstr = sprintf("%d",$return)
}

/*
*probe nfsd.lookup
*  Fires when client opens/searchs file on server
*
*Arguments:
*  fh  : file handle of parent dir(the first part is the length of the file handle)
*  filename : file name 
*  filelen  : the length of file name
*/

probe nfsd.lookup = kernel.function("nfsd_lookup")?,
                    module("nfsd").function("nfsd_lookup")?
{
	fh = __svc_fh($fhp)

	filename = kernel_string($name)
	filelen = $len

	name = "nfsd.lookup"
	argstr = sprintf("%s",filename)
}

probe nfsd.lookup.return = kernel.function("nfsd_lookup").return?,
                            module("nfsd").function("nfsd_lookup").return?
{
	name = "nfsd.lookup.return"
	retstr = sprintf("%d",$return)
}
/*
* probe nfsd.create
*  Fires when client creates a file(regular,dir,device,fifo) on server side,
*  sometimes nfsd will call nfsd_create_v3 instead of this function
*
* Arguments:
*
*  fh  : file handle (the first part is the length of the file handle)
*  filename : file name 
*  filelen  : the length of file name
*  type : file type(regular,dir,device,fifo ...)
*  iap: inode attributes 
*/
probe nfsd.create = kernel.function("nfsd_create")?,         
                    module("nfsd").function("nfsd_create")?
{
	fh = __svc_fh($fhp)

	filename = kernel_string($fname)
	filelen = $flen
	type = $type
	iap = $iap

	name = "nfsd.create"
	argstr = sprintf("%s,%d",filename,iap)
}

probe nfsd.create.return = kernel.function("nfsd_create").return?,         
                    module("nfsd").function("nfsd_create").return?
{
	name = "nfsd.create.return"
	retstr = sprintf("%d",$return)
}

/*
* probe nfsd.createv3
*  Fires when client creates a regular file or set file attributes on server side,
*  only called by nfsd3_proc_create and nfsd4_open(op_claim_type is NFS4_OPEN_CLAIM_NULL)
*
* Arguments:
*
*  fh  : file handle (the first part is the length of the file handle)
*  filename : file name 
*  filelen  : the length of file name
*  iap : inode attributes 
*  createmode : create mode .The possible values could be:
*	NFS3_CREATE_EXCLUSIVE,NFS3_CREATE_UNCHECKED,NFS3_CREATE_GUARDED
*  truncp : trunp arguments, indicates if the file shouldbe truncate
*  verfier :  file attributes (atime,mtime,mode).It's used to reset file
              attributes for CREATE_EXCLUSIVE
*/
probe nfsd.createv3 = kernel.function("nfsd_create_v3")?,         
                    module("nfsd").function("nfsd_create_v3")?
{
	fh = __svc_fh($fhp)

	filename = kernel_string($fname)
	filelen = $flen
	ia_mode = $iap
	truncp = $truncp
	verfier = $verifier
	createmode = $createmode

	name = "nfsd.createv3"
	argstr = sprintf("%s,%d",filename,createmode)
}

probe nfsd.createv3.return = kernel.function("nfsd_create_v3").return?,         
                    module("nfsd").function("nfsd_create_v3").return?
{
	name = "nfsd.createv3.return"
	retstr = sprintf("%d",$return)
}

/*
* probe nfsd.unlink
*  Fires when client removes a file or a dir  on server side,
*
* Arguments:
*
*  fh  : file handle (the first part is the length of the file handle)
*  filename : file name 
*  filelen  : the length of file name
*  type : file type(file or dir)
*/
probe nfsd.unlink = kernel.function("nfsd_unlink")?,         
                    module("nfsd").function("nfsd_unlink")?
{
	fh = __svc_fh($fhp)

	filename = kernel_string($fname)
	filelen = $flen
	type = $type

	name = "nfsd.unlink"
	argstr = sprintf("%s,%d",filename,iap)
}

probe nfsd.unlink.return = kernel.function("nfsd_unlink").return?,         
                    module("nfsd").function("nfsd_unlink").return?
{
	name = "nfsd.unlink.return"
	retstr = sprintf("%d",$return)
}

/*
* probe nfsd.rename
*  Fires when clients rename a file on server side
*
* Arguments:
*   fh : file handler of old path
*   tfh : file handler of new path
*   filename : old file name 
*   tname : new file name
*   flen : length of old file name 
*   tlen : length of new file name
*/

probe nfsd.rename =  kernel.function("nfsd_rename")?,
                           module("nfsd").function("nfsd_rename")?
{
	fh = __svc_fh($ffhp)
	tfh = __svc_fh($tfhp)

	filename  = kernel_string($fname) 
	filelen = $flen
	tname = kernel_string($tname)
	tlen = $tlen

	name = "nfsd.rename"
	argstr = sprintf("%s,%s",filename,tname)
}

probe nfsd.rename.return =  kernel.function("nfsd_rename").return?,
                           module("nfsd").function("nfsd_rename").return?
{
	name = "nfsd.rename.return"
	retstr = sprintf("%d",$return)
}

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2006-08-22 10:06 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <OF053E04B8.D96A9ADC-ON482571B7.0031B2AD-482571B7.00323E27@cn.ibm.com>
2006-07-27 13:56 ` [ltc-perf] draft of nfs event hook Li Guanglei
2006-07-27 15:29   ` [NFS] " Chuck Lever
2006-07-27 17:01     ` Jose R. Santos
2006-07-27 22:46     ` Li Guanglei
     [not found]       ` <001301c6b1e8$bd7cf590$160b0a0a@ict25eacacc325>
2006-07-28  2:03         ` Li Guanglei
2006-08-11  1:59   ` Xue Peng Li
2006-08-16  8:53     ` Xue Peng Li
2006-08-22 10:06       ` Xue Peng Li

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).