Author: rmacklem
Date: Fri Jun 22 21:25:27 2018
New Revision: 335567
URL: https://svnweb.freebsd.org/changeset/base/335567

Log:
  Change the NFSv4.1 pNFS client so that it returns the DS error in 
layoutreturn.
  
  When the NFSv4.1 pNFS client gets an error for a DS I/O operation using a
  Flexible File layout, it returns the layout with an error.
  This patch changes the code slightly, so that it returns the layout for all
  errors except EACCES and lets the MDS decide what to do based on the error.
  It also makes a couple of changes to nfscl_layoutrecall() to ensure that
  the first layoutreturn(s) will have the error in the reply.
  Plus, the patch adds a wakeup() so that the "nfscl" thread won't wait 1sec
  before doing the LayoutReturn.
  Tested against the pNFS service.
  This patch should not affect non-pNFS use of the client.
  The unused "dsp" argument will be used by a future patch that disables the
  connection to the DS when possible.
  
  MFC after:    2 weeks

Modified:
  head/sys/fs/nfs/nfs_var.h
  head/sys/fs/nfsclient/nfs_clrpcops.c
  head/sys/fs/nfsclient/nfs_clstate.c

Modified: head/sys/fs/nfs/nfs_var.h
==============================================================================
--- head/sys/fs/nfs/nfs_var.h   Fri Jun 22 20:58:51 2018        (r335566)
+++ head/sys/fs/nfs/nfs_var.h   Fri Jun 22 21:25:27 2018        (r335567)
@@ -601,7 +601,8 @@ int nfscl_layout(struct nfsmount *, vnode_t, u_int8_t 
     NFSPROC_T *);
 struct nfscllayout *nfscl_getlayout(struct nfsclclient *, uint8_t *, int,
     uint64_t, struct nfsclflayout **, int *);
-void nfscl_dserr(uint32_t, struct nfscldevinfo *, struct nfscllayout *);
+void nfscl_dserr(uint32_t, uint32_t, struct nfscldevinfo *,
+    struct nfscllayout *, struct nfsclds *);
 void nfscl_rellayout(struct nfscllayout *, int);
 struct nfscldevinfo *nfscl_getdevinfo(struct nfsclclient *, uint8_t *,
     struct nfscldevinfo *);

Modified: head/sys/fs/nfsclient/nfs_clrpcops.c
==============================================================================
--- head/sys/fs/nfsclient/nfs_clrpcops.c        Fri Jun 22 20:58:51 2018        
(r335566)
+++ head/sys/fs/nfsclient/nfs_clrpcops.c        Fri Jun 22 21:25:27 2018        
(r335567)
@@ -6040,10 +6040,11 @@ nfscl_dofflayoutio(vnode_t vp, struct uio *uiop, int *
                                            *dspp, fhp, dp->nfsdi_vers,
                                            dp->nfsdi_minorvers, tcred, p);
                                NFSCL_DEBUG(4, "commitds=%d\n", error);
-                               if (nfsds_failerr(error)) {
+                               if (error != 0 && error != EACCES) {
                                        NFSCL_DEBUG(4,
                                            "DS layreterr for commit\n");
-                                       nfscl_dserr(NFSV4OP_COMMIT, dp, lyp);
+                                       nfscl_dserr(NFSV4OP_COMMIT, error, dp,
+                                           lyp, *dspp);
                                }
                        }
                        NFSCL_DEBUG(4, "aft nfsio_commitds=%d\n", error);
@@ -6064,9 +6065,10 @@ nfscl_dofflayoutio(vnode_t vp, struct uio *uiop, int *
                            off, xfer, fhp, 1, dp->nfsdi_vers,
                            dp->nfsdi_minorvers, tcred, p);
                        NFSCL_DEBUG(4, "readds=%d\n", error);
