bmap.c revision 5df55d7f847e29d23227592a0bb23daad1a61500
130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o/* 280e808fceb61c2061b32593c610893bf07a863eeTheodore Ts'o * bmap.c --- logical to physical block mapping 330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o * 430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o * Copyright (C) 1997 Theodore Ts'o. 530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o * 630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o * %Begin-Header% 730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o * This file may be redistributed under the terms of the GNU Public 830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o * License. 930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o * %End-Header% 1030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o */ 1130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 1230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o#include <stdio.h> 1330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o#include <string.h> 1430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o#if HAVE_UNISTD_H 1530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o#include <unistd.h> 1630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o#endif 1730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 18b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o#include "ext2_fs.h" 1930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o#include "ext2fs.h" 2030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 2178d8f90ffae45808096133c461ef1ee0e65de937Theodore Ts'o#if defined(__GNUC__) && !defined(NO_INLINE_FUNCS) 2230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o#define _BMAP_INLINE_ __inline__ 2330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o#else 2430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o#define _BMAP_INLINE_ 2530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o#endif 2630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 2731dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'oextern errcode_t ext2fs_bmap(ext2_filsys fs, ext2_ino_t ino, 2830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o struct ext2_inode *inode, 2930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o char *block_buf, int bmap_flags, 3030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blk_t block, blk_t *phys_blk); 3130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 3230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o#define BMAP_ALLOC 1 3330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 3430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o#define inode_bmap(inode, nr) ((inode)->i_block[(nr)]) 3530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 3630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'ostatic errcode_t _BMAP_INLINE_ block_ind_bmap(ext2_filsys fs, int flags, 3730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blk_t ind, char *block_buf, 3830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o int *blocks_alloc, 3930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blk_t nr, blk_t *ret_blk) 4030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o{ 4130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o errcode_t retval; 4230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blk_t b; 4330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 4430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (!ind) { 4530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o *ret_blk = 0; 4630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o return 0; 4730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o } 4830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = io_channel_read_blk(fs->io, ind, 1, block_buf); 4930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (retval) 5030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o return retval; 5130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 5230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o b = ((blk_t *) block_buf)[nr]; 5330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 545df55d7f847e29d23227592a0bb23daad1a61500Theodore Ts'o#ifdef EXT2FS_ENABLE_SWAPFS 5530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if ((fs->flags & EXT2_FLAG_SWAP_BYTES) || 5630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)) 5730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o b = ext2fs_swab32(b); 585df55d7f847e29d23227592a0bb23daad1a61500Theodore Ts'o#endif 5930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 6030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (!b && (flags & BMAP_ALLOC)) { 6130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o b = nr ? ((blk_t *) block_buf)[nr-1] : 0; 6230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = ext2fs_alloc_block(fs, b, 6330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o block_buf + fs->blocksize, &b); 6430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (retval) 6530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o return retval; 6630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 675df55d7f847e29d23227592a0bb23daad1a61500Theodore Ts'o#ifdef EXT2FS_ENABLE_SWAPFS 6830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if ((fs->flags & EXT2_FLAG_SWAP_BYTES) || 6930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)) 7030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o ((blk_t *) block_buf)[nr] = ext2fs_swab32(b); 7130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o else 725df55d7f847e29d23227592a0bb23daad1a61500Theodore Ts'o#endif 7330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o ((blk_t *) block_buf)[nr] = b; 7430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 7530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = io_channel_write_blk(fs->io, ind, 1, block_buf); 7630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (retval) 7730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o return retval; 7830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 7930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o (*blocks_alloc)++; 8030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o } 8130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 8230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o *ret_blk = b; 8330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o return 0; 8430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o} 8530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 8630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'ostatic errcode_t _BMAP_INLINE_ block_dind_bmap(ext2_filsys fs, int flags, 8730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blk_t dind, char *block_buf, 8830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o int *blocks_alloc, 8930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blk_t nr, blk_t *ret_blk) 9030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o{ 9130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blk_t b; 9230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o errcode_t retval; 932eb374c9401079aa56aa12f0047ca3866e69b754Theodore Ts'o blk_t addr_per_block; 9430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 952eb374c9401079aa56aa12f0047ca3866e69b754Theodore Ts'o addr_per_block = (blk_t) fs->blocksize >> 2; 9630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 9730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = block_ind_bmap(fs, flags, dind, block_buf, blocks_alloc, 9830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o nr / addr_per_block, &b); 9930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (retval) 10030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o return retval; 10130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = block_ind_bmap(fs, flags, b, block_buf, blocks_alloc, 10230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o nr % addr_per_block, ret_blk); 10330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o return retval; 10430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o} 10530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 10630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'ostatic errcode_t _BMAP_INLINE_ block_tind_bmap(ext2_filsys fs, int flags, 10730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blk_t tind, char *block_buf, 10830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o int *blocks_alloc, 10930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blk_t nr, blk_t *ret_blk) 11030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o{ 11130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blk_t b; 11230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o errcode_t retval; 1132eb374c9401079aa56aa12f0047ca3866e69b754Theodore Ts'o blk_t addr_per_block; 11430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 1152eb374c9401079aa56aa12f0047ca3866e69b754Theodore Ts'o addr_per_block = (blk_t) fs->blocksize >> 2; 11630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 11730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = block_dind_bmap(fs, flags, tind, block_buf, blocks_alloc, 11830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o nr / addr_per_block, &b); 11930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (retval) 12030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o return retval; 12130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = block_ind_bmap(fs, flags, b, block_buf, blocks_alloc, 12230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o nr % addr_per_block, ret_blk); 12330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o return retval; 12430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o} 12530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 12631dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'oerrcode_t ext2fs_bmap(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode, 12730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o char *block_buf, int bmap_flags, blk_t block, 12830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blk_t *phys_blk) 12930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o{ 13030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o struct ext2_inode inode_buf; 1312eb374c9401079aa56aa12f0047ca3866e69b754Theodore Ts'o blk_t addr_per_block; 13230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blk_t b; 13330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o char *buf = 0; 13430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o errcode_t retval = 0; 13530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o int blocks_alloc = 0; 13630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 13730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o *phys_blk = 0; 13830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 13930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o /* Read inode structure if necessary */ 14030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (!inode) { 14130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = ext2fs_read_inode(fs, ino, &inode_buf); 14230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (!retval) 14330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o return retval; 14430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o inode = &inode_buf; 14530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o } 1462eb374c9401079aa56aa12f0047ca3866e69b754Theodore Ts'o addr_per_block = (blk_t) fs->blocksize >> 2; 14730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 14830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (!block_buf) { 1497b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o retval = ext2fs_get_mem(fs->blocksize * 2, (void **) &buf); 1507b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o if (retval) 1517b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o return retval; 15230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o block_buf = buf; 15330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o } 15430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 15530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (block < EXT2_NDIR_BLOCKS) { 15630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o *phys_blk = inode_bmap(inode, block); 15730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o b = block ? inode_bmap(inode, block-1) : 0; 15830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 15930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if ((*phys_blk == 0) && (bmap_flags & BMAP_ALLOC)) { 16030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = ext2fs_alloc_block(fs, b, block_buf, &b); 16130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (retval) 16230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o goto done; 16330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o inode_bmap(inode, block) = b; 16430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blocks_alloc++; 16530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o *phys_blk = b; 16630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o } 16730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o goto done; 16830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o } 16930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 17030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o /* Indirect block */ 17130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o block -= EXT2_NDIR_BLOCKS; 17230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (block < addr_per_block) { 17330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o b = inode_bmap(inode, EXT2_IND_BLOCK); 17430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (!b) { 17530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (!(bmap_flags & BMAP_ALLOC)) 17630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o goto done; 17730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 17830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o b = inode_bmap(inode, EXT2_IND_BLOCK-1); 17930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = ext2fs_alloc_block(fs, b, block_buf, &b); 18030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (retval) 18130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o goto done; 18230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o inode_bmap(inode, EXT2_IND_BLOCK) = b; 18330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blocks_alloc++; 18430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o } 18530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = block_ind_bmap(fs, bmap_flags, b, block_buf, 18630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o &blocks_alloc, block, phys_blk); 18730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o goto done; 18830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o } 18930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 19030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o /* Doubly indirect block */ 19130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o block -= addr_per_block; 19230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (block < addr_per_block * addr_per_block) { 19330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o b = inode_bmap(inode, EXT2_DIND_BLOCK); 19430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (!b) { 19530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (!(bmap_flags & BMAP_ALLOC)) 19630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o goto done; 19730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 19830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o b = inode_bmap(inode, EXT2_IND_BLOCK); 19930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = ext2fs_alloc_block(fs, b, block_buf, &b); 20030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (retval) 20130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o goto done; 20230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o inode_bmap(inode, EXT2_DIND_BLOCK) = b; 20330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blocks_alloc++; 20430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o } 20530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = block_dind_bmap(fs, bmap_flags, b, block_buf, 20630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o &blocks_alloc, block, phys_blk); 20730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o goto done; 20830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o } 20930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 21030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o /* Triply indirect block */ 21130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o block -= addr_per_block * addr_per_block; 21230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o b = inode_bmap(inode, EXT2_TIND_BLOCK); 21330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (!b) { 21430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (!(bmap_flags & BMAP_ALLOC)) 21530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o goto done; 21630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 21730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o b = inode_bmap(inode, EXT2_DIND_BLOCK); 21830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = ext2fs_alloc_block(fs, b, block_buf, &b); 21930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (retval) 22030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o goto done; 22130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o inode_bmap(inode, EXT2_TIND_BLOCK) = b; 22230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blocks_alloc++; 22330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o } 22430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = block_tind_bmap(fs, bmap_flags, b, block_buf, 22530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o &blocks_alloc, block, phys_blk); 22630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'odone: 22730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (buf) 2287b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o ext2fs_free_mem((void **) &buf); 22930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if ((retval == 0) && blocks_alloc) { 23030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o inode->i_blocks += (blocks_alloc * fs->blocksize) / 512; 23130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = ext2fs_write_inode(fs, ino, inode); 23230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o } 23330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o return retval; 23430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o} 23530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 23630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 23730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 238