[OpenAFS-devel] A few fixes

Jeff Riegel riegel@almaden.ibm.com
Mon, 4 Jun 2001 19:14:42 -0700


Here are a few bug fixes for OpenAFS.  Diffs are based on 5/1/2001 snapshot.
Changes:

1) Fixed bug allowing user with only lookup permission on a dir. to stat
files in the dir. if the stat information was already in the cache.

2) Fixed race condition with RX connections by adding RX_CONN_BUSY status.

3) Fixed bug checking open mode in uafs_open.


Jeff Riegel
riegel@almaden.ibm.com


diff -Nur --exclude-from=exclude orig-src/afs/UKERNEL/afs_usrops.c src/afs/UKERNEL/afs_usrops.c
--- orig-src/afs/UKERNEL/afs_usrops.c	Sat Apr 14 10:27:43 2001
+++ src/afs/UKERNEL/afs_usrops.c	Thu May 24 17:07:58 2001
@@ -2678,6 +2678,7 @@
 	    if (flags & (O_WRONLY|O_RDWR)) {
 		fileMode |= VWRITE;
 	    }
+         if (!fileMode) fileMode = VREAD;  /* since O_RDONLY is 0 */
 	    code = afs_access(fileP, fileMode, u.u_cred);
 	    if (code != 0) {
 		VN_RELE(fileP);
diff -Nur --exclude-from=exclude orig-src/afs/VNOPS/afs_vnop_create.c src/afs/VNOPS/afs_vnop_create.c
--- orig-src/afs/VNOPS/afs_vnop_create.c	Mon Mar 26 23:06:38 2001
+++ src/afs/VNOPS/afs_vnop_create.c	Fri Jun  1 20:04:30 2001
@@ -177,6 +177,10 @@
 		if ((amode & VWRITE) || len != 0xffffffff) 
 #endif
 		  {
+              /* these lines are needed for write access check */
+              tvc->parentVnode = adp->fid.Fid.Vnode;
+              tvc->parentUnique = adp->fid.Fid.Unique;
+
 		    /* need write mode for these guys */
 		    if (!afs_AccessOK(tvc, PRSFS_WRITE, &treq, CHECK_MODE_BITS)) {
 			afs_PutVCache(tvc, READ_LOCK);
diff -Nur --exclude-from=exclude orig-src/afs/VNOPS/afs_vnop_lookup.c src/afs/VNOPS/afs_vnop_lookup.c
--- orig-src/afs/VNOPS/afs_vnop_lookup.c	Sat Feb 24 07:35:05 2001
+++ src/afs/VNOPS/afs_vnop_lookup.c	Thu May 24 17:01:40 2001
@@ -883,6 +883,7 @@
     extern afs_int32 afs_mariner;			/*Writing activity to log?*/
     OSI_VC_CONVERT(adp)
     afs_hyper_t versionNo;
+    int no_read_access = 0;
 
     AFS_STATCNT(afs_lookup);
 #ifdef	AFS_OSF_ENV
@@ -990,6 +991,10 @@
        else adp->last_looker = treq.uid;
     } 
 
+    /* Check for read access as well.  We need read access in order to
+       stat files, but not to stat subdirectories. */
+    if (!afs_AccessOK(adp, PRSFS_READ, &treq, CHECK_MODE_BITS))
+      no_read_access = 1;
 
     /* special case lookup of ".".  Can we check for it sooner in this code,
      * for instance, way up before "redo:" ??
@@ -1011,8 +1016,15 @@
 
     tvc = osi_dnlc_lookup (adp, tname, WRITE_LOCK);
     *avcp = tvc;  /* maybe wasn't initialized, but it is now */
-#ifdef AFS_LINUX22_ENV
     if (tvc) {
+      if (no_read_access && vType(tvc) != VDIR) {
+        /* need read access on dir to stat non-directory */
+        afs_PutVCache(tvc, WRITE_LOCK);
+        *avcp = (struct vcache *)0;
+        code = EACCES;
+        goto done;
+      }
+#ifdef AFS_LINUX22_ENV
       if (tvc->mvstat == 2) { /* we don't trust the dnlc for root vcaches */
 	AFS_RELE(tvc);
 	*avcp = 0;
@@ -1022,14 +1034,12 @@
 	hit = 1;
 	goto done;
       }
-    }
 #else /* non - LINUX */
-    if (tvc) {
       code = 0;
       hit = 1;
       goto done;
-    }
 #endif /* linux22 */
+    }
 
     {
     register struct dcache *tdc;
diff -Nur --exclude-from=exclude orig-src/afs/afs_pioctl.c src/afs/afs_pioctl.c
--- orig-src/afs/afs_pioctl.c	Mon Apr 30 15:08:40 2001
+++ src/afs/afs_pioctl.c	Fri Jun  1 20:00:47 2001
@@ -1845,6 +1845,13 @@
 	    afs_ResetUserConns(tu);
 	    tu->refCount--;
 	    ObtainWriteLock(&afs_xuser,228);
+#ifdef UKERNEL
+            /* set the expire times to 0, causes
+             * afs_GCUserData to remove this entry
+             */
+            tu->ct.EndTimestamp = 0;
+            tu->tokenTime = 0;
+#endif  /* UKERNEL */
 	}
     }
     ReleaseWriteLock(&afs_xuser);
