Subversion Repositories Kolibri OS

Rev

Rev 9337 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <errno.h>
  5.  
  6. #include "umka.h"
  7. #include "trace.h"
  8. #include "vdisk.h"
  9.  
  10. typedef struct {
  11.     FILE *file;
  12.     uint32_t sect_size;
  13.     uint64_t sect_cnt;
  14.     unsigned cache_size;
  15.     int      adjust_cache_size;
  16. } vdisk_t;
  17.  
  18. void *vdisk_init(const char *fname, int adjust_cache_size, size_t cache_size) {
  19.     FILE *f = fopen(fname, "r+");
  20.     if (!f) {
  21.         printf("vdisk: can't open file '%s': %s\n", fname, strerror(errno));
  22.         return NULL;
  23.     }
  24.     fseek(f, 0, SEEK_END);
  25.     off_t fsize = ftell(f);
  26.     fseek(f, 0, SEEK_SET);
  27.     size_t sect_size = 512;
  28.     if (strstr(fname, "s4096") != NULL || strstr(fname, "s4k") != NULL) {
  29.         sect_size = 4096;
  30.     }
  31.     vdisk_t *vdisk = (vdisk_t*)malloc(sizeof(vdisk_t));
  32.     *vdisk = (vdisk_t){.file = f,
  33.                        .sect_size = sect_size,
  34.                        .sect_cnt = (uint64_t)fsize / sect_size,
  35.                        .cache_size = cache_size,
  36.                        .adjust_cache_size = adjust_cache_size};
  37.     return vdisk;
  38. }
  39.  
  40. STDCALL void
  41. vdisk_close(void *userdata) {
  42.     COVERAGE_OFF();
  43.     vdisk_t *vdisk = userdata;
  44.     fclose(vdisk->file);
  45.     free(vdisk);
  46.     COVERAGE_ON();
  47. }
  48.  
  49. STDCALL int
  50. vdisk_read(void *userdata, void *buffer, off_t startsector,
  51.                size_t *numsectors) {
  52.     COVERAGE_OFF();
  53.     vdisk_t *vdisk = userdata;
  54.     fseek(vdisk->file, startsector * vdisk->sect_size, SEEK_SET);
  55.     fread(buffer, *numsectors * vdisk->sect_size, 1, vdisk->file);
  56.     COVERAGE_ON();
  57.     return ERROR_SUCCESS;
  58. }
  59.  
  60. STDCALL int
  61. vdisk_write(void *userdata, void *buffer, off_t startsector,
  62.                 size_t *numsectors) {
  63.     COVERAGE_OFF();
  64.     vdisk_t *vdisk = userdata;
  65.     fseek(vdisk->file, startsector * vdisk->sect_size, SEEK_SET);
  66.     fwrite(buffer, *numsectors * vdisk->sect_size, 1, vdisk->file);
  67.     COVERAGE_ON();
  68.     return ERROR_SUCCESS;
  69. }
  70.  
  71. STDCALL int
  72. vdisk_querymedia(void *userdata, diskmediainfo_t *minfo) {
  73.     COVERAGE_OFF();
  74.     vdisk_t *vdisk = userdata;
  75.     minfo->flags = 0u;
  76.     minfo->sector_size = vdisk->sect_size;
  77.     minfo->capacity = vdisk->sect_cnt;
  78.     COVERAGE_ON();
  79.     return ERROR_SUCCESS;
  80. }
  81.  
  82. STDCALL size_t
  83. vdisk_adjust_cache_size(void *userdata, size_t suggested_size) {
  84.     vdisk_t *vdisk = userdata;
  85.     if (vdisk->adjust_cache_size) {
  86.         return vdisk->cache_size;
  87.     } else {
  88.         return suggested_size;
  89.     }
  90. }
  91.  
  92. diskfunc_t vdisk_functions = {
  93.                                  .strucsize = sizeof(diskfunc_t),
  94.                                  .close = vdisk_close,
  95.                                  .closemedia = NULL,
  96.                                  .querymedia = vdisk_querymedia,
  97.                                  .read = vdisk_read,
  98.                                  .write = vdisk_write,
  99.                                  .flush = NULL,
  100.                                  .adjust_cache_size = vdisk_adjust_cache_size,
  101.                                 };
  102.