浏览代码

[slam] Request all remaining blocks if we run out of space for the blocklist

In a SLAM NACK packet, if we run out of space to represent the
missing-block list, then indicate all remaining blocks as missing.
This avoids the need to wait for the one-second timeout before
receiving the blocks that otherwise wouldn't have been requested due
to running out of space.
tags/v0.9.4
Michael Brown 17 年前
父节点
当前提交
2456b9b4ba
共有 1 个文件被更改,包括 41 次插入22 次删除
  1. 41
    22
      src/net/udp/slam.c

+ 41
- 22
src/net/udp/slam.c 查看文件

191
  * @v slam		SLAM request
191
  * @v slam		SLAM request
192
  * @v iobuf		I/O buffer
192
  * @v iobuf		I/O buffer
193
  * @v value		Value to add
193
  * @v value		Value to add
194
- * @ret rc		Return status code
194
+ * @v reserved		Length of reserved space at end of buffer
195
+ * @ret len		Length of value, or negative error.
195
  *
196
  *
196
- * Adds a variable-length value to the end of an I/O buffer.  Will
197
- * refuse to use the last byte of the I/O buffer; this is to allow
198
- * space for the terminating NUL.
197
+ * Adds a variable-length value to the end of an I/O buffer.
199
  */
198
  */
200
 static int slam_put_value ( struct slam_request *slam,
199
 static int slam_put_value ( struct slam_request *slam,
201
-			    struct io_buffer *iobuf, unsigned long value ) {
200
+			    struct io_buffer *iobuf, unsigned long value,
201
+			    size_t reserved ) {
202
 	uint8_t *data;
202
 	uint8_t *data;
203
 	size_t len;
203
 	size_t len;
204
 	unsigned int i;
204
 	unsigned int i;
207
 	 * leave at least one byte in the I/O buffer.
207
 	 * leave at least one byte in the I/O buffer.
208
 	 */
208
 	 */
209
 	len = ( ( flsl ( value ) + 10 ) / 8 );
209
 	len = ( ( flsl ( value ) + 10 ) / 8 );
210
-	if ( len >= iob_tailroom ( iobuf ) ) {
210
+	if ( ( len + reserved ) > iob_tailroom ( iobuf ) ) {
211
 		DBGC2 ( slam, "SLAM %p cannot add %d-byte value\n",
211
 		DBGC2 ( slam, "SLAM %p cannot add %d-byte value\n",
212
 			slam, len );
212
 			slam, len );
213
 		return -ENOBUFS;
213
 		return -ENOBUFS;
227
 	*data |= ( len << 5 );
227
 	*data |= ( len << 5 );
228
 	assert ( value == 0 );
228
 	assert ( value == 0 );
229
 
229
 
230
-	return 0;
230
+	return len;
231
 }
231
 }
232
 
232
 
233
 /**
233
 /**
239
  */
239
  */
240
 static int slam_build_block_list ( struct slam_request *slam,
240
 static int slam_build_block_list ( struct slam_request *slam,
241
 				   struct io_buffer *iobuf ) {
241
 				   struct io_buffer *iobuf ) {
242
-	unsigned int block;
243
-	unsigned int block_count;
242
+	unsigned long block;
243
+	unsigned long block_count;
244
 	int block_present;
244
 	int block_present;
245
 	int last_block_present;
245
 	int last_block_present;
246
+	int len;
247
+	size_t last_len = 0;
248
+	unsigned long last_block_count = 0;
246
 	int rc;
249
 	int rc;
247
 
250
 
248
-	DBGC ( slam, "SLAM %p asking for ", slam );
251
+	DBGC ( slam, "SLAM %p asking for", slam );
249
 
252
 
250
 	/* Walk bitmap to construct list */
253
 	/* Walk bitmap to construct list */
251
 	block_count = 0;
254
 	block_count = 0;
253
 	for ( block = 0 ; block < slam->num_blocks ; block++ ) {
256
 	for ( block = 0 ; block < slam->num_blocks ; block++ ) {
254
 		block_present = ( !! bitmap_test ( &slam->bitmap, block ) );
257
 		block_present = ( !! bitmap_test ( &slam->bitmap, block ) );
255
 		if ( block_present != last_block_present ) {
258
 		if ( block_present != last_block_present ) {
256
-			if ( ( rc = slam_put_value ( slam, iobuf,
257
-						     block_count ) ) != 0 ) {
258
-				DBGC ( slam, "...\n" );
259
-				return rc;
260
-			}
261
-			DBGC ( slam, "%c%d",
259
+			if ( ( len = slam_put_value ( slam, iobuf, block_count,
260
+					     ( sizeof ( block ) + 1 ) ) ) < 0 )
261
+				goto truncated;
262
+			DBGC ( slam, "%c%ld",
262
 			       ( last_block_present ? ' ' : '-' ),
263
 			       ( last_block_present ? ' ' : '-' ),
263
 			       ( last_block_present ? block : block - 1 ) );
264
 			       ( last_block_present ? block : block - 1 ) );
264
-			block_count = 0;
265
+			last_len = len;
266
+			last_block_count = block_count;
265
 			last_block_present = block_present;
267
 			last_block_present = block_present;
268
+			block_count = 0;
266
 		}
269
 		}
267
 		block_count++;
270
 		block_count++;
268
 	}
271
 	}
269
-	if ( ( rc = slam_put_value ( slam, iobuf, block_count ) ) != 0 ) {
270
-		DBGC ( slam, "...\n" );
271
-		return rc;
272
-	}
273
-	DBGC ( slam, "%c%d\n", ( last_block_present ? ' ' : '-' ),
272
+	if ( ( len = slam_put_value ( slam, iobuf, block_count,
273
+				      ( sizeof ( block ) + 1 ) ) ) < 0 )
274
+		goto truncated;
275
+	DBGC ( slam, "%c%ld\n", ( last_block_present ? ' ' : '-' ),
274
 	       ( last_block_present ? block : block - 1 ) );
276
 	       ( last_block_present ? block : block - 1 ) );
275
 
277
 
276
 	return 0;
278
 	return 0;
279
+
280
+ truncated:
281
+	rc = len;
282
+	block -= block_count;
283
+	assert ( last_len != 0 ); /* Cannot truncate on first entry */
284
+	if ( last_block_present ) {
285
+		/* Replace last missing-blocks number */
286
+		DBGC ( slam, "#" );
287
+		iob_unput ( iobuf, last_len );
288
+		block -= last_block_count;
289
+	}
290
+	/* Report all remaining blocks as missing */
291
+	block_count = ( slam->num_blocks - block );
292
+	DBGC ( slam, "-%ld\n", ( slam->num_blocks - 1 ) );
293
+	len = slam_put_value ( slam, iobuf, block_count, 1 );
294
+	assert ( len > 0 );
295
+	return rc;
277
 }
296
 }
278
 
297
 
279
 /**
298
 /**

正在加载...
取消
保存