€• Œ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”Œ0/translations/zh_CN/filesystems/iomap/operations”Œmodname”NŒ classname”NŒrefexplicit”ˆuŒtagname”hhhubh)�”}”(hhh]”hŒChinese (Traditional)”…”�”}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ0/translations/zh_TW/filesystems/iomap/operations”Œmodname”NŒ classname”NŒrefexplicit”ˆuh1hhhubh)�”}”(hhh]”hŒItalian”…”�”}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ0/translations/it_IT/filesystems/iomap/operations”Œmodname”NŒ classname”NŒrefexplicit”ˆuh1hhhubh)�”}”(hhh]”hŒJapanese”…”�”}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ0/translations/ja_JP/filesystems/iomap/operations”Œmodname”NŒ classname”NŒrefexplicit”ˆuh1hhhubh)�”}”(hhh]”hŒKorean”…”�”}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ0/translations/ko_KR/filesystems/iomap/operations”Œmodname”NŒ classname”NŒrefexplicit”ˆuh1hhhubh)�”}”(hhh]”hŒPortuguese (Brazilian)”…”�”}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ0/translations/pt_BR/filesystems/iomap/operations”Œmodname”NŒ classname”NŒrefexplicit”ˆuh1hhhubh)�”}”(hhh]”hŒSpanish”…”�”}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ0/translations/sp_SP/filesystems/iomap/operations”Œmodname”NŒ classname”NŒrefexplicit”ˆuh1hhhubeh}”(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³ŒJ/var/lib/git/docbuild/linux/Documentation/filesystems/iomap/operations.rst”h´KubhŒtarget”“”)�”}”(hŒ.. _iomap_operations:”h]”h}”(h]”Œiomap-operations”ah ]”h"]”Œiomap_operations”ah$]”h&]”uh1hÈh´Khhh²hh³hÇubh¶)�”}”(hŒÈDumb style notes to maintain the author's sanity:
Please try to start sentences on separate lines so that
sentence changes don't bleed colors in diff.
Heading decorations are documented in sphinx.rst.”h]”hŒÈDumb style notes to maintain the author's sanity:
Please try to start sentences on separate lines so that
sentence changes don't bleed colors in diff.
Heading decorations are documented in sphinx.rst.”…”�”}”hhÖsbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆuh1hµhhh²hh³hÇh´K ubhŒsection”“”)�”}”(hhh]”(hŒtitle”“”)�”}”(hŒSupported File Operations”h]”hŒSupported File Operations”…”�”}”(hhëh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1héhhæh²hh³hÇh´KubhŒtopic”“”)�”}”(hŒTable of Contents
”h]”(hê)�”}”(hŒTable of Contents”h]”hŒTable of Contents”…”�”}”(hhÿh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1héhhûh³hÇh´KubhŒbullet_list”“”)�”}”(hhh]”(hŒ list_item”“”)�”}”(hhh]”(hŒ paragraph”“”)�”}”(hhh]”hŒ reference”“”)�”}”(hhh]”hŒBuffered I/O”…”�”}”(hj h²hh³Nh´Nubah}”(h]”Œid1”ah ]”h"]”h$]”h&]”Œrefid”Œbuffered-i-o”uh1j hj ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj ubj )�”}”(hhh]”(j )�”}”(hhh]”j )�”}”(hhh]”j )�”}”(hhh]”hŒliteral”“”)�”}”(hŒ#``struct address_space_operations``”h]”hŒstruct address_space_operations”…”�”}”(hjB h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j@ h³Nh´Nhj= ubah}”(h]”Œid2”ah ]”h"]”h$]”h&]”Œrefid”Œstruct-address-space-operations”uh1j hj: ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj7 ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj4 ubj )�”}”(hhh]”j )�”}”(hhh]”j )�”}”(hhh]”jA )�”}”(hŒ``struct iomap_write_ops``”h]”hŒstruct iomap_write_ops”…”�”}”(hjn h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j@ h³Nh´Nhjk ubah}”(h]”Œid3”ah ]”h"]”h$]”h&]”Œrefid”Œstruct-iomap-write-ops”uh1j hjh ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hje ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj4 ubj )�”}”(hhh]”j )�”}”(hhh]”j )�”}”(hhh]”jA )�”}”(hŒ``struct iomap_read_ops``”h]”hŒstruct iomap_read_ops”…”�”}”(hjš h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j@ h³Nh´Nhj— ubah}”(h]”Œid4”ah ]”h"]”h$]”h&]”Œrefid”Œstruct-iomap-read-ops”uh1j hj” ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj‘ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj4 ubj )�”}”(hhh]”j )�”}”(hhh]”j )�”}”(hhh]”hŒInternal per-Folio State”…”�”}”(hjà h²hh³Nh´Nubah}”(h]”Œid5”ah ]”h"]”h$]”h&]”Œrefid”Œinternal-per-folio-state”uh1j hjÀ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj½ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj4 ubj )�”}”(hhh]”j )�”}”(hhh]”j )�”}”(hhh]”hŒBuffered Readahead and Reads”…”�”}”(hjå h²hh³Nh´Nubah}”(h]”Œid6”ah ]”h"]”h$]”h&]”Œrefid”Œbuffered-readahead-and-reads”uh1j hjâ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjß ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj4 ubj )�”}”(hhh]”(j )�”}”(hhh]”j )�”}”(hhh]”hŒBuffered Writes”…”�”}”(hj h²hh³Nh´Nubah}”(h]”Œid7”ah ]”h"]”h$]”h&]”Œrefid”Œbuffered-writes”uh1j hj ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj ubj )�”}”(hhh]”(j )�”}”(hhh]”j )�”}”(hhh]”j )�”}”(hhh]”hŒmmap Write Faults”…”�”}”(hj& h²hh³Nh´Nubah}”(h]”Œid8”ah ]”h"]”h$]”h&]”Œrefid”Œmmap-write-faults”uh1j hj# ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj ubj )�”}”(hhh]”j )�”}”(hhh]”j )�”}”(hhh]”hŒBuffered Write Failures”…”�”}”(hjH h²hh³Nh´Nubah}”(h]”Œid9”ah ]”h"]”h$]”h&]”Œrefid”Œbuffered-write-failures”uh1j hjE ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjB ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj ubj )�”}”(hhh]”j )�”}”(hhh]”j )�”}”(hhh]”hŒZeroing for File Operations”…”�”}”(hjj h²hh³Nh´Nubah}”(h]”Œid10”ah ]”h"]”h$]”h&]”Œrefid”Œzeroing-for-file-operations”uh1j hjg ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjd ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj ubj )�”}”(hhh]”j )�”}”(hhh]”j )�”}”(hhh]”hŒUnsharing Reflinked File Data”…”�”}”(hjŒ h²hh³Nh´Nubah}”(h]”Œid11”ah ]”h"]”h$]”h&]”Œrefid”Œunsharing-reflinked-file-data”uh1j hj‰ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj† ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j
hj ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j hj4 ubj )�”}”(hhh]”j )�”}”(hhh]”j )�”}”(hhh]”hŒ
Truncation”…”�”}”(hjº h²hh³Nh´Nubah}”(h]”Œid12”ah ]”h"]”h$]”h&]”Œrefid”Œ
truncation”uh1j hj· ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj´ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj4 ubj )�”}”(hhh]”(j )�”}”(hhh]”j )�”}”(hhh]”hŒPagecache Writeback”…”�”}”(hjÜ h²hh³Nh´Nubah}”(h]”Œid13”ah ]”h"]”h$]”h&]”Œrefid”Œpagecache-writeback”uh1j hjÙ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjÖ ubj )�”}”(hhh]”(j )�”}”(hhh]”j )�”}”(hhh]”j )�”}”(hhh]”jA )�”}”(hŒ``struct iomap_writeback_ops``”h]”hŒstruct iomap_writeback_ops”…”�”}”(hjþ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j@ h³Nh´Nhjû ubah}”(h]”Œid14”ah ]”h"]”h$]”h&]”Œrefid”Œstruct-iomap-writeback-ops”uh1j hjø ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjõ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjò ubj )�”}”(hhh]”j )�”}”(hhh]”j )�”}”(hhh]”hŒPagecache Writeback Completion”…”�”}”(hj' h²hh³Nh´Nubah}”(h]”Œid15”ah ]”h"]”h$]”h&]”Œrefid”Œpagecache-writeback-completion”uh1j hj$ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj! ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjò ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j
hjÖ ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j hj4 ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j
hj ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j hj ubj )�”}”(hhh]”(j )�”}”(hhh]”j )�”}”(hhh]”hŒ
Direct I/O”…”�”}”(hja h²hh³Nh´Nubah}”(h]”Œid16”ah ]”h"]”h$]”h&]”Œrefid”Œ
direct-i-o”uh1j hj^ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj[ ubj )�”}”(hhh]”(j )�”}”(hhh]”j )�”}”(hhh]”j )�”}”(hhh]”hŒ
Return Values”…”�”}”(hj€ h²hh³Nh´Nubah}”(h]”Œid17”ah ]”h"]”h$]”h&]”Œrefid”Œ
return-values”uh1j hj} ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjz ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjw ubj )�”}”(hhh]”j )�”}”(hhh]”j )�”}”(hhh]”hŒDirect Reads”…”�”}”(hj¢ h²hh³Nh´Nubah}”(h]”Œid18”ah ]”h"]”h$]”h&]”Œrefid”Œdirect-reads”uh1j hjŸ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjœ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjw ubj )�”}”(hhh]”j )�”}”(hhh]”j )�”}”(hhh]”hŒ
Direct Writes”…”�”}”(hjÄ h²hh³Nh´Nubah}”(h]”Œid19”ah ]”h"]”h$]”h&]”Œrefid”Œ
direct-writes”uh1j hjÁ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj¾ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjw ubj )�”}”(hhh]”j )�”}”(hhh]”j )�”}”(hhh]”jA )�”}”(hŒ``struct iomap_dio_ops:``”h]”hŒstruct iomap_dio_ops:”…”�”}”(hjé h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j@ h³Nh´Nhjæ ubah}”(h]”Œid20”ah ]”h"]”h$]”h&]”Œrefid”Œstruct-iomap-dio-ops”uh1j hjã ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjà ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjw ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j
hj[ ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j hj ubj )�”}”(hhh]”(j )�”}”(hhh]”j )�”}”(hhh]”hŒDAX I/O”…”�”}”(hj h²hh³Nh´Nubah}”(h]”Œid21”ah ]”h"]”h$]”h&]”Œrefid”Œdax-i-o”uh1j hj ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj ubj )�”}”(hhh]”(j )�”}”(hhh]”j )�”}”(hhh]”j )�”}”(hhh]”hŒfsdax Reads”…”�”}”(hj= h²hh³Nh´Nubah}”(h]”Œid22”ah ]”h"]”h$]”h&]”Œrefid”Œfsdax-reads”uh1j hj: ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj7 ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj4 ubj )�”}”(hhh]”(j )�”}”(hhh]”j )�”}”(hhh]”hŒfsdax Writes”…”�”}”(hj_ h²hh³Nh´Nubah}”(h]”Œid23”ah ]”h"]”h$]”h&]”Œrefid”Œfsdax-writes”uh1j hj\ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjY ubj )�”}”(hhh]”j )�”}”(hhh]”j )�”}”(hhh]”j )�”}”(hhh]”hŒfsdax mmap Faults”…”�”}”(hj~ h²hh³Nh´Nubah}”(h]”Œid24”ah ]”h"]”h$]”h&]”Œrefid”Œfsdax-mmap-faults”uh1j hj{ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjx ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hju ubah}”(h]”h ]”h"]”h$]”h&]”uh1j
hjY ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j hj4 ubj )�”}”(hhh]”j )�”}”(hhh]”j )�”}”(hhh]”hŒ*fsdax Truncation, fallocate, and Unsharing”…”�”}”(hj¬ h²hh³Nh´Nubah}”(h]”Œid25”ah ]”h"]”h$]”h&]”Œrefid”Œ(fsdax-truncation-fallocate-and-unsharing”uh1j hj© ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj¦ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj4 ubj )�”}”(hhh]”j )�”}”(hhh]”j )�”}”(hhh]”hŒfsdax Deduplication”…”�”}”(hjÎ h²hh³Nh´Nubah}”(h]”Œid26”ah ]”h"]”h$]”h&]”Œrefid”Œfsdax-deduplication”uh1j hjË ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjÈ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj4 ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j
hj ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j hj ubj )�”}”(hhh]”(j )�”}”(hhh]”j )�”}”(hhh]”hŒ
Seeking Files”…”�”}”(hjü h²hh³Nh´Nubah}”(h]”Œid27”ah ]”h"]”h$]”h&]”Œrefid”Œ
seeking-files”uh1j hjù ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjö ubj )�”}”(hhh]”(j )�”}”(hhh]”j )�”}”(hhh]”j )�”}”(hhh]”hŒ SEEK_DATA”…”�”}”(hj h²hh³Nh´Nubah}”(h]”Œid28”ah ]”h"]”h$]”h&]”Œrefid”Œ seek-data”uh1j hj ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj ubj )�”}”(hhh]”j )�”}”(hhh]”j )�”}”(hhh]”hŒ SEEK_HOLE”…”�”}”(hj= h²hh³Nh´Nubah}”(h]”Œid29”ah ]”h"]”h$]”h&]”Œrefid”Œ seek-hole”uh1j hj: ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj7 ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j
hjö ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j hj ubj )�”}”(hhh]”j )�”}”(hhh]”j )�”}”(hhh]”hŒSwap File Activation”…”�”}”(hjk h²hh³Nh´Nubah}”(h]”Œid30”ah ]”h"]”h$]”h&]”Œrefid”Œswap-file-activation”uh1j hjh ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hje ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj ubj )�”}”(hhh]”(j )�”}”(hhh]”j )�”}”(hhh]”hŒFile Space Mapping Reporting”…”�”}”(hj� h²hh³Nh´Nubah}”(h]”Œid31”ah ]”h"]”h$]”h&]”Œrefid”Œfile-space-mapping-reporting”uh1j hjŠ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj‡ ubj )�”}”(hhh]”(j )�”}”(hhh]”j )�”}”(hhh]”j )�”}”(hhh]”hŒ
FS_IOC_FIEMAP”…”�”}”(hj¬ h²hh³Nh´Nubah}”(h]”Œid32”ah ]”h"]”h$]”h&]”Œrefid”Œ
fs-ioc-fiemap”uh1j hj© ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj¦ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj£ ubj )�”}”(hhh]”j )�”}”(hhh]”j )�”}”(hhh]”hŒFIBMAP (deprecated)”…”�”}”(hjÎ h²hh³Nh´Nubah}”(h]”Œid33”ah ]”h"]”h$]”h&]”Œrefid”Œfibmap-deprecated”uh1j hjË ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hjÈ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj£ ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j
hj‡ ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j hj ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j
hhûh²hh³Nh´Nubeh}”(h]”Œtable-of-contents”ah ]”(Œcontents”Œlocal”eh"]”Œtable of contents”ah$]”h&]”uh1hùh³hÇh´Khhæh²hubj )�”}”(hŒOBelow are a discussion of the high level file operations that iomap
implements.”h]”hŒOBelow are a discussion of the high level file operations that iomap
implements.”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j h³hÇh´Khhæh²hubhå)�”}”(hhh]”(hê)�”}”(hŒBuffered I/O”h]”hŒBuffered I/O”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œrefid”j' uh1héhj h²hh³hÇh´Kubj )�”}”(hŒçBuffered I/O is the default file I/O path in Linux.
File contents are cached in memory ("pagecache") to satisfy reads and
writes.
Dirty cache will be written back to disk at some point that can be
forced via ``fsync`` and variants.”h]”(hŒÔBuffered I/O is the default file I/O path in Linux.
File contents are cached in memory (“pagecache�) to satisfy reads and
writes.
Dirty cache will be written back to disk at some point that can be
forced via ”…”�”}”(hj& h²hh³Nh´NubjA )�”}”(hŒ ``fsync``”h]”hŒfsync”…”�”}”(hj. h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j@ hj& ubhŒ and variants.”…”�”}”(hj& h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1j h³hÇh´Khj h²hubj )�”}”(hX\ iomap implements nearly all the folio and pagecache management that
filesystems have to implement themselves under the legacy I/O model.
This means that the filesystem need not know the details of allocating,
mapping, managing uptodate and dirty state, or writeback of pagecache
folios.
Under the legacy I/O model, this was managed very inefficiently with
linked lists of buffer heads instead of the per-folio bitmaps that iomap
uses.
Unless the filesystem explicitly opts in to buffer heads, they will not
be used, which makes buffered I/O much more efficient, and the pagecache
maintainer much happier.”h]”hX\ iomap implements nearly all the folio and pagecache management that
filesystems have to implement themselves under the legacy I/O model.
This means that the filesystem need not know the details of allocating,
mapping, managing uptodate and dirty state, or writeback of pagecache
folios.
Under the legacy I/O model, this was managed very inefficiently with
linked lists of buffer heads instead of the per-folio bitmaps that iomap
uses.
Unless the filesystem explicitly opts in to buffer heads, they will not
be used, which makes buffered I/O much more efficient, and the pagecache
maintainer much happier.”…”�”}”(hjF h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j h³hÇh´Khj h²hubhå)�”}”(hhh]”(hê)�”}”(hjD h]”jA )�”}”(hjD h]”hŒstruct address_space_operations”…”�”}”(hjZ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j@ hjW ubah}”(h]”h ]”h"]”h$]”h&]”j% jR uh1héhjT h²hh³hÇh´K*ubj )�”}”(hŒeThe following iomap functions can be referenced directly from the
address space operations structure:”h]”hŒeThe following iomap functions can be referenced directly from the
address space operations structure:”…”�”}”(hjm h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j h³hÇh´K,hjT h²hubhŒblock_quote”“”)�”}”(hŒq* ``iomap_dirty_folio``
* ``iomap_release_folio``
* ``iomap_invalidate_folio``
* ``iomap_is_partially_uptodate``
”h]”j )�”}”(hhh]”(j )�”}”(hŒ``iomap_dirty_folio``”h]”j )�”}”(hj† h]”jA )�”}”(hj† h]”hŒiomap_dirty_folio”…”�”}”(hj‹ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j@ hjˆ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j h³hÇh´K/hj„ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj� ubj )�”}”(hŒ``iomap_release_folio``”h]”j )�”}”(hj¦ h]”jA )�”}”(hj¦ h]”hŒiomap_release_folio”…”�”}”(hj« h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j@ hj¨ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j h³hÇh´K0hj¤ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj� ubj )�”}”(hŒ``iomap_invalidate_folio``”h]”j )�”}”(hjÆ h]”jA )�”}”(hjÆ h]”hŒiomap_invalidate_folio”…”�”}”(hjË h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j@ hjÈ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j h³hÇh´K1hjÄ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj� ubj )�”}”(hŒ ``iomap_is_partially_uptodate``
”h]”j )�”}”(hŒ``iomap_is_partially_uptodate``”h]”jA )�”}”(hjê h]”hŒiomap_is_partially_uptodate”…”�”}”(hjì h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j@ hjè ubah}”(h]”h ]”h"]”h$]”h&]”uh1j h³hÇh´K2hjä ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj� ubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ*”uh1j
h³hÇh´K/hj} ubah}”(h]”h ]”h"]”h$]”h&]”uh1j{ h³hÇh´K/hjT h²hubj )�”}”(hŒ=The following address space operations can be wrapped easily:”h]”hŒ=The following address space operations can be wrapped easily:”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j h³hÇh´K4hjT h²hubj| )�”}”(hŒQ* ``read_folio``
* ``readahead``
* ``writepages``
* ``bmap``
* ``swap_activate``
”h]”j )�”}”(hhh]”(j )�”}”(hŒ``read_folio``”h]”j )�”}”(hj* h]”jA )�”}”(hj* h]”hŒ
read_folio”…”�”}”(hj/ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j@ hj, ubah}”(h]”h ]”h"]”h$]”h&]”uh1j h³hÇh´K6hj( ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj% ubj )�”}”(hŒ
``readahead``”h]”j )�”}”(hjJ h]”jA )�”}”(hjJ h]”hŒ readahead”…”�”}”(hjO h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j@ hjL ubah}”(h]”h ]”h"]”h$]”h&]”uh1j h³hÇh´K7hjH ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj% ubj )�”}”(hŒ``writepages``”h]”j )�”}”(hjj h]”jA )�”}”(hjj h]”hŒ
writepages”…”�”}”(hjo h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j@ hjl ubah}”(h]”h ]”h"]”h$]”h&]”uh1j h³hÇh´K8hjh ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj% ubj )�”}”(hŒ``bmap``”h]”j )�”}”(hjŠ h]”jA )�”}”(hjŠ h]”hŒbmap”…”�”}”(hj� h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j@ hjŒ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j h³hÇh´K9hjˆ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj% ubj )�”}”(hŒ``swap_activate``
”h]”j )�”}”(hŒ``swap_activate``”h]”jA )�”}”(hj® h]”hŒ
swap_activate”…”�”}”(hj° h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j@ hj¬ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j h³hÇh´K:hj¨ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj% ubeh}”(h]”h ]”h"]”h$]”h&]”j j uh1j
h³hÇh´K6hj! ubah}”(h]”h ]”h"]”h$]”h&]”uh1j{ h³hÇh´K6hjT h²hubeh}”(h]”jX ah ]”h"]”Œstruct address_space_operations”ah$]”h&]”uh1hähj h²hh³hÇh´K*ubhå)�”}”(hhh]”(hê)�”}”(hjp h]”jA )�”}”(hjp h]”hŒstruct iomap_write_ops”…”�”}”(hjâ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j@ hjß ubah}”(h]”h ]”h"]”h$]”h&]”j% j~ uh1héhjÜ h²hh³hÇh´K=ubhŒ
literal_block”“”)�”}”(hXÊ struct iomap_write_ops {
struct folio *(*get_folio)(struct iomap_iter *iter, loff_t pos,
unsigned len);
void (*put_folio)(struct inode *inode, loff_t pos, unsigned copied,
struct folio *folio);
bool (*iomap_valid)(struct inode *inode, const struct iomap *iomap);
int (*read_folio_range)(const struct iomap_iter *iter,
struct folio *folio, loff_t pos, size_t len);
};”h]”hXÊ struct iomap_write_ops {
struct folio *(*get_folio)(struct iomap_iter *iter, loff_t pos,
unsigned len);
void (*put_folio)(struct inode *inode, loff_t pos, unsigned copied,
struct folio *folio);
bool (*iomap_valid)(struct inode *inode, const struct iomap *iomap);
int (*read_folio_range)(const struct iomap_iter *iter,
struct folio *folio, loff_t pos, size_t len);
};”…”�”}”hj÷ sbah}”(h]”h ]”h"]”h$]”h&]”hÅhÆŒforce”‰Œlanguage”Œc”Œhighlight_args”}”uh1jõ h³hÇh´K?hjÜ h²hubj )�”}”(hŒiomap calls these functions:”h]”hŒiomap calls these functions:”…”�”}”(hj
h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j h³hÇh´KKhjÜ h²hubj| )�”}”(hXŸ
- ``get_folio``: Called to allocate and return an active reference to
a locked folio prior to starting a write.
If this function is not provided, iomap will call
``iomap_get_folio``.
This could be used to `set up per-folio filesystem state
`_
for a write.
- ``put_folio``: Called to unlock and put a folio after a pagecache
operation completes.
If this function is not provided, iomap will ``folio_unlock`` and
``folio_put`` on its own.
This could be used to `commit per-folio filesystem state
`_
that was set up by ``->get_folio``.
- ``iomap_valid``: The filesystem may not hold locks between
``->iomap_begin`` and ``->iomap_end`` because pagecache operations
can take folio locks, fault on userspace pages, initiate writeback
for memory reclamation, or engage in other time-consuming actions.
If a file's space mapping data are mutable, it is possible that the
mapping for a particular pagecache folio can `change in the time it
takes
`_
to allocate, install, and lock that folio.
For the pagecache, races can happen if writeback doesn't take
``i_rwsem`` or ``invalidate_lock`` and updates mapping information.
Races can also happen if the filesystem allows concurrent writes.
For such files, the mapping *must* be revalidated after the folio
lock has been taken so that iomap can manage the folio correctly.
fsdax does not need this revalidation because there's no writeback
and no support for unwritten extents.
Filesystems subject to this kind of race must provide a
``->iomap_valid`` function to decide if the mapping is still valid.
If the mapping is not valid, the mapping will be sampled again.
To support making the validity decision, the filesystem's
``->iomap_begin`` function may set ``struct iomap::validity_cookie``
at the same time that it populates the other iomap fields.
A simple validation cookie implementation is a sequence counter.
If the filesystem bumps the sequence counter every time it modifies
the inode's extent map, it can be placed in the ``struct
iomap::validity_cookie`` during ``->iomap_begin``.
If the value in the cookie is found to be different to the value
the filesystem holds when the mapping is passed back to
``->iomap_valid``, then the iomap should considered stale and the
validation failed.
- ``read_folio_range``: Called to synchronously read in the range that will
be written to. If this function is not provided, iomap will default to
submitting a bio read request.
”h]”j )�”}”(hhh]”(j )�”}”(hXG ``get_folio``: Called to allocate and return an active reference to
a locked folio prior to starting a write.
If this function is not provided, iomap will call
``iomap_get_folio``.
This could be used to `set up per-folio filesystem state
`_
for a write.
”h]”j )�”}”(hXF ``get_folio``: Called to allocate and return an active reference to
a locked folio prior to starting a write.
If this function is not provided, iomap will call
``iomap_get_folio``.
This could be used to `set up per-folio filesystem state
`_
for a write.”h]”(jA )�”}”(hŒ
``get_folio``”h]”hŒ get_folio”…”�”}”(hj' h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j@ hj# ubhŒ“: Called to allocate and return an active reference to
a locked folio prior to starting a write.
If this function is not provided, iomap will call
”…”�”}”(hj# h²hh³Nh´NubjA )�”}”(hŒ``iomap_get_folio``”h]”hŒiomap_get_folio”…”�”}”(hj9 h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j@ hj# ubhŒ.
This could be used to ”…”�”}”(hj# h²hh³Nh´Nubj )�”}”(hŒn`set up per-folio filesystem state
`_”h]”hŒ!set up per-folio filesystem state”…”�”}”(hjK h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œname”Œ!set up per-folio filesystem state”Œrefuri”ŒGhttps://lore.kernel.org/all/20190429220934.10415-5-agruenba@redhat.com/”uh1j hj# ubhÉ)�”}”(hŒJ
”h]”h}”(h]”Œ!set-up-per-folio-filesystem-state”ah ]”h"]”Œ!set up per-folio filesystem state”ah$]”h&]”Œrefuri”j\ uh1hÈŒ
referenced”Khj# ubhŒ
for a write.”…”�”}”(hj# h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1j h³hÇh´KMhj ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj ubj )�”}”(hXS ``put_folio``: Called to unlock and put a folio after a pagecache
operation completes.
If this function is not provided, iomap will ``folio_unlock`` and
``folio_put`` on its own.
This could be used to `commit per-folio filesystem state
`_
that was set up by ``->get_folio``.
”h]”j )�”}”(hXR ``put_folio``: Called to unlock and put a folio after a pagecache
operation completes.
If this function is not provided, iomap will ``folio_unlock`` and
``folio_put`` on its own.
This could be used to `commit per-folio filesystem state
`_
that was set up by ``->get_folio``.”h]”(jA )�”}”(hŒ
``put_folio``”h]”hŒ put_folio”…”�”}”(hjƒ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j@ hj ubhŒw: Called to unlock and put a folio after a pagecache
operation completes.
If this function is not provided, iomap will ”…”�”}”(hj h²hh³Nh´NubjA )�”}”(hŒ``folio_unlock``”h]”hŒfolio_unlock”…”�”}”(hj• h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j@ hj ubhŒ and
”…”�”}”(hj h²hh³Nh´NubjA )�”}”(hŒ
``folio_put``”h]”hŒ folio_put”…”�”}”(hj§ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j@ hj ubhŒ# on its own.
This could be used to ”…”�”}”(hj h²hh³Nh´Nubj )�”}”(hŒe`commit per-folio filesystem state
`_”h]”hŒ!commit per-folio filesystem state”…”�”}”(hj¹ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œname”Œ!commit per-folio filesystem state”j[ Œ>https://lore.kernel.org/all/20180619164137.13720-6-hch@lst.de/”uh1j hj ubhÉ)�”}”(hŒA
”h]”h}”(h]”Œ!commit-per-folio-filesystem-state”ah ]”h"]”Œ!commit per-folio filesystem state”ah$]”h&]”Œrefuri”jÉ uh1hÈjj Khj ubhŒ
that was set up by ”…”�”}”(hj h²hh³Nh´NubjA )�”}”(hŒ``->get_folio``”h]”hŒ->get_folio”…”�”}”(hjÛ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j@ hj ubhŒ.”…”�”}”(hj h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1j h³hÇh´KUhj{ ubah}”(h]”h ]”h"]”h$]”h&]”uh1j hj ubj )�”}”(hXô ``iomap_valid``: The filesystem may not hold locks between
``->iomap_begin`` and ``->iomap_end`` because pagecache operations
can take folio locks, fault on userspace pages, initiate writeback
for memory reclamation, or engage in other time-consuming actions.
If a file's space mapping data are mutable, it is possible that the
mapping for a particular pagecache folio can `change in the time it
takes
`_
to allocate, install, and lock that folio.
For the pagecache, races can happen if writeback doesn't take
``i_rwsem`` or ``invalidate_lock`` and updates mapping information.
Races can also happen if the filesystem allows concurrent writes.
For such files, the mapping *must* be revalidated after the folio
lock has been taken so that iomap can manage the folio correctly.
fsdax does not need this revalidation because there's no writeback
and no support for unwritten extents.
Filesystems subject to this kind of race must provide a
``->iomap_valid`` function to decide if the mapping is still valid.
If the mapping is not valid, the mapping will be sampled again.
To support making the validity decision, the filesystem's
``->iomap_begin`` function may set ``struct iomap::validity_cookie``
at the same time that it populates the other iomap fields.
A simple validation cookie implementation is a sequence counter.
If the filesystem bumps the sequence counter every time it modifies
the inode's extent map, it can be placed in the ``struct
iomap::validity_cookie`` during ``->iomap_begin``.
If the value in the cookie is found to be different to the value
the filesystem holds when the mapping is passed back to
``->iomap_valid``, then the iomap should considered stale and the
validation failed.
”h]”(j )�”}”(hX ``iomap_valid``: The filesystem may not hold locks between
``->iomap_begin`` and ``->iomap_end`` because pagecache operations
can take folio locks, fault on userspace pages, initiate writeback
for memory reclamation, or engage in other time-consuming actions.
If a file's space mapping data are mutable, it is possible that the
mapping for a particular pagecache folio can `change in the time it
takes
`_
to allocate, install, and lock that folio.”h]”(jA )�”}”(hŒ``iomap_valid``”h]”hŒiomap_valid”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j@ hjý ubhŒ,: The filesystem may not hold locks between
”…”�”}”(hjý h²hh³Nh´NubjA )�”}”(hŒ``->iomap_begin``”h]”hŒ
->iomap_begin”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j@ hjý ubhŒ and ”…”�”}”(hjý h²hh³Nh´NubjA )�”}”(hŒ``->iomap_end``”h]”hŒ->iomap_end”…”�”}”(hj% h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j@ hjý ubhX because pagecache operations
can take folio locks, fault on userspace pages, initiate writeback
for memory reclamation, or engage in other time-consuming actions.
If a file’s space mapping data are mutable, it is possible that the
mapping for a particular pagecache folio can ”…”�”}”(hjý h²hh³Nh´Nubj )�”}”(hŒi`change in the time it
takes
`_”h]”hŒchange in the time it
takes”…”�”}”(hj7 h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”Œname”Œchange in the time it takes”j[ ŒHhttps://lore.kernel.org/all/20221123055812.747923-8-david@fromorbit.com/”uh1j hjý ubhÉ)�”}”(hŒK
”h]”h}”(h]”Œchange-in-the-time-it-takes”ah ]”h"]”Œchange in the time it takes”ah$]”h&]”Œrefuri”jG uh1hÈjj Khjý ubhŒ+
to allocate, install, and lock that folio.”…”�”}”(hjý h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1j h³hÇh´K]hjù ubj )�”}”(hXG For the pagecache, races can happen if writeback doesn't take
``i_rwsem`` or ``invalidate_lock`` and updates mapping information.
Races can also happen if the filesystem allows concurrent writes.
For such files, the mapping *must* be revalidated after the folio
lock has been taken so that iomap can manage the folio correctly.”h]”(hŒ@For the pagecache, races can happen if writeback doesn’t take
”…”�”}”(hj_ h²hh³Nh´NubjA )�”}”(hŒ``i_rwsem``”h]”hŒi_rwsem”…”�”}”(hjg h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j@ hj_ ubhŒ or ”…”�”}”(hj_ h²hh³Nh´NubjA )�”}”(hŒ``invalidate_lock``”h]”hŒinvalidate_lock”…”�”}”(hjy h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j@ hj_ ubhŒ€ and updates mapping information.
Races can also happen if the filesystem allows concurrent writes.
For such files, the mapping ”…”�”}”(hj_ h²hh³Nh´NubhŒemphasis”“”)�”}”(hŒ*must*”h]”hŒmust”…”�”}”(hj� h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j‹ hj_ ubhŒa be revalidated after the folio
lock has been taken so that iomap can manage the folio correctly.”…”�”}”(hj_ h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1j h³hÇh´Kghjù ubj )�”}”(hŒhfsdax does not need this revalidation because there's no writeback
and no support for unwritten extents.”h]”hŒjfsdax does not need this revalidation because there’s no writeback
and no support for unwritten extents.”…”�”}”(hj¥ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j h³hÇh´Kmhjù ubj )�”}”(hŒ»Filesystems subject to this kind of race must provide a
``->iomap_valid`` function to decide if the mapping is still valid.
If the mapping is not valid, the mapping will be sampled again.”h]”(hŒ8Filesystems subject to this kind of race must provide a
”…”�”}”(hj³ h²hh³Nh´NubjA )�”}”(hŒ``->iomap_valid``”h]”hŒ
->iomap_valid”…”�”}”(hj» h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j@ hj³ ubhŒr function to decide if the mapping is still valid.
If the mapping is not valid, the mapping will be sampled again.”…”�”}”(hj³ h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1j h³hÇh´Kphjù ubj )�”}”(hXx To support making the validity decision, the filesystem's
``->iomap_begin`` function may set ``struct iomap::validity_cookie``
at the same time that it populates the other iomap fields.
A simple validation cookie implementation is a sequence counter.
If the filesystem bumps the sequence counter every time it modifies
the inode's extent map, it can be placed in the ``struct
iomap::validity_cookie`` during ``->iomap_begin``.
If the value in the cookie is found to be different to the value
the filesystem holds when the mapping is passed back to
``->iomap_valid``, then the iomap should considered stale and the
validation failed.”h]”(hŒ