← Documents Documentation/block/data-integrity.rst GitHub 원문 ↗

Linux 6.18.37 · Block

Data Integrity

SCSI/SATA integrity metadata와 Linux block layer의 end-to-end data protection API를 설명합니다.

Source pathDocumentation/block/data-integrity.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약과 해설

data-integrity.rst:1-248

Linux data integrity framework는 sector checksum·순서·위치 정보를 I/O와 함께 전달해 application에서 storage device까지 corruption을 검출하고 failure 지점을 격리합니다.

block layer는 일반 filesystem을 위해 IMD를 자동 생성·검증할 수 있고, integrity-aware filesystem에는 `bio_integrity_prep()`, `bio_integrity_alloc()`, `bio_integrity_add_page()` API를 제공합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 ==============
2 Data Integrity
3 ==============
4
5 1. Introduction
6 ===============
7
8 Modern filesystems feature checksumming of data and metadata to
9 protect against data corruption. However, the detection of the
10 corruption is done at read time which could potentially be months
11 after the data was written. At that point the original data that the
12 application tried to write is most likely lost.
13
14 The solution is to ensure that the disk is actually storing what the
15 application meant it to. Recent additions to both the SCSI family
16 protocols (SBC Data Integrity Field, SCC protection proposal) as well
17 as SATA/T13 (External Path Protection) try to remedy this by adding
18 support for appending integrity metadata to an I/O. The integrity
19 metadata (or protection information in SCSI terminology) includes a
20 checksum for each sector as well as an incrementing counter that
21 ensures the individual sectors are written in the right order. And
22 for some protection schemes also that the I/O is written to the right
23 place on disk.
24
25 Current storage controllers and devices implement various protective
26 measures, for instance checksumming and scrubbing. But these
27 technologies are working in their own isolated domains or at best
28 between adjacent nodes in the I/O path. The interesting thing about
29 DIF and the other integrity extensions is that the protection format
30 is well defined and every node in the I/O path can verify the
31 integrity of the I/O and reject it if corruption is detected. This
32 allows not only corruption prevention but also isolation of the point
33 of failure.
34
35 2. The Data Integrity Extensions
36 ================================
37
38 As written, the protocol extensions only protect the path between
39 controller and storage device. However, many controllers actually
40 allow the operating system to interact with the integrity metadata
41 (IMD). We have been working with several FC/SAS HBA vendors to enable
42 the protection information to be transferred to and from their
43 controllers.
44
45 The SCSI Data Integrity Field works by appending 8 bytes of protection
46 information to each sector. The data + integrity metadata is stored
47 in 520 byte sectors on disk. Data + IMD are interleaved when
48 transferred between the controller and target. The T13 proposal is
49 similar.
50
51 Because it is highly inconvenient for operating systems to deal with
52 520 (and 4104) byte sectors, we approached several HBA vendors and
53 encouraged them to allow separation of the data and integrity metadata
54 scatter-gather lists.
55
56 The controller will interleave the buffers on write and split them on
57 read. This means that Linux can DMA the data buffers to and from
58 host memory without changes to the page cache.
59
60 Also, the 16-bit CRC checksum mandated by both the SCSI and SATA specs
61 is somewhat heavy to compute in software. Benchmarks found that
62 calculating this checksum had a significant impact on system
63 performance for a number of workloads. Some controllers allow a
64 lighter-weight checksum to be used when interfacing with the operating
65 system. Emulex, for instance, supports the TCP/IP checksum instead.
66 The IP checksum received from the OS is converted to the 16-bit CRC
67 when writing and vice versa. This allows the integrity metadata to be
68 generated by Linux or the application at very low cost (comparable to
69 software RAID5).
70
71 The IP checksum is weaker than the CRC in terms of detecting bit
72 errors. However, the strength is really in the separation of the data
73 buffers and the integrity metadata. These two distinct buffers must
74 match up for an I/O to complete.
75
76 The separation of the data and integrity metadata buffers as well as
77 the choice in checksums is referred to as the Data Integrity
78 Extensions. As these extensions are outside the scope of the protocol
79 bodies (T10, T13), Oracle and its partners are trying to standardize
80 them within the Storage Networking Industry Association.
81
82 3. Kernel Changes
83 =================
84
85 The data integrity framework in Linux enables protection information
86 to be pinned to I/Os and sent to/received from controllers that
87 support it.
88
89 The advantage to the integrity extensions in SCSI and SATA is that
90 they enable us to protect the entire path from application to storage
91 device. However, at the same time this is also the biggest
92 disadvantage. It means that the protection information must be in a
93 format that can be understood by the disk.
94
95 Generally Linux/POSIX applications are agnostic to the intricacies of
96 the storage devices they are accessing. The virtual filesystem switch
97 and the block layer make things like hardware sector size and
98 transport protocols completely transparent to the application.
99
100 However, this level of detail is required when preparing the
101 protection information to send to a disk. Consequently, the very
102 concept of an end-to-end protection scheme is a layering violation.
103 It is completely unreasonable for an application to be aware whether
104 it is accessing a SCSI or SATA disk.
105
106 The data integrity support implemented in Linux attempts to hide this
107 from the application. As far as the application (and to some extent
108 the kernel) is concerned, the integrity metadata is opaque information
109 that's attached to the I/O.
110
111 The current implementation allows the block layer to automatically
112 generate the protection information for any I/O. Eventually the
113 intent is to move the integrity metadata calculation to userspace for
114 user data. Metadata and other I/O that originates within the kernel
115 will still use the automatic generation interface.
116
117 Some storage devices allow each hardware sector to be tagged with a
118 16-bit value. The owner of this tag space is the owner of the block
119 device. I.e. the filesystem in most cases. The filesystem can use
120 this extra space to tag sectors as they see fit. Because the tag
121 space is limited, the block interface allows tagging bigger chunks by
122 way of interleaving. This way, 8*16 bits of information can be
123 attached to a typical 4KB filesystem block.
124
125 This also means that applications such as fsck and mkfs will need
126 access to manipulate the tags from user space. A passthrough
127 interface for this is being worked on.
128
129
130 4. Block Layer Implementation Details
131 =====================================
132
133 4.1 Bio
134 -------
135
136 The data integrity patches add a new field to struct bio when
137 CONFIG_BLK_DEV_INTEGRITY is enabled. bio_integrity(bio) returns a
138 pointer to a struct bip which contains the bio integrity payload.
139 Essentially a bip is a trimmed down struct bio which holds a bio_vec
140 containing the integrity metadata and the required housekeeping
141 information (bvec pool, vector count, etc.)
142
143 A kernel subsystem can enable data integrity protection on a bio by
144 calling bio_integrity_alloc(bio). This will allocate and attach the
145 bip to the bio.
146
147 Individual pages containing integrity metadata can subsequently be
148 attached using bio_integrity_add_page().
149
150 bio_free() will automatically free the bip.
151
152
153 4.2 Block Device
154 ----------------
155
156 Block devices can set up the integrity information in the integrity
157 sub-struture of the queue_limits structure.
158
159 Layered block devices will need to pick a profile that's appropriate
160 for all subdevices. queue_limits_stack_integrity() can help with that. DM
161 and MD linear, RAID0 and RAID1 are currently supported. RAID4/5/6
162 will require extra work due to the application tag.
163
164
165 5.0 Block Layer Integrity API
166 =============================
167
168 5.1 Normal Filesystem
169 ---------------------
170
171 The normal filesystem is unaware that the underlying block device
172 is capable of sending/receiving integrity metadata. The IMD will
173 be automatically generated by the block layer at submit_bio() time
174 in case of a WRITE. A READ request will cause the I/O integrity
175 to be verified upon completion.
176
177 IMD generation and verification can be toggled using the::
178
179 /sys/block/<bdev>/integrity/write_generate
180
181 and::
182
183 /sys/block/<bdev>/integrity/read_verify
184
185 flags.
186
187
188 5.2 Integrity-Aware Filesystem
189 ------------------------------
190
191 A filesystem that is integrity-aware can prepare I/Os with IMD
192 attached. It can also use the application tag space if this is
193 supported by the block device.
194
195
196 `bool bio_integrity_prep(bio);`
197
198 To generate IMD for WRITE and to set up buffers for READ, the
199 filesystem must call bio_integrity_prep(bio).
200
201 Prior to calling this function, the bio data direction and start
202 sector must be set, and the bio should have all data pages
203 added. It is up to the caller to ensure that the bio does not
204 change while I/O is in progress.
205 Complete bio with error if prepare failed for some reason.
206
207
208 5.3 Passing Existing Integrity Metadata
209 ---------------------------------------
210
211 Filesystems that either generate their own integrity metadata or
212 are capable of transferring IMD from user space can use the
213 following calls:
214
215
216 `struct bip * bio_integrity_alloc(bio, gfp_mask, nr_pages);`
217
218 Allocates the bio integrity payload and hangs it off of the bio.
219 nr_pages indicate how many pages of protection data need to be
220 stored in the integrity bio_vec list (similar to bio_alloc()).
221
222 The integrity payload will be freed at bio_free() time.
223
224
225 `int bio_integrity_add_page(bio, page, len, offset);`
226
227 Attaches a page containing integrity metadata to an existing
228 bio. The bio must have an existing bip,
229 i.e. bio_integrity_alloc() must have been called. For a WRITE,
230 the integrity metadata in the pages must be in a format
231 understood by the target device with the notable exception that
232 the sector numbers will be remapped as the request traverses the
233 I/O stack. This implies that the pages added using this call
234 will be modified during I/O! The first reference tag in the
235 integrity metadata must have a value of bip->bip_sector.
236
237 Pages can be added using bio_integrity_add_page() as long as
238 there is room in the bip bio_vec array (nr_pages).
239
240 Upon completion of a READ operation, the attached pages will
241 contain the integrity metadata received from the storage device.
242 It is up to the receiver to process them and verify data
243 integrity upon completion.
244
245
246 ----------------------------------------------------------------------
247
248 2007-12-24 Martin K. Petersen <[email protected]>
249

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

