sphinx.addnodesdocument)}( rawsource children](translations
LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}parenthsba
attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget+/translations/zh_CN/filesystems/path-lookupmodnameN classnameNrefexplicitutagnamehhhubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget+/translations/zh_TW/filesystems/path-lookupmodnameN classnameNrefexplicituh1hhhubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget+/translations/it_IT/filesystems/path-lookupmodnameN classnameNrefexplicituh1hhhubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget+/translations/ja_JP/filesystems/path-lookupmodnameN classnameNrefexplicituh1hhhubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget+/translations/ko_KR/filesystems/path-lookupmodnameN classnameNrefexplicituh1hhhubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget+/translations/sp_SP/filesystems/path-lookupmodnameN classnameNrefexplicituh1hhhubeh}(h]h ]h"]h$]h&]current_languageEnglishuh1h
hh _documenthsourceNlineNubhsection)}(hhh](htitle)}(hPathname lookuph]hPathname lookup}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhE/var/lib/git/docbuild/linux/Documentation/filesystems/path-lookup.rsthKubh paragraph)}(h>This write-up is based on three articles published at lwn.net:h]h>This write-up is based on three articles published at lwn.net:}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubhbullet_list)}(hhh](h list_item)}(h; Pathname lookup in Linuxh]h)}(hhh](h<}(hhhhhNhNubh reference)}(h https://lwn.net/Articles/649115/h]h https://lwn.net/Articles/649115/}(hhhhhNhNubah}(h]h ]h"]h$]h&]refurihuh1hhhubh> Pathname lookup in Linux}(hhhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhhubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubh)}(hL RCU-walk: faster pathname lookup in Linuxh]h)}(hhh](h<}(hhhhhNhNubh)}(h https://lwn.net/Articles/649729/h]h https://lwn.net/Articles/649729/}(hj hhhNhNubah}(h]h ]h"]h$]h&]refurij uh1hhhubh+> RCU-walk: faster pathname lookup in Linux}(hhhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhhubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubh)}(h= A walk among the symlinks
h]h)}(h< A walk among the symlinksh](h<}(hj( hhhNhNubh)}(h https://lwn.net/Articles/650786/h]h https://lwn.net/Articles/650786/}(hj0 hhhNhNubah}(h]h ]h"]h$]h&]refurij2 uh1hhj( ubh> A walk among the symlinks}(hj( hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK hj$ ubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubeh}(h]h ]h"]h$]h&]bullet-uh1hhhhKhhhhubh)}(hWritten by Neil Brown with help from Al Viro and Jon Corbet.
It has subsequently been updated to reflect changes in the kernel
including:h]hWritten by Neil Brown with help from Al Viro and Jon Corbet.
It has subsequently been updated to reflect changes in the kernel
including:}(hjW hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hhh](h)}(h#per-directory parallel name lookup.h]h)}(hjj h]h#per-directory parallel name lookup.}(hjl hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjh ubah}(h]h ]h"]h$]h&]uh1hhje hhhhhNubh)}(h,``openat2()`` resolution restriction flags.
h]h)}(h+``openat2()`` resolution restriction flags.h](hliteral)}(h
``openat2()``h]h openat2()}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh resolution restriction flags.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1hhje hhhhhNubeh}(h]h ]h"]h$]h&]jU jV uh1hhhhKhhhhubh)}(hhh](h)}(hIntroduction to pathname lookuph]hIntroduction to pathname lookup}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhKubh)}(hX The most obvious aspect of pathname lookup, which very little
exploration is needed to discover, is that it is complex. There are
many rules, special cases, and implementation alternatives that all
combine to confuse the unwary reader. Computer science has long been
acquainted with such complexity and has tools to help manage it. One
tool that we will make extensive use of is "divide and conquer". For
the early parts of the analysis we will divide off symlinks - leaving
them until the final part. Well before we get to symlinks we have
another major division based on the VFS's approach to locking which
will allow us to review "REF-walk" and "RCU-walk" separately. But we
are getting ahead of ourselves. There are some important low level
distinctions we need to clarify first.h]hX$ The most obvious aspect of pathname lookup, which very little
exploration is needed to discover, is that it is complex. There are
many rules, special cases, and implementation alternatives that all
combine to confuse the unwary reader. Computer science has long been
acquainted with such complexity and has tools to help manage it. One
tool that we will make extensive use of is “divide and conquer”. For
the early parts of the analysis we will divide off symlinks - leaving
them until the final part. Well before we get to symlinks we have
another major division based on the VFS’s approach to locking which
will allow us to review “REF-walk” and “RCU-walk” separately. But we
are getting ahead of ourselves. There are some important low level
distinctions we need to clarify first.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj hhubh)}(hhh](h)}(hThere are two sorts of ...h]hThere are two sorts of ...}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhK#ubhtarget)}(h>.. _openat: http://man7.org/linux/man-pages/man2/openat.2.htmlh]h}(h]openatah ]h"]openatah$]h&]refuri2http://man7.org/linux/man-pages/man2/openat.2.htmluh1j hK%hj hhhh
referencedKubh)}(hXO Pathnames (sometimes "file names"), used to identify objects in the
filesystem, will be familiar to most readers. They contain two sorts
of elements: "slashes" that are sequences of one or more "``/``"
characters, and "components" that are sequences of one or more
non-"``/``" characters. These form two kinds of paths. Those that
start with slashes are "absolute" and start from the filesystem root.
The others are "relative" and start from the current directory, or
from some other location specified by a file descriptor given to
"``*at()``" system calls such as `openat() `_.h](hPathnames (sometimes “file names”), used to identify objects in the
filesystem, will be familiar to most readers. They contain two sorts
of elements: “slashes” that are sequences of one or more “}(hj hhhNhNubj )}(h``/``h]h/}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubhN”
characters, and “components” that are sequences of one or more
non-”}(hj hhhNhNubj )}(h``/``h]h/}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubhX ” characters. These form two kinds of paths. Those that
start with slashes are “absolute” and start from the filesystem root.
The others are “relative” and start from the current directory, or
from some other location specified by a file descriptor given to
“}(hj hhhNhNubj )}(h ``*at()``h]h*at()}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh” system calls such as }(hj hhhNhNubh)}(h`openat() `_h]hopenat()}(hj, hhhNhNubah}(h]h ]h"]h$]h&]nameopenat()j j uh1hhj resolvedKubj )}(h
h]h}(h]h ]h"]openat()ah$]h&]j j uh1j indirect_reference_nameopenathj j< Kubh.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK'hj hhubj )}(hB.. _execveat: http://man7.org/linux/man-pages/man2/execveat.2.htmlh]h}(h]execveatah ]h"]execveatah$]h&]j 4http://man7.org/linux/man-pages/man2/execveat.2.htmluh1j hK1hj hhhhj Kubh)}(hX It is tempting to describe the second kind as starting with a
component, but that isn't always accurate: a pathname can lack both
slashes and components, it can be empty, in other words. This is
generally forbidden in POSIX, but some of those "``*at()``" system calls
in Linux permit it when the ``AT_EMPTY_PATH`` flag is given. For
example, if you have an open file descriptor on an executable file you
can execute it by calling `execveat() `_ passing
the file descriptor, an empty path, and the ``AT_EMPTY_PATH`` flag.h](hIt is tempting to describe the second kind as starting with a
component, but that isn’t always accurate: a pathname can lack both
slashes and components, it can be empty, in other words. This is
generally forbidden in POSIX, but some of those “}(hja hhhNhNubj )}(h ``*at()``h]h*at()}(hji hhhNhNubah}(h]h ]h"]h$]h&]uh1j hja ubh-” system calls
in Linux permit it when the }(hja hhhNhNubj )}(h``AT_EMPTY_PATH``h]h
AT_EMPTY_PATH}(hj{ hhhNhNubah}(h]h ]h"]h$]h&]uh1j hja ubhv flag is given. For
example, if you have an open file descriptor on an executable file you
can execute it by calling }(hja hhhNhNubh)}(h`execveat() `_h]h
execveat()}(hj hhhNhNubah}(h]h ]h"]h$]h&]name
execveat()j j` uh1hhja j< Kubj )}(h h]h}(h]h ]h"]
execveat()ah$]h&]j j` uh1j jH execveathja j< Kubh5 passing
the file descriptor, an empty path, and the }(hja hhhNhNubj )}(h``AT_EMPTY_PATH``h]h
AT_EMPTY_PATH}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hja ubh flag.}(hja hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK3hj hhubh)}(hX These paths can be divided into two sections: the final component and
everything else. The "everything else" is the easy bit. In all cases
it must identify a directory that already exists, otherwise an error
such as ``ENOENT`` or ``ENOTDIR`` will be reported.h](hThese paths can be divided into two sections: the final component and
everything else. The “everything else” is the easy bit. In all cases
it must identify a directory that already exists, otherwise an error
such as }(hj hhhNhNubj )}(h
``ENOENT``h]hENOENT}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh or }(hj hhhNhNubj )}(h``ENOTDIR``h]hENOTDIR}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j hj ubh will be reported.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK