aboutsummaryrefslogtreecommitdiff
path: root/lib/sqfs/data_writer/internal.h
blob: 53ddc5fc164f7d3b940fd0c182a9321cff5556db (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/* SPDX-License-Identifier: LGPL-3.0-or-later */
/*
 * internal.h
 *
 * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
 */
#ifndef INTERNAL_H
#define INTERNAL_H

#include "config.h"

#include "sqfs/data_writer.h"
#include "sqfs/compress.h"
#include "sqfs/inode.h"
#include "sqfs/table.h"
#include "sqfs/error.h"
#include "sqfs/block.h"
#include "sqfs/data.h"
#include "sqfs/io.h"
#include "util.h"

#include <string.h>
#include <stdlib.h>
#include <zlib.h>

#ifdef WITH_PTHREAD
#include <pthread.h>
#endif


#define MK_BLK_HASH(chksum, size) \
	(((uint64_t)(size) << 32) | (uint64_t)(chksum))

#define INIT_BLOCK_COUNT (128)


typedef struct {
	uint64_t offset;
	uint64_t hash;
} blk_info_t;

typedef struct {
	uint32_t index;
	uint32_t offset;
	uint64_t hash;
} frag_info_t;


#ifdef WITH_PTHREAD
typedef struct {
	sqfs_data_writer_t *shared;
	sqfs_compressor_t *cmp;
	pthread_t thread;
	uint8_t scratch[];
} compress_worker_t;
#endif

struct sqfs_data_writer_t {
	/* synchronization primitives */
#ifdef WITH_PTHREAD
	pthread_mutex_t mtx;
	pthread_cond_t queue_cond;
	pthread_cond_t done_cond;
#endif

	/* needs rw access by worker and main thread */
	sqfs_block_t *queue;
	sqfs_block_t *queue_last;

	sqfs_block_t *done;
	size_t backlog;
	int status;

	/* used by main thread only */
	uint32_t enqueue_id;
	uint32_t dequeue_id;

	unsigned int num_workers;
	size_t max_backlog;

	size_t devblksz;
	sqfs_file_t *file;

	sqfs_fragment_t *fragments;
	size_t num_fragments;
	size_t max_fragments;

	uint64_t start;

	size_t file_start;
	size_t num_blocks;
	size_t max_blocks;
	blk_info_t *blocks;
	sqfs_compressor_t *cmp;

	sqfs_block_t *frag_block;
	frag_info_t *frag_list;
	size_t frag_list_num;
	size_t frag_list_max;

	const sqfs_block_hooks_t *hooks;
	void *user_ptr;

	/* used only by workers */
	size_t max_block_size;

#ifdef WITH_PTHREAD
	compress_worker_t *workers[];
#else
	uint8_t scratch[];
#endif
};

SQFS_INTERNAL int process_completed_block(sqfs_data_writer_t *proc,
					  sqfs_block_t *block);

SQFS_INTERNAL
int process_completed_fragment(sqfs_data_writer_t *proc, sqfs_block_t *frag,
			       sqfs_block_t **blk_out);

SQFS_INTERNAL void free_blk_list(sqfs_block_t *list);

SQFS_INTERNAL
int data_writer_init(sqfs_data_writer_t *proc, size_t max_block_size,
		     sqfs_compressor_t *cmp, unsigned int num_workers,
		     size_t max_backlog, size_t devblksz, sqfs_file_t *file);

SQFS_INTERNAL void data_writer_cleanup(sqfs_data_writer_t *proc);

SQFS_INTERNAL
void data_writer_store_done(sqfs_data_writer_t *proc, sqfs_block_t *blk,
			    int status);

SQFS_INTERNAL
sqfs_block_t *data_writer_next_work_item(sqfs_data_writer_t *proc);

SQFS_INTERNAL
int data_writer_do_block(sqfs_block_t *block, sqfs_compressor_t *cmp,
			 uint8_t *scratch, size_t scratch_size);

#endif /* INTERNAL_H */