]> Zhao Yanbai Git Server - minix.git/commitdiff
Fix tll state bug
authorThomas Veerman <thomas@minix3.org>
Wed, 11 Jan 2012 10:20:44 +0000 (10:20 +0000)
committerThomas Veerman <thomas@minix3.org>
Thu, 12 Jan 2012 11:30:24 +0000 (11:30 +0000)
When a lock has read-serialized and read-only locks, releasing the read-
serialized lock would not set the state to read-only when no other locks
were pending.

servers/avfs/tll.c

index 6ce2f2c80130752840dff091ff70129db23bd5cc..bf728e880c59e54d3f520717d7de65af4a8c4f73 100644 (file)
@@ -93,6 +93,7 @@ PUBLIC void tll_downgrade(tll_t *tllp)
     case TLL_READSER:
        /* If nothing is queued on write-only, but there is a pending lock
         * requesting read-serialized, grant it and keep the lock type. */
+
        if (tllp->t_write == NULL && tllp->t_serial != NULL) {
                tllp->t_owner = tllp->t_serial;
                tllp->t_serial = tllp->t_serial->w_next; /* Remove head */
@@ -108,6 +109,9 @@ PUBLIC void tll_downgrade(tll_t *tllp)
        break;
     default: panic("VFS: Incorrect lock state");
   }
+
+  if (tllp->t_current != TLL_WRITE && tllp->t_current != TLL_READSER)
+       assert(tllp->t_owner == NULL);
 }
 
 PUBLIC void tll_init(tll_t *tllp)
@@ -233,6 +237,7 @@ PUBLIC int tll_unlock(tll_t *tllp)
        /* This unlock must have been done by a read-only lock */
        tllp->t_readonly--;
        assert(tllp->t_readonly >= 0);
+       assert(tllp->t_current == TLL_READ || tllp->t_current == TLL_READSER);
 
        /* If a read-serialized lock is trying to upgrade and there are no more
         * read-only locks, the lock can now be upgraded to write-only */
@@ -269,8 +274,12 @@ PUBLIC int tll_unlock(tll_t *tllp)
   }
 
   /* If no one is using this lock, mark it as not in use */
-  if (tllp->t_owner == NULL && tllp->t_readonly == 0)
-       tllp->t_current = TLL_NONE;
+  if (tllp->t_owner == NULL) {
+       if (tllp->t_readonly == 0)
+               tllp->t_current = TLL_NONE;
+       else
+               tllp->t_current = TLL_READ;
+  }
 
   if (tllp->t_current == TLL_NONE || tllp->t_current == TLL_READ) {
        if (!signal_owner) {