res_gdt.c revision dc8ce3463791366ac844d3f0436709511fa09c49
17d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org/*
27d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org * res_gdt.c --- reserve blocks for growing the group descriptor table
37d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org *               during online resizing.
47d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org *
57d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org * Copyright (C) 2002 Andreas Dilger
67d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org *
77d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org * %Begin-Header%
821d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org * This file may be redistributed under the terms of the GNU Public
97d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org * License.
107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org * %End-Header%
117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org */
127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include <stdio.h>
147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include <string.h>
157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include <time.h>
167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "ext2_fs.h"
177d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#include "ext2fs.h"
187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
197d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org/*
207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org * Iterate through the groups which hold BACKUP superblock/GDT copies in an
217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org * ext3 filesystem.  The counters should be initialized to 1, 5, and 7 before
227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org * calling this for the first time.  In a sparse filesystem it will be the
237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org * sequence of powers of 3, 5, and 7: 1, 3, 5, 7, 9, 25, 27, 49, 81, ...
247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org * For a non-sparse filesystem it will be every group: 1, 2, 3, 4, ...
257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org */
267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgstatic unsigned int list_backups(ext2_filsys fs, unsigned int *three,
277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org				 unsigned int *five, unsigned int *seven)
287d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org{
297d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	unsigned int *min = three;
3021d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org	int mult = 3;
317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	unsigned int ret;
327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	if (!(fs->super->s_feature_ro_compat &
347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	      EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		ret = *min;
367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		*min += 1;
377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		return ret;
387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	}
397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	if (*five < *min) {
417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		min = five;
427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		mult = 5;
437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	}
447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	if (*seven < *min) {
457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		min = seven;
467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		mult = 7;
477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	}
4821d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org
4921d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org	ret = *min;
5021d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org	*min *= mult;
5121d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org
5221d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org	return ret;
537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org/*
567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org * This code assumes that the reserved blocks have already been marked in-use
5721d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org * during ext2fs_initialize(), so that they are not allocated for other
587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org * uses before we can add them to the resize inode (which has to come
597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org * after the creation of the inode table).
607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org */
6121d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.orgerrcode_t ext2fs_create_resize_inode(ext2_filsys fs)
627d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org{
637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	errcode_t		retval, retval2;
647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	struct ext2_super_block	*sb;
657d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	struct ext2_inode	inode;
6621d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org	__u32			*dindir_buf, *gdt_buf;
677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	int			rsv_add;
687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	unsigned long long	apb, inode_size;
697d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	blk_t			dindir_blk, rsv_off, gdt_off, gdt_blk;
707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	int			dindir_dirty = 0, inode_dirty = 0;
7121d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org
727d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
737d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
7421d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org	sb = fs->super;
7521d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org	if (!sb->s_reserved_gdt_blocks)
767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		return 0;
777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
787d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	retval = ext2fs_get_mem(2 * fs->blocksize, (void **)&dindir_buf);
7921d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org	if (retval)
807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		goto out_free;
817d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	gdt_buf = (__u32 *)((char *)dindir_buf + fs->blocksize);
8221d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org
837d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
8421d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org	if (retval)
857d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		goto out_free;
867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
8721d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org	/* Maximum possible file size (we donly use the dindirect blocks) */
887d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	apb = EXT2_ADDR_PER_BLOCK(sb);
897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	rsv_add = fs->blocksize / 512;
907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	if ((dindir_blk = inode.i_block[EXT2_DIND_BLOCK])) {
917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#ifdef RES_GDT_DEBUG
927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		printf("reading GDT dindir %u\n", dindir_blk);
9321d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org#endif
9421d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org		retval = ext2fs_read_ind_block(fs, dindir_blk, dindir_buf);
9521d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org		if (retval)
9621d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org			goto out_inode;
9721d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org	} else {
9821d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org		blk_t goal = 3 + sb->s_reserved_gdt_blocks +
997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org			fs->desc_blocks + fs->inode_blocks_per_group;
1007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
10121d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org		retval = ext2fs_alloc_block(fs, goal, 0, &dindir_blk);
10221d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org		if (retval)
1037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org			goto out_free;
1047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		inode.i_mode = LINUX_S_IFREG | 0600;
1057d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		inode.i_links_count = 1;
1067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		inode.i_block[EXT2_DIND_BLOCK] = dindir_blk;
1077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		inode.i_blocks = rsv_add;
1086313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org		memset(dindir_buf, 0, fs->blocksize);
1097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#ifdef RES_GDT_DEBUG
11021d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org		printf("allocated GDT dindir %u\n", dindir_blk);
11121d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org#endif
11221d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org		dindir_dirty = inode_dirty = 1;
1137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		inode_size = apb*apb + apb + EXT2_NDIR_BLOCKS;
1146313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org		inode_size *= fs->blocksize;
11521d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org		inode.i_size = inode_size & 0xFFFFFFFF;
11621d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org		inode.i_size_high = (inode_size >> 32) & 0xFFFFFFFF;
1176313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org		if(inode.i_size_high) {
1186313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org			sb->s_feature_ro_compat |=
1196313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org				EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
1207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		}
1217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		inode.i_ctime = time(0);
1226313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org	}
12321d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org
1247d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	for (rsv_off = 0, gdt_off = fs->desc_blocks,
1257d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	     gdt_blk = sb->s_first_data_block + 1 + fs->desc_blocks;
1267d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	     rsv_off < sb->s_reserved_gdt_blocks;
1277d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	     rsv_off++, gdt_off++, gdt_blk++) {
12821d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org		unsigned int three = 1, five = 5, seven = 7;
12921d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org		unsigned int grp, last = 0;
1307d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		int gdt_dirty = 0;
1317d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1327d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		gdt_off %= apb;
1337d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		if (!dindir_buf[gdt_off]) {
1347d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org			/* FIXME XXX XXX
1357d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org			blk_t new_blk;
1367d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1377d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org			retval = ext2fs_new_block(fs, gdt_blk, 0, &new_blk);
1387d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org			if (retval)
1397d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org				goto out_free;
1407d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org			if (new_blk != gdt_blk) {
1417d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org				// XXX free block
1427d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org				retval = -1; // XXX
1437d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org			}
1447d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org			*/
1457d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org			gdt_dirty = dindir_dirty = inode_dirty = 1;
1467d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org			memset(gdt_buf, 0, fs->blocksize);
1477d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org			dindir_buf[gdt_off] = gdt_blk;
1487d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org			inode.i_blocks += rsv_add;
1497d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#ifdef RES_GDT_DEBUG
1507d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org			printf("added primary GDT block %u at %u[%u]\n",
1517d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org			       gdt_blk, dindir_blk, gdt_off);
1527d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#endif
1537d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		} else if (dindir_buf[gdt_off] == gdt_blk) {
1547d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#ifdef RES_GDT_DEBUG
1557d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org			printf("reading primary GDT block %u\n", gdt_blk);
1567d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#endif
1577d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org			retval = ext2fs_read_ind_block(fs, gdt_blk, gdt_buf);
1587d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org			if (retval)
1597d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org				goto out_dindir;
1607d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		} else {
1617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#ifdef RES_GDT_DEBUG
162e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org			printf("bad primary GDT %u != %u at %u[%u]\n",
1637d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org			       dindir_buf[gdt_off], gdt_blk,dindir_blk,gdt_off);
1647d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#endif
165e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org			retval = EXT2_ET_RESIZE_INODE_CORRUPT;
1667d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org			goto out_dindir;
1677d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		}
1687d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
1691af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org		while ((grp = list_backups(fs, &three, &five, &seven)) <
1707d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		       fs->group_desc_count) {
1711af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org			blk_t expect = gdt_blk + grp * sb->s_blocks_per_group;
1721af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org
1731af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org			if (!gdt_buf[last]) {
1747d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#ifdef RES_GDT_DEBUG
1751af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org				printf("added backup GDT %u grp %u@%u[%u]\n",
1767d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org				       expect, grp, gdt_blk, last);
1777d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#endif
1781af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org				gdt_buf[last] = expect;
1797d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org				inode.i_blocks += rsv_add;
1807d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org				gdt_dirty = inode_dirty = 1;
1811af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org			} else if (gdt_buf[last] != expect) {
1827d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#ifdef RES_GDT_DEBUG
1831af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org				printf("bad backup GDT %u != %u at %u[%u]\n",
1841af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org				       gdt_buf[last], expect, gdt_blk, last);
1851af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org#endif
1867d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org				retval = EXT2_ET_RESIZE_INODE_CORRUPT;
1871af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org				goto out_dindir;
1881af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org			}
1897d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org			last++;
1907d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		}
1917d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		if (gdt_dirty) {
1927d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#ifdef RES_GDT_DEBUG
1937d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org			printf("writing primary GDT block %u\n", gdt_blk);
1947d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#endif
1957d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org			retval = ext2fs_write_ind_block(fs, gdt_blk, gdt_buf);
1967d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org			if (retval)
1971af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org				goto out_dindir;
1987d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		}
1997d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	}
2007d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2011af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.orgout_dindir:
2027d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	if (dindir_dirty) {
2037d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		retval2 = ext2fs_write_ind_block(fs, dindir_blk, dindir_buf);
2047d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		if (!retval)
2051af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org			retval = retval2;
2067d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	}
2077d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgout_inode:
2087d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#ifdef RES_GDT_DEBUG
2097d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	printf("inode.i_blocks = %u, i_size = %u\n", inode.i_blocks,
2107d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	       inode.i_size);
2117d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org#endif
2127d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	if (inode_dirty) {
2137d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		inode.i_atime = inode.i_mtime = time(0);
2147d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		retval2 = ext2fs_write_inode(fs, EXT2_RESIZE_INO, &inode);
2157d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org		if (!retval)
2167d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org			retval = retval2;
21721d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org	}
2187d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.orgout_free:
21921d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org	ext2fs_free_mem((void **)&dindir_buf);
2207d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org	return retval;
2217d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org}
2227d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org
2237d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org