diff options
author | Roman Zippel <zippel@linux-m68k.org> | 2005-03-28 04:08:56 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-03-28 04:08:56 -0800 |
commit | 849fbf664537f7bf17b87f63ef2051ee8e2c4d9c (patch) | |
tree | de8fc8c473b862e74003a3bac932111da9b94ac3 | |
parent | 75fd58c6c5418b69ad93f40d53f65ae05dbe32e0 (diff) | |
download | history-849fbf664537f7bf17b87f63ef2051ee8e2c4d9c.tar.gz |
[PATCH] hfs: more bnode error checks
Check for errors during reading of bnode pages and report them. Also improve
error checks in case bnode validity checks failed.
Signed-off-by: Roman Zippel <zippel@linux-m68k.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | fs/hfs/bnode.c | 12 | ||||
-rw-r--r-- | fs/hfsplus/bnode.c | 12 |
2 files changed, 24 insertions, 0 deletions
diff --git a/fs/hfs/bnode.c b/fs/hfs/bnode.c index b47ab4283cca6..6ad1211f84edb 100644 --- a/fs/hfs/bnode.c +++ b/fs/hfs/bnode.c @@ -285,6 +285,10 @@ static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid) page = read_cache_page(mapping, block++, (filler_t *)mapping->a_ops->readpage, NULL); if (IS_ERR(page)) goto fail; + if (PageError(page)) { + page_cache_release(page); + goto fail; + } #if !REF_PAGES page_cache_release(page); #endif @@ -326,12 +330,16 @@ struct hfs_bnode *hfs_bnode_find(struct hfs_btree *tree, u32 num) hfs_bnode_get(node); spin_unlock(&tree->hash_lock); wait_event(node->lock_wq, !test_bit(HFS_BNODE_NEW, &node->flags)); + if (test_bit(HFS_BNODE_ERROR, &node->flags)) + goto node_error; return node; } spin_unlock(&tree->hash_lock); node = __hfs_bnode_create(tree, num); if (!node) return ERR_PTR(-ENOMEM); + if (test_bit(HFS_BNODE_ERROR, &node->flags)) + goto node_error; if (!test_bit(HFS_BNODE_NEW, &node->flags)) return node; @@ -416,6 +424,10 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) node = __hfs_bnode_create(tree, num); if (!node) return ERR_PTR(-ENOMEM); + if (test_bit(HFS_BNODE_ERROR, &node->flags)) { + hfs_bnode_put(node); + return ERR_PTR(-EIO); + } pagep = node->page; memset(kmap(*pagep) + node->page_offset, 0, diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index f44e826e5e666..267872e84d714 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -446,6 +446,10 @@ static struct hfs_bnode *__hfs_bnode_create(struct hfs_btree *tree, u32 cnid) page = read_cache_page(mapping, block, (filler_t *)mapping->a_ops->readpage, NULL); if (IS_ERR(page)) goto fail; + if (PageError(page)) { + page_cache_release(page); + goto fail; + } #if !REF_PAGES page_cache_release(page); #endif @@ -487,12 +491,16 @@ struct hfs_bnode *hfs_bnode_find(struct hfs_btree *tree, u32 num) hfs_bnode_get(node); spin_unlock(&tree->hash_lock); wait_event(node->lock_wq, !test_bit(HFS_BNODE_NEW, &node->flags)); + if (test_bit(HFS_BNODE_ERROR, &node->flags)) + goto node_error; return node; } spin_unlock(&tree->hash_lock); node = __hfs_bnode_create(tree, num); if (!node) return ERR_PTR(-ENOMEM); + if (test_bit(HFS_BNODE_ERROR, &node->flags)) + goto node_error; if (!test_bit(HFS_BNODE_NEW, &node->flags)) return node; @@ -579,6 +587,10 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) node = __hfs_bnode_create(tree, num); if (!node) return ERR_PTR(-ENOMEM); + if (test_bit(HFS_BNODE_ERROR, &node->flags)) { + hfs_bnode_put(node); + return ERR_PTR(-EIO); + } pagep = node->page; memset(kmap(*pagep) + node->page_offset, 0, |