/*
 * 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 (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 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++)
        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;
}

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