Skip to content

Commit

Permalink
Merge branch 'fm/file-operations' into dev
Browse files Browse the repository at this point in the history
* fm/file-operations:
  Update preloaded modules
  Add file:advise/4 - a wrapper to the POSIX syscall posix_fadvise
  Add file:datasync/1 for syncing file contents only
  sys.h: Correct the get_int64() macro

OTP-8637 fm/file-operations

The functions file:advise/4 and file:datasync/1 have been added. (Thanks to
Filipe David Manana.)
  • Loading branch information
Erlang/OTP committed May 24, 2010
2 parents 458dcb1 + 329aff8 commit be2ebfd
Show file tree
Hide file tree
Showing 22 changed files with 511 additions and 37 deletions.
7 changes: 7 additions & 0 deletions erts/configure.in
Expand Up @@ -1054,6 +1054,7 @@ fi

AC_SUBST(ERTS_BUILD_SMP_EMU)

AC_CHECK_FUNCS([posix_fadvise])


#
Expand Down Expand Up @@ -1757,6 +1758,12 @@ fi
dnl Need by run_erl.
AC_CHECK_FUNCS([openpty])

dnl fdatasync syscall (Unix only)
AC_CHECK_FUNCS([fdatasync])

dnl Find which C libraries are required to use fdatasync
AC_SEARCH_LIBS(fdatasync, [rt])

dnl ----------------------------------------------------------------------
dnl Checks for features/quirks in the system that affects Erlang.
dnl ----------------------------------------------------------------------
Expand Down
16 changes: 8 additions & 8 deletions erts/emulator/beam/sys.h
Expand Up @@ -1173,14 +1173,14 @@ EXTERN_FUNCTION(void*, sys_calloc2, (Uint, Uint));

/* Standard set of integer macros .. */

#define get_int64(s) ((((unsigned char*) (s))[0] << 56) | \
(((unsigned char*) (s))[1] << 48) | \
(((unsigned char*) (s))[2] << 40) | \
(((unsigned char*) (s))[3] << 32) | \
(((unsigned char*) (s))[4] << 24) | \
(((unsigned char*) (s))[5] << 16) | \
(((unsigned char*) (s))[6] << 8) | \
(((unsigned char*) (s))[7]))
#define get_int64(s) (((Uint64)(((unsigned char*) (s))[0]) << 56) | \
(((Uint64)((unsigned char*) (s))[1]) << 48) | \
(((Uint64)((unsigned char*) (s))[2]) << 40) | \
(((Uint64)((unsigned char*) (s))[3]) << 32) | \
(((Uint64)((unsigned char*) (s))[4]) << 24) | \
(((Uint64)((unsigned char*) (s))[5]) << 16) | \
(((Uint64)((unsigned char*) (s))[6]) << 8) | \
(((Uint64)((unsigned char*) (s))[7])))

#define put_int64(i, s) do {((char*)(s))[0] = (char)((Sint64)(i) >> 56) & 0xff;\
((char*)(s))[1] = (char)((Sint64)(i) >> 48) & 0xff;\
Expand Down
57 changes: 57 additions & 0 deletions erts/emulator/drivers/common/efile_drv.c
Expand Up @@ -53,6 +53,8 @@
#define FILE_IPREAD 27
#define FILE_ALTNAME 28
#define FILE_READ_LINE 29
#define FILE_FDATASYNC 30
#define FILE_FADVISE 31

/* Return codes */

Expand Down Expand Up @@ -357,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];
};
Expand Down Expand Up @@ -883,6 +890,15 @@ static void invoke_chdir(void *data)
invoke_name(data, efile_chdir);
}

static void invoke_fdatasync(void *data)
{
struct t_data *d = (struct t_data *) data;
int fd = (int) d->fd;

d->again = 0;
d->result_ok = efile_fdatasync(&d->errInfo, fd);
}

static void invoke_fsync(void *data)
{
struct t_data *d = (struct t_data *) data;
Expand Down Expand Up @@ -1637,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;
Expand Down Expand Up @@ -1919,12 +1947,14 @@ file_async_ready(ErlDrvData e, ErlDrvThreadData data)
case FILE_RMDIR:
case FILE_CHDIR:
case FILE_DELETE:
case FILE_FDATASYNC:
case FILE_FSYNC:
case FILE_TRUNCATE:
case FILE_LINK:
case FILE_SYMLINK:
case FILE_RENAME:
case FILE_WRITE_INFO:
case FILE_FADVISE:
reply(desc, d->result_ok, &d->errInfo);
free_data(data);
break;
Expand Down Expand Up @@ -2209,6 +2239,18 @@ file_output(ErlDrvData e, char* buf, int count)
goto done;
}

case FILE_FDATASYNC:
{
d = EF_SAFE_ALLOC(sizeof(struct t_data));

d->fd = fd;
d->command = command;
d->invoke = invoke_fdatasync;
d->free = free_data;
d->level = 2;
goto done;
}

case FILE_FSYNC:
{
d = EF_SAFE_ALLOC(sizeof(struct t_data));
Expand Down Expand Up @@ -2332,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;
}

}

