darwin-afs-syscall-eliminate-needless-vfs-context-hold-20070618
authorDerrick Brashear <shadow@dementia.org>
Mon, 18 Jun 2007 18:05:05 +0000 (18:05 +0000)
committerDerrick Brashear <shadow@dementia.org>
Mon, 18 Jun 2007 18:05:05 +0000 (18:05 +0000)
avoid potential deadlock if e.g. SetTokens is called before the kernel module initialization completes

src/afs/afs_call.c
src/afs/afs_syscall.c

index 771b95a..68a313a 100644 (file)
@@ -457,26 +457,27 @@ afs_syscall_call(parm, parm2, parm3, parm4, parm5, parm6)
 #endif /* AFS_SGI61_ENV */
 
     AFS_STATCNT(afs_syscall_call);
+    if (!afs_suser(
 #ifdef AFS_SUN5_ENV
-    if (!afs_suser(CRED()) && (parm != AFSOP_GETMTU)
-       && (parm != AFSOP_GETMASK)) {
-       /* only root can run this code */
-       return (EACCES);
+                  CRED()
 #else
-    if (!afs_suser(NULL) && (parm != AFSOP_GETMTU)
-       && (parm != AFSOP_GETMASK)) {
+                  NULL
+#endif
+                  ) && (parm != AFSOP_GETMTU) && (parm != AFSOP_GETMASK)) {
        /* only root can run this code */
+#if defined(AFS_OSF_ENV) || defined(AFS_SUN5_ENV) || defined(KERNEL_HAVE_UERROR)
 #if defined(KERNEL_HAVE_UERROR)
        setuerror(EACCES);
-       return (EACCES);
+#endif
+       code = EACCES;
 #else
-#if defined(AFS_OSF_ENV)
-       return EACCES;
-#else /* AFS_OSF_ENV */
-       return EPERM;
-#endif /* AFS_OSF_ENV */
+       code = EPERM;
 #endif
+       AFS_GLOCK();
+#ifdef AFS_DARWIN80_ENV
+       put_vfs_context();
 #endif
+       goto out;
     }
     AFS_GLOCK();
 #ifdef AFS_DARWIN80_ENV
@@ -763,7 +764,7 @@ afs_syscall_call(parm, parm2, parm3, parm4, parm5, parm6)
            afs_osi_Sleep(&afs_initState);
 
 #ifdef AFS_DARWIN80_ENV
-    get_vfs_context();
+       get_vfs_context();
 #endif
        /* do it by inode */
 #ifdef AFS_SGI62_ENV
@@ -771,7 +772,7 @@ afs_syscall_call(parm, parm2, parm3, parm4, parm5, parm6)
 #endif
        code = afs_InitCacheFile(NULL, ainode);
 #ifdef AFS_DARWIN80_ENV
-    put_vfs_context();
+       put_vfs_context();
 #endif
     } else if (parm == AFSOP_ROOTVOLUME) {
        /* wait for basic init */
@@ -811,7 +812,7 @@ afs_syscall_call(parm, parm2, parm3, parm4, parm5, parm6)
            else if (parm == AFSOP_CELLINFO)
                code = afs_InitCellInfo(tbuffer);
 #ifdef AFS_DARWIN80_ENV
-    put_vfs_context();
+           put_vfs_context();
 #endif
        }
        osi_FreeSmallSpace(tbuffer);
@@ -1050,9 +1051,6 @@ afs_syscall_call(parm, parm2, parm3, parm4, parm5, parm6)
        code = EINVAL;
 
   out:
-#ifdef AFS_DARWIN80_ENV /* to balance the put in afs3_syscall() */
-    get_vfs_context();
-#endif
     AFS_GUNLOCK();
 #ifdef AFS_LINUX20_ENV
     return -code;
index ae17aa6..5b1d782 100644 (file)
@@ -705,7 +705,8 @@ Afs_syscall()
     }
 
 #if defined(AFS_DARWIN80_ENV)
-    put_vfs_context();
+    if (uap->syscall != AFSCALL_CALL)
+       put_vfs_context();
 #endif
 #ifdef AFS_LINUX20_ENV
     code = -code;