← Documents Documentation/filesystems/zonefs.rst GitHub 원문 ↗

Linux 6.18.37 · Filesystems

ZoneFS - Zone filesystem for Zoned block devices

Zone file I/O, 오류 복구, explicit-open과 sysfs 제한을 다룬 전문 번역입니다.

Source pathDocumentation/filesystems/zonefs.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

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

1. 요약·해설

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

요약·해설

zonefs.rst:1-485

zonefs는 zoned block device의 zone 하나를 file 하나로 노출하여 application이 raw sector와 ioctl 대신 file API를 사용하게 한다. `cnv` file은 random I/O가 가능하고 `seq` file은 direct append만 허용하며 write pointer가 file size가 된다.

오류 복구에서는 device zone report와 inode size를 다시 맞추고 READONLY·OFFLINE 상태를 permission에 반영한다. `errors=` behavior가 추가 제한을 정하지만 device 상태 전이로 생긴 제한은 remount나 reformat으로 되돌릴 수 없다.

`explicit-open`은 write-open file 수와 device open-zone resource를 연결한다. `/sys/fs/zonefs/<dev>/`의 open-for-write counter와 active counter를 함께 사용하면 application이 device concurrency limit 안에서 동작할 수 있다.

Zonefs 운영 핵심
`mkzonefs`로 immutable metadata와 format option 기록Mount 시 device zone report로 정적 tree 생성`cnv` random I/O 또는 `seq` direct appendWrite pointer와 inode size 동기화I/O 오류 시 zone condition·persisted data 재확인`errors=` policy와 permission 변화 적용

Format부터 sequential I/O와 오류 복구까지 이어지는 전체 흐름이다.

2. 영어 원문 전체

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

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0
2
3 ================================================
4 ZoneFS - Zone filesystem for Zoned block devices
5 ================================================
6
7 Introduction
8 ============
9
10 zonefs is a very simple file system exposing each zone of a zoned block device
11 as a file. Unlike a regular POSIX-compliant file system with native zoned block
12 device support (e.g. f2fs), zonefs does not hide the sequential write
13 constraint of zoned block devices to the user. Files representing sequential
14 write zones of the device must be written sequentially starting from the end
15 of the file (append only writes).
16
17 As such, zonefs is in essence closer to a raw block device access interface
18 than to a full-featured POSIX file system. The goal of zonefs is to simplify
19 the implementation of zoned block device support in applications by replacing
20 raw block device file accesses with a richer file API, avoiding relying on
21 direct block device file ioctls which may be more obscure to developers. One
22 example of this approach is the implementation of LSM (log-structured merge)
23 tree structures (such as used in RocksDB and LevelDB) on zoned block devices
24 by allowing SSTables to be stored in a zone file similarly to a regular file
25 system rather than as a range of sectors of the entire disk. The introduction
26 of the higher level construct "one file is one zone" can help reducing the
27 amount of changes needed in the application as well as introducing support for
28 different application programming languages.
29
30 Zoned block devices
31 -------------------
32
33 Zoned storage devices belong to a class of storage devices with an address
34 space that is divided into zones. A zone is a group of consecutive LBAs and all
35 zones are contiguous (there are no LBA gaps). Zones may have different types.
36
37 * Conventional zones: there are no access constraints to LBAs belonging to
38 conventional zones. Any read or write access can be executed, similarly to a
39 regular block device.
40 * Sequential zones: these zones accept random reads but must be written
41 sequentially. Each sequential zone has a write pointer maintained by the
42 device that keeps track of the mandatory start LBA position of the next write
43 to the device. As a result of this write constraint, LBAs in a sequential zone
44 cannot be overwritten. Sequential zones must first be erased using a special
45 command (zone reset) before rewriting.
46
47 Zoned storage devices can be implemented using various recording and media
48 technologies. The most common form of zoned storage today uses the SCSI Zoned
49 Block Commands (ZBC) and Zoned ATA Commands (ZAC) interfaces on Shingled
50 Magnetic Recording (SMR) HDDs.
51
52 Solid State Disks (SSD) storage devices can also implement a zoned interface
53 to, for instance, reduce internal write amplification due to garbage collection.
54 The NVMe Zoned NameSpace (ZNS) is a technical proposal of the NVMe standard
55 committee aiming at adding a zoned storage interface to the NVMe protocol.
56
57 Zonefs Overview
58 ===============
59
60 Zonefs exposes the zones of a zoned block device as files. The files
61 representing zones are grouped by zone type, which are themselves represented
62 by sub-directories. This file structure is built entirely using zone information
63 provided by the device and so does not require any complex on-disk metadata
64 structure.
65
66 On-disk metadata
67 ----------------
68
69 zonefs on-disk metadata is reduced to an immutable super block which
70 persistently stores a magic number and optional feature flags and values. On
71 mount, zonefs uses blkdev_report_zones() to obtain the device zone configuration
72 and populates the mount point with a static file tree solely based on this
73 information. File sizes come from the device zone type and write pointer
74 position managed by the device itself.
75
76 The super block is always written on disk at sector 0. The first zone of the
77 device storing the super block is never exposed as a zone file by zonefs. If
78 the zone containing the super block is a sequential zone, the mkzonefs format
79 tool always "finishes" the zone, that is, it transitions the zone to a full
80 state to make it read-only, preventing any data write.
81
82 Zone type sub-directories
83 -------------------------
84
85 Files representing zones of the same type are grouped together under the same
86 sub-directory automatically created on mount.
87
88 For conventional zones, the sub-directory "cnv" is used. This directory is
89 however created if and only if the device has usable conventional zones. If
90 the device only has a single conventional zone at sector 0, the zone will not
91 be exposed as a file as it will be used to store the zonefs super block. For
92 such devices, the "cnv" sub-directory will not be created.
93
94 For sequential write zones, the sub-directory "seq" is used.
95
96 These two directories are the only directories that exist in zonefs. Users
97 cannot create other directories and cannot rename nor delete the "cnv" and
98 "seq" sub-directories.
99
100 The size of the directories indicated by the st_size field of struct stat,
101 obtained with the stat() or fstat() system calls, indicates the number of files
102 existing under the directory.
103
104 Zone files
105 ----------
106
107 Zone files are named using the number of the zone they represent within the set
108 of zones of a particular type. That is, both the "cnv" and "seq" directories
109 contain files named "0", "1", "2", ... The file numbers also represent
110 increasing zone start sector on the device.
111
112 All read and write operations to zone files are not allowed beyond the file
113 maximum size, that is, beyond the zone capacity. Any access exceeding the zone
114 capacity is failed with the -EFBIG error.
115
116 Creating, deleting, renaming or modifying any attribute of files and
117 sub-directories is not allowed.
118
119 The number of blocks of a file as reported by stat() and fstat() indicates the
120 capacity of the zone file, or in other words, the maximum file size.
121
122 Conventional zone files
123 -----------------------
124
125 The size of conventional zone files is fixed to the size of the zone they
126 represent. Conventional zone files cannot be truncated.
127
128 These files can be randomly read and written using any type of I/O operation:
129 buffered I/Os, direct I/Os, memory mapped I/Os (mmap), etc. There are no I/O
130 constraint for these files beyond the file size limit mentioned above.
131
132 Sequential zone files
133 ---------------------
134
135 The size of sequential zone files grouped in the "seq" sub-directory represents
136 the file's zone write pointer position relative to the zone start sector.
137
138 Sequential zone files can only be written sequentially, starting from the file
139 end, that is, write operations can only be append writes. Zonefs makes no
140 attempt at accepting random writes and will fail any write request that has a
141 start offset not corresponding to the end of the file, or to the end of the last
142 write issued and still in-flight (for asynchronous I/O operations).
143
144 Since dirty page writeback by the page cache does not guarantee a sequential
145 write pattern, zonefs prevents buffered writes and writeable shared mappings
146 on sequential files. Only direct I/O writes are accepted for these files.
147 zonefs relies on the sequential delivery of write I/O requests to the device
148 implemented by the block layer elevator. An elevator implementing the sequential
149 write feature for zoned block device (ELEVATOR_F_ZBD_SEQ_WRITE elevator feature)
150 must be used. This type of elevator (e.g. mq-deadline) is set by default
151 for zoned block devices on device initialization.
152
153 There are no restrictions on the type of I/O used for read operations in
154 sequential zone files. Buffered I/Os, direct I/Os and shared read mappings are
155 all accepted.
156
157 Truncating sequential zone files is allowed only down to 0, in which case, the
158 zone is reset to rewind the file zone write pointer position to the start of
159 the zone, or up to the zone capacity, in which case the file's zone is
160 transitioned to the FULL state (finish zone operation).
161
162 Format options
163 --------------
164
165 Several optional features of zonefs can be enabled at format time.
166
167 * Conventional zone aggregation: ranges of contiguous conventional zones can be
168 aggregated into a single larger file instead of the default one file per zone.
169 * File ownership: The owner UID and GID of zone files is by default 0 (root)
170 but can be changed to any valid UID/GID.
171 * File access permissions: the default 640 access permissions can be changed.
172
173 IO error handling
174 -----------------
175
176 Zoned block devices may fail I/O requests for reasons similar to regular block
177 devices, e.g. due to bad sectors. However, in addition to such known I/O
178 failure pattern, the standards governing zoned block devices behavior define
179 additional conditions that result in I/O errors.
180
181 * A zone may transition to the read-only condition (BLK_ZONE_COND_READONLY):
182 While the data already written in the zone is still readable, the zone can
183 no longer be written. No user action on the zone (zone management command or
184 read/write access) can change the zone condition back to a normal read/write
185 state. While the reasons for the device to transition a zone to read-only
186 state are not defined by the standards, a typical cause for such transition
187 would be a defective write head on an HDD (all zones under this head are
188 changed to read-only).
189
190 * A zone may transition to the offline condition (BLK_ZONE_COND_OFFLINE):
191 An offline zone cannot be read nor written. No user action can transition an
192 offline zone back to an operational good state. Similarly to zone read-only
193 transitions, the reasons for a drive to transition a zone to the offline
194 condition are undefined. A typical cause would be a defective read-write head
195 on an HDD causing all zones on the platter under the broken head to be
196 inaccessible.
197
198 * Unaligned write errors: These errors result from the host issuing write
199 requests with a start sector that does not correspond to a zone write pointer
200 position when the write request is executed by the device. Even though zonefs
201 enforces sequential file write for sequential zones, unaligned write errors
202 may still happen in the case of a partial failure of a very large direct I/O
203 operation split into multiple BIOs/requests or asynchronous I/O operations.
204 If one of the write request within the set of sequential write requests
205 issued to the device fails, all write requests queued after it will
206 become unaligned and fail.
207
208 * Delayed write errors: similarly to regular block devices, if the device side
209 write cache is enabled, write errors may occur in ranges of previously
210 completed writes when the device write cache is flushed, e.g. on fsync().
211 Similarly to the previous immediate unaligned write error case, delayed write
212 errors can propagate through a stream of cached sequential data for a zone
213 causing all data to be dropped after the sector that caused the error.
214
215 All I/O errors detected by zonefs are notified to the user with an error code
216 return for the system call that triggered or detected the error. The recovery
217 actions taken by zonefs in response to I/O errors depend on the I/O type (read
218 vs write) and on the reason for the error (bad sector, unaligned writes or zone
219 condition change).
220
221 * For read I/O errors, zonefs does not execute any particular recovery action,
222 but only if the file zone is still in a good condition and there is no
223 inconsistency between the file inode size and its zone write pointer position.
224 If a problem is detected, I/O error recovery is executed (see below table).
225
226 * For write I/O errors, zonefs I/O error recovery is always executed.
227
228 * A zone condition change to read-only or offline also always triggers zonefs
229 I/O error recovery.
230
231 Zonefs minimal I/O error recovery may change a file size and file access
232 permissions.
233
234 * File size changes:
235 Immediate or delayed write errors in a sequential zone file may cause the file
236 inode size to be inconsistent with the amount of data successfully written in
237 the file zone. For instance, the partial failure of a multi-BIO large write
238 operation will cause the zone write pointer to advance partially, even though
239 the entire write operation will be reported as failed to the user. In such
240 case, the file inode size must be advanced to reflect the zone write pointer
241 change and eventually allow the user to restart writing at the end of the
242 file.
243 A file size may also be reduced to reflect a delayed write error detected on
244 fsync(): in this case, the amount of data effectively written in the zone may
245 be less than originally indicated by the file inode size. After such I/O
246 error, zonefs always fixes the file inode size to reflect the amount of data
247 persistently stored in the file zone.
248
249 * Access permission changes:
250 A zone condition change to read-only is indicated with a change in the file
251 access permissions to render the file read-only. This disables changes to the
252 file attributes and data modification. For offline zones, all permissions
253 (read and write) to the file are disabled.
254
255 Further action taken by zonefs I/O error recovery can be controlled by the user
256 with the "errors=xxx" mount option. The table below summarizes the result of
257 zonefs I/O error processing depending on the mount option and on the zone
258 conditions::
259
260 +--------------+-----------+-----------------------------------------+
261 | | | Post error state |
262 | "errors=xxx" | device | access permissions |
263 | mount | zone | file file device zone |
264 | option | condition | size read write read write |
265 +--------------+-----------+-----------------------------------------+
266 | | good | fixed yes no yes yes |
267 | remount-ro | read-only | as is yes no yes no |
268 | (default) | offline | 0 no no no no |
269 +--------------+-----------+-----------------------------------------+
270 | | good | fixed yes no yes yes |
271 | zone-ro | read-only | as is yes no yes no |
272 | | offline | 0 no no no no |
273 +--------------+-----------+-----------------------------------------+
274 | | good | 0 no no yes yes |
275 | zone-offline | read-only | 0 no no yes no |
276 | | offline | 0 no no no no |
277 +--------------+-----------+-----------------------------------------+
278 | | good | fixed yes yes yes yes |
279 | repair | read-only | as is yes no yes no |
280 | | offline | 0 no no no no |
281 +--------------+-----------+-----------------------------------------+
282
283 Further notes:
284
285 * The "errors=remount-ro" mount option is the default behavior of zonefs I/O
286 error processing if no errors mount option is specified.
287 * With the "errors=remount-ro" mount option, the change of the file access
288 permissions to read-only applies to all files. The file system is remounted
289 read-only.
290 * Access permission and file size changes due to the device transitioning zones
291 to the offline condition are permanent. Remounting or reformatting the device
292 with mkfs.zonefs (mkzonefs) will not change back offline zone files to a good
293 state.
294 * File access permission changes to read-only due to the device transitioning
295 zones to the read-only condition are permanent. Remounting or reformatting
296 the device will not re-enable file write access.
297 * File access permission changes implied by the remount-ro, zone-ro and
298 zone-offline mount options are temporary for zones in a good condition.
299 Unmounting and remounting the file system will restore the previous default
300 (format time values) access rights to the files affected.
301 * The repair mount option triggers only the minimal set of I/O error recovery
302 actions, that is, file size fixes for zones in a good condition. Zones
303 indicated as being read-only or offline by the device still imply changes to
304 the zone file access permissions as noted in the table above.
305
306 Mount options
307 -------------
308
309 zonefs defines several mount options:
310 * errors=<behavior>
311 * explicit-open
312
313 "errors=<behavior>" option
314 ~~~~~~~~~~~~~~~~~~~~~~~~~~
315
316 The "errors=<behavior>" option mount option allows the user to specify zonefs
317 behavior in response to I/O errors, inode size inconsistencies or zone
318 condition changes. The defined behaviors are as follow:
319
320 * remount-ro (default)
321 * zone-ro
322 * zone-offline
323 * repair
324
325 The run-time I/O error actions defined for each behavior are detailed in the
326 previous section. Mount time I/O errors will cause the mount operation to fail.
327 The handling of read-only zones also differs between mount-time and run-time.
328 If a read-only zone is found at mount time, the zone is always treated in the
329 same manner as offline zones, that is, all accesses are disabled and the zone
330 file size set to 0. This is necessary as the write pointer of read-only zones
331 is defined as invalib by the ZBC and ZAC standards, making it impossible to
332 discover the amount of data that has been written to the zone. In the case of a
333 read-only zone discovered at run-time, as indicated in the previous section.
334 The size of the zone file is left unchanged from its last updated value.
335
336 "explicit-open" option
337 ~~~~~~~~~~~~~~~~~~~~~~
338
339 A zoned block device (e.g. an NVMe Zoned Namespace device) may have limits on
340 the number of zones that can be active, that is, zones that are in the
341 implicit open, explicit open or closed conditions. This potential limitation
342 translates into a risk for applications to see write IO errors due to this
343 limit being exceeded if the zone of a file is not already active when a write
344 request is issued by the user.
345
346 To avoid these potential errors, the "explicit-open" mount option forces zones
347 to be made active using an open zone command when a file is opened for writing
348 for the first time. If the zone open command succeeds, the application is then
349 guaranteed that write requests can be processed. Conversely, the
350 "explicit-open" mount option will result in a zone close command being issued
351 to the device on the last close() of a zone file if the zone is not full nor
352 empty.
353
354 Runtime sysfs attributes
355 ------------------------
356
357 zonefs defines several sysfs attributes for mounted devices. All attributes
358 are user readable and can be found in the directory /sys/fs/zonefs/<dev>/,
359 where <dev> is the name of the mounted zoned block device.
360
361 The attributes defined are as follows.
362
363 * **max_wro_seq_files**: This attribute reports the maximum number of
364 sequential zone files that can be open for writing. This number corresponds
365 to the maximum number of explicitly or implicitly open zones that the device
366 supports. A value of 0 means that the device has no limit and that any zone
367 (any file) can be open for writing and written at any time, regardless of the
368 state of other zones. When the *explicit-open* mount option is used, zonefs
369 will fail any open() system call requesting to open a sequential zone file for
370 writing when the number of sequential zone files already open for writing has
371 reached the *max_wro_seq_files* limit.
372 * **nr_wro_seq_files**: This attribute reports the current number of sequential
373 zone files open for writing. When the "explicit-open" mount option is used,
374 this number can never exceed *max_wro_seq_files*. If the *explicit-open*
375 mount option is not used, the reported number can be greater than
376 *max_wro_seq_files*. In such case, it is the responsibility of the
377 application to not write simultaneously more than *max_wro_seq_files*
378 sequential zone files. Failure to do so can result in write errors.
379 * **max_active_seq_files**: This attribute reports the maximum number of
380 sequential zone files that are in an active state, that is, sequential zone
381 files that are partially written (not empty nor full) or that have a zone that
382 is explicitly open (which happens only if the *explicit-open* mount option is
383 used). This number is always equal to the maximum number of active zones that
384 the device supports. A value of 0 means that the mounted device has no limit
385 on the number of sequential zone files that can be active.
386 * **nr_active_seq_files**: This attributes reports the current number of
387 sequential zone files that are active. If *max_active_seq_files* is not 0,
388 then the value of *nr_active_seq_files* can never exceed the value of
389 *nr_active_seq_files*, regardless of the use of the *explicit-open* mount
390 option.
391
392 Zonefs User Space Tools
393 =======================
394
395 The mkzonefs tool is used to format zoned block devices for use with zonefs.
396 This tool is available on Github at:
397
398 https://github.com/damien-lemoal/zonefs-tools
399
400 zonefs-tools also includes a test suite which can be run against any zoned
401 block device, including null_blk block device created with zoned mode.
402
403 Examples
404 --------
405
406 The following formats a 15TB host-managed SMR HDD with 256 MB zones
407 with the conventional zones aggregation feature enabled::
408
409 # mkzonefs -o aggr_cnv /dev/sdX
410 # mount -t zonefs /dev/sdX /mnt
411 # ls -l /mnt/
412 total 0
413 dr-xr-xr-x 2 root root 1 Nov 25 13:23 cnv
414 dr-xr-xr-x 2 root root 55356 Nov 25 13:23 seq
415
416 The size of the zone files sub-directories indicate the number of files
417 existing for each type of zones. In this example, there is only one
418 conventional zone file (all conventional zones are aggregated under a single
419 file)::
420
421 # ls -l /mnt/cnv
422 total 137101312
423 -rw-r----- 1 root root 140391743488 Nov 25 13:23 0
424
425 This aggregated conventional zone file can be used as a regular file::
426
427 # mkfs.ext4 /mnt/cnv/0
428 # mount -o loop /mnt/cnv/0 /data
429
430 The "seq" sub-directory grouping files for sequential write zones has in this
431 example 55356 zones::
432
433 # ls -lv /mnt/seq
434 total 14511243264
435 -rw-r----- 1 root root 0 Nov 25 13:23 0
436 -rw-r----- 1 root root 0 Nov 25 13:23 1
437 -rw-r----- 1 root root 0 Nov 25 13:23 2
438 ...
439 -rw-r----- 1 root root 0 Nov 25 13:23 55354
440 -rw-r----- 1 root root 0 Nov 25 13:23 55355
441
442 For sequential write zone files, the file size changes as data is appended at
443 the end of the file, similarly to any regular file system::
444
445 # dd if=/dev/zero of=/mnt/seq/0 bs=4096 count=1 conv=notrunc oflag=direct
446 1+0 records in
447 1+0 records out
448 4096 bytes (4.1 kB, 4.0 KiB) copied, 0.00044121 s, 9.3 MB/s
449
450 # ls -l /mnt/seq/0
451 -rw-r----- 1 root root 4096 Nov 25 13:23 /mnt/seq/0
452
453 The written file can be truncated to the zone size, preventing any further
454 write operation::
455
456 # truncate -s 268435456 /mnt/seq/0
457 # ls -l /mnt/seq/0
458 -rw-r----- 1 root root 268435456 Nov 25 13:49 /mnt/seq/0
459
460 Truncation to 0 size allows freeing the file zone storage space and restart
461 append-writes to the file::
462
463 # truncate -s 0 /mnt/seq/0
464 # ls -l /mnt/seq/0
465 -rw-r----- 1 root root 0 Nov 25 13:49 /mnt/seq/0
466
467 Since files are statically mapped to zones on the disk, the number of blocks
468 of a file as reported by stat() and fstat() indicates the capacity of the file
469 zone::
470
471 # stat /mnt/seq/0
472 File: /mnt/seq/0
473 Size: 0 Blocks: 524288 IO Block: 4096 regular empty file
474 Device: 870h/2160d Inode: 50431 Links: 1
475 Access: (0640/-rw-r-----) Uid: ( 0/ root) Gid: ( 0/ root)
476 Access: 2019-11-25 13:23:57.048971997 +0900
477 Modify: 2019-11-25 13:52:25.553805765 +0900
478 Change: 2019-11-25 13:52:25.553805765 +0900
479 Birth: -
480
481 The number of blocks of the file ("Blocks") in units of 512B blocks gives the
482 maximum file size of 524288 * 512 B = 256 MB, corresponding to the device zone
483 capacity in this example. Of note is that the "IO block" field always
484 indicates the minimum I/O size for writes and corresponds to the device
485 physical sector size.
486

3. 한국어 전문 번역

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

Zone을 file로 노출하는 단순 파일 시스템

1-29

zonefs는 zoned block device의 각 zone을 하나의 file로 노출하는 매우 단순한 파일 시스템이다. f2fs처럼 zoned block device를 native로 지원하면서 일반 POSIX 파일 시스템처럼 보이게 하는 구현과 달리, sequential write 제약을 사용자에게 숨기지 않는다.

Sequential write zone을 나타내는 file은 현재 file 끝부터 순서대로 써야 한다. 즉 write는 append-only이며, file offset을 임의로 골라 기존 데이터를 덮어쓰는 일반 random write를 허용하지 않는다.

따라서 zonefs는 완전한 POSIX 파일 시스템보다 raw block device access interface에 가깝다. 목표는 개발자에게 익숙하지 않을 수 있는 block device file ioctl과 sector range 관리를, 더 풍부한 file API와 `one file is one zone`이라는 상위 추상화로 바꾸는 것이다.

예를 들어 RocksDB나 LevelDB가 사용하는 LSM(log-structured merge) tree의 SSTable을 디스크 전체의 sector range로 직접 관리하는 대신 zone file에 일반 file처럼 저장할 수 있다. 이 대응은 application 수정량을 줄이고 서로 다른 programming language에서도 zoned storage 지원을 구현하기 쉽게 한다.

Zonefs 추상화
Zoned block device의 연속 LBA zoneZonefs가 zone 하나를 file 하나로 대응Application이 file API로 open·read·direct writeSequential zone은 file 끝에 appendDevice write pointer가 실제 다음 write 위치 관리

Application이 raw sector 대신 zone file을 다루는 경로다.

일반 파일 시스템과 zonefs
관점일반 POSIX 파일 시스템zonefs
Zone 제약구현 내부에 숨길 수 있음사용자에게 그대로 노출
Address 단위pathname과 file offsetzone file과 file offset
Sequential write일반적으로 application이 의식하지 않음file 끝 append만 허용
Metadatadirectory·inode 등 복잡한 구조 가능immutable superblock과 device zone 정보
주요 목적범용 file storagezoned application 구현 단순화

Zone 제약을 숨기는 정도와 application이 보는 interface를 비교한다.

.. SPDX-License-Identifier: GPL-2.0

================================================
ZoneFS - Zone filesystem for Zoned block devices
================================================

Introduction
============

zonefs is a very simple file system exposing each zone of a zoned block device
as a file. Unlike a regular POSIX-compliant file system with native zoned block
device support (e.g. f2fs), zonefs does not hide the sequential write
constraint of zoned block devices to the user. Files representing sequential
write zones of the device must be written sequentially starting from the end
of the file (append only writes).

As such, zonefs is in essence closer to a raw block device access interface
than to a full-featured POSIX file system. The goal of zonefs is to simplify
the implementation of zoned block device support in applications by replacing
raw block device file accesses with a richer file API, avoiding relying on
direct block device file ioctls which may be more obscure to developers. One
example of this approach is the implementation of LSM (log-structured merge)
tree structures (such as used in RocksDB and LevelDB) on zoned block devices
by allowing SSTables to be stored in a zone file similarly to a regular file
system rather than as a range of sectors of the entire disk. The introduction
of the higher level construct "one file is one zone" can help reducing the
amount of changes needed in the application as well as introducing support for
different application programming languages.

Conventional zone과 sequential zone

30-56

Zoned storage device의 address space는 여러 zone으로 나뉜다. Zone은 연속한 LBA(Logical Block Address)의 집합이며, 모든 zone도 서로 맞닿아 있어 중간에 LBA gap이 없다. 각 zone은 conventional 또는 sequential 같은 type을 가진다.

Conventional zone의 LBA에는 접근 제약이 없다. 일반 block device처럼 zone 안의 임의 위치를 읽거나 쓸 수 있다. 반면 sequential zone은 random read를 허용하지만 write는 반드시 순서대로 수행해야 한다.

각 sequential zone은 device가 유지하는 write pointer를 가진다. 이 pointer가 다음 write의 의무적인 시작 LBA를 가리키므로 이미 기록한 LBA는 덮어쓸 수 없다. 다시 기록하려면 먼저 zone reset command로 zone을 지워 write pointer를 시작 위치로 되돌려야 한다.

현재 흔한 zoned storage는 SMR(Shingled Magnetic Recording) HDD에서 SCSI ZBC(Zoned Block Commands) 또는 ATA ZAC(Zoned ATA Commands) interface를 사용한다. SSD도 garbage collection에 따른 내부 write amplification을 줄이기 위해 zoned interface를 구현할 수 있으며, NVMe protocol에는 ZNS(Zoned Namespace)가 정의되어 있다.

Zone type별 접근 계약
동작Conventional zoneSequential zone
Read임의 LBA 가능임의 LBA 가능
Write임의 LBA 가능write pointer 위치에서만 가능
Overwrite가능불가능
재사용일반 writezone reset 후 처음부터 write
위치 추적Host가 offset 지정Device write pointer가 다음 LBA 지정

Read·write·overwrite·재사용 가능성을 type별로 정리한다.

Sequential zone 재사용
Empty zone과 시작 write pointerWrite pointer 위치에 순차 writePointer가 기록량만큼 전진기존 LBA overwrite는 거부Zone reset command 실행Pointer가 zone 시작으로 복귀

기록이 끝난 zone을 다시 쓰기 위한 상태 흐름이다.

Zoned block devices
-------------------

Zoned storage devices belong to a class of storage devices with an address
space that is divided into zones. A zone is a group of consecutive LBAs and all
zones are contiguous (there are no LBA gaps). Zones may have different types.

* Conventional zones: there are no access constraints to LBAs belonging to
  conventional zones. Any read or write access can be executed, similarly to a
  regular block device.
* Sequential zones: these zones accept random reads but must be written
  sequentially. Each sequential zone has a write pointer maintained by the
  device that keeps track of the mandatory start LBA position of the next write
  to the device. As a result of this write constraint, LBAs in a sequential zone
  cannot be overwritten. Sequential zones must first be erased using a special
  command (zone reset) before rewriting.

Zoned storage devices can be implemented using various recording and media
technologies. The most common form of zoned storage today uses the SCSI Zoned
Block Commands (ZBC) and Zoned ATA Commands (ZAC) interfaces on Shingled
Magnetic Recording (SMR) HDDs.

Solid State Disks (SSD) storage devices can also implement a zoned interface
to, for instance, reduce internal write amplification due to garbage collection.
The NVMe Zoned NameSpace (ZNS) is a technical proposal of the NVMe standard
committee aiming at adding a zoned storage interface to the NVMe protocol.

정적 file tree와 on-disk metadata

57-81

zonefs는 device의 zone을 file로, zone type을 sub-directory로 표현한다. File tree는 mount 시 device가 보고한 zone 정보만으로 전부 구성되므로 복잡한 on-disk metadata 구조가 필요하지 않다.

Disk에 영구 저장하는 metadata는 immutable superblock뿐이다. Superblock에는 magic number와 선택적인 feature flag·value가 들어간다. Mount할 때 `blkdev_report_zones()`로 device zone configuration을 얻어 정적 tree를 채우며, file size는 zone type과 device가 관리하는 write pointer 위치에서 결정한다.

Superblock은 항상 sector 0에 기록된다. 이를 저장하는 device의 첫 zone은 zone file로 노출하지 않는다. 첫 zone이 sequential zone이면 `mkzonefs` format tool은 그 zone을 `FULL` 상태로 finish하여 read-only로 만들고, superblock 뒤에 data가 추가로 기록되는 것을 막는다.

Mount 시 tree 구성
Sector 0의 immutable superblock 읽기Magic number와 feature 확인`blkdev_report_zones()` 호출Zone type·capacity·write pointer 수집`cnv`·`seq` directory와 zone file 생성정적 mount tree 공개

영구 directory metadata 없이 device report로 namespace를 재구성한다.

Zonefs metadata 원천
정보원천용도
Magic numberSector 0 superblockzonefs format 식별
Feature flag·valueImmutable superblock선택 format 기능
Zone type·capacityDevice zone reportdirectory 분류와 최대 file size
Write pointerDevicesequential file의 현재 size
File treeMount 시 memory에서 생성zone을 pathname으로 노출

정보별 영구 저장 위치와 mount 시 용도를 구분한다.

Zonefs Overview
===============

Zonefs exposes the zones of a zoned block device as files. The files
representing zones are grouped by zone type, which are themselves represented
by sub-directories. This file structure is built entirely using zone information
provided by the device and so does not require any complex on-disk metadata
structure.

On-disk metadata
----------------

zonefs on-disk metadata is reduced to an immutable super block which
persistently stores a magic number and optional feature flags and values. On
mount, zonefs uses blkdev_report_zones() to obtain the device zone configuration
and populates the mount point with a static file tree solely based on this
information. File sizes come from the device zone type and write pointer
position managed by the device itself.

The super block is always written on disk at sector 0. The first zone of the
device storing the super block is never exposed as a zone file by zonefs. If
the zone containing the super block is a sequential zone, the mkzonefs format
tool always "finishes" the zone, that is, it transitions the zone to a full
state to make it read-only, preventing any data write.

Zone type directory와 file naming

82-121

같은 type의 zone file은 mount 시 자동으로 만들어지는 하나의 sub-directory 아래에 모인다. Conventional zone은 `cnv`, sequential write zone은 `seq` directory를 사용한다.

`cnv`는 usable conventional zone이 있을 때만 생긴다. Device에 conventional zone이 sector 0의 첫 zone 하나뿐이면 그 zone은 superblock 저장에 사용되어 file로 노출되지 않으므로 `cnv` directory도 만들지 않는다.

Zonefs에 존재하는 directory는 `cnv`와 `seq`뿐이다. 사용자는 다른 directory를 만들 수 없고 두 directory를 rename하거나 delete할 수도 없다. `stat()` 또는 `fstat()`이 반환한 `struct stat`의 directory `st_size`는 그 아래에 존재하는 file 수를 나타낸다.

각 directory 안의 zone file 이름은 같은 type 집합에서의 zone 번호인 `0`, `1`, `2`, ... 형식이다. 번호가 커질수록 device의 zone start sector도 증가한다. File 최대 size, 즉 zone capacity를 넘는 read·write는 `-EFBIG`로 실패한다.

File과 sub-directory의 create·delete·rename 및 attribute 수정은 허용되지 않는다. `stat()`·`fstat()`이 보고하는 file block 수는 현재 기록량이 아니라 zone file의 capacity, 곧 최대 file size를 뜻한다.

Zonefs namespace 규칙
항목표현의미
Conventional directory`cnv`usable conventional zone file 집합
Sequential directory`seq`sequential write zone file 집합
File name`0`, `1`, `2`, ...type별 zone 번호와 증가하는 start sector
Directory st_size정수directory 아래 file 수
File blocks512B block 단위zone capacity
Capacity 초과 I/O`-EFBIG`최대 file size 경계 위반

정적 tree에서 pathname과 metadata field가 표현하는 값이다.

Device zone에서 pathname으로
Device가 zone type과 start sector 보고Sector 0 superblock zone 제외Type에 따라 `cnv` 또는 `seq` 선택같은 type에서 start sector 순으로 번호 부여`/cnv/N` 또는 `/seq/N` file 생성

Zone type과 순서가 고정된 pathname을 만드는 방식이다.

Zone type sub-directories
-------------------------

Files representing zones of the same type are grouped together under the same
sub-directory automatically created on mount.

For conventional zones, the sub-directory "cnv" is used. This directory is
however created if and only if the device has usable conventional zones. If
the device only has a single conventional zone at sector 0, the zone will not
be exposed as a file as it will be used to store the zonefs super block. For
such devices, the "cnv" sub-directory will not be created.

For sequential write zones, the sub-directory "seq" is used.

These two directories are the only directories that exist in zonefs. Users
cannot create other directories and cannot rename nor delete the "cnv" and
"seq" sub-directories.

The size of the directories indicated by the st_size field of struct stat,
obtained with the stat() or fstat() system calls, indicates the number of files
existing under the directory.

Zone files
----------

Zone files are named using the number of the zone they represent within the set
of zones of a particular type. That is, both the "cnv" and "seq" directories
contain files named "0", "1", "2", ... The file numbers also represent
increasing zone start sector on the device.

All read and write operations to zone files are not allowed beyond the file
maximum size, that is, beyond the zone capacity. Any access exceeding the zone
capacity is failed with the -EFBIG error.

Creating, deleting, renaming or modifying any attribute of files and
sub-directories is not allowed.

The number of blocks of a file as reported by stat() and fstat() indicates the
capacity of the zone file, or in other words, the maximum file size.

Conventional·sequential zone file I/O

122-161

Conventional zone file의 size는 해당 zone size로 고정되며 truncate할 수 없다. File size 경계 안에서는 buffered I/O, direct I/O, `mmap` 등 모든 방식으로 random read·write할 수 있다.

`seq` directory의 sequential zone file size는 zone start sector를 기준으로 한 write pointer의 상대 위치다. 따라서 file size는 성공적으로 순차 기록된 data 끝을 나타내며 write가 진행될수록 증가한다.

Sequential file write는 file 끝, 또는 asynchronous I/O에서 이미 발행되어 아직 in-flight인 마지막 write의 끝에서 시작해야 한다. Zonefs는 random write를 순차 write로 바꾸지 않으며 start offset이 이 위치와 다르면 request를 실패시킨다.

Page cache의 dirty page writeback은 순차 순서를 보장하지 않으므로 sequential file에는 buffered write와 writable shared mapping을 금지하고 direct I/O write만 허용한다. Block layer에서는 `ELEVATOR_F_ZBD_SEQ_WRITE` feature를 구현한 elevator가 request를 device에 순서대로 전달해야 하며, zoned device 초기화 시 일반적으로 `mq-deadline`이 기본으로 설정된다.

Sequential file read에는 I/O 방식 제한이 없어 buffered I/O, direct I/O, shared read mapping을 모두 사용할 수 있다. Truncate는 두 값만 허용한다. 0으로 줄이면 zone reset으로 write pointer를 zone 시작으로 되돌리고, zone capacity로 늘리면 finish zone operation으로 zone을 `FULL` 상태로 전환한다.

Zone file I/O 지원
동작Conventional fileSequential file
Random read허용허용
Buffered write허용금지
Direct write임의 offset 허용file 끝 append만 허용
Writable shared mmap허용금지
Shared read mapping허용허용
Truncate 0금지zone reset
Truncate capacity고정 size라 불필요zone finish와 FULL 전환

File type별 read·write·mapping·truncate 계약을 비교한다.

Sequential direct write 검증
Application이 direct I/O write 제출Start offset이 file 끝 또는 in-flight tail인지 검사불일치하면 write 실패일치하면 block layer elevator에 전달`ELEVATOR_F_ZBD_SEQ_WRITE`가 request 순서 유지Device write pointer 전진과 file size 갱신

Offset와 block elevator가 순차 write 계약을 함께 지킨다.

Sequential truncate 의미
Target sizeZone operation결과
0Zone resetwrite pointer를 시작으로 되돌려 재사용 가능
Zone capacityZone finishFULL 상태, 추가 write 불가
그 밖의 값없음truncate 거부

허용되는 두 target size가 zone management command로 대응된다.

Conventional zone files
-----------------------

The size of conventional zone files is fixed to the size of the zone they
represent. Conventional zone files cannot be truncated.

These files can be randomly read and written using any type of I/O operation:
buffered I/Os, direct I/Os, memory mapped I/Os (mmap), etc. There are no I/O
constraint for these files beyond the file size limit mentioned above.

Sequential zone files
---------------------

The size of sequential zone files grouped in the "seq" sub-directory represents
the file's zone write pointer position relative to the zone start sector.

Sequential zone files can only be written sequentially, starting from the file
end, that is, write operations can only be append writes. Zonefs makes no
attempt at accepting random writes and will fail any write request that has a
start offset not corresponding to the end of the file, or to the end of the last
write issued and still in-flight (for asynchronous I/O operations).

Since dirty page writeback by the page cache does not guarantee a sequential
write pattern, zonefs prevents buffered writes and writeable shared mappings
on sequential files. Only direct I/O writes are accepted for these files.
zonefs relies on the sequential delivery of write I/O requests to the device
implemented by the block layer elevator. An elevator implementing the sequential
write feature for zoned block device (ELEVATOR_F_ZBD_SEQ_WRITE elevator feature)
must be used. This type of elevator (e.g. mq-deadline) is set by default
for zoned block devices on device initialization.

There are no restrictions on the type of I/O used for read operations in
sequential zone files. Buffered I/Os, direct I/Os and shared read mappings are
all accepted.

Truncating sequential zone files is allowed only down to 0, in which case, the
zone is reset to rewind the file zone write pointer position to the start of
the zone, or up to the zone capacity, in which case the file's zone is
transitioned to the FULL state (finish zone operation).

Format 시 선택 기능

162-172

여러 선택 기능은 mount할 때가 아니라 zonefs를 format할 때 활성화한다. Format 결과는 immutable superblock과 mount 시 구성되는 file 속성에 반영되므로 변경하려면 device를 다시 format해야 할 수 있다.

Conventional zone aggregation을 사용하면 서로 연속한 conventional zone 범위를 기본적인 zone당 file 하나 대신 더 큰 file 하나로 합친다. Sequential zone의 one-file-per-zone 규칙을 바꾸는 option은 아니다.

Zone file owner는 기본적으로 UID 0, GID 0인 root지만 유효한 UID·GID로 바꿀 수 있다. File access permission의 기본값은 `0640`이며 format option으로 다른 permission을 지정할 수 있다.

Zonefs format option
기능기본값선택 효과
Conventional aggregationZone당 file 하나연속 conventional zone을 큰 file 하나로 결합
Owner UID·GID0:0유효한 다른 UID·GID 지정
Access permission0640다른 file mode 지정

Format 시 결정되는 namespace·ownership·permission 항목이다.

Format options
--------------

Several optional features of zonefs can be enabled at format time.

* Conventional zone aggregation: ranges of contiguous conventional zones can be
  aggregated into a single larger file instead of the default one file per zone.
* File ownership: The owner UID and GID of zone files is by default 0 (root)
  but can be changed to any valid UID/GID.
* File access permissions: the default 640 access permissions can be changed.

Zoned device 고유 I/O 오류

173-218

Zoned block device도 bad sector처럼 일반 block device와 같은 원인으로 I/O request가 실패할 수 있다. 여기에 zoned standard가 정의하는 read-only·offline 상태 전이, write pointer 불일치, delayed cache error가 추가된다.

Zone이 `BLK_ZONE_COND_READONLY`로 바뀌면 이미 기록한 data는 읽을 수 있지만 더 쓸 수 없다. Zone management command나 read·write로 정상 read/write 상태로 되돌릴 수 없다. Standard는 전이 원인을 규정하지 않지만 HDD write head 결함으로 그 head 아래 zone 전체가 read-only가 되는 경우가 예다.

`BLK_ZONE_COND_OFFLINE` zone은 읽기와 쓰기가 모두 불가능하며 사용자 action으로 정상 상태에 복귀시킬 수 없다. HDD의 read-write head 결함으로 platter의 해당 영역에 접근하지 못하는 경우가 전형적인 예다.

Unaligned write error는 request 실행 시 start sector가 zone write pointer와 다를 때 발생한다. Zonefs가 append를 강제해도 큰 direct I/O가 여러 BIO·request로 나뉜 뒤 일부가 실패하거나 asynchronous write 묶음 중 하나가 실패하면, 뒤에 queue된 request가 모두 write pointer와 어긋나 연쇄 실패할 수 있다.

Device write cache가 켜져 있으면 이미 완료로 보고한 write 범위의 오류가 `fsync()` 같은 cache flush 시점에 늦게 드러날 수 있다. 이런 delayed write error도 문제 sector 뒤의 cached sequential stream을 무효화하여 data가 연속해서 버려질 수 있다.

Zonefs I/O 오류 원인
오류발견·원인Zone 접근사용자 복귀
일반 media 오류Bad sector 등영향 범위에 따라 다름Device 상태에 따름
READONLYDevice zone 상태 전이Read만 가능불가능
OFFLINEDevice zone 상태 전이Read·write 모두 불가불가능
Unaligned writeRequest start와 write pointer 불일치뒤 request도 연쇄 실패 가능Size·pointer 재동기화 필요
Delayed writeCache flush에서 과거 write 오류 발견오류 뒤 data 손실 가능지속 저장량 기준 size 수정

상태·발견 시점·접근 가능성과 복구 가능성을 구분한다.

Partial write의 연쇄 오류
Large direct I/O를 여러 BIO·request로 분할앞 request 일부는 성공하여 write pointer 전진중간 request 하나가 실패뒤 request의 start sector가 pointer와 불일치뒤 request가 unaligned write로 연쇄 실패Zone report를 기준으로 inode size 복구

여러 request로 분할된 sequential write에서 한 실패가 뒤 request에 미치는 영향이다.

IO error handling
-----------------

Zoned block devices may fail I/O requests for reasons similar to regular block
devices, e.g. due to bad sectors. However, in addition to such known I/O
failure pattern, the standards governing zoned block devices behavior define
additional conditions that result in I/O errors.

* A zone may transition to the read-only condition (BLK_ZONE_COND_READONLY):
  While the data already written in the zone is still readable, the zone can
  no longer be written. No user action on the zone (zone management command or
  read/write access) can change the zone condition back to a normal read/write
  state. While the reasons for the device to transition a zone to read-only
  state are not defined by the standards, a typical cause for such transition
  would be a defective write head on an HDD (all zones under this head are
  changed to read-only).

* A zone may transition to the offline condition (BLK_ZONE_COND_OFFLINE):
  An offline zone cannot be read nor written. No user action can transition an
  offline zone back to an operational good state. Similarly to zone read-only
  transitions, the reasons for a drive to transition a zone to the offline
  condition are undefined. A typical cause would be a defective read-write head
  on an HDD causing all zones on the platter under the broken head to be
  inaccessible.

* Unaligned write errors: These errors result from the host issuing write
  requests with a start sector that does not correspond to a zone write pointer
  position when the write request is executed by the device. Even though zonefs
  enforces sequential file write for sequential zones, unaligned write errors
  may still happen in the case of a partial failure of a very large direct I/O
  operation split into multiple BIOs/requests or asynchronous I/O operations.
  If one of the write request within the set of sequential write requests
  issued to the device fails, all write requests queued after it will
  become unaligned and fail.

* Delayed write errors: similarly to regular block devices, if the device side
  write cache is enabled, write errors may occur in ranges of previously
  completed writes when the device write cache is flushed, e.g. on fsync().
  Similarly to the previous immediate unaligned write error case, delayed write
  errors can propagate through a stream of cached sequential data for a zone
  causing all data to be dropped after the sector that caused the error.

All I/O errors detected by zonefs are notified to the user with an error code
return for the system call that triggered or detected the error. The recovery
actions taken by zonefs in response to I/O errors depend on the I/O type (read
vs write) and on the reason for the error (bad sector, unaligned writes or zone

오류 통지와 최소 복구

219-251

Zonefs가 감지한 모든 I/O 오류는 오류를 유발했거나 감지한 system call의 error code로 사용자에게 통지한다. 복구 action은 read·write I/O type과 bad sector, unaligned write, zone condition change 같은 원인에 따라 달라진다.

Read I/O 오류 자체에는 특별한 복구를 하지 않는다. 단, file zone이 여전히 good condition이고 inode size와 zone write pointer가 일치할 때에만 그렇다. 상태 또는 size 불일치가 발견되면 아래의 I/O error recovery를 실행한다. Write I/O 오류와 read-only·offline condition 전이는 항상 복구를 실행한다.

Sequential write의 immediate·delayed 오류는 inode size와 실제 성공 기록량을 다르게 만들 수 있다. Multi-BIO write가 일부만 성공했어도 전체 operation은 실패로 보고될 수 있으므로 write pointer가 전진한 만큼 inode size를 늘려야 이후 file 끝에서 write를 재시작할 수 있다.

반대로 `fsync()`에서 delayed error를 발견하면 실제로 영구 저장된 data가 inode size보다 적을 수 있다. Zonefs는 오류 후 file size를 zone에 persist된 양과 맞춘다. 즉 복구의 기준은 userspace에 과거 보고한 길이가 아니라 device가 보존한 data와 write pointer다.

Zone이 read-only가 되면 file permission도 read-only로 바꿔 attribute와 data 수정을 막는다. Offline zone은 read·write permission을 모두 제거한다. 이 최소 복구 위에 추가할 조치는 `errors=xxx` mount option이 결정한다.

최소 오류 복구 판정
I/O 오류 또는 zone condition change 감지Write 오류면 항상 복구Read-only·offline 전이면 항상 복구Read 오류면 zone condition과 inode size·write pointer 검사불일치가 없으면 error만 반환불일치가 있으면 size·permission 복구

I/O type과 zone consistency가 복구 실행 여부를 결정한다.

최소 복구 결과
상황File sizePermission
Good zone의 partial immediate write전진한 write pointer까지 증가Behavior에 따라 추가 제한
Good zone의 delayed write error영구 저장된 data 끝까지 감소Behavior에 따라 추가 제한
Read-only zoneRun-time이면 마지막 값 유지Write 제거
Offline zone0Read·write 모두 제거

Device가 확정한 상태를 file metadata에 반영한다.

condition change).

* For read I/O errors, zonefs does not execute any particular recovery action,
  but only if the file zone is still in a good condition and there is no
  inconsistency between the file inode size and its zone write pointer position.
  If a problem is detected, I/O error recovery is executed (see below table).

* For write I/O errors, zonefs I/O error recovery is always executed.

* A zone condition change to read-only or offline also always triggers zonefs
  I/O error recovery.

Zonefs minimal I/O error recovery may change a file size and file access
permissions.

* File size changes:
  Immediate or delayed write errors in a sequential zone file may cause the file
  inode size to be inconsistent with the amount of data successfully written in
  the file zone. For instance, the partial failure of a multi-BIO large write
  operation will cause the zone write pointer to advance partially, even though
  the entire write operation will be reported as failed to the user. In such
  case, the file inode size must be advanced to reflect the zone write pointer
  change and eventually allow the user to restart writing at the end of the
  file.
  A file size may also be reduced to reflect a delayed write error detected on
  fsync(): in this case, the amount of data effectively written in the zone may
  be less than originally indicated by the file inode size. After such I/O
  error, zonefs always fixes the file inode size to reflect the amount of data
  persistently stored in the file zone.

* Access permission changes:
  A zone condition change to read-only is indicated with a change in the file
  access permissions to render the file read-only. This disables changes to the

errors behavior별 post-error 상태

252-305

`errors=xxx`는 최소 복구 뒤 zonefs가 취할 추가 action을 선택한다. 원문의 ASCII 표는 아래 구조화 표와 같다. `fixed`는 device write pointer와 persist된 data에 맞춰 file size를 수정한다는 뜻이며, device zone의 read·write 가능 여부와 zone file permission을 구분해야 한다.

I/O 오류 후 상태
errorsZone conditionFile sizeFile readFile writeDevice readDevice write
remount-rogoodfixedyesnoyesyes
remount-roread-onlyas isyesnoyesno
remount-rooffline0nononono
zone-rogoodfixedyesnoyesyes
zone-roread-onlyas isyesnoyesno
zone-rooffline0nononono
zone-offlinegood0nonoyesyes
zone-offlineread-only0nonoyesno
zone-offlineoffline0nononono
repairgoodfixedyesyesyesyes
repairread-onlyas isyesnoyesno
repairoffline0nononono

Behavior와 device zone condition에 따른 file size·file permission·device 접근 상태다.

Option을 지정하지 않으면 `errors=remount-ro`가 기본이다. 이 behavior는 오류 file 하나가 아니라 모든 file permission을 read-only로 바꾸고 파일 시스템 전체를 read-only로 remount한다.

Device가 zone을 offline으로 전환하여 생긴 size·permission 변화는 영구적이다. `mkfs.zonefs`(`mkzonefs`)로 다시 format하거나 remount해도 offline zone file을 good state로 되돌릴 수 없다. Device가 read-only로 바꾼 zone의 write permission 제거도 마찬가지로 영구적이다.

반면 good condition zone에 `remount-ro`, `zone-ro`, `zone-offline` behavior가 추가한 permission 제한은 임시다. Unmount 후 remount하면 format 시 정한 기본 access right로 복구된다. `repair`는 good zone의 file size 수정이라는 최소 action만 수행하지만, device가 read-only·offline으로 보고한 zone의 permission 제한은 여전히 적용한다.

Permission 변화의 지속성
원인지속성Remount·reformat 결과
Device OFFLINE 전이영구복구되지 않음
Device READONLY 전이영구Write access 복구되지 않음
Good zone의 remount-ro 제한임시Remount 시 format 기본값 복구
Good zone의 zone-ro 제한임시Remount 시 format 기본값 복구
Good zone의 zone-offline 제한임시Remount 시 format 기본값 복구
repair의 size fix실제 persist 상태 반영Device write pointer 기준 유지

제한의 원인이 device 상태인지 mount behavior인지에 따라 복구 가능성이 달라진다.

  file attributes and data modification. For offline zones, all permissions
  (read and write) to the file are disabled.

Further action taken by zonefs I/O error recovery can be controlled by the user
with the "errors=xxx" mount option. The table below summarizes the result of
zonefs I/O error processing depending on the mount option and on the zone
conditions::

    +--------------+-----------+-----------------------------------------+
    |              |           |            Post error state             |
    | "errors=xxx" |  device   |                 access permissions      |
    |    mount     |   zone    | file         file          device zone  |
    |    option    | condition | size     read    write    read    write |
    +--------------+-----------+-----------------------------------------+
    |              | good      | fixed    yes     no       yes     yes   |
    | remount-ro   | read-only | as is    yes     no       yes     no    |
    | (default)    | offline   |   0      no      no       no      no    |
    +--------------+-----------+-----------------------------------------+
    |              | good      | fixed    yes     no       yes     yes   |
    | zone-ro      | read-only | as is    yes     no       yes     no    |
    |              | offline   |   0      no      no       no      no    |
    +--------------+-----------+-----------------------------------------+
    |              | good      |   0      no      no       yes     yes   |
    | zone-offline | read-only |   0      no      no       yes     no    |
    |              | offline   |   0      no      no       no      no    |
    +--------------+-----------+-----------------------------------------+
    |              | good      | fixed    yes     yes      yes     yes   |
    | repair       | read-only | as is    yes     no       yes     no    |
    |              | offline   |   0      no      no       no      no    |
    +--------------+-----------+-----------------------------------------+

Further notes:

* The "errors=remount-ro" mount option is the default behavior of zonefs I/O
  error processing if no errors mount option is specified.
* With the "errors=remount-ro" mount option, the change of the file access
  permissions to read-only applies to all files. The file system is remounted
  read-only.
* Access permission and file size changes due to the device transitioning zones
  to the offline condition are permanent. Remounting or reformatting the device
  with mkfs.zonefs (mkzonefs) will not change back offline zone files to a good
  state.
* File access permission changes to read-only due to the device transitioning
  zones to the read-only condition are permanent. Remounting or reformatting
  the device will not re-enable file write access.
* File access permission changes implied by the remount-ro, zone-ro and
  zone-offline mount options are temporary for zones in a good condition.
  Unmounting and remounting the file system will restore the previous default
  (format time values) access rights to the files affected.
* The repair mount option triggers only the minimal set of I/O error recovery
  actions, that is, file size fixes for zones in a good condition. Zones
  indicated as being read-only or offline by the device still imply changes to
  the zone file access permissions as noted in the table above.

errors mount option과 mount-time 차이

306-335

Zonefs mount option은 `errors=<behavior>`와 `explicit-open`이다. `errors=<behavior>`는 I/O error, inode size inconsistency, zone condition change에 대응하는 policy를 `remount-ro`, `zone-ro`, `zone-offline`, `repair` 중에서 고르게 하며 기본값은 `remount-ro`다.

앞 절의 표는 run-time I/O error action을 설명한다. Mount 중 발생한 I/O 오류는 behavior와 관계없이 mount operation 자체를 실패시킨다. Read-only zone 처리도 발견 시점에 따라 다르다.

Mount time에 read-only zone을 발견하면 offline zone과 동일하게 모든 access를 끄고 zone file size를 0으로 설정한다. ZBC와 ZAC standard에서 read-only zone의 write pointer는 invalid로 정의되어 이미 기록된 data 양을 알아낼 수 없기 때문이다.

Run-time에 read-only로 전환된 zone은 마지막으로 갱신된 zone file size를 그대로 둔다. 원문에는 write pointer를 `invalib`라고 쓴 오탈자가 있지만 의미는 `invalid`다. 번역에서는 원문의 철자를 source block에 보존하고 기술적 의미를 이 문장처럼 명확히 한다.

Read-only zone 발견 시점
발견 시점File sizeAccess이유
Mount time0모두 비활성Read-only write pointer가 invalid라 기록량 판단 불가
Run-time마지막 갱신값 유지Write 비활성전환 전까지 추적한 size가 존재

Write pointer 신뢰 가능성 때문에 mount-time과 run-time 처리가 다르다.

Mount-time 오류 처리
Superblock과 device zone report 읽기I/O 오류이면 mount 실패Read-only zone 발견Write pointer가 invalid라 data 양 확인 불가Offline처럼 size 0·access disabled로 구성나머지 zone으로 정적 tree 생성

Mount 중에는 run-time recovery보다 namespace 공개 여부가 우선한다.

Mount options
-------------

zonefs defines several mount options:
* errors=<behavior>
* explicit-open

"errors=<behavior>" option
~~~~~~~~~~~~~~~~~~~~~~~~~~

The "errors=<behavior>" option mount option allows the user to specify zonefs
behavior in response to I/O errors, inode size inconsistencies or zone
condition changes. The defined behaviors are as follow:

* remount-ro (default)
* zone-ro
* zone-offline
* repair

The run-time I/O error actions defined for each behavior are detailed in the
previous section. Mount time I/O errors will cause the mount operation to fail.
The handling of read-only zones also differs between mount-time and run-time.
If a read-only zone is found at mount time, the zone is always treated in the
same manner as offline zones, that is, all accesses are disabled and the zone
file size set to 0. This is necessary as the write pointer of read-only zones
is defined as invalib by the ZBC and ZAC standards, making it impossible to
discover the amount of data that has been written to the zone. In the case of a
read-only zone discovered at run-time, as indicated in the previous section.
The size of the zone file is left unchanged from its last updated value.

Active zone 제한과 explicit-open

336-353

NVMe ZNS 같은 zoned block device는 active zone 수를 제한할 수 있다. Active에는 implicit open, explicit open, closed condition의 zone이 포함된다. 아직 active가 아닌 file zone에 write를 시작할 때 이 limit를 넘으면 application이 write I/O error를 볼 수 있다.

`explicit-open` mount option은 file을 처음 write-open할 때 open zone command를 보내 zone을 미리 active로 만든다. Open command가 성공하면 application은 해당 file의 write request를 device가 처리할 수 있음을 보장받는다.

반대로 zone file의 마지막 `close()`가 실행될 때 zone이 full도 empty도 아니면 zone close command를 device에 보낸다. 이 방식은 file descriptor 수명과 device의 explicit-open resource를 연결하여 open zone limit을 예측 가능하게 관리한다.

explicit-open 수명
Sequential zone file을 처음 write-openZonefs가 open zone command 발행성공하면 active slot 확보Application write request 처리마지막 close() 실행Zone이 full·empty가 아니면 close zone command 발행

첫 write-open과 마지막 close가 device zone command에 대응된다.

Active 상태와 close 동작
Zone 상태Active 계산마지막 close 시 zone close
Implicit open포함필요할 수 있음
Explicit open포함필요
Closed·partially written포함이미 closed이면 불필요
Fullactive 아님발행하지 않음
Emptyactive 아님발행하지 않음

Zone 상태에 따라 마지막 file close에서 command가 필요한지 구분한다.

"explicit-open" option
~~~~~~~~~~~~~~~~~~~~~~

A zoned block device (e.g. an NVMe Zoned Namespace device) may have limits on
the number of zones that can be active, that is, zones that are in the
implicit open, explicit open or closed conditions.  This potential limitation
translates into a risk for applications to see write IO errors due to this
limit being exceeded if the zone of a file is not already active when a write
request is issued by the user.

To avoid these potential errors, the "explicit-open" mount option forces zones
to be made active using an open zone command when a file is opened for writing
for the first time. If the zone open command succeeds, the application is then
guaranteed that write requests can be processed. Conversely, the
"explicit-open" mount option will result in a zone close command being issued
to the device on the last close() of a zone file if the zone is not full nor
empty.

Runtime sysfs counter

354-391

Mount된 device마다 user-readable zonefs attribute가 `/sys/fs/zonefs/<dev>/` 아래에 생긴다. `<dev>`는 mount한 zoned block device 이름이며, counter는 open-for-write 제한과 active-zone 제한을 구분해 보여 준다.

Zonefs runtime sysfs attribute
Attribute의미0의 의미explicit-open 관계
max_wro_seq_files동시에 write-open 가능한 sequential file 최대 수Open zone 제한 없음도달 시 추가 write-open을 zonefs가 실패
nr_wro_seq_files현재 write-open된 sequential file 수현재 없음사용 시 max를 넘지 않음
max_active_seq_files동시에 active일 수 있는 sequential file 최대 수Active zone 제한 없음Device maximum active zones와 같음
nr_active_seq_files현재 active sequential file 수현재 active 없음Option 유무와 무관하게 max 제한 적용

최대값 0은 제한 없음이며 write-open 수와 active 수는 서로 다른 자원을 센다.

`max_wro_seq_files`는 device가 지원하는 explicit·implicit open zone의 최대 수다. 값이 0이면 제한이 없다. `explicit-open` 사용 중 현재 write-open 수가 limit에 도달하면 zonefs가 새 sequential file의 write `open()`을 실패시킨다.

`nr_wro_seq_files`는 현재 write-open file 수다. `explicit-open`을 쓰면 절대 maximum을 넘지 않는다. 쓰지 않으면 보고값이 maximum보다 클 수 있으므로 application이 동시에 실제 write하는 file 수를 limit 이하로 제한해야 하며, 지키지 않으면 write error가 발생할 수 있다.

`max_active_seq_files`는 partially written, 즉 empty도 full도 아닌 zone file과 explicit-open zone을 합친 active file 최대 수이며 device의 maximum active zones와 같다. `nr_active_seq_files`는 현재 active file 수다.

원문 마지막 문장은 `nr_active_seq_files`가 자기 자신을 넘을 수 없다고 적었지만 문맥상 maximum인 `max_active_seq_files`를 뜻한다. 이 명백한 식별자 오탈자는 영어 source에는 그대로 보존하고, 해설과 구조화 표에서는 `max_active_seq_files != 0`일 때 `nr_active_seq_files <= max_active_seq_files`라는 실제 관계로 제시한다.

두 limit의 관계
Device가 open zone limit과 active zone limit 보고max_wro_seq_files와 max_active_seq_files 공개Write-open 시 nr_wro_seq_files 갱신Partially written·explicit-open 상태로 nr_active_seq_files 갱신Maximum이 0이 아니면 각 resource limit 준수Application이 sysfs 값으로 concurrency 조절

Write-open file과 active zone을 별도 counter로 관리한다.

Runtime sysfs attributes
------------------------

zonefs defines several sysfs attributes for mounted devices.  All attributes
are user readable and can be found in the directory /sys/fs/zonefs/<dev>/,
where <dev> is the name of the mounted zoned block device.

The attributes defined are as follows.

* **max_wro_seq_files**:  This attribute reports the maximum number of
  sequential zone files that can be open for writing.  This number corresponds
  to the maximum number of explicitly or implicitly open zones that the device
  supports.  A value of 0 means that the device has no limit and that any zone
  (any file) can be open for writing and written at any time, regardless of the
  state of other zones.  When the *explicit-open* mount option is used, zonefs
  will fail any open() system call requesting to open a sequential zone file for
  writing when the number of sequential zone files already open for writing has
  reached the *max_wro_seq_files* limit.
* **nr_wro_seq_files**:  This attribute reports the current number of sequential
  zone files open for writing.  When the "explicit-open" mount option is used,
  this number can never exceed *max_wro_seq_files*.  If the *explicit-open*
  mount option is not used, the reported number can be greater than
  *max_wro_seq_files*.  In such case, it is the responsibility of the
  application to not write simultaneously more than *max_wro_seq_files*
  sequential zone files.  Failure to do so can result in write errors.
* **max_active_seq_files**:  This attribute reports the maximum number of
  sequential zone files that are in an active state, that is, sequential zone
  files that are partially written (not empty nor full) or that have a zone that
  is explicitly open (which happens only if the *explicit-open* mount option is
  used).  This number is always equal to the maximum number of active zones that
  the device supports.  A value of 0 means that the mounted device has no limit
  on the number of sequential zone files that can be active.
* **nr_active_seq_files**:  This attributes reports the current number of
  sequential zone files that are active. If *max_active_seq_files* is not 0,
  then the value of *nr_active_seq_files* can never exceed the value of
  *nr_active_seq_files*, regardless of the use of the *explicit-open* mount
  option.

User space format·test 도구

392-402

`mkzonefs`는 zoned block device를 zonefs용으로 format하는 user space tool이다. Source와 배포 정보는 `https://github.com/damien-lemoal/zonefs-tools`에서 제공한다.

