diff options
Diffstat (limited to 'fs/udf/balloc.c')
| -rw-r--r-- | fs/udf/balloc.c | 355 |
1 files changed, 129 insertions, 226 deletions
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c index f855dcbbdfb..1ba2baaf436 100644 --- a/fs/udf/balloc.c +++ b/fs/udf/balloc.c @@ -21,65 +21,16 @@ #include "udfdecl.h" -#include <linux/quotaops.h> #include <linux/buffer_head.h> #include <linux/bitops.h> #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_first_one_bit(addr, size) find_first_one_bit(addr, size) -#define udf_find_next_one_bit(addr, size, offset) \ - find_next_one_bit(addr, size, offset) - -#define leBPL_to_cpup(x) leNUM_to_cpup(BITS_PER_LONG, x) -#define leNUM_to_cpup(x, y) xleNUM_to_cpup(x, y) -#define xleNUM_to_cpup(x, y) (le ## x ## _to_cpup(y)) -#define uintBPL_t uint(BITS_PER_LONG) -#define uint(x) xuint(x) -#define xuint(x) __le ## x - -static inline int find_next_one_bit(void *addr, int size, int offset) -{ - uintBPL_t *p = ((uintBPL_t *) addr) + (offset / BITS_PER_LONG); - int result = offset & ~(BITS_PER_LONG - 1); - unsigned long tmp; - - if (offset >= size) - return size; - size -= result; - offset &= (BITS_PER_LONG - 1); - if (offset) { - tmp = leBPL_to_cpup(p++); - tmp &= ~0UL << offset; - if (size < BITS_PER_LONG) - goto found_first; - if (tmp) - goto found_middle; - size -= BITS_PER_LONG; - result += BITS_PER_LONG; - } - while (size & ~(BITS_PER_LONG - 1)) { - tmp = leBPL_to_cpup(p++); - if (tmp) - goto found_middle; - result += BITS_PER_LONG; - size -= BITS_PER_LONG; - } - if (!size) - return result; - tmp = leBPL_to_cpup(p); -found_first: - tmp &= ~0UL >> (BITS_PER_LONG - size); -found_middle: - return result + ffz(~tmp); -} - -#define find_first_one_bit(addr, size)\ - find_next_one_bit((addr), (size), 0) +#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, @@ -87,12 +38,12 @@ static int read_block_bitmap(struct super_block *sb, { struct buffer_head *bh = NULL; int retval = 0; - kernel_lb_addr loc; + struct kernel_lb_addr loc; loc.logicalBlockNum = bitmap->s_extPosition; loc.partitionReferenceNum = UDF_SB(sb)->s_partition; - bh = udf_tread(sb, udf_get_lb_pblock(sb, loc, block)); + bh = udf_tread(sb, udf_get_lb_pblock(sb, &loc, block)); if (!bh) retval = -EIO; @@ -108,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]) { @@ -140,28 +91,28 @@ static inline int load_block_bitmap(struct super_block *sb, return slot; } -static bool udf_add_free_space(struct udf_sb_info *sbi, - u16 partition, u32 cnt) +static void udf_add_free_space(struct super_block *sb, u16 partition, u32 cnt) { + struct udf_sb_info *sbi = UDF_SB(sb); struct logicalVolIntegrityDesc *lvid; - if (sbi->s_lvid_bh == NULL) - return false; + if (!sbi->s_lvid_bh) + return; lvid = (struct logicalVolIntegrityDesc *)sbi->s_lvid_bh->b_data; - lvid->freeSpaceTable[partition] = cpu_to_le32(le32_to_cpu( - lvid->freeSpaceTable[partition]) + cnt); - return true; + le32_add_cpu(&lvid->freeSpaceTable[partition], cnt); + udf_updated_lvid(sb); } static void udf_bitmap_free_blocks(struct super_block *sb, - struct inode *inode, struct udf_bitmap *bitmap, - kernel_lb_addr bloc, uint32_t offset, + struct kernel_lb_addr *bloc, + uint32_t offset, uint32_t count) { struct udf_sb_info *sbi = UDF_SB(sb); struct buffer_head *bh = NULL; + struct udf_part_map *partmap; unsigned long block; unsigned long block_group; unsigned long bit; @@ -170,17 +121,17 @@ static void udf_bitmap_free_blocks(struct super_block *sb, unsigned long overflow; mutex_lock(&sbi->s_alloc_mutex); - if (bloc.logicalBlockNum < 0 || - (bloc.logicalBlockNum + count) > - sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) { + partmap = &sbi->s_partmaps[bloc->partitionReferenceNum]; + 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, - sbi->s_partmaps[bloc.partitionReferenceNum]. - s_partition_len); + bloc->logicalBlockNum, 0, + bloc->logicalBlockNum, count, + partmap->s_partition_len); goto error_return; } - block = bloc.logicalBlockNum + offset + + block = bloc->logicalBlockNum + offset + (sizeof(struct spaceBitmapDesc) << 3); do { @@ -204,13 +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 { - if (inode) - DQUOT_FREE_BLOCK(inode, 1); - udf_add_free_space(sbi, 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; @@ -219,14 +167,10 @@ static void udf_bitmap_free_blocks(struct super_block *sb, } while (overflow); error_return: - sb->s_dirt = 1; - if (sbi->s_lvid_bh) - mark_buffer_dirty(sbi->s_lvid_bh); mutex_unlock(&sbi->s_alloc_mutex); } 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) @@ -240,7 +184,7 @@ static int udf_bitmap_prealloc_blocks(struct super_block *sb, mutex_lock(&sbi->s_alloc_mutex); part_len = sbi->s_partmaps[partition].s_partition_len; - if (first_block < 0 || first_block >= part_len) + if (first_block >= part_len) goto out; if (first_block + block_count > part_len) @@ -260,15 +204,8 @@ static int udf_bitmap_prealloc_blocks(struct super_block *sb, bit = block % (sb->s_blocksize << 3); while (bit < (sb->s_blocksize << 3) && block_count > 0) { - if (!udf_test_bit(bit, bh->b_data)) + if (!udf_clear_bit(bit, bh->b_data)) goto out; - else if (DQUOT_PREALLOC_BLOCK(inode, 1)) - goto out; - else if (!udf_clear_bit(bit, bh->b_data)) { - udf_debug("bit already cleared for block %d\n", bit); - DQUOT_FREE_BLOCK(inode, 1); - goto out; - } block_count--; alloc_count++; bit++; @@ -278,15 +215,12 @@ static int udf_bitmap_prealloc_blocks(struct super_block *sb, } while (block_count > 0); out: - if (udf_add_free_space(sbi, partition, -alloc_count)) - mark_buffer_dirty(sbi->s_lvid_bh); - sb->s_dirt = 1; + udf_add_free_space(sb, partition, -alloc_count); mutex_unlock(&sbi->s_alloc_mutex); return alloc_count; } 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) { @@ -301,7 +235,7 @@ static int udf_bitmap_new_block(struct super_block *sb, mutex_lock(&sbi->s_alloc_mutex); repeat: - if (goal < 0 || goal >= sbi->s_partmaps[partition].s_partition_len) + if (goal >= sbi->s_partmaps[partition].s_partition_len) goal = 0; nr_groups = bitmap->s_nr_groups; @@ -360,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) @@ -390,16 +324,6 @@ search_back: } got_block: - - /* - * Check quota for allocation of this block. - */ - if (inode && DQUOT_ALLOC_BLOCK(inode, 1)) { - mutex_unlock(&sbi->s_alloc_mutex); - *err = -EDQUOT; - return 0; - } - newblock = bit + (block_group << (sb->s_blocksize_bits + 3)) - (sizeof(struct spaceBitmapDesc) << 3); @@ -410,9 +334,7 @@ got_block: mark_buffer_dirty(bh); - if (udf_add_free_space(sbi, partition, -1)) - mark_buffer_dirty(sbi->s_lvid_bh); - sb->s_dirt = 1; + udf_add_free_space(sb, partition, -1); mutex_unlock(&sbi->s_alloc_mutex); *err = 0; return newblock; @@ -424,41 +346,37 @@ error_return: } static void udf_table_free_blocks(struct super_block *sb, - struct inode *inode, struct inode *table, - kernel_lb_addr bloc, uint32_t offset, + struct kernel_lb_addr *bloc, + uint32_t offset, uint32_t count) { struct udf_sb_info *sbi = UDF_SB(sb); + struct udf_part_map *partmap; uint32_t start, end; uint32_t elen; - kernel_lb_addr eloc; + struct kernel_lb_addr eloc; struct extent_position oepos, epos; int8_t etype; int i; struct udf_inode_info *iinfo; mutex_lock(&sbi->s_alloc_mutex); - if (bloc.logicalBlockNum < 0 || - (bloc.logicalBlockNum + count) > - sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) { + partmap = &sbi->s_partmaps[bloc->partitionReferenceNum]; + 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, - sbi->s_partmaps[bloc.partitionReferenceNum]. - s_partition_len); + bloc->logicalBlockNum, 0, + bloc->logicalBlockNum, count, + partmap->s_partition_len); goto error_return; } iinfo = UDF_I(table); - /* We do this up front - There are some error conditions that - could occure, but.. oh well */ - if (inode) - DQUOT_FREE_BLOCK(inode, count); - if (udf_add_free_space(sbi, sbi->s_partition, count)) - mark_buffer_dirty(sbi->s_lvid_bh); + udf_add_free_space(sb, sbi->s_partition, count); - start = bloc.logicalBlockNum + offset; - end = bloc.logicalBlockNum + offset + count - 1; + start = bloc->logicalBlockNum + offset; + end = bloc->logicalBlockNum + offset + count - 1; epos.offset = oepos.offset = sizeof(struct unallocSpaceEntry); elen = 0; @@ -484,7 +402,7 @@ static void udf_table_free_blocks(struct super_block *sb, start += count; count = 0; } - udf_write_aext(table, &oepos, eloc, elen, 1); + udf_write_aext(table, &oepos, &eloc, elen, 1); } else if (eloc.logicalBlockNum == (end + 1)) { if ((0x3FFFFFFF - elen) < (count << sb->s_blocksize_bits)) { @@ -503,7 +421,7 @@ static void udf_table_free_blocks(struct super_block *sb, end -= count; count = 0; } - udf_write_aext(table, &oepos, eloc, elen, 1); + udf_write_aext(table, &oepos, &eloc, elen, 1); } if (epos.bh != oepos.bh) { @@ -533,8 +451,8 @@ static void udf_table_free_blocks(struct super_block *sb, */ int adsize; - short_ad *sad = NULL; - long_ad *lad = NULL; + struct short_ad *sad = NULL; + struct long_ad *lad = NULL; struct allocExtDesc *aed; eloc.logicalBlockNum = start; @@ -542,9 +460,9 @@ static void udf_table_free_blocks(struct super_block *sb, (count << sb->s_blocksize_bits); if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) - adsize = sizeof(short_ad); + adsize = sizeof(struct short_ad); else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) - adsize = sizeof(long_ad); + adsize = sizeof(struct long_ad); else { brelse(oepos.bh); brelse(epos.bh); @@ -552,7 +470,7 @@ static void udf_table_free_blocks(struct super_block *sb, } if (epos.offset + (2 * adsize) > sb->s_blocksize) { - char *sptr, *dptr; + unsigned char *sptr, *dptr; int loffset; brelse(oepos.bh); @@ -564,7 +482,7 @@ static void udf_table_free_blocks(struct super_block *sb, elen -= sb->s_blocksize; epos.bh = udf_tread(sb, - udf_get_lb_pblock(sb, epos.block, 0)); + udf_get_lb_pblock(sb, &epos.block, 0)); if (!epos.bh) { brelse(oepos.bh); goto error_return; @@ -589,10 +507,8 @@ static void udf_table_free_blocks(struct super_block *sb, sptr = oepos.bh->b_data + epos.offset; aed = (struct allocExtDesc *) oepos.bh->b_data; - aed->lengthAllocDescs = - cpu_to_le32(le32_to_cpu( - aed->lengthAllocDescs) + - adsize); + le32_add_cpu(&aed->lengthAllocDescs, + adsize); } else { sptr = iinfo->i_ext.i_data + epos.offset; @@ -604,15 +520,15 @@ static void udf_table_free_blocks(struct super_block *sb, if (sbi->s_udfrev >= 0x0200) udf_new_tag(epos.bh->b_data, TAG_IDENT_AED, 3, 1, epos.block.logicalBlockNum, - sizeof(tag)); + sizeof(struct tag)); else udf_new_tag(epos.bh->b_data, TAG_IDENT_AED, 2, 1, epos.block.logicalBlockNum, - sizeof(tag)); + sizeof(struct tag)); switch (iinfo->i_alloc_type) { case ICBTAG_FLAG_AD_SHORT: - sad = (short_ad *)sptr; + sad = (struct short_ad *)sptr; sad->extLength = cpu_to_le32( EXT_NEXT_EXTENT_ALLOCDECS | sb->s_blocksize); @@ -620,7 +536,7 @@ static void udf_table_free_blocks(struct super_block *sb, cpu_to_le32(epos.block.logicalBlockNum); break; case ICBTAG_FLAG_AD_LONG: - lad = (long_ad *)sptr; + lad = (struct long_ad *)sptr; lad->extLength = cpu_to_le32( EXT_NEXT_EXTENT_ALLOCDECS | sb->s_blocksize); @@ -638,16 +554,14 @@ static void udf_table_free_blocks(struct super_block *sb, /* It's possible that stealing the block emptied the extent */ if (elen) { - udf_write_aext(table, &epos, eloc, elen, 1); + udf_write_aext(table, &epos, &eloc, elen, 1); if (!epos.bh) { iinfo->i_lenAlloc += adsize; mark_inode_dirty(table); } else { aed = (struct allocExtDesc *)epos.bh->b_data; - aed->lengthAllocDescs = - cpu_to_le32(le32_to_cpu( - aed->lengthAllocDescs) + adsize); + le32_add_cpu(&aed->lengthAllocDescs, adsize); udf_update_tag(epos.bh->b_data, epos.offset); mark_buffer_dirty(epos.bh); } @@ -658,33 +572,30 @@ static void udf_table_free_blocks(struct super_block *sb, brelse(oepos.bh); error_return: - sb->s_dirt = 1; mutex_unlock(&sbi->s_alloc_mutex); 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) { struct udf_sb_info *sbi = UDF_SB(sb); int alloc_count = 0; uint32_t elen, adsize; - kernel_lb_addr eloc; + struct kernel_lb_addr eloc; struct extent_position epos; int8_t etype = -1; struct udf_inode_info *iinfo; - if (first_block < 0 || - first_block >= sbi->s_partmaps[partition].s_partition_len) + if (first_block >= sbi->s_partmaps[partition].s_partition_len) return 0; iinfo = UDF_I(table); if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) - adsize = sizeof(short_ad); + adsize = sizeof(struct short_ad); else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) - adsize = sizeof(long_ad); + adsize = sizeof(struct long_ad); else return 0; @@ -705,14 +616,11 @@ static int udf_table_prealloc_blocks(struct super_block *sb, epos.offset -= adsize; alloc_count = (elen >> sb->s_blocksize_bits); - if (inode && DQUOT_PREALLOC_BLOCK(inode, - alloc_count > block_count ? block_count : alloc_count)) - alloc_count = 0; - else if (alloc_count > block_count) { + if (alloc_count > block_count) { alloc_count = block_count; eloc.logicalBlockNum += alloc_count; elen -= (alloc_count << sb->s_blocksize_bits); - udf_write_aext(table, &epos, eloc, + udf_write_aext(table, &epos, &eloc, (etype << 30) | elen, 1); } else udf_delete_aext(table, epos, eloc, @@ -723,16 +631,13 @@ static int udf_table_prealloc_blocks(struct super_block *sb, brelse(epos.bh); - if (alloc_count && udf_add_free_space(sbi, partition, -alloc_count)) { - mark_buffer_dirty(sbi->s_lvid_bh); - sb->s_dirt = 1; - } + if (alloc_count) + udf_add_free_space(sb, partition, -alloc_count); mutex_unlock(&sbi->s_alloc_mutex); return alloc_count; } static int udf_table_new_block(struct super_block *sb, - struct inode *inode, struct inode *table, uint16_t partition, uint32_t goal, int *err) { @@ -740,7 +645,7 @@ static int udf_table_new_block(struct super_block *sb, uint32_t spread = 0xFFFFFFFF, nspread = 0xFFFFFFFF; uint32_t newblock = 0, adsize; uint32_t elen, goal_elen = 0; - kernel_lb_addr eloc, uninitialized_var(goal_eloc); + struct kernel_lb_addr eloc, uninitialized_var(goal_eloc); struct extent_position epos, goal_epos; int8_t etype; struct udf_inode_info *iinfo = UDF_I(table); @@ -748,14 +653,14 @@ static int udf_table_new_block(struct super_block *sb, *err = -ENOSPC; if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) - adsize = sizeof(short_ad); + adsize = sizeof(struct short_ad); else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) - adsize = sizeof(long_ad); + adsize = sizeof(struct long_ad); else return newblock; mutex_lock(&sbi->s_alloc_mutex); - if (goal < 0 || goal >= sbi->s_partmaps[partition].s_partition_len) + if (goal >= sbi->s_partmaps[partition].s_partition_len) goal = 0; /* We search for the closest matching block to goal. If we find @@ -811,54 +716,43 @@ static int udf_table_new_block(struct super_block *sb, goal_eloc.logicalBlockNum++; goal_elen -= sb->s_blocksize; - if (inode && DQUOT_ALLOC_BLOCK(inode, 1)) { - brelse(goal_epos.bh); - mutex_unlock(&sbi->s_alloc_mutex); - *err = -EDQUOT; - return 0; - } - if (goal_elen) - udf_write_aext(table, &goal_epos, goal_eloc, goal_elen, 1); + udf_write_aext(table, &goal_epos, &goal_eloc, goal_elen, 1); else udf_delete_aext(table, goal_epos, goal_eloc, goal_elen); brelse(goal_epos.bh); - if (udf_add_free_space(sbi, partition, -1)) - mark_buffer_dirty(sbi->s_lvid_bh); + udf_add_free_space(sb, partition, -1); - sb->s_dirt = 1; mutex_unlock(&sbi->s_alloc_mutex); *err = 0; return newblock; } -inline void udf_free_blocks(struct super_block *sb, - struct inode *inode, - kernel_lb_addr bloc, uint32_t offset, - uint32_t count) +void udf_free_blocks(struct super_block *sb, struct inode *inode, + struct kernel_lb_addr *bloc, uint32_t offset, + uint32_t count) { - uint16_t partition = bloc.partitionReferenceNum; + uint16_t partition = bloc->partitionReferenceNum; struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) { - return udf_bitmap_free_blocks(sb, inode, - map->s_uspace.s_bitmap, - bloc, offset, count); + udf_bitmap_free_blocks(sb, map->s_uspace.s_bitmap, + bloc, offset, count); } else if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) { - return udf_table_free_blocks(sb, inode, - map->s_uspace.s_table, - bloc, offset, count); + udf_table_free_blocks(sb, map->s_uspace.s_table, + bloc, offset, count); } else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) { - return udf_bitmap_free_blocks(sb, inode, - map->s_fspace.s_bitmap, - bloc, offset, count); + udf_bitmap_free_blocks(sb, map->s_fspace.s_bitmap, + bloc, offset, count); } else if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) { - return udf_table_free_blocks(sb, inode, - map->s_fspace.s_table, - bloc, offset, count); - } else { - return; + 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); } } @@ -868,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, @@ -898,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; } |
