// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
 */

/*
 * _XOPEN_SOURCE is needed for pread, but we define _GNU_SOURCE, which defines
 * that.
 */
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <arpa/inet.h>
#include <endian.h>
#include "cow.h"
#include "cow_sys.h"

#define PATH_LEN_V1 256

typedef __u32 time32_t;

struct cow_header_v1 {
	__s32 magic;
	__s32 version;
	char backing_file[PATH_LEN_V1];
	time32_t mtime;
	__u64 size;
	__s32 sectorsize;
} __attribute__((packed));

/*
 * Define PATH_LEN_V3 as the usual value of MAXPATHLEN, just hard-code it in
 * case other systems have different values for MAXPATHLEN.
 *
 * The same must hold for V2 - we want file format compatibility, not anything
 * else.
 */
#define PATH_LEN_V3 4096
#define PATH_LEN_V2 PATH_LEN_V3

struct cow_header_v2 {
	__u32 magic;
	__u32 version;
	char backing_file[PATH_LEN_V2];
	time32_t mtime;
	__u64 size;
	__s32 sectorsize;
} __attribute__((packed));

/*
 * Changes from V2 -
 *	PATH_LEN_V3 as described above
 *	Explicitly specify field bit lengths for systems with different
 *		lengths for the usual C types.  Not sure whether char or
 *		time_t should be changed, this can be changed later without
 *		breaking compatibility
 *	Add alignment field so that different alignments can be used for the
 *		bitmap and data
 * 	Add cow_format field to allow for the possibility of different ways
 *		of specifying the COW blocks.  For now, the only value is 0,
 * 		for the traditional COW bitmap.
 *	Move the backing_file field to the end of the header.  This allows
 *		for the possibility of expanding it into the padding required
 *		by the bitmap alignment.
 * 	The bitmap and data portions of the file will be aligned as specified
 * 		by the alignment field.  This is to allow COW files to be
 *		put on devices with restrictions on access alignments, such as
 *		/dev/raw, with a 512 byte alignment restriction.  This also
 *		allows the data to be more aligned more strictly than on
 *		sector boundaries.  This is needed for ubd-mmap, which needs
 *		the data to be page aligned.
 *	Fixed (finally!) the rounding bug
 */

/*
 * Until Dec2005, __attribute__((packed)) was left out from the below
 * definition, leading on 64-bit systems to 4 bytes of padding after mtime, to
 * align size to 8-byte alignment.  This shifted all fields above (no padding
 * was present on 32-bit, no other padding was added).
 *
 * However, this _can be detected_: it means that cow_format (always 0 until
 * now) is shifted onto the first 4 bytes of backing_file, where it is otherwise
 * impossible to find 4 zeros. -bb */

struct cow_header_v3 {
	__u32 magic;
	__u32 version;
	__u32 mtime;
	__u64 size;
	__u32 sectorsize;
	__u32 alignment;
	__u32 cow_format;
	char backing_file[PATH_LEN_V3];
} __attribute__((packed));

/* This is the broken layout used by some 64-bit binaries. */
struct cow_header_v3_broken {
	__u32 magic;
	__u32 version;
	__s64 mtime;
	__u64 size;
	__u32 sectorsize;
	__u32 alignment;
	__u32 cow_format;
	char backing_file[PATH_LEN_V3];
};

/* COW format definitions - for now, we have only the usual COW bitmap */
#define COW_BITMAP 0

union cow_header {
	struct cow_header_v1 v1;
	struct cow_header_v2 v2;
	struct cow_header_v3 v3;
	struct cow_header_v3_broken v3_b;
};

#define COW_MAGIC 0x4f4f4f4d  /* MOOO */
#define COW_VERSION 3

#define DIV_ROUND(x, len) (((x) + (len) - 1) / (len))
#define ROUND_UP(x, align) DIV_ROUND(x, align) * (align)

void cow_sizes(int version, __u64 size, int sectorsize, int align,
	       int bitmap_offset, unsigned long *bitmap_len_out,
	       int *data_offset_out)
{
	if (version < 3) {
		*bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);

		*data_offset_out = bitmap_offset + *bitmap_len_out;
		*data_offset_out = (*data_offset_out + sectorsize - 1) /
			sectorsize;
		*data_offset_out *= sectorsize;
	}
	else {
		*bitmap_len_out = DIV_ROUND(size, sectorsize);
		*bitmap_len_out = DIV_ROUND(*bitmap_len_out, 8);

		*data_offset_out = bitmap_offset + *bitmap_len_out;
		*data_offset_out = ROUND_UP(*data_offset_out, align);
	}
}

