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 "indirect.h"
19ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross#include "allocate.h"
20ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
21dc5abeee1e6fc4827ee0d5ece12aaed2dd56f4c7Colin Cross#include <sparse/sparse.h>
22dc5abeee1e6fc4827ee0d5ece12aaed2dd56f4c7Colin Cross
2333f96c66e9a1f2e266a75e5e84c091dffa6ef118Colin Cross#include <stdlib.h>
2433f96c66e9a1f2e266a75e5e84c091dffa6ef118Colin Cross#include <stdio.h>
2533f96c66e9a1f2e266a75e5e84c091dffa6ef118Colin Cross
26ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/* Creates data buffers for the first backing_len bytes of a block allocation
27ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   and queues them to be written */
28ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic u8 *create_backing(struct block_allocation *alloc,
29ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		unsigned long backing_len)
30ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
31ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (DIV_ROUND_UP(backing_len, info.block_size) > EXT4_NDIR_BLOCKS)
32ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		critical_error("indirect backing larger than %d blocks", EXT4_NDIR_BLOCKS);
33ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
34ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u8 *data = calloc(backing_len, 1);
35ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (!data)
36ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		critical_error_errno("calloc");
37ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
38ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u8 *ptr = data;
39ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	for (; alloc != NULL && backing_len > 0; get_next_region(alloc)) {
40ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		u32 region_block;
41ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		u32 region_len;
42ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		u32 len;
43ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		get_region(alloc, &region_block, &region_len);
44ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
45ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		len = min(region_len * info.block_size, backing_len);
46ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
47782879ab61fe825835a9c6a701f91aa7d305acefColin Cross		sparse_file_add_data(ext4_sparse_file, ptr, len, region_block);
48ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		ptr += len;
49ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		backing_len -= len;
50ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
51ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
52ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	return data;
53ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
54ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
55ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic void reserve_indirect_block(struct block_allocation *alloc, int len)
56ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
57ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (reserve_oob_blocks(alloc, 1)) {
588aef66d2125af8de7672a12895276802fcc1948fColin Cross		error("failed to reserve oob block");
598aef66d2125af8de7672a12895276802fcc1948fColin Cross		return;
608aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
61ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
62ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (advance_blocks(alloc, len)) {
63ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		error("failed to advance %d blocks", len);
64ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return;
65ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
66ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
67ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
68ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic void reserve_dindirect_block(struct block_allocation *alloc, int len)
69ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
70ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (reserve_oob_blocks(alloc, 1)) {
718aef66d2125af8de7672a12895276802fcc1948fColin Cross		error("failed to reserve oob block");
728aef66d2125af8de7672a12895276802fcc1948fColin Cross		return;
738aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
74ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
75ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	while (len > 0) {
76ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		int ind_block_len = min((int)aux_info.blocks_per_ind, len);
77ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
78ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		reserve_indirect_block(alloc, ind_block_len);
79ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
80ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		len -= ind_block_len;
81ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
82ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
83ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
84ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
85ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic void reserve_tindirect_block(struct block_allocation *alloc, int len)
86ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
87ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (reserve_oob_blocks(alloc, 1)) {
888aef66d2125af8de7672a12895276802fcc1948fColin Cross		error("failed to reserve oob block");
898aef66d2125af8de7672a12895276802fcc1948fColin Cross		return;
908aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
91ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
92ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	while (len > 0) {
93ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		int dind_block_len = min((int)aux_info.blocks_per_dind, len);
94ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
95ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		reserve_dindirect_block(alloc, dind_block_len);
96ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
97ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		len -= dind_block_len;
98ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
99ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
100ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
101ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic void fill_indirect_block(u32 *ind_block, int len, struct block_allocation *alloc)
102ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
103ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int i;
104ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	for (i = 0; i < len; i++) {
105ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		ind_block[i] = get_block(alloc, i);
106ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
107ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
108ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
109ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic void fill_dindirect_block(u32 *dind_block, int len, struct block_allocation *alloc)
110ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
111ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int i;
112ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 ind_block;
113ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
114ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	for (i = 0; len >  0; i++) {
115ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		ind_block = get_oob_block(alloc, 0);
116ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		if (advance_oob_blocks(alloc, 1)) {
1178aef66d2125af8de7672a12895276802fcc1948fColin Cross			error("failed to reserve oob block");
1188aef66d2125af8de7672a12895276802fcc1948fColin Cross			return;
1198aef66d2125af8de7672a12895276802fcc1948fColin Cross		}
120ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
121ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		dind_block[i] = ind_block;
122ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
123ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		u32 *ind_block_data = calloc(info.block_size, 1);
124782879ab61fe825835a9c6a701f91aa7d305acefColin Cross		sparse_file_add_data(ext4_sparse_file, ind_block_data, info.block_size,
125f0ee37ffded79afdb03e15ae3a69969d2b7e6079Colin Cross				ind_block);
126ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		int ind_block_len = min((int)aux_info.blocks_per_ind, len);
127ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
128ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		fill_indirect_block(ind_block_data, ind_block_len, alloc);
129ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
130ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		if (advance_blocks(alloc, ind_block_len)) {
131ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross			error("failed to advance %d blocks", ind_block_len);
132ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross			return;
133ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		}
134ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
135ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		len -= ind_block_len;
136ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
137ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
138ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
139ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic void fill_tindirect_block(u32 *tind_block, int len, struct block_allocation *alloc)
140ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
141ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int i;
142ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 dind_block;
143ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
144ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	for (i = 0; len > 0; i++) {
145ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		dind_block = get_oob_block(alloc, 0);
146ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		if (advance_oob_blocks(alloc, 1)) {
1478aef66d2125af8de7672a12895276802fcc1948fColin Cross			error("failed to reserve oob block");
1488aef66d2125af8de7672a12895276802fcc1948fColin Cross			return;
1498aef66d2125af8de7672a12895276802fcc1948fColin Cross		}
150ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
1518aef66d2125af8de7672a12895276802fcc1948fColin Cross		tind_block[i] = dind_block;
152ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
153ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		u32 *dind_block_data = calloc(info.block_size, 1);
154782879ab61fe825835a9c6a701f91aa7d305acefColin Cross		sparse_file_add_data(ext4_sparse_file, dind_block_data, info.block_size,
155f0ee37ffded79afdb03e15ae3a69969d2b7e6079Colin Cross				dind_block);
156ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		int dind_block_len = min((int)aux_info.blocks_per_dind, len);
157ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
158ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		fill_dindirect_block(dind_block_data, dind_block_len, alloc);
159ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
1608aef66d2125af8de7672a12895276802fcc1948fColin Cross		len -= dind_block_len;
161ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
162ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
163ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
164ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/* Given an allocation, attach as many blocks as possible to direct inode
165ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   blocks, and return the rest */
166ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic int inode_attach_direct_blocks(struct ext4_inode *inode,
167ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		struct block_allocation *alloc, u32 *block_len)
168ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
169ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int len = min(*block_len, EXT4_NDIR_BLOCKS);
170ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int i;
171ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
172ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	for (i = 0; i < len; i++) {
173ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		inode->i_block[i] = get_block(alloc, i);
174ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
175ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
1768aef66d2125af8de7672a12895276802fcc1948fColin Cross	if (advance_blocks(alloc, len)) {
1778aef66d2125af8de7672a12895276802fcc1948fColin Cross		error("failed to advance %d blocks", len);
1788aef66d2125af8de7672a12895276802fcc1948fColin Cross		return -1;
1798aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
180ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
1818aef66d2125af8de7672a12895276802fcc1948fColin Cross	*block_len -= len;
1828aef66d2125af8de7672a12895276802fcc1948fColin Cross	return 0;
183ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
184ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
185ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/* Given an allocation, attach as many blocks as possible to indirect blocks,
186ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   and return the rest
187ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   Assumes that the blocks necessary to hold the indirect blocks were included
188ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   as part of the allocation */
189ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic int inode_attach_indirect_blocks(struct ext4_inode *inode,
190ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		struct block_allocation *alloc, u32 *block_len)
191ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
192ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int len = min(*block_len, aux_info.blocks_per_ind);
193ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
194ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int ind_block = get_oob_block(alloc, 0);
195ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_block[EXT4_IND_BLOCK] = ind_block;
196ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
1978aef66d2125af8de7672a12895276802fcc1948fColin Cross	if (advance_oob_blocks(alloc, 1)) {
1988aef66d2125af8de7672a12895276802fcc1948fColin Cross		error("failed to advance oob block");
1998aef66d2125af8de7672a12895276802fcc1948fColin Cross		return -1;
2008aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
201ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
202ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 *ind_block_data = calloc(info.block_size, 1);
203782879ab61fe825835a9c6a701f91aa7d305acefColin Cross	sparse_file_add_data(ext4_sparse_file, ind_block_data, info.block_size,
204f0ee37ffded79afdb03e15ae3a69969d2b7e6079Colin Cross			ind_block);
205ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
206ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	fill_indirect_block(ind_block_data, len, alloc);
207ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
2088aef66d2125af8de7672a12895276802fcc1948fColin Cross	if (advance_blocks(alloc, len)) {
2098aef66d2125af8de7672a12895276802fcc1948fColin Cross		error("failed to advance %d blocks", len);
2108aef66d2125af8de7672a12895276802fcc1948fColin Cross		return -1;
2118aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
212ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
2138aef66d2125af8de7672a12895276802fcc1948fColin Cross	*block_len -= len;
2148aef66d2125af8de7672a12895276802fcc1948fColin Cross	return 0;
215ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
216ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
217ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/* Given an allocation, attach as many blocks as possible to doubly indirect
218ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   blocks, and return the rest.
219ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   Assumes that the blocks necessary to hold the indirect and doubly indirect
220ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   blocks were included as part of the allocation */
221ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic int inode_attach_dindirect_blocks(struct ext4_inode *inode,
222ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		struct block_allocation *alloc, u32 *block_len)
223ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
224ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int len = min(*block_len, aux_info.blocks_per_dind);
225ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
226ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int dind_block = get_oob_block(alloc, 0);
227ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_block[EXT4_DIND_BLOCK] = dind_block;
228ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
2298aef66d2125af8de7672a12895276802fcc1948fColin Cross	if (advance_oob_blocks(alloc, 1)) {
2308aef66d2125af8de7672a12895276802fcc1948fColin Cross		error("failed to advance oob block");
2318aef66d2125af8de7672a12895276802fcc1948fColin Cross		return -1;
2328aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
233ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
234ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 *dind_block_data = calloc(info.block_size, 1);
235782879ab61fe825835a9c6a701f91aa7d305acefColin Cross	sparse_file_add_data(ext4_sparse_file, dind_block_data, info.block_size,
236f0ee37ffded79afdb03e15ae3a69969d2b7e6079Colin Cross			dind_block);
237ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
238ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	fill_dindirect_block(dind_block_data, len, alloc);
239ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
2408aef66d2125af8de7672a12895276802fcc1948fColin Cross	if (advance_blocks(alloc, len)) {
2418aef66d2125af8de7672a12895276802fcc1948fColin Cross		error("failed to advance %d blocks", len);
2428aef66d2125af8de7672a12895276802fcc1948fColin Cross		return -1;
2438aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
244ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
2458aef66d2125af8de7672a12895276802fcc1948fColin Cross	*block_len -= len;
246ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	return 0;
247ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
248ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
249ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/* Given an allocation, attach as many blocks as possible to triply indirect
250ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   blocks, and return the rest.
251ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   Assumes that the blocks necessary to hold the indirect, doubly indirect and
252ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   triply indirect blocks were included as part of the allocation */
253ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic int inode_attach_tindirect_blocks(struct ext4_inode *inode,
254ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		struct block_allocation *alloc, u32 *block_len)
255ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
256ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int len = min(*block_len, aux_info.blocks_per_tind);
257ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
258ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int tind_block = get_oob_block(alloc, 0);
259ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_block[EXT4_TIND_BLOCK] = tind_block;
260ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
2618aef66d2125af8de7672a12895276802fcc1948fColin Cross	if (advance_oob_blocks(alloc, 1)) {
2628aef66d2125af8de7672a12895276802fcc1948fColin Cross		error("failed to advance oob block");
2638aef66d2125af8de7672a12895276802fcc1948fColin Cross		return -1;
2648aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
265ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
266ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 *tind_block_data = calloc(info.block_size, 1);
267782879ab61fe825835a9c6a701f91aa7d305acefColin Cross	sparse_file_add_data(ext4_sparse_file, tind_block_data, info.block_size,
268f0ee37ffded79afdb03e15ae3a69969d2b7e6079Colin Cross			tind_block);
269ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
270ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	fill_tindirect_block(tind_block_data, len, alloc);
271ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
2728aef66d2125af8de7672a12895276802fcc1948fColin Cross	if (advance_blocks(alloc, len)) {
2738aef66d2125af8de7672a12895276802fcc1948fColin Cross		error("failed to advance %d blocks", len);
2748aef66d2125af8de7672a12895276802fcc1948fColin Cross		return -1;
2758aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
276ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
2778aef66d2125af8de7672a12895276802fcc1948fColin Cross	*block_len -= len;
2788aef66d2125af8de7672a12895276802fcc1948fColin Cross	return 0;
279ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
280ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
281ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic void reserve_all_indirect_blocks(struct block_allocation *alloc, u32 len)
282ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
283ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (len <= EXT4_NDIR_BLOCKS)
284ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return;
285ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
286ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	len -= EXT4_NDIR_BLOCKS;
287ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	advance_blocks(alloc, EXT4_NDIR_BLOCKS);
288ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
289ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 ind_block_len = min(aux_info.blocks_per_ind, len);
290ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	reserve_indirect_block(alloc, ind_block_len);
291ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
292ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	len -= ind_block_len;
293ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (len == 0)
294ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return;
295ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
296ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 dind_block_len = min(aux_info.blocks_per_dind, len);
297ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	reserve_dindirect_block(alloc, dind_block_len);
298ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
299ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	len -= dind_block_len;
300ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (len == 0)
301ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return;
302ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
303ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 tind_block_len = min(aux_info.blocks_per_tind, len);
304ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	reserve_tindirect_block(alloc, tind_block_len);
305ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
306ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	len -= tind_block_len;
307ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (len == 0)
308ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return;
309ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
310ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	error("%d blocks remaining", len);
311ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
312ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
313ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic u32 indirect_blocks_needed(u32 len)
314ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
315ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 ind = 0;
316ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
317ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (len <= EXT4_NDIR_BLOCKS)
318ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return ind;
319ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
320ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	len -= EXT4_NDIR_BLOCKS;
321ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
322ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	/* We will need an indirect block for the rest of the blocks */
323ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	ind += DIV_ROUND_UP(len, aux_info.blocks_per_ind);
324ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
325ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (len <= aux_info.blocks_per_ind)
326ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return ind;
327ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
328ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	len -= aux_info.blocks_per_ind;
329ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
330ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	ind += DIV_ROUND_UP(len, aux_info.blocks_per_dind);
331ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
332ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (len <= aux_info.blocks_per_dind)
333ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return ind;
334ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
335ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	len -= aux_info.blocks_per_dind;
336ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
337ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	ind += DIV_ROUND_UP(len, aux_info.blocks_per_tind);
338ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
339ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (len <= aux_info.blocks_per_tind)
340ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return ind;
341ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
342ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	critical_error("request too large");
343ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	return 0;
344ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
345ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
346ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic int do_inode_attach_indirect(struct ext4_inode *inode,
347ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		struct block_allocation *alloc, u32 block_len)
348ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
349ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 count = block_len;
350ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
351ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (inode_attach_direct_blocks(inode, alloc, &count)) {
352ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		error("failed to attach direct blocks to inode");
353ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return -1;
354ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
355ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
356ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (count > 0) {
3578aef66d2125af8de7672a12895276802fcc1948fColin Cross		if (inode_attach_indirect_blocks(inode, alloc, &count)) {
3588aef66d2125af8de7672a12895276802fcc1948fColin Cross			error("failed to attach indirect blocks to inode");
3598aef66d2125af8de7672a12895276802fcc1948fColin Cross			return -1;
3608aef66d2125af8de7672a12895276802fcc1948fColin Cross		}
3618aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
3628aef66d2125af8de7672a12895276802fcc1948fColin Cross
3638aef66d2125af8de7672a12895276802fcc1948fColin Cross	if (count > 0) {
3648aef66d2125af8de7672a12895276802fcc1948fColin Cross		if (inode_attach_dindirect_blocks(inode, alloc, &count)) {
3658aef66d2125af8de7672a12895276802fcc1948fColin Cross			error("failed to attach dindirect blocks to inode");
3668aef66d2125af8de7672a12895276802fcc1948fColin Cross			return -1;
3678aef66d2125af8de7672a12895276802fcc1948fColin Cross		}
368ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
369ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
3708aef66d2125af8de7672a12895276802fcc1948fColin Cross	if (count > 0) {
3718aef66d2125af8de7672a12895276802fcc1948fColin Cross		if (inode_attach_tindirect_blocks(inode, alloc, &count)) {
3728aef66d2125af8de7672a12895276802fcc1948fColin Cross			error("failed to attach tindirect blocks to inode");
3738aef66d2125af8de7672a12895276802fcc1948fColin Cross			return -1;
3748aef66d2125af8de7672a12895276802fcc1948fColin Cross		}
3758aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
3768aef66d2125af8de7672a12895276802fcc1948fColin Cross
3778aef66d2125af8de7672a12895276802fcc1948fColin Cross	if (count) {
378ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		error("blocks left after triply-indirect allocation");
379ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return -1;
3808aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
381ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
382ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	rewind_alloc(alloc);
383ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
384ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	return 0;
385ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
386ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
387ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic struct block_allocation *do_inode_allocate_indirect(
3885446bde9c02f6ae95a30d9c178b13a05bb580fe1Nick Kralevich		u32 block_len)
389ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
390ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 indirect_len = indirect_blocks_needed(block_len);
391ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
392ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	struct block_allocation *alloc = allocate_blocks(block_len + indirect_len);
393ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
394ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (alloc == NULL) {
395ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		error("Failed to allocate %d blocks", block_len + indirect_len);
396ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return NULL;
397ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
398ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
399ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	return alloc;
400ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
401ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
402ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/* Allocates enough blocks to hold len bytes and connects them to an inode */
403ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossvoid inode_allocate_indirect(struct ext4_inode *inode, unsigned long len)
404ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
405ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	struct block_allocation *alloc;
406ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 block_len = DIV_ROUND_UP(len, info.block_size);
407ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 indirect_len = indirect_blocks_needed(block_len);
408ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
4095446bde9c02f6ae95a30d9c178b13a05bb580fe1Nick Kralevich	alloc = do_inode_allocate_indirect(block_len);
410ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (alloc == NULL) {
411ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		error("failed to allocate extents for %lu bytes", len);
412ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return;
413ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
414ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
415ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	reserve_all_indirect_blocks(alloc, block_len);
416ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	rewind_alloc(alloc);
417ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
418ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (do_inode_attach_indirect(inode, alloc, block_len))
419ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		error("failed to attach blocks to indirect inode");
420ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
421ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_flags = 0;
422ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_blocks_lo = (block_len + indirect_len) * info.block_size / 512;
423ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_size_lo = len;
424ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
425ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	free_alloc(alloc);
426ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
427ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
428ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossvoid inode_attach_resize(struct ext4_inode *inode,
429ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		struct block_allocation *alloc)
430ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
431ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 block_len = block_allocation_len(alloc);
43222742ce739a046a079b2e1b03342a25472dfa352Colin Cross	u32 superblocks = block_len / info.bg_desc_reserve_blocks;
433ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 i, j;
434ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u64 blocks;
435ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u64 size;
436ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
43722742ce739a046a079b2e1b03342a25472dfa352Colin Cross	if (block_len % info.bg_desc_reserve_blocks)
438ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		critical_error("reserved blocks not a multiple of %d",
43922742ce739a046a079b2e1b03342a25472dfa352Colin Cross				info.bg_desc_reserve_blocks);
440ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
441ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	append_oob_allocation(alloc, 1);
442ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 dind_block = get_oob_block(alloc, 0);
443ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
444ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 *dind_block_data = calloc(info.block_size, 1);
445ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (!dind_block_data)
446ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		critical_error_errno("calloc");
447782879ab61fe825835a9c6a701f91aa7d305acefColin Cross	sparse_file_add_data(ext4_sparse_file, dind_block_data, info.block_size,
448f0ee37ffded79afdb03e15ae3a69969d2b7e6079Colin Cross			dind_block);
449ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
45022742ce739a046a079b2e1b03342a25472dfa352Colin Cross	u32 *ind_block_data = calloc(info.block_size, info.bg_desc_reserve_blocks);
451ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (!ind_block_data)
452ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		critical_error_errno("calloc");
453782879ab61fe825835a9c6a701f91aa7d305acefColin Cross	sparse_file_add_data(ext4_sparse_file, ind_block_data,
45422742ce739a046a079b2e1b03342a25472dfa352Colin Cross			info.block_size * info.bg_desc_reserve_blocks,
455ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross			get_block(alloc, 0));
456ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
45722742ce739a046a079b2e1b03342a25472dfa352Colin Cross	for (i = 0; i < info.bg_desc_reserve_blocks; i++) {
45822742ce739a046a079b2e1b03342a25472dfa352Colin Cross		int r = (i - aux_info.bg_desc_blocks) % info.bg_desc_reserve_blocks;
459ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		if (r < 0)
46022742ce739a046a079b2e1b03342a25472dfa352Colin Cross			r += info.bg_desc_reserve_blocks;
461ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
462ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		dind_block_data[i] = get_block(alloc, r);
463ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
464ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		for (j = 1; j < superblocks; j++) {
46522742ce739a046a079b2e1b03342a25472dfa352Colin Cross			u32 b = j * info.bg_desc_reserve_blocks + r;
466ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross			ind_block_data[r * aux_info.blocks_per_ind + j - 1] = get_block(alloc, b);
467ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		}
468ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
469ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
470ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 last_block = EXT4_NDIR_BLOCKS + aux_info.blocks_per_ind +
47122742ce739a046a079b2e1b03342a25472dfa352Colin Cross			aux_info.blocks_per_ind * (info.bg_desc_reserve_blocks - 1) +
472ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross			superblocks - 2;
473ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
474ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	blocks = ((u64)block_len + 1) * info.block_size / 512;
475ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	size = (u64)last_block * info.block_size;
476ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
477ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_block[EXT4_DIND_BLOCK] = dind_block;
478ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_flags = 0;
479ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_blocks_lo = blocks;
480ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->osd2.linux2.l_i_blocks_high = blocks >> 32;
481ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_size_lo = size;
482ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_size_high = size >> 32;
483ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
484ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
485ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/* Allocates enough blocks to hold len bytes, with backing_len bytes in a data
486ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   buffer, and connects them to an inode.  Returns a pointer to the data
487ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   buffer. */
488ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossu8 *inode_allocate_data_indirect(struct ext4_inode *inode, unsigned long len,
489ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		unsigned long backing_len)
490ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
491ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	struct block_allocation *alloc;
49282c18e022db437b22c0d76cca420bfe558bf2ebbJohan Rudholm	u32 block_len = DIV_ROUND_UP(len, info.block_size);
493ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u8 *data = NULL;
494ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
4955446bde9c02f6ae95a30d9c178b13a05bb580fe1Nick Kralevich	alloc = do_inode_allocate_indirect(block_len);
496ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (alloc == NULL) {
497ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		error("failed to allocate extents for %lu bytes", len);
498ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return NULL;
499ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
500ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
501ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (backing_len) {
502ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		data = create_backing(alloc, backing_len);
503ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		if (!data)
504ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross			error("failed to create backing for %lu bytes", backing_len);
505ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
506ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
50782c18e022db437b22c0d76cca420bfe558bf2ebbJohan Rudholm	rewind_alloc(alloc);
50882c18e022db437b22c0d76cca420bfe558bf2ebbJohan Rudholm	if (do_inode_attach_indirect(inode, alloc, block_len))
50982c18e022db437b22c0d76cca420bfe558bf2ebbJohan Rudholm		error("failed to attach blocks to indirect inode");
51082c18e022db437b22c0d76cca420bfe558bf2ebbJohan Rudholm
511ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	free_alloc(alloc);
512ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
513ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	return data;
514ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
515