2 #define _FILE_OFFSET_BITS 64
11 static int csum_ok(struct lafs_state *st, int size)
16 crc2 = crc32(0, (uint32_t*)st, size);
21 char *lafs_mount(struct lafs *fs, int force)
24 struct lafs_device *dv;
25 struct lafs_state *st;
26 struct lafs_snapshot **ssp;
29 if (fs->blocksize == 0)
30 return strdup("mount: no devices loaded");
32 if (fs->loaded_devs != fs->devices) {
34 "need %d devices, only %d loaded",
35 fs->devices, fs->loaded_devs);
38 /* - check that the loaded devices don't overlap.
39 * - Choose and load a state block
40 * - fill in data in 'lafs': e..g ss, max_segment, checkpoint_cluster,
44 if (fs->ss.root || fs->ss.root_addr) {
45 asprintf(&err, "LaFS is already mounted");
49 /* FIXME check seq number is OK. */
50 for (dv = fs->devs; dv; dv = dv->next) {
51 struct lafs_device *dv2;
52 for (dv2 = dv->next; dv2; dv2= dv->next) {
53 if (dv->start < dv2->start + dv2->size &&
54 dv->start + dv->size <= dv2->start)
56 if (dv2->start < dv->start + dv->size &&
57 dv2->start + dv2->size <= dv->start)
59 asprintf(&err, "devices %s and %s overlap",
64 st = malloc(fs->statesize);
65 for (dv = fs->devs; dv; dv = dv->next)
66 if (lseek64(dv->fd, dv->stateaddr[dv->recent_state], 0)
67 == dv->stateaddr[dv->recent_state]
68 && read(dv->fd, st, fs->statesize) == fs->statesize)
71 asprintf(&err, "Couldn't load a state block from any device");
75 /* The state block has already been checked by lafs_load, but just
78 if (memcmp(st->idtag, "LaFS-State-Block", 16) != 0 ||
79 memcmp(st->uuid, fs->uuid, 16) != 0 ||
80 !csum_ok(st, fs->statesize)) {
81 asprintf(&err, "state block nolonger looks correct");
85 /* OK, let-her-rip. */
86 fs->seq = __le32_to_cpu(st->seq);
87 // fs->levels = __le32_to_cpu(st->levels);
88 fs->checkpoint_cluster = __le64_to_cpu(st->checkpointcluster);
89 fs->youth_next = __le16_to_cpu(st->nextyouth);
90 fs->ss.root_addr = __le64_to_cpu(st->root_inodes[0]);
94 for (s = 1; s < __le32_to_cpu(st->maxsnapshot); s++) {
95 struct lafs_snapshot *ss;
96 if (st->root_inodes[s] == 0)
98 ss = talloc(fs, struct lafs_snapshot);
100 ss->root_addr = __le64_to_cpu(st->root_inodes[s]);
109 for (dv = fs->devs ; dv; dv=dv->next)
110 if (fs->max_segment < dv->segment_size)
111 fs->max_segment = dv->segment_size;
113 fs->checkpointing = 0;