Author: avg
Date: Tue Nov  6 14:21:26 2018
New Revision: 340183
URL: https://svnweb.freebsd.org/changeset/base/340183

Log:
  MFC r339595: nfsrvd_readdirplus: for some errors, do not fail the entire 
request
  
  Sponsored by: Panzura

Modified:
  stable/11/sys/fs/nfsserver/nfs_nfsdport.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/fs/nfsserver/nfs_nfsdport.c
==============================================================================
--- stable/11/sys/fs/nfsserver/nfs_nfsdport.c   Tue Nov  6 13:54:24 2018        
(r340182)
+++ stable/11/sys/fs/nfsserver/nfs_nfsdport.c   Tue Nov  6 14:21:26 2018        
(r340183)
@@ -2150,10 +2150,22 @@ again:
                                                }
                                        }
                                }
-                               if (!r) {
-                                   if (refp == NULL &&
-                                       ((nd->nd_flag & ND_NFSV3) ||
-                                        NFSNONZERO_ATTRBIT(&attrbits))) {
+
+                               /*
+                                * If we failed to look up the entry, then it
+                                * has become invalid, most likely removed.
+                                */
+                               if (r != 0) {
+                                       if (needs_unbusy)
+                                               vfs_unbusy(new_mp);
+                                       goto invalid;
+                               }
+                               KASSERT(refp != NULL || nvp != NULL,
+                                   ("%s: undetected lookup error", __func__));
+
+                               if (refp == NULL &&
+                                   ((nd->nd_flag & ND_NFSV3) ||
+                                    NFSNONZERO_ATTRBIT(&attrbits))) {
                                        r = nfsvno_getfh(nvp, &nfh, p);
                                        if (!r)
                                            r = nfsvno_getattr(nvp, nvap,
@@ -2174,17 +2186,25 @@ again:
                                            if (new_mp == mp)
                                                new_mp = nvp->v_mount;
                                        }
-                                   }
-                               } else {
-                                   nvp = NULL;
                                }
-                               if (r) {
+
+                               /*
+                                * If we failed to get attributes of the entry,
+                                * then just skip it for NFSv3 (the traditional
+                                * behavior in the old NFS server).
+                                * For NFSv4 the behavior is controlled by
+                                * RDATTRERROR: we either ignore the error or
+                                * fail the request.
+                                * Note that RDATTRERROR is never set for NFSv3.
+                                */
+                               if (r != 0) {
                                        if (!NFSISSET_ATTRBIT(&attrbits,
                                            NFSATTRBIT_RDATTRERROR)) {
-                                               if (nvp != NULL)
-                                                       vput(nvp);
+                                               vput(nvp);
                                                if (needs_unbusy != 0)
                                                        vfs_unbusy(new_mp);
+                                               if ((nd->nd_flag & ND_NFSV3))
+                                                       goto invalid;
                                                nd->nd_repstat = r;
                                                break;
                                        }
@@ -2253,6 +2273,7 @@ again:
                        if (dirlen <= cnt)
                                entrycnt++;
                }
+invalid:
                cpos += dp->d_reclen;
                dp = (struct dirent *)cpos;
                cookiep++;
_______________________________________________
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