indirect.c revision 22742ce739a046a079b2e1b03342a25472dfa352
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 <stdlib.h>
18ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross#include <stdio.h>
19ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
20ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross#include "ext4_utils.h"
21ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross#include "ext4.h"
22ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross#include "ext4_extents.h"
23ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross#include "backed_block.h"
24ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross#include "indirect.h"
25ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross#include "allocate.h"
26ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
27ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/* Creates data buffers for the first backing_len bytes of a block allocation
28ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   and queues them to be written */
29ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic u8 *create_backing(struct block_allocation *alloc,
30ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		unsigned long backing_len)
31ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
32ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (DIV_ROUND_UP(backing_len, info.block_size) > EXT4_NDIR_BLOCKS)
33ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		critical_error("indirect backing larger than %d blocks", EXT4_NDIR_BLOCKS);
34ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
35ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u8 *data = calloc(backing_len, 1);
36ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (!data)
37ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		critical_error_errno("calloc");
38ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
39ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u8 *ptr = data;
40ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	for (; alloc != NULL && backing_len > 0; get_next_region(alloc)) {
41ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		u32 region_block;
42ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		u32 region_len;
43ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		u32 len;
44ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		get_region(alloc, &region_block, &region_len);
45ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
46ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		len = min(region_len * info.block_size, backing_len);
47ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
48ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		queue_data_block(ptr, len, region_block);
49ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		ptr += len;
50ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		backing_len -= len;
51ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
52ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
53ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	return data;
54ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
55ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
56ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic void reserve_indirect_block(struct block_allocation *alloc, int len)
57ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
58ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (reserve_oob_blocks(alloc, 1)) {
598aef66d2125af8de7672a12895276802fcc1948fColin Cross		error("failed to reserve oob block");
608aef66d2125af8de7672a12895276802fcc1948fColin Cross		return;
618aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
62ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
63ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (advance_blocks(alloc, len)) {
64ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		error("failed to advance %d blocks", len);
65ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return;
66ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
67ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
68ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
69ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic void reserve_dindirect_block(struct block_allocation *alloc, int len)
70ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
71ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (reserve_oob_blocks(alloc, 1)) {
728aef66d2125af8de7672a12895276802fcc1948fColin Cross		error("failed to reserve oob block");
738aef66d2125af8de7672a12895276802fcc1948fColin Cross		return;
748aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
75ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
76ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	while (len > 0) {
77ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		int ind_block_len = min((int)aux_info.blocks_per_ind, len);
78ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
79ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		reserve_indirect_block(alloc, ind_block_len);
80ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
81ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		len -= ind_block_len;
82ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
83ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
84ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
85ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
86ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic void reserve_tindirect_block(struct block_allocation *alloc, int len)
87ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
88ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (reserve_oob_blocks(alloc, 1)) {
898aef66d2125af8de7672a12895276802fcc1948fColin Cross		error("failed to reserve oob block");
908aef66d2125af8de7672a12895276802fcc1948fColin Cross		return;
918aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
92ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
93ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	while (len > 0) {
94ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		int dind_block_len = min((int)aux_info.blocks_per_dind, len);
95ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
96ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		reserve_dindirect_block(alloc, dind_block_len);
97ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
98ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		len -= dind_block_len;
99ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
100ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
101ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
102ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic void fill_indirect_block(u32 *ind_block, int len, struct block_allocation *alloc)
103ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
104ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int i;
105ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	for (i = 0; i < len; i++) {
106ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		ind_block[i] = get_block(alloc, i);
107ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
108ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
109ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
110ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic void fill_dindirect_block(u32 *dind_block, int len, struct block_allocation *alloc)
111ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
112ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int i;
113ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 ind_block;
114ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
115ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	for (i = 0; len >  0; i++) {
116ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		ind_block = get_oob_block(alloc, 0);
117ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		if (advance_oob_blocks(alloc, 1)) {
1188aef66d2125af8de7672a12895276802fcc1948fColin Cross			error("failed to reserve oob block");
1198aef66d2125af8de7672a12895276802fcc1948fColin Cross			return;
1208aef66d2125af8de7672a12895276802fcc1948fColin Cross		}
121ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
122ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		dind_block[i] = ind_block;
123ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
124ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		u32 *ind_block_data = calloc(info.block_size, 1);
125ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		queue_data_block((u8*)ind_block_data, info.block_size, 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);
154ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		queue_data_block((u8*)dind_block_data, info.block_size, dind_block);
155ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		int dind_block_len = min((int)aux_info.blocks_per_dind, len);
156ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
157ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		fill_dindirect_block(dind_block_data, dind_block_len, alloc);
158ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
1598aef66d2125af8de7672a12895276802fcc1948fColin Cross		len -= dind_block_len;
160ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
161ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
162ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
163ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/* Given an allocation, attach as many blocks as possible to direct inode
164ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   blocks, and return the rest */
165ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic int inode_attach_direct_blocks(struct ext4_inode *inode,
166ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		struct block_allocation *alloc, u32 *block_len)
167ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
168ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int len = min(*block_len, EXT4_NDIR_BLOCKS);
169ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int i;
170ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
171ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	for (i = 0; i < len; i++) {
172ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		inode->i_block[i] = get_block(alloc, i);
173ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
174ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
1758aef66d2125af8de7672a12895276802fcc1948fColin Cross	if (advance_blocks(alloc, len)) {
1768aef66d2125af8de7672a12895276802fcc1948fColin Cross		error("failed to advance %d blocks", len);
1778aef66d2125af8de7672a12895276802fcc1948fColin Cross		return -1;
1788aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
179ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
1808aef66d2125af8de7672a12895276802fcc1948fColin Cross	*block_len -= len;
1818aef66d2125af8de7672a12895276802fcc1948fColin Cross	return 0;
182ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
183ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
184ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/* Given an allocation, attach as many blocks as possible to indirect blocks,
185ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   and return the rest
186ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   Assumes that the blocks necessary to hold the indirect blocks were included
187ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   as part of the allocation */
188ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic int inode_attach_indirect_blocks(struct ext4_inode *inode,
189ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		struct block_allocation *alloc, u32 *block_len)
190ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
191ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int len = min(*block_len, aux_info.blocks_per_ind);
192ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
193ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int ind_block = get_oob_block(alloc, 0);
194ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_block[EXT4_IND_BLOCK] = ind_block;
195ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
1968aef66d2125af8de7672a12895276802fcc1948fColin Cross	if (advance_oob_blocks(alloc, 1)) {
1978aef66d2125af8de7672a12895276802fcc1948fColin Cross		error("failed to advance oob block");
1988aef66d2125af8de7672a12895276802fcc1948fColin Cross		return -1;
1998aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
200ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
201ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 *ind_block_data = calloc(info.block_size, 1);
202ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	queue_data_block((u8*)ind_block_data, info.block_size, ind_block);
203ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
204ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	fill_indirect_block(ind_block_data, len, alloc);
205ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
2068aef66d2125af8de7672a12895276802fcc1948fColin Cross	if (advance_blocks(alloc, len)) {
2078aef66d2125af8de7672a12895276802fcc1948fColin Cross		error("failed to advance %d blocks", len);
2088aef66d2125af8de7672a12895276802fcc1948fColin Cross		return -1;
2098aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
210ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
2118aef66d2125af8de7672a12895276802fcc1948fColin Cross	*block_len -= len;
2128aef66d2125af8de7672a12895276802fcc1948fColin Cross	return 0;
213ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
214ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
215ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/* Given an allocation, attach as many blocks as possible to doubly indirect
216ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   blocks, and return the rest.
217ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   Assumes that the blocks necessary to hold the indirect and doubly indirect
218ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   blocks were included as part of the allocation */
219ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic int inode_attach_dindirect_blocks(struct ext4_inode *inode,
220ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		struct block_allocation *alloc, u32 *block_len)
221ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
222ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int len = min(*block_len, aux_info.blocks_per_dind);
223ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
224ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int dind_block = get_oob_block(alloc, 0);
225ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_block[EXT4_DIND_BLOCK] = dind_block;
226ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
2278aef66d2125af8de7672a12895276802fcc1948fColin Cross	if (advance_oob_blocks(alloc, 1)) {
2288aef66d2125af8de7672a12895276802fcc1948fColin Cross		error("failed to advance oob block");
2298aef66d2125af8de7672a12895276802fcc1948fColin Cross		return -1;
2308aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
231ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
232ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 *dind_block_data = calloc(info.block_size, 1);
233ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	queue_data_block((u8*)dind_block_data, info.block_size, dind_block);
234ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
235ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	fill_dindirect_block(dind_block_data, len, alloc);
236ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
2378aef66d2125af8de7672a12895276802fcc1948fColin Cross	if (advance_blocks(alloc, len)) {
2388aef66d2125af8de7672a12895276802fcc1948fColin Cross		error("failed to advance %d blocks", len);
2398aef66d2125af8de7672a12895276802fcc1948fColin Cross		return -1;
2408aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
241ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
2428aef66d2125af8de7672a12895276802fcc1948fColin Cross	*block_len -= len;
243ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	return 0;
244ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
245ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
246ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/* Given an allocation, attach as many blocks as possible to triply indirect
247ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   blocks, and return the rest.
248ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   Assumes that the blocks necessary to hold the indirect, doubly indirect and
249ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   triply indirect blocks were included as part of the allocation */
250ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic int inode_attach_tindirect_blocks(struct ext4_inode *inode,
251ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		struct block_allocation *alloc, u32 *block_len)
252ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
253ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int len = min(*block_len, aux_info.blocks_per_tind);
254ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
255ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	int tind_block = get_oob_block(alloc, 0);
256ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_block[EXT4_TIND_BLOCK] = tind_block;
257ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
2588aef66d2125af8de7672a12895276802fcc1948fColin Cross	if (advance_oob_blocks(alloc, 1)) {
2598aef66d2125af8de7672a12895276802fcc1948fColin Cross		error("failed to advance oob block");
2608aef66d2125af8de7672a12895276802fcc1948fColin Cross		return -1;
2618aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
262ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
263ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 *tind_block_data = calloc(info.block_size, 1);
264ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	queue_data_block((u8*)tind_block_data, info.block_size, tind_block);
265ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
266ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	fill_tindirect_block(tind_block_data, len, alloc);
267ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
2688aef66d2125af8de7672a12895276802fcc1948fColin Cross	if (advance_blocks(alloc, len)) {
2698aef66d2125af8de7672a12895276802fcc1948fColin Cross		error("failed to advance %d blocks", len);
2708aef66d2125af8de7672a12895276802fcc1948fColin Cross		return -1;
2718aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
272ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
2738aef66d2125af8de7672a12895276802fcc1948fColin Cross	*block_len -= len;
2748aef66d2125af8de7672a12895276802fcc1948fColin Cross	return 0;
275ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
276ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
277ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic void reserve_all_indirect_blocks(struct block_allocation *alloc, u32 len)
278ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
279ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (len <= EXT4_NDIR_BLOCKS)
280ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return;
281ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
282ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	len -= EXT4_NDIR_BLOCKS;
283ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	advance_blocks(alloc, EXT4_NDIR_BLOCKS);
284ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
285ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 ind_block_len = min(aux_info.blocks_per_ind, len);
286ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	reserve_indirect_block(alloc, ind_block_len);
287ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
288ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	len -= ind_block_len;
289ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (len == 0)
290ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return;
291ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
292ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 dind_block_len = min(aux_info.blocks_per_dind, len);
293ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	reserve_dindirect_block(alloc, dind_block_len);
294ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
295ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	len -= dind_block_len;
296ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (len == 0)
297ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return;
298ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
299ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 tind_block_len = min(aux_info.blocks_per_tind, len);
300ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	reserve_tindirect_block(alloc, tind_block_len);
301ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
302ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	len -= tind_block_len;
303ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (len == 0)
304ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return;
305ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
306ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	error("%d blocks remaining", len);
307ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
308ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
309ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic u32 indirect_blocks_needed(u32 len)
310ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
311ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 ind = 0;
312ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
313ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (len <= EXT4_NDIR_BLOCKS)
314ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return ind;
315ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
316ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	len -= EXT4_NDIR_BLOCKS;
317ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
318ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	/* We will need an indirect block for the rest of the blocks */
319ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	ind += DIV_ROUND_UP(len, aux_info.blocks_per_ind);
320ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
321ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (len <= aux_info.blocks_per_ind)
322ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return ind;
323ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
324ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	len -= aux_info.blocks_per_ind;
325ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
326ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	ind += DIV_ROUND_UP(len, aux_info.blocks_per_dind);
327ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
328ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (len <= aux_info.blocks_per_dind)
329ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return ind;
330ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
331ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	len -= aux_info.blocks_per_dind;
332ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
333ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	ind += DIV_ROUND_UP(len, aux_info.blocks_per_tind);
334ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
335ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (len <= aux_info.blocks_per_tind)
336ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return ind;
337ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
338ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	critical_error("request too large");
339ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	return 0;
340ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
341ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
342ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic int do_inode_attach_indirect(struct ext4_inode *inode,
343ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		struct block_allocation *alloc, u32 block_len)
344ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
345ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 count = block_len;
346ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
347ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (inode_attach_direct_blocks(inode, alloc, &count)) {
348ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		error("failed to attach direct blocks to inode");
349ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return -1;
350ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
351ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
352ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (count > 0) {
3538aef66d2125af8de7672a12895276802fcc1948fColin Cross		if (inode_attach_indirect_blocks(inode, alloc, &count)) {
3548aef66d2125af8de7672a12895276802fcc1948fColin Cross			error("failed to attach indirect blocks to inode");
3558aef66d2125af8de7672a12895276802fcc1948fColin Cross			return -1;
3568aef66d2125af8de7672a12895276802fcc1948fColin Cross		}
3578aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
3588aef66d2125af8de7672a12895276802fcc1948fColin Cross
3598aef66d2125af8de7672a12895276802fcc1948fColin Cross	if (count > 0) {
3608aef66d2125af8de7672a12895276802fcc1948fColin Cross		if (inode_attach_dindirect_blocks(inode, alloc, &count)) {
3618aef66d2125af8de7672a12895276802fcc1948fColin Cross			error("failed to attach dindirect blocks to inode");
3628aef66d2125af8de7672a12895276802fcc1948fColin Cross			return -1;
3638aef66d2125af8de7672a12895276802fcc1948fColin Cross		}
364ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
365ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
3668aef66d2125af8de7672a12895276802fcc1948fColin Cross	if (count > 0) {
3678aef66d2125af8de7672a12895276802fcc1948fColin Cross		if (inode_attach_tindirect_blocks(inode, alloc, &count)) {
3688aef66d2125af8de7672a12895276802fcc1948fColin Cross			error("failed to attach tindirect blocks to inode");
3698aef66d2125af8de7672a12895276802fcc1948fColin Cross			return -1;
3708aef66d2125af8de7672a12895276802fcc1948fColin Cross		}
3718aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
3728aef66d2125af8de7672a12895276802fcc1948fColin Cross
3738aef66d2125af8de7672a12895276802fcc1948fColin Cross	if (count) {
374ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		error("blocks left after triply-indirect allocation");
375ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return -1;
3768aef66d2125af8de7672a12895276802fcc1948fColin Cross	}
377ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
378ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	rewind_alloc(alloc);
379ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
380ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	return 0;
381ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
382ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
383ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossstatic struct block_allocation *do_inode_allocate_indirect(
384ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		struct ext4_inode *inode, u32 block_len)
385ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
386ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 indirect_len = indirect_blocks_needed(block_len);
387ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
388ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	struct block_allocation *alloc = allocate_blocks(block_len + indirect_len);
389ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
390ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (alloc == NULL) {
391ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		error("Failed to allocate %d blocks", block_len + indirect_len);
392ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return NULL;
393ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
394ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
395ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	return alloc;
396ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
397ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
398ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/* Allocates enough blocks to hold len bytes and connects them to an inode */
399ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossvoid inode_allocate_indirect(struct ext4_inode *inode, unsigned long len)
400ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
401ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	struct block_allocation *alloc;
402ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 block_len = DIV_ROUND_UP(len, info.block_size);
403ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 indirect_len = indirect_blocks_needed(block_len);
404ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
405ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	alloc = do_inode_allocate_indirect(inode, block_len);
406ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (alloc == NULL) {
407ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		error("failed to allocate extents for %lu bytes", len);
408ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return;
409ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
410ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
411ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	reserve_all_indirect_blocks(alloc, block_len);
412ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	rewind_alloc(alloc);
413ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
414ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (do_inode_attach_indirect(inode, alloc, block_len))
415ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		error("failed to attach blocks to indirect inode");
416ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
417ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_flags = 0;
418ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_blocks_lo = (block_len + indirect_len) * info.block_size / 512;
419ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_size_lo = len;
420ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
421ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	free_alloc(alloc);
422ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
423ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
424ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossvoid inode_attach_resize(struct ext4_inode *inode,
425ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		struct block_allocation *alloc)
426ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
427ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 block_len = block_allocation_len(alloc);
42822742ce739a046a079b2e1b03342a25472dfa352Colin Cross	u32 superblocks = block_len / info.bg_desc_reserve_blocks;
429ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 i, j;
430ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u64 blocks;
431ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u64 size;
432ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
43322742ce739a046a079b2e1b03342a25472dfa352Colin Cross	if (block_len % info.bg_desc_reserve_blocks)
434ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		critical_error("reserved blocks not a multiple of %d",
43522742ce739a046a079b2e1b03342a25472dfa352Colin Cross				info.bg_desc_reserve_blocks);
436ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
437ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	append_oob_allocation(alloc, 1);
438ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 dind_block = get_oob_block(alloc, 0);
439ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
440ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 *dind_block_data = calloc(info.block_size, 1);
441ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (!dind_block_data)
442ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		critical_error_errno("calloc");
443ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	queue_data_block((u8 *)dind_block_data, info.block_size, dind_block);
444ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
44522742ce739a046a079b2e1b03342a25472dfa352Colin Cross	u32 *ind_block_data = calloc(info.block_size, info.bg_desc_reserve_blocks);
446ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (!ind_block_data)
447ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		critical_error_errno("calloc");
448ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	queue_data_block((u8 *)ind_block_data,
44922742ce739a046a079b2e1b03342a25472dfa352Colin Cross			info.block_size * info.bg_desc_reserve_blocks,
450ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross			get_block(alloc, 0));
451ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
45222742ce739a046a079b2e1b03342a25472dfa352Colin Cross	for (i = 0; i < info.bg_desc_reserve_blocks; i++) {
45322742ce739a046a079b2e1b03342a25472dfa352Colin Cross		int r = (i - aux_info.bg_desc_blocks) % info.bg_desc_reserve_blocks;
454ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		if (r < 0)
45522742ce739a046a079b2e1b03342a25472dfa352Colin Cross			r += info.bg_desc_reserve_blocks;
456ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
457ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		dind_block_data[i] = get_block(alloc, r);
458ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
459ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		for (j = 1; j < superblocks; j++) {
46022742ce739a046a079b2e1b03342a25472dfa352Colin Cross			u32 b = j * info.bg_desc_reserve_blocks + r;
461ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross			ind_block_data[r * aux_info.blocks_per_ind + j - 1] = get_block(alloc, b);
462ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		}
463ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
464ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
465ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u32 last_block = EXT4_NDIR_BLOCKS + aux_info.blocks_per_ind +
46622742ce739a046a079b2e1b03342a25472dfa352Colin Cross			aux_info.blocks_per_ind * (info.bg_desc_reserve_blocks - 1) +
467ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross			superblocks - 2;
468ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
469ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	blocks = ((u64)block_len + 1) * info.block_size / 512;
470ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	size = (u64)last_block * info.block_size;
471ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
472ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_block[EXT4_DIND_BLOCK] = dind_block;
473ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_flags = 0;
474ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_blocks_lo = blocks;
475ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->osd2.linux2.l_i_blocks_high = blocks >> 32;
476ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_size_lo = size;
477ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	inode->i_size_high = size >> 32;
478ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
479ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
480ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross/* Allocates enough blocks to hold len bytes, with backing_len bytes in a data
481ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   buffer, and connects them to an inode.  Returns a pointer to the data
482ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross   buffer. */
483ec0a2e83dc66d67addeb90e83144187691852a3eColin Crossu8 *inode_allocate_data_indirect(struct ext4_inode *inode, unsigned long len,
484ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		unsigned long backing_len)
485ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross{
486ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	struct block_allocation *alloc;
487ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	u8 *data = NULL;
488ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
489ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	alloc = do_inode_allocate_indirect(inode, len);
490ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (alloc == NULL) {
491ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		error("failed to allocate extents for %lu bytes", len);
492ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		return NULL;
493ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
494ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
495ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	if (backing_len) {
496ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		data = create_backing(alloc, backing_len);
497ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross		if (!data)
498ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross			error("failed to create backing for %lu bytes", backing_len);
499ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	}
500ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
501ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	free_alloc(alloc);
502ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross
503ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross	return data;
504ec0a2e83dc66d67addeb90e83144187691852a3eColin Cross}
505