Browse Source

[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 16 years ago
parent
commit
2456b9b4ba
1 changed files with 41 additions and 22 deletions
  1. 41
    22
      src/net/udp/slam.c

+ 41
- 22
src/net/udp/slam.c View File

@@ -191,14 +191,14 @@ static void slam_finished ( struct slam_request *slam, int rc ) {
191 191
  * @v slam		SLAM request
192 192
  * @v iobuf		I/O buffer
193 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 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 202
 	uint8_t *data;
203 203
 	size_t len;
204 204
 	unsigned int i;
@@ -207,7 +207,7 @@ static int slam_put_value ( struct slam_request *slam,
207 207
 	 * leave at least one byte in the I/O buffer.
208 208
 	 */
209 209
 	len = ( ( flsl ( value ) + 10 ) / 8 );
210
-	if ( len >= iob_tailroom ( iobuf ) ) {
210
+	if ( ( len + reserved ) > iob_tailroom ( iobuf ) ) {
211 211
 		DBGC2 ( slam, "SLAM %p cannot add %d-byte value\n",
212 212
 			slam, len );
213 213
 		return -ENOBUFS;
@@ -227,7 +227,7 @@ static int slam_put_value ( struct slam_request *slam,
227 227
 	*data |= ( len << 5 );
228 228
 	assert ( value == 0 );
229 229
 
230
-	return 0;
230
+	return len;
231 231
 }
232 232
 
233 233
 /**
@@ -239,13 +239,16 @@ static int slam_put_value ( struct slam_request *slam,
239 239
  */
240 240
 static int slam_build_block_list ( struct slam_request *slam,
241 241
 				   struct io_buffer *iobuf ) {
242
-	unsigned int block;
243
-	unsigned int block_count;
242
+	unsigned long block;
243
+	unsigned long block_count;
244 244
 	int block_present;
245 245
 	int last_block_present;
246
+	int len;
247
+	size_t last_len = 0;
248
+	unsigned long last_block_count = 0;
246 249
 	int rc;
247 250
 
248
-	DBGC ( slam, "SLAM %p asking for ", slam );
251
+	DBGC ( slam, "SLAM %p asking for", slam );
249 252
 
250 253
 	/* Walk bitmap to construct list */
251 254
 	block_count = 0;
@@ -253,27 +256,43 @@ static int slam_build_block_list ( struct slam_request *slam,
253 256
 	for ( block = 0 ; block < slam->num_blocks ; block++ ) {
254 257
 		block_present = ( !! bitmap_test ( &slam->bitmap, block ) );
255 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 263
 			       ( last_block_present ? ' ' : '-' ),
263 264
 			       ( last_block_present ? block : block - 1 ) );
264
-			block_count = 0;
265
+			last_len = len;
266
+			last_block_count = block_count;
265 267
 			last_block_present = block_present;
268
+			block_count = 0;
266 269
 		}
267 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 276
 	       ( last_block_present ? block : block - 1 ) );
275 277
 
276 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
 /**

Loading…
Cancel
Save