/*
 * Block driver for the COW format
 * 
 * Copyright (c) 2004 Fabrice Bellard
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#ifndef _WIN32
#include "vl.h"
#include "block_int.h"
#include <sys/mman.h>

/**************************************************************/
/* COW block driver using file system holes */

/* user mode linux compatible COW file */
#define COW_MAGIC 0x4f4f4f4d  /* MOOO */
#define COW_VERSION 2

struct cow_header_v2 {
    uint32_t magic;
    uint32_t version;
    char backing_file[1024];
    int32_t mtime;
    uint64_t size;
    uint32_t sectorsize;
};

typedef struct BDRVCowState {
    int fd;
    uint8_t *cow_bitmap; /* if non NULL, COW mappings are used first */
    uint8_t *cow_bitmap_addr; /* mmap address of cow_bitmap */
    int cow_bitmap_size;
    int64_t cow_sectors_offset;
} BDRVCowState;

static int cow_probe(const uint8_t *buf, int buf_size, const char *filename)
{
    const struct cow_header_v2 *cow_header = (const void *)buf;

    if (buf_size >= sizeof(struct cow_header_v2) &&
        be32_to_cpu(cow_header->magic) == COW_MAGIC &&
        be32_to_cpu(cow_header->version) == COW_VERSION) 
        return 100;
    else
        return 0;
}

static int cow_open(BlockDriverState *bs, const char *filename)
{
    BDRVCowState *s = bs->opaque;
    int fd;
    struct cow_header_v2 cow_header;
    int64_t size;

    fd = open(filename, O_RDWR | O_BINARY | O_LARGEFILE);
    if (fd < 0) {
        fd = open(filename, O_RDONLY | O_BINARY | O_LARGEFILE);
        if (fd < 0)
            return -1;
    }
    s->fd = fd;
    /* see if it is a cow image */
    if (read(fd, &cow_header, sizeof(cow_header)) != sizeof(cow_header)) {
        goto fail;
    }

    if (be32_to_cpu(cow_header.magic) != COW_MAGIC ||
        be32_to_cpu(cow_header.version) != COW_VERSION) {
        goto fail;
    }
        
    /* cow image found */
    size = be64_to_cpu(cow_header.size);
    bs->total_sectors = size / 512;

    pstrcpy(bs->backing_file, sizeof(bs->backing_file), 
            cow_header.backing_file);
    
#if 0
    if (cow_header.backing_file[0] != '\0') {
        if (stat(cow_header.backing_file, &st) != 0) {
            fprintf(stderr, "%s: could not find original disk image '%s'\n", filename, cow_header.backing_file);
            goto fail;
        }
        if (st.st_mtime != be32_to_cpu(cow_header.mtime)) {
            fprintf(stderr, "%s: original raw disk image '%s' does not match saved timestamp\n", filename, cow_header.backing_file);
            goto fail;
            }
        fd = open(cow_header.backing_file, O_RDONLY | O_LARGEFILE);
        if (fd < 0)
            goto fail;
        bs->fd = fd;
    }
#endif
    /* mmap the bitmap */
    s->cow_bitmap_size = ((bs->total_sectors + 7) >> 3) + sizeof(cow_header);
    s->cow_bitmap_addr = mmap(get_mmap_addr(s->cow_bitmap_size), 
                              s->cow_bitmap_size, 
                              PROT_READ | PROT_WRITE,
                              MAP_SHARED, s->fd, 0);
    if (s->cow_bitmap_addr == MAP_FAILED)
        goto fail;
    s->cow_bitmap = s->cow_bitmap_addr + sizeof(cow_header);
    s->cow_sectors_offset = (s->cow_bitmap_size + 511) & ~511;
    return 0;
 fail:
    close(fd);
    return -1;
}

static inline void cow_set_bit(uint8_t *bitmap, int64_t bitnum)
{
    bitmap[bitnum / 8] |= (1 << (bitnum%8));
}

static inline int is_bit_set(const uint8_t *bitmap, int64_t bitnum)
{
    return !!(bitmap[bitnum / 8] & (1 << (bitnum%8)));
}


