int smb_vop_frlock(vnode_t *vp, cred_t *cr, int flag, flock64_t *bf) { int cmd = nbl_need_check(vp) ? F_SETLK_NBMAND : F_SETLK; flk_callback_t flk_cb; flk_init_callback(&flk_cb, smb_lock_frlock_callback, NULL); return (VOP_FRLOCK(vp, cmd, bf, flag, 0, &flk_cb, cr, &smb_ct)); }
/* * Helper for nlm_do_lock(), partly for observability, * (we'll see a call blocked in this function) and * because nlm_do_lock() was getting quite long. */ static void nlm_block(nlm4_lockargs *lockargs, struct nlm_host *host, struct nlm_vhold *nvp, nlm_rpc_t *rpcp, struct flock64 *flp, nlm_testargs_cb grant_cb) { nlm4_testargs args; int error; flk_callback_t flk_cb; struct nlm_block_cb_data cb_data; /* * Keep a list of blocked locks on nh_pending, and use it * to cancel these threads in nlm_destroy_client_pending. * * Check to see if this lock is already in the list * and if not, add an entry for it. Allocate first, * then if we don't insert, free the new one. * Caller already has vp held. */ error = nlm_slreq_register(host, nvp, flp); if (error != 0) { /* * Sleeping lock request with given fl is already * registered by someone else. This means that * some other thread is handling the request, let * it do its work. */ ASSERT(error == EEXIST); return; } cb_data.hostp = host; cb_data.nvp = nvp; cb_data.flp = flp; flk_init_callback(&flk_cb, nlm_block_callback, &cb_data); /* BSD: VOP_ADVLOCK(vp, NULL, F_SETLK, fl, F_REMOTE); */ error = nlm_vop_frlock(nvp->nv_vp, F_SETLKW, flp, F_REMOTELOCK | FREAD | FWRITE, (u_offset_t)0, &flk_cb, CRED(), NULL); if (error != 0) { /* * We failed getting the lock, but have no way to * tell the client about that. Let 'em time out. */ (void) nlm_slreq_unregister(host, nvp, flp); return; } /* * Do the "granted" call-back to the client. */ args.cookie = lockargs->cookie; args.exclusive = lockargs->exclusive; args.alock = lockargs->alock; NLM_INVOKE_CALLBACK("grant", rpcp, &args, grant_cb); }