]> git.neil.brown.name Git - lafs-utils.git/commitdiff
Add lafs_find_free
authorNeilBrown <neilb@suse.de>
Fri, 25 Mar 2011 21:32:30 +0000 (08:32 +1100)
committerNeilBrown <neilb@suse.de>
Fri, 25 Mar 2011 21:32:30 +0000 (08:32 +1100)
to find some free segments.

Signed-off-by: NeilBrown <neilb@suse.de>
include/lafs/lafs.h
lib/lafs_find_free.c [new file with mode: 0644]
lib/lafs_new_segment.c
tools/mkfs.lafs.c

index 792c80400e49b238cdfad63f51ced973fac8f89d..f2369110ebfe8cc0df3a620192fcee2a9a14fbd6 100644 (file)
@@ -32,6 +32,7 @@ struct lafs_ino *lafs_get_inode(struct lafs_ino *fsys, int inum);
 int lafs_imap_set(struct lafs_ino *, int inum);
 
 int lafs_add_free_seg(struct lafs*, int dev, loff_t seg);
+void lafs_find_free(struct lafs *fs);
 
 void lafs_inode_init(struct lafs *, char *, int type);
 struct lafs_ino *lafs_import_inode_buf(struct lafs *fs,
diff --git a/lib/lafs_find_free.c b/lib/lafs_find_free.c
new file mode 100644 (file)
index 0000000..145f3bf
--- /dev/null
@@ -0,0 +1,44 @@
+
+#include <lafs/lafs.h>
+#include "internal.h"
+
+/* lafs_find_free
+ * Find free blocks and add them to the list.
+ * Only run if free list is empty, to avoid any chance
+ * of duplicate entries.
+ * We add anything which has a youth of 0 in the
+ * segusage files, but not any currently open segment
+ */
+
+void lafs_find_free(struct lafs *fs)
+{
+       struct lafs_device *dev;
+       int mask = (1<<(fs->blockbits - 1)) - 1;
+
+       for (dev = fs->devs; dev; dev = dev->next) {
+               struct lafs_ino *ino = dev->segsum;
+               struct lafs_dblk *db = NULL;
+               loff_t seg;
+
+               for (seg = 0; seg < dev->segment_count; seg++) {
+                       u32 bnum = seg >> (fs->blockbits-1);
+                       if (db == NULL || db->b.fileaddr != bnum) {
+                               db = lafs_dblk(ino, bnum);
+                               if (!db || lafs_load_dblk(db))
+                                       break;
+                               if (((u16*)db->b.data)[seg&mask] == 0) {
+                                       /* possible contender */
+                                       int s;
+                                       for (s = 0; s < WC_NUM;s++)
+                                               if (fs->wc[s].seg.dev == dev->devnum &&
+                                                   fs->wc[s].seg.num == seg)
+                                                       break;
+                                       if (s == WC_NUM)
+                                               if (lafs_add_free_seg(fs, dev->devnum,
+                                                                     seg) == 0)
+                                                       return;
+                               }
+                       }
+               }
+       }
+}
index 38c84d8aa324562ca269364fa2faa0bd0c844a3e..4efede2f572409b396adfa87eb50df02267a4489 100644 (file)
@@ -35,10 +35,12 @@ int lafs_new_segment(struct lafs *fs, int cnum)
        loff_t seg;
        struct lafs_cluster *wc = &fs->wc[cnum];
 
-       if (fs->free_head == fs->free_tail)
+       if (fs->free_head == fs->free_tail) {
                /* list is empty */
-               return 0;
-
+               lafs_find_free(fs);
+               if (fs->free_head == fs->free_tail)
+                       return 0;
+       }
        dev = fs->freelist[fs->free_head].dev;
        seg = fs->freelist[fs->free_head].seg;
 
index 784658dcf3b7dcd9a13335746c64d49c3ab4b2f8..484920c4918d5307c8ae145b14ae8ceb4970ca10 100644 (file)
@@ -270,7 +270,6 @@ int main(int argc, char *argv[])
        lafs_imap_set(imfile, 16);
 
        lafs_cluster_init(lafs, 0, 0, 0, 1);
-       lafs_add_free_seg(lafs, dev->devnum, 0);
        /* Write checkpoint and state blocks */
        lafs_checkpoint(lafs);
        /* Write state blocks a second time, so all 4 copies are written */