iPXE
xferbuf.c File Reference

Data transfer buffer. More...

#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ipxe/xfer.h>
#include <ipxe/iobuf.h>
#include <ipxe/umalloc.h>
#include <ipxe/profile.h>
#include <ipxe/xferbuf.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
void xferbuf_detach (struct xfer_buffer *xferbuf)
 Detach data from data transfer buffer.
void xferbuf_free (struct xfer_buffer *xferbuf)
 Free data transfer buffer.
static int xferbuf_ensure_size (struct xfer_buffer *xferbuf, size_t len)
 Ensure that data transfer buffer is large enough for the specified size.
int xferbuf_write (struct xfer_buffer *xferbuf, size_t offset, const void *data, size_t len)
 Write to data transfer buffer.
int xferbuf_read (struct xfer_buffer *xferbuf, size_t offset, void *data, size_t len)
 Read from data transfer buffer.
int xferbuf_deliver (struct xfer_buffer *xferbuf, struct io_buffer *iobuf, struct xfer_metadata *meta)
 Add received data to data transfer buffer.
static int xferbuf_malloc_realloc (struct xfer_buffer *xferbuf, size_t len)
 Reallocate malloc()-based data transfer buffer.
static int xferbuf_umalloc_realloc (struct xfer_buffer *xferbuf, size_t len)
 Reallocate umalloc()-based data transfer buffer.
static int xferbuf_fixed_realloc (struct xfer_buffer *xferbuf, size_t len)
 Reallocate fixed-size data transfer buffer.
static int xferbuf_void_realloc (struct xfer_buffer *xferbuf, size_t len __unused)
 Reallocate void data transfer buffer.
struct xfer_buffer * xfer_buffer (struct interface *intf)
 Get underlying data transfer buffer.

Variables

static struct profiler xferbuf_deliver_profiler __profiler
 Data delivery profiler.
struct xfer_buffer_operations xferbuf_malloc_operations
 malloc()-based data buffer operations
struct xfer_buffer_operations xferbuf_umalloc_operations
 umalloc()-based data buffer operations
struct xfer_buffer_operations xferbuf_fixed_operations
 Fixed-size data buffer operations.
struct xfer_buffer_operations xferbuf_void_operations
 Void data buffer operations.

Detailed Description

Data transfer buffer.

Definition in file xferbuf.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ xferbuf_detach()

void xferbuf_detach ( struct xfer_buffer * xferbuf)

Detach data from data transfer buffer.

Parameters
xferbufData transfer buffer

The caller assumes responsibility for eventually freeing the data previously owned by the data transfer buffer.

Definition at line 62 of file xferbuf.c.

62 {
63
64 xferbuf->data = NULL;
65 xferbuf->len = 0;
66 xferbuf->max = 0;
67 xferbuf->pos = 0;
68}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
size_t len
Size of data.
Definition xferbuf.h:23
size_t max
Maximum required size of data.
Definition xferbuf.h:25
size_t pos
Current offset within data.
Definition xferbuf.h:27
void * data
Data.
Definition xferbuf.h:21

References xfer_buffer::data, xfer_buffer::len, xfer_buffer::max, NULL, and xfer_buffer::pos.

Referenced by downloader_finished(), and xferbuf_free().

◆ xferbuf_free()

void xferbuf_free ( struct xfer_buffer * xferbuf)

Free data transfer buffer.

Parameters
xferbufData transfer buffer

Definition at line 75 of file xferbuf.c.

75 {
76
77 xferbuf->op->realloc ( xferbuf, 0 );
78 xferbuf_detach ( xferbuf );
79}
int(* realloc)(struct xfer_buffer *xferbuf, size_t len)
Reallocate data buffer.
Definition xferbuf.h:40
struct xfer_buffer_operations * op
Data transfer buffer operations.
Definition xferbuf.h:29
void xferbuf_detach(struct xfer_buffer *xferbuf)
Detach data from data transfer buffer.
Definition xferbuf.c:62

References xfer_buffer::op, xfer_buffer_operations::realloc, and xferbuf_detach().

Referenced by downloader_free(), peerblk_reset(), peermux_free(), validator_free(), and validator_xfer_close().

◆ xferbuf_ensure_size()

int xferbuf_ensure_size ( struct xfer_buffer * xferbuf,
size_t len )
static

Ensure that data transfer buffer is large enough for the specified size.

Parameters
xferbufData transfer buffer
lenRequired minimum size
Return values
rcReturn status code

Definition at line 88 of file xferbuf.c.

