mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
pkg/atomicwriter: use sequential file access on Windows
Using sequential file access ([FILE_FLAG_SEQUENTIAL_SCAN]) prevents Windows from aggressively keeping files in the cache, freeing up system memory for other tasks. On Linux, these changes have no effect, as the sequential package use the standard (os.CreateTemp, os.OpenFile) on non-Windows platforms. Refer to the [Win32 API documentation] for details on sequential file access. [Win32 API documentation]: https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea#FILE_FLAG_SEQUENTIAL_SCAN [FILE_FLAG_SEQUENTIAL_SCAN]: https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea#FILE_FLAG_SEQUENTIAL_SCAN Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
@@ -6,6 +6,8 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/moby/sys/sequential"
|
||||
)
|
||||
|
||||
func validateDestination(fileName string) error {
|
||||
@@ -66,6 +68,13 @@ func validateFileMode(mode os.FileMode) error {
|
||||
// temporary file and closing it atomically changes the temporary file to
|
||||
// destination path. Writing and closing concurrently is not allowed.
|
||||
// NOTE: umask is not considered for the file's permissions.
|
||||
//
|
||||
// New uses [sequential.CreateTemp] to use sequential file access on Windows,
|
||||
// avoiding depleting the standby list un-necessarily. On Linux, this equates to
|
||||
// a regular [os.CreateTemp]. Refer to the [Win32 API documentation] for details
|
||||
// on sequential file access.
|
||||
//
|
||||
// [Win32 API documentation]: https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea#FILE_FLAG_SEQUENTIAL_SCAN
|
||||
func New(filename string, perm os.FileMode) (io.WriteCloser, error) {
|
||||
if err := validateDestination(filename); err != nil {
|
||||
return nil, err
|
||||
@@ -75,7 +84,7 @@ func New(filename string, perm os.FileMode) (io.WriteCloser, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
f, err := os.CreateTemp(filepath.Dir(abspath), ".tmp-"+filepath.Base(filename))
|
||||
f, err := sequential.CreateTemp(filepath.Dir(abspath), ".tmp-"+filepath.Base(filename))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -197,8 +206,15 @@ func (w syncFileCloser) Close() error {
|
||||
|
||||
// FileWriter opens a file writer inside the set. The file
|
||||
// should be synced and closed before calling commit.
|
||||
//
|
||||
// FileWriter uses [sequential.OpenFile] to use sequential file access on Windows,
|
||||
// avoiding depleting the standby list un-necessarily. On Linux, this equates to
|
||||
// a regular [os.OpenFile]. Refer to the [Win32 API documentation] for details
|
||||
// on sequential file access.
|
||||
//
|
||||
// [Win32 API documentation]: https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea#FILE_FLAG_SEQUENTIAL_SCAN
|
||||
func (ws *WriteSet) FileWriter(name string, flag int, perm os.FileMode) (io.WriteCloser, error) {
|
||||
f, err := os.OpenFile(filepath.Join(ws.root, name), flag, perm)
|
||||
f, err := sequential.OpenFile(filepath.Join(ws.root, name), flag, perm)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user