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