From 279eebf766a3db072a854f3a7a830acb94be40b2 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sat, 26 Mar 2011 08:32:30 +1100 Subject: [PATCH] Add lafs_find_free to find some free segments. Signed-off-by: NeilBrown --- include/lafs/lafs.h | 1 + lib/lafs_find_free.c | 44 ++++++++++++++++++++++++++++++++++++++++++ lib/lafs_new_segment.c | 8 +++++--- tools/mkfs.lafs.c | 1 - 4 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 lib/lafs_find_free.c diff --git a/include/lafs/lafs.h b/include/lafs/lafs.h index 792c804..f236911 100644 --- a/include/lafs/lafs.h +++ b/include/lafs/lafs.h @@ -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 index 0000000..145f3bf --- /dev/null +++ b/lib/lafs_find_free.c @@ -0,0 +1,44 @@ + +#include +#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; + } + } + } + } +} diff --git a/lib/lafs_new_segment.c b/lib/lafs_new_segment.c index 38c84d8..4efede2 100644 --- a/lib/lafs_new_segment.c +++ b/lib/lafs_new_segment.c @@ -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; diff --git a/tools/mkfs.lafs.c b/tools/mkfs.lafs.c index 784658d..484920c 100644 --- a/tools/mkfs.lafs.c +++ b/tools/mkfs.lafs.c @@ -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 */ -- 2.43.0