1b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* 2587c4b3e94c6ef877137d067d5d0f574f69b1391Mark Wielaard * image.c --- writes out the critical parts of the filesystem as a 3de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * flat file. 4b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper * 5b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper * Copyright (C) 2000 Theodore Ts'o. 6de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * 7de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * Note: this uses the POSIX IO interfaces, unlike most of the other 8de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * functions in this library. So sue me. 9de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * 10b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper * %Begin-Header% 11de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * This file may be redistributed under the terms of the GNU Library 12361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper * General Public License, version 2. 13de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * %End-Header% 14de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard */ 15361df7da6dfecd817b27e62b91752ac316d7cdd4Ulrich Drepper 16de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard#include <stdio.h> 17de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard#include <string.h> 18b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#if HAVE_UNISTD_H 19b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <unistd.h> 20b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif 21b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#if HAVE_ERRNO_H 22b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <errno.h> 23b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif 24b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <fcntl.h> 25b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <time.h> 26b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#if HAVE_SYS_STAT_H 27b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <sys/stat.h> 28b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif 29b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#if HAVE_SYS_TYPES_H 30b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include <sys/types.h> 31b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif 32b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 33b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include "ext2_fs.h" 34b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#include "ext2fs.h" 35b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 36b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#ifndef HAVE_TYPE_SSIZE_T 37b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppertypedef int ssize_t; 38b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#endif 39b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 40b337b1fd5f3b3410fe522a690ccee70bce8519eeRoland McGrath/* 41b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper * This function returns 1 if the specified block is all zeros 42b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper */ 43b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepperstatic int check_zero_block(char *buf, int blocksize) 44b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 45b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char *cp = buf; 46b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int left = blocksize; 471662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard 48b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (left > 0) { 49b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (*cp++) 50b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 0; 51fdc93e12a77866cafd1aae4463d89cef2c01d9b1Ulrich Drepper left--; 52b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 53b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 1; 54fdc93e12a77866cafd1aae4463d89cef2c01d9b1Ulrich Drepper} 55b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 56b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* 57b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper * Write the inode table out as a single block. 58b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper */ 59b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper#define BUF_BLOCKS 32 600b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath 611662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaarderrcode_t ext2fs_image_inode_write(ext2_filsys fs, int fd, int flags) 62b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 63b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper unsigned int group, left, c, d; 64b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char *buf, *cp; 65b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper blk64_t blk; 66b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ssize_t actual; 67b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper errcode_t retval; 684be1524398af8e24011cfdfa77c66832f8654a56Roland McGrath off_t r; 69b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 70b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper buf = malloc(fs->blocksize * BUF_BLOCKS); 71b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (!buf) 72b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return ENOMEM; 738f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath 74b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (group = 0; group < fs->group_desc_count; group++) { 758f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath blk = ext2fs_inode_table_loc(fs, (unsigned)group); 768f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath if (!blk) { 770b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath retval = EXT2_ET_MISSING_INODE_TABLE; 780b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath goto errout; 79b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 80b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper left = fs->inode_blocks_per_group; 811662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard while (left) { 821662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard c = BUF_BLOCKS; 83b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (c > left) 84b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper c = left; 858f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath retval = io_channel_read_blk64(fs->io, blk, c, buf); 86b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (retval) 87b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto errout; 88b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cp = buf; 89b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (c) { 90b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (!(flags & IMAGER_FLAG_SPARSEWRITE)) { 91b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper d = c; 92b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto skip_sparse; 93b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 94b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Skip zero blocks */ 95b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (check_zero_block(cp, fs->blocksize)) { 96b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper c--; 97b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper blk++; 98b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper left--; 99b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cp += fs->blocksize; 100b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper r = lseek(fd, fs->blocksize, SEEK_CUR); 101b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (r < 0) { 102b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper retval = errno; 103b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto errout; 104b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 105b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper continue; 106b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 107b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* Find non-zero blocks */ 108b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper for (d=1; d < c; d++) { 109b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (check_zero_block(cp + d*fs->blocksize, fs->blocksize)) 110b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper break; 111b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1128c4aa0ef998191ed828a37190dc179b91649938aMax Filippov skip_sparse: 113b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper actual = write(fd, cp, fs->blocksize * d); 114b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (actual == -1) { 115b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper retval = errno; 116cb499c489299de2b77472fc836a6b28ecf5361b9Mark Wielaard goto errout; 117b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 1186d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard if (actual != (ssize_t) (fs->blocksize * d)) { 1196d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard retval = EXT2_ET_SHORT_WRITE; 1206d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard goto errout; 1216d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard } 1221ccdfb683ad6c7e59793136c3a657ddf131cafd1Mark Wielaard blk += d; 1236d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard left -= d; 124b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cp += fs->blocksize * d; 1256d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard c -= d; 1266d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard } 1276d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard } 1286d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard } 1296d93c8c46d9b2b381c889e5f176451996845b055Mark Wielaard retval = 0; 130b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 131b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppererrout: 132b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper free(buf); 133b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return retval; 134b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 135b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 136b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* 137b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper * Read in the inode table and stuff it into place 138b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper */ 139b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppererrcode_t ext2fs_image_inode_read(ext2_filsys fs, int fd, 140b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int flags EXT2FS_ATTR((unused))) 141b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 142b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper unsigned int group, c, left; 143b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char *buf; 144b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper blk64_t blk; 145b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ssize_t actual; 146b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper errcode_t retval; 147b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 148b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper buf = malloc(fs->blocksize * BUF_BLOCKS); 149b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (!buf) 1500b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath return ENOMEM; 1510b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath 1520b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath for (group = 0; group < fs->group_desc_count; group++) { 153b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper blk = ext2fs_inode_table_loc(fs, (unsigned)group); 154b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (!blk) { 155b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper retval = EXT2_ET_MISSING_INODE_TABLE; 1561662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard goto errout; 1571662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard } 1581662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard left = fs->inode_blocks_per_group; 159b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (left) { 160b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper c = BUF_BLOCKS; 161b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (c > left) 162b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper c = left; 163b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper actual = read(fd, buf, fs->blocksize * c); 164b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (actual == -1) { 165b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper retval = errno; 166b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto errout; 167b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 168b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (actual != (ssize_t) (fs->blocksize * c)) { 169b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper retval = EXT2_ET_SHORT_READ; 170b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto errout; 171b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 172b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper retval = io_channel_write_blk64(fs->io, blk, c, buf); 173b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (retval) 174b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto errout; 175b0243863149acde9e42b25688c7c2959830e69a9Ulrich Drepper 176b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper blk += c; 177b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper left -= c; 178b0243863149acde9e42b25688c7c2959830e69a9Ulrich Drepper } 179b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 180b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper retval = ext2fs_flush_icache(fs); 181b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 182b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppererrout: 183b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper free(buf); 1841662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard return retval; 1851662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard} 1861662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard 1871662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard/* 188b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper * Write out superblock and group descriptors 189b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper */ 190b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppererrcode_t ext2fs_image_super_write(ext2_filsys fs, int fd, 191b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int flags EXT2FS_ATTR((unused))) 192b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 193b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char *buf, *cp; 194b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ssize_t actual; 195b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper errcode_t retval; 196b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 197b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper buf = malloc(fs->blocksize); 198b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (!buf) 199b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return ENOMEM; 200b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 201b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* 202b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper * Write out the superblock 203b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper */ 204b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper memset(buf, 0, fs->blocksize); 205b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper memcpy(buf, fs->super, SUPERBLOCK_SIZE); 206b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper actual = write(fd, buf, fs->blocksize); 207b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (actual == -1) { 208b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper retval = errno; 209b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto errout; 210b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 211b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (actual != (ssize_t) fs->blocksize) { 212b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper retval = EXT2_ET_SHORT_WRITE; 213b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto errout; 214b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 215b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 216b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* 217b0243863149acde9e42b25688c7c2959830e69a9Ulrich Drepper * Now write out the block group descriptors 218b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper */ 219b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cp = (char *) fs->group_desc; 220b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper actual = write(fd, cp, fs->blocksize * fs->desc_blocks); 221b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (actual == -1) { 2223a64a3087f53ab860c7de04da0e53dabef459520Ulrich Drepper retval = errno; 223b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto errout; 224b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 225b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (actual != (ssize_t) (fs->blocksize * fs->desc_blocks)) { 226b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper retval = EXT2_ET_SHORT_WRITE; 227b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto errout; 228b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2291c83bf1fd46b74492297694b642df36d18c6e7b5Roland McGrath 230b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper retval = 0; 231b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 232b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppererrout: 233b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper free(buf); 234b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return retval; 235b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 236b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 237b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* 238b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper * Read the superblock and group descriptors and overwrite them. 239b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper */ 240b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppererrcode_t ext2fs_image_super_read(ext2_filsys fs, int fd, 241b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper int flags EXT2FS_ATTR((unused))) 242b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 243b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char *buf; 244b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ssize_t actual, size; 245b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper errcode_t retval; 246b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 247b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size = fs->blocksize * (fs->group_desc_count + 1); 248b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper buf = malloc(size); 249b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (!buf) 250b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return ENOMEM; 251b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 252b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper /* 253b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper * Read it all in. 254b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper */ 255b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper actual = read(fd, buf, size); 256b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (actual == -1) { 257b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper retval = errno; 258b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto errout; 259b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 260b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (actual != size) { 261b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper retval = EXT2_ET_SHORT_READ; 262b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper goto errout; 263b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 2641662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard 2651662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard /* 2661662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard * Now copy in the superblock and group descriptors 2671662bc3880ae5acae6aa2a3013d193223c36f189Mark Wielaard */ 268b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper memcpy(fs->super, buf, SUPERBLOCK_SIZE); 269b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 270b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper memcpy(fs->group_desc, buf + fs->blocksize, 271b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper fs->blocksize * fs->group_desc_count); 2728f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath 2738f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath retval = 0; 2748f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath 2758f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGratherrout: 2768f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath free(buf); 2778f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath return retval; 2788f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath} 2798f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath 2808f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath/* 2818f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath * Write the block/inode bitmaps. 2828f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath */ 283b08d5a8fb42f4586d756068065186b5af7e48daUlrich Dreppererrcode_t ext2fs_image_bitmap_write(ext2_filsys fs, int fd, int flags) 2848f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath{ 2858f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath ext2fs_generic_bitmap bmap; 286b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper errcode_t retval; 287b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ssize_t actual; 288b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __u32 itr, cnt, size; 2890b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath int c, total_size; 2900b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath char buf[1024]; 2910b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath 2920b9d1fb534604a9ba19999cd8ce8e7efce28da24Roland McGrath if (flags & IMAGER_FLAG_INODEMAP) { 293b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (!fs->inode_map) { 294b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper retval = ext2fs_read_inode_bitmap(fs); 295b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (retval) 296b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return retval; 2978f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath } 2988f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath bmap = fs->inode_map; 2998f31c2c6f18323daf2a6ce30a24fa4dfe0a70fb3Roland McGrath itr = 1; 300b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count; 301b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size = (EXT2_INODES_PER_GROUP(fs->super) / 8); 302b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } else { 303b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (!fs->block_map) { 304b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper retval = ext2fs_read_block_bitmap(fs); 305b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (retval) 306b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return retval; 307b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 308b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bmap = fs->block_map; 309b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper itr = fs->super->s_first_data_block; 310b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt = EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count; 311b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size = EXT2_BLOCKS_PER_GROUP(fs->super) / 8; 312b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 3133425454a10d307fae891fb667cf7969e945cde79Josh Stone total_size = size * fs->group_desc_count; 3148c4aa0ef998191ed828a37190dc179b91649938aMax Filippov 315b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (cnt > 0) { 316b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size = sizeof(buf); 317b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (size > (cnt >> 3)) 3183425454a10d307fae891fb667cf7969e945cde79Josh Stone size = (cnt >> 3); 319b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 320e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper retval = ext2fs_get_generic_bmap_range(bmap, itr, 321b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size << 3, buf); 322b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (retval) 323b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return retval; 324b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 325b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper actual = write(fd, buf, size); 3268c4aa0ef998191ed828a37190dc179b91649938aMax Filippov if (actual == -1) 3278c4aa0ef998191ed828a37190dc179b91649938aMax Filippov return errno; 328b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (actual != (int) size) 329b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return EXT2_ET_SHORT_READ; 330b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 331095a01b14c2562a33615f079f300ac86da95bc56Roland McGrath itr += size << 3; 332b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt -= size << 3; 333b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 334e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper 335b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size = total_size % fs->blocksize; 336b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper memset(buf, 0, sizeof(buf)); 337b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (size) { 338b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size = fs->blocksize - size; 339b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (size) { 340b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper c = size; 3413425454a10d307fae891fb667cf7969e945cde79Josh Stone if (c > (int) sizeof(buf)) 3423425454a10d307fae891fb667cf7969e945cde79Josh Stone c = sizeof(buf); 343b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper actual = write(fd, buf, c); 344e3f9b7db6c7361579ec5cc5eb5e414f7e93baeb6Ulrich Drepper if (actual == -1) 345b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return errno; 346b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (actual != c) 347b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return EXT2_ET_SHORT_WRITE; 348b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size -= c; 349b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 350b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 351b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 0; 352b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 353b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 354b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 355b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper/* 356b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper * Read the block/inode bitmaps. 357095a01b14c2562a33615f079f300ac86da95bc56Roland McGrath */ 358095a01b14c2562a33615f079f300ac86da95bc56Roland McGratherrcode_t ext2fs_image_bitmap_read(ext2_filsys fs, int fd, int flags) 359b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper{ 360b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ext2fs_generic_bitmap bmap; 361b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper errcode_t retval; 362b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper __u32 itr, cnt; 363b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper char buf[1024]; 364b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper unsigned int size; 365b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper ssize_t actual; 366b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 367b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (flags & IMAGER_FLAG_INODEMAP) { 368b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (!fs->inode_map) { 369b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper retval = ext2fs_read_inode_bitmap(fs); 3708190db6a86a37aec86c81626ab1b083c96aff891Roland McGrath if (retval) 371b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return retval; 3728190db6a86a37aec86c81626ab1b083c96aff891Roland McGrath } 373b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper bmap = fs->inode_map; 374b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper itr = 1; 375b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count; 376b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size = (EXT2_INODES_PER_GROUP(fs->super) / 8); 377cb499c489299de2b77472fc836a6b28ecf5361b9Mark Wielaard } else { 378cb499c489299de2b77472fc836a6b28ecf5361b9Mark Wielaard if (!fs->block_map) { 379cb499c489299de2b77472fc836a6b28ecf5361b9Mark Wielaard retval = ext2fs_read_block_bitmap(fs); 380cb499c489299de2b77472fc836a6b28ecf5361b9Mark Wielaard if (retval) 381cb499c489299de2b77472fc836a6b28ecf5361b9Mark Wielaard return retval; 382cb499c489299de2b77472fc836a6b28ecf5361b9Mark Wielaard } 383cb499c489299de2b77472fc836a6b28ecf5361b9Mark Wielaard bmap = fs->block_map; 384cb499c489299de2b77472fc836a6b28ecf5361b9Mark Wielaard itr = fs->super->s_first_data_block; 385cb499c489299de2b77472fc836a6b28ecf5361b9Mark Wielaard cnt = EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count; 386cb499c489299de2b77472fc836a6b28ecf5361b9Mark Wielaard size = EXT2_BLOCKS_PER_GROUP(fs->super) / 8; 387cb499c489299de2b77472fc836a6b28ecf5361b9Mark Wielaard } 388b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 389b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper while (cnt > 0) { 390b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size = sizeof(buf); 391b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (size > (cnt >> 3)) 392b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size = (cnt >> 3); 393b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 394b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper actual = read(fd, buf, size); 395b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (actual == -1) 396b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return errno; 397b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (actual != (int) size) 398b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return EXT2_ET_SHORT_READ; 399b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 400b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper retval = ext2fs_set_generic_bmap_range(bmap, itr, 401b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper size << 3, buf); 402b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper if (retval) 403b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return retval; 404b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper 405b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper itr += size << 3; 406b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper cnt -= size << 3; 407b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper } 408b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper return 0; 409b08d5a8fb42f4586d756068065186b5af7e48daUlrich Drepper} 4108c4aa0ef998191ed828a37190dc179b91649938aMax Filippov