/* * pool_memset -- memset pool part described by off and count */ int pool_memset(struct pool_data *pool, uint64_t off, int c, size_t count) { int result = 0; if (pool->params.type != POOL_TYPE_BTT) memset((char *)off, 0, count); else { pool_btt_lseek(pool, (off_t)off, SEEK_SET); size_t zero_size = min(count, RW_BUFFERING_SIZE); void *buf = malloc(zero_size); if (!buf) { ERR("!malloc"); return -1; } memset(buf, c, zero_size); ssize_t nwrite = 0; do { zero_size = min(zero_size, count); nwrite = pool_btt_write(pool, buf, zero_size); if (nwrite < 0) { result = -1; break; } count -= (size_t)nwrite; } while (count > 0); free(buf); } return result; }
/* * pool_copy -- make a copy of the pool */ int pool_copy(struct pool_data *pool, const char *dst_path) { struct pool_set_file *file = pool->set_file; int dfd = util_file_create(dst_path, file->size, 0); if (dfd < 0) return -1; int result = 0; struct stat stat_buf; if (stat(file->fname, &stat_buf)) { result = -1; goto out_close; } if (fchmod(dfd, stat_buf.st_mode)) { result = -1; goto out_close; } void *daddr = mmap(NULL, file->size, PROT_READ | PROT_WRITE, MAP_SHARED, dfd, 0); if (daddr == MAP_FAILED) { result = -1; goto out_close; } if (pool->params.type != POOL_TYPE_BTT) { void *saddr = pool_set_file_map(file, 0); memcpy(daddr, saddr, file->size); goto out_unmap; } void *buf = malloc(RW_BUFFERING_SIZE); if (buf == NULL) { ERR("!malloc"); result = -1; goto out_unmap; } pool_btt_lseek(pool, 0, SEEK_SET); ssize_t buf_read = 0; void *dst = daddr; while ((buf_read = pool_btt_read(pool, buf, RW_BUFFERING_SIZE))) { if (buf_read == -1) break; memcpy(dst, buf, (size_t)buf_read); dst = (void *)((ssize_t)dst + buf_read); } free(buf); out_unmap: munmap(daddr, file->size); out_close: if (dfd >= 0) close(dfd); return result; }
/* * pool_read -- read from pool set file or regular file */ int pool_read(struct pool_data *pool, void *buff, size_t nbytes, uint64_t off) { if (off + nbytes > pool->set_file->size) return -1; if (pool->params.type != POOL_TYPE_BTT) memcpy(buff, (char *)pool->set_file->addr + off, nbytes); else { if (pool_btt_lseek(pool, (off_t)off, SEEK_SET) == -1) return -1; if ((size_t)pool_btt_read(pool, buff, nbytes) != nbytes) return -1; } return 0; }
/* * pool_write -- write to pool set file or regular file * * 'buff' has to be a buffer at least 'nbytes' long * 'off' is an offset from the beginning of the pool */ int pool_write(struct pool_data *pool, const void *buff, size_t nbytes, uint64_t off) { if (off + nbytes > pool->set_file->size) return -1; if (pool->params.type != POOL_TYPE_BTT) { memcpy((char *)pool->set_file->addr + off, buff, nbytes); util_persist_auto(pool->params.is_dev_dax, (char *)pool->set_file->addr + off, nbytes); } else { if (pool_btt_lseek(pool, (off_t)off, SEEK_SET) == -1) return -1; if ((size_t)pool_btt_write(pool, buff, nbytes) != nbytes) return -1; } return 0; }
/* * pool_copy -- make a copy of the pool */ int pool_copy(struct pool_data *pool, const char *dst_path, int overwrite) { struct pool_set_file *file = pool->set_file; int dfd; if (!os_access(dst_path, F_OK)) { if (!overwrite) { errno = EEXIST; return -1; } dfd = util_file_open(dst_path, NULL, 0, O_RDWR); } else { if (errno == ENOENT) { errno = 0; dfd = util_file_create(dst_path, file->size, 0); } else { return -1; } } if (dfd < 0) return -1; int result = 0; os_stat_t stat_buf; if (os_stat(file->fname, &stat_buf)) { result = -1; goto out_close; } if (fchmod(dfd, stat_buf.st_mode)) { result = -1; goto out_close; } void *daddr = mmap(NULL, file->size, PROT_READ | PROT_WRITE, MAP_SHARED, dfd, 0); if (daddr == MAP_FAILED) { result = -1; goto out_close; } if (pool->params.type != POOL_TYPE_BTT) { void *saddr = pool_set_file_map(file, 0); memcpy(daddr, saddr, file->size); goto out_unmap; } void *buf = malloc(RW_BUFFERING_SIZE); if (buf == NULL) { ERR("!malloc"); result = -1; goto out_unmap; } if (pool_btt_lseek(pool, 0, SEEK_SET) == -1) { result = -1; goto out_free; } ssize_t buf_read = 0; void *dst = daddr; while ((buf_read = pool_btt_read(pool, buf, RW_BUFFERING_SIZE))) { if (buf_read == -1) break; memcpy(dst, buf, (size_t)buf_read); dst = (void *)((ssize_t)dst + buf_read); } out_free: free(buf); out_unmap: munmap(daddr, file->size); out_close: (void) os_close(dfd); return result; }