iPXE
Defines | Functions
nfs.c File Reference

Network File System protocol. More...

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <libgen.h>
#include <byteswap.h>
#include <ipxe/time.h>
#include <ipxe/iobuf.h>
#include <ipxe/open.h>
#include <ipxe/features.h>
#include <ipxe/nfs.h>
#include <ipxe/oncrpc.h>
#include <ipxe/oncrpc_iob.h>
#include <ipxe/portmap.h>
#include <ipxe/mount.h>
#include <ipxe/settings.h>

Go to the source code of this file.

Defines

#define NFS_LOOKUP   3
 NFS LOOKUP procedure.
#define NFS_READLINK   5
 NFS READLINK procedure.
#define NFS_READ   6
 NFS READ procedure.

Functions

size_t nfs_iob_get_fh (struct io_buffer *io_buf, struct nfs_fh *fh)
 Extract a file handle from the beginning of an I/O buffer.
size_t nfs_iob_add_fh (struct io_buffer *io_buf, const struct nfs_fh *fh)
 Add a file handle to the end of an I/O buffer.
int nfs_lookup (struct interface *intf, struct oncrpc_session *session, const struct nfs_fh *fh, const char *filename)
 Send a LOOKUP request.
int nfs_readlink (struct interface *intf, struct oncrpc_session *session, const struct nfs_fh *fh)
 Send a READLINK request.
int nfs_read (struct interface *intf, struct oncrpc_session *session, const struct nfs_fh *fh, uint64_t offset, uint32_t count)
 Send a READ request.
int nfs_get_lookup_reply (struct nfs_lookup_reply *lookup_reply, struct oncrpc_reply *reply)
 Parse a LOOKUP reply.
int nfs_get_readlink_reply (struct nfs_readlink_reply *readlink_reply, struct oncrpc_reply *reply)
 Parse a READLINK reply.
int nfs_get_read_reply (struct nfs_read_reply *read_reply, struct oncrpc_reply *reply)
 Parse a READ reply.

Detailed Description

Network File System protocol.

Definition in file nfs.c.


Define Documentation

#define NFS_LOOKUP   3

NFS LOOKUP procedure.

Definition at line 46 of file nfs.c.

Referenced by nfs_lookup().

#define NFS_READLINK   5

NFS READLINK procedure.

Definition at line 48 of file nfs.c.

Referenced by nfs_readlink().

#define NFS_READ   6

NFS READ procedure.

Definition at line 50 of file nfs.c.

Referenced by nfs_read().


Function Documentation

size_t nfs_iob_get_fh ( struct io_buffer io_buf,
struct nfs_fh fh 
)

Extract a file handle from the beginning of an I/O buffer.

Parameters:
io_bufI/O buffer
fhFile handle
Return values:
sizeSize of the data read

Definition at line 59 of file nfs.c.

References io_buffer::data, nfs_fh::fh, iob_pull, memcpy(), oncrpc_iob_get_int, and nfs_fh::size.

Referenced by mount_get_mnt_reply(), and nfs_get_lookup_reply().

                                                                      {
        fh->size = oncrpc_iob_get_int ( io_buf );

        if ( fh->size > 64 )
                return sizeof ( uint32_t );

        memcpy (fh->fh, io_buf->data, fh->size );
        iob_pull ( io_buf, fh->size );

        return fh->size + sizeof ( uint32_t );
}
size_t nfs_iob_add_fh ( struct io_buffer io_buf,
const struct nfs_fh fh 
)

Add a file handle to the end of an I/O buffer.

Parameters:
io_bufI/O buffer
fhFile handle
Return values:
sizeSize of the data written

Definition at line 78 of file nfs.c.

References nfs_fh::fh, iob_put, memcpy(), oncrpc_iob_add_int(), and nfs_fh::size.

                                                                            {
        size_t s;

        s = oncrpc_iob_add_int ( io_buf, fh->size );
        memcpy ( iob_put ( io_buf, fh->size ), &fh->fh, fh->size );

        return s + fh->size;
}
int nfs_lookup ( struct interface intf,
struct oncrpc_session session,
const struct nfs_fh fh,
const char *  filename 
)

Send a LOOKUP request.

Parameters:
intfInterface to send the request on
sessionONC RPC session
fhThe file handle of the the directory
filenameThe file name
Return values:
rcReturn status code

Definition at line 96 of file nfs.c.

References array, nfs_fh::fh, NFS_LOOKUP, oncrpc_call(), ONCRPC_FIELD, ONCRPC_FIELD_END, ONCRPC_SUBFIELD, and nfs_fh::size.

