|
@@ -359,3 +359,34 @@ int xfer_seek ( struct interface *intf, off_t offset ) {
|
359
|
359
|
|
360
|
360
|
return xfer_deliver ( intf, iobuf, &meta );
|
361
|
361
|
}
|
|
362
|
+
|
|
363
|
+/**
|
|
364
|
+ * Check that data is delivered strictly in order
|
|
365
|
+ *
|
|
366
|
+ * @v meta Data transfer metadata
|
|
367
|
+ * @v pos Current position
|
|
368
|
+ * @v len Length of data
|
|
369
|
+ * @ret rc Return status code
|
|
370
|
+ */
|
|
371
|
+int xfer_check_order ( struct xfer_metadata *meta, size_t *pos, size_t len ) {
|
|
372
|
+ size_t new_pos;
|
|
373
|
+
|
|
374
|
+ /* Allow out-of-order zero-length packets (as used by xfer_seek()) */
|
|
375
|
+ if ( len == 0 )
|
|
376
|
+ return 0;
|
|
377
|
+
|
|
378
|
+ /* Calculate position of this delivery */
|
|
379
|
+ new_pos = *pos;
|
|
380
|
+ if ( meta->flags & XFER_FL_ABS_OFFSET )
|
|
381
|
+ new_pos = 0;
|
|
382
|
+ new_pos += meta->offset;
|
|
383
|
+
|
|
384
|
+ /* Fail if delivery position is not equal to current position */
|
|
385
|
+ if ( new_pos != *pos )
|
|
386
|
+ return -EPROTO;
|
|
387
|
+
|
|
388
|
+ /* Update current position */
|
|
389
|
+ *pos += len;
|
|
390
|
+
|
|
391
|
+ return 0;
|
|
392
|
+}
|