Diff for /qemu/block-cow.c between versions 1.1 and 1.1.1.4

version 1.1, 2018/04/24 16:37:52 version 1.1.1.4, 2018/04/24 16:47:01
Line 1 Line 1
 /*  /*
  * Block driver for the COW format   * Block driver for the COW format
  *    *
  * Copyright (c) 2004 Fabrice Bellard   * Copyright (c) 2004 Fabrice Bellard
  *    *
  * Permission is hereby granted, free of charge, to any person obtaining a copy   * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal   * of this software and associated documentation files (the "Software"), to deal
  * in the Software without restriction, including without limitation the rights   * in the Software without restriction, including without limitation the rights
Line 22 Line 22
  * THE SOFTWARE.   * THE SOFTWARE.
  */   */
 #ifndef _WIN32  #ifndef _WIN32
 #include "vl.h"  #include "qemu-common.h"
 #include "block_int.h"  #include "block_int.h"
 #include <sys/mman.h>  #include <sys/mman.h>
   
Line 56  static int cow_probe(const uint8_t *buf, Line 56  static int cow_probe(const uint8_t *buf,
   
     if (buf_size >= sizeof(struct cow_header_v2) &&      if (buf_size >= sizeof(struct cow_header_v2) &&
         be32_to_cpu(cow_header->magic) == COW_MAGIC &&          be32_to_cpu(cow_header->magic) == COW_MAGIC &&
         be32_to_cpu(cow_header->version) == COW_VERSION)           be32_to_cpu(cow_header->version) == COW_VERSION)
         return 100;          return 100;
     else      else
         return 0;          return 0;
 }  }
   
 static int cow_open(BlockDriverState *bs, const char *filename)  static int cow_open(BlockDriverState *bs, const char *filename, int flags)
 {  {
     BDRVCowState *s = bs->opaque;      BDRVCowState *s = bs->opaque;
     int fd;      int fd;
Line 85  static int cow_open(BlockDriverState *bs Line 85  static int cow_open(BlockDriverState *bs
         be32_to_cpu(cow_header.version) != COW_VERSION) {          be32_to_cpu(cow_header.version) != COW_VERSION) {
         goto fail;          goto fail;
     }      }
           
     /* cow image found */      /* cow image found */
     size = be64_to_cpu(cow_header.size);      size = be64_to_cpu(cow_header.size);
     bs->total_sectors = size / 512;      bs->total_sectors = size / 512;
   
     pstrcpy(bs->backing_file, sizeof(bs->backing_file),       pstrcpy(bs->backing_file, sizeof(bs->backing_file),
             cow_header.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 */      /* mmap the bitmap */
     s->cow_bitmap_size = ((bs->total_sectors + 7) >> 3) + sizeof(cow_header);      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_addr = mmap(get_mmap_addr(s->cow_bitmap_size),
                               s->cow_bitmap_size,                                 s->cow_bitmap_size,
                               PROT_READ | PROT_WRITE,                                PROT_READ | PROT_WRITE,
                               MAP_SHARED, s->fd, 0);                                MAP_SHARED, s->fd, 0);
     if (s->cow_bitmap_addr == MAP_FAILED)      if (s->cow_bitmap_addr == MAP_FAILED)
Line 159  static inline int is_changed(uint8_t *bi Line 143  static inline int is_changed(uint8_t *bi
     return changed;      return changed;
 }  }
   
 static int cow_is_allocated(BlockDriverState *bs, int64_t sector_num,   static int cow_is_allocated(BlockDriverState *bs, int64_t sector_num,
                             int nb_sectors, int *pnum)                              int nb_sectors, int *pnum)
 {  {
     BDRVCowState *s = bs->opaque;      BDRVCowState *s = bs->opaque;
     return is_changed(s->cow_bitmap, sector_num, nb_sectors, pnum);      return is_changed(s->cow_bitmap, sector_num, nb_sectors, pnum);
 }  }
   
 static int cow_read(BlockDriverState *bs, int64_t sector_num,   static int cow_read(BlockDriverState *bs, int64_t sector_num,
                     uint8_t *buf, int nb_sectors)                      uint8_t *buf, int nb_sectors)
 {  {
     BDRVCowState *s = bs->opaque;      BDRVCowState *s = bs->opaque;
     int ret, n;      int ret, n;
       
     while (nb_sectors > 0) {      while (nb_sectors > 0) {
         if (is_changed(s->cow_bitmap, sector_num, nb_sectors, &n)) {          if (is_changed(s->cow_bitmap, sector_num, nb_sectors, &n)) {
             lseek(s->fd, s->cow_sectors_offset + sector_num * 512, SEEK_SET);              lseek(s->fd, s->cow_sectors_offset + sector_num * 512, SEEK_SET);
             ret = read(s->fd, buf, n * 512);              ret = read(s->fd, buf, n * 512);
             if (ret != n * 512)               if (ret != n * 512)
                 return -1;                  return -1;
         } else {          } else {
               if (bs->backing_hd) {
                   /* read from the base image */
                   ret = bdrv_read(bs->backing_hd, sector_num, buf, n);
                   if (ret < 0)
                       return -1;
               } else {
             memset(buf, 0, n * 512);              memset(buf, 0, n * 512);
         }          }
           }
         nb_sectors -= n;          nb_sectors -= n;
         sector_num += n;          sector_num += n;
         buf += n * 512;          buf += n * 512;
Line 188  static int cow_read(BlockDriverState *bs Line 179  static int cow_read(BlockDriverState *bs
     return 0;      return 0;
 }  }
   
 static int cow_write(BlockDriverState *bs, int64_t sector_num,   static int cow_write(BlockDriverState *bs, int64_t sector_num,
                      const uint8_t *buf, int nb_sectors)                       const uint8_t *buf, int nb_sectors)
 {  {
     BDRVCowState *s = bs->opaque;      BDRVCowState *s = bs->opaque;
     int ret, i;      int ret, i;
       
     lseek(s->fd, s->cow_sectors_offset + sector_num * 512, SEEK_SET);      lseek(s->fd, s->cow_sectors_offset + sector_num * 512, SEEK_SET);
     ret = write(s->fd, buf, nb_sectors * 512);      ret = write(s->fd, buf, nb_sectors * 512);
     if (ret != nb_sectors * 512)       if (ret != nb_sectors * 512)
         return -1;          return -1;
     for (i = 0; i < nb_sectors; i++)      for (i = 0; i < nb_sectors; i++)
         cow_set_bit(s->cow_bitmap, sector_num + i);          cow_set_bit(s->cow_bitmap, sector_num + i);
Line 220  static int cow_create(const char *filena Line 211  static int cow_create(const char *filena
     if (flags)      if (flags)
         return -ENOTSUP;          return -ENOTSUP;
   
     cow_fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,       cow_fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
               0644);                0644);
     if (cow_fd < 0)      if (cow_fd < 0)
         return -1;          return -1;
Line 228  static int cow_create(const char *filena Line 219  static int cow_create(const char *filena
     cow_header.magic = cpu_to_be32(COW_MAGIC);      cow_header.magic = cpu_to_be32(COW_MAGIC);
     cow_header.version = cpu_to_be32(COW_VERSION);      cow_header.version = cpu_to_be32(COW_VERSION);
     if (image_filename) {      if (image_filename) {
           /* Note: if no file, we put a dummy mtime */
           cow_header.mtime = cpu_to_be32(0);
   
         fd = open(image_filename, O_RDONLY | O_BINARY);          fd = open(image_filename, O_RDONLY | O_BINARY);
         if (fd < 0) {          if (fd < 0) {
             close(cow_fd);              close(cow_fd);
             return -1;              goto mtime_fail;
         }          }
         if (fstat(fd, &st) != 0) {          if (fstat(fd, &st) != 0) {
             close(fd);              close(fd);
             return -1;              goto mtime_fail;
         }          }
         close(fd);          close(fd);
         cow_header.mtime = cpu_to_be32(st.st_mtime);          cow_header.mtime = cpu_to_be32(st.st_mtime);
         realpath(image_filename, cow_header.backing_file);      mtime_fail:
           pstrcpy(cow_header.backing_file, sizeof(cow_header.backing_file),
                   image_filename);
     }      }
     cow_header.sectorsize = cpu_to_be32(512);      cow_header.sectorsize = cpu_to_be32(512);
     cow_header.size = cpu_to_be64(image_sectors * 512);      cow_header.size = cpu_to_be64(image_sectors * 512);
Line 250  static int cow_create(const char *filena Line 246  static int cow_create(const char *filena
     return 0;      return 0;
 }  }
   
   static void cow_flush(BlockDriverState *bs)
   {
       BDRVCowState *s = bs->opaque;
       fsync(s->fd);
   }
   
 BlockDriver bdrv_cow = {  BlockDriver bdrv_cow = {
     "cow",      "cow",
     sizeof(BDRVCowState),      sizeof(BDRVCowState),
Line 259  BlockDriver bdrv_cow = { Line 261  BlockDriver bdrv_cow = {
     cow_write,      cow_write,
     cow_close,      cow_close,
     cow_create,      cow_create,
       cow_flush,
     cow_is_allocated,      cow_is_allocated,
 };  };
 #endif  #endif

Removed from v.1.1  
changed lines
  Added in v.1.1.1.4


unix.superglobalmegacorp.com