Osphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget$/translations/zh_CN/filesystems/fusemodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/zh_TW/filesystems/fusemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/it_IT/filesystems/fusemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/ja_JP/filesystems/fusemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/ko_KR/filesystems/fusemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/sp_SP/filesystems/fusemodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageEnglishuh1h hh _documenthsourceNlineNubhcomment)}(h SPDX-License-Identifier: GPL-2.0h]h SPDX-License-Identifier: GPL-2.0}hhsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhh>/var/lib/git/docbuild/linux/Documentation/filesystems/fuse.rsthKubhsection)}(hhh](htitle)}(hFUSEh]hFUSE}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(h Definitionsh]h Definitions}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubhdefinition_list)}(hhh](hdefinition_list_item)}(hUserspace filesystem: A filesystem in which data and metadata are provided by an ordinary userspace process. The filesystem can be accessed normally through the kernel interface. h](hterm)}(hUserspace filesystem:h]hUserspace filesystem:}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK hhubh definition)}(hhh]h paragraph)}(hA filesystem in which data and metadata are provided by an ordinary userspace process. The filesystem can be accessed normally through the kernel interface.h]hA filesystem in which data and metadata are provided by an ordinary userspace process. The filesystem can be accessed normally through the kernel interface.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK hhubah}(h]h ]h"]h$]h&]uh1hhhubeh}(h]h ]h"]h$]h&]uh1hhhhK hhubh)}(hVFilesystem daemon: The process(es) providing the data and metadata of the filesystem. h](h)}(hFilesystem daemon:h]hFilesystem daemon:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubh)}(hhh]h)}(hBThe process(es) providing the data and metadata of the filesystem.h]hBThe process(es) providing the data and metadata of the filesystem.}(hj+hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj(ubah}(h]h ]h"]h$]h&]uh1hhjubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hX&Non-privileged mount (or user mount): A userspace filesystem mounted by a non-privileged (non-root) user. The filesystem daemon is running with the privileges of the mounting user. NOTE: this is not the same as mounts allowed with the "user" option in /etc/fstab, which is not discussed here. h](h)}(h%Non-privileged mount (or user mount):h]h%Non-privileged mount (or user mount):}(hjIhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjEubh)}(hhh]h)}(hA userspace filesystem mounted by a non-privileged (non-root) user. The filesystem daemon is running with the privileges of the mounting user. NOTE: this is not the same as mounts allowed with the "user" option in /etc/fstab, which is not discussed here.h]hXA userspace filesystem mounted by a non-privileged (non-root) user. The filesystem daemon is running with the privileges of the mounting user. NOTE: this is not the same as mounts allowed with the “user” option in /etc/fstab, which is not discussed here.}(hjZhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjWubah}(h]h ]h"]h$]h&]uh1hhjEubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hXRFilesystem connection: A connection between the filesystem daemon and the kernel. The connection exists until either the daemon dies, or the filesystem is umounted. Note that detaching (or lazy umounting) the filesystem does *not* break the connection, in this case it will exist until the last reference to the filesystem is released. h](h)}(hFilesystem connection:h]hFilesystem connection:}(hjxhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjtubh)}(hhh]h)}(hX:A connection between the filesystem daemon and the kernel. The connection exists until either the daemon dies, or the filesystem is umounted. Note that detaching (or lazy umounting) the filesystem does *not* break the connection, in this case it will exist until the last reference to the filesystem is released.h](hA connection between the filesystem daemon and the kernel. The connection exists until either the daemon dies, or the filesystem is umounted. Note that detaching (or lazy umounting) the filesystem does }(hjhhhNhNubhemphasis)}(h*not*h]hnot}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubhi break the connection, in this case it will exist until the last reference to the filesystem is released.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1hhjtubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(h-Mount owner: The user who does the mounting. h](h)}(h Mount owner:h]h Mount owner:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK hjubh)}(hhh]h)}(hThe user who does the mounting.h]hThe user who does the mounting.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK hjubah}(h]h ]h"]h$]h&]uh1hhjubeh}(h]h ]h"]h$]h&]uh1hhhhK hhhhubh)}(h8User: The user who is performing filesystem operations. h](h)}(hUser:h]hUser:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK#hjubh)}(hhh]h)}(h1The user who is performing filesystem operations.h]h1The user who is performing filesystem operations.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK#hjubah}(h]h ]h"]h$]h&]uh1hhjubeh}(h]h ]h"]h$]h&]uh1hhhhK#hhhhubeh}(h]h ]h"]h$]h&]uh1hhhhhhhhNubeh}(h] definitionsah ]h"] definitionsah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(h What is FUSE?h]h What is FUSE?}(hj&hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj#hhhhhK&ubh)}(hFUSE is a userspace filesystem framework. It consists of a kernel module (fuse.ko), a userspace library (libfuse.*) and a mount utility (fusermount).h]hFUSE is a userspace filesystem framework. It consists of a kernel module (fuse.ko), a userspace library (libfuse.*) and a mount utility (fusermount).}(hj4hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK(hj#hhubh)}(hOne of the most important features of FUSE is allowing secure, non-privileged mounts. This opens up new possibilities for the use of filesystems. A good example is sshfs: a secure network filesystem using the sftp protocol.h]hOne of the most important features of FUSE is allowing secure, non-privileged mounts. This opens up new possibilities for the use of filesystems. A good example is sshfs: a secure network filesystem using the sftp protocol.}(hjBhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK,hj#hhubh)}(hjThe userspace library and utilities are available from the `FUSE homepage: `_h](h;The userspace library and utilities are available from the }(hjPhhhNhNubh reference)}(h/`FUSE homepage: `_h]hFUSE homepage:}(hjZhhhNhNubah}(h]h ]h"]h$]h&]nameFUSE homepage:refurihttps://github.com/libfuse/uh1jXhjPubhtarget)}(h h]h}(h] fuse-homepageah ]h"]fuse homepage:ah$]h&]refurijkuh1jl referencedKhjPubeh}(h]h ]h"]h$]h&]uh1hhhhK1hj#hhubeh}(h] what-is-fuseah ]h"] what is fuse?ah$]h&]uh1hhhhhhhhK&ubh)}(hhh](h)}(hFilesystem typeh]hFilesystem type}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK5ubh)}(hBThe filesystem type given to mount(2) can be one of the following:h]hBThe filesystem type given to mount(2) can be one of the following:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK7hjhhubh block_quote)}(hX=fuse This is the usual way to mount a FUSE filesystem. The first argument of the mount system call may contain an arbitrary string, which is not interpreted by the kernel. fuseblk The filesystem is block device based. The first argument of the mount system call is interpreted as the name of the device. h]h)}(hhh](h)}(hfuse This is the usual way to mount a FUSE filesystem. The first argument of the mount system call may contain an arbitrary string, which is not interpreted by the kernel. h](h)}(hfuseh]hfuse}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj, ubeh}(h]h ]h"]h$]h&]uh1jhj) ubj)}(hXEven if 1) is solved the mount owner can change the behavior of other users' processes. i) It can slow down or indefinitely delay the execution of a filesystem operation creating a DoS against the user or the whole system. For example a suid application locking a system file, and then accessing a file on the mount owner's filesystem could be stopped, and thus causing the system file to be locked forever. ii) It can present files or directories of unlimited length, or directory structures of unlimited depth, possibly causing a system process to eat up diskspace, memory or other resources, again causing *DoS*. The solution to this as well as B) is not to allow processes to access the filesystem, which could otherwise not be monitored or manipulated by the mount owner. Since if the mount owner can ptrace a process, it can do all of the above without using a FUSE mount, the same criteria as used in ptrace can be used to check if a process is allowed to access the filesystem or not. Note that the *ptrace* check is not strictly necessary to prevent C/2/i, it is enough to check if mount owner has enough privilege to send signal to the process accessing the filesystem, since *SIGSTOP* can be used to get a similar effect. h](h)}(hWEven if 1) is solved the mount owner can change the behavior of other users' processes.h]hYEven if 1) is solved the mount owner can change the behavior of other users’ processes.}(hjV hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjR ubj)}(hX-i) It can slow down or indefinitely delay the execution of a filesystem operation creating a DoS against the user or the whole system. For example a suid application locking a system file, and then accessing a file on the mount owner's filesystem could be stopped, and thus causing the system file to be locked forever. ii) It can present files or directories of unlimited length, or directory structures of unlimited depth, possibly causing a system process to eat up diskspace, memory or other resources, again causing *DoS*. h]jW)}(hhh](j)}(hX>It can slow down or indefinitely delay the execution of a filesystem operation creating a DoS against the user or the whole system. For example a suid application locking a system file, and then accessing a file on the mount owner's filesystem could be stopped, and thus causing the system file to be locked forever. h]h)}(hX=It can slow down or indefinitely delay the execution of a filesystem operation creating a DoS against the user or the whole system. For example a suid application locking a system file, and then accessing a file on the mount owner's filesystem could be stopped, and thus causing the system file to be locked forever.h]hX?It can slow down or indefinitely delay the execution of a filesystem operation creating a DoS against the user or the whole system. For example a suid application locking a system file, and then accessing a file on the mount owner’s filesystem could be stopped, and thus causing the system file to be locked forever.}(hjo hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjk ubah}(h]h ]h"]h$]h&]uh1jhjh ubj)}(hIt can present files or directories of unlimited length, or directory structures of unlimited depth, possibly causing a system process to eat up diskspace, memory or other resources, again causing *DoS*. h]h)}(hIt can present files or directories of unlimited length, or directory structures of unlimited depth, possibly causing a system process to eat up diskspace, memory or other resources, again causing *DoS*.h](hIt can present files or directories of unlimited length, or directory structures of unlimited depth, possibly causing a system process to eat up diskspace, memory or other resources, again causing }(hj hhhNhNubj)}(h*DoS*h]hDoS}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM hj ubah}(h]h ]h"]h$]h&]uh1jhjh ubeh}(h]h ]h"]h$]h&]j lowerromanjhjjGuh1jVhjd ubah}(h]h ]h"]h$]h&]uh1jhhhMhjR ubh)}(hXyThe solution to this as well as B) is not to allow processes to access the filesystem, which could otherwise not be monitored or manipulated by the mount owner. Since if the mount owner can ptrace a process, it can do all of the above without using a FUSE mount, the same criteria as used in ptrace can be used to check if a process is allowed to access the filesystem or not.h]hXyThe solution to this as well as B) is not to allow processes to access the filesystem, which could otherwise not be monitored or manipulated by the mount owner. Since if the mount owner can ptrace a process, it can do all of the above without using a FUSE mount, the same criteria as used in ptrace can be used to check if a process is allowed to access the filesystem or not.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjR ubh)}(hNote that the *ptrace* check is not strictly necessary to prevent C/2/i, it is enough to check if mount owner has enough privilege to send signal to the process accessing the filesystem, since *SIGSTOP* can be used to get a similar effect.h](hNote that the }(hj hhhNhNubj)}(h*ptrace*h]hptrace}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh check is not strictly necessary to prevent C/2/i, it is enough to check if mount owner has enough privilege to send signal to the process accessing the filesystem, since }(hj hhhNhNubj)}(h *SIGSTOP*h]hSIGSTOP}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh% can be used to get a similar effect.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjR ubeh}(h]h ]h"]h$]h&]uh1jhj) ubeh}(h]h ]h"]h$]h&]jjjhjjGuh1jVhj% ubah}(h]h ]h"]h$]h&]uh1jhhhKhj ubeh}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]jjgjhjjGuh1jVhjubah}(h]h ]h"]h$]h&]uh1jhhhKhjvhhubeh}(h]how-are-requirements-fulfilledah ]h"]how are requirements fulfilled?ah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(h+I think these limitations are unacceptable?h]h+I think these limitations are unacceptable?}(hj) hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj& hhhhhMubh)}(hIf a sysadmin trusts the users enough, or can ensure through other measures, that system processes will never enter non-privileged mounts, it can relax the last limitation in several ways:h]hIf a sysadmin trusts the users enough, or can ensure through other measures, that system processes will never enter non-privileged mounts, it can relax the last limitation in several ways:}(hj7 hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM!hj& hhubj)}(hXz- With the 'user_allow_other' config option. If this config option is set, the mounting user can add the 'allow_other' mount option which disables the check for other users' processes. User namespaces have an unintuitive interaction with 'allow_other': an unprivileged user - normally restricted from mounting with 'allow_other' - could do so in a user namespace where they're privileged. If any process could access such an 'allow_other' mount this would give the mounting user the ability to manipulate processes in user namespaces where they're unprivileged. For this reason 'allow_other' restricts access to users in the same userns or a descendant. - With the 'allow_sys_admin_access' module option. If this option is set, super user's processes have unrestricted access to mounts irrespective of allow_other setting or user namespace of the mounting user. h]j)}(hhh](j)}(hXWith the 'user_allow_other' config option. If this config option is set, the mounting user can add the 'allow_other' mount option which disables the check for other users' processes. User namespaces have an unintuitive interaction with 'allow_other': an unprivileged user - normally restricted from mounting with 'allow_other' - could do so in a user namespace where they're privileged. If any process could access such an 'allow_other' mount this would give the mounting user the ability to manipulate processes in user namespaces where they're unprivileged. For this reason 'allow_other' restricts access to users in the same userns or a descendant. h](h)}(hWith the 'user_allow_other' config option. If this config option is set, the mounting user can add the 'allow_other' mount option which disables the check for other users' processes.h]hWith the ‘user_allow_other’ config option. If this config option is set, the mounting user can add the ‘allow_other’ mount option which disables the check for other users’ processes.}(hjP hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM%hjL ubh)}(hXUser namespaces have an unintuitive interaction with 'allow_other': an unprivileged user - normally restricted from mounting with 'allow_other' - could do so in a user namespace where they're privileged. If any process could access such an 'allow_other' mount this would give the mounting user the ability to manipulate processes in user namespaces where they're unprivileged. For this reason 'allow_other' restricts access to users in the same userns or a descendant.h]hXUser namespaces have an unintuitive interaction with ‘allow_other’: an unprivileged user - normally restricted from mounting with ‘allow_other’ - could do so in a user namespace where they’re privileged. If any process could access such an ‘allow_other’ mount this would give the mounting user the ability to manipulate processes in user namespaces where they’re unprivileged. For this reason ‘allow_other’ restricts access to users in the same userns or a descendant.}(hj^ hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM)hjL ubeh}(h]h ]h"]h$]h&]uh1jhjI ubj)}(hWith the 'allow_sys_admin_access' module option. If this option is set, super user's processes have unrestricted access to mounts irrespective of allow_other setting or user namespace of the mounting user. h]h)}(hWith the 'allow_sys_admin_access' module option. If this option is set, super user's processes have unrestricted access to mounts irrespective of allow_other setting or user namespace of the mounting user.h]hWith the ‘allow_sys_admin_access’ module option. If this option is set, super user’s processes have unrestricted access to mounts irrespective of allow_other setting or user namespace of the mounting user.}(hjv hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM2hjr ubah}(h]h ]h"]h$]h&]uh1jhjI ubeh}(h]h ]h"]h$]h&]jjuh1jhhhM%hjE ubah}(h]h ]h"]h$]h&]uh1jhhhM%hj& hhubh)}(hNote that both of these relaxations expose the system to potential information leak or *DoS* as described in points B and C/2/i-ii in the preceding section.h](hWNote that both of these relaxations expose the system to potential information leak or }(hj hhhNhNubj)}(h*DoS*h]hDoS}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj ubh@ as described in points B and C/2/i-ii in the preceding section.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM7hj& hhubeh}(h]*i-think-these-limitations-are-unacceptableah ]h"]+i think these limitations are unacceptable?ah$]h&]uh1hhhhhhhhMubh)}(hhh](h)}(hKernel - userspace interfaceh]hKernel - userspace interface}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhM<ubh)}(hhThe following diagram shows how a filesystem operation (in this example unlink) is performed in FUSE. ::h]heThe following diagram shows how a filesystem operation (in this example unlink) is performed in FUSE.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM>hj hhubj)}(hX| "rm /mnt/fuse/file" | FUSE filesystem daemon | | | | >sys_read() | | >fuse_dev_read() | | >request_wait() | | [sleep on fc->waitq] | | | >sys_unlink() | | >fuse_unlink() | | [get request from | | fc->unused_list] | | >request_send() | | [queue req on fc->pending] | | [wake up fc->waitq] | [woken up] | >request_wait_answer() | | [sleep on req->waitq] | | | pending] | | [copy req to read buffer] | | [add req to fc->processing] | | sys_write() | | >fuse_dev_write() | | [look up req in fc->processing] | | [remove from fc->processing] | | [copy write buffer to req] | [woken up] | [wake up req->waitq] | | unused_list] | | sys_read() | | >fuse_dev_read() | | >request_wait() | | [sleep on fc->waitq] | | | >sys_unlink() | | >fuse_unlink() | | [get request from | | fc->unused_list] | | >request_send() | | [queue req on fc->pending] | | [wake up fc->waitq] | [woken up] | >request_wait_answer() | | [sleep on req->waitq] | | | pending] | | [copy req to read buffer] | | [add req to fc->processing] | | sys_write() | | >fuse_dev_write() | | [look up req in fc->processing] | | [remove from fc->processing] | | [copy write buffer to req] | [woken up] | [wake up req->waitq] | | unused_list] | | sys_unlink("/mnt/fuse/file") | | [acquire inode semaphore | | for "file"] | | >fuse_unlink() | | [sleep on req->waitq] | | | sys_unlink("/mnt/fuse/file") | | [acquire inode semaphore | | for "file"] | | *DEADLOCK*h]hXQ| "rm /mnt/fuse/file" | FUSE filesystem daemon | | | >sys_unlink("/mnt/fuse/file") | | [acquire inode semaphore | | for "file"] | | >fuse_unlink() | | [sleep on req->waitq] | | | sys_unlink("/mnt/fuse/file") | | [acquire inode semaphore | | for "file"] | | *DEADLOCK*}hj0 sbah}(h]h ]h"]h$]h&]hhuh1jhhhMrhj hhubh)}(h?The solution for this is to allow the filesystem to be aborted.h]h?The solution for this is to allow the filesystem to be aborted.}(hj> hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubh)}(h **Scenario 2 - Tricky deadlock**h]j )}(hjN h]hScenario 2 - Tricky deadlock}(hjP hhhNhNubah}(h]h ]h"]h$]h&]uh1j hjL ubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubh)}(hThis one needs a carefully crafted filesystem. It's a variation on the above, only the call back to the filesystem is not explicit, but is caused by a pagefault. ::h]hThis one needs a carefully crafted filesystem. It’s a variation on the above, only the call back to the filesystem is not explicit, but is caused by a pagefault.}(hjc hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubj)}(hX| Kamikaze filesystem thread 1 | Kamikaze filesystem thread 2 | | | [fd = open("/mnt/fuse/file")] | [request served normally] | [mmap fd to 'addr'] | | [close fd] | [FLUSH triggers 'magic' flag] | [read a byte from addr] | | >do_page_fault() | | [find or create page] | | [lock page] | | >fuse_readpage() | | [queue READ request] | | [sleep on req->waitq] | | | [read request to buffer] | | [create reply header before addr] | | >sys_write(addr - headerlength) | | >fuse_dev_write() | | [look up req in fc->processing] | | [remove from fc->processing] | | [copy write buffer to req] | | >do_page_fault() | | [find or create page] | | [lock page] | | * DEADLOCK *h]hX| Kamikaze filesystem thread 1 | Kamikaze filesystem thread 2 | | | [fd = open("/mnt/fuse/file")] | [request served normally] | [mmap fd to 'addr'] | | [close fd] | [FLUSH triggers 'magic' flag] | [read a byte from addr] | | >do_page_fault() | | [find or create page] | | [lock page] | | >fuse_readpage() | | [queue READ request] | | [sleep on req->waitq] | | | [read request to buffer] | | [create reply header before addr] | | >sys_write(addr - headerlength) | | >fuse_dev_write() | | [look up req in fc->processing] | | [remove from fc->processing] | | [copy write buffer to req] | | >do_page_fault() | | [find or create page] | | [lock page] | | * DEADLOCK *}hjq sbah}(h]h ]h"]h$]h&]hhuh1jhhhMhj hhubh)}(h,The solution is basically the same as above.h]h,The solution is basically the same as above.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubh)}(hAn additional problem is that while the write buffer is being copied to the request, the request must not be interrupted/aborted. This is because the destination address of the copy may not be valid after the request has returned.h]hAn additional problem is that while the write buffer is being copied to the request, the request must not be interrupted/aborted. This is because the destination address of the copy may not be valid after the request has returned.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubh)}(hXThis is solved with doing the copy atomically, and allowing abort while the page(s) belonging to the write buffer are faulted with get_user_pages(). The 'req->locked' flag indicates when the copy is taking place, and abort is delayed until this flag is unset.h]hXThis is solved with doing the copy atomically, and allowing abort while the page(s) belonging to the write buffer are faulted with get_user_pages(). The ‘req->locked’ flag indicates when the copy is taking place, and abort is delayed until this flag is unset.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubeh}(h]kernel-userspace-interfaceah ]h"]kernel - userspace interfaceah$]h&]uh1hhhhhhhhM<ubeh}(h]fuseah ]h"]fuseah$]h&]uh1hhhhhhhhKubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(hN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerj error_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourceh _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}refids}nameids}(j j j jjjjwjtj!jjjjjjjjjjsjpj# j j j j j u nametypes}(j j jjwj!jjjjjsj# j j uh}(j hjhjj#jtjnjjjj$jjjjjjjpjj jvj j& j j u footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}Rparse_messages]transform_messages] transformerN include_log] decorationNhhub.