/* * Naïve backing implementation, using one file (possibly a device * special file, eg a disk partition) to hold the current image. */ #include #include #include #include #include #include #include "backing.h" typedef struct priv PRIV; struct priv { int fd; char *detail; } ; static int simple_write(void *pv, unsigned int blkno, const void *data) { return(pwrite(((PRIV *)pv)->fd,data,512,blkno*(off_t)512)); } static int simple_read(void *pv, unsigned int blkno, unsigned int nblks, void *data) { return(pread(((PRIV *)pv)->fd,data,nblks*512,blkno*(off_t)512)); } static void simple_set_size(void *pv, unsigned int nblks) { ftruncate(((PRIV *)pv)->fd,nblks*(off_t)512); } static void simple_done(void *pv) { PRIV *p; p = pv; if (p->fd >= 0) close(p->fd); free(p->detail); free(p); } static const char *simple_detail(void *pv) { PRIV *p; p = pv; free(p->detail); asprintf(&p->detail,"%d",p->fd); return(p->detail); } static void *simple_open(const char *fn, void (*err)(const char *, ...)) { int fd; PRIV *p; fd = open(fn,O_RDWR|O_CREAT,0600); if (fd < 0) { (*err)("can't open %s: %s",fn,strerror(errno)); return(0); } p = malloc(sizeof(PRIV)); p->fd = fd; p->detail = 0; return(p); } static int simple_fstat(void *pv, struct stat *stb) { return(fstat(((PRIV *)pv)->fd,stb)); } static void simple_move(void **fvp, void **tvp) { PRIV *f; PRIV *t; f = *fvp; t = *tvp; close(t->fd); t->fd = f->fd; f->fd = -1; } static int simple_flock(void *pv, int op) { return(flock(((PRIV *)pv)->fd,op)); } const BACKING backing_simple = BACKING_INIT(simple);