kernel - Fix ESTALE handling in stat() and access()
authorMatthew Dillon <dillon@apollo.backplane.com>
Mon, 18 Nov 2013 18:42:08 +0000 (10:42 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Mon, 18 Nov 2013 18:42:08 +0000 (10:42 -0800)
* ESTALE could cause a panic due to shared namecache lock.  Relock
  the ncp exclusively when forcing re-resolution of the ncp due to
  ESTALE.

  ESTALE can occur on NFS mounts.

Reported-by: thesjg
sys/kern/vfs_syscalls.c

index d9db9f6..e030d89 100644 (file)
@@ -2659,10 +2659,13 @@ retry:
 
                /*
                 * If the file handle is stale we have to re-resolve the
-                * entry.  This is a hack at the moment.
+                * entry with the ncp held exclusively.  This is a hack
+                * at the moment.
                 */
                if (error == ESTALE) {
                        vput(vp);
+                       cache_unlock(&nd->nl_nch);
+                       cache_lock(&nd->nl_nch);
                        cache_setunresolved(&nd->nl_nch);
                        error = cache_resolve(&nd->nl_nch, nd->nl_cred);
                        if (error == 0) {
@@ -2752,11 +2755,14 @@ again:
        error = vn_stat(vp, st, nd->nl_cred);
 
        /*
-        * If the file handle is stale we have to re-resolve the entry.  This
-        * is a hack at the moment.
+        * If the file handle is stale we have to re-resolve the
+        * entry with the ncp held exclusively.  This is a hack
+        * at the moment.
         */
        if (error == ESTALE) {
                vput(vp);
+               cache_unlock(&nd->nl_nch);
+               cache_lock(&nd->nl_nch);
                cache_setunresolved(&nd->nl_nch);
                error = cache_resolve(&nd->nl_nch, nd->nl_cred);
                if (error == 0)