1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-16 10:20:30 +00:00

Add Flex File Layout support to the NFSv4.1 pNFS client.

This patch adds support for the Flexible File Layout to the pNFS client.
Although the patch is rather large, it should only affect NFS mounts
using the "pnfs" option against pNFS servers that do not support File
Layout.
There are still a couple of things missing from the Flexible File Layout
client implementation:
- The code does not yet do a LayoutReturn with I/O error stats when
  I/O error(s) occur when attempting to do I/O on a DS.
  This will be fixed in a future commit, since it is important for the
  MDS to know that I/O on a DS is failing.
- The current code does writes and commits to mirror DSs serially.
  Making them happen concurrently will be done in a future commit,
  after discussion on freebsd-current@ on the best way to do this.
- The code does not handle NFSv4.0 DSs. Since there is no extant pNFS
  server that implements NFSv4.0 DSs and NFSv4.1 DSs makes more sense
  now, I don't intend to implement this until there is a need for it.
  There is support for NFSv4.1 and NFSv3 DSs.
This commit is contained in:
Rick Macklem 2017-10-05 20:10:40 +00:00
parent d07e22cdd8
commit b949cc41d1
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=324336
3 changed files with 948 additions and 225 deletions

View File

@ -555,7 +555,7 @@ int nfscl_tryclose(struct nfsclopen *, struct ucred *,
struct nfsmount *, NFSPROC_T *);
void nfscl_cleanup(NFSPROC_T *);
int nfscl_layout(struct nfsmount *, vnode_t, u_int8_t *, int, nfsv4stateid_t *,
int, struct nfsclflayouthead *, struct nfscllayout **, struct ucred *,
int, int, struct nfsclflayouthead *, struct nfscllayout **, struct ucred *,
NFSPROC_T *);
struct nfscllayout *nfscl_getlayout(struct nfsclclient *, uint8_t *, int,
uint64_t, struct nfsclflayout **, int *);

File diff suppressed because it is too large Load Diff

View File

