hfsplus: avoid crash on failed block map free
If the read fails we kmap an error code. This doesn't end well. Instead print a critical error and pray. This mirrors the rest of the fs behaviour with critical error cases. Acked-by: Vyacheslav Dubeyko <slava@dubeyko.com> Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Vyacheslav Dubeyko <slava@dubeyko.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Christoph Hellwig <hch@lst.de> Cc: Jan Kara <jack@suse.cz> Acked-by: Hin-Tak Leung <htl10@users.sourceforge.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
44fd07e989
commit
5daa669c80
|
@ -176,12 +176,14 @@ int hfsplus_block_free(struct super_block *sb, u32 offset, u32 count)
|
||||||
dprint(DBG_BITMAP, "block_free: %u,%u\n", offset, count);
|
dprint(DBG_BITMAP, "block_free: %u,%u\n", offset, count);
|
||||||
/* are all of the bits in range? */
|
/* are all of the bits in range? */
|
||||||
if ((offset + count) > sbi->total_blocks)
|
if ((offset + count) > sbi->total_blocks)
|
||||||
return -2;
|
return -ENOENT;
|
||||||
|
|
||||||
mutex_lock(&sbi->alloc_mutex);
|
mutex_lock(&sbi->alloc_mutex);
|
||||||
mapping = sbi->alloc_file->i_mapping;
|
mapping = sbi->alloc_file->i_mapping;
|
||||||
pnr = offset / PAGE_CACHE_BITS;
|
pnr = offset / PAGE_CACHE_BITS;
|
||||||
page = read_mapping_page(mapping, pnr, NULL);
|
page = read_mapping_page(mapping, pnr, NULL);
|
||||||
|
if (IS_ERR(page))
|
||||||
|
goto kaboom;
|
||||||
pptr = kmap(page);
|
pptr = kmap(page);
|
||||||
curr = pptr + (offset & (PAGE_CACHE_BITS - 1)) / 32;
|
curr = pptr + (offset & (PAGE_CACHE_BITS - 1)) / 32;
|
||||||
end = pptr + PAGE_CACHE_BITS / 32;
|
end = pptr + PAGE_CACHE_BITS / 32;
|
||||||
|
@ -214,6 +216,8 @@ int hfsplus_block_free(struct super_block *sb, u32 offset, u32 count)
|
||||||
set_page_dirty(page);
|
set_page_dirty(page);
|
||||||
kunmap(page);
|
kunmap(page);
|
||||||
page = read_mapping_page(mapping, ++pnr, NULL);
|
page = read_mapping_page(mapping, ++pnr, NULL);
|
||||||
|
if (IS_ERR(page))
|
||||||
|
goto kaboom;
|
||||||
pptr = kmap(page);
|
pptr = kmap(page);
|
||||||
curr = pptr;
|
curr = pptr;
|
||||||
end = pptr + PAGE_CACHE_BITS / 32;
|
end = pptr + PAGE_CACHE_BITS / 32;
|
||||||
|
@ -232,4 +236,11 @@ out:
|
||||||
mutex_unlock(&sbi->alloc_mutex);
|
mutex_unlock(&sbi->alloc_mutex);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
kaboom:
|
||||||
|
printk(KERN_CRIT "hfsplus: unable to mark blocks free: error %ld\n",
|
||||||
|
PTR_ERR(page));
|
||||||
|
mutex_unlock(&sbi->alloc_mutex);
|
||||||
|
|
||||||
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue