Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 26 Feb 2013 22:51:52 +0000 (14:51 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 26 Feb 2013 22:51:52 +0000 (14:51 -0800)
Pull ext2, ext3, udf updates from Jan Kara:
 "Several UDF fixes, a support for UDF extent cache, and couple of ext2
  and ext3 cleanups and minor fixes"

* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs:
  Ext2: remove the static function release_blocks to optimize the kernel
  Ext2: mark inode dirty after the function dquot_free_block_nodirty is called
  Ext2: remove the overhead check about sb in the function ext2_new_blocks
  udf: Remove unused s_extLength from udf_bitmap
  udf: Make s_block_bitmap standard array
  udf: Fix bitmap overflow on large filesystems with small block size
  udf: add extent cache support in case of file reading
  udf: Write LVID to disk after opening / closing
  Ext3: return ENOMEM rather than EIO if sb_getblk fails
  Ext2: return ENOMEM rather than EIO if sb_getblk fails
  Ext3: use unlikely to improve the efficiency of the kernel
  Ext2: use unlikely to improve the efficiency of the kernel
  Ext3: add necessary check in case IO error happens
  Ext2: free memory allocated and forget buffer head when io error happens
  ext3: Fix memory leak when quota options are specified multiple times
  ext3, ext4, ocfs2: remove unused macro NAMEI_RA_INDEX

16 files changed:
fs/ext2/balloc.c
fs/ext2/inode.c
fs/ext2/super.c
fs/ext2/xattr.c
fs/ext3/inode.c
fs/ext3/namei.c
fs/ext3/resize.c
fs/ext3/super.c
fs/ext3/xattr.c
fs/ext4/namei.c
fs/ocfs2/dir.c
fs/udf/inode.c
fs/udf/super.c
fs/udf/udf_i.h
fs/udf/udf_sb.h
fs/udf/udfdecl.h

index 2616d0e..9f9992b 100644 (file)
@@ -159,15 +159,6 @@ read_block_bitmap(struct super_block *sb, unsigned int block_group)
        return bh;
 }
 
-static void release_blocks(struct super_block *sb, int count)
-{
-       if (count) {
-               struct ext2_sb_info *sbi = EXT2_SB(sb);
-
-               percpu_counter_add(&sbi->s_freeblocks_counter, count);
-       }
-}
-
 static void group_adjust_blocks(struct super_block *sb, int group_no,
        struct ext2_group_desc *desc, struct buffer_head *bh, int count)
 {
@@ -568,8 +559,11 @@ do_more:
        }
 error_return:
        brelse(bitmap_bh);
-       release_blocks(sb, freed);
-       dquot_free_block_nodirty(inode, freed);
+       if (freed) {
+               percpu_counter_add(&sbi->s_freeblocks_counter, freed);
+               dquot_free_block_nodirty(inode, freed);
+               mark_inode_dirty(inode);
+       }
 }
 
 /**
@@ -1239,10 +1233,6 @@ ext2_fsblk_t ext2_new_blocks(struct inode *inode, ext2_fsblk_t goal,
 
        *errp = -ENOSPC;
        sb = inode->i_sb;
-       if (!sb) {
-               printk("ext2_new_blocks: nonexistent device");
-               return 0;
-       }
 
        /*
         * Check quota for allocation of this block.
@@ -1416,9 +1406,11 @@ allocated:
 
        *errp = 0;
        brelse(bitmap_bh);
-       dquot_free_block_nodirty(inode, *count-num);
-       mark_inode_dirty(inode);
-       *count = num;
+       if (num < *count) {
+               dquot_free_block_nodirty(inode, *count-num);
+               mark_inode_dirty(inode);
+               *count = num;
+       }
        return ret_block;
 
 io_error:
index 6363ac6..c3881e5 100644 (file)
@@ -495,6 +495,10 @@ static int ext2_alloc_branch(struct inode *inode,
                 * parent to disk.
                 */
                bh = sb_getblk(inode->i_sb, new_blocks[n-1]);
+               if (unlikely(!bh)) {
+                       err = -ENOMEM;
+                       goto failed;
+               }
                branch[n].bh = bh;
                lock_buffer(bh);
                memset(bh->b_data, 0, blocksize);
