€•7OŒ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”Œ-/translations/zh_CN/filesystems/multigrain-ts”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)”}”(hhh]”hŒChinese (Traditional)”…””}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ-/translations/zh_TW/filesystems/multigrain-ts”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒItalian”…””}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ-/translations/it_IT/filesystems/multigrain-ts”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒJapanese”…””}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ-/translations/ja_JP/filesystems/multigrain-ts”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒKorean”…””}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ-/translations/ko_KR/filesystems/multigrain-ts”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒPortuguese (Brazilian)”…””}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ-/translations/pt_BR/filesystems/multigrain-ts”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒSpanish”…””}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ-/translations/sp_SP/filesystems/multigrain-ts”Œ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³ŒG/var/lib/git/docbuild/linux/Documentation/filesystems/multigrain-ts.rst”h´KubhŒsection”“”)”}”(hhh]”(hŒtitle”“”)”}”(hŒMultigrain Timestamps”h]”hŒMultigrain Timestamps”…””}”(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”“”)”}”(hŒÁHistorically, the kernel has always used coarse time values to stamp inodes. This value is updated every jiffy, so any change that happens within that jiffy will end up with the same timestamp.”h]”hŒÁHistorically, the kernel has always used coarse time values to stamp inodes. This value is updated every jiffy, so any change that happens within that jiffy will end up with the same timestamp.”…””}”(hhðh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K hhÝh²hubhï)”}”(hŒûWhen the kernel goes to stamp an inode (due to a read or write), it first gets the current time and then compares it to the existing timestamp(s) to see whether anything will change. If nothing changed, then it can avoid updating the inode's metadata.”h]”hŒýWhen the kernel goes to stamp an inode (due to a read or write), it first gets the current time and then compares it to the existing timestamp(s) to see whether anything will change. If nothing changed, then it can avoid updating the inode’s metadata.”…””}”(hhþh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K hhÝh²hubhï)”}”(hŒêCoarse timestamps are therefore good from a performance standpoint, since they reduce the need for metadata updates, but bad from the standpoint of determining whether anything has changed, since a lot of things can happen in a jiffy.”h]”hŒêCoarse timestamps are therefore good from a performance standpoint, since they reduce the need for metadata updates, but bad from the standpoint of determining whether anything has changed, since a lot of things can happen in a jiffy.”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KhhÝh²hubhï)”}”(hXJThey are particularly troublesome with NFSv3, where unchanging timestamps can make it difficult to tell whether to invalidate caches. NFSv4 provides a dedicated change attribute that should always show a visible change, but not all filesystems implement this properly, causing the NFS server to substitute the ctime in many cases.”h]”hXJThey are particularly troublesome with NFSv3, where unchanging timestamps can make it difficult to tell whether to invalidate caches. NFSv4 provides a dedicated change attribute that should always show a visible change, but not all filesystems implement this properly, causing the NFS server to substitute the ctime in many cases.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KhhÝh²hubhï)”}”(hŒÇMultigrain timestamps aim to remedy this by selectively using fine-grained timestamps when a file has had its timestamps queried recently, and the current coarse-grained time does not cause a change.”h]”hŒÇMultigrain timestamps aim to remedy this by selectively using fine-grained timestamps when a file has had its timestamps queried recently, and the current coarse-grained time does not cause a change.”…””}”(hj(h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KhhÝh²hubeh}”(h]”Œ introduction”ah ]”h"]”Œ introduction”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KubhÉ)”}”(hhh]”(hÎ)”}”(hŒInode Timestamps”h]”hŒInode Timestamps”…””}”(hjAh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj>h²hh³hÇh´K"ubhï)”}”(hŒsThere are currently 3 timestamps in the inode that are updated to the current wallclock time on different activity:”h]”hŒsThere are currently 3 timestamps in the inode that are updated to the current wallclock time on different activity:”…””}”(hjOh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K#hj>h²hubhŒdefinition_list”“”)”}”(hhh]”(hŒdefinition_list_item”“”)”}”(hŒ¢ctime: The inode change time. This is stamped with the current time whenever the inode's metadata is changed. Note that this value is not settable from userland. ”h]”(hŒterm”“”)”}”(hŒctime:”h]”hŒctime:”…””}”(hjjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhh³hÇh´K)hjdubhŒ definition”“”)”}”(hhh]”hï)”}”(hŒšThe inode change time. This is stamped with the current time whenever the inode's metadata is changed. Note that this value is not settable from userland.”h]”hŒœThe inode change time. This is stamped with the current time whenever the inode’s metadata is changed. Note that this value is not settable from userland.”…””}”(hj}h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K'hjzubah}”(h]”h ]”h"]”h$]”h&]”uh1jxhjdubeh}”(h]”h ]”h"]”h$]”h&]”uh1jbh³hÇh´K)hj_ubjc)”}”(hŒmmtime: The inode modification time. This is stamped with the current time any time a file's contents change. ”h]”(ji)”}”(hŒmtime:”h]”hŒmtime:”…””}”(hj›h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhh³hÇh´K-hj—ubjy)”}”(hhh]”hï)”}”(hŒeThe inode modification time. This is stamped with the current time any time a file's contents change.”h]”hŒgThe inode modification time. This is stamped with the current time any time a file’s contents change.”…””}”(hj¬h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K,hj©ubah}”(h]”h ]”h"]”h$]”h&]”uh1jxhj—ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jbh³hÇh´K-hj_h²hubjc)”}”(hŒ¸atime: The inode access time. This is stamped whenever an inode's contents are read. Widely considered to be a terrible mistake. Usually avoided with options like noatime or relatime. ”h]”(ji)”}”(hŒatime:”h]”hŒatime:”…””}”(hjÊh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jhh³hÇh´K2hjÆubjy)”}”(hhh]”hï)”}”(hŒ°The inode access time. This is stamped whenever an inode's contents are read. Widely considered to be a terrible mistake. Usually avoided with options like noatime or relatime.”h]”hŒ²The inode access time. This is stamped whenever an inode’s contents are read. Widely considered to be a terrible mistake. Usually avoided with options like noatime or relatime.”…””}”(hjÛh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K0hjØubah}”(h]”h ]”h"]”h$]”h&]”uh1jxhjÆubeh}”(h]”h ]”h"]”h$]”h&]”uh1jbh³hÇh´K2hj_h²hubeh}”(h]”h ]”h"]”h$]”h&]”uh1j]hj>h²hh³hÇh´Nubhï)”}”(hŒoUpdating the mtime always implies a change to the ctime, but updating the atime due to a read request does not.”h]”hŒoUpdating the mtime always implies a change to the ctime, but updating the atime due to a read request does not.”…””}”(hjûh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K4hj>h²hubhï)”}”(hŒ›Multigrain timestamps are only tracked for the ctime and the mtime. atimes are not affected and always use the coarse-grained value (subject to the floor).”h]”hŒ›Multigrain timestamps are only tracked for the ctime and the mtime. atimes are not affected and always use the coarse-grained value (subject to the floor).”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K7hj>h²hubeh}”(h]”Œinode-timestamps”ah ]”h"]”Œinode timestamps”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´K"ubhÉ)”}”(hhh]”(hÎ)”}”(hŒInode Timestamp Ordering”h]”hŒInode Timestamp Ordering”…””}”(hj"h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjh²hh³hÇh´K;ubhï)”}”(hXIn addition to just providing info about changes to individual files, file timestamps also serve an important purpose in applications like "make". These programs measure timestamps in order to determine whether source files might be newer than cached objects.”h]”hXIn addition to just providing info about changes to individual files, file timestamps also serve an important purpose in applications like “makeâ€. These programs measure timestamps in order to determine whether source files might be newer than cached objects.”…””}”(hj0h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K=hjh²hubhï)”}”(hXYUserland applications like make can only determine ordering based on operational boundaries. For a syscall those are the syscall entry and exit points. For io_uring or nfsd operations, that's the request submission and response. In the case of concurrent operations, userland can make no determination about the order in which things will occur.”h]”hX[Userland applications like make can only determine ordering based on operational boundaries. For a syscall those are the syscall entry and exit points. For io_uring or nfsd operations, that’s the request submission and response. In the case of concurrent operations, userland can make no determination about the order in which things will occur.”…””}”(hj>h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KBhjh²hubhï)”}”(hŒôFor instance, if a single thread modifies one file, and then another file in sequence, the second file must show an equal or later mtime than the first. The same is true if two threads are issuing similar operations that do not overlap in time.”h]”hŒôFor instance, if a single thread modifies one file, and then another file in sequence, the second file must show an equal or later mtime than the first. The same is true if two threads are issuing similar operations that do not overlap in time.”…””}”(hjLh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KHhjh²hubhï)”}”(hŒõIf however, two threads have racing syscalls that overlap in time, then there is no such guarantee, and the second file may appear to have been modified before, after or at the same time as the first, regardless of which one was submitted first.”h]”hŒõIf however, two threads have racing syscalls that overlap in time, then there is no such guarantee, and the second file may appear to have been modified before, after or at the same time as the first, regardless of which one was submitted first.”…””}”(hjZh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KMhjh²hubhï)”}”(hŒÞNote that the above assumes that the system doesn't experience a backward jump of the realtime clock. If that occurs at an inopportune time, then timestamps can appear to go backward, even on a properly functioning system.”h]”hŒàNote that the above assumes that the system doesn’t experience a backward jump of the realtime clock. If that occurs at an inopportune time, then timestamps can appear to go backward, even on a properly functioning system.”…””}”(hjhh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KRhjh²hubeh}”(h]”Œinode-timestamp-ordering”ah ]”h"]”Œinode timestamp ordering”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´K;ubhÉ)”}”(hhh]”(hÎ)”}”(hŒ#Multigrain Timestamp Implementation”h]”hŒ#Multigrain Timestamp Implementation”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj~h²hh³hÇh´KWubhï)”}”(hXMultigrain timestamps are aimed at ensuring that changes to a single file are always recognizable, without violating the ordering guarantees when multiple different files are modified. This affects the mtime and the ctime, but the atime will always use coarse-grained timestamps.”h]”hXMultigrain timestamps are aimed at ensuring that changes to a single file are always recognizable, without violating the ordering guarantees when multiple different files are modified. This affects the mtime and the ctime, but the atime will always use coarse-grained timestamps.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´KXhj~h²hubhï)”}”(hXIt uses an unused bit in the i_ctime_nsec field to indicate whether the mtime or ctime has been queried. If either or both have, then the kernel takes special care to ensure the next timestamp update will display a visible change. This ensures tight cache coherency for use-cases like NFS, without sacrificing the benefits of reduced metadata updates when files aren't being watched.”h]”hXIt uses an unused bit in the i_ctime_nsec field to indicate whether the mtime or ctime has been queried. If either or both have, then the kernel takes special care to ensure the next timestamp update will display a visible change. This ensures tight cache coherency for use-cases like NFS, without sacrificing the benefits of reduced metadata updates when files aren’t being watched.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´K]hj~h²hubeh}”(h]”Œ#multigrain-timestamp-implementation”ah ]”h"]”Œ#multigrain timestamp implementation”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KWubhÉ)”}”(hhh]”(hÎ)”}”(hŒThe Ctime Floor Value”h]”hŒThe Ctime Floor Value”…””}”(hj¶h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhj³h²hh³hÇh´Kdubhï)”}”(hXLIt's not sufficient to simply use fine or coarse-grained timestamps based on whether the mtime or ctime has been queried. A file could get a fine grained timestamp, and then a second file modified later could get a coarse-grained one that appears earlier than the first, which would break the kernel's timestamp ordering guarantees.”h]”hXPIt’s not sufficient to simply use fine or coarse-grained timestamps based on whether the mtime or ctime has been queried. A file could get a fine grained timestamp, and then a second file modified later could get a coarse-grained one that appears earlier than the first, which would break the kernel’s timestamp ordering guarantees.”…””}”(hjÄh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´Kehj³h²hubhï)”}”(hXˆTo mitigate this problem, maintain a global floor value that ensures that this can't happen. The two files in the above example may appear to have been modified at the same time in such a case, but they will never show the reverse order. To avoid problems with realtime clock jumps, the floor is managed as a monotonic ktime_t, and the values are converted to realtime clock values as needed.”h]”hXŠTo mitigate this problem, maintain a global floor value that ensures that this can’t happen. The two files in the above example may appear to have been modified at the same time in such a case, but they will never show the reverse order. To avoid problems with realtime clock jumps, the floor is managed as a monotonic ktime_t, and the values are converted to realtime clock values as needed.”…””}”(hjÒh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´Kkhj³h²hubeh}”(h]”Œthe-ctime-floor-value”ah ]”h"]”Œthe ctime floor value”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´KdubhÉ)”}”(hhh]”(hÎ)”}”(hŒImplementation Notes”h]”hŒImplementation Notes”…””}”(hjëh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÍhjèh²hh³hÇh´Ksubhï)”}”(hŒÔMultigrain timestamps are intended for use by local filesystems that get ctime values from the local clock. This is in contrast to network filesystems and the like that just mirror timestamp values from a server.”h]”hŒÔMultigrain timestamps are intended for use by local filesystems that get ctime values from the local clock. This is in contrast to network filesystems and the like that just mirror timestamp values from a server.”…””}”(hjùh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´Kthjèh²hubhï)”}”(hX¢For most filesystems, it's sufficient to just set the FS_MGTIME flag in the fstype->fs_flags in order to opt-in, providing the ctime is only ever set via inode_set_ctime_current(). If the filesystem has a ->getattr routine that doesn't call generic_fillattr, then it should call fill_mg_cmtime() to fill those values. For setattr, it should use setattr_copy() to update the timestamps, or otherwise mimic its behavior.”h]”hX¦For most filesystems, it’s sufficient to just set the FS_MGTIME flag in the fstype->fs_flags in order to opt-in, providing the ctime is only ever set via inode_set_ctime_current(). If the filesystem has a ->getattr routine that doesn’t call generic_fillattr, then it should call fill_mg_cmtime() to fill those values. For setattr, it should use setattr_copy() to update the timestamps, or otherwise mimic its behavior.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hîh³hÇh´Kxhjèh²hubeh}”(h]”Œimplementation-notes”ah ]”h"]”Œimplementation notes”ah$]”h&]”uh1hÈhhÊh²hh³hÇh´Ksubeh}”(h]”Œmultigrain-timestamps”ah ]”h"]”Œmultigrain timestamps”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”jHŒ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"jj;j8jjj{jxj°j­jåjâjjuŒ nametypes”}”(j"‰j;‰j‰j{‰j°‰jå‰j‰uh}”(jhÊj8hÝjj>jxjj­j~jâj³jjè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.