Project

General

Profile

Bug #11675

NFSv4 client: Exclusive create should close the file after setattr failure

Added by Marcel Telka about 1 year ago. Updated about 1 year ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
nfs - NFS server and client
Start date:
Due date:
% Done:

100%

Estimated time:
Difficulty:
Medium
Tags:
Gerrit CR:

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.

History

#1

Updated by Marcel Telka about 1 year 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.

#3

Updated by Marcel Telka about 1 year ago

  • Status changed from In Progress to Pending RTI
#4

Updated by Electric Monk about 1 year 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>

Also available in: Atom PDF