.. | .. |
---|
276 | 276 | dprintk("lockd: unlinking block %p...\n", block); |
---|
277 | 277 | |
---|
278 | 278 | /* Remove block from list */ |
---|
279 | | - status = posix_unblock_lock(&block->b_call->a_args.lock.fl); |
---|
| 279 | + status = locks_delete_block(&block->b_call->a_args.lock.fl); |
---|
280 | 280 | nlmsvc_remove_block(block); |
---|
281 | 281 | return status; |
---|
282 | 282 | } |
---|
.. | .. |
---|
332 | 332 | mutex_unlock(&file->f_mutex); |
---|
333 | 333 | } |
---|
334 | 334 | |
---|
| 335 | +static struct nlm_lockowner * |
---|
| 336 | +nlmsvc_get_lockowner(struct nlm_lockowner *lockowner) |
---|
| 337 | +{ |
---|
| 338 | + refcount_inc(&lockowner->count); |
---|
| 339 | + return lockowner; |
---|
| 340 | +} |
---|
| 341 | + |
---|
| 342 | +static void nlmsvc_put_lockowner(struct nlm_lockowner *lockowner) |
---|
| 343 | +{ |
---|
| 344 | + if (!refcount_dec_and_lock(&lockowner->count, &lockowner->host->h_lock)) |
---|
| 345 | + return; |
---|
| 346 | + list_del(&lockowner->list); |
---|
| 347 | + spin_unlock(&lockowner->host->h_lock); |
---|
| 348 | + nlmsvc_release_host(lockowner->host); |
---|
| 349 | + kfree(lockowner); |
---|
| 350 | +} |
---|
| 351 | + |
---|
| 352 | +static struct nlm_lockowner *__nlmsvc_find_lockowner(struct nlm_host *host, pid_t pid) |
---|
| 353 | +{ |
---|
| 354 | + struct nlm_lockowner *lockowner; |
---|
| 355 | + list_for_each_entry(lockowner, &host->h_lockowners, list) { |
---|
| 356 | + if (lockowner->pid != pid) |
---|
| 357 | + continue; |
---|
| 358 | + return nlmsvc_get_lockowner(lockowner); |
---|
| 359 | + } |
---|
| 360 | + return NULL; |
---|
| 361 | +} |
---|
| 362 | + |
---|
| 363 | +static struct nlm_lockowner *nlmsvc_find_lockowner(struct nlm_host *host, pid_t pid) |
---|
| 364 | +{ |
---|
| 365 | + struct nlm_lockowner *res, *new = NULL; |
---|
| 366 | + |
---|
| 367 | + spin_lock(&host->h_lock); |
---|
| 368 | + res = __nlmsvc_find_lockowner(host, pid); |
---|
| 369 | + |
---|
| 370 | + if (res == NULL) { |
---|
| 371 | + spin_unlock(&host->h_lock); |
---|
| 372 | + new = kmalloc(sizeof(*res), GFP_KERNEL); |
---|
| 373 | + spin_lock(&host->h_lock); |
---|
| 374 | + res = __nlmsvc_find_lockowner(host, pid); |
---|
| 375 | + if (res == NULL && new != NULL) { |
---|
| 376 | + res = new; |
---|
| 377 | + /* fs/locks.c will manage the refcount through lock_ops */ |
---|
| 378 | + refcount_set(&new->count, 1); |
---|
| 379 | + new->pid = pid; |
---|
| 380 | + new->host = nlm_get_host(host); |
---|
| 381 | + list_add(&new->list, &host->h_lockowners); |
---|
| 382 | + new = NULL; |
---|
| 383 | + } |
---|
| 384 | + } |
---|
| 385 | + |
---|
| 386 | + spin_unlock(&host->h_lock); |
---|
| 387 | + kfree(new); |
---|
| 388 | + return res; |
---|
| 389 | +} |
---|
| 390 | + |
---|
| 391 | +void |
---|
| 392 | +nlmsvc_release_lockowner(struct nlm_lock *lock) |
---|
| 393 | +{ |
---|
| 394 | + if (lock->fl.fl_owner) |
---|
| 395 | + nlmsvc_put_lockowner(lock->fl.fl_owner); |
---|
| 396 | +} |
---|
| 397 | + |
---|
| 398 | +void nlmsvc_locks_init_private(struct file_lock *fl, struct nlm_host *host, |
---|
| 399 | + pid_t pid) |
---|
| 400 | +{ |
---|
| 401 | + fl->fl_owner = nlmsvc_find_lockowner(host, pid); |
---|
| 402 | +} |
---|
| 403 | + |
---|
335 | 404 | /* |
---|
336 | 405 | * Initialize arguments for GRANTED call. The nlm_rqst structure |
---|
337 | 406 | * has been cleared already. |
---|
.. | .. |
---|
345 | 414 | |
---|
346 | 415 | /* set default data area */ |
---|
347 | 416 | call->a_args.lock.oh.data = call->a_owner; |
---|
348 | | - call->a_args.lock.svid = lock->fl.fl_pid; |
---|
| 417 | + call->a_args.lock.svid = ((struct nlm_lockowner *)lock->fl.fl_owner)->pid; |
---|
349 | 418 | |
---|
350 | 419 | if (lock->oh.len > NLMCLNT_OHSIZE) { |
---|
351 | 420 | void *data = kmalloc(lock->oh.len, GFP_KERNEL); |
---|
.. | .. |
---|
509 | 578 | { |
---|
510 | 579 | int error; |
---|
511 | 580 | __be32 ret; |
---|
| 581 | + struct nlm_lockowner *test_owner; |
---|
512 | 582 | |
---|
513 | 583 | dprintk("lockd: nlmsvc_testlock(%s/%ld, ty=%d, %Ld-%Ld)\n", |
---|
514 | 584 | locks_inode(file->f_file)->i_sb->s_id, |
---|
.. | .. |
---|
521 | 591 | ret = nlm_lck_denied_grace_period; |
---|
522 | 592 | goto out; |
---|
523 | 593 | } |
---|
| 594 | + |
---|
| 595 | + /* If there's a conflicting lock, remember to clean up the test lock */ |
---|
| 596 | + test_owner = (struct nlm_lockowner *)lock->fl.fl_owner; |
---|
524 | 597 | |
---|
525 | 598 | error = vfs_test_lock(file->f_file, &lock->fl); |
---|
526 | 599 | if (error) { |
---|
.. | .. |
---|
548 | 621 | conflock->fl.fl_start = lock->fl.fl_start; |
---|
549 | 622 | conflock->fl.fl_end = lock->fl.fl_end; |
---|
550 | 623 | locks_release_private(&lock->fl); |
---|
| 624 | + |
---|
| 625 | + /* Clean up the test lock */ |
---|
| 626 | + lock->fl.fl_owner = NULL; |
---|
| 627 | + nlmsvc_put_lockowner(test_owner); |
---|
| 628 | + |
---|
551 | 629 | ret = nlm_lck_denied; |
---|
552 | 630 | out: |
---|
553 | 631 | return ret; |
---|
.. | .. |
---|
692 | 770 | printk(KERN_WARNING "lockd: notification for unknown block!\n"); |
---|
693 | 771 | } |
---|
694 | 772 | |
---|
695 | | -static int nlmsvc_same_owner(struct file_lock *fl1, struct file_lock *fl2) |
---|
| 773 | +static fl_owner_t nlmsvc_get_owner(fl_owner_t owner) |
---|
696 | 774 | { |
---|
697 | | - return fl1->fl_owner == fl2->fl_owner && fl1->fl_pid == fl2->fl_pid; |
---|
| 775 | + return nlmsvc_get_lockowner(owner); |
---|
698 | 776 | } |
---|
699 | 777 | |
---|
700 | | -/* |
---|
701 | | - * Since NLM uses two "keys" for tracking locks, we need to hash them down |
---|
702 | | - * to one for the blocked_hash. Here, we're just xor'ing the host address |
---|
703 | | - * with the pid in order to create a key value for picking a hash bucket. |
---|
704 | | - */ |
---|
705 | | -static unsigned long |
---|
706 | | -nlmsvc_owner_key(struct file_lock *fl) |
---|
| 778 | +static void nlmsvc_put_owner(fl_owner_t owner) |
---|
707 | 779 | { |
---|
708 | | - return (unsigned long)fl->fl_owner ^ (unsigned long)fl->fl_pid; |
---|
| 780 | + nlmsvc_put_lockowner(owner); |
---|
709 | 781 | } |
---|
710 | 782 | |
---|
711 | 783 | const struct lock_manager_operations nlmsvc_lock_operations = { |
---|
712 | | - .lm_compare_owner = nlmsvc_same_owner, |
---|
713 | | - .lm_owner_key = nlmsvc_owner_key, |
---|
714 | 784 | .lm_notify = nlmsvc_notify_blocked, |
---|
715 | 785 | .lm_grant = nlmsvc_grant_deferred, |
---|
| 786 | + .lm_get_owner = nlmsvc_get_owner, |
---|
| 787 | + .lm_put_owner = nlmsvc_put_owner, |
---|
716 | 788 | }; |
---|
717 | 789 | |
---|
718 | 790 | /* |
---|