backed_block.c revision be8ddcb35a459481c0bcf5bfe645c1fefe963f5c
128fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross/*
228fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross * Copyright (C) 2010 The Android Open Source Project
328fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross *
428fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross * Licensed under the Apache License, Version 2.0 (the "License");
528fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross * you may not use this file except in compliance with the License.
628fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross * You may obtain a copy of the License at
728fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross *
828fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross *      http://www.apache.org/licenses/LICENSE-2.0
928fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross *
1028fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross * Unless required by applicable law or agreed to in writing, software
1128fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross * distributed under the License is distributed on an "AS IS" BASIS,
1228fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1328fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross * See the License for the specific language governing permissions and
1428fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross * limitations under the License.
1528fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross */
1628fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
17b55dceea986ab24f8b836b5116b389ed619c816eColin Cross#include <assert.h>
18b55dceea986ab24f8b836b5116b389ed619c816eColin Cross#include <errno.h>
19b55dceea986ab24f8b836b5116b389ed619c816eColin Cross#include <stdint.h>
2028fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross#include <stdlib.h>
2128fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross#include <string.h>
2228fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
2328fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross#include "backed_block.h"
24be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross#include "sparse_defs.h"
25b55dceea986ab24f8b836b5116b389ed619c816eColin Cross
26b55dceea986ab24f8b836b5116b389ed619c816eColin Crossstruct backed_block {
27b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	unsigned int block;
28b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	unsigned int len;
29b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	enum backed_block_type type;
30b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	union {
31b55dceea986ab24f8b836b5116b389ed619c816eColin Cross		struct {
32b55dceea986ab24f8b836b5116b389ed619c816eColin Cross			void *data;
33b55dceea986ab24f8b836b5116b389ed619c816eColin Cross		} data;
34b55dceea986ab24f8b836b5116b389ed619c816eColin Cross		struct {
35b55dceea986ab24f8b836b5116b389ed619c816eColin Cross			char *filename;
36b55dceea986ab24f8b836b5116b389ed619c816eColin Cross			int64_t offset;
37b55dceea986ab24f8b836b5116b389ed619c816eColin Cross		} file;
38b55dceea986ab24f8b836b5116b389ed619c816eColin Cross		struct {
399e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross			int fd;
409e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross			int64_t offset;
419e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross		} fd;
429e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross		struct {
43b55dceea986ab24f8b836b5116b389ed619c816eColin Cross			uint32_t val;
44b55dceea986ab24f8b836b5116b389ed619c816eColin Cross		} fill;
45b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	};
46b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	struct backed_block *next;
4728fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross};
4828fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
49411619e921904b896eddae81c086c1f687c8304dColin Crossstruct backed_block_list {
50b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	struct backed_block *data_blocks;
51b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	struct backed_block *last_used;
52be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	unsigned int block_size;
53411619e921904b896eddae81c086c1f687c8304dColin Cross};
54411619e921904b896eddae81c086c1f687c8304dColin Cross
55b55dceea986ab24f8b836b5116b389ed619c816eColin Crossstruct backed_block *backed_block_iter_new(struct backed_block_list *bbl)
56b55dceea986ab24f8b836b5116b389ed619c816eColin Cross{
57b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	return bbl->data_blocks;
58b55dceea986ab24f8b836b5116b389ed619c816eColin Cross}
59b55dceea986ab24f8b836b5116b389ed619c816eColin Cross
60b55dceea986ab24f8b836b5116b389ed619c816eColin Crossstruct backed_block *backed_block_iter_next(struct backed_block *bb)
61b55dceea986ab24f8b836b5116b389ed619c816eColin Cross{
62b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	return bb->next;
63b55dceea986ab24f8b836b5116b389ed619c816eColin Cross}
64b55dceea986ab24f8b836b5116b389ed619c816eColin Cross
65b55dceea986ab24f8b836b5116b389ed619c816eColin Crossunsigned int backed_block_len(struct backed_block *bb)
66b55dceea986ab24f8b836b5116b389ed619c816eColin Cross{
67b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	return bb->len;
68b55dceea986ab24f8b836b5116b389ed619c816eColin Cross}
69b55dceea986ab24f8b836b5116b389ed619c816eColin Cross
70b55dceea986ab24f8b836b5116b389ed619c816eColin Crossunsigned int backed_block_block(struct backed_block *bb)
71b55dceea986ab24f8b836b5116b389ed619c816eColin Cross{
72b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	return bb->block;
73b55dceea986ab24f8b836b5116b389ed619c816eColin Cross}
74b55dceea986ab24f8b836b5116b389ed619c816eColin Cross
75b55dceea986ab24f8b836b5116b389ed619c816eColin Crossvoid *backed_block_data(struct backed_block *bb)
76b55dceea986ab24f8b836b5116b389ed619c816eColin Cross{
77b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	assert(bb->type == BACKED_BLOCK_DATA);
78b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	return bb->data.data;
79b55dceea986ab24f8b836b5116b389ed619c816eColin Cross}
80b55dceea986ab24f8b836b5116b389ed619c816eColin Cross
81b55dceea986ab24f8b836b5116b389ed619c816eColin Crossconst char *backed_block_filename(struct backed_block *bb)
82b55dceea986ab24f8b836b5116b389ed619c816eColin Cross{
83b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	assert(bb->type == BACKED_BLOCK_FILE);
84b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	return bb->file.filename;
85b55dceea986ab24f8b836b5116b389ed619c816eColin Cross}
86b55dceea986ab24f8b836b5116b389ed619c816eColin Cross
879e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Crossint backed_block_fd(struct backed_block *bb)
889e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross{
899e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross	assert(bb->type == BACKED_BLOCK_FD);
909e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross	return bb->fd.fd;
919e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross}
929e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross
93b55dceea986ab24f8b836b5116b389ed619c816eColin Crossint64_t backed_block_file_offset(struct backed_block *bb)
94b55dceea986ab24f8b836b5116b389ed619c816eColin Cross{
959e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross	assert(bb->type == BACKED_BLOCK_FILE || bb->type == BACKED_BLOCK_FD);
969e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross	if (bb->type == BACKED_BLOCK_FILE) {
979e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross		return bb->file.offset;
989e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross	} else { /* bb->type == BACKED_BLOCK_FD */
999e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross		return bb->fd.offset;
1009e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross	}
101b55dceea986ab24f8b836b5116b389ed619c816eColin Cross}
102b55dceea986ab24f8b836b5116b389ed619c816eColin Cross
103b55dceea986ab24f8b836b5116b389ed619c816eColin Crossuint32_t backed_block_fill_val(struct backed_block *bb)
104b55dceea986ab24f8b836b5116b389ed619c816eColin Cross{
105b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	assert(bb->type == BACKED_BLOCK_FILL);
106b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	return bb->fill.val;
107b55dceea986ab24f8b836b5116b389ed619c816eColin Cross}
108b55dceea986ab24f8b836b5116b389ed619c816eColin Cross
109b55dceea986ab24f8b836b5116b389ed619c816eColin Crossenum backed_block_type backed_block_type(struct backed_block *bb)
110b55dceea986ab24f8b836b5116b389ed619c816eColin Cross{
111b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	return bb->type;
112b55dceea986ab24f8b836b5116b389ed619c816eColin Cross}
113b55dceea986ab24f8b836b5116b389ed619c816eColin Cross
114be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Crossvoid backed_block_destroy(struct backed_block *bb)
115411619e921904b896eddae81c086c1f687c8304dColin Cross{
116be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	if (bb->type == BACKED_BLOCK_FILE) {
117be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross		free(bb->file.filename);
118be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	}
119411619e921904b896eddae81c086c1f687c8304dColin Cross
120be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	free(bb);
121be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross}
122be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross
123be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Crossstruct backed_block_list *backed_block_list_new(unsigned int block_size)
124be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross{
125be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	struct backed_block_list *b = calloc(sizeof(struct backed_block_list), 1);
126be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	b->block_size = block_size;
127411619e921904b896eddae81c086c1f687c8304dColin Cross	return b;
128411619e921904b896eddae81c086c1f687c8304dColin Cross}
12928fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
130b55dceea986ab24f8b836b5116b389ed619c816eColin Crossvoid backed_block_list_destroy(struct backed_block_list *bbl)
131411619e921904b896eddae81c086c1f687c8304dColin Cross{
132b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	if (bbl->data_blocks) {
133b55dceea986ab24f8b836b5116b389ed619c816eColin Cross		struct backed_block *bb = bbl->data_blocks;
134b55dceea986ab24f8b836b5116b389ed619c816eColin Cross		while (bb) {
135b55dceea986ab24f8b836b5116b389ed619c816eColin Cross			struct backed_block *next = bb->next;
136be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross			backed_block_destroy(bb);
137b55dceea986ab24f8b836b5116b389ed619c816eColin Cross			bb = next;
138411619e921904b896eddae81c086c1f687c8304dColin Cross		}
139411619e921904b896eddae81c086c1f687c8304dColin Cross	}
140411619e921904b896eddae81c086c1f687c8304dColin Cross
141b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	free(bbl);
142411619e921904b896eddae81c086c1f687c8304dColin Cross}
143411619e921904b896eddae81c086c1f687c8304dColin Cross
144be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross/* may free b */
145be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Crossstatic int merge_bb(struct backed_block_list *bbl,
146be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross		struct backed_block *a, struct backed_block *b)
147be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross{
148be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	unsigned int block_len;
149be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross
150be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	/* Block doesn't exist (possible if one block is the last block) */
151be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	if (!a || !b) {
152be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross		return -EINVAL;
153be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	}
154be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross
155be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	assert(a->block < b->block);
156be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross
157be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	/* Blocks are of different types */
158be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	if (a->type != b->type) {
159be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross		return -EINVAL;
160be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	}
161be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross
162be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	/* Blocks are not adjacent */
163be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	block_len = a->len / bbl->block_size; /* rounds down */
164be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	if (a->block + block_len != b->block) {
165be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross		return -EINVAL;
166be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	}
167be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross
168be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	switch (a->type) {
169be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	case BACKED_BLOCK_DATA:
170be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross		/* Don't support merging data for now */
171be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross		return -EINVAL;
172be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	case BACKED_BLOCK_FILL:
173be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross		if (a->fill.val != b->fill.val) {
174be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross			return -EINVAL;
175be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross		}
176be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross		break;
177be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	case BACKED_BLOCK_FILE:
178be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross		if (a->file.filename != b->file.filename ||
179be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross				a->file.offset + a->len != b->file.offset) {
180be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross			return -EINVAL;
181be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross		}
182be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross		break;
183be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	case BACKED_BLOCK_FD:
184be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross		if (a->fd.fd != b->fd.fd ||
185be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross				a->fd.offset + a->len != b->fd.offset) {
186be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross			return -EINVAL;
187be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross		}
188be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross		break;
189be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	}
190be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross
191be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	/* Blocks are compatible and adjacent, with a before b.  Merge b into a,
192be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	 * and free b */
193be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	a->len += b->len;
194be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	a->next = b->next;
195be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross
196be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	backed_block_destroy(b);
197be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross
198be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	return 0;
199be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross}
200be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross
201b55dceea986ab24f8b836b5116b389ed619c816eColin Crossstatic int queue_bb(struct backed_block_list *bbl, struct backed_block *new_bb)
20228fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross{
203b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	struct backed_block *bb;
20428fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
205b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	if (bbl->data_blocks == NULL) {
206b55dceea986ab24f8b836b5116b389ed619c816eColin Cross		bbl->data_blocks = new_bb;
207b55dceea986ab24f8b836b5116b389ed619c816eColin Cross		return 0;
20828fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross	}
20928fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
210b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	if (bbl->data_blocks->block > new_bb->block) {
211b55dceea986ab24f8b836b5116b389ed619c816eColin Cross		new_bb->next = bbl->data_blocks;
212b55dceea986ab24f8b836b5116b389ed619c816eColin Cross		bbl->data_blocks = new_bb;
213b55dceea986ab24f8b836b5116b389ed619c816eColin Cross		return 0;
21428fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross	}
21528fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
21628fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross	/* Optimization: blocks are mostly queued in sequence, so save the
217b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	   pointer to the last bb that was added, and start searching from
21828fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross	   there if the next block number is higher */
219b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	if (bbl->last_used && new_bb->block > bbl->last_used->block)
220b55dceea986ab24f8b836b5116b389ed619c816eColin Cross		bb = bbl->last_used;
22128fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross	else
222b55dceea986ab24f8b836b5116b389ed619c816eColin Cross		bb = bbl->data_blocks;
223b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	bbl->last_used = new_bb;
22428fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
225b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	for (; bb->next && bb->next->block < new_bb->block; bb = bb->next)
22628fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross		;
22728fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
228b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	if (bb->next == NULL) {
229b55dceea986ab24f8b836b5116b389ed619c816eColin Cross		bb->next = new_bb;
23028fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross	} else {
231b55dceea986ab24f8b836b5116b389ed619c816eColin Cross		new_bb->next = bb->next;
232b55dceea986ab24f8b836b5116b389ed619c816eColin Cross		bb->next = new_bb;
23328fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross	}
234b55dceea986ab24f8b836b5116b389ed619c816eColin Cross
235be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	merge_bb(bbl, new_bb, new_bb->next);
236be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross	merge_bb(bbl, bb, new_bb);
237be8ddcb35a459481c0bcf5bfe645c1fefe963f5cColin Cross
238b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	return 0;
23928fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross}
24028fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
24128fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross/* Queues a fill block of memory to be written to the specified data blocks */
242b55dceea986ab24f8b836b5116b389ed619c816eColin Crossint backed_block_add_fill(struct backed_block_list *bbl, unsigned int fill_val,
243411619e921904b896eddae81c086c1f687c8304dColin Cross		unsigned int len, unsigned int block)
24428fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross{
245b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	struct backed_block *bb = calloc(1, sizeof(struct backed_block));
246b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	if (bb == NULL) {
247b55dceea986ab24f8b836b5116b389ed619c816eColin Cross		return -ENOMEM;
24828fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross	}
24928fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
250b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	bb->block = block;
251b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	bb->len = len;
252b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	bb->type = BACKED_BLOCK_FILL;
253b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	bb->fill.val = fill_val;
254b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	bb->next = NULL;
25528fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
256b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	return queue_bb(bbl, bb);
25728fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross}
25828fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
25928fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross/* Queues a block of memory to be written to the specified data blocks */
260b55dceea986ab24f8b836b5116b389ed619c816eColin Crossint backed_block_add_data(struct backed_block_list *bbl, void *data,
261b55dceea986ab24f8b836b5116b389ed619c816eColin Cross		unsigned int len, unsigned int block)
26228fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross{
263b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	struct backed_block *bb = calloc(1, sizeof(struct backed_block));
264b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	if (bb == NULL) {
265b55dceea986ab24f8b836b5116b389ed619c816eColin Cross		return -ENOMEM;
26628fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross	}
26728fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
268b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	bb->block = block;
269b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	bb->len = len;
270b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	bb->type = BACKED_BLOCK_DATA;
271b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	bb->data.data = data;
272b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	bb->next = NULL;
27328fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
274b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	return queue_bb(bbl, bb);
27528fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross}
27628fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
27728fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross/* Queues a chunk of a file on disk to be written to the specified data blocks */
278b55dceea986ab24f8b836b5116b389ed619c816eColin Crossint backed_block_add_file(struct backed_block_list *bbl, const char *filename,
279411619e921904b896eddae81c086c1f687c8304dColin Cross		int64_t offset, unsigned int len, unsigned int block)
28028fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross{
281b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	struct backed_block *bb = calloc(1, sizeof(struct backed_block));
282b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	if (bb == NULL) {
283b55dceea986ab24f8b836b5116b389ed619c816eColin Cross		return -ENOMEM;
28428fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross	}
28528fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
286b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	bb->block = block;
287b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	bb->len = len;
288b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	bb->type = BACKED_BLOCK_FILE;
289b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	bb->file.filename = strdup(filename);
290b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	bb->file.offset = offset;
291b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	bb->next = NULL;
29228fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross
293b55dceea986ab24f8b836b5116b389ed619c816eColin Cross	return queue_bb(bbl, bb);
29428fa5bc347390480fe190294c6c385b6a9f0d68bColin Cross}
2959e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross
2969e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross/* Queues a chunk of a fd to be written to the specified data blocks */
2979e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Crossint backed_block_add_fd(struct backed_block_list *bbl, int fd, int64_t offset,
2989e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross		unsigned int len, unsigned int block)
2999e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross{
3009e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross	struct backed_block *bb = calloc(1, sizeof(struct backed_block));
3019e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross	if (bb == NULL) {
3029e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross		return -ENOMEM;
3039e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross	}
3049e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross
3059e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross	bb->block = block;
3069e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross	bb->len = len;
3079e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross	bb->type = BACKED_BLOCK_FD;
3089e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross	bb->fd.fd = fd;
3099e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross	bb->fd.offset = offset;
3109e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross	bb->next = NULL;
3119e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross
3129e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross	return queue_bb(bbl, bb);
3139e1f17e926fa20255c5f4b4d2f68aa98a964253aColin Cross}
314