The unified diff between revisions [f681bbc6..] and [10d21c7e..] is displayed below. It can also be downloaded as a raw diff.

#
#
# patch "src/fs/coss/store_coss.h"
#  from [712f79a4e81633580a6bd795168f7f2cd6bbe02d]
#    to [866cd796dde6cce04a8cd07d69e5724e7cb1aa39]
#
# patch "src/fs/coss/store_dir_coss.c"
#  from [fe7ccefa847ca91ccb5b9a56dab745d41158090e]
#    to [8415487ec90dc6e8dd23553a03a7ab157f71abe5]
#
============================================================
--- src/fs/coss/store_coss.h	712f79a4e81633580a6bd795168f7f2cd6bbe02d
+++ src/fs/coss/store_coss.h	866cd796dde6cce04a8cd07d69e5724e7cb1aa39
@@ -149,6 +149,7 @@ struct _cossinfo {
 	    char reading;
 	    int curstripe;
 	    char *buf;
+	    int buflen;
     } rebuild;
 };

============================================================
--- src/fs/coss/store_dir_coss.c	fe7ccefa847ca91ccb5b9a56dab745d41158090e
+++ src/fs/coss/store_dir_coss.c	8415487ec90dc6e8dd23553a03a7ab157f71abe5
@@ -882,6 +882,7 @@ static void storeDirCoss_ReadStripe(Rebu
 /* New storedir rebuilding code! */

 static void storeDirCoss_ReadStripe(RebuildState *rb);
+static void storeDirCoss_ParseStripeBuffer(RebuildState *rb);

 static void
 storeDirCoss_ReadStripeComplete(int fd, const char *buf, int r_len, int r_errflag, void *my_data)
@@ -890,13 +891,15 @@ storeDirCoss_ReadStripeComplete(int fd,
 	SwapDir *SD = rb->sd;
 	CossInfo *cs = SD->fsdata;

-	debug(47, 1) ("COSS: %s: read stripe %d, read %d bytes, status %d\n", SD->path, cs->rebuild.curstripe, r_len, r_errflag);
+	debug(47, 1) ("COSS: %s: stripe %d, read %d bytes, status %d\n", SD->path, cs->rebuild.curstripe, r_len, r_errflag);
 	cs->rebuild.reading = 0;
 	if (r_errflag != DISK_OK) {
 		debug(47, 1) ("COSS: %s: stripe %d: error! Ignoring objects in this stripe.\n", SD->path, cs->rebuild.curstripe);
 		goto nextstripe;
 	}
+	cs->rebuild.buflen = r_len;
 	/* parse the stripe contents */
+	storeDirCoss_ParseStripeBuffer(rb);

 nextstripe:
 	cs->rebuild.curstripe++;
@@ -939,3 +942,76 @@ storeDirCoss_StartDiskRebuild(RebuildSta
 	debug(47, 1) ("COSS: %s: Beginning disk rebuild.\n", SD->path);
 	storeDirCoss_ReadStripe(rb);
 }
+
+/*
+ * Take a stripe and attempt to place objects into it
+ */
+static void
+storeDirCoss_ParseStripeBuffer(RebuildState *rb)
+{
+	SwapDir *SD = rb->sd;
+	CossInfo *cs = SD->fsdata;
+	tlv *t, *tlv_list;
+	int j = 0;
+	int bl = 0;
+	squid_off_t *l;
+	int blocksize = cs->blksz_mask + 1;
+
+	assert(cs->rebuild.rebuilding == 1);
+	assert(cs->numstripes > 0);
+	assert(cs->rebuild.buf != NULL);
+
+	debug(47, 1) ("COSS: debug: blocksize is %d\n", blocksize);
+
+	if (cs->rebuild.buflen == 0) {
+		debug(47, 1) ("COSS: %s: stripe %d: read 0 bytes, skipping stripe\n", SD->path, cs->rebuild.curstripe);
+		return;
+	}
+
+	while (j < cs->rebuild.buflen)
+	{
+		l = NULL;
+		bl = 0;
+		/* XXX there's no bounds checking on the buffer being passed into storeSwapMetaUnpack! */
+		tlv_list = storeSwapMetaUnpack(cs->rebuild.buf + j, &bl);
+		if (tlv_list == NULL) {
+			debug(47, 1) ("COSS: %s: stripe %d: offset %d gives NULL swapmeta data; end of stripe\n", SD->path, cs->rebuild.curstripe, j);
+			return;
+		}
+		debug(47, 1) ("COSS: %s: stripe %d: filen %d: header size %d\n", SD->path, cs->rebuild.curstripe, j / blocksize + (cs->rebuild.curstripe * COSS_MEMBUF_SZ / blocksize), bl);
+
+		/* COSS objects will have an object size written into the metadata */
+		for (t = tlv_list; t; t = t->next) {
+			switch(t->type) {
+				case STORE_META_URL:
+					debug(47, 1) ("    URL: %s\n", (char *)t->value);
+					break;
+				case STORE_META_OBJSIZE:
+					l = t->value;
+					debug(47, 1) ("Size: %lld (len %d)\n", *l, t->length);
+				break;
+			}
+		}
+		/* Make sure we have an object; if we don't then it may be an indication of trouble */
+		if (l == NULL) {
+			debug(47, 1) ("COSS: %s: stripe %d: Object with no size; end of stripe\n", SD->path, cs->rebuild.curstripe);
+			return;
+		}
+		/* Finally, make sure there's enough data left in this stripe to satisfy the object
+		 * we've just been informed about
+		 */
+
+		/* Houston, we have an object */
+
+		/* Free the TLV data */
+		storeSwapTLVFree(tlv_list);
+		tlv_list = NULL;
+
+		/* Now, advance to the next block-aligned offset after this object */
+		j = j + *l + bl;
+		/* And now, the blocksize! */
+		tmp = j / blocksize;
+		tmp = (tmp+1) * blocksize;
+		j = tmp;
+	}
+}