1ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/*
2ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross * Copyright (C) 2010 The Android Open Source Project
3ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross *
4ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross * Licensed under the Apache License, Version 2.0 (the "License");
5ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross * you may not use this file except in compliance with the License.
6ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross * You may obtain a copy of the License at
7ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross *
8ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross *      http://www.apache.org/licenses/LICENSE-2.0
9ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross *
10ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross * Unless required by applicable law or agreed to in writing, software
11ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross * distributed under the License is distributed on an "AS IS" BASIS,
12ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross * See the License for the specific language governing permissions and
14ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross * limitations under the License.
15ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross */
16ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
17ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross#include "ext4_utils.h"
18ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross#include "ext4.h"
19ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross#include "ext4_extents.h"
20ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross#include "indirect.h"
21ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross#include "allocate.h"
22ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
23dc5abeee1e6fc4827ee0d5ece12aaed2dd56f4c7Colin Cross#include <sparse/sparse.h>
24dc5abeee1e6fc4827ee0d5ece12aaed2dd56f4c7Colin Cross
2533f96c66e9a1f2e266a75e5e84c091dffa6ef118Colin Cross#include <stdlib.h>
2633f96c66e9a1f2e266a75e5e84c091dffa6ef118Colin Cross#include <stdio.h>
2733f96c66e9a1f2e266a75e5e84c091dffa6ef118Colin Cross
28ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/* Creates data buffers for the first backing_len bytes of a block allocation
29ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   and queues them to be written */
30ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic u8 *create_backing(struct block_allocation *alloc,
31ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		unsigned long backing_len)
32ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
33ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (DIV_ROUND_UP(backing_len, info.block_size) > EXT4_NDIR_BLOCKS)
34ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		critical_error("indirect backing larger than %d blocks", EXT4_NDIR_BLOCKS);
35ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
36ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u8 *data = calloc(backing_len, 1);
37ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (!data)
38ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		critical_error_errno("calloc");
39ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
40ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u8 *ptr = data;
41ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	for (; alloc != NULL && backing_len > 0; get_next_region(alloc)) {
42ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		u32 region_block;
43ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		u32 region_len;
44ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		u32 len;
45ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		get_region(alloc, &region_block, &region_len);
46ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
47ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		len = min(region_len * info.block_size, backing_len);
48ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
49f0ee37ffded79afdb03e15ae3a69969d2b7e6079Colin Cross		sparse_file_add_data(info.sparse_file, ptr, len, region_block);
50ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		ptr += len;
51ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		backing_len -= len;
52ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
53ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
54ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	return data;
55ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
56ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
57ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic void reserve_indirect_block(struct block_allocation *alloc, int len)
58ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
59ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (reserve_oob_blocks(alloc, 1)) {
608aef66d2125af8de7672a12895276802fcc1948fColin Cross		error("failed to reserve oob block");
618aef66d2125af8de7672a12895276802fcc1948fColin Cross		return;
628aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
63ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
64ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (advance_blocks(alloc, len)) {
65ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		error("failed to advance %d blocks", len);
66ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return;
67ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
68ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
69ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
70ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic void reserve_dindirect_block(struct block_allocation *alloc, int len)
71ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
72ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (reserve_oob_blocks(alloc, 1)) {
738aef66d2125af8de7672a12895276802fcc1948fColin Cross		error("failed to reserve oob block");
748aef66d2125af8de7672a12895276802fcc1948fColin Cross		return;
758aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
76ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
77ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	while (len > 0) {
78ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		int ind_block_len = min((int)aux_info.blocks_per_ind, len);
79ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
80ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		reserve_indirect_block(alloc, ind_block_len);
81ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
82ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		len -= ind_block_len;
83ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
84ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
85ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
86ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
87ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic void reserve_tindirect_block(struct block_allocation *alloc, int len)
88ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
89ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (reserve_oob_blocks(alloc, 1)) {
908aef66d2125af8de7672a12895276802fcc1948fColin Cross		error("failed to reserve oob block");
918aef66d2125af8de7672a12895276802fcc1948fColin Cross		return;
928aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
93ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
94ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	while (len > 0) {
95ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		int dind_block_len = min((int)aux_info.blocks_per_dind, len);
96ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
97ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		reserve_dindirect_block(alloc, dind_block_len);
98ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
99ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		len -= dind_block_len;
100ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
101ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
102ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
103ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic void fill_indirect_block(u32 *ind_block, int len, struct block_allocation *alloc)
104ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
105ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int i;
106ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	for (i = 0; i < len; i++) {
107ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		ind_block[i] = get_block(alloc, i);
108ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
109ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
110ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
111ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic void fill_dindirect_block(u32 *dind_block, int len, struct block_allocation *alloc)
112ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
113ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int i;
114ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 ind_block;
115ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
116ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	for (i = 0; len >  0; i++) {
117ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		ind_block = get_oob_block(alloc, 0);
118ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		if (advance_oob_blocks(alloc, 1)) {
1198aef66d2125af8de7672a12895276802fcc1948fColin Cross			error("failed to reserve oob block");
1208aef66d2125af8de7672a12895276802fcc1948fColin Cross			return;
1218aef66d2125af8de7672a12895276802fcc1948fColin Cross		}
122ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
123ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		dind_block[i] = ind_block;
124ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
125ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		u32 *ind_block_data = calloc(info.block_size, 1);
126f0ee37ffded79afdb03e15ae3a69969d2b7e6079Colin Cross		sparse_file_add_data(info.sparse_file, ind_block_data, info.block_size,
127f0ee37ffded79afdb03e15ae3a69969d2b7e6079Colin Cross				ind_block);
128ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		int ind_block_len = min((int)aux_info.blocks_per_ind, len);
129ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
130ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		fill_indirect_block(ind_block_data, ind_block_len, alloc);
131ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
132ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		if (advance_blocks(alloc, ind_block_len)) {
133ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross			error("failed to advance %d blocks", ind_block_len);
134ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross			return;
135ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		}
136ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
137ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		len -= ind_block_len;
138ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
139ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
140ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
141ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic void fill_tindirect_block(u32 *tind_block, int len, struct block_allocation *alloc)
142ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
143ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int i;
144ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 dind_block;
145ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
146ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	for (i = 0; len > 0; i++) {
147ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		dind_block = get_oob_block(alloc, 0);
148ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		if (advance_oob_blocks(alloc, 1)) {
1498aef66d2125af8de7672a12895276802fcc1948fColin Cross			error("failed to reserve oob block");
1508aef66d2125af8de7672a12895276802fcc1948fColin Cross			return;
1518aef66d2125af8de7672a12895276802fcc1948fColin Cross		}
152ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
1538aef66d2125af8de7672a12895276802fcc1948fColin Cross		tind_block[i] = dind_block;
154ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
155ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		u32 *dind_block_data = calloc(info.block_size, 1);
156f0ee37ffded79afdb03e15ae3a69969d2b7e6079Colin Cross		sparse_file_add_data(info.sparse_file, dind_block_data, info.block_size,
157f0ee37ffded79afdb03e15ae3a69969d2b7e6079Colin Cross				dind_block);
158ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		int dind_block_len = min((int)aux_info.blocks_per_dind, len);
159ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
160ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		fill_dindirect_block(dind_block_data, dind_block_len, alloc);
161ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
1628aef66d2125af8de7672a12895276802fcc1948fColin Cross		len -= dind_block_len;
163ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
164ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
165ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
166ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/* Given an allocation, attach as many blocks as possible to direct inode
167ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   blocks, and return the rest */
168ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic int inode_attach_direct_blocks(struct ext4_inode *inode,
169ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		struct block_allocation *alloc, u32 *block_len)
170ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
171ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int len = min(*block_len, EXT4_NDIR_BLOCKS);
172ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int i;
173ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
174ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	for (i = 0; i < len; i++) {
175ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		inode->i_block[i] = get_block(alloc, i);
176ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
177ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
1788aef66d2125af8de7672a12895276802fcc1948fColin Cross	if (advance_blocks(alloc, len)) {
1798aef66d2125af8de7672a12895276802fcc1948fColin Cross		error("failed to advance %d blocks", len);
1808aef66d2125af8de7672a12895276802fcc1948fColin Cross		return -1;
1818aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
182ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
1838aef66d2125af8de7672a12895276802fcc1948fColin Cross	*block_len -= len;
1848aef66d2125af8de7672a12895276802fcc1948fColin Cross	return 0;
185ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
186ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
187ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/* Given an allocation, attach as many blocks as possible to indirect blocks,
188ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   and return the rest
189ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   Assumes that the blocks necessary to hold the indirect blocks were included
190ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   as part of the allocation */
191ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic int inode_attach_indirect_blocks(struct ext4_inode *inode,
192ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		struct block_allocation *alloc, u32 *block_len)
193ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
194ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int len = min(*block_len, aux_info.blocks_per_ind);
195ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
196ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int ind_block = get_oob_block(alloc, 0);
197ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_block[EXT4_IND_BLOCK] = ind_block;
198ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
1998aef66d2125af8de7672a12895276802fcc1948fColin Cross	if (advance_oob_blocks(alloc, 1)) {
2008aef66d2125af8de7672a12895276802fcc1948fColin Cross		error("failed to advance oob block");
2018aef66d2125af8de7672a12895276802fcc1948fColin Cross		return -1;
2028aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
203ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
204ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 *ind_block_data = calloc(info.block_size, 1);
205f0ee37ffded79afdb03e15ae3a69969d2b7e6079Colin Cross	sparse_file_add_data(info.sparse_file, ind_block_data, info.block_size,
206f0ee37ffded79afdb03e15ae3a69969d2b7e6079Colin Cross			ind_block);
207ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
208ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	fill_indirect_block(ind_block_data, len, alloc);
209ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
2108aef66d2125af8de7672a12895276802fcc1948fColin Cross	if (advance_blocks(alloc, len)) {
2118aef66d2125af8de7672a12895276802fcc1948fColin Cross		error("failed to advance %d blocks", len);
2128aef66d2125af8de7672a12895276802fcc1948fColin Cross		return -1;
2138aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
214ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
2158aef66d2125af8de7672a12895276802fcc1948fColin Cross	*block_len -= len;
2168aef66d2125af8de7672a12895276802fcc1948fColin Cross	return 0;
217ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
218ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
219ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/* Given an allocation, attach as many blocks as possible to doubly indirect
220ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   blocks, and return the rest.
221ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   Assumes that the blocks necessary to hold the indirect and doubly indirect
222ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   blocks were included as part of the allocation */
223ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic int inode_attach_dindirect_blocks(struct ext4_inode *inode,
224ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		struct block_allocation *alloc, u32 *block_len)
225ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
226ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int len = min(*block_len, aux_info.blocks_per_dind);
227ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
228ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int dind_block = get_oob_block(alloc, 0);
229ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_block[EXT4_DIND_BLOCK] = dind_block;
230ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
2318aef66d2125af8de7672a12895276802fcc1948fColin Cross	if (advance_oob_blocks(alloc, 1)) {
2328aef66d2125af8de7672a12895276802fcc1948fColin Cross		error("failed to advance oob block");
2338aef66d2125af8de7672a12895276802fcc1948fColin Cross		return -1;
2348aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
235ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
236ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 *dind_block_data = calloc(info.block_size, 1);
237f0ee37ffded79afdb03e15ae3a69969d2b7e6079Colin Cross	sparse_file_add_data(info.sparse_file, dind_block_data, info.block_size,
238f0ee37ffded79afdb03e15ae3a69969d2b7e6079Colin Cross			dind_block);
239ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
240ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	fill_dindirect_block(dind_block_data, len, alloc);
241ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
2428aef66d2125af8de7672a12895276802fcc1948fColin Cross	if (advance_blocks(alloc, len)) {
2438aef66d2125af8de7672a12895276802fcc1948fColin Cross		error("failed to advance %d blocks", len);
2448aef66d2125af8de7672a12895276802fcc1948fColin Cross		return -1;
2458aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
246ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
2478aef66d2125af8de7672a12895276802fcc1948fColin Cross	*block_len -= len;
248ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	return 0;
249ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
250ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
251ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/* Given an allocation, attach as many blocks as possible to triply indirect
252ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   blocks, and return the rest.
253ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   Assumes that the blocks necessary to hold the indirect, doubly indirect and
254ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   triply indirect blocks were included as part of the allocation */
255ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic int inode_attach_tindirect_blocks(struct ext4_inode *inode,
256ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		struct block_allocation *alloc, u32 *block_len)
257ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
258ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int len = min(*block_len, aux_info.blocks_per_tind);
259ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
260ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int tind_block = get_oob_block(alloc, 0);
261ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_block[EXT4_TIND_BLOCK] = tind_block;
262ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
2638aef66d2125af8de7672a12895276802fcc1948fColin Cross	if (advance_oob_blocks(alloc, 1)) {
2648aef66d2125af8de7672a12895276802fcc1948fColin Cross		error("failed to advance oob block");
2658aef66d2125af8de7672a12895276802fcc1948fColin Cross		return -1;
2668aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
267ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
268ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 *tind_block_data = calloc(info.block_size, 1);
269f0ee37ffded79afdb03e15ae3a69969d2b7e6079Colin Cross	sparse_file_add_data(info.sparse_file, tind_block_data, info.block_size,
270f0ee37ffded79afdb03e15ae3a69969d2b7e6079Colin Cross			tind_block);
271ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
272ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	fill_tindirect_block(tind_block_data, len, alloc);
273ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
2748aef66d2125af8de7672a12895276802fcc1948fColin Cross	if (advance_blocks(alloc, len)) {
2758aef66d2125af8de7672a12895276802fcc1948fColin Cross		error("failed to advance %d blocks", len);
2768aef66d2125af8de7672a12895276802fcc1948fColin Cross		return -1;
2778aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
278ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
2798aef66d2125af8de7672a12895276802fcc1948fColin Cross	*block_len -= len;
2808aef66d2125af8de7672a12895276802fcc1948fColin Cross	return 0;
281ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
282ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
283ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic void reserve_all_indirect_blocks(struct block_allocation *alloc, u32 len)
284ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
285ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (len <= EXT4_NDIR_BLOCKS)
286ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return;
287ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
288ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	len -= EXT4_NDIR_BLOCKS;
289ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	advance_blocks(alloc, EXT4_NDIR_BLOCKS);
290ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
291ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 ind_block_len = min(aux_info.blocks_per_ind, len);
292ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	reserve_indirect_block(alloc, ind_block_len);
293ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
294ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	len -= ind_block_len;
295ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (len == 0)
296ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return;
297ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
298ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 dind_block_len = min(aux_info.blocks_per_dind, len);
299ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	reserve_dindirect_block(alloc, dind_block_len);
300ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
301ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	len -= dind_block_len;
302ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (len == 0)
303ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return;
304ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
305ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 tind_block_len = min(aux_info.blocks_per_tind, len);
306ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	reserve_tindirect_block(alloc, tind_block_len);
307ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
308ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	len -= tind_block_len;
309ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (len == 0)
310ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return;
311ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
312ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	error("%d blocks remaining", len);
313ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
314ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
315ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic u32 indirect_blocks_needed(u32 len)
316ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
317ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 ind = 0;
318ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
319ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (len <= EXT4_NDIR_BLOCKS)
320ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return ind;
321ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
322ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	len -= EXT4_NDIR_BLOCKS;
323ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
324ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	/* We will need an indirect block for the rest of the blocks */
325ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	ind += DIV_ROUND_UP(len, aux_info.blocks_per_ind);
326ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
327ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (len <= aux_info.blocks_per_ind)
328ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return ind;
329ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
330ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	len -= aux_info.blocks_per_ind;
331ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
332ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	ind += DIV_ROUND_UP(len, aux_info.blocks_per_dind);
333ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
334ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (len <= aux_info.blocks_per_dind)
335ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return ind;
336ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
337ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	len -= aux_info.blocks_per_dind;
338ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
339ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	ind += DIV_ROUND_UP(len, aux_info.blocks_per_tind);
340ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
341ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (len <= aux_info.blocks_per_tind)
342ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return ind;
343ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
344ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	critical_error("request too large");
345ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	return 0;
346ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
347ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
348ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic int do_inode_attach_indirect(struct ext4_inode *inode,
349ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		struct block_allocation *alloc, u32 block_len)
350ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
351ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 count = block_len;
352ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
353ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (inode_attach_direct_blocks(inode, alloc, &count)) {
354ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		error("failed to attach direct blocks to inode");
355ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return -1;
356ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
357ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
358ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (count > 0) {
3598aef66d2125af8de7672a12895276802fcc1948fColin Cross		if (inode_attach_indirect_blocks(inode, alloc, &count)) {
3608aef66d2125af8de7672a12895276802fcc1948fColin Cross			error("failed to attach indirect blocks to inode");
3618aef66d2125af8de7672a12895276802fcc1948fColin Cross			return -1;
3628aef66d2125af8de7672a12895276802fcc1948fColin Cross		}
3638aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
3648aef66d2125af8de7672a12895276802fcc1948fColin Cross
3658aef66d2125af8de7672a12895276802fcc1948fColin Cross	if (count > 0) {
3668aef66d2125af8de7672a12895276802fcc1948fColin Cross		if (inode_attach_dindirect_blocks(inode, alloc, &count)) {
3678aef66d2125af8de7672a12895276802fcc1948fColin Cross			error("failed to attach dindirect blocks to inode");
3688aef66d2125af8de7672a12895276802fcc1948fColin Cross			return -1;
3698aef66d2125af8de7672a12895276802fcc1948fColin Cross		}
370ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
371ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
3728aef66d2125af8de7672a12895276802fcc1948fColin Cross	if (count > 0) {
3738aef66d2125af8de7672a12895276802fcc1948fColin Cross		if (inode_attach_tindirect_blocks(inode, alloc, &count)) {
3748aef66d2125af8de7672a12895276802fcc1948fColin Cross			error("failed to attach tindirect blocks to inode");
3758aef66d2125af8de7672a12895276802fcc1948fColin Cross			return -1;
3768aef66d2125af8de7672a12895276802fcc1948fColin Cross		}
3778aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
3788aef66d2125af8de7672a12895276802fcc1948fColin Cross
3798aef66d2125af8de7672a12895276802fcc1948fColin Cross	if (count) {
380ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		error("blocks left after triply-indirect allocation");
381ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return -1;
3828aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
383ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
384ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	rewind_alloc(alloc);
385ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
386ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	return 0;
387ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
388ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
389ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic struct block_allocation *do_inode_allocate_indirect(
390ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		struct ext4_inode *inode, u32 block_len)
391ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
392ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 indirect_len = indirect_blocks_needed(block_len);
393ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
394ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	struct block_allocation *alloc = allocate_blocks(block_len + indirect_len);
395ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
396ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (alloc == NULL) {
397ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		error("Failed to allocate %d blocks", block_len + indirect_len);
398ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return NULL;
399ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
400ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
401ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	return alloc;
402ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
403ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
404ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/* Allocates enough blocks to hold len bytes and connects them to an inode */
405ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossvoid inode_allocate_indirect(struct ext4_inode *inode, unsigned long len)
406ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
407ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	struct block_allocation *alloc;
408ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 block_len = DIV_ROUND_UP(len, info.block_size);
409ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 indirect_len = indirect_blocks_needed(block_len);
410ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
411ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	alloc = do_inode_allocate_indirect(inode, block_len);
412ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (alloc == NULL) {
413ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		error("failed to allocate extents for %lu bytes", len);
414ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return;
415ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
416ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
417ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	reserve_all_indirect_blocks(alloc, block_len);
418ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	rewind_alloc(alloc);
419ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
420ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (do_inode_attach_indirect(inode, alloc, block_len))
421ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		error("failed to attach blocks to indirect inode");
422ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
423ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_flags = 0;
424ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_blocks_lo = (block_len + indirect_len) * info.block_size / 512;
425ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_size_lo = len;
426ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
427ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	free_alloc(alloc);
428ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
429ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
430ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossvoid inode_attach_resize(struct ext4_inode *inode,
431ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		struct block_allocation *alloc)
432ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
433ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 block_len = block_allocation_len(alloc);
43422742ce739a046a079b2e1b03342a25472dfa352Colin Cross	u32 superblocks = block_len / info.bg_desc_reserve_blocks;
435ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 i, j;
436ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u64 blocks;
437ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u64 size;
438ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
43922742ce739a046a079b2e1b03342a25472dfa352Colin Cross	if (block_len % info.bg_desc_reserve_blocks)
440ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		critical_error("reserved blocks not a multiple of %d",
44122742ce739a046a079b2e1b03342a25472dfa352Colin Cross				info.bg_desc_reserve_blocks);
442ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
443ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	append_oob_allocation(alloc, 1);
444ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 dind_block = get_oob_block(alloc, 0);
445ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
446ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 *dind_block_data = calloc(info.block_size, 1);
447ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (!dind_block_data)
448ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		critical_error_errno("calloc");
449f0ee37ffded79afdb03e15ae3a69969d2b7e6079Colin Cross	sparse_file_add_data(info.sparse_file, dind_block_data, info.block_size,
450f0ee37ffded79afdb03e15ae3a69969d2b7e6079Colin Cross			dind_block);
451ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
45222742ce739a046a079b2e1b03342a25472dfa352Colin Cross	u32 *ind_block_data = calloc(info.block_size, info.bg_desc_reserve_blocks);
453ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (!ind_block_data)
454ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		critical_error_errno("calloc");
455f0ee37ffded79afdb03e15ae3a69969d2b7e6079Colin Cross	sparse_file_add_data(info.sparse_file, ind_block_data,
45622742ce739a046a079b2e1b03342a25472dfa352Colin Cross			info.block_size * info.bg_desc_reserve_blocks,
457ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross			get_block(alloc, 0));
458ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
45922742ce739a046a079b2e1b03342a25472dfa352Colin Cross	for (i = 0; i < info.bg_desc_reserve_blocks; i++) {
46022742ce739a046a079b2e1b03342a25472dfa352Colin Cross		int r = (i - aux_info.bg_desc_blocks) % info.bg_desc_reserve_blocks;
461ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		if (r < 0)
46222742ce739a046a079b2e1b03342a25472dfa352Colin Cross			r += info.bg_desc_reserve_blocks;
463ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
464ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		dind_block_data[i] = get_block(alloc, r);
465ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
466ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		for (j = 1; j < superblocks; j++) {
46722742ce739a046a079b2e1b03342a25472dfa352Colin Cross			u32 b = j * info.bg_desc_reserve_blocks + r;
468ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross			ind_block_data[r * aux_info.blocks_per_ind + j - 1] = get_block(alloc, b);
469ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		}
470ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
471ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
472ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 last_block = EXT4_NDIR_BLOCKS + aux_info.blocks_per_ind +
47322742ce739a046a079b2e1b03342a25472dfa352Colin Cross			aux_info.blocks_per_ind * (info.bg_desc_reserve_blocks - 1) +
474ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross			superblocks - 2;
475ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
476ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	blocks = ((u64)block_len + 1) * info.block_size / 512;
477ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	size = (u64)last_block * info.block_size;
478ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
479ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_block[EXT4_DIND_BLOCK] = dind_block;
480ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_flags = 0;
481ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_blocks_lo = blocks;
482ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->osd2.linux2.l_i_blocks_high = blocks >> 32;
483ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_size_lo = size;
484ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_size_high = size >> 32;
485ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
486ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
487ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/* Allocates enough blocks to hold len bytes, with backing_len bytes in a data
488ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   buffer, and connects them to an inode.  Returns a pointer to the data
489ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   buffer. */
490ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossu8 *inode_allocate_data_indirect(struct ext4_inode *inode, unsigned long len,
491ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		unsigned long backing_len)
492ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
493ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	struct block_allocation *alloc;
49482c18e022db437b22c0d76cca420bfe558bf2ebbJohan Rudholm	u32 block_len = DIV_ROUND_UP(len, info.block_size);
495ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u8 *data = NULL;
496ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
49782c18e022db437b22c0d76cca420bfe558bf2ebbJohan Rudholm	alloc = do_inode_allocate_indirect(inode, block_len);
498ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (alloc == NULL) {
499ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		error("failed to allocate extents for %lu bytes", len);
500ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return NULL;
501ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
502ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
503ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (backing_len) {
504ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		data = create_backing(alloc, backing_len);
505ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		if (!data)
506ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross			error("failed to create backing for %lu bytes", backing_len);
507ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
508ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
50982c18e022db437b22c0d76cca420bfe558bf2ebbJohan Rudholm	rewind_alloc(alloc);
51082c18e022db437b22c0d76cca420bfe558bf2ebbJohan Rudholm	if (do_inode_attach_indirect(inode, alloc, block_len))
51182c18e022db437b22c0d76cca420bfe558bf2ebbJohan Rudholm		error("failed to attach blocks to indirect inode");
51282c18e022db437b22c0d76cca420bfe558bf2ebbJohan Rudholm
513ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	free_alloc(alloc);
514ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
515ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	return data;
516ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
517