describe ap (Kirk); delete lfs_mntinvalbuf, lfs_vinvalbuf, add
[unix-history] / usr / src / sys / ufs / ffs / ufs_lockf.c
index 4dcab13..33cb8bb 100644 (file)
@@ -7,25 +7,22 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)ufs_lockf.c 7.2 (Berkeley) %G%
+ *     @(#)ufs_lockf.c 7.9.1.1 (Berkeley) %G%
  */
 
  */
 
-#include "param.h"
-#include "systm.h"
-#include "user.h"
-#include "kernel.h"
-#include "file.h"
-#include "proc.h"
-#include "socketvar.h"
-#include "socket.h"
-#include "vnode.h"
-#include "ioctl.h"
-#include "tty.h"
-#include "malloc.h"
-#include "fcntl.h"
-#include "../ufs/lockf.h"
-#include "../ufs/quota.h"
-#include "../ufs/inode.h"
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/file.h>
+#include <sys/proc.h>
+#include <sys/vnode.h>
+#include <sys/malloc.h>
+#include <sys/fcntl.h>
+
+#include <ufs/ufs/lockf.h>
+#include <ufs/ufs/quota.h>
+#include <ufs/ufs/inode.h>
+#include <ufs/ufs/ufs_extern.h>
 
 /*
  * This variable controls the maximum number of processes that will
 
 /*
  * This variable controls the maximum number of processes that will
@@ -35,15 +32,18 @@ int maxlockdepth = MAXDEPTH;
 
 #ifdef LOCKF_DEBUG
 int    lockf_debug = 0;
 
 #ifdef LOCKF_DEBUG
 int    lockf_debug = 0;
-#endif /* LOCKF_DEBUG */
+#endif
 
 #define NOLOCKF (struct lockf *)0
 #define SELF   0x1
 #define OTHERS 0x2
 
 
 #define NOLOCKF (struct lockf *)0
 #define SELF   0x1
 #define OTHERS 0x2
 
+#define HASBLOCK 0x100
+
 /*
  * Set a byte-range lock.
  */
 /*
  * Set a byte-range lock.
  */
+int
 lf_setlock(lock)
        register struct lockf *lock;
 {
 lf_setlock(lock)
        register struct lockf *lock;
 {
@@ -132,9 +132,23 @@ lf_setlock(lock)
                        lf_printlist("lf_setlock", block);
                }
 #endif /* LOCKF_DEBUG */
                        lf_printlist("lf_setlock", block);
                }
 #endif /* LOCKF_DEBUG */
-               if (error = tsleep((caddr_t *)lock, priority, lockstr, 0)) {
-                       free(lock, M_LOCKF);
-                       return (error);
+               if (error = tsleep((caddr_t)lock, priority, lockstr, 0)) {
+                       /*
+                        * Delete ourselves from the waiting to lock list.
+                        */
+                       for (block = lock->lf_next;
+                            block != NOLOCKF;
+                            block = block->lf_block) {
+                               if (block->lf_block != lock)
+                                       continue;
+                               block->lf_block = block->lf_block->lf_block;
+                               block->lf_spare = block->lf_block->lf_block;
+                               if ((block->lf_block->lf_flags & HASBLOCK) == 0)
+                                       block->lf_flags &= ~HASBLOCK;
+                               free(lock, M_LOCKF);
+                               return (error);
+                       }
+                       panic("lf_setlock: lost lock");
                }
        }
        /*
                }
        }
        /*
@@ -149,8 +163,8 @@ lf_setlock(lock)
        block = ip->i_lockf;
        needtolink = 1;
        for (;;) {
        block = ip->i_lockf;
        needtolink = 1;
        for (;;) {
-               ovcase = lf_findoverlap(block, lock, SELF, &prev, &overlap);
-               block = overlap->lf_next;
+               if (ovcase = lf_findoverlap(block, lock, SELF, &prev, &overlap))
+                       block = overlap->lf_next;
                /*
                 * Six cases:
                 *      0) no overlap
                /*
                 * Six cases:
                 *      0) no overlap
@@ -251,7 +265,6 @@ lf_setlock(lock)
                }
                break;
        }
                }
                break;
        }
-out:
 #ifdef LOCKF_DEBUG
        if (lockf_debug & 1) {
                lf_print("lf_setlock: got the lock", lock);
 #ifdef LOCKF_DEBUG
        if (lockf_debug & 1) {
                lf_print("lf_setlock: got the lock", lock);
@@ -267,6 +280,7 @@ out:
  * Generally, find the lock (or an overlap to that lock)
  * and remove it (or shrink it), then wakeup anyone we can.
  */
  * Generally, find the lock (or an overlap to that lock)
  * and remove it (or shrink it), then wakeup anyone we can.
  */
+int
 lf_clearlock(unlock)
        register struct lockf *unlock;
 {
 lf_clearlock(unlock)
        register struct lockf *unlock;
 {
@@ -335,6 +349,7 @@ lf_clearlock(unlock)
  * Check whether there is a blocking lock,
  * and if so return its process identifier.
  */
  * Check whether there is a blocking lock,
  * and if so return its process identifier.
  */
+int
 lf_getlock(lock, fl)
        register struct lockf *lock;
        register struct flock *fl;
 lf_getlock(lock, fl)
        register struct lockf *lock;
        register struct flock *fl;
@@ -359,6 +374,8 @@ lf_getlock(lock, fl)
                        fl->l_pid = ((struct proc *)(block->lf_id))->p_pid;
                else
                        fl->l_pid = -1;
                        fl->l_pid = ((struct proc *)(block->lf_id))->p_pid;
                else
                        fl->l_pid = -1;
+       } else {
+               fl->l_type = F_UNLCK;
        }
        return (0);
 }
        }
        return (0);
 }
@@ -397,6 +414,7 @@ lf_getblock(lock)
  * NOTE: this returns only the FIRST overlapping lock.  There
  *      may be more than one.
  */
  * NOTE: this returns only the FIRST overlapping lock.  There
  *      may be more than one.
  */
+int
 lf_findoverlap(lf, lock, type, prev, overlap)
        register struct lockf *lf;
        struct lockf *lock;
 lf_findoverlap(lf, lock, type, prev, overlap)
        register struct lockf *lf;
        struct lockf *lock;
@@ -505,6 +523,7 @@ lf_findoverlap(lf, lock, type, prev, overlap)
 /*
  * Add a lock to the end of the blocked list.
  */
 /*
  * Add a lock to the end of the blocked list.
  */
+void
 lf_addblock(lock, blocked)
        struct lockf *lock;
        struct lockf *blocked;
 lf_addblock(lock, blocked)
        struct lockf *lock;
        struct lockf *blocked;
@@ -521,11 +540,15 @@ lf_addblock(lock, blocked)
 #endif /* LOCKF_DEBUG */
        if ((lf = lock->lf_block) == NOLOCKF) {
                lock->lf_block = blocked;
 #endif /* LOCKF_DEBUG */
        if ((lf = lock->lf_block) == NOLOCKF) {
                lock->lf_block = blocked;
+               lock->lf_spare = blocked;
+               lock->lf_flags |= HASBLOCK;
                return;
        }
        while (lf->lf_block != NOLOCKF)
                lf = lf->lf_block;
        lf->lf_block = blocked;
                return;
        }
        while (lf->lf_block != NOLOCKF)
                lf = lf->lf_block;
        lf->lf_block = blocked;
+       lf->lf_spare = blocked;
+       lf->lf_flags |= HASBLOCK;
        return;
 }
 
        return;
 }
 
@@ -533,6 +556,7 @@ lf_addblock(lock, blocked)
  * Split a lock and a contained region into
  * two or three locks as necessary.
  */
  * Split a lock and a contained region into
  * two or three locks as necessary.
  */
+void
 lf_split(lock1, lock2)
        register struct lockf *lock1;
        register struct lockf *lock2;
 lf_split(lock1, lock2)
        register struct lockf *lock1;
        register struct lockf *lock2;
@@ -567,6 +591,7 @@ lf_split(lock1, lock2)
        bcopy((caddr_t)lock1, (caddr_t)splitlock, sizeof *splitlock);
        splitlock->lf_start = lock2->lf_end + 1;
        splitlock->lf_block = NOLOCKF;
        bcopy((caddr_t)lock1, (caddr_t)splitlock, sizeof *splitlock);
        splitlock->lf_start = lock2->lf_end + 1;
        splitlock->lf_block = NOLOCKF;
+       splitlock->lf_spare = NOLOCKF;
        lock1->lf_end = lock2->lf_start - 1;
        /*
         * OK, now link it in
        lock1->lf_end = lock2->lf_start - 1;
        /*
         * OK, now link it in
@@ -579,16 +604,30 @@ lf_split(lock1, lock2)
 /*
  * Wakeup a blocklist
  */
 /*
  * Wakeup a blocklist
  */
+void
 lf_wakelock(listhead)
        struct lockf *listhead;
 {
         register struct lockf *blocklist, *wakelock;
 
 lf_wakelock(listhead)
        struct lockf *listhead;
 {
         register struct lockf *blocklist, *wakelock;
 
+       if (listhead->lf_block != NOLOCKF) {
+               if ((listhead->lf_flags & HASBLOCK) == 0)
+                       panic("lf_wakelock: listhead unexpected ptr");
+               if (listhead->lf_block != listhead->lf_spare)
+                       panic("lf_wakelock: listhead corrupted ptr");
+       }
        blocklist = listhead->lf_block;
        blocklist = listhead->lf_block;
-       listhead->lf_block = NOLOCKF;
         while (blocklist != NOLOCKF) {
                 wakelock = blocklist;
                 blocklist = blocklist->lf_block;
         while (blocklist != NOLOCKF) {
                 wakelock = blocklist;
                 blocklist = blocklist->lf_block;
+               if (blocklist != NOLOCKF) {
+                       if ((wakelock->lf_flags & HASBLOCK) == 0)
+                               panic("lf_wakelock: unexpected ptr");
+                       if (wakelock->lf_block != wakelock->lf_spare)
+                               panic("lf_wakelock: corrupted ptr");
+               }
+               wakelock->lf_flags &= ~HASBLOCK;
+               wakelock->lf_spare = NOLOCKF;
                wakelock->lf_block = NOLOCKF;
                wakelock->lf_next = NOLOCKF;
 #ifdef LOCKF_DEBUG
                wakelock->lf_block = NOLOCKF;
                wakelock->lf_next = NOLOCKF;
 #ifdef LOCKF_DEBUG
@@ -597,18 +636,22 @@ lf_wakelock(listhead)
 #endif /* LOCKF_DEBUG */
                 wakeup((caddr_t)wakelock);
         }
 #endif /* LOCKF_DEBUG */
                 wakeup((caddr_t)wakelock);
         }
+       listhead->lf_flags &= ~HASBLOCK;
+       listhead->lf_spare = NOLOCKF;
+       listhead->lf_block = NOLOCKF;
 }
 
 #ifdef LOCKF_DEBUG
 /*
  * Print out a lock.
  */
 }
 
 #ifdef LOCKF_DEBUG
 /*
  * Print out a lock.
  */
+void
 lf_print(tag, lock)
        char *tag;
        register struct lockf *lock;
 {
        
 lf_print(tag, lock)
        char *tag;
        register struct lockf *lock;
 {
        
-       printf("%s: lock 0x%X for ", tag, lock);
+       printf("%s: lock 0x%lx for ", tag, lock);
        if (lock->lf_flags & F_POSIX)
                printf("proc %d", ((struct proc *)(lock->lf_id))->p_pid);
        else
        if (lock->lf_flags & F_POSIX)
                printf("proc %d", ((struct proc *)(lock->lf_id))->p_pid);
        else
@@ -627,6 +670,7 @@ lf_print(tag, lock)
                printf("\n");
 }
 
                printf("\n");
 }
 
+void
 lf_printlist(tag, lock)
        char *tag;
        struct lockf *lock;
 lf_printlist(tag, lock)
        char *tag;
        struct lockf *lock;
@@ -638,7 +682,7 @@ lf_printlist(tag, lock)
                major(lock->lf_inode->i_dev),
                minor(lock->lf_inode->i_dev));
        for (lf = lock->lf_inode->i_lockf; lf; lf = lf->lf_next) {
                major(lock->lf_inode->i_dev),
                minor(lock->lf_inode->i_dev));
        for (lf = lock->lf_inode->i_lockf; lf; lf = lf->lf_next) {
-               printf("\tlock 0x%X for ", lf);
+               printf("\tlock 0x%lx for ", lf);
                if (lf->lf_flags & F_POSIX)
                        printf("proc %d", ((struct proc *)(lf->lf_id))->p_pid);
                else
                if (lf->lf_flags & F_POSIX)
                        printf("proc %d", ((struct proc *)(lf->lf_id))->p_pid);
                else