static int absolutize(char *to, int size, char *from)
{
	char save_cwd[256], *slash;
	int remaining;

	if (getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
		cow_printf("absolutize : unable to get cwd - errno = %d\n",
			   errno);
		return -1;
	}
	slash = strrchr(from, '/');
	if (slash != NULL) {
		*slash = '\0';
		if (chdir(from)) {
			*slash = '/';
			cow_printf("absolutize : Can't cd to '%s' - "
				   "errno = %d\n", from, errno);
			return -1;
		}
		*slash = '/';
		if (getcwd(to, size) == NULL) {
			cow_printf("absolutize : unable to get cwd of '%s' - "
			       "errno = %d\n", from, errno);
			return -1;
		}
		remaining = size - strlen(to);
		if (strlen(slash) + 1 > remaining) {
			cow_printf("absolutize : unable to fit '%s' into %d "
			       "chars\n", from, size);
			return -1;
		}
		strcat(to, slash);
	}
	else {
		if (strlen(save_cwd) + 1 + strlen(from) + 1 > size) {
			cow_printf("absolutize : unable to fit '%s' into %d "
			       "chars\n", from, size);
			return -1;
		}
		strcpy(to, save_cwd);
		strcat(to, "/");
		strcat(to, from);
	}
	if (chdir(save_cwd)) {
		cow_printf("absolutize : Can't cd to '%s' - "
			   "errno = %d\n", save_cwd, errno);
		return -1;
	}
	return 0;
}

int write_cow_header(char *cow_file, int fd, char *backing_file,
		     int sectorsize, int alignment, unsigned long long *size)
{
	struct cow_header_v3 *header;
	unsigned long modtime;
	int err;

	err = cow_seek_file(fd, 0);
	if (err < 0) {
		cow_printf("write_cow_header - lseek failed, err = %d\n", -err);
		goto out;
	}

	err = -ENOMEM;
	header = cow_malloc(sizeof(*header));
	if (header == NULL) {
		cow_printf("write_cow_header - failed to allocate COW V3 "
			   "header\n");
		goto out;
	}
	header->magic = htobe32(COW_MAGIC);
	header->version = htobe32(COW_VERSION);

	err = -EINVAL;
	if (strlen(backing_file) > sizeof(header->backing_file) - 1) {
		/* Below, %zd is for a size_t value */
		cow_printf("Backing file name \"%s\" is too long - names are "
			   "limited to %zd characters\n", backing_file,
			   sizeof(header->backing_file) - 1);
		goto out_free;
	}

	if (absolutize(header->backing_file, sizeof(header->backing_file),
		      backing_file))
		goto out_free;

	err = os_file_modtime(header->backing_file, &modtime);
	if (err < 0) {
		cow_printf("write_cow_header - backing file '%s' mtime "
			   "request failed, err = %d\n", header->backing_file,
			   -err);
		goto out_free;
	}

	err = cow_file_size(header->backing_file, size);
	if (err < 0) {
		cow_printf("write_cow_header - couldn't get size of "
			   "backing file '%s', err = %d\n",
			   header->backing_file, -err);
		goto out_free;
	}

	header->mtime = htobe32(modtime);
	header->size = htobe64(*size);
	header->sectorsize = htobe32(sectorsize);
	header->alignment = htobe32(alignment);
	header->cow_format = COW_BITMAP;

	err = cow_write_file(fd, header, sizeof(*header));
	if (err != sizeof(*header)) {
		cow_printf("write_cow_header - write of header to "
			   "new COW file '%s' failed, err = %d\n", cow_file,
			   -err);
		goto out_free;
	}
	err = 0;
 out_free:
	cow_free(header);
 out:
	return err;
}

int file_reader(__u64 offset, char *buf, int len, void *arg)
{
	int fd = *((int *) arg);

	return pread(fd, buf, len, offset);
}

/* XXX Need to sanity-check the values read from the header */

