NodeJS 哪些操作系统支持写时复制?

gmxoilav  于 2023-06-22  发布在  Node.js
关注(0)|答案(4)|浏览(127)

我尝试在Linux和Windows中运行以下代码:

const fs = require("fs/promises")
const {
    constants,
    existsSync
} = require("fs")

async function copy() {
    try {
        await fs.writeFile("demo.txt", "Hello World")
        await fs.copyFile("demo.txt", "copy.txt", constants.COPYFILE_FICLONE_FORCE)
    } finally {
        fs.rm("demo.txt")
        if (existsSync("copy.txt")) fs.rm("copy.txt")
    }
}

copy().catch(console.error)

两者均失败,错误消息:
Linux:

[Error: ENOTSUP: operation not supported on socket, copyfile 'demo.txt' -> 'copy.txt'] {
  errno: -95,
  code: 'ENOTSUP',
  syscall: 'copyfile',
  path: 'demo.txt',
  dest: 'copy.txt'
}

窗口:

Error: ENOSYS: function not implemented, copyfile 'demo.txt' -> 'copy.txt'] {
  errno: -4054,
  code: 'ENOSYS',
  syscall: 'copyfile',
  path: 'demo.txt',
  dest: 'copy.txt'
}

nodejs的官方文档说
fs.constants.COPYFILE_FICLONE_FORCE:复制操作将尝试创建写时复制重新链接。如果平台不支持写时复制,那么操作将失败。”
大多数服务器操作系统应该是Windows服务器或Linux。
我确信nodejs的开发人员不会开发一个不起作用的特性,所以我想知道在什么平台上可以使用“fs.constants.COPYFILE_FICLONE_FORCE”文件复制方法。达尔文,BSD,还是其他OS?
以下是一些参考信息:

node version: v16.14.2

windows version: windows 10
windows file system: NTFS

linux version: 5.10.109-1-MANJARO
linux core version: 5.10
linux file system: ext4
kqhtkvqz

kqhtkvqz1#

Node.js最初是由Joyent赞助并大量开发的。Joyent也是Illumos(它基于Solaris,Solaris是Sun和后来的Oracle销售的BSD发行版)的忠实支持者。
在早期,node在Illumos上进行了大量测试。还有惊喜。Illumos的默认文件系统是ZFS,它具有写时复制功能。
但是ZFS也可以在其他操作系统上使用(苹果甚至一度为OSX开发了一个官方的ZFS驱动程序),所以如果你使用ZFS之类的东西,你可以在写时复制。我不太确定node的写时复制支持是否适用于其他写时复制文件系统,如Btrfs,但理论上应该是这样。

g52tjvyc

g52tjvyc2#

这是一个非常先进的FS功能。
如果系统上的文件系统支持特定的Activity(COPYFILE_FICLONE_FORCE),则它将工作。否则,它将失败。它只是说没有/自动/回退。
COW就像是让FS创建一个符号链接到你复制的文件,但是如果(并且只有当)你修改了那个文件,它实际上会创建一个“真实的的”副本并应用你的修改。
所以,如果你需要非常/非常/快速地复制一个文件。也许有时(不是所有时候)它可能需要稍后修改,那么这个选项就很有意义。否则,您可能只需要执行一个“常规”拷贝,让文件系统缓存来处理内务。

wd2eg0qa

wd2eg0qa3#

这是一个文件系统特性,不是操作系统。如果文件系统支持它,那么显然您可以直接调用驱动程序函数来执行写时复制操作
但是,如果操作系统支持,当底层也支持CoW,那么它会更容易,因为你可以利用系统调用,将工作在任何CoW文件系统(ZFS,Btrfs,XFS,ReFS,APFS之间的常见操作系统)。由于您使用的是nodejs,因此会有另一个依赖于nodejs实现系统调用的抽象层
如果你使用ext4,那么你就不走运了,因为它不支持CoW。在Linux上,您必须使用具有CoW支持的FS,如ZFSBtrfsXFS。还有一些其他的文件系统支持CoW,比如ext3cowNext3,但是它们已经过时了
在Windows方面,自Windows Server 2016以来,在ReFS上支持copy-on-write。甚至还有一个.NET library来避免直接调用Win32 API。同样,NTFS是不可能的,根本没有CoW支持。不幸的是,到目前为止,nodejs使用的libuv还没有更新到使用Windows CoW API。有一个closed PRs though
在macOS上,您还可以通过APFS获得CoW支持,但不支持HFS或HFS+。看起来libuv也支持macOS

tzcvj98z

tzcvj98z4#

提示是在名称ficlone中,这指的是ioctl_ficlone*系列的系统调用,它最初是Linux btrfs特定内核接口的一部分。
系统调用已经被通用化,并成为Linux通用文件系统接口的一部分,因此其他文件系统驱动程序也可以实现系统调用。我相信XFS也为类似的CoW功能实现了这个系统调用。
ext4和ntfs不支持写时复制,所以如果这是您使用的文件系统,那么使用ficlone创建CoW文件将永远不起作用。
这在Windows上可能也不起作用,因为它们使用完全不同的文件系统接口和完全不同的方式来创建CoW文件。当在ReFS上运行时,该标志可能会被shimmed以执行与Windows Filesystem API等效的功能,但我认为当前版本的nodejs不会这样做。

相关问题