Пример #1
0
/*
 * 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;
}
Пример #2
0
/*
 * 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;
}
Пример #3
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;
}