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