-                       if (nfsds_failerr(error)) {
+                       if (error != 0 && error != EACCES) {
                                NFSCL_DEBUG(4, "DS layreterr for read\n");
-                               nfscl_dserr(NFSV4OP_READ, dp, lyp);
+                               nfscl_dserr(NFSV4OP_READ, error, dp, lyp,
+                                   *dspp);
                        }
                } else {
                        if (flp->nfsfl_mirrorcnt == 1) {
@@ -6099,10 +6101,11 @@ nfscl_dofflayoutio(vnode_t vp, struct uio *uiop, int *
                                            xfer, fhp, m, dp->nfsdi_vers,
                                            dp->nfsdi_minorvers, tcred, p);
                                NFSCL_DEBUG(4, "nfsio_writedsmir=%d\n", error);
-                               if (nfsds_failerr(error)) {
+                               if (error != 0 && error != EACCES) {
                                        NFSCL_DEBUG(4,
                                            "DS layreterr for write\n");
-                                       nfscl_dserr(NFSV4OP_WRITE, dp, lyp);
+                                       nfscl_dserr(NFSV4OP_WRITE, error, dp,
+                                           lyp, *dspp);
                                }
                        }
                }

Modified: head/sys/fs/nfsclient/nfs_clstate.c
==============================================================================
--- head/sys/fs/nfsclient/nfs_clstate.c Fri Jun 22 20:58:51 2018        
(r335566)
+++ head/sys/fs/nfsclient/nfs_clstate.c Fri Jun 22 21:25:27 2018        
(r335567)
@@ -4973,11 +4973,13 @@ nfscl_retoncloselayout(vnode_t vp, struct nfsclclient 
  * Mark the layout to be recalled and with an error.
  */
 void
-nfscl_dserr(uint32_t op, struct nfscldevinfo *dp, struct nfscllayout *lyp)
+nfscl_dserr(uint32_t op, uint32_t stat, struct nfscldevinfo *dp,
+    struct nfscllayout *lyp, __unused struct nfsclds *dsp)
 {
        struct nfsclrecalllayout *recallp;
        uint32_t iomode;
 
+       /* Set up the return of the layout. */
        recallp = malloc(sizeof(*recallp), M_NFSLAYRECALL, M_WAITOK);
        iomode = 0;
        NFSLOCKCLSTATE();
@@ -4987,10 +4989,10 @@ nfscl_dserr(uint32_t op, struct nfscldevinfo *dp, stru
                if (!LIST_EMPTY(&lyp->nfsly_flayrw))
                        iomode |= NFSLAYOUTIOMODE_RW;
                (void)nfscl_layoutrecall(NFSLAYOUTRETURN_FILE, lyp, iomode,
-                   0, UINT64_MAX, lyp->nfsly_stateid.seqid, NFSERR_IO, op,
+                   0, UINT64_MAX, lyp->nfsly_stateid.seqid, stat, op,
                    dp->nfsdi_deviceid, recallp);
                NFSUNLOCKCLSTATE();
-               NFSCL_DEBUG(4, "retoncls recall iomode=%d\n", iomode);
+               NFSCL_DEBUG(4, "nfscl_dserr recall iomode=%d\n", iomode);
        } else {
                NFSUNLOCKCLSTATE();
                free(recallp, M_NFSLAYRECALL);
@@ -5247,6 +5249,19 @@ nfscl_layoutrecall(int recalltype, struct nfscllayout 
                        LIST_INSERT_BEFORE(rp, recallp, nfsrecly_list);
                        break;
                }
+
+               /*
+                * Put any error return on all the file returns that will
+                * preceed this one.
+                */
+               if (rp->nfsrecly_recalltype == NFSLAYOUTRETURN_FILE &&
+                  stat != 0 && rp->nfsrecly_stat == 0) {
+                       rp->nfsrecly_stat = stat;
+                       rp->nfsrecly_op = op;
+                       if (devid != NULL)
+                               NFSBCOPY(devid, rp->nfsrecly_devid,
+                                   NFSX_V4DEVICEID);
+               }
        }
        if (rp == NULL) {
                if (orp == NULL)
@@ -5256,6 +5271,7 @@ nfscl_layoutrecall(int recalltype, struct nfscllayout 
                        LIST_INSERT_AFTER(orp, recallp, nfsrecly_list);
        }
        lyp->nfsly_flags |= NFSLY_RECALL;
+       wakeup(lyp->nfsly_clp);
        return (0);
 }
 
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to