Bug #11675
closedNFSv4 client: Exclusive create should close the file after setattr failure
100%
Description
The following code in nfs4open_otw()
:
1528 if (createmode == EXCLUSIVE4 && 1529 (in_va->va_mask & ~(AT_GID | AT_SIZE))) { ... 1557 e.error = nfs4setattr(vp, in_va, 0, cr, NULL); 1558 if (e.error) { ... 1570 VN_RELE(vp); 1571 (void) nfs4_remove(dvp, file_name, cr, NULL, 0);
is missing an explicit file close right before the VN_RELE()
call at line 1570.
Updated by Marcel Telka almost 3 years ago
Root cause analysis
With the current code when the VN_RELE()
at line 1570 is called the file is still considered as open by the NFSv4 client, because few lines above (at line 1458) an open stream was created. Because of this the nfs4_inactive()
called from VN_RELE()
is unable to consider the associated rnode as free and asynchronous inactive is scheduled by calling nfs4_async_inactive()
at line 4714. The asynchronous inactive just closes all open streams for the file.
In a case the asynchronous inactive (and thus file close) is slow for some reason (busy machine, for example), then nfs4_remove()
at line 1571 is called before the file is closed and its related vnode/rnode pair freed. This will cause that nfs4_remove()
won't remove the file at the NFSv4 server immediately, but rename it to a .nfsXXXXXX
file instead (as it is done with all still open files we need to remove at the NFS client).
The above scenario usually works properly, even with the rename to .nfsXXXXXX
. The only minor drawback of it is that we could end up with one phantom .nfsXXXXXX
file at the server (until it is automatically cleaned up, but it is not a big deal). The real problem happens when the rename to .nfsXXXXXX
fails too. In this case we will end up with phantom file with real name, but with zero size, zero perms and strange time stamp.
This can happen when we do reach ZFS quota at the server and both setattr and rename operations fails with NFS4ERR_DQUOT
, but plain remove would succeed.
To fix this issue we should add explicit (synchronous) file close right before VN_RELE()
at line 1570.
Updated by Marcel Telka almost 3 years ago
Updated by Marcel Telka almost 3 years ago
- Status changed from In Progress to Pending RTI
Updated by Electric Monk almost 3 years ago
- Status changed from Pending RTI to Closed
- % Done changed from 0 to 100
git commit 20f5f9633a7f7a00734c4c03c7c12016e6935b05
commit 20f5f9633a7f7a00734c4c03c7c12016e6935b05 Author: Marcel Telka <marcel@telka.sk> Date: 2019-09-23T18:10:00.000Z 11675 NFSv4 client: Exclusive create should close the file after setattr failure Reviewed by: Andy Fiddaman <omnios@citrus-it.co.uk> Reviewed by: Toomas Soome <tsoome@me.com> Reviewed by: Gordon Ross <Gordon.W.Ross@gmail.com> Reviewed by: Rich Lowe <richlowe@richlowe.net> Reviewed by: Jan Schlien <illumos-bugs@jan-o-sch.net> Approved by: Dan McDonald <danmcd@joyent.com>