aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/drivers/common
diff options
context:
space:
mode:
authorFilipe David Manana <[email protected]>2010-04-26 13:04:40 +0200
committerRaimo Niskanen <[email protected]>2010-05-20 15:48:17 +0200
commit21a67b797e40df930b83bd407ffc165b3f4b91b2 (patch)
tree268a10e8d1d4cd00c30d3f5ded8f103d9699167a /erts/emulator/drivers/common
parent3f53a96a8bd0cd4a18f819b6857e6a764706ede5 (diff)
downloadotp-21a67b797e40df930b83bd407ffc165b3f4b91b2.tar.gz
otp-21a67b797e40df930b83bd407ffc165b3f4b91b2.tar.bz2
otp-21a67b797e40df930b83bd407ffc165b3f4b91b2.zip
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.
Diffstat (limited to 'erts/emulator/drivers/common')
-rw-r--r--erts/emulator/drivers/common/efile_drv.c34
-rw-r--r--erts/emulator/drivers/common/erl_efile.h2
-rw-r--r--erts/emulator/drivers/common/ram_file_drv.c9
3 files changed, 45 insertions, 0 deletions
diff --git a/erts/emulator/drivers/common/efile_drv.c b/erts/emulator/drivers/common/efile_drv.c
index b64d27de68..60ae4cb108 100644
--- a/erts/emulator/drivers/common/efile_drv.c
+++ b/erts/emulator/drivers/common/efile_drv.c
@@ -54,6 +54,7 @@
#define FILE_ALTNAME 28
#define FILE_READ_LINE 29
#define FILE_FDATASYNC 30
+#define FILE_FADVISE 31
/* Return codes */
@@ -358,6 +359,11 @@ struct t_data
struct t_readdir_buf *first_buf;
struct t_readdir_buf *last_buf;
} read_dir;
+ struct {
+ Sint64 offset;
+ Sint64 length;
+ int advise;
+ } fadvise;
} c;
char b[1];
};
@@ -1647,6 +1653,18 @@ static void invoke_open(void *data)
d->result_ok = status;
}
+static void invoke_fadvise(void *data)
+{
+ struct t_data *d = (struct t_data *) data;
+ int fd = (int) d->fd;
+ off_t offset = (off_t) d->c.fadvise.offset;
+ off_t length = (off_t) d->c.fadvise.length;
+ int advise = (int) d->c.fadvise.advise;
+
+ d->again = 0;
+ d->result_ok = efile_fadvise(&d->errInfo, fd, offset, length, advise);
+}
+
static void free_readdir(void *data)
{
struct t_data *d = (struct t_data *) data;
@@ -1936,6 +1954,7 @@ file_async_ready(ErlDrvData e, ErlDrvThreadData data)
case FILE_SYMLINK:
case FILE_RENAME:
case FILE_WRITE_INFO:
+ case FILE_FADVISE:
reply(desc, d->result_ok, &d->errInfo);
free_data(data);
break;
@@ -2355,6 +2374,21 @@ file_output(ErlDrvData e, char* buf, int count)
goto done;
}
+ case FILE_FADVISE:
+ {
+ d = EF_SAFE_ALLOC(sizeof(struct t_data));
+
+ d->fd = fd;
+ d->command = command;
+ d->invoke = invoke_fadvise;
+ d->free = free_data;
+ d->level = 2;
+ d->c.fadvise.offset = get_int64((uchar*) buf);
+ d->c.fadvise.length = get_int64(((uchar*) buf) + sizeof(Sint64));
+ d->c.fadvise.advise = get_int32(((uchar*) buf) + 2 * sizeof(Sint64));
+ goto done;
+ }
+
}
/*
diff --git a/erts/emulator/drivers/common/erl_efile.h b/erts/emulator/drivers/common/erl_efile.h
index 6821a0e2ee..61684af6c9 100644
--- a/erts/emulator/drivers/common/erl_efile.h
+++ b/erts/emulator/drivers/common/erl_efile.h
@@ -151,3 +151,5 @@ int efile_altname(Efile_error* errInfo, char *name,
int efile_link(Efile_error* errInfo, char* old, char* new);
int efile_symlink(Efile_error* errInfo, char* old, char* new);
int efile_may_openfile(Efile_error* errInfo, char *name);
+int efile_fadvise(Efile_error* errInfo, int fd, Sint64 offset, Sint64 length,
+ int advise);
diff --git a/erts/emulator/drivers/common/ram_file_drv.c b/erts/emulator/drivers/common/ram_file_drv.c
index d4e547ade6..abedcc933a 100644
--- a/erts/emulator/drivers/common/ram_file_drv.c
+++ b/erts/emulator/drivers/common/ram_file_drv.c
@@ -46,6 +46,8 @@
#define RAM_FILE_UUENCODE 35 /* uuencode file */
#define RAM_FILE_UUDECODE 36 /* uudecode file */
#define RAM_FILE_SIZE 37 /* get file size */
+#define RAM_FILE_ADVISE 38 /* predeclare the access
+ * pattern for file data */
/* possible new operations include:
DES_ENCRYPT
DES_DECRYPT
@@ -693,6 +695,13 @@ static void rfile_command(ErlDrvData e, char* buf, int count)
case RAM_FILE_UUDECODE: /* uudecode file */
ram_file_uudecode(f);
break;
+
+ case RAM_FILE_ADVISE:
+ if (f->flags == 0)
+ error_reply(f, EBADF);
+ else
+ reply(f, 1, 0);
+ break;
}
/*
* Ignore anything else -- let the caller hang.