diff -Nur --exclude-from=exclude orig-src/rx/rx.c src/rx/rx.c
--- orig-src/rx/rx.c	Mon Apr 30 00:03:55 2001
+++ src/rx/rx.c	Thu May 24 17:16:51 2001
@@ -863,7 +863,7 @@
 	MUTEX_EXIT(&rx_stats_mutex);
     }
 
-    if (conn->refCount > 0) {
+    if ((conn->refCount > 0) || (conn->flags & RX_CONN_BUSY)) {
 	/* Busy; wait till the last guy before proceeding */
 	MUTEX_EXIT(&conn->conn_data_lock);
 	USERPRI;
@@ -1763,6 +1763,7 @@
 	MUTEX_ENTER(&conn->conn_call_lock);
 	MUTEX_ENTER(&call->lock);
 	MUTEX_ENTER(&conn->conn_data_lock);
+	conn->flags |= RX_CONN_BUSY;
 	if (conn->flags & RX_CONN_MAKECALL_WAITING) {
 	    conn->flags &= (~RX_CONN_MAKECALL_WAITING);
 	    MUTEX_EXIT(&conn->conn_data_lock);
@@ -1801,8 +1802,10 @@
 
     CALL_RELE(call, RX_CALL_REFCOUNT_BEGIN);
     MUTEX_EXIT(&call->lock);
-    if (conn->type == RX_CLIENT_CONNECTION)
+    if (conn->type == RX_CLIENT_CONNECTION) {
 	MUTEX_EXIT(&conn->conn_call_lock);
+	conn->flags &= ~RX_CONN_BUSY;
+    }
     AFS_RXGUNLOCK();
     USERPRI;
     /*
@@ -6600,7 +6603,8 @@
      * queue.
      */
 
-    if ((rpc_stat == NULL) ||
+    if (queue_IsEnd(stats, rpc_stat) ||
+	(rpc_stat == NULL) ||
 	(rpc_stat->stats[0].interfaceId != rxInterface) ||
 	(rpc_stat->stats[0].remote_is_server != isServer)) {
 	int i;
diff -Nur --exclude-from=exclude orig-src/rx/rx.h src/rx/rx.h
--- orig-src/rx/rx.h	Mon Mar 26 16:51:36 2001
+++ src/rx/rx.h	Thu May 24 17:17:28 2001
@@ -481,6 +481,7 @@
 #define RX_CONN_USING_PACKET_CKSUM  4	/* non-zero header.spare field seen */
 #define RX_CONN_KNOW_WINDOW         8   /* window size negotiation works */
 #define RX_CONN_RESET		   16   /* connection is reset, remove */
+#define RX_CONN_BUSY               32   /* connection is busy; don't delete */
 
 /* Type of connection, client or server */
 #define	RX_CLIENT_CONNECTION	0