1 /*- 2 * Copyright (c) 1982, 1986, 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Scooter Morris at Genentech Inc. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 4. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * @(#)ufs_lockf.c 8.3 (Berkeley) 1/6/94 33 */ 34 35 #include <sys/cdefs.h> 36 __FBSDID("$FreeBSD$"); 37 38 #include "opt_debug_lockf.h" 39 40 #include <sys/param.h> 41 #include <sys/systm.h> 42 #include <sys/kernel.h> 43 #include <sys/limits.h> 44 #include <sys/lock.h> 45 #include <sys/mount.h> 46 #include <sys/mutex.h> 47 #include <sys/proc.h> 48 #include <sys/unistd.h> 49 #include <sys/vnode.h> 50 #include <sys/malloc.h> 51 #include <sys/fcntl.h> 52 #include <sys/lockf.h> 53 54 /* 55 * This variable controls the maximum number of processes that will 56 * be checked in doing deadlock detection. 57 */ 58 static int maxlockdepth = MAXDEPTH; 59 60 #ifdef LOCKF_DEBUG 61 #include <sys/sysctl.h> 62 63 #include <ufs/ufs/quota.h> 64 #include <ufs/ufs/inode.h> 65 66 67 static int lockf_debug = 0; 68 SYSCTL_INT(_debug, OID_AUTO, lockf_debug, CTLFLAG_RW, &lockf_debug, 0, ""); 69 #endif 70 71 MALLOC_DEFINE(M_LOCKF, "lockf", "Byte-range locking structures"); 72 73 #define NOLOCKF (struct lockf *)0 74 #define SELF 0x1 75 #define OTHERS 0x2 76 static int lf_clearlock(struct lockf *); 77 static int lf_findoverlap(struct lockf *, 78 struct lockf *, int, struct lockf ***, struct lockf **); 79 static struct lockf * 80 lf_getblock(struct lockf *); 81 static int lf_getlock(struct lockf *, struct flock *); 82 static int lf_setlock(struct lockf *); 83 static void lf_split(struct lockf *, struct lockf *); 84 static void lf_wakelock(struct lockf *); 85 86 /* 87 * Advisory record locking support 88 */ 89 int 90 lf_advlock(ap, head, size) 91 struct vop_advlock_args /* { 92 struct vnode *a_vp; 93 caddr_t a_id; 94 int a_op; 95 struct flock *a_fl; 96 int a_flags; 97 } */ *ap; 98 struct lockf **head; 99 u_quad_t size; 100 { 101 register struct flock *fl = ap->a_fl; 102 register struct lockf *lock; 103 off_t start, end, oadd; 104 int error; 105 106 /* 107 * Convert the flock structure into a start and end. 108 */ 109 switch (fl->l_whence) { 110 111 case SEEK_SET: 112 case SEEK_CUR: 113 /* 114 * Caller is responsible for adding any necessary offset 115 * when SEEK_CUR is used. 116 */ 117 start = fl->l_start; 118 break; 119 120 case SEEK_END: 121 if (size > OFF_MAX || 122 (fl->l_start > 0 && size > OFF_MAX - fl->l_start)) 123 return (EOVERFLOW); 124 start = size + fl->l_start; 125 break; 126 127 default: 128 return (EINVAL); 129 } 130 if (start < 0) 131 return (EINVAL); 132 if (fl->l_len < 0) { 133 if (start == 0) 134 return (EINVAL); 135 end = start - 1; 136 start += fl->l_len; 137 if (start < 0) 138 return (EINVAL); 139 } else if (fl->l_len == 0) 140 end = -1; 141 else { 142 oadd = fl->l_len - 1; 143 if (oadd > OFF_MAX - start) 144 return (EOVERFLOW); 145 end = start + oadd; 146 } 147 /* 148 * Avoid the common case of unlocking when inode has no locks. 149 */ 150 if (*head == (struct lockf *)0) { 151 if (ap->a_op != F_SETLK) { 152 fl->l_type = F_UNLCK; 153 return (0); 154 } 155 } 156 /* 157 * Create the lockf structure 158 */ 159 MALLOC(lock, struct lockf *, sizeof *lock, M_LOCKF, M_WAITOK); 160 lock->lf_start = start; 161 lock->lf_end = end; 162 lock->lf_id = ap->a_id; 163 /* 164 * XXX The problem is that VTOI is ufs specific, so it will 165 * break LOCKF_DEBUG for all other FS's other than UFS because 166 * it casts the vnode->data ptr to struct inode *. 167 */ 168 /* lock->lf_inode = VTOI(ap->a_vp); */ 169 lock->lf_inode = (struct inode *)0; 170 lock->lf_type = fl->l_type; 171 lock->lf_head = head; 172 lock->lf_next = (struct lockf *)0; 173 TAILQ_INIT(&lock->lf_blkhd); 174 lock->lf_flags = ap->a_flags; 175 /* 176 * Do the requested operation. 177 */ 178 switch(ap->a_op) { 179 case F_SETLK: 180 return (lf_setlock(lock)); 181 182 case F_UNLCK: 183 error = lf_clearlock(lock); 184 FREE(lock, M_LOCKF); 185 return (error); 186 187 case F_GETLK: 188 error = lf_getlock(lock, fl); 189 FREE(lock, M_LOCKF); 190 return (error); 191 192 default: 193 free(lock, M_LOCKF); 194 return (EINVAL); 195 } 196 /* NOTREACHED */ 197 } 198 199 /* 200 * Set a byte-range lock. 201 */ 202 static int 203 lf_setlock(lock) 204 register struct lockf *lock; 205 { 206 register struct lockf *block; 207 struct lockf **head = lock->lf_head; 208 struct lockf **prev, *overlap, *ltmp; 209 static char lockstr[] = "lockf"; 210 int ovcase, priority, needtolink, error; 211 212 #ifdef LOCKF_DEBUG 213 if (lockf_debug & 1) 214 lf_print("lf_setlock", lock); 215 #endif /* LOCKF_DEBUG */ 216 217 /* 218 * Set the priority 219 */ 220 priority = PLOCK; 221 if (lock->lf_type == F_WRLCK) 222 priority += 4; 223 priority |= PCATCH; 224 /* 225 * Scan lock list for this file looking for locks that would block us. 226 */ 227 while ((block = lf_getblock(lock))) { 228 /* 229 * Free the structure and return if nonblocking. 230 */ 231 if ((lock->lf_flags & F_WAIT) == 0) { 232 FREE(lock, M_LOCKF); 233 return (EAGAIN); 234 } 235 /* 236 * We are blocked. Since flock style locks cover 237 * the whole file, there is no chance for deadlock. 238 * For byte-range locks we must check for deadlock. 239 * 240 * Deadlock detection is done by looking through the 241 * wait channels to see if there are any cycles that 242 * involve us. MAXDEPTH is set just to make sure we 243 * do not go off into neverland. 244 */ 245 if ((lock->lf_flags & F_POSIX) && 246 (block->lf_flags & F_POSIX)) { 247 register struct proc *wproc; 248 struct thread *td; 249 register struct lockf *waitblock; 250 int i = 0; 251 252 /* The block is waiting on something */ 253 /* XXXKSE this is not complete under threads */ 254 wproc = (struct proc *)block->lf_id; 255 mtx_lock_spin(&sched_lock); 256 FOREACH_THREAD_IN_PROC(wproc, td) { 257 while (td->td_wchan && 258 (td->td_wmesg == lockstr) && 259 (i++ < maxlockdepth)) { 260 waitblock = (struct lockf *)td->td_wchan; 261 /* Get the owner of the blocking lock */ 262 waitblock = waitblock->lf_next; 263 if ((waitblock->lf_flags & F_POSIX) == 0) 264 break; 265 wproc = (struct proc *)waitblock->lf_id; 266 if (wproc == (struct proc *)lock->lf_id) { 267 mtx_unlock_spin(&sched_lock); 268 free(lock, M_LOCKF); 269 return (EDEADLK); 270 } 271 } 272 } 273 mtx_unlock_spin(&sched_lock); 274 } 275 /* 276 * For flock type locks, we must first remove 277 * any shared locks that we hold before we sleep 278 * waiting for an exclusive lock. 279 */ 280 if ((lock->lf_flags & F_FLOCK) && 281 lock->lf_type == F_WRLCK) { 282 lock->lf_type = F_UNLCK; 283 (void) lf_clearlock(lock); 284 lock->lf_type = F_WRLCK; 285 } 286 /* 287 * Add our lock to the blocked list and sleep until we're free. 288 * Remember who blocked us (for deadlock detection). 289 */ 290 lock->lf_next = block; 291 TAILQ_INSERT_TAIL(&block->lf_blkhd, lock, lf_block); 292 #ifdef LOCKF_DEBUG 293 if (lockf_debug & 1) { 294 lf_print("lf_setlock: blocking on", block); 295 lf_printlist("lf_setlock", block); 296 } 297 #endif /* LOCKF_DEBUG */ 298 error = tsleep(lock, priority, lockstr, 0); 299 /* 300 * We may have been awakened by a signal and/or by a 301 * debugger continuing us (in which cases we must remove 302 * ourselves from the blocked list) and/or by another 303 * process releasing a lock (in which case we have 304 * already been removed from the blocked list and our 305 * lf_next field set to NOLOCKF). 306 */ 307 if (lock->lf_next) { 308 TAILQ_REMOVE(&lock->lf_next->lf_blkhd, lock, lf_block); 309 lock->lf_next = NOLOCKF; 310 } 311 if (error) { 312 free(lock, M_LOCKF); 313 return (error); 314 } 315 } 316 /* 317 * No blocks!! Add the lock. Note that we will 318 * downgrade or upgrade any overlapping locks this 319 * process already owns. 320 * 321 * Skip over locks owned by other processes. 322 * Handle any locks that overlap and are owned by ourselves. 323 */ 324 prev = head; 325 block = *head; 326 needtolink = 1; 327 for (;;) { 328 ovcase = lf_findoverlap(block, lock, SELF, &prev, &overlap); 329 if (ovcase) 330 block = overlap->lf_next; 331 /* 332 * Six cases: 333 * 0) no overlap 334 * 1) overlap == lock 335 * 2) overlap contains lock 336 * 3) lock contains overlap 337 * 4) overlap starts before lock 338 * 5) overlap ends after lock 339 */ 340 switch (ovcase) { 341 case 0: /* no overlap */ 342 if (needtolink) { 343 *prev = lock; 344 lock->lf_next = overlap; 345 } 346 break; 347 348 case 1: /* overlap == lock */ 349 /* 350 * If downgrading lock, others may be 351 * able to acquire it. 352 */ 353 if (lock->lf_type == F_RDLCK && 354 overlap->lf_type == F_WRLCK) 355 lf_wakelock(overlap); 356 overlap->lf_type = lock->lf_type; 357 FREE(lock, M_LOCKF); 358 lock = overlap; /* for debug output below */ 359 break; 360 361 case 2: /* overlap contains lock */ 362 /* 363 * Check for common starting point and different types. 364 */ 365 if (overlap->lf_type == lock->lf_type) { 366 free(lock, M_LOCKF); 367 lock = overlap; /* for debug output below */ 368 break; 369 } 370 if (overlap->lf_start == lock->lf_start) { 371 *prev = lock; 372 lock->lf_next = overlap; 373 overlap->lf_start = lock->lf_end + 1; 374 } else 375 lf_split(overlap, lock); 376 lf_wakelock(overlap); 377 break; 378 379 case 3: /* lock contains overlap */ 380 /* 381 * If downgrading lock, others may be able to 382 * acquire it, otherwise take the list. 383 */ 384 if (lock->lf_type == F_RDLCK && 385 overlap->lf_type == F_WRLCK) { 386 lf_wakelock(overlap); 387 } else { 388 while (!TAILQ_EMPTY(&overlap->lf_blkhd)) { 389 ltmp = TAILQ_FIRST(&overlap->lf_blkhd); 390 TAILQ_REMOVE(&overlap->lf_blkhd, ltmp, 391 lf_block); 392 TAILQ_INSERT_TAIL(&lock->lf_blkhd, 393 ltmp, lf_block); 394 ltmp->lf_next = lock; 395 } 396 } 397 /* 398 * Add the new lock if necessary and delete the overlap. 399 */ 400 if (needtolink) { 401 *prev = lock; 402 lock->lf_next = overlap->lf_next; 403 prev = &lock->lf_next; 404 needtolink = 0; 405 } else 406 *prev = overlap->lf_next; 407 free(overlap, M_LOCKF); 408 continue; 409 410 case 4: /* overlap starts before lock */ 411 /* 412 * Add lock after overlap on the list. 413 */ 414 lock->lf_next = overlap->lf_next; 415 overlap->lf_next = lock; 416 overlap->lf_end = lock->lf_start - 1; 417 prev = &lock->lf_next; 418 lf_wakelock(overlap); 419 needtolink = 0; 420 continue; 421 422 case 5: /* overlap ends after lock */ 423 /* 424 * Add the new lock before overlap. 425 */ 426 if (needtolink) { 427 *prev = lock; 428 lock->lf_next = overlap; 429 } 430 overlap->lf_start = lock->lf_end + 1; 431 lf_wakelock(overlap); 432 break; 433 } 434 break; 435 } 436 #ifdef LOCKF_DEBUG 437 if (lockf_debug & 1) { 438 lf_print("lf_setlock: got the lock", lock); 439 lf_printlist("lf_setlock", lock); 440 } 441 #endif /* LOCKF_DEBUG */ 442 return (0); 443 } 444 445 /* 446 * Remove a byte-range lock on an inode. 447 * 448 * Generally, find the lock (or an overlap to that lock) 449 * and remove it (or shrink it), then wakeup anyone we can. 450 */ 451 static int 452 lf_clearlock(unlock) 453 register struct lockf *unlock; 454 { 455 struct lockf **head = unlock->lf_head; 456 register struct lockf *lf = *head; 457 struct lockf *overlap, **prev; 458 int ovcase; 459 460 if (lf == NOLOCKF) 461 return (0); 462 #ifdef LOCKF_DEBUG 463 if (unlock->lf_type != F_UNLCK) 464 panic("lf_clearlock: bad type"); 465 if (lockf_debug & 1) 466 lf_print("lf_clearlock", unlock); 467 #endif /* LOCKF_DEBUG */ 468 prev = head; 469 while ((ovcase = lf_findoverlap(lf, unlock, SELF, &prev, &overlap))) { 470 /* 471 * Wakeup the list of locks to be retried. 472 */ 473 lf_wakelock(overlap); 474 475 switch (ovcase) { 476 477 case 1: /* overlap == lock */ 478 *prev = overlap->lf_next; 479 FREE(overlap, M_LOCKF); 480 break; 481 482 case 2: /* overlap contains lock: split it */ 483 if (overlap->lf_start == unlock->lf_start) { 484 overlap->lf_start = unlock->lf_end + 1; 485 break; 486 } 487 lf_split(overlap, unlock); 488 overlap->lf_next = unlock->lf_next; 489 break; 490 491 case 3: /* lock contains overlap */ 492 *prev = overlap->lf_next; 493 lf = overlap->lf_next; 494 free(overlap, M_LOCKF); 495 continue; 496 497 case 4: /* overlap starts before lock */ 498 overlap->lf_end = unlock->lf_start - 1; 499 prev = &overlap->lf_next; 500 lf = overlap->lf_next; 501 continue; 502 503 case 5: /* overlap ends after lock */ 504 overlap->lf_start = unlock->lf_end + 1; 505 break; 506 } 507 break; 508 } 509 #ifdef LOCKF_DEBUG 510 if (lockf_debug & 1) 511 lf_printlist("lf_clearlock", unlock); 512 #endif /* LOCKF_DEBUG */ 513 return (0); 514 } 515 516 /* 517 * Check whether there is a blocking lock, 518 * and if so return its process identifier. 519 */ 520 static int 521 lf_getlock(lock, fl) 522 register struct lockf *lock; 523 register struct flock *fl; 524 { 525 register struct lockf *block; 526 527 #ifdef LOCKF_DEBUG 528 if (lockf_debug & 1) 529 lf_print("lf_getlock", lock); 530 #endif /* LOCKF_DEBUG */ 531 532 if ((block = lf_getblock(lock))) { 533 fl->l_type = block->lf_type; 534 fl->l_whence = SEEK_SET; 535 fl->l_start = block->lf_start; 536 if (block->lf_end == -1) 537 fl->l_len = 0; 538 else 539 fl->l_len = block->lf_end - block->lf_start + 1; 540 if (block->lf_flags & F_POSIX) 541 fl->l_pid = ((struct proc *)(block->lf_id))->p_pid; 542 else 543 fl->l_pid = -1; 544 } else { 545 fl->l_type = F_UNLCK; 546 } 547 return (0); 548 } 549 550 /* 551 * Walk the list of locks for an inode and 552 * return the first blocking lock. 553 */ 554 static struct lockf * 555 lf_getblock(lock) 556 register struct lockf *lock; 557 { 558 struct lockf **prev, *overlap, *lf = *(lock->lf_head); 559 int ovcase; 560 561 prev = lock->lf_head; 562 while ((ovcase = lf_findoverlap(lf, lock, OTHERS, &prev, &overlap))) { 563 /* 564 * We've found an overlap, see if it blocks us 565 */ 566 if ((lock->lf_type == F_WRLCK || overlap->lf_type == F_WRLCK)) 567 return (overlap); 568 /* 569 * Nope, point to the next one on the list and 570 * see if it blocks us 571 */ 572 lf = overlap->lf_next; 573 } 574 return (NOLOCKF); 575 } 576 577 /* 578 * Walk the list of locks for an inode to 579 * find an overlapping lock (if any). 580 * 581 * NOTE: this returns only the FIRST overlapping lock. There 582 * may be more than one. 583 */ 584 static int 585 lf_findoverlap(lf, lock, type, prev, overlap) 586 register struct lockf *lf; 587 struct lockf *lock; 588 int type; 589 struct lockf ***prev; 590 struct lockf **overlap; 591 { 592 off_t start, end; 593 594 *overlap = lf; 595 if (lf == NOLOCKF) 596 return (0); 597 #ifdef LOCKF_DEBUG 598 if (lockf_debug & 2) 599 lf_print("lf_findoverlap: looking for overlap in", lock); 600 #endif /* LOCKF_DEBUG */ 601 start = lock->lf_start; 602 end = lock->lf_end; 603 while (lf != NOLOCKF) { 604 if (((type & SELF) && lf->lf_id != lock->lf_id) || 605 ((type & OTHERS) && lf->lf_id == lock->lf_id)) { 606 *prev = &lf->lf_next; 607 *overlap = lf = lf->lf_next; 608 continue; 609 } 610 #ifdef LOCKF_DEBUG 611 if (lockf_debug & 2) 612 lf_print("\tchecking", lf); 613 #endif /* LOCKF_DEBUG */ 614 /* 615 * OK, check for overlap 616 * 617 * Six cases: 618 * 0) no overlap 619 * 1) overlap == lock 620 * 2) overlap contains lock 621 * 3) lock contains overlap 622 * 4) overlap starts before lock 623 * 5) overlap ends after lock 624 */ 625 if ((lf->lf_end != -1 && start > lf->lf_end) || 626 (end != -1 && lf->lf_start > end)) { 627 /* Case 0 */ 628 #ifdef LOCKF_DEBUG 629 if (lockf_debug & 2) 630 printf("no overlap\n"); 631 #endif /* LOCKF_DEBUG */ 632 if ((type & SELF) && end != -1 && lf->lf_start > end) 633 return (0); 634 *prev = &lf->lf_next; 635 *overlap = lf = lf->lf_next; 636 continue; 637 } 638 if ((lf->lf_start == start) && (lf->lf_end == end)) { 639 /* Case 1 */ 640 #ifdef LOCKF_DEBUG 641 if (lockf_debug & 2) 642 printf("overlap == lock\n"); 643 #endif /* LOCKF_DEBUG */ 644 return (1); 645 } 646 if ((lf->lf_start <= start) && 647 (end != -1) && 648 ((lf->lf_end >= end) || (lf->lf_end == -1))) { 649 /* Case 2 */ 650 #ifdef LOCKF_DEBUG 651 if (lockf_debug & 2) 652 printf("overlap contains lock\n"); 653 #endif /* LOCKF_DEBUG */ 654 return (2); 655 } 656 if (start <= lf->lf_start && 657 (end == -1 || 658 (lf->lf_end != -1 && end >= lf->lf_end))) { 659 /* Case 3 */ 660 #ifdef LOCKF_DEBUG 661 if (lockf_debug & 2) 662 printf("lock contains overlap\n"); 663 #endif /* LOCKF_DEBUG */ 664 return (3); 665 } 666 if ((lf->lf_start < start) && 667 ((lf->lf_end >= start) || (lf->lf_end == -1))) { 668 /* Case 4 */ 669 #ifdef LOCKF_DEBUG 670 if (lockf_debug & 2) 671 printf("overlap starts before lock\n"); 672 #endif /* LOCKF_DEBUG */ 673 return (4); 674 } 675 if ((lf->lf_start > start) && 676 (end != -1) && 677 ((lf->lf_end > end) || (lf->lf_end == -1))) { 678 /* Case 5 */ 679 #ifdef LOCKF_DEBUG 680 if (lockf_debug & 2) 681 printf("overlap ends after lock\n"); 682 #endif /* LOCKF_DEBUG */ 683 return (5); 684 } 685 panic("lf_findoverlap: default"); 686 } 687 return (0); 688 } 689 690 /* 691 * Split a lock and a contained region into 692 * two or three locks as necessary. 693 */ 694 static void 695 lf_split(lock1, lock2) 696 register struct lockf *lock1; 697 register struct lockf *lock2; 698 { 699 register struct lockf *splitlock; 700 701 #ifdef LOCKF_DEBUG 702 if (lockf_debug & 2) { 703 lf_print("lf_split", lock1); 704 lf_print("splitting from", lock2); 705 } 706 #endif /* LOCKF_DEBUG */ 707 /* 708 * Check to see if spliting into only two pieces. 709 */ 710 if (lock1->lf_start == lock2->lf_start) { 711 lock1->lf_start = lock2->lf_end + 1; 712 lock2->lf_next = lock1; 713 return; 714 } 715 if (lock1->lf_end == lock2->lf_end) { 716 lock1->lf_end = lock2->lf_start - 1; 717 lock2->lf_next = lock1->lf_next; 718 lock1->lf_next = lock2; 719 return; 720 } 721 /* 722 * Make a new lock consisting of the last part of 723 * the encompassing lock 724 */ 725 MALLOC(splitlock, struct lockf *, sizeof *splitlock, M_LOCKF, M_WAITOK); 726 bcopy(lock1, splitlock, sizeof *splitlock); 727 splitlock->lf_start = lock2->lf_end + 1; 728 TAILQ_INIT(&splitlock->lf_blkhd); 729 lock1->lf_end = lock2->lf_start - 1; 730 /* 731 * OK, now link it in 732 */ 733 splitlock->lf_next = lock1->lf_next; 734 lock2->lf_next = splitlock; 735 lock1->lf_next = lock2; 736 } 737 738 /* 739 * Wakeup a blocklist 740 */ 741 static void 742 lf_wakelock(listhead) 743 struct lockf *listhead; 744 { 745 register struct lockf *wakelock; 746 747 while (!TAILQ_EMPTY(&listhead->lf_blkhd)) { 748 wakelock = TAILQ_FIRST(&listhead->lf_blkhd); 749 TAILQ_REMOVE(&listhead->lf_blkhd, wakelock, lf_block); 750 wakelock->lf_next = NOLOCKF; 751 #ifdef LOCKF_DEBUG 752 if (lockf_debug & 2) 753 lf_print("lf_wakelock: awakening", wakelock); 754 #endif /* LOCKF_DEBUG */ 755 wakeup(wakelock); 756 } 757 } 758 759 #ifdef LOCKF_DEBUG 760 /* 761 * Print out a lock. 762 */ 763 void 764 lf_print(tag, lock) 765 char *tag; 766 register struct lockf *lock; 767 { 768 769 printf("%s: lock %p for ", tag, (void *)lock); 770 if (lock->lf_flags & F_POSIX) 771 printf("proc %ld", (long)((struct proc *)lock->lf_id)->p_pid); 772 else 773 printf("id %p", (void *)lock->lf_id); 774 if (lock->lf_inode != (struct inode *)0) 775 printf(" in ino %ju on dev <%d, %d>, %s, start %jd, end %jd", 776 (uintmax_t)lock->lf_inode->i_number, 777 major(lock->lf_inode->i_dev), 778 minor(lock->lf_inode->i_dev), 779 lock->lf_type == F_RDLCK ? "shared" : 780 lock->lf_type == F_WRLCK ? "exclusive" : 781 lock->lf_type == F_UNLCK ? "unlock" : "unknown", 782 (intmax_t)lock->lf_start, (intmax_t)lock->lf_end); 783 else 784 printf(" %s, start %jd, end %jd", 785 lock->lf_type == F_RDLCK ? "shared" : 786 lock->lf_type == F_WRLCK ? "exclusive" : 787 lock->lf_type == F_UNLCK ? "unlock" : "unknown", 788 (intmax_t)lock->lf_start, (intmax_t)lock->lf_end); 789 if (!TAILQ_EMPTY(&lock->lf_blkhd)) 790 printf(" block %p\n", (void *)TAILQ_FIRST(&lock->lf_blkhd)); 791 else 792 printf("\n"); 793 } 794 795 void 796 lf_printlist(tag, lock) 797 char *tag; 798 struct lockf *lock; 799 { 800 register struct lockf *lf, *blk; 801 802 if (lock->lf_inode == (struct inode *)0) 803 return; 804 805 printf("%s: Lock list for ino %ju on dev <%d, %d>:\n", 806 tag, (uintmax_t)lock->lf_inode->i_number, 807 major(lock->lf_inode->i_dev), 808 minor(lock->lf_inode->i_dev)); 809 for (lf = lock->lf_inode->i_lockf; lf; lf = lf->lf_next) { 810 printf("\tlock %p for ",(void *)lf); 811 if (lf->lf_flags & F_POSIX) 812 printf("proc %ld", 813 (long)((struct proc *)lf->lf_id)->p_pid); 814 else 815 printf("id %p", (void *)lf->lf_id); 816 printf(", %s, start %jd, end %jd", 817 lf->lf_type == F_RDLCK ? "shared" : 818 lf->lf_type == F_WRLCK ? "exclusive" : 819 lf->lf_type == F_UNLCK ? "unlock" : 820 "unknown", (intmax_t)lf->lf_start, (intmax_t)lf->lf_end); 821 TAILQ_FOREACH(blk, &lf->lf_blkhd, lf_block) { 822 printf("\n\t\tlock request %p for ", (void *)blk); 823 if (blk->lf_flags & F_POSIX) 824 printf("proc %ld", 825 (long)((struct proc *)blk->lf_id)->p_pid); 826 else 827 printf("id %p", (void *)blk->lf_id); 828 printf(", %s, start %jd, end %jd", 829 blk->lf_type == F_RDLCK ? "shared" : 830 blk->lf_type == F_WRLCK ? "exclusive" : 831 blk->lf_type == F_UNLCK ? "unlock" : 832 "unknown", (intmax_t)blk->lf_start, 833 (intmax_t)blk->lf_end); 834 if (!TAILQ_EMPTY(&blk->lf_blkhd)) 835 panic("lf_printlist: bad list"); 836 } 837 printf("\n"); 838 } 839 } 840 #endif /* LOCKF_DEBUG */ 841