Lines Matching refs:lock

66 #include <sys/lock.h>
89 void lf_print(const char *tag, struct lockf *lock);
90 void lf_printlist(const char *tag, struct lockf *lock);
116 * Overlapping lock states
143 * lock operation to be attempted.
166 struct lockf *lock;
180 LOCKF_DEBUG(0, "lf_advlock: '%s' unlock without lock\n", vfs_context_proc(context)->p_comm);
251 MALLOC(lock, struct lockf *, sizeof *lock, M_LOCKF, M_WAITOK);
252 if (lock == NULL)
254 lock->lf_start = start;
255 lock->lf_end = end;
256 lock->lf_id = ap->a_id;
257 lock->lf_vnode = vp;
258 lock->lf_type = fl->l_type;
259 lock->lf_head = head;
260 lock->lf_next = (struct lockf *)0;
261 TAILQ_INIT(&lock->lf_blkhd);
262 lock->lf_flags = ap->a_flags;
265 lock->lf_flags |= F_WAKE1_SAFE;
273 error = lf_setlock(lock);
277 error = lf_clearlock(lock);
278 FREE(lock, M_LOCKF);
282 error = lf_getlock(lock, fl, -1);
283 FREE(lock, M_LOCKF);
288 error = lf_getlock(lock, fl, fl->l_pid);
289 FREE(lock, M_LOCKF);
294 FREE(lock, M_LOCKF);
305 * Empty the queue of msleeping requests for a lock on the given vnode.
307 * a flock(2) invoker sleeping on a blocked lock holds an iocount reference
313 struct lockf *lock;
315 if ((lock = vp->v_lockf) == NULL)
320 if (!TAILQ_EMPTY(&lock->lf_blkhd)) {
323 TAILQ_FOREACH(tlock, &lock->lf_blkhd, lf_block) {
331 lf_wakelock(lock, TRUE);
336 * Take any lock attempts which are currently blocked by a given lock ("from")
337 * and mark them as blocked by a different lock ("to"). Used in the case
355 * Description: Helper function: when setting a lock, coalesce adjacent
359 * Parameters: lock The new lock which may be adjacent
366 lf_coalesce_adjacent(struct lockf *lock)
368 struct lockf **lf = lock->lf_head;
372 if ((*lf == lock) ||
373 ((*lf)->lf_id != lock->lf_id) ||
374 ((*lf)->lf_type != lock->lf_type)) {
384 ((*lf)->lf_end + 1) == lock->lf_start) {
388 lock->lf_start = (*lf)->lf_start;
389 *lf = lock;
392 lf_move_blocked(lock, adjacent);
397 /* If the lock starts adjacent to us, we can coalesce it */
398 if (lock->lf_end != -1 &&
399 (lock->lf_end + 1) == (*lf)->lf_start) {
403 lock->lf_end = (*lf)->lf_end;
404 lock->lf_next = (*lf)->lf_next;
405 lf = &lock->lf_next;
407 lf_move_blocked(lock, adjacent);
413 /* no matching conditions; go on to next lock */
422 * Description: Set a byte-range lock.
424 * Parameters: lock The lock structure describing the lock
426 * will be linked into the lock list if
437 * Notes: We add the lock to the provisional lock list. We do not
438 * coalesce at this time; this has implications for other lock
442 lf_setlock(struct lockf *lock)
445 struct lockf **head = lock->lf_head;
449 struct vnode *vp = lock->lf_vnode;
454 lf_print("lf_setlock", lock);
455 lf_printlist("lf_setlock(in)", lock);
463 if (lock->lf_type == F_WRLCK)
467 * Scan lock list for this file looking for locks that would block us.
469 while ((block = lf_getblock(lock, -1))) {
473 if ((lock->lf_flags & F_WAIT) == 0) {
474 FREE(lock, M_LOCKF);
488 if ((lock->lf_flags & F_POSIX) &&
504 * cycle to see if the lock is blocked behind
512 * Get the lock blocking the lock
526 * lock and not an overall file lock;
527 * if we mix lock types, it's our own
534 * If the owner of the lock that's
535 * blocking a lock that's blocking us
536 * getting the requested lock, then we
540 if (bproc == (struct proc *)lock->lf_id) {
542 FREE(lock, M_LOCKF);
553 * waiting for an exclusive lock.
555 if ((lock->lf_flags & F_FLOCK) &&
556 lock->lf_type == F_WRLCK) {
557 lock->lf_type = F_UNLCK;
558 if ((error = lf_clearlock(lock)) != 0) {
559 FREE(lock, M_LOCKF);
562 lock->lf_type = F_WRLCK;
565 * Add our lock to the blocked list and sleep until we're free.
568 lock->lf_next = block;
569 TAILQ_INSERT_TAIL(&block->lf_blkhd, lock, lf_block);
571 if ( !(lock->lf_flags & F_FLOCK))
580 error = msleep(lock, &vp->v_lock, priority, lockstr, 0);
582 if (error == 0 && (lock->lf_flags & F_ABORT) != 0)
585 if (lock->lf_next) {
591 * Remove 'lock' from the block list (avoids double-add
594 TAILQ_REMOVE(&lock->lf_next->lf_blkhd, lock, lf_block);
595 lock->lf_next = NULL;
601 printf("%s: spurious wakeup, retrying lock\n",
607 if (!TAILQ_EMPTY(&lock->lf_blkhd)) {
608 if ((block = lf_getblock(lock, -1)) != NULL)
609 lf_move_blocked(block, lock);
613 if (!TAILQ_EMPTY(&lock->lf_blkhd))
614 lf_wakelock(lock, TRUE);
615 FREE(lock, M_LOCKF);
621 * No blocks!! Add the lock. Note that we will
632 ovcase = lf_findoverlap(block, lock, SELF, &prev, &overlap);
638 * 1) overlap == lock
639 * 2) overlap contains lock
640 * 3) lock contains overlap
641 * 4) overlap starts before lock
642 * 5) overlap ends after lock
647 *prev = lock;
648 lock->lf_next = overlap;
654 * If downgrading lock, others may be
657 if (lock->lf_type == F_RDLCK &&
660 overlap->lf_type = lock->lf_type;
661 FREE(lock, M_LOCKF);
662 lock = overlap; /* for lf_coalesce_adjacent() */
669 if (overlap->lf_type == lock->lf_type) {
670 FREE(lock, M_LOCKF);
671 lock = overlap; /* for lf_coalesce_adjacent() */
674 if (overlap->lf_start == lock->lf_start) {
675 *prev = lock;
676 lock->lf_next = overlap;
677 overlap->lf_start = lock->lf_end + 1;
680 * If we can't split the lock, we can't
684 if (lf_split(overlap, lock)) {
685 FREE(lock, M_LOCKF);
694 * If downgrading lock, others may be able to
697 if (lock->lf_type == F_RDLCK &&
705 TAILQ_INSERT_TAIL(&lock->lf_blkhd,
707 ltmp->lf_next = lock;
711 * Add the new lock if necessary and delete the overlap.
714 *prev = lock;
715 lock->lf_next = overlap->lf_next;
716 prev = &lock->lf_next;
725 * Add lock after overlap on the list.
727 lock->lf_next = overlap->lf_next;
728 overlap->lf_next = lock;
729 overlap->lf_end = lock->lf_start - 1;
730 prev = &lock->lf_next;
737 * Add the new lock before overlap.
740 *prev = lock;
741 lock->lf_next = overlap;
743 overlap->lf_start = lock->lf_end + 1;
750 lf_coalesce_adjacent(lock);
753 lf_print("lf_setlock: got the lock", lock);
754 lf_printlist("lf_setlock(out)", lock);
764 * Description: Remove a byte-range lock on an vnode. Generally, find the
765 * lock (or an overlap to that lock) and remove it (or shrink
768 * Parameters: unlock The lock to clear
815 * If we can't split the lock, we can't grant it.
852 * Description: Check whether there is a blocking lock, and if so return
853 * its process identifier into the lock being requested.
855 * Parameters: lock Pointer to lock to test for blocks
857 * the blocking lock information, if a
858 * blocking lock is found.
865 * blocking lock, if one is found; not
872 lf_getlock(struct lockf *lock, struct flock *fl, pid_t matchpid)
878 lf_print("lf_getlock", lock);
881 if ((block = lf_getblock(lock, matchpid))) {
903 * blocking lock. A lock is considered blocking if we are not
904 * the lock owner; otherwise, we are permitted to upgrade or
907 * Parameters: lock The lock for which we are interested
908 * in obtaining the blocking lock, if any
911 * Returns: NOLOCKF No blocking lock exists
912 * !NOLOCKF The address of the blocking lock's
916 lf_getblock(struct lockf *lock, pid_t matchpid)
918 struct lockf **prev, *overlap, *lf = *(lock->lf_head);
920 for (prev = lock->lf_head;
921 lf_findoverlap(lf, lock, OTHERS, &prev, &overlap) != OVERLAP_NONE;
926 * If we're matching pids, and it's a record lock,
936 if ((lock->lf_type == F_WRLCK || overlap->lf_type == F_WRLCK))
946 * Description: Walk the list of locks to find an overlapping lock (if any).
948 * Parameters: lf First lock on lock list
949 * lock The lock we are checking for an overlap
952 * address of pointer to previous lock
953 * pointer to overlapping lock, if overlap
955 * of overlapping lock
966 * lock previous to the overlapping lock;
968 * lock list, avoiding a second iteration.
969 * *overlap The pointer to the overlapping lock
972 * caller to modify the overlapping lock,
975 * Note: This returns only the FIRST overlapping lock. There may be
976 * more than one. lf_getlock will return the first blocking lock,
982 * we can report a blocking lock on an F_GETLK request.
985 * no overlapping lock found; always check the return code.
988 lf_findoverlap(struct lockf *lf, struct lockf *lock, int type,
999 lf_print("lf_findoverlap: looking for overlap in", lock);
1001 start = lock->lf_start;
1002 end = lock->lf_end;
1004 if (((type & SELF) && lf->lf_id != lock->lf_id) ||
1005 ((type & OTHERS) && lf->lf_id == lock->lf_id)) {
1051 LOCKF_DEBUG(2, "overlap == lock\n");
1057 LOCKF_DEBUG(2, "overlap contains lock\n");
1063 LOCKF_DEBUG(2, "lock contains overlap\n");
1068 LOCKF_DEBUG(2, "overlap starts before lock\n");
1074 LOCKF_DEBUG(2, "overlap ends after lock\n");
1086 * Description: Split a lock and a contained region into two or three locks
1090 * lock2 Overlapping lock region requiring the
1094 * ENOLCK No memory for new lock
1097 * *lock1 Modified original lock
1098 * *lock2 Overlapping lock (inserted into list)
1099 * (new lock) Potential new lock inserted into list
1104 * lock; in that case, neither of the locks will be modified.
1132 * Make a new lock consisting of the last part of
1133 * the encompassing lock
1157 * waiting on the lock may now be able to acquire it.
1221 * Print out a lock; lock information is prefixed by the string in 'tag'
1224 * lock The lock whose information should be
1230 lf_print(const char *tag, struct lockf *lock)
1232 printf("%s: lock %p for ", tag, (void *)lock);
1233 if (lock->lf_flags & F_POSIX)
1234 printf("proc %ld", (long)((struct proc *)lock->lf_id)->p_pid);
1236 printf("id %p", (void *)lock->lf_id);
1237 if (lock->lf_vnode != 0)
1239 lock->lf_vnode,
1240 lock->lf_type == F_RDLCK ? "shared" :
1241 lock->lf_type == F_WRLCK ? "exclusive" :
1242 lock->lf_type == F_UNLCK ? "unlock" : "unknown",
1243 (intmax_t)lock->lf_start, (intmax_t)lock->lf_end);
1246 lock->lf_type == F_RDLCK ? "shared" :
1247 lock->lf_type == F_WRLCK ? "exclusive" :
1248 lock->lf_type == F_UNLCK ? "unlock" : "unknown",
1249 (intmax_t)lock->lf_start, (intmax_t)lock->lf_end);
1250 if (!TAILQ_EMPTY(&lock->lf_blkhd))
1251 printf(" block %p\n", (void *)TAILQ_FIRST(&lock->lf_blkhd));
1260 * Print out a lock list for the vnode associated with 'lock'; lock information
1264 * lock The lock whose vnode's lock list should
1270 lf_printlist(const char *tag, struct lockf *lock)
1274 if (lock->lf_vnode == 0)
1278 tag, lock->lf_vnode);
1279 for (lf = lock->lf_vnode->v_lockf; lf; lf = lf->lf_next) {