data integrity가 필요한 이유

1-34

modern filesystem은 data와 metadata에 checksum을 적용해 data corruption을 막습니다. 그러나 corruption은 read 시점에 검출되며, data를 쓴 뒤 수개월이 지난 시점일 수도 있습니다. 그때는 application이 원래 쓰려던 data가 이미 사라졌을 가능성이 큽니다.

해법은 disk가 application의 의도와 같은 내용을 실제로 저장하는지 보장하는 것입니다. SCSI 계열 protocol의 `SBC Data Integrity Field`, `SCC protection proposal`과 SATA/T13의 `External Path Protection`은 I/O에 integrity metadata를 덧붙이는 방식으로 이를 해결합니다.

SCSI 용어로 protection information이라고도 하는 integrity metadata에는 sector마다 checksum과 증가하는 counter가 들어 있습니다. counter는 각 sector가 올바른 순서로 기록되었음을 보장하며, 일부 protection scheme에서는 I/O가 disk의 올바른 위치에 기록되었는지도 확인합니다.

현재 storage controller와 device도 checksumming, scrubbing 같은 여러 보호 수단을 구현합니다. 그러나 이 기술은 각자의 격리된 domain에서만, 잘해도 I/O path의 인접 node 사이에서만 동작합니다.

`DIF`와 다른 integrity extension의 중요한 점은 protection format이 명확히 정의되어 I/O path의 모든 node가 I/O integrity를 검증하고 corruption을 발견하면 거부할 수 있다는 것입니다. 따라서 corruption을 예방할 뿐 아니라 failure가 발생한 지점을 격리할 수 있습니다.

