code: libextents

Download patch

ref: 02044e5668850757a17a2ba0a1f41754f96fde7e
parent: 9eaeb41d951cda9fad195a4cf39cc7be37b001b0
author: 9ferno <gophone2015@gmail.com>
date: Sun Jan 15 14:57:50 EST 2023

save extests in text

--- a/extents.c
+++ b/extents.c
@@ -870,6 +870,99 @@
 
 /* string length when the extents are written as a string */
 s32
+sizeoftxtextents(Extents *es)
+{
+	u64 n, used;
+	s8 tmp[128];
+	Extent *e;
+
+	used = 0;
+	qlock(&es->lck);
+	for(e = lowest(es); e != nil; e = e->high){
+		n = snprint(tmp, 128, "%llud %llud %llud\n",
+						e->start, e->start+e->len-1, e->len);
+		if(n == 128)
+			es->panic("sizeofextents(): increase tmp size");
+		used += n;
+	}
+	// keep it locked?
+	qunlock(&es->lck);
+	return used;
+}
+/*
+	write to *buf returns the length written.
+	Ensure that nbuf has an extra byte at the end
+	as snprint() alway places a terminating NUL byte.
+	If there is no extra byte, the content gets trimmed.
+ */
+s32
+savetxtextents(Extents *es, s8 *buf, u32 nbuf)
+{
+	u64 used;
+	Extent *e;
+	s32 ret;
+
+	used = 0;
+	qlock(&es->lck);
+	for(e = lowest(es); e != nil; e = e->high){
+		used += snprint(buf+used, nbuf-used,
+						"%llud %llud %llud\n",
+						e->start, e->start+e->len-1, e->len);
+		if(used >= nbuf){
+			es->panic("saveextents(): increase buf size");
+			ret = -1;	/* increase buf size */
+			goto end;
+		}
+	}
+	ret = used;
+	// keep it locked?
+end:
+	qunlock(&es->lck);
+	return ret;
+}
+
+/* load the extents from buf of length nbuf */
+/* make this be called multiple times to add more extents - not needed now */
+/* assumes that the input is in ascending order of block numbers */
+s32
+loadtxtextents(Extents *es, s8 *buf, u32 nbuf)
+{
+	s8 *p, *ep;
+	u64 start, end, nblocks;
+
+	p = buf;
+	if(es->lru != nil || es->n != 0){
+		es->panic("extents already loaded.\n"
+			"	TODO make loadextents() be called multiple times");
+	}
+	while(*p != 0 && p-buf < nbuf){
+		start = strtoull(p, &ep, 10);
+		if(p == ep)
+			es->panic("could not read");
+
+		p = ep;
+		p += 1; /* skip over the space */
+		end = strtoull(p, &ep, 10);
+		if(p == ep)
+			es->panic("could not read");
+
+		p = ep;
+		p += 1; /* skip over the space */
+		nblocks = strtoull(p, &ep, 10);
+		if(p == ep)
+			es->panic("could not read");
+		if(end-start+1 != nblocks)
+			es->panic("loadextents does not match up: start %llud end %llud nblocks %llud",
+					start, end, nblocks);
+
+		p = ep;
+		p++; /* to skip over the new line */
+		ufree(es, start, nblocks);
+	}
+	return es->n;
+}
+
+s32
 sizeofextents(Extents *es)
 {
 	/* Do I need a lock? */
@@ -919,6 +1012,8 @@
 	for(n = nbuf/(3*sizeof(u64)); n>0; n--){
 		start = *p; p++;
 		end = *p; p++;
+		if(start == 0 && end == 0)
+			panic("loadextents(): nil extent");
 		nunits = *p; p++;
 		ufree(es, start, nunits);
 	}
--- a/extents.h
+++ b/extents.h
@@ -95,5 +95,7 @@
 void	showextentslists(int fd, char *msg, Extents *es);
 void	showextentspointers(int fd, char *msg, Extents *es);
 s32	sizeofextents(Extents *es);
+s32	sizeoftxtextents(Extents *es);
 s32	saveextents(Extents *es, s8 *buf, u32 nbuf);
+s32	savetxtextents(Extents *es, s8 *buf, u32 nbuf);
 s32	loadextents(Extents *es, s8 *buf, u32 nbuf);