direct-io.hg

changeset 4264:04400e772fd7

bitkeeper revision 1.1236.1.112 (4240562521wc_bQiFaxW7o5zjRAkFg)

Fix merge conflict from earlier today.

Signed-off-by: andrew.warfield@cl.cam.ac.uk
author akw27@arcadians.cl.cam.ac.uk
date Tue Mar 22 17:30:13 2005 +0000 (2005-03-22)
parents 1c7c83cdf0ed
children 4a49af0cc9d9 6d3b2d99e2a0
files tools/blktap/blockstore.c
line diff
     1.1 --- a/tools/blktap/blockstore.c	Tue Mar 22 16:07:38 2005 +0000
     1.2 +++ b/tools/blktap/blockstore.c	Tue Mar 22 17:30:13 2005 +0000
     1.3 @@ -15,6 +15,7 @@
     1.4  #include <sys/stat.h>
     1.5  #include <stdarg.h>
     1.6  #include "blockstore.h"
     1.7 +#include "parallax-threaded.h"
     1.8  
     1.9  #define BLOCKSTORE_REMOTE
    1.10  //#define BSDEBUG
    1.11 @@ -790,7 +791,6 @@ u64 allocblock_hint(void *block, u64 hin
    1.12  
    1.13  #else /* /BLOCKSTORE_REMOTE */
    1.14  
    1.15 -static int block_fp = -1;
    1.16   
    1.17  /**
    1.18   * readblock: read a block from disk
    1.19 @@ -801,21 +801,36 @@ static int block_fp = -1;
    1.20  
    1.21  void *readblock(u64 id) {
    1.22      void *block;
    1.23 +    int block_fp;
    1.24 +    
    1.25 +    block_fp = open("blockstore.dat", O_RDONLY | O_CREAT | O_LARGEFILE, 0644);
    1.26 +
    1.27 +    if (block_fp < 0) {
    1.28 +        perror("open");
    1.29 +        return NULL;
    1.30 +    }
    1.31 +    
    1.32      if (lseek64(block_fp, ((off64_t) id - 1LL) * BLOCK_SIZE, SEEK_SET) < 0) {
    1.33 +        printf ("%Ld ", id);
    1.34          printf ("%Ld\n", (id - 1) * BLOCK_SIZE);
    1.35          perror("readblock lseek");
    1.36 -        return NULL;
    1.37 +        goto err;
    1.38      }
    1.39      if ((block = malloc(BLOCK_SIZE)) == NULL) {
    1.40          perror("readblock malloc");
    1.41 -        return NULL;
    1.42 +        goto err;
    1.43      }
    1.44      if (read(block_fp, block, BLOCK_SIZE) != BLOCK_SIZE) {
    1.45          perror("readblock read");
    1.46          free(block);
    1.47 -        return NULL;
    1.48 +        goto err;
    1.49      }
    1.50 +    close(block_fp);
    1.51      return block;
    1.52 +    
    1.53 +err:
    1.54 +    close(block_fp);
    1.55 +    return NULL;
    1.56  }
    1.57  
    1.58  /**
    1.59 @@ -826,15 +841,30 @@ void *readblock(u64 id) {
    1.60   *   @return: zero on success, -1 on failure
    1.61   */
    1.62  int writeblock(u64 id, void *block) {
    1.63 +    
    1.64 +    int block_fp;
    1.65 +    
    1.66 +    block_fp = open("blockstore.dat", O_RDWR | O_CREAT | O_LARGEFILE, 0644);
    1.67 +
    1.68 +    if (block_fp < 0) {
    1.69 +        perror("open");
    1.70 +        return -1;
    1.71 +    }
    1.72 +
    1.73      if (lseek64(block_fp, ((off64_t) id - 1LL) * BLOCK_SIZE, SEEK_SET) < 0) {
    1.74          perror("writeblock lseek");
    1.75 -        return -1;
    1.76 +        goto err;
    1.77      }
    1.78      if (write(block_fp, block, BLOCK_SIZE) < 0) {
    1.79          perror("writeblock write");
    1.80 -        return -1;
    1.81 +        goto err;
    1.82      }
    1.83 +    close(block_fp);
    1.84      return 0;
    1.85 +
    1.86 +err:
    1.87 +    close(block_fp);
    1.88 +    return -1;
    1.89  }
    1.90  
    1.91  /**
    1.92 @@ -843,30 +873,41 @@ int writeblock(u64 id, void *block) {
    1.93   *
    1.94   *   @return: new id of block on disk
    1.95   */
    1.96 -static u64 lastblock = 0;
    1.97  
    1.98  u64 allocblock(void *block) {
    1.99      u64 lb;
   1.100 -    off64_t pos = lseek64(block_fp, 0, SEEK_END);
   1.101 +    off64_t pos;
   1.102 +    int block_fp;
   1.103 +    
   1.104 +    block_fp = open("blockstore.dat", O_RDWR | O_CREAT | O_LARGEFILE, 0644);
   1.105 +
   1.106 +    if (block_fp < 0) {
   1.107 +        perror("open");
   1.108 +        return 0;
   1.109 +    }
   1.110 +
   1.111 +    pos = lseek64(block_fp, 0, SEEK_END);
   1.112      if (pos == (off64_t)-1) {
   1.113          perror("allocblock lseek");
   1.114 -        return 0;
   1.115 +        goto err;
   1.116      }
   1.117      if (pos % BLOCK_SIZE != 0) {
   1.118          fprintf(stderr, "file size not multiple of %d\n", BLOCK_SIZE);
   1.119 -        return 0;
   1.120 +        goto err;
   1.121      }
   1.122      if (write(block_fp, block, BLOCK_SIZE) != BLOCK_SIZE) {
   1.123          perror("allocblock write");
   1.124 -        return 0;
   1.125 +        goto err;
   1.126      }
   1.127      lb = pos / BLOCK_SIZE + 1;
   1.128 +//printf("alloc(%Ld)\n", lb);
   1.129 +    close(block_fp);
   1.130 +    return lb;
   1.131      
   1.132 -    if (lb <= lastblock)
   1.133 -        printf("[*** %Ld alredy allocated! ***]\n", lb);
   1.134 +err:
   1.135 +    close(block_fp);
   1.136 +    return 0;
   1.137      
   1.138 -    lastblock = lb;
   1.139 -    return lb;
   1.140  }
   1.141  
   1.142  /**
   1.143 @@ -908,13 +949,119 @@ void freeblock(void *block) {
   1.144          free(block);
   1.145  }
   1.146  
   1.147 +static freeblock_t *new_freeblock(void)
   1.148 +{
   1.149 +    freeblock_t *fb;
   1.150 +    
   1.151 +    fb = newblock();
   1.152 +    
   1.153 +    if (fb == NULL) return NULL;
   1.154 +    
   1.155 +    fb->magic = FREEBLOCK_MAGIC;
   1.156 +    fb->next  = 0ULL;
   1.157 +    fb->count = 0ULL;
   1.158 +    memset(fb->list, 0, sizeof fb->list);
   1.159 +    
   1.160 +    return fb;
   1.161 +}
   1.162 +
   1.163 +void releaseblock(u64 id)
   1.164 +{
   1.165 +    blockstore_super_t *bs_super;
   1.166 +    freeblock_t *fl_current;
   1.167 +    
   1.168 +    /* get superblock */
   1.169 +    bs_super = (blockstore_super_t *) readblock(BLOCKSTORE_SUPER);
   1.170 +    
   1.171 +    /* get freeblock_current */
   1.172 +    if (bs_super->freelist_current == 0ULL) 
   1.173 +    {
   1.174 +        fl_current = new_freeblock();
   1.175 +        bs_super->freelist_current = allocblock(fl_current);
   1.176 +        writeblock(BLOCKSTORE_SUPER, bs_super);
   1.177 +    } else {
   1.178 +        fl_current = readblock(bs_super->freelist_current);
   1.179 +    }
   1.180 +    
   1.181 +    /* if full, chain to superblock and allocate new current */
   1.182 +    
   1.183 +    if (fl_current->count == FREEBLOCK_SIZE) {
   1.184 +        fl_current->next = bs_super->freelist_full;
   1.185 +        writeblock(bs_super->freelist_current, fl_current);
   1.186 +        bs_super->freelist_full = bs_super->freelist_current;
   1.187 +        freeblock(fl_current);
   1.188 +        fl_current = new_freeblock();
   1.189 +        bs_super->freelist_current = allocblock(fl_current);
   1.190 +        writeblock(BLOCKSTORE_SUPER, bs_super);
   1.191 +    }
   1.192 +    
   1.193 +    /* append id to current */
   1.194 +    fl_current->list[fl_current->count++] = id;
   1.195 +    writeblock(bs_super->freelist_current, fl_current);
   1.196 +    
   1.197 +    freeblock(fl_current);
   1.198 +    freeblock(bs_super);
   1.199 +    
   1.200 +    
   1.201 +}
   1.202 +
   1.203 +/* freelist debug functions: */
   1.204 +void freelist_count(int print_each)
   1.205 +{
   1.206 +    blockstore_super_t *bs_super;
   1.207 +    freeblock_t *fb;
   1.208 +    u64 total = 0, next;
   1.209 +    
   1.210 +    bs_super = (blockstore_super_t *) readblock(BLOCKSTORE_SUPER);
   1.211 +    
   1.212 +    if (bs_super->freelist_current == 0ULL) {
   1.213 +        printf("freelist is empty!\n");
   1.214 +        return;
   1.215 +    }
   1.216 +    
   1.217 +    fb = readblock(bs_super->freelist_current);
   1.218 +    printf("%Ld entires on current.\n", fb->count);
   1.219 +    total += fb->count;
   1.220 +    if (print_each == 1)
   1.221 +    {
   1.222 +        int i;
   1.223 +        for (i=0; i< fb->count; i++)
   1.224 +            printf("  %Ld\n", fb->list[i]);
   1.225 +    }
   1.226 +    
   1.227 +    freeblock(fb);
   1.228 +    
   1.229 +    if (bs_super->freelist_full == 0ULL) {
   1.230 +        printf("freelist_full is empty!\n");
   1.231 +        return;
   1.232 +    }
   1.233 +    
   1.234 +    next = bs_super->freelist_full;
   1.235 +    for (;;) {
   1.236 +        fb = readblock(next);
   1.237 +        total += fb->count;
   1.238 +        if (print_each == 1)
   1.239 +        {
   1.240 +            int i;
   1.241 +            for (i=0; i< fb->count; i++)
   1.242 +                printf("  %Ld\n", fb->list[i]);
   1.243 +        }
   1.244 +        next = fb->next;
   1.245 +        freeblock(fb);
   1.246 +        if (next == 0ULL) break;
   1.247 +    }
   1.248 +    printf("Total of %Ld ids on freelist.\n", total);
   1.249 +}
   1.250  
   1.251  int __init_blockstore(void)
   1.252  {
   1.253 +    int i;
   1.254 +    blockstore_super_t *bs_super;
   1.255 +    u64 ret;
   1.256 +    int block_fp;
   1.257 +    
   1.258  #ifdef BLOCKSTORE_REMOTE
   1.259      struct hostent *addr;
   1.260 -    int i;
   1.261 -
   1.262      bsservers[0].hostname = "firebug.cl.cam.ac.uk";
   1.263      bsservers[1].hostname = "planb.cl.cam.ac.uk";
   1.264      bsservers[2].hostname = "simcity.cl.cam.ac.uk";
   1.265 @@ -996,7 +1143,30 @@ int __init_blockstore(void)
   1.266      if (block_fp < 0) {
   1.267          perror("open");
   1.268          return -1;
   1.269 +        exit(-1);
   1.270      }
   1.271 +    
   1.272 +    if (lseek(block_fp, 0, SEEK_END) == 0) {
   1.273 +        bs_super = newblock();
   1.274 +        bs_super->magic            = BLOCKSTORE_MAGIC;
   1.275 +        bs_super->freelist_full    = 0LL;
   1.276 +        bs_super->freelist_current = 0LL;
   1.277 +        
   1.278 +        ret = allocblock(bs_super);
   1.279 +        
   1.280 +        freeblock(bs_super);
   1.281 +    } else {
   1.282 +        bs_super = (blockstore_super_t *) readblock(BLOCKSTORE_SUPER);
   1.283 +        if (bs_super->magic != BLOCKSTORE_MAGIC)
   1.284 +        {
   1.285 +            printf("BLOCKSTORE IS CORRUPT! (no magic in superblock!)\n");
   1.286 +            exit(-1);
   1.287 +        }
   1.288 +        freeblock(bs_super);
   1.289 +    }
   1.290 +        
   1.291 +    close(block_fp);
   1.292 +        
   1.293  #endif /*  BLOCKSTORE_REMOTE */   
   1.294      return 0;
   1.295  }