diff options
Diffstat (limited to 'fs/hfsplus/bitmap.c')
| -rw-r--r-- | fs/hfsplus/bitmap.c | 29 | 
1 files changed, 20 insertions, 9 deletions
diff --git a/fs/hfsplus/bitmap.c b/fs/hfsplus/bitmap.c index ad57f5991eb..d2954451519 100644 --- a/fs/hfsplus/bitmap.c +++ b/fs/hfsplus/bitmap.c @@ -15,7 +15,8 @@  #define PAGE_CACHE_BITS	(PAGE_CACHE_SIZE * 8) -int hfsplus_block_allocate(struct super_block *sb, u32 size, u32 offset, u32 *max) +int hfsplus_block_allocate(struct super_block *sb, u32 size, +		u32 offset, u32 *max)  {  	struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb);  	struct page *page; @@ -29,7 +30,7 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size, u32 offset, u32 *ma  	if (!len)  		return size; -	dprint(DBG_BITMAP, "block_allocate: %u,%u,%u\n", size, offset, len); +	hfs_dbg(BITMAP, "block_allocate: %u,%u,%u\n", size, offset, len);  	mutex_lock(&sbi->alloc_mutex);  	mapping = sbi->alloc_file->i_mapping;  	page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS, NULL); @@ -88,14 +89,14 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size, u32 offset, u32 *ma  		else  			end = pptr + ((size + 31) & (PAGE_CACHE_BITS - 1)) / 32;  	} -	dprint(DBG_BITMAP, "bitmap full\n"); +	hfs_dbg(BITMAP, "bitmap full\n");  	start = size;  	goto out;  found:  	start = offset + (curr - pptr) * 32 + i;  	if (start >= size) { -		dprint(DBG_BITMAP, "bitmap full\n"); +		hfs_dbg(BITMAP, "bitmap full\n");  		goto out;  	}  	/* do any partial u32 at the start */ @@ -152,8 +153,8 @@ done:  	kunmap(page);  	*max = offset + (curr - pptr) * 32 + i - start;  	sbi->free_blocks -= *max; -	sb->s_dirt = 1; -	dprint(DBG_BITMAP, "-> %u,%u\n", start, *max); +	hfsplus_mark_mdb_dirty(sb); +	hfs_dbg(BITMAP, "-> %u,%u\n", start, *max);  out:  	mutex_unlock(&sbi->alloc_mutex);  	return start; @@ -172,15 +173,17 @@ int hfsplus_block_free(struct super_block *sb, u32 offset, u32 count)  	if (!count)  		return 0; -	dprint(DBG_BITMAP, "block_free: %u,%u\n", offset, count); +	hfs_dbg(BITMAP, "block_free: %u,%u\n", offset, count);  	/* are all of the bits in range? */  	if ((offset + count) > sbi->total_blocks) -		return -2; +		return -ENOENT;  	mutex_lock(&sbi->alloc_mutex);  	mapping = sbi->alloc_file->i_mapping;  	pnr = offset / PAGE_CACHE_BITS;  	page = read_mapping_page(mapping, pnr, NULL); +	if (IS_ERR(page)) +		goto kaboom;  	pptr = kmap(page);  	curr = pptr + (offset & (PAGE_CACHE_BITS - 1)) / 32;  	end = pptr + PAGE_CACHE_BITS / 32; @@ -213,6 +216,8 @@ int hfsplus_block_free(struct super_block *sb, u32 offset, u32 count)  		set_page_dirty(page);  		kunmap(page);  		page = read_mapping_page(mapping, ++pnr, NULL); +		if (IS_ERR(page)) +			goto kaboom;  		pptr = kmap(page);  		curr = pptr;  		end = pptr + PAGE_CACHE_BITS / 32; @@ -227,8 +232,14 @@ out:  	set_page_dirty(page);  	kunmap(page);  	sbi->free_blocks += len; -	sb->s_dirt = 1; +	hfsplus_mark_mdb_dirty(sb);  	mutex_unlock(&sbi->alloc_mutex);  	return 0; + +kaboom: +	pr_crit("unable to mark blocks free: error %ld\n", PTR_ERR(page)); +	mutex_unlock(&sbi->alloc_mutex); + +	return -EIO;  }  | 