Referenced by nfs_step().

                                                                 {
        struct oncrpc_field fields[] = {
                ONCRPC_SUBFIELD ( array, fh->size, &fh->fh ),
                ONCRPC_FIELD ( str, filename ),
                ONCRPC_FIELD_END,
        };

        return oncrpc_call ( intf, session, NFS_LOOKUP, fields );
}
int nfs_readlink ( struct interface intf,
struct oncrpc_session session,
const struct nfs_fh fh 
)

Send a READLINK request.

Parameters:
intfInterface to send the request on
sessionONC RPC session
fhThe symlink file handle
Return values:
rcReturn status code

Definition at line 115 of file nfs.c.

References array, nfs_fh::fh, NFS_READLINK, oncrpc_call(), ONCRPC_FIELD_END, ONCRPC_SUBFIELD, and nfs_fh::size.

Referenced by nfs_step().

                                             {
        struct oncrpc_field fields[] = {
                ONCRPC_SUBFIELD ( array, fh->size, &fh->fh ),
                ONCRPC_FIELD_END,
        };

        return oncrpc_call ( intf, session, NFS_READLINK, fields );
}
int nfs_read ( struct interface intf,
struct oncrpc_session session,
const struct nfs_fh fh,
uint64_t  offset,
uint32_t  count 
)

Send a READ request.

Parameters:
intfInterface to send the request on
sessionONC RPC session
fhThe file handle
offsetOffset
countByte count
Return values:
rcReturn status code

Definition at line 135 of file nfs.c.

References array, nfs_fh::fh, NFS_READ, oncrpc_call(), ONCRPC_FIELD, ONCRPC_FIELD_END, ONCRPC_SUBFIELD, and nfs_fh::size.

Referenced by nfs_step().

                                                                          {
        struct oncrpc_field fields[] = {
                ONCRPC_SUBFIELD ( array, fh->size, &fh->fh ),
                ONCRPC_FIELD ( int64, offset ),
                ONCRPC_FIELD ( int32, count ),
                ONCRPC_FIELD_END,
        };

        return oncrpc_call ( intf, session, NFS_READ, fields );
}
int nfs_get_lookup_reply ( struct nfs_lookup_reply lookup_reply,
struct oncrpc_reply reply 
)

Parse a LOOKUP reply.

Parameters:
lookup_replyA structure where the data will be saved
replyThe ONC RPC reply to get data from
Return values:
rcReturn status code

Definition at line 154 of file nfs.c.

References oncrpc_reply::data, EACCES, EINVAL, EIO, ENAMETOOLONG, ENOENT, ENOTDIR, nfs_lookup_reply::ent_type, EPERM, EPROTO, ESTALE, nfs_lookup_reply::fh, NFS3_OK, NFS3ERR_ACCES, NFS3ERR_BADHANDLE, NFS3ERR_IO, NFS3ERR_NAMETOOLONG, NFS3ERR_NOENT, NFS3ERR_NOTDIR, NFS3ERR_PERM, NFS3ERR_SERVERFAULT, NFS3ERR_STALE, nfs_iob_get_fh(), oncrpc_iob_get_int, and nfs_lookup_reply::status.

Referenced by nfs_deliver().

                                                        {
        if ( ! lookup_reply || ! reply )
                return -EINVAL;

        lookup_reply->status = oncrpc_iob_get_int ( reply->data );
        switch ( lookup_reply->status )
        {
        case NFS3_OK:
                break;
        case NFS3ERR_PERM:
                return -EPERM;
        case NFS3ERR_NOENT:
                return -ENOENT;
        case NFS3ERR_IO:
                return -EIO;
        case NFS3ERR_ACCES:
                return -EACCES;
        case NFS3ERR_NOTDIR:
                return -ENOTDIR;
        case NFS3ERR_NAMETOOLONG:
                return -ENAMETOOLONG;
        case NFS3ERR_STALE:
                return -ESTALE;
        case NFS3ERR_BADHANDLE:
        case NFS3ERR_SERVERFAULT:
        default:
                return -EPROTO;
        }

        nfs_iob_get_fh ( reply->data, &lookup_reply->fh );

        if ( oncrpc_iob_get_int ( reply->data ) == 1 )
                lookup_reply->ent_type = oncrpc_iob_get_int ( reply->data );

        return 0;
}
int nfs_get_readlink_reply ( struct nfs_readlink_reply readlink_reply,
struct oncrpc_reply reply 
)

