162306a36Sopenharmony_ciReexporting NFS filesystems
262306a36Sopenharmony_ci===========================
362306a36Sopenharmony_ci
462306a36Sopenharmony_ciOverview
562306a36Sopenharmony_ci--------
662306a36Sopenharmony_ci
762306a36Sopenharmony_ciIt is possible to reexport an NFS filesystem over NFS.  However, this
862306a36Sopenharmony_cifeature comes with a number of limitations.  Before trying it, we
962306a36Sopenharmony_cirecommend some careful research to determine whether it will work for
1062306a36Sopenharmony_ciyour purposes.
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ciA discussion of current known limitations follows.
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci"fsid=" required, crossmnt broken
1562306a36Sopenharmony_ci---------------------------------
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ciWe require the "fsid=" export option on any reexport of an NFS
1862306a36Sopenharmony_cifilesystem.  You can use "uuidgen -r" to generate a unique argument.
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ciThe "crossmnt" export does not propagate "fsid=", so it will not allow
2162306a36Sopenharmony_citraversing into further nfs filesystems; if you wish to export nfs
2262306a36Sopenharmony_cifilesystems mounted under the exported filesystem, you'll need to export
2362306a36Sopenharmony_cithem explicitly, assigning each its own unique "fsid= option.
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ciReboot recovery
2662306a36Sopenharmony_ci---------------
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ciThe NFS protocol's normal reboot recovery mechanisms don't work for the
2962306a36Sopenharmony_cicase when the reexport server reboots.  Clients will lose any locks
3062306a36Sopenharmony_cithey held before the reboot, and further IO will result in errors.
3162306a36Sopenharmony_ciClosing and reopening files should clear the errors.
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ciFilehandle limits
3462306a36Sopenharmony_ci-----------------
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ciIf the original server uses an X byte filehandle for a given object, the
3762306a36Sopenharmony_cireexport server's filehandle for the reexported object will be X+22
3862306a36Sopenharmony_cibytes, rounded up to the nearest multiple of four bytes.
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ciThe result must fit into the RFC-mandated filehandle size limits:
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci+-------+-----------+
4362306a36Sopenharmony_ci| NFSv2 |  32 bytes |
4462306a36Sopenharmony_ci+-------+-----------+
4562306a36Sopenharmony_ci| NFSv3 |  64 bytes |
4662306a36Sopenharmony_ci+-------+-----------+
4762306a36Sopenharmony_ci| NFSv4 | 128 bytes |
4862306a36Sopenharmony_ci+-------+-----------+
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ciSo, for example, you will only be able to reexport a filesystem over
5162306a36Sopenharmony_ciNFSv2 if the original server gives you filehandles that fit in 10
5262306a36Sopenharmony_cibytes--which is unlikely.
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ciIn general there's no way to know the maximum filehandle size given out
5562306a36Sopenharmony_ciby an NFS server without asking the server vendor.
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ciBut the following table gives a few examples.  The first column is the
5862306a36Sopenharmony_citypical length of the filehandle from a Linux server exporting the given
5962306a36Sopenharmony_cifilesystem, the second is the length after that nfs export is reexported
6062306a36Sopenharmony_ciby another Linux host:
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci+--------+-------------------+----------------+
6362306a36Sopenharmony_ci|        | filehandle length | after reexport |
6462306a36Sopenharmony_ci+========+===================+================+
6562306a36Sopenharmony_ci| ext4:  | 28 bytes          | 52 bytes       |
6662306a36Sopenharmony_ci+--------+-------------------+----------------+
6762306a36Sopenharmony_ci| xfs:   | 32 bytes          | 56 bytes       |
6862306a36Sopenharmony_ci+--------+-------------------+----------------+
6962306a36Sopenharmony_ci| btrfs: | 40 bytes          | 64 bytes       |
7062306a36Sopenharmony_ci+--------+-------------------+----------------+
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ciAll will therefore fit in an NFSv3 or NFSv4 filehandle after reexport,
7362306a36Sopenharmony_cibut none are reexportable over NFSv2.
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ciLinux server filehandles are a bit more complicated than this, though;
7662306a36Sopenharmony_cifor example:
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci        - The (non-default) "subtreecheck" export option generally
7962306a36Sopenharmony_ci          requires another 4 to 8 bytes in the filehandle.
8062306a36Sopenharmony_ci        - If you export a subdirectory of a filesystem (instead of
8162306a36Sopenharmony_ci          exporting the filesystem root), that also usually adds 4 to 8
8262306a36Sopenharmony_ci          bytes.
8362306a36Sopenharmony_ci        - If you export over NFSv2, knfsd usually uses a shorter
8462306a36Sopenharmony_ci          filesystem identifier that saves 8 bytes.
8562306a36Sopenharmony_ci        - The root directory of an export uses a filehandle that is
8662306a36Sopenharmony_ci          shorter.
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ciAs you can see, the 128-byte NFSv4 filehandle is large enough that
8962306a36Sopenharmony_ciyou're unlikely to have trouble using NFSv4 to reexport any filesystem
9062306a36Sopenharmony_ciexported from a Linux server.  In general, if the original server is
9162306a36Sopenharmony_cisomething that also supports NFSv3, you're *probably* OK.  Re-exporting
9262306a36Sopenharmony_ciover NFSv3 may be dicier, and reexporting over NFSv2 will probably
9362306a36Sopenharmony_cinever work.
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ciFor more details of Linux filehandle structure, the best reference is
9662306a36Sopenharmony_cithe source code and comments; see in particular:
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci        - include/linux/exportfs.h:enum fid_type
9962306a36Sopenharmony_ci        - include/uapi/linux/nfsd/nfsfh.h:struct nfs_fhbase_new
10062306a36Sopenharmony_ci        - fs/nfsd/nfsfh.c:set_version_and_fsid_type
10162306a36Sopenharmony_ci        - fs/nfs/export.c:nfs_encode_fh
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ciOpen DENY bits ignored
10462306a36Sopenharmony_ci----------------------
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ciNFS since NFSv4 supports ALLOW and DENY bits taken from Windows, which
10762306a36Sopenharmony_ciallow you, for example, to open a file in a mode which forbids other
10862306a36Sopenharmony_ciread opens or write opens. The Linux client doesn't use them, and the
10962306a36Sopenharmony_ciserver's support has always been incomplete: they are enforced only
11062306a36Sopenharmony_ciagainst other NFS users, not against processes accessing the exported
11162306a36Sopenharmony_cifilesystem locally. A reexport server will also not pass them along to
11262306a36Sopenharmony_cithe original server, so they will not be enforced between clients of
11362306a36Sopenharmony_cidifferent reexport servers.
114