int ulo_loop(int sig, ulo_cb_t store, void *arg) { int err; static sigset_t sigset; union ulo_ctl ctl; err = sigemptyset(&sigset); if (!err) err = sigaddset(&sigset, sig); if (!err) err = sigprocmask(SIG_BLOCK, &sigset, NULL); while (!err) { ctl.ready.signum = sig; //Dbg("ready\n"); err = ioctl(g_uloop.fd[ULO_DEV], ULOCTL_READY, &ctl); DbgErr(err); if (!err) err = sigwaitinfo(&sigset, NULL); //DbgErr(err); if (err == sig) err = ioctl(g_uloop.fd[ULO_DEV], ULOCTL_RCVREQ, &ctl); DbgErr(err); if (!err) err = store(ctl.rcvreq.start, ctl.rcvreq.size, arg); if (!err) { ctl.sndres.start = ctl.rcvreq.start; ctl.sndres.size = ctl.rcvreq.size; err = ioctl(g_uloop.fd[ULO_DEV], ULOCTL_SNDRES, &ctl); DbgErr(err); } } return err; }
static int store(unsigned long long start, int size, void *arg) { int err; unsigned long long m, tsize; char *src, *dst; //Dbg("start %Lu, size %d\n", start, size); assert(start + size <= uloop->cache_size); err = -1; m = start % uloop->pagesize; start -= m; size += m; tsize = uloop->tgt_size; if (tsize < start + size) size = tsize - start; src = mmap(NULL, size, PROT_READ, MAP_SHARED, real_fd, start); if (src == MAP_FAILED) goto out; dst = mmap(NULL, size, PROT_WRITE, MAP_SHARED, ulo_cache_fd, start); if (dst == MAP_FAILED) goto out_src; memcpy(dst, src, size); #if 0 err = msync(dst, size, MS_SYNC); DbgErr(err); #endif err = munmap(dst, size); out_src: munmap(src, size); /* ignore */ out: DbgErr(err); return err; }
static int ulo_init_loop(char *dev_path, int dev_flags, char *cache_path) { int err; struct loop_info64 loinfo64; union ulo_ctl ctl; err = open(dev_path, dev_flags); if (err < 0) goto out; g_uloop.fd[ULO_DEV] = err; err = ioctl(g_uloop.fd[ULO_DEV], LOOP_SET_FD, g_uloop.fd[ULO_CACHE]); if (err) goto out; memset(&loinfo64, 0, sizeof(loinfo64)); strncpy((void *)(loinfo64.lo_file_name), cache_path, LO_NAME_SIZE); loinfo64.lo_encrypt_type = LOOP_FILTER_ULOOP; //strncpy((void *)(loinfo64.lo_crypt_name), "ulttp", LO_NAME_SIZE); //loinfo64.lo_sizelimit = cache_size; err = ioctl(g_uloop.fd[ULO_DEV], LOOP_SET_STATUS64, &loinfo64); if (err) goto out_loop; ctl.setbmp.fd = g_uloop.fd[ULO_BITMAP]; ctl.setbmp.pagesize = g_uloop.pagesize; err = ioctl(g_uloop.fd[ULO_DEV], ULOCTL_SETBMP, &ctl); if (!err) { #if 0 Dbg("{%d, %d, %d}, pgae %d, tgt %Lu, cache %Lu\n", uloop->fd[0], uloop->fd[1], uloop->fd[2], uloop->pagesize, uloop->tgt_size, uloop->cache_size); #endif return 0; } DbgErr(err); out_loop: ioctl(g_uloop.fd[ULO_DEV], LOOP_CLR_FD, g_uloop.fd[ULO_CACHE]); out: return err; }