@@ -523,6 +527,14 @@ static int ext2_alloc_branch(struct inode *inode,
        }
        *blks = num;
        return err;
+
+failed:
+       for (i = 1; i < n; i++)
+               bforget(branch[i].bh);
+       for (i = 0; i < indirect_blks; i++)
+               ext2_free_blocks(inode, new_blocks[i], 1);
+       ext2_free_blocks(inode, new_blocks[i], num);
+       return err;
 }
 
 /**
index fa04d02..7f68c81 100644 (file)
@@ -1500,7 +1500,7 @@ static ssize_t ext2_quota_write(struct super_block *sb, int type,
                        bh = sb_bread(sb, tmp_bh.b_blocknr);
                else
                        bh = sb_getblk(sb, tmp_bh.b_blocknr);
-               if (!bh) {
+               if (unlikely(!bh)) {
                        err = -EIO;
                        goto out;
                }
index b6754db..2d7557d 100644 (file)
@@ -662,10 +662,10 @@ ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh,
                        ea_idebug(inode, "creating block %d", block);
 
                        new_bh = sb_getblk(sb, block);
-                       if (!new_bh) {
+                       if (unlikely(!new_bh)) {
                                ext2_free_blocks(inode, block, 1);
                                mark_inode_dirty(inode);
-                               error = -EIO;
+                               error = -ENOMEM;
                                goto cleanup;
                        }
                        lock_buffer(new_bh);
index b176d42..d512c4b 100644 (file)
@@ -676,6 +676,10 @@ static int ext3_alloc_branch(handle_t *handle, struct inode *inode,
                 * parent to disk.
                 */
                bh = sb_getblk(inode->i_sb, new_blocks[n-1]);
+               if (unlikely(!bh)) {
+                       err = -ENOMEM;
+                       goto failed;
+               }
                branch[n].bh = bh;
                lock_buffer(bh);
                BUFFER_TRACE(bh, "call get_create_access");
@@ -717,7 +721,7 @@ failed:
                BUFFER_TRACE(branch[i].bh, "call journal_forget");
                ext3_journal_forget(handle, branch[i].bh);
        }
-       for (i = 0; i <indirect_blks; i++)
+       for (i = 0; i < indirect_blks; i++)
                ext3_free_blocks(handle, inode, new_blocks[i], 1);
 
        ext3_free_blocks(handle, inode, new_blocks[i], num);
