Skip to content

unix: treat futimens() as best-effort in copyfile#5053

Merged
saghul merged 1 commit into
libuv:v1.xfrom
skooch:fix-copyfile-cifs-futimens
Apr 17, 2026
Merged

unix: treat futimens() as best-effort in copyfile#5053
saghul merged 1 commit into
libuv:v1.xfrom
skooch:fix-copyfile-cifs-futimens

Conversation

@skooch

@skooch skooch commented Mar 11, 2026

Copy link
Copy Markdown
Contributor

futimens() in uv__fs_copyfile() fails with EPERM on CIFS/SMB
mounts as these filesystems don't support setting timestamps. This
causes uv_fs_copyfile() to fail when copying files to CIFS shares.

Since timestamp preservation during copy is best-effort (same as
fchown() in the same function), ignore the return value
unconditionally rather than failing the entire copy.

Reproducer: mount a CIFS share in a Linux container and call
uv_fs_copyfile() to copy a file from local disk to the share.

Fixes: nodejs/node#56248
Refs: #4396

Comment thread src/unix/fs.c Outdated
@skooch
skooch force-pushed the fix-copyfile-cifs-futimens branch from 2f65b5f to 498579e Compare March 11, 2026 23:25
@saghul
saghul force-pushed the fix-copyfile-cifs-futimens branch from 498579e to 2681bf0 Compare March 12, 2026 12:57

@santigimeno santigimeno left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not blocking this but I was wondering if preserving timestamps is best effort, why don't just simply ignore whether futimens() fails or not.

@bnoordhuis

Copy link
Copy Markdown
Member

Santi has a good point.

@skooch

skooch commented Mar 27, 2026

Copy link
Copy Markdown
Contributor Author

I did think about ignoring futimens() failures unconditionally, but there are a few errors that probably still warrant surfacing e.g. EBADF.

Other options I can think of (other than the current approach) are:

  1. Squelch EPERM unconditionally, drop the uv__is_cifs_or_smb() check but still only ignore EPERM which covers any filesystem that rejects timestamp changes, not just CIFS/SMB.
  2. Ignore all futimens() errors as you say, treat timestamps as fully best-effort, same as fchown() (line 1349).

I'm happy to go with any of these but as I'm a new contributor I'd appreciate your guidance. Thank you! :)

@santigimeno

Copy link
Copy Markdown
Member

I did think about ignoring futimens() failures unconditionally, but there are a few errors that probably still warrant surfacing e.g. EBADF.

It that's the case, next syscalls on the same fd will fail, won't they?

2. Ignore all futimens() errors as you say, treat timestamps as fully best-effort, same as `fchown()` (line 1349).

Yes, I would go this route.

futimens() may fail with EPERM on CIFS/SMB shares that do not
support setting timestamps. Since preserving timestamps during
copyfile is best-effort, ignore the return value unconditionally.

Fixes: nodejs/node#56248
Refs: libuv#4396
@skooch
skooch force-pushed the fix-copyfile-cifs-futimens branch from 2681bf0 to 94c5b04 Compare April 15, 2026 12:47
@skooch skooch changed the title unix: squelch futimens() EPERM on CIFS/SMB shares in copyfile unix: treat futimens() as best-effort in copyfile Apr 15, 2026
@skooch

skooch commented Apr 15, 2026

Copy link
Copy Markdown
Contributor Author

@santigimeno I've updated this to reflect your recommended route, I appreciate the assistance.

@skooch

skooch commented Apr 17, 2026

Copy link
Copy Markdown
Contributor Author

@saghul @santigimeno Let me know if there's anything I can do to assist in getting this merged. I'm keen on getting started on back-porting this fix to the affected Node versions for nodejs/node#56248

@saghul
saghul merged commit 439a54b into libuv:v1.x Apr 17, 2026
34 checks passed
@skooch
skooch deleted the fix-copyfile-cifs-futimens branch April 17, 2026 23:04
@skooch

skooch commented Apr 25, 2026

Copy link
Copy Markdown
Contributor Author

If perchance anyone here is also a Node maintainer and would like to review the cherry-pick, that would be much appreciated: nodejs/node#62881

nodejs-github-bot pushed a commit to nodejs/node that referenced this pull request Apr 25, 2026
Original commit message:

    unix: treat futimens() as best-effort in copyfile

    futimens() may fail with EPERM on CIFS/SMB shares that do not
    support setting timestamps. Since preserving timestamps during
    copyfile is best-effort, ignore the return value unconditionally.

    Refs: libuv/libuv#4396

Fixes: #56248
PR-URL: #62881
Refs: libuv/libuv#5053
Refs: libuv/libuv#4396
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: Santiago Gimeno <[email protected]>
aduh95 pushed a commit to nodejs/node that referenced this pull request May 5, 2026
Original commit message:

    unix: treat futimens() as best-effort in copyfile

    futimens() may fail with EPERM on CIFS/SMB shares that do not
    support setting timestamps. Since preserving timestamps during
    copyfile is best-effort, ignore the return value unconditionally.

    Refs: libuv/libuv#4396