Data Integrity Extensions

35-81

protocol extension 자체는 controller와 storage device 사이의 path만 보호합니다. 하지만 많은 controller가 operating system이 integrity metadata, 즉 `IMD`와 상호 작용하도록 지원합니다. 여러 FC/SAS HBA vendor와 협력해 protection information을 controller로 주고받을 수 있게 했습니다.

`SCSI Data Integrity Field`는 sector마다 protection information 8 byte를 덧붙입니다. data와 integrity metadata는 disk의 520 byte sector에 저장되고, controller와 target 사이를 전송할 때 data와 IMD를 interleave합니다. T13 proposal도 비슷합니다.

operating system에서 520 byte, 그리고 4104 byte sector를 다루기는 매우 불편합니다. 이에 여러 HBA vendor가 data scatter-gather list와 integrity metadata scatter-gather list를 분리하도록 권장했습니다.

controller는 write할 때 두 buffer를 interleave하고 read할 때 분리합니다. 덕분에 Linux는 page cache를 바꾸지 않고 data buffer를 host memory와 주고받도록 DMA할 수 있습니다.

SCSI와 SATA specification이 요구하는 16-bit CRC checksum은 software로 계산하기에 다소 무겁습니다. benchmark에서는 여러 workload에서 이 checksum 계산이 system performance에 상당한 영향을 미쳤습니다.