/*
Expand Down
13 changes: 8 additions & 5 deletions erts/emulator/drivers/common/erl_efile.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
*
* Copyright Ericsson AB 1997-2009. All Rights Reserved.
*
*
* Copyright Ericsson AB 1997-2010. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
*
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
*
* %CopyrightEnd%
*/
/*
Expand Down Expand Up @@ -126,6 +126,7 @@ int efile_readdir(Efile_error* errInfo, char* name,
int efile_openfile(Efile_error* errInfo, char* name, int flags,
int* pfd, Sint64* pSize);
void efile_closefile(int fd);
int efile_fdatasync(Efile_error* errInfo, int fd);
int efile_fsync(Efile_error* errInfo, int fd);
int efile_fileinfo(Efile_error* errInfo, Efile_info* pInfo,
char *name, int info_for_link);
Expand All @@ -150,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);
17 changes: 17 additions & 0 deletions erts/emulator/drivers/common/ram_file_drv.c
Expand Up @@ -35,6 +35,7 @@
#define RAM_FILE_TRUNCATE 14
#define RAM_FILE_PREAD 17
#define RAM_FILE_PWRITE 18
#define RAM_FILE_FDATASYNC 19

/* other operations */
#define RAM_FILE_GET 30
Expand All @@ -45,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
Expand Down Expand Up @@ -558,6 +561,13 @@ static void rfile_command(ErlDrvData e, char* buf, int count)
numeric_reply(f, 0); /* 0 is not used */
break;

case RAM_FILE_FDATASYNC:
if (f->flags == 0)
error_reply(f, EBADF);
else
reply(f, 1, 0);
break;

case RAM_FILE_FSYNC:
if (f->flags == 0)
error_reply(f, EBADF);
Expand Down Expand Up @@ -685,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.
Expand Down
22 changes: 22 additions & 0 deletions erts/emulator/drivers/unix/unix_efile.c
Expand Up @@ -773,6 +773,17 @@ efile_closefile(int fd)
close(fd);
}

int
efile_fdatasync(Efile_error *errInfo, /* Where to return error codes. */
int fd) /* File descriptor for file to sync data. */
{
#ifdef HAVE_FDATASYNC
return check_error(fdatasync(fd), errInfo);
#else
return efile_fsync(errInfo, fd);
#endif
}

int
efile_fsync(Efile_error *errInfo, /* Where to return error codes. */
int fd) /* File descriptor for file to sync. */
Expand Down Expand Up @@ -1437,3 +1448,14 @@ efile_symlink(Efile_error* errInfo, char* old, char* new)
return check_error(symlink(old, new), errInfo);
#endif
}

int
efile_fadvise(Efile_error* errInfo, int fd, Sint64 offset,
Sint64 length, int advise)
{
#ifdef HAVE_POSIX_FADVISE
return check_error(posix_fadvise(fd, offset, length, advise), errInfo);
#else
return check_error(0, errInfo);
#endif
}
28 changes: 23 additions & 5 deletions erts/emulator/drivers/win32/win_efile.c
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
*
* Copyright Ericsson AB 1997-2009. All Rights Reserved.
*
*
* Copyright Ericsson AB 1997-2010. All Rights Reserved.
*
* The contents of this file are subject to the Erlang Public License,
* Version 1.1, (the "License"); you may not use this file except in
* compliance with the License. You should have received a copy of the
* Erlang Public License along with this software. If not, it can be
* retrieved online at http://www.erlang.org/.
*
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
*
* %CopyrightEnd%
*/
/*
Expand Down Expand Up @@ -763,6 +763,15 @@ int fd; /* File descriptor for file to close. */
CloseHandle((HANDLE) fd);
}

int
efile_fdatasync(errInfo, fd)
Efile_error* errInfo; /* Where to return error codes. */
int fd; /* File descriptor for file to sync. */
{
/* Not available in Windows, just call regular fsync */
return efile_fsync(errInfo, fd);
}

int
efile_fsync(errInfo, fd)
Efile_error* errInfo; /* Where to return error codes. */
Expand Down Expand Up @@ -1424,3 +1433,12 @@ efile_symlink(Efile_error* errInfo, char* old, char* new)
errno = ENOTSUP;
return check_error(-1, errInfo);
}

int
efile_fadvise(Efile_error* errInfo, int fd, Sint64 offset,
Sint64 length, int advise)
{
/* posix_fadvise is not available on Windows, do nothing */
errno = ERROR_SUCCESS;
return check_error(0, errInfo);
}
Binary file modified erts/preloaded/ebin/erl_prim_loader.beam
Binary file not shown.
Binary file modified erts/preloaded/ebin/erlang.beam
Binary file not shown.
Binary file modified erts/preloaded/ebin/init.beam
Binary file not shown.
Binary file modified erts/preloaded/ebin/otp_ring0.beam
Binary file not shown.
Binary file modified erts/preloaded/ebin/prim_file.beam
Binary file not shown.
Binary file modified erts/preloaded/ebin/prim_inet.beam
Binary file not shown.
Binary file modified erts/preloaded/ebin/prim_zip.beam
Binary file not shown.
Binary file modified erts/preloaded/ebin/zlib.beam
Binary file not shown.

0 comments on commit be2ebfd

Please sign in to comment.