/* * Find a block for a given lock and optionally remove it from * the list. */ static struct nlm_block * nlmsvc_lookup_block(struct nlm_file *file, struct nlm_lock *lock, int remove) { struct nlm_block **head, *block; struct file_lock *fl; dprintk("lockd: nlmsvc_lookup_block f=%p pd=%d %Ld-%Ld ty=%d\n", file, lock->fl.fl_pid, (long long)lock->fl.fl_start, (long long)lock->fl.fl_end, lock->fl.fl_type); for (head = &nlm_blocked; (block = *head); head = &block->b_next) { fl = &block->b_call.a_args.lock.fl; dprintk("lockd: check f=%p pd=%d %Ld-%Ld ty=%d cookie=%s\n", block->b_file, fl->fl_pid, (long long)fl->fl_start, (long long)fl->fl_end, fl->fl_type, nlmdbg_cookie2a(&block->b_call.a_args.cookie)); if (block->b_file == file && nlm_compare_locks(fl, &lock->fl)) { if (remove) { *head = block->b_next; block->b_queued = 0; } return block; } } return NULL; }
/* * The server lockd has called us back to tell us the lock was granted */ u32 nlmclnt_grant(struct nlm_lock *lock) { struct nlm_wait *block; /* * Look up blocked request based on arguments. * Warning: must not use cookie to match it! */ for (block = nlm_blocked; block; block = block->b_next) { if (nlm_compare_locks(block->b_lock, &lock->fl)) break; } /* Ooops, no blocked request found. */ if (block == NULL) return nlm_lck_denied; /* Alright, we found the lock. Set the return status and * wake up the caller. */ block->b_status = NLM_LCK_GRANTED; wake_up(&block->b_wait); return nlm_granted; }
static void test_lockd(void){ struct nlm_file file; struct sockaddr_in sin1, sin2; struct file_lock fl1, fl2; nlm_compare_locks(&fl1, &fl2); nlm_cmp_addr(&sin1,&sin2); nlmsvc_file_inode(&file); printk("finished lockd test\n"); }
/* * Unblock a blocked lock request. This is a callback invoked from the * VFS layer when a lock on which we blocked is removed. * * This function doesn't grant the blocked lock instantly, but rather moves * the block to the head of nlm_blocked where it can be picked up by lockd. */ static void nlmsvc_notify_blocked(struct file_lock *fl) { struct nlm_block **bp, *block; dprintk("lockd: VFS unblock notification for block %p\n", fl); for (bp = &nlm_blocked; (block = *bp) != 0; bp = &block->b_next) { if (nlm_compare_locks(&block->b_call.a_args.lock.fl, fl)) { nlmsvc_insert_block(block, 0); svc_wake_up(block->b_daemon); return; } } printk(KERN_WARNING "lockd: notification for unknown block!\n"); }
/* * Find a block for a given lock and optionally remove it from * the list. */ static struct nlm_block * nlmsvc_lookup_block(struct nlm_file *file, struct nlm_lock *lock, int remove) { struct nlm_block **head, *block; struct file_lock *fl; dprintk("lockd: nlmsvc_lookup_block f=%p pd=%d %ld-%ld ty=%d\n", file, lock->fl.fl_pid, lock->fl.fl_start, lock->fl.fl_end, lock->fl.fl_type); for (head = &nlm_blocked; (block = *head); head = &block->b_next) { fl = &block->b_call.a_args.lock.fl; dprintk(" check f=%p pd=%d %ld-%ld ty=%d\n", block->b_file, fl->fl_pid, fl->fl_start, fl->fl_end, fl->fl_type); if (block->b_file == file && nlm_compare_locks(fl, &lock->fl)) { if (remove) *head = block->b_next; return block; } } return NULL; }