일부 controller는 operating system과 통신할 때 더 가벼운 checksum을 허용합니다. 예를 들어 Emulex는 대신 TCP/IP checksum을 지원합니다. OS에서 받은 IP checksum을 write할 때 16-bit CRC로 변환하고 read할 때는 반대로 변환합니다. 따라서 Linux나 application이 software RAID5와 비슷한 매우 낮은 비용으로 integrity metadata를 생성할 수 있습니다.

bit error 검출 능력은 IP checksum이 CRC보다 약합니다. 그러나 실제 강점은 data buffer와 integrity metadata를 분리하는 데 있습니다. I/O가 완료되려면 서로 분리된 두 buffer가 반드시 서로 일치해야 합니다.

data buffer와 integrity metadata buffer의 분리, 그리고 checksum 선택 기능을 합쳐 `Data Integrity Extensions`라고 합니다. 이 extension은 protocol 단체인 T10과 T13의 범위 밖에 있으므로 Oracle과 partner들은 Storage Networking Industry Association에서 표준화를 추진하고 있습니다.

Linux kernel의 추상화

82-129

Linux data integrity framework는 protection information을 I/O에 고정해 이를 지원하는 controller로 보내거나 controller에서 받게 합니다.

SCSI와 SATA integrity extension은 application부터 storage device까지 전체 path를 보호한다는 장점이 있습니다. 동시에 이것이 가장 큰 단점이기도 합니다. protection information이 disk가 이해할 수 있는 format이어야 하기 때문입니다.

일반적으로 Linux/POSIX application은 접근하는 storage device의 세부 사항을 알지 못합니다. virtual filesystem switch와 block layer는 hardware sector size와 transport protocol 같은 요소를 application에 완전히 투명하게 만듭니다.

그러나 disk에 보낼 protection information을 준비할 때는 이런 세부 정보가 필요합니다. 따라서 end-to-end protection scheme이라는 개념 자체가 layering violation입니다. application이 SCSI disk에 접근하는지 SATA disk에 접근하는지 알아야 한다는 것은 합리적이지 않습니다.

Linux의 data integrity 지원은 이런 내용을 application에서 숨깁니다. application과 어느 정도 kernel의 관점에서 integrity metadata는 I/O에 붙은 opaque information입니다.

현재 구현에서는 block layer가 모든 I/O의 protection information을 자동으로 생성할 수 있습니다. 최종 목표는 user data의 integrity metadata 계산을 userspace로 옮기는 것입니다. metadata와 kernel 내부에서 시작된 다른 I/O는 계속 automatic generation interface를 사용합니다.

일부 storage device는 각 hardware sector에 16-bit value tag를 붙일 수 있습니다. 이 tag space의 소유자는 block device 소유자이며 대부분 filesystem입니다. filesystem은 이 추가 공간을 원하는 방식으로 sector tagging에 사용할 수 있습니다.

tag space가 제한되어 있으므로 block interface는 interleaving으로 더 큰 chunk를 tagging하게 합니다. 이 방식이면 일반적인 4KB filesystem block에 `8*16 bits`의 정보를 붙일 수 있습니다.

이는 `fsck`, `mkfs` 같은 application도 userspace에서 tag를 조작할 수 있어야 한다는 뜻입니다. 이를 위한 passthrough interface를 개발 중입니다.

Bio integrity payload

130-152

`CONFIG_BLK_DEV_INTEGRITY`가 enabled이면 data integrity patch가 `struct bio`에 새 field를 추가합니다. `bio_integrity(bio)`는 bio integrity payload를 포함하는 `struct bip` pointer를 반환합니다.

