€•CŒ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”Œ4/translations/zh_CN/filesystems/bcachefs/casefolding”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)”}”(hhh]”hŒChinese (Traditional)”…””}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ4/translations/zh_TW/filesystems/bcachefs/casefolding”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒItalian”…””}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ4/translations/it_IT/filesystems/bcachefs/casefolding”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒJapanese”…””}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ4/translations/ja_JP/filesystems/bcachefs/casefolding”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒKorean”…””}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ4/translations/ko_KR/filesystems/bcachefs/casefolding”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒSpanish”…””}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ4/translations/sp_SP/filesystems/bcachefs/casefolding”Œ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ŸŒN/var/lib/git/docbuild/linux/Documentation/filesystems/bcachefs/casefolding.rst”h KubhŒsection”“”)”}”(hhh]”(hŒtitle”“”)”}”(hŒ Casefolding”h]”hŒ Casefolding”…””}”(hh»hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¹hh¶hžhhŸh³h KubhŒ paragraph”“”)”}”(hŒ›bcachefs has support for case-insensitive file and directory lookups using the regular `chattr +F` (`S_CASEFOLD`, `FS_CASEFOLD_FL`) casefolding attributes.”h]”(hŒWbcachefs has support for case-insensitive file and directory lookups using the regular ”…””}”(hhËhžhhŸNh NubhŒtitle_reference”“”)”}”(hŒ `chattr +F`”h]”hŒ chattr +F”…””}”(hhÕhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÓhhËubhŒ (”…””}”(hhËhžhhŸNh NubhÔ)”}”(hŒ `S_CASEFOLD`”h]”hŒ S_CASEFOLD”…””}”(hhçhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÓhhËubhŒ, ”…””}”(hhËhžhhŸNh NubhÔ)”}”(hŒ`FS_CASEFOLD_FL`”h]”hŒFS_CASEFOLD_FL”…””}”(hhùhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÓhhËubhŒ) casefolding attributes.”…””}”(hhËhžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h Khh¶hžhubhÊ)”}”(hXThe main usecase for casefolding is compatibility with software written against other filesystems that rely on casefolded lookups (eg. NTFS and Wine/Proton). Taking advantage of file-system level casefolding can lead to great loading time gains in many applications and games.”h]”hXThe main usecase for casefolding is compatibility with software written against other filesystems that rely on casefolded lookups (eg. NTFS and Wine/Proton). Taking advantage of file-system level casefolding can lead to great loading time gains in many applications and games.”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h K hh¶hžhubhÊ)”}”(hXgCasefolding support requires a kernel with the `CONFIG_UNICODE` enabled. Once a directory has been flagged for casefolding, a feature bit is enabled on the superblock which marks the filesystem as using casefolding. When the feature bit for casefolding is enabled, it is no longer possible to mount that filesystem on kernels without `CONFIG_UNICODE` enabled.”h]”(hŒ/Casefolding support requires a kernel with the ”…””}”(hjhžhhŸNh NubhÔ)”}”(hŒ`CONFIG_UNICODE`”h]”hŒCONFIG_UNICODE”…””}”(hj'hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÓhjubhX enabled. Once a directory has been flagged for casefolding, a feature bit is enabled on the superblock which marks the filesystem as using casefolding. When the feature bit for casefolding is enabled, it is no longer possible to mount that filesystem on kernels without ”…””}”(hjhžhhŸNh NubhÔ)”}”(hŒ`CONFIG_UNICODE`”h]”hŒCONFIG_UNICODE”…””}”(hj9hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÓhjubhŒ enabled.”…””}”(hjhžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h Khh¶hžhubhÊ)”}”(hŒ©On the lookup/query side: casefolding is implemented by allocating a new string of `BCH_NAME_MAX` length using the `utf8_casefold` function to casefold the query string.”h]”(hŒSOn the lookup/query side: casefolding is implemented by allocating a new string of ”…””}”(hjQhžhhŸNh NubhÔ)”}”(hŒ`BCH_NAME_MAX`”h]”hŒ BCH_NAME_MAX”…””}”(hjYhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÓhjQubhŒ length using the ”…””}”(hjQhžhhŸNh NubhÔ)”}”(hŒ`utf8_casefold`”h]”hŒ utf8_casefold”…””}”(hjkhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÓhjQubhŒ' function to casefold the query string.”…””}”(hjQhžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h Khh¶hžhubhÊ)”}”(hŒ»On the dirent side: casefolding is implemented by ensuring the `bkey`'s hash is made from the casefolded string and storing the cached casefolded name with the regular name in the dirent.”h]”(hŒ?On the dirent side: casefolding is implemented by ensuring the ”…””}”(hjƒhžhhŸNh NubhÔ)”}”(hŒ`bkey`”h]”hŒbkey”…””}”(hj‹hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÓhjƒubhŒx’s hash is made from the casefolded string and storing the cached casefolded name with the regular name in the dirent.”…””}”(hjƒhžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h Khh¶hžhubhÊ)”}”(hŒThe structure looks like this:”h]”hŒThe structure looks like this:”…””}”(hj£hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h Khh¶hžhubhŒ bullet_list”“”)”}”(hhh]”(hŒ list_item”“”)”}”(hŒ4Regular: [dirent data][regular name][nul][nul]...”h]”hÊ)”}”(hjºh]”hŒ4Regular: [dirent data][regular name][nul][nul]...”…””}”(hj¼hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h K!hj¸ubah}”(h]”h ]”h"]”h$]”h&]”uh1j¶hj³hžhhŸh³h Nubj·)”}”(hŒWCasefolded: [dirent data][reg len][cf len][regular name][casefolded name][nul][nul]... ”h]”hÊ)”}”(hŒVCasefolded: [dirent data][reg len][cf len][regular name][casefolded name][nul][nul]...”h]”hŒVCasefolded: [dirent data][reg len][cf len][regular name][casefolded name][nul][nul]...”…””}”(hjÓhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h K"hjÏubah}”(h]”h ]”h"]”h$]”h&]”uh1j¶hj³hžhhŸh³h Nubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ*”uh1j±hŸh³h K!hh¶hžhubhÊ)”}”(hŒ¥(Do note, the number of NULs here is merely for illustration; their count can vary per-key, and they may not even be present if the key is aligned to `sizeof(u64)`.)”h]”(hŒ–(Do note, the number of NULs here is merely for illustration; their count can vary per-key, and they may not even be present if the key is aligned to ”…””}”(hjïhžhhŸNh NubhÔ)”}”(hŒ `sizeof(u64)`”h]”hŒ sizeof(u64)”…””}”(hj÷hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÓhjïubhŒ.)”…””}”(hjïhžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h K$hh¶hžhubhÊ)”}”(hŒ±This is efficient as it means that for all file lookups that require casefolding, it has identical performance to a regular lookup: a hash comparison and a `memcmp` of the name.”h]”(hŒœThis is efficient as it means that for all file lookups that require casefolding, it has identical performance to a regular lookup: a hash comparison and a ”…””}”(hjhžhhŸNh NubhÔ)”}”(hŒ`memcmp`”h]”hŒmemcmp”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÓhjubhŒ of the name.”…””}”(hjhžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h K(hh¶hžhubhµ)”}”(hhh]”(hº)”}”(hŒ Rationale”h]”hŒ Rationale”…””}”(hj2hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¹hj/hžhhŸh³h K-ubhÊ)”}”(hX Several designs were considered for this system: One was to introduce a dirent_v2, however that would be painful especially as the hash system only has support for a single key type. This would also need `BCH_NAME_MAX` to change between versions, and a new feature bit.”h]”(hŒÌSeveral designs were considered for this system: One was to introduce a dirent_v2, however that would be painful especially as the hash system only has support for a single key type. This would also need ”…””}”(hj@hžhhŸNh NubhÔ)”}”(hŒ`BCH_NAME_MAX`”h]”hŒ BCH_NAME_MAX”…””}”(hjHhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÓhj@ubhŒ3 to change between versions, and a new feature bit.”…””}”(hj@hžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h K/hj/hžhubhÊ)”}”(hX+Another option was to store without the two lengths, and just take the length of the regular name and casefolded name contiguously / 2 as the length. This would assume that the regular length == casefolded length, but that could potentially not be true, if the uppercase unicode glyph had a different UTF-8 encoding than the lowercase unicode glyph. It would be possible to disregard the casefold cache for those cases, but it was decided to simply encode the two string lengths in the key to avoid random performance issues if this edgecase was ever hit.”h]”hX+Another option was to store without the two lengths, and just take the length of the regular name and casefolded name contiguously / 2 as the length. This would assume that the regular length == casefolded length, but that could potentially not be true, if the uppercase unicode glyph had a different UTF-8 encoding than the lowercase unicode glyph. It would be possible to disregard the casefold cache for those cases, but it was decided to simply encode the two string lengths in the key to avoid random performance issues if this edgecase was ever hit.”…””}”(hj`hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h K4hj/hžhubhÊ)”}”(hŒéThe option settled on was to use a free-bit in d_type to mark a dirent as having a casefold cache, and then treat the first 4 bytes the name block as lengths. You can see this in the `d_cf_name_block` member of union in `bch_dirent`.”h]”(hŒ·The option settled on was to use a free-bit in d_type to mark a dirent as having a casefold cache, and then treat the first 4 bytes the name block as lengths. You can see this in the ”…””}”(hjnhžhhŸNh NubhÔ)”}”(hŒ`d_cf_name_block`”h]”hŒd_cf_name_block”…””}”(hjvhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÓhjnubhŒ member of union in ”…””}”(hjnhžhhŸNh NubhÔ)”}”(hŒ `bch_dirent`”h]”hŒ bch_dirent”…””}”(hjˆhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÓhjnubhŒ.”…””}”(hjnhžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h K=hj/hžhubhÊ)”}”(hXPThe feature bit was used to allow casefolding support to be enabled for the majority of users, but some allow users who have no need for the feature to still use bcachefs as `CONFIG_UNICODE` can increase the kernel side a significant amount due to the tables used, which may be decider between using bcachefs for eg. embedded platforms.”h]”(hŒ®The feature bit was used to allow casefolding support to be enabled for the majority of users, but some allow users who have no need for the feature to still use bcachefs as ”…””}”(hj hžhhŸNh NubhÔ)”}”(hŒ`CONFIG_UNICODE`”h]”hŒCONFIG_UNICODE”…””}”(hj¨hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÓhj ubhŒ’ can increase the kernel side a significant amount due to the tables used, which may be decider between using bcachefs for eg. embedded platforms.”…””}”(hj hžhhŸNh Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h KAhj/hžhubhÊ)”}”(hX/Other filesystems like ext4 and f2fs have a super-block level option for casefolding encoding, but bcachefs currently does not provide this. ext4 and f2fs do not expose any encodings than a single UTF-8 version. When future encodings are desirable, they will be added trivially using the opts mechanism.”h]”hX/Other filesystems like ext4 and f2fs have a super-block level option for casefolding encoding, but bcachefs currently does not provide this. ext4 and f2fs do not expose any encodings than a single UTF-8 version. When future encodings are desirable, they will be added trivially using the opts mechanism.”…””}”(hjÀhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h KFhj/hžhubeh}”(h]”Œ rationale”ah ]”h"]”Œ rationale”ah$]”h&]”uh1h´hh¶hžhhŸh³h K-ubhµ)”}”(hhh]”(hº)”}”(hŒdentry/dcache considerations”h]”hŒdentry/dcache considerations”…””}”(hjÙhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1h¹hjÖhžhhŸh³h KLubhÊ)”}”(hŒiCurrently, in casefolded directories, bcachefs (like other filesystems) will not cache negative dentry's.”h]”hŒkCurrently, in casefolded directories, bcachefs (like other filesystems) will not cache negative dentry’s.”…””}”(hjçhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h KNhjÖhžhubhÊ)”}”(hŒPThis is because currently doing so presents a problem in the following scenario:”h]”hŒPThis is because currently doing so presents a problem in the following scenario:”…””}”(hjõhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h KQhjÖhžhubhŒ block_quote”“”)”}”(hŒ’- Lookup file "blAH" in a casefolded directory - Creation of file "BLAH" in a casefolded directory - Lookup file "blAH" in a casefolded directory ”h]”j²)”}”(hhh]”(j·)”}”(hŒ,Lookup file "blAH" in a casefolded directory”h]”hÊ)”}”(hjh]”hŒ0Lookup file “blAH†in a casefolded directory”…””}”(hjhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h KShj ubah}”(h]”h ]”h"]”h$]”h&]”uh1j¶hj ubj·)”}”(hŒ1Creation of file "BLAH" in a casefolded directory”h]”hÊ)”}”(hj%h]”hŒ5Creation of file “BLAH†in a casefolded directory”…””}”(hj'hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h KThj#ubah}”(h]”h ]”h"]”h$]”h&]”uh1j¶hj ubj·)”}”(hŒ-Lookup file "blAH" in a casefolded directory ”h]”hÊ)”}”(hŒ,Lookup file "blAH" in a casefolded directory”h]”hŒ0Lookup file “blAH†in a casefolded directory”…””}”(hj>hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h KUhj:ubah}”(h]”h ]”h"]”h$]”h&]”uh1j¶hj ubeh}”(h]”h ]”h"]”h$]”h&]”jíŒ-”uh1j±hŸh³h KShjubah}”(h]”h ]”h"]”h$]”h&]”uh1jhŸh³h KShjÖhžhubhÊ)”}”(hŒ1This would fail if negative dentry's were cached.”h]”hŒ3This would fail if negative dentry’s were cached.”…””}”(hj_hžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h KWhjÖhžhubhÊ)”}”(hŒMThis is slightly suboptimal, but could be fixed in future with some vfs work.”h]”hŒMThis is slightly suboptimal, but could be fixed in future with some vfs work.”…””}”(hjmhžhhŸNh Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÉhŸh³h KYhjÖhžhubeh}”(h]”Œdentry-dcache-considerations”ah ]”h"]”Œdentry/dcache considerations”ah$]”h&]”uh1h´hh¶hžhhŸh³h KLubeh}”(h]”Œ casefolding”ah ]”h"]”Œ casefolding”ah$]”h&]”uh1h´hhhžhhŸh³h Kubeh}”(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”}”Œnameids”}”(jˆj…jÓjÐj€j}uŒ nametypes”}”(jˆ‰jÓ‰j€‰uh}”(j…h¶jÐj/j}jÖ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”]”Œ transformer”NŒ include_log”]”Œ decoration”Nhžhub.