Mercurial > hvf > hvf-old
view cp/fs/bcache.c @ 618:535aec703236
cp: define a FIXME macro that leaves a sclp message
There are far too many fixmes in the code. Sadly, the compiler simply
discards them. This usually isn't an issue until one accidentally hits a
"weird" bug which just turns out to be an unhandled (but documented) case in
another part of the code. Using a macro instead of a comment will let the
compiler string-ify the text, and then at runtime use SCLP to print it out.
This will immediatelly point at problem areas. So, keep an eye on SCLP from
now on :)
Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author | Josef 'Jeff' Sipek <jeffpc@josefsipek.net> |
---|---|
date | Tue, 13 Dec 2011 22:20:50 -0500 |
parents | 162125ad17ee |
children |
line wrap: on
line source
/* * (C) Copyright 2007-2011 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> * * This file is released under the GPLv2. See the COPYING file for more * details. */ #include <list.h> #include <mutex.h> #include <buddy.h> #include <slab.h> #include <edf.h> #include <bdev.h> #include <bcache.h> struct bcache_entry { struct list_head bcache; int level; /* 0 = data */ u32 blk; u32 lba; void *data; }; static struct bcache_entry *__bcache_add(struct file *file, int level, u32 blk, u32 lba) { struct bcache_entry *ent; ent = malloc(sizeof(struct bcache_entry), ZONE_NORMAL); if (!ent) return ERR_PTR(-ENOMEM); INIT_LIST_HEAD(&ent->bcache); ent->level = level; ent->blk = blk; ent->lba = lba; ent->data = NULL; list_add_tail(&ent->bcache, &file->bcache); return ent; } int bcache_add(struct file *file, int level, u32 blk, u32 lba) { struct bcache_entry *ent; ent = __bcache_add(file, level, blk, lba); return IS_ERR(ent) ? PTR_ERR(ent) : 0; } void *bcache_read(struct file *file, int level, u32 blk) { struct bcache_entry *cur; struct page *page; void *buf; u32 *ptrs; u32 nblk, off; int ret; BUG_ON(level > file->FST.NLVL); list_for_each_entry(cur, &file->bcache, bcache) { if ((cur->level == level) && (cur->blk == blk)) goto found; } if (level == file->FST.NLVL) { /* we can get the lba for this from the FST */ cur = __bcache_add(file, level, 0, file->FST.FOP); if (IS_ERR(cur)) return cur; goto found; } else { /* we need to read the pointer block one level up */ off = blk % (file->fs->ADT.DBSIZ / 4); nblk = blk / (file->fs->ADT.DBSIZ / 4); /* * WARNING: recursive call below! * * Thankfully, there is a bound on the number of levels - 2 * pointer blocks worth & 1 data block level. */ ptrs = bcache_read(file, level+1, nblk); if (IS_ERR(ptrs)) return ptrs; /* add the pointer to the cache */ FIXME("since we read the whole block, we should probably " "add all the pointers to the cache"); cur = __bcache_add(file, level, blk, ptrs[off]); if (IS_ERR(cur)) return cur; goto found; } return ERR_PTR(-EFAULT); found: if (cur->data) return cur->data; page = alloc_pages(0, ZONE_NORMAL); if (!page) return ERR_PTR(-ENOMEM); buf = page_to_addr(page); ret = bdev_read_block(file->fs->dev, buf, cur->lba); if (ret) { free_pages(buf, 0); return ERR_PTR(ret); } cur->data = buf; return buf; }