]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[downloader] Use generic data-transfer buffer mechanism
authorMichael Brown <mcb30@ipxe.org>
Wed, 15 Jul 2015 12:55:56 +0000 (13:55 +0100)
committerMichael Brown <mcb30@ipxe.org>
Wed, 22 Jul 2015 20:17:47 +0000 (21:17 +0100)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/core/downloader.c

index 5ec6b3b729898798101d9710410ff93a0e2fd9f6..82cb4b1ed02fc1fabe8348734955a820719e12e7 100644 (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 );
-
-       /* Calculate new buffer position */
-       if ( meta->flags & XFER_FL_ABS_OFFSET )
-               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 )
-               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 );
+       /* Add data to buffer */
+       if ( ( rc = xferbuf_deliver ( &downloader->buffer, iob_disown ( iobuf ),
+                                     meta ) ) != 0 )
+               goto err_deliver;
+
+       return 0;
+
+ 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 )