diff options
author | Michael Brown | 2008-01-08 17:46:55 +0100 |
---|---|---|
committer | Michael Brown | 2008-01-08 17:46:55 +0100 |
commit | f6a8158eed215954dafb7f622f6fd345b5b473d2 (patch) | |
tree | 74c855e3fb0a953ec463bfd4b5edb0248bd93ce8 /src/core | |
parent | Added the embedded pxelinux payload patch from hpa. (diff) | |
download | ipxe-f6a8158eed215954dafb7f622f6fd345b5b473d2.tar.gz ipxe-f6a8158eed215954dafb7f622f6fd345b5b473d2.tar.xz ipxe-f6a8158eed215954dafb7f622f6fd345b5b473d2.zip |
Make seek information part of the xfer metadata, rather than an entirely
separate xfer method.
Add missing .alloc_iob entries to several xfer_interface_operations
structures.
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/downloader.c | 69 | ||||
-rw-r--r-- | src/core/filter.c | 6 | ||||
-rw-r--r-- | src/core/hw.c | 2 | ||||
-rw-r--r-- | src/core/posix_io.c | 37 | ||||
-rw-r--r-- | src/core/resolv.c | 1 | ||||
-rw-r--r-- | src/core/xfer.c | 69 |
6 files changed, 61 insertions, 123 deletions
diff --git a/src/core/downloader.c b/src/core/downloader.c index 3726c6e1..0a443db2 100644 --- a/src/core/downloader.c +++ b/src/core/downloader.c @@ -96,6 +96,9 @@ static int downloader_ensure_size ( struct downloader *downloader, if ( len <= downloader->image->len ) return 0; + DBGC ( downloader, "Downloader %p extending to %zd bytes\n", + downloader, len ); + /* Extend buffer */ new_buffer = urealloc ( downloader->image->data, len ); if ( ! new_buffer ) { @@ -142,67 +145,43 @@ static struct job_interface_operations downloader_job_operations = { */ /** - * Handle seek() event received via data transfer interface - * - * @v xfer Downloader data transfer interface - * @v pos New position - * @ret rc Return status code - */ -static int downloader_xfer_seek ( struct xfer_interface *xfer, off_t offset, - int whence ) { - struct downloader *downloader = - container_of ( xfer, struct downloader, xfer ); - off_t new_pos; - int rc; - - /* Calculate new buffer position */ - switch ( whence ) { - case SEEK_SET: - new_pos = offset; - break; - case SEEK_CUR: - new_pos = ( downloader->pos + offset ); - break; - default: - assert ( 0 ); - return -EINVAL; - } - - /* Ensure that we have enough buffer space for this buffer position */ - if ( ( rc = downloader_ensure_size ( downloader, new_pos ) ) != 0 ) - return rc; - downloader->pos = new_pos; - - return 0; -} - -/** * Handle deliver_raw() event received via data transfer interface * * @v xfer Downloader data transfer interface - * @v data Data buffer - * @v len Length of data buffer + * @v iobuf Datagram I/O buffer + * @v meta Data transfer metadata * @ret rc Return status code */ -static int downloader_xfer_deliver_raw ( struct xfer_interface *xfer, - const void *data, size_t len ) { +static int downloader_xfer_deliver_iob ( struct xfer_interface *xfer, + struct io_buffer *iobuf, + struct xfer_metadata *meta ) { struct downloader *downloader = container_of ( xfer, struct downloader, xfer ); + size_t len; size_t max; int rc; + /* Calculate new buffer position */ + if ( meta->whence != SEEK_CUR ) + downloader->pos = 0; + downloader->pos += meta->offset; + /* Ensure that we have enough buffer space for this data */ + len = iob_len ( iobuf ); max = ( downloader->pos + len ); if ( ( rc = downloader_ensure_size ( downloader, max ) ) != 0 ) - return rc; + goto done; /* Copy data to buffer */ - copy_to_user ( downloader->image->data, downloader->pos, data, len ); + copy_to_user ( downloader->image->data, downloader->pos, + iobuf->data, len ); /* Update current buffer position */ downloader->pos += len; - return 0; + done: + free_iob ( iobuf ); + return rc; } /** @@ -227,10 +206,10 @@ static void downloader_xfer_close ( struct xfer_interface *xfer, int rc ) { static struct xfer_interface_operations downloader_xfer_operations = { .close = downloader_xfer_close, .vredirect = xfer_vopen, - .seek = downloader_xfer_seek, .window = unlimited_xfer_window, - .deliver_iob = xfer_deliver_as_raw, - .deliver_raw = downloader_xfer_deliver_raw, + .alloc_iob = default_xfer_alloc_iob, + .deliver_iob = downloader_xfer_deliver_iob, + .deliver_raw = xfer_deliver_as_iob, }; /**************************************************************************** diff --git a/src/core/filter.c b/src/core/filter.c index 51ec5c4b..f9ebe7cf 100644 --- a/src/core/filter.c +++ b/src/core/filter.c @@ -44,12 +44,6 @@ int filter_vredirect ( struct xfer_interface *xfer, int type, return xfer_vredirect ( other, type, args ); } -int filter_seek ( struct xfer_interface *xfer, off_t offset, int whence ) { - struct xfer_interface *other = filter_other_half ( xfer ); - - return xfer_seek ( other, offset, whence ); -} - size_t filter_window ( struct xfer_interface *xfer ) { struct xfer_interface *other = filter_other_half ( xfer ); diff --git a/src/core/hw.c b/src/core/hw.c index 3502dbfb..65604ee0 100644 --- a/src/core/hw.c +++ b/src/core/hw.c @@ -36,8 +36,8 @@ static void hw_xfer_close ( struct xfer_interface *xfer, int rc ) { static struct xfer_interface_operations hw_xfer_operations = { .close = hw_xfer_close, .vredirect = ignore_xfer_vredirect, - .seek = ignore_xfer_seek, .window = unlimited_xfer_window, + .alloc_iob = default_xfer_alloc_iob, .deliver_iob = xfer_deliver_as_raw, .deliver_raw = ignore_xfer_deliver_raw, }; diff --git a/src/core/posix_io.c b/src/core/posix_io.c index 27c72100..2e3781ad 100644 --- a/src/core/posix_io.c +++ b/src/core/posix_io.c @@ -104,38 +104,11 @@ static void posix_file_xfer_close ( struct xfer_interface *xfer, int rc ) { } /** - * Handle seek() event - * - * @v xfer POSIX file data transfer interface - * @v pos New position - * @ret rc Return status code - */ -static int posix_file_xfer_seek ( struct xfer_interface *xfer, off_t offset, - int whence ) { - struct posix_file *file = - container_of ( xfer, struct posix_file, xfer ); - - switch ( whence ) { - case SEEK_SET: - file->pos = offset; - break; - case SEEK_CUR: - file->pos += offset; - break; - } - - if ( file->filesize < file->pos ) - file->filesize = file->pos; - - return 0; -} - -/** * Handle deliver_iob() event * * @v xfer POSIX file data transfer interface * @v iobuf I/O buffer - * @v meta Data transfer metadata, or NULL + * @v meta Data transfer metadata * @ret rc Return status code */ static int @@ -145,6 +118,13 @@ posix_file_xfer_deliver_iob ( struct xfer_interface *xfer, struct posix_file *file = container_of ( xfer, struct posix_file, xfer ); + /* Keep track of file position solely for the filesize */ + if ( meta->whence != SEEK_CUR ) + file->pos = 0; + file->pos += meta->offset; + if ( file->filesize < file->pos ) + file->filesize = file->pos; + list_add_tail ( &iobuf->list, &file->data ); return 0; } @@ -153,7 +133,6 @@ posix_file_xfer_deliver_iob ( struct xfer_interface *xfer, static struct xfer_interface_operations posix_file_xfer_operations = { .close = posix_file_xfer_close, .vredirect = xfer_vopen, - .seek = posix_file_xfer_seek, .window = unlimited_xfer_window, .alloc_iob = default_xfer_alloc_iob, .deliver_iob = posix_file_xfer_deliver_iob, diff --git a/src/core/resolv.c b/src/core/resolv.c index 808ab657..f4a587f1 100644 --- a/src/core/resolv.c +++ b/src/core/resolv.c @@ -312,7 +312,6 @@ struct named_socket { static struct xfer_interface_operations named_xfer_ops = { .close = ignore_xfer_close, .vredirect = ignore_xfer_vredirect, - .seek = ignore_xfer_seek, .window = no_xfer_window, .alloc_iob = default_xfer_alloc_iob, .deliver_iob = xfer_deliver_as_raw, diff --git a/src/core/xfer.c b/src/core/xfer.c index 3add057b..e8503476 100644 --- a/src/core/xfer.c +++ b/src/core/xfer.c @@ -86,31 +86,6 @@ int xfer_redirect ( struct xfer_interface *xfer, int type, ... ) { } /** - * Seek to position - * - * @v xfer Data transfer interface - * @v offset Offset to new position - * @v whence Basis for new position - * @ret rc Return status code - */ -int xfer_seek ( struct xfer_interface *xfer, off_t offset, int whence ) { - struct xfer_interface *dest = xfer_get_dest ( xfer ); - int rc; - - DBGC ( xfer, "XFER %p->%p seek %s+%ld\n", xfer, dest, - whence_text ( whence ), offset ); - - rc = dest->op->seek ( dest, offset, whence ); - - if ( rc != 0 ) { - DBGC ( xfer, "XFER %p<-%p seek: %s\n", xfer, dest, - strerror ( rc ) ); - } - xfer_put ( dest ); - return rc; -} - -/** * Check flow control window * * @v xfer Data transfer interface @@ -153,7 +128,7 @@ struct io_buffer * xfer_alloc_iob ( struct xfer_interface *xfer, size_t len ) { * * @v xfer Data transfer interface * @v iobuf Datagram I/O buffer - * @v meta Data transfer metadata, or NULL + * @v meta Data transfer metadata * @ret rc Return status code */ int xfer_deliver_iob_meta ( struct xfer_interface *xfer, @@ -184,7 +159,8 @@ int xfer_deliver_iob_meta ( struct xfer_interface *xfer, */ int xfer_deliver_iob ( struct xfer_interface *xfer, struct io_buffer *iobuf ) { - return xfer_deliver_iob_meta ( xfer, iobuf, NULL ); + static struct xfer_metadata dummy_metadata; + return xfer_deliver_iob_meta ( xfer, iobuf, &dummy_metadata ); } /** @@ -253,6 +229,31 @@ int xfer_printf ( struct xfer_interface *xfer, const char *format, ... ) { return rc; } +/** + * Seek to position + * + * @v xfer Data transfer interface + * @v offset Offset to new position + * @v whence Basis for new position + * @ret rc Return status code + */ +int xfer_seek ( struct xfer_interface *xfer, off_t offset, int whence ) { + struct io_buffer *iobuf; + struct xfer_metadata meta = { + .offset = offset, + .whence = whence, + }; + + DBGC ( xfer, "XFER %p seek %s+%ld\n", xfer, + whence_text ( whence ), offset ); + + /* Allocate and send a zero-length data buffer */ + iobuf = xfer_alloc_iob ( xfer, 0 ); + if ( ! iobuf ) + return -ENOMEM; + return xfer_deliver_iob_meta ( xfer, iobuf, &meta ); +} + /**************************************************************************** * * Helper methods @@ -287,19 +288,6 @@ int ignore_xfer_vredirect ( struct xfer_interface *xfer __unused, } /** - * Ignore seek() event - * - * @v xfer Data transfer interface - * @v offset Offset to new position - * @v whence Basis for new position - * @ret rc Return status code - */ -int ignore_xfer_seek ( struct xfer_interface *xfer __unused, - off_t offset __unused, int whence __unused ) { - return 0; -} - -/** * Unlimited flow control window * * @v xfer Data transfer interface @@ -401,7 +389,6 @@ int ignore_xfer_deliver_raw ( struct xfer_interface *xfer, struct xfer_interface_operations null_xfer_ops = { .close = ignore_xfer_close, .vredirect = ignore_xfer_vredirect, - .seek = ignore_xfer_seek, .window = unlimited_xfer_window, .alloc_iob = default_xfer_alloc_iob, .deliver_iob = xfer_deliver_as_raw, |