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/nfs/exportingmodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget-/translations/zh_TW/filesystems/nfs/exportingmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget-/translations/it_IT/filesystems/nfs/exportingmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget-/translations/ja_JP/filesystems/nfs/exportingmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget-/translations/ko_KR/filesystems/nfs/exportingmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hPortuguese (Brazilian)}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget-/translations/pt_BR/filesystems/nfs/exportingmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget-/translations/sp_SP/filesystems/nfs/exportingmodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageEnglishuh1h hh _documenthsourceNlineNubhsection)}(hhh](htitle)}(hMaking Filesystems Exportableh]hMaking Filesystems Exportable}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhG/var/lib/git/docbuild/linux/Documentation/filesystems/nfs/exporting.rsthKubh)}(hhh](h)}(hOverviewh]hOverview}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubh paragraph)}(hXUAll filesystem operations require a dentry (or two) as a starting point. Local applications have a reference-counted hold on suitable dentries via open file descriptors or cwd/root. However remote applications that access a filesystem via a remote filesystem protocol such as NFS may not be able to hold such a reference, and so need a different way to refer to a particular dentry. As the alternative form of reference needs to be stable across renames, truncates, and server-reboot (among other things, though these tend to be the most problematic), there is no simple answer like 'filename'.h]hXYAll filesystem operations require a dentry (or two) as a starting point. Local applications have a reference-counted hold on suitable dentries via open file descriptors or cwd/root. However remote applications that access a filesystem via a remote filesystem protocol such as NFS may not be able to hold such a reference, and so need a different way to refer to a particular dentry. As the alternative form of reference needs to be stable across renames, truncates, and server-reboot (among other things, though these tend to be the most problematic), there is no simple answer like ‘filename’.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK hhhhubh)}(hXOThe mechanism discussed here allows each filesystem implementation to specify how to generate an opaque (outside of the filesystem) byte string for any dentry, and how to find an appropriate dentry for any given opaque byte string. This byte string will be called a "filehandle fragment" as it corresponds to part of an NFS filehandle.h]hXSThe mechanism discussed here allows each filesystem implementation to specify how to generate an opaque (outside of the filesystem) byte string for any dentry, and how to find an appropriate dentry for any given opaque byte string. This byte string will be called a “filehandle fragment” as it corresponds to part of an NFS filehandle.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hnA filesystem which supports the mapping between filehandle fragments and dentries will be termed "exportable".h]hrA filesystem which supports the mapping between filehandle fragments and dentries will be termed “exportable”.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubeh}(h]overviewah ]h"]overviewah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(h Dcache Issuesh]h Dcache Issues}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK ubh)}(hXgThe dcache normally contains a proper prefix of any given filesystem tree. This means that if any filesystem object is in the dcache, then all of the ancestors of that filesystem object are also in the dcache. As normal access is by filename this prefix is created naturally and maintained easily (by each object maintaining a reference count on its parent).h]hXgThe dcache normally contains a proper prefix of any given filesystem tree. This means that if any filesystem object is in the dcache, then all of the ancestors of that filesystem object are also in the dcache. As normal access is by filename this prefix is created naturally and maintained easily (by each object maintaining a reference count on its parent).}(hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK"hjhhubh)}(hX However when objects are included into the dcache by interpreting a filehandle fragment, there is no automatic creation of a path prefix for the object. This leads to two related but distinct features of the dcache that are not needed for normal filesystem access.h]hX However when objects are included into the dcache by interpreting a filehandle fragment, there is no automatic creation of a path prefix for the object. This leads to two related but distinct features of the dcache that are not needed for normal filesystem access.}(hj/hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK)hjhhubhenumerated_list)}(hhh](h list_item)}(hyThe dcache must sometimes contain objects that are not part of the proper prefix. i.e that are not connected to the root.h]h)}(hyThe dcache must sometimes contain objects that are not part of the proper prefix. i.e that are not connected to the root.h]hyThe dcache must sometimes contain objects that are not part of the proper prefix. i.e that are not connected to the root.}(hjHhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK.hjDubah}(h]h ]h"]h$]h&]uh1jBhj?hhhhhNubjC)}(hXBThe dcache must be prepared for a newly found (via ->lookup) directory to already have a (non-connected) dentry, and must be able to move that dentry into place (based on the parent and name in the ->lookup). This is particularly needed for directories as it is a dcache invariant that directories only have one dentry. h]h)}(hXAThe dcache must be prepared for a newly found (via ->lookup) directory to already have a (non-connected) dentry, and must be able to move that dentry into place (based on the parent and name in the ->lookup). This is particularly needed for directories as it is a dcache invariant that directories only have one dentry.h]hXAThe dcache must be prepared for a newly found (via ->lookup) directory to already have a (non-connected) dentry, and must be able to move that dentry into place (based on the parent and name in the ->lookup). This is particularly needed for directories as it is a dcache invariant that directories only have one dentry.}(hj`hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK0hj\ubah}(h]h ]h"]h$]h&]uh1jBhj?hhhhhNubeh}(h]h ]h"]h$]h&]enumtypearabicprefixhsuffix.uh1j=hjhhhhhK.ubh)}(h,To implement these features, the dcache has:h]h,To implement these features, the dcache has:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK6hjhhubj>)}(hhh](jC)}(hXA dentry flag DCACHE_DISCONNECTED which is set on any dentry that might not be part of the proper prefix. This is set when anonymous dentries are created, and cleared when a dentry is noticed to be a child of a dentry which is in the proper prefix. If the refcount on a dentry with this flag set becomes zero, the dentry is immediately discarded, rather than being kept in the dcache. If a dentry that is not already in the dcache is repeatedly accessed by filehandle (as NFSD might do), an new dentry will be a allocated for each access, and discarded at the end of the access. Note that such a dentry can acquire children, name, ancestors, etc. without losing DCACHE_DISCONNECTED - that flag is only cleared when subtree is successfully reconnected to root. Until then dentries in such subtree are retained only as long as there are references; refcount reaching zero means immediate eviction, same as for unhashed dentries. That guarantees that we won't need to hunt them down upon umount. h](h)}(hXDA dentry flag DCACHE_DISCONNECTED which is set on any dentry that might not be part of the proper prefix. This is set when anonymous dentries are created, and cleared when a dentry is noticed to be a child of a dentry which is in the proper prefix. If the refcount on a dentry with this flag set becomes zero, the dentry is immediately discarded, rather than being kept in the dcache. If a dentry that is not already in the dcache is repeatedly accessed by filehandle (as NFSD might do), an new dentry will be a allocated for each access, and discarded at the end of the access.h]hXDA dentry flag DCACHE_DISCONNECTED which is set on any dentry that might not be part of the proper prefix. This is set when anonymous dentries are created, and cleared when a dentry is noticed to be a child of a dentry which is in the proper prefix. If the refcount on a dentry with this flag set becomes zero, the dentry is immediately discarded, rather than being kept in the dcache. If a dentry that is not already in the dcache is repeatedly accessed by filehandle (as NFSD might do), an new dentry will be a allocated for each access, and discarded at the end of the access.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK8hjubh)}(hXNote that such a dentry can acquire children, name, ancestors, etc. without losing DCACHE_DISCONNECTED - that flag is only cleared when subtree is successfully reconnected to root. Until then dentries in such subtree are retained only as long as there are references; refcount reaching zero means immediate eviction, same as for unhashed dentries. That guarantees that we won't need to hunt them down upon umount.h]hXNote that such a dentry can acquire children, name, ancestors, etc. without losing DCACHE_DISCONNECTED - that flag is only cleared when subtree is successfully reconnected to root. Until then dentries in such subtree are retained only as long as there are references; refcount reaching zero means immediate eviction, same as for unhashed dentries. That guarantees that we won’t need to hunt them down upon umount.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKChjubeh}(h]h ]h"]h$]h&]uh1jBhjhhhhhNubjC)}(hA primitive for creation of secondary roots - d_obtain_root(inode). Those do _not_ bear DCACHE_DISCONNECTED. They are placed on the per-superblock list (->s_roots), so they can be located at umount time for eviction purposes. h]h)}(hA primitive for creation of secondary roots - d_obtain_root(inode). Those do _not_ bear DCACHE_DISCONNECTED. They are placed on the per-superblock list (->s_roots), so they can be located at umount time for eviction purposes.h]hA primitive for creation of secondary roots - d_obtain_root(inode). Those do _not_ bear DCACHE_DISCONNECTED. They are placed on the per-superblock list (->s_roots), so they can be located at umount time for eviction purposes.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKKhjubah}(h]h ]h"]h$]h&]uh1jBhjhhhhhNubjC)}(hXHelper routines to allocate anonymous dentries, and to help attach loose directory dentries at lookup time. They are: d_obtain_alias(inode) will return a dentry for the given inode. If the inode already has a dentry, one of those is returned. If it doesn't, a new anonymous (IS_ROOT and DCACHE_DISCONNECTED) dentry is allocated and attached. In the case of a directory, care is taken that only one dentry can ever be attached. d_splice_alias(inode, dentry) will introduce a new dentry into the tree; either the passed-in dentry or a preexisting alias for the given inode (such as an anonymous one created by d_obtain_alias), if appropriate. It returns NULL when the passed-in dentry is used, following the calling convention of ->lookup. h](h)}(huHelper routines to allocate anonymous dentries, and to help attach loose directory dentries at lookup time. They are:h]huHelper routines to allocate anonymous dentries, and to help attach loose directory dentries at lookup time. They are:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKPhjubh block_quote)}(hXd_obtain_alias(inode) will return a dentry for the given inode. If the inode already has a dentry, one of those is returned. If it doesn't, a new anonymous (IS_ROOT and DCACHE_DISCONNECTED) dentry is allocated and attached. In the case of a directory, care is taken that only one dentry can ever be attached. d_splice_alias(inode, dentry) will introduce a new dentry into the tree; either the passed-in dentry or a preexisting alias for the given inode (such as an anonymous one created by d_obtain_alias), if appropriate. It returns NULL when the passed-in dentry is used, following the calling convention of ->lookup. h]hdefinition_list)}(hhh](hdefinition_list_item)}(hX7d_obtain_alias(inode) will return a dentry for the given inode. If the inode already has a dentry, one of those is returned. If it doesn't, a new anonymous (IS_ROOT and DCACHE_DISCONNECTED) dentry is allocated and attached. In the case of a directory, care is taken that only one dentry can ever be attached. h](hterm)}(h?d_obtain_alias(inode) will return a dentry for the given inode.h]h?d_obtain_alias(inode) will return a dentry for the given inode.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKZhjubh definition)}(hhh](h)}(hlookup. h](j)}(hHd_splice_alias(inode, dentry) will introduce a new dentry into the tree;h]hHd_splice_alias(inode, dentry) will introduce a new dentry into the tree;}(hj@hhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhK`hj<ubj)}(hhh]h)}(heither the passed-in dentry or a preexisting alias for the given inode (such as an anonymous one created by d_obtain_alias), if appropriate. It returns NULL when the passed-in dentry is used, following the calling convention of ->lookup.h]heither the passed-in dentry or a preexisting alias for the given inode (such as an anonymous one created by d_obtain_alias), if appropriate. It returns NULL when the passed-in dentry is used, following the calling convention of ->lookup.}(hjQhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK]hjNubah}(h]h ]h"]h$]h&]uh1jhj<ubeh}(h]h ]h"]h$]h&]uh1jhhhK`hjubeh}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1jhhhKShjubeh}(h]h ]h"]h$]h&]uh1jBhjhhhhhNubeh}(h]h ]h"]h$]h&]jz loweralphaj|hj}j~uh1j=hjhhhhhK8ubeh}(h] dcache-issuesah ]h"] dcache issuesah$]h&]uh1hhhhhhhhK ubh)}(hhh](h)}(hFilesystem Issuesh]hFilesystem Issues}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKcubh)}(h*For a filesystem to be exportable it must:h]h*For a filesystem to be exportable it must:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKehjhhubj)}(hX1. provide the filehandle fragment routines described below. 2. make sure that d_splice_alias is used rather than d_add when ->lookup finds an inode for a given parent and name. If inode is NULL, d_splice_alias(inode, dentry) is equivalent to:: d_add(dentry, inode), NULL Similarly, d_splice_alias(ERR_PTR(err), dentry) = ERR_PTR(err) Typically the ->lookup routine will simply end with a:: return d_splice_alias(inode, dentry); } h]j>)}(hhh](jC)}(h9provide the filehandle fragment routines described below.h]h)}(hjh]h9provide the filehandle fragment routines described below.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKghjubah}(h]h ]h"]h$]h&]uh1jBhjubjC)}(hXmake sure that d_splice_alias is used rather than d_add when ->lookup finds an inode for a given parent and name. If inode is NULL, d_splice_alias(inode, dentry) is equivalent to:: d_add(dentry, inode), NULL Similarly, d_splice_alias(ERR_PTR(err), dentry) = ERR_PTR(err) Typically the ->lookup routine will simply end with a:: return d_splice_alias(inode, dentry); } h](h)}(hqmake sure that d_splice_alias is used rather than d_add when ->lookup finds an inode for a given parent and name.h]hqmake sure that d_splice_alias is used rather than d_add when ->lookup finds an inode for a given parent and name.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhjubh)}(hBIf inode is NULL, d_splice_alias(inode, dentry) is equivalent to::h]hAIf inode is NULL, d_splice_alias(inode, dentry) is equivalent to:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKkhjubh literal_block)}(hd_add(dentry, inode), NULLh]hd_add(dentry, inode), NULL}hjsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1jhhhKmhjubh)}(h>Similarly, d_splice_alias(ERR_PTR(err), dentry) = ERR_PTR(err)h]h>Similarly, d_splice_alias(ERR_PTR(err), dentry) = ERR_PTR(err)}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKohjubh)}(h7Typically the ->lookup routine will simply end with a::h]h6Typically the ->lookup routine will simply end with a:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKqhjubj)}(h/ return d_splice_alias(inode, dentry); }h]h/ return d_splice_alias(inode, dentry); }}hjsbah}(h]h ]h"]h$]h&]jjuh1jhhhKshjubeh}(h]h ]h"]h$]h&]uh1jBhjubeh}(h]h ]h"]h$]h&]jzj{j|hj}j~uh1j=hjubah}(h]h ]h"]h$]h&]uh1jhhhKghjhhubh)}(hA file system implementation declares that instances of the filesystem are exportable by setting the s_export_op field in the struct super_block. This field must point to a struct export_operations which has the following members:h]hA file system implementation declares that instances of the filesystem are exportable by setting the s_export_op field in the struct super_block. This field must point to a struct export_operations which has the following members:}(hj7hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKxhjhhubhindex)}(hhh]h}(h]h ]h"]h$]h&]entries](singleexport_operations (C struct)c.export_operationshNtauh1jEhjhhhNhNubhdesc)}(hhh](hdesc_signature)}(hexport_operationsh]hdesc_signature_line)}(hstruct export_operationsh](hdesc_sig_keyword)}(hstructh]hstruct}(hjihhhNhNubah}(h]h ]kah"]h$]h&]uh1jghjchhhc/var/lib/git/docbuild/linux/Documentation/filesystems/nfs/exporting:125: ./include/linux/exportfs.hhKubhdesc_sig_space)}(h h]h }(hj{hhhNhNubah}(h]h ]wah"]h$]h&]uh1jyhjchhhjxhKubh desc_name)}(hexport_operationsh]h desc_sig_name)}(hj_h]hexport_operations}(hjhhhNhNubah}(h]h ]nah"]h$]h&]uh1jhjubah}(h]h ](sig-namedescnameeh"]h$]h&]jjuh1jhjchhhjxhKubeh}(h]h ]h"]h$]h&]jj add_permalinkuh1jasphinx_line_type declaratorhj]hhhjxhKubah}(h]jTah ](sig sig-objecteh"]h$]h&] is_multiline _toc_parts) _toc_namehuh1j[hjxhKhjXhhubh desc_content)}(hhh]h)}(h)for nfsd to communicate with file systemsh]h)for nfsd to communicate with file systems}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhc/var/lib/git/docbuild/linux/Documentation/filesystems/nfs/exporting:125: ./include/linux/exportfs.hhKhjhhubah}(h]h ]h"]h$]h&]uh1jhjXhhhjxhKubeh}(h]h ](cstructeh"]h$]h&]domainjobjtypejdesctypejnoindex noindexentrynocontentsentryuh1jVhhhjhNhNubh container)}(hX**Definition**:: struct export_operations { int (*encode_fh)(struct inode *inode, __u32 *fh, int *max_len, struct inode *parent); struct dentry * (*fh_to_dentry)(struct super_block *sb, struct fid *fid, int fh_len, int fh_type); struct dentry * (*fh_to_parent)(struct super_block *sb, struct fid *fid, int fh_len, int fh_type); int (*get_name)(struct dentry *parent, char *name, struct dentry *child); struct dentry * (*get_parent)(struct dentry *child); int (*commit_metadata)(struct inode *inode); int (*get_uuid)(struct super_block *sb, u8 *buf, u32 *len, u64 *offset); int (*map_blocks)(struct inode *inode, loff_t offset, u64 len, struct iomap *iomap, bool write, u32 *device_generation); int (*commit_blocks)(struct inode *inode, struct iomap *iomaps, int nr_iomaps, struct iattr *iattr); int (*permission)(struct handle_to_path_ctx *ctx, unsigned int oflags); struct file * (*open)(const struct path *path, unsigned int oflags); #define EXPORT_OP_NOWCC (0x1) ; #define EXPORT_OP_NOSUBTREECHK (0x2) ; #define EXPORT_OP_CLOSE_BEFORE_UNLINK (0x4) ; #define EXPORT_OP_REMOTE_FS (0x8) ; #define EXPORT_OP_NOATOMIC_ATTR (0x10) #define EXPORT_OP_FLUSH_ON_CLOSE (0x20) ; #define EXPORT_OP_NOLOCKS (0x40) ; unsigned long flags; }; **Members** ``encode_fh`` **encode_fh** should store in the file handle fragment **fh** (using at most **max_len** bytes) information that can be used by **decode_fh** to recover the file referred to by the :c:type:`struct dentry ` **de**. If **flag** has CONNECTABLE bit set, the encode_fh() should store sufficient information so that a good attempt can be made to find not only the file but also it's place in the filesystem. This typically means storing a reference to de->d_parent in the filehandle fragment. encode_fh() should return the fileid_type on success and on error returns 255 (if the space needed to encode fh is greater than **max_len***4 bytes). On error **max_len** contains the minimum size(in 4 byte unit) needed to encode the file handle. ``fh_to_dentry`` **fh_to_dentry** is given a :c:type:`struct super_block ` (**sb**) and a file handle fragment (**fh**, **fh_len**). It should return a :c:type:`struct dentry ` which refers to the same file that the file handle fragment refers to. If it cannot, it should return a ``NULL`` pointer if the file cannot be found, or an ``ERR_PTR`` error code of ``ENOMEM`` if a memory allocation failure occurred. Any other error code is treated like ``NULL``, and will cause an ``ESTALE`` error for callers of exportfs_decode_fh(). Any suitable dentry can be returned including, if necessary, a new dentry created with d_alloc_root. The caller can then find any other extant dentries by following the d_alias links. ``fh_to_parent`` Same as **fh_to_dentry**, except that it returns a pointer to the parent dentry if it was encoded into the filehandle fragment by **encode_fh**. ``get_name`` **get_name** should find a name for the given **child** in the given **parent** directory. The name should be stored in the **name** (with the understanding that it is already pointing to a ``NAME_MAX`` + 1 sized buffer. get_name() should return ``0`` on success, a negative error code or error. **get_name** will be called without **parent->i_rwsem** held. ``get_parent`` **get_parent** should find the parent directory for the given **child** which is also a directory. In the event that it cannot be found, or storage space cannot be allocated, a ``ERR_PTR`` should be returned. ``commit_metadata`` **commit_metadata** should commit metadata changes to stable storage. ``get_uuid`` Get a filesystem unique signature exposed to clients. ``map_blocks`` Map and, if necessary, allocate blocks for a layout. ``commit_blocks`` Commit blocks in a layout once the client is done with them. ``permission`` Allow filesystems to specify a custom permission function for the open_by_handle_at(2) syscall instead of the default permission check. This custom permission function is not respected by nfsd. ``open`` Allow filesystems to specify a custom open function for the open_by_handle_at(2) syscall instead of the default file_open_root(). This custom open function is not respected by nfsd. ``flags`` Allows the filesystem to communicate to nfsd that it may want to do things differently when dealing with it.h](h)}(h**Definition**::h](hstrong)}(h**Definition**h]h Definition}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhc/var/lib/git/docbuild/linux/Documentation/filesystems/nfs/exporting:125: ./include/linux/exportfs.hhKhjubj)}(hX2struct export_operations { int (*encode_fh)(struct inode *inode, __u32 *fh, int *max_len, struct inode *parent); struct dentry * (*fh_to_dentry)(struct super_block *sb, struct fid *fid, int fh_len, int fh_type); struct dentry * (*fh_to_parent)(struct super_block *sb, struct fid *fid, int fh_len, int fh_type); int (*get_name)(struct dentry *parent, char *name, struct dentry *child); struct dentry * (*get_parent)(struct dentry *child); int (*commit_metadata)(struct inode *inode); int (*get_uuid)(struct super_block *sb, u8 *buf, u32 *len, u64 *offset); int (*map_blocks)(struct inode *inode, loff_t offset, u64 len, struct iomap *iomap, bool write, u32 *device_generation); int (*commit_blocks)(struct inode *inode, struct iomap *iomaps, int nr_iomaps, struct iattr *iattr); int (*permission)(struct handle_to_path_ctx *ctx, unsigned int oflags); struct file * (*open)(const struct path *path, unsigned int oflags); #define EXPORT_OP_NOWCC (0x1) ; #define EXPORT_OP_NOSUBTREECHK (0x2) ; #define EXPORT_OP_CLOSE_BEFORE_UNLINK (0x4) ; #define EXPORT_OP_REMOTE_FS (0x8) ; #define EXPORT_OP_NOATOMIC_ATTR (0x10) #define EXPORT_OP_FLUSH_ON_CLOSE (0x20) ; #define EXPORT_OP_NOLOCKS (0x40) ; unsigned long flags; };h]hX2struct export_operations { int (*encode_fh)(struct inode *inode, __u32 *fh, int *max_len, struct inode *parent); struct dentry * (*fh_to_dentry)(struct super_block *sb, struct fid *fid, int fh_len, int fh_type); struct dentry * (*fh_to_parent)(struct super_block *sb, struct fid *fid, int fh_len, int fh_type); int (*get_name)(struct dentry *parent, char *name, struct dentry *child); struct dentry * (*get_parent)(struct dentry *child); int (*commit_metadata)(struct inode *inode); int (*get_uuid)(struct super_block *sb, u8 *buf, u32 *len, u64 *offset); int (*map_blocks)(struct inode *inode, loff_t offset, u64 len, struct iomap *iomap, bool write, u32 *device_generation); int (*commit_blocks)(struct inode *inode, struct iomap *iomaps, int nr_iomaps, struct iattr *iattr); int (*permission)(struct handle_to_path_ctx *ctx, unsigned int oflags); struct file * (*open)(const struct path *path, unsigned int oflags); #define EXPORT_OP_NOWCC (0x1) ; #define EXPORT_OP_NOSUBTREECHK (0x2) ; #define EXPORT_OP_CLOSE_BEFORE_UNLINK (0x4) ; #define EXPORT_OP_REMOTE_FS (0x8) ; #define EXPORT_OP_NOATOMIC_ATTR (0x10) #define EXPORT_OP_FLUSH_ON_CLOSE (0x20) ; #define EXPORT_OP_NOLOCKS (0x40) ; unsigned long flags; };}hj sbah}(h]h ]h"]h$]h&]jjuh1jhc/var/lib/git/docbuild/linux/Documentation/filesystems/nfs/exporting:125: ./include/linux/exportfs.hhKhjubh)}(h **Members**h]j)}(hjh]hMembers}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubah}(h]h ]h"]h$]h&]uh1hhc/var/lib/git/docbuild/linux/Documentation/filesystems/nfs/exporting:125: ./include/linux/exportfs.hhKhjubj)}(hhh](j)}(hX``encode_fh`` **encode_fh** should store in the file handle fragment **fh** (using at most **max_len** bytes) information that can be used by **decode_fh** to recover the file referred to by the :c:type:`struct dentry ` **de**. If **flag** has CONNECTABLE bit set, the encode_fh() should store sufficient information so that a good attempt can be made to find not only the file but also it's place in the filesystem. This typically means storing a reference to de->d_parent in the filehandle fragment. encode_fh() should return the fileid_type on success and on error returns 255 (if the space needed to encode fh is greater than **max_len***4 bytes). On error **max_len** contains the minimum size(in 4 byte unit) needed to encode the file handle. h](j)}(h ``encode_fh``h]hliteral)}(hj9h]h encode_fh}(hj=hhhNhNubah}(h]h ]h"]h$]h&]uh1j;hj7ubah}(h]h ]h"]h$]h&]uh1jhc/var/lib/git/docbuild/linux/Documentation/filesystems/nfs/exporting:125: ./include/linux/exportfs.hhKhj3ubj)}(hhh]h)}(hX**encode_fh** should store in the file handle fragment **fh** (using at most **max_len** bytes) information that can be used by **decode_fh** to recover the file referred to by the :c:type:`struct dentry ` **de**. If **flag** has CONNECTABLE bit set, the encode_fh() should store sufficient information so that a good attempt can be made to find not only the file but also it's place in the filesystem. This typically means storing a reference to de->d_parent in the filehandle fragment. encode_fh() should return the fileid_type on success and on error returns 255 (if the space needed to encode fh is greater than **max_len***4 bytes). On error **max_len** contains the minimum size(in 4 byte unit) needed to encode the file handle.h](j)}(h **encode_fh**h]h encode_fh}(hjXhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjTubh* should store in the file handle fragment }(hjThhhNhNubj)}(h**fh**h]hfh}(hjjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjTubh (using at most }(hjThhhNhNubj)}(h **max_len**h]hmax_len}(hj|hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjTubh( bytes) information that can be used by }(hjThhhNhNubj)}(h **decode_fh**h]h decode_fh}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjTubh( to recover the file referred to by the }(hjThhhNhNubh)}(h :c:type:`struct dentry `h]j<)}(hjh]h struct dentry}(hjhhhNhNubah}(h]h ](xrefjc-typeeh"]h$]h&]uh1j;hjubah}(h]h ]h"]h$]h&]refdocfilesystems/nfs/exporting refdomainjreftypetype refexplicitrefwarn c:parent_keysphinx.domains.c LookupKey)}data]sb reftargetdentryuh1hhc/var/lib/git/docbuild/linux/Documentation/filesystems/nfs/exporting:125: ./include/linux/exportfs.hhKhjTubh }(hjThhhNhNubj)}(h**de**h]hde}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjTubh. If }(hjThhhNhNubj)}(h**flag**h]hflag}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjTubhX has CONNECTABLE bit set, the encode_fh() should store sufficient information so that a good attempt can be made to find not only the file but also it’s place in the filesystem. This typically means storing a reference to de->d_parent in the filehandle fragment. encode_fh() should return the fileid_type on success and on error returns 255 (if the space needed to encode fh is greater than }(hjThhhNhNubj)}(h***max_len***4 bytes). On error **max_len**h]h&max_len***4 bytes). On error **max_len}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjTubhL contains the minimum size(in 4 byte unit) needed to encode the file handle.}(hjThhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhKhjQubah}(h]h ]h"]h$]h&]uh1jhj3ubeh}(h]h ]h"]h$]h&]uh1jhjPhKhj0ubj)}(hX``fh_to_dentry`` **fh_to_dentry** is given a :c:type:`struct super_block ` (**sb**) and a file handle fragment (**fh**, **fh_len**). It should return a :c:type:`struct dentry ` which refers to the same file that the file handle fragment refers to. If it cannot, it should return a ``NULL`` pointer if the file cannot be found, or an ``ERR_PTR`` error code of ``ENOMEM`` if a memory allocation failure occurred. Any other error code is treated like ``NULL``, and will cause an ``ESTALE`` error for callers of exportfs_decode_fh(). Any suitable dentry can be returned including, if necessary, a new dentry created with d_alloc_root. The caller can then find any other extant dentries by following the d_alias links. h](j)}(h``fh_to_dentry``h]j<)}(hjh]h fh_to_dentry}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j;hjubah}(h]h ]h"]h$]h&]uh1jhc/var/lib/git/docbuild/linux/Documentation/filesystems/nfs/exporting:125: ./include/linux/exportfs.hhKhjubj)}(hhh]h)}(hX**fh_to_dentry** is given a :c:type:`struct super_block ` (**sb**) and a file handle fragment (**fh**, **fh_len**). It should return a :c:type:`struct dentry ` which refers to the same file that the file handle fragment refers to. If it cannot, it should return a ``NULL`` pointer if the file cannot be found, or an ``ERR_PTR`` error code of ``ENOMEM`` if a memory allocation failure occurred. Any other error code is treated like ``NULL``, and will cause an ``ESTALE`` error for callers of exportfs_decode_fh(). Any suitable dentry can be returned including, if necessary, a new dentry created with d_alloc_root. The caller can then find any other extant dentries by following the d_alias links.h](j)}(h**fh_to_dentry**h]h fh_to_dentry}(hj:hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj6ubh is given a }(hj6hhhNhNubh)}(h*:c:type:`struct super_block `h]j<)}(hjNh]hstruct super_block}(hjPhhhNhNubah}(h]h ](jjc-typeeh"]h$]h&]uh1j;hjLubah}(h]h ]h"]h$]h&]refdocj refdomainjreftypetype refexplicitrefwarnjjj super_blockuh1hhc/var/lib/git/docbuild/linux/Documentation/filesystems/nfs/exporting:125: ./include/linux/exportfs.hhKhj6ubh (}(hj6hhhNhNubj)}(h**sb**h]hsb}(hjphhhNhNubah}(h]h ]h"]h$]h&]uh1jhj6ubh) and a file handle fragment (}(hj6hhhNhNubj)}(h**fh**h]hfh}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj6ubh, }(hj6hhhNhNubj)}(h **fh_len**h]hfh_len}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj6ubh). It should return a }(hj6hhhNhNubh)}(h :c:type:`struct dentry `h]j<)}(hjh]h struct dentry}(hjhhhNhNubah}(h]h ](jjc-typeeh"]h$]h&]uh1j;hjubah}(h]h ]h"]h$]h&]refdocj refdomainjreftypetype refexplicitrefwarnjjjdentryuh1hhjkhKhj6ubhj which refers to the same file that the file handle fragment refers to. If it cannot, it should return a }(hj6hhhNhNubj<)}(h``NULL``h]hNULL}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j;hj6ubh, pointer if the file cannot be found, or an }(hj6hhhNhNubj<)}(h ``ERR_PTR``h]hERR_PTR}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j;hj6ubh error code of }(hj6hhhNhNubj<)}(h ``ENOMEM``h]hENOMEM}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j;hj6ubhO if a memory allocation failure occurred. Any other error code is treated like }(hj6hhhNhNubj<)}(h``NULL``h]hNULL}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j;hj6ubh, and will cause an }(hj6hhhNhNubj<)}(h ``ESTALE``h]hESTALE}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j;hj6ubh error for callers of exportfs_decode_fh(). Any suitable dentry can be returned including, if necessary, a new dentry created with d_alloc_root. The caller can then find any other extant dentries by following the d_alias links.}(hj6hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjkhKhj3ubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhj2hKhj0ubj)}(h``fh_to_parent`` Same as **fh_to_dentry**, except that it returns a pointer to the parent dentry if it was encoded into the filehandle fragment by **encode_fh**. h](j)}(h``fh_to_parent``h]j<)}(hj;h]h fh_to_parent}(hj=hhhNhNubah}(h]h ]h"]h$]h&]uh1j;hj9ubah}(h]h ]h"]h$]h&]uh1jhc/var/lib/git/docbuild/linux/Documentation/filesystems/nfs/exporting:125: ./include/linux/exportfs.hhKhj5ubj)}(hhh]h)}(hSame as **fh_to_dentry**, except that it returns a pointer to the parent dentry if it was encoded into the filehandle fragment by **encode_fh**.h](hSame as }(hjThhhNhNubj)}(h**fh_to_dentry**h]h fh_to_dentry}(hj\hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjTubhj, except that it returns a pointer to the parent dentry if it was encoded into the filehandle fragment by }(hjThhhNhNubj)}(h **encode_fh**h]h encode_fh}(hjnhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjTubh.}(hjThhhNhNubeh}(h]h ]h"]h$]h&]uh1hhc/var/lib/git/docbuild/linux/Documentation/filesystems/nfs/exporting:125: ./include/linux/exportfs.hhKhjQubah}(h]h ]h"]h$]h&]uh1jhj5ubeh}(h]h ]h"]h$]h&]uh1jhjPhKhj0ubj)}(hXw``get_name`` **get_name** should find a name for the given **child** in the given **parent** directory. The name should be stored in the **name** (with the understanding that it is already pointing to a ``NAME_MAX`` + 1 sized buffer. get_name() should return ``0`` on success, a negative error code or error. **get_name** will be called without **parent->i_rwsem** held. h](j)}(h ``get_name``h]j<)}(hjh]hget_name}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j;hjubah}(h]h ]h"]h$]h&]uh1jhc/var/lib/git/docbuild/linux/Documentation/filesystems/nfs/exporting:125: ./include/linux/exportfs.hhKhjubj)}(hhh]h)}(hXi**get_name** should find a name for the given **child** in the given **parent** directory. The name should be stored in the **name** (with the understanding that it is already pointing to a ``NAME_MAX`` + 1 sized buffer. get_name() should return ``0`` on success, a negative error code or error. **get_name** will be called without **parent->i_rwsem** held.h](j)}(h **get_name**h]hget_name}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh" should find a name for the given }(hjhhhNhNubj)}(h **child**h]hchild}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh in the given }(hjhhhNhNubj)}(h **parent**h]hparent}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh. directory. The name should be stored in the }(hjhhhNhNubj)}(h**name**h]hname}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh: (with the understanding that it is already pointing to a }(hjhhhNhNubj<)}(h ``NAME_MAX``h]hNAME_MAX}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j;hjubh. + 1 sized buffer. get_name() should return }(hjhhhNhNubj<)}(h``0``h]h0}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j;hjubh. on success, a negative error code or error. }(hjhhhNhNubj)}(h **get_name**h]hget_name}(hj"hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh will be called without }(hjhhhNhNubj)}(h**parent->i_rwsem**h]hparent->i_rwsem}(hj4hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh held.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhc/var/lib/git/docbuild/linux/Documentation/filesystems/nfs/exporting:125: ./include/linux/exportfs.hhKhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhKhj0ubj)}(h``get_parent`` **get_parent** should find the parent directory for the given **child** which is also a directory. In the event that it cannot be found, or storage space cannot be allocated, a ``ERR_PTR`` should be returned. h](j)}(h``get_parent``h]j<)}(hj_h]h get_parent}(hjahhhNhNubah}(h]h ]h"]h$]h&]uh1j;hj]ubah}(h]h ]h"]h$]h&]uh1jhc/var/lib/git/docbuild/linux/Documentation/filesystems/nfs/exporting:125: ./include/linux/exportfs.hhKhjYubj)}(hhh]h)}(h**get_parent** should find the parent directory for the given **child** which is also a directory. In the event that it cannot be found, or storage space cannot be allocated, a ``ERR_PTR`` should be returned.h](j)}(h**get_parent**h]h get_parent}(hj|hhhNhNubah}(h]h ]h"]h$]h&]uh1jhjxubh0 should find the parent directory for the given }(hjxhhhNhNubj)}(h **child**h]hchild}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjxubhk which is also a directory. In the event that it cannot be found, or storage space cannot be allocated, a }(hjxhhhNhNubj<)}(h ``ERR_PTR``h]hERR_PTR}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j;hjxubh should be returned.}(hjxhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhc/var/lib/git/docbuild/linux/Documentation/filesystems/nfs/exporting:125: ./include/linux/exportfs.hhKhjuubah}(h]h ]h"]h$]h&]uh1jhjYubeh}(h]h ]h"]h$]h&]uh1jhjthKhj0ubj)}(hZ``commit_metadata`` **commit_metadata** should commit metadata changes to stable storage. h](j)}(h``commit_metadata``h]j<)}(hjh]hcommit_metadata}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j;hjubah}(h]h ]h"]h$]h&]uh1jhc/var/lib/git/docbuild/linux/Documentation/filesystems/nfs/exporting:125: ./include/linux/exportfs.hhMhjubj)}(hhh]h)}(hE**commit_metadata** should commit metadata changes to stable storage.h](j)}(h**commit_metadata**h]hcommit_metadata}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh2 should commit metadata changes to stable storage.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhjhMhjubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]uh1jhjhMhj0ubj)}(hC``get_uuid`` Get a filesystem unique signature exposed to clients. h](j)}(h ``get_uuid``h]j<)}(hjh]hget_uuid}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j;hjubah}(h]h ]h"]h$]h&]uh1jhc/var/lib/git/docbuild/linux/Documentation/filesystems/nfs/exporting:125: ./include/linux/exportfs.hhMhj ubj)}(hhh]h)}(h5Get a filesystem unique signature exposed to clients.h]h5Get a filesystem unique signature exposed to clients.}(hj+hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj'hMhj(ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhj'hMhj0ubj)}(hD``map_blocks`` Map and, if necessary, allocate blocks for a layout. h](j)}(h``map_blocks``h]j<)}(hjKh]h map_blocks}(hjMhhhNhNubah}(h]h ]h"]h$]h&]uh1j;hjIubah}(h]h ]h"]h$]h&]uh1jhc/var/lib/git/docbuild/linux/Documentation/filesystems/nfs/exporting:125: ./include/linux/exportfs.hhM hjEubj)}(hhh]h)}(h4Map and, if necessary, allocate blocks for a layout.h]h4Map and, if necessary, allocate blocks for a layout.}(hjdhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj`hM hjaubah}(h]h ]h"]h$]h&]uh1jhjEubeh}(h]h ]h"]h$]h&]uh1jhj`hM hj0ubj)}(hO``commit_blocks`` Commit blocks in a layout once the client is done with them. h](j)}(h``commit_blocks``h]j<)}(hjh]h commit_blocks}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j;hjubah}(h]h ]h"]h$]h&]uh1jhc/var/lib/git/docbuild/linux/Documentation/filesystems/nfs/exporting:125: ./include/linux/exportfs.hhMhj~ubj)}(hhh]h)}(hd_inode->i_rwsem down get_name is not (which is possibly inconsistent) h](j)}(hLocking rules:h]hLocking rules:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhc/var/lib/git/docbuild/linux/Documentation/filesystems/nfs/exporting:125: ./include/linux/exportfs.hhKhj ubj)}(hhh]h)}(hgget_parent is called with child->d_inode->i_rwsem down get_name is not (which is possibly inconsistent)h]hgget_parent is called with child->d_inode->i_rwsem down get_name is not (which is possibly inconsistent)}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhc/var/lib/git/docbuild/linux/Documentation/filesystems/nfs/exporting:125: ./include/linux/exportfs.hhKhj ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhj hKhj ubah}(h]h ]h"]h$]h&]uh1jhjhhhNhNubh)}(hXA filehandle fragment consists of an array of 1 or more 4byte words, together with a one byte "type". The decode_fh routine should not depend on the stated size that is passed to it. This size may be larger than the original filehandle generated by encode_fh, in which case it will have been padded with nuls. Rather, the encode_fh routine should choose a "type" which indicates the decode_fh how much of the filehandle is valid, and how it should be interpreted.h]hXA filehandle fragment consists of an array of 1 or more 4byte words, together with a one byte “type”. The decode_fh routine should not depend on the stated size that is passed to it. This size may be larger than the original filehandle generated by encode_fh, in which case it will have been padded with nuls. Rather, the encode_fh routine should choose a “type” which indicates the decode_fh how much of the filehandle is valid, and how it should be interpreted.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]filesystem-issuesah ]h"]filesystem issuesah$]h&]uh1hhhhhhhhKcubh)}(hhh](h)}(hExport Operations Flagsh]hExport Operations Flags}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhKubh)}(hIn addition to the operation vector pointers, struct export_operations also contains a "flags" field that allows the filesystem to communicate to nfsd that it may want to do things differently when dealing with it. The following flags are defined:h]hIn addition to the operation vector pointers, struct export_operations also contains a “flags” field that allows the filesystem to communicate to nfsd that it may want to do things differently when dealing with it. The following flags are defined:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj hhubj)}(hX_EXPORT_OP_NOWCC - disable NFSv3 WCC attributes on this filesystem RFC 1813 recommends that servers always send weak cache consistency (WCC) data to the client after each operation. The server should atomically collect attributes about the inode, do an operation on it, and then collect the attributes afterward. This allows the client to skip issuing GETATTRs in some situations but means that the server is calling vfs_getattr for almost all RPCs. On some filesystems (particularly those that are clustered or networked) this is expensive and atomicity is difficult to guarantee. This flag indicates to nfsd that it should skip providing WCC attributes to the client in NFSv3 replies when doing operations on this filesystem. Consider enabling this on filesystems that have an expensive ->getattr inode operation, or when atomicity between pre and post operation attribute collection is impossible to guarantee. EXPORT_OP_NOSUBTREECHK - disallow subtree checking on this fs Many NFS operations deal with filehandles, which the server must then vet to ensure that they live inside of an exported tree. When the export consists of an entire filesystem, this is trivial. nfsd can just ensure that the filehandle live on the filesystem. When only part of a filesystem is exported however, then nfsd must walk the ancestors of the inode to ensure that it's within an exported subtree. This is an expensive operation and not all filesystems can support it properly. This flag exempts the filesystem from subtree checking and causes exportfs to get back an error if it tries to enable subtree checking on it. EXPORT_OP_CLOSE_BEFORE_UNLINK - always close cached files before unlinking On some exportable filesystems (such as NFS) unlinking a file that is still open can cause a fair bit of extra work. For instance, the NFS client will do a "sillyrename" to ensure that the file sticks around while it's still open. When reexporting, that open file is held by nfsd so we usually end up doing a sillyrename, and then immediately deleting the sillyrenamed file just afterward when the link count actually goes to zero. Sometimes this delete can race with other operations (for instance an rmdir of the parent directory). This flag causes nfsd to close any open files for this inode _before_ calling into the vfs to do an unlink or a rename that would replace an existing file. EXPORT_OP_REMOTE_FS - Backing storage for this filesystem is remote PF_LOCAL_THROTTLE exists for loopback NFSD, where a thread needs to write to one bdi (the final bdi) in order to free up writes queued to another bdi (the client bdi). Such threads get a private balance of dirty pages so that dirty pages for the client bdi do not imact the daemon writing to the final bdi. For filesystems whose durable storage is not local (such as exported NFS filesystems), this constraint has negative consequences. EXPORT_OP_REMOTE_FS enables an export to disable writeback throttling. EXPORT_OP_NOATOMIC_ATTR - Filesystem does not update attributes atomically EXPORT_OP_NOATOMIC_ATTR indicates that the exported filesystem cannot provide the semantics required by the "atomic" boolean in NFSv4's change_info4. This boolean indicates to a client whether the returned before and after change attributes were obtained atomically with the respect to the requested metadata operation (UNLINK, OPEN/CREATE, MKDIR, etc). EXPORT_OP_FLUSH_ON_CLOSE - Filesystem flushes file data on close(2) On most filesystems, inodes can remain under writeback after the file is closed. NFSD relies on client activity or local flusher threads to handle writeback. Certain filesystems, such as NFS, flush all of an inode's dirty data on last close. Exports that behave this way should set EXPORT_OP_FLUSH_ON_CLOSE so that NFSD knows to skip waiting for writeback when closing such files. h]j)}(hhh](j)}(hXEXPORT_OP_NOWCC - disable NFSv3 WCC attributes on this filesystem RFC 1813 recommends that servers always send weak cache consistency (WCC) data to the client after each operation. The server should atomically collect attributes about the inode, do an operation on it, and then collect the attributes afterward. This allows the client to skip issuing GETATTRs in some situations but means that the server is calling vfs_getattr for almost all RPCs. On some filesystems (particularly those that are clustered or networked) this is expensive and atomicity is difficult to guarantee. This flag indicates to nfsd that it should skip providing WCC attributes to the client in NFSv3 replies when doing operations on this filesystem. Consider enabling this on filesystems that have an expensive ->getattr inode operation, or when atomicity between pre and post operation attribute collection is impossible to guarantee. h](j)}(hAEXPORT_OP_NOWCC - disable NFSv3 WCC attributes on this filesystemh]hAEXPORT_OP_NOWCC - disable NFSv3 WCC attributes on this filesystem}(hj! hhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKhj ubj)}(hhh]h)}(hXNRFC 1813 recommends that servers always send weak cache consistency (WCC) data to the client after each operation. The server should atomically collect attributes about the inode, do an operation on it, and then collect the attributes afterward. This allows the client to skip issuing GETATTRs in some situations but means that the server is calling vfs_getattr for almost all RPCs. On some filesystems (particularly those that are clustered or networked) this is expensive and atomicity is difficult to guarantee. This flag indicates to nfsd that it should skip providing WCC attributes to the client in NFSv3 replies when doing operations on this filesystem. Consider enabling this on filesystems that have an expensive ->getattr inode operation, or when atomicity between pre and post operation attribute collection is impossible to guarantee.h]hXNRFC 1813 recommends that servers always send weak cache consistency (WCC) data to the client after each operation. The server should atomically collect attributes about the inode, do an operation on it, and then collect the attributes afterward. This allows the client to skip issuing GETATTRs in some situations but means that the server is calling vfs_getattr for almost all RPCs. On some filesystems (particularly those that are clustered or networked) this is expensive and atomicity is difficult to guarantee. This flag indicates to nfsd that it should skip providing WCC attributes to the client in NFSv3 replies when doing operations on this filesystem. Consider enabling this on filesystems that have an expensive ->getattr inode operation, or when atomicity between pre and post operation attribute collection is impossible to guarantee.}(hj2 hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj/ ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhhhKhj ubj)}(hXEXPORT_OP_NOSUBTREECHK - disallow subtree checking on this fs Many NFS operations deal with filehandles, which the server must then vet to ensure that they live inside of an exported tree. When the export consists of an entire filesystem, this is trivial. nfsd can just ensure that the filehandle live on the filesystem. When only part of a filesystem is exported however, then nfsd must walk the ancestors of the inode to ensure that it's within an exported subtree. This is an expensive operation and not all filesystems can support it properly. This flag exempts the filesystem from subtree checking and causes exportfs to get back an error if it tries to enable subtree checking on it. h](j)}(h=EXPORT_OP_NOSUBTREECHK - disallow subtree checking on this fsh]h=EXPORT_OP_NOSUBTREECHK - disallow subtree checking on this fs}(hjP hhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKhjL ubj)}(hhh]h)}(hXsMany NFS operations deal with filehandles, which the server must then vet to ensure that they live inside of an exported tree. When the export consists of an entire filesystem, this is trivial. nfsd can just ensure that the filehandle live on the filesystem. When only part of a filesystem is exported however, then nfsd must walk the ancestors of the inode to ensure that it's within an exported subtree. This is an expensive operation and not all filesystems can support it properly. This flag exempts the filesystem from subtree checking and causes exportfs to get back an error if it tries to enable subtree checking on it.h]hXuMany NFS operations deal with filehandles, which the server must then vet to ensure that they live inside of an exported tree. When the export consists of an entire filesystem, this is trivial. nfsd can just ensure that the filehandle live on the filesystem. When only part of a filesystem is exported however, then nfsd must walk the ancestors of the inode to ensure that it’s within an exported subtree. This is an expensive operation and not all filesystems can support it properly. This flag exempts the filesystem from subtree checking and causes exportfs to get back an error if it tries to enable subtree checking on it.}(hja hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj^ ubah}(h]h ]h"]h$]h&]uh1jhjL ubeh}(h]h ]h"]h$]h&]uh1jhhhKhj ubj)}(hXEXPORT_OP_CLOSE_BEFORE_UNLINK - always close cached files before unlinking On some exportable filesystems (such as NFS) unlinking a file that is still open can cause a fair bit of extra work. For instance, the NFS client will do a "sillyrename" to ensure that the file sticks around while it's still open. When reexporting, that open file is held by nfsd so we usually end up doing a sillyrename, and then immediately deleting the sillyrenamed file just afterward when the link count actually goes to zero. Sometimes this delete can race with other operations (for instance an rmdir of the parent directory). This flag causes nfsd to close any open files for this inode _before_ calling into the vfs to do an unlink or a rename that would replace an existing file. Uh](j)}(hJEXPORT_OP_CLOSE_BEFORE_UNLINK - always close cached files before unlinkingh]hJEXPORT_OP_CLOSE_BEFORE_UNLINK - always close cached files before unlinking}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKhj{ ubj)}(hhh]h)}(hXOn some exportable filesystems (such as NFS) unlinking a file that is still open can cause a fair bit of extra work. For instance, the NFS client will do a "sillyrename" to ensure that the file sticks around while it's still open. When reexporting, that open file is held by nfsd so we usually end up doing a sillyrename, and then immediately deleting the sillyrenamed file just afterward when the link count actually goes to zero. Sometimes this delete can race with other operations (for instance an rmdir of the parent directory). This flag causes nfsd to close any open files for this inode _before_ calling into the vfs to do an unlink or a rename that would replace an existing file.h]hXOn some exportable filesystems (such as NFS) unlinking a file that is still open can cause a fair bit of extra work. For instance, the NFS client will do a “sillyrename” to ensure that the file sticks around while it’s still open. When reexporting, that open file is held by nfsd so we usually end up doing a sillyrename, and then immediately deleting the sillyrenamed file just afterward when the link count actually goes to zero. Sometimes this delete can race with other operations (for instance an rmdir of the parent directory). This flag causes nfsd to close any open files for this inode _before_ calling into the vfs to do an unlink or a rename that would replace an existing file.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1jhj{ ubeh}(h]h ]h"]h$]h&]uh1jhhhKhj ubj)}(hX@EXPORT_OP_REMOTE_FS - Backing storage for this filesystem is remote PF_LOCAL_THROTTLE exists for loopback NFSD, where a thread needs to write to one bdi (the final bdi) in order to free up writes queued to another bdi (the client bdi). Such threads get a private balance of dirty pages so that dirty pages for the client bdi do not imact the daemon writing to the final bdi. For filesystems whose durable storage is not local (such as exported NFS filesystems), this constraint has negative consequences. EXPORT_OP_REMOTE_FS enables an export to disable writeback throttling. h](j)}(hCEXPORT_OP_REMOTE_FS - Backing storage for this filesystem is remoteh]hCEXPORT_OP_REMOTE_FS - Backing storage for this filesystem is remote}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKhj ubj)}(hhh]h)}(hXPF_LOCAL_THROTTLE exists for loopback NFSD, where a thread needs to write to one bdi (the final bdi) in order to free up writes queued to another bdi (the client bdi). Such threads get a private balance of dirty pages so that dirty pages for the client bdi do not imact the daemon writing to the final bdi. For filesystems whose durable storage is not local (such as exported NFS filesystems), this constraint has negative consequences. EXPORT_OP_REMOTE_FS enables an export to disable writeback throttling.h]hXPF_LOCAL_THROTTLE exists for loopback NFSD, where a thread needs to write to one bdi (the final bdi) in order to free up writes queued to another bdi (the client bdi). Such threads get a private balance of dirty pages so that dirty pages for the client bdi do not imact the daemon writing to the final bdi. For filesystems whose durable storage is not local (such as exported NFS filesystems), this constraint has negative consequences. EXPORT_OP_REMOTE_FS enables an export to disable writeback throttling.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhhhKhj ubj)}(hXEXPORT_OP_NOATOMIC_ATTR - Filesystem does not update attributes atomically EXPORT_OP_NOATOMIC_ATTR indicates that the exported filesystem cannot provide the semantics required by the "atomic" boolean in NFSv4's change_info4. This boolean indicates to a client whether the returned before and after change attributes were obtained atomically with the respect to the requested metadata operation (UNLINK, OPEN/CREATE, MKDIR, etc). h](j)}(hJEXPORT_OP_NOATOMIC_ATTR - Filesystem does not update attributes atomicallyh]hJEXPORT_OP_NOATOMIC_ATTR - Filesystem does not update attributes atomically}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKhj ubj)}(hhh]h)}(hXaEXPORT_OP_NOATOMIC_ATTR indicates that the exported filesystem cannot provide the semantics required by the "atomic" boolean in NFSv4's change_info4. This boolean indicates to a client whether the returned before and after change attributes were obtained atomically with the respect to the requested metadata operation (UNLINK, OPEN/CREATE, MKDIR, etc).h]hXgEXPORT_OP_NOATOMIC_ATTR indicates that the exported filesystem cannot provide the semantics required by the “atomic” boolean in NFSv4’s change_info4. This boolean indicates to a client whether the returned before and after change attributes were obtained atomically with the respect to the requested metadata operation (UNLINK, OPEN/CREATE, MKDIR, etc).}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhhhKhj ubj)}(hXEXPORT_OP_FLUSH_ON_CLOSE - Filesystem flushes file data on close(2) On most filesystems, inodes can remain under writeback after the file is closed. NFSD relies on client activity or local flusher threads to handle writeback. Certain filesystems, such as NFS, flush all of an inode's dirty data on last close. Exports that behave this way should set EXPORT_OP_FLUSH_ON_CLOSE so that NFSD knows to skip waiting for writeback when closing such files. h](j)}(hCEXPORT_OP_FLUSH_ON_CLOSE - Filesystem flushes file data on close(2)h]hCEXPORT_OP_FLUSH_ON_CLOSE - Filesystem flushes file data on close(2)}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKhj ubj)}(hhh]h)}(hX|On most filesystems, inodes can remain under writeback after the file is closed. NFSD relies on client activity or local flusher threads to handle writeback. Certain filesystems, such as NFS, flush all of an inode's dirty data on last close. Exports that behave this way should set EXPORT_OP_FLUSH_ON_CLOSE so that NFSD knows to skip waiting for writeback when closing such files.h]hX~On most filesystems, inodes can remain under writeback after the file is closed. NFSD relies on client activity or local flusher threads to handle writeback. Certain filesystems, such as NFS, flush all of an inode’s dirty data on last close. Exports that behave this way should set EXPORT_OP_FLUSH_ON_CLOSE so that NFSD knows to skip waiting for writeback when closing such files.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhhhKhj ubeh}(h]h ]h"]h$]h&]uh1jhj ubah}(h]h ]h"]h$]h&]uh1jhhhKhj hhubeh}(h]export-operations-flagsah ]h"]export operations flagsah$]h&]uh1hhhhhhhhKubh)}(hhh](h)}(hSigned Filehandlesh]hSigned Filehandles}(hjN hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjK hhhhhKubh)}(hTo protect against filehandle guessing attacks, the Linux NFS server can be configured to sign filehandles with a Message Authentication Code (MAC).h]hTo protect against filehandle guessing attacks, the Linux NFS server can be configured to sign filehandles with a Message Authentication Code (MAC).}(hj\ hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjK hhubh)}(hXStandard NFS filehandles are often predictable. If an attacker can guess a valid filehandle for a file they do not have permission to access via directory traversal, they may be able to bypass path-based permissions (though they still remain subject to inode-level permissions).h]hXStandard NFS filehandles are often predictable. If an attacker can guess a valid filehandle for a file they do not have permission to access via directory traversal, they may be able to bypass path-based permissions (though they still remain subject to inode-level permissions).}(hjj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjK hhubh)}(hXaSigned filehandles prevent this by appending a MAC to the filehandle before it is sent to the client. Upon receiving a filehandle back from a client, the server re-calculates the MAC using its internal key and verifies it against the one provided. If the signatures do not match, the server treats the filehandle as invalid (returning NFS[34]ERR_STALE).h]hXaSigned filehandles prevent this by appending a MAC to the filehandle before it is sent to the client. Upon receiving a filehandle back from a client, the server re-calculates the MAC using its internal key and verifies it against the one provided. If the signatures do not match, the server treats the filehandle as invalid (returning NFS[34]ERR_STALE).}(hjx hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjK hhubh)}(hNote that signing filehandles provides integrity and authenticity but not confidentiality. The contents of the filehandle remain visible to the client; they simply cannot be forged or modified.h]hNote that signing filehandles provides integrity and authenticity but not confidentiality. The contents of the filehandle remain visible to the client; they simply cannot be forged or modified.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjK hhubh)}(hhh](h)}(h Configurationh]h Configuration}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhKubh)}(hTo enable signed filehandles, the administrator must provide a signing key to the kernel and enable the "sign_fh" export option.h]hTo enable signed filehandles, the administrator must provide a signing key to the kernel and enable the “sign_fh” export option.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj hhubj>)}(hhh](jC)}(hProviding a Key The signing key is managed via the nfsd netlink interface. This key is per-network-namespace and must be set before any exports using "sign_fh" become active. h]h)}(hProviding a Key The signing key is managed via the nfsd netlink interface. This key is per-network-namespace and must be set before any exports using "sign_fh" become active.h]hProviding a Key The signing key is managed via the nfsd netlink interface. This key is per-network-namespace and must be set before any exports using “sign_fh” become active.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1jBhj hhhhhNubjC)}(hExport Options The feature is controlled on a per-export basis in /etc/exports: sign_fh Enables signing for all filehandles generated under this export. no_sign_fh (Default) Disables signing. h](h)}(hOExport Options The feature is controlled on a per-export basis in /etc/exports:h]hOExport Options The feature is controlled on a per-export basis in /etc/exports:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj ubj)}(hhh](j)}(hIsign_fh Enables signing for all filehandles generated under this export. h](j)}(hsign_fhh]hsign_fh}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKhj ubj)}(hhh]h)}(h@Enables signing for all filehandles generated under this export.h]h@Enables signing for all filehandles generated under this export.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhhhKhj ubj)}(h'no_sign_fh (Default) Disables signing. h](j)}(h no_sign_fhh]h no_sign_fh}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhKhj ubj)}(hhh]h)}(h(Default) Disables signing.h]h(Default) Disables signing.}(hj' hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj$ ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhhhKhj ubeh}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jBhj hhhNhNubeh}(h]h ]h"]h$]h&]jzj{j|hj}j~uh1j=hj hhhhhKubeh}(h] configurationah ]h"] configurationah$]h&]uh1hhjK hhhhhKubh)}(hhh](h)}(hKey Management and Rotationh]hKey Management and Rotation}(hj^ hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj[ hhhhhKubh)}(hQThe security of this mechanism relies entirely on the secrecy of the signing key.h]hQThe security of this mechanism relies entirely on the secrecy of the signing key.}(hjl hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj[ hhubj)}(hhh](j)}(hInitial Setup: The key should be generated using a high-quality random source and loaded early in the boot process or during the nfs-server startup sequence. h](j)}(hInitial Setup:h]hInitial Setup:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhMhj} ubj)}(hhh]h)}(hThe key should be generated using a high-quality random source and loaded early in the boot process or during the nfs-server startup sequence.h]hThe key should be generated using a high-quality random source and loaded early in the boot process or during the nfs-server startup sequence.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1jhj} ubeh}(h]h ]h"]h$]h&]uh1jhhhMhjz ubj)}(hChanging Keys: If a key is changed while clients have active mounts, existing filehandles held by those clients will become invalid, resulting in "Stale file handle" errors on the client side. h](j)}(hChanging Keys:h]hChanging Keys:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhM hj ubj)}(hhh]h)}(hIf a key is changed while clients have active mounts, existing filehandles held by those clients will become invalid, resulting in "Stale file handle" errors on the client side.h]hIf a key is changed while clients have active mounts, existing filehandles held by those clients will become invalid, resulting in “Stale file handle” errors on the client side.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhhhM hjz hhubj)}(hSafe Rotation: Currently, there is no mechanism for "graceful" key rotation (maintaining multiple valid keys). Changing the key is an atomic operation that immediately invalidates all previous signatures. h](j)}(hSafe Rotation:h]hSafe Rotation:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1jhhhMhj ubj)}(hhh]h)}(hCurrently, there is no mechanism for "graceful" key rotation (maintaining multiple valid keys). Changing the key is an atomic operation that immediately invalidates all previous signatures.h]hCurrently, there is no mechanism for “graceful” key rotation (maintaining multiple valid keys). Changing the key is an atomic operation that immediately invalidates all previous signatures.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM hj ubah}(h]h ]h"]h$]h&]uh1jhj ubeh}(h]h ]h"]h$]h&]uh1jhhhMhjz hhubeh}(h]h ]h"]h$]h&]uh1jhj[ hhhhhNubeh}(h]key-management-and-rotationah ]h"]key management and rotationah$]h&]uh1hhjK hhhhhKubh)}(hhh](h)}(hTransitioning Exportsh]hTransitioning Exports}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhMubh)}(hmWhen adding or removing the "sign_fh" flag from an active export, the following behaviors should be expected:h]hqWhen adding or removing the “sign_fh” flag from an active export, the following behaviors should be expected:}(hj) hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj hhubhtable)}(hhh]htgroup)}(hhh](hcolspec)}(hhh]h}(h]h ]h"]h$]h&]colwidthKuh1jA hj> ubjB )}(hhh]h}(h]h ]h"]h$]h&]colwidthK3uh1jA hj> ubhthead)}(hhh]hrow)}(hhh](hentry)}(hhh]h)}(hChangeh]hChange}(hjf hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjc ubah}(h]h ]h"]h$]h&]uh1ja hj^ ubjb )}(hhh]h)}(hResult for Existing Clientsh]hResult for Existing Clients}(hj} hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjz ubah}(h]h ]h"]h$]h&]uh1ja hj^ ubeh}(h]h ]h"]h$]h&]uh1j\ hjY ubah}(h]h ]h"]h$]h&]uh1jW hj> ubhtbody)}(hhh](j] )}(hhh](jb )}(hhh]h)}(hAdding sign_fhh]hAdding sign_fh}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1ja hj ubjb )}(hhh]h)}(hdClients holding unsigned filehandles will find them rejected, as the server now expects a signature.h]hdClients holding unsigned filehandles will find them rejected, as the server now expects a signature.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1ja hj ubeh}(h]h ]h"]h$]h&]uh1j\ hj ubj] )}(hhh](jb )}(hhh]h)}(hRemoving sign_fhh]hRemoving sign_fh}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1ja hj ubjb )}(hhh]h)}(hClients holding signed filehandles will find them rejected, as the server now expects the filehandle to end at its traditional boundary without a MAC.h]hClients holding signed filehandles will find them rejected, as the server now expects the filehandle to end at its traditional boundary without a MAC.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj ubah}(h]h ]h"]h$]h&]uh1ja hj ubeh}(h]h ]h"]h$]h&]uh1j\ hj ubeh}(h]h ]h"]h$]h&]uh1j hj> ubeh}(h]h ]h"]h$]h&]colsKuh1j< hj9 ubah}(h]h ]h"]h$]h&]uh1j7 hj hhhhhNubh)}(hBecause filehandles are often cached persistently by clients, adding or removing this option should generally be done during a scheduled maintenance window involving a NFS client unmount/remount.h]hBecause filehandles are often cached persistently by clients, adding or removing this option should generally be done during a scheduled maintenance window involving a NFS client unmount/remount.}(hj#hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM#hj hhubeh}(h]transitioning-exportsah ]h"]transitioning exportsah$]h&]uh1hhjK hhhhhMubeh}(h]signed-filehandlesah ]h"]signed filehandlesah$]h&]uh1hhhhhhhhKubeh}(h]making-filesystems-exportableah ]h"]making filesystems exportableah$]h&]uh1hhhhhhhhKubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(hN generatorN datestampN source_linkN source_urlN toc_backlinksja footnote_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_handlerjkerror_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}(jFjCj j jjj j jH jE j>j;jX jU j j j6j3u nametypes}(jFj jj jH j>jX j j6uh}(jChj hjjj jjTj]jE j j;jK jU j j j[ j3j u footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}Rparse_messages]transform_messages] transformerN include_log] decorationNhhub.