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
142
143
144
145
|
/* 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/block_processor.h"
#include "sqfs/compress.h"
#include "sqfs/inode.h"
#include "sqfs/table.h"
#include "sqfs/error.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_SIG(chksum, size) \
(((uint64_t)(size) << 32) | (uint64_t)(chksum))
#define INIT_BLOCK_COUNT (128)
typedef struct {
uint64_t offset;
uint64_t signature;
} blk_info_t;
typedef struct {
uint32_t index;
uint32_t offset;
uint64_t signature;
} frag_info_t;
#ifdef WITH_PTHREAD
typedef struct {
sqfs_block_processor_t *shared;
sqfs_compressor_t *cmp;
pthread_t thread;
uint8_t scratch[];
} compress_worker_t;
#endif
struct sqfs_block_processor_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;
/* 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_block_processor_t *proc,
sqfs_block_t *block);
SQFS_INTERNAL
int handle_fragment(sqfs_block_processor_t *proc, sqfs_block_t *frag,
sqfs_block_t **blk_out);
SQFS_INTERNAL size_t deduplicate_blocks(sqfs_block_processor_t *proc,
size_t count);
SQFS_INTERNAL int store_block_location(sqfs_block_processor_t *proc,
uint64_t offset, uint32_t size,
uint32_t chksum);
SQFS_INTERNAL void free_blk_list(sqfs_block_t *list);
SQFS_INTERNAL
int block_processor_init(sqfs_block_processor_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 block_processor_cleanup(sqfs_block_processor_t *proc);
SQFS_INTERNAL
void block_processor_store_done(sqfs_block_processor_t *proc,
sqfs_block_t *blk, int status);
SQFS_INTERNAL
sqfs_block_t *block_processor_next_work_item(sqfs_block_processor_t *proc);
SQFS_INTERNAL
int block_processor_do_block(sqfs_block_t *block, sqfs_compressor_t *cmp,
uint8_t *scratch, size_t scratch_size);
#endif /* INTERNAL_H */
|