Whamcloud - gitweb
Clean up resize inode routines in ext2fs library. We no longer print
[tools/e2fsprogs.git] / lib / ext2fs / res_gdt.c
index 727b826..4706589 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * res_gdt.h --- reserve blocks for growing the group descriptor table
+ * res_gdt.c --- reserve blocks for growing the group descriptor table
  *               during online resizing.
  *
  * Copyright (C) 2002 Andreas Dilger
 #include "ext2fs.h"
 
 /*
+ * Iterate through the groups which hold BACKUP superblock/GDT copies in an
+ * ext3 filesystem.  The counters should be initialized to 1, 5, and 7 before
+ * calling this for the first time.  In a sparse filesystem it will be the
+ * sequence of powers of 3, 5, and 7: 1, 3, 5, 7, 9, 25, 27, 49, 81, ...
+ * For a non-sparse filesystem it will be every group: 1, 2, 3, 4, ...
+ */
+static unsigned int list_backups(ext2_filsys fs, unsigned int *three,
+                                unsigned int *five, unsigned int *seven)
+{
+       unsigned int *min = three;
+       int mult = 3;
+       unsigned int ret;
+
+       if (!(fs->super->s_feature_ro_compat &
+             EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
+               ret = *min;
+               *min += 1;
+               return ret;
+       }
+
+       if (*five < *min) {
+               min = five;
+               mult = 5;
+       }
+       if (*seven < *min) {
+               min = seven;
+               mult = 7;
+       }
+
+       ret = *min;
+       *min *= mult;
+
+       return ret;
+}
+
+/*
  * This code assumes that the reserved blocks have already been marked in-use
  * during ext2fs_initialize(), so that they are not allocated for other
  * uses before we can add them to the resize inode (which has to come
@@ -52,7 +88,9 @@ errcode_t ext2fs_create_resize_inode(ext2_filsys fs)
        apb = EXT2_ADDR_PER_BLOCK(sb);
        rsv_add = fs->blocksize / 512;
        if ((dindir_blk = inode.i_block[EXT2_DIND_BLOCK])) {
+#ifdef RES_GDT_DEBUG
                printf("reading GDT dindir %u\n", dindir_blk);
+#endif
                retval = io_channel_read_blk(fs->io, dindir_blk, 1, dindir_buf);
                if (retval)
                        goto out_inode;
@@ -84,7 +122,7 @@ errcode_t ext2fs_create_resize_inode(ext2_filsys fs)
        }
 
        for (rsv_off = 0, gdt_off = fs->desc_blocks,
-            gdt_blk = sb->s_first_data_block + 1 + gdt_off;
+            gdt_blk = sb->s_first_data_block + 1 + fs->desc_blocks;
             rsv_off < sb->s_reserved_gdt_blocks;
             rsv_off++, gdt_off++, gdt_blk++) {
                unsigned int three = 1, five = 5, seven = 7;
@@ -113,18 +151,22 @@ errcode_t ext2fs_create_resize_inode(ext2_filsys fs)
                               gdt_blk, dindir_blk, gdt_off);
 #endif
                } else if (dindir_buf[gdt_off] == gdt_blk) {
+#ifdef RES_GDT_DEBUG
                        printf("reading primary GDT block %u\n", gdt_blk);
+#endif
                        retval = io_channel_read_blk(fs->io,gdt_blk,1,gdt_buf);
                        if (retval)
                                goto out_dindir;
                } else {
+#ifdef RES_GDT_DEBUG
                        printf("bad primary GDT %u != %u at %u[%u]\n",
                               dindir_buf[gdt_off], gdt_blk,dindir_blk,gdt_off);
-                       retval = -1; // XXX
+#endif
+                       retval = EXT2_ET_RESIZE_INODE_CORRUPT;
                        goto out_dindir;
                }
 
-               while ((grp = ext2fs_list_backups(fs, &three, &five, &seven)) <
+               while ((grp = list_backups(fs, &three, &five, &seven)) <
                       fs->group_desc_count) {
                        blk_t expect = gdt_blk + grp * sb->s_blocks_per_group;
 
@@ -137,9 +179,11 @@ errcode_t ext2fs_create_resize_inode(ext2_filsys fs)
                                inode.i_blocks += rsv_add;
                                gdt_dirty = inode_dirty = 1;
                        } else if (gdt_buf[last] != expect) {
+#ifdef RES_GDT_DEBUG
                                printf("bad backup GDT %u != %u at %u[%u]\n",
                                       gdt_buf[last], expect, gdt_blk, last);
-                               retval = -1; // XXX
+#endif
+                               retval = EXT2_ET_RESIZE_INODE_CORRUPT;
                                goto out_dindir;
                        }
                        last++;
@@ -161,8 +205,10 @@ out_dindir:
                        retval = retval2;
        }
 out_inode:
+#ifdef RES_GDT_DEBUG
        printf("inode.i_blocks = %u, i_size = %u\n", inode.i_blocks,
               inode.i_size);
+#endif
        if (inode_dirty) {
                inode.i_atime = inode.i_mtime = time(0);
                retval2 = ext2fs_write_inode(fs, EXT2_RESIZE_INO, &inode);