Author: rmacklem
Date: Sat Jul  7 19:27:49 2018
New Revision: 336075
URL: https://svnweb.freebsd.org/changeset/base/336075

Log:
  Fix handling of the hybrid DS case for a pNFS server.
  
  After the addition of the "#mds_path" suffix for a DS specification on the
  "-p" nfsd option, it is possible to have a mix of DSs assigned to an MDS
  file system and DSs that store files for all DSs. This is what I referred
  to as "hybrid" above.
  At first, I didn't think this hybrid case would be useful, but I now believe
  that some system administrators may fine it useful.
  This patch modifies the file storage assignment algorithm so that it
  makes the "#mds_path" DSs take priority and the all file systems DSs
  are now only used for MDS file systems with no "#mds_path" DS servers.
  This only affects the pNFS server for this "hybrid" case.

Modified:
  head/sys/fs/nfsserver/nfs_nfsdport.c

Modified: head/sys/fs/nfsserver/nfs_nfsdport.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdport.c        Sat Jul  7 19:11:43 2018        
(r336074)
+++ head/sys/fs/nfsserver/nfs_nfsdport.c        Sat Jul  7 19:27:49 2018        
(r336075)
@@ -3848,7 +3848,7 @@ nfsrv_pnfscreate(struct vnode *vp, struct vattr *vap, 
     NFSPROC_T *p)
 {
        struct nfsrvdscreate *dsc, *tdsc;
-       struct nfsdevice *ds, *mds;
+       struct nfsdevice *ds, *tds, *fds;
        struct mount *mp;
        struct pnfsdsfile *pf, *tpf;
        struct pnfsdsattr dsattr;
@@ -3866,12 +3866,25 @@ nfsrv_pnfscreate(struct vnode *vp, struct vattr *vap, 
        /* Get a DS server directory in a round-robin order. */
        mirrorcnt = 1;
        mp = vp->v_mount;
+       ds = fds = NULL;
        NFSDDSLOCK();
-       TAILQ_FOREACH(ds, &nfsrv_devidhead, nfsdev_list) {
-               if (ds->nfsdev_nmp != NULL && (ds->nfsdev_mdsisset == 0 ||
-                   (mp->mnt_stat.f_fsid.val[0] == ds->nfsdev_mdsfsid.val[0] &&
-                    mp->mnt_stat.f_fsid.val[1] == ds->nfsdev_mdsfsid.val[1])))
-                       break;
+       /*
+        * Search for the first entry that handles this MDS fs, but use the
+        * first entry for all MDS fs's otherwise.
+        */
+       TAILQ_FOREACH(tds, &nfsrv_devidhead, nfsdev_list) {
+               if (tds->nfsdev_nmp != NULL) {
+                       if (tds->nfsdev_mdsisset == 0 && ds == NULL)
+                               ds = tds;
+                       else if (tds->nfsdev_mdsisset != 0 &&
+                           mp->mnt_stat.f_fsid.val[0] ==
+                           tds->nfsdev_mdsfsid.val[0] &&
+                           mp->mnt_stat.f_fsid.val[1] ==
+                           tds->nfsdev_mdsfsid.val[1]) {
+                               ds = fds = tds;
+                               break;
+                       }
+               }
        }
        if (ds == NULL) {
                NFSDDSUNLOCK();
@@ -3881,17 +3894,18 @@ nfsrv_pnfscreate(struct vnode *vp, struct vattr *vap, 
        i = dsdir[0] = ds->nfsdev_nextdir;
        ds->nfsdev_nextdir = (ds->nfsdev_nextdir + 1) % nfsrv_dsdirsize;
        dvp[0] = ds->nfsdev_dsdir[i];
-       mds = TAILQ_NEXT(ds, nfsdev_list);
-       if (nfsrv_maxpnfsmirror > 1 && mds != NULL) {
-               TAILQ_FOREACH_FROM(mds, &nfsrv_devidhead, nfsdev_list) {
-                       if (mds->nfsdev_nmp != NULL &&
-                           (mds->nfsdev_mdsisset == 0 ||
-                            (mp->mnt_stat.f_fsid.val[0] ==
-                             mds->nfsdev_mdsfsid.val[0] &&
+       tds = TAILQ_NEXT(ds, nfsdev_list);
+       if (nfsrv_maxpnfsmirror > 1 && tds != NULL) {
+               TAILQ_FOREACH_FROM(tds, &nfsrv_devidhead, nfsdev_list) {
+                       if (tds->nfsdev_nmp != NULL &&
+                           ((tds->nfsdev_mdsisset == 0 && fds == NULL) ||
+                            (tds->nfsdev_mdsisset != 0 && fds != NULL &&
+                             mp->mnt_stat.f_fsid.val[0] ==
+                             tds->nfsdev_mdsfsid.val[0] &&
                              mp->mnt_stat.f_fsid.val[1] ==
-                             mds->nfsdev_mdsfsid.val[1]))) {
+                             tds->nfsdev_mdsfsid.val[1]))) {
                                dsdir[mirrorcnt] = i;
-                               dvp[mirrorcnt] = mds->nfsdev_dsdir[i];
+                               dvp[mirrorcnt] = tds->nfsdev_dsdir[i];
                                mirrorcnt++;
                                if (mirrorcnt >= nfsrv_maxpnfsmirror)
                                        break;
@@ -4495,7 +4509,7 @@ nfsrv_dsgetsockmnt(struct vnode *vp, int lktype, char 
        struct nfsmount *nmp, *newnmp;
        struct sockaddr *sad;
        struct sockaddr_in *sin;
-       struct nfsdevice *ds, *fndds;
+       struct nfsdevice *ds, *tds, *fndds;
        struct pnfsdsfile *pf;
        uint32_t dsdir;
        int error, fhiszero, fnd, gotone, i, mirrorcnt;
@@ -4563,6 +4577,7 @@ nfsrv_dsgetsockmnt(struct vnode *vp, int lktype, char 
                        /* Use the socket address to find the mount point. */
                        fndds = NULL;
                        NFSDDSLOCK();
+                       /* Find a match for the IP address. */
                        TAILQ_FOREACH(ds, &nfsrv_devidhead, nfsdev_list) {
                                if (ds->nfsdev_nmp != NULL) {
                                        dvp = ds->nfsdev_dvp;
@@ -4570,25 +4585,41 @@ nfsrv_dsgetsockmnt(struct vnode *vp, int lktype, char 
                                        if (nmp != ds->nfsdev_nmp)
                                                printf("different2 nmp %p %p\n",
                                                    nmp, ds->nfsdev_nmp);
-                                       if (nfsaddr2_match(sad, nmp->nm_nam))
+                                       if (nfsaddr2_match(sad, nmp->nm_nam)) {
                                                fndds = ds;
-                                       else if (newnmpp != NULL &&
-                                           newnmp == NULL &&
-                                           (*newnmpp == NULL ||
-                                            fndds == NULL) &&
-                                           (ds->nfsdev_mdsisset == 0 ||
-                                            (ds->nfsdev_mdsfsid.val[0] ==
+                                               break;
+                                       }
+                               }
+                       }
+                       if (fndds != NULL && newnmpp != NULL &&
+                           newnmp == NULL) {
+                               /* Search for a place to make a mirror copy. */
+                               TAILQ_FOREACH(tds, &nfsrv_devidhead,
+                                   nfsdev_list) {
+                                       if (tds->nfsdev_nmp != NULL &&
+                                           fndds != tds &&
+                                           ((tds->nfsdev_mdsisset == 0 &&
+                                             fndds->nfsdev_mdsisset == 0) ||
+                                            (tds->nfsdev_mdsisset != 0 &&
+                                             fndds->nfsdev_mdsisset != 0 &&
+                                             tds->nfsdev_mdsfsid.val[0] ==
                                              mp->mnt_stat.f_fsid.val[0] &&
-                                             ds->nfsdev_mdsfsid.val[1] ==
-                                             mp->mnt_stat.f_fsid.val[1])))
-                                               /*
-                                                * Return a destination for the
-                                                * copy in newnmpp. Choose the
-                                                * last valid one before the
-                                                * source mirror, so it isn't
-                                                * always the first one.
-                                                */
-                                               *newnmpp = nmp;
+                                             tds->nfsdev_mdsfsid.val[1] ==
+                                             mp->mnt_stat.f_fsid.val[1]))) {
+                                               *newnmpp = tds->nfsdev_nmp;
+                                               break;
+                                       }
+                               }
+                               if (tds != NULL) {
+                                       /*
+                                        * Move this entry to the end of the
+                                        * list, so it won't be selected as
+                                        * easily the next time.
+                                        */
+                                       TAILQ_REMOVE(&nfsrv_devidhead, tds,
+                                           nfsdev_list);
+                                       TAILQ_INSERT_TAIL(&nfsrv_devidhead, tds,
+                                           nfsdev_list);
                                }
                        }
                        NFSDDSUNLOCK();
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to