€•ƒ¦Œsphinx.addnodes”Œdocument”“”)”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)”}”(hhh]”(hŒ pending_xref”“”)”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…””}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ2/translations/zh_CN/filesystems/ext4/atomic_writes”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)”}”(hhh]”hŒChinese (Traditional)”…””}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ2/translations/zh_TW/filesystems/ext4/atomic_writes”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒItalian”…””}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ2/translations/it_IT/filesystems/ext4/atomic_writes”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒJapanese”…””}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ2/translations/ja_JP/filesystems/ext4/atomic_writes”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒKorean”…””}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ2/translations/ko_KR/filesystems/ext4/atomic_writes”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒPortuguese (Brazilian)”…””}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ2/translations/pt_BR/filesystems/ext4/atomic_writes”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒSpanish”…””}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ2/translations/sp_SP/filesystems/ext4/atomic_writes”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒcomment”“”)”}”(hŒ SPDX-License-Identifier: GPL-2.0”h]”hŒ SPDX-License-Identifier: GPL-2.0”…””}”hh·sbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1hµhhh²hh³ŒL/var/lib/git/docbuild/linux/Documentation/filesystems/ext4/atomic_writes.rst”h´KubhŒtarget”“”)”}”(hŒ.. _atomic_writes:”h]”h}”(h]”h ]”h"]”h$]”h&]”Œrefid”Œ atomic-writes”uh1hÈh´Khhh²hh³hÇubhŒsection”“”)”}”(hhh]”(hŒtitle”“”)”}”(hŒAtomic Block Writes”h]”hŒAtomic Block Writes”…””}”(hhÝh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÛhhØh²hh³hÇh´Kubh×)”}”(hhh]”(hÜ)”}”(hŒ Introduction”h]”hŒ Introduction”…””}”(hhîh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÛhhëh²hh³hÇh´KubhŒ paragraph”“”)”}”(hX~Atomic (untorn) block writes ensure that either the entire write is committed to disk or none of it is. This prevents "torn writes" during power loss or system crashes. The ext4 filesystem supports atomic writes (only with Direct I/O) on regular files with extents, provided the underlying storage device supports hardware atomic writes. This is supported in the following two ways:”h]”hX‚Atomic (untorn) block writes ensure that either the entire write is committed to disk or none of it is. This prevents “torn writes†during power loss or system crashes. The ext4 filesystem supports atomic writes (only with Direct I/O) on regular files with extents, provided the underlying storage device supports hardware atomic writes. This is supported in the following two ways:”…””}”(hhþh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K hhëh²hubhŒenumerated_list”“”)”}”(hhh]”(hŒ list_item”“”)”}”(hX6**Single-fsblock Atomic Writes**: EXT4 supports atomic write operations with a single filesystem block since v6.13. In this the atomic write unit minimum and maximum sizes are both set to filesystem blocksize. e.g. doing atomic write of 16KB with 16KB filesystem blocksize on 64KB pagesize system is possible. ”h]”hý)”}”(hX5**Single-fsblock Atomic Writes**: EXT4 supports atomic write operations with a single filesystem block since v6.13. In this the atomic write unit minimum and maximum sizes are both set to filesystem blocksize. e.g. doing atomic write of 16KB with 16KB filesystem blocksize on 64KB pagesize system is possible.”h]”(hŒstrong”“”)”}”(hŒ **Single-fsblock Atomic Writes**”h]”hŒSingle-fsblock Atomic Writes”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjubhX: EXT4 supports atomic write operations with a single filesystem block since v6.13. In this the atomic write unit minimum and maximum sizes are both set to filesystem blocksize. e.g. doing atomic write of 16KB with 16KB filesystem blocksize on 64KB pagesize system is possible.”…””}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´Khjubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjh²hh³hÇh´Nubj)”}”(hXR**Multi-fsblock Atomic Writes with Bigalloc**: EXT4 now also supports atomic writes spanning multiple filesystem blocks using a feature known as bigalloc. The atomic write unit's minimum and maximum sizes are determined by the filesystem block size and cluster size, based on the underlying device’s supported atomic write unit limits. ”h]”hý)”}”(hXQ**Multi-fsblock Atomic Writes with Bigalloc**: EXT4 now also supports atomic writes spanning multiple filesystem blocks using a feature known as bigalloc. The atomic write unit's minimum and maximum sizes are determined by the filesystem block size and cluster size, based on the underlying device’s supported atomic write unit limits.”h]”(j)”}”(hŒ-**Multi-fsblock Atomic Writes with Bigalloc**”h]”hŒ)Multi-fsblock Atomic Writes with Bigalloc”…””}”(hjCh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj?ubhX&: EXT4 now also supports atomic writes spanning multiple filesystem blocks using a feature known as bigalloc. The atomic write unit’s minimum and maximum sizes are determined by the filesystem block size and cluster size, based on the underlying device’s supported atomic write unit limits.”…””}”(hj?h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´Khj;ubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjh²hh³hÇh´Nubeh}”(h]”h ]”h"]”h$]”h&]”Œenumtype”Œarabic”Œprefix”hŒsuffix”Œ.”uh1j hhëh²hh³hÇh´Kubeh}”(h]”Œ introduction”ah ]”h"]”Œ introduction”ah$]”h&]”uh1hÖhhØh²hh³hÇh´Kubh×)”}”(hhh]”(hÜ)”}”(hŒ Requirements”h]”hŒ Requirements”…””}”(hjwh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÛhjth²hh³hÇh´Kubhý)”}”(hŒ-Basic requirements for atomic writes in ext4:”h]”hŒ-Basic requirements for atomic writes in ext4:”…””}”(hj…h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K hjth²hubhŒ block_quote”“”)”}”(hXg1. The extents feature must be enabled (default for ext4) 2. The underlying block device must support atomic writes 3. For single-fsblock atomic writes: 1. A filesystem with appropriate block size (up to the page size) 4. For multi-fsblock atomic writes: 1. The bigalloc feature must be enabled 2. The cluster size must be appropriately configured ”h]”j )”}”(hhh]”(j)”}”(hŒ6The extents feature must be enabled (default for ext4)”h]”hý)”}”(hjžh]”hŒ6The extents feature must be enabled (default for ext4)”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K"hjœubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj™ubj)”}”(hŒ6The underlying block device must support atomic writes”h]”hý)”}”(hjµh]”hŒ6The underlying block device must support atomic writes”…””}”(hj·h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K#hj³ubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj™ubj)”}”(hŒdFor single-fsblock atomic writes: 1. A filesystem with appropriate block size (up to the page size)”h]”(hý)”}”(hŒ!For single-fsblock atomic writes:”h]”hŒ!For single-fsblock atomic writes:”…””}”(hjÎh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K$hjÊubj )”}”(hhh]”j)”}”(hŒ>A filesystem with appropriate block size (up to the page size)”h]”hý)”}”(hjáh]”hŒ>A filesystem with appropriate block size (up to the page size)”…””}”(hjãh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K&hjßubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÜubah}”(h]”h ]”h"]”h$]”h&]”jgjhjihjjjkuh1j hjÊubeh}”(h]”h ]”h"]”h$]”h&]”uh1jhj™ubj)”}”(hŒFor multi-fsblock atomic writes: 1. The bigalloc feature must be enabled 2. The cluster size must be appropriately configured ”h]”(hý)”}”(hŒ For multi-fsblock atomic writes:”h]”hŒ For multi-fsblock atomic writes:”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K'hjubj )”}”(hhh]”(j)”}”(hŒ$The bigalloc feature must be enabled”h]”hý)”}”(hjh]”hŒ$The bigalloc feature must be enabled”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K)hjubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjubj)”}”(hŒ2The cluster size must be appropriately configured ”h]”hý)”}”(hŒ1The cluster size must be appropriately configured”h]”hŒ1The cluster size must be appropriately configured”…””}”(hj2h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K*hj.ubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjubeh}”(h]”h ]”h"]”h$]”h&]”jgjhjihjjjkuh1j hjubeh}”(h]”h ]”h"]”h$]”h&]”uh1jhj™ubeh}”(h]”h ]”h"]”h$]”h&]”jgjhjihjjjkuh1j hj•ubah}”(h]”h ]”h"]”h$]”h&]”uh1j“h³hÇh´K"hjth²hubhý)”}”(hŒžNOTE: EXT4 does not support software or COW based atomic write, which means atomic writes on ext4 are only supported if underlying storage device supports it.”h]”hŒžNOTE: EXT4 does not support software or COW based atomic write, which means atomic writes on ext4 are only supported if underlying storage device supports it.”…””}”(hj^h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K,hjth²hubeh}”(h]”Œ requirements”ah ]”h"]”Œ requirements”ah$]”h&]”uh1hÖhhØh²hh³hÇh´Kubh×)”}”(hhh]”(hÜ)”}”(hŒ$Multi-fsblock Implementation Details”h]”hŒ$Multi-fsblock Implementation Details”…””}”(hjwh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÛhjth²hh³hÇh´K1ubhý)”}”(hXThe bigalloc feature changes ext4 to allocate in units of multiple filesystem blocks, also known as clusters. With bigalloc each bit within block bitmap represents a cluster (power of 2 number of blocks) rather than individual filesystem blocks. EXT4 supports multi-fsblock atomic writes with bigalloc, subject to the following constraints. The minimum atomic write size is the larger of the fs block size and the minimum hardware atomic write unit; and the maximum atomic write size is smaller of the bigalloc cluster size and the maximum hardware atomic write unit. Bigalloc ensures that all allocations are aligned to the cluster size, which satisfies the LBA alignment requirements of the hardware device if the start of the partition/logical volume is itself aligned correctly.”h]”hXThe bigalloc feature changes ext4 to allocate in units of multiple filesystem blocks, also known as clusters. With bigalloc each bit within block bitmap represents a cluster (power of 2 number of blocks) rather than individual filesystem blocks. EXT4 supports multi-fsblock atomic writes with bigalloc, subject to the following constraints. The minimum atomic write size is the larger of the fs block size and the minimum hardware atomic write unit; and the maximum atomic write size is smaller of the bigalloc cluster size and the maximum hardware atomic write unit. Bigalloc ensures that all allocations are aligned to the cluster size, which satisfies the LBA alignment requirements of the hardware device if the start of the partition/logical volume is itself aligned correctly.”…””}”(hj…h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K3hjth²hubhý)”}”(hŒDHere is the block allocation strategy in bigalloc for atomic writes:”h]”hŒDHere is the block allocation strategy in bigalloc for atomic writes:”…””}”(hj“h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K?hjth²hubj”)”}”(hXx* For regions with fully mapped extents, no additional work is needed * For append writes, a new mapped extent is allocated * For regions that are entirely holes, unwritten extent is created * For large unwritten extents, the extent gets split into two unwritten extents of appropriate requested size * For mixed mapping regions (combinations of holes, unwritten extents, or mapped extents), ext4_map_blocks() is called in a loop with EXT4_GET_BLOCKS_ZERO flag to convert the region into a single contiguous mapped extent by writing zeroes to it and converting any unwritten extents to written, if found within the range. ”h]”hŒ bullet_list”“”)”}”(hhh]”(j)”}”(hŒCFor regions with fully mapped extents, no additional work is needed”h]”hý)”}”(hj¬h]”hŒCFor regions with fully mapped extents, no additional work is needed”…””}”(hj®h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´KAhjªubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj§ubj)”}”(hŒ3For append writes, a new mapped extent is allocated”h]”hý)”}”(hjÃh]”hŒ3For append writes, a new mapped extent is allocated”…””}”(hjÅh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´KBhjÁubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj§ubj)”}”(hŒ@For regions that are entirely holes, unwritten extent is created”h]”hý)”}”(hjÚh]”hŒ@For regions that are entirely holes, unwritten extent is created”…””}”(hjÜh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´KChjØubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj§ubj)”}”(hŒkFor large unwritten extents, the extent gets split into two unwritten extents of appropriate requested size”h]”hý)”}”(hŒkFor large unwritten extents, the extent gets split into two unwritten extents of appropriate requested size”h]”hŒkFor large unwritten extents, the extent gets split into two unwritten extents of appropriate requested size”…””}”(hjóh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´KDhjïubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj§ubj)”}”(hX?For mixed mapping regions (combinations of holes, unwritten extents, or mapped extents), ext4_map_blocks() is called in a loop with EXT4_GET_BLOCKS_ZERO flag to convert the region into a single contiguous mapped extent by writing zeroes to it and converting any unwritten extents to written, if found within the range. ”h]”hý)”}”(hX>For mixed mapping regions (combinations of holes, unwritten extents, or mapped extents), ext4_map_blocks() is called in a loop with EXT4_GET_BLOCKS_ZERO flag to convert the region into a single contiguous mapped extent by writing zeroes to it and converting any unwritten extents to written, if found within the range.”h]”hX>For mixed mapping regions (combinations of holes, unwritten extents, or mapped extents), ext4_map_blocks() is called in a loop with EXT4_GET_BLOCKS_ZERO flag to convert the region into a single contiguous mapped extent by writing zeroes to it and converting any unwritten extents to written, if found within the range.”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´KFhjubah}”(h]”h ]”h"]”h$]”h&]”uh1jhj§ubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ*”uh1j¥h³hÇh´KAhj¡ubah}”(h]”h ]”h"]”h$]”h&]”uh1j“h³hÇh´KAhjth²hubhý)”}”(hXNote: Writing on a single contiguous underlying extent, whether mapped or unwritten, is not inherently problematic. However, writing to a mixed mapping region (i.e. one containing a combination of mapped and unwritten extents) must be avoided when performing atomic writes.”h]”hXNote: Writing on a single contiguous underlying extent, whether mapped or unwritten, is not inherently problematic. However, writing to a mixed mapping region (i.e. one containing a combination of mapped and unwritten extents) must be avoided when performing atomic writes.”…””}”(hj-h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´KLhjth²hubhý)”}”(hXfThe reason is that, atomic writes when issued via pwritev2() with the RWF_ATOMIC flag, requires that either all data is written or none at all. In the event of a system crash or unexpected power loss during the write operation, the affected region (when later read) must reflect either the complete old data or the complete new data, but never a mix of both.”h]”hXfThe reason is that, atomic writes when issued via pwritev2() with the RWF_ATOMIC flag, requires that either all data is written or none at all. In the event of a system crash or unexpected power loss during the write operation, the affected region (when later read) must reflect either the complete old data or the complete new data, but never a mix of both.”…””}”(hj;h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´KQhjth²hubhý)”}”(hX‡To enforce this guarantee, we ensure that the write target is backed by a single, contiguous extent before any data is written. This is critical because ext4 defers the conversion of unwritten extents to written extents until the I/O completion path (typically in ->end_io()). If a write is allowed to proceed over a mixed mapping region (with mapped and unwritten extents) and a failure occurs mid-write, the system could observe partially updated regions after reboot, i.e. new data over mapped areas, and stale (old) data over unwritten extents that were never marked written. This violates the atomicity and/or torn write prevention guarantee.”h]”hX‡To enforce this guarantee, we ensure that the write target is backed by a single, contiguous extent before any data is written. This is critical because ext4 defers the conversion of unwritten extents to written extents until the I/O completion path (typically in ->end_io()). If a write is allowed to proceed over a mixed mapping region (with mapped and unwritten extents) and a failure occurs mid-write, the system could observe partially updated regions after reboot, i.e. new data over mapped areas, and stale (old) data over unwritten extents that were never marked written. This violates the atomicity and/or torn write prevention guarantee.”…””}”(hjIh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´KWhjth²hubhý)”}”(hXŠTo prevent such torn writes, ext4 proactively allocates a single contiguous extent for the entire requested region in ``ext4_iomap_alloc`` via ``ext4_map_blocks_atomic()``. EXT4 also force commits the current journalling transaction in case if allocation is done over mixed mapping. This ensures any pending metadata updates (like unwritten to written extents conversion) in this range are in consistent state with the file data blocks, before performing the actual write I/O. If the commit fails, the whole I/O must be aborted to prevent from any possible torn writes. Only after this step, the actual data write operation is performed by the iomap.”h]”(hŒvTo prevent such torn writes, ext4 proactively allocates a single contiguous extent for the entire requested region in ”…””}”(hjWh²hh³Nh´NubhŒliteral”“”)”}”(hŒ``ext4_iomap_alloc``”h]”hŒext4_iomap_alloc”…””}”(hjah²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j_hjWubhŒ via ”…””}”(hjWh²hh³Nh´Nubj`)”}”(hŒ``ext4_map_blocks_atomic()``”h]”hŒext4_map_blocks_atomic()”…””}”(hjsh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j_hjWubhXß. EXT4 also force commits the current journalling transaction in case if allocation is done over mixed mapping. This ensures any pending metadata updates (like unwritten to written extents conversion) in this range are in consistent state with the file data blocks, before performing the actual write I/O. If the commit fails, the whole I/O must be aborted to prevent from any possible torn writes. Only after this step, the actual data write operation is performed by the iomap.”…””}”(hjWh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´Kahjth²hubeh}”(h]”Œ$multi-fsblock-implementation-details”ah ]”h"]”Œ$multi-fsblock implementation details”ah$]”h&]”uh1hÖhhØh²hh³hÇh´K1ubh×)”}”(hhh]”(hÜ)”}”(hŒ)Handling Split Extents Across Leaf Blocks”h]”hŒ)Handling Split Extents Across Leaf Blocks”…””}”(hj–h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÛhj“h²hh³hÇh´Klubhý)”}”(hX&There can be a special edge case where we have logically and physically contiguous extents stored in separate leaf nodes of the on-disk extent tree. This occurs because on-disk extent tree merges only happens within the leaf blocks except for a case where we have 2-level tree which can get merged and collapsed entirely into the inode. If such a layout exists and, in the worst case, the extent status cache entries are reclaimed due to memory pressure, ``ext4_map_blocks()`` may never return a single contiguous extent for these split leaf extents.”h]”(hXÇThere can be a special edge case where we have logically and physically contiguous extents stored in separate leaf nodes of the on-disk extent tree. This occurs because on-disk extent tree merges only happens within the leaf blocks except for a case where we have 2-level tree which can get merged and collapsed entirely into the inode. If such a layout exists and, in the worst case, the extent status cache entries are reclaimed due to memory pressure, ”…””}”(hj¤h²hh³Nh´Nubj`)”}”(hŒ``ext4_map_blocks()``”h]”hŒext4_map_blocks()”…””}”(hj¬h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j_hj¤ubhŒJ may never return a single contiguous extent for these split leaf extents.”…””}”(hj¤h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´Knhj“h²hubhý)”}”(hŒŸTo address this edge case, a new get block flag ``EXT4_GET_BLOCKS_QUERY_LEAF_BLOCKS flag`` is added to enhance the ``ext4_map_query_blocks()`` lookup behavior.”h]”(hŒ0To address this edge case, a new get block flag ”…””}”(hjÄh²hh³Nh´Nubj`)”}”(hŒ*``EXT4_GET_BLOCKS_QUERY_LEAF_BLOCKS flag``”h]”hŒ&EXT4_GET_BLOCKS_QUERY_LEAF_BLOCKS flag”…””}”(hjÌh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j_hjÄubhŒ is added to enhance the ”…””}”(hjÄh²hh³Nh´Nubj`)”}”(hŒ``ext4_map_query_blocks()``”h]”hŒext4_map_query_blocks()”…””}”(hjÞh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j_hjÄubhŒ lookup behavior.”…””}”(hjÄh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´Kwhj“h²hubhý)”}”(hXnThis new get block flag allows ``ext4_map_blocks()`` to first check if there is an entry in the extent status cache for the full range. If not present, it consults the on-disk extent tree using ``ext4_map_query_blocks()``. If the located extent is at the end of a leaf node, it probes the next logical block (lblk) to detect a contiguous extent in the adjacent leaf.”h]”(hŒThis new get block flag allows ”…””}”(hjöh²hh³Nh´Nubj`)”}”(hŒ``ext4_map_blocks()``”h]”hŒext4_map_blocks()”…””}”(hjþh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j_hjöubhŒŽ to first check if there is an entry in the extent status cache for the full range. If not present, it consults the on-disk extent tree using ”…””}”(hjöh²hh³Nh´Nubj`)”}”(hŒ``ext4_map_query_blocks()``”h]”hŒext4_map_query_blocks()”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j_hjöubhŒ‘. If the located extent is at the end of a leaf node, it probes the next logical block (lblk) to detect a contiguous extent in the adjacent leaf.”…””}”(hjöh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K{hj“h²hubhý)”}”(hŒ¤For now only one additional leaf block is queried to maintain efficiency, as atomic writes are typically constrained to small sizes (e.g. [blocksize, clustersize]).”h]”hŒ¤For now only one additional leaf block is queried to maintain efficiency, as atomic writes are typically constrained to small sizes (e.g. [blocksize, clustersize]).”…””}”(hj(h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K‚hj“h²hubeh}”(h]”Œ)handling-split-extents-across-leaf-blocks”ah ]”h"]”Œ)handling split extents across leaf blocks”ah$]”h&]”uh1hÖhhØh²hh³hÇh´Klubh×)”}”(hhh]”(hÜ)”}”(hŒHandling Journal transactions”h]”hŒHandling Journal transactions”…””}”(hjAh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÛhj>h²hh³hÇh´Kˆubhý)”}”(hŒ]To support multi-fsblock atomic writes, we ensure enough journal credits are reserved during:”h]”hŒ]To support multi-fsblock atomic writes, we ensure enough journal credits are reserved during:”…””}”(hjOh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´KŠhj>h²hubj”)”}”(hXï1. Block allocation time in ``ext4_iomap_alloc()``. We first query if there could be a mixed mapping for the underlying requested range. If yes, then we reserve credits of up to ``m_len``, assuming every alternate block can be an unwritten extent followed by a hole. 2. During ``->end_io()`` call, we make sure a single transaction is started for doing unwritten-to-written conversion. The loop for conversion is mainly only required to handle a split extent across leaf blocks. ”h]”j )”}”(hhh]”(j)”}”(hXBlock allocation time in ``ext4_iomap_alloc()``. We first query if there could be a mixed mapping for the underlying requested range. If yes, then we reserve credits of up to ``m_len``, assuming every alternate block can be an unwritten extent followed by a hole. ”h]”hý)”}”(hXBlock allocation time in ``ext4_iomap_alloc()``. We first query if there could be a mixed mapping for the underlying requested range. If yes, then we reserve credits of up to ``m_len``, assuming every alternate block can be an unwritten extent followed by a hole.”h]”(hŒBlock allocation time in ”…””}”(hjhh²hh³Nh´Nubj`)”}”(hŒ``ext4_iomap_alloc()``”h]”hŒext4_iomap_alloc()”…””}”(hjph²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j_hjhubhŒ€. We first query if there could be a mixed mapping for the underlying requested range. If yes, then we reserve credits of up to ”…””}”(hjhh²hh³Nh´Nubj`)”}”(hŒ ``m_len``”h]”hŒm_len”…””}”(hj‚h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j_hjhubhŒO, assuming every alternate block can be an unwritten extent followed by a hole.”…””}”(hjhh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´Khjdubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjaubj)”}”(hŒÑDuring ``->end_io()`` call, we make sure a single transaction is started for doing unwritten-to-written conversion. The loop for conversion is mainly only required to handle a split extent across leaf blocks. ”h]”hý)”}”(hŒÐDuring ``->end_io()`` call, we make sure a single transaction is started for doing unwritten-to-written conversion. The loop for conversion is mainly only required to handle a split extent across leaf blocks.”h]”(hŒDuring ”…””}”(hj¤h²hh³Nh´Nubj`)”}”(hŒ``->end_io()``”h]”hŒ ->end_io()”…””}”(hj¬h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j_hj¤ubhŒ» call, we make sure a single transaction is started for doing unwritten-to-written conversion. The loop for conversion is mainly only required to handle a split extent across leaf blocks.”…””}”(hj¤h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K’hj ubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjaubeh}”(h]”h ]”h"]”h$]”h&]”jgjhjihjjjkuh1j hj]ubah}”(h]”h ]”h"]”h$]”h&]”uh1j“h³hÇh´Khj>h²hubeh}”(h]”Œhandling-journal-transactions”ah ]”h"]”Œhandling journal transactions”ah$]”h&]”uh1hÖhhØh²hh³hÇh´Kˆubh×)”}”(hhh]”(hÜ)”}”(hŒHow to”h]”hŒHow to”…””}”(hjáh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÛhjÞh²hh³hÇh´K—ubh×)”}”(hhh]”(hÜ)”}”(hŒ.Creating Filesystems with Atomic Write Support”h]”hŒ.Creating Filesystems with Atomic Write Support”…””}”(hjòh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÛhjïh²hh³hÇh´Kšubhý)”}”(hŒtFirst check the atomic write units supported by block device. See :ref:`atomic_write_bdev_support` for more details.”h]”(hŒBFirst check the atomic write units supported by block device. See ”…””}”(hjh²hh³Nh´Nubh)”}”(hŒ :ref:`atomic_write_bdev_support`”h]”hŒinline”“”)”}”(hj h]”hŒatomic_write_bdev_support”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”(Œxref”Œstd”Œstd-ref”eh"]”h$]”h&]”uh1j hjubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”Œfilesystems/ext4/atomic_writes”Œ refdomain”jŒreftype”Œref”Œ refexplicit”‰Œrefwarn”ˆŒ reftarget”Œatomic_write_bdev_support”uh1hh³hÇh´KœhjubhŒ for more details.”…””}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´Kœhjïh²hubhý)”}”(hŒcFor single-fsblock atomic writes with a larger block size (on systems with block size < page size):”h]”hŒcFor single-fsblock atomic writes with a larger block size (on systems with block size < page size):”…””}”(hj7h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´KŸhjïh²hubhŒ literal_block”“”)”}”(hŒp# Create an ext4 filesystem with a 16KB block size # (requires page size >= 16KB) mkfs.ext4 -b 16384 /dev/device”h]”hŒp# Create an ext4 filesystem with a 16KB block size # (requires page size >= 16KB) mkfs.ext4 -b 16384 /dev/device”…””}”hjGsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆŒforce”‰Œlanguage”Œbash”Œhighlight_args”}”uh1jEh³hÇh´K¢hjïh²hubhý)”}”(hŒ.For multi-fsblock atomic writes with bigalloc:”h]”hŒ.For multi-fsblock atomic writes with bigalloc:”…””}”(hjZh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K¨hjïh²hubjF)”}”(hŒu# Create an ext4 filesystem with bigalloc and 64KB cluster size mkfs.ext4 -F -O bigalloc -b 4096 -C 65536 /dev/device”h]”hŒu# Create an ext4 filesystem with bigalloc and 64KB cluster size mkfs.ext4 -F -O bigalloc -b 4096 -C 65536 /dev/device”…””}”hjhsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆjU‰jVŒbash”jX}”uh1jEh³hÇh´Kªhjïh²hubhý)”}”(hŒ„Where ``-b`` specifies the block size, ``-C`` specifies the cluster size in bytes, and ``-O bigalloc`` enables the bigalloc feature.”h]”(hŒWhere ”…””}”(hjxh²hh³Nh´Nubj`)”}”(hŒ``-b``”h]”hŒ-b”…””}”(hj€h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j_hjxubhŒ specifies the block size, ”…””}”(hjxh²hh³Nh´Nubj`)”}”(hŒ``-C``”h]”hŒ-C”…””}”(hj’h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j_hjxubhŒ* specifies the cluster size in bytes, and ”…””}”(hjxh²hh³Nh´Nubj`)”}”(hŒ``-O bigalloc``”h]”hŒ -O bigalloc”…””}”(hj¤h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j_hjxubhŒ enables the bigalloc feature.”…””}”(hjxh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K¯hjïh²hubeh}”(h]”Œ.creating-filesystems-with-atomic-write-support”ah ]”h"]”Œ.creating filesystems with atomic write support”ah$]”h&]”uh1hÖhjÞh²hh³hÇh´Kšubh×)”}”(hhh]”(hÜ)”}”(hŒApplication Interface”h]”hŒApplication Interface”…””}”(hjÇh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÛhjÄh²hh³hÇh´K³ubhý)”}”(hŒjApplications can use the ``pwritev2()`` system call with the ``RWF_ATOMIC`` flag to perform atomic writes:”h]”(hŒApplications can use the ”…””}”(hjÕh²hh³Nh´Nubj`)”}”(hŒ``pwritev2()``”h]”hŒ pwritev2()”…””}”(hjÝh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j_hjÕubhŒ system call with the ”…””}”(hjÕh²hh³Nh´Nubj`)”}”(hŒ``RWF_ATOMIC``”h]”hŒ RWF_ATOMIC”…””}”(hjïh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j_hjÕubhŒ flag to perform atomic writes:”…””}”(hjÕh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´KµhjÄh²hubjF)”}”(hŒ.pwritev2(fd, iov, iovcnt, offset, RWF_ATOMIC);”h]”hŒ.pwritev2(fd, iov, iovcnt, offset, RWF_ATOMIC);”…””}”hjsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆjU‰jVŒc”jX}”uh1jEh³hÇh´K¸hjÄh²hubhý)”}”(hŒ¯The write must be aligned to the filesystem's block size and not exceed the filesystem's maximum atomic write unit size. See ``generic_atomic_write_valid()`` for more details.”h]”(hŒThe write must be aligned to the filesystem’s block size and not exceed the filesystem’s maximum atomic write unit size. See ”…””}”(hjh²hh³Nh´Nubj`)”}”(hŒ ``generic_atomic_write_valid()``”h]”hŒgeneric_atomic_write_valid()”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j_hjubhŒ for more details.”…””}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´K¼hjÄh²hubhý)”}”(hŒW``statx()`` system call with ``STATX_WRITE_ATOMIC`` flag can provide following details:”h]”(j`)”}”(hŒ ``statx()``”h]”hŒstatx()”…””}”(hj;h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j_hj7ubhŒ system call with ”…””}”(hj7h²hh³Nh´Nubj`)”}”(hŒ``STATX_WRITE_ATOMIC``”h]”hŒSTATX_WRITE_ATOMIC”…””}”(hjMh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j_hj7ubhŒ$ flag can provide following details:”…””}”(hj7h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´KÀhjÄh²hubj”)”}”(hXz* ``stx_atomic_write_unit_min``: Minimum size of an atomic write request. * ``stx_atomic_write_unit_max``: Maximum size of an atomic write request. * ``stx_atomic_write_segments_max``: Upper limit for segments. The number of separate memory buffers that can be gathered into a write operation (e.g., the iovcnt parameter for IOV_ITER). Currently, this is always set to one. ”h]”j¦)”}”(hhh]”(j)”}”(hŒG``stx_atomic_write_unit_min``: Minimum size of an atomic write request.”h]”hý)”}”(hjnh]”(j`)”}”(hŒ``stx_atomic_write_unit_min``”h]”hŒstx_atomic_write_unit_min”…””}”(hjsh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j_hjpubhŒ*: Minimum size of an atomic write request.”…””}”(hjph²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´KÃhjlubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjiubj)”}”(hŒG``stx_atomic_write_unit_max``: Maximum size of an atomic write request.”h]”hý)”}”(hj“h]”(j`)”}”(hŒ``stx_atomic_write_unit_max``”h]”hŒstx_atomic_write_unit_max”…””}”(hj˜h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j_hj•ubhŒ*: Maximum size of an atomic write request.”…””}”(hj•h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´KÄhj‘ubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjiubj)”}”(hŒà``stx_atomic_write_segments_max``: Upper limit for segments. The number of separate memory buffers that can be gathered into a write operation (e.g., the iovcnt parameter for IOV_ITER). Currently, this is always set to one. ”h]”hý)”}”(hŒß``stx_atomic_write_segments_max``: Upper limit for segments. The number of separate memory buffers that can be gathered into a write operation (e.g., the iovcnt parameter for IOV_ITER). Currently, this is always set to one.”h]”(j`)”}”(hŒ!``stx_atomic_write_segments_max``”h]”hŒstx_atomic_write_segments_max”…””}”(hj¾h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j_hjºubhŒ¾: Upper limit for segments. The number of separate memory buffers that can be gathered into a write operation (e.g., the iovcnt parameter for IOV_ITER). Currently, this is always set to one.”…””}”(hjºh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´KÅhj¶ubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjiubeh}”(h]”h ]”h"]”h$]”h&]”j%j&uh1j¥h³hÇh´KÃhjeubah}”(h]”h ]”h"]”h$]”h&]”uh1j“h³hÇh´KÃhjÄh²hubhý)”}”(hŒ`The STATX_ATTR_WRITE_ATOMIC flag in ``statx->attributes`` is set if atomic writes are supported.”h]”(hŒ$The STATX_ATTR_WRITE_ATOMIC flag in ”…””}”(hjèh²hh³Nh´Nubj`)”}”(hŒ``statx->attributes``”h]”hŒstatx->attributes”…””}”(hjðh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j_hjèubhŒ' is set if atomic writes are supported.”…””}”(hjèh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´KÉhjÄh²hubhÉ)”}”(hŒ.. _atomic_write_bdev_support:”h]”h}”(h]”h ]”h"]”h$]”h&]”hÔŒatomic-write-bdev-support”uh1hÈh´KÌhjÄh²hh³hÇubeh}”(h]”Œapplication-interface”ah ]”h"]”Œapplication interface”ah$]”h&]”uh1hÖhjÞh²hh³hÇh´K³ubeh}”(h]”Œhow-to”ah ]”h"]”Œhow to”ah$]”h&]”uh1hÖhhØh²hh³hÇh´K—ubh×)”}”(hhh]”(hÜ)”}”(hŒHardware Support”h]”hŒHardware Support”…””}”(hj&h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÛhj#h²hh³hÇh´KÏubhý)”}”(hŒ¸The underlying storage device must support atomic write operations. Modern NVMe and SCSI devices often provide this capability. The Linux kernel exposes this information through sysfs:”h]”hŒ¸The underlying storage device must support atomic write operations. Modern NVMe and SCSI devices often provide this capability. The Linux kernel exposes this information through sysfs:”…””}”(hj4h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´KÑhj#h²hubj¦)”}”(hhh]”(j)”}”(hŒO``/sys/block//queue/atomic_write_unit_min`` - Minimum atomic write size”h]”hý)”}”(hjGh]”(j`)”}”(hŒ3``/sys/block//queue/atomic_write_unit_min``”h]”hŒ//sys/block//queue/atomic_write_unit_min”…””}”(hjLh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j_hjIubhŒ - Minimum atomic write size”…””}”(hjIh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´KÕhjEubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjBh²hh³hÇh´Nubj)”}”(hŒP``/sys/block//queue/atomic_write_unit_max`` - Maximum atomic write size ”h]”hý)”}”(hŒO``/sys/block//queue/atomic_write_unit_max`` - Maximum atomic write size”h]”(j`)”}”(hŒ3``/sys/block//queue/atomic_write_unit_max``”h]”hŒ//sys/block//queue/atomic_write_unit_max”…””}”(hjrh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j_hjnubhŒ - Maximum atomic write size”…””}”(hjnh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´KÖhjjubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjBh²hh³hÇh´Nubeh}”(h]”h ]”h"]”h$]”h&]”j%j&uh1j¥h³hÇh´KÕhj#h²hubhý)”}”(hŒTNonzero values for these attributes indicate that the device supports atomic writes.”h]”hŒTNonzero values for these attributes indicate that the device supports atomic writes.”…””}”(hj–h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´KØhj#h²hubeh}”(h]”(Œhardware-support”jeh ]”h"]”(Œhardware support”Œatomic_write_bdev_support”eh$]”h&]”uh1hÖhhØh²hh³hÇh´KÏŒexpect_referenced_by_name”}”jªjsŒexpect_referenced_by_id”}”jjsubh×)”}”(hhh]”(hÜ)”}”(hŒSee Also”h]”hŒSee Also”…””}”(hj´h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÛhj±h²hh³hÇh´KÜubj¦)”}”(hhh]”(j)”}”(hŒ7:doc:`bigalloc` - Documentation on the bigalloc feature”h]”hý)”}”(hjÇh]”(h)”}”(hŒ:doc:`bigalloc`”h]”j )”}”(hjÎh]”hŒbigalloc”…””}”(hjÐh²hh³Nh´Nubah}”(h]”h ]”(jŒstd”Œstd-doc”eh"]”h$]”h&]”uh1j hjÌubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”j%Œ refdomain”jÚŒreftype”Œdoc”Œ refexplicit”‰Œrefwarn”ˆj+Œbigalloc”uh1hh³hÇh´KÞhjÉubhŒ( - Documentation on the bigalloc feature”…””}”(hjÉh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´KÞhjÅubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÂh²hh³hÇh´Nubj)”}”(hŒ=:doc:`allocators` - Documentation on block allocation in ext4”h]”hý)”}”(hjþh]”(h)”}”(hŒ:doc:`allocators`”h]”j )”}”(hjh]”hŒ allocators”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”(jŒstd”Œstd-doc”eh"]”h$]”h&]”uh1j hjubah}”(h]”h ]”h"]”h$]”h&]”Œrefdoc”j%Œ refdomain”jŒreftype”Œdoc”Œ refexplicit”‰Œrefwarn”ˆj+Œ allocators”uh1hh³hÇh´KßhjubhŒ, - Documentation on block allocation in ext4”…””}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´Kßhjüubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÂh²hh³hÇh´Nubj)”}”(hŒJSupport for atomic block writes in 6.13: https://lwn.net/Articles/1009298/”h]”hý)”}”(hŒJSupport for atomic block writes in 6.13: https://lwn.net/Articles/1009298/”h]”(hŒ)Support for atomic block writes in 6.13: ”…””}”(hj7h²hh³Nh´NubhŒ reference”“”)”}”(hŒ!https://lwn.net/Articles/1009298/”h]”hŒ!https://lwn.net/Articles/1009298/”…””}”(hjAh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefuri”jCuh1j?hj7ubeh}”(h]”h ]”h"]”h$]”h&]”uh1hüh³hÇh´Kàhj3ubah}”(h]”h ]”h"]”h$]”h&]”uh1jhjÂh²hh³hÇh´Nubeh}”(h]”h ]”h"]”h$]”h&]”j%j&uh1j¥h³hÇh´KÞhj±h²hubeh}”(h]”Œsee-also”ah ]”h"]”Œsee also”ah$]”h&]”uh1hÖhhØh²hh³hÇh´KÜubeh}”(h]”(Œatomic-block-writes”hÕeh ]”h"]”(Œatomic block writes”Œ atomic_writes”eh$]”h&]”uh1hÖhhh²hh³hÇh´Kj­}”jphÊsj¯}”hÕhÊsubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”hÇuh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)”}”(hÛNŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”j˜Œerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”hÇŒ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”Œrefids”}”(hÕ]”hÊaj]”jauŒnameids”}”(jphÕjojljqjnjqjnjjj;j8jÛjØj jjÁj¾jjjªjj©j¦jgjduŒ nametypes”}”(jpˆjo‰jq‰jq‰j‰j;‰jÛ‰j ‰jÁ‰j‰jªˆj©‰jg‰uh}”(hÕhØjlhØjnhëjnjtjjtj8j“jØj>jjÞj¾jïjjÄjj#j¦j#jdj±uŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”…”R”Œparse_messages”]”Œtransform_messages”]”(hŒsystem_message”“”)”}”(hhh]”hý)”}”(hhh]”hŒ3Hyperlink target "atomic-writes" is not referenced.”…””}”hj sbah}”(h]”h ]”h"]”h$]”h&]”uh1hühj ubah}”(h]”h ]”h"]”h$]”h&]”Œlevel”KŒtype”ŒINFO”Œsource”hÇŒline”Kuh1jþubjÿ)”}”(hhh]”hý)”}”(hhh]”hŒ?Hyperlink target "atomic-write-bdev-support" is not referenced.”…””}”hj sbah}”(h]”h ]”h"]”h$]”h&]”uh1hühj ubah}”(h]”h ]”h"]”h$]”h&]”Œlevel”KŒtype”j Œsource”hÇŒline”KÌuh1jþubeŒ transformer”NŒ include_log”]”Œ decoration”Nh²hub.