summaryrefslogtreecommitdiff
path: root/liblogfs/dump.c
diff options
context:
space:
mode:
Diffstat (limited to 'liblogfs/dump.c')
-rw-r--r--liblogfs/dump.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/liblogfs/dump.c b/liblogfs/dump.c
new file mode 100644
index 00000000..90e2d1f4
--- /dev/null
+++ b/liblogfs/dump.c
@@ -0,0 +1,71 @@
+#include "lib9.h"
+#include "logfs.h"
+#include "local.h"
+#include "fcall.h"
+
+typedef struct WalkState {
+ u32int *flashaddrp;
+ u32int *lengthp;
+ int i;
+ int nth;
+} WalkState;
+
+static int
+walk(void *magic, Extent *e, int hole)
+{
+ WalkState *s = magic;
+ USED(hole);
+ if(s->i == s->nth) {
+ *s->flashaddrp = e->flashaddr;
+ *s->lengthp = e->max - e->min;
+ return 0;
+ }
+ s->i++;
+ return 1;
+}
+
+char *
+logfsserverreadpathextent(LogfsServer *server, u32int path, int nth, u32int *flashaddrp, u32int *lengthp,
+ long *blockp, int *pagep, int *offsetp)
+{
+ Entry *e;
+ WalkState s;
+ long index;
+ e = logfspathmapfinde(server->pathmap, path);
+ if(e == nil)
+ return logfseunknownpath;
+ if(e->perm & DMDIR)
+ return Eisdir;
+ s.flashaddrp = flashaddrp;
+ s.lengthp = lengthp;
+ s.i = 0;
+ s.nth = nth;
+ *lengthp = 0;
+ logfsextentlistwalk(e->u.file.extent, walk, &s);
+ if(*lengthp) {
+ logfsflashaddr2spo(server, *flashaddrp, &index, pagep, offsetp);
+ if(*flashaddrp & LogAddr)
+ if(index >= server->activelog->unsweptblockindex)
+ if(index <= server->activelog->curblockindex)
+ *blockp = server->activelog->blockmap[index];
+ else
+ *blockp = -1;
+ else if(server->sweptlog)
+ if(index <= server->sweptlog->curblockindex)
+ *blockp = server->sweptlog->blockmap[index];
+ else
+ *blockp = -1;
+ else
+ *blockp = -1;
+ else if(index < server->ndatablocks)
+ *blockp = server->datablock[index].block;
+ else
+ *blockp = -1;
+ }
+ else {
+ *blockp = 0;
+ *pagep = 0;
+ *offsetp = 0;
+ }
+ return nil;
+}