`bip`는 간소화된 `struct bio`와 본질적으로 같습니다. integrity metadata를 담은 `bio_vec`와 bvec pool, vector count 같은 필수 관리 정보를 보관합니다.

kernel subsystem은 `bio_integrity_alloc(bio)`를 호출해 `bio`의 data integrity protection을 활성화할 수 있습니다. 이 함수는 `bip`를 할당해 `bio`에 연결합니다.

그 뒤 `bio_integrity_add_page()`로 integrity metadata가 든 개별 page를 연결할 수 있습니다. `bio_free()`는 `bip`를 자동으로 free합니다.

Block device profile

153-164

block device는 `queue_limits` 구조체의 integrity sub-structure에 integrity information을 설정할 수 있습니다.

layered block device는 모든 subdevice에 적합한 profile을 선택해야 하며 `queue_limits_stack_integrity()`가 이를 도울 수 있습니다. 현재 DM과 MD linear, RAID0, RAID1을 지원합니다. RAID4/5/6은 application tag 때문에 추가 작업이 필요합니다.

일반 filesystem API

165-187

일반 filesystem은 underlying block device가 integrity metadata를 송수신할 수 있다는 사실을 알지 못합니다. WRITE라면 `submit_bio()` 시점에 block layer가 IMD를 자동 생성하고, READ request라면 완료 시 I/O integrity를 검증합니다.

IMD 생성을 다음 flag로 켜거나 끌 수 있습니다.

/sys/block/<bdev>/integrity/write_generate

IMD 검증은 다음 flag로 켜거나 끌 수 있습니다.

/sys/block/<bdev>/integrity/read_verify

integrity-aware filesystem API

188-207

integrity-aware filesystem은 IMD가 연결된 I/O를 준비할 수 있으며 block device가 지원하면 application tag space도 사용할 수 있습니다.

`bool bio_integrity_prep(bio);`

WRITE용 IMD를 생성하고 READ용 buffer를 설정하려면 filesystem이 `bio_integrity_prep(bio)`를 호출해야 합니다. 호출하기 전에 bio data direction과 start sector를 설정하고 모든 data page를 `bio`에 추가해야 합니다.

I/O가 진행되는 동안 `bio`가 변하지 않도록 보장하는 책임은 caller에게 있습니다. 어떤 이유로 prepare가 실패하면 해당 `bio`를 error로 완료합니다.

기존 IMD 전달: payload 할당

208-224

자체 integrity metadata를 생성하거나 userspace에서 IMD를 전달할 수 있는 filesystem은 다음 호출을 사용할 수 있습니다.

`struct bip * bio_integrity_alloc(bio, gfp_mask, nr_pages);`

`bio_integrity_alloc(bio, gfp_mask, nr_pages)`는 bio integrity payload를 할당해 `bio`에 연결합니다. `nr_pages`는 protection data를 integrity `bio_vec` list에 저장하는 데 필요한 page 수이며 `bio_alloc()`의 동작과 비슷합니다.

integrity payload는 `bio_free()` 시점에 free됩니다.

기존 IMD 전달: page 연결

225-248
`int bio_integrity_add_page(bio, page, len, offset);`

`bio_integrity_add_page(bio, page, len, offset)`는 integrity metadata가 든 page를 기존 `bio`에 연결합니다. `bio`에는 기존 `bip`가 있어야 하므로 먼저 `bio_integrity_alloc()`을 호출해야 합니다.

WRITE의 경우 page 안 integrity metadata는 target device가 이해하는 format이어야 합니다. 단, request가 I/O stack을 통과하는 동안 sector number는 remap됩니다. 따라서 이 호출로 추가한 page는 I/O 중에 수정됩니다. integrity metadata의 첫 reference tag 값은 반드시 `bip->bip_sector`여야 합니다.

`bip`의 `bio_vec` array에 `nr_pages` 범위의 공간이 남아 있는 동안 `bio_integrity_add_page()`로 page를 추가할 수 있습니다.

READ operation이 완료되면 연결된 page에는 storage device에서 받은 integrity metadata가 들어 있습니다. 완료 시 이를 처리하고 data integrity를 검증하는 책임은 receiver에게 있습니다.

원문 기록: `2007-12-24 Martin K. Petersen <[email protected]>`.