162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * linux/fs/ext4/indirect.c 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * from 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * linux/fs/ext4/inode.c 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * Copyright (C) 1992, 1993, 1994, 1995 1062306a36Sopenharmony_ci * Remy Card (card@masi.ibp.fr) 1162306a36Sopenharmony_ci * Laboratoire MASI - Institut Blaise Pascal 1262306a36Sopenharmony_ci * Universite Pierre et Marie Curie (Paris VI) 1362306a36Sopenharmony_ci * 1462306a36Sopenharmony_ci * from 1562306a36Sopenharmony_ci * 1662306a36Sopenharmony_ci * linux/fs/minix/inode.c 1762306a36Sopenharmony_ci * 1862306a36Sopenharmony_ci * Copyright (C) 1991, 1992 Linus Torvalds 1962306a36Sopenharmony_ci * 2062306a36Sopenharmony_ci * Goal-directed block allocation by Stephen Tweedie 2162306a36Sopenharmony_ci * (sct@redhat.com), 1993, 1998 2262306a36Sopenharmony_ci */ 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci#include "ext4_jbd2.h" 2562306a36Sopenharmony_ci#include "truncate.h" 2662306a36Sopenharmony_ci#include <linux/dax.h> 2762306a36Sopenharmony_ci#include <linux/uio.h> 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci#include <trace/events/ext4.h> 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_citypedef struct { 3262306a36Sopenharmony_ci __le32 *p; 3362306a36Sopenharmony_ci __le32 key; 3462306a36Sopenharmony_ci struct buffer_head *bh; 3562306a36Sopenharmony_ci} Indirect; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_cistatic inline void add_chain(Indirect *p, struct buffer_head *bh, __le32 *v) 3862306a36Sopenharmony_ci{ 3962306a36Sopenharmony_ci p->key = *(p->p = v); 4062306a36Sopenharmony_ci p->bh = bh; 4162306a36Sopenharmony_ci} 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci/** 4462306a36Sopenharmony_ci * ext4_block_to_path - parse the block number into array of offsets 4562306a36Sopenharmony_ci * @inode: inode in question (we are only interested in its superblock) 4662306a36Sopenharmony_ci * @i_block: block number to be parsed 4762306a36Sopenharmony_ci * @offsets: array to store the offsets in 4862306a36Sopenharmony_ci * @boundary: set this non-zero if the referred-to block is likely to be 4962306a36Sopenharmony_ci * followed (on disk) by an indirect block. 5062306a36Sopenharmony_ci * 5162306a36Sopenharmony_ci * To store the locations of file's data ext4 uses a data structure common 5262306a36Sopenharmony_ci * for UNIX filesystems - tree of pointers anchored in the inode, with 5362306a36Sopenharmony_ci * data blocks at leaves and indirect blocks in intermediate nodes. 5462306a36Sopenharmony_ci * This function translates the block number into path in that tree - 5562306a36Sopenharmony_ci * return value is the path length and @offsets[n] is the offset of 5662306a36Sopenharmony_ci * pointer to (n+1)th node in the nth one. If @block is out of range 5762306a36Sopenharmony_ci * (negative or too large) warning is printed and zero returned. 5862306a36Sopenharmony_ci * 5962306a36Sopenharmony_ci * Note: function doesn't find node addresses, so no IO is needed. All 6062306a36Sopenharmony_ci * we need to know is the capacity of indirect blocks (taken from the 6162306a36Sopenharmony_ci * inode->i_sb). 6262306a36Sopenharmony_ci */ 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci/* 6562306a36Sopenharmony_ci * Portability note: the last comparison (check that we fit into triple 6662306a36Sopenharmony_ci * indirect block) is spelled differently, because otherwise on an 6762306a36Sopenharmony_ci * architecture with 32-bit longs and 8Kb pages we might get into trouble 6862306a36Sopenharmony_ci * if our filesystem had 8Kb blocks. We might use long long, but that would 6962306a36Sopenharmony_ci * kill us on x86. Oh, well, at least the sign propagation does not matter - 7062306a36Sopenharmony_ci * i_block would have to be negative in the very beginning, so we would not 7162306a36Sopenharmony_ci * get there at all. 7262306a36Sopenharmony_ci */ 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_cistatic int ext4_block_to_path(struct inode *inode, 7562306a36Sopenharmony_ci ext4_lblk_t i_block, 7662306a36Sopenharmony_ci ext4_lblk_t offsets[4], int *boundary) 7762306a36Sopenharmony_ci{ 7862306a36Sopenharmony_ci int ptrs = EXT4_ADDR_PER_BLOCK(inode->i_sb); 7962306a36Sopenharmony_ci int ptrs_bits = EXT4_ADDR_PER_BLOCK_BITS(inode->i_sb); 8062306a36Sopenharmony_ci const long direct_blocks = EXT4_NDIR_BLOCKS, 8162306a36Sopenharmony_ci indirect_blocks = ptrs, 8262306a36Sopenharmony_ci double_blocks = (1 << (ptrs_bits * 2)); 8362306a36Sopenharmony_ci int n = 0; 8462306a36Sopenharmony_ci int final = 0; 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci if (i_block < direct_blocks) { 8762306a36Sopenharmony_ci offsets[n++] = i_block; 8862306a36Sopenharmony_ci final = direct_blocks; 8962306a36Sopenharmony_ci } else if ((i_block -= direct_blocks) < indirect_blocks) { 9062306a36Sopenharmony_ci offsets[n++] = EXT4_IND_BLOCK; 9162306a36Sopenharmony_ci offsets[n++] = i_block; 9262306a36Sopenharmony_ci final = ptrs; 9362306a36Sopenharmony_ci } else if ((i_block -= indirect_blocks) < double_blocks) { 9462306a36Sopenharmony_ci offsets[n++] = EXT4_DIND_BLOCK; 9562306a36Sopenharmony_ci offsets[n++] = i_block >> ptrs_bits; 9662306a36Sopenharmony_ci offsets[n++] = i_block & (ptrs - 1); 9762306a36Sopenharmony_ci final = ptrs; 9862306a36Sopenharmony_ci } else if (((i_block -= double_blocks) >> (ptrs_bits * 2)) < ptrs) { 9962306a36Sopenharmony_ci offsets[n++] = EXT4_TIND_BLOCK; 10062306a36Sopenharmony_ci offsets[n++] = i_block >> (ptrs_bits * 2); 10162306a36Sopenharmony_ci offsets[n++] = (i_block >> ptrs_bits) & (ptrs - 1); 10262306a36Sopenharmony_ci offsets[n++] = i_block & (ptrs - 1); 10362306a36Sopenharmony_ci final = ptrs; 10462306a36Sopenharmony_ci } else { 10562306a36Sopenharmony_ci ext4_warning(inode->i_sb, "block %lu > max in inode %lu", 10662306a36Sopenharmony_ci i_block + direct_blocks + 10762306a36Sopenharmony_ci indirect_blocks + double_blocks, inode->i_ino); 10862306a36Sopenharmony_ci } 10962306a36Sopenharmony_ci if (boundary) 11062306a36Sopenharmony_ci *boundary = final - 1 - (i_block & (ptrs - 1)); 11162306a36Sopenharmony_ci return n; 11262306a36Sopenharmony_ci} 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci/** 11562306a36Sopenharmony_ci * ext4_get_branch - read the chain of indirect blocks leading to data 11662306a36Sopenharmony_ci * @inode: inode in question 11762306a36Sopenharmony_ci * @depth: depth of the chain (1 - direct pointer, etc.) 11862306a36Sopenharmony_ci * @offsets: offsets of pointers in inode/indirect blocks 11962306a36Sopenharmony_ci * @chain: place to store the result 12062306a36Sopenharmony_ci * @err: here we store the error value 12162306a36Sopenharmony_ci * 12262306a36Sopenharmony_ci * Function fills the array of triples <key, p, bh> and returns %NULL 12362306a36Sopenharmony_ci * if everything went OK or the pointer to the last filled triple 12462306a36Sopenharmony_ci * (incomplete one) otherwise. Upon the return chain[i].key contains 12562306a36Sopenharmony_ci * the number of (i+1)-th block in the chain (as it is stored in memory, 12662306a36Sopenharmony_ci * i.e. little-endian 32-bit), chain[i].p contains the address of that 12762306a36Sopenharmony_ci * number (it points into struct inode for i==0 and into the bh->b_data 12862306a36Sopenharmony_ci * for i>0) and chain[i].bh points to the buffer_head of i-th indirect 12962306a36Sopenharmony_ci * block for i>0 and NULL for i==0. In other words, it holds the block 13062306a36Sopenharmony_ci * numbers of the chain, addresses they were taken from (and where we can 13162306a36Sopenharmony_ci * verify that chain did not change) and buffer_heads hosting these 13262306a36Sopenharmony_ci * numbers. 13362306a36Sopenharmony_ci * 13462306a36Sopenharmony_ci * Function stops when it stumbles upon zero pointer (absent block) 13562306a36Sopenharmony_ci * (pointer to last triple returned, *@err == 0) 13662306a36Sopenharmony_ci * or when it gets an IO error reading an indirect block 13762306a36Sopenharmony_ci * (ditto, *@err == -EIO) 13862306a36Sopenharmony_ci * or when it reads all @depth-1 indirect blocks successfully and finds 13962306a36Sopenharmony_ci * the whole chain, all way to the data (returns %NULL, *err == 0). 14062306a36Sopenharmony_ci * 14162306a36Sopenharmony_ci * Need to be called with 14262306a36Sopenharmony_ci * down_read(&EXT4_I(inode)->i_data_sem) 14362306a36Sopenharmony_ci */ 14462306a36Sopenharmony_cistatic Indirect *ext4_get_branch(struct inode *inode, int depth, 14562306a36Sopenharmony_ci ext4_lblk_t *offsets, 14662306a36Sopenharmony_ci Indirect chain[4], int *err) 14762306a36Sopenharmony_ci{ 14862306a36Sopenharmony_ci struct super_block *sb = inode->i_sb; 14962306a36Sopenharmony_ci Indirect *p = chain; 15062306a36Sopenharmony_ci struct buffer_head *bh; 15162306a36Sopenharmony_ci unsigned int key; 15262306a36Sopenharmony_ci int ret = -EIO; 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci *err = 0; 15562306a36Sopenharmony_ci /* i_data is not going away, no lock needed */ 15662306a36Sopenharmony_ci add_chain(chain, NULL, EXT4_I(inode)->i_data + *offsets); 15762306a36Sopenharmony_ci if (!p->key) 15862306a36Sopenharmony_ci goto no_block; 15962306a36Sopenharmony_ci while (--depth) { 16062306a36Sopenharmony_ci key = le32_to_cpu(p->key); 16162306a36Sopenharmony_ci if (key > ext4_blocks_count(EXT4_SB(sb)->s_es)) { 16262306a36Sopenharmony_ci /* the block was out of range */ 16362306a36Sopenharmony_ci ret = -EFSCORRUPTED; 16462306a36Sopenharmony_ci goto failure; 16562306a36Sopenharmony_ci } 16662306a36Sopenharmony_ci bh = sb_getblk(sb, key); 16762306a36Sopenharmony_ci if (unlikely(!bh)) { 16862306a36Sopenharmony_ci ret = -ENOMEM; 16962306a36Sopenharmony_ci goto failure; 17062306a36Sopenharmony_ci } 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci if (!bh_uptodate_or_lock(bh)) { 17362306a36Sopenharmony_ci if (ext4_read_bh(bh, 0, NULL) < 0) { 17462306a36Sopenharmony_ci put_bh(bh); 17562306a36Sopenharmony_ci goto failure; 17662306a36Sopenharmony_ci } 17762306a36Sopenharmony_ci /* validate block references */ 17862306a36Sopenharmony_ci if (ext4_check_indirect_blockref(inode, bh)) { 17962306a36Sopenharmony_ci put_bh(bh); 18062306a36Sopenharmony_ci goto failure; 18162306a36Sopenharmony_ci } 18262306a36Sopenharmony_ci } 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci add_chain(++p, bh, (__le32 *)bh->b_data + *++offsets); 18562306a36Sopenharmony_ci /* Reader: end */ 18662306a36Sopenharmony_ci if (!p->key) 18762306a36Sopenharmony_ci goto no_block; 18862306a36Sopenharmony_ci } 18962306a36Sopenharmony_ci return NULL; 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_cifailure: 19262306a36Sopenharmony_ci *err = ret; 19362306a36Sopenharmony_cino_block: 19462306a36Sopenharmony_ci return p; 19562306a36Sopenharmony_ci} 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci/** 19862306a36Sopenharmony_ci * ext4_find_near - find a place for allocation with sufficient locality 19962306a36Sopenharmony_ci * @inode: owner 20062306a36Sopenharmony_ci * @ind: descriptor of indirect block. 20162306a36Sopenharmony_ci * 20262306a36Sopenharmony_ci * This function returns the preferred place for block allocation. 20362306a36Sopenharmony_ci * It is used when heuristic for sequential allocation fails. 20462306a36Sopenharmony_ci * Rules are: 20562306a36Sopenharmony_ci * + if there is a block to the left of our position - allocate near it. 20662306a36Sopenharmony_ci * + if pointer will live in indirect block - allocate near that block. 20762306a36Sopenharmony_ci * + if pointer will live in inode - allocate in the same 20862306a36Sopenharmony_ci * cylinder group. 20962306a36Sopenharmony_ci * 21062306a36Sopenharmony_ci * In the latter case we colour the starting block by the callers PID to 21162306a36Sopenharmony_ci * prevent it from clashing with concurrent allocations for a different inode 21262306a36Sopenharmony_ci * in the same block group. The PID is used here so that functionally related 21362306a36Sopenharmony_ci * files will be close-by on-disk. 21462306a36Sopenharmony_ci * 21562306a36Sopenharmony_ci * Caller must make sure that @ind is valid and will stay that way. 21662306a36Sopenharmony_ci */ 21762306a36Sopenharmony_cistatic ext4_fsblk_t ext4_find_near(struct inode *inode, Indirect *ind) 21862306a36Sopenharmony_ci{ 21962306a36Sopenharmony_ci struct ext4_inode_info *ei = EXT4_I(inode); 22062306a36Sopenharmony_ci __le32 *start = ind->bh ? (__le32 *) ind->bh->b_data : ei->i_data; 22162306a36Sopenharmony_ci __le32 *p; 22262306a36Sopenharmony_ci 22362306a36Sopenharmony_ci /* Try to find previous block */ 22462306a36Sopenharmony_ci for (p = ind->p - 1; p >= start; p--) { 22562306a36Sopenharmony_ci if (*p) 22662306a36Sopenharmony_ci return le32_to_cpu(*p); 22762306a36Sopenharmony_ci } 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci /* No such thing, so let's try location of indirect block */ 23062306a36Sopenharmony_ci if (ind->bh) 23162306a36Sopenharmony_ci return ind->bh->b_blocknr; 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_ci /* 23462306a36Sopenharmony_ci * It is going to be referred to from the inode itself? OK, just put it 23562306a36Sopenharmony_ci * into the same cylinder group then. 23662306a36Sopenharmony_ci */ 23762306a36Sopenharmony_ci return ext4_inode_to_goal_block(inode); 23862306a36Sopenharmony_ci} 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci/** 24162306a36Sopenharmony_ci * ext4_find_goal - find a preferred place for allocation. 24262306a36Sopenharmony_ci * @inode: owner 24362306a36Sopenharmony_ci * @block: block we want 24462306a36Sopenharmony_ci * @partial: pointer to the last triple within a chain 24562306a36Sopenharmony_ci * 24662306a36Sopenharmony_ci * Normally this function find the preferred place for block allocation, 24762306a36Sopenharmony_ci * returns it. 24862306a36Sopenharmony_ci * Because this is only used for non-extent files, we limit the block nr 24962306a36Sopenharmony_ci * to 32 bits. 25062306a36Sopenharmony_ci */ 25162306a36Sopenharmony_cistatic ext4_fsblk_t ext4_find_goal(struct inode *inode, ext4_lblk_t block, 25262306a36Sopenharmony_ci Indirect *partial) 25362306a36Sopenharmony_ci{ 25462306a36Sopenharmony_ci ext4_fsblk_t goal; 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci /* 25762306a36Sopenharmony_ci * XXX need to get goal block from mballoc's data structures 25862306a36Sopenharmony_ci */ 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci goal = ext4_find_near(inode, partial); 26162306a36Sopenharmony_ci goal = goal & EXT4_MAX_BLOCK_FILE_PHYS; 26262306a36Sopenharmony_ci return goal; 26362306a36Sopenharmony_ci} 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci/** 26662306a36Sopenharmony_ci * ext4_blks_to_allocate - Look up the block map and count the number 26762306a36Sopenharmony_ci * of direct blocks need to be allocated for the given branch. 26862306a36Sopenharmony_ci * 26962306a36Sopenharmony_ci * @branch: chain of indirect blocks 27062306a36Sopenharmony_ci * @k: number of blocks need for indirect blocks 27162306a36Sopenharmony_ci * @blks: number of data blocks to be mapped. 27262306a36Sopenharmony_ci * @blocks_to_boundary: the offset in the indirect block 27362306a36Sopenharmony_ci * 27462306a36Sopenharmony_ci * return the total number of blocks to be allocate, including the 27562306a36Sopenharmony_ci * direct and indirect blocks. 27662306a36Sopenharmony_ci */ 27762306a36Sopenharmony_cistatic int ext4_blks_to_allocate(Indirect *branch, int k, unsigned int blks, 27862306a36Sopenharmony_ci int blocks_to_boundary) 27962306a36Sopenharmony_ci{ 28062306a36Sopenharmony_ci unsigned int count = 0; 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ci /* 28362306a36Sopenharmony_ci * Simple case, [t,d]Indirect block(s) has not allocated yet 28462306a36Sopenharmony_ci * then it's clear blocks on that path have not allocated 28562306a36Sopenharmony_ci */ 28662306a36Sopenharmony_ci if (k > 0) { 28762306a36Sopenharmony_ci /* right now we don't handle cross boundary allocation */ 28862306a36Sopenharmony_ci if (blks < blocks_to_boundary + 1) 28962306a36Sopenharmony_ci count += blks; 29062306a36Sopenharmony_ci else 29162306a36Sopenharmony_ci count += blocks_to_boundary + 1; 29262306a36Sopenharmony_ci return count; 29362306a36Sopenharmony_ci } 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ci count++; 29662306a36Sopenharmony_ci while (count < blks && count <= blocks_to_boundary && 29762306a36Sopenharmony_ci le32_to_cpu(*(branch[0].p + count)) == 0) { 29862306a36Sopenharmony_ci count++; 29962306a36Sopenharmony_ci } 30062306a36Sopenharmony_ci return count; 30162306a36Sopenharmony_ci} 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci/** 30462306a36Sopenharmony_ci * ext4_alloc_branch() - allocate and set up a chain of blocks 30562306a36Sopenharmony_ci * @handle: handle for this transaction 30662306a36Sopenharmony_ci * @ar: structure describing the allocation request 30762306a36Sopenharmony_ci * @indirect_blks: number of allocated indirect blocks 30862306a36Sopenharmony_ci * @offsets: offsets (in the blocks) to store the pointers to next. 30962306a36Sopenharmony_ci * @branch: place to store the chain in. 31062306a36Sopenharmony_ci * 31162306a36Sopenharmony_ci * This function allocates blocks, zeroes out all but the last one, 31262306a36Sopenharmony_ci * links them into chain and (if we are synchronous) writes them to disk. 31362306a36Sopenharmony_ci * In other words, it prepares a branch that can be spliced onto the 31462306a36Sopenharmony_ci * inode. It stores the information about that chain in the branch[], in 31562306a36Sopenharmony_ci * the same format as ext4_get_branch() would do. We are calling it after 31662306a36Sopenharmony_ci * we had read the existing part of chain and partial points to the last 31762306a36Sopenharmony_ci * triple of that (one with zero ->key). Upon the exit we have the same 31862306a36Sopenharmony_ci * picture as after the successful ext4_get_block(), except that in one 31962306a36Sopenharmony_ci * place chain is disconnected - *branch->p is still zero (we did not 32062306a36Sopenharmony_ci * set the last link), but branch->key contains the number that should 32162306a36Sopenharmony_ci * be placed into *branch->p to fill that gap. 32262306a36Sopenharmony_ci * 32362306a36Sopenharmony_ci * If allocation fails we free all blocks we've allocated (and forget 32462306a36Sopenharmony_ci * their buffer_heads) and return the error value the from failed 32562306a36Sopenharmony_ci * ext4_alloc_block() (normally -ENOSPC). Otherwise we set the chain 32662306a36Sopenharmony_ci * as described above and return 0. 32762306a36Sopenharmony_ci */ 32862306a36Sopenharmony_cistatic int ext4_alloc_branch(handle_t *handle, 32962306a36Sopenharmony_ci struct ext4_allocation_request *ar, 33062306a36Sopenharmony_ci int indirect_blks, ext4_lblk_t *offsets, 33162306a36Sopenharmony_ci Indirect *branch) 33262306a36Sopenharmony_ci{ 33362306a36Sopenharmony_ci struct buffer_head * bh; 33462306a36Sopenharmony_ci ext4_fsblk_t b, new_blocks[4]; 33562306a36Sopenharmony_ci __le32 *p; 33662306a36Sopenharmony_ci int i, j, err, len = 1; 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_ci for (i = 0; i <= indirect_blks; i++) { 33962306a36Sopenharmony_ci if (i == indirect_blks) { 34062306a36Sopenharmony_ci new_blocks[i] = ext4_mb_new_blocks(handle, ar, &err); 34162306a36Sopenharmony_ci } else { 34262306a36Sopenharmony_ci ar->goal = new_blocks[i] = ext4_new_meta_blocks(handle, 34362306a36Sopenharmony_ci ar->inode, ar->goal, 34462306a36Sopenharmony_ci ar->flags & EXT4_MB_DELALLOC_RESERVED, 34562306a36Sopenharmony_ci NULL, &err); 34662306a36Sopenharmony_ci /* Simplify error cleanup... */ 34762306a36Sopenharmony_ci branch[i+1].bh = NULL; 34862306a36Sopenharmony_ci } 34962306a36Sopenharmony_ci if (err) { 35062306a36Sopenharmony_ci i--; 35162306a36Sopenharmony_ci goto failed; 35262306a36Sopenharmony_ci } 35362306a36Sopenharmony_ci branch[i].key = cpu_to_le32(new_blocks[i]); 35462306a36Sopenharmony_ci if (i == 0) 35562306a36Sopenharmony_ci continue; 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_ci bh = branch[i].bh = sb_getblk(ar->inode->i_sb, new_blocks[i-1]); 35862306a36Sopenharmony_ci if (unlikely(!bh)) { 35962306a36Sopenharmony_ci err = -ENOMEM; 36062306a36Sopenharmony_ci goto failed; 36162306a36Sopenharmony_ci } 36262306a36Sopenharmony_ci lock_buffer(bh); 36362306a36Sopenharmony_ci BUFFER_TRACE(bh, "call get_create_access"); 36462306a36Sopenharmony_ci err = ext4_journal_get_create_access(handle, ar->inode->i_sb, 36562306a36Sopenharmony_ci bh, EXT4_JTR_NONE); 36662306a36Sopenharmony_ci if (err) { 36762306a36Sopenharmony_ci unlock_buffer(bh); 36862306a36Sopenharmony_ci goto failed; 36962306a36Sopenharmony_ci } 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_ci memset(bh->b_data, 0, bh->b_size); 37262306a36Sopenharmony_ci p = branch[i].p = (__le32 *) bh->b_data + offsets[i]; 37362306a36Sopenharmony_ci b = new_blocks[i]; 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_ci if (i == indirect_blks) 37662306a36Sopenharmony_ci len = ar->len; 37762306a36Sopenharmony_ci for (j = 0; j < len; j++) 37862306a36Sopenharmony_ci *p++ = cpu_to_le32(b++); 37962306a36Sopenharmony_ci 38062306a36Sopenharmony_ci BUFFER_TRACE(bh, "marking uptodate"); 38162306a36Sopenharmony_ci set_buffer_uptodate(bh); 38262306a36Sopenharmony_ci unlock_buffer(bh); 38362306a36Sopenharmony_ci 38462306a36Sopenharmony_ci BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata"); 38562306a36Sopenharmony_ci err = ext4_handle_dirty_metadata(handle, ar->inode, bh); 38662306a36Sopenharmony_ci if (err) 38762306a36Sopenharmony_ci goto failed; 38862306a36Sopenharmony_ci } 38962306a36Sopenharmony_ci return 0; 39062306a36Sopenharmony_cifailed: 39162306a36Sopenharmony_ci if (i == indirect_blks) { 39262306a36Sopenharmony_ci /* Free data blocks */ 39362306a36Sopenharmony_ci ext4_free_blocks(handle, ar->inode, NULL, new_blocks[i], 39462306a36Sopenharmony_ci ar->len, 0); 39562306a36Sopenharmony_ci i--; 39662306a36Sopenharmony_ci } 39762306a36Sopenharmony_ci for (; i >= 0; i--) { 39862306a36Sopenharmony_ci /* 39962306a36Sopenharmony_ci * We want to ext4_forget() only freshly allocated indirect 40062306a36Sopenharmony_ci * blocks. Buffer for new_blocks[i] is at branch[i+1].bh 40162306a36Sopenharmony_ci * (buffer at branch[0].bh is indirect block / inode already 40262306a36Sopenharmony_ci * existing before ext4_alloc_branch() was called). Also 40362306a36Sopenharmony_ci * because blocks are freshly allocated, we don't need to 40462306a36Sopenharmony_ci * revoke them which is why we don't set 40562306a36Sopenharmony_ci * EXT4_FREE_BLOCKS_METADATA. 40662306a36Sopenharmony_ci */ 40762306a36Sopenharmony_ci ext4_free_blocks(handle, ar->inode, branch[i+1].bh, 40862306a36Sopenharmony_ci new_blocks[i], 1, 40962306a36Sopenharmony_ci branch[i+1].bh ? EXT4_FREE_BLOCKS_FORGET : 0); 41062306a36Sopenharmony_ci } 41162306a36Sopenharmony_ci return err; 41262306a36Sopenharmony_ci} 41362306a36Sopenharmony_ci 41462306a36Sopenharmony_ci/** 41562306a36Sopenharmony_ci * ext4_splice_branch() - splice the allocated branch onto inode. 41662306a36Sopenharmony_ci * @handle: handle for this transaction 41762306a36Sopenharmony_ci * @ar: structure describing the allocation request 41862306a36Sopenharmony_ci * @where: location of missing link 41962306a36Sopenharmony_ci * @num: number of indirect blocks we are adding 42062306a36Sopenharmony_ci * 42162306a36Sopenharmony_ci * This function fills the missing link and does all housekeeping needed in 42262306a36Sopenharmony_ci * inode (->i_blocks, etc.). In case of success we end up with the full 42362306a36Sopenharmony_ci * chain to new block and return 0. 42462306a36Sopenharmony_ci */ 42562306a36Sopenharmony_cistatic int ext4_splice_branch(handle_t *handle, 42662306a36Sopenharmony_ci struct ext4_allocation_request *ar, 42762306a36Sopenharmony_ci Indirect *where, int num) 42862306a36Sopenharmony_ci{ 42962306a36Sopenharmony_ci int i; 43062306a36Sopenharmony_ci int err = 0; 43162306a36Sopenharmony_ci ext4_fsblk_t current_block; 43262306a36Sopenharmony_ci 43362306a36Sopenharmony_ci /* 43462306a36Sopenharmony_ci * If we're splicing into a [td]indirect block (as opposed to the 43562306a36Sopenharmony_ci * inode) then we need to get write access to the [td]indirect block 43662306a36Sopenharmony_ci * before the splice. 43762306a36Sopenharmony_ci */ 43862306a36Sopenharmony_ci if (where->bh) { 43962306a36Sopenharmony_ci BUFFER_TRACE(where->bh, "get_write_access"); 44062306a36Sopenharmony_ci err = ext4_journal_get_write_access(handle, ar->inode->i_sb, 44162306a36Sopenharmony_ci where->bh, EXT4_JTR_NONE); 44262306a36Sopenharmony_ci if (err) 44362306a36Sopenharmony_ci goto err_out; 44462306a36Sopenharmony_ci } 44562306a36Sopenharmony_ci /* That's it */ 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_ci *where->p = where->key; 44862306a36Sopenharmony_ci 44962306a36Sopenharmony_ci /* 45062306a36Sopenharmony_ci * Update the host buffer_head or inode to point to more just allocated 45162306a36Sopenharmony_ci * direct blocks blocks 45262306a36Sopenharmony_ci */ 45362306a36Sopenharmony_ci if (num == 0 && ar->len > 1) { 45462306a36Sopenharmony_ci current_block = le32_to_cpu(where->key) + 1; 45562306a36Sopenharmony_ci for (i = 1; i < ar->len; i++) 45662306a36Sopenharmony_ci *(where->p + i) = cpu_to_le32(current_block++); 45762306a36Sopenharmony_ci } 45862306a36Sopenharmony_ci 45962306a36Sopenharmony_ci /* We are done with atomic stuff, now do the rest of housekeeping */ 46062306a36Sopenharmony_ci /* had we spliced it onto indirect block? */ 46162306a36Sopenharmony_ci if (where->bh) { 46262306a36Sopenharmony_ci /* 46362306a36Sopenharmony_ci * If we spliced it onto an indirect block, we haven't 46462306a36Sopenharmony_ci * altered the inode. Note however that if it is being spliced 46562306a36Sopenharmony_ci * onto an indirect block at the very end of the file (the 46662306a36Sopenharmony_ci * file is growing) then we *will* alter the inode to reflect 46762306a36Sopenharmony_ci * the new i_size. But that is not done here - it is done in 46862306a36Sopenharmony_ci * generic_commit_write->__mark_inode_dirty->ext4_dirty_inode. 46962306a36Sopenharmony_ci */ 47062306a36Sopenharmony_ci ext4_debug("splicing indirect only\n"); 47162306a36Sopenharmony_ci BUFFER_TRACE(where->bh, "call ext4_handle_dirty_metadata"); 47262306a36Sopenharmony_ci err = ext4_handle_dirty_metadata(handle, ar->inode, where->bh); 47362306a36Sopenharmony_ci if (err) 47462306a36Sopenharmony_ci goto err_out; 47562306a36Sopenharmony_ci } else { 47662306a36Sopenharmony_ci /* 47762306a36Sopenharmony_ci * OK, we spliced it into the inode itself on a direct block. 47862306a36Sopenharmony_ci */ 47962306a36Sopenharmony_ci err = ext4_mark_inode_dirty(handle, ar->inode); 48062306a36Sopenharmony_ci if (unlikely(err)) 48162306a36Sopenharmony_ci goto err_out; 48262306a36Sopenharmony_ci ext4_debug("splicing direct\n"); 48362306a36Sopenharmony_ci } 48462306a36Sopenharmony_ci return err; 48562306a36Sopenharmony_ci 48662306a36Sopenharmony_cierr_out: 48762306a36Sopenharmony_ci for (i = 1; i <= num; i++) { 48862306a36Sopenharmony_ci /* 48962306a36Sopenharmony_ci * branch[i].bh is newly allocated, so there is no 49062306a36Sopenharmony_ci * need to revoke the block, which is why we don't 49162306a36Sopenharmony_ci * need to set EXT4_FREE_BLOCKS_METADATA. 49262306a36Sopenharmony_ci */ 49362306a36Sopenharmony_ci ext4_free_blocks(handle, ar->inode, where[i].bh, 0, 1, 49462306a36Sopenharmony_ci EXT4_FREE_BLOCKS_FORGET); 49562306a36Sopenharmony_ci } 49662306a36Sopenharmony_ci ext4_free_blocks(handle, ar->inode, NULL, le32_to_cpu(where[num].key), 49762306a36Sopenharmony_ci ar->len, 0); 49862306a36Sopenharmony_ci 49962306a36Sopenharmony_ci return err; 50062306a36Sopenharmony_ci} 50162306a36Sopenharmony_ci 50262306a36Sopenharmony_ci/* 50362306a36Sopenharmony_ci * The ext4_ind_map_blocks() function handles non-extents inodes 50462306a36Sopenharmony_ci * (i.e., using the traditional indirect/double-indirect i_blocks 50562306a36Sopenharmony_ci * scheme) for ext4_map_blocks(). 50662306a36Sopenharmony_ci * 50762306a36Sopenharmony_ci * Allocation strategy is simple: if we have to allocate something, we will 50862306a36Sopenharmony_ci * have to go the whole way to leaf. So let's do it before attaching anything 50962306a36Sopenharmony_ci * to tree, set linkage between the newborn blocks, write them if sync is 51062306a36Sopenharmony_ci * required, recheck the path, free and repeat if check fails, otherwise 51162306a36Sopenharmony_ci * set the last missing link (that will protect us from any truncate-generated 51262306a36Sopenharmony_ci * removals - all blocks on the path are immune now) and possibly force the 51362306a36Sopenharmony_ci * write on the parent block. 51462306a36Sopenharmony_ci * That has a nice additional property: no special recovery from the failed 51562306a36Sopenharmony_ci * allocations is needed - we simply release blocks and do not touch anything 51662306a36Sopenharmony_ci * reachable from inode. 51762306a36Sopenharmony_ci * 51862306a36Sopenharmony_ci * `handle' can be NULL if create == 0. 51962306a36Sopenharmony_ci * 52062306a36Sopenharmony_ci * return > 0, # of blocks mapped or allocated. 52162306a36Sopenharmony_ci * return = 0, if plain lookup failed. 52262306a36Sopenharmony_ci * return < 0, error case. 52362306a36Sopenharmony_ci * 52462306a36Sopenharmony_ci * The ext4_ind_get_blocks() function should be called with 52562306a36Sopenharmony_ci * down_write(&EXT4_I(inode)->i_data_sem) if allocating filesystem 52662306a36Sopenharmony_ci * blocks (i.e., flags has EXT4_GET_BLOCKS_CREATE set) or 52762306a36Sopenharmony_ci * down_read(&EXT4_I(inode)->i_data_sem) if not allocating file system 52862306a36Sopenharmony_ci * blocks. 52962306a36Sopenharmony_ci */ 53062306a36Sopenharmony_ciint ext4_ind_map_blocks(handle_t *handle, struct inode *inode, 53162306a36Sopenharmony_ci struct ext4_map_blocks *map, 53262306a36Sopenharmony_ci int flags) 53362306a36Sopenharmony_ci{ 53462306a36Sopenharmony_ci struct ext4_allocation_request ar; 53562306a36Sopenharmony_ci int err = -EIO; 53662306a36Sopenharmony_ci ext4_lblk_t offsets[4]; 53762306a36Sopenharmony_ci Indirect chain[4]; 53862306a36Sopenharmony_ci Indirect *partial; 53962306a36Sopenharmony_ci int indirect_blks; 54062306a36Sopenharmony_ci int blocks_to_boundary = 0; 54162306a36Sopenharmony_ci int depth; 54262306a36Sopenharmony_ci int count = 0; 54362306a36Sopenharmony_ci ext4_fsblk_t first_block = 0; 54462306a36Sopenharmony_ci 54562306a36Sopenharmony_ci trace_ext4_ind_map_blocks_enter(inode, map->m_lblk, map->m_len, flags); 54662306a36Sopenharmony_ci ASSERT(!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))); 54762306a36Sopenharmony_ci ASSERT(handle != NULL || (flags & EXT4_GET_BLOCKS_CREATE) == 0); 54862306a36Sopenharmony_ci depth = ext4_block_to_path(inode, map->m_lblk, offsets, 54962306a36Sopenharmony_ci &blocks_to_boundary); 55062306a36Sopenharmony_ci 55162306a36Sopenharmony_ci if (depth == 0) 55262306a36Sopenharmony_ci goto out; 55362306a36Sopenharmony_ci 55462306a36Sopenharmony_ci partial = ext4_get_branch(inode, depth, offsets, chain, &err); 55562306a36Sopenharmony_ci 55662306a36Sopenharmony_ci /* Simplest case - block found, no allocation needed */ 55762306a36Sopenharmony_ci if (!partial) { 55862306a36Sopenharmony_ci first_block = le32_to_cpu(chain[depth - 1].key); 55962306a36Sopenharmony_ci count++; 56062306a36Sopenharmony_ci /*map more blocks*/ 56162306a36Sopenharmony_ci while (count < map->m_len && count <= blocks_to_boundary) { 56262306a36Sopenharmony_ci ext4_fsblk_t blk; 56362306a36Sopenharmony_ci 56462306a36Sopenharmony_ci blk = le32_to_cpu(*(chain[depth-1].p + count)); 56562306a36Sopenharmony_ci 56662306a36Sopenharmony_ci if (blk == first_block + count) 56762306a36Sopenharmony_ci count++; 56862306a36Sopenharmony_ci else 56962306a36Sopenharmony_ci break; 57062306a36Sopenharmony_ci } 57162306a36Sopenharmony_ci goto got_it; 57262306a36Sopenharmony_ci } 57362306a36Sopenharmony_ci 57462306a36Sopenharmony_ci /* Next simple case - plain lookup failed */ 57562306a36Sopenharmony_ci if ((flags & EXT4_GET_BLOCKS_CREATE) == 0) { 57662306a36Sopenharmony_ci unsigned epb = inode->i_sb->s_blocksize / sizeof(u32); 57762306a36Sopenharmony_ci int i; 57862306a36Sopenharmony_ci 57962306a36Sopenharmony_ci /* 58062306a36Sopenharmony_ci * Count number blocks in a subtree under 'partial'. At each 58162306a36Sopenharmony_ci * level we count number of complete empty subtrees beyond 58262306a36Sopenharmony_ci * current offset and then descend into the subtree only 58362306a36Sopenharmony_ci * partially beyond current offset. 58462306a36Sopenharmony_ci */ 58562306a36Sopenharmony_ci count = 0; 58662306a36Sopenharmony_ci for (i = partial - chain + 1; i < depth; i++) 58762306a36Sopenharmony_ci count = count * epb + (epb - offsets[i] - 1); 58862306a36Sopenharmony_ci count++; 58962306a36Sopenharmony_ci /* Fill in size of a hole we found */ 59062306a36Sopenharmony_ci map->m_pblk = 0; 59162306a36Sopenharmony_ci map->m_len = min_t(unsigned int, map->m_len, count); 59262306a36Sopenharmony_ci goto cleanup; 59362306a36Sopenharmony_ci } 59462306a36Sopenharmony_ci 59562306a36Sopenharmony_ci /* Failed read of indirect block */ 59662306a36Sopenharmony_ci if (err == -EIO) 59762306a36Sopenharmony_ci goto cleanup; 59862306a36Sopenharmony_ci 59962306a36Sopenharmony_ci /* 60062306a36Sopenharmony_ci * Okay, we need to do block allocation. 60162306a36Sopenharmony_ci */ 60262306a36Sopenharmony_ci if (ext4_has_feature_bigalloc(inode->i_sb)) { 60362306a36Sopenharmony_ci EXT4_ERROR_INODE(inode, "Can't allocate blocks for " 60462306a36Sopenharmony_ci "non-extent mapped inodes with bigalloc"); 60562306a36Sopenharmony_ci err = -EFSCORRUPTED; 60662306a36Sopenharmony_ci goto out; 60762306a36Sopenharmony_ci } 60862306a36Sopenharmony_ci 60962306a36Sopenharmony_ci /* Set up for the direct block allocation */ 61062306a36Sopenharmony_ci memset(&ar, 0, sizeof(ar)); 61162306a36Sopenharmony_ci ar.inode = inode; 61262306a36Sopenharmony_ci ar.logical = map->m_lblk; 61362306a36Sopenharmony_ci if (S_ISREG(inode->i_mode)) 61462306a36Sopenharmony_ci ar.flags = EXT4_MB_HINT_DATA; 61562306a36Sopenharmony_ci if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) 61662306a36Sopenharmony_ci ar.flags |= EXT4_MB_DELALLOC_RESERVED; 61762306a36Sopenharmony_ci if (flags & EXT4_GET_BLOCKS_METADATA_NOFAIL) 61862306a36Sopenharmony_ci ar.flags |= EXT4_MB_USE_RESERVED; 61962306a36Sopenharmony_ci 62062306a36Sopenharmony_ci ar.goal = ext4_find_goal(inode, map->m_lblk, partial); 62162306a36Sopenharmony_ci 62262306a36Sopenharmony_ci /* the number of blocks need to allocate for [d,t]indirect blocks */ 62362306a36Sopenharmony_ci indirect_blks = (chain + depth) - partial - 1; 62462306a36Sopenharmony_ci 62562306a36Sopenharmony_ci /* 62662306a36Sopenharmony_ci * Next look up the indirect map to count the totoal number of 62762306a36Sopenharmony_ci * direct blocks to allocate for this branch. 62862306a36Sopenharmony_ci */ 62962306a36Sopenharmony_ci ar.len = ext4_blks_to_allocate(partial, indirect_blks, 63062306a36Sopenharmony_ci map->m_len, blocks_to_boundary); 63162306a36Sopenharmony_ci 63262306a36Sopenharmony_ci /* 63362306a36Sopenharmony_ci * Block out ext4_truncate while we alter the tree 63462306a36Sopenharmony_ci */ 63562306a36Sopenharmony_ci err = ext4_alloc_branch(handle, &ar, indirect_blks, 63662306a36Sopenharmony_ci offsets + (partial - chain), partial); 63762306a36Sopenharmony_ci 63862306a36Sopenharmony_ci /* 63962306a36Sopenharmony_ci * The ext4_splice_branch call will free and forget any buffers 64062306a36Sopenharmony_ci * on the new chain if there is a failure, but that risks using 64162306a36Sopenharmony_ci * up transaction credits, especially for bitmaps where the 64262306a36Sopenharmony_ci * credits cannot be returned. Can we handle this somehow? We 64362306a36Sopenharmony_ci * may need to return -EAGAIN upwards in the worst case. --sct 64462306a36Sopenharmony_ci */ 64562306a36Sopenharmony_ci if (!err) 64662306a36Sopenharmony_ci err = ext4_splice_branch(handle, &ar, partial, indirect_blks); 64762306a36Sopenharmony_ci if (err) 64862306a36Sopenharmony_ci goto cleanup; 64962306a36Sopenharmony_ci 65062306a36Sopenharmony_ci map->m_flags |= EXT4_MAP_NEW; 65162306a36Sopenharmony_ci 65262306a36Sopenharmony_ci ext4_update_inode_fsync_trans(handle, inode, 1); 65362306a36Sopenharmony_ci count = ar.len; 65462306a36Sopenharmony_ci 65562306a36Sopenharmony_ci /* 65662306a36Sopenharmony_ci * Update reserved blocks/metadata blocks after successful block 65762306a36Sopenharmony_ci * allocation which had been deferred till now. 65862306a36Sopenharmony_ci */ 65962306a36Sopenharmony_ci if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE) 66062306a36Sopenharmony_ci ext4_da_update_reserve_space(inode, count, 1); 66162306a36Sopenharmony_ci 66262306a36Sopenharmony_cigot_it: 66362306a36Sopenharmony_ci map->m_flags |= EXT4_MAP_MAPPED; 66462306a36Sopenharmony_ci map->m_pblk = le32_to_cpu(chain[depth-1].key); 66562306a36Sopenharmony_ci map->m_len = count; 66662306a36Sopenharmony_ci if (count > blocks_to_boundary) 66762306a36Sopenharmony_ci map->m_flags |= EXT4_MAP_BOUNDARY; 66862306a36Sopenharmony_ci err = count; 66962306a36Sopenharmony_ci /* Clean up and exit */ 67062306a36Sopenharmony_ci partial = chain + depth - 1; /* the whole chain */ 67162306a36Sopenharmony_cicleanup: 67262306a36Sopenharmony_ci while (partial > chain) { 67362306a36Sopenharmony_ci BUFFER_TRACE(partial->bh, "call brelse"); 67462306a36Sopenharmony_ci brelse(partial->bh); 67562306a36Sopenharmony_ci partial--; 67662306a36Sopenharmony_ci } 67762306a36Sopenharmony_ciout: 67862306a36Sopenharmony_ci trace_ext4_ind_map_blocks_exit(inode, flags, map, err); 67962306a36Sopenharmony_ci return err; 68062306a36Sopenharmony_ci} 68162306a36Sopenharmony_ci 68262306a36Sopenharmony_ci/* 68362306a36Sopenharmony_ci * Calculate number of indirect blocks touched by mapping @nrblocks logically 68462306a36Sopenharmony_ci * contiguous blocks 68562306a36Sopenharmony_ci */ 68662306a36Sopenharmony_ciint ext4_ind_trans_blocks(struct inode *inode, int nrblocks) 68762306a36Sopenharmony_ci{ 68862306a36Sopenharmony_ci /* 68962306a36Sopenharmony_ci * With N contiguous data blocks, we need at most 69062306a36Sopenharmony_ci * N/EXT4_ADDR_PER_BLOCK(inode->i_sb) + 1 indirect blocks, 69162306a36Sopenharmony_ci * 2 dindirect blocks, and 1 tindirect block 69262306a36Sopenharmony_ci */ 69362306a36Sopenharmony_ci return DIV_ROUND_UP(nrblocks, EXT4_ADDR_PER_BLOCK(inode->i_sb)) + 4; 69462306a36Sopenharmony_ci} 69562306a36Sopenharmony_ci 69662306a36Sopenharmony_cistatic int ext4_ind_trunc_restart_fn(handle_t *handle, struct inode *inode, 69762306a36Sopenharmony_ci struct buffer_head *bh, int *dropped) 69862306a36Sopenharmony_ci{ 69962306a36Sopenharmony_ci int err; 70062306a36Sopenharmony_ci 70162306a36Sopenharmony_ci if (bh) { 70262306a36Sopenharmony_ci BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata"); 70362306a36Sopenharmony_ci err = ext4_handle_dirty_metadata(handle, inode, bh); 70462306a36Sopenharmony_ci if (unlikely(err)) 70562306a36Sopenharmony_ci return err; 70662306a36Sopenharmony_ci } 70762306a36Sopenharmony_ci err = ext4_mark_inode_dirty(handle, inode); 70862306a36Sopenharmony_ci if (unlikely(err)) 70962306a36Sopenharmony_ci return err; 71062306a36Sopenharmony_ci /* 71162306a36Sopenharmony_ci * Drop i_data_sem to avoid deadlock with ext4_map_blocks. At this 71262306a36Sopenharmony_ci * moment, get_block can be called only for blocks inside i_size since 71362306a36Sopenharmony_ci * page cache has been already dropped and writes are blocked by 71462306a36Sopenharmony_ci * i_rwsem. So we can safely drop the i_data_sem here. 71562306a36Sopenharmony_ci */ 71662306a36Sopenharmony_ci BUG_ON(EXT4_JOURNAL(inode) == NULL); 71762306a36Sopenharmony_ci ext4_discard_preallocations(inode, 0); 71862306a36Sopenharmony_ci up_write(&EXT4_I(inode)->i_data_sem); 71962306a36Sopenharmony_ci *dropped = 1; 72062306a36Sopenharmony_ci return 0; 72162306a36Sopenharmony_ci} 72262306a36Sopenharmony_ci 72362306a36Sopenharmony_ci/* 72462306a36Sopenharmony_ci * Truncate transactions can be complex and absolutely huge. So we need to 72562306a36Sopenharmony_ci * be able to restart the transaction at a convenient checkpoint to make 72662306a36Sopenharmony_ci * sure we don't overflow the journal. 72762306a36Sopenharmony_ci * 72862306a36Sopenharmony_ci * Try to extend this transaction for the purposes of truncation. If 72962306a36Sopenharmony_ci * extend fails, we restart transaction. 73062306a36Sopenharmony_ci */ 73162306a36Sopenharmony_cistatic int ext4_ind_truncate_ensure_credits(handle_t *handle, 73262306a36Sopenharmony_ci struct inode *inode, 73362306a36Sopenharmony_ci struct buffer_head *bh, 73462306a36Sopenharmony_ci int revoke_creds) 73562306a36Sopenharmony_ci{ 73662306a36Sopenharmony_ci int ret; 73762306a36Sopenharmony_ci int dropped = 0; 73862306a36Sopenharmony_ci 73962306a36Sopenharmony_ci ret = ext4_journal_ensure_credits_fn(handle, EXT4_RESERVE_TRANS_BLOCKS, 74062306a36Sopenharmony_ci ext4_blocks_for_truncate(inode), revoke_creds, 74162306a36Sopenharmony_ci ext4_ind_trunc_restart_fn(handle, inode, bh, &dropped)); 74262306a36Sopenharmony_ci if (dropped) 74362306a36Sopenharmony_ci down_write(&EXT4_I(inode)->i_data_sem); 74462306a36Sopenharmony_ci if (ret <= 0) 74562306a36Sopenharmony_ci return ret; 74662306a36Sopenharmony_ci if (bh) { 74762306a36Sopenharmony_ci BUFFER_TRACE(bh, "retaking write access"); 74862306a36Sopenharmony_ci ret = ext4_journal_get_write_access(handle, inode->i_sb, bh, 74962306a36Sopenharmony_ci EXT4_JTR_NONE); 75062306a36Sopenharmony_ci if (unlikely(ret)) 75162306a36Sopenharmony_ci return ret; 75262306a36Sopenharmony_ci } 75362306a36Sopenharmony_ci return 0; 75462306a36Sopenharmony_ci} 75562306a36Sopenharmony_ci 75662306a36Sopenharmony_ci/* 75762306a36Sopenharmony_ci * Probably it should be a library function... search for first non-zero word 75862306a36Sopenharmony_ci * or memcmp with zero_page, whatever is better for particular architecture. 75962306a36Sopenharmony_ci * Linus? 76062306a36Sopenharmony_ci */ 76162306a36Sopenharmony_cistatic inline int all_zeroes(__le32 *p, __le32 *q) 76262306a36Sopenharmony_ci{ 76362306a36Sopenharmony_ci while (p < q) 76462306a36Sopenharmony_ci if (*p++) 76562306a36Sopenharmony_ci return 0; 76662306a36Sopenharmony_ci return 1; 76762306a36Sopenharmony_ci} 76862306a36Sopenharmony_ci 76962306a36Sopenharmony_ci/** 77062306a36Sopenharmony_ci * ext4_find_shared - find the indirect blocks for partial truncation. 77162306a36Sopenharmony_ci * @inode: inode in question 77262306a36Sopenharmony_ci * @depth: depth of the affected branch 77362306a36Sopenharmony_ci * @offsets: offsets of pointers in that branch (see ext4_block_to_path) 77462306a36Sopenharmony_ci * @chain: place to store the pointers to partial indirect blocks 77562306a36Sopenharmony_ci * @top: place to the (detached) top of branch 77662306a36Sopenharmony_ci * 77762306a36Sopenharmony_ci * This is a helper function used by ext4_truncate(). 77862306a36Sopenharmony_ci * 77962306a36Sopenharmony_ci * When we do truncate() we may have to clean the ends of several 78062306a36Sopenharmony_ci * indirect blocks but leave the blocks themselves alive. Block is 78162306a36Sopenharmony_ci * partially truncated if some data below the new i_size is referred 78262306a36Sopenharmony_ci * from it (and it is on the path to the first completely truncated 78362306a36Sopenharmony_ci * data block, indeed). We have to free the top of that path along 78462306a36Sopenharmony_ci * with everything to the right of the path. Since no allocation 78562306a36Sopenharmony_ci * past the truncation point is possible until ext4_truncate() 78662306a36Sopenharmony_ci * finishes, we may safely do the latter, but top of branch may 78762306a36Sopenharmony_ci * require special attention - pageout below the truncation point 78862306a36Sopenharmony_ci * might try to populate it. 78962306a36Sopenharmony_ci * 79062306a36Sopenharmony_ci * We atomically detach the top of branch from the tree, store the 79162306a36Sopenharmony_ci * block number of its root in *@top, pointers to buffer_heads of 79262306a36Sopenharmony_ci * partially truncated blocks - in @chain[].bh and pointers to 79362306a36Sopenharmony_ci * their last elements that should not be removed - in 79462306a36Sopenharmony_ci * @chain[].p. Return value is the pointer to last filled element 79562306a36Sopenharmony_ci * of @chain. 79662306a36Sopenharmony_ci * 79762306a36Sopenharmony_ci * The work left to caller to do the actual freeing of subtrees: 79862306a36Sopenharmony_ci * a) free the subtree starting from *@top 79962306a36Sopenharmony_ci * b) free the subtrees whose roots are stored in 80062306a36Sopenharmony_ci * (@chain[i].p+1 .. end of @chain[i].bh->b_data) 80162306a36Sopenharmony_ci * c) free the subtrees growing from the inode past the @chain[0]. 80262306a36Sopenharmony_ci * (no partially truncated stuff there). */ 80362306a36Sopenharmony_ci 80462306a36Sopenharmony_cistatic Indirect *ext4_find_shared(struct inode *inode, int depth, 80562306a36Sopenharmony_ci ext4_lblk_t offsets[4], Indirect chain[4], 80662306a36Sopenharmony_ci __le32 *top) 80762306a36Sopenharmony_ci{ 80862306a36Sopenharmony_ci Indirect *partial, *p; 80962306a36Sopenharmony_ci int k, err; 81062306a36Sopenharmony_ci 81162306a36Sopenharmony_ci *top = 0; 81262306a36Sopenharmony_ci /* Make k index the deepest non-null offset + 1 */ 81362306a36Sopenharmony_ci for (k = depth; k > 1 && !offsets[k-1]; k--) 81462306a36Sopenharmony_ci ; 81562306a36Sopenharmony_ci partial = ext4_get_branch(inode, k, offsets, chain, &err); 81662306a36Sopenharmony_ci /* Writer: pointers */ 81762306a36Sopenharmony_ci if (!partial) 81862306a36Sopenharmony_ci partial = chain + k-1; 81962306a36Sopenharmony_ci /* 82062306a36Sopenharmony_ci * If the branch acquired continuation since we've looked at it - 82162306a36Sopenharmony_ci * fine, it should all survive and (new) top doesn't belong to us. 82262306a36Sopenharmony_ci */ 82362306a36Sopenharmony_ci if (!partial->key && *partial->p) 82462306a36Sopenharmony_ci /* Writer: end */ 82562306a36Sopenharmony_ci goto no_top; 82662306a36Sopenharmony_ci for (p = partial; (p > chain) && all_zeroes((__le32 *) p->bh->b_data, p->p); p--) 82762306a36Sopenharmony_ci ; 82862306a36Sopenharmony_ci /* 82962306a36Sopenharmony_ci * OK, we've found the last block that must survive. The rest of our 83062306a36Sopenharmony_ci * branch should be detached before unlocking. However, if that rest 83162306a36Sopenharmony_ci * of branch is all ours and does not grow immediately from the inode 83262306a36Sopenharmony_ci * it's easier to cheat and just decrement partial->p. 83362306a36Sopenharmony_ci */ 83462306a36Sopenharmony_ci if (p == chain + k - 1 && p > chain) { 83562306a36Sopenharmony_ci p->p--; 83662306a36Sopenharmony_ci } else { 83762306a36Sopenharmony_ci *top = *p->p; 83862306a36Sopenharmony_ci /* Nope, don't do this in ext4. Must leave the tree intact */ 83962306a36Sopenharmony_ci#if 0 84062306a36Sopenharmony_ci *p->p = 0; 84162306a36Sopenharmony_ci#endif 84262306a36Sopenharmony_ci } 84362306a36Sopenharmony_ci /* Writer: end */ 84462306a36Sopenharmony_ci 84562306a36Sopenharmony_ci while (partial > p) { 84662306a36Sopenharmony_ci brelse(partial->bh); 84762306a36Sopenharmony_ci partial--; 84862306a36Sopenharmony_ci } 84962306a36Sopenharmony_cino_top: 85062306a36Sopenharmony_ci return partial; 85162306a36Sopenharmony_ci} 85262306a36Sopenharmony_ci 85362306a36Sopenharmony_ci/* 85462306a36Sopenharmony_ci * Zero a number of block pointers in either an inode or an indirect block. 85562306a36Sopenharmony_ci * If we restart the transaction we must again get write access to the 85662306a36Sopenharmony_ci * indirect block for further modification. 85762306a36Sopenharmony_ci * 85862306a36Sopenharmony_ci * We release `count' blocks on disk, but (last - first) may be greater 85962306a36Sopenharmony_ci * than `count' because there can be holes in there. 86062306a36Sopenharmony_ci * 86162306a36Sopenharmony_ci * Return 0 on success, 1 on invalid block range 86262306a36Sopenharmony_ci * and < 0 on fatal error. 86362306a36Sopenharmony_ci */ 86462306a36Sopenharmony_cistatic int ext4_clear_blocks(handle_t *handle, struct inode *inode, 86562306a36Sopenharmony_ci struct buffer_head *bh, 86662306a36Sopenharmony_ci ext4_fsblk_t block_to_free, 86762306a36Sopenharmony_ci unsigned long count, __le32 *first, 86862306a36Sopenharmony_ci __le32 *last) 86962306a36Sopenharmony_ci{ 87062306a36Sopenharmony_ci __le32 *p; 87162306a36Sopenharmony_ci int flags = EXT4_FREE_BLOCKS_VALIDATED; 87262306a36Sopenharmony_ci int err; 87362306a36Sopenharmony_ci 87462306a36Sopenharmony_ci if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode) || 87562306a36Sopenharmony_ci ext4_test_inode_flag(inode, EXT4_INODE_EA_INODE)) 87662306a36Sopenharmony_ci flags |= EXT4_FREE_BLOCKS_FORGET | EXT4_FREE_BLOCKS_METADATA; 87762306a36Sopenharmony_ci else if (ext4_should_journal_data(inode)) 87862306a36Sopenharmony_ci flags |= EXT4_FREE_BLOCKS_FORGET; 87962306a36Sopenharmony_ci 88062306a36Sopenharmony_ci if (!ext4_inode_block_valid(inode, block_to_free, count)) { 88162306a36Sopenharmony_ci EXT4_ERROR_INODE(inode, "attempt to clear invalid " 88262306a36Sopenharmony_ci "blocks %llu len %lu", 88362306a36Sopenharmony_ci (unsigned long long) block_to_free, count); 88462306a36Sopenharmony_ci return 1; 88562306a36Sopenharmony_ci } 88662306a36Sopenharmony_ci 88762306a36Sopenharmony_ci err = ext4_ind_truncate_ensure_credits(handle, inode, bh, 88862306a36Sopenharmony_ci ext4_free_data_revoke_credits(inode, count)); 88962306a36Sopenharmony_ci if (err < 0) 89062306a36Sopenharmony_ci goto out_err; 89162306a36Sopenharmony_ci 89262306a36Sopenharmony_ci for (p = first; p < last; p++) 89362306a36Sopenharmony_ci *p = 0; 89462306a36Sopenharmony_ci 89562306a36Sopenharmony_ci ext4_free_blocks(handle, inode, NULL, block_to_free, count, flags); 89662306a36Sopenharmony_ci return 0; 89762306a36Sopenharmony_ciout_err: 89862306a36Sopenharmony_ci ext4_std_error(inode->i_sb, err); 89962306a36Sopenharmony_ci return err; 90062306a36Sopenharmony_ci} 90162306a36Sopenharmony_ci 90262306a36Sopenharmony_ci/** 90362306a36Sopenharmony_ci * ext4_free_data - free a list of data blocks 90462306a36Sopenharmony_ci * @handle: handle for this transaction 90562306a36Sopenharmony_ci * @inode: inode we are dealing with 90662306a36Sopenharmony_ci * @this_bh: indirect buffer_head which contains *@first and *@last 90762306a36Sopenharmony_ci * @first: array of block numbers 90862306a36Sopenharmony_ci * @last: points immediately past the end of array 90962306a36Sopenharmony_ci * 91062306a36Sopenharmony_ci * We are freeing all blocks referred from that array (numbers are stored as 91162306a36Sopenharmony_ci * little-endian 32-bit) and updating @inode->i_blocks appropriately. 91262306a36Sopenharmony_ci * 91362306a36Sopenharmony_ci * We accumulate contiguous runs of blocks to free. Conveniently, if these 91462306a36Sopenharmony_ci * blocks are contiguous then releasing them at one time will only affect one 91562306a36Sopenharmony_ci * or two bitmap blocks (+ group descriptor(s) and superblock) and we won't 91662306a36Sopenharmony_ci * actually use a lot of journal space. 91762306a36Sopenharmony_ci * 91862306a36Sopenharmony_ci * @this_bh will be %NULL if @first and @last point into the inode's direct 91962306a36Sopenharmony_ci * block pointers. 92062306a36Sopenharmony_ci */ 92162306a36Sopenharmony_cistatic void ext4_free_data(handle_t *handle, struct inode *inode, 92262306a36Sopenharmony_ci struct buffer_head *this_bh, 92362306a36Sopenharmony_ci __le32 *first, __le32 *last) 92462306a36Sopenharmony_ci{ 92562306a36Sopenharmony_ci ext4_fsblk_t block_to_free = 0; /* Starting block # of a run */ 92662306a36Sopenharmony_ci unsigned long count = 0; /* Number of blocks in the run */ 92762306a36Sopenharmony_ci __le32 *block_to_free_p = NULL; /* Pointer into inode/ind 92862306a36Sopenharmony_ci corresponding to 92962306a36Sopenharmony_ci block_to_free */ 93062306a36Sopenharmony_ci ext4_fsblk_t nr; /* Current block # */ 93162306a36Sopenharmony_ci __le32 *p; /* Pointer into inode/ind 93262306a36Sopenharmony_ci for current block */ 93362306a36Sopenharmony_ci int err = 0; 93462306a36Sopenharmony_ci 93562306a36Sopenharmony_ci if (this_bh) { /* For indirect block */ 93662306a36Sopenharmony_ci BUFFER_TRACE(this_bh, "get_write_access"); 93762306a36Sopenharmony_ci err = ext4_journal_get_write_access(handle, inode->i_sb, 93862306a36Sopenharmony_ci this_bh, EXT4_JTR_NONE); 93962306a36Sopenharmony_ci /* Important: if we can't update the indirect pointers 94062306a36Sopenharmony_ci * to the blocks, we can't free them. */ 94162306a36Sopenharmony_ci if (err) 94262306a36Sopenharmony_ci return; 94362306a36Sopenharmony_ci } 94462306a36Sopenharmony_ci 94562306a36Sopenharmony_ci for (p = first; p < last; p++) { 94662306a36Sopenharmony_ci nr = le32_to_cpu(*p); 94762306a36Sopenharmony_ci if (nr) { 94862306a36Sopenharmony_ci /* accumulate blocks to free if they're contiguous */ 94962306a36Sopenharmony_ci if (count == 0) { 95062306a36Sopenharmony_ci block_to_free = nr; 95162306a36Sopenharmony_ci block_to_free_p = p; 95262306a36Sopenharmony_ci count = 1; 95362306a36Sopenharmony_ci } else if (nr == block_to_free + count) { 95462306a36Sopenharmony_ci count++; 95562306a36Sopenharmony_ci } else { 95662306a36Sopenharmony_ci err = ext4_clear_blocks(handle, inode, this_bh, 95762306a36Sopenharmony_ci block_to_free, count, 95862306a36Sopenharmony_ci block_to_free_p, p); 95962306a36Sopenharmony_ci if (err) 96062306a36Sopenharmony_ci break; 96162306a36Sopenharmony_ci block_to_free = nr; 96262306a36Sopenharmony_ci block_to_free_p = p; 96362306a36Sopenharmony_ci count = 1; 96462306a36Sopenharmony_ci } 96562306a36Sopenharmony_ci } 96662306a36Sopenharmony_ci } 96762306a36Sopenharmony_ci 96862306a36Sopenharmony_ci if (!err && count > 0) 96962306a36Sopenharmony_ci err = ext4_clear_blocks(handle, inode, this_bh, block_to_free, 97062306a36Sopenharmony_ci count, block_to_free_p, p); 97162306a36Sopenharmony_ci if (err < 0) 97262306a36Sopenharmony_ci /* fatal error */ 97362306a36Sopenharmony_ci return; 97462306a36Sopenharmony_ci 97562306a36Sopenharmony_ci if (this_bh) { 97662306a36Sopenharmony_ci BUFFER_TRACE(this_bh, "call ext4_handle_dirty_metadata"); 97762306a36Sopenharmony_ci 97862306a36Sopenharmony_ci /* 97962306a36Sopenharmony_ci * The buffer head should have an attached journal head at this 98062306a36Sopenharmony_ci * point. However, if the data is corrupted and an indirect 98162306a36Sopenharmony_ci * block pointed to itself, it would have been detached when 98262306a36Sopenharmony_ci * the block was cleared. Check for this instead of OOPSing. 98362306a36Sopenharmony_ci */ 98462306a36Sopenharmony_ci if ((EXT4_JOURNAL(inode) == NULL) || bh2jh(this_bh)) 98562306a36Sopenharmony_ci ext4_handle_dirty_metadata(handle, inode, this_bh); 98662306a36Sopenharmony_ci else 98762306a36Sopenharmony_ci EXT4_ERROR_INODE(inode, 98862306a36Sopenharmony_ci "circular indirect block detected at " 98962306a36Sopenharmony_ci "block %llu", 99062306a36Sopenharmony_ci (unsigned long long) this_bh->b_blocknr); 99162306a36Sopenharmony_ci } 99262306a36Sopenharmony_ci} 99362306a36Sopenharmony_ci 99462306a36Sopenharmony_ci/** 99562306a36Sopenharmony_ci * ext4_free_branches - free an array of branches 99662306a36Sopenharmony_ci * @handle: JBD handle for this transaction 99762306a36Sopenharmony_ci * @inode: inode we are dealing with 99862306a36Sopenharmony_ci * @parent_bh: the buffer_head which contains *@first and *@last 99962306a36Sopenharmony_ci * @first: array of block numbers 100062306a36Sopenharmony_ci * @last: pointer immediately past the end of array 100162306a36Sopenharmony_ci * @depth: depth of the branches to free 100262306a36Sopenharmony_ci * 100362306a36Sopenharmony_ci * We are freeing all blocks referred from these branches (numbers are 100462306a36Sopenharmony_ci * stored as little-endian 32-bit) and updating @inode->i_blocks 100562306a36Sopenharmony_ci * appropriately. 100662306a36Sopenharmony_ci */ 100762306a36Sopenharmony_cistatic void ext4_free_branches(handle_t *handle, struct inode *inode, 100862306a36Sopenharmony_ci struct buffer_head *parent_bh, 100962306a36Sopenharmony_ci __le32 *first, __le32 *last, int depth) 101062306a36Sopenharmony_ci{ 101162306a36Sopenharmony_ci ext4_fsblk_t nr; 101262306a36Sopenharmony_ci __le32 *p; 101362306a36Sopenharmony_ci 101462306a36Sopenharmony_ci if (ext4_handle_is_aborted(handle)) 101562306a36Sopenharmony_ci return; 101662306a36Sopenharmony_ci 101762306a36Sopenharmony_ci if (depth--) { 101862306a36Sopenharmony_ci struct buffer_head *bh; 101962306a36Sopenharmony_ci int addr_per_block = EXT4_ADDR_PER_BLOCK(inode->i_sb); 102062306a36Sopenharmony_ci p = last; 102162306a36Sopenharmony_ci while (--p >= first) { 102262306a36Sopenharmony_ci nr = le32_to_cpu(*p); 102362306a36Sopenharmony_ci if (!nr) 102462306a36Sopenharmony_ci continue; /* A hole */ 102562306a36Sopenharmony_ci 102662306a36Sopenharmony_ci if (!ext4_inode_block_valid(inode, nr, 1)) { 102762306a36Sopenharmony_ci EXT4_ERROR_INODE(inode, 102862306a36Sopenharmony_ci "invalid indirect mapped " 102962306a36Sopenharmony_ci "block %lu (level %d)", 103062306a36Sopenharmony_ci (unsigned long) nr, depth); 103162306a36Sopenharmony_ci break; 103262306a36Sopenharmony_ci } 103362306a36Sopenharmony_ci 103462306a36Sopenharmony_ci /* Go read the buffer for the next level down */ 103562306a36Sopenharmony_ci bh = ext4_sb_bread(inode->i_sb, nr, 0); 103662306a36Sopenharmony_ci 103762306a36Sopenharmony_ci /* 103862306a36Sopenharmony_ci * A read failure? Report error and clear slot 103962306a36Sopenharmony_ci * (should be rare). 104062306a36Sopenharmony_ci */ 104162306a36Sopenharmony_ci if (IS_ERR(bh)) { 104262306a36Sopenharmony_ci ext4_error_inode_block(inode, nr, -PTR_ERR(bh), 104362306a36Sopenharmony_ci "Read failure"); 104462306a36Sopenharmony_ci continue; 104562306a36Sopenharmony_ci } 104662306a36Sopenharmony_ci 104762306a36Sopenharmony_ci /* This zaps the entire block. Bottom up. */ 104862306a36Sopenharmony_ci BUFFER_TRACE(bh, "free child branches"); 104962306a36Sopenharmony_ci ext4_free_branches(handle, inode, bh, 105062306a36Sopenharmony_ci (__le32 *) bh->b_data, 105162306a36Sopenharmony_ci (__le32 *) bh->b_data + addr_per_block, 105262306a36Sopenharmony_ci depth); 105362306a36Sopenharmony_ci brelse(bh); 105462306a36Sopenharmony_ci 105562306a36Sopenharmony_ci /* 105662306a36Sopenharmony_ci * Everything below this pointer has been 105762306a36Sopenharmony_ci * released. Now let this top-of-subtree go. 105862306a36Sopenharmony_ci * 105962306a36Sopenharmony_ci * We want the freeing of this indirect block to be 106062306a36Sopenharmony_ci * atomic in the journal with the updating of the 106162306a36Sopenharmony_ci * bitmap block which owns it. So make some room in 106262306a36Sopenharmony_ci * the journal. 106362306a36Sopenharmony_ci * 106462306a36Sopenharmony_ci * We zero the parent pointer *after* freeing its 106562306a36Sopenharmony_ci * pointee in the bitmaps, so if extend_transaction() 106662306a36Sopenharmony_ci * for some reason fails to put the bitmap changes and 106762306a36Sopenharmony_ci * the release into the same transaction, recovery 106862306a36Sopenharmony_ci * will merely complain about releasing a free block, 106962306a36Sopenharmony_ci * rather than leaking blocks. 107062306a36Sopenharmony_ci */ 107162306a36Sopenharmony_ci if (ext4_handle_is_aborted(handle)) 107262306a36Sopenharmony_ci return; 107362306a36Sopenharmony_ci if (ext4_ind_truncate_ensure_credits(handle, inode, 107462306a36Sopenharmony_ci NULL, 107562306a36Sopenharmony_ci ext4_free_metadata_revoke_credits( 107662306a36Sopenharmony_ci inode->i_sb, 1)) < 0) 107762306a36Sopenharmony_ci return; 107862306a36Sopenharmony_ci 107962306a36Sopenharmony_ci /* 108062306a36Sopenharmony_ci * The forget flag here is critical because if 108162306a36Sopenharmony_ci * we are journaling (and not doing data 108262306a36Sopenharmony_ci * journaling), we have to make sure a revoke 108362306a36Sopenharmony_ci * record is written to prevent the journal 108462306a36Sopenharmony_ci * replay from overwriting the (former) 108562306a36Sopenharmony_ci * indirect block if it gets reallocated as a 108662306a36Sopenharmony_ci * data block. This must happen in the same 108762306a36Sopenharmony_ci * transaction where the data blocks are 108862306a36Sopenharmony_ci * actually freed. 108962306a36Sopenharmony_ci */ 109062306a36Sopenharmony_ci ext4_free_blocks(handle, inode, NULL, nr, 1, 109162306a36Sopenharmony_ci EXT4_FREE_BLOCKS_METADATA| 109262306a36Sopenharmony_ci EXT4_FREE_BLOCKS_FORGET); 109362306a36Sopenharmony_ci 109462306a36Sopenharmony_ci if (parent_bh) { 109562306a36Sopenharmony_ci /* 109662306a36Sopenharmony_ci * The block which we have just freed is 109762306a36Sopenharmony_ci * pointed to by an indirect block: journal it 109862306a36Sopenharmony_ci */ 109962306a36Sopenharmony_ci BUFFER_TRACE(parent_bh, "get_write_access"); 110062306a36Sopenharmony_ci if (!ext4_journal_get_write_access(handle, 110162306a36Sopenharmony_ci inode->i_sb, parent_bh, 110262306a36Sopenharmony_ci EXT4_JTR_NONE)) { 110362306a36Sopenharmony_ci *p = 0; 110462306a36Sopenharmony_ci BUFFER_TRACE(parent_bh, 110562306a36Sopenharmony_ci "call ext4_handle_dirty_metadata"); 110662306a36Sopenharmony_ci ext4_handle_dirty_metadata(handle, 110762306a36Sopenharmony_ci inode, 110862306a36Sopenharmony_ci parent_bh); 110962306a36Sopenharmony_ci } 111062306a36Sopenharmony_ci } 111162306a36Sopenharmony_ci } 111262306a36Sopenharmony_ci } else { 111362306a36Sopenharmony_ci /* We have reached the bottom of the tree. */ 111462306a36Sopenharmony_ci BUFFER_TRACE(parent_bh, "free data blocks"); 111562306a36Sopenharmony_ci ext4_free_data(handle, inode, parent_bh, first, last); 111662306a36Sopenharmony_ci } 111762306a36Sopenharmony_ci} 111862306a36Sopenharmony_ci 111962306a36Sopenharmony_civoid ext4_ind_truncate(handle_t *handle, struct inode *inode) 112062306a36Sopenharmony_ci{ 112162306a36Sopenharmony_ci struct ext4_inode_info *ei = EXT4_I(inode); 112262306a36Sopenharmony_ci __le32 *i_data = ei->i_data; 112362306a36Sopenharmony_ci int addr_per_block = EXT4_ADDR_PER_BLOCK(inode->i_sb); 112462306a36Sopenharmony_ci ext4_lblk_t offsets[4]; 112562306a36Sopenharmony_ci Indirect chain[4]; 112662306a36Sopenharmony_ci Indirect *partial; 112762306a36Sopenharmony_ci __le32 nr = 0; 112862306a36Sopenharmony_ci int n = 0; 112962306a36Sopenharmony_ci ext4_lblk_t last_block, max_block; 113062306a36Sopenharmony_ci unsigned blocksize = inode->i_sb->s_blocksize; 113162306a36Sopenharmony_ci 113262306a36Sopenharmony_ci last_block = (inode->i_size + blocksize-1) 113362306a36Sopenharmony_ci >> EXT4_BLOCK_SIZE_BITS(inode->i_sb); 113462306a36Sopenharmony_ci max_block = (EXT4_SB(inode->i_sb)->s_bitmap_maxbytes + blocksize-1) 113562306a36Sopenharmony_ci >> EXT4_BLOCK_SIZE_BITS(inode->i_sb); 113662306a36Sopenharmony_ci 113762306a36Sopenharmony_ci if (last_block != max_block) { 113862306a36Sopenharmony_ci n = ext4_block_to_path(inode, last_block, offsets, NULL); 113962306a36Sopenharmony_ci if (n == 0) 114062306a36Sopenharmony_ci return; 114162306a36Sopenharmony_ci } 114262306a36Sopenharmony_ci 114362306a36Sopenharmony_ci ext4_es_remove_extent(inode, last_block, EXT_MAX_BLOCKS - last_block); 114462306a36Sopenharmony_ci 114562306a36Sopenharmony_ci /* 114662306a36Sopenharmony_ci * The orphan list entry will now protect us from any crash which 114762306a36Sopenharmony_ci * occurs before the truncate completes, so it is now safe to propagate 114862306a36Sopenharmony_ci * the new, shorter inode size (held for now in i_size) into the 114962306a36Sopenharmony_ci * on-disk inode. We do this via i_disksize, which is the value which 115062306a36Sopenharmony_ci * ext4 *really* writes onto the disk inode. 115162306a36Sopenharmony_ci */ 115262306a36Sopenharmony_ci ei->i_disksize = inode->i_size; 115362306a36Sopenharmony_ci 115462306a36Sopenharmony_ci if (last_block == max_block) { 115562306a36Sopenharmony_ci /* 115662306a36Sopenharmony_ci * It is unnecessary to free any data blocks if last_block is 115762306a36Sopenharmony_ci * equal to the indirect block limit. 115862306a36Sopenharmony_ci */ 115962306a36Sopenharmony_ci return; 116062306a36Sopenharmony_ci } else if (n == 1) { /* direct blocks */ 116162306a36Sopenharmony_ci ext4_free_data(handle, inode, NULL, i_data+offsets[0], 116262306a36Sopenharmony_ci i_data + EXT4_NDIR_BLOCKS); 116362306a36Sopenharmony_ci goto do_indirects; 116462306a36Sopenharmony_ci } 116562306a36Sopenharmony_ci 116662306a36Sopenharmony_ci partial = ext4_find_shared(inode, n, offsets, chain, &nr); 116762306a36Sopenharmony_ci /* Kill the top of shared branch (not detached) */ 116862306a36Sopenharmony_ci if (nr) { 116962306a36Sopenharmony_ci if (partial == chain) { 117062306a36Sopenharmony_ci /* Shared branch grows from the inode */ 117162306a36Sopenharmony_ci ext4_free_branches(handle, inode, NULL, 117262306a36Sopenharmony_ci &nr, &nr+1, (chain+n-1) - partial); 117362306a36Sopenharmony_ci *partial->p = 0; 117462306a36Sopenharmony_ci /* 117562306a36Sopenharmony_ci * We mark the inode dirty prior to restart, 117662306a36Sopenharmony_ci * and prior to stop. No need for it here. 117762306a36Sopenharmony_ci */ 117862306a36Sopenharmony_ci } else { 117962306a36Sopenharmony_ci /* Shared branch grows from an indirect block */ 118062306a36Sopenharmony_ci BUFFER_TRACE(partial->bh, "get_write_access"); 118162306a36Sopenharmony_ci ext4_free_branches(handle, inode, partial->bh, 118262306a36Sopenharmony_ci partial->p, 118362306a36Sopenharmony_ci partial->p+1, (chain+n-1) - partial); 118462306a36Sopenharmony_ci } 118562306a36Sopenharmony_ci } 118662306a36Sopenharmony_ci /* Clear the ends of indirect blocks on the shared branch */ 118762306a36Sopenharmony_ci while (partial > chain) { 118862306a36Sopenharmony_ci ext4_free_branches(handle, inode, partial->bh, partial->p + 1, 118962306a36Sopenharmony_ci (__le32*)partial->bh->b_data+addr_per_block, 119062306a36Sopenharmony_ci (chain+n-1) - partial); 119162306a36Sopenharmony_ci BUFFER_TRACE(partial->bh, "call brelse"); 119262306a36Sopenharmony_ci brelse(partial->bh); 119362306a36Sopenharmony_ci partial--; 119462306a36Sopenharmony_ci } 119562306a36Sopenharmony_cido_indirects: 119662306a36Sopenharmony_ci /* Kill the remaining (whole) subtrees */ 119762306a36Sopenharmony_ci switch (offsets[0]) { 119862306a36Sopenharmony_ci default: 119962306a36Sopenharmony_ci nr = i_data[EXT4_IND_BLOCK]; 120062306a36Sopenharmony_ci if (nr) { 120162306a36Sopenharmony_ci ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 1); 120262306a36Sopenharmony_ci i_data[EXT4_IND_BLOCK] = 0; 120362306a36Sopenharmony_ci } 120462306a36Sopenharmony_ci fallthrough; 120562306a36Sopenharmony_ci case EXT4_IND_BLOCK: 120662306a36Sopenharmony_ci nr = i_data[EXT4_DIND_BLOCK]; 120762306a36Sopenharmony_ci if (nr) { 120862306a36Sopenharmony_ci ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 2); 120962306a36Sopenharmony_ci i_data[EXT4_DIND_BLOCK] = 0; 121062306a36Sopenharmony_ci } 121162306a36Sopenharmony_ci fallthrough; 121262306a36Sopenharmony_ci case EXT4_DIND_BLOCK: 121362306a36Sopenharmony_ci nr = i_data[EXT4_TIND_BLOCK]; 121462306a36Sopenharmony_ci if (nr) { 121562306a36Sopenharmony_ci ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 3); 121662306a36Sopenharmony_ci i_data[EXT4_TIND_BLOCK] = 0; 121762306a36Sopenharmony_ci } 121862306a36Sopenharmony_ci fallthrough; 121962306a36Sopenharmony_ci case EXT4_TIND_BLOCK: 122062306a36Sopenharmony_ci ; 122162306a36Sopenharmony_ci } 122262306a36Sopenharmony_ci} 122362306a36Sopenharmony_ci 122462306a36Sopenharmony_ci/** 122562306a36Sopenharmony_ci * ext4_ind_remove_space - remove space from the range 122662306a36Sopenharmony_ci * @handle: JBD handle for this transaction 122762306a36Sopenharmony_ci * @inode: inode we are dealing with 122862306a36Sopenharmony_ci * @start: First block to remove 122962306a36Sopenharmony_ci * @end: One block after the last block to remove (exclusive) 123062306a36Sopenharmony_ci * 123162306a36Sopenharmony_ci * Free the blocks in the defined range (end is exclusive endpoint of 123262306a36Sopenharmony_ci * range). This is used by ext4_punch_hole(). 123362306a36Sopenharmony_ci */ 123462306a36Sopenharmony_ciint ext4_ind_remove_space(handle_t *handle, struct inode *inode, 123562306a36Sopenharmony_ci ext4_lblk_t start, ext4_lblk_t end) 123662306a36Sopenharmony_ci{ 123762306a36Sopenharmony_ci struct ext4_inode_info *ei = EXT4_I(inode); 123862306a36Sopenharmony_ci __le32 *i_data = ei->i_data; 123962306a36Sopenharmony_ci int addr_per_block = EXT4_ADDR_PER_BLOCK(inode->i_sb); 124062306a36Sopenharmony_ci ext4_lblk_t offsets[4], offsets2[4]; 124162306a36Sopenharmony_ci Indirect chain[4], chain2[4]; 124262306a36Sopenharmony_ci Indirect *partial, *partial2; 124362306a36Sopenharmony_ci Indirect *p = NULL, *p2 = NULL; 124462306a36Sopenharmony_ci ext4_lblk_t max_block; 124562306a36Sopenharmony_ci __le32 nr = 0, nr2 = 0; 124662306a36Sopenharmony_ci int n = 0, n2 = 0; 124762306a36Sopenharmony_ci unsigned blocksize = inode->i_sb->s_blocksize; 124862306a36Sopenharmony_ci 124962306a36Sopenharmony_ci max_block = (EXT4_SB(inode->i_sb)->s_bitmap_maxbytes + blocksize-1) 125062306a36Sopenharmony_ci >> EXT4_BLOCK_SIZE_BITS(inode->i_sb); 125162306a36Sopenharmony_ci if (end >= max_block) 125262306a36Sopenharmony_ci end = max_block; 125362306a36Sopenharmony_ci if ((start >= end) || (start > max_block)) 125462306a36Sopenharmony_ci return 0; 125562306a36Sopenharmony_ci 125662306a36Sopenharmony_ci n = ext4_block_to_path(inode, start, offsets, NULL); 125762306a36Sopenharmony_ci n2 = ext4_block_to_path(inode, end, offsets2, NULL); 125862306a36Sopenharmony_ci 125962306a36Sopenharmony_ci BUG_ON(n > n2); 126062306a36Sopenharmony_ci 126162306a36Sopenharmony_ci if ((n == 1) && (n == n2)) { 126262306a36Sopenharmony_ci /* We're punching only within direct block range */ 126362306a36Sopenharmony_ci ext4_free_data(handle, inode, NULL, i_data + offsets[0], 126462306a36Sopenharmony_ci i_data + offsets2[0]); 126562306a36Sopenharmony_ci return 0; 126662306a36Sopenharmony_ci } else if (n2 > n) { 126762306a36Sopenharmony_ci /* 126862306a36Sopenharmony_ci * Start and end are on a different levels so we're going to 126962306a36Sopenharmony_ci * free partial block at start, and partial block at end of 127062306a36Sopenharmony_ci * the range. If there are some levels in between then 127162306a36Sopenharmony_ci * do_indirects label will take care of that. 127262306a36Sopenharmony_ci */ 127362306a36Sopenharmony_ci 127462306a36Sopenharmony_ci if (n == 1) { 127562306a36Sopenharmony_ci /* 127662306a36Sopenharmony_ci * Start is at the direct block level, free 127762306a36Sopenharmony_ci * everything to the end of the level. 127862306a36Sopenharmony_ci */ 127962306a36Sopenharmony_ci ext4_free_data(handle, inode, NULL, i_data + offsets[0], 128062306a36Sopenharmony_ci i_data + EXT4_NDIR_BLOCKS); 128162306a36Sopenharmony_ci goto end_range; 128262306a36Sopenharmony_ci } 128362306a36Sopenharmony_ci 128462306a36Sopenharmony_ci 128562306a36Sopenharmony_ci partial = p = ext4_find_shared(inode, n, offsets, chain, &nr); 128662306a36Sopenharmony_ci if (nr) { 128762306a36Sopenharmony_ci if (partial == chain) { 128862306a36Sopenharmony_ci /* Shared branch grows from the inode */ 128962306a36Sopenharmony_ci ext4_free_branches(handle, inode, NULL, 129062306a36Sopenharmony_ci &nr, &nr+1, (chain+n-1) - partial); 129162306a36Sopenharmony_ci *partial->p = 0; 129262306a36Sopenharmony_ci } else { 129362306a36Sopenharmony_ci /* Shared branch grows from an indirect block */ 129462306a36Sopenharmony_ci BUFFER_TRACE(partial->bh, "get_write_access"); 129562306a36Sopenharmony_ci ext4_free_branches(handle, inode, partial->bh, 129662306a36Sopenharmony_ci partial->p, 129762306a36Sopenharmony_ci partial->p+1, (chain+n-1) - partial); 129862306a36Sopenharmony_ci } 129962306a36Sopenharmony_ci } 130062306a36Sopenharmony_ci 130162306a36Sopenharmony_ci /* 130262306a36Sopenharmony_ci * Clear the ends of indirect blocks on the shared branch 130362306a36Sopenharmony_ci * at the start of the range 130462306a36Sopenharmony_ci */ 130562306a36Sopenharmony_ci while (partial > chain) { 130662306a36Sopenharmony_ci ext4_free_branches(handle, inode, partial->bh, 130762306a36Sopenharmony_ci partial->p + 1, 130862306a36Sopenharmony_ci (__le32 *)partial->bh->b_data+addr_per_block, 130962306a36Sopenharmony_ci (chain+n-1) - partial); 131062306a36Sopenharmony_ci partial--; 131162306a36Sopenharmony_ci } 131262306a36Sopenharmony_ci 131362306a36Sopenharmony_ciend_range: 131462306a36Sopenharmony_ci partial2 = p2 = ext4_find_shared(inode, n2, offsets2, chain2, &nr2); 131562306a36Sopenharmony_ci if (nr2) { 131662306a36Sopenharmony_ci if (partial2 == chain2) { 131762306a36Sopenharmony_ci /* 131862306a36Sopenharmony_ci * Remember, end is exclusive so here we're at 131962306a36Sopenharmony_ci * the start of the next level we're not going 132062306a36Sopenharmony_ci * to free. Everything was covered by the start 132162306a36Sopenharmony_ci * of the range. 132262306a36Sopenharmony_ci */ 132362306a36Sopenharmony_ci goto do_indirects; 132462306a36Sopenharmony_ci } 132562306a36Sopenharmony_ci } else { 132662306a36Sopenharmony_ci /* 132762306a36Sopenharmony_ci * ext4_find_shared returns Indirect structure which 132862306a36Sopenharmony_ci * points to the last element which should not be 132962306a36Sopenharmony_ci * removed by truncate. But this is end of the range 133062306a36Sopenharmony_ci * in punch_hole so we need to point to the next element 133162306a36Sopenharmony_ci */ 133262306a36Sopenharmony_ci partial2->p++; 133362306a36Sopenharmony_ci } 133462306a36Sopenharmony_ci 133562306a36Sopenharmony_ci /* 133662306a36Sopenharmony_ci * Clear the ends of indirect blocks on the shared branch 133762306a36Sopenharmony_ci * at the end of the range 133862306a36Sopenharmony_ci */ 133962306a36Sopenharmony_ci while (partial2 > chain2) { 134062306a36Sopenharmony_ci ext4_free_branches(handle, inode, partial2->bh, 134162306a36Sopenharmony_ci (__le32 *)partial2->bh->b_data, 134262306a36Sopenharmony_ci partial2->p, 134362306a36Sopenharmony_ci (chain2+n2-1) - partial2); 134462306a36Sopenharmony_ci partial2--; 134562306a36Sopenharmony_ci } 134662306a36Sopenharmony_ci goto do_indirects; 134762306a36Sopenharmony_ci } 134862306a36Sopenharmony_ci 134962306a36Sopenharmony_ci /* Punch happened within the same level (n == n2) */ 135062306a36Sopenharmony_ci partial = p = ext4_find_shared(inode, n, offsets, chain, &nr); 135162306a36Sopenharmony_ci partial2 = p2 = ext4_find_shared(inode, n2, offsets2, chain2, &nr2); 135262306a36Sopenharmony_ci 135362306a36Sopenharmony_ci /* Free top, but only if partial2 isn't its subtree. */ 135462306a36Sopenharmony_ci if (nr) { 135562306a36Sopenharmony_ci int level = min(partial - chain, partial2 - chain2); 135662306a36Sopenharmony_ci int i; 135762306a36Sopenharmony_ci int subtree = 1; 135862306a36Sopenharmony_ci 135962306a36Sopenharmony_ci for (i = 0; i <= level; i++) { 136062306a36Sopenharmony_ci if (offsets[i] != offsets2[i]) { 136162306a36Sopenharmony_ci subtree = 0; 136262306a36Sopenharmony_ci break; 136362306a36Sopenharmony_ci } 136462306a36Sopenharmony_ci } 136562306a36Sopenharmony_ci 136662306a36Sopenharmony_ci if (!subtree) { 136762306a36Sopenharmony_ci if (partial == chain) { 136862306a36Sopenharmony_ci /* Shared branch grows from the inode */ 136962306a36Sopenharmony_ci ext4_free_branches(handle, inode, NULL, 137062306a36Sopenharmony_ci &nr, &nr+1, 137162306a36Sopenharmony_ci (chain+n-1) - partial); 137262306a36Sopenharmony_ci *partial->p = 0; 137362306a36Sopenharmony_ci } else { 137462306a36Sopenharmony_ci /* Shared branch grows from an indirect block */ 137562306a36Sopenharmony_ci BUFFER_TRACE(partial->bh, "get_write_access"); 137662306a36Sopenharmony_ci ext4_free_branches(handle, inode, partial->bh, 137762306a36Sopenharmony_ci partial->p, 137862306a36Sopenharmony_ci partial->p+1, 137962306a36Sopenharmony_ci (chain+n-1) - partial); 138062306a36Sopenharmony_ci } 138162306a36Sopenharmony_ci } 138262306a36Sopenharmony_ci } 138362306a36Sopenharmony_ci 138462306a36Sopenharmony_ci if (!nr2) { 138562306a36Sopenharmony_ci /* 138662306a36Sopenharmony_ci * ext4_find_shared returns Indirect structure which 138762306a36Sopenharmony_ci * points to the last element which should not be 138862306a36Sopenharmony_ci * removed by truncate. But this is end of the range 138962306a36Sopenharmony_ci * in punch_hole so we need to point to the next element 139062306a36Sopenharmony_ci */ 139162306a36Sopenharmony_ci partial2->p++; 139262306a36Sopenharmony_ci } 139362306a36Sopenharmony_ci 139462306a36Sopenharmony_ci while (partial > chain || partial2 > chain2) { 139562306a36Sopenharmony_ci int depth = (chain+n-1) - partial; 139662306a36Sopenharmony_ci int depth2 = (chain2+n2-1) - partial2; 139762306a36Sopenharmony_ci 139862306a36Sopenharmony_ci if (partial > chain && partial2 > chain2 && 139962306a36Sopenharmony_ci partial->bh->b_blocknr == partial2->bh->b_blocknr) { 140062306a36Sopenharmony_ci /* 140162306a36Sopenharmony_ci * We've converged on the same block. Clear the range, 140262306a36Sopenharmony_ci * then we're done. 140362306a36Sopenharmony_ci */ 140462306a36Sopenharmony_ci ext4_free_branches(handle, inode, partial->bh, 140562306a36Sopenharmony_ci partial->p + 1, 140662306a36Sopenharmony_ci partial2->p, 140762306a36Sopenharmony_ci (chain+n-1) - partial); 140862306a36Sopenharmony_ci goto cleanup; 140962306a36Sopenharmony_ci } 141062306a36Sopenharmony_ci 141162306a36Sopenharmony_ci /* 141262306a36Sopenharmony_ci * The start and end partial branches may not be at the same 141362306a36Sopenharmony_ci * level even though the punch happened within one level. So, we 141462306a36Sopenharmony_ci * give them a chance to arrive at the same level, then walk 141562306a36Sopenharmony_ci * them in step with each other until we converge on the same 141662306a36Sopenharmony_ci * block. 141762306a36Sopenharmony_ci */ 141862306a36Sopenharmony_ci if (partial > chain && depth <= depth2) { 141962306a36Sopenharmony_ci ext4_free_branches(handle, inode, partial->bh, 142062306a36Sopenharmony_ci partial->p + 1, 142162306a36Sopenharmony_ci (__le32 *)partial->bh->b_data+addr_per_block, 142262306a36Sopenharmony_ci (chain+n-1) - partial); 142362306a36Sopenharmony_ci partial--; 142462306a36Sopenharmony_ci } 142562306a36Sopenharmony_ci if (partial2 > chain2 && depth2 <= depth) { 142662306a36Sopenharmony_ci ext4_free_branches(handle, inode, partial2->bh, 142762306a36Sopenharmony_ci (__le32 *)partial2->bh->b_data, 142862306a36Sopenharmony_ci partial2->p, 142962306a36Sopenharmony_ci (chain2+n2-1) - partial2); 143062306a36Sopenharmony_ci partial2--; 143162306a36Sopenharmony_ci } 143262306a36Sopenharmony_ci } 143362306a36Sopenharmony_ci 143462306a36Sopenharmony_cicleanup: 143562306a36Sopenharmony_ci while (p && p > chain) { 143662306a36Sopenharmony_ci BUFFER_TRACE(p->bh, "call brelse"); 143762306a36Sopenharmony_ci brelse(p->bh); 143862306a36Sopenharmony_ci p--; 143962306a36Sopenharmony_ci } 144062306a36Sopenharmony_ci while (p2 && p2 > chain2) { 144162306a36Sopenharmony_ci BUFFER_TRACE(p2->bh, "call brelse"); 144262306a36Sopenharmony_ci brelse(p2->bh); 144362306a36Sopenharmony_ci p2--; 144462306a36Sopenharmony_ci } 144562306a36Sopenharmony_ci return 0; 144662306a36Sopenharmony_ci 144762306a36Sopenharmony_cido_indirects: 144862306a36Sopenharmony_ci /* Kill the remaining (whole) subtrees */ 144962306a36Sopenharmony_ci switch (offsets[0]) { 145062306a36Sopenharmony_ci default: 145162306a36Sopenharmony_ci if (++n >= n2) 145262306a36Sopenharmony_ci break; 145362306a36Sopenharmony_ci nr = i_data[EXT4_IND_BLOCK]; 145462306a36Sopenharmony_ci if (nr) { 145562306a36Sopenharmony_ci ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 1); 145662306a36Sopenharmony_ci i_data[EXT4_IND_BLOCK] = 0; 145762306a36Sopenharmony_ci } 145862306a36Sopenharmony_ci fallthrough; 145962306a36Sopenharmony_ci case EXT4_IND_BLOCK: 146062306a36Sopenharmony_ci if (++n >= n2) 146162306a36Sopenharmony_ci break; 146262306a36Sopenharmony_ci nr = i_data[EXT4_DIND_BLOCK]; 146362306a36Sopenharmony_ci if (nr) { 146462306a36Sopenharmony_ci ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 2); 146562306a36Sopenharmony_ci i_data[EXT4_DIND_BLOCK] = 0; 146662306a36Sopenharmony_ci } 146762306a36Sopenharmony_ci fallthrough; 146862306a36Sopenharmony_ci case EXT4_DIND_BLOCK: 146962306a36Sopenharmony_ci if (++n >= n2) 147062306a36Sopenharmony_ci break; 147162306a36Sopenharmony_ci nr = i_data[EXT4_TIND_BLOCK]; 147262306a36Sopenharmony_ci if (nr) { 147362306a36Sopenharmony_ci ext4_free_branches(handle, inode, NULL, &nr, &nr+1, 3); 147462306a36Sopenharmony_ci i_data[EXT4_TIND_BLOCK] = 0; 147562306a36Sopenharmony_ci } 147662306a36Sopenharmony_ci fallthrough; 147762306a36Sopenharmony_ci case EXT4_TIND_BLOCK: 147862306a36Sopenharmony_ci ; 147962306a36Sopenharmony_ci } 148062306a36Sopenharmony_ci goto cleanup; 148162306a36Sopenharmony_ci} 1482