Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Michael Brown committed Jan 8, 2008
1 parent 74fd544 commit f6a8158
Show file tree
Hide file tree
Showing 18 changed files with 83 additions and 165 deletions.
69 changes: 24 additions & 45 deletions src/core/downloader.c
Expand Up @@ -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 ) {
Expand Down Expand Up @@ -141,68 +144,44 @@ 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;
}

/**
Expand All @@ -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,
};

/****************************************************************************
Expand Down
6 changes: 0 additions & 6 deletions src/core/filter.c
Expand Up @@ -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 );

Expand Down
2 changes: 1 addition & 1 deletion src/core/hw.c
Expand Up @@ -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,
};
Expand Down
37 changes: 8 additions & 29 deletions src/core/posix_io.c
Expand Up @@ -103,39 +103,12 @@ static void posix_file_xfer_close ( struct xfer_interface *xfer, int rc ) {
posix_file_finished ( file, 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
Expand All @@ -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;
}
Expand All @@ -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,
Expand Down
1 change: 0 additions & 1 deletion src/core/resolv.c
Expand Up @@ -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,
Expand Down
69 changes: 28 additions & 41 deletions src/core/xfer.c
Expand Up @@ -85,31 +85,6 @@ int xfer_redirect ( struct xfer_interface *xfer, int type, ... ) {
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 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
*
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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 );
}

/**
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -286,19 +287,6 @@ int ignore_xfer_vredirect ( struct xfer_interface *xfer __unused,
return 0;
}

/**
* 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
*
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 0 additions & 2 deletions src/include/gpxe/filter.h
Expand Up @@ -41,8 +41,6 @@ filter_other_half ( struct xfer_interface *xfer ) {
extern void filter_close ( struct xfer_interface *xfer, int rc );
extern int filter_vredirect ( struct xfer_interface *xfer, int type,
va_list args );
extern int filter_seek ( struct xfer_interface *xfer, off_t offset,
int whence );
extern size_t filter_window ( struct xfer_interface *xfer );
extern struct io_buffer * filter_alloc_iob ( struct xfer_interface *xfer,
size_t len );
Expand Down

0 comments on commit f6a8158

Please sign in to comment.