13839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/*
23839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * block.c --- iterate over all blocks in an inode
3efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o *
421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o *
621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * %Begin-Header%
7543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * This file may be redistributed under the terms of the GNU Library
8543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * General Public License, version 2.
921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * %End-Header%
103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */
113839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <stdio.h>
133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <string.h>
144cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#if HAVE_UNISTD_H
153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <unistd.h>
164cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#endif
17f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o
18b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o#include "ext2_fs.h"
193839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "ext2fs.h"
203839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
213839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostruct block_context {
223839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	ext2_filsys	fs;
233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	int (*func)(ext2_filsys	fs,
24e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		    blk64_t	*blocknr,
2503673dbb04a3458ce78a394f27d17d434b51a714Theodore Ts'o		    e2_blkcnt_t	bcount,
26e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		    blk64_t	ref_blk,
2721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o		    int		ref_offset,
28b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o		    void	*priv_data);
2903673dbb04a3458ce78a394f27d17d434b51a714Theodore Ts'o	e2_blkcnt_t	bcount;
303839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	int		bsize;
313839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	int		flags;
323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	errcode_t	errcode;
333839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	char	*ind_buf;
343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	char	*dind_buf;
353839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	char	*tind_buf;
36b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o	void	*priv_data;
373839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o};
383839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
39206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o#define check_for_ro_violation_return(ctx, ret)				\
40357d1863d64ce807c2904e101fc87d3f6be2f3caTheodore Ts'o	do {								\
41357d1863d64ce807c2904e101fc87d3f6be2f3caTheodore Ts'o		if (((ctx)->flags & BLOCK_FLAG_READ_ONLY) &&		\
42357d1863d64ce807c2904e101fc87d3f6be2f3caTheodore Ts'o		    ((ret) & BLOCK_CHANGED)) {				\
43357d1863d64ce807c2904e101fc87d3f6be2f3caTheodore Ts'o			(ctx)->errcode = EXT2_ET_RO_BLOCK_ITERATE;	\
44206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o			ret |= BLOCK_ABORT | BLOCK_ERROR;		\
45206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o			return ret;					\
46206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o		}							\
47206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o	} while (0)
48206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o
49206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o#define check_for_ro_violation_goto(ctx, ret, label)			\
50206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o	do {								\
51206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o		if (((ctx)->flags & BLOCK_FLAG_READ_ONLY) &&		\
52206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o		    ((ret) & BLOCK_CHANGED)) {				\
53206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o			(ctx)->errcode = EXT2_ET_RO_BLOCK_ITERATE;	\
54206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o			ret |= BLOCK_ABORT | BLOCK_ERROR;		\
55206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o			goto label;					\
56357d1863d64ce807c2904e101fc87d3f6be2f3caTheodore Ts'o		}							\
57357d1863d64ce807c2904e101fc87d3f6be2f3caTheodore Ts'o	} while (0)
58357d1863d64ce807c2904e101fc87d3f6be2f3caTheodore Ts'o
5921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'ostatic int block_iterate_ind(blk_t *ind_block, blk_t ref_block,
6021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o			     int ref_offset, struct block_context *ctx)
613839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
623839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	int	ret = 0, changed = 0;
6321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	int	i, flags, limit, offset;
643839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	blk_t	*block_nr;
65e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	blk64_t	blk64;
663839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
67a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o	limit = ctx->fs->blocksize >> 2;
681e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	if (!(ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
69e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	    !(ctx->flags & BLOCK_FLAG_DATA_ONLY)) {
70e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		blk64 = *ind_block;
71e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ret = (*ctx->func)(ctx->fs, &blk64,
7221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o				   BLOCK_COUNT_IND, ref_block,
73b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o				   ref_offset, ctx->priv_data);
74e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		*ind_block = blk64;
75e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
76206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o	check_for_ro_violation_return(ctx, ret);
77a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o	if (!*ind_block || (ret & BLOCK_ABORT)) {
78a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o		ctx->bcount += limit;
793839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return ret;
80a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o	}
81e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (*ind_block >= ext2fs_blocks_count(ctx->fs->super) ||
82f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	    *ind_block < ctx->fs->super->s_first_data_block) {
83f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o		ctx->errcode = EXT2_ET_BAD_IND_BLOCK;
84f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o		ret |= BLOCK_ERROR;
85f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o		return ret;
86f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	}
87efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o	ctx->errcode = ext2fs_read_ind_block(ctx->fs, *ind_block,
88dc8ce3463791366ac844d3f0436709511fa09c49Theodore Ts'o					     ctx->ind_buf);
893839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (ctx->errcode) {
903839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		ret |= BLOCK_ERROR;
913839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return ret;
923839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
93dc8ce3463791366ac844d3f0436709511fa09c49Theodore Ts'o
9450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	block_nr = (blk_t *) ctx->ind_buf;
9521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	offset = 0;
9650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	if (ctx->flags & BLOCK_FLAG_APPEND) {
9750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		for (i = 0; i < limit; i++, ctx->bcount++, block_nr++) {
98e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			blk64 = *block_nr;
99e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			flags = (*ctx->func)(ctx->fs, &blk64, ctx->bcount,
100efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o					     *ind_block, offset,
101b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o					     ctx->priv_data);
102e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			*block_nr = blk64;
10350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			changed	|= flags;
10450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			if (flags & BLOCK_ABORT) {
10550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o				ret |= BLOCK_ABORT;
10650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o				break;
10750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			}
10821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o			offset += sizeof(blk_t);
10950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		}
11050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	} else {
11150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		for (i = 0; i < limit; i++, ctx->bcount++, block_nr++) {
11250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			if (*block_nr == 0)
11394ded6c16bdcc77b43caaa151bd7afa55c5d3cf1Theodore Ts'o				goto skip_sparse;
114e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			blk64 = *block_nr;
115e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			flags = (*ctx->func)(ctx->fs, &blk64, ctx->bcount,
116efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o					     *ind_block, offset,
117b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o					     ctx->priv_data);
118e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			*block_nr = blk64;
11950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			changed	|= flags;
1203839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			if (flags & BLOCK_ABORT) {
1213839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				ret |= BLOCK_ABORT;
1223839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				break;
1233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			}
12494ded6c16bdcc77b43caaa151bd7afa55c5d3cf1Theodore Ts'o		skip_sparse:
12521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o			offset += sizeof(blk_t);
1263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		}
1273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
128206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o	check_for_ro_violation_return(ctx, changed);
129dc8ce3463791366ac844d3f0436709511fa09c49Theodore Ts'o	if (changed & BLOCK_CHANGED) {
130dc8ce3463791366ac844d3f0436709511fa09c49Theodore Ts'o		ctx->errcode = ext2fs_write_ind_block(ctx->fs, *ind_block,
131dc8ce3463791366ac844d3f0436709511fa09c49Theodore Ts'o						      ctx->ind_buf);
1323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		if (ctx->errcode)
1333839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			ret |= BLOCK_ERROR | BLOCK_ABORT;
1343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
1353839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if ((ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
1361e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	    !(ctx->flags & BLOCK_FLAG_DATA_ONLY) &&
137e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	    !(ret & BLOCK_ABORT)) {
138e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		blk64 = *ind_block;
139e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ret |= (*ctx->func)(ctx->fs, &blk64,
14021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o				    BLOCK_COUNT_IND, ref_block,
141b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o				    ref_offset, ctx->priv_data);
142e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		*ind_block = blk64;
143e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
144206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o	check_for_ro_violation_return(ctx, ret);
1453839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return ret;
1463839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
147efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
14821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'ostatic int block_iterate_dind(blk_t *dind_block, blk_t ref_block,
14921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o			      int ref_offset, struct block_context *ctx)
1503839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
1513839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	int	ret = 0, changed = 0;
15221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	int	i, flags, limit, offset;
1533839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	blk_t	*block_nr;
154e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	blk64_t	blk64;
1553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
156a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o	limit = ctx->fs->blocksize >> 2;
15706af47f0e81c8dd75daf83c848659ef011ea5450Theodore Ts'o	if (!(ctx->flags & (BLOCK_FLAG_DEPTH_TRAVERSE |
158e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			    BLOCK_FLAG_DATA_ONLY))) {
159e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		blk64 = *dind_block;
160e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ret = (*ctx->func)(ctx->fs, &blk64,
16121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o				   BLOCK_COUNT_DIND, ref_block,
162b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o				   ref_offset, ctx->priv_data);
163e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		*dind_block = blk64;
164e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
165206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o	check_for_ro_violation_return(ctx, ret);
166a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o	if (!*dind_block || (ret & BLOCK_ABORT)) {
167a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o		ctx->bcount += limit*limit;
1683839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return ret;
169a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o	}
170e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (*dind_block >= ext2fs_blocks_count(ctx->fs->super) ||
171f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	    *dind_block < ctx->fs->super->s_first_data_block) {
172f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o		ctx->errcode = EXT2_ET_BAD_DIND_BLOCK;
173f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o		ret |= BLOCK_ERROR;
174f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o		return ret;
175f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	}
176efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o	ctx->errcode = ext2fs_read_ind_block(ctx->fs, *dind_block,
177dc8ce3463791366ac844d3f0436709511fa09c49Theodore Ts'o					     ctx->dind_buf);
1783839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (ctx->errcode) {
1793839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		ret |= BLOCK_ERROR;
1803839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return ret;
1813839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
182dc8ce3463791366ac844d3f0436709511fa09c49Theodore Ts'o
18350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	block_nr = (blk_t *) ctx->dind_buf;
18421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	offset = 0;
18550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	if (ctx->flags & BLOCK_FLAG_APPEND) {
18650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		for (i = 0; i < limit; i++, block_nr++) {
18721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o			flags = block_iterate_ind(block_nr,
18821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o						  *dind_block, offset,
18921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o						  ctx);
19050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			changed |= flags;
19150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			if (flags & (BLOCK_ABORT | BLOCK_ERROR)) {
19250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o				ret |= flags & (BLOCK_ABORT | BLOCK_ERROR);
19350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o				break;
19450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			}
19521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o			offset += sizeof(blk_t);
19650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		}
19750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	} else {
19850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		for (i = 0; i < limit; i++, block_nr++) {
199a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o			if (*block_nr == 0) {
200a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o				ctx->bcount += limit;
20150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o				continue;
202a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o			}
20321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o			flags = block_iterate_ind(block_nr,
20421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o						  *dind_block, offset,
20521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o						  ctx);
20650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			changed |= flags;
2073839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			if (flags & (BLOCK_ABORT | BLOCK_ERROR)) {
2083839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				ret |= flags & (BLOCK_ABORT | BLOCK_ERROR);
2093839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				break;
2103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			}
21121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o			offset += sizeof(blk_t);
2123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		}
2133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
214206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o	check_for_ro_violation_return(ctx, changed);
215dc8ce3463791366ac844d3f0436709511fa09c49Theodore Ts'o	if (changed & BLOCK_CHANGED) {
216dc8ce3463791366ac844d3f0436709511fa09c49Theodore Ts'o		ctx->errcode = ext2fs_write_ind_block(ctx->fs, *dind_block,
217dc8ce3463791366ac844d3f0436709511fa09c49Theodore Ts'o						      ctx->dind_buf);
2183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		if (ctx->errcode)
2193839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			ret |= BLOCK_ERROR | BLOCK_ABORT;
2203839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
2213839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if ((ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
2221e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	    !(ctx->flags & BLOCK_FLAG_DATA_ONLY) &&
223e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	    !(ret & BLOCK_ABORT)) {
224e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		blk64 = *dind_block;
225e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ret |= (*ctx->func)(ctx->fs, &blk64,
22621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o				    BLOCK_COUNT_DIND, ref_block,
227b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o				    ref_offset, ctx->priv_data);
228e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		*dind_block = blk64;
229e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
230206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o	check_for_ro_violation_return(ctx, ret);
2313839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return ret;
2323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
233efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
23421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'ostatic int block_iterate_tind(blk_t *tind_block, blk_t ref_block,
23521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o			      int ref_offset, struct block_context *ctx)
2363839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
2373839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	int	ret = 0, changed = 0;
23821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	int	i, flags, limit, offset;
2393839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	blk_t	*block_nr;
240e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	blk64_t	blk64;
2413839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
242a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o	limit = ctx->fs->blocksize >> 2;
24306af47f0e81c8dd75daf83c848659ef011ea5450Theodore Ts'o	if (!(ctx->flags & (BLOCK_FLAG_DEPTH_TRAVERSE |
244e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			    BLOCK_FLAG_DATA_ONLY))) {
245e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		blk64 = *tind_block;
246e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ret = (*ctx->func)(ctx->fs, &blk64,
24721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o				   BLOCK_COUNT_TIND, ref_block,
248b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o				   ref_offset, ctx->priv_data);
249e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		*tind_block = blk64;
250e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
251206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o	check_for_ro_violation_return(ctx, ret);
252a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o	if (!*tind_block || (ret & BLOCK_ABORT)) {
253a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o		ctx->bcount += limit*limit*limit;
2543839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return ret;
255a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o	}
256e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	if (*tind_block >= ext2fs_blocks_count(ctx->fs->super) ||
257f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	    *tind_block < ctx->fs->super->s_first_data_block) {
258f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o		ctx->errcode = EXT2_ET_BAD_TIND_BLOCK;
259f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o		ret |= BLOCK_ERROR;
260f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o		return ret;
261f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	}
262efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o	ctx->errcode = ext2fs_read_ind_block(ctx->fs, *tind_block,
263dc8ce3463791366ac844d3f0436709511fa09c49Theodore Ts'o					     ctx->tind_buf);
2643839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (ctx->errcode) {
2653839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		ret |= BLOCK_ERROR;
2663839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return ret;
2673839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
268dc8ce3463791366ac844d3f0436709511fa09c49Theodore Ts'o
26950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	block_nr = (blk_t *) ctx->tind_buf;
27021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	offset = 0;
27150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	if (ctx->flags & BLOCK_FLAG_APPEND) {
27250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		for (i = 0; i < limit; i++, block_nr++) {
27321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o			flags = block_iterate_dind(block_nr,
27421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o						   *tind_block,
27521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o						   offset, ctx);
27650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			changed |= flags;
27750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			if (flags & (BLOCK_ABORT | BLOCK_ERROR)) {
27850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o				ret |= flags & (BLOCK_ABORT | BLOCK_ERROR);
27950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o				break;
28050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			}
28121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o			offset += sizeof(blk_t);
28250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		}
28350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	} else {
28450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		for (i = 0; i < limit; i++, block_nr++) {
285a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o			if (*block_nr == 0) {
286a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o				ctx->bcount += limit*limit;
28750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o				continue;
288a29f4d30f24d68f1f1c75548e020689ede532c05Theodore Ts'o			}
28921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o			flags = block_iterate_dind(block_nr,
29021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o						   *tind_block,
29121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o						   offset, ctx);
29250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			changed |= flags;
2933839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			if (flags & (BLOCK_ABORT | BLOCK_ERROR)) {
2943839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				ret |= flags & (BLOCK_ABORT | BLOCK_ERROR);
2953839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o				break;
2963839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			}
29721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o			offset += sizeof(blk_t);
2983839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		}
2993839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
300206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o	check_for_ro_violation_return(ctx, changed);
301dc8ce3463791366ac844d3f0436709511fa09c49Theodore Ts'o	if (changed & BLOCK_CHANGED) {
302dc8ce3463791366ac844d3f0436709511fa09c49Theodore Ts'o		ctx->errcode = ext2fs_write_ind_block(ctx->fs, *tind_block,
303dc8ce3463791366ac844d3f0436709511fa09c49Theodore Ts'o						      ctx->tind_buf);
3043839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		if (ctx->errcode)
3053839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			ret |= BLOCK_ERROR | BLOCK_ABORT;
3063839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
3073839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if ((ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
3081e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	    !(ctx->flags & BLOCK_FLAG_DATA_ONLY) &&
309e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	    !(ret & BLOCK_ABORT)) {
310e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		blk64 = *tind_block;
311e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ret |= (*ctx->func)(ctx->fs, &blk64,
31221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o				    BLOCK_COUNT_TIND, ref_block,
313b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o				    ref_offset, ctx->priv_data);
314e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		*tind_block = blk64;
315e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	}
316206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o	check_for_ro_violation_return(ctx, ret);
3173839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return ret;
3183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
319efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
320e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallerrcode_t ext2fs_block_iterate3(ext2_filsys fs,
32131dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'o				ext2_ino_t ino,
32221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o				int	flags,
32321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o				char *block_buf,
32421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o				int (*func)(ext2_filsys fs,
325e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					    blk64_t	*blocknr,
32603673dbb04a3458ce78a394f27d17d434b51a714Theodore Ts'o					    e2_blkcnt_t	blockcnt,
327e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					    blk64_t	ref_blk,
32821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o					    int		ref_offset,
329b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o					    void	*priv_data),
330b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o				void *priv_data)
3313839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
3323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	int	i;
333d7b92206ba7f987a68ba42971c930039729831e1Theodore Ts'o	int	r, ret = 0;
3343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	struct ext2_inode inode;
3353839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	errcode_t	retval;
33621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	struct block_context ctx;
337674a4ee1e3e05133ddad701730bfc21c283272a4Theodore Ts'o	int	limit;
338e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	blk64_t	blk64;
33921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o
340f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
341f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o
342206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o	ctx.errcode = ext2fs_read_inode(fs, ino, &inode);
343206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o	if (ctx.errcode)
344206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o		return ctx.errcode;
345206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o
346674a4ee1e3e05133ddad701730bfc21c283272a4Theodore Ts'o	/*
347674a4ee1e3e05133ddad701730bfc21c283272a4Theodore Ts'o	 * Check to see if we need to limit large files
348674a4ee1e3e05133ddad701730bfc21c283272a4Theodore Ts'o	 */
349674a4ee1e3e05133ddad701730bfc21c283272a4Theodore Ts'o	if (flags & BLOCK_FLAG_NO_LARGE) {
350674a4ee1e3e05133ddad701730bfc21c283272a4Theodore Ts'o		if (!LINUX_S_ISDIR(inode.i_mode) &&
351674a4ee1e3e05133ddad701730bfc21c283272a4Theodore Ts'o		    (inode.i_size_high != 0))
352674a4ee1e3e05133ddad701730bfc21c283272a4Theodore Ts'o			return EXT2_ET_FILE_TOO_BIG;
353674a4ee1e3e05133ddad701730bfc21c283272a4Theodore Ts'o	}
354674a4ee1e3e05133ddad701730bfc21c283272a4Theodore Ts'o
355674a4ee1e3e05133ddad701730bfc21c283272a4Theodore Ts'o	limit = fs->blocksize >> 2;
356674a4ee1e3e05133ddad701730bfc21c283272a4Theodore Ts'o
3573839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	ctx.fs = fs;
3583839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	ctx.func = func;
359b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o	ctx.priv_data = priv_data;
3603839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	ctx.flags = flags;
36121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	ctx.bcount = 0;
3623839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (block_buf) {
3633839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		ctx.ind_buf = block_buf;
3643839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	} else {
365ee01079a17bfecd17292ccd60058056fb3a8ba6cTheodore Ts'o		retval = ext2fs_get_array(3, fs->blocksize, &ctx.ind_buf);
3667b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o		if (retval)
3677b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o			return retval;
3683839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
3693839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	ctx.dind_buf = ctx.ind_buf + fs->blocksize;
3703839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	ctx.tind_buf = ctx.dind_buf + fs->blocksize;
3711e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o
3721e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	/*
3731e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	 * Iterate over the HURD translator block (if present)
3741e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	 */
3751e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	if ((fs->super->s_creator_os == EXT2_OS_HURD) &&
3765c576477ccb2f0ca8c5d5af2e2354fd8eeff1589Theodore Ts'o	    !(flags & BLOCK_FLAG_DATA_ONLY)) {
3775c576477ccb2f0ca8c5d5af2e2354fd8eeff1589Theodore Ts'o		if (inode.osd1.hurd1.h_i_translator) {
378e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			blk64 = inode.osd1.hurd1.h_i_translator;
379e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			ret |= (*ctx.func)(fs, &blk64,
38021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o					   BLOCK_COUNT_TRANSLATOR,
381b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o					   0, 0, priv_data);
382e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			inode.osd1.hurd1.h_i_translator = (blk_t) blk64;
3835c576477ccb2f0ca8c5d5af2e2354fd8eeff1589Theodore Ts'o			if (ret & BLOCK_ABORT)
38431dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'o				goto abort_exit;
385206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o			check_for_ro_violation_goto(&ctx, ret, abort_exit);
3865c576477ccb2f0ca8c5d5af2e2354fd8eeff1589Theodore Ts'o		}
3871e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	}
388efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
389206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o	if (inode.i_flags & EXT4_EXTENTS_FL) {
390206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o		ext2_extent_handle_t	handle;
391e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		struct ext2fs_extent	extent, next;
392685d544effc774de1580fec047629cd814bad660Theodore Ts'o		e2_blkcnt_t		blockcnt = 0;
393e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		blk64_t			blk, new_blk;
394206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o		int			op = EXT2_EXTENT_ROOT;
39507f1a070ff45c8381c3ddf8552c726525104e1eeTheodore Ts'o		int			uninit;
3962d328bb76d2d63bdfdba923b54c28bd686bd8fecTheodore Ts'o		unsigned int		j;
397206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o
39884b239aea4da04c7a569b428d3abf6c720e82645number		ctx.errcode = ext2fs_extent_open2(fs, ino, &inode, &handle);
399206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o		if (ctx.errcode)
400206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o			goto abort_exit;
401206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o
402206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o		while (1) {
403e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			if (op == EXT2_EXTENT_CURRENT)
404e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				ctx.errcode = 0;
405e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			else
406e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				ctx.errcode = ext2fs_extent_get(handle, op,
407e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall								&extent);
408206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o			if (ctx.errcode) {
409685d544effc774de1580fec047629cd814bad660Theodore Ts'o				if (ctx.errcode != EXT2_ET_EXTENT_NO_NEXT)
410685d544effc774de1580fec047629cd814bad660Theodore Ts'o					break;
411685d544effc774de1580fec047629cd814bad660Theodore Ts'o				ctx.errcode = 0;
412685d544effc774de1580fec047629cd814bad660Theodore Ts'o				if (!(flags & BLOCK_FLAG_APPEND))
413685d544effc774de1580fec047629cd814bad660Theodore Ts'o					break;
4148e2399d57ac2bec1830e27deeeac66002d81001cTheodore Ts'o			next_block_set:
415685d544effc774de1580fec047629cd814bad660Theodore Ts'o				blk = 0;
416685d544effc774de1580fec047629cd814bad660Theodore Ts'o				r = (*ctx.func)(fs, &blk, blockcnt,
417685d544effc774de1580fec047629cd814bad660Theodore Ts'o						0, 0, priv_data);
418685d544effc774de1580fec047629cd814bad660Theodore Ts'o				ret |= r;
419685d544effc774de1580fec047629cd814bad660Theodore Ts'o				check_for_ro_violation_goto(&ctx, ret,
420e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall							    extent_done);
421685d544effc774de1580fec047629cd814bad660Theodore Ts'o				if (r & BLOCK_CHANGED) {
422efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o					ctx.errcode =
423685d544effc774de1580fec047629cd814bad660Theodore Ts'o						ext2fs_extent_set_bmap(handle,
424685d544effc774de1580fec047629cd814bad660Theodore Ts'o						       (blk64_t) blockcnt++,
425685d544effc774de1580fec047629cd814bad660Theodore Ts'o						       (blk64_t) blk, 0);
426685d544effc774de1580fec047629cd814bad660Theodore Ts'o					if (ctx.errcode || (ret & BLOCK_ABORT))
42764987c052c235d60373995d36b5c01291c464b74Theodore Ts'o						break;
4288e2399d57ac2bec1830e27deeeac66002d81001cTheodore Ts'o					if (blk)
4298e2399d57ac2bec1830e27deeeac66002d81001cTheodore Ts'o						goto next_block_set;
430685d544effc774de1580fec047629cd814bad660Theodore Ts'o				}
43164987c052c235d60373995d36b5c01291c464b74Theodore Ts'o				break;
432206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o			}
433206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o
434206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o			op = EXT2_EXTENT_NEXT;
435206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o			blk = extent.e_pblk;
436d7b92206ba7f987a68ba42971c930039729831e1Theodore Ts'o			if (!(extent.e_flags & EXT2_EXTENT_FLAGS_LEAF)) {
437d7b92206ba7f987a68ba42971c930039729831e1Theodore Ts'o				if (ctx.flags & BLOCK_FLAG_DATA_ONLY)
438d7b92206ba7f987a68ba42971c930039729831e1Theodore Ts'o					continue;
439d7b92206ba7f987a68ba42971c930039729831e1Theodore Ts'o				if ((!(extent.e_flags &
440d7b92206ba7f987a68ba42971c930039729831e1Theodore Ts'o				       EXT2_EXTENT_FLAGS_SECOND_VISIT) &&
441d7b92206ba7f987a68ba42971c930039729831e1Theodore Ts'o				     !(ctx.flags & BLOCK_FLAG_DEPTH_TRAVERSE)) ||
442d7b92206ba7f987a68ba42971c930039729831e1Theodore Ts'o				    ((extent.e_flags &
443d7b92206ba7f987a68ba42971c930039729831e1Theodore Ts'o				      EXT2_EXTENT_FLAGS_SECOND_VISIT) &&
444d7b92206ba7f987a68ba42971c930039729831e1Theodore Ts'o				     (ctx.flags & BLOCK_FLAG_DEPTH_TRAVERSE))) {
445d7b92206ba7f987a68ba42971c930039729831e1Theodore Ts'o					ret |= (*ctx.func)(fs, &blk,
446d7b92206ba7f987a68ba42971c930039729831e1Theodore Ts'o							   -1, 0, 0, priv_data);
447d7b92206ba7f987a68ba42971c930039729831e1Theodore Ts'o					if (ret & BLOCK_CHANGED) {
448213fe9288bbebe6566f554996660a7c242a910ddTheodore Ts'o						extent.e_pblk = blk;
449213fe9288bbebe6566f554996660a7c242a910ddTheodore Ts'o						ctx.errcode =
450213fe9288bbebe6566f554996660a7c242a910ddTheodore Ts'o				ext2fs_extent_replace(handle, 0, &extent);
451213fe9288bbebe6566f554996660a7c242a910ddTheodore Ts'o						if (ctx.errcode)
45264987c052c235d60373995d36b5c01291c464b74Theodore Ts'o							break;
453d7b92206ba7f987a68ba42971c930039729831e1Theodore Ts'o					}
454e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					if (ret & BLOCK_ABORT)
455e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall						break;
456d7b92206ba7f987a68ba42971c930039729831e1Theodore Ts'o				}
457206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o				continue;
458206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o			}
45907f1a070ff45c8381c3ddf8552c726525104e1eeTheodore Ts'o			uninit = 0;
46007f1a070ff45c8381c3ddf8552c726525104e1eeTheodore Ts'o			if (extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT)
46107f1a070ff45c8381c3ddf8552c726525104e1eeTheodore Ts'o				uninit = EXT2_EXTENT_SET_BMAP_UNINIT;
462e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
463e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			/*
464e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			 * Get the next extent before we start messing
465e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			 * with the current extent
466e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			 */
467e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			retval = ext2fs_extent_get(handle, op, &next);
468e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
469e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#if 0
470e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			printf("lblk %llu pblk %llu len %d blockcnt %llu\n",
471e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			       extent.e_lblk, extent.e_pblk,
472e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			       extent.e_len, blockcnt);
473e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif
474e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			if (extent.e_lblk + extent.e_len <= (blk64_t) blockcnt)
475e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				continue;
476e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			if (extent.e_lblk > (blk64_t) blockcnt)
477e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				blockcnt = extent.e_lblk;
478e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			j = blockcnt - extent.e_lblk;
479e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			blk += j;
4802d328bb76d2d63bdfdba923b54c28bd686bd8fecTheodore Ts'o			for (blockcnt = extent.e_lblk, j = 0;
4812d328bb76d2d63bdfdba923b54c28bd686bd8fecTheodore Ts'o			     j < extent.e_len;
4822d328bb76d2d63bdfdba923b54c28bd686bd8fecTheodore Ts'o			     blk++, blockcnt++, j++) {
483d7b92206ba7f987a68ba42971c930039729831e1Theodore Ts'o				new_blk = blk;
484d7b92206ba7f987a68ba42971c930039729831e1Theodore Ts'o				r = (*ctx.func)(fs, &new_blk, blockcnt,
485d7b92206ba7f987a68ba42971c930039729831e1Theodore Ts'o						0, 0, priv_data);
486d7b92206ba7f987a68ba42971c930039729831e1Theodore Ts'o				ret |= r;
487206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o				check_for_ro_violation_goto(&ctx, ret,
488e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall							    extent_done);
489d7b92206ba7f987a68ba42971c930039729831e1Theodore Ts'o				if (r & BLOCK_CHANGED) {
490d7b92206ba7f987a68ba42971c930039729831e1Theodore Ts'o					ctx.errcode =
491d7b92206ba7f987a68ba42971c930039729831e1Theodore Ts'o						ext2fs_extent_set_bmap(handle,
492d7b92206ba7f987a68ba42971c930039729831e1Theodore Ts'o						       (blk64_t) blockcnt,
493e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall						       new_blk, uninit);
494d7b92206ba7f987a68ba42971c930039729831e1Theodore Ts'o					if (ctx.errcode)
495e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall						goto extent_done;
496206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o				}
49764987c052c235d60373995d36b5c01291c464b74Theodore Ts'o				if (ret & BLOCK_ABORT)
498e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					goto extent_done;
499e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			}
500e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			if (retval == 0) {
501e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				extent = next;
502e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				op = EXT2_EXTENT_CURRENT;
503beb388a473bc12fa874743a7b9f97ec3094bb9d1Theodore Ts'o			}
504206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o		}
505206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o
506e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	extent_done:
507206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o		ext2fs_extent_free(handle);
508e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ret |= BLOCK_ERROR; /* ctx.errcode is always valid here */
509d7b92206ba7f987a68ba42971c930039729831e1Theodore Ts'o		goto errout;
510206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o	}
511206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o
5121e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	/*
5131e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	 * Iterate over normal data blocks
5141e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	 */
5153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	for (i = 0; i < EXT2_NDIR_BLOCKS ; i++, ctx.bcount++) {
516206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o		if (inode.i_block[i] || (flags & BLOCK_FLAG_APPEND)) {
517e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			blk64 = inode.i_block[i];
518e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			ret |= (*ctx.func)(fs, &blk64, ctx.bcount, 0, i,
519e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					   priv_data);
520e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			inode.i_block[i] = (blk_t) blk64;
5213839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			if (ret & BLOCK_ABORT)
52231dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'o				goto abort_exit;
5233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		}
5243839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
525206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o	check_for_ro_violation_goto(&ctx, ret, abort_exit);
526206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o	if (inode.i_block[EXT2_IND_BLOCK] || (flags & BLOCK_FLAG_APPEND)) {
527e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		ret |= block_iterate_ind(&inode.i_block[EXT2_IND_BLOCK],
52836a43d675ef61d0f5d5b2ad62d2e670c408d14acTheodore Ts'o					 0, EXT2_IND_BLOCK, &ctx);
5293839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		if (ret & BLOCK_ABORT)
53031dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'o			goto abort_exit;
531674a4ee1e3e05133ddad701730bfc21c283272a4Theodore Ts'o	} else
532674a4ee1e3e05133ddad701730bfc21c283272a4Theodore Ts'o		ctx.bcount += limit;
533206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o	if (inode.i_block[EXT2_DIND_BLOCK] || (flags & BLOCK_FLAG_APPEND)) {
534206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o		ret |= block_iterate_dind(&inode.i_block[EXT2_DIND_BLOCK],
53536a43d675ef61d0f5d5b2ad62d2e670c408d14acTheodore Ts'o					  0, EXT2_DIND_BLOCK, &ctx);
5363839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		if (ret & BLOCK_ABORT)
53731dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'o			goto abort_exit;
538674a4ee1e3e05133ddad701730bfc21c283272a4Theodore Ts'o	} else
539674a4ee1e3e05133ddad701730bfc21c283272a4Theodore Ts'o		ctx.bcount += limit * limit;
540206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o	if (inode.i_block[EXT2_TIND_BLOCK] || (flags & BLOCK_FLAG_APPEND)) {
541206fea69f8624843c2ffd32bab171059ec137780Theodore Ts'o		ret |= block_iterate_tind(&inode.i_block[EXT2_TIND_BLOCK],
54236a43d675ef61d0f5d5b2ad62d2e670c408d14acTheodore Ts'o					  0, EXT2_TIND_BLOCK, &ctx);
5431e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o		if (ret & BLOCK_ABORT)
54431dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'o			goto abort_exit;
5451e3472c5f37ca3686dd69b079d4d02a302f5798dTheodore Ts'o	}
5463839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
54731dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'oabort_exit:
5483839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (ret & BLOCK_CHANGED) {
5493839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		retval = ext2fs_write_inode(fs, ino, &inode);
5509922c53a4df10e660a1b425629a1f4db2b4fc03fTheodore Ts'o		if (retval) {
5519922c53a4df10e660a1b425629a1f4db2b4fc03fTheodore Ts'o			ret |= BLOCK_ERROR;
5529922c53a4df10e660a1b425629a1f4db2b4fc03fTheodore Ts'o			ctx.errcode = retval;
5539922c53a4df10e660a1b425629a1f4db2b4fc03fTheodore Ts'o		}
5543839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
555d7b92206ba7f987a68ba42971c930039729831e1Theodore Ts'oerrout:
5563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (!block_buf)
557c4e3d3f374b409500e3dd05c0b0eca6ac98a6b4eTheodore Ts'o		ext2fs_free_mem(&ctx.ind_buf);
5583839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
5593839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return (ret & BLOCK_ERROR) ? ctx.errcode : 0;
5603839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
56121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o
562674a4ee1e3e05133ddad701730bfc21c283272a4Theodore Ts'o/*
563674a4ee1e3e05133ddad701730bfc21c283272a4Theodore Ts'o * Emulate the old ext2fs_block_iterate function!
564674a4ee1e3e05133ddad701730bfc21c283272a4Theodore Ts'o */
565674a4ee1e3e05133ddad701730bfc21c283272a4Theodore Ts'o
566e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstruct xlate64 {
567e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	int (*func)(ext2_filsys fs,
568e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		    blk_t	*blocknr,
569e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		    e2_blkcnt_t	blockcnt,
570e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		    blk_t	ref_blk,
571e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		    int		ref_offset,
572e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		    void	*priv_data);
573e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	void *real_private;
574e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall};
575e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
576e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallstatic int xlate64_func(ext2_filsys fs, blk64_t	*blocknr,
577e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			e2_blkcnt_t blockcnt, blk64_t ref_blk,
578e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			int ref_offset, void *priv_data)
579e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{
580e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	struct xlate64 *xl = (struct xlate64 *) priv_data;
581e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	int		ret;
582e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	blk_t		block32 = *blocknr;
583e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
584e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	ret = (*xl->func)(fs, &block32, blockcnt, (blk_t) ref_blk, ref_offset,
585e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall			     xl->real_private);
586e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	*blocknr = block32;
587e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	return ret;
588e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall}
589e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
590e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallerrcode_t ext2fs_block_iterate2(ext2_filsys fs,
591e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				ext2_ino_t ino,
592e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				int	flags,
593e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				char *block_buf,
594e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				int (*func)(ext2_filsys fs,
595e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					    blk_t	*blocknr,
596e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					    e2_blkcnt_t	blockcnt,
597e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					    blk_t	ref_blk,
598e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					    int		ref_offset,
599e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall					    void	*priv_data),
600e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				void *priv_data)
601e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{
602e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	struct xlate64 xl;
603e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
604e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	xl.real_private = priv_data;
605e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	xl.func = func;
606e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
607e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall	return ext2fs_block_iterate3(fs, ino, flags, block_buf,
608e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall				     xlate64_func, &xl);
609e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall}
610e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
611e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall
61221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'ostruct xlate {
61321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	int (*func)(ext2_filsys	fs,
61421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o		    blk_t	*blocknr,
61521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o		    int		bcount,
616b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o		    void	*priv_data);
61721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	void *real_private;
61821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o};
61921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o
6203cb6c5021d722e17b7105d1bc090880671f6fc6dTheodore Ts'o#ifdef __TURBOC__
62131dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'o #pragma argsused
6223cb6c5021d722e17b7105d1bc090880671f6fc6dTheodore Ts'o#endif
62303673dbb04a3458ce78a394f27d17d434b51a714Theodore Ts'ostatic int xlate_func(ext2_filsys fs, blk_t *blocknr, e2_blkcnt_t blockcnt,
624544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		      blk_t ref_block EXT2FS_ATTR((unused)),
625544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		      int ref_offset EXT2FS_ATTR((unused)),
626544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o		      void *priv_data)
62721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o{
628b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o	struct xlate *xl = (struct xlate *) priv_data;
62921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o
630674a4ee1e3e05133ddad701730bfc21c283272a4Theodore Ts'o	return (*xl->func)(fs, blocknr, (int) blockcnt, xl->real_private);
63121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o}
63221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o
63321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'oerrcode_t ext2fs_block_iterate(ext2_filsys fs,
63431dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'o			       ext2_ino_t ino,
63521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o			       int	flags,
63621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o			       char *block_buf,
63721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o			       int (*func)(ext2_filsys fs,
63821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o					   blk_t	*blocknr,
63921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o					   int	blockcnt,
640b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o					   void	*priv_data),
641b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o			       void *priv_data)
64221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o{
64321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	struct xlate xl;
644efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
645b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o	xl.real_private = priv_data;
64621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o	xl.func = func;
64721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o
64836a43d675ef61d0f5d5b2ad62d2e670c408d14acTheodore Ts'o	return ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_NO_LARGE | flags,
649674a4ee1e3e05133ddad701730bfc21c283272a4Theodore Ts'o				     block_buf, xlate_func, &xl);
650674a4ee1e3e05133ddad701730bfc21c283272a4Theodore Ts'o}
651674a4ee1e3e05133ddad701730bfc21c283272a4Theodore Ts'o
652