diff options
Diffstat (limited to 'fs/udf/balloc.c')
| -rw-r--r-- | fs/udf/balloc.c | 112 | 
1 files changed, 60 insertions, 52 deletions
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c index b608efaa4ce..1ba2baaf436 100644 --- a/fs/udf/balloc.c +++ b/fs/udf/balloc.c @@ -27,11 +27,10 @@  #include "udf_i.h"  #include "udf_sb.h" -#define udf_clear_bit(nr, addr) ext2_clear_bit(nr, addr) -#define udf_set_bit(nr, addr) ext2_set_bit(nr, addr) -#define udf_test_bit(nr, addr) ext2_test_bit(nr, addr) -#define udf_find_next_one_bit(addr, size, offset) \ -		ext2_find_next_bit(addr, size, offset) +#define udf_clear_bit	__test_and_clear_bit_le +#define udf_set_bit	__test_and_set_bit_le +#define udf_test_bit	test_bit_le +#define udf_find_next_one_bit	find_next_bit_le  static int read_block_bitmap(struct super_block *sb,  			     struct udf_bitmap *bitmap, unsigned int block, @@ -60,8 +59,8 @@ static int __load_block_bitmap(struct super_block *sb,  	int nr_groups = bitmap->s_nr_groups;  	if (block_group >= nr_groups) { -		udf_debug("block_group (%d) > nr_groups (%d)\n", block_group, -			  nr_groups); +		udf_debug("block_group (%d) > nr_groups (%d)\n", +			  block_group, nr_groups);  	}  	if (bitmap->s_block_bitmap[block_group]) { @@ -106,7 +105,6 @@ static void udf_add_free_space(struct super_block *sb, u16 partition, u32 cnt)  }  static void udf_bitmap_free_blocks(struct super_block *sb, -				   struct inode *inode,  				   struct udf_bitmap *bitmap,  				   struct kernel_lb_addr *bloc,  				   uint32_t offset, @@ -127,8 +125,9 @@ static void udf_bitmap_free_blocks(struct super_block *sb,  	if (bloc->logicalBlockNum + count < count ||  	    (bloc->logicalBlockNum + count) > partmap->s_partition_len) {  		udf_debug("%d < %d || %d + %d > %d\n", -			  bloc->logicalBlockNum, 0, bloc->logicalBlockNum, -			  count, partmap->s_partition_len); +			  bloc->logicalBlockNum, 0, +			  bloc->logicalBlockNum, count, +			  partmap->s_partition_len);  		goto error_return;  	} @@ -156,11 +155,10 @@ static void udf_bitmap_free_blocks(struct super_block *sb,  			if (udf_set_bit(bit + i, bh->b_data)) {  				udf_debug("bit %ld already set\n", bit + i);  				udf_debug("byte=%2x\n", -					((char *)bh->b_data)[(bit + i) >> 3]); -			} else { -				udf_add_free_space(sb, sbi->s_partition, 1); +					  ((char *)bh->b_data)[(bit + i) >> 3]);  			}  		} +		udf_add_free_space(sb, sbi->s_partition, count);  		mark_buffer_dirty(bh);  		if (overflow) {  			block += count; @@ -173,7 +171,6 @@ error_return:  }  static int udf_bitmap_prealloc_blocks(struct super_block *sb, -				      struct inode *inode,  				      struct udf_bitmap *bitmap,  				      uint16_t partition, uint32_t first_block,  				      uint32_t block_count) @@ -224,7 +221,6 @@ out:  }  static int udf_bitmap_new_block(struct super_block *sb, -				struct inode *inode,  				struct udf_bitmap *bitmap, uint16_t partition,  				uint32_t goal, int *err)  { @@ -298,7 +294,7 @@ repeat:  				break;  			}  		} else { -			bit = udf_find_next_one_bit((char *)bh->b_data, +			bit = udf_find_next_one_bit(bh->b_data,  						    sb->s_blocksize << 3,  						    group_start << 3);  			if (bit < sb->s_blocksize << 3) @@ -350,7 +346,6 @@ error_return:  }  static void udf_table_free_blocks(struct super_block *sb, -				  struct inode *inode,  				  struct inode *table,  				  struct kernel_lb_addr *bloc,  				  uint32_t offset, @@ -371,7 +366,8 @@ static void udf_table_free_blocks(struct super_block *sb,  	if (bloc->logicalBlockNum + count < count ||  	    (bloc->logicalBlockNum + count) > partmap->s_partition_len) {  		udf_debug("%d < %d || %d + %d > %d\n", -			  bloc->logicalBlockNum, 0, bloc->logicalBlockNum, count, +			  bloc->logicalBlockNum, 0, +			  bloc->logicalBlockNum, count,  			  partmap->s_partition_len);  		goto error_return;  	} @@ -581,7 +577,6 @@ error_return:  }  static int udf_table_prealloc_blocks(struct super_block *sb, -				     struct inode *inode,  				     struct inode *table, uint16_t partition,  				     uint32_t first_block, uint32_t block_count)  { @@ -643,7 +638,6 @@ static int udf_table_prealloc_blocks(struct super_block *sb,  }  static int udf_table_new_block(struct super_block *sb, -			       struct inode *inode,  			       struct inode *table, uint16_t partition,  			       uint32_t goal, int *err)  { @@ -743,18 +737,23 @@ void udf_free_blocks(struct super_block *sb, struct inode *inode,  	struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition];  	if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) { -		udf_bitmap_free_blocks(sb, inode, map->s_uspace.s_bitmap, +		udf_bitmap_free_blocks(sb, map->s_uspace.s_bitmap,  				       bloc, offset, count);  	} else if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) { -		udf_table_free_blocks(sb, inode, map->s_uspace.s_table, +		udf_table_free_blocks(sb, map->s_uspace.s_table,  				      bloc, offset, count);  	} else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) { -		udf_bitmap_free_blocks(sb, inode, map->s_fspace.s_bitmap, +		udf_bitmap_free_blocks(sb, map->s_fspace.s_bitmap,  				       bloc, offset, count);  	} else if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) { -		udf_table_free_blocks(sb, inode, map->s_fspace.s_table, +		udf_table_free_blocks(sb, map->s_fspace.s_table,  				      bloc, offset, count);  	} + +	if (inode) { +		inode_sub_bytes(inode, +				((sector_t)count) << sb->s_blocksize_bits); +	}  }  inline int udf_prealloc_blocks(struct super_block *sb, @@ -763,29 +762,34 @@ inline int udf_prealloc_blocks(struct super_block *sb,  			       uint32_t block_count)  {  	struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; +	sector_t allocated;  	if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) -		return udf_bitmap_prealloc_blocks(sb, inode, -						  map->s_uspace.s_bitmap, -						  partition, first_block, -						  block_count); +		allocated = udf_bitmap_prealloc_blocks(sb, +						       map->s_uspace.s_bitmap, +						       partition, first_block, +						       block_count);  	else if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) -		return udf_table_prealloc_blocks(sb, inode, -						 map->s_uspace.s_table, -						 partition, first_block, -						 block_count); +		allocated = udf_table_prealloc_blocks(sb, +						      map->s_uspace.s_table, +						      partition, first_block, +						      block_count);  	else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) -		return udf_bitmap_prealloc_blocks(sb, inode, -						  map->s_fspace.s_bitmap, -						  partition, first_block, -						  block_count); +		allocated = udf_bitmap_prealloc_blocks(sb, +						       map->s_fspace.s_bitmap, +						       partition, first_block, +						       block_count);  	else if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) -		return udf_table_prealloc_blocks(sb, inode, -						 map->s_fspace.s_table, -						 partition, first_block, -						 block_count); +		allocated = udf_table_prealloc_blocks(sb, +						      map->s_fspace.s_table, +						      partition, first_block, +						      block_count);  	else  		return 0; + +	if (inode && allocated > 0) +		inode_add_bytes(inode, allocated << sb->s_blocksize_bits); +	return allocated;  }  inline int udf_new_block(struct super_block *sb, @@ -793,25 +797,29 @@ inline int udf_new_block(struct super_block *sb,  			 uint16_t partition, uint32_t goal, int *err)  {  	struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; +	int block;  	if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) -		return udf_bitmap_new_block(sb, inode, -					   map->s_uspace.s_bitmap, -					   partition, goal, err); +		block = udf_bitmap_new_block(sb, +					     map->s_uspace.s_bitmap, +					     partition, goal, err);  	else if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) -		return udf_table_new_block(sb, inode, -					   map->s_uspace.s_table, -					   partition, goal, err); -	else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) -		return udf_bitmap_new_block(sb, inode, -					    map->s_fspace.s_bitmap, +		block = udf_table_new_block(sb, +					    map->s_uspace.s_table,  					    partition, goal, err); +	else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) +		block = udf_bitmap_new_block(sb, +					     map->s_fspace.s_bitmap, +					     partition, goal, err);  	else if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) -		return udf_table_new_block(sb, inode, -					   map->s_fspace.s_table, -					   partition, goal, err); +		block = udf_table_new_block(sb, +					    map->s_fspace.s_table, +					    partition, goal, err);  	else {  		*err = -EIO;  		return 0;  	} +	if (inode && block) +		inode_add_bytes(inode, sb->s_blocksize); +	return block;  }  | 