Parse a READLINK reply.

Parameters:
readlink_replyA structure where the data will be saved
replyThe ONC RPC reply to get data from
Return values:
rcReturn status code

Definition at line 198 of file nfs.c.

References io_buffer::data, oncrpc_reply::data, EACCES, EINVAL, EIO, ENOTSUP, EPROTO, ESTALE, iob_pull, NFS3_OK, NFS3ERR_ACCES, NFS3ERR_BADHANDLE, NFS3ERR_INVAL, NFS3ERR_IO, NFS3ERR_NOTSUPP, NFS3ERR_SERVERFAULT, NFS3ERR_STALE, oncrpc_iob_get_int, nfs_readlink_reply::path, nfs_readlink_reply::path_len, and nfs_readlink_reply::status.

Referenced by nfs_deliver().

                                                          {
        if ( ! readlink_reply || ! reply )
                return -EINVAL;

        readlink_reply->status = oncrpc_iob_get_int ( reply->data );
        switch ( readlink_reply->status )
        {
        case NFS3_OK:
                 break;
        case NFS3ERR_IO:
                return -EIO;
        case NFS3ERR_ACCES:
                return -EACCES;
        case NFS3ERR_INVAL:
                return -EINVAL;
        case NFS3ERR_NOTSUPP:
                return -ENOTSUP;
        case NFS3ERR_STALE:
                return -ESTALE;
        case NFS3ERR_BADHANDLE:
        case NFS3ERR_SERVERFAULT:
        default:
                return -EPROTO;
        }

        if ( oncrpc_iob_get_int ( reply->data ) == 1 )
                iob_pull ( reply->data, 5 * sizeof ( uint32_t ) +
                                        8 * sizeof ( uint64_t ) );

        readlink_reply->path_len = oncrpc_iob_get_int ( reply->data );
        readlink_reply->path     = reply->data->data;

        return 0;
}
int nfs_get_read_reply ( struct nfs_read_reply read_reply,
struct oncrpc_reply reply 
)

Parse a READ reply.

Parameters:
read_replyA structure where the data will be saved
replyThe ONC RPC reply to get data from
Return values:
rcReturn status code

Definition at line 241 of file nfs.c.

References nfs_read_reply::count, io_buffer::data, oncrpc_reply::data, nfs_read_reply::data, nfs_read_reply::data_len, EACCES, EINVAL, EIO, ENOENT, ENXIO, nfs_read_reply::eof, EPERM, EPROTO, ESTALE, nfs_read_reply::filesize, iob_pull, NFS3_OK, NFS3ERR_ACCES, NFS3ERR_BADHANDLE, NFS3ERR_INVAL, NFS3ERR_IO, NFS3ERR_NOENT, NFS3ERR_NXIO, NFS3ERR_PERM, NFS3ERR_SERVERFAULT, NFS3ERR_STALE, oncrpc_iob_get_int, oncrpc_iob_get_int64, and nfs_read_reply::status.

Referenced by nfs_deliver().

                                                      {
        if ( ! read_reply || ! reply )
                return -EINVAL;

        read_reply->status = oncrpc_iob_get_int ( reply->data );
        switch ( read_reply->status )
        {
        case NFS3_OK:
                 break;
        case NFS3ERR_PERM:
                return -EPERM;
        case NFS3ERR_NOENT:
                return -ENOENT;
        case NFS3ERR_IO:
                return -EIO;
        case NFS3ERR_NXIO:
                return -ENXIO;
        case NFS3ERR_ACCES:
                return -EACCES;
        case NFS3ERR_INVAL:
                return -EINVAL;
        case NFS3ERR_STALE:
                return -ESTALE;
        case NFS3ERR_BADHANDLE:
        case NFS3ERR_SERVERFAULT:
        default:
                return -EPROTO;
        }

        if ( oncrpc_iob_get_int ( reply->data ) == 1 )
        {
                iob_pull ( reply->data, 5 * sizeof ( uint32_t ) );
                read_reply->filesize = oncrpc_iob_get_int64 ( reply->data );
                iob_pull ( reply->data, 7 * sizeof ( uint64_t ) );
        }

        read_reply->count    = oncrpc_iob_get_int ( reply->data );
        read_reply->eof      = oncrpc_iob_get_int ( reply->data );
        read_reply->data_len = oncrpc_iob_get_int ( reply->data );
        read_reply->data     = reply->data->data;

        if ( read_reply->count != read_reply->data_len )
                return -EPROTO;

        return 0;
}