⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 048_fs_locks_c.html

📁 重读linux 2.4.2o所写的笔记
💻 HTML
📖 第 1 页 / 共 3 页
字号:
  @page {    @top {      content: flow(header);    }    @bottom {      content: flow(footer);    }  }  /* end default print css */ /* custom css *//* end custom css */  /* ui edited css */    body {    font-family: Verdana;        font-size: 10.0pt;    line-height: normal;    background-color: #ffffff;  }    .documentBG {    background-color: #ffffff;  }  /* end ui edited css */</style>   </head>  <body  revision="dcbsxfpf_71f49z6wdg:331">      <div align=center id=bte9>
  <table align=center border=0 cellpadding=0 cellspacing=0 height=5716 id=f4h2 width=800>
    <tbody id=lzoi>
    <tr id=sj:o>
      <td height=5716 id=n5md valign=top width=100%>
        <pre id=sfdi>2008-1-16<br id=vudn><br id=n_4->  在fcntl.c的分析中已经对file lock做了一个概要性质的介绍. 这里简单回顾下. <font color=#3333ff id=use5>linux有两种文件加锁的系统调用:flock, fcntl<br id=r67d>(lockf就是fcntl). <br id=youx>  fcntl默认是</font><font color=#3333ff id=ktfn><span id=ovh3 style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal">Advisory lock. </span><span id=rm22 style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal">Mandatory lock需要以特殊的方式安装文</span></font><font color=#3333ff id=m4gk><span id=aqpj style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal">件系统然</span></font><font color=#3333ff id=f5fh><span id=hd79 style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal">后再把文件的属性改为:</span></font><span id=n53b style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=yekf style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><font color=#3333ff id=c65e>disabling  group  <br id=z1fy>execute + enabling the set-group-ID. 然后使用fcntl加锁后就是Mandatory lock了.<br id=yy1n>  </font></span></span><span id=ju_- style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=l7e6 style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><font color=#3333ff id=o2zk><font color=#000000 id=nfta>flock只容许对整个文件进行加锁,是BSD风格的,和fcntl实现的posix锁都是</font></font></span></span>advisory锁.<span id=cvuc style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=v5zo style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><font color=#3333ff id=vglz><font color=#000000 id=td52>而在在linux内部,posix锁,flock锁和文件<br id=sk0g>lease都是使用 flle_lock来实现的.在浏览这个文件之前,先复习下fcntl这个重要接口:<br id=e_dq><br id=rgvh></font></font></span></span>static long <font color=#000099 id=v3:j><b id=kyfe>do_fcntl</b></font>(unsigned int fd, unsigned int cmd,<br id=np1n>		     unsigned long arg, struct file * filp)<br id=x-2l>{<br id=vzrz>	switch (cmd) {<br id=egnb>	             .....<br id=r6s:>		<b id=jgiy>case F_GETLK</b>: <font color=#3333ff id=yuol><b id=hzpp>/*Posix Lock 操作*/</b></font><br id=dg7->			err = fcntl_getlk(fd, (struct flock *) arg);<br id=ycrd>			break;<br id=wo4u>		<b id=tz.8>case F_SETLK</b>:<br id=o9jh>		<b id=zgc3>case F_SETLKW</b>:<br id=scxh>			err = fcntl_setlk(fd, cmd, (struct flock *) arg);<br id=yjk9>			break;<br id=azmk>		case<font color=#3333ff id=c3j6> F_GETOWN</font>: <font color=#3333ff id=xr3_>/*分析dnotify.c的时候说过,owener用于记录当文件发生变化<br id=tm02>                               需要通知的进程, owener在不同的情景中有不同的用法:<br id=trac>                              <font color=#cc0000 id=er:k> 1. dir notify  2.lease(via fl-&gt;fl_fasync) <br id=ymbg>                               3. fasync (via specific fasync queue)</font><br id=gd2_>                               */</font><br id=cdbj>			err = filp-&gt;f_owner.pid;<br id=tihb>			break;<br id=apol>		case<font color=#3333ff id=gymr> F_SETOWN:</font><br id=upuj>			lock_kernel();<br id=xbp6>			filp-&gt;f_owner.pid = arg;<br id=d86d>			filp-&gt;f_owner.uid = current-&gt;uid;<br id=nh4q>			filp-&gt;f_owner.euid = current-&gt;euid;<br id=gzfv>			err = 0;<br id=b3:2>			if (S_ISSOCK (filp-&gt;f_dentry-&gt;d_inode-&gt;i_mode))<br id=plh7>				err = sock_fcntl (filp, F_SETOWN, arg);<br id=s59b>			unlock_kernel();<br id=w9jx>			break;<br id=jluc>		case <font color=#3333ff id=a3fs>F_GETSIG:</font><br id=d.dd>			err = filp-&gt;f_owner.signum;<br id=tj4y>			break;<br id=j7u3>		case <font color=#3333ff id=g28b>F_SETSIG</font>:<br id=q5su>			/* arg == 0 restores default behaviour. */<br id=x4vh>			if (arg &lt; 0 || arg &gt; _NSIG) {<br id=jb-s>				break;<br id=ukxn>			}<br id=n8mr>			err = 0;<br id=w16q>			filp-&gt;f_owner.signum = arg;<br id=vps_>			break;<br id=tnh->		<font color=#cc33cc id=yvm4>case F_GETLEASE:</font><br id=fquq>			err = fcntl_getlease(filp);<br id=na:d>			break;<br id=vc0r>		<font color=#cc33cc id=yx8.>case F_SETLEASE:</font><br id=hv:_>			err = fcntl_setlease(fd, filp, arg);<br id=icy2>			break;<br id=ne-q>		<font color=#336666 id=ch50>case F_NOTIFY: /*dir notify 通知*/</font><br id=fxqo>			err = fcntl_dirnotify(fd, filp, arg);<br id=l415>			break;<br id=vskk>		...<br id=bw4:>}<br id=pidg><span id=imre style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=p9zt style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><font color=#3333ff id=p8bi><font color=#000000 id=dy7j><br id=gw01>然后看文件的全部函数,可以将其分成几个功能部分:<br id=reyg><br id=er6t>0) </font></font></span></span><span id=vjfe style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=cg-a style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal">struct <font color=#000099 id=s3mv><b id=d28b>file_lock</b></font> 的管理<br id=ss.2></span></span><span id=cnex style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=sc9w style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal">struct <font color=#000099 id=z:_f><b id=tauw>file_lock</b></font> {<br id=gkjg>	struct file_lock *fl_next;	/* singly linked list for this inode:<font color=#3333ff id=n.90>file_lock 在inode上配置</font>*/<br id=hjhj>	struct list_head fl_link;	/* <font color=#3333ff id=a:78>接入全局链表file_lock_list,lease或者file_lock:正在使用</font>*/<br id=l74s>	struct list_head fl_block;	/* <font color=#3333ff id=u3qh>circular list of blocked processes:被block的file_lock(file_lock-&gt;<br id=sm3y>                                           fl_wait才是那个进程)</font> (</span></span><font color=#3333ff id=swym><span id=k:xe style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal">Mandatory or flock)</span></font><span id=lmie style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=bu9h style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal">*/<br id=no9z>	fl_owner_t fl_owner; /*typedef struct files_struct *fl_owner_t;对文件加锁的进程之文件系统接口 */<br id=ucsy>	unsigned int fl_pid; /*对文件加锁的进程的pid*/<br id=hi2w>	wait_queue_head_t fl_wait; /*锁的等待队列:</span></span><font color=#3333ff id=rvx:><span id=aqad style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal">Mandatory 和flock使用,</span></font><span id=inm1 style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=i_qw style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal">*/<br id=vq6l>	struct file *fl_file;/*被加锁的文件*/<br id=fl_y>	unsigned char fl_flags;/* <font color=#cc0000 id=rb1c>FL_POSIX</font> <font color=#ff0000 id=y4bk>FL_FLOCK</font> <strike id=dot8>FL_BROKEN</strike>  FL_ACCESS <strike id=bn:r>FL_LOCKD</strike> <font color=#ff0000 id=pu3y>FL_LEASE</font>*/<br id=weuu>	unsigned char fl_type; /* <font color=#cc0000 id=seuh>F_RDLC F_WRLCK  F_UNLCK</font> */<br id=wu41>       &nbsp;loff_t fl_start;<br id=up95>	loff_t fl_end;<br id=mb2.>       <font color=#3333ff id=r7e0> /*下面三个没啥用, 都是NULL*/</font><br id=hzh6>	void (*fl_notify)(struct file_lock *);	/* unblock callback */  <br id=c:ei>	void (*fl_insert)(struct file_lock *);	/* lock insertion callback */<br id=igse>	void (*fl_remove)(struct file_lock *);	/* lock removal callback */<br id=dtsi><br id=p3hl>	struct fasync_struct *	fl_fasync; /* for <font color=#cc0000 id=jike>lease</font> break notifications */<br id=j3bz><br id=isfl>	union {<br id=blt.>		struct nfs_lock_info	nfs_fl;<br id=c:-s>	} fl_u;<br id=m9vp>};<br id=ilsh>管理比较简单,就是free alloc而已,没有像dentry和inode那样的cache机制了(因为也不把flock写到磁盘的...).再说下file_lock<br id=qsox>的类别: fl_flags指出是那种类型的锁:posix,lease,flock三种,还有access,access是一个临时锁,用于加锁的时候发现有冲突时把<br id=lkxv>access类型的锁(总是posix类型的)挂入冲突链表,而进程是wait在这个access类型的锁的fl_wait上(</span></span><font color=#3333ff id=z22a><span id=q8uc style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal">Mandatory </span></font><span id=saq8 style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=k.nt style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal">).(<font color=#000099 id=wd0_>这个设计需要注<br id=h.vy>意</font>)<br id=bxli>static struct file_lock *<font color=#000066 id=jv-f><b id=v2tv>locks_alloc_lock</b></font>(int account)<br id=r82.>static inline void <font color=#000066 id=lmzr><b id=kxkk>locks_free_lock</b></font>(struct file_lock *fl)<br id=qzrb>void <font color=#000099 id=c3wy><b id=j-vt>locks_init_lock(</b></font>struct file_lock *fl)<br id=qz5v>void <font color=#000099 id=a8ja><b id=uxl1>locks_copy_lock</b></font>(struct file_lock *new, struct file_lock *fl)<br id=w3nz><br id=nfzq></span></span><span id=l.cu style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=j0my style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><font color=#3333ff id=kowh><font color=#000000 id=ro9b>1)Advisoy lock/ Mandatory lock 的实现<br id=ky8u>上面说过advisoy lock有:fcntl实现的posix锁和flock实现的BSD风格的锁. Mandatory锁是posix锁的一种加强形式.开启方式上面也<br id=ls.n>都说过了. 下面几个函数是比较简单几个:<br id=pg93><br id=thxz>static int <font color=#000066 id=xyer><b id=s3o1>assign_type</b></font>(struct file_lock *fl, int type)/*处理fl_type:</font></font></span></span><span id=j57l style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=wy-: style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"> <font color=#cc0000 id=yrn9>F_RDLC F_WRLCK  F_UNLCK</font></span></span><span id=wrqc style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=n7oc style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><font color=#3333ff id=r9oh><font color=#000000 id=xrmu>*/<br id=xynx>static int <font color=#000066 id=mx5h><b id=qf75>flock_to_posix_lock</b></font>(struct file *filp, struct file_lock *fl, struct flock *l)/*把用户传递的l转换成fl*/<br id=zxg5>static int <font color=#000099 id=g5:8><b id=kuuv>flock64_to_posix_lock</b></font>(struct file *filp, struct file_lock *fl,...)/*同上*/<br id=e92v>另外以部分函数实现锁检测,判断是否已经加锁,有没有冲突.从大的模块看去,posix lock, mandatory lock,和flock各有一个函数用<br id=x2bt>于判定锁是否冲突:<br id=ctgk>/*<font color=#cc0000 id=zlz4>这个函数用于posix advisory lock的冲突判定</font>,主要caller:<font color=#000099 id=xh_.><b id=wxjs>posix_lock_file</b></font>,<font color=#000099 id=clz_><b id=oq1w>posix_test_lock</b></font> */<br id=ipa3>static int <font color=#3333ff id=ce-2><b id=oth_>posix_locks_conflict</b></font>(struct file_lock *caller_fl, struct file_lock *sys_fl)<br id=j4fj>{<br id=pe6b>	/* 某一个进程加的锁不会锁定自己*/<br id=jox3>	if (!(sys_fl-&gt;fl_flags &amp; FL_POSIX) ||<br id=r_t0>	    <font color=#006600 id=ijof><b id=o3hy>locks_same_owner</b></font>(caller_fl, sys_fl))<br id=xyrt>		return (0);<br id=stoh>	/* Check whether they overlap */<br id=vdb8>	if (!<font color=#006600 id=c5ik><b id=buad>locks_overlap</b></font>(caller_fl, sys_fl)) <font color=#3333ff id=ifb9>/*如果没有overlap也不冲突(锁定区域不同)*/</font><br id=e7op>		return 0;<br id=etat>	return (<font color=#006600 id=hf18><b id=nvbm>locks_conflict</b></font>(caller_fl, sys_fl)); <font color=#000099 id=c8s.>/*reader不会block reader, writer要block 所有 .....*/</font><br id=uu15>}<br id=rrdz><br id=u321>/*flock 的冲突判定: 唯一caller,<font color=#000099 id=e1gb><b id=lbcs>flock_lock_file</b></font>*/<br id=en8b>static int <font color=#3333ff id=th3n><b id=ijks>flock_locks_conflict</b></font>(struct file_lock *caller_fl, struct file_lock *sys_fl)<br id=mj9i>{<br id=gohs>	<font color=#3333ff id=v:fq>/* flock对同一个filep(比如dup会使用同一个fl_file,即struct file*)不会冲突*/</font><br id=l2yq>	if (!(sys_fl-&gt;fl_flags &amp; FL_FLOCK) ||(caller_fl-&gt;fl_file == sys_fl-&gt;fl_file))<br id=buoi>		return (0);<br id=oa5e>#ifdef MSNFS<br id=khvu>	if ((caller_fl-&gt;fl_type &amp; LOCK_MAND) || (sys_fl-&gt;fl_type &amp; LOCK_MAND))<br id=ssos>		return 0;<br id=re2_>#endif<br id=mszl>	return (<font color=#006600 id=ukq9><b id=lhze>locks_conflict</b></font>(caller_fl, sys_fl)); /*已经看过了*/<br id=yi8y>}<br id=mg-u>/*mandatory lock的冲突判定,用于读写文件时判定mandatory lock,主要caller:<font color=#000099 id=mfcv><b id=pw9w>locks_verify_area</b></font>*/<br id=m-xr>/*只有mandatory性质的锁才会在检测的时候同时等待:强制执行,而flock和posix lock只是加锁的时候才必须等待(读写文件,<br id=il1c>getlk都不用等的*/<br id=soof>int <font color=#3333ff id=l2pu><b id=p410>locks_mandatory_area</b></font>(int read_write, struct inode *inode,struct file *filp, loff_t offset,size_t count)<br id=aj1b>{<br id=lhy4>	struct file_lock *fl;<br id=x3mz>	struct file_lock *new_fl = locks_alloc_lock(0);<br id=qla->	int error;<br id=m42t>/*创建一个access锁,*/<br id=dhzt>....<br id=pt8r>	new_fl-&gt;fl_flags =<font color=#990000 id=mcto> <font color=#cc0000 id=k6vj>FL_POSIX | FL_ACCESS</font></font><font color=#cc0000 id=idn0>;</font><br id=kjkl>	new_fl-&gt;fl_type = (read_write == FLOCK_VERIFY_WRITE) ? F_WRLCK : F_RDLCK;<br id=vn-0>....<br id=s8l5>	error = 0;<br id=iup1>	lock_kernel();<br id=hvoh>repeat:<br id=trtx>	/* 找到冲突的lock,然后block到这个file_lock上:进程wait在new_fl-&gt;fl_wait,new_fl挂入fl-&gt;fl_block链表 */<br id=nkih>	for (fl = inode-&gt;i_flock; fl != NULL; fl = fl-&gt;fl_next) {<br id=o-hv>		if (!(fl-&gt;fl_flags &amp; FL_POSIX))<br id=d9.k>			continue;<br id=j8jz>		if (fl-&gt;fl_start &gt; new_fl-&gt;fl_end)<br id=o:p7>			break;<br id=er_g>		if (<font color=#006600 id=ypw1><b id=kx:n>posix_locks_conflict</b></font>(new_fl, fl)) {<br id=s9om>			error = -EAGAIN;<br id=vc45>			if (filp &amp;&amp; (filp-&gt;f_flags &amp; O_NONBLOCK))<br id=x:8o>				break;<br id=nizg>			error = -EDEADLK;<br id=v4y6>                      	if (<font color=#006600 id=z_qm><b id=swvt>posix_locks_deadlock</b></font>(new_fl, fl)) <font color=#3333ff id=gtj1>/*检测死锁...*/</font><br id=ilmt>				break;<br id=f:ve>	               <font color=#3333ff id=lk7g>/*block on操作同样用于flock和file lease*/<br id=s2cv></font></font></font></span></span><span id=x4w0 style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=hho5 style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><font color=#3333ff id=kxx_><font color=#000000 id=q__:><font color=#3333ff id=fwaz>                       /*</font></font></font></span></span><font color=#3333ff id=wjpv><span id=wnpx style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=c9tu style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal">进程wait在new_fl-&gt;fl_wait,new_fl(access)挂入fl-&gt;fl_block链表</span></span></font><span id=ecvl style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=jwfw style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><font color=#3333ff id=a5x1><font color=#000000 id=v5:z><font color=#3333ff id=jpd4>*/</font></font></font></span></span><span id=t_bz style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=h-6o style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><font color=#3333ff id=lfg2><font color=#000000 id=z8x_><font color=#3333ff id=pfel><br id=r73h></font> 		        error = <font color=#006600 id=a8v9><b id=rvlo>locks_block_on</b></font>(fl, new_fl); </font></font></span></span><span id=w6nr style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=u540 style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><font color=#3333ff id=euj8><font color=#000000 id=n3q4><br id=iwav>			if (error != 0)<br id=sw9w>				break;<br id=mef6>			/*<font color=#990000 id=bemd> 小心对待sleeping问题</font><br id=rgik>			 * If we've been sleeping someone might have<br id=pew6>			 * changed the permissions behind our back.<br id=u-l3>			 */<br id=vdlz>			if ((inode-&gt;i_mode &amp; (S_ISGID | S_IXGRP)) != S_ISGID)<br id=hdld>				break;<br id=mhz.>			goto repeat;<br id=zscp>		}<br id=auye>	}<br id=d_5.>	locks_free_lock(new_fl);<font color=#3333ff id=iw54> /*释放access file lock*/</font><br id=msa0>	unlock_kernel();<br id=r1y6>	return error;<br id=c0-l>}<br id=emwc>然后看看死锁避免算法:<br id=bzxq>static int posix_locks_deadlock(struct file_lock *caller_fl,<br id=n:tq>				struct file_lock *block_fl)<br id=pd75>{<br id=f:vb>	struct list_head *tmp;<br id=xjtd>	fl_owner_t caller_owner, blocked_owner;<br id=vzn2>	unsigned int	 caller_pid, blocked_pid;<br id=y.:d><br id=czk.>	caller_owner = caller_fl-&gt;fl_owner; <font color=#000099 id=mwc9>//caller,比如是进程X试图获得此锁</font><br id=jsxd>	caller_pid = caller_fl-&gt;fl_pid;<br id=ipcb>	blocked_owner = block_fl-&gt;fl_owner;<font color=#000099 id=wlgu> //进程A已经获得此锁了(没有被block)</font><br id=lvt_>	blocked_pid = block_fl-&gt;fl_pid;<br id=qgdc><br id=kdjp>next_task:<br id=sj8j>	if (caller_owner == blocked_owner &amp;&amp; caller_pid == blocked_pid) <font color=#3333ff id=imrs>/*如果X==A,证明A试图再次获取同一个锁,dead!*/</font><br id=m9r4>		return 1;<br id=jlwe>	list_for_each(tmp, &amp;blocked_list) { <font color=#3333ff id=rdtr>/*试图获得此锁的进程不是A,那就看A是否在等待其他锁*/</font><br id=pkpb>		struct file_lock *fl = list_entry(tmp, struct file_lock, fl_link);<br id=yzkm>		if ((fl-&gt;fl_owner == blocked_owner)<br id=b..v>		    &amp;&amp; (fl-&gt;fl_pid == blocked_pid)) {<br id=l5il>			fl = fl-&gt;fl_next;<br id=c.oz>			blocked_owner = fl-&gt;fl_owner; <font color=#3333ff id=u6f->/*A在等待另一个进程B的锁,则其等待进程不能是X....*/</font><br id=zn0c>			blocked_pid = fl-&gt;fl_pid;<br id=l6:x>			goto next_task;<br id=ykrs>		}<br id=awcs>	}<br id=k_pm>	return 0;<br id=hdli>}<br id=wqx->出了上面提到的真正需要等带的情况,还有锁检测,只是看看有没有冲突...<br id=d63q><font color=#000099 id=dkpf><b id=kw3_>posix_test_lock</b></font>(struct file *filp, struct file_lock *fl) <font color=#3366ff id=zt-b>/*posix fcntl getlk使用,返回冲突的fl*/</font><br id=zt5.>int <font color=#000099 id=sggi><b id=o8e7>locks_mandatory_locked</b></font>(struct inode *inode) <font color=#3366ff id=e8xj>/*只看有没有锁,不看锁定哪里,shared mmap互斥用*/</font><br id=johp><br id=b:zw>当文件关闭的时候需要清理locks,这一点上posix lock和flock的清理时机是不同的(具体的函数就不列举了....):<br id=to:k>void <font color=#3333ff id=cmif><b id=w0j4>locks_remove_posix</b></font>(struct file *filp, fl_owner_t owner) <font color=#3333ff id=hnh:>/*posix lock在进程关闭时把本进程加的锁清理掉*/</font><br id=gzx->void <font color=#3333ff id=tkb2><b id=ro:i>locks_remove_flock</b></font>(struct file *filp) <font color=#3366ff id=g7sz>/*而flock只有当os释放文件本身时才会清理(比如dup了,那么原始进程close文<br id=y0ph>件的时候就不能吧flock清理掉*/</font><br id=a-xq><br id=e823>2)posix lock加锁的实现<br id=oog5>就是函数int posix_lock_file,看起来挺长挺繁琐. 这里做一个分析方式的讨论. 首先,posix lock如果是setfl的话先去处理可能的<br id=t_mv>冲突情况,并预先分配好file_lock.然后就是合并操作带来的繁琐操作,合并分两种:<br id=ixzm>   I)类型相同  那么就寻找当前fl中有没有邻接或者包含,只有这种情况才能合并.<br id=a5.z>   I)类型不同  只能合并overlap的fl,newfl把当前的分成两个部分,或者newfl从左边或者从右边覆盖当前fl<br id=ndnh>分析的时候记着画张图,就简单多了. 具体代码就不列举了.<br id=obbm>下面的函数也不再分析或列举.<br id=y2xo>int fcntl_setlk(unsigned int fd, unsigned int cmd, struct flock *l)<br id=vnp1>int fcntl_getlk(unsigned int fd, struct flock *l)<br id=i7b1>static void lock_get_status(char* out, struct file_lock *fl, int id, char *pfx)<br id=sxnz><br id=kclp>注: locks_block_on 和 locks_wake_up_blocks是一对相互呼应的函数.file_lock的等待是这样实现的:(以mandatory为例)<br id=iqj9>分配一个新的file_lock,比如newfl,(mandatory lock将其标记为access类型),如果有冲突发生,将newfl接入冲突的fl值fl_block队<br id=qk6i>列,然后进程是wait在newfl-&gt;fl_wait之上的.<br id=qce9><br id=n7-_></font></font></span></span><span id=jq.t style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=vnxk style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><font color=#3333ff id=vriw><font color=#000000 id=u6vc>3)flock<br id=wpl.></font></font></span></span><span id=j1kf style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=u747 style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><font color=#3333ff id=xfxl><font color=#000000 id=ksuu>flock和posix lock都共享一组机制.看完posix的lock再看flock也就比较容易理解.<br id=c8xj>static inline int <font color=#000099 id=v_mz><b id=w6rz>flock_translate_cmd</b></font>(int cmd) /*simple*/<br id=j380></font></font></span></span><span id=bfis style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=a70t style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><font color=#3333ff id=nz0l><font color=#000000 id=h:bx>static struct file_lock *<font color=#cc0000 id=pk5f><b id=gx_h>flock_make_lock</b></font>(struct file *filp, unsigned int type) /*只针对整个文件*/</font></font></span></span><br id=tot3><span id=c.s. style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=uqom style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><font color=#3333ff id=o1ty><font color=#000000 id=xo3t>asmlinkage long sys_flock(unsigned int fd, unsigned int cmd)/*系统调用接口,*/<br id=ktmn>加锁的过程:(把filep想成是加锁者吧,好理解些)<br id=df2m>  1)如果是unlock,就找到同一个的filep的flock,删除即可. (想象是'filep'发起的lock,一个进程open两次同一个file...)<br id=x1hd>  2)如果是相同的锁, read对read可以成功, r 对w,或者w对w就冲突,见</font></font></span></span><span id=ctaf style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=i2gk style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><font color=#3333ff id=x6x2><font color=#000000 id=r0.f><span id=s.je style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=m2fc style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><font color=#3333ff id=kz0x><font color=#000000 id=cucb><font color=#009900 id=l608><b id=uoev>flock_locks_conflict.<br id=h_60></b></font></font></font></span></span>  3)对同一个filep的flock可能有多个,比如都是read(多次open),</font></font></span></span><span id=mhsp style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=ppr. style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><font color=#3333ff id=qldy><font color=#000000 id=vi3l>如果要加write类型的锁</font></font></span></span><span id=ena7 style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=rezb style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><font color=#3333ff id=ig_7><font color=#000000 id=h2d0>可能需要等待多个flock撤销<br id=njz1><br id=sbqo>static int <font color=#3333ff id=yz39><b id=lmhe>flock_lock_file</b></font>(struct file *filp, unsigned int lock_type,unsigned int wait)/*核心函数*/<br id=fixk>{<br id=fhs8>	struct file_lock *fl;<br id=l17x>	struct file_lock *new_fl = NULL; /*为了使用和posix lock一样的wait机制,总是试图file_lock*/<br id=worj>	struct file_lock **before;<br id=hp7e>	struct inode * inode = filp-&gt;f_dentry-&gt;d_inode;<br id=fcqd>	int error, change;<br id=yq4b>	int unlock = (lock_type == F_UNLCK);<br id=wj94><br id=xr8e>	/*<br id=tj2.>	 * If we need a new lock, get it in advance to avoid races.<br id=qa:->	 */<br id=cbi1>	if (!unlock) { <br id=cwmz>		error = -ENOLCK;<br id=npip>		new_fl =<font color=#009900 id=n-gb><b id=zev_> flock_make_lock</b></font>(filp, lock_type); /*预分配*/<br id=g_sd>		if (!new_fl)<br id=toi4>			return error;<br id=dpwj>	}<br id=nv_p><br id=ig7i>	error = 0;<br id=nae->search: <font color=#3333ff id=f52c>/*search这段保证一个filep只有一个flock存在...*/</font><br id=ppra>	change = 0;<br id=bdhs>	before = &amp;inode-&gt;i_flock;<br id=gm27>	while (((fl = *before) != NULL) &amp;&amp; (fl-&gt;fl_flags &amp; FL_FLOCK)) {<br id=kgqr>		if (filp == fl-&gt;fl_file) {<font color=#cc0000 id=jxv9>/*flock认为是一个filp(而不是进程)来进行加锁*/ </font><br id=evno>			if (lock_type == fl-&gt;fl_type) /*</font></font></span></span><span id=k1.d style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=h8u- style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><font color=#3333ff id=hoku><font color=#000000 id=u1w_><font color=#cc0000 id=ptnw>,如果对dup的fd进行两次加ex锁,那就都会成功....注意了....</font></font></font></span></span><span id=irtk style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=ul11 style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><font color=#3333ff id=o4_t><font color=#000000 id=xo3b>*/<br id=j9v6>				goto out;<br id=u5yo>			change = 1;<br id=ho7h>			break;<br id=irzg>		}<br id=gk9o>		before = &amp;fl-&gt;fl_next;<br id=q79p>	}<br id=tvcg>	/* change means that we are changing the type of an existing lock,<br id=h_bh>	 * or else unlocking it.<br id=kwc2>	 */<br id=xlns>	if (change) {<br id=pc_a>		/* N.B. What if the wait argument is false? */<br id=udn1>	     <font color=#009900 id=zwjp> <b id=gw98>locks_delete_lock</b>(</font>before, !unlock);<font color=#3333ff id=y8mm>/*对同一个filp进行不同种类的加锁,会修改现有的锁类型..注意了....*/</font><br id=p72y><font color=#3333ff id=adnm>	         /*<br id=ymue>		 * If we waited, another lock may have been added ...<br id=j60z>		 */</font><br id=z6qo>		if (!unlock)<br id=i2cb>			goto search;<br id=accx>	}<br id=ybfq>	if (unlock)<br id=j76o>		goto out;<br id=feq2><br id=pdqj>repeat: <font color=#000099 id=adwz>/*这段保证不同的filep之间如果冲突了,就要进行互斥*/</font><br id=rmk7>	for (fl = inode-&gt;i_flock; (fl != NULL) &amp;&amp; (fl-&gt;fl_flags &amp; FL_FLOCK);<br id=kf04>	     fl = fl-&gt;fl_next) {</font></font></span></span><span id=tz3t style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=m4h. style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><font color=#3333ff id=hhmq><font color=#000000 id=l6ve><font color=#3333ff id=bpza>/*flock应用在inode上(物理文件上)*/</font></font></font></span></span><span id=e8.j style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=z_yj style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><font color=#3333ff id=zrnn><font color=#000000 id=a7-6><br id=pxzb>               &nbsp;if (!<font color=#006600 id=ou3w><b id=rybe>flock_locks_conflict</b></font>(new_fl, fl))<br id=qasc>			continue;<br id=q0jn>		error = -EAGAIN;<br id=y8sc>		if (!wait)<br id=mb22>			goto out;<br id=le0x>		error = <font color=#006600 id=kfvz><b id=utc5>locks_block_on</b></font>(fl, new_fl);<br id=rxgv>		if (error != 0)<br id=v:6x>			goto out;<br id=ofu1>		goto repeat;<br id=jn4z>	}<br id=w.s->	<font color=#006600 id=yw11><b id=muku>locks_insert_lock</b></font>(&amp;inode-&gt;i_flock, new_fl);<br id=jl26>	new_fl = NULL;<br id=m03d>	error = 0;<br id=xc_g><br id=s42y>out:<br id=u7lw>	if (new_fl)<br id=fa7i>		locks_free_lock(new_fl);<br id=q:t2>	return error;<br id=u:k5>}<br id=qzqf><br id=zda:>3)file lease<br id=myll>还是看看man怎么说:<br id=c_1y></font></font></span></span>A <span class=highlight2 id=m70d>file</span> <span class=highlight3 id=dood>lease</span> provides a mechanism whereby the process holding the <span class=highlight3 id=howu>lease</span> (the "<span class=highlight3 id=cb2i>lease</span> holder") is notified <br id=r.8y>(via delivery of a signal) when a process (the "<span class=highlight3 id=w6j4>lease</span> breaker") tries to <i id=yzdm><b id=zmci><a href=http://linux.die.net/man/2/open id=wtes rel=nofollow>open</a></b>(2)</i> or <i id=bk63><b id=rs70><a href=http://linux.die.net/man/2/truncate id=wan9>truncate</a></b>(2)</i> that <span class=highlight2 id=zr3m>file</span>.<br id=l._3><span id=ys0s style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=tsua style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><font color=#3333ff id=l0_n><font color=#000000 id=nhpx><br id=e:cf>我能找到的例子是</font></font></span></span> Samba 使用了file lease 来实现一种opportunistic locks (oplocks).具体的file lease也是一个比较隐晦的操作:<br id=ulc.>hold file lease的进程需要主动降级或者删除lease,否则内核会强制的降级或者删除其lease.不知道这样是什么道理....<br id=dmkj>另外看似如果在一个文件上使用了lease,就不能再有flock或者posix lock了(有冲突...很奇怪,file lease的代码假定lease类型的锁必须在<br id=kkdp>inode-&gt;i_flock的第一个上,否则就会有问题....<font color=#3333ff id=t_a4> 好在,linux2.6修正了这个问题</font>...).<br id=q9dc><br id=c9-u><br id=wgzr><span id=jf05 style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=xn:3 style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><font color=#3333ff id=bjk5><font color=#000000 id=r7a2>static int <font color=#000099 id=eq7c><b id=fhnv>lease_alloc</b></font>(struct file *filp, int type, struct file_lock **flp) /*一个类型为FL_LEASE的file lock*/<br id=ubvn>int fcntl_getlease(struct file *filp)<br id=jy8t>{<br id=v-5u>	struct file_lock *fl;<br id=pxfp>	<br id=mu:d>	fl = filp-&gt;f_dentry-&gt;d_inode-&gt;i_flock; <font color=#3333ff id=eyoi>/*从这里看出lease有重大缺陷....linux2.6已经完全不同了...*/</font><br id=widb>	if ((fl == NULL) || ((fl-&gt;fl_flags &amp; FL_LEASE) == 0))<br id=x9qp>		return F_UNLCK;<br id=sm7e>	return fl-&gt;fl_type &amp; ~F_INPROGRESS;<br id=uwpu>}<br id=bt2:>get_lease, linux2.6中更名为 _break_lease,更容易理解些..,这个函数是在open和truncate的时候进行的租约判定:<br id=tw8u>int __get_lease(struct inode *inode, unsigned int mode)<br id=medk>{<br id=j11d>	int error = 0, future;<br id=ipwl>	struct file_lock *new_fl, *flock;<br id=gco:>	struct file_lock *fl;<br id=tofy>	int alloc_err;<br id=mw:c><br id=v:sw>	alloc_err = <font color=#006600 id=r06w><b id=ji:d>lease_alloc</b></font>(NULL, 0, &amp;new_fl); <font color=#3333ff id=j.en>/*类似posix lock 的access,总之用同样的代码...*/</font><br id=w9t6><br id=p947>	lock_kernel();<br id=r530>	flock = inode-&gt;i_flock; <font color=#3333ff id=wfrh>/*认为第一个floc就是FL_LEASE...!!! 2.6中已经修正了.(或者我想错了?!)*/</font><br id=d9q:>	if (flock-&gt;fl_type &amp; F_INPROGRESS) { <font color=#3333ff id=cdxr>/*等待lease的holder解除/降级lease*/</font><br id=lnh:>		if ((mode &amp; O_NONBLOCK)<br id=v7yh>		    || (flock-&gt;fl_owner == current-&gt;files)) { <br id=pv3q>                        /*NONBLOCK好理解,但是自己拥有这个lease的情况约定返回would block?*/<br id=n9tr>                        <font color=#3333ff id=ejn1>/*如果是自己拥有这个lease,就返回would block(RequestComments)*/</font><br id=h30z>			error = -EWOULDBLOCK;<br id=jxw9>			goto out;<br id=zcqj>		}<br id=u7q4>		if (alloc_err != 0) {<br id=da1z>			error = alloc_err;<br id=dlf3>			goto out;<br id=oi1b>		}<br id=dh23>		do {<br id=r.eh>			error = <font color=#006600 id=aj_r><b id=n_8o>locks_block_on</b></font>(flock, new_fl); <font color=#3333ff id=jyr_>/*F_INPROGRESS的情况,等待所有的lease解除*/</font><br id=ikd.>			if (error != 0)<br id=tyk1>				goto out;<br id=kqvi>			flock = inode-&gt;i_flock;<br id=j8k2>			if (!(flock &amp;&amp; (flock-&gt;fl_flags &amp; FL_LEASE)))<font color=#3333ff id=o8b:>/*2.6干净许多,这个操作很tricky*/</font><br id=o4vp>				goto out;<br id=ywpa>		} while (flock-&gt;fl_type &amp; F_INPROGRESS);<br id=e3wz>	}<br id=jnwg>        <font color=#3333ff id=yrrm>/*根据要求的操作,决定lease是降级还是解锁...*/</font><br id=zx_e>	if (mode &amp; FMODE_WRITE) {<br id=hvcu>		/* If we want write access, we have to revoke any lease. */<br id=l7xg>		future = F_UNLCK | F_INPROGRESS;<br id=qyze>	} else if (flock-&gt;fl_type &amp; F_WRLCK) {<br id=t7t_>		/* Downgrade the exclusive lease to a read-only lease. */<br id=g0dp>		future = F_RDLCK | F_INPROGRESS;<br id=dhrp>	} else {<br id=sp6e>		/* the existing lease was read-only, so we can read too. */<br id=izto>		goto out;<br id=pgl_>	}<br id=e5f1><br id=y_8t>	if (alloc_err &amp;&amp; (flock-&gt;fl_owner != current-&gt;files)) {<br id=y9-k>		error = alloc_err;<br id=ngwo>		goto out;<br id=d9jt>	}<br id=qvlp>     <font color=#3333ff id=fki1>   /*降级lease*/</font><br id=u8jc>	fl = flock;<br id=lflc>	do {<br id=u9vz>		fl-&gt;fl_type = future;<br id=w0mz>		fl = fl-&gt;fl_next;<br id=cn_f>	} while (fl != NULL &amp;&amp; (fl-&gt;fl_flags &amp; FL_LEASE));<br id=mn1k><br id=wew7>	<font color=#006600 id=j74q><b id=l1.n>kill_fasync</b></font>(&amp;flock-&gt;fl_fasync, SIGIO, POLL_MSG); <font color=#3333ff id=a7y1>/*通知lease的holder,参考fcntl对fasync的分析*/</font><br id=pc98><br id=tj7h>	if ((mode &amp; O_NONBLOCK) || (flock-&gt;fl_owner == current-&gt;files)) {<br id=w:ix>		error = -EWOULDBLOCK;<br id=o1ck>		goto out;<br id=hnf:>	}<br id=ofir><br id=aijz>	if (lease_break_time &gt; 0)<br id=a3he>		error = lease_break_time * HZ;<br id=qldd>	else<br id=hfdt>		error = 0;<br id=al_a>restart:<br id=fk38>	error = locks_block_on_timeout(flock, new_fl, error); <font color=#000099 id=nbja>/*等待降级!*/</font><br id=j8cv>	if (error == 0) {<br id=j8z6>		/* We timed out.  Unilaterally break the lease. */<br id=h_tr>		<font color=#006600 id=odia><b id=lidw>locks_delete_lock</b></font>(&amp;inode-&gt;i_flock, 0); <font color=#000099 id=fabq>/*超时,强制降级*/</font><br id=vt6o>		printk(KERN_WARNING "lease timed out\n");<br id=gef:>	} else if (error &gt; 0) {<br id=bkif>		flock = inode-&gt;i_flock;<br id=foia>		if (flock &amp;&amp; (flock-&gt;fl_flags &amp; FL_LEASE))<br id=a0wf>			goto restart;<br id=f67->		error = 0;<br id=bfpr>	}<br id=zd76><br id=dx:f>out:<br id=qekn>	unlock_kernel();<br id=sg06>	if (!alloc_err)<br id=fgz4>		locks_free_lock(new_fl);<br id=hdaa>	return error;<br id=mjr0>}<br id=nv72>然后,关于lease,还有一个函数:<br id=dr0j>int fcntl_setlease(unsigned int fd, struct file *filp, long arg)<br id=c7eh><font color=#993399 id=d7ix>强烈建议不要看这个函数了,读一下2.6的对应函数即可,这个实在不是很好.</font><br id=gtel>{<br id=mtzm>        /*sanity check*/	<br id=hkmc><br id=h5vz>	/*<br id=da23>	 * FIXME: What about F_RDLCK and files open for writing?<br id=g6bv>	 */<br id=m:5u>	if ((arg == F_WRLCK)<font color=#663366 id=bvt3> <font color=#cc0000 id=k-ss>/*加write租约要求没有其他人已经打开这个文件(dentry,open一次计数增1)*/</font></font><br id=ix.4>	    &amp;&amp; ((atomic_read(&amp;dentry-&gt;d_count) &gt; 1)<br id=yv1l>		|| (atomic_read(&amp;inode-&gt;i_count) &gt; 1)))<br id=oald>		return -EAGAIN;<br id=xf-h><br id=wt-e>	before = &amp;inode-&gt;i_flock;<br id=jfz.><br id=j5au>	lock_kernel();<br id=zn6d></font></font></span></span><span id=x2hi style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=y0d5 style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><font color=#3333ff id=abl6><font color=#000000 id=fwjn>  <font color=#3333ff id=vmnx>      /*  comments in 2.6<br id=thga>	 * At this point, we know that if there is an exclusive<br id=hx.v>	 * lease on this file, then we hold it on this filp<br id=nbq1>	 * (otherwise our open of this file would have blocked).<br id=xe0r>	 * And if we are trying to acquire an exclusive lease,<br id=ek6j>	 * then the file is not open by anyone (including us)<br id=h5xj>	 * except for this filp.<br id=jgjk>	 */</font></font></font></span></span><br id=lq:1><span id=h:-y style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=ki1o style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><font color=#3333ff id=uceq><font color=#000000 id=zvhm>	while ((fl = *before) != NULL) {<br id=cqdx>		if (fl-&gt;fl_flags != FL_LEASE)<br id=ypfo>			break;<br id=kak6>		if (fl-&gt;fl_file == filp)<br id=h2pm>			my_before = before; /<font color=#3333ff id=mave>*对同一个filp lease几次的话只有最后一个生效,也就是只有一个flock*/</font><br id=bq_n>		else if (fl-&gt;fl_type &amp; F_WRLCK)<br id=fijm>			wrlease_count++;<br id=kta->		else<br id=zm:j>			rdlease_count++;<br id=nf31>		before = &amp;fl-&gt;fl_next;<br id=xg..>	}<br id=z3t8><br id=pokk>	if ((arg == F_RDLCK &amp;&amp; (wrlease_count &gt; 0)) ||<br id=v0kx>	    (arg == F_WRLCK &amp;&amp; ((rdlease_count + wrlease_count) &gt; 0))) {<br id=of98>		error = -EAGAIN;<br id=ebvy>		goto out_unlock;<br id=ju86>	}<br id=q4pn><br id=h66:>	if (my_before != NULL) {</font></font></span></span><span id=n0ra style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=jfsq style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><font color=#3333ff id=r9-t><font color=#000000 id=da10>/<font color=#3333ff id=f9-m>*对同一个filp lease几次的话只有最后一个生效,也就是只有一个flock*/</font></font></font></span></span><span id=vm1u style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><span id=h:vk style="FONT-SIZE:10.5pt; COLOR:#000000; LINE-HEIGHT:normal"><font color=#3333ff id=anpg><font color=#000000 id=awhy><br id=s016>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; error = lease_modify(my_before, arg, fd, filp);<br id=fnb0>		goto out_unlock;<br id=kyqb>	}<br id=ph46><br id=f2v8>............<br id=stu9>	error = lease_alloc(filp, arg, &amp;fl);<br id=fkfx>	if (error)<br id=u:n2>		goto out_unlock;<br id=a5lp><br id=ove->	error = fasync_helper(fd, filp, 1, &amp;fl-&gt;fl_fasync);<br id=t26v>	if (error &lt; 0) {<br id=g.se>		locks_free_lock(fl);<br id=q70y>		goto out_unlock;<br id=nelg>	}<br id=m_5r>..........<br id=yx_l>}<br id=c.du><br id=c.d0>许有未决问题....<br id=jb7p><br id=j2d4>注:略过了对NFS的分析....<br id=z:xb><br id=pnc.></font><br id=i902><br id=k39n><br id=fofe></font></span></span></pre>
      </td>
    </tr>
    </tbody>
  </table>
</div></body></html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -