diff options
author | Michael Cahill <michael.cahill@wiredtiger.com> | 2011-12-05 12:01:48 +1100 |
---|---|---|
committer | Michael Cahill <michael.cahill@wiredtiger.com> | 2011-12-05 12:01:48 +1100 |
commit | 7489bf6901b68469fd1526d6fc2a8fae1996b619 (patch) | |
tree | 5ec9061d36673d6a90acad6a33dd6ff4831864dd | |
parent | 5fd5e806f4680ee8cea96f27e0c0e37a6c5f87b4 (diff) | |
download | mongo-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.py | 5 | ||||
-rw-r--r-- | src/block/block_open.c | 6 | ||||
-rw-r--r-- | src/config/config_def.c | 25 | ||||
-rw-r--r-- | src/conn/conn_api.c | 41 | ||||
-rw-r--r-- | src/include/api.h | 3 | ||||
-rw-r--r-- | src/include/extern.h | 3 | ||||
-rw-r--r-- | src/include/wiredtiger.in | 3 | ||||
-rw-r--r-- | src/os_posix/os_open.c | 12 |
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); |