summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Cahill <michael.cahill@wiredtiger.com>2011-12-05 12:01:48 +1100
committerMichael Cahill <michael.cahill@wiredtiger.com>2011-12-05 12:01:48 +1100
commit7489bf6901b68469fd1526d6fc2a8fae1996b619 (patch)
tree5ec9061d36673d6a90acad6a33dd6ff4831864dd
parent5fd5e806f4680ee8cea96f27e0c0e37a6c5f87b4 (diff)
downloadmongo-7489bf6901b68469fd1526d6fc2a8fae1996b619.tar.gz
Add support for direct I/O, with the config "direct_io=(data,log)".
--HG-- extra : rebase_source : c9ece039e84f16dcb4cf4fe8419e6de04f970a13
-rw-r--r--dist/api_data.py5
-rw-r--r--src/block/block_open.c6
-rw-r--r--src/config/config_def.c25
-rw-r--r--src/conn/conn_api.c41
-rw-r--r--src/include/api.h3
-rw-r--r--src/include/extern.h3
-rw-r--r--src/include/wiredtiger.in3
-rw-r--r--src/os_posix/os_open.c12
8 files changed, 66 insertions, 32 deletions
diff --git a/dist/api_data.py b/dist/api_data.py
index c3fb21366ba..e689b28446b 100644
--- a/dist/api_data.py
+++ b/dist/api_data.py
@@ -328,6 +328,10 @@ methods = {
Config('create', 'false', r'''
create the database if it does not exist''',
type='boolean'),
+ Config('direct_io', '', r'''
+ Use \c O_DIRECT to access files. Options are given as a
+ list, such as <code>"direct_io=[data]"</code>''',
+ type='list', choices=['data', 'log']),
Config('home_environment', 'false', r'''
use the \c WIREDTIGER_HOME environment variable for naming
unless the process is running with special privileges.
@@ -394,6 +398,7 @@ flags = {
###################################################
# Internal routine flag declarations
###################################################
+ 'direct_io' : [ 'DIRECTIO_DATA', 'DIRECTIO_LOG' ],
'page_free' : [ 'PAGE_FREE_IGNORE_DISK' ],
'rec_evict' : [ 'REC_SINGLE' ],
'verbose' : [
diff --git a/src/block/block_open.c b/src/block/block_open.c
index bdab374ce78..eba5de0c1a7 100644
--- a/src/block/block_open.c
+++ b/src/block/block_open.c
@@ -21,7 +21,7 @@ __wt_block_truncate(WT_SESSION_IMPL *session, const char *filename)
int ret;
/* Open the underlying file handle. */
- WT_RET(__wt_open(session, filename, 0, &fh));
+ WT_RET(__wt_open(session, filename, 0, 1, &fh));
/* Truncate the file. */
WT_ERR(__wt_ftruncate(session, fh, (off_t)0));
@@ -54,7 +54,7 @@ __wt_block_create(WT_SESSION_IMPL *session, const char *filename)
filename);
/* Open the underlying file handle. */
- WT_RET(__wt_open(session, filename, 1, &fh));
+ WT_RET(__wt_open(session, filename, 1, 1, &fh));
/* Write out the file's meta-data. */
ret = __wt_desc_init(session, fh);
@@ -96,7 +96,7 @@ __wt_block_open(WT_SESSION_IMPL *session, const char *filename,
__wt_block_freelist_open(session, block);
/* Open the underlying file handle. */
- WT_ERR(__wt_open(session, filename, 1, &block->fh));
+ WT_ERR(__wt_open(session, filename, 1, 1, &block->fh));
/* Get the allocation size. */
WT_ERR(__wt_config_getones(session, config, "allocation_size", &cval));
diff --git a/src/config/config_def.c b/src/config/config_def.c
index 416c4be9797..7d5acc492df 100644
--- a/src/config/config_def.c
+++ b/src/config/config_def.c
@@ -266,19 +266,20 @@ __wt_confchk_table_meta =
const char *
__wt_confdfl_wiredtiger_open =
- "cache_size=100MB,create=false,error_prefix="",eviction_target=80,"
- "eviction_trigger=95,extensions=(),hazard_max=30,home_environment=false,"
- "home_environment_priv=false,logging=false,multiprocess=false,"
- "session_max=50,transactional=false,verbose=()";
+ "cache_size=100MB,create=false,direct_io=(),error_prefix="","
+ "eviction_target=80,eviction_trigger=95,extensions=(),hazard_max=30,"
+ "home_environment=false,home_environment_priv=false,logging=false,"
+ "multiprocess=false,session_max=50,transactional=false,verbose=()";
const char *
__wt_confchk_wiredtiger_open =
"cache_size=(type=int,min=1MB,max=10TB),create=(type=boolean),"
- "error_prefix=(),eviction_target=(type=int,min=10,max=99),"
- "eviction_trigger=(type=int,min=10,max=99),extensions=(type=list),"
- "hazard_max=(type=int,min=15),home_environment=(type=boolean),"
- "home_environment_priv=(type=boolean),logging=(type=boolean),"
- "multiprocess=(type=boolean),session_max=(type=int,min=1),"
- "transactional=(type=boolean),verbose=(type=list,choices=[\"block\","
- "\"evict\",\"evictserver\",\"fileops\",\"hazard\",\"mutex\",\"read\","
- "\"readserver\",\"reconcile\",\"salvage\",\"verify\",\"write\"])";
+ "direct_io=(type=list,choices=[\"data\",\"log\"]),error_prefix=(),"
+ "eviction_target=(type=int,min=10,max=99),eviction_trigger=(type=int,"
+ "min=10,max=99),extensions=(type=list),hazard_max=(type=int,min=15),"
+ "home_environment=(type=boolean),home_environment_priv=(type=boolean),"
+ "logging=(type=boolean),multiprocess=(type=boolean),session_max=(type=int"
+ ",min=1),transactional=(type=boolean),verbose=(type=list,"
+ "choices=[\"block\",\"evict\",\"evictserver\",\"fileops\",\"hazard\","
+ "\"mutex\",\"read\",\"readserver\",\"reconcile\",\"salvage\",\"verify\","
+ "\"write\"])";
diff --git a/src/conn/conn_api.c b/src/conn/conn_api.c
index 47d3f71f2d3..00ff16cbe08 100644
--- a/src/conn/conn_api.c
+++ b/src/conn/conn_api.c
@@ -346,9 +346,9 @@ wiredtiger_open(const char *home, WT_EVENT_HANDLER *event_handler,
__conn_open_session
};
static struct {
- const char *vname;
- uint32_t vflag;
- } *vt, verbtypes[] = {
+ const char *name;
+ uint32_t flag;
+ } *ft, verbtypes[] = {
{ "block", WT_VERB_block },
{ "evict", WT_VERB_evict },
{ "evictserver",WT_VERB_evictserver },
@@ -362,6 +362,10 @@ wiredtiger_open(const char *home, WT_EVENT_HANDLER *event_handler,
{ "verify", WT_VERB_verify },
{ "write", WT_VERB_write },
{ NULL, 0 }
+ }, directio_types[] = {
+ { "data", WT_DIRECTIO_DATA },
+ { "log", WT_DIRECTIO_LOG },
+ { NULL, 0 }
};
WT_CONFIG subconfig;
WT_CONFIG_ITEM cval, skey, sval;
@@ -444,21 +448,30 @@ wiredtiger_open(const char *home, WT_EVENT_HANDLER *event_handler,
conn->verbose = 0;
#ifdef HAVE_VERBOSE
WT_ERR(__wt_config_gets(session, cfg, "verbose", &cval));
- for (vt = verbtypes; vt->vname != NULL; vt++) {
- WT_ERR(__wt_config_subinit(session, &subconfig, &cval));
- skey.str = vt->vname;
- skey.len = strlen(vt->vname);
- ret = __wt_config_getraw(&subconfig, &skey, &sval);
- if (ret == 0 && sval.val)
- FLD_SET(conn->verbose, vt->vflag);
- else if (ret != WT_NOTFOUND)
+ for (ft = verbtypes; ft->name != NULL; ft++) {
+ ret = __wt_config_subgets(session, &cval, ft->name, &sval);
+ if (ret == 0) {
+ if (sval.val)
+ FLD_SET(conn->verbose, ft->flag);
+ } else if (ret != WT_NOTFOUND)
goto err;
}
#endif
WT_ERR(__wt_config_gets(session, cfg, "logging", &cval));
if (cval.val != 0)
- WT_ERR(__wt_open(session, WT_LOG_FILENAME, 1, &conn->log_fh));
+ WT_ERR(__wt_open(session, WT_LOG_FILENAME, 1, 0, &conn->log_fh));
+
+ /* Configure direct I/O flags. */
+ WT_ERR(__wt_config_gets(session, cfg, "direct_io", &cval));
+ for (ft = directio_types; ft->name != NULL; ft++) {
+ ret = __wt_config_subgets(session, &cval, ft->name, &sval);
+ if (ret == 0) {
+ if (sval.val)
+ FLD_SET(conn->direct_io, ft->flag);
+ } else if (ret != WT_NOTFOUND)
+ goto err;
+ }
/* Load any extensions referenced in the config. */
WT_ERR(__wt_config_gets(session, cfg, "extensions", &cval));
@@ -578,7 +591,7 @@ __conn_single(WT_CONNECTION_IMPL *conn, const char **cfg)
*/
WT_RET(__wt_config_gets(session, cfg, "create", &cval));
WT_RET(__wt_open(session,
- WT_FLAGFILE, cval.val == 0 ? 0 : 1, &conn->lock_fh));
+ WT_FLAGFILE, cval.val == 0 ? 0 : 1, 0, &conn->lock_fh));
/*
* Lock a byte of the file: if we don't get the lock, some other process
@@ -670,7 +683,7 @@ __conn_config(WT_CONNECTION_IMPL *conn, const char **cfg, WT_ITEM **cbufp)
return (0);
/* Open the configuration file. */
- WT_RET(__wt_open(session, WT_CONFIGFILE, 0, &fh));
+ WT_RET(__wt_open(session, WT_CONFIGFILE, 0, 0, &fh));
WT_ERR(__wt_filesize(session, fh, &size));
if (size == 0)
goto err;
diff --git a/src/include/api.h b/src/include/api.h
index 571c40eca43..683994911b0 100644
--- a/src/include/api.h
+++ b/src/include/api.h
@@ -202,6 +202,7 @@ struct __wt_connection_impl {
FILE *msgfile;
void (*msgcall)(const WT_CONNECTION_IMPL *, const char *);
+ uint32_t direct_io;
uint32_t verbose;
uint32_t flags;
@@ -266,6 +267,8 @@ extern WT_PROCESS __wt_process;
* DO NOT EDIT: automatically built by dist/api_flags.py.
* API flags section: BEGIN
*/
+#define WT_DIRECTIO_DATA 0x00000002
+#define WT_DIRECTIO_LOG 0x00000001
#define WT_PAGE_FREE_IGNORE_DISK 0x00000001
#define WT_REC_SINGLE 0x00000001
#define WT_SERVER_RUN 0x00000001
diff --git a/src/include/extern.h b/src/include/extern.h
index c0b7bb641ee..308c62ac56c 100644
--- a/src/include/extern.h
+++ b/src/include/extern.h
@@ -551,7 +551,8 @@ extern void __wt_rwunlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock);
extern int __wt_rwlock_destroy(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock);
extern int __wt_open(WT_SESSION_IMPL *session,
const char *name,
- int create,
+ int ok_create,
+ int is_tree,
WT_FH **fhp);
extern int __wt_close(WT_SESSION_IMPL *session, WT_FH *fh);
extern int __wt_has_priv(void);
diff --git a/src/include/wiredtiger.in b/src/include/wiredtiger.in
index 757c6fceb38..960ed49a3c0 100644
--- a/src/include/wiredtiger.in
+++ b/src/include/wiredtiger.in
@@ -1039,6 +1039,9 @@ struct __wt_connection {
* between 1MB and 10TB; default \c 100MB.}
* @config{create, create the database if it does not exist.,a boolean flag;
* default \c false.}
+ * @config{direct_io, Use \c O_DIRECT to access files. Options are given as a
+ * list\, such as <code>"direct_io=[data]"</code>.,a list\, with values chosen
+ * from the following options: \c "data"\, \c "log"; default empty.}
* @config{error_prefix, prefix string for error messages.,a string; default
* empty.}
* @config{eviction_target, continue evicting until the cache becomes less full
diff --git a/src/os_posix/os_open.c b/src/os_posix/os_open.c
index b82d88987a0..281db425917 100644
--- a/src/os_posix/os_open.c
+++ b/src/os_posix/os_open.c
@@ -12,7 +12,8 @@
* Open a file handle.
*/
int
-__wt_open(WT_SESSION_IMPL *session, const char *name, int create, WT_FH **fhp)
+__wt_open(WT_SESSION_IMPL *session,
+ const char *name, int ok_create, int is_tree, WT_FH **fhp)
{
const char *path;
WT_CONNECTION_IMPL *conn;
@@ -49,12 +50,19 @@ __wt_open(WT_SESSION_IMPL *session, const char *name, int create, WT_FH **fhp)
/* Windows clones: we always want to treat the file as a binary. */
f |= O_BINARY;
#endif
- if (create) {
+ if (ok_create) {
f |= O_CREAT;
mode = 0666;
} else
mode = 0;
+#ifdef O_DIRECT
+ if (is_tree && FLD_ISSET(conn->direct_io, WT_DIRECTIO_DATA))
+ f |= O_DIRECT;
+#else
+ WT_UNUSED(is_tree);
+#endif
+
WT_SYSCALL_RETRY(((fd = open(path, f, mode)) == -1 ? 1 : 0), ret);
if (ret != 0)
WT_ERR_MSG(session, ret, "%s", name);