File: chunk.h

package info (click to toggle)
lizardfs 3.12.0+dfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: buster, sid
  • size: 8,064 kB
  • sloc: cpp: 91,899; sh: 9,341; python: 3,878; ansic: 3,109; pascal: 128; makefile: 57
file content (193 lines) | stat: -rw-r--r-- 5,867 bytes parent folder | download | duplicates (2)
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/*
   Copyright 2013-2015 Skytechnology sp. z o.o.

   This file is part of LizardFS.

   LizardFS is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, version 3.

   LizardFS is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with LizardFS. If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include "common/platform.h"

#include <cstdint>
#include <cstdlib>
#include <string>
#include <sys/types.h>

#include <condition_variable>
#include <thread>

#include "chunkserver/chunk_format.h"
#include "common/chunk_part_type.h"
#include "common/disk_info.h"
#include "protocol/MFSCommunication.h"

#define STATSHISTORY (24*60)
#define LASTERRSIZE 30

// Block data and crc summaric size.
constexpr uint32_t kHddBlockSize = MFSBLOCKSIZE + 4;

enum ChunkState {
	CH_AVAIL,
	CH_LOCKED,
	CH_DELETED,
	CH_TOBEDELETED
};

class Chunk;

struct cntcond {
	std::condition_variable cond;
	uint32_t wcnt;
	Chunk *owner;
	struct cntcond *next;
};

struct ioerror {
	uint64_t chunkid;
	uint32_t timestamp;
	int errornumber;
};

struct folder {
	char *path;
#define SCST_SCANNEEDED 0u
#define SCST_SCANINPROGRESS 1u
#define SCST_SCANTERMINATE 2u
#define SCST_SCANFINISHED 3u
#define SCST_SENDNEEDED 4u
#define SCST_WORKING 5u
	unsigned int scanstate:3;
	unsigned int needrefresh:1;
	unsigned int todel:2;
	unsigned int damaged:1;
	unsigned int toremove:2;
	uint8_t scanprogress;
#define MGST_MIGRATEDONE 0u
#define MGST_MIGRATEINPROGRESS 1u
#define MGST_MIGRATETERMINATE 2u
#define MGST_MIGRATEFINISHED 3u
	uint8_t migratestate;
	uint64_t leavefree;
	uint64_t avail;
	uint64_t total;
	HddAtomicStatistics cstat;
	HddStatistics stats[STATSHISTORY];
	uint32_t statspos;
	ioerror lasterrtab[LASTERRSIZE];
	uint32_t chunkcount;
	uint32_t lasterrindx;
	uint32_t lastrefresh;
	dev_t devid;
	ino_t lockinode;
	int lfd;
	double carry;
	std::thread scanthread;
	std::thread migratethread;
	Chunk *testhead,**testtail;
	struct folder *next;
};

class Chunk {
public:
	static const uint32_t kNumberOfSubfolders = 256;
	enum { kCurrentDirectoryLayout = 0, kMooseFSDirectoryLayout };

	Chunk(uint64_t chunkId, ChunkPartType type, ChunkState state);
	virtual ~Chunk() {};

	std::string filename() const {
		return filename_layout_ >= kCurrentDirectoryLayout
		               ? generateFilenameForVersion(version, filename_layout_)
		               : std::string();
	};

	std::string generateFilenameForVersion(uint32_t version, int layout_version = kCurrentDirectoryLayout) const;
	int renameChunkFile(uint32_t new_version, int new_layout_version = kCurrentDirectoryLayout);
	void setFilenameLayout(int layout_version) { filename_layout_ = layout_version; }

	virtual off_t getBlockOffset(uint16_t blockNumber) const = 0;
	virtual off_t getFileSizeFromBlockCount(uint32_t blockCount) const = 0;
	virtual bool isFileSizeValid(off_t fileSize) const = 0;
	virtual ChunkFormat chunkFormat() const { return ChunkFormat::IMPROPER; };
	uint32_t maxBlocksInFile() const;
	virtual void setBlockCountFromFizeSize(off_t fileSize) = 0;
	ChunkPartType type() const { return type_; }
	static uint32_t getSubfolderNumber(uint64_t chunkId, int layout_version = 0);
	static std::string getSubfolderNameGivenNumber(uint32_t subfolderNumber, int layout_version = 0);
	static std::string getSubfolderNameGivenChunkId(uint64_t chunkId, int layout_version = 0);

	Chunk *testnext, **testprev;
	Chunk *next;
	cntcond *ccond;
	struct folder *owner;
	uint64_t chunkid;
	uint32_t version;
	int32_t  fd;
	uint16_t blocks;
	uint16_t refcount;
	uint16_t blockExpectedToBeReadNext;

protected:
	ChunkPartType type_;
	int8_t filename_layout_; /*!< <0 - no valid name (empty string)
	                               0 - current directory layout
	                              >0 - older directory layouts */
public:
	uint8_t validattr;
	uint8_t todel;
	uint8_t state;
	uint8_t wasChanged;
};

class MooseFSChunk : public Chunk {
public:
	static const size_t kMaxSignatureBlockSize = 1024;
	static const size_t kMaxCrcBlockSize = MFSBLOCKSINCHUNK * sizeof(uint32_t);
	static const size_t kMaxPaddingBlockSize = 4096;
	static const size_t kMaxHeaderSize =
			kMaxSignatureBlockSize + kMaxCrcBlockSize + kMaxPaddingBlockSize;
	static const size_t kDiskBlockSize = 4096; // 4kB

	typedef std::array<uint8_t, kMaxCrcBlockSize> CrcDataContainer;

	MooseFSChunk(uint64_t chunkId, ChunkPartType type, ChunkState state);
	off_t getBlockOffset(uint16_t blockNumber) const override;
	off_t getFileSizeFromBlockCount(uint32_t blockCount) const override;
	bool isFileSizeValid(off_t fileSize) const override;
	void setBlockCountFromFizeSize(off_t fileSize) override;
	ChunkFormat chunkFormat() const override { return ChunkFormat::MOOSEFS; };
	off_t getSignatureOffset() const;
	void readaheadHeader() const;
	size_t getHeaderSize() const;
	off_t getCrcOffset() const;
	size_t getCrcBlockSize() const;
};

class InterleavedChunk : public Chunk {
public:
	InterleavedChunk(uint64_t chunkId, ChunkPartType type, ChunkState state);
	off_t getBlockOffset(uint16_t blockNumber) const override;
	off_t getFileSizeFromBlockCount(uint32_t blockCount) const override;
	bool isFileSizeValid(off_t fileSize) const override;
	void setBlockCountFromFizeSize(off_t fileSize) override;
	ChunkFormat chunkFormat() const override { return ChunkFormat::INTERLEAVED; };
};

#define IF_MOOSEFS_CHUNK(mc, chunk) \
	if (MooseFSChunk *mc = dynamic_cast<MooseFSChunk *>(chunk))

#define IF_INTERLEAVED_CHUNK(lc, chunk) \
	if (InterleavedChunk *lc = dynamic_cast<InterleavedChunk *>(chunk))