文件解锁是加锁的反操作,当处理完毕后应该尽量赶快解锁,避免影响其他用户访问文件。NFS中与文件解锁相关的操作有两个:LOCKU和RELEASE_LOCKOWNER。LOCKU的作用是解锁,RELEASE_LOCKOWNER的作用是释放stateid。
LOCKU客户端程序
客户端处理LOCKU请求的函数是nfs4_proc_unlck(),这个函数最终调用了nfs4_do_unlck(),这个函数负责创建一个RPC任务,根据文件锁的信息初始化RPC请求报文,然后向服务器发送请求,代码如下:
static struct rpc_task *nfs4_do_unlck(struct file_lock *fl,
struct nfs_open_context *ctx,
struct nfs4_lock_state *lsp,
struct nfs_seqid *seqid)
{
struct nfs4_unlockdata *data;
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOCKU],
.rpc_cred = ctx->cred,
};
struct rpc_task_setup task_setup_data = {
.rpc_client = NFS_CLIENT(lsp->ls_state->inode),
.rpc_message = &msg,
.callback_ops = &nfs4_locku_ops,
.workqueue = nfsiod_workqueue,
.flags = RPC_TASK_ASYNC,
};
/* Ensure this is an unlock - when canceling a lock, the
* canceled lock is passed in, and it won't be an unlock.
*/
fl->fl_type = F_UNLCK; // 文件锁操作是F_UNLCK
// 创建一个新的nfs4_unlockdata结构,初始化LOCKU请求的参数信息
data = nfs4_alloc_unlockdata(fl, ctx, lsp, seqid);
if (data == NULL) {
nfs_free_seqid(seqid);
return ERR_PTR(-ENOMEM);
}
nfs41_init_sequence(&data->arg.seq_args, &data->res.seq_res, 1);
msg.rpc_argp = &data->arg;
msg.rpc_resp = &data->res;
task_setup_data.callback_data = data;
return rpc_run_task(&task_setup_data); // 创建一个RPC任务,发送RPC请求.
}
<