bmap.c revision 31dbecd482405e0d3a67eb58e1a1c8cb9f2ad83e
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#if EXT2_FLAT_INCLUDES 19b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o#include "ext2_fs.h" 20b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o#else 2130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o#include <linux/ext2_fs.h> 22b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o#endif 2330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 2430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o#include "ext2fs.h" 2530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 2678d8f90ffae45808096133c461ef1ee0e65de937Theodore Ts'o#if defined(__GNUC__) && !defined(NO_INLINE_FUNCS) 2730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o#define _BMAP_INLINE_ __inline__ 2830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o#else 2930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o#define _BMAP_INLINE_ 3030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o#endif 3130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 3231dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'oextern errcode_t ext2fs_bmap(ext2_filsys fs, ext2_ino_t ino, 3330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o struct ext2_inode *inode, 3430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o char *block_buf, int bmap_flags, 3530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blk_t block, blk_t *phys_blk); 3630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 3730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o#define BMAP_ALLOC 1 3830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 3930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o#define inode_bmap(inode, nr) ((inode)->i_block[(nr)]) 4030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 4130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'ostatic errcode_t _BMAP_INLINE_ block_ind_bmap(ext2_filsys fs, int flags, 4230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blk_t ind, char *block_buf, 4330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o int *blocks_alloc, 4430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blk_t nr, blk_t *ret_blk) 4530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o{ 4630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o errcode_t retval; 4730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blk_t b; 4830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 4930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (!ind) { 5030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o *ret_blk = 0; 5130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o return 0; 5230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o } 5330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = io_channel_read_blk(fs->io, ind, 1, block_buf); 5430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (retval) 5530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o return retval; 5630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 5730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o b = ((blk_t *) block_buf)[nr]; 5830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 5930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if ((fs->flags & EXT2_FLAG_SWAP_BYTES) || 6030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)) 6130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o b = ext2fs_swab32(b); 6230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 6330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (!b && (flags & BMAP_ALLOC)) { 6430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o b = nr ? ((blk_t *) block_buf)[nr-1] : 0; 6530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = ext2fs_alloc_block(fs, b, 6630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o block_buf + fs->blocksize, &b); 6730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (retval) 6830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o return retval; 6930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 7030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if ((fs->flags & EXT2_FLAG_SWAP_BYTES) || 7130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)) 7230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o ((blk_t *) block_buf)[nr] = ext2fs_swab32(b); 7330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o else 7430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o ((blk_t *) block_buf)[nr] = b; 7530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 7630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = io_channel_write_blk(fs->io, ind, 1, block_buf); 7730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (retval) 7830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o return retval; 7930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 8030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o (*blocks_alloc)++; 8130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o } 8230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 8330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o *ret_blk = b; 8430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o return 0; 8530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o} 8630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 8730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'ostatic errcode_t _BMAP_INLINE_ block_dind_bmap(ext2_filsys fs, int flags, 8830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blk_t dind, char *block_buf, 8930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o int *blocks_alloc, 9030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blk_t nr, blk_t *ret_blk) 9130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o{ 9230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blk_t b; 9330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o errcode_t retval; 942eb374c9401079aa56aa12f0047ca3866e69b754Theodore Ts'o blk_t addr_per_block; 9530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 962eb374c9401079aa56aa12f0047ca3866e69b754Theodore Ts'o addr_per_block = (blk_t) fs->blocksize >> 2; 9730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 9830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = block_ind_bmap(fs, flags, dind, block_buf, blocks_alloc, 9930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o nr / addr_per_block, &b); 10030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (retval) 10130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o return retval; 10230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = block_ind_bmap(fs, flags, b, block_buf, blocks_alloc, 10330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o nr % addr_per_block, ret_blk); 10430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o return retval; 10530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o} 10630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 10730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'ostatic errcode_t _BMAP_INLINE_ block_tind_bmap(ext2_filsys fs, int flags, 10830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blk_t tind, char *block_buf, 10930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o int *blocks_alloc, 11030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blk_t nr, blk_t *ret_blk) 11130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o{ 11230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blk_t b; 11330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o errcode_t retval; 1142eb374c9401079aa56aa12f0047ca3866e69b754Theodore Ts'o blk_t addr_per_block; 11530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 1162eb374c9401079aa56aa12f0047ca3866e69b754Theodore Ts'o addr_per_block = (blk_t) fs->blocksize >> 2; 11730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 11830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = block_dind_bmap(fs, flags, tind, block_buf, blocks_alloc, 11930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o nr / addr_per_block, &b); 12030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (retval) 12130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o return retval; 12230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = block_ind_bmap(fs, flags, b, block_buf, blocks_alloc, 12330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o nr % addr_per_block, ret_blk); 12430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o return retval; 12530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o} 12630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 12731dbecd482405e0d3a67eb58e1a1c8cb9f2ad83eTheodore Ts'oerrcode_t ext2fs_bmap(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode, 12830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o char *block_buf, int bmap_flags, blk_t block, 12930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blk_t *phys_blk) 13030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o{ 13130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o struct ext2_inode inode_buf; 1322eb374c9401079aa56aa12f0047ca3866e69b754Theodore Ts'o blk_t addr_per_block; 13330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blk_t b; 13430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o char *buf = 0; 13530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o errcode_t retval = 0; 13630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o int blocks_alloc = 0; 13730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 13830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o *phys_blk = 0; 13930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 14030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o /* Read inode structure if necessary */ 14130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (!inode) { 14230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = ext2fs_read_inode(fs, ino, &inode_buf); 14330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (!retval) 14430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o return retval; 14530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o inode = &inode_buf; 14630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o } 1472eb374c9401079aa56aa12f0047ca3866e69b754Theodore Ts'o addr_per_block = (blk_t) fs->blocksize >> 2; 14830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 14930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (!block_buf) { 1507b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o retval = ext2fs_get_mem(fs->blocksize * 2, (void **) &buf); 1517b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o if (retval) 1527b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o return retval; 15330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o block_buf = buf; 15430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o } 15530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 15630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (block < EXT2_NDIR_BLOCKS) { 15730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o *phys_blk = inode_bmap(inode, block); 15830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o b = block ? inode_bmap(inode, block-1) : 0; 15930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 16030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if ((*phys_blk == 0) && (bmap_flags & BMAP_ALLOC)) { 16130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = ext2fs_alloc_block(fs, b, block_buf, &b); 16230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (retval) 16330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o goto done; 16430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o inode_bmap(inode, block) = b; 16530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blocks_alloc++; 16630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o *phys_blk = b; 16730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o } 16830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o goto done; 16930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o } 17030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 17130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o /* Indirect block */ 17230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o block -= EXT2_NDIR_BLOCKS; 17330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (block < addr_per_block) { 17430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o b = inode_bmap(inode, EXT2_IND_BLOCK); 17530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (!b) { 17630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (!(bmap_flags & BMAP_ALLOC)) 17730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o goto done; 17830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 17930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o b = inode_bmap(inode, EXT2_IND_BLOCK-1); 18030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = ext2fs_alloc_block(fs, b, block_buf, &b); 18130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (retval) 18230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o goto done; 18330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o inode_bmap(inode, EXT2_IND_BLOCK) = b; 18430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blocks_alloc++; 18530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o } 18630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = block_ind_bmap(fs, bmap_flags, b, block_buf, 18730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o &blocks_alloc, block, phys_blk); 18830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o goto done; 18930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o } 19030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 19130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o /* Doubly indirect block */ 19230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o block -= addr_per_block; 19330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (block < addr_per_block * addr_per_block) { 19430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o b = inode_bmap(inode, EXT2_DIND_BLOCK); 19530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (!b) { 19630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (!(bmap_flags & BMAP_ALLOC)) 19730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o goto done; 19830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 19930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o b = inode_bmap(inode, EXT2_IND_BLOCK); 20030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = ext2fs_alloc_block(fs, b, block_buf, &b); 20130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (retval) 20230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o goto done; 20330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o inode_bmap(inode, EXT2_DIND_BLOCK) = b; 20430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blocks_alloc++; 20530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o } 20630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = block_dind_bmap(fs, bmap_flags, b, block_buf, 20730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o &blocks_alloc, block, phys_blk); 20830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o goto done; 20930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o } 21030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 21130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o /* Triply indirect block */ 21230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o block -= addr_per_block * addr_per_block; 21330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o b = inode_bmap(inode, EXT2_TIND_BLOCK); 21430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (!b) { 21530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (!(bmap_flags & BMAP_ALLOC)) 21630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o goto done; 21730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 21830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o b = inode_bmap(inode, EXT2_DIND_BLOCK); 21930fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = ext2fs_alloc_block(fs, b, block_buf, &b); 22030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (retval) 22130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o goto done; 22230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o inode_bmap(inode, EXT2_TIND_BLOCK) = b; 22330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o blocks_alloc++; 22430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o } 22530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = block_tind_bmap(fs, bmap_flags, b, block_buf, 22630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o &blocks_alloc, block, phys_blk); 22730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'odone: 22830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if (buf) 2297b4e4534f9361b21d3fafdd88a58f133decee38cTheodore Ts'o ext2fs_free_mem((void **) &buf); 23030fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o if ((retval == 0) && blocks_alloc) { 23130fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o inode->i_blocks += (blocks_alloc * fs->blocksize) / 512; 23230fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o retval = ext2fs_write_inode(fs, ino, inode); 23330fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o } 23430fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o return retval; 23530fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o} 23630fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 23730fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 23830fab293065b7fc6d7d138e8e9eea533a3560873Theodore Ts'o 239