@ -4783,7 +4783,7 @@ nfscl_errmap(struct nfsrv_descript *nd, u_int32_t minorvers)
*/
APPLESTATIC int
nfscl_layout(struct nfsmount *nmp, vnode_t vp, u_int8_t *fhp, int fhlen,
nfsv4stateid_t *stateidp, int retonclose,
nfsv4stateid_t *stateidp, int layouttype, int retonclose,
struct nfsclflayouthead *fhlp, struct nfscllayout **lypp,
struct ucred *cred, NFSPROC_T *p)
{
@ -4835,8 +4835,12 @@ nfscl_layout(struct nfsmount *nmp, vnode_t vp, u_int8_t *fhp, int fhlen,
lyp->nfsly_filesid[0] = np->n_vattr.na_filesid[0];
lyp->nfsly_filesid[1] = np->n_vattr.na_filesid[1];
lyp->nfsly_clp = clp;
lyp->nfsly_flags = (retonclose != 0) ?
(NFSLY_FILES | NFSLY_RETONCLOSE) : NFSLY_FILES;
if (layouttype == NFSLAYOUT_FLEXFILE)
lyp->nfsly_flags = NFSLY_FLEXFILE;
else
lyp->nfsly_flags = NFSLY_FILES;
if (retonclose != 0)
lyp->nfsly_flags |= NFSLY_RETONCLOSE;
lyp->nfsly_fhlen = fhlen;
NFSBCOPY(fhp, lyp->nfsly_fh, fhlen);
TAILQ_INSERT_HEAD(&clp->nfsc_layout, lyp, nfsly_list);
@ -5079,6 +5083,7 @@ nfscl_adddevinfo(struct nfsmount *nmp, struct nfscldevinfo *dip,
{
struct nfsclclient *clp;
struct nfscldevinfo *tdip;
uint8_t *dev;
NFSLOCKCLSTATE();
clp = nmp->nm_clp;
@ -5088,7 +5093,11 @@ nfscl_adddevinfo(struct nfsmount *nmp, struct nfscldevinfo *dip,
free(dip, M_NFSDEVINFO);
return (ENODEV);
}
tdip = nfscl_finddevinfo(clp, flp->nfsfl_dev);
if ((flp->nfsfl_flags & NFSFL_FILE) != 0)
dev = flp->nfsfl_dev;
else
dev = flp->nfsfl_ffm[0].dev;
tdip = nfscl_finddevinfo(clp, dev);
if (tdip != NULL) {
tdip->nfsdi_layoutrefs++;
flp->nfsfl_devp = tdip;
@ -5140,10 +5149,15 @@ nfscl_freelayout(struct nfscllayout *layp)
APPLESTATIC void
nfscl_freeflayout(struct nfsclflayout *flp)
{
int i;
int i, j;
for (i = 0; i < flp->nfsfl_fhcnt; i++)
free(flp->nfsfl_fh[i], M_NFSFH);
if ((flp->nfsfl_flags & NFSFL_FILE) != 0)
for (i = 0; i < flp->nfsfl_fhcnt; i++)
free(flp->nfsfl_fh[i], M_NFSFH);
if ((flp->nfsfl_flags & NFSFL_FLEXFILE) != 0)
for (i = 0; i < flp->nfsfl_mirrorcnt; i++)
for (j = 0; j < flp->nfsfl_ffm[i].fhcnt; j++)
free(flp->nfsfl_ffm[i].fh[j], M_NFSFH);
if (flp->nfsfl_devp != NULL)
flp->nfsfl_devp->nfsdi_layoutrefs--;
free(flp, M_NFSFLAYOUT);
@ -5235,12 +5249,17 @@ nfscl_layoutreturn(struct nfsmount *nmp, struct nfscllayout *lyp,
{
struct nfsclrecalllayout *rp;
nfsv4stateid_t stateid;
int layouttype;
NFSBCOPY(lyp->nfsly_stateid.other, stateid.other, NFSX_STATEIDOTHER);
stateid.seqid = lyp->nfsly_stateid.seqid;
if ((lyp->nfsly_flags & NFSLY_FILES) != 0)
layouttype = NFSLAYOUT_NFSV4_1_FILES;
else
layouttype = NFSLAYOUT_FLEXFILE;
LIST_FOREACH(rp, &lyp->nfsly_recall, nfsrecly_list) {
(void)nfsrpc_layoutreturn(nmp, lyp->nfsly_fh,
lyp->nfsly_fhlen, 0, NFSLAYOUT_NFSV4_1_FILES,
lyp->nfsly_fhlen, 0, layouttype,
rp->nfsrecly_iomode, rp->nfsrecly_recalltype,
rp->nfsrecly_off, rp->nfsrecly_len,
&stateid, cred, p, NULL);
@ -5256,15 +5275,27 @@ nfscl_dolayoutcommit(struct nfsmount *nmp, struct nfscllayout *lyp,
{
struct nfsclflayout *flp;
uint64_t len;
int error;
int error, layouttype;
if ((lyp->nfsly_flags & NFSLY_FILES) != 0)
layouttype = NFSLAYOUT_NFSV4_1_FILES;
else
layouttype = NFSLAYOUT_FLEXFILE;
LIST_FOREACH(flp, &lyp->nfsly_flayrw, nfsfl_list) {
if (flp->nfsfl_off <= lyp->nfsly_lastbyte) {
if (layouttype == NFSLAYOUT_FLEXFILE &&
(flp->nfsfl_fflags & NFSFLEXFLAG_NO_LAYOUTCOMMIT) != 0) {
NFSCL_DEBUG(4, "Flex file: no layoutcommit\n");
/* If not supported, don't bother doing it. */
NFSLOCKMNT(nmp);
nmp->nm_state |= NFSSTA_NOLAYOUTCOMMIT;
NFSUNLOCKMNT(nmp);
break;
} else if (flp->nfsfl_off <= lyp->nfsly_lastbyte) {
len = flp->nfsfl_end - flp->nfsfl_off;
error = nfsrpc_layoutcommit(nmp, lyp->nfsly_fh,
lyp->nfsly_fhlen, 0, flp->nfsfl_off, len,
lyp->nfsly_lastbyte, &lyp->nfsly_stateid,
NFSLAYOUT_NFSV4_1_FILES, cred, p, NULL);
layouttype, cred, p, NULL);
NFSCL_DEBUG(4, "layoutcommit err=%d\n", error);
if (error == NFSERR_NOTSUPP) {
/* If not supported, don't bother doing it. */