^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * _XOPEN_SOURCE is needed for pread, but we define _GNU_SOURCE, which defines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <arpa/inet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <endian.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "cow.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "cow_sys.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define PATH_LEN_V1 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) /* unsigned time_t works until year 2106 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) typedef __u32 time32_t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct cow_header_v1 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) __s32 magic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) __s32 version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) char backing_file[PATH_LEN_V1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) time32_t mtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) __u64 size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) __s32 sectorsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) } __attribute__((packed));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * Define PATH_LEN_V3 as the usual value of MAXPATHLEN, just hard-code it in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * case other systems have different values for MAXPATHLEN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * The same must hold for V2 - we want file format compatibility, not anything
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * else.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define PATH_LEN_V3 4096
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define PATH_LEN_V2 PATH_LEN_V3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct cow_header_v2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) __u32 magic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) __u32 version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) char backing_file[PATH_LEN_V2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) time32_t mtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) __u64 size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) __s32 sectorsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) } __attribute__((packed));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * Changes from V2 -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * PATH_LEN_V3 as described above
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * Explicitly specify field bit lengths for systems with different
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * lengths for the usual C types. Not sure whether char or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * time_t should be changed, this can be changed later without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * breaking compatibility
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * Add alignment field so that different alignments can be used for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * bitmap and data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * Add cow_format field to allow for the possibility of different ways
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * of specifying the COW blocks. For now, the only value is 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * for the traditional COW bitmap.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * Move the backing_file field to the end of the header. This allows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * for the possibility of expanding it into the padding required
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * by the bitmap alignment.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * The bitmap and data portions of the file will be aligned as specified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * by the alignment field. This is to allow COW files to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * put on devices with restrictions on access alignments, such as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * /dev/raw, with a 512 byte alignment restriction. This also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * allows the data to be more aligned more strictly than on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * sector boundaries. This is needed for ubd-mmap, which needs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * the data to be page aligned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * Fixed (finally!) the rounding bug
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * Until Dec2005, __attribute__((packed)) was left out from the below
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * definition, leading on 64-bit systems to 4 bytes of padding after mtime, to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * align size to 8-byte alignment. This shifted all fields above (no padding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * was present on 32-bit, no other padding was added).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * However, this _can be detected_: it means that cow_format (always 0 until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * now) is shifted onto the first 4 bytes of backing_file, where it is otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * impossible to find 4 zeros. -bb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct cow_header_v3 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) __u32 magic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) __u32 version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) __u32 mtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) __u64 size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) __u32 sectorsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) __u32 alignment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) __u32 cow_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) char backing_file[PATH_LEN_V3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) } __attribute__((packed));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /* This is the broken layout used by some 64-bit binaries. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct cow_header_v3_broken {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) __u32 magic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) __u32 version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) __s64 mtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) __u64 size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) __u32 sectorsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) __u32 alignment;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) __u32 cow_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) char backing_file[PATH_LEN_V3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /* COW format definitions - for now, we have only the usual COW bitmap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define COW_BITMAP 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) union cow_header {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct cow_header_v1 v1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct cow_header_v2 v2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct cow_header_v3 v3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct cow_header_v3_broken v3_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define COW_MAGIC 0x4f4f4f4d /* MOOO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define COW_VERSION 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define DIV_ROUND(x, len) (((x) + (len) - 1) / (len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define ROUND_UP(x, align) DIV_ROUND(x, align) * (align)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) void cow_sizes(int version, __u64 size, int sectorsize, int align,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) int bitmap_offset, unsigned long *bitmap_len_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) int *data_offset_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (version < 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) *data_offset_out = bitmap_offset + *bitmap_len_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) *data_offset_out = (*data_offset_out + sectorsize - 1) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) sectorsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) *data_offset_out *= sectorsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) *bitmap_len_out = DIV_ROUND(size, sectorsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) *bitmap_len_out = DIV_ROUND(*bitmap_len_out, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) *data_offset_out = bitmap_offset + *bitmap_len_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) *data_offset_out = ROUND_UP(*data_offset_out, align);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static int absolutize(char *to, int size, char *from)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) char save_cwd[256], *slash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) int remaining;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) cow_printf("absolutize : unable to get cwd - errno = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) slash = strrchr(from, '/');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (slash != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) *slash = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (chdir(from)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) *slash = '/';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) cow_printf("absolutize : Can't cd to '%s' - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) "errno = %d\n", from, errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) *slash = '/';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (getcwd(to, size) == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) cow_printf("absolutize : unable to get cwd of '%s' - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) "errno = %d\n", from, errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) remaining = size - strlen(to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (strlen(slash) + 1 > remaining) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) cow_printf("absolutize : unable to fit '%s' into %d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) "chars\n", from, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) strcat(to, slash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (strlen(save_cwd) + 1 + strlen(from) + 1 > size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) cow_printf("absolutize : unable to fit '%s' into %d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) "chars\n", from, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) strcpy(to, save_cwd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) strcat(to, "/");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) strcat(to, from);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) if (chdir(save_cwd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) cow_printf("absolutize : Can't cd to '%s' - "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) "errno = %d\n", save_cwd, errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) int write_cow_header(char *cow_file, int fd, char *backing_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) int sectorsize, int alignment, unsigned long long *size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct cow_header_v3 *header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) long long modtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) err = cow_seek_file(fd, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) cow_printf("write_cow_header - lseek failed, err = %d\n", -err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) header = cow_malloc(sizeof(*header));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (header == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) cow_printf("write_cow_header - failed to allocate COW V3 "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) "header\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) header->magic = htobe32(COW_MAGIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) header->version = htobe32(COW_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (strlen(backing_file) > sizeof(header->backing_file) - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) /* Below, %zd is for a size_t value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) cow_printf("Backing file name \"%s\" is too long - names are "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) "limited to %zd characters\n", backing_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) sizeof(header->backing_file) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (absolutize(header->backing_file, sizeof(header->backing_file),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) backing_file))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) err = os_file_modtime(header->backing_file, &modtime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) cow_printf("write_cow_header - backing file '%s' mtime "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) "request failed, err = %d\n", header->backing_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) -err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) err = cow_file_size(header->backing_file, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) cow_printf("write_cow_header - couldn't get size of "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) "backing file '%s', err = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) header->backing_file, -err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) header->mtime = htobe32(modtime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) header->size = htobe64(*size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) header->sectorsize = htobe32(sectorsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) header->alignment = htobe32(alignment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) header->cow_format = COW_BITMAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) err = cow_write_file(fd, header, sizeof(*header));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (err != sizeof(*header)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) cow_printf("write_cow_header - write of header to "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) "new COW file '%s' failed, err = %d\n", cow_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) -err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) cow_free(header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) int file_reader(__u64 offset, char *buf, int len, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) int fd = *((int *) arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return pread(fd, buf, len, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /* XXX Need to sanity-check the values read from the header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) __u32 *version_out, char **backing_file_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) long long *mtime_out, unsigned long long *size_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) int *sectorsize_out, __u32 *align_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) int *bitmap_offset_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) union cow_header *header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) char *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) int err, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) unsigned long version, magic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) header = cow_malloc(sizeof(*header));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if (header == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) cow_printf("read_cow_header - Failed to allocate header\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) n = (*reader)(0, (char *) header, sizeof(*header), arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (n < offsetof(typeof(header->v1), backing_file)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) cow_printf("read_cow_header - short header\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) magic = header->v1.magic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (magic == COW_MAGIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) version = header->v1.version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) else if (magic == be32toh(COW_MAGIC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) version = be32toh(header->v1.version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) /* No error printed because the non-COW case comes through here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) else goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) *version_out = version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (version == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (n < sizeof(header->v1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) cow_printf("read_cow_header - failed to read V1 "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) "header\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) *mtime_out = header->v1.mtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) *size_out = header->v1.size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) *sectorsize_out = header->v1.sectorsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) *bitmap_offset_out = sizeof(header->v1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) *align_out = *sectorsize_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) file = header->v1.backing_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) else if (version == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (n < sizeof(header->v2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) cow_printf("read_cow_header - failed to read V2 "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) "header\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) *mtime_out = be32toh(header->v2.mtime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) *size_out = be64toh(header->v2.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) *sectorsize_out = be32toh(header->v2.sectorsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) *bitmap_offset_out = sizeof(header->v2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) *align_out = *sectorsize_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) file = header->v2.backing_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) /* This is very subtle - see above at union cow_header definition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) else if (version == 3 && (*((int*)header->v3.backing_file) != 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (n < sizeof(header->v3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) cow_printf("read_cow_header - failed to read V3 "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) "header\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) *mtime_out = be32toh(header->v3.mtime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) *size_out = be64toh(header->v3.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) *sectorsize_out = be32toh(header->v3.sectorsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) *align_out = be32toh(header->v3.alignment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (*align_out == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) cow_printf("read_cow_header - invalid COW header, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) "align == 0\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) *bitmap_offset_out = ROUND_UP(sizeof(header->v3), *align_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) file = header->v3.backing_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) else if (version == 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) cow_printf("read_cow_header - broken V3 file with"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) " 64-bit layout - recovering content.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (n < sizeof(header->v3_b)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) cow_printf("read_cow_header - failed to read V3 "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) "header\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * this was used until Dec2005 - 64bits are needed to represent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) * 2106+. I.e. we can safely do this truncating cast.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * Additionally, we must use be32toh() instead of be64toh(), since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * the program used to use the former (tested - I got mtime
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) * mismatch "0 vs whatever").
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) * Ever heard about bug-to-bug-compatibility ? ;-) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) *mtime_out = (time32_t) be32toh(header->v3_b.mtime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) *size_out = be64toh(header->v3_b.size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) *sectorsize_out = be32toh(header->v3_b.sectorsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) *align_out = be32toh(header->v3_b.alignment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (*align_out == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) cow_printf("read_cow_header - invalid COW header, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) "align == 0\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) *bitmap_offset_out = ROUND_UP(sizeof(header->v3_b), *align_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) file = header->v3_b.backing_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) cow_printf("read_cow_header - invalid COW version\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) *backing_file_out = cow_strdup(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (*backing_file_out == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) cow_printf("read_cow_header - failed to allocate backing "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) "file\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) cow_free(header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) int alignment, int *bitmap_offset_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) unsigned long *bitmap_len_out, int *data_offset_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) unsigned long long size, offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) char zero = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) err = write_cow_header(cow_file, fd, backing_file, sectorsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) alignment, &size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) *bitmap_offset_out = ROUND_UP(sizeof(struct cow_header_v3), alignment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) cow_sizes(COW_VERSION, size, sectorsize, alignment, *bitmap_offset_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) bitmap_len_out, data_offset_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) offset = *data_offset_out + size - sizeof(zero);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) err = cow_seek_file(fd, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) cow_printf("cow bitmap lseek failed : err = %d\n", -err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) * does not really matter how much we write it is just to set EOF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) * this also sets the entire COW bitmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) * to zero without having to allocate it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) err = cow_write_file(fd, &zero, sizeof(zero));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) if (err != sizeof(zero)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) cow_printf("Write of bitmap to new COW file '%s' failed, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) "err = %d\n", cow_file, -err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (err >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }