0001 .. SPDX-License-Identifier: GPL-2.0
0002
0003 ================================================
0004 ZoneFS - Zone filesystem for Zoned block devices
0005 ================================================
0006
0007 Introduction
0008 ============
0009
0010 zonefs is a very simple file system exposing each zone of a zoned block device
0011 as a file. Unlike a regular POSIX-compliant file system with native zoned block
0012 device support (e.g. f2fs), zonefs does not hide the sequential write
0013 constraint of zoned block devices to the user. Files representing sequential
0014 write zones of the device must be written sequentially starting from the end
0015 of the file (append only writes).
0016
0017 As such, zonefs is in essence closer to a raw block device access interface
0018 than to a full-featured POSIX file system. The goal of zonefs is to simplify
0019 the implementation of zoned block device support in applications by replacing
0020 raw block device file accesses with a richer file API, avoiding relying on
0021 direct block device file ioctls which may be more obscure to developers. One
0022 example of this approach is the implementation of LSM (log-structured merge)
0023 tree structures (such as used in RocksDB and LevelDB) on zoned block devices
0024 by allowing SSTables to be stored in a zone file similarly to a regular file
0025 system rather than as a range of sectors of the entire disk. The introduction
0026 of the higher level construct "one file is one zone" can help reducing the
0027 amount of changes needed in the application as well as introducing support for
0028 different application programming languages.
0029
0030 Zoned block devices
0031 -------------------
0032
0033 Zoned storage devices belong to a class of storage devices with an address
0034 space that is divided into zones. A zone is a group of consecutive LBAs and all
0035 zones are contiguous (there are no LBA gaps). Zones may have different types.
0036
0037 * Conventional zones: there are no access constraints to LBAs belonging to
0038 conventional zones. Any read or write access can be executed, similarly to a
0039 regular block device.
0040 * Sequential zones: these zones accept random reads but must be written
0041 sequentially. Each sequential zone has a write pointer maintained by the
0042 device that keeps track of the mandatory start LBA position of the next write
0043 to the device. As a result of this write constraint, LBAs in a sequential zone
0044 cannot be overwritten. Sequential zones must first be erased using a special
0045 command (zone reset) before rewriting.
0046
0047 Zoned storage devices can be implemented using various recording and media
0048 technologies. The most common form of zoned storage today uses the SCSI Zoned
0049 Block Commands (ZBC) and Zoned ATA Commands (ZAC) interfaces on Shingled
0050 Magnetic Recording (SMR) HDDs.
0051
0052 Solid State Disks (SSD) storage devices can also implement a zoned interface
0053 to, for instance, reduce internal write amplification due to garbage collection.
0054 The NVMe Zoned NameSpace (ZNS) is a technical proposal of the NVMe standard
0055 committee aiming at adding a zoned storage interface to the NVMe protocol.
0056
0057 Zonefs Overview
0058 ===============
0059
0060 Zonefs exposes the zones of a zoned block device as files. The files
0061 representing zones are grouped by zone type, which are themselves represented
0062 by sub-directories. This file structure is built entirely using zone information
0063 provided by the device and so does not require any complex on-disk metadata
0064 structure.
0065
0066 On-disk metadata
0067 ----------------
0068
0069 zonefs on-disk metadata is reduced to an immutable super block which
0070 persistently stores a magic number and optional feature flags and values. On
0071 mount, zonefs uses blkdev_report_zones() to obtain the device zone configuration
0072 and populates the mount point with a static file tree solely based on this
0073 information. File sizes come from the device zone type and write pointer
0074 position managed by the device itself.
0075
0076 The super block is always written on disk at sector 0. The first zone of the
0077 device storing the super block is never exposed as a zone file by zonefs. If
0078 the zone containing the super block is a sequential zone, the mkzonefs format
0079 tool always "finishes" the zone, that is, it transitions the zone to a full
0080 state to make it read-only, preventing any data write.
0081
0082 Zone type sub-directories
0083 -------------------------
0084
0085 Files representing zones of the same type are grouped together under the same
0086 sub-directory automatically created on mount.
0087
0088 For conventional zones, the sub-directory "cnv" is used. This directory is
0089 however created if and only if the device has usable conventional zones. If
0090 the device only has a single conventional zone at sector 0, the zone will not
0091 be exposed as a file as it will be used to store the zonefs super block. For
0092 such devices, the "cnv" sub-directory will not be created.
0093
0094 For sequential write zones, the sub-directory "seq" is used.
0095
0096 These two directories are the only directories that exist in zonefs. Users
0097 cannot create other directories and cannot rename nor delete the "cnv" and
0098 "seq" sub-directories.
0099
0100 The size of the directories indicated by the st_size field of struct stat,
0101 obtained with the stat() or fstat() system calls, indicates the number of files
0102 existing under the directory.
0103
0104 Zone files
0105 ----------
0106
0107 Zone files are named using the number of the zone they represent within the set
0108 of zones of a particular type. That is, both the "cnv" and "seq" directories
0109 contain files named "0", "1", "2", ... The file numbers also represent
0110 increasing zone start sector on the device.
0111
0112 All read and write operations to zone files are not allowed beyond the file
0113 maximum size, that is, beyond the zone capacity. Any access exceeding the zone
0114 capacity is failed with the -EFBIG error.
0115
0116 Creating, deleting, renaming or modifying any attribute of files and
0117 sub-directories is not allowed.
0118
0119 The number of blocks of a file as reported by stat() and fstat() indicates the
0120 capacity of the zone file, or in other words, the maximum file size.
0121
0122 Conventional zone files
0123 -----------------------
0124
0125 The size of conventional zone files is fixed to the size of the zone they
0126 represent. Conventional zone files cannot be truncated.
0127
0128 These files can be randomly read and written using any type of I/O operation:
0129 buffered I/Os, direct I/Os, memory mapped I/Os (mmap), etc. There are no I/O
0130 constraint for these files beyond the file size limit mentioned above.
0131
0132 Sequential zone files
0133 ---------------------
0134
0135 The size of sequential zone files grouped in the "seq" sub-directory represents
0136 the file's zone write pointer position relative to the zone start sector.
0137
0138 Sequential zone files can only be written sequentially, starting from the file
0139 end, that is, write operations can only be append writes. Zonefs makes no
0140 attempt at accepting random writes and will fail any write request that has a
0141 start offset not corresponding to the end of the file, or to the end of the last
0142 write issued and still in-flight (for asynchronous I/O operations).
0143
0144 Since dirty page writeback by the page cache does not guarantee a sequential
0145 write pattern, zonefs prevents buffered writes and writeable shared mappings
0146 on sequential files. Only direct I/O writes are accepted for these files.
0147 zonefs relies on the sequential delivery of write I/O requests to the device
0148 implemented by the block layer elevator. An elevator implementing the sequential
0149 write feature for zoned block device (ELEVATOR_F_ZBD_SEQ_WRITE elevator feature)
0150 must be used. This type of elevator (e.g. mq-deadline) is set by default
0151 for zoned block devices on device initialization.
0152
0153 There are no restrictions on the type of I/O used for read operations in
0154 sequential zone files. Buffered I/Os, direct I/Os and shared read mappings are
0155 all accepted.
0156
0157 Truncating sequential zone files is allowed only down to 0, in which case, the
0158 zone is reset to rewind the file zone write pointer position to the start of
0159 the zone, or up to the zone capacity, in which case the file's zone is
0160 transitioned to the FULL state (finish zone operation).
0161
0162 Format options
0163 --------------
0164
0165 Several optional features of zonefs can be enabled at format time.
0166
0167 * Conventional zone aggregation: ranges of contiguous conventional zones can be
0168 aggregated into a single larger file instead of the default one file per zone.
0169 * File ownership: The owner UID and GID of zone files is by default 0 (root)
0170 but can be changed to any valid UID/GID.
0171 * File access permissions: the default 640 access permissions can be changed.
0172
0173 IO error handling
0174 -----------------
0175
0176 Zoned block devices may fail I/O requests for reasons similar to regular block
0177 devices, e.g. due to bad sectors. However, in addition to such known I/O
0178 failure pattern, the standards governing zoned block devices behavior define
0179 additional conditions that result in I/O errors.
0180
0181 * A zone may transition to the read-only condition (BLK_ZONE_COND_READONLY):
0182 While the data already written in the zone is still readable, the zone can
0183 no longer be written. No user action on the zone (zone management command or
0184 read/write access) can change the zone condition back to a normal read/write
0185 state. While the reasons for the device to transition a zone to read-only
0186 state are not defined by the standards, a typical cause for such transition
0187 would be a defective write head on an HDD (all zones under this head are
0188 changed to read-only).
0189
0190 * A zone may transition to the offline condition (BLK_ZONE_COND_OFFLINE):
0191 An offline zone cannot be read nor written. No user action can transition an
0192 offline zone back to an operational good state. Similarly to zone read-only
0193 transitions, the reasons for a drive to transition a zone to the offline
0194 condition are undefined. A typical cause would be a defective read-write head
0195 on an HDD causing all zones on the platter under the broken head to be
0196 inaccessible.
0197
0198 * Unaligned write errors: These errors result from the host issuing write
0199 requests with a start sector that does not correspond to a zone write pointer
0200 position when the write request is executed by the device. Even though zonefs
0201 enforces sequential file write for sequential zones, unaligned write errors
0202 may still happen in the case of a partial failure of a very large direct I/O
0203 operation split into multiple BIOs/requests or asynchronous I/O operations.
0204 If one of the write request within the set of sequential write requests
0205 issued to the device fails, all write requests queued after it will
0206 become unaligned and fail.
0207
0208 * Delayed write errors: similarly to regular block devices, if the device side
0209 write cache is enabled, write errors may occur in ranges of previously
0210 completed writes when the device write cache is flushed, e.g. on fsync().
0211 Similarly to the previous immediate unaligned write error case, delayed write
0212 errors can propagate through a stream of cached sequential data for a zone
0213 causing all data to be dropped after the sector that caused the error.
0214
0215 All I/O errors detected by zonefs are notified to the user with an error code
0216 return for the system call that triggered or detected the error. The recovery
0217 actions taken by zonefs in response to I/O errors depend on the I/O type (read
0218 vs write) and on the reason for the error (bad sector, unaligned writes or zone
0219 condition change).
0220
0221 * For read I/O errors, zonefs does not execute any particular recovery action,
0222 but only if the file zone is still in a good condition and there is no
0223 inconsistency between the file inode size and its zone write pointer position.
0224 If a problem is detected, I/O error recovery is executed (see below table).
0225
0226 * For write I/O errors, zonefs I/O error recovery is always executed.
0227
0228 * A zone condition change to read-only or offline also always triggers zonefs
0229 I/O error recovery.
0230
0231 Zonefs minimal I/O error recovery may change a file size and file access
0232 permissions.
0233
0234 * File size changes:
0235 Immediate or delayed write errors in a sequential zone file may cause the file
0236 inode size to be inconsistent with the amount of data successfully written in
0237 the file zone. For instance, the partial failure of a multi-BIO large write
0238 operation will cause the zone write pointer to advance partially, even though
0239 the entire write operation will be reported as failed to the user. In such
0240 case, the file inode size must be advanced to reflect the zone write pointer
0241 change and eventually allow the user to restart writing at the end of the
0242 file.
0243 A file size may also be reduced to reflect a delayed write error detected on
0244 fsync(): in this case, the amount of data effectively written in the zone may
0245 be less than originally indicated by the file inode size. After such I/O
0246 error, zonefs always fixes the file inode size to reflect the amount of data
0247 persistently stored in the file zone.
0248
0249 * Access permission changes:
0250 A zone condition change to read-only is indicated with a change in the file
0251 access permissions to render the file read-only. This disables changes to the
0252 file attributes and data modification. For offline zones, all permissions
0253 (read and write) to the file are disabled.
0254
0255 Further action taken by zonefs I/O error recovery can be controlled by the user
0256 with the "errors=xxx" mount option. The table below summarizes the result of
0257 zonefs I/O error processing depending on the mount option and on the zone
0258 conditions::
0259
0260 +--------------+-----------+-----------------------------------------+
0261 | | | Post error state |
0262 | "errors=xxx" | device | access permissions |
0263 | mount | zone | file file device zone |
0264 | option | condition | size read write read write |
0265 +--------------+-----------+-----------------------------------------+
0266 | | good | fixed yes no yes yes |
0267 | remount-ro | read-only | as is yes no yes no |
0268 | (default) | offline | 0 no no no no |
0269 +--------------+-----------+-----------------------------------------+
0270 | | good | fixed yes no yes yes |
0271 | zone-ro | read-only | as is yes no yes no |
0272 | | offline | 0 no no no no |
0273 +--------------+-----------+-----------------------------------------+
0274 | | good | 0 no no yes yes |
0275 | zone-offline | read-only | 0 no no yes no |
0276 | | offline | 0 no no no no |
0277 +--------------+-----------+-----------------------------------------+
0278 | | good | fixed yes yes yes yes |
0279 | repair | read-only | as is yes no yes no |
0280 | | offline | 0 no no no no |
0281 +--------------+-----------+-----------------------------------------+
0282
0283 Further notes:
0284
0285 * The "errors=remount-ro" mount option is the default behavior of zonefs I/O
0286 error processing if no errors mount option is specified.
0287 * With the "errors=remount-ro" mount option, the change of the file access
0288 permissions to read-only applies to all files. The file system is remounted
0289 read-only.
0290 * Access permission and file size changes due to the device transitioning zones
0291 to the offline condition are permanent. Remounting or reformatting the device
0292 with mkfs.zonefs (mkzonefs) will not change back offline zone files to a good
0293 state.
0294 * File access permission changes to read-only due to the device transitioning
0295 zones to the read-only condition are permanent. Remounting or reformatting
0296 the device will not re-enable file write access.
0297 * File access permission changes implied by the remount-ro, zone-ro and
0298 zone-offline mount options are temporary for zones in a good condition.
0299 Unmounting and remounting the file system will restore the previous default
0300 (format time values) access rights to the files affected.
0301 * The repair mount option triggers only the minimal set of I/O error recovery
0302 actions, that is, file size fixes for zones in a good condition. Zones
0303 indicated as being read-only or offline by the device still imply changes to
0304 the zone file access permissions as noted in the table above.
0305
0306 Mount options
0307 -------------
0308
0309 zonefs defines several mount options:
0310 * errors=<behavior>
0311 * explicit-open
0312
0313 "errors=<behavior>" option
0314 ~~~~~~~~~~~~~~~~~~~~~~~~~~
0315
0316 The "errors=<behavior>" option mount option allows the user to specify zonefs
0317 behavior in response to I/O errors, inode size inconsistencies or zone
0318 condition changes. The defined behaviors are as follow:
0319
0320 * remount-ro (default)
0321 * zone-ro
0322 * zone-offline
0323 * repair
0324
0325 The run-time I/O error actions defined for each behavior are detailed in the
0326 previous section. Mount time I/O errors will cause the mount operation to fail.
0327 The handling of read-only zones also differs between mount-time and run-time.
0328 If a read-only zone is found at mount time, the zone is always treated in the
0329 same manner as offline zones, that is, all accesses are disabled and the zone
0330 file size set to 0. This is necessary as the write pointer of read-only zones
0331 is defined as invalib by the ZBC and ZAC standards, making it impossible to
0332 discover the amount of data that has been written to the zone. In the case of a
0333 read-only zone discovered at run-time, as indicated in the previous section.
0334 The size of the zone file is left unchanged from its last updated value.
0335
0336 "explicit-open" option
0337 ~~~~~~~~~~~~~~~~~~~~~~
0338
0339 A zoned block device (e.g. an NVMe Zoned Namespace device) may have limits on
0340 the number of zones that can be active, that is, zones that are in the
0341 implicit open, explicit open or closed conditions. This potential limitation
0342 translates into a risk for applications to see write IO errors due to this
0343 limit being exceeded if the zone of a file is not already active when a write
0344 request is issued by the user.
0345
0346 To avoid these potential errors, the "explicit-open" mount option forces zones
0347 to be made active using an open zone command when a file is opened for writing
0348 for the first time. If the zone open command succeeds, the application is then
0349 guaranteed that write requests can be processed. Conversely, the
0350 "explicit-open" mount option will result in a zone close command being issued
0351 to the device on the last close() of a zone file if the zone is not full nor
0352 empty.
0353
0354 Runtime sysfs attributes
0355 ------------------------
0356
0357 zonefs defines several sysfs attributes for mounted devices. All attributes
0358 are user readable and can be found in the directory /sys/fs/zonefs/<dev>/,
0359 where <dev> is the name of the mounted zoned block device.
0360
0361 The attributes defined are as follows.
0362
0363 * **max_wro_seq_files**: This attribute reports the maximum number of
0364 sequential zone files that can be open for writing. This number corresponds
0365 to the maximum number of explicitly or implicitly open zones that the device
0366 supports. A value of 0 means that the device has no limit and that any zone
0367 (any file) can be open for writing and written at any time, regardless of the
0368 state of other zones. When the *explicit-open* mount option is used, zonefs
0369 will fail any open() system call requesting to open a sequential zone file for
0370 writing when the number of sequential zone files already open for writing has
0371 reached the *max_wro_seq_files* limit.
0372 * **nr_wro_seq_files**: This attribute reports the current number of sequential
0373 zone files open for writing. When the "explicit-open" mount option is used,
0374 this number can never exceed *max_wro_seq_files*. If the *explicit-open*
0375 mount option is not used, the reported number can be greater than
0376 *max_wro_seq_files*. In such case, it is the responsibility of the
0377 application to not write simultaneously more than *max_wro_seq_files*
0378 sequential zone files. Failure to do so can result in write errors.
0379 * **max_active_seq_files**: This attribute reports the maximum number of
0380 sequential zone files that are in an active state, that is, sequential zone
0381 files that are partially writen (not empty nor full) or that have a zone that
0382 is explicitly open (which happens only if the *explicit-open* mount option is
0383 used). This number is always equal to the maximum number of active zones that
0384 the device supports. A value of 0 means that the mounted device has no limit
0385 on the number of sequential zone files that can be active.
0386 * **nr_active_seq_files**: This attributes reports the current number of
0387 sequential zone files that are active. If *max_active_seq_files* is not 0,
0388 then the value of *nr_active_seq_files* can never exceed the value of
0389 *nr_active_seq_files*, regardless of the use of the *explicit-open* mount
0390 option.
0391
0392 Zonefs User Space Tools
0393 =======================
0394
0395 The mkzonefs tool is used to format zoned block devices for use with zonefs.
0396 This tool is available on Github at:
0397
0398 https://github.com/damien-lemoal/zonefs-tools
0399
0400 zonefs-tools also includes a test suite which can be run against any zoned
0401 block device, including null_blk block device created with zoned mode.
0402
0403 Examples
0404 --------
0405
0406 The following formats a 15TB host-managed SMR HDD with 256 MB zones
0407 with the conventional zones aggregation feature enabled::
0408
0409 # mkzonefs -o aggr_cnv /dev/sdX
0410 # mount -t zonefs /dev/sdX /mnt
0411 # ls -l /mnt/
0412 total 0
0413 dr-xr-xr-x 2 root root 1 Nov 25 13:23 cnv
0414 dr-xr-xr-x 2 root root 55356 Nov 25 13:23 seq
0415
0416 The size of the zone files sub-directories indicate the number of files
0417 existing for each type of zones. In this example, there is only one
0418 conventional zone file (all conventional zones are aggregated under a single
0419 file)::
0420
0421 # ls -l /mnt/cnv
0422 total 137101312
0423 -rw-r----- 1 root root 140391743488 Nov 25 13:23 0
0424
0425 This aggregated conventional zone file can be used as a regular file::
0426
0427 # mkfs.ext4 /mnt/cnv/0
0428 # mount -o loop /mnt/cnv/0 /data
0429
0430 The "seq" sub-directory grouping files for sequential write zones has in this
0431 example 55356 zones::
0432
0433 # ls -lv /mnt/seq
0434 total 14511243264
0435 -rw-r----- 1 root root 0 Nov 25 13:23 0
0436 -rw-r----- 1 root root 0 Nov 25 13:23 1
0437 -rw-r----- 1 root root 0 Nov 25 13:23 2
0438 ...
0439 -rw-r----- 1 root root 0 Nov 25 13:23 55354
0440 -rw-r----- 1 root root 0 Nov 25 13:23 55355
0441
0442 For sequential write zone files, the file size changes as data is appended at
0443 the end of the file, similarly to any regular file system::
0444
0445 # dd if=/dev/zero of=/mnt/seq/0 bs=4096 count=1 conv=notrunc oflag=direct
0446 1+0 records in
0447 1+0 records out
0448 4096 bytes (4.1 kB, 4.0 KiB) copied, 0.00044121 s, 9.3 MB/s
0449
0450 # ls -l /mnt/seq/0
0451 -rw-r----- 1 root root 4096 Nov 25 13:23 /mnt/seq/0
0452
0453 The written file can be truncated to the zone size, preventing any further
0454 write operation::
0455
0456 # truncate -s 268435456 /mnt/seq/0
0457 # ls -l /mnt/seq/0
0458 -rw-r----- 1 root root 268435456 Nov 25 13:49 /mnt/seq/0
0459
0460 Truncation to 0 size allows freeing the file zone storage space and restart
0461 append-writes to the file::
0462
0463 # truncate -s 0 /mnt/seq/0
0464 # ls -l /mnt/seq/0
0465 -rw-r----- 1 root root 0 Nov 25 13:49 /mnt/seq/0
0466
0467 Since files are statically mapped to zones on the disk, the number of blocks
0468 of a file as reported by stat() and fstat() indicates the capacity of the file
0469 zone::
0470
0471 # stat /mnt/seq/0
0472 File: /mnt/seq/0
0473 Size: 0 Blocks: 524288 IO Block: 4096 regular empty file
0474 Device: 870h/2160d Inode: 50431 Links: 1
0475 Access: (0640/-rw-r-----) Uid: ( 0/ root) Gid: ( 0/ root)
0476 Access: 2019-11-25 13:23:57.048971997 +0900
0477 Modify: 2019-11-25 13:52:25.553805765 +0900
0478 Change: 2019-11-25 13:52:25.553805765 +0900
0479 Birth: -
0480
0481 The number of blocks of the file ("Blocks") in units of 512B blocks gives the
0482 maximum file size of 524288 * 512 B = 256 MB, corresponding to the device zone
0483 capacity in this example. Of note is that the "IO block" field always
0484 indicates the minimum I/O size for writes and corresponds to the device
0485 physical sector size.