int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
		    __u32 *version_out, char **backing_file_out,
		    time_t *mtime_out, unsigned long long *size_out,
		    int *sectorsize_out, __u32 *align_out,
		    int *bitmap_offset_out)
{
	union cow_header *header;
	char *file;
	int err, n;
	unsigned long version, magic;

	header = cow_malloc(sizeof(*header));
	if (header == NULL) {
	        cow_printf("read_cow_header - Failed to allocate header\n");
		return -ENOMEM;
	}
	err = -EINVAL;
	n = (*reader)(0, (char *) header, sizeof(*header), arg);
	if (n < offsetof(typeof(header->v1), backing_file)) {
		cow_printf("read_cow_header - short header\n");
		goto out;
	}

	magic = header->v1.magic;
	if (magic == COW_MAGIC)
		version = header->v1.version;
	else if (magic == be32toh(COW_MAGIC))
		version = be32toh(header->v1.version);
	/* No error printed because the non-COW case comes through here */
	else goto out;

	*version_out = version;

	if (version == 1) {
		if (n < sizeof(header->v1)) {
			cow_printf("read_cow_header - failed to read V1 "
				   "header\n");
			goto out;
		}
		*mtime_out = header->v1.mtime;
		*size_out = header->v1.size;
		*sectorsize_out = header->v1.sectorsize;
		*bitmap_offset_out = sizeof(header->v1);
		*align_out = *sectorsize_out;
		file = header->v1.backing_file;
	}
	else if (version == 2) {
		if (n < sizeof(header->v2)) {
			cow_printf("read_cow_header - failed to read V2 "
				   "header\n");
			goto out;
		}
		*mtime_out = be32toh(header->v2.mtime);
		*size_out = be64toh(header->v2.size);
		*sectorsize_out = be32toh(header->v2.sectorsize);
		*bitmap_offset_out = sizeof(header->v2);
		*align_out = *sectorsize_out;
		file = header->v2.backing_file;
	}
	/* This is very subtle - see above at union cow_header definition */
	else if (version == 3 && (*((int*)header->v3.backing_file) != 0)) {
		if (n < sizeof(header->v3)) {
			cow_printf("read_cow_header - failed to read V3 "
				   "header\n");
			goto out;
		}
		*mtime_out = be32toh(header->v3.mtime);
		*size_out = be64toh(header->v3.size);
		*sectorsize_out = be32toh(header->v3.sectorsize);
		*align_out = be32toh(header->v3.alignment);
		if (*align_out == 0) {
			cow_printf("read_cow_header - invalid COW header, "
				   "align == 0\n");
		}
		*bitmap_offset_out = ROUND_UP(sizeof(header->v3), *align_out);
		file = header->v3.backing_file;
	}
	else if (version == 3) {
		cow_printf("read_cow_header - broken V3 file with"
			   " 64-bit layout - recovering content.\n");

		if (n < sizeof(header->v3_b)) {
			cow_printf("read_cow_header - failed to read V3 "
				   "header\n");
			goto out;
		}

		/*
		 * this was used until Dec2005 - 64bits are needed to represent
		 * 2038+. I.e. we can safely do this truncating cast.
		 *
		 * Additionally, we must use be32toh() instead of be64toh(), since
		 * the program used to use the former (tested - I got mtime
		 * mismatch "0 vs whatever").
		 *
		 * Ever heard about bug-to-bug-compatibility ? ;-) */
		*mtime_out = (time32_t) be32toh(header->v3_b.mtime);

		*size_out = be64toh(header->v3_b.size);
		*sectorsize_out = be32toh(header->v3_b.sectorsize);
		*align_out = be32toh(header->v3_b.alignment);
		if (*align_out == 0) {
			cow_printf("read_cow_header - invalid COW header, "
				   "align == 0\n");
		}
		*bitmap_offset_out = ROUND_UP(sizeof(header->v3_b), *align_out);
		file = header->v3_b.backing_file;
	}
	else {
		cow_printf("read_cow_header - invalid COW version\n");
		goto out;
	}
	err = -ENOMEM;
	*backing_file_out = cow_strdup(file);
	if (*backing_file_out == NULL) {
		cow_printf("read_cow_header - failed to allocate backing "
			   "file\n");
		goto out;
	}
	err = 0;
 out:
	cow_free(header);
	return err;
}

int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize,
		  int alignment, int *bitmap_offset_out,
		  unsigned long *bitmap_len_out, int *data_offset_out)
{
	unsigned long long size, offset;
	char zero = 0;
	int err;

	err = write_cow_header(cow_file, fd, backing_file, sectorsize,
			       alignment, &size);
	if (err)
		goto out;

	*bitmap_offset_out = ROUND_UP(sizeof(struct cow_header_v3), alignment);
	cow_sizes(COW_VERSION, size, sectorsize, alignment, *bitmap_offset_out,
		  bitmap_len_out, data_offset_out);

	offset = *data_offset_out + size - sizeof(zero);
	err = cow_seek_file(fd, offset);
	if (err < 0) {
		cow_printf("cow bitmap lseek failed : err = %d\n", -err);
		goto out;
	}

	/*
	 * does not really matter how much we write it is just to set EOF
	 * this also sets the entire COW bitmap
	 * to zero without having to allocate it
	 */
	err = cow_write_file(fd, &zero, sizeof(zero));
	if (err != sizeof(zero)) {
		cow_printf("Write of bitmap to new COW file '%s' failed, "
			   "err = %d\n", cow_file, -err);
		if (err >= 0)
			err = -EINVAL;
		goto out;
	}

	return 0;
 out:
	return err;
}
