文件加锁

本文深入探讨Linux NFS文件系统的文件加锁过程,包括客户端如何通过nfs4_proc_setlk()创建RPC任务来发起LOCK请求,以及服务器端如何使用nfsd4_decode_lock()解析请求并创建或查找nfs4_ol_stateid(lock)结构来设置文件锁。重点介绍了涉及的数据结构如nfs4_lock_state、nfs4_client等,并阐述了处理流程。
摘要由CSDN通过智能技术生成

1.客户端处理程序

    这篇文章中我们讲讲文件锁的加锁过程,首先说说与文件锁相关的数据结构

struct nfs4_lock_state {
        // nfs4_state结构中包含多个nfs4_lock_state结构,这些结构构成了一个链表,
        // ls_locks指向链表中相邻的元素.
        struct list_head        ls_locks;       /* Other lock stateids */
        // 这个nfs4_lock_state结构所属的nfs4_state结构
        struct nfs4_state *     ls_state;       /* Pointer to open state */
// nfs4_lock_state已经初始化完毕了.
#define NFS_LOCK_INITIALIZED 1
        int                     ls_flags;
        // 这个结构保证文件锁操作按顺序进行.
        struct nfs_seqid_counter        ls_seqid;
        nfs4_stateid            ls_stateid;     // 这是服务器返回来的stateid.
        atomic_t                ls_count;       // 这个数据结构的计数.
        struct nfs4_lock_owner  ls_owner;       // 这是这个nfs4_lock_state的名称.
};

    这个数据结构跟LOCK操作相关,Linux中文件锁跟进程有关,不同进程之间的文件锁不能发生冲突,同一个进程可以对文件加多个锁。nfs4_lock_state记录了一个进程中加的所有文件锁的信息。如果用户在同一个进程中调用LOCK多文件加了多个锁,那么每次LOCK结果后都会更新这个数据结构中的值,最主要的是这个数据结构中记录了一个stateid,服务器可以根据这个stateid检查用户对文件的访问权限。

    上一遍文章中讲过,当客户端创建文件锁时会调用nfs4_proc_setlk(),这个函数最终调用了_nfs4_do_setlk(),这个函数也很简单,就是创建了一个RPC任务,根据参数信息填充了RPC请求报文,然后向服务器发起了LOCK请求。所以就不讲解这个函数的处理流程了,我们对比RFC的规定,Linux是如何填充LOCK请求报文的。

static void encode_lock(struct xdr_stream *xdr, const struct nfs_lock_args *args, struct compound_hdr *hdr)
{
        __be32 *p;

        encode_op_hdr(xdr, OP_LOCK, decode_lock_maxsz, hdr);            // 这是LOCK请求编号, 12
        p = reserve_space(xdr, 28);
        // 这是文件锁类型   4字节
        *p++ = cpu_to_be32(nfs4_lock_type(args->fl, args->block));
        // 是否是reclaim文件锁,当服务器重启后客户端需要重新获取文件锁信息,称为reclaim.   4字节
        *p++ = cpu_to_be32(args->reclaim);
        // 这是文件锁在文件中的偏移位置   8字节
        p = xdr_encode_hyper(p, args->fl->fl_start);
        // 这是文件锁长度   8字节
        p = xdr_encode_hyper(p, nfs4_lock_length(args->fl));
        *p = cpu_to_be32(args->new_lock_owner);         // 1    4字节
        // 如果这是进程中第一个文件锁
        if (args->new_lock_owner){
                // 这是OPEN操作的seqid编号
                encode_nfs4_seqid(xdr, args->open_seqid);       // 这是open --> lock --> unlock -->close  这个过程中的编号
                // 这是OPEN操作中的stateid
                encode_nfs4_stateid(xdr, args->open_stateid);   // 文件的stateid.
                // 这是LOCK操作中的seqid编号
                encode_nfs4_seqid(xdr, args->lock_seqid);
                // 这相当于是为这个nfs4_lock_state起的名称
                encode_lockowner(xdr, &args->lock_owner);       // owner
        }
        else {  // 如果不是进程中第一个文件锁
                // 首先编码上次文件锁操作返回的stateid
                encode
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值