You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2014/06/23 22:50:12 UTC

svn commit: r1604933 - in /subversion/trunk/subversion: include/svn_fs.h libsvn_fs_fs/cached_data.c libsvn_fs_fs/fs.h libsvn_fs_fs/fs_fs.c mod_dav_svn/dav_svn.h mod_dav_svn/mod_dav_svn.c mod_dav_svn/repos.c svnadmin/svnadmin.c svnserve/svnserve.c

Author: stefan2
Date: Mon Jun 23 20:50:11 2014
New Revision: 1604933

URL: http://svn.apache.org/r1604933
Log:
Make the FSFS format7 "block read" feature opt-in.  People with small
caches (e.g. default config) or very fast fopen() and read() functions
won't benefit from it and simply see high CPU usage.

So, this adds the "block-read" config option to both servers (nothing
here for file://).  SVNadmin always enables it as the usual dump and
verify operations are naturally suited for this option.  This also helps
our test coverage ('off' in RA defaults, 'on' in svnadmin tests).

* subversion/include/svn_fs.h
  (SVN_FS_CONFIG_FSFS_BLOCK_READ): New config option.

* subversion/libsvn_fs_fs/cached_data.c
  (block_read): Skip if block-read has not been enabled and if the caller
                did not want us to read anything specific.  If they did,
                read the required item only.

* subversion/libsvn_fs_fs/fs.h
  (fs_fs_data_t): Add the new option flag.

* subversion/libsvn_fs_fs/fs_fs.c
  (read_global_config): New utility function. Evaluating FS->CONFIG should
                        not be merged with the fsfs config file reader.
  (svn_fs_fs__open,
   svn_fs_fs__create): Call the new util to init the new option flag.

* subversion/mod_dav_svn/dav_svn.h
  (dav_svn__get_block_read_flag): New config option presence check as per
                                  usual pattern.

* subversion/mod_dav_svn/mod_dav_svn.c
  (dir_conf_t): Add flag for the new option as per usual pattern.
  (merge_dir_config): Copy it with the lot.
  (SVNBlockRead_cmd): New option command / callback for it.
  (dav_svn__get_block_read_flag): Implement.
  (cmds): Register the new option.

* subversion/mod_dav_svn/repos.c
  (get_resource): Set the option in the FS CONFIG structure just as
                  all the others.

* subversion/svnadmin/svnadmin.c
  (open_repos): Unconditionally enable block-read for svnadmin.

* subversion/svnserve/svnserve.c
  (SVNSERVE_OPT_BLOCK_READ): Declare new option token / ID.
  (svnserve__options): Describe the new command line option.
  (sub_main): Handle the CL option and pass it to the FS CONFIG.

Modified:
    subversion/trunk/subversion/include/svn_fs.h
    subversion/trunk/subversion/libsvn_fs_fs/cached_data.c
    subversion/trunk/subversion/libsvn_fs_fs/fs.h
    subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c
    subversion/trunk/subversion/mod_dav_svn/dav_svn.h
    subversion/trunk/subversion/mod_dav_svn/mod_dav_svn.c
    subversion/trunk/subversion/mod_dav_svn/repos.c
    subversion/trunk/subversion/svnadmin/svnadmin.c
    subversion/trunk/subversion/svnserve/svnserve.c

Modified: subversion/trunk/subversion/include/svn_fs.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_fs.h?rev=1604933&r1=1604932&r2=1604933&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_fs.h (original)
+++ subversion/trunk/subversion/include/svn_fs.h Mon Jun 23 20:50:11 2014
@@ -110,6 +110,12 @@ typedef struct svn_fs_t svn_fs_t;
  */
 #define SVN_FS_CONFIG_FSFS_CACHE_NS             "fsfs-cache-namespace"
 
+/** Enable / disable the FSFS format 7 "block read" feature.
+ *
+ * @since New in 1.9.
+ */
+#define SVN_FS_CONFIG_FSFS_BLOCK_READ           "fsfs-block-read"
+
 /* Note to maintainers: if you add further SVN_FS_CONFIG_FSFS_CACHE_* knobs,
    update fs_fs.c:verify_as_revision_before_current_plus_plus(). */
 

Modified: subversion/trunk/subversion/libsvn_fs_fs/cached_data.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/cached_data.c?rev=1604933&r1=1604932&r2=1604933&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/cached_data.c (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/cached_data.c Mon Jun 23 20:50:11 2014
@@ -3210,7 +3210,14 @@ block_read(void **result,
   apr_array_header_t *entries;
   int run_count = 0;
   int i;
-  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+  apr_pool_t *iterpool;
+
+  /* Block read is an optional feature. If the caller does not want anything
+   * specific we may not have to read anything. */
+  if (!result && !ffd->use_block_read)
+    return SVN_NO_ERROR;
+
+  iterpool = svn_pool_create(scratch_pool);
 
   /* don't try this on transaction protorev files */
   SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(revision));
@@ -3267,7 +3274,8 @@ block_read(void **result,
           /* handle all items that start within this block and are relatively
            * small (i.e. < block size).  Always read the item we need to return.
            */
-          if (is_result || (   entry->offset >= block_start
+          if (is_result || (   ffd->use_block_read
+                            && entry->offset >= block_start
                             && entry->size < ffd->block_size))
             {
               void *item = NULL;

Modified: subversion/trunk/subversion/libsvn_fs_fs/fs.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/fs.h?rev=1604933&r1=1604932&r2=1604933&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/fs.h (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/fs.h Mon Jun 23 20:50:11 2014
@@ -303,7 +303,11 @@ typedef struct fs_fs_data_t
 
   /* Rev / pack file granularity covered by phys-to-log index pages */
   apr_int64_t p2l_page_size;
-  
+
+  /* If set, parse and cache *all* data of each block that we read
+   * (not just the one bit that we need, atm). */
+  svn_boolean_t use_block_read;
+
   /* The revision that was youngest, last time we checked. */
   svn_revnum_t youngest_rev_cache;
 

Modified: subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c?rev=1604933&r1=1604932&r2=1604933&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/fs_fs.c Mon Jun 23 20:50:11 2014
@@ -43,6 +43,7 @@
 
 #include "private/svn_fs_util.h"
 #include "private/svn_string_private.h"
+#include "private/svn_subr_private.h"
 #include "../libsvn_fs/fs-loader.h"
 
 /* The default maximum number of files per directory to store in the
@@ -993,6 +994,18 @@ write_config(svn_fs_t *fs,
                             fsfs_conf_contents, pool);
 }
 
+/* Read / Evaluate the global configuration in FS->CONFIG to set up
+ * parameters in FS. */
+static svn_error_t *
+read_global_config(svn_fs_t *fs)
+{
+  fs_fs_data_t *ffd = fs->fsap_data;
+  ffd->use_block_read 
+    = svn_hash__get_bool(fs->config, SVN_FS_CONFIG_FSFS_BLOCK_READ, TRUE);
+
+  return SVN_NO_ERROR;
+}
+
 svn_error_t *
 svn_fs_fs__open(svn_fs_t *fs, const char *path, apr_pool_t *pool)
 {
@@ -1031,6 +1044,9 @@ svn_fs_fs__open(svn_fs_t *fs, const char
   /* Read the configuration file. */
   SVN_ERR(read_config(ffd, fs->path, fs->pool, pool));
 
+  /* Global configuration options. */
+  SVN_ERR(read_global_config(fs));
+
   return get_youngest(&(ffd->youngest_rev_cache), path, pool);
 }
 
@@ -1605,6 +1621,9 @@ svn_fs_fs__create(svn_fs_t *fs,
 
   SVN_ERR(read_config(ffd, fs->path, fs->pool, pool));
 
+  /* Global configuration options. */
+  SVN_ERR(read_global_config(fs));
+
   /* Create the min unpacked rev file. */
   if (ffd->format >= SVN_FS_FS__MIN_PACKED_FORMAT)
     SVN_ERR(svn_io_file_create(svn_fs_fs__path_min_unpacked_rev(fs, pool),

Modified: subversion/trunk/subversion/mod_dav_svn/dav_svn.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/mod_dav_svn/dav_svn.h?rev=1604933&r1=1604932&r2=1604933&view=diff
==============================================================================
--- subversion/trunk/subversion/mod_dav_svn/dav_svn.h (original)
+++ subversion/trunk/subversion/mod_dav_svn/dav_svn.h Mon Jun 23 20:50:11 2014
@@ -329,6 +329,10 @@ svn_boolean_t dav_svn__get_fulltext_cach
 /* for the repository referred to by this request, is revprop caching active? */
 svn_boolean_t dav_svn__get_revprop_cache_flag(request_rec *r);
 
+/* has block read mode been enabled for the repository referred to by this
+ * request? */
+svn_boolean_t dav_svn__get_block_read_flag(request_rec *r);
+
 /* for the repository referred to by this request, are subrequests bypassed?
  * A function pointer if yes, NULL if not.
  */

Modified: subversion/trunk/subversion/mod_dav_svn/mod_dav_svn.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/mod_dav_svn/mod_dav_svn.c?rev=1604933&r1=1604932&r2=1604933&view=diff
==============================================================================
--- subversion/trunk/subversion/mod_dav_svn/mod_dav_svn.c (original)
+++ subversion/trunk/subversion/mod_dav_svn/mod_dav_svn.c Mon Jun 23 20:50:11 2014
@@ -105,6 +105,7 @@ typedef struct dir_conf_t {
   enum conf_flag txdelta_cache;      /* whether to enable txdelta caching */
   enum conf_flag fulltext_cache;     /* whether to enable fulltext caching */
   enum conf_flag revprop_cache;      /* whether to enable revprop caching */
+  enum conf_flag block_read;         /* whether to enable block read mode */
   const char *hooks_env;             /* path to hook script env config file */
 } dir_conf_t;
 
@@ -248,6 +249,7 @@ merge_dir_config(apr_pool_t *p, void *ba
   newconf->txdelta_cache = INHERIT_VALUE(parent, child, txdelta_cache);
   newconf->fulltext_cache = INHERIT_VALUE(parent, child, fulltext_cache);
   newconf->revprop_cache = INHERIT_VALUE(parent, child, revprop_cache);
+  newconf->block_read = INHERIT_VALUE(parent, child, block_read);  
   newconf->root_dir = INHERIT_VALUE(parent, child, root_dir);
   newconf->hooks_env = INHERIT_VALUE(parent, child, hooks_env);
 
@@ -544,6 +546,19 @@ SVNCacheRevProps_cmd(cmd_parms *cmd, voi
 }
 
 static const char *
+SVNBlockRead_cmd(cmd_parms *cmd, void *config, int arg)
+{
+  dir_conf_t *conf = config;
+
+  if (arg)
+    conf->block_read = CONF_FLAG_ON;
+  else
+    conf->block_read = CONF_FLAG_OFF;
+
+  return NULL;
+}
+
+static const char *
 SVNInMemoryCacheSize_cmd(cmd_parms *cmd, void *config, const char *arg1)
 {
   svn_cache_config_t settings = *svn_cache_config_get();
@@ -948,6 +963,15 @@ dav_svn__get_revprop_cache_flag(request_
 }
 
 
+svn_boolean_t
+dav_svn__get_block_read_flag(request_rec *r)
+{
+  dir_conf_t *conf;
+
+  conf = ap_get_module_config(r->per_dir_config, &dav_svn_module);
+  return conf->block_read == CONF_FLAG_ON;
+}
+
 int
 dav_svn__get_compression_level(request_rec *r)
 {
@@ -1289,6 +1313,13 @@ static const command_rec cmds[] =
                "in the documentation"
                "(default is Off)."),
 
+  /* per directory/location */
+  AP_INIT_FLAG("SVNBlockRead", SVNBlockRead_cmd, NULL,
+               ACCESS_CONF|RSRC_CONF,
+               "speeds up operations of FSFS 1.9+ repositories if large"
+               "caches (see SVNInMemoryCacheSize) have been configured."
+               "(default is Off)."),
+
   /* per server */
   AP_INIT_TAKE1("SVNInMemoryCacheSize", SVNInMemoryCacheSize_cmd, NULL,
                 RSRC_CONF,

Modified: subversion/trunk/subversion/mod_dav_svn/repos.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/mod_dav_svn/repos.c?rev=1604933&r1=1604932&r2=1604933&view=diff
==============================================================================
--- subversion/trunk/subversion/mod_dav_svn/repos.c (original)
+++ subversion/trunk/subversion/mod_dav_svn/repos.c Mon Jun 23 20:50:11 2014
@@ -2269,6 +2269,8 @@ get_resource(request_rec *r,
                     dav_svn__get_fulltext_cache_flag(r) ? "1" :"0");
       svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_CACHE_REVPROPS,
                     dav_svn__get_revprop_cache_flag(r) ? "2" :"0");
+      svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_BLOCK_READ,
+                    dav_svn__get_block_read_flag(r) ? "1" :"0");
 
       /* Disallow BDB/event until issue 4157 is fixed. */
       if (!strcmp(ap_show_mpm(), "event"))

Modified: subversion/trunk/subversion/svnadmin/svnadmin.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svnadmin/svnadmin.c?rev=1604933&r1=1604932&r2=1604933&view=diff
==============================================================================
--- subversion/trunk/subversion/svnadmin/svnadmin.c (original)
+++ subversion/trunk/subversion/svnadmin/svnadmin.c Mon Jun 23 20:50:11 2014
@@ -120,6 +120,7 @@ open_repos(svn_repos_t **repos,
   svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_CACHE_REVPROPS, "2");
   svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_CACHE_NS,
                            svn_uuid_generate(pool));
+  svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_BLOCK_READ, "1");
 
   /* now, open the requested repository */
   SVN_ERR(svn_repos_open3(repos, path, fs_config, pool, pool));

Modified: subversion/trunk/subversion/svnserve/svnserve.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svnserve/svnserve.c?rev=1604933&r1=1604932&r2=1604933&view=diff
==============================================================================
--- subversion/trunk/subversion/svnserve/svnserve.c (original)
+++ subversion/trunk/subversion/svnserve/svnserve.c Mon Jun 23 20:50:11 2014
@@ -209,6 +209,7 @@ void winservice_notify_stop(void)
 #define SVNSERVE_OPT_VIRTUAL_HOST    270
 #define SVNSERVE_OPT_MIN_THREADS     271
 #define SVNSERVE_OPT_MAX_THREADS     272
+#define SVNSERVE_OPT_BLOCK_READ      273
 
 static const apr_getopt_option_t svnserve__options[] =
   {
@@ -301,6 +302,14 @@ static const apr_getopt_option_t svnserv
         "ARG Mbit/s.\n"
         "                             "
         "Default is 0 (optimizations disabled).")},
+    {"block-read", SVNSERVE_OPT_BLOCK_READ, 1,
+     N_("Parse and cache all data found in block instead\n"
+        "                             "
+        "of just the requested item.\n"
+        "                             "
+        "Default is no.\n"
+        "                             "
+        "[used for FSFS repositories in 1.9 format only]")},
 #ifdef CONNECTION_HAVE_THREAD_OPTION
     /* ### Making the assumption here that WIN32 never has fork and so
      * ### this option never exists when --service exists. */
@@ -671,6 +680,7 @@ sub_main(int *exit_code, int argc, const
   svn_boolean_t cache_fulltexts = TRUE;
   svn_boolean_t cache_txdeltas = TRUE;
   svn_boolean_t cache_revprops = FALSE;
+  svn_boolean_t use_block_read = FALSE;
   apr_uint16_t port = SVN_RA_SVN_PORT;
   const char *host = NULL;
   int family = APR_INET;
@@ -858,6 +868,10 @@ sub_main(int *exit_code, int argc, const
           cache_revprops = svn_tristate__from_word(arg) == svn_tristate_true;
           break;
 
+        case SVNSERVE_OPT_BLOCK_READ:
+          use_block_read = svn_tristate__from_word(arg) == svn_tristate_true;
+          break;
+
         case SVNSERVE_OPT_CLIENT_SPEED:
           {
             apr_size_t bandwidth = (apr_size_t)apr_strtoi64(arg, NULL, 0);
@@ -966,6 +980,8 @@ sub_main(int *exit_code, int argc, const
                 cache_fulltexts ? "1" :"0");
   svn_hash_sets(params.fs_config, SVN_FS_CONFIG_FSFS_CACHE_REVPROPS,
                 cache_revprops ? "2" :"0");
+  svn_hash_sets(params.fs_config, SVN_FS_CONFIG_FSFS_BLOCK_READ,
+                use_block_read ? "1" :"0");  
 
   SVN_ERR(svn_repos__config_pool_create(&params.config_pool,
                                         is_multi_threaded,