같은 `zonefs-tools` project에는 test suite도 포함된다. 실제 zoned block device뿐 아니라 zoned mode로 만든 `null_blk` block device에도 실행할 수 있어 hardware 없이 format·mount·I/O 동작과 error path를 검증할 수 있다.

운영 device에 test suite를 적용할 때는 format과 destructive zone operation 가능성을 먼저 확인해야 한다. 이 문서는 도구 위치와 적용 대상을 설명하며, 실제 command option과 안전 절차는 해당 tool documentation을 따른다.

Zonefs 도구 검증 경로
실제 zoned device 또는 zoned null_blk 준비`mkzonefs`로 zonefs formatZonefs mountzonefs-tools test suite 실행Zone file I/O와 상태 전이 확인

Format tool과 test suite가 실제 또는 emulated zoned device를 준비·검증한다.

Zonefs User Space Tools
=======================

The mkzonefs tool is used to format zoned block devices for use with zonefs.
This tool is available on Github at:

https://github.com/damien-lemoal/zonefs-tools

zonefs-tools also includes a test suite which can be run against any zoned
block device, including null_blk block device created with zoned mode.

15TB SMR HDD format과 conventional aggregation

403-433

예시는 zone 크기가 256MB인 15TB host-managed SMR HDD를 conventional zone aggregation 기능과 함께 format한다. `mkzonefs -o aggr_cnv /dev/sdX`로 format하고 zonefs로 mount한 뒤 root directory를 확인한다.

출력에서 `cnv` directory의 `st_size`는 1, `seq`의 `st_size`는 55356이다. Directory size가 byte 용량이 아니라 해당 type의 zone file 개수라는 앞의 계약을 실제 `ls -l` 결과로 보여 준다.

모든 conventional zone은 aggregation되어 `/mnt/cnv/0` file 하나가 되고 size는 140391743488 bytes다. 이 aggregated conventional file은 random I/O가 가능한 일반 file처럼 다룰 수 있어 그 안에 ext4를 만들고 loop mount할 수도 있다.

# mkzonefs -o aggr_cnv /dev/sdX
# mount -t zonefs /dev/sdX /mnt
# mkfs.ext4 /mnt/cnv/0
# mount -o loop /mnt/cnv/0 /data
Conventional aggregation 예
15TB SMR HDD와 256MB zone`mkzonefs -o aggr_cnv /dev/sdX`여러 conventional zone을 `/mnt/cnv/0` 하나로 집계`mkfs.ext4 /mnt/cnv/0`Loop device 방식으로 `/data`에 mount

여러 conventional zone을 하나의 file로 묶어 내부에 일반 파일 시스템을 배치한다.

예제 root directory 해석
Directoryst_size해석
cnv1Aggregated conventional file 하나
seq55356Sequential zone file 55356개

`ls -l /mnt/`의 directory size를 file 개수로 읽는다.

Examples
--------

The following formats a 15TB host-managed SMR HDD with 256 MB zones
with the conventional zones aggregation feature enabled::

    # mkzonefs -o aggr_cnv /dev/sdX
    # mount -t zonefs /dev/sdX /mnt
    # ls -l /mnt/
    total 0
    dr-xr-xr-x 2 root root     1 Nov 25 13:23 cnv
    dr-xr-xr-x 2 root root 55356 Nov 25 13:23 seq

The size of the zone files sub-directories indicate the number of files
existing for each type of zones. In this example, there is only one
conventional zone file (all conventional zones are aggregated under a single
file)::

    # ls -l /mnt/cnv
    total 137101312
    -rw-r----- 1 root root 140391743488 Nov 25 13:23 0

This aggregated conventional zone file can be used as a regular file::

    # mkfs.ext4 /mnt/cnv/0
    # mount -o loop /mnt/cnv/0 /data

The "seq" sub-directory grouping files for sequential write zones has in this
example 55356 zones::

    # ls -lv /mnt/seq

Sequential append와 truncate

434-461

`seq` directory에는 예제 device의 sequential write zone 55356개가 file `0`부터 `55355`까지 나타난다. 아직 기록하지 않은 zone file size는 0이지만 `ls`의 total과 `stat` block 수는 각 zone capacity를 반영한다.

예제는 `dd`에 `oflag=direct`를 지정하여 `/mnt/seq/0` 끝에 4096 bytes를 직접 쓴다. 성공 후 file size가 4096으로 증가하며 이는 device write pointer가 zone 시작에서 4096 bytes만큼 전진했음을 뜻한다.

File을 268435456 bytes, 즉 256MB zone capacity로 truncate하면 zone finish operation이 실행되어 추가 write를 막는다. 반대로 size 0으로 truncate하면 zone reset으로 storage space를 비우고 append write를 처음부터 다시 시작할 수 있다.

Sequential file 크기 변화
Empty `/mnt/seq/0`, size 04096B direct appendWrite pointer 전진, size 4096Capacity로 truncate하면 FULL·write 금지0으로 truncate하면 zone resetSize 0에서 append 재시작 가능

Direct append와 두 truncate target이 write pointer 상태를 바꾼다.

예제 command와 결과
Operation결과 sizeZone 효과
`dd ... bs=4096 count=1 oflag=direct`4096Direct append와 pointer 전진
`truncate -s 268435456`268435456Zone finish, 추가 write 방지
`truncate -s 0`0Zone reset, space 해제와 재사용

각 user operation이 file size와 zone에 미치는 결과다.

    total 14511243264
    -rw-r----- 1 root root 0 Nov 25 13:23 0
    -rw-r----- 1 root root 0 Nov 25 13:23 1
    -rw-r----- 1 root root 0 Nov 25 13:23 2
    ...
    -rw-r----- 1 root root 0 Nov 25 13:23 55354
    -rw-r----- 1 root root 0 Nov 25 13:23 55355

For sequential write zone files, the file size changes as data is appended at
the end of the file, similarly to any regular file system::

    # dd if=/dev/zero of=/mnt/seq/0 bs=4096 count=1 conv=notrunc oflag=direct
    1+0 records in
    1+0 records out
    4096 bytes (4.1 kB, 4.0 KiB) copied, 0.00044121 s, 9.3 MB/s

    # ls -l /mnt/seq/0
    -rw-r----- 1 root root 4096 Nov 25 13:23 /mnt/seq/0

The written file can be truncated to the zone size, preventing any further
write operation::

    # truncate -s 268435456 /mnt/seq/0
    # ls -l /mnt/seq/0
    -rw-r----- 1 root root 268435456 Nov 25 13:49 /mnt/seq/0

Truncation to 0 size allows freeing the file zone storage space and restart
append-writes to the file::

stat block 수와 최대 file size

462-485

Zonefs file은 disk zone에 정적으로 대응되므로 `stat()`·`fstat()`이 보고하는 `Blocks`는 현재 file size가 아니라 zone capacity를 나타낸다. 예제 file은 size 0이어도 `Blocks: 524288`을 보고한다.

POSIX `stat`의 block count 단위는 512 bytes이므로 최대 file size는 `524288 * 512 B = 256 MB`다. 이는 예제 device의 zone capacity와 정확히 일치한다. Application은 current data length인 `st_size`와 최대 기록 가능량인 `st_blocks * 512`를 구분해야 한다.

출력의 `IO Block: 4096`은 capacity가 아니라 write에 필요한 minimum I/O size를 뜻하며 device physical sector size와 대응한다. Sequential append request는 이 alignment까지 충족해야 device가 요구하는 write granularity를 지킬 수 있다.

stat field 해석
Field예제 값의미
Size0현재 write pointer까지 기록된 byte 수
Blocks524288512B 단위 zone capacity
계산 최대 size524288 × 512B = 256MB추가 가능한 file 최대 경계
IO Block4096Write minimum I/O size·physical sector size
Access0640Format 시 정한 file permission

Zone file에서 size·blocks·IO block이 각각 나타내는 값이다.

Application의 capacity 계산
`stat()` 또는 `fstat()` 호출`st_size`에서 현재 data 길이 확인`st_blocks`에 512B를 곱함Zone capacity와 최대 file size 계산`st_blksize`에서 minimum I/O 기준 확인남은 append 가능량과 alignment 결정

stat 결과에서 현재 길이와 zone 최대 크기를 별도로 얻는다.


    # truncate -s 0 /mnt/seq/0
    # ls -l /mnt/seq/0
    -rw-r----- 1 root root 0 Nov 25 13:49 /mnt/seq/0

Since files are statically mapped to zones on the disk, the number of blocks
of a file as reported by stat() and fstat() indicates the capacity of the file
zone::

    # stat /mnt/seq/0
    File: /mnt/seq/0
    Size: 0                 Blocks: 524288     IO Block: 4096   regular empty file
    Device: 870h/2160d        Inode: 50431       Links: 1
    Access: (0640/-rw-r-----)  Uid: (    0/    root)   Gid: (    0/    root)
    Access: 2019-11-25 13:23:57.048971997 +0900
    Modify: 2019-11-25 13:52:25.553805765 +0900
    Change: 2019-11-25 13:52:25.553805765 +0900
    Birth: -

The number of blocks of the file ("Blocks") in units of 512B blocks gives the
maximum file size of 524288 * 512 B = 256 MB, corresponding to the device zone
capacity in this example. Of note is that the "IO block" field always
indicates the minimum I/O size for writes and corresponds to the device
physical sector size.