david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

[downloader] Use generic data-transfer buffer mechanism

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown 2015-07-15 13:55:56 +01:00
parent 07b0d4fa30
commit ae5e7f0cf4
1 changed files with 16 additions and 72 deletions

View File

@ -33,7 +33,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <ipxe/uaccess.h>
#include <ipxe/umalloc.h>
#include <ipxe/image.h>
#include <ipxe/profile.h>
#include <ipxe/xferbuf.h>
#include <ipxe/downloader.h>
/** @file
@ -42,14 +42,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
*
*/
/** Receive profiler */
static struct profiler downloader_rx_profiler __profiler =
{ .name = "downloader.rx" };
/** Data copy profiler */
static struct profiler downloader_copy_profiler __profiler =
{ .name = "downloader.copy" };
/** A downloader */
struct downloader {
/** Reference count for this object */
@ -62,8 +54,8 @@ struct downloader {
/** Image to contain downloaded file */
struct image *image;
/** Current position within image buffer */
size_t pos;
/** Data transfer buffer */
struct xfer_buffer buffer;
};
/**
@ -96,42 +88,14 @@ static void downloader_finished ( struct downloader *downloader, int rc ) {
downloader->image->name, strerror ( rc ) );
}
/* Update image length */
downloader->image->len = downloader->buffer.len;
/* Shut down interfaces */
intf_shutdown ( &downloader->xfer, rc );
intf_shutdown ( &downloader->job, rc );
}
/**
* Ensure that download buffer is large enough for the specified size
*
* @v downloader Downloader
* @v len Required minimum size
* @ret rc Return status code
*/
static int downloader_ensure_size ( struct downloader *downloader,
size_t len ) {
userptr_t new_buffer;
/* If buffer is already large enough, do nothing */
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 ) {
DBGC ( downloader, "Downloader %p could not extend buffer to "
"%zd bytes\n", downloader, len );
return -ENOSPC;
}
downloader->image->data = new_buffer;
downloader->image->len = len;
return 0;
}
/****************************************************************************
*
* Job control interface
@ -152,8 +116,8 @@ static int downloader_progress ( struct downloader *downloader,
* arrive out of order (e.g. with multicast protocols), but
* it's a reasonable first approximation.
*/
progress->completed = downloader->pos;
progress->total = downloader->image->len;
progress->completed = downloader->buffer.pos;
progress->total = downloader->buffer.len;
return 0;
}
@ -175,38 +139,17 @@ static int downloader_progress ( struct downloader *downloader,
static int downloader_xfer_deliver ( struct downloader *downloader,
struct io_buffer *iobuf,
struct xfer_metadata *meta ) {
size_t len;
size_t max;
int rc;
/* Start profiling */
profile_start ( &downloader_rx_profiler );
/* Add data to buffer */
if ( ( rc = xferbuf_deliver ( &downloader->buffer, iob_disown ( iobuf ),
meta ) ) != 0 )
goto err_deliver;
/* Calculate new buffer position */
if ( meta->flags & XFER_FL_ABS_OFFSET )
downloader->pos = 0;
downloader->pos += meta->offset;
return 0;
/* 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 )
goto done;
/* Copy data to buffer */
profile_start ( &downloader_copy_profiler );
copy_to_user ( downloader->image->data, downloader->pos,
iobuf->data, len );
profile_stop ( &downloader_copy_profiler );
/* Update current buffer position */
downloader->pos += len;
done:
free_iob ( iobuf );
if ( rc != 0 )
downloader_finished ( downloader, rc );
profile_stop ( &downloader_rx_profiler );
err_deliver:
downloader_finished ( downloader, rc );
return rc;
}
@ -266,6 +209,7 @@ int create_downloader ( struct interface *job, struct image *image ) {
intf_init ( &downloader->xfer, &downloader_xfer_desc,
&downloader->refcnt );
downloader->image = image_get ( image );
xferbuf_umalloc_init ( &downloader->buffer, &image->data );
/* Instantiate child objects and attach to our interfaces */
if ( ( rc = xfer_open_uri ( &downloader->xfer, image->uri ) ) != 0 )