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 a 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.
nfs_init
int nfs_init(struct ip_addr server);
This function should be called once at startup, passing the
address of your NFS server.
nfs_timeout
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 using the timer.
mnt_get_export_list
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.
mnt_mount
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.
nfs_lookup
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.
nfs_getattr
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.
nfs_create
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.
nfs_read
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.
nfs_write
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.
nfs_readdir
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 *file;
};
This function reads the contents, that is the filenames, from a
directory pfh . When complete this transaction will
call func with a pointer to an array of
filenames . This array is num_entries
long. Each entry in the array contains a size and a
pointer to the name, file . Note that
file 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:
29 Aug 2011.
|