88 {
89 int rc;
90
91 /* Record maximum required size */
92 if ( len > xferbuf->max )
93 xferbuf->max = len;
94
95 /* If buffer is already large enough, do nothing */
97 return 0;
98
99 /* Extend buffer */
100 if ( ( rc = xferbuf->op->realloc ( xferbuf, len ) ) != 0 ) {
101 DBGC ( xferbuf, "XFERBUF %p could not extend buffer to "
102 "%zd bytes: %s\n", xferbuf, len, strerror ( rc ) );
103 return rc;
104 }
105 xferbuf->len = len;
106
107 return 0;
108}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
ring len
Length.
Definition dwmac.h:226
#define DBGC(...)
Definition compiler.h:505
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79

References DBGC, len, xfer_buffer::len, xfer_buffer::max, xfer_buffer::op, rc, xfer_buffer_operations::realloc, and strerror().

Referenced by xferbuf_write().

◆ xferbuf_write()

int xferbuf_write ( struct xfer_buffer * xferbuf,
size_t offset,
const void * data,
size_t len )

Write to data transfer buffer.

Parameters
xferbufData transfer buffer
offsetStarting offset
dataData to write
lenLength of data

Definition at line 118 of file xferbuf.c.

119 {
120 size_t max_len;
121 int rc;
122
123 /* Check for overflow */
124 max_len = ( offset + len );
125 if ( max_len < offset )
126 return -EOVERFLOW;
127
128 /* Ensure buffer is large enough to contain this write */
129 if ( ( rc = xferbuf_ensure_size ( xferbuf, max_len ) ) != 0 )
130 return rc;
131
132 /* Copy data to buffer (if non-void) */
133 profile_start ( &xferbuf_write_profiler );
134 if ( xferbuf->data )
135 memcpy ( ( xferbuf->data + offset ), data, len );
136 profile_stop ( &xferbuf_write_profiler );
137
138 return 0;
139}
uint16_t offset
Offset to command line.
Definition bzimage.h:3
uint8_t data[48]
Additional event data.
Definition ena.h:11
#define EOVERFLOW
Value too large to be stored in data type.
Definition errno.h:610
static void profile_stop(struct profiler *profiler)
Stop profiling.
Definition profile.h:174
static void profile_start(struct profiler *profiler)
Start profiling.
Definition profile.h:161
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static int xferbuf_ensure_size(struct xfer_buffer *xferbuf, size_t len)
Ensure that data transfer buffer is large enough for the specified size.
Definition xferbuf.c:88

References data, xfer_buffer::data, EOVERFLOW, len, memcpy(), offset, profile_start(), profile_stop(), rc, and xferbuf_ensure_size().

Referenced by peerblk_decrypt_write(), peerblk_retrieval_rx(), and xferbuf_deliver().

◆ xferbuf_read()

int xferbuf_read ( struct xfer_buffer * xferbuf,
size_t offset,
void * data,
size_t len )

Read from data transfer buffer.

Parameters
xferbufData transfer buffer
offsetStarting offset
dataData to write
lenLength of data

Definition at line 149 of file xferbuf.c.

150 {
151
152 /* Check that read is within buffer range */
153 if ( ( offset > xferbuf->len ) ||
154 ( len > ( xferbuf->len - offset ) ) )
155 return -ENOENT;
156
157 /* Check that buffer is non-void */
158 if ( len && ( ! xferbuf->data ) )
159 return -ENOTTY;
160
161 /* Copy data from buffer */
162 profile_start ( &xferbuf_read_profiler );
163 memcpy ( data, ( xferbuf->data + offset ), len );
164 profile_stop ( &xferbuf_read_profiler );
165
166 return 0;
167}
#define ENOENT
No such file or directory.
Definition errno.h:515
#define ENOTTY
Inappropriate I/O control operation.
Definition errno.h:595

References data, xfer_buffer::data, ENOENT, ENOTTY, len, xfer_buffer::len, memcpy(), offset, profile_start(), and profile_stop().

Referenced by peerblk_decrypt_read().

◆ xferbuf_deliver()

int xferbuf_deliver ( struct xfer_buffer * xferbuf,
struct io_buffer * iobuf,
struct xfer_metadata * meta )

Add received data to data transfer buffer.

Parameters
xferbufData transfer buffer
iobufI/O buffer
metaData transfer metadata
Return values
rcReturn status code

Definition at line 177 of file xferbuf.c.

