Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 15 Jun 2026 05:27:50 +0000
From:      bugzilla-noreply@freebsd.org
To:        bugs@FreeBSD.org
Subject:   [Bug 296066] macOS vi creates swap files with mode 0 on FreeBSD 15.1 NFSv4 export
Message-ID:  <bug-296066-227@https.bugs.freebsd.org/bugzilla/>

index | next in thread | raw e-mail

https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=296066

            Bug ID: 296066
           Summary: macOS vi creates swap files with mode 0 on FreeBSD
                    15.1 NFSv4 export
           Product: Base System
           Version: 15.1-RELEASE
          Hardware: amd64
                OS: Any
            Status: New
          Severity: Affects Only Me
          Priority: ---
         Component: kern
          Assignee: bugs@FreeBSD.org
          Reporter: freebsd.geography231@slmails.com

Created attachment 271811
  --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=271811&action=edit
Patch to fix the two issues

I've got a macOS 26.5 client mounting a NFSv4 share from a FreeBSD 15.1-RELEASE
server. The exported filesystem is on a ZFS pool. I noticed that on the Mac, if
I try to create a new file with vi, I get the following error:

>>>
E325: ATTENTION
Found a swap file by the name "/Volumes/zraid/.foobar6.swp"
             dated: Fri Jun 12 14:50:49 2026
         [cannot be opened]
While opening file "/Volumes/zraid/foobar6"
      CANNOT BE FOUND
(1) Another program may be editing the same file.  If this is the case,
    be careful not to end up with two different instances of the same
    file when making changes.  Quit, or continue with caution.
(2) An edit session for this file crashed.
    If this is the case, use ":recover" or "vim -r /Volumes/zraid/foobar6"
    to recover the changes (see ":help recovery").
    If you did this already, delete the swap file "/Volumes/zraid/.foobar6.swp"
    to avoid this message.
Swap file "/Volumes/zraid/.foobar6.swp" already exists!
[O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort:
<<<

If I inspect the swap file, I see it has mode 0 permissions:

$ ls -l /Volumes/zraid/.foobar6.swp
----------  1 1001  1001  0 Jun 12 14:50 /Volumes/zraid/.foobar6.swp
$

I am not versed in the NFS protocol, nor in the FreeBSD kernel or C, so I used
AI to help me debug some packet captures and trace the issue in the kernel. It
ultimately identified two separate bugs I was running into, and gave me a patch
to fix both of them, which did indeed resolve the issues I was having.

I generally take AI's conclusions with a grain of salt, but given that it was
correct with a prior FreeBSD bug, and that its patch did fix this issue, I
figure I'd bring it to you all the experts and see if there's anything there.
I've attached the patch for your reference rather than as a proposed fix, since
I imagine you all can do a better one. I'll also include its summary here in
the hope that it is more illuminating:

>>>
Title: nfsrvd_setattr: SETATTR of time_create and BSD file flags fails
non-fatally, leaving swap files with mode 0 on NFSv4 exports

Component: sys/fs/nfsserver/nfs_nfsdserv.c

Affected versions: FreeBSD 15.1-RELEASE (and likely earlier)

# Summary:

When a macOS NFSv4.0 client creates a file using OPEN4_CREATE with EXCLUSIVE4
createmode and then issues a follow-up SETATTR containing mode,
time_access_set, time_modify_set, time_create, archive, and hidden in a single
compound, the FreeBSD NFSv4 server fails the entire SETATTR and reports a
non-OK status to the client. This causes vim (and other applications using the
same open-create pattern) to leave swap files with mode 0 (----------),
triggering spurious E325 ATTENTION warnings on every subsequent open of the
file.

Root cause — two bugs in nfsrvd_setattr():

## Bug 1: NFSATTRBIT_TIMECREATE in SETATTR

nfsrvd_setattr() attempts to set birthtime (va_btime) via nfsvno_setattr() →
VOP_SETATTR() when the client includes time_create in a SETATTR request. On
FreeBSD, birthtime is not settable via VOP_SETATTR — ZFS returns EINVAL
(because AT_XVATTR is set but z_use_fuids is false, or simply because
XAT_CREATETIME is a read-only attribute). This sets nd->nd_repstat before the
mode attribute group is processed, so the mode is never applied and the file
remains at mode 0. The attrsset bitmap in the reply shows only time_access_set
and time_modify_set (the groups that ran before time_create), and the overall
status is NFS4ERR_INVAL.

RFC 7530 does not require servers to support setting time_create via SETATTR.
The correct behavior is to silently treat it as a no-op and report it as
successfully set, consistent with the behavior of Linux nfsd and other NFSv4
server implementations.

## Bug 2: NFSATTRBIT_ARCHIVE/NFSATTRBIT_HIDDEN/NFSATTRBIT_SYSTEM in SETATTR

After Bug 1 is fixed, a second failure surfaces: nfsrvd_setattr() attempts to
set BSD va_flags (via nfsvno_setattr()) when the client includes archive or
hidden in the SETATTR request. On ZFS filesystems that do not support BSD file
flags (including any pool where z_use_fuids is false, such as ZFS pools at
version 1), this call fails and the error is returned as the overall SETATTR
status — even though mode, time_access_set, and time_modify_set have all been
successfully applied. The result is NFS4ERR_IO on the wire, which causes vim to
treat the swap file as unreadable even though its mode is now correct.

These attributes are Windows/HFS+ compatibility metadata with no semantic
equivalent on such filesystems. Failure to set them should be treated as
non-fatal.

# Fix:

Two changes to nfsrvd_setattr() in sys/fs/nfsserver/nfs_nfsdserv.c:

Replace the NFSATTRBIT_TIMECREATE block's nfsvno_setattr() call with an
unconditional success — skip the VOP call entirely and just set the bit in
retbits.

After the NFSATTRBIT_ARCHIVE/HIDDEN/SYSTEM block's nfsvno_setattr() call, clear
nd->nd_repstat if it is non-zero, treating the failure as non-fatal.

# Reproduction:

FreeBSD 15.1-RELEASE server exporting a ZFS filesystem via NFSv4.

macOS client mounting the export via NFSv4.0.

Run vim <file> on the mount. Observe E325 ATTENTION and mode 0 on the .swp
file.

Packet capture confirms the follow-up SETATTR after EXCLUSIVE4 open-create
includes time_create, archive, and hidden, and the server returns a non-OK
status.
<<<

-- 
You are receiving this mail because:
You are the assignee for the bug.

home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-296066-227>