Fixes: #56248
PR-URL: #62881
Refs: libuv/libuv#5053
Refs: libuv/libuv#4396
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: Santiago Gimeno <[email protected]>
aduh95 pushed a commit to nodejs/node that referenced this pull request May 7, 2026
Original commit message:

    unix: treat futimens() as best-effort in copyfile

    futimens() may fail with EPERM on CIFS/SMB shares that do not
    support setting timestamps. Since preserving timestamps during
    copyfile is best-effort, ignore the return value unconditionally.

    Refs: libuv/libuv#4396

Fixes: #56248
PR-URL: #62881
Refs: libuv/libuv#5053
Refs: libuv/libuv#4396
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: Santiago Gimeno <[email protected]>
araujogui pushed a commit to araujogui/node that referenced this pull request May 26, 2026
Original commit message:

    unix: treat futimens() as best-effort in copyfile

    futimens() may fail with EPERM on CIFS/SMB shares that do not
    support setting timestamps. Since preserving timestamps during
    copyfile is best-effort, ignore the return value unconditionally.

    Refs: libuv/libuv#4396

Fixes: nodejs#56248
PR-URL: nodejs#62881
Refs: libuv/libuv#5053
Refs: libuv/libuv#4396
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: Santiago Gimeno <[email protected]>
juanarbol pushed a commit to juanarbol/node that referenced this pull request Jul 16, 2026
Original commit message:

    unix: treat futimens() as best-effort in copyfile

    futimens() may fail with EPERM on CIFS/SMB shares that do not
    support setting timestamps. Since preserving timestamps during
    copyfile is best-effort, ignore the return value unconditionally.

    Refs: libuv/libuv#4396

Fixes: nodejs#56248
PR-URL: nodejs#62881
Refs: libuv/libuv#5053
Refs: libuv/libuv#4396
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: Santiago Gimeno <[email protected]>
juanarbol pushed a commit to juanarbol/node that referenced this pull request Jul 16, 2026
Original commit message:

    unix: treat futimens() as best-effort in copyfile

    futimens() may fail with EPERM on CIFS/SMB shares that do not
    support setting timestamps. Since preserving timestamps during
    copyfile is best-effort, ignore the return value unconditionally.

    Refs: libuv/libuv#4396

Fixes: nodejs#56248
PR-URL: nodejs#62881
Refs: libuv/libuv#5053
Refs: libuv/libuv#4396
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: Santiago Gimeno <[email protected]>
juanarbol pushed a commit to juanarbol/node that referenced this pull request Jul 16, 2026
Original commit message:

    unix: treat futimens() as best-effort in copyfile

    futimens() may fail with EPERM on CIFS/SMB shares that do not
    support setting timestamps. Since preserving timestamps during
    copyfile is best-effort, ignore the return value unconditionally.

    Refs: libuv/libuv#4396

Fixes: nodejs#56248
PR-URL: nodejs#62881
Refs: libuv/libuv#5053
Refs: libuv/libuv#4396
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: Santiago Gimeno <[email protected]>
juanarbol pushed a commit to nodejs/node that referenced this pull request Jul 17, 2026
Original commit message:

    unix: treat futimens() as best-effort in copyfile

    futimens() may fail with EPERM on CIFS/SMB shares that do not
    support setting timestamps. Since preserving timestamps during
    copyfile is best-effort, ignore the return value unconditionally.

    Refs: libuv/libuv#4396

Fixes: #56248
PR-URL: #62881
Refs: libuv/libuv#5053
Refs: libuv/libuv#4396
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: Santiago Gimeno <[email protected]>
juanarbol pushed a commit to nodejs/node that referenced this pull request Jul 17, 2026
Original commit message:

    unix: treat futimens() as best-effort in copyfile

    futimens() may fail with EPERM on CIFS/SMB shares that do not
    support setting timestamps. Since preserving timestamps during
    copyfile is best-effort, ignore the return value unconditionally.

    Refs: libuv/libuv#4396

Fixes: #56248
PR-URL: #62881
Refs: libuv/libuv#5053
Refs: libuv/libuv#4396
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: Santiago Gimeno <[email protected]>
juanarbol pushed a commit to nodejs/node that referenced this pull request Jul 19, 2026
Original commit message:

    unix: treat futimens() as best-effort in copyfile

    futimens() may fail with EPERM on CIFS/SMB shares that do not
    support setting timestamps. Since preserving timestamps during
    copyfile is best-effort, ignore the return value unconditionally.

    Refs: libuv/libuv#4396

Fixes: #56248
PR-URL: #62881
Refs: libuv/libuv#5053
Refs: libuv/libuv#4396
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: Santiago Gimeno <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

4 participants