Merge branch 'master' into next
[safe/jmp/linux-2.6] / fs / udf / balloc.c
index dc9f8a9..1b809bd 100644 (file)
@@ -140,6 +140,19 @@ 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)
+{
+       struct logicalVolIntegrityDesc *lvid;
+
+       if (sbi->s_lvid_bh == NULL)
+               return false;
+
+       lvid = (struct logicalVolIntegrityDesc *)sbi->s_lvid_bh->b_data;
+       le32_add_cpu(&lvid->freeSpaceTable[partition], cnt);
+       return true;
+}
+
 static void udf_bitmap_free_blocks(struct super_block *sb,
                                   struct inode *inode,
                                   struct udf_bitmap *bitmap,
@@ -169,50 +182,46 @@ static void udf_bitmap_free_blocks(struct super_block *sb,
        block = bloc.logicalBlockNum + offset +
                (sizeof(struct spaceBitmapDesc) << 3);
 
-do_more:
-       overflow = 0;
-       block_group = block >> (sb->s_blocksize_bits + 3);
-       bit = block % (sb->s_blocksize << 3);
+       do {
+               overflow = 0;
+               block_group = block >> (sb->s_blocksize_bits + 3);
+               bit = block % (sb->s_blocksize << 3);
 
-       /*
-        * Check to see if we are freeing blocks across a group boundary.
-        */
-       if (bit + count > (sb->s_blocksize << 3)) {
-               overflow = bit + count - (sb->s_blocksize << 3);
-               count -= overflow;
-       }
-       bitmap_nr = load_block_bitmap(sb, bitmap, block_group);
-       if (bitmap_nr < 0)
-               goto error_return;
+               /*
+               * Check to see if we are freeing blocks across a group boundary.
+               */
+               if (bit + count > (sb->s_blocksize << 3)) {
+                       overflow = bit + count - (sb->s_blocksize << 3);
+                       count -= overflow;
+               }
+               bitmap_nr = load_block_bitmap(sb, bitmap, block_group);
+               if (bitmap_nr < 0)
+                       goto error_return;
 
-       bh = bitmap->s_block_bitmap[bitmap_nr];
-       for (i = 0; i < count; i++) {
-               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);
-                       if (sbi->s_lvid_bh) {
-                               struct logicalVolIntegrityDesc *lvid = (struct logicalVolIntegrityDesc *)sbi->s_lvid_bh->b_data;
-                               lvid->freeSpaceTable[sbi->s_partition] =
-                                       cpu_to_le32(le32_to_cpu(lvid->freeSpaceTable[sbi->s_partition]) + 1);
+               bh = bitmap->s_block_bitmap[bitmap_nr];
+               for (i = 0; i < count; i++) {
+                       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);
                        }
                }
-       }
-       mark_buffer_dirty(bh);
-       if (overflow) {
-               block += count;
-               count = overflow;
-               goto do_more;
-       }
+               mark_buffer_dirty(bh);
+               if (overflow) {
+                       block += count;
+                       count = overflow;
+               }
+       } 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);
-       return;
 }
 
 static int udf_bitmap_prealloc_blocks(struct super_block *sb,
@@ -236,44 +245,40 @@ static int udf_bitmap_prealloc_blocks(struct super_block *sb,
        if (first_block + block_count > part_len)
                block_count = part_len - first_block;
 
-repeat:
-       nr_groups = udf_compute_nr_groups(sb, partition);
-       block = first_block + (sizeof(struct spaceBitmapDesc) << 3);
-       block_group = block >> (sb->s_blocksize_bits + 3);
-       group_start = block_group ? 0 : sizeof(struct spaceBitmapDesc);
+       do {
+               nr_groups = udf_compute_nr_groups(sb, partition);
+               block = first_block + (sizeof(struct spaceBitmapDesc) << 3);
+               block_group = block >> (sb->s_blocksize_bits + 3);
+               group_start = block_group ? 0 : sizeof(struct spaceBitmapDesc);
 
-       bitmap_nr = load_block_bitmap(sb, bitmap, block_group);
-       if (bitmap_nr < 0)
-               goto out;
-       bh = bitmap->s_block_bitmap[bitmap_nr];
+               bitmap_nr = load_block_bitmap(sb, bitmap, block_group);
+               if (bitmap_nr < 0)
+                       goto out;
+               bh = bitmap->s_block_bitmap[bitmap_nr];
 
-       bit = block % (sb->s_blocksize << 3);
+               bit = block % (sb->s_blocksize << 3);
 
-       while (bit < (sb->s_blocksize << 3) && block_count > 0) {
-               if (!udf_test_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;
+               while (bit < (sb->s_blocksize << 3) && block_count > 0) {
+                       if (!udf_test_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++;
+                       block++;
                }
-               block_count--;
-               alloc_count++;
-               bit++;
-               block++;
-       }
-       mark_buffer_dirty(bh);
-       if (block_count > 0)
-               goto repeat;
+               mark_buffer_dirty(bh);
+       } while (block_count > 0);
+
 out:
-       if (sbi->s_lvid_bh) {
-               struct logicalVolIntegrityDesc *lvid = (struct logicalVolIntegrityDesc *)sbi->s_lvid_bh->b_data;
-               lvid->freeSpaceTable[partition] =
-                       cpu_to_le32(le32_to_cpu(lvid->freeSpaceTable[partition]) - alloc_count);
+       if (udf_add_free_space(sbi, partition, -alloc_count))
                mark_buffer_dirty(sbi->s_lvid_bh);
-       }
        sb->s_dirt = 1;
        mutex_unlock(&sbi->s_alloc_mutex);
        return alloc_count;
@@ -404,12 +409,8 @@ got_block:
 
        mark_buffer_dirty(bh);
 
-       if (sbi->s_lvid_bh) {
-               struct logicalVolIntegrityDesc *lvid = (struct logicalVolIntegrityDesc *)sbi->s_lvid_bh->b_data;
-               lvid->freeSpaceTable[partition] =
-                       cpu_to_le32(le32_to_cpu(lvid->freeSpaceTable[partition]) - 1);
+       if (udf_add_free_space(sbi, partition, -1))
                mark_buffer_dirty(sbi->s_lvid_bh);
-       }
        sb->s_dirt = 1;
        mutex_unlock(&sbi->s_alloc_mutex);
        *err = 0;
@@ -434,6 +435,7 @@ static void udf_table_free_blocks(struct super_block *sb,
        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 ||
@@ -446,23 +448,20 @@ static void udf_table_free_blocks(struct super_block *sb,
                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 (sbi->s_lvid_bh) {
-               struct logicalVolIntegrityDesc *lvid = (struct logicalVolIntegrityDesc *)sbi->s_lvid_bh->b_data;
-               lvid->freeSpaceTable[sbi->s_partition] =
-                       cpu_to_le32(le32_to_cpu(lvid->freeSpaceTable[sbi->s_partition]) + count);
+       if (udf_add_free_space(sbi, sbi->s_partition, count))
                mark_buffer_dirty(sbi->s_lvid_bh);
-       }
 
        start = bloc.logicalBlockNum + offset;
        end = bloc.logicalBlockNum + offset + count - 1;
 
        epos.offset = oepos.offset = sizeof(struct unallocSpaceEntry);
        elen = 0;
-       epos.block = oepos.block = UDF_I_LOCATION(table);
+       epos.block = oepos.block = iinfo->i_location;
        epos.bh = oepos.bh = NULL;
 
        while (count &&
@@ -541,11 +540,11 @@ static void udf_table_free_blocks(struct super_block *sb,
                elen = EXT_RECORDED_ALLOCATED |
                        (count << sb->s_blocksize_bits);
 
-               if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_SHORT) {
+               if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
                        adsize = sizeof(short_ad);
-               } else if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_LONG) {
+               else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
                        adsize = sizeof(long_ad);
-               else {
+               else {
                        brelse(oepos.bh);
                        brelse(epos.bh);
                        goto error_return;
@@ -575,7 +574,8 @@ static void udf_table_free_blocks(struct super_block *sb,
                        if (epos.offset + adsize > sb->s_blocksize) {
                                loffset = epos.offset;
                                aed->lengthAllocDescs = cpu_to_le32(adsize);
-                               sptr = UDF_I_DATA(table) + epos.offset - adsize;
+                               sptr = iinfo->i_ext.i_data + epos.offset
+                                                               - adsize;
                                dptr = epos.bh->b_data +
                                        sizeof(struct allocExtDesc);
                                memcpy(dptr, sptr, adsize);
@@ -588,13 +588,12 @@ 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 = UDF_I_DATA(table) + epos.offset;
-                                       UDF_I_LENALLOC(table) += adsize;
+                                       sptr = iinfo->i_ext.i_data +
+                                                               epos.offset;
+                                       iinfo->i_lenAlloc += adsize;
                                        mark_inode_dirty(table);
                                }
                                epos.offset = sizeof(struct allocExtDesc);
@@ -608,7 +607,7 @@ static void udf_table_free_blocks(struct super_block *sb,
                                            2, 1, epos.block.logicalBlockNum,
                                            sizeof(tag));
 
-                       switch (UDF_I_ALLOCTYPE(table)) {
+                       switch (iinfo->i_alloc_type) {
                        case ICBTAG_FLAG_AD_SHORT:
                                sad = (short_ad *)sptr;
                                sad->extLength = cpu_to_le32(
@@ -639,13 +638,11 @@ static void udf_table_free_blocks(struct super_block *sb,
                        udf_write_aext(table, &epos, eloc, elen, 1);
 
                        if (!epos.bh) {
-                               UDF_I_LENALLOC(table) += adsize;
+                               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);
                        }
@@ -672,21 +669,23 @@ static int udf_table_prealloc_blocks(struct super_block *sb,
        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)
                return 0;
 
-       if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_SHORT)
+       iinfo = UDF_I(table);
+       if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
                adsize = sizeof(short_ad);
-       else if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_LONG)
+       else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
                adsize = sizeof(long_ad);
        else
                return 0;
 
        mutex_lock(&sbi->s_alloc_mutex);
        epos.offset = sizeof(struct unallocSpaceEntry);
-       epos.block = UDF_I_LOCATION(table);
+       epos.block = iinfo->i_location;
        epos.bh = NULL;
        eloc.logicalBlockNum = 0xFFFFFFFF;
 
@@ -719,10 +718,7 @@ static int udf_table_prealloc_blocks(struct super_block *sb,
 
        brelse(epos.bh);
 
-       if (alloc_count && sbi->s_lvid_bh) {
-               struct logicalVolIntegrityDesc *lvid = (struct logicalVolIntegrityDesc *)sbi->s_lvid_bh->b_data;
-               lvid->freeSpaceTable[partition] =
-                       cpu_to_le32(le32_to_cpu(lvid->freeSpaceTable[partition]) - alloc_count);
+       if (alloc_count && udf_add_free_space(sbi, partition, -alloc_count)) {
                mark_buffer_dirty(sbi->s_lvid_bh);
                sb->s_dirt = 1;
        }
@@ -742,12 +738,13 @@ static int udf_table_new_block(struct super_block *sb,
        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);
 
        *err = -ENOSPC;
 
-       if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_SHORT)
+       if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
                adsize = sizeof(short_ad);
-       else if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_LONG)
+       else if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG)
                adsize = sizeof(long_ad);
        else
                return newblock;
@@ -762,7 +759,7 @@ static int udf_table_new_block(struct super_block *sb,
           of the current closest match and use that when we are done.
         */
        epos.offset = sizeof(struct unallocSpaceEntry);
-       epos.block = UDF_I_LOCATION(table);
+       epos.block = iinfo->i_location;
        epos.bh = goal_epos.bh = NULL;
 
        while (spread &&
@@ -822,12 +819,8 @@ static int udf_table_new_block(struct super_block *sb,
                udf_delete_aext(table, goal_epos, goal_eloc, goal_elen);
        brelse(goal_epos.bh);
 
-       if (sbi->s_lvid_bh) {
-               struct logicalVolIntegrityDesc *lvid = (struct logicalVolIntegrityDesc *)sbi->s_lvid_bh->b_data;
-               lvid->freeSpaceTable[partition] =
-                       cpu_to_le32(le32_to_cpu(lvid->freeSpaceTable[partition]) - 1);
+       if (udf_add_free_space(sbi, partition, -1))
                mark_buffer_dirty(sbi->s_lvid_bh);
-       }
 
        sb->s_dirt = 1;
        mutex_unlock(&sbi->s_alloc_mutex);