@@ -1078,8 +1082,8 @@ struct buffer_head *ext3_getblk(handle_t *handle, struct inode *inode,
        if (!err && buffer_mapped(&dummy)) {
                struct buffer_head *bh;
                bh = sb_getblk(inode->i_sb, dummy.b_blocknr);
-               if (!bh) {
-                       *errp = -EIO;
+               if (unlikely(!bh)) {
+                       *errp = -ENOMEM;
                        goto err;
                }
                if (buffer_new(&dummy)) {
@@ -2729,12 +2733,12 @@ static int __ext3_get_inode_loc(struct inode *inode,
                return -EIO;
 
        bh = sb_getblk(inode->i_sb, block);
-       if (!bh) {
+       if (unlikely(!bh)) {
                ext3_error (inode->i_sb, "ext3_get_inode_loc",
                                "unable to read inode block - "
                                "inode=%lu, block="E3FSBLK,
                                 inode->i_ino, block);
-               return -EIO;
+               return -ENOMEM;
        }
        if (!buffer_uptodate(bh)) {
                lock_buffer(bh);
@@ -2783,7 +2787,7 @@ static int __ext3_get_inode_loc(struct inode *inode,
 
                        bitmap_bh = sb_getblk(inode->i_sb,
                                        le32_to_cpu(desc->bg_inode_bitmap));
-                       if (!bitmap_bh)
+                       if (unlikely(!bitmap_bh))
                                goto make_io;
 
                        /*
index 890b894..88f64eb 100644 (file)
@@ -36,7 +36,6 @@
 #define NAMEI_RA_CHUNKS  2
 #define NAMEI_RA_BLOCKS  4
 #define NAMEI_RA_SIZE        (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
-#define NAMEI_RA_INDEX(c,b)  (((c) * NAMEI_RA_BLOCKS) + (b))
 
 static struct buffer_head *ext3_append(handle_t *handle,
                                        struct inode *inode,
index 0f814f3..2710565 100644 (file)
@@ -116,8 +116,8 @@ static struct buffer_head *bclean(handle_t *handle, struct super_block *sb,
        int err;
 
        bh = sb_getblk(sb, blk);
-       if (!bh)
-               return ERR_PTR(-EIO);
+       if (unlikely(!bh))
+               return ERR_PTR(-ENOMEM);
        if ((err = ext3_journal_get_write_access(handle, bh))) {
                brelse(bh);
                bh = ERR_PTR(err);
@@ -234,8 +234,8 @@ static int setup_new_group_blocks(struct super_block *sb,
                        goto exit_bh;
 
                gdb = sb_getblk(sb, block);
-               if (!gdb) {
-                       err = -EIO;
+               if (unlikely(!gdb)) {
+                       err = -ENOMEM;
                        goto exit_bh;
                }
                if ((err = ext3_journal_get_write_access(handle, gdb))) {
@@ -722,8 +722,8 @@ static void update_backups(struct super_block *sb,
                        break;
 
                bh = sb_getblk(sb, group * bpg + blk_off);
-               if (!bh) {
-                       err = -EIO;
+               if (unlikely(!bh)) {
+                       err = -ENOMEM;
                        break;
                }
                ext3_debug("update metadata backup %#04lx\n",
index 4ba2683..5546ca2 100644 (file)
@@ -916,21 +916,24 @@ static int set_qf_name(struct super_block *sb, int qtype, substring_t *args)
                        "Not enough memory for storing quotafile name");
                return 0;
        }
-       if (sbi->s_qf_names[qtype] &&
-               strcmp(sbi->s_qf_names[qtype], qname)) {
-               ext3_msg(sb, KERN_ERR,
-                       "%s quota file already specified", QTYPE2NAME(qtype));
+       if (sbi->s_qf_names[qtype]) {
+               int same = !strcmp(sbi->s_qf_names[qtype], qname);
+
                kfree(qname);
-               return 0;
+               if (!same) {
+                       ext3_msg(sb, KERN_ERR,
+                                "%s quota file already specified",
+                                QTYPE2NAME(qtype));
+               }
+               return same;
        }
-       sbi->s_qf_names[qtype] = qname;
-       if (strchr(sbi->s_qf_names[qtype], '/')) {
+       if (strchr(qname, '/')) {
                ext3_msg(sb, KERN_ERR,
                        "quotafile must be on filesystem root");
-               kfree(sbi->s_qf_names[qtype]);
-               sbi->s_qf_names[qtype] = NULL;
+               kfree(qname);
                return 0;
        }
+       sbi->s_qf_names[qtype] = qname;
        set_opt(sbi->s_mount_opt, QUOTA);
        return 1;
 }
@@ -945,11 +948,10 @@ static int clear_qf_name(struct super_block *sb, int qtype) {
                        " when quota turned on");
                return 0;
        }
-       /*
-        * The space will be released later when all options are confirmed
-        * to be correct
-        */
-       sbi->s_qf_names[qtype] = NULL;
+       if (sbi->s_qf_names[qtype]) {
+               kfree(sbi->s_qf_names[qtype]);
+               sbi->s_qf_names[qtype] = NULL;
+       }
        return 1;
 }
 #endif
@@ -2606,7 +2608,18 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
 #ifdef CONFIG_QUOTA
        old_opts.s_jquota_fmt = sbi->s_jquota_fmt;
        for (i = 0; i < MAXQUOTAS; i++)
-               old_opts.s_qf_names[i] = sbi->s_qf_names[i];
+               if (sbi->s_qf_names[i]) {
+                       old_opts.s_qf_names[i] = kstrdup(sbi->s_qf_names[i],
+                                                        GFP_KERNEL);
+                       if (!old_opts.s_qf_names[i]) {
+                               int j;
+
+                               for (j = 0; j < i; j++)
+                                       kfree(old_opts.s_qf_names[j]);
+                               return -ENOMEM;
+                       }
+               } else
+                       old_opts.s_qf_names[i] = NULL;
 #endif
 
        /*
@@ -2699,9 +2712,7 @@ static int ext3_remount (struct super_block * sb, int * flags, char * data)
 #ifdef CONFIG_QUOTA
        /* Release old quota file names */
        for (i = 0; i < MAXQUOTAS; i++)
-               if (old_opts.s_qf_names[i] &&
-                   old_opts.s_qf_names[i] != sbi->s_qf_names[i])
-                       kfree(old_opts.s_qf_names[i]);
+               kfree(old_opts.s_qf_names[i]);
 #endif
        if (enable_quota)
                dquot_resume(sb, -1);
@@ -2715,9 +2726,7 @@ restore_opts:
 #ifdef CONFIG_QUOTA
        sbi->s_jquota_fmt = old_opts.s_jquota_fmt;
        for (i = 0; i < MAXQUOTAS; i++) {
-               if (sbi->s_qf_names[i] &&
-                   old_opts.s_qf_names[i] != sbi->s_qf_names[i])
-                       kfree(sbi->s_qf_names[i]);
+               kfree(sbi->s_qf_names[i]);
                sbi->s_qf_names[i] = old_opts.s_qf_names[i];
        }
 #endif
index d22ebb7..b1fc963 100644 (file)
@@ -813,10 +813,10 @@ inserted:
                        ea_idebug(inode, "creating block %d", block);
 
                        new_bh = sb_getblk(sb, block);
-                       if (!new_bh) {
+                       if (unlikely(!new_bh)) {
 getblk_failed:
                                ext3_free_blocks(handle, inode, block, 1);
-                               error = -EIO;
+                               error = -ENOMEM;
                                goto cleanup;
                        }
                        lock_buffer(new_bh);
index f9ed946..cc9a512 100644 (file)
@@ -47,7 +47,6 @@
 #define NAMEI_RA_CHUNKS  2
 #define NAMEI_RA_BLOCKS  4
 #define NAMEI_RA_SIZE       (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
-#define NAMEI_RA_INDEX(c,b)  (((c) * NAMEI_RA_BLOCKS) + (b))
 
 static struct buffer_head *ext4_append(handle_t *handle,
                                        struct inode *inode,
index 8fe4e28..fc12135 100644 (file)
@@ -67,7 +67,6 @@
 #define NAMEI_RA_CHUNKS  2
 #define NAMEI_RA_BLOCKS  4
 #define NAMEI_RA_SIZE        (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS)
-#define NAMEI_RA_INDEX(c,b)  (((c) * NAMEI_RA_BLOCKS) + (b))
 
 static unsigned char ocfs2_filetype_table[] = {
        DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK
index cbae1ed..7a12e48 100644 (file)
@@ -67,6 +67,74 @@ static void udf_update_extents(struct inode *,
                               struct extent_position *);
 static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);
 
+static void __udf_clear_extent_cache(struct inode *inode)
+{
+       struct udf_inode_info *iinfo = UDF_I(inode);
+
+       if (iinfo->cached_extent.lstart != -1) {
+               brelse(iinfo->cached_extent.epos.bh);
+               iinfo->cached_extent.lstart = -1;
+       }
+}
+
+/* Invalidate extent cache */
+static void udf_clear_extent_cache(struct inode *inode)
+{
+       struct udf_inode_info *iinfo = UDF_I(inode);
+
+       spin_lock(&iinfo->i_extent_cache_lock);
+       __udf_clear_extent_cache(inode);
+       spin_unlock(&iinfo->i_extent_cache_lock);
+}
+
+/* Return contents of extent cache */
+static int udf_read_extent_cache(struct inode *inode, loff_t bcount,
+                                loff_t *lbcount, struct extent_position *pos)
+{
+       struct udf_inode_info *iinfo = UDF_I(inode);
+       int ret = 0;
+
+       spin_lock(&iinfo->i_extent_cache_lock);
+       if ((iinfo->cached_extent.lstart <= bcount) &&
+           (iinfo->cached_extent.lstart != -1)) {
+               /* Cache hit */
+               *lbcount = iinfo->cached_extent.lstart;
+               memcpy(pos, &iinfo->cached_extent.epos,
+                      sizeof(struct extent_position));
+               if (pos->bh)
+                       get_bh(pos->bh);
+               ret = 1;
+       }
+       spin_unlock(&iinfo->i_extent_cache_lock);
+       return ret;
+}
+
+/* Add extent to extent cache */
+static void udf_update_extent_cache(struct inode *inode, loff_t estart,
+                                   struct extent_position *pos, int next_epos)
+{
+       struct udf_inode_info *iinfo = UDF_I(inode);
+
+       spin_lock(&iinfo->i_extent_cache_lock);
+       /* Invalidate previously cached extent */
+       __udf_clear_extent_cache(inode);
+       if (pos->bh)
+               get_bh(pos->bh);
+       memcpy(&iinfo->cached_extent.epos, pos,
+              sizeof(struct extent_position));
+       iinfo->cached_extent.lstart = estart;
+       if (next_epos)
+               switch (iinfo->i_alloc_type) {
+               case ICBTAG_FLAG_AD_SHORT:
+                       iinfo->cached_extent.epos.offset -=
+                       sizeof(struct short_ad);
+                       break;
+               case ICBTAG_FLAG_AD_LONG:
+                       iinfo->cached_extent.epos.offset -=
+                       sizeof(struct long_ad);
+               }
+       spin_unlock(&iinfo->i_extent_cache_lock);
+}
 
 void udf_evict_inode(struct inode *inode)
 {
@@ -90,6 +158,7 @@ void udf_evict_inode(struct inode *inode)
        }
        kfree(iinfo->i_ext.i_data);
        iinfo->i_ext.i_data = NULL;
+       udf_clear_extent_cache(inode);
        if (want_delete) {
                udf_free_inode(inode);
        }
@@ -105,6 +174,7 @@ static void udf_write_failed(struct address_space *mapping, loff_t to)
                truncate_pagecache(inode, to, isize);
                if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
                        down_write(&iinfo->i_data_sem);
+                       udf_clear_extent_cache(inode);
                        udf_truncate_extents(inode);
                        up_write(&iinfo->i_data_sem);
                }
@@ -372,7 +442,7 @@ static int udf_get_block(struct inode *inode, sector_t block,
                iinfo->i_next_alloc_goal++;
        }
 
-
+       udf_clear_extent_cache(inode);
        phys = inode_getblk(inode, block, &err, &new);
        if (!phys)
                goto abort;
@@ -1171,6 +1241,7 @@ set_size:
        } else {
                if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
                        down_write(&iinfo->i_data_sem);
+                       udf_clear_extent_cache(inode);
                        memset(iinfo->i_ext.i_data + iinfo->i_lenEAttr + newsize,
                               0x00, bsize - newsize -
                               udf_file_entry_alloc_offset(inode));
@@ -1184,6 +1255,7 @@ set_size:
                if (err)
                        return err;
                down_write(&iinfo->i_data_sem);
+               udf_clear_extent_cache(inode);
                truncate_setsize(inode, newsize);
                udf_truncate_extents(inode);
                up_write(&iinfo->i_data_sem);
@@ -2156,11 +2228,12 @@ int8_t inode_bmap(struct inode *inode, sector_t block,
        struct udf_inode_info *iinfo;
 
        iinfo = UDF_I(inode);
-       pos->offset = 0;
-       pos->block = iinfo->i_location;
-       pos->bh = NULL;
+       if (!udf_read_extent_cache(inode, bcount, &lbcount, pos)) {
+               pos->offset = 0;
+               pos->block = iinfo->i_location;
+               pos->bh = NULL;
+       }
        *elen = 0;
-
        do {
                etype = udf_next_aext(inode, pos, eloc, elen, 1);
                if (etype == -1) {
@@ -2170,7 +2243,8 @@ int8_t inode_bmap(struct inode *inode, sector_t block,
                }
                lbcount += *elen;
        } while (lbcount <= bcount);
-
+       /* update extent cache */
+       udf_update_extent_cache(inode, lbcount - *elen, pos, 1);
        *offset = (bcount + *elen - lbcount) >> blocksize_bits;
 
        return etype;
index e9be396..bc5b30a 100644 (file)
@@ -134,6 +134,8 @@ static struct inode *udf_alloc_inode(struct super_block *sb)
        ei->i_next_alloc_goal = 0;
        ei->i_strat4096 = 0;
        init_rwsem(&ei->i_data_sem);
+       ei->cached_extent.lstart = -1;
+       spin_lock_init(&ei->i_extent_cache_lock);
 
        return &ei->vfs_inode;
 }
@@ -1021,7 +1023,6 @@ static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index)
        if (bitmap == NULL)
                return NULL;
 
-       bitmap->s_block_bitmap = (struct buffer_head **)(bitmap + 1);
        bitmap->s_nr_groups = nr_groups;
        return bitmap;
 }
@@ -1079,8 +1080,6 @@ static int udf_fill_partdesc_info(struct super_block *sb,
                if (!bitmap)
                        return 1;
                map->s_uspace.s_bitmap = bitmap;
-               bitmap->s_extLength = le32_to_cpu(
-                               phd->unallocSpaceBitmap.extLength);
                bitmap->s_extPosition = le32_to_cpu(
                                phd->unallocSpaceBitmap.extPosition);
                map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_BITMAP;
@@ -1115,8 +1114,6 @@ static int udf_fill_partdesc_info(struct super_block *sb,
                if (!bitmap)
                        return 1;
                map->s_fspace.s_bitmap = bitmap;
-               bitmap->s_extLength = le32_to_cpu(
-                               phd->freedSpaceBitmap.extLength);
                bitmap->s_extPosition = le32_to_cpu(
                                phd->freedSpaceBitmap.extPosition);
                map->s_partition_flags |= UDF_PART_FLAG_FREED_BITMAP;
@@ -1866,6 +1863,8 @@ static void udf_open_lvid(struct super_block *sb)
        mark_buffer_dirty(bh);
        sbi->s_lvid_dirty = 0;
        mutex_unlock(&sbi->s_alloc_mutex);
+       /* Make opening of filesystem visible on the media immediately */
+       sync_dirty_buffer(bh);
 }
 
 static void udf_close_lvid(struct super_block *sb)
@@ -1906,6 +1905,8 @@ static void udf_close_lvid(struct super_block *sb)
        mark_buffer_dirty(bh);
        sbi->s_lvid_dirty = 0;
        mutex_unlock(&sbi->s_alloc_mutex);
+       /* Make closing of filesystem visible on the media immediately */
+       sync_dirty_buffer(bh);
 }
 
 u64 lvid_get_unique_id(struct super_block *sb)
index bb8309d..b5cd8ed 100644 (file)
@@ -1,6 +1,19 @@
 #ifndef _UDF_I_H
 #define _UDF_I_H
 
+struct extent_position {
+       struct buffer_head *bh;
+       uint32_t offset;
+       struct kernel_lb_addr block;
+};
+
+struct udf_ext_cache {
+       /* Extent position */
+       struct extent_position epos;
+       /* Start logical offset in bytes */
+       loff_t lstart;
+};
+
 /*
  * The i_data_sem and i_mutex serve for protection of allocation information
  * of a regular files and symlinks. This includes all extents belonging to
@@ -35,6 +48,9 @@ struct udf_inode_info {
                __u8            *i_data;
        } i_ext;
        struct rw_semaphore     i_data_sem;
+       struct udf_ext_cache cached_extent;
+       /* Spinlock for protecting extent cache */
+       spinlock_t i_extent_cache_lock;
        struct inode vfs_inode;
 };
 
index 5f02722..ed401e9 100644 (file)
@@ -80,10 +80,9 @@ struct udf_virtual_data {
 };
 
 struct udf_bitmap {
-       __u32                   s_extLength;
        __u32                   s_extPosition;
-       __u16                   s_nr_groups;
-       struct buffer_head      **s_block_bitmap;
+       int                     s_nr_groups;
+       struct buffer_head      *s_block_bitmap[0];
 };
 
 struct udf_part_map {
index de038da..be7dabb 100644 (file)
@@ -113,11 +113,6 @@ struct ustr {
        uint8_t u_len;
 };
 
-struct extent_position {
-       struct buffer_head *bh;
-       uint32_t offset;
-       struct kernel_lb_addr block;
-};
 
 /* super.c */