From 3f53a96a8bd0cd4a18f819b6857e6a764706ede5 Mon Sep 17 00:00:00 2001 From: Filipe David Manana Date: Thu, 22 Apr 2010 23:40:26 +0100 Subject: Add file:datasync/1 for syncing file contents only file:datasync/1 invokes the POSIX system call "int fdatasync(int fd)". This system call is similar to "fsync" but, unlike fsync, it does not update the metadata associated with the file (like the access time for example). It's used by many DBMSs (MySQL and SQLite of example) to increase disk IO performance, as it avoids disk seeks and disk write operations compared to fsync. More details on it at: http://linux.die.net/man/2/fdatasync An example, from the MySQL source: http://bazaar.launchpad.net/~mysql/mysql-server/mysql-5.1-telco-6.1/annotate/head%3A/mysys/my_sync.c#L61 This new function just calls fsync on systems not implementing fdatasync. --- erts/preloaded/src/prim_file.erl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'erts/preloaded/src') diff --git a/erts/preloaded/src/prim_file.erl b/erts/preloaded/src/prim_file.erl index 43e6f6cd88..53c741e66e 100644 --- a/erts/preloaded/src/prim_file.erl +++ b/erts/preloaded/src/prim_file.erl @@ -25,7 +25,7 @@ %%% Interface towards a single file's contents. Uses ?FD_DRV. %% Generic file contents operations --export([open/2, close/1, sync/1, position/2, truncate/1, +-export([open/2, close/1, datasync/1, sync/1, position/2, truncate/1, write/2, pwrite/2, pwrite/3, read/2, read_line/1, pread/2, pread/3, copy/3]). %% Specialized file operations @@ -96,6 +96,7 @@ -define(FILE_IPREAD, 27). -define(FILE_ALTNAME, 28). -define(FILE_READ_LINE, 29). +-define(FILE_FDATASYNC, 30). %% Driver responses -define(FILE_RESP_OK, 0). @@ -292,6 +293,9 @@ pwrite(#file_descriptor{module = ?MODULE}, _, _) -> {error, badarg}. +%% Returns {error, Reason} | ok. +datasync(#file_descriptor{module = ?MODULE, data = {Port, _}}) -> + drv_command(Port, [?FILE_FDATASYNC]). %% Returns {error, Reason} | ok. sync(#file_descriptor{module = ?MODULE, data = {Port, _}}) -> -- cgit v1.2.3 From 21a67b797e40df930b83bd407ffc165b3f4b91b2 Mon Sep 17 00:00:00 2001 From: Filipe David Manana Date: Mon, 26 Apr 2010 13:04:40 +0200 Subject: Add file:advise/4 - a wrapper to the POSIX syscall posix_fadvise Useful for informing the Operating System about the access pattern for a file's data, so that it can adapt the caching strategy to maximize disk IO performance. --- erts/preloaded/src/prim_file.erl | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) (limited to 'erts/preloaded/src') diff --git a/erts/preloaded/src/prim_file.erl b/erts/preloaded/src/prim_file.erl index 53c741e66e..e9df5752ab 100644 --- a/erts/preloaded/src/prim_file.erl +++ b/erts/preloaded/src/prim_file.erl @@ -25,7 +25,7 @@ %%% Interface towards a single file's contents. Uses ?FD_DRV. %% Generic file contents operations --export([open/2, close/1, datasync/1, sync/1, position/2, truncate/1, +-export([open/2, close/1, datasync/1, sync/1, advise/4, position/2, truncate/1, write/2, pwrite/2, pwrite/3, read/2, read_line/1, pread/2, pread/3, copy/3]). %% Specialized file operations @@ -97,6 +97,7 @@ -define(FILE_ALTNAME, 28). -define(FILE_READ_LINE, 29). -define(FILE_FDATASYNC, 30). +-define(FILE_ADVISE, 31). %% Driver responses -define(FILE_RESP_OK, 0). @@ -131,6 +132,13 @@ %% IPREAD variants -define(IPREAD_S32BU_P32BU, 0). +%% POSIX file advises +-define(POSIX_FADV_NORMAL, 0). +-define(POSIX_FADV_RANDOM, 1). +-define(POSIX_FADV_SEQUENTIAL, 2). +-define(POSIX_FADV_WILLNEED, 3). +-define(POSIX_FADV_DONTNEED, 4). +-define(POSIX_FADV_NOREUSE, 5). %%%----------------------------------------------------------------- @@ -221,7 +229,35 @@ close(#file_descriptor{module = ?MODULE, data = {Port, _}}) -> close(Port) when is_port(Port) -> drv_close(Port). +-define(ADVISE(Offs, Len, Adv), + <>). +%% Returns {error, Reason} | ok. +advise(#file_descriptor{module = ?MODULE, data = {Port, _}}, + Offset, Length, Advise) -> + case Advise of + normal -> + Cmd = ?ADVISE(Offset, Length, ?POSIX_FADV_NORMAL), + drv_command(Port, Cmd); + random -> + Cmd = ?ADVISE(Offset, Length, ?POSIX_FADV_RANDOM), + drv_command(Port, Cmd); + sequential -> + Cmd = ?ADVISE(Offset, Length, ?POSIX_FADV_SEQUENTIAL), + drv_command(Port, Cmd); + will_need -> + Cmd = ?ADVISE(Offset, Length, ?POSIX_FADV_WILLNEED), + drv_command(Port, Cmd); + dont_need -> + Cmd = ?ADVISE(Offset, Length, ?POSIX_FADV_DONTNEED), + drv_command(Port, Cmd); + no_reuse -> + Cmd = ?ADVISE(Offset, Length, ?POSIX_FADV_NOREUSE), + drv_command(Port, Cmd); + _ -> + {error, einval} + end. %% Returns {error, Reason} | ok. write(#file_descriptor{module = ?MODULE, data = {Port, _}}, Bytes) -> -- cgit v1.2.3