/* Return true if first block has been changed (ie. current version is
 * in COW file).  Set the number of continuous blocks for which that
 * is true. */
static inline int is_changed(uint8_t *bitmap,
                             int64_t sector_num, int nb_sectors,
                             int *num_same)
{
    int changed;

    if (!bitmap || nb_sectors == 0) {
	*num_same = nb_sectors;
	return 0;
    }

    changed = is_bit_set(bitmap, sector_num);
    for (*num_same = 1; *num_same < nb_sectors; (*num_same)++) {
	if (is_bit_set(bitmap, sector_num + *num_same) != changed)
	    break;
    }

    return changed;
}

static int cow_is_allocated(BlockDriverState *bs, int64_t sector_num, 
                            int nb_sectors, int *pnum)
{
    BDRVCowState *s = bs->opaque;
    return is_changed(s->cow_bitmap, sector_num, nb_sectors, pnum);
}

static int cow_read(BlockDriverState *bs, int64_t sector_num, 
                    uint8_t *buf, int nb_sectors)
{
    BDRVCowState *s = bs->opaque;
    int ret, n;
    
    while (nb_sectors > 0) {
        if (is_changed(s->cow_bitmap, sector_num, nb_sectors, &n)) {
            lseek(s->fd, s->cow_sectors_offset + sector_num * 512, SEEK_SET);
            ret = read(s->fd, buf, n * 512);
            if (ret != n * 512) 
                return -1;
        } else {
            memset(buf, 0, n * 512);
        }
        nb_sectors -= n;
        sector_num += n;
        buf += n * 512;
    }
    return 0;
}

static int cow_write(BlockDriverState *bs, int64_t sector_num, 
                     const uint8_t *buf, int nb_sectors)
{
    BDRVCowState *s = bs->opaque;
    int ret, i;
    
    lseek(s->fd, s->cow_sectors_offset + sector_num * 512, SEEK_SET);
    ret = write(s->fd, buf, nb_sectors * 512);
    if (ret != nb_sectors * 512) 
        return -1;
    for (i = 0; i < nb_sectors; i++)
        cow_set_bit(s->cow_bitmap, sector_num + i);
    return 0;
}

static void cow_close(BlockDriverState *bs)
{
    BDRVCowState *s = bs->opaque;
    munmap(s->cow_bitmap_addr, s->cow_bitmap_size);
    close(s->fd);
}

static int cow_create(const char *filename, int64_t image_sectors,
                      const char *image_filename, int flags)
{
    int fd, cow_fd;
    struct cow_header_v2 cow_header;
    struct stat st;

    if (flags)
        return -ENOTSUP;

    cow_fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE, 
              0644);
    if (cow_fd < 0)
        return -1;
    memset(&cow_header, 0, sizeof(cow_header));
    cow_header.magic = cpu_to_be32(COW_MAGIC);
    cow_header.version = cpu_to_be32(COW_VERSION);
    if (image_filename) {
        fd = open(image_filename, O_RDONLY | O_BINARY);
        if (fd < 0) {
            close(cow_fd);
            return -1;
        }
        if (fstat(fd, &st) != 0) {
            close(fd);
            return -1;
        }
        close(fd);
        cow_header.mtime = cpu_to_be32(st.st_mtime);
        realpath(image_filename, cow_header.backing_file);
    }
    cow_header.sectorsize = cpu_to_be32(512);
    cow_header.size = cpu_to_be64(image_sectors * 512);
    write(cow_fd, &cow_header, sizeof(cow_header));
    /* resize to include at least all the bitmap */
    ftruncate(cow_fd, sizeof(cow_header) + ((image_sectors + 7) >> 3));
    close(cow_fd);
    return 0;
}

static void cow_flush(BlockDriverState *bs)
{
    BDRVCowState *s = bs->opaque;
    fsync(s->fd);
}

BlockDriver bdrv_cow = {
    "cow",
    sizeof(BDRVCowState),
    cow_probe,
    cow_open,
    cow_read,
    cow_write,
    cow_close,
    cow_create,
    cow_flush,
    cow_is_allocated,
};
#endif
