[CSE]  Advanced Operating Systems 
 COMP9242 2006/S2 
CRICOS Provider
Number: 00098G

PRINTER Printer-Friendly Version
- Notices
- Course Intro
- Consultations
- Survey Results
- Lectures
- Selected Papers
- Project Spec
- Exam
2006 Patchlist
Project Resources
Slug Lab
L4 Debugging Guide
Developing on a Mac
Developing on Linux
SOS source browser

L4Ka::Pistachio FAQ
L4 reference manual
L4 user manual
IXP42X hardware manual 
NSLU2-Linux HomePage
Intel IXP400 Software

Related Info
Aurema OS Prize
OS Hall of Fame
- 1997
- Gernot Heiser (LiC)
- Kevin Elphinstone
- Guest Lecturers (TBA)
- Student Reps

Valid HTML 4.0!

NFS Client Library

The NFS client library provides a simple interface for accessing files on an NFS server. The majority of these functions provide an asynchronous interface. Instead of blocking until the NFS transaction is complete you instead pass a function pointer, which will be called when the operation is complete. The first argument of these function is token which you also specify on the call. More information on NFS can be found in the NFS RFC.

This documents the basic functionality and functions provided. You will probably want to look at the header files rpc.h and nfs.h which defines the structures used.

If you are running this code at home you will need to set up an NFS server on your machine. This requires running portmapper, mountd and nfsd. The NFS code also relies on the UDP time protocol to generate a unique transaction ID on boot.


int nfs_init(struct ip_addr server);

This function should be called once at startup, passing the adderss of your NFS server.


void nfs_timeout(void);

Since NFS runs over UDP, an unreliable protocol, it is possible that packets may be dropped. To allow NFS to retransmit packets that might have been dropped you must arrange for nfs_timeout to be called every 100ms. This could be achieved by either extending your clock driver, or using L4_Sleep.


int mnt_get_export_list(void)

This is simply a debugging function which will print out a list of mount points available on the server.


unsigned int mnt_mount(char* dir, struct cookie *pfh);

This will mount a filesystem and return a cookie to it in pfh. In your assignment you will be mounting the /tftpboot filesystem. The returned cookie will be used on subsequent NFS transactions.


int nfs_lookup(struct cookie *directory, char *name, void (*func) (uintptr_t token, int status, struct cookie * fh, fattr_t *attr), uintptr_t token);

Before you are able to complete any operation on a file you must obtain a handle to it. This is what the nfs_lookup function provides. This function will find a file named name in the specified directory. The root directory is of course the handle returned from mnt_mount. When the transaction has completed it will call the func you pass. This will be called with your token, and a status code. If the call is successful status will be zero, and you will also be passed a handle to the file, and its current attributes. NB: The pointers *fh and *attr are only valid during the call, if you need to keep them you must copy them into some other memory.


int nfs_getattr(struct cookie *fh, void (*func) (uintptr_t, int, fattr_t *), uintptr_t token);

This function is the equivilant of the UNIX stat function. It will find the current attributes on a given file handle (*fh). The attributes are passed back through the callback func. You may be able to avoid using this call since nfs_lookup, nfs_read and nfs_write also return the current file attributes.


int nfs_create(struct cookie *fh, char *name, sattr_t *sat, void (*func) (uintptr_t, int, struct cookie *, fattr_t *), uintptr_t token);

This function is used to create a new file named name with the attributes sat. On completion func is called with a handle to the new file and its attributes.


int nfs_read(struct cookie *fh, int pos, int count, void (*func) (uintptr_t, int, fattr_t *attr, int bytes_read, char *data), uintptr_t token);

nfs_read will read count bytes of data, starting at a given pos from the provided file handle. On completion your func is called with the current file attributes, the number of bytes_read and a pointer to the data. The data is only available for the duration of the system call, after which it is reused for other network packets. You will most likely need to copy this data into a user's data buffer.


int nfs_write(struct cookie *fh, int offset, int count, void *data, void (*func) (uintptr_t, int, fattr_t *), uintptr_t token);

nfs_write will write count bytes of data at a specific offset. When the transaction is completed your func will be called with the status and the current file attributes.


int nfs_readdir(struct cookie *pfh, int cookie, int read_size, void (*func) (uintptr_t token, int status, int num_entries, struct nfs_filename *filenames, int next_cookie), uintptr_t token);

struct nfs_filename {
  int size;
  const char *filename;

This function reads the contents, that is the filenames, from a directory pfh. When complete this transaction will call func with a pointer an array of filenames. This array is num_entries long. Each entry in the array contains a size and a pointer to the filename. Note that filename is NOT a null terminated string. Its length is specified by the size. As with other NFS callbacks the data here is only valid for the duration of the call and must be copied elsewhere if required.

The next_cookie argument indicates whether there are more directory entries available. If next_cookie is zero then all directory entries have been read. If it is greater than zero then there are more entries available and this value should be passed as the cookie argument to another nfs_readdir request. Note that zero should be passed as the initial cookie value.

The read_size parameter specifies the number of bytes of data to read on each request.

Last modified: 21 Jul 2006.