178 {
179 size_t len = iob_len ( iobuf );
180 size_t pos;
181 int rc;
182
183 /* Start profiling */
184 profile_start ( &xferbuf_deliver_profiler );
185
186 /* Calculate new buffer position */
187 pos = xferbuf->pos;
188 if ( meta->flags & XFER_FL_ABS_OFFSET )
189 pos = 0;
190 pos += meta->offset;
191
192 /* Write data to buffer */
193 if ( ( rc = xferbuf_write ( xferbuf, pos, iobuf->data, len ) ) != 0 )
194 goto done;
195
196 /* Update current buffer position */
197 xferbuf->pos = ( pos + len );
198
199 done:
200 free_iob ( iobuf );
201 profile_stop ( &xferbuf_deliver_profiler );
202 return rc;
203}
struct bofm_section_header done
Definition bofm_test.c:46
uint8_t meta
Metadata flags.
Definition ena.h:3
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
void * data
Start of data.
Definition iobuf.h:53
#define XFER_FL_ABS_OFFSET
Offset is absolute.
Definition xfer.h:48
int xferbuf_write(struct xfer_buffer *xferbuf, size_t offset, const void *data, size_t len)
Write to data transfer buffer.
Definition xferbuf.c:118

References io_buffer::data, done, free_iob(), iob_len(), len, meta, xfer_buffer::pos, profile_start(), profile_stop(), rc, XFER_FL_ABS_OFFSET, and xferbuf_write().

Referenced by blktrans_deliver(), downloader_deliver(), efi_pxe_tftp_deliver(), peermux_info_deliver(), and validator_xfer_deliver().

◆ xferbuf_malloc_realloc()

int xferbuf_malloc_realloc ( struct xfer_buffer * xferbuf,
size_t len )
static

Reallocate malloc()-based data transfer buffer.

Parameters
xferbufData transfer buffer
lenNew length (or zero to free buffer)
Return values
rcReturn status code

Definition at line 212 of file xferbuf.c.

212 {
213 void *new_data;
214
215 new_data = realloc ( xferbuf->data, len );
216 if ( ! new_data )
217 return -ENOSPC;
218 xferbuf->data = new_data;
219 return 0;
220}
#define ENOSPC
No space left on device.
Definition errno.h:550
void * realloc(void *old_ptr, size_t new_size)
Reallocate memory.
Definition malloc.c:607

References xfer_buffer::data, ENOSPC, len, and realloc().

◆ xferbuf_umalloc_realloc()

int xferbuf_umalloc_realloc ( struct xfer_buffer * xferbuf,
size_t len )
static

Reallocate umalloc()-based data transfer buffer.

Parameters
xferbufData transfer buffer
lenNew length (or zero to free buffer)
Return values
rcReturn status code

Definition at line 234 of file xferbuf.c.

234 {
235 void *new_udata;
236
237 new_udata = urealloc ( xferbuf->data, len );
238 if ( ! new_udata )
239 return -ENOSPC;
240 xferbuf->data = new_udata;
241 return 0;
242}
void * urealloc(void *ptr, size_t new_size)
Reallocate external memory.

References xfer_buffer::data, ENOSPC, len, and urealloc().

◆ xferbuf_fixed_realloc()

int xferbuf_fixed_realloc ( struct xfer_buffer * xferbuf,
size_t len )
static

Reallocate fixed-size data transfer buffer.

Parameters
xferbufData transfer buffer
lenNew length (or zero to free buffer)
Return values
rcReturn status code

Definition at line 256 of file xferbuf.c.

256 {
257
258 /* Refuse to allocate extra space */
259 if ( len > xferbuf->len ) {
260 /* Note that EFI relies upon this error mapping to
261 * EFI_BUFFER_TOO_SMALL.
262 */
263 return -ERANGE;
264 }
265
266 return 0;
267}
#define ERANGE
Result too large.
Definition errno.h:640

References ERANGE, len, and xfer_buffer::len.

◆ xferbuf_void_realloc()

int xferbuf_void_realloc ( struct xfer_buffer * xferbuf,
size_t len __unused )
static

Reallocate void data transfer buffer.

Parameters
xferbufData transfer buffer
lenNew length (or zero to free buffer)
Return values
rcReturn status code

Definition at line 281 of file xferbuf.c.

282 {
283
284 /* Succeed without ever allocating data */
285 assert ( xferbuf->data == NULL );
286 return 0;
287}
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50

References __unused, assert, xfer_buffer::data, len, and NULL.

◆ xfer_buffer()

struct xfer_buffer * xfer_buffer ( struct interface * intf)

Get underlying data transfer buffer.

Parameters
interfaceData transfer interface
Return values
xferbufData transfer buffer, or NULL on error

This call will check that the xfer_buffer() handler belongs to the destination interface which also provides xfer_deliver() for this interface.

This is done to prevent accidental accesses to a data transfer buffer which may be located behind a non-transparent datapath via a series of pass-through interfaces.

Definition at line 308 of file xferbuf.c.

308 {
309 struct interface *dest;
310 xfer_buffer_TYPE ( void * ) *op =
312 void *object = intf_object ( dest );
313 struct interface *xfer_deliver_dest;
314 struct xfer_buffer *xferbuf;
315
316 /* Check that this operation is provided by the same interface
317 * which handles xfer_deliver().
318 */
319 ( void ) intf_get_dest_op ( intf, xfer_deliver, &xfer_deliver_dest );
320
321 if ( op && ( dest == xfer_deliver_dest ) ) {
322 xferbuf = op ( object );
323 } else {
324 /* Default is to not have a data transfer buffer */
325 xferbuf = NULL;
326 }
327
328 intf_put ( xfer_deliver_dest );
329 intf_put ( dest );
330 return xferbuf;
331}
if(len >=6 *4) __asm__ __volatile__("movsl" if(len >=5 *4) __asm__ __volatile__("movsl" if(len >=4 *4) __asm__ __volatile__("movsl" if(len >=3 *4) __asm__ __volatile__("movsl" if(len >=2 *4) __asm__ __volatile__("movsl" if(len >=1 *4) __asm__ __volatile__("movsl" if((len % 4) >=2) __asm__ __volatile__("movsw" if((len % 2) >=1) __asm__ __volatile__("movsb" retur dest)
Definition string.h:151
void * intf_object(struct interface *intf)
Get pointer to object containing object interface.
Definition interface.c:160
void intf_put(struct interface *intf)
Decrement reference count on an object interface.
Definition interface.c:150
#define intf_get_dest_op(intf, type, dest)
Get object interface destination and operation method.
Definition interface.h:270
static uint16_t struct vmbus_xfer_pages_operations * op
Definition netvsc.h:327
An object interface.
Definition interface.h:125
struct interface * intf
Original interface.
Definition interface.h:159
A data transfer buffer.
Definition xferbuf.h:19
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition xfer.c:195
#define xfer_buffer_TYPE(object_type)
Definition xferbuf.h:113

References dest, interface::intf, intf_get_dest_op, intf_object(), intf_put(), NULL, op, xfer_buffer_TYPE, and xfer_deliver().

Referenced by http_content_buffer(), peerblk_decrypt(), and peermux_block_buffer().

Variable Documentation

◆ __profiler

struct profiler xferbuf_read_profiler __profiler
static
Initial value:
=
{ .name = "xferbuf.deliver" }

Data delivery profiler.

Data read profiler.

Data write profiler.

Definition at line 43 of file xferbuf.c.

44 { .name = "xferbuf.deliver" };

◆ xferbuf_malloc_operations

struct xfer_buffer_operations xferbuf_malloc_operations
Initial value:
= {
}
static int xferbuf_malloc_realloc(struct xfer_buffer *xferbuf, size_t len)
Reallocate malloc()-based data transfer buffer.
Definition xferbuf.c:212

malloc()-based data buffer operations

Definition at line 223 of file xferbuf.c.

223 {
224 .realloc = xferbuf_malloc_realloc,
225};

Referenced by xferbuf_malloc_init().

◆ xferbuf_umalloc_operations

struct xfer_buffer_operations xferbuf_umalloc_operations
Initial value:
= {
}
static int xferbuf_umalloc_realloc(struct xfer_buffer *xferbuf, size_t len)
Reallocate umalloc()-based data transfer buffer.
Definition xferbuf.c:234

umalloc()-based data buffer operations

Definition at line 245 of file xferbuf.c.

245 {
246 .realloc = xferbuf_umalloc_realloc,
247};

Referenced by xferbuf_umalloc_init().

◆ xferbuf_fixed_operations

struct xfer_buffer_operations xferbuf_fixed_operations
Initial value:
= {
}
static int xferbuf_fixed_realloc(struct xfer_buffer *xferbuf, size_t len)
Reallocate fixed-size data transfer buffer.
Definition xferbuf.c:256

Fixed-size data buffer operations.

Definition at line 270 of file xferbuf.c.

270 {
271 .realloc = xferbuf_fixed_realloc,
272};

Referenced by xferbuf_fixed_init().

◆ xferbuf_void_operations

struct xfer_buffer_operations xferbuf_void_operations
Initial value:
= {
}
static int xferbuf_void_realloc(struct xfer_buffer *xferbuf, size_t len __unused)
Reallocate void data transfer buffer.
Definition xferbuf.c:281

Void data buffer operations.

Definition at line 290 of file xferbuf.c.

290 {
291 .realloc = xferbuf_void_realloc,
292};

Referenced by xferbuf_void_init().