sphinx.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/netfs_librarymodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget-/translations/zh_TW/filesystems/netfs_librarymodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget-/translations/it_IT/filesystems/netfs_librarymodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget-/translations/ja_JP/filesystems/netfs_librarymodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget-/translations/ko_KR/filesystems/netfs_librarymodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget-/translations/sp_SP/filesystems/netfs_librarymodnameN 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:spacepreserveuh1hhhhhhG/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library.rsthKubhsection)}(hhh](htitle)}(h#Network Filesystem Services Libraryh]h#Network Filesystem Services Library}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubh)}(hXuContents: - Overview. - Requests and streams. - Subrequests. - Result collection and retry. - Local caching. - Content encryption (fscrypt). - Per-inode context. - Inode context helper functions. - Inode locking. - Inode writeback. - High-level VFS API. - Unlocked read/write iter. - Pre-locked read/write iter. - Monolithic files API. - Memory-mapped I/O API. - High-level VM API. - Deprecated PG_private2 API. - I/O request API. - Request structure. - Stream structure. - Subrequest structure. - Filesystem methods. - Terminating a subrequest. - Local cache API. - API function reference.h]hXuContents: - Overview. - Requests and streams. - Subrequests. - Result collection and retry. - Local caching. - Content encryption (fscrypt). - Per-inode context. - Inode context helper functions. - Inode locking. - Inode writeback. - High-level VFS API. - Unlocked read/write iter. - Pre-locked read/write iter. - Monolithic files API. - Memory-mapped I/O API. - High-level VM API. - Deprecated PG_private2 API. - I/O request API. - Request structure. - Stream structure. - Subrequest structure. - Filesystem methods. - Terminating a subrequest. - Local cache API. - API function reference.}hhsbah}(h]h ]h"]h$]h&]hhuh1hhhhhhhhK#ubh)}(hhh](h)}(hOverviewh]hOverview}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhK%ubh paragraph)}(hXThe network filesystem services library, netfslib, is a set of functions designed to aid a network filesystem in implementing VM/VFS API operations. It takes over the normal buffered read, readahead, write and writeback and also handles unbuffered and direct I/O.h]hXThe network filesystem services library, netfslib, is a set of functions designed to aid a network filesystem in implementing VM/VFS API operations. It takes over the normal buffered read, readahead, write and writeback and also handles unbuffered and direct I/O.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK'hhhhubh)}(hThe library provides support for (re-)negotiation of I/O sizes and retrying failed I/O as well as local caching and will, in the future, provide content encryption.h]hThe library provides support for (re-)negotiation of I/O sizes and retrying failed I/O as well as local caching and will, in the future, provide content encryption.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK,hhhhubh)}(hIt insulates the filesystem from VM interface changes as much as possible and handles VM features such as large multipage folios. The filesystem basically just has to provide a way to perform read and write RPC calls.h]hIt insulates the filesystem from VM interface changes as much as possible and handles VM features such as large multipage folios. The filesystem basically just has to provide a way to perform read and write RPC calls.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK0hhhhubh)}(hIThe way I/O is organised inside netfslib consists of a number of objects:h]hIThe way I/O is organised inside netfslib consists of a number of objects:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK4hhhhubh block_quote)}(hX7* A *request*. A request is used to track the progress of the I/O overall and to hold on to resources. The collection of results is done at the request level. The I/O within a request is divided into a number of parallel streams of subrequests. * A *stream*. A non-overlapping series of subrequests. The subrequests within a stream do not have to be contiguous. * A *subrequest*. This is the basic unit of I/O. It represents a single RPC call or a single cache I/O operation. The library passes these to the filesystem and the cache to perform. h]h bullet_list)}(hhh](h list_item)}(hA *request*. A request is used to track the progress of the I/O overall and to hold on to resources. The collection of results is done at the request level. The I/O within a request is divided into a number of parallel streams of subrequests. h]h)}(hA *request*. A request is used to track the progress of the I/O overall and to hold on to resources. The collection of results is done at the request level. The I/O within a request is divided into a number of parallel streams of subrequests.h](hA }(hj3hhhNhNubhemphasis)}(h *request*h]hrequest}(hj=hhhNhNubah}(h]h ]h"]h$]h&]uh1j;hj3ubh. A request is used to track the progress of the I/O overall and to hold on to resources. The collection of results is done at the request level. The I/O within a request is divided into a number of parallel streams of subrequests.}(hj3hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK6hj/ubah}(h]h ]h"]h$]h&]uh1j-hj*ubj.)}(huA *stream*. A non-overlapping series of subrequests. The subrequests within a stream do not have to be contiguous. h]h)}(htA *stream*. A non-overlapping series of subrequests. The subrequests within a stream do not have to be contiguous.h](hA }(hj_hhhNhNubj<)}(h*stream*h]hstream}(hjghhhNhNubah}(h]h ]h"]h$]h&]uh1j;hj_ubhj. A non-overlapping series of subrequests. The subrequests within a stream do not have to be contiguous.}(hj_hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK;hj[ubah}(h]h ]h"]h$]h&]uh1j-hj*ubj.)}(hA *subrequest*. This is the basic unit of I/O. It represents a single RPC call or a single cache I/O operation. The library passes these to the filesystem and the cache to perform. h]h)}(hA *subrequest*. This is the basic unit of I/O. It represents a single RPC call or a single cache I/O operation. The library passes these to the filesystem and the cache to perform.h](hA }(hjhhhNhNubj<)}(h *subrequest*h]h subrequest}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j;hjubh. This is the basic unit of I/O. It represents a single RPC call or a single cache I/O operation. The library passes these to the filesystem and the cache to perform.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK>hjubah}(h]h ]h"]h$]h&]uh1j-hj*ubeh}(h]h ]h"]h$]h&]bullet*uh1j(hhhK6hj$ubah}(h]h ]h"]h$]h&]uh1j"hhhK6hhhhubh)}(hhh](h)}(hRequests and Streamsh]hRequests and Streams}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKCubh)}(hWhen actually performing I/O (as opposed to just copying into the pagecache), netfslib will create one or more requests to track the progress of the I/O and to hold resources.h]hWhen actually performing I/O (as opposed to just copying into the pagecache), netfslib will create one or more requests to track the progress of the I/O and to hold resources.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKEhjhhubh)}(hA read operation will have a single stream and the subrequests within that stream may be of mixed origins, for instance mixing RPC subrequests and cache subrequests.h]hA read operation will have a single stream and the subrequests within that stream may be of mixed origins, for instance mixing RPC subrequests and cache subrequests.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKIhjhhubh)}(hXDOn the other hand, a write operation may have multiple streams, where each stream targets a different destination. For instance, there may be one stream writing to the local cache and one to the server. Currently, only two streams are allowed, but this could be increased if parallel writes to multiple servers is desired.h]hXDOn the other hand, a write operation may have multiple streams, where each stream targets a different destination. For instance, there may be one stream writing to the local cache and one to the server. Currently, only two streams are allowed, but this could be increased if parallel writes to multiple servers is desired.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKMhjhhubh)}(hX:The subrequests within a write stream do not need to match alignment or size with the subrequests in another write stream and netfslib performs the tiling of subrequests in each stream over the source buffer independently. Further, each stream may contain holes that don't correspond to holes in the other stream.h]hX<The subrequests within a write stream do not need to match alignment or size with the subrequests in another write stream and netfslib performs the tiling of subrequests in each stream over the source buffer independently. Further, each stream may contain holes that don’t correspond to holes in the other stream.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKShjhhubh)}(hIn addition, the subrequests do not need to correspond to the boundaries of the folios or vectors in the source/destination buffer. The library handles the collection of results and the wrangling of folio flags and references.h]hIn addition, the subrequests do not need to correspond to the boundaries of the folios or vectors in the source/destination buffer. The library handles the collection of results and the wrangling of folio flags and references.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKYhjhhubeh}(h]requests-and-streamsah ]h"]requests and streamsah$]h&]uh1hhhhhhhhKCubh)}(hhh](h)}(h Subrequestsh]h Subrequests}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK^ubh)}(hX'Subrequests are at the heart of the interaction between netfslib and the filesystem using it. Each subrequest is expected to correspond to a single read or write RPC or cache operation. The library will stitch together the results from a set of subrequests to provide a higher level operation.h]hX'Subrequests are at the heart of the interaction between netfslib and the filesystem using it. Each subrequest is expected to correspond to a single read or write RPC or cache operation. The library will stitch together the results from a set of subrequests to provide a higher level operation.}(hj-hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK`hjhhubh)}(hX}Netfslib has two interactions with the filesystem or the cache when setting up a subrequest. First, there's an optional preparatory step that allows the filesystem to negotiate the limits on the subrequest, both in terms of maximum number of bytes and maximum number of vectors (e.g. for RDMA). This may involve negotiating with the server (e.g. cifs needing to acquire credits).h]hXNetfslib has two interactions with the filesystem or the cache when setting up a subrequest. First, there’s an optional preparatory step that allows the filesystem to negotiate the limits on the subrequest, both in terms of maximum number of bytes and maximum number of vectors (e.g. for RDMA). This may involve negotiating with the server (e.g. cifs needing to acquire credits).}(hj;hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKehjhhubh)}(hkAnd, secondly, there's the issuing step in which the subrequest is handed off to the filesystem to perform.h]hmAnd, secondly, there’s the issuing step in which the subrequest is handed off to the filesystem to perform.}(hjIhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKkhjhhubh)}(hONote that these two steps are done slightly differently between read and write:h]hONote that these two steps are done slightly differently between read and write:}(hjWhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKnhjhhubj#)}(hX* For reads, the VM/VFS tells us how much is being requested up front, so the library can preset maximum values that the cache and then the filesystem can then reduce. The cache also gets consulted first on whether it wants to do a read before the filesystem is consulted. * For writeback, it is unknown how much there will be to write until the pagecache is walked, so no limit is set by the library. h]j))}(hhh](j.)}(hXFor reads, the VM/VFS tells us how much is being requested up front, so the library can preset maximum values that the cache and then the filesystem can then reduce. The cache also gets consulted first on whether it wants to do a read before the filesystem is consulted. h]h)}(hXFor reads, the VM/VFS tells us how much is being requested up front, so the library can preset maximum values that the cache and then the filesystem can then reduce. The cache also gets consulted first on whether it wants to do a read before the filesystem is consulted.h]hXFor reads, the VM/VFS tells us how much is being requested up front, so the library can preset maximum values that the cache and then the filesystem can then reduce. The cache also gets consulted first on whether it wants to do a read before the filesystem is consulted.}(hjphhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKphjlubah}(h]h ]h"]h$]h&]uh1j-hjiubj.)}(hFor writeback, it is unknown how much there will be to write until the pagecache is walked, so no limit is set by the library. h]h)}(h~For writeback, it is unknown how much there will be to write until the pagecache is walked, so no limit is set by the library.h]h~For writeback, it is unknown how much there will be to write until the pagecache is walked, so no limit is set by the library.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKuhjubah}(h]h ]h"]h$]h&]uh1j-hjiubeh}(h]h ]h"]h$]h&]jjuh1j(hhhKphjeubah}(h]h ]h"]h$]h&]uh1j"hhhKphjhhubh)}(hXOnce a subrequest is completed, the filesystem or cache informs the library of the completion and then collection is invoked. Depending on whether the request is synchronous or asynchronous, the collection of results will be done in either the application thread or in a work queue.h]hXOnce a subrequest is completed, the filesystem or cache informs the library of the completion and then collection is invoked. Depending on whether the request is synchronous or asynchronous, the collection of results will be done in either the application thread or in a work queue.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKxhjhhubeh}(h] subrequestsah ]h"] subrequestsah$]h&]uh1hhhhhhhhK^ubh)}(hhh](h)}(hResult Collection and Retryh]hResult Collection and Retry}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK~ubh)}(hXuAs subrequests complete, the results are collected and collated by the library and folio unlocking is performed progressively (if appropriate). Once the request is complete, async completion will be invoked (again, if appropriate). It is possible for the filesystem to provide interim progress reports to the library to cause folio unlocking to happen earlier if possible.h]hXuAs subrequests complete, the results are collected and collated by the library and folio unlocking is performed progressively (if appropriate). Once the request is complete, async completion will be invoked (again, if appropriate). It is possible for the filesystem to provide interim progress reports to the library to cause folio unlocking to happen earlier if possible.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hXIf any subrequests fail, netfslib can retry them. It will wait until all subrequests are completed, offer the filesystem the opportunity to fiddle with the resources/state held by the request and poke at the subrequests before re-preparing and re-issuing the subrequests.h]hXIf any subrequests fail, netfslib can retry them. It will wait until all subrequests are completed, offer the filesystem the opportunity to fiddle with the resources/state held by the request and poke at the subrequests before re-preparing and re-issuing the subrequests.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hThis allows the tiling of contiguous sets of failed subrequest within a stream to be changed, adding more subrequests or ditching excess as necessary (for instance, if the network sizes change or the server decides it wants smaller chunks).h]hThis allows the tiling of contiguous sets of failed subrequest within a stream to be changed, adding more subrequests or ditching excess as necessary (for instance, if the network sizes change or the server decides it wants smaller chunks).}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hFurther, if one or more contiguous cache-read subrequests fail, the library will pass them to the filesystem to perform instead, renegotiating and retiling them as necessary to fit with the filesystem's parameters rather than those of the cache.h]hFurther, if one or more contiguous cache-read subrequests fail, the library will pass them to the filesystem to perform instead, renegotiating and retiling them as necessary to fit with the filesystem’s parameters rather than those of the cache.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]result-collection-and-retryah ]h"]result collection and retryah$]h&]uh1hhhhhhhhK~ubh)}(hhh](h)}(h Local Cachingh]h Local Caching}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(hXEOne of the services netfslib provides, via ``fscache``, is the option to cache on local disk a copy of the data obtained from/written to a network filesystem. The library will manage the storing, retrieval and some invalidation of data automatically on behalf of the filesystem if a cookie is attached to the ``netfs_inode``.h](h+One of the services netfslib provides, via }(hj hhhNhNubhliteral)}(h ``fscache``h]hfscache}(hj*hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj ubh, is the option to cache on local disk a copy of the data obtained from/written to a network filesystem. The library will manage the storing, retrieval and some invalidation of data automatically on behalf of the filesystem if a cookie is attached to the }(hj hhhNhNubj))}(h``netfs_inode``h]h netfs_inode}(hj<hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj ubh.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hNote that local caching used to use the PG_private_2 (aliased as PG_fscache) to keep track of a page that was being written to the cache, but this is now deprecated as PG_private_2 will be removed.h]hNote that local caching used to use the PG_private_2 (aliased as PG_fscache) to keep track of a page that was being written to the cache, but this is now deprecated as PG_private_2 will be removed.}(hjThhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hXaInstead, folios that are read from the server for which there was no data in the cache will be marked as dirty and will have ``folio->private`` set to a special value (``NETFS_FOLIO_COPY_TO_CACHE``) and left to writeback to write. If the folio is modified before that happened, the special value will be cleared and the write will become normally dirty.h](h}Instead, folios that are read from the server for which there was no data in the cache will be marked as dirty and will have }(hjbhhhNhNubj))}(h``folio->private``h]hfolio->private}(hjjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjbubh set to a special value (}(hjbhhhNhNubj))}(h``NETFS_FOLIO_COPY_TO_CACHE``h]hNETFS_FOLIO_COPY_TO_CACHE}(hj|hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjbubh) and left to writeback to write. If the folio is modified before that happened, the special value will be cleared and the write will become normally dirty.}(hjbhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hX=When writeback occurs, folios that are so marked will only be written to the cache and not to the server. Writeback handles mixed cache-only writes and server-and-cache writes by using two streams, sending one to the cache and one to the server. The server stream will have gaps in it corresponding to those folios.h]hX=When writeback occurs, folios that are so marked will only be written to the cache and not to the server. Writeback handles mixed cache-only writes and server-and-cache writes by using two streams, sending one to the cache and one to the server. The server stream will have gaps in it corresponding to those folios.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h] local-cachingah ]h"] local cachingah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(hContent Encryption (fscrypt)h]hContent Encryption (fscrypt)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(hThough it does not do so yet, at some point netfslib will acquire the ability to do client-side content encryption on behalf of the network filesystem (Ceph, for example). fscrypt can be used for this if appropriate (it may not be - cifs, for example).h]hThough it does not do so yet, at some point netfslib will acquire the ability to do client-side content encryption on behalf of the network filesystem (Ceph, for example). fscrypt can be used for this if appropriate (it may not be - cifs, for example).}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hThe data will be stored encrypted in the local cache using the same manner of encryption as the data written to the server and the library will impose bounce buffering and RMW cycles as necessary.h]hThe data will be stored encrypted in the local cache using the same manner of encryption as the data written to the server and the library will impose bounce buffering and RMW cycles as necessary.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]content-encryption-fscryptah ]h"]content encryption (fscrypt)ah$]h&]uh1hhhhhhhhKubeh}(h]overviewah ]h"]overviewah$]h&]uh1hhhhhhhhK%ubh)}(hhh](h)}(hPer-Inode Contexth]hPer-Inode Context}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKubh)}(hThe network filesystem helper library needs a place to store a bit of state for its use on each netfs inode it is helping to manage. To this end, a context structure is defined::h]hThe network filesystem helper library needs a place to store a bit of state for its use on each netfs inode it is helping to manage. To this end, a context structure is defined:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh literal_block)}(hstruct netfs_inode { struct inode inode; const struct netfs_request_ops *ops; struct fscache_cookie * cache; loff_t remote_i_size; unsigned long flags; ... };h]hstruct netfs_inode { struct inode inode; const struct netfs_request_ops *ops; struct fscache_cookie * cache; loff_t remote_i_size; unsigned long flags; ... };}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhKhjhhubh)}(hA network filesystem that wants to use netfslib must place one of these in its inode wrapper struct instead of the VFS ``struct inode``. This can be done in a way similar to the following::h](hwA network filesystem that wants to use netfslib must place one of these in its inode wrapper struct instead of the VFS }(hjhhhNhNubj))}(h``struct inode``h]h struct inode}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubh6. This can be done in a way similar to the following:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj)}(hgstruct my_inode { struct netfs_inode netfs; /* Netfslib context and vfs inode */ ... };h]hgstruct my_inode { struct netfs_inode netfs; /* Netfslib context and vfs inode */ ... };}hj6sbah}(h]h ]h"]h$]h&]hhuh1jhhhKhjhhubh)}(hThis allows netfslib to find its state by using ``container_of()`` from the inode pointer, thereby allowing the netfslib helper functions to be pointed to directly by the VFS/VM operation tables.h](h0This allows netfslib to find its state by using }(hjDhhhNhNubj))}(h``container_of()``h]hcontainer_of()}(hjLhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjDubh from the inode pointer, thereby allowing the netfslib helper functions to be pointed to directly by the VFS/VM operation tables.}(hjDhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hSThe structure contains the following fields that are of interest to the filesystem:h]hSThe structure contains the following fields that are of interest to the filesystem:}(hjdhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj#)}(hX * ``inode`` The VFS inode structure. * ``ops`` The set of operations provided by the network filesystem to netfslib. * ``cache`` Local caching cookie, or NULL if no caching is enabled. This field does not exist if fscache is disabled. * ``remote_i_size`` The size of the file on the server. This differs from inode->i_size if local modifications have been made but not yet written back. * ``flags`` A set of flags, some of which the filesystem might be interested in: * ``NETFS_ICTX_MODIFIED_ATTR`` Set if netfslib modifies mtime/ctime. The filesystem is free to ignore this or clear it. * ``NETFS_ICTX_UNBUFFERED`` Do unbuffered I/O upon the file. Like direct I/O but without the alignment limitations. RMW will be performed if necessary. The pagecache will not be used unless mmap() is also used. * ``NETFS_ICTX_WRITETHROUGH`` Do writethrough caching upon the file. I/O will be set up and dispatched as buffered writes are made to the page cache. mmap() does the normal writeback thing. * ``NETFS_ICTX_SINGLE_NO_UPLOAD`` Set if the file has a monolithic content that must be read entirely in a single go and must not be written back to the server, though it can be cached (e.g. AFS directories). h]j))}(hhh](j.)}(h$``inode`` The VFS inode structure. h](h)}(h ``inode``h]j))}(hjh]hinode}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj}ubah}(h]h ]h"]h$]h&]uh1hhhhKhjyubh)}(hThe VFS inode structure.h]hThe VFS inode structure.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjyubeh}(h]h ]h"]h$]h&]uh1j-hjvubj.)}(hO``ops`` The set of operations provided by the network filesystem to netfslib. h](h)}(h``ops``h]j))}(hjh]hops}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhKhjubh)}(hEThe set of operations provided by the network filesystem to netfslib.h]hEThe set of operations provided by the network filesystem to netfslib.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubeh}(h]h ]h"]h$]h&]uh1j-hjvubj.)}(hv``cache`` Local caching cookie, or NULL if no caching is enabled. This field does not exist if fscache is disabled. h](h)}(h ``cache``h]j))}(hjh]hcache}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhKhjubh)}(hjLocal caching cookie, or NULL if no caching is enabled. This field does not exist if fscache is disabled.h]hjLocal caching cookie, or NULL if no caching is enabled. This field does not exist if fscache is disabled.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubeh}(h]h ]h"]h$]h&]uh1j-hjvubj.)}(h``remote_i_size`` The size of the file on the server. This differs from inode->i_size if local modifications have been made but not yet written back. h](h)}(h``remote_i_size``h]j))}(hj h]h remote_i_size}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj ubah}(h]h ]h"]h$]h&]uh1hhhhKhjubh)}(hThe size of the file on the server. This differs from inode->i_size if local modifications have been made but not yet written back.h]hThe size of the file on the server. This differs from inode->i_size if local modifications have been made but not yet written back.}(hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubeh}(h]h ]h"]h$]h&]uh1j-hjvubj.)}(hXN``flags`` A set of flags, some of which the filesystem might be interested in: * ``NETFS_ICTX_MODIFIED_ATTR`` Set if netfslib modifies mtime/ctime. The filesystem is free to ignore this or clear it. * ``NETFS_ICTX_UNBUFFERED`` Do unbuffered I/O upon the file. Like direct I/O but without the alignment limitations. RMW will be performed if necessary. The pagecache will not be used unless mmap() is also used. * ``NETFS_ICTX_WRITETHROUGH`` Do writethrough caching upon the file. I/O will be set up and dispatched as buffered writes are made to the page cache. mmap() does the normal writeback thing. * ``NETFS_ICTX_SINGLE_NO_UPLOAD`` Set if the file has a monolithic content that must be read entirely in a single go and must not be written back to the server, though it can be cached (e.g. AFS directories). h](h)}(h ``flags``h]j))}(hj;h]hflags}(hj=hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj9ubah}(h]h ]h"]h$]h&]uh1hhhhKhj5ubh)}(hDA set of flags, some of which the filesystem might be interested in:h]hDA set of flags, some of which the filesystem might be interested in:}(hjPhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj5ubj))}(hhh](j.)}(hx``NETFS_ICTX_MODIFIED_ATTR`` Set if netfslib modifies mtime/ctime. The filesystem is free to ignore this or clear it. h](h)}(h``NETFS_ICTX_MODIFIED_ATTR``h]j))}(hjgh]hNETFS_ICTX_MODIFIED_ATTR}(hjihhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjeubah}(h]h ]h"]h$]h&]uh1hhhhKhjaubh)}(hYSet if netfslib modifies mtime/ctime. The filesystem is free to ignore this or clear it.h]hYSet if netfslib modifies mtime/ctime. The filesystem is free to ignore this or clear it.}(hj|hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjaubeh}(h]h ]h"]h$]h&]uh1j-hj^ubj.)}(h``NETFS_ICTX_UNBUFFERED`` Do unbuffered I/O upon the file. Like direct I/O but without the alignment limitations. RMW will be performed if necessary. The pagecache will not be used unless mmap() is also used. h](h)}(h``NETFS_ICTX_UNBUFFERED``h]j))}(hjh]hNETFS_ICTX_UNBUFFERED}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhKhjubh)}(hDo unbuffered I/O upon the file. Like direct I/O but without the alignment limitations. RMW will be performed if necessary. The pagecache will not be used unless mmap() is also used.h]hDo unbuffered I/O upon the file. Like direct I/O but without the alignment limitations. RMW will be performed if necessary. The pagecache will not be used unless mmap() is also used.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubeh}(h]h ]h"]h$]h&]uh1j-hj^ubj.)}(h``NETFS_ICTX_WRITETHROUGH`` Do writethrough caching upon the file. I/O will be set up and dispatched as buffered writes are made to the page cache. mmap() does the normal writeback thing. h](h)}(h``NETFS_ICTX_WRITETHROUGH``h]j))}(hjh]hNETFS_ICTX_WRITETHROUGH}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhKhjubh)}(hDo writethrough caching upon the file. I/O will be set up and dispatched as buffered writes are made to the page cache. mmap() does the normal writeback thing.h]hDo writethrough caching upon the file. I/O will be set up and dispatched as buffered writes are made to the page cache. mmap() does the normal writeback thing.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjubeh}(h]h ]h"]h$]h&]uh1j-hj^ubj.)}(h``NETFS_ICTX_SINGLE_NO_UPLOAD`` Set if the file has a monolithic content that must be read entirely in a single go and must not be written back to the server, though it can be cached (e.g. AFS directories). h](h)}(h``NETFS_ICTX_SINGLE_NO_UPLOAD``h]j))}(hjh]hNETFS_ICTX_SINGLE_NO_UPLOAD}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhMhjubh)}(hSet if the file has a monolithic content that must be read entirely in a single go and must not be written back to the server, though it can be cached (e.g. AFS directories).h]hSet if the file has a monolithic content that must be read entirely in a single go and must not be written back to the server, though it can be cached (e.g. AFS directories).}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubeh}(h]h ]h"]h$]h&]uh1j-hj^ubeh}(h]h ]h"]h$]h&]jjuh1j(hhhKhj5ubeh}(h]h ]h"]h$]h&]uh1j-hjvubeh}(h]h ]h"]h$]h&]jjuh1j(hhhKhjrubah}(h]h ]h"]h$]h&]uh1j"hhhKhjhhubh)}(hhh](h)}(hInode Context Helper Functionsh]hInode Context Helper Functions}(hj8hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj5hhhhhM ubh)}(hTo help deal with the per-inode context, a number helper functions are provided. Firstly, a function to perform basic initialisation on a context and set the operations table pointer::h]hTo help deal with the per-inode context, a number helper functions are provided. Firstly, a function to perform basic initialisation on a context and set the operations table pointer:}(hjFhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM hj5hhubj)}(hjvoid netfs_inode_init(struct netfs_inode *ctx, const struct netfs_request_ops *ops);h]hjvoid netfs_inode_init(struct netfs_inode *ctx, const struct netfs_request_ops *ops);}hjTsbah}(h]h ]h"]h$]h&]hhuh1jhhhMhj5hhubh)}(hKthen a function to cast from the VFS inode structure to the netfs context::h]hJthen a function to cast from the VFS inode structure to the netfs context:}(hjbhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj5hhubj)}(h5struct netfs_inode *netfs_inode(struct inode *inode);h]h5struct netfs_inode *netfs_inode(struct inode *inode);}hjpsbah}(h]h ]h"]h$]h&]hhuh1jhhhMhj5hhubh)}(hand finally, a function to get the cache cookie pointer from the context attached to an inode (or NULL if fscache is disabled)::h]hand finally, a function to get the cache cookie pointer from the context attached to an inode (or NULL if fscache is disabled):}(hj~hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj5hhubj)}(h?struct fscache_cookie *netfs_i_cookie(struct netfs_inode *ctx);h]h?struct fscache_cookie *netfs_i_cookie(struct netfs_inode *ctx);}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhMhj5hhubeh}(h]inode-context-helper-functionsah ]h"]inode context helper functionsah$]h&]uh1hhjhhhhhM ubh)}(hhh](h)}(h Inode Lockingh]h Inode Locking}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMubh)}(hA number of functions are provided to manage the locking of i_rwsem for I/O and to effectively extend it to provide more separate classes of exclusion::h]hA number of functions are provided to manage the locking of i_rwsem for I/O and to effectively extend it to provide more separate classes of exclusion:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubj)}(hXint netfs_start_io_read(struct inode *inode); void netfs_end_io_read(struct inode *inode); int netfs_start_io_write(struct inode *inode); void netfs_end_io_write(struct inode *inode); int netfs_start_io_direct(struct inode *inode); void netfs_end_io_direct(struct inode *inode);h]hXint netfs_start_io_read(struct inode *inode); void netfs_end_io_read(struct inode *inode); int netfs_start_io_write(struct inode *inode); void netfs_end_io_write(struct inode *inode); int netfs_start_io_direct(struct inode *inode); void netfs_end_io_direct(struct inode *inode);}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhM!hjhhubh)}(h5The exclusion breaks down into four separate classes:h]h5The exclusion breaks down into four separate classes:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM(hjhhubj#)}(hX1) Buffered reads and writes. Buffered reads can run concurrently each other and with buffered writes, but buffered writes cannot run concurrently with each other. 2) Direct reads and writes. Direct (and unbuffered) reads and writes can run concurrently since they do not share local buffering (i.e. the pagecache) and, in a network filesystem, are expected to have exclusion managed on the server (though this may not be the case for, say, Ceph). 3) Other major inode modifying operations (e.g. truncate, fallocate). These should just access i_rwsem directly. 4) mmap(). mmap'd accesses might operate concurrently with any of the other classes. They might form the buffer for an intra-file loopback DIO read/write. They might be permitted on unbuffered files. h]henumerated_list)}(hhh](j.)}(hBuffered reads and writes. Buffered reads can run concurrently each other and with buffered writes, but buffered writes cannot run concurrently with each other. h](h)}(hBuffered reads and writes.h]hBuffered reads and writes.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM*hjubh)}(hBuffered reads can run concurrently each other and with buffered writes, but buffered writes cannot run concurrently with each other.h]hBuffered reads can run concurrently each other and with buffered writes, but buffered writes cannot run concurrently with each other.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM,hjubeh}(h]h ]h"]h$]h&]uh1j-hjubj.)}(hXDirect reads and writes. Direct (and unbuffered) reads and writes can run concurrently since they do not share local buffering (i.e. the pagecache) and, in a network filesystem, are expected to have exclusion managed on the server (though this may not be the case for, say, Ceph). h](h)}(hDirect reads and writes.h]hDirect reads and writes.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM/hj ubh)}(hDirect (and unbuffered) reads and writes can run concurrently since they do not share local buffering (i.e. the pagecache) and, in a network filesystem, are expected to have exclusion managed on the server (though this may not be the case for, say, Ceph).h]hDirect (and unbuffered) reads and writes can run concurrently since they do not share local buffering (i.e. the pagecache) and, in a network filesystem, are expected to have exclusion managed on the server (though this may not be the case for, say, Ceph).}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM1hj ubeh}(h]h ]h"]h$]h&]uh1j-hjubj.)}(hoOther major inode modifying operations (e.g. truncate, fallocate). These should just access i_rwsem directly. h](h)}(hBOther major inode modifying operations (e.g. truncate, fallocate).h]hBOther major inode modifying operations (e.g. truncate, fallocate).}(hj6hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM6hj2ubh)}(h*These should just access i_rwsem directly.h]h*These should just access i_rwsem directly.}(hjDhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM8hj2ubeh}(h]h ]h"]h$]h&]uh1j-hjubj.)}(hmmap(). mmap'd accesses might operate concurrently with any of the other classes. They might form the buffer for an intra-file loopback DIO read/write. They might be permitted on unbuffered files. h](h)}(hmmap().h]hmmap().}(hj\hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM:hjXubh)}(hmmap'd accesses might operate concurrently with any of the other classes. They might form the buffer for an intra-file loopback DIO read/write. They might be permitted on unbuffered files.h]hmmap’d accesses might operate concurrently with any of the other classes. They might form the buffer for an intra-file loopback DIO read/write. They might be permitted on unbuffered files.}(hjjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM<hjXubeh}(h]h ]h"]h$]h&]uh1j-hjubeh}(h]h ]h"]h$]h&]enumtypearabicprefixhsuffix)uh1jhjubah}(h]h ]h"]h$]h&]uh1j"hhhM*hjhhubeh}(h] inode-lockingah ]h"] inode lockingah$]h&]uh1hhjhhhhhMubh)}(hhh](h)}(hInode Writebackh]hInode Writeback}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMAubh)}(hNetfslib will pin resources on an inode for future writeback (such as pinning use of an fscache cookie) when an inode is dirtied. However, this pinning needs careful management. To manage the pinning, the following sequence occurs:h]hNetfslib will pin resources on an inode for future writeback (such as pinning use of an fscache cookie) when an inode is dirtied. However, this pinning needs careful management. To manage the pinning, the following sequence occurs:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMChjhhubj#)}(hX1) An inode state flag ``I_PINNING_NETFS_WB`` is set by netfslib when the pinning begins (when a folio is dirtied, for example) if the cache is active to stop the cache structures from being discarded and the cache space from being culled. This also prevents re-getting of cache resources if the flag is already set. 2) This flag then cleared inside the inode lock during inode writeback in the VM - and the fact that it was set is transferred to ``->unpinned_netfs_wb`` in ``struct writeback_control``. 3) If ``->unpinned_netfs_wb`` is now set, the write_inode procedure is forced. 4) The filesystem's ``->write_inode()`` function is invoked to do the cleanup. 5) The filesystem invokes netfs to do its cleanup. h]j)}(hhh](j.)}(hX;An inode state flag ``I_PINNING_NETFS_WB`` is set by netfslib when the pinning begins (when a folio is dirtied, for example) if the cache is active to stop the cache structures from being discarded and the cache space from being culled. This also prevents re-getting of cache resources if the flag is already set. h]h)}(hX:An inode state flag ``I_PINNING_NETFS_WB`` is set by netfslib when the pinning begins (when a folio is dirtied, for example) if the cache is active to stop the cache structures from being discarded and the cache space from being culled. This also prevents re-getting of cache resources if the flag is already set.h](hAn inode state flag }(hjhhhNhNubj))}(h``I_PINNING_NETFS_WB``h]hI_PINNING_NETFS_WB}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubhX is set by netfslib when the pinning begins (when a folio is dirtied, for example) if the cache is active to stop the cache structures from being discarded and the cache space from being culled. This also prevents re-getting of cache resources if the flag is already set.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMHhjubah}(h]h ]h"]h$]h&]uh1j-hjubj.)}(hThis flag then cleared inside the inode lock during inode writeback in the VM - and the fact that it was set is transferred to ``->unpinned_netfs_wb`` in ``struct writeback_control``. h]h)}(hThis flag then cleared inside the inode lock during inode writeback in the VM - and the fact that it was set is transferred to ``->unpinned_netfs_wb`` in ``struct writeback_control``.h](hThis flag then cleared inside the inode lock during inode writeback in the VM - and the fact that it was set is transferred to }(hjhhhNhNubj))}(h``->unpinned_netfs_wb``h]h->unpinned_netfs_wb}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubh in }(hjhhhNhNubj))}(h``struct writeback_control``h]hstruct writeback_control}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMNhjubah}(h]h ]h"]h$]h&]uh1j-hjubj.)}(hLIf ``->unpinned_netfs_wb`` is now set, the write_inode procedure is forced. h]h)}(hKIf ``->unpinned_netfs_wb`` is now set, the write_inode procedure is forced.h](hIf }(hj'hhhNhNubj))}(h``->unpinned_netfs_wb``h]h->unpinned_netfs_wb}(hj/hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj'ubh1 is now set, the write_inode procedure is forced.}(hj'hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMRhj#ubah}(h]h ]h"]h$]h&]uh1j-hjubj.)}(hLThe filesystem's ``->write_inode()`` function is invoked to do the cleanup. h]h)}(hKThe filesystem's ``->write_inode()`` function is invoked to do the cleanup.h](hThe filesystem’s }(hjQhhhNhNubj))}(h``->write_inode()``h]h->write_inode()}(hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjQubh' function is invoked to do the cleanup.}(hjQhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMThjMubah}(h]h ]h"]h$]h&]uh1j-hjubj.)}(h0The filesystem invokes netfs to do its cleanup. h]h)}(h/The filesystem invokes netfs to do its cleanup.h]h/The filesystem invokes netfs to do its cleanup.}(hj{hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMVhjwubah}(h]h ]h"]h$]h&]uh1j-hjubeh}(h]h ]h"]h$]h&]jjjhjjuh1jhjubah}(h]h ]h"]h$]h&]uh1j"hhhMHhjhhubh)}(hNTo do the cleanup, netfslib provides a function to do the resource unpinning::h]hMTo do the cleanup, netfslib provides a function to do the resource unpinning:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMXhjhhubj)}(hNint netfs_unpin_writeback(struct inode *inode, struct writeback_control *wbc);h]hNint netfs_unpin_writeback(struct inode *inode, struct writeback_control *wbc);}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhMZhjhhubh)}(heIf the filesystem doesn't need to do anything else, this may be set as a its ``.write_inode`` method.h](hOIf the filesystem doesn’t need to do anything else, this may be set as a its }(hjhhhNhNubj))}(h``.write_inode``h]h .write_inode}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubh method.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM\hjhhubh)}(h]Further, if an inode is deleted, the filesystem's write_inode method may not get called, so::h]h^Further, if an inode is deleted, the filesystem’s write_inode method may not get called, so:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM_hjhhubj)}(hGvoid netfs_clear_inode_writeback(struct inode *inode, const void *aux);h]hGvoid netfs_clear_inode_writeback(struct inode *inode, const void *aux);}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhMbhjhhubh)}(hMmust be called from ``->evict_inode()`` *before* ``clear_inode()`` is called.h](hmust be called from }(hjhhhNhNubj))}(h``->evict_inode()``h]h->evict_inode()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubh }(hjhhhNhNubj<)}(h*before*h]hbefore}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j;hjubh }hjsbj))}(h``clear_inode()``h]h clear_inode()}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubh is called.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMdhjhhubeh}(h]inode-writebackah ]h"]inode writebackah$]h&]uh1hhjhhhhhMAubeh}(h]per-inode-contextah ]h"]per-inode contextah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(hHigh-Level VFS APIh]hHigh-Level VFS API}(hjJ hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjG hhhhhMhubh)}(hNetfslib provides a number of sets of API calls for the filesystem to delegate VFS operations to. Netfslib, in turn, will call out to the filesystem and the cache to negotiate I/O sizes, issue RPCs and provide places for it to intervene at various times.h]hNetfslib provides a number of sets of API calls for the filesystem to delegate VFS operations to. Netfslib, in turn, will call out to the filesystem and the cache to negotiate I/O sizes, issue RPCs and provide places for it to intervene at various times.}(hjX hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMjhjG hhubh)}(hhh](h)}(hUnlocked Read/Write Iterh]hUnlocked Read/Write Iter}(hji hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjf hhhhhMpubh)}(hThe first API set is for the delegation of operations to netfslib when the filesystem is called through the standard VFS read/write_iter methods::h]hThe first API set is for the delegation of operations to netfslib when the filesystem is called through the standard VFS read/write_iter methods:}(hjw hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMrhjf hhubj)}(hX~ssize_t netfs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter); ssize_t netfs_file_write_iter(struct kiocb *iocb, struct iov_iter *from); ssize_t netfs_buffered_read_iter(struct kiocb *iocb, struct iov_iter *iter); ssize_t netfs_unbuffered_read_iter(struct kiocb *iocb, struct iov_iter *iter); ssize_t netfs_unbuffered_write_iter(struct kiocb *iocb, struct iov_iter *from);h]hX~ssize_t netfs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter); ssize_t netfs_file_write_iter(struct kiocb *iocb, struct iov_iter *from); ssize_t netfs_buffered_read_iter(struct kiocb *iocb, struct iov_iter *iter); ssize_t netfs_unbuffered_read_iter(struct kiocb *iocb, struct iov_iter *iter); ssize_t netfs_unbuffered_write_iter(struct kiocb *iocb, struct iov_iter *from);}hj sbah}(h]h ]h"]h$]h&]hhuh1jhhhMuhjf hhubh)}(hThey can be assigned directly to ``.read_iter`` and ``.write_iter``. They perform the inode locking themselves and the first two will switch between buffered I/O and DIO as appropriate.h](h!They can be assigned directly to }(hj hhhNhNubj))}(h``.read_iter``h]h .read_iter}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj ubh and }(hj hhhNhNubj))}(h``.write_iter``h]h .write_iter}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj ubhw. They perform the inode locking themselves and the first two will switch between buffered I/O and DIO as appropriate.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM{hjf hhubeh}(h]unlocked-read-write-iterah ]h"]unlocked read/write iterah$]h&]uh1hhjG hhhhhMpubh)}(hhh](h)}(hPre-Locked Read/Write Iterh]hPre-Locked Read/Write Iter}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhMubh)}(hX(The second API set is for the delegation of operations to netfslib when the filesystem is called through the standard VFS methods, but needs to do some other stuff before or after calling netfslib whilst still inside locked section (e.g. Ceph negotiating caps). The unbuffered read function is::h]hX'The second API set is for the delegation of operations to netfslib when the filesystem is called through the standard VFS methods, but needs to do some other stuff before or after calling netfslib whilst still inside locked section (e.g. Ceph negotiating caps). The unbuffered read function is:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubj)}(hUssize_t netfs_unbuffered_read_iter_locked(struct kiocb *iocb, struct iov_iter *iter);h]hUssize_t netfs_unbuffered_read_iter_locked(struct kiocb *iocb, struct iov_iter *iter);}hj sbah}(h]h ]h"]h$]h&]hhuh1jhhhMhj hhubh)}(hThis must not be assigned directly to ``.read_iter`` and the filesystem is responsible for performing the inode locking before calling it. In the case of buffered read, the filesystem should use ``filemap_read()``.h](h&This must not be assigned directly to }(hj hhhNhNubj))}(h``.read_iter``h]h .read_iter}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj ubh and the filesystem is responsible for performing the inode locking before calling it. In the case of buffered read, the filesystem should use }(hj hhhNhNubj))}(h``filemap_read()``h]hfilemap_read()}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj ubh.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj hhubh)}(h&There are three functions for writes::h]h%There are three functions for writes:}(hj, hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubj)}(hXssize_t netfs_buffered_write_iter_locked(struct kiocb *iocb, struct iov_iter *from, struct netfs_group *netfs_group); ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter, struct netfs_group *netfs_group); ssize_t netfs_unbuffered_write_iter_locked(struct kiocb *iocb, struct iov_iter *iter, struct netfs_group *netfs_group);h]hXssize_t netfs_buffered_write_iter_locked(struct kiocb *iocb, struct iov_iter *from, struct netfs_group *netfs_group); ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter, struct netfs_group *netfs_group); ssize_t netfs_unbuffered_write_iter_locked(struct kiocb *iocb, struct iov_iter *iter, struct netfs_group *netfs_group);}hj: sbah}(h]h ]h"]h$]h&]hhuh1jhhhMhj hhubh)}(hThese must not be assigned directly to ``.write_iter`` and the filesystem is responsible for performing the inode locking before calling them.h](h'These must not be assigned directly to }(hjH hhhNhNubj))}(h``.write_iter``h]h .write_iter}(hjP hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjH ubhX and the filesystem is responsible for performing the inode locking before calling them.}(hjH hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj hhubh)}(hXThe first two functions are for buffered writes; the first just adds some standard write checks and jumps to the second, but if the filesystem wants to do the checks itself, it can use the second directly. The third function is for unbuffered or DIO writes.h]hXThe first two functions are for buffered writes; the first just adds some standard write checks and jumps to the second, but if the filesystem wants to do the checks itself, it can use the second directly. The third function is for unbuffered or DIO writes.}(hjh hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubh)}(hXLOn all three write functions, there is a writeback group pointer (which should be NULL if the filesystem doesn't use this). Writeback groups are set on folios when they're modified. If a folio to-be-modified is already marked with a different group, it is flushed first. The writeback API allows writing back of a specific group.h]hXPOn all three write functions, there is a writeback group pointer (which should be NULL if the filesystem doesn’t use this). Writeback groups are set on folios when they’re modified. If a folio to-be-modified is already marked with a different group, it is flushed first. The writeback API allows writing back of a specific group.}(hjv hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubeh}(h]pre-locked-read-write-iterah ]h"]pre-locked read/write iterah$]h&]uh1hhjG hhhhhMubh)}(hhh](h)}(hMemory-Mapped I/O APIh]hMemory-Mapped I/O API}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhMubh)}(h0An API for support of mmap()'d I/O is provided::h]h1An API for support of mmap()’d I/O is provided:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubj)}(hUvm_fault_t netfs_page_mkwrite(struct vm_fault *vmf, struct netfs_group *netfs_group);h]hUvm_fault_t netfs_page_mkwrite(struct vm_fault *vmf, struct netfs_group *netfs_group);}hj sbah}(h]h ]h"]h$]h&]hhuh1jhhhMhj hhubh)}(hX4This allows the filesystem to delegate ``.page_mkwrite`` to netfslib. The filesystem should not take the inode lock before calling it, but, as with the locked write functions above, this does take a writeback group pointer. If the page to be made writable is in a different group, it will be flushed first.h](h'This allows the filesystem to delegate }(hj hhhNhNubj))}(h``.page_mkwrite``h]h .page_mkwrite}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj ubh to netfslib. The filesystem should not take the inode lock before calling it, but, as with the locked write functions above, this does take a writeback group pointer. If the page to be made writable is in a different group, it will be flushed first.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj hhubeh}(h]memory-mapped-i-o-apiah ]h"]memory-mapped i/o apiah$]h&]uh1hhjG hhhhhMubh)}(hhh](h)}(hMonolithic Files APIh]hMonolithic Files API}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhMubh)}(hThere is also a special API set for files for which the content must be read in a single RPC (and not written back) and is maintained as a monolithic blob (e.g. an AFS directory), though it can be stored and updated in the local cache::h]hThere is also a special API set for files for which the content must be read in a single RPC (and not written back) and is maintained as a monolithic blob (e.g. an AFS directory), though it can be stored and updated in the local cache:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubj)}(hX9ssize_t netfs_read_single(struct inode *inode, struct file *file, struct iov_iter *iter); void netfs_single_mark_inode_dirty(struct inode *inode); int netfs_writeback_single(struct address_space *mapping, struct writeback_control *wbc, struct iov_iter *iter);h]hX9ssize_t netfs_read_single(struct inode *inode, struct file *file, struct iov_iter *iter); void netfs_single_mark_inode_dirty(struct inode *inode); int netfs_writeback_single(struct address_space *mapping, struct writeback_control *wbc, struct iov_iter *iter);}hj sbah}(h]h ]h"]h$]h&]hhuh1jhhhMhj hhubh)}(hX?The first function reads from a file into the given buffer, reading from the cache in preference if the data is cached there; the second function allows the inode to be marked dirty, causing a later writeback; and the third function can be called from the writeback code to write the data to the cache, if there is one.h]hX?The first function reads from a file into the given buffer, reading from the cache in preference if the data is cached there; the second function allows the inode to be marked dirty, causing a later writeback; and the third function can be called from the writeback code to write the data to the cache, if there is one.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubh)}(hThe inode should be marked ``NETFS_ICTX_SINGLE_NO_UPLOAD`` if this API is to be used. The writeback function requires the buffer to be of ITER_FOLIOQ type.h](hThe inode should be marked }(hj hhhNhNubj))}(h``NETFS_ICTX_SINGLE_NO_UPLOAD``h]hNETFS_ICTX_SINGLE_NO_UPLOAD}(hj$ hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj ubhb if this API is to be used. The writeback function requires the buffer to be of ITER_FOLIOQ type.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj hhubeh}(h]monolithic-files-apiah ]h"]monolithic files apiah$]h&]uh1hhjG hhhhhMubeh}(h]high-level-vfs-apiah ]h"]high-level vfs apiah$]h&]uh1hhhhhhhhMhubh)}(hhh](h)}(hHigh-Level VM APIh]hHigh-Level VM API}(hjO hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjL hhhhhMubh)}(hX Netfslib also provides a number of sets of API calls for the filesystem to delegate VM operations to. Again, netfslib, in turn, will call out to the filesystem and the cache to negotiate I/O sizes, issue RPCs and provide places for it to intervene at various times::h]hX Netfslib also provides a number of sets of API calls for the filesystem to delegate VM operations to. Again, netfslib, in turn, will call out to the filesystem and the cache to negotiate I/O sizes, issue RPCs and provide places for it to intervene at various times:}(hj] hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjL hhubj)}(hXvoid netfs_readahead(struct readahead_control *); int netfs_read_folio(struct file *, struct folio *); int netfs_writepages(struct address_space *mapping, struct writeback_control *wbc); bool netfs_dirty_folio(struct address_space *mapping, struct folio *folio); void netfs_invalidate_folio(struct folio *folio, size_t offset, size_t length); bool netfs_release_folio(struct folio *folio, gfp_t gfp);h]hXvoid netfs_readahead(struct readahead_control *); int netfs_read_folio(struct file *, struct folio *); int netfs_writepages(struct address_space *mapping, struct writeback_control *wbc); bool netfs_dirty_folio(struct address_space *mapping, struct folio *folio); void netfs_invalidate_folio(struct folio *folio, size_t offset, size_t length); bool netfs_release_folio(struct folio *folio, gfp_t gfp);}hjk sbah}(h]h ]h"]h$]h&]hhuh1jhhhMhjL hhubh)}(h_These are ``address_space_operations`` methods and can be set directly in the operations table.h](h These are }(hjy hhhNhNubj))}(h``address_space_operations``h]haddress_space_operations}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjy ubh9 methods and can be set directly in the operations table.}(hjy hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjL hhubh)}(hhh](h)}(hDeprecated PG_private_2 APIh]hDeprecated PG_private_2 API}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhMubh)}(haThere is also a deprecated function for filesystems that still use the ``->write_begin`` method::h](hGThere is also a deprecated function for filesystems that still use the }(hj hhhNhNubj))}(h``->write_begin``h]h ->write_begin}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj ubh method:}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj hhubj)}(hint netfs_write_begin(struct netfs_inode *inode, struct file *file, struct address_space *mapping, loff_t pos, unsigned int len, struct folio **_folio, void **_fsdata);h]hint netfs_write_begin(struct netfs_inode *inode, struct file *file, struct address_space *mapping, loff_t pos, unsigned int len, struct folio **_folio, void **_fsdata);}hj sbah}(h]h ]h"]h$]h&]hhuh1jhhhMhj hhubh)}(hCIt uses the deprecated PG_private_2 flag and so should not be used.h]hCIt uses the deprecated PG_private_2 flag and so should not be used.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubeh}(h]deprecated-pg-private-2-apiah ]h"]deprecated pg_private_2 apiah$]h&]uh1hhjL hhhhhMubeh}(h]high-level-vm-apiah ]h"]high-level vm apiah$]h&]uh1hhhhhhhhMubh)}(hhh](h)}(hI/O Request APIh]hI/O Request API}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhMubh)}(hsThe I/O request API comprises a number of structures and a number of functions that the filesystem may need to use.h]hsThe I/O request API comprises a number of structures and a number of functions that the filesystem may need to use.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubh)}(hhh](h)}(hRequest Structureh]hRequest Structure}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhMubh)}(hThe request structure manages the request as a whole, holding some resources and state on behalf of the filesystem and tracking the collection of results::h]hThe request structure manages the request as a whole, holding some resources and state on behalf of the filesystem and tracking the collection of results:}(hj& hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubj)}(hXstruct netfs_io_request { enum netfs_io_origin origin; struct inode *inode; struct address_space *mapping; struct netfs_group *group; struct netfs_io_stream io_streams[]; void *netfs_priv; void *netfs_priv2; unsigned long long start; unsigned long long len; unsigned long long i_size; unsigned int debug_id; unsigned long flags; ... };h]hXstruct netfs_io_request { enum netfs_io_origin origin; struct inode *inode; struct address_space *mapping; struct netfs_group *group; struct netfs_io_stream io_streams[]; void *netfs_priv; void *netfs_priv2; unsigned long long start; unsigned long long len; unsigned long long i_size; unsigned int debug_id; unsigned long flags; ... };}hj4 sbah}(h]h ]h"]h$]h&]hhuh1jhhhMhj hhubh)}(heMany of the fields are for internal use, but the fields shown here are of interest to the filesystem:h]heMany of the fields are for internal use, but the fields shown here are of interest to the filesystem:}(hjB hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubj#)}(hXh* ``origin`` The origin of the request (readahead, read_folio, DIO read, writeback, ...). * ``inode`` * ``mapping`` The inode and the address space of the file being read from. The mapping may or may not point to inode->i_data. * ``group`` The writeback group this request is dealing with or NULL. This holds a ref on the group. * ``io_streams`` The parallel streams of subrequests available to the request. Currently two are available, but this may be made extensible in future. ``NR_IO_STREAMS`` indicates the size of the array. * ``netfs_priv`` * ``netfs_priv2`` The network filesystem's private data. The value for this can be passed in to the helper functions or set during the request. * ``start`` * ``len`` The file position of the start of the read request and the length. These may be altered by the ->expand_readahead() op. * ``i_size`` The size of the file at the start of the request. * ``debug_id`` A number allocated to this operation that can be displayed in trace lines for reference. * ``flags`` Flags for managing and controlling the operation of the request. Some of these may be of interest to the filesystem: * ``NETFS_RREQ_RETRYING`` Netfslib sets this when generating retries. * ``NETFS_RREQ_PAUSE`` The filesystem can set this to request to pause the library's subrequest issuing loop - but care needs to be taken as netfslib may also set it. * ``NETFS_RREQ_NONBLOCK`` * ``NETFS_RREQ_BLOCKED`` Netfslib sets the first to indicate that non-blocking mode was set by the caller and the filesystem can set the second to indicate that it would have had to block. * ``NETFS_RREQ_USE_PGPRIV2`` The filesystem can set this if it wants to use PG_private_2 to track whether a folio is being written to the cache. This is deprecated as PG_private_2 is going to go away. h]j))}(hhh](j.)}(hY``origin`` The origin of the request (readahead, read_folio, DIO read, writeback, ...). h](h)}(h ``origin``h]j))}(hj] h]horigin}(hj_ hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj[ ubah}(h]h ]h"]h$]h&]uh1hhhhMhjW ubh)}(hLThe origin of the request (readahead, read_folio, DIO read, writeback, ...).h]hLThe origin of the request (readahead, read_folio, DIO read, writeback, ...).}(hjr hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjW ubeh}(h]h ]h"]h$]h&]uh1j-hjT ubj.)}(h ``inode``h]h)}(hj h]j))}(hj h]hinode}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj ubah}(h]h ]h"]h$]h&]uh1hhhhM hj ubah}(h]h ]h"]h$]h&]uh1j-hjT ubj.)}(h~``mapping`` The inode and the address space of the file being read from. The mapping may or may not point to inode->i_data. h](h)}(h ``mapping``h]j))}(hj h]hmapping}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj ubah}(h]h ]h"]h$]h&]uh1hhhhM hj ubh)}(hpThe inode and the address space of the file being read from. The mapping may or may not point to inode->i_data.h]hpThe inode and the address space of the file being read from. The mapping may or may not point to inode->i_data.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM hj ubeh}(h]h ]h"]h$]h&]uh1j-hjT ubj.)}(he``group`` The writeback group this request is dealing with or NULL. This holds a ref on the group. h](h)}(h ``group``h]j))}(hj h]hgroup}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj ubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubh)}(hYThe writeback group this request is dealing with or NULL. This holds a ref on the group.h]hYThe writeback group this request is dealing with or NULL. This holds a ref on the group.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubeh}(h]h ]h"]h$]h&]uh1j-hjT ubj.)}(h``io_streams`` The parallel streams of subrequests available to the request. Currently two are available, but this may be made extensible in future. ``NR_IO_STREAMS`` indicates the size of the array. h](h)}(h``io_streams``h]j))}(hj h]h io_streams}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj ubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubh)}(hThe parallel streams of subrequests available to the request. Currently two are available, but this may be made extensible in future. ``NR_IO_STREAMS`` indicates the size of the array.h](hThe parallel streams of subrequests available to the request. Currently two are available, but this may be made extensible in future. }(hj hhhNhNubj))}(h``NR_IO_STREAMS``h]h NR_IO_STREAMS}(hj' hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj ubh! indicates the size of the array.}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj ubeh}(h]h ]h"]h$]h&]uh1j-hjT ubj.)}(h``netfs_priv``h]h)}(hjG h]j))}(hjG h]h netfs_priv}(hjL hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjI ubah}(h]h ]h"]h$]h&]uh1hhhhMhjE ubah}(h]h ]h"]h$]h&]uh1j-hjT ubj.)}(h``netfs_priv2`` The network filesystem's private data. The value for this can be passed in to the helper functions or set during the request. h](h)}(h``netfs_priv2``h]j))}(hjk h]h netfs_priv2}(hjm hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hji ubah}(h]h ]h"]h$]h&]uh1hhhhMhje ubh)}(h~The network filesystem's private data. The value for this can be passed in to the helper functions or set during the request.h]hThe network filesystem’s private data. The value for this can be passed in to the helper functions or set during the request.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhje ubeh}(h]h ]h"]h$]h&]uh1j-hjT ubj.)}(h ``start``h]h)}(hj h]j))}(hj h]hstart}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj ubah}(h]h ]h"]h$]h&]uh1hhhhM hj ubah}(h]h ]h"]h$]h&]uh1j-hjT ubj.)}(h``len`` The file position of the start of the read request and the length. These may be altered by the ->expand_readahead() op. h](h)}(h``len``h]j))}(hj h]hlen}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj ubah}(h]h ]h"]h$]h&]uh1hhhhM!hj ubh)}(hxThe file position of the start of the read request and the length. These may be altered by the ->expand_readahead() op.h]hxThe file position of the start of the read request and the length. These may be altered by the ->expand_readahead() op.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM#hj ubeh}(h]h ]h"]h$]h&]uh1j-hjT ubj.)}(h>``i_size`` The size of the file at the start of the request. h](h)}(h ``i_size``h]j))}(hj h]hi_size}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj ubah}(h]h ]h"]h$]h&]uh1hhhhM&hj ubh)}(h1The size of the file at the start of the request.h]h1The size of the file at the start of the request.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM(hj ubeh}(h]h ]h"]h$]h&]uh1j-hjT ubj.)}(hg``debug_id`` A number allocated to this operation that can be displayed in trace lines for reference. h](h)}(h ``debug_id``h]j))}(hjh]hdebug_id}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhM*hjubh)}(hXA number allocated to this operation that can be displayed in trace lines for reference.h]hXA number allocated to this operation that can be displayed in trace lines for reference.}(hj-hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM,hjubeh}(h]h ]h"]h$]h&]uh1j-hjT ubj.)}(hX)``flags`` Flags for managing and controlling the operation of the request. Some of these may be of interest to the filesystem: * ``NETFS_RREQ_RETRYING`` Netfslib sets this when generating retries. * ``NETFS_RREQ_PAUSE`` The filesystem can set this to request to pause the library's subrequest issuing loop - but care needs to be taken as netfslib may also set it. * ``NETFS_RREQ_NONBLOCK`` * ``NETFS_RREQ_BLOCKED`` Netfslib sets the first to indicate that non-blocking mode was set by the caller and the filesystem can set the second to indicate that it would have had to block. * ``NETFS_RREQ_USE_PGPRIV2`` The filesystem can set this if it wants to use PG_private_2 to track whether a folio is being written to the cache. This is deprecated as PG_private_2 is going to go away. h](h)}(h ``flags``h]j))}(hjGh]hflags}(hjIhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjEubah}(h]h ]h"]h$]h&]uh1hhhhM/hjAubh)}(huFlags for managing and controlling the operation of the request. Some of these may be of interest to the filesystem:h]huFlags for managing and controlling the operation of the request. Some of these may be of interest to the filesystem:}(hj\hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM1hjAubj))}(hhh](j.)}(hE``NETFS_RREQ_RETRYING`` Netfslib sets this when generating retries. h](h)}(h``NETFS_RREQ_RETRYING``h]j))}(hjsh]hNETFS_RREQ_RETRYING}(hjuhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjqubah}(h]h ]h"]h$]h&]uh1hhhhM4hjmubh)}(h+Netfslib sets this when generating retries.h]h+Netfslib sets this when generating retries.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM6hjmubeh}(h]h ]h"]h$]h&]uh1j-hjjubj.)}(h``NETFS_RREQ_PAUSE`` The filesystem can set this to request to pause the library's subrequest issuing loop - but care needs to be taken as netfslib may also set it. h](h)}(h``NETFS_RREQ_PAUSE``h]j))}(hjh]hNETFS_RREQ_PAUSE}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhM8hjubh)}(hThe filesystem can set this to request to pause the library's subrequest issuing loop - but care needs to be taken as netfslib may also set it.h]hThe filesystem can set this to request to pause the library’s subrequest issuing loop - but care needs to be taken as netfslib may also set it.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM:hjubeh}(h]h ]h"]h$]h&]uh1j-hjjubj.)}(h``NETFS_RREQ_NONBLOCK``h]h)}(hjh]j))}(hjh]hNETFS_RREQ_NONBLOCK}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhM=hjubah}(h]h ]h"]h$]h&]uh1j-hjjubj.)}(h``NETFS_RREQ_BLOCKED`` Netfslib sets the first to indicate that non-blocking mode was set by the caller and the filesystem can set the second to indicate that it would have had to block. h](h)}(h``NETFS_RREQ_BLOCKED``h]j))}(hjh]hNETFS_RREQ_BLOCKED}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhM>hjubh)}(hNetfslib sets the first to indicate that non-blocking mode was set by the caller and the filesystem can set the second to indicate that it would have had to block.h]hNetfslib sets the first to indicate that non-blocking mode was set by the caller and the filesystem can set the second to indicate that it would have had to block.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM@hjubeh}(h]h ]h"]h$]h&]uh1j-hjjubj.)}(h``NETFS_RREQ_USE_PGPRIV2`` The filesystem can set this if it wants to use PG_private_2 to track whether a folio is being written to the cache. This is deprecated as PG_private_2 is going to go away. h](h)}(h``NETFS_RREQ_USE_PGPRIV2``h]j))}(hj h]hNETFS_RREQ_USE_PGPRIV2}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhMDhjubh)}(hThe filesystem can set this if it wants to use PG_private_2 to track whether a folio is being written to the cache. This is deprecated as PG_private_2 is going to go away.h]hThe filesystem can set this if it wants to use PG_private_2 to track whether a folio is being written to the cache. This is deprecated as PG_private_2 is going to go away.}(hj5hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMFhjubeh}(h]h ]h"]h$]h&]uh1j-hjjubeh}(h]h ]h"]h$]h&]jjuh1j(hhhM4hjAubeh}(h]h ]h"]h$]h&]uh1j-hjT ubeh}(h]h ]h"]h$]h&]jjuh1j(hhhMhjP ubah}(h]h ]h"]h$]h&]uh1j"hhhMhj hhubh)}(hIf the filesystem wants more private data than is afforded by this structure, then it should wrap it and provide its own allocator.h]hIf the filesystem wants more private data than is afforded by this structure, then it should wrap it and provide its own allocator.}(hjahhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMJhj hhubeh}(h]request-structureah ]h"]request structureah$]h&]uh1hhj hhhhhMubh)}(hhh](h)}(hStream Structureh]hStream Structure}(hjzhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjwhhhhhMNubh)}(hjA request is comprised of one or more parallel streams and each stream may be aimed at a different target.h]hjA request is comprised of one or more parallel streams and each stream may be aimed at a different target.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMPhjwhhubh)}(hXFor read requests, only stream 0 is used. This can contain a mixture of subrequests aimed at different sources. For write requests, stream 0 is used for the server and stream 1 is used for the cache. For buffered writeback, stream 0 is not enabled unless a normal dirty folio is encountered, at which point ->begin_writeback() will be invoked and the filesystem can mark the stream available.h]hXFor read requests, only stream 0 is used. This can contain a mixture of subrequests aimed at different sources. For write requests, stream 0 is used for the server and stream 1 is used for the cache. For buffered writeback, stream 0 is not enabled unless a normal dirty folio is encountered, at which point ->begin_writeback() will be invoked and the filesystem can mark the stream available.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMShjwhhubh)}(hThe stream struct looks like::h]hThe stream struct looks like:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMZhjwhhubj)}(hX struct netfs_io_stream { unsigned char stream_nr; bool avail; size_t sreq_max_len; unsigned int sreq_max_segs; unsigned int submit_extendable_to; ... };h]hX struct netfs_io_stream { unsigned char stream_nr; bool avail; size_t sreq_max_len; unsigned int sreq_max_segs; unsigned int submit_extendable_to; ... };}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhM\hjwhhubh)}(hCA number of members are available for access/use by the filesystem:h]hCA number of members are available for access/use by the filesystem:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMehjwhhubj#)}(hX* ``stream_nr`` The number of the stream within the request. * ``avail`` True if the stream is available for use. The filesystem should set this on stream zero if in ->begin_writeback(). * ``sreq_max_len`` * ``sreq_max_segs`` These are set by the filesystem or the cache in ->prepare_read() or ->prepare_write() for each subrequest to indicate the maximum number of bytes and, optionally, the maximum number of segments (if not 0) that that subrequest can support. * ``submit_extendable_to`` The size that a subrequest can be rounded up to beyond the EOF, given the available buffer. This allows the cache to work out if it can do a DIO read or write that straddles the EOF marker. h]j))}(hhh](j.)}(h<``stream_nr`` The number of the stream within the request. h](h)}(h ``stream_nr``h]j))}(hjh]h stream_nr}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhMghjubh)}(h,The number of the stream within the request.h]h,The number of the stream within the request.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMihjubeh}(h]h ]h"]h$]h&]uh1j-hjubj.)}(h~``avail`` True if the stream is available for use. The filesystem should set this on stream zero if in ->begin_writeback(). h](h)}(h ``avail``h]j))}(hj h]havail}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhMkhjubh)}(hrTrue if the stream is available for use. The filesystem should set this on stream zero if in ->begin_writeback().h]hrTrue if the stream is available for use. The filesystem should set this on stream zero if in ->begin_writeback().}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMmhjubeh}(h]h ]h"]h$]h&]uh1j-hjubj.)}(h``sreq_max_len``h]h)}(hj5h]j))}(hj5h]h sreq_max_len}(hj:hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj7ubah}(h]h ]h"]h$]h&]uh1hhhhMphj3ubah}(h]h ]h"]h$]h&]uh1j-hjubj.)}(hX``sreq_max_segs`` These are set by the filesystem or the cache in ->prepare_read() or ->prepare_write() for each subrequest to indicate the maximum number of bytes and, optionally, the maximum number of segments (if not 0) that that subrequest can support. h](h)}(h``sreq_max_segs``h]j))}(hjYh]h sreq_max_segs}(hj[hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjWubah}(h]h ]h"]h$]h&]uh1hhhhMqhjSubh)}(hThese are set by the filesystem or the cache in ->prepare_read() or ->prepare_write() for each subrequest to indicate the maximum number of bytes and, optionally, the maximum number of segments (if not 0) that that subrequest can support.h]hThese are set by the filesystem or the cache in ->prepare_read() or ->prepare_write() for each subrequest to indicate the maximum number of bytes and, optionally, the maximum number of segments (if not 0) that that subrequest can support.}(hjnhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMshjSubeh}(h]h ]h"]h$]h&]uh1j-hjubj.)}(h``submit_extendable_to`` The size that a subrequest can be rounded up to beyond the EOF, given the available buffer. This allows the cache to work out if it can do a DIO read or write that straddles the EOF marker. h](h)}(h``submit_extendable_to``h]j))}(hjh]hsubmit_extendable_to}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhMxhjubh)}(hThe size that a subrequest can be rounded up to beyond the EOF, given the available buffer. This allows the cache to work out if it can do a DIO read or write that straddles the EOF marker.h]hThe size that a subrequest can be rounded up to beyond the EOF, given the available buffer. This allows the cache to work out if it can do a DIO read or write that straddles the EOF marker.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMzhjubeh}(h]h ]h"]h$]h&]uh1j-hjubeh}(h]h ]h"]h$]h&]jjuh1j(hhhMghjubah}(h]h ]h"]h$]h&]uh1j"hhhMghjwhhubeh}(h]stream-structureah ]h"]stream structureah$]h&]uh1hhj hhhhhMNubh)}(hhh](h)}(hSubrequest Structureh]hSubrequest Structure}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMubh)}(hIndividual units of I/O are managed by the subrequest structure. These represent slices of the overall request and run independently::h]hIndividual units of I/O are managed by the subrequest structure. These represent slices of the overall request and run independently:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubj)}(hXstruct netfs_io_subrequest { struct netfs_io_request *rreq; struct iov_iter io_iter; unsigned long long start; size_t len; size_t transferred; unsigned long flags; short error; unsigned short debug_index; unsigned char stream_nr; ... };h]hXstruct netfs_io_subrequest { struct netfs_io_request *rreq; struct iov_iter io_iter; unsigned long long start; size_t len; size_t transferred; unsigned long flags; short error; unsigned short debug_index; unsigned char stream_nr; ... };}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhMhjhhubh)}(hEach subrequest is expected to access a single source, though the library will handle falling back from one source type to another. The members are:h]hEach subrequest is expected to access a single source, though the library will handle falling back from one source type to another. The members are:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubj#)}(hX * ``rreq`` A pointer to the read request. * ``io_iter`` An I/O iterator representing a slice of the buffer to be read into or written from. * ``start`` * ``len`` The file position of the start of this slice of the read request and the length. * ``transferred`` The amount of data transferred so far for this subrequest. This should be added to with the length of the transfer made by this issuance of the subrequest. If this is less than ``len`` then the subrequest may be reissued to continue. * ``flags`` Flags for managing the subrequest. There are a number of interest to the filesystem or cache: * ``NETFS_SREQ_MADE_PROGRESS`` Set by the filesystem to indicates that at least one byte of data was read or written. * ``NETFS_SREQ_HIT_EOF`` The filesystem should set this if a read hit the EOF on the file (in which case ``transferred`` should stop at the EOF). Netfslib may expand the subrequest out to the size of the folio containing the EOF on the off chance that a third party change happened or a DIO read may have asked for more than is available. The library will clear any excess pagecache. * ``NETFS_SREQ_CLEAR_TAIL`` The filesystem can set this to indicate that the remainder of the slice, from transferred to len, should be cleared. Do not set if HIT_EOF is set. * ``NETFS_SREQ_NEED_RETRY`` The filesystem can set this to tell netfslib to retry the subrequest. * ``NETFS_SREQ_BOUNDARY`` This can be set by the filesystem on a subrequest to indicate that it ends at a boundary with the filesystem structure (e.g. at the end of a Ceph object). It tells netfslib not to retile subrequests across it. * ``error`` This is for the filesystem to store result of the subrequest. It should be set to 0 if successful and a negative error code otherwise. * ``debug_index`` * ``stream_nr`` A number allocated to this slice that can be displayed in trace lines for reference and the number of the request stream that it belongs to. h]j))}(hhh](j.)}(h)``rreq`` A pointer to the read request. h](h)}(h``rreq``h]j))}(hj h]hrreq}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj ubah}(h]h ]h"]h$]h&]uh1hhhhMhjubh)}(hA pointer to the read request.h]hA pointer to the read request.}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubeh}(h]h ]h"]h$]h&]uh1j-hjubj.)}(ha``io_iter`` An I/O iterator representing a slice of the buffer to be read into or written from. h](h)}(h ``io_iter``h]j))}(hj<h]hio_iter}(hj>hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj:ubah}(h]h ]h"]h$]h&]uh1hhhhMhj6ubh)}(hSAn I/O iterator representing a slice of the buffer to be read into or written from.h]hSAn I/O iterator representing a slice of the buffer to be read into or written from.}(hjQhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj6ubeh}(h]h ]h"]h$]h&]uh1j-hjubj.)}(h ``start``h]h)}(hjgh]j))}(hjgh]hstart}(hjlhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjiubah}(h]h ]h"]h$]h&]uh1hhhhMhjeubah}(h]h ]h"]h$]h&]uh1j-hjubj.)}(hZ``len`` The file position of the start of this slice of the read request and the length. h](h)}(h``len``h]j))}(hjh]hlen}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhMhjubh)}(hPThe file position of the start of this slice of the read request and the length.h]hPThe file position of the start of this slice of the read request and the length.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubeh}(h]h ]h"]h$]h&]uh1j-hjubj.)}(h``transferred`` The amount of data transferred so far for this subrequest. This should be added to with the length of the transfer made by this issuance of the subrequest. If this is less than ``len`` then the subrequest may be reissued to continue. h](h)}(h``transferred``h]j))}(hjh]h transferred}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhMhjubh)}(hThe amount of data transferred so far for this subrequest. This should be added to with the length of the transfer made by this issuance of the subrequest. If this is less than ``len`` then the subrequest may be reissued to continue.h](hThe amount of data transferred so far for this subrequest. This should be added to with the length of the transfer made by this issuance of the subrequest. If this is less than }(hjhhhNhNubj))}(h``len``h]hlen}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubh1 then the subrequest may be reissued to continue.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubeh}(h]h ]h"]h$]h&]uh1j-hjubj.)}(hX``flags`` Flags for managing the subrequest. There are a number of interest to the filesystem or cache: * ``NETFS_SREQ_MADE_PROGRESS`` Set by the filesystem to indicates that at least one byte of data was read or written. * ``NETFS_SREQ_HIT_EOF`` The filesystem should set this if a read hit the EOF on the file (in which case ``transferred`` should stop at the EOF). Netfslib may expand the subrequest out to the size of the folio containing the EOF on the off chance that a third party change happened or a DIO read may have asked for more than is available. The library will clear any excess pagecache. * ``NETFS_SREQ_CLEAR_TAIL`` The filesystem can set this to indicate that the remainder of the slice, from transferred to len, should be cleared. Do not set if HIT_EOF is set. * ``NETFS_SREQ_NEED_RETRY`` The filesystem can set this to tell netfslib to retry the subrequest. * ``NETFS_SREQ_BOUNDARY`` This can be set by the filesystem on a subrequest to indicate that it ends at a boundary with the filesystem structure (e.g. at the end of a Ceph object). It tells netfslib not to retile subrequests across it. h](h)}(h ``flags``h]j))}(hjh]hflags}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhMhjubh)}(h^Flags for managing the subrequest. There are a number of interest to the filesystem or cache:h]h^Flags for managing the subrequest. There are a number of interest to the filesystem or cache:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubj))}(hhh](j.)}(hu``NETFS_SREQ_MADE_PROGRESS`` Set by the filesystem to indicates that at least one byte of data was read or written. h](h)}(h``NETFS_SREQ_MADE_PROGRESS``h]j))}(hj'h]hNETFS_SREQ_MADE_PROGRESS}(hj)hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj%ubah}(h]h ]h"]h$]h&]uh1hhhhMhj!ubh)}(hVSet by the filesystem to indicates that at least one byte of data was read or written.h]hVSet by the filesystem to indicates that at least one byte of data was read or written.}(hj<hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj!ubeh}(h]h ]h"]h$]h&]uh1j-hjubj.)}(hX``NETFS_SREQ_HIT_EOF`` The filesystem should set this if a read hit the EOF on the file (in which case ``transferred`` should stop at the EOF). Netfslib may expand the subrequest out to the size of the folio containing the EOF on the off chance that a third party change happened or a DIO read may have asked for more than is available. The library will clear any excess pagecache. h](h)}(h``NETFS_SREQ_HIT_EOF``h]j))}(hjVh]hNETFS_SREQ_HIT_EOF}(hjXhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjTubah}(h]h ]h"]h$]h&]uh1hhhhMhjPubh)}(hXhThe filesystem should set this if a read hit the EOF on the file (in which case ``transferred`` should stop at the EOF). Netfslib may expand the subrequest out to the size of the folio containing the EOF on the off chance that a third party change happened or a DIO read may have asked for more than is available. The library will clear any excess pagecache.h](hPThe filesystem should set this if a read hit the EOF on the file (in which case }(hjkhhhNhNubj))}(h``transferred``h]h transferred}(hjshhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjkubhX  should stop at the EOF). Netfslib may expand the subrequest out to the size of the folio containing the EOF on the off chance that a third party change happened or a DIO read may have asked for more than is available. The library will clear any excess pagecache.}(hjkhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjPubeh}(h]h ]h"]h$]h&]uh1j-hjubj.)}(h``NETFS_SREQ_CLEAR_TAIL`` The filesystem can set this to indicate that the remainder of the slice, from transferred to len, should be cleared. Do not set if HIT_EOF is set. h](h)}(h``NETFS_SREQ_CLEAR_TAIL``h]j))}(hjh]hNETFS_SREQ_CLEAR_TAIL}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhMhjubh)}(hThe filesystem can set this to indicate that the remainder of the slice, from transferred to len, should be cleared. Do not set if HIT_EOF is set.h]hThe filesystem can set this to indicate that the remainder of the slice, from transferred to len, should be cleared. Do not set if HIT_EOF is set.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubeh}(h]h ]h"]h$]h&]uh1j-hjubj.)}(ha``NETFS_SREQ_NEED_RETRY`` The filesystem can set this to tell netfslib to retry the subrequest. h](h)}(h``NETFS_SREQ_NEED_RETRY``h]j))}(hjh]hNETFS_SREQ_NEED_RETRY}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhMhjubh)}(hEThe filesystem can set this to tell netfslib to retry the subrequest.h]hEThe filesystem can set this to tell netfslib to retry the subrequest.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubeh}(h]h ]h"]h$]h&]uh1j-hjubj.)}(h``NETFS_SREQ_BOUNDARY`` This can be set by the filesystem on a subrequest to indicate that it ends at a boundary with the filesystem structure (e.g. at the end of a Ceph object). It tells netfslib not to retile subrequests across it. h](h)}(h``NETFS_SREQ_BOUNDARY``h]j))}(hjh]hNETFS_SREQ_BOUNDARY}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhMhjubh)}(hThis can be set by the filesystem on a subrequest to indicate that it ends at a boundary with the filesystem structure (e.g. at the end of a Ceph object). It tells netfslib not to retile subrequests across it.h]hThis can be set by the filesystem on a subrequest to indicate that it ends at a boundary with the filesystem structure (e.g. at the end of a Ceph object). It tells netfslib not to retile subrequests across it.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubeh}(h]h ]h"]h$]h&]uh1j-hjubeh}(h]h ]h"]h$]h&]jjuh1j(hhhMhjubeh}(h]h ]h"]h$]h&]uh1j-hjubj.)}(h``error`` This is for the filesystem to store result of the subrequest. It should be set to 0 if successful and a negative error code otherwise. h](h)}(h ``error``h]j))}(hj0h]herror}(hj2hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj.ubah}(h]h ]h"]h$]h&]uh1hhhhMhj*ubh)}(hThis is for the filesystem to store result of the subrequest. It should be set to 0 if successful and a negative error code otherwise.h]hThis is for the filesystem to store result of the subrequest. It should be set to 0 if successful and a negative error code otherwise.}(hjEhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj*ubeh}(h]h ]h"]h$]h&]uh1j-hjubj.)}(h``debug_index``h]h)}(hj[h]j))}(hj[h]h debug_index}(hj`hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj]ubah}(h]h ]h"]h$]h&]uh1hhhhMhjYubah}(h]h ]h"]h$]h&]uh1j-hjubj.)}(h``stream_nr`` A number allocated to this slice that can be displayed in trace lines for reference and the number of the request stream that it belongs to. h](h)}(h ``stream_nr``h]j))}(hjh]h stream_nr}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj}ubah}(h]h ]h"]h$]h&]uh1hhhhMhjyubh)}(hA number allocated to this slice that can be displayed in trace lines for reference and the number of the request stream that it belongs to.h]hA number allocated to this slice that can be displayed in trace lines for reference and the number of the request stream that it belongs to.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjyubeh}(h]h ]h"]h$]h&]uh1j-hjubeh}(h]h ]h"]h$]h&]jjuh1j(hhhMhjubah}(h]h ]h"]h$]h&]uh1j"hhhMhjhhubh)}(hWIf necessary, the filesystem can get and put extra refs on the subrequest it is given::h]hVIf necessary, the filesystem can get and put extra refs on the subrequest it is given:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubj)}(hvoid netfs_get_subrequest(struct netfs_io_subrequest *subreq, enum netfs_sreq_ref_trace what); void netfs_put_subrequest(struct netfs_io_subrequest *subreq, enum netfs_sreq_ref_trace what);h]hvoid netfs_get_subrequest(struct netfs_io_subrequest *subreq, enum netfs_sreq_ref_trace what); void netfs_put_subrequest(struct netfs_io_subrequest *subreq, enum netfs_sreq_ref_trace what);}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhMhjhhubh)}(husing netfs trace codes to indicate the reason. Care must be taken, however, as once control of the subrequest is returned to netfslib, the same subrequest can be reissued/retried.h]husing netfs trace codes to indicate the reason. Care must be taken, however, as once control of the subrequest is returned to netfslib, the same subrequest can be reissued/retried.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubeh}(h]subrequest-structureah ]h"]subrequest structureah$]h&]uh1hhj hhhhhMubh)}(hhh](h)}(hFilesystem Methodsh]hFilesystem Methods}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMubh)}(hRThe filesystem sets a table of operations in ``netfs_inode`` for netfslib to use::h](h-The filesystem sets a table of operations in }(hjhhhNhNubj))}(h``netfs_inode``h]h netfs_inode}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubh for netfslib to use:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjhhubj)}(hXstruct netfs_request_ops { mempool_t *request_pool; mempool_t *subrequest_pool; int (*init_request)(struct netfs_io_request *rreq, struct file *file); void (*free_request)(struct netfs_io_request *rreq); void (*free_subrequest)(struct netfs_io_subrequest *rreq); void (*expand_readahead)(struct netfs_io_request *rreq); int (*prepare_read)(struct netfs_io_subrequest *subreq); void (*issue_read)(struct netfs_io_subrequest *subreq); void (*done)(struct netfs_io_request *rreq); void (*update_i_size)(struct inode *inode, loff_t i_size); void (*post_modify)(struct inode *inode); void (*begin_writeback)(struct netfs_io_request *wreq); void (*prepare_write)(struct netfs_io_subrequest *subreq); void (*issue_write)(struct netfs_io_subrequest *subreq); void (*retry_request)(struct netfs_io_request *wreq, struct netfs_io_stream *stream); void (*invalidate_cache)(struct netfs_io_request *wreq); };h]hXstruct netfs_request_ops { mempool_t *request_pool; mempool_t *subrequest_pool; int (*init_request)(struct netfs_io_request *rreq, struct file *file); void (*free_request)(struct netfs_io_request *rreq); void (*free_subrequest)(struct netfs_io_subrequest *rreq); void (*expand_readahead)(struct netfs_io_request *rreq); int (*prepare_read)(struct netfs_io_subrequest *subreq); void (*issue_read)(struct netfs_io_subrequest *subreq); void (*done)(struct netfs_io_request *rreq); void (*update_i_size)(struct inode *inode, loff_t i_size); void (*post_modify)(struct inode *inode); void (*begin_writeback)(struct netfs_io_request *wreq); void (*prepare_write)(struct netfs_io_subrequest *subreq); void (*issue_write)(struct netfs_io_subrequest *subreq); void (*retry_request)(struct netfs_io_request *wreq, struct netfs_io_stream *stream); void (*invalidate_cache)(struct netfs_io_request *wreq); };}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhMhjhhubh)}(hXcThe table starts with a pair of optional pointers to memory pools from which requests and subrequests can be allocated. If these are not given, netfslib has default pools that it will use instead. If the filesystem wraps the netfs structs in its own larger structs, then it will need to use its own pools. Netfslib will allocate directly from the pools.h]hXcThe table starts with a pair of optional pointers to memory pools from which requests and subrequests can be allocated. If these are not given, netfslib has default pools that it will use instead. If the filesystem wraps the netfs structs in its own larger structs, then it will need to use its own pools. Netfslib will allocate directly from the pools.}(hj%hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(h%The methods defined in the table are:h]h%The methods defined in the table are:}(hj3hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubj#)}(hX* ``init_request()`` * ``free_request()`` * ``free_subrequest()`` [Optional] A filesystem may implement these to initialise or clean up any resources that it attaches to the request or subrequest. * ``expand_readahead()`` [Optional] This is called to allow the filesystem to expand the size of a readahead request. The filesystem gets to expand the request in both directions, though it must retain the initial region as that may represent an allocation already made. If local caching is enabled, it gets to expand the request first. Expansion is communicated by changing ->start and ->len in the request structure. Note that if any change is made, ->len must be increased by at least as much as ->start is reduced. * ``prepare_read()`` [Optional] This is called to allow the filesystem to limit the size of a subrequest. It may also limit the number of individual regions in iterator, such as required by RDMA. This information should be set on stream zero in:: rreq->io_streams[0].sreq_max_len rreq->io_streams[0].sreq_max_segs The filesystem can use this, for example, to chop up a request that has to be split across multiple servers or to put multiple reads in flight. Zero should be returned on success and an error code otherwise. * ``issue_read()`` [Required] Netfslib calls this to dispatch a subrequest to the server for reading. In the subrequest, ->start, ->len and ->transferred indicate what data should be read from the server and ->io_iter indicates the buffer to be used. There is no return value; the ``netfs_read_subreq_terminated()`` function should be called to indicate that the subrequest completed either way. ->error, ->transferred and ->flags should be updated before completing. The termination can be done asynchronously. Note: the filesystem must not deal with setting folios uptodate, unlocking them or dropping their refs - the library deals with this as it may have to stitch together the results of multiple subrequests that variously overlap the set of folios. * ``done()`` [Optional] This is called after the folios in a read request have all been unlocked (and marked uptodate if applicable). * ``update_i_size()`` [Optional] This is invoked by netfslib at various points during the write paths to ask the filesystem to update its idea of the file size. If not given, netfslib will set i_size and i_blocks and update the local cache cookie. * ``post_modify()`` [Optional] This is called after netfslib writes to the pagecache or when it allows an mmap'd page to be marked as writable. * ``begin_writeback()`` [Optional] Netfslib calls this when processing a writeback request if it finds a dirty page that isn't simply marked NETFS_FOLIO_COPY_TO_CACHE, indicating it must be written to the server. This allows the filesystem to only set up writeback resources when it knows it's going to have to perform a write. * ``prepare_write()`` [Optional] This is called to allow the filesystem to limit the size of a subrequest. It may also limit the number of individual regions in iterator, such as required by RDMA. This information should be set on stream to which the subrequest belongs:: rreq->io_streams[subreq->stream_nr].sreq_max_len rreq->io_streams[subreq->stream_nr].sreq_max_segs The filesystem can use this, for example, to chop up a request that has to be split across multiple servers or to put multiple writes in flight. This is not permitted to return an error. Instead, in the event of failure, ``netfs_prepare_write_failed()`` must be called. * ``issue_write()`` [Required] This is used to dispatch a subrequest to the server for writing. In the subrequest, ->start, ->len and ->transferred indicate what data should be written to the server and ->io_iter indicates the buffer to be used. There is no return value; the ``netfs_write_subreq_terminated()`` function should be called to indicate that the subrequest completed either way. ->error, ->transferred and ->flags should be updated before completing. The termination can be done asynchronously. Note: the filesystem must not deal with removing the dirty or writeback marks on folios involved in the operation and should not take refs or pins on them, but should leave retention to netfslib. * ``retry_request()`` [Optional] Netfslib calls this at the beginning of a retry cycle. This allows the filesystem to examine the state of the request, the subrequests in the indicated stream and of its own data and make adjustments or renegotiate resources. * ``invalidate_cache()`` [Optional] This is called by netfslib to invalidate data stored in the local cache in the event that writing to the local cache fails, providing updated coherency data that netfs can't provide. h]j))}(hhh](j.)}(h``init_request()``h]h)}(hjJh]j))}(hjJh]hinit_request()}(hjOhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjLubah}(h]h ]h"]h$]h&]uh1hhhhMhjHubah}(h]h ]h"]h$]h&]uh1j-hjEubj.)}(h``free_request()``h]h)}(hjjh]j))}(hjjh]hfree_request()}(hjohhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjlubah}(h]h ]h"]h$]h&]uh1hhhhMhjhubah}(h]h ]h"]h$]h&]uh1j-hjEubj.)}(h``free_subrequest()`` [Optional] A filesystem may implement these to initialise or clean up any resources that it attaches to the request or subrequest. h](h)}(h``free_subrequest()``h]j))}(hjh]hfree_subrequest()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhMhjubh)}(h[Optional] A filesystem may implement these to initialise or clean up any resources that it attaches to the request or subrequest.h]h[Optional] A filesystem may implement these to initialise or clean up any resources that it attaches to the request or subrequest.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubeh}(h]h ]h"]h$]h&]uh1j-hjEubj.)}(hX ``expand_readahead()`` [Optional] This is called to allow the filesystem to expand the size of a readahead request. The filesystem gets to expand the request in both directions, though it must retain the initial region as that may represent an allocation already made. If local caching is enabled, it gets to expand the request first. Expansion is communicated by changing ->start and ->len in the request structure. Note that if any change is made, ->len must be increased by at least as much as ->start is reduced. h](h)}(h``expand_readahead()``h]j))}(hjh]hexpand_readahead()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhM hjubh)}(hX9[Optional] This is called to allow the filesystem to expand the size of a readahead request. The filesystem gets to expand the request in both directions, though it must retain the initial region as that may represent an allocation already made. If local caching is enabled, it gets to expand the request first.h]hX9[Optional] This is called to allow the filesystem to expand the size of a readahead request. The filesystem gets to expand the request in both directions, though it must retain the initial region as that may represent an allocation already made. If local caching is enabled, it gets to expand the request first.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM hjubh)}(hExpansion is communicated by changing ->start and ->len in the request structure. Note that if any change is made, ->len must be increased by at least as much as ->start is reduced.h]hExpansion is communicated by changing ->start and ->len in the request structure. Note that if any change is made, ->len must be increased by at least as much as ->start is reduced.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubeh}(h]h ]h"]h$]h&]uh1j-hjEubj.)}(hX``prepare_read()`` [Optional] This is called to allow the filesystem to limit the size of a subrequest. It may also limit the number of individual regions in iterator, such as required by RDMA. This information should be set on stream zero in:: rreq->io_streams[0].sreq_max_len rreq->io_streams[0].sreq_max_segs The filesystem can use this, for example, to chop up a request that has to be split across multiple servers or to put multiple reads in flight. Zero should be returned on success and an error code otherwise. h](h)}(h``prepare_read()``h]j))}(hjh]hprepare_read()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhMhjubh)}(h[Optional] This is called to allow the filesystem to limit the size of a subrequest. It may also limit the number of individual regions in iterator, such as required by RDMA. This information should be set on stream zero in::h]h[Optional] This is called to allow the filesystem to limit the size of a subrequest. It may also limit the number of individual regions in iterator, such as required by RDMA. This information should be set on stream zero in:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubj)}(hBrreq->io_streams[0].sreq_max_len rreq->io_streams[0].sreq_max_segsh]hBrreq->io_streams[0].sreq_max_len rreq->io_streams[0].sreq_max_segs}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhMhjubh)}(hThe filesystem can use this, for example, to chop up a request that has to be split across multiple servers or to put multiple reads in flight.h]hThe filesystem can use this, for example, to chop up a request that has to be split across multiple servers or to put multiple reads in flight.}(hj+hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM hjubh)}(h?Zero should be returned on success and an error code otherwise.h]h?Zero should be returned on success and an error code otherwise.}(hj9hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM#hjubeh}(h]h ]h"]h$]h&]uh1j-hjEubj.)}(hX``issue_read()`` [Required] Netfslib calls this to dispatch a subrequest to the server for reading. In the subrequest, ->start, ->len and ->transferred indicate what data should be read from the server and ->io_iter indicates the buffer to be used. There is no return value; the ``netfs_read_subreq_terminated()`` function should be called to indicate that the subrequest completed either way. ->error, ->transferred and ->flags should be updated before completing. The termination can be done asynchronously. Note: the filesystem must not deal with setting folios uptodate, unlocking them or dropping their refs - the library deals with this as it may have to stitch together the results of multiple subrequests that variously overlap the set of folios. h](h)}(h``issue_read()``h]j))}(hjSh]h issue_read()}(hjUhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjQubah}(h]h ]h"]h$]h&]uh1hhhhM%hjMubh)}(h[Required] Netfslib calls this to dispatch a subrequest to the server for reading. In the subrequest, ->start, ->len and ->transferred indicate what data should be read from the server and ->io_iter indicates the buffer to be used.h]h[Required] Netfslib calls this to dispatch a subrequest to the server for reading. In the subrequest, ->start, ->len and ->transferred indicate what data should be read from the server and ->io_iter indicates the buffer to be used.}(hjhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM'hjMubh)}(hXThere is no return value; the ``netfs_read_subreq_terminated()`` function should be called to indicate that the subrequest completed either way. ->error, ->transferred and ->flags should be updated before completing. The termination can be done asynchronously.h](hThere is no return value; the }(hjvhhhNhNubj))}(h"``netfs_read_subreq_terminated()``h]hnetfs_read_subreq_terminated()}(hj~hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjvubh function should be called to indicate that the subrequest completed either way. ->error, ->transferred and ->flags should be updated before completing. The termination can be done asynchronously.}(hjvhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM,hjMubh)}(hNote: the filesystem must not deal with setting folios uptodate, unlocking them or dropping their refs - the library deals with this as it may have to stitch together the results of multiple subrequests that variously overlap the set of folios.h]hNote: the filesystem must not deal with setting folios uptodate, unlocking them or dropping their refs - the library deals with this as it may have to stitch together the results of multiple subrequests that variously overlap the set of folios.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM1hjMubeh}(h]h ]h"]h$]h&]uh1j-hjEubj.)}(h``done()`` [Optional] This is called after the folios in a read request have all been unlocked (and marked uptodate if applicable). h](h)}(h ``done()``h]j))}(hjh]hdone()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhM6hjubh)}(hx[Optional] This is called after the folios in a read request have all been unlocked (and marked uptodate if applicable).h]hx[Optional] This is called after the folios in a read request have all been unlocked (and marked uptodate if applicable).}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM8hjubeh}(h]h ]h"]h$]h&]uh1j-hjEubj.)}(h``update_i_size()`` [Optional] This is invoked by netfslib at various points during the write paths to ask the filesystem to update its idea of the file size. If not given, netfslib will set i_size and i_blocks and update the local cache cookie. h](h)}(h``update_i_size()``h]j))}(hjh]hupdate_i_size()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhM;hjubh)}(h[Optional] This is invoked by netfslib at various points during the write paths to ask the filesystem to update its idea of the file size. If not given, netfslib will set i_size and i_blocks and update the local cache cookie.h]h[Optional] This is invoked by netfslib at various points during the write paths to ask the filesystem to update its idea of the file size. If not given, netfslib will set i_size and i_blocks and update the local cache cookie.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM=hjubeh}(h]h ]h"]h$]h&]uh1j-hjEubj.)}(h``post_modify()`` [Optional] This is called after netfslib writes to the pagecache or when it allows an mmap'd page to be marked as writable. h](h)}(h``post_modify()``h]j))}(hjh]h post_modify()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj ubah}(h]h ]h"]h$]h&]uh1hhhhMBhjubh)}(h{[Optional] This is called after netfslib writes to the pagecache or when it allows an mmap'd page to be marked as writable.h]h}[Optional] This is called after netfslib writes to the pagecache or when it allows an mmap’d page to be marked as writable.}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMDhjubeh}(h]h ]h"]h$]h&]uh1j-hjEubj.)}(hXH``begin_writeback()`` [Optional] Netfslib calls this when processing a writeback request if it finds a dirty page that isn't simply marked NETFS_FOLIO_COPY_TO_CACHE, indicating it must be written to the server. This allows the filesystem to only set up writeback resources when it knows it's going to have to perform a write. h](h)}(h``begin_writeback()``h]j))}(hj=h]hbegin_writeback()}(hj?hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj;ubah}(h]h ]h"]h$]h&]uh1hhhhMGhj7ubh)}(hX0[Optional] Netfslib calls this when processing a writeback request if it finds a dirty page that isn't simply marked NETFS_FOLIO_COPY_TO_CACHE, indicating it must be written to the server. This allows the filesystem to only set up writeback resources when it knows it's going to have to perform a write.h]hX4[Optional] Netfslib calls this when processing a writeback request if it finds a dirty page that isn’t simply marked NETFS_FOLIO_COPY_TO_CACHE, indicating it must be written to the server. This allows the filesystem to only set up writeback resources when it knows it’s going to have to perform a write.}(hjRhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMIhj7ubeh}(h]h ]h"]h$]h&]uh1j-hjEubj.)}(hX``prepare_write()`` [Optional] This is called to allow the filesystem to limit the size of a subrequest. It may also limit the number of individual regions in iterator, such as required by RDMA. This information should be set on stream to which the subrequest belongs:: rreq->io_streams[subreq->stream_nr].sreq_max_len rreq->io_streams[subreq->stream_nr].sreq_max_segs The filesystem can use this, for example, to chop up a request that has to be split across multiple servers or to put multiple writes in flight. This is not permitted to return an error. Instead, in the event of failure, ``netfs_prepare_write_failed()`` must be called. h](h)}(h``prepare_write()``h]j))}(hjlh]hprepare_write()}(hjnhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjjubah}(h]h ]h"]h$]h&]uh1hhhhMOhjfubh)}(h[Optional] This is called to allow the filesystem to limit the size of a subrequest. It may also limit the number of individual regions in iterator, such as required by RDMA. This information should be set on stream to which the subrequest belongs::h]h[Optional] This is called to allow the filesystem to limit the size of a subrequest. It may also limit the number of individual regions in iterator, such as required by RDMA. This information should be set on stream to which the subrequest belongs:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMQhjfubj)}(hbrreq->io_streams[subreq->stream_nr].sreq_max_len rreq->io_streams[subreq->stream_nr].sreq_max_segsh]hbrreq->io_streams[subreq->stream_nr].sreq_max_len rreq->io_streams[subreq->stream_nr].sreq_max_segs}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhMVhjfubh)}(hThe filesystem can use this, for example, to chop up a request that has to be split across multiple servers or to put multiple writes in flight.h]hThe filesystem can use this, for example, to chop up a request that has to be split across multiple servers or to put multiple writes in flight.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMYhjfubh)}(h}This is not permitted to return an error. Instead, in the event of failure, ``netfs_prepare_write_failed()`` must be called.h](hMThis is not permitted to return an error. Instead, in the event of failure, }(hjhhhNhNubj))}(h ``netfs_prepare_write_failed()``h]hnetfs_prepare_write_failed()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubh must be called.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhM\hjfubeh}(h]h ]h"]h$]h&]uh1j-hjEubj.)}(hX``issue_write()`` [Required] This is used to dispatch a subrequest to the server for writing. In the subrequest, ->start, ->len and ->transferred indicate what data should be written to the server and ->io_iter indicates the buffer to be used. There is no return value; the ``netfs_write_subreq_terminated()`` function should be called to indicate that the subrequest completed either way. ->error, ->transferred and ->flags should be updated before completing. The termination can be done asynchronously. Note: the filesystem must not deal with removing the dirty or writeback marks on folios involved in the operation and should not take refs or pins on them, but should leave retention to netfslib. h](h)}(h``issue_write()``h]j))}(hjh]h issue_write()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhM_hjubh)}(h[Required] This is used to dispatch a subrequest to the server for writing. In the subrequest, ->start, ->len and ->transferred indicate what data should be written to the server and ->io_iter indicates the buffer to be used.h]h[Required] This is used to dispatch a subrequest to the server for writing. In the subrequest, ->start, ->len and ->transferred indicate what data should be written to the server and ->io_iter indicates the buffer to be used.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMahjubh)}(hXThere is no return value; the ``netfs_write_subreq_terminated()`` function should be called to indicate that the subrequest completed either way. ->error, ->transferred and ->flags should be updated before completing. The termination can be done asynchronously.h](hThere is no return value; the }(hjhhhNhNubj))}(h#``netfs_write_subreq_terminated()``h]hnetfs_write_subreq_terminated()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubh function should be called to indicate that the subrequest completed either way. ->error, ->transferred and ->flags should be updated before completing. The termination can be done asynchronously.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMfhjubh)}(hNote: the filesystem must not deal with removing the dirty or writeback marks on folios involved in the operation and should not take refs or pins on them, but should leave retention to netfslib.h]hNote: the filesystem must not deal with removing the dirty or writeback marks on folios involved in the operation and should not take refs or pins on them, but should leave retention to netfslib.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMkhjubeh}(h]h ]h"]h$]h&]uh1j-hjEubj.)}(hX``retry_request()`` [Optional] Netfslib calls this at the beginning of a retry cycle. This allows the filesystem to examine the state of the request, the subrequests in the indicated stream and of its own data and make adjustments or renegotiate resources. h](h)}(h``retry_request()``h]j))}(hj4h]hretry_request()}(hj6hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj2ubah}(h]h ]h"]h$]h&]uh1hhhhMohj.ubh)}(h[Optional] Netfslib calls this at the beginning of a retry cycle. This allows the filesystem to examine the state of the request, the subrequests in the indicated stream and of its own data and make adjustments or renegotiate resources.h]h[Optional] Netfslib calls this at the beginning of a retry cycle. This allows the filesystem to examine the state of the request, the subrequests in the indicated stream and of its own data and make adjustments or renegotiate resources.}(hjIhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMqhj.ubeh}(h]h ]h"]h$]h&]uh1j-hjEubj.)}(h``invalidate_cache()`` [Optional] This is called by netfslib to invalidate data stored in the local cache in the event that writing to the local cache fails, providing updated coherency data that netfs can't provide. h](h)}(h``invalidate_cache()``h]j))}(hjch]hinvalidate_cache()}(hjehhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjaubah}(h]h ]h"]h$]h&]uh1hhhhMvhj]ubh)}(h[Optional] This is called by netfslib to invalidate data stored in the local cache in the event that writing to the local cache fails, providing updated coherency data that netfs can't provide.h]h[Optional] This is called by netfslib to invalidate data stored in the local cache in the event that writing to the local cache fails, providing updated coherency data that netfs can’t provide.}(hjxhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMxhj]ubeh}(h]h ]h"]h$]h&]uh1j-hjEubeh}(h]h ]h"]h$]h&]jjuh1j(hhhMhjAubah}(h]h ]h"]h$]h&]uh1j"hhhMhjhhubeh}(h]filesystem-methodsah ]h"]filesystem methodsah$]h&]uh1hhj hhhhhMubh)}(hhh](h)}(hTerminating a subrequesth]hTerminating a subrequest}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhM}ubh)}(hWhen a subrequest completes, there are a number of functions that the cache or subrequest can call to inform netfslib of the status change. One function is provided to terminate a write subrequest at the preparation stage and acts synchronously:h]hWhen a subrequest completes, there are a number of functions that the cache or subrequest can call to inform netfslib of the status change. One function is provided to terminate a write subrequest at the preparation stage and acts synchronously:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubj#)}(h* ``void netfs_prepare_write_failed(struct netfs_io_subrequest *subreq);`` Indicate that the ->prepare_write() call failed. The ``error`` field should have been updated. h]j))}(hhh]j.)}(h``void netfs_prepare_write_failed(struct netfs_io_subrequest *subreq);`` Indicate that the ->prepare_write() call failed. The ``error`` field should have been updated. h](h)}(hH``void netfs_prepare_write_failed(struct netfs_io_subrequest *subreq);``h]j))}(hjh]hDvoid netfs_prepare_write_failed(struct netfs_io_subrequest *subreq);}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhMhjubh)}(h_Indicate that the ->prepare_write() call failed. The ``error`` field should have been updated.h](h6Indicate that the ->prepare_write() call failed. The }(hjhhhNhNubj))}(h ``error``h]herror}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubh field should have been updated.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubeh}(h]h ]h"]h$]h&]uh1j-hjubah}(h]h ]h"]h$]h&]jjuh1j(hhhMhjubah}(h]h ]h"]h$]h&]uh1j"hhhMhjhhubh)}(h{Note that ->prepare_read() can return an error as a read can simply be aborted. Dealing with writeback failure is trickier.h]h{Note that ->prepare_read() can return an error as a read can simply be aborted. Dealing with writeback failure is trickier.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(hMThe other functions are used for subrequests that got as far as being issued:h]hMThe other functions are used for subrequests that got as far as being issued:}(hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubj#)}(hX,* ``void netfs_read_subreq_terminated(struct netfs_io_subrequest *subreq);`` Tell netfslib that a read subrequest has terminated. The ``error``, ``flags`` and ``transferred`` fields should have been updated. * ``void netfs_write_subrequest_terminated(void *_op, ssize_t transferred_or_error);`` Tell netfslib that a write subrequest has terminated. Either the amount of data processed or the negative error code can be passed in. This is can be used as a kiocb completion function. * ``void netfs_read_subreq_progress(struct netfs_io_subrequest *subreq);`` This is provided to optionally update netfslib on the incremental progress of a read, allowing some folios to be unlocked early and does not actually terminate the subrequest. The ``transferred`` field should have been updated. h]j))}(hhh](j.)}(h``void netfs_read_subreq_terminated(struct netfs_io_subrequest *subreq);`` Tell netfslib that a read subrequest has terminated. The ``error``, ``flags`` and ``transferred`` fields should have been updated. h](h)}(hJ``void netfs_read_subreq_terminated(struct netfs_io_subrequest *subreq);``h]j))}(hj<h]hFvoid netfs_read_subreq_terminated(struct netfs_io_subrequest *subreq);}(hj>hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj:ubah}(h]h ]h"]h$]h&]uh1hhhhMhj6ubh)}(hTell netfslib that a read subrequest has terminated. The ``error``, ``flags`` and ``transferred`` fields should have been updated.h](h:Tell netfslib that a read subrequest has terminated. The }(hjQhhhNhNubj))}(h ``error``h]herror}(hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjQubh, }(hjQhhhNhNubj))}(h ``flags``h]hflags}(hjkhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjQubh and }(hjQhhhNhNubj))}(h``transferred``h]h transferred}(hj}hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjQubh! fields should have been updated.}(hjQhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj6ubeh}(h]h ]h"]h$]h&]uh1j-hj3ubj.)}(hX``void netfs_write_subrequest_terminated(void *_op, ssize_t transferred_or_error);`` Tell netfslib that a write subrequest has terminated. Either the amount of data processed or the negative error code can be passed in. This is can be used as a kiocb completion function. h](h)}(hT``void netfs_write_subrequest_terminated(void *_op, ssize_t transferred_or_error);``h]j))}(hjh]hPvoid netfs_write_subrequest_terminated(void *_op, ssize_t transferred_or_error);}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhMhjubh)}(hTell netfslib that a write subrequest has terminated. Either the amount of data processed or the negative error code can be passed in. This is can be used as a kiocb completion function.h]hTell netfslib that a write subrequest has terminated. Either the amount of data processed or the negative error code can be passed in. This is can be used as a kiocb completion function.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubeh}(h]h ]h"]h$]h&]uh1j-hj3ubj.)}(hX/``void netfs_read_subreq_progress(struct netfs_io_subrequest *subreq);`` This is provided to optionally update netfslib on the incremental progress of a read, allowing some folios to be unlocked early and does not actually terminate the subrequest. The ``transferred`` field should have been updated. h](h)}(hH``void netfs_read_subreq_progress(struct netfs_io_subrequest *subreq);``h]j))}(hjh]hDvoid netfs_read_subreq_progress(struct netfs_io_subrequest *subreq);}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhMhjubh)}(hThis is provided to optionally update netfslib on the incremental progress of a read, allowing some folios to be unlocked early and does not actually terminate the subrequest. The ``transferred`` field should have been updated.h](hThis is provided to optionally update netfslib on the incremental progress of a read, allowing some folios to be unlocked early and does not actually terminate the subrequest. The }(hjhhhNhNubj))}(h``transferred``h]h transferred}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubh field should have been updated.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubeh}(h]h ]h"]h$]h&]uh1j-hj3ubeh}(h]h ]h"]h$]h&]jjuh1j(hhhMhj/ubah}(h]h ]h"]h$]h&]uh1j"hhhMhjhhubeh}(h]terminating-a-subrequestah ]h"]terminating a subrequestah$]h&]uh1hhj hhhhhM}ubh)}(hhh](h)}(hLocal Cache APIh]hLocal Cache API}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMubh)}(hNetfslib provides a separate API for a local cache to implement, though it provides some somewhat similar routines to the filesystem request API.h]hNetfslib provides a separate API for a local cache to implement, though it provides some somewhat similar routines to the filesystem request API.}(hj0hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(hWFirstly, the netfs_io_request object contains a place for the cache to hang its state::h]hVFirstly, the netfs_io_request object contains a place for the cache to hang its state:}(hj>hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubj)}(hX#struct netfs_cache_resources { const struct netfs_cache_ops *ops; void *cache_priv; void *cache_priv2; unsigned int debug_id; unsigned int inval_counter; };h]hX#struct netfs_cache_resources { const struct netfs_cache_ops *ops; void *cache_priv; void *cache_priv2; unsigned int debug_id; unsigned int inval_counter; };}hjLsbah}(h]h ]h"]h$]h&]hhuh1jhhhMhjhhubh)}(hXThis contains an operations table pointer and two private pointers plus the debug ID of the fscache cookie for tracing purposes and an invalidation counter that is cranked by calls to ``fscache_invalidate()`` allowing cache subrequests to be invalidated after completion.h](hThis contains an operations table pointer and two private pointers plus the debug ID of the fscache cookie for tracing purposes and an invalidation counter that is cranked by calls to }(hjZhhhNhNubj))}(h``fscache_invalidate()``h]hfscache_invalidate()}(hjbhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjZubh? allowing cache subrequests to be invalidated after completion.}(hjZhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjhhubh)}(h4The cache operation table looks like the following::h]h3The cache operation table looks like the following:}(hjzhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubj)}(hXstruct netfs_cache_ops { void (*end_operation)(struct netfs_cache_resources *cres); void (*expand_readahead)(struct netfs_cache_resources *cres, loff_t *_start, size_t *_len, loff_t i_size); enum netfs_io_source (*prepare_read)(struct netfs_io_subrequest *subreq, loff_t i_size); int (*read)(struct netfs_cache_resources *cres, loff_t start_pos, struct iov_iter *iter, bool seek_data, netfs_io_terminated_t term_func, void *term_func_priv); void (*prepare_write_subreq)(struct netfs_io_subrequest *subreq); void (*issue_write)(struct netfs_io_subrequest *subreq); };h]hXstruct netfs_cache_ops { void (*end_operation)(struct netfs_cache_resources *cres); void (*expand_readahead)(struct netfs_cache_resources *cres, loff_t *_start, size_t *_len, loff_t i_size); enum netfs_io_source (*prepare_read)(struct netfs_io_subrequest *subreq, loff_t i_size); int (*read)(struct netfs_cache_resources *cres, loff_t start_pos, struct iov_iter *iter, bool seek_data, netfs_io_terminated_t term_func, void *term_func_priv); void (*prepare_write_subreq)(struct netfs_io_subrequest *subreq); void (*issue_write)(struct netfs_io_subrequest *subreq); };}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhMhjhhubh)}(h-With a termination handler function pointer::h]h,With a termination handler function pointer:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubj)}(htypedef void (*netfs_io_terminated_t)(void *priv, ssize_t transferred_or_error, bool was_async);h]htypedef void (*netfs_io_terminated_t)(void *priv, ssize_t transferred_or_error, bool was_async);}hjsbah}(h]h ]h"]h$]h&]hhuh1jhhhMhjhhubh)}(h%The methods defined in the table are:h]h%The methods defined in the table are:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjhhubj#)}(hX5 * ``end_operation()`` [Required] Called to clean up the resources at the end of the read request. * ``expand_readahead()`` [Optional] Called at the beginning of a readahead operation to allow the cache to expand a request in either direction. This allows the cache to size the request appropriately for the cache granularity. * ``prepare_read()`` [Required] Called to configure the next slice of a request. ->start and ->len in the subrequest indicate where and how big the next slice can be; the cache gets to reduce the length to match its granularity requirements. The function is passed pointers to the start and length in its parameters, plus the size of the file for reference, and adjusts the start and length appropriately. It should return one of: * ``NETFS_FILL_WITH_ZEROES`` * ``NETFS_DOWNLOAD_FROM_SERVER`` * ``NETFS_READ_FROM_CACHE`` * ``NETFS_INVALID_READ`` to indicate whether the slice should just be cleared or whether it should be downloaded from the server or read from the cache - or whether slicing should be given up at the current point. * ``read()`` [Required] Called to read from the cache. The start file offset is given along with an iterator to read to, which gives the length also. It can be given a hint requesting that it seek forward from that start position for data. Also provided is a pointer to a termination handler function and private data to pass to that function. The termination function should be called with the number of bytes transferred or an error code, plus a flag indicating whether the termination is definitely happening in the caller's context. * ``prepare_write_subreq()`` [Required] This is called to allow the cache to limit the size of a subrequest. It may also limit the number of individual regions in iterator, such as required by DIO/DMA. This information should be set on stream to which the subrequest belongs:: rreq->io_streams[subreq->stream_nr].sreq_max_len rreq->io_streams[subreq->stream_nr].sreq_max_segs The filesystem can use this, for example, to chop up a request that has to be split across multiple servers or to put multiple writes in flight. This is not permitted to return an error. In the event of failure, ``netfs_prepare_write_failed()`` must be called. * ``issue_write()`` [Required] This is used to dispatch a subrequest to the cache for writing. In the subrequest, ->start, ->len and ->transferred indicate what data should be written to the cache and ->io_iter indicates the buffer to be used. There is no return value; the ``netfs_write_subreq_terminated()`` function should be called to indicate that the subrequest completed either way. ->error, ->transferred and ->flags should be updated before completing. The termination can be done asynchronously. h]j))}(hhh](j.)}(ha``end_operation()`` [Required] Called to clean up the resources at the end of the read request. h](h)}(h``end_operation()``h]j))}(hjh]hend_operation()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhMhjubh)}(hK[Required] Called to clean up the resources at the end of the read request.h]hK[Required] Called to clean up the resources at the end of the read request.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubeh}(h]h ]h"]h$]h&]uh1j-hjubj.)}(h``expand_readahead()`` [Optional] Called at the beginning of a readahead operation to allow the cache to expand a request in either direction. This allows the cache to size the request appropriately for the cache granularity. h](h)}(h``expand_readahead()``h]j))}(hjh]hexpand_readahead()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhMhjubh)}(h[Optional] Called at the beginning of a readahead operation to allow the cache to expand a request in either direction. This allows the cache to size the request appropriately for the cache granularity.h]h[Optional] Called at the beginning of a readahead operation to allow the cache to expand a request in either direction. This allows the cache to size the request appropriately for the cache granularity.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubeh}(h]h ]h"]h$]h&]uh1j-hjubj.)}(hX``prepare_read()`` [Required] Called to configure the next slice of a request. ->start and ->len in the subrequest indicate where and how big the next slice can be; the cache gets to reduce the length to match its granularity requirements. The function is passed pointers to the start and length in its parameters, plus the size of the file for reference, and adjusts the start and length appropriately. It should return one of: * ``NETFS_FILL_WITH_ZEROES`` * ``NETFS_DOWNLOAD_FROM_SERVER`` * ``NETFS_READ_FROM_CACHE`` * ``NETFS_INVALID_READ`` to indicate whether the slice should just be cleared or whether it should be downloaded from the server or read from the cache - or whether slicing should be given up at the current point. h](h)}(h``prepare_read()``h]j))}(hj+h]hprepare_read()}(hj-hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj)ubah}(h]h ]h"]h$]h&]uh1hhhhMhj%ubh)}(h[Required] Called to configure the next slice of a request. ->start and ->len in the subrequest indicate where and how big the next slice can be; the cache gets to reduce the length to match its granularity requirements.h]h[Required] Called to configure the next slice of a request. ->start and ->len in the subrequest indicate where and how big the next slice can be; the cache gets to reduce the length to match its granularity requirements.}(hj@hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj%ubh)}(hThe function is passed pointers to the start and length in its parameters, plus the size of the file for reference, and adjusts the start and length appropriately. It should return one of:h]hThe function is passed pointers to the start and length in its parameters, plus the size of the file for reference, and adjusts the start and length appropriately. It should return one of:}(hjNhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj%ubj))}(hhh](j.)}(h``NETFS_FILL_WITH_ZEROES``h]h)}(hjah]j))}(hjah]hNETFS_FILL_WITH_ZEROES}(hjfhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjcubah}(h]h ]h"]h$]h&]uh1hhhhMhj_ubah}(h]h ]h"]h$]h&]uh1j-hj\ubj.)}(h``NETFS_DOWNLOAD_FROM_SERVER``h]h)}(hjh]j))}(hjh]hNETFS_DOWNLOAD_FROM_SERVER}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1j-hj\ubj.)}(h``NETFS_READ_FROM_CACHE``h]h)}(hjh]j))}(hjh]hNETFS_READ_FROM_CACHE}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1j-hj\ubj.)}(h``NETFS_INVALID_READ`` h]h)}(h``NETFS_INVALID_READ``h]j))}(hjh]hNETFS_INVALID_READ}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhMhjubah}(h]h ]h"]h$]h&]uh1j-hj\ubeh}(h]h ]h"]h$]h&]jjuh1j(hhhMhj%ubh)}(hto indicate whether the slice should just be cleared or whether it should be downloaded from the server or read from the cache - or whether slicing should be given up at the current point.h]hto indicate whether the slice should just be cleared or whether it should be downloaded from the server or read from the cache - or whether slicing should be given up at the current point.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj%ubeh}(h]h ]h"]h$]h&]uh1j-hjubj.)}(hX``read()`` [Required] Called to read from the cache. The start file offset is given along with an iterator to read to, which gives the length also. It can be given a hint requesting that it seek forward from that start position for data. Also provided is a pointer to a termination handler function and private data to pass to that function. The termination function should be called with the number of bytes transferred or an error code, plus a flag indicating whether the termination is definitely happening in the caller's context. h](h)}(h ``read()``h]j))}(hjh]hread()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhMhjubh)}(h[Required] Called to read from the cache. The start file offset is given along with an iterator to read to, which gives the length also. It can be given a hint requesting that it seek forward from that start position for data.h]h[Required] Called to read from the cache. The start file offset is given along with an iterator to read to, which gives the length also. It can be given a hint requesting that it seek forward from that start position for data.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubh)}(hX)Also provided is a pointer to a termination handler function and private data to pass to that function. The termination function should be called with the number of bytes transferred or an error code, plus a flag indicating whether the termination is definitely happening in the caller's context.h]hX+Also provided is a pointer to a termination handler function and private data to pass to that function. The termination function should be called with the number of bytes transferred or an error code, plus a flag indicating whether the termination is definitely happening in the caller’s context.}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjubeh}(h]h ]h"]h$]h&]uh1j-hjubj.)}(hX``prepare_write_subreq()`` [Required] This is called to allow the cache to limit the size of a subrequest. It may also limit the number of individual regions in iterator, such as required by DIO/DMA. This information should be set on stream to which the subrequest belongs:: rreq->io_streams[subreq->stream_nr].sreq_max_len rreq->io_streams[subreq->stream_nr].sreq_max_segs The filesystem can use this, for example, to chop up a request that has to be split across multiple servers or to put multiple writes in flight. This is not permitted to return an error. In the event of failure, ``netfs_prepare_write_failed()`` must be called. h](h)}(h``prepare_write_subreq()``h]j))}(hj=h]hprepare_write_subreq()}(hj?hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj;ubah}(h]h ]h"]h$]h&]uh1hhhhMhj7ubh)}(h[Required] This is called to allow the cache to limit the size of a subrequest. It may also limit the number of individual regions in iterator, such as required by DIO/DMA. This information should be set on stream to which the subrequest belongs::h]h[Required] This is called to allow the cache to limit the size of a subrequest. It may also limit the number of individual regions in iterator, such as required by DIO/DMA. This information should be set on stream to which the subrequest belongs:}(hjRhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj7ubj)}(hbrreq->io_streams[subreq->stream_nr].sreq_max_len rreq->io_streams[subreq->stream_nr].sreq_max_segsh]hbrreq->io_streams[subreq->stream_nr].sreq_max_len rreq->io_streams[subreq->stream_nr].sreq_max_segs}hj`sbah}(h]h ]h"]h$]h&]hhuh1jhhhMhj7ubh)}(hThe filesystem can use this, for example, to chop up a request that has to be split across multiple servers or to put multiple writes in flight.h]hThe filesystem can use this, for example, to chop up a request that has to be split across multiple servers or to put multiple writes in flight.}(hjnhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj7ubh)}(htThis is not permitted to return an error. In the event of failure, ``netfs_prepare_write_failed()`` must be called.h](hDThis is not permitted to return an error. In the event of failure, }(hj|hhhNhNubj))}(h ``netfs_prepare_write_failed()``h]hnetfs_prepare_write_failed()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj|ubh must be called.}(hj|hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhj7ubeh}(h]h ]h"]h$]h&]uh1j-hjubj.)}(hX``issue_write()`` [Required] This is used to dispatch a subrequest to the cache for writing. In the subrequest, ->start, ->len and ->transferred indicate what data should be written to the cache and ->io_iter indicates the buffer to be used. There is no return value; the ``netfs_write_subreq_terminated()`` function should be called to indicate that the subrequest completed either way. ->error, ->transferred and ->flags should be updated before completing. The termination can be done asynchronously. h](h)}(h``issue_write()``h]j))}(hjh]h issue_write()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubah}(h]h ]h"]h$]h&]uh1hhhhM hjubh)}(h[Required] This is used to dispatch a subrequest to the cache for writing. In the subrequest, ->start, ->len and ->transferred indicate what data should be written to the cache and ->io_iter indicates the buffer to be used.h]h[Required] This is used to dispatch a subrequest to the cache for writing. In the subrequest, ->start, ->len and ->transferred indicate what data should be written to the cache and ->io_iter indicates the buffer to be used.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM hjubh)}(hXThere is no return value; the ``netfs_write_subreq_terminated()`` function should be called to indicate that the subrequest completed either way. ->error, ->transferred and ->flags should be updated before completing. The termination can be done asynchronously.h](hThere is no return value; the }(hjhhhNhNubj))}(h#``netfs_write_subreq_terminated()``h]hnetfs_write_subreq_terminated()}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjubh function should be called to indicate that the subrequest completed either way. ->error, ->transferred and ->flags should be updated before completing. The termination can be done asynchronously.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjubeh}(h]h ]h"]h$]h&]uh1j-hjubeh}(h]h ]h"]h$]h&]jjuh1j(hhhMhjubah}(h]h ]h"]h$]h&]uh1j"hhhMhjhhubeh}(h]local-cache-apiah ]h"]local cache apiah$]h&]uh1hhj hhhhhMubeh}(h]i-o-request-apiah ]h"]i/o request apiah$]h&]uh1hhhhhhhhMubh)}(hhh](h)}(hAPI Function Referenceh]hAPI Function Reference}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhMubhindex)}(hhh]h}(h]h ]h"]h$]h&]entries](single"folio_start_private_2 (C function)c.folio_start_private_2hNtauh1jhj hhhNhNubhdesc)}(hhh](hdesc_signature)}(h0void folio_start_private_2 (struct folio *folio)h]hdesc_signature_line)}(h/void folio_start_private_2(struct folio *folio)h](hdesc_sig_keyword_type)}(hvoidh]hvoid}(hjBhhhNhNubah}(h]h ]ktah"]h$]h&]uh1j@hj<hhha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhKubhdesc_sig_space)}(h h]h }(hjThhhNhNubah}(h]h ]wah"]h$]h&]uh1jRhj<hhhjQhKubh desc_name)}(hfolio_start_private_2h]h desc_sig_name)}(hfolio_start_private_2h]hfolio_start_private_2}(hjkhhhNhNubah}(h]h ]nah"]h$]h&]uh1jihjeubah}(h]h ](sig-namedescnameeh"]h$]h&]hhuh1jchj<hhhjQhKubhdesc_parameterlist)}(h(struct folio *folio)h]hdesc_parameter)}(hstruct folio *folioh](hdesc_sig_keyword)}(hstructh]hstruct}(hjhhhNhNubah}(h]h ]kah"]h$]h&]uh1jhjubjS)}(h h]h }(hjhhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhjubh)}(hhh]jj)}(hfolioh]hfolio}(hjhhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihjubah}(h]h ]h"]h$]h&] refdomaincreftype identifier reftargetjmodnameN classnameN c:parent_keysphinx.domains.c LookupKey)}data]j ASTIdentifier)}jjmsbc.folio_start_private_2asbuh1hhjubjS)}(h h]h }(hjhhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhjubhdesc_sig_punctuation)}(hjh]h*}(hjhhhNhNubah}(h]h ]pah"]h$]h&]uh1jhjubjj)}(hfolioh]hfolio}(hjhhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihjubeh}(h]h ]h"]h$]h&]noemphhhuh1jhjubah}(h]h ]h"]h$]h&]hhuh1jhj<hhhjQhKubeh}(h]h ]h"]h$]h&]hh add_permalinkuh1j:sphinx_line_type declaratorhj6hhhjQhKubah}(h]j-ah ](sig sig-objecteh"]h$]h&] is_multiline _toc_parts) _toc_namehuh1j4hjQhKhj1hhubh desc_content)}(hhh]h)}(h/Start an fscache write on a folio. [DEPRECATED]h]h/Start an fscache write on a folio. [DEPRECATED]}(hj+hhhNhNubah}(h]h ]h"]h$]h&]uh1hha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhKhj(hhubah}(h]h ]h"]h$]h&]uh1j&hj1hhhjQhKubeh}(h]h ](jfunctioneh"]h$]h&]domainjobjtypejCdesctypejCnoindex noindexentrynocontentsentryuh1j/hhhj hNhNubh container)}(h**Parameters** ``struct folio *folio`` The folio. **Description** Call this function before writing a folio to a local cache. Starting a second write before the first one finishes is not allowed. Note that this should no longer be used.h](h)}(h**Parameters**h]hstrong)}(hjUh]h Parameters}(hjYhhhNhNubah}(h]h ]h"]h$]h&]uh1jWhjSubah}(h]h ]h"]h$]h&]uh1hha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhK hjOubhdefinition_list)}(hhh]hdefinition_list_item)}(h#``struct folio *folio`` The folio. h](hterm)}(h``struct folio *folio``h]j))}(hj|h]hstruct folio *folio}(hj~hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjzubah}(h]h ]h"]h$]h&]uh1jxha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhKhjtubh definition)}(hhh]h)}(h The folio.h]h The folio.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjubah}(h]h ]h"]h$]h&]uh1jhjtubeh}(h]h ]h"]h$]h&]uh1jrhjhKhjoubah}(h]h ]h"]h$]h&]uh1jmhjOubh)}(h**Description**h]jX)}(hjh]h Description}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jWhjubah}(h]h ]h"]h$]h&]uh1hha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhKhjOubh)}(hCall this function before writing a folio to a local cache. Starting a second write before the first one finishes is not allowed.h]hCall this function before writing a folio to a local cache. Starting a second write before the first one finishes is not allowed.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhKhjOubh)}(h(Note that this should no longer be used.h]h(Note that this should no longer be used.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhK"hjOubeh}(h]h ] kernelindentah"]h$]h&]uh1jMhj hhhNhNubj)}(hhh]h}(h]h ]h"]h$]h&]entries](j+netfs_inode (C function) c.netfs_inodehNtauh1jhj hhhNhNubj0)}(hhh](j5)}(h6struct netfs_inode * netfs_inode (struct inode *inode)h]j;)}(h4struct netfs_inode *netfs_inode(struct inode *inode)h](j)}(hjh]hstruct}(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj hhha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhMubjS)}(h h]h }(hjhhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhj hhhjhMubh)}(hhh]jj)}(h netfs_inodeh]h netfs_inode}(hj,hhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihj)ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj.modnameN classnameNjj)}j]j)}j netfs_inodesb c.netfs_inodeasbuh1hhj hhhjhMubjS)}(h h]h }(hjMhhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhj hhhjhMubj)}(hjh]h*}(hj[hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj hhhjhMubjd)}(h netfs_inodeh]jj)}(hjJh]h netfs_inode}(hjlhhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihjhubah}(h]h ](j}j~eh"]h$]h&]hhuh1jchj hhhjhMubj)}(h(struct inode *inode)h]j)}(hstruct inode *inodeh](j)}(hjh]hstruct}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubjS)}(h h]h }(hjhhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhjubh)}(hhh]jj)}(hinodeh]hinode}(hjhhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihjubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetjmodnameN classnameNjj)}j]jH c.netfs_inodeasbuh1hhjubjS)}(h h]h }(hjhhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhjubj)}(hjh]h*}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubjj)}(hinodeh]hinode}(hjhhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihjubeh}(h]h ]h"]h$]h&]noemphhhuh1jhjubah}(h]h ]h"]h$]h&]hhuh1jhj hhhjhMubeh}(h]h ]h"]h$]h&]hhjuh1j:jjhjhhhjhMubah}(h]jah ](jjeh"]h$]h&]j#j$)j%huh1j4hjhMhjhhubj')}(hhh]h)}(h*Get the netfs inode context from the inodeh]h*Get the netfs inode context from the inode}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhMhjhhubah}(h]h ]h"]h$]h&]uh1j&hjhhhjhMubeh}(h]h ](jfunctioneh"]h$]h&]jGjjHj jIj jJjKjLuh1j/hhhj hNhNubjN)}(h**Parameters** ``struct inode *inode`` The inode to query **Description** Get the netfs lib inode context from the network filesystem's inode. The context struct is expected to directly follow on from the VFS inode struct.h](h)}(h**Parameters**h]jX)}(hj*h]h Parameters}(hj,hhhNhNubah}(h]h ]h"]h$]h&]uh1jWhj(ubah}(h]h ]h"]h$]h&]uh1hha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhMhj$ubjn)}(hhh]js)}(h+``struct inode *inode`` The inode to query h](jy)}(h``struct inode *inode``h]j))}(hjIh]hstruct inode *inode}(hjKhhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjGubah}(h]h ]h"]h$]h&]uh1jxha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhMhjCubj)}(hhh]h)}(hThe inode to queryh]hThe inode to query}(hjbhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj^hMhj_ubah}(h]h ]h"]h$]h&]uh1jhjCubeh}(h]h ]h"]h$]h&]uh1jrhj^hMhj@ubah}(h]h ]h"]h$]h&]uh1jmhj$ubh)}(h**Description**h]jX)}(hjh]h Description}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jWhjubah}(h]h ]h"]h$]h&]uh1hha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhMhj$ubh)}(hGet the netfs lib inode context from the network filesystem's inode. The context struct is expected to directly follow on from the VFS inode struct.h]hGet the netfs lib inode context from the network filesystem’s inode. The context struct is expected to directly follow on from the VFS inode struct.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhMhj$ubeh}(h]h ] kernelindentah"]h$]h&]uh1jMhj hhhNhNubj)}(hhh]h}(h]h ]h"]h$]h&]entries](j+netfs_inode_init (C function)c.netfs_inode_inithNtauh1jhj hhhNhNubj0)}(hhh](j5)}(hivoid netfs_inode_init (struct netfs_inode *ctx, const struct netfs_request_ops *ops, bool use_zero_point)h]j;)}(hhvoid netfs_inode_init(struct netfs_inode *ctx, const struct netfs_request_ops *ops, bool use_zero_point)h](jA)}(hvoidh]hvoid}(hjhhhNhNubah}(h]h ]jMah"]h$]h&]uh1j@hjhhha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhMubjS)}(h h]h }(hjhhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhjhhhjhMubjd)}(hnetfs_inode_inith]jj)}(hnetfs_inode_inith]hnetfs_inode_init}(hjhhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihjubah}(h]h ](j}j~eh"]h$]h&]hhuh1jchjhhhjhMubj)}(hS(struct netfs_inode *ctx, const struct netfs_request_ops *ops, bool use_zero_point)h](j)}(hstruct netfs_inode *ctxh](j)}(hjh]hstruct}(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj ubjS)}(h h]h }(hj hhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhj ubh)}(hhh]jj)}(h netfs_inodeh]h netfs_inode}(hj$ hhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihj! ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj& modnameN classnameNjj)}j]j)}jjsbc.netfs_inode_initasbuh1hhj ubjS)}(h h]h }(hjD hhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhj ubj)}(hjh]h*}(hjR hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj ubjj)}(hctxh]hctx}(hj_ hhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihj ubeh}(h]h ]h"]h$]h&]noemphhhuh1jhjubj)}(h#const struct netfs_request_ops *opsh](j)}(hconsth]hconst}(hjx hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjt ubjS)}(h h]h }(hj hhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhjt ubj)}(hjh]hstruct}(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjt ubjS)}(h h]h }(hj hhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhjt ubh)}(hhh]jj)}(hnetfs_request_opsh]hnetfs_request_ops}(hj hhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihj ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj modnameN classnameNjj)}j]j@ c.netfs_inode_initasbuh1hhjt ubjS)}(h h]h }(hj hhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhjt ubj)}(hjh]h*}(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjt ubjj)}(hopsh]hops}(hj hhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihjt ubeh}(h]h ]h"]h$]h&]noemphhhuh1jhjubj)}(hbool use_zero_pointh](jA)}(hboolh]hbool}(hj!hhhNhNubah}(h]h ]jMah"]h$]h&]uh1j@hj!ubjS)}(h h]h }(hj!hhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhj!ubjj)}(huse_zero_pointh]huse_zero_point}(hj !hhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihj!ubeh}(h]h ]h"]h$]h&]noemphhhuh1jhjubeh}(h]h ]h"]h$]h&]hhuh1jhjhhhjhMubeh}(h]h ]h"]h$]h&]hhjuh1j:jjhjhhhjhMubah}(h]jah ](jjeh"]h$]h&]j#j$)j%huh1j4hjhMhjhhubj')}(hhh]h)}(h#Initialise a netfslib inode contexth]h#Initialise a netfslib inode context}(hjJ!hhhNhNubah}(h]h ]h"]h$]h&]uh1hha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhMhjG!hhubah}(h]h ]h"]h$]h&]uh1j&hjhhhjhMubeh}(h]h ](jfunctioneh"]h$]h&]jGjjHjb!jIjb!jJjKjLuh1j/hhhj hNhNubjN)}(hX\**Parameters** ``struct netfs_inode *ctx`` The netfs inode to initialise ``const struct netfs_request_ops *ops`` The netfs's operations list ``bool use_zero_point`` True to use the zero_point read optimisation **Description** Initialise the netfs library context struct. This is expected to follow on directly from the VFS inode struct.h](h)}(h**Parameters**h]jX)}(hjl!h]h Parameters}(hjn!hhhNhNubah}(h]h ]h"]h$]h&]uh1jWhjj!ubah}(h]h ]h"]h$]h&]uh1hha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhMhjf!ubjn)}(hhh](js)}(h:``struct netfs_inode *ctx`` The netfs inode to initialise h](jy)}(h``struct netfs_inode *ctx``h]j))}(hj!h]hstruct netfs_inode *ctx}(hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj!ubah}(h]h ]h"]h$]h&]uh1jxha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhMhj!ubj)}(hhh]h)}(hThe netfs inode to initialiseh]hThe netfs inode to initialise}(hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj!hMhj!ubah}(h]h ]h"]h$]h&]uh1jhj!ubeh}(h]h ]h"]h$]h&]uh1jrhj!hMhj!ubjs)}(hD``const struct netfs_request_ops *ops`` The netfs's operations list h](jy)}(h'``const struct netfs_request_ops *ops``h]j))}(hj!h]h#const struct netfs_request_ops *ops}(hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj!ubah}(h]h ]h"]h$]h&]uh1jxha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhMhj!ubj)}(hhh]h)}(hThe netfs's operations listh]hThe netfs’s operations list}(hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj!hMhj!ubah}(h]h ]h"]h$]h&]uh1jhj!ubeh}(h]h ]h"]h$]h&]uh1jrhj!hMhj!ubjs)}(hE``bool use_zero_point`` True to use the zero_point read optimisation h](jy)}(h``bool use_zero_point``h]j))}(hj!h]hbool use_zero_point}(hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj!ubah}(h]h ]h"]h$]h&]uh1jxha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhMhj!ubj)}(hhh]h)}(h,True to use the zero_point read optimisationh]h,True to use the zero_point read optimisation}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj"hMhj"ubah}(h]h ]h"]h$]h&]uh1jhj!ubeh}(h]h ]h"]h$]h&]uh1jrhj"hMhj!ubeh}(h]h ]h"]h$]h&]uh1jmhjf!ubh)}(h**Description**h]jX)}(hj8"h]h Description}(hj:"hhhNhNubah}(h]h ]h"]h$]h&]uh1jWhj6"ubah}(h]h ]h"]h$]h&]uh1hha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhMhjf!ubh)}(hoInitialise the netfs library context struct. This is expected to follow on directly from the VFS inode struct.h]hoInitialise the netfs library context struct. This is expected to follow on directly from the VFS inode struct.}(hjN"hhhNhNubah}(h]h ]h"]h$]h&]uh1hha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhMhjf!ubeh}(h]h ] kernelindentah"]h$]h&]uh1jMhj hhhNhNubj)}(hhh]h}(h]h ]h"]h$]h&]entries](j+netfs_resize_file (C function)c.netfs_resize_filehNtauh1jhj hhhNhNubj0)}(hhh](j5)}(h[void netfs_resize_file (struct netfs_inode *ctx, loff_t new_i_size, bool changed_on_server)h]j;)}(hZvoid netfs_resize_file(struct netfs_inode *ctx, loff_t new_i_size, bool changed_on_server)h](jA)}(hvoidh]hvoid}(hj}"hhhNhNubah}(h]h ]jMah"]h$]h&]uh1j@hjy"hhha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhMubjS)}(h h]h }(hj"hhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhjy"hhhj"hMubjd)}(hnetfs_resize_fileh]jj)}(hnetfs_resize_fileh]hnetfs_resize_file}(hj"hhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihj"ubah}(h]h ](j}j~eh"]h$]h&]hhuh1jchjy"hhhj"hMubj)}(hD(struct netfs_inode *ctx, loff_t new_i_size, bool changed_on_server)h](j)}(hstruct netfs_inode *ctxh](j)}(hjh]hstruct}(hj"hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj"ubjS)}(h h]h }(hj"hhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhj"ubh)}(hhh]jj)}(h netfs_inodeh]h netfs_inode}(hj"hhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihj"ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj"modnameN classnameNjj)}j]j)}jj"sbc.netfs_resize_fileasbuh1hhj"ubjS)}(h h]h }(hj"hhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhj"ubj)}(hjh]h*}(hj#hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj"ubjj)}(hctxh]hctx}(hj#hhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihj"ubeh}(h]h ]h"]h$]h&]noemphhhuh1jhj"ubj)}(hloff_t new_i_sizeh](h)}(hhh]jj)}(hloff_th]hloff_t}(hj/#hhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihj,#ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj1#modnameN classnameNjj)}j]j"c.netfs_resize_fileasbuh1hhj(#ubjS)}(h h]h }(hjM#hhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhj(#ubjj)}(h new_i_sizeh]h new_i_size}(hj[#hhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihj(#ubeh}(h]h ]h"]h$]h&]noemphhhuh1jhj"ubj)}(hbool changed_on_serverh](jA)}(hj!h]hbool}(hjt#hhhNhNubah}(h]h ]jMah"]h$]h&]uh1j@hjp#ubjS)}(h h]h }(hj#hhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhjp#ubjj)}(hchanged_on_serverh]hchanged_on_server}(hj#hhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihjp#ubeh}(h]h ]h"]h$]h&]noemphhhuh1jhj"ubeh}(h]h ]h"]h$]h&]hhuh1jhjy"hhhj"hMubeh}(h]h ]h"]h$]h&]hhjuh1j:jjhju"hhhj"hMubah}(h]jp"ah ](jjeh"]h$]h&]j#j$)j%huh1j4hj"hMhjr"hhubj')}(hhh]h)}(hNote that a file got resizedh]hNote that a file got resized}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1hha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhMhj#hhubah}(h]h ]h"]h$]h&]uh1j&hjr"hhhj"hMubeh}(h]h ](jfunctioneh"]h$]h&]jGjjHj#jIj#jJjKjLuh1j/hhhj hNhNubjN)}(hX**Parameters** ``struct netfs_inode *ctx`` The netfs inode being resized ``loff_t new_i_size`` The new file size ``bool changed_on_server`` The change was applied to the server **Description** Inform the netfs lib that a file got resized so that it can adjust its state.h](h)}(h**Parameters**h]jX)}(hj#h]h Parameters}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1jWhj#ubah}(h]h ]h"]h$]h&]uh1hha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhMhj#ubjn)}(hhh](js)}(h:``struct netfs_inode *ctx`` The netfs inode being resized h](jy)}(h``struct netfs_inode *ctx``h]j))}(hj#h]hstruct netfs_inode *ctx}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj#ubah}(h]h ]h"]h$]h&]uh1jxha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhMhj#ubj)}(hhh]h)}(hThe netfs inode being resizedh]hThe netfs inode being resized}(hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj$hMhj$ubah}(h]h ]h"]h$]h&]uh1jhj#ubeh}(h]h ]h"]h$]h&]uh1jrhj$hMhj#ubjs)}(h(``loff_t new_i_size`` The new file size h](jy)}(h``loff_t new_i_size``h]j))}(hj3$h]hloff_t new_i_size}(hj5$hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj1$ubah}(h]h ]h"]h$]h&]uh1jxha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhMhj-$ubj)}(hhh]h)}(hThe new file sizeh]hThe new file size}(hjL$hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjH$hMhjI$ubah}(h]h ]h"]h$]h&]uh1jhj-$ubeh}(h]h ]h"]h$]h&]uh1jrhjH$hMhj#ubjs)}(h@``bool changed_on_server`` The change was applied to the server h](jy)}(h``bool changed_on_server``h]j))}(hjl$h]hbool changed_on_server}(hjn$hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjj$ubah}(h]h ]h"]h$]h&]uh1jxha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhMhjf$ubj)}(hhh]h)}(h$The change was applied to the serverh]h$The change was applied to the server}(hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj$hMhj$ubah}(h]h ]h"]h$]h&]uh1jhjf$ubeh}(h]h ]h"]h$]h&]uh1jrhj$hMhj#ubeh}(h]h ]h"]h$]h&]uh1jmhj#ubh)}(h**Description**h]jX)}(hj$h]h Description}(hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1jWhj$ubah}(h]h ]h"]h$]h&]uh1hha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhMhj#ubh)}(hMInform the netfs lib that a file got resized so that it can adjust its state.h]hMInform the netfs lib that a file got resized so that it can adjust its state.}(hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1hha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhMhj#ubeh}(h]h ] kernelindentah"]h$]h&]uh1jMhj hhhNhNubj)}(hhh]h}(h]h ]h"]h$]h&]entries](j+netfs_i_cookie (C function)c.netfs_i_cookiehNtauh1jhj hhhNhNubj0)}(hhh](j5)}(h@struct fscache_cookie * netfs_i_cookie (struct netfs_inode *ctx)h]j;)}(h>struct fscache_cookie *netfs_i_cookie(struct netfs_inode *ctx)h](j)}(hjh]hstruct}(hj$hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj$hhha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhMubjS)}(h h]h }(hj$hhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhj$hhhj$hMubh)}(hhh]jj)}(hfscache_cookieh]hfscache_cookie}(hj %hhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihj%ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj %modnameN classnameNjj)}j]j)}jnetfs_i_cookiesbc.netfs_i_cookieasbuh1hhj$hhhj$hMubjS)}(h h]h }(hj,%hhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhj$hhhj$hMubj)}(hjh]h*}(hj:%hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj$hhhj$hMubjd)}(hnetfs_i_cookieh]jj)}(hj)%h]hnetfs_i_cookie}(hjK%hhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihjG%ubah}(h]h ](j}j~eh"]h$]h&]hhuh1jchj$hhhj$hMubj)}(h(struct netfs_inode *ctx)h]j)}(hstruct netfs_inode *ctxh](j)}(hjh]hstruct}(hjf%hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjb%ubjS)}(h h]h }(hjs%hhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhjb%ubh)}(hhh]jj)}(h netfs_inodeh]h netfs_inode}(hj%hhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihj%ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj%modnameN classnameNjj)}j]j'%c.netfs_i_cookieasbuh1hhjb%ubjS)}(h h]h }(hj%hhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhjb%ubj)}(hjh]h*}(hj%hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjb%ubjj)}(hctxh]hctx}(hj%hhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihjb%ubeh}(h]h ]h"]h$]h&]noemphhhuh1jhj^%ubah}(h]h ]h"]h$]h&]hhuh1jhj$hhhj$hMubeh}(h]h ]h"]h$]h&]hhjuh1j:jjhj$hhhj$hMubah}(h]j$ah ](jjeh"]h$]h&]j#j$)j%huh1j4hj$hMhj$hhubj')}(hhh]h)}(h#Get the cache cookie from the inodeh]h#Get the cache cookie from the inode}(hj%hhhNhNubah}(h]h ]h"]h$]h&]uh1hha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhMhj%hhubah}(h]h ]h"]h$]h&]uh1j&hj$hhhj$hMubeh}(h]h ](jfunctioneh"]h$]h&]jGjjHj%jIj%jJjKjLuh1j/hhhj hNhNubjN)}(h**Parameters** ``struct netfs_inode *ctx`` The netfs inode to query **Description** Get the caching cookie (if enabled) from the network filesystem's inode.h](h)}(h**Parameters**h]jX)}(hj &h]h Parameters}(hj &hhhNhNubah}(h]h ]h"]h$]h&]uh1jWhj&ubah}(h]h ]h"]h$]h&]uh1hha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhMhj&ubjn)}(hhh]js)}(h5``struct netfs_inode *ctx`` The netfs inode to query h](jy)}(h``struct netfs_inode *ctx``h]j))}(hj(&h]hstruct netfs_inode *ctx}(hj*&hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj&&ubah}(h]h ]h"]h$]h&]uh1jxha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhMhj"&ubj)}(hhh]h)}(hThe netfs inode to queryh]hThe netfs inode to query}(hjA&hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj=&hMhj>&ubah}(h]h ]h"]h$]h&]uh1jhj"&ubeh}(h]h ]h"]h$]h&]uh1jrhj=&hMhj&ubah}(h]h ]h"]h$]h&]uh1jmhj&ubh)}(h**Description**h]jX)}(hjc&h]h Description}(hje&hhhNhNubah}(h]h ]h"]h$]h&]uh1jWhja&ubah}(h]h ]h"]h$]h&]uh1hha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhMhj&ubh)}(hHGet the caching cookie (if enabled) from the network filesystem's inode.h]hJGet the caching cookie (if enabled) from the network filesystem’s inode.}(hjy&hhhNhNubah}(h]h ]h"]h$]h&]uh1hha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhMhj&ubeh}(h]h ] kernelindentah"]h$]h&]uh1jMhj hhhNhNubj)}(hhh]h}(h]h ]h"]h$]h&]entries](j+*netfs_wait_for_outstanding_io (C function)c.netfs_wait_for_outstanding_iohNtauh1jhj hhhNhNubj0)}(hhh](j5)}(h8void netfs_wait_for_outstanding_io (struct inode *inode)h]j;)}(h7void netfs_wait_for_outstanding_io(struct inode *inode)h](jA)}(hvoidh]hvoid}(hj&hhhNhNubah}(h]h ]jMah"]h$]h&]uh1j@hj&hhha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhMubjS)}(h h]h }(hj&hhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhj&hhhj&hMubjd)}(hnetfs_wait_for_outstanding_ioh]jj)}(hnetfs_wait_for_outstanding_ioh]hnetfs_wait_for_outstanding_io}(hj&hhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihj&ubah}(h]h ](j}j~eh"]h$]h&]hhuh1jchj&hhhj&hMubj)}(h(struct inode *inode)h]j)}(hstruct inode *inodeh](j)}(hjh]hstruct}(hj&hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj&ubjS)}(h h]h }(hj&hhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhj&ubh)}(hhh]jj)}(hinodeh]hinode}(hj'hhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihj'ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj'modnameN classnameNjj)}j]j)}jj&sbc.netfs_wait_for_outstanding_ioasbuh1hhj&ubjS)}(h h]h }(hj#'hhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhj&ubj)}(hjh]h*}(hj1'hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj&ubjj)}(hinodeh]hinode}(hj>'hhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihj&ubeh}(h]h ]h"]h$]h&]noemphhhuh1jhj&ubah}(h]h ]h"]h$]h&]hhuh1jhj&hhhj&hMubeh}(h]h ]h"]h$]h&]hhjuh1j:jjhj&hhhj&hMubah}(h]j&ah ](jjeh"]h$]h&]j#j$)j%huh1j4hj&hMhj&hhubj')}(hhh]h)}(h$Wait for outstanding I/O to completeh]h$Wait for outstanding I/O to complete}(hjh'hhhNhNubah}(h]h ]h"]h$]h&]uh1hha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhMhje'hhubah}(h]h ]h"]h$]h&]uh1j&hj&hhhj&hMubeh}(h]h ](jfunctioneh"]h$]h&]jGjjHj'jIj'jJjKjLuh1j/hhhj hNhNubjN)}(hX@**Parameters** ``struct inode *inode`` The netfs inode to wait on **Description** Wait for outstanding I/O requests of any type to complete. This is intended to be called from inode eviction routines. This makes sure that any resources held by those requests are cleaned up before we let the inode get cleaned up.h](h)}(h**Parameters**h]jX)}(hj'h]h Parameters}(hj'hhhNhNubah}(h]h ]h"]h$]h&]uh1jWhj'ubah}(h]h ]h"]h$]h&]uh1hha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhM!hj'ubjn)}(hhh]js)}(h3``struct inode *inode`` The netfs inode to wait on h](jy)}(h``struct inode *inode``h]j))}(hj'h]hstruct inode *inode}(hj'hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj'ubah}(h]h ]h"]h$]h&]uh1jxha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhMhj'ubj)}(hhh]h)}(hThe netfs inode to wait onh]hThe netfs inode to wait on}(hj'hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj'hMhj'ubah}(h]h ]h"]h$]h&]uh1jhj'ubeh}(h]h ]h"]h$]h&]uh1jrhj'hMhj'ubah}(h]h ]h"]h$]h&]uh1jmhj'ubh)}(h**Description**h]jX)}(hj'h]h Description}(hj'hhhNhNubah}(h]h ]h"]h$]h&]uh1jWhj'ubah}(h]h ]h"]h$]h&]uh1hha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhM hj'ubh)}(hWait for outstanding I/O requests of any type to complete. This is intended to be called from inode eviction routines. This makes sure that any resources held by those requests are cleaned up before we let the inode get cleaned up.h]hWait for outstanding I/O requests of any type to complete. This is intended to be called from inode eviction routines. This makes sure that any resources held by those requests are cleaned up before we let the inode get cleaned up.}(hj'hhhNhNubah}(h]h ]h"]h$]h&]uh1hha/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1050: ./include/linux/netfs.hhM hj'ubeh}(h]h ] kernelindentah"]h$]h&]uh1jMhj hhhNhNubj)}(hhh]h}(h]h ]h"]h$]h&]entries](j+netfs_readahead (C function)c.netfs_readaheadhNtauh1jhj hhhNhNubj0)}(hhh](j5)}(h6void netfs_readahead (struct readahead_control *ractl)h]j;)}(h5void netfs_readahead(struct readahead_control *ractl)h](jA)}(hvoidh]hvoid}(hj)(hhhNhNubah}(h]h ]jMah"]h$]h&]uh1j@hj%(hhhd/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1051: ./fs/netfs/buffered_read.chMEubjS)}(h h]h }(hj8(hhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhj%(hhhj7(hMEubjd)}(hnetfs_readaheadh]jj)}(hnetfs_readaheadh]hnetfs_readahead}(hjJ(hhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihjF(ubah}(h]h ](j}j~eh"]h$]h&]hhuh1jchj%(hhhj7(hMEubj)}(h!(struct readahead_control *ractl)h]j)}(hstruct readahead_control *ractlh](j)}(hjh]hstruct}(hjf(hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjb(ubjS)}(h h]h }(hjs(hhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhjb(ubh)}(hhh]jj)}(hreadahead_controlh]hreadahead_control}(hj(hhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihj(ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj(modnameN classnameNjj)}j]j)}jjL(sbc.netfs_readaheadasbuh1hhjb(ubjS)}(h h]h }(hj(hhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhjb(ubj)}(hjh]h*}(hj(hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjb(ubjj)}(hractlh]hractl}(hj(hhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihjb(ubeh}(h]h ]h"]h$]h&]noemphhhuh1jhj^(ubah}(h]h ]h"]h$]h&]hhuh1jhj%(hhhj7(hMEubeh}(h]h ]h"]h$]h&]hhjuh1j:jjhj!(hhhj7(hMEubah}(h]j(ah ](jjeh"]h$]h&]j#j$)j%huh1j4hj7(hMEhj(hhubj')}(hhh]h)}(hHelper to manage a read requesth]hHelper to manage a read request}(hj(hhhNhNubah}(h]h ]h"]h$]h&]uh1hhd/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1051: ./fs/netfs/buffered_read.chMEhj(hhubah}(h]h ]h"]h$]h&]uh1j&hj(hhhj7(hMEubeh}(h]h ](jfunctioneh"]h$]h&]jGjjHj)jIj)jJjKjLuh1j/hhhj hNhNubjN)}(hXu**Parameters** ``struct readahead_control *ractl`` The description of the readahead request **Description** Fulfil a readahead request by drawing data from the cache if possible, or the netfs if not. Space beyond the EOF is zero-filled. Multiple I/O requests from different sources will get munged together. If necessary, the readahead window can be expanded in either direction to a more convenient alighment for RPC efficiency or to make storage in the cache feasible. The calling netfs must initialise a netfs context contiguous to the vfs inode before calling this. This is usable whether or not caching is enabled.h](h)}(h**Parameters**h]jX)}(hj )h]h Parameters}(hj )hhhNhNubah}(h]h ]h"]h$]h&]uh1jWhj )ubah}(h]h ]h"]h$]h&]uh1hhd/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1051: ./fs/netfs/buffered_read.chMIhj)ubjn)}(hhh]js)}(hM``struct readahead_control *ractl`` The description of the readahead request h](jy)}(h#``struct readahead_control *ractl``h]j))}(hj*)h]hstruct readahead_control *ractl}(hj,)hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj()ubah}(h]h ]h"]h$]h&]uh1jxhd/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1051: ./fs/netfs/buffered_read.chMFhj$)ubj)}(hhh]h)}(h(The description of the readahead requesth]h(The description of the readahead request}(hjC)hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj?)hMFhj@)ubah}(h]h ]h"]h$]h&]uh1jhj$)ubeh}(h]h ]h"]h$]h&]uh1jrhj?)hMFhj!)ubah}(h]h ]h"]h$]h&]uh1jmhj)ubh)}(h**Description**h]jX)}(hje)h]h Description}(hjg)hhhNhNubah}(h]h ]h"]h$]h&]uh1jWhjc)ubah}(h]h ]h"]h$]h&]uh1hhd/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1051: ./fs/netfs/buffered_read.chMHhj)ubh)}(hXmFulfil a readahead request by drawing data from the cache if possible, or the netfs if not. Space beyond the EOF is zero-filled. Multiple I/O requests from different sources will get munged together. If necessary, the readahead window can be expanded in either direction to a more convenient alighment for RPC efficiency or to make storage in the cache feasible.h]hXmFulfil a readahead request by drawing data from the cache if possible, or the netfs if not. Space beyond the EOF is zero-filled. Multiple I/O requests from different sources will get munged together. If necessary, the readahead window can be expanded in either direction to a more convenient alighment for RPC efficiency or to make storage in the cache feasible.}(hj{)hhhNhNubah}(h]h ]h"]h$]h&]uh1hhd/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1051: ./fs/netfs/buffered_read.chMHhj)ubh)}(hbThe calling netfs must initialise a netfs context contiguous to the vfs inode before calling this.h]hbThe calling netfs must initialise a netfs context contiguous to the vfs inode before calling this.}(hj)hhhNhNubah}(h]h ]h"]h$]h&]uh1hhd/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1051: ./fs/netfs/buffered_read.chMNhj)ubh)}(h1This is usable whether or not caching is enabled.h]h1This is usable whether or not caching is enabled.}(hj)hhhNhNubah}(h]h ]h"]h$]h&]uh1hhd/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1051: ./fs/netfs/buffered_read.chMQhj)ubeh}(h]h ] kernelindentah"]h$]h&]uh1jMhj hhhNhNubj)}(hhh]h}(h]h ]h"]h$]h&]entries](j+netfs_read_folio (C function)c.netfs_read_foliohNtauh1jhj hhhNhNubj0)}(hhh](j5)}(h=int netfs_read_folio (struct file *file, struct folio *folio)h]j;)}(hread_iter() routine for all filesystems that can use the page cache directly. The IOCB_NOWAIT flag in iocb->ki_flags indicates that -EAGAIN shall be returned when no data can be read without waiting for I/O requests to complete; it doesn't prevent readahead. The IOCB_NOIO flag in iocb->ki_flags indicates that no new I/O requests shall be made for the read or for readahead. When no data can be read, -EAGAIN shall be returned. When readahead would be triggered, a partial, possibly empty read shall be returned. **Return** * number of bytes copied, even for partial reads * negative error code (or 0 if IOCB_NOIO) if nothing was readh](h)}(h**Parameters**h]jX)}(hj2h]h Parameters}(hj2hhhNhNubah}(h]h ]h"]h$]h&]uh1jWhj2ubah}(h]h ]h"]h$]h&]uh1hhd/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1051: ./fs/netfs/buffered_read.chMhj2ubjn)}(hhh](js)}(h0``struct kiocb *iocb`` kernel I/O control block h](jy)}(h``struct kiocb *iocb``h]j))}(hj 3h]hstruct kiocb *iocb}(hj3hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj 3ubah}(h]h ]h"]h$]h&]uh1jxhd/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1051: ./fs/netfs/buffered_read.chMhj3ubj)}(hhh]h)}(hkernel I/O control blockh]hkernel I/O control block}(hj&3hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj"3hMhj#3ubah}(h]h ]h"]h$]h&]uh1jhj3ubeh}(h]h ]h"]h$]h&]uh1jrhj"3hMhj3ubjs)}(h8``struct iov_iter *iter`` destination for the data read h](jy)}(h``struct iov_iter *iter``h]j))}(hjF3h]hstruct iov_iter *iter}(hjH3hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hjD3ubah}(h]h ]h"]h$]h&]uh1jxhd/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1051: ./fs/netfs/buffered_read.chMhj@3ubj)}(hhh]h)}(hdestination for the data readh]hdestination for the data read}(hj_3hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj[3hMhj\3ubah}(h]h ]h"]h$]h&]uh1jhj@3ubeh}(h]h ]h"]h$]h&]uh1jrhj[3hMhj3ubeh}(h]h ]h"]h$]h&]uh1jmhj2ubh)}(h**Description**h]jX)}(hj3h]h Description}(hj3hhhNhNubah}(h]h ]h"]h$]h&]uh1jWhj3ubah}(h]h ]h"]h$]h&]uh1hhd/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1051: ./fs/netfs/buffered_read.chMhj2ubh)}(h[This is the ->read_iter() routine for all filesystems that can use the page cache directly.h]h[This is the ->read_iter() routine for all filesystems that can use the page cache directly.}(hj3hhhNhNubah}(h]h ]h"]h$]h&]uh1hhd/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1051: ./fs/netfs/buffered_read.chMhj2ubh)}(hThe IOCB_NOWAIT flag in iocb->ki_flags indicates that -EAGAIN shall be returned when no data can be read without waiting for I/O requests to complete; it doesn't prevent readahead.h]hThe IOCB_NOWAIT flag in iocb->ki_flags indicates that -EAGAIN shall be returned when no data can be read without waiting for I/O requests to complete; it doesn’t prevent readahead.}(hj3hhhNhNubah}(h]h ]h"]h$]h&]uh1hhd/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1051: ./fs/netfs/buffered_read.chMhj2ubh)}(hXThe IOCB_NOIO flag in iocb->ki_flags indicates that no new I/O requests shall be made for the read or for readahead. When no data can be read, -EAGAIN shall be returned. When readahead would be triggered, a partial, possibly empty read shall be returned.h]hXThe IOCB_NOIO flag in iocb->ki_flags indicates that no new I/O requests shall be made for the read or for readahead. When no data can be read, -EAGAIN shall be returned. When readahead would be triggered, a partial, possibly empty read shall be returned.}(hj3hhhNhNubah}(h]h ]h"]h$]h&]uh1hhd/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1051: ./fs/netfs/buffered_read.chMhj2ubh)}(h **Return**h]jX)}(hj3h]hReturn}(hj3hhhNhNubah}(h]h ]h"]h$]h&]uh1jWhj3ubah}(h]h ]h"]h$]h&]uh1hhd/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1051: ./fs/netfs/buffered_read.chM hj2ubj))}(hhh](j.)}(h.number of bytes copied, even for partial readsh]h)}(hj3h]h.number of bytes copied, even for partial reads}(hj3hhhNhNubah}(h]h ]h"]h$]h&]uh1hhd/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1051: ./fs/netfs/buffered_read.chM hj3ubah}(h]h ]h"]h$]h&]uh1j-hj3ubj.)}(h;negative error code (or 0 if IOCB_NOIO) if nothing was readh]h)}(hj3h]h;negative error code (or 0 if IOCB_NOIO) if nothing was read}(hj3hhhNhNubah}(h]h ]h"]h$]h&]uh1hhd/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1051: ./fs/netfs/buffered_read.chM hj3ubah}(h]h ]h"]h$]h&]uh1j-hj3ubeh}(h]h ]h"]h$]h&]jjuh1j(hj3hM hj2ubeh}(h]h ] kernelindentah"]h$]h&]uh1jMhj hhhNhNubj)}(hhh]h}(h]h ]h"]h$]h&]entries](j+!netfs_file_read_iter (C function)c.netfs_file_read_iterhNtauh1jhj hhhNhNubj0)}(hhh](j5)}(hHssize_t netfs_file_read_iter (struct kiocb *iocb, struct iov_iter *iter)h]j;)}(hGssize_t netfs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)h](h)}(hhh]jj)}(hssize_th]hssize_t}(hj84hhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihj54ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj:4modnameN classnameNjj)}j]j)}jnetfs_file_read_itersbc.netfs_file_read_iterasbuh1hhj14hhhd/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1051: ./fs/netfs/buffered_read.chM$ubjS)}(h h]h }(hjZ4hhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhj14hhhjY4hM$ubjd)}(hnetfs_file_read_iterh]jj)}(hjV4h]hnetfs_file_read_iter}(hjl4hhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihjh4ubah}(h]h ](j}j~eh"]h$]h&]hhuh1jchj14hhhjY4hM$ubj)}(h+(struct kiocb *iocb, struct iov_iter *iter)h](j)}(hstruct kiocb *iocbh](j)}(hjh]hstruct}(hj4hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj4ubjS)}(h h]h }(hj4hhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhj4ubh)}(hhh]jj)}(hkiocbh]hkiocb}(hj4hhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihj4ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj4modnameN classnameNjj)}j]jT4c.netfs_file_read_iterasbuh1hhj4ubjS)}(h h]h }(hj4hhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhj4ubj)}(hjh]h*}(hj4hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj4ubjj)}(hiocbh]hiocb}(hj4hhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihj4ubeh}(h]h ]h"]h$]h&]noemphhhuh1jhj4ubj)}(hstruct iov_iter *iterh](j)}(hjh]hstruct}(hj4hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj4ubjS)}(h h]h }(hj5hhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhj4ubh)}(hhh]jj)}(hiov_iterh]hiov_iter}(hj5hhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihj5ubah}(h]h ]h"]h$]h&] refdomainjreftypej reftargetj5modnameN classnameNjj)}j]jT4c.netfs_file_read_iterasbuh1hhj4ubjS)}(h h]h }(hj35hhhNhNubah}(h]h ]j_ah"]h$]h&]uh1jRhj4ubj)}(hjh]h*}(hjA5hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj4ubjj)}(hiterh]hiter}(hjN5hhhNhNubah}(h]h ]jvah"]h$]h&]uh1jihj4ubeh}(h]h ]h"]h$]h&]noemphhhuh1jhj4ubeh}(h]h ]h"]h$]h&]hhuh1jhj14hhhjY4hM$ubeh}(h]h ]h"]h$]h&]hhjuh1j:jjhj-4hhhjY4hM$ubah}(h]j(4ah ](jjeh"]h$]h&]j#j$)j%huh1j4hjY4hM$hj*4hhubj')}(hhh]h)}(hGeneric filesystem read routineh]hGeneric filesystem read routine}(hjx5hhhNhNubah}(h]h ]h"]h$]h&]uh1hhd/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1051: ./fs/netfs/buffered_read.chM$hju5hhubah}(h]h ]h"]h$]h&]uh1j&hj*4hhhjY4hM$ubeh}(h]h ](jfunctioneh"]h$]h&]jGjjHj5jIj5jJjKjLuh1j/hhhj hNhNubjN)}(hX**Parameters** ``struct kiocb *iocb`` kernel I/O control block ``struct iov_iter *iter`` destination for the data read **Description** This is the ->read_iter() routine for all filesystems that can use the page cache directly. The IOCB_NOWAIT flag in iocb->ki_flags indicates that -EAGAIN shall be returned when no data can be read without waiting for I/O requests to complete; it doesn't prevent readahead. The IOCB_NOIO flag in iocb->ki_flags indicates that no new I/O requests shall be made for the read or for readahead. When no data can be read, -EAGAIN shall be returned. When readahead would be triggered, a partial, possibly empty read shall be returned. **Return** * number of bytes copied, even for partial reads * negative error code (or 0 if IOCB_NOIO) if nothing was readh](h)}(h**Parameters**h]jX)}(hj5h]h Parameters}(hj5hhhNhNubah}(h]h ]h"]h$]h&]uh1jWhj5ubah}(h]h ]h"]h$]h&]uh1hhd/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1051: ./fs/netfs/buffered_read.chM(hj5ubjn)}(hhh](js)}(h0``struct kiocb *iocb`` kernel I/O control block h](jy)}(h``struct kiocb *iocb``h]j))}(hj5h]hstruct kiocb *iocb}(hj5hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj5ubah}(h]h ]h"]h$]h&]uh1jxhd/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1051: ./fs/netfs/buffered_read.chM%hj5ubj)}(hhh]h)}(hkernel I/O control blockh]hkernel I/O control block}(hj5hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj5hM%hj5ubah}(h]h ]h"]h$]h&]uh1jhj5ubeh}(h]h ]h"]h$]h&]uh1jrhj5hM%hj5ubjs)}(h8``struct iov_iter *iter`` destination for the data read h](jy)}(h``struct iov_iter *iter``h]j))}(hj5h]hstruct iov_iter *iter}(hj5hhhNhNubah}(h]h ]h"]h$]h&]uh1j(hj5ubah}(h]h ]h"]h$]h&]uh1jxhd/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1051: ./fs/netfs/buffered_read.chM&hj5ubj)}(hhh]h)}(hdestination for the data readh]hdestination for the data read}(hj 6hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj6hM&hj6ubah}(h]h ]h"]h$]h&]uh1jhj5ubeh}(h]h ]h"]h$]h&]uh1jrhj6hM&hj5ubeh}(h]h ]h"]h$]h&]uh1jmhj5ubh)}(h**Description**h]jX)}(hj-6h]h Description}(hj/6hhhNhNubah}(h]h ]h"]h$]h&]uh1jWhj+6ubah}(h]h ]h"]h$]h&]uh1hhd/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1051: ./fs/netfs/buffered_read.chM(hj5ubh)}(h[This is the ->read_iter() routine for all filesystems that can use the page cache directly.h]h[This is the ->read_iter() routine for all filesystems that can use the page cache directly.}(hjC6hhhNhNubah}(h]h ]h"]h$]h&]uh1hhd/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1051: ./fs/netfs/buffered_read.chM(hj5ubh)}(hThe IOCB_NOWAIT flag in iocb->ki_flags indicates that -EAGAIN shall be returned when no data can be read without waiting for I/O requests to complete; it doesn't prevent readahead.h]hThe IOCB_NOWAIT flag in iocb->ki_flags indicates that -EAGAIN shall be returned when no data can be read without waiting for I/O requests to complete; it doesn’t prevent readahead.}(hjR6hhhNhNubah}(h]h ]h"]h$]h&]uh1hhd/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1051: ./fs/netfs/buffered_read.chM+hj5ubh)}(hXThe IOCB_NOIO flag in iocb->ki_flags indicates that no new I/O requests shall be made for the read or for readahead. When no data can be read, -EAGAIN shall be returned. When readahead would be triggered, a partial, possibly empty read shall be returned.h]hXThe IOCB_NOIO flag in iocb->ki_flags indicates that no new I/O requests shall be made for the read or for readahead. When no data can be read, -EAGAIN shall be returned. When readahead would be triggered, a partial, possibly empty read shall be returned.}(hja6hhhNhNubah}(h]h ]h"]h$]h&]uh1hhd/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1051: ./fs/netfs/buffered_read.chM/hj5ubh)}(h **Return**h]jX)}(hjr6h]hReturn}(hjt6hhhNhNubah}(h]h ]h"]h$]h&]uh1jWhjp6ubah}(h]h ]h"]h$]h&]uh1hhd/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1051: ./fs/netfs/buffered_read.chM4hj5ubj))}(hhh](j.)}(h.number of bytes copied, even for partial readsh]h)}(hj6h]h.number of bytes copied, even for partial reads}(hj6hhhNhNubah}(h]h ]h"]h$]h&]uh1hhd/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1051: ./fs/netfs/buffered_read.chM4hj6ubah}(h]h ]h"]h$]h&]uh1j-hj6ubj.)}(h;negative error code (or 0 if IOCB_NOIO) if nothing was readh]h)}(hj6h]h;negative error code (or 0 if IOCB_NOIO) if nothing was read}(hj6hhhNhNubah}(h]h ]h"]h$]h&]uh1hhd/var/lib/git/docbuild/linux/Documentation/filesystems/netfs_library:1051: ./fs/netfs/buffered_read.chM5hj6ubah}(h]h ]h"]h$]h&]uh1j-hj6ubeh}(h]h ]h"]h$]h&]jjuh1j(hj6hM4hj5ubeh}(h]h ] kernelindentah"]h$]h&]uh1jMhj hhhNhNubeh}(h]api-function-referenceah ]h"]api function referenceah$]h&]uh1hhhhhhhhMubeh}(h]#network-filesystem-services-libraryah ]h"]#network filesystem services libraryah$]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_handlerj6error_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}(j6j6jjjjjjj j jjjjjD jA jjjjj< j9 jI jF j j j j j j jA j> j j j j j jjtjqjjjjjjjjjjj6j6u nametypes}(j6jjjj jjjD jjj< jI j j j jA j j j jtjjjjjj6uh}(j6hjhjjjjj jjjjjjA jjj5jjj9 jjF jG j jf j j j j j> j j jL j j jj jqj jjwjjjjjjjjj6j j-j6jjjjjp"ju"j$j$j&j&j(j!(j)j)j,j,j|1j1j(4j-4u 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.