[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

[PATCH] (in progress) FS format numbers

From: <kfogel_at_collab.net>
Date: 2005-03-12 00:08:32 CET

This patch isn't done yet, I just thought I'd post it here for early
review, since I'll be finishing it later tonight or tomorrow anyway.

I have no idea if it passes 'make check' or if it even works. It
does, however, compile.

-Karl

[[[
Add a filesystem format number, separate from the repository format.
This is so that in the future, the FS back ends can notice their own
formats, and either soft upgrade or error out as appropriate.

Throughout, consistently say "format" not "version", because the
latter is too easy to confuse with the version (i.e., release) of
Subversion. For example, the function svn_fs_version() is unrelated
to these format numbers.

* subversion/libsvn_fs_fs/fs.h
  (SVN_FS_FS__FORMAT_NUMBER, SVN_FS_FS__FORMAT_FILE): New #defines.
  (struct fs_fs_data_t): Add format field.

* subversion/libsvn_fs_base/fs.h
  (SVN_FS_BASE__FORMAT_NUMBER, SVN_FS_BASE__FORMAT_FILE): New #defines.
  (base_fs_data_t): Add format field.

* subversion/libsvn_fs_fs/fs_fs.c
  (PATH_FORMAT): New #define.
  (path_format, check_format): New helper functions.
  (svn_fs_fs__create): Set the format number on the new filesystem.
  (svn_fs_fs__open): Get the format number, creating it if necessary.

* subversion/libsvn_fs_base/fs.c
  (check_format): New helper function.
  (base_create): Set the format number on the new filesystem.
  (base_open): Get the format number, creating it if necessary.
  Also, fix an old, unrelated pool usage buglet.

* subversion/include/svn_error_codes.h
  (SVN_ERR_FS_UNSUPPORTED_FORMAT): New error code.
  (SVN_ERR_REPOS_UNSUPPORTED_VERSION): Add comment explaining name.

Since we're now calling it a "format" number, not a "version", adjust
libsvn_repos to be consistent with this new terminology:

* subversion/libsvn_repos/repos.h
  (SVN_REPOS__FORMAT_NUMBER): Replace SVN_REPOS__VERSION, which was
  too easy to confuse with the version (i.e., release number) of
  Subversion.

* subversion/libsvn_repos/repos.c
  (check_repos_format): Rename from 'check_repos_version', adjust
  error message slightly, and adjust for above changes of course.
  (create_repos_structure): Adjust for above.
  (get_repos): Call check_repos_format instead of check_repos_version.
]]]

Index: subversion/libsvn_fs_base/fs.c
===================================================================
--- subversion/libsvn_fs_base/fs.c (revision 13373)
+++ subversion/libsvn_fs_base/fs.c (working copy)
@@ -612,6 +612,12 @@
   svn_err = svn_fs_base__dag_init_fs (fs);
   if (svn_err) goto error;
 
+ /* This filesystem is ready. Stamp it with a format number. */
+ svn_err = svn_io_write_version_file
+ (svn_path_join (fs->path, SVN_FS_BASE__FORMAT_FILE, pool),
+ SVN_FS_BASE__FORMAT_NUMBER, pool);
+ if (svn_err) goto error;
+
   return SVN_NO_ERROR;
 
 error:
@@ -623,12 +629,32 @@
 /* Gaining access to an existing Berkeley DB-based filesystem. */
 
 
+/* Return the error SVN_ERR_FS_UNSUPPORTED_FORMAT if FS's format
+ number is not the same as the format number supported by this
+ Subversion. */
 static svn_error_t *
+check_format (svn_fs_t *fs)
+{
+ int format = ((base_fs_data_t *) fs->fsap_data)->format;
+
+ if (format != SVN_FS_BASE__FORMAT_NUMBER)
+ {
+ return svn_error_createf
+ (SVN_ERR_FS_UNSUPPORTED_FORMAT, NULL,
+ _("Expected FS format '%d'; found format '%d'"),
+ SVN_FS_BASE__FORMAT_NUMBER, format);
+ }
+
+ return SVN_NO_ERROR;
+}
+
+static svn_error_t *
 base_open (svn_fs_t *fs, const char *path, apr_pool_t *pool)
 {
   svn_error_t *svn_err;
   const char *path_native;
   base_fs_data_t *bfd;
+ int format;
 
   SVN_ERR (check_already_open (fs));
 
@@ -646,7 +672,7 @@
   if (svn_err) goto error;
 
   /* Open the Berkeley DB environment. */
- SVN_ERR (svn_utf_cstring_from_utf8 (&path_native, fs->path, fs->pool));
+ SVN_ERR (svn_utf_cstring_from_utf8 (&path_native, fs->path, pool));
   svn_err = BDB_WRAP (fs, "opening environment",
                       bfd->env->open (bfd->env, path_native,
                                       (DB_CREATE
@@ -693,6 +719,27 @@
 
   return SVN_NO_ERROR;
 
+ /* Read the FS format number. */
+ svn_err = svn_io_read_version_file
+ (&format, svn_path_join (fs->path, SVN_FS_BASE__FORMAT_FILE, pool), pool);
+ if (svn_err && APR_STATUS_IS_ENOENT (svn_err->apr_err))
+ {
+ /* Pre-1.2 filesystems did not have a format file (you could say
+ they were format "0"), so they get upgraded on the fly. */
+ svn_error_clear (svn_err), svn_err = NULL;
+ format = SVN_FS_BASE__FORMAT_NUMBER;
+ svn_err = svn_io_write_version_file
+ (svn_path_join (fs->path, SVN_FS_BASE__FORMAT_FILE, pool),
+ format, pool);
+ if (svn_err) goto error;
+ }
+ else if (svn_err)
+ goto error;
+
+ /* Now we've got a format number no matter what. */
+ ((base_fs_data_t *) fs->fsap_data)->format = format;
+ SVN_ERR (check_format (fs));
+
  error:
   svn_error_clear (cleanup_fs (fs));
   return svn_err;
Index: subversion/libsvn_fs_base/fs.h
===================================================================
--- subversion/libsvn_fs_base/fs.h (revision 13376)
+++ subversion/libsvn_fs_base/fs.h (working copy)
@@ -33,6 +33,14 @@
 
 /*** The filesystem structure. ***/
 
+/* The format number of this filesystem.
+ This is independent of the repository format number, and
+ independent of any other FS back ends. */
+#define SVN_FS_BASE__FORMAT_NUMBER 1
+
+/* Where the format number is stored. */
+#define SVN_FS_BASE__FORMAT_FILE "format"
+
 #define BDB_ERRCALL_BATON_ERRPFX_STRING "svn (bdb): "
 typedef struct
 {
@@ -81,6 +89,10 @@
 
   /* A baton for collecting detailed errors from Berkeley DB. */
   bdb_errcall_baton_t *errcall_baton;
+
+ /* The format number of this FS. */
+ int format;
+
 } base_fs_data_t;
 
 
Index: subversion/include/svn_error_codes.h
===================================================================
--- subversion/include/svn_error_codes.h (revision 13373)
+++ subversion/include/svn_error_codes.h (working copy)
@@ -512,6 +512,18 @@
               SVN_ERR_FS_CATEGORY_START + 33,
               "Unknown FS type")
 
+ /* @since New in 1.2.
+ *
+ * This is analogous to SVN_ERR_REPOS_UNSUPPORTED_VERSION. To avoid
+ * confusion with "versions" (i.e., releases) of Subversion, we've
+ * started calling this the "format" number instead. The old
+ * SVN_ERR_REPOS_UNSUPPORTED_VERSION error predates this and so
+ * retains its name.
+ */
+ SVN_ERRDEF (SVN_ERR_FS_UNSUPPORTED_FORMAT,
+ SVN_ERR_FS_CATEGORY_START + 34,
+ "Unsupported FS format")
+
   /* repos errors */
 
   SVN_ERRDEF (SVN_ERR_REPOS_LOCKED,
@@ -534,6 +546,11 @@
               SVN_ERR_REPOS_CATEGORY_START + 4,
               "Bogus revision report")
  
+ /* This is analogous to SVN_ERR_FS_UNSUPPORTED_FORMAT. To avoid
+ * confusion with "versions" (i.e., releases) of Subversion, we
+ * started using the word "format" instead of "version". However,
+ * this error code's name predates that decision.
+ */
   SVN_ERRDEF (SVN_ERR_REPOS_UNSUPPORTED_VERSION,
               SVN_ERR_REPOS_CATEGORY_START + 5,
               "Unsupported repository version")
Index: subversion/libsvn_repos/repos.c
===================================================================
--- subversion/libsvn_repos/repos.c (revision 13373)
+++ subversion/libsvn_repos/repos.c (working copy)
@@ -995,7 +995,7 @@
   /* Write the top-level FORMAT file. */
   SVN_ERR (svn_io_write_version_file
            (svn_path_join (path, SVN_REPOS__FORMAT, pool),
- SVN_REPOS__VERSION, pool));
+ SVN_REPOS__FORMAT_NUMBER, pool));
 
   return SVN_NO_ERROR;
 }
@@ -1079,22 +1079,22 @@
 
 /* Verify that the repository's 'format' file is a suitable version. */
 static svn_error_t *
-check_repos_version (svn_repos_t *repos,
+check_repos_format (svn_repos_t *repos,
                      apr_pool_t *pool)
 {
- int version;
+ int format;
   const char *format_path;
 
   format_path = svn_path_join (repos->path, SVN_REPOS__FORMAT, pool);
- SVN_ERR (svn_io_read_version_file (&version, format_path, pool));
+ SVN_ERR (svn_io_read_version_file (&format, format_path, pool));
 
- if (version != SVN_REPOS__VERSION)
+ if (format != SVN_REPOS__FORMAT_NUMBER)
     return svn_error_createf
       (SVN_ERR_REPOS_UNSUPPORTED_VERSION, NULL,
- _("Expected version '%d' of repository; found version '%d'"),
- SVN_REPOS__VERSION, version);
+ _("Expected format '%d' of repository; found format '%d'"),
+ SVN_REPOS__FORMAT_NUMBER, format);
 
- repos->format = version;
+ repos->format = format;
 
   return SVN_NO_ERROR;
 }
@@ -1125,7 +1125,7 @@
   init_repos_dirs (repos, path, pool);
 
   /* Verify the validity of our repository format. */
- SVN_ERR (check_repos_version (repos, pool));
+ SVN_ERR (check_repos_format (repos, pool));
 
   /* Locking. */
   {
Index: subversion/libsvn_repos/repos.h
===================================================================
--- subversion/libsvn_repos/repos.h (revision 13373)
+++ subversion/libsvn_repos/repos.h (working copy)
@@ -28,8 +28,8 @@
 #endif /* __cplusplus */
 
 
-/*** Repository version number. */
-#define SVN_REPOS__VERSION 3
+/*** Repository format number. */
+#define SVN_REPOS__FORMAT_NUMBER 3
 
 
 /*** Repository layout. ***/
Index: subversion/libsvn_fs_fs/fs_fs.c
===================================================================
--- subversion/libsvn_fs_fs/fs_fs.c (revision 13373)
+++ subversion/libsvn_fs_fs/fs_fs.c (working copy)
@@ -52,6 +52,7 @@
    native filesystem directories and revision files. */
 
 /* Names of special files in the fs_fs filesystem. */
+#define PATH_FORMAT "format" /* Contains format number */
 #define PATH_UUID "uuid" /* Contains UUID */
 #define PATH_CURRENT "current" /* Youngest revision */
 #define PATH_LOCK_FILE "write-lock" /* Revision lock file */
@@ -124,6 +125,12 @@
 /* Pathname helper functions */
 
 static const char *
+path_format (svn_fs_t *fs, apr_pool_t *pool)
+{
+ return svn_path_join (fs->path, PATH_FORMAT, pool);
+}
+
+static const char *
 path_uuid (svn_fs_t *fs, apr_pool_t *pool)
 {
   return svn_path_join (fs->path, PATH_UUID, pool);
@@ -226,22 +233,58 @@
   return SVN_NO_ERROR;
 }
 
+/* Return the error SVN_ERR_FS_UNSUPPORTED_FORMAT if FS's format
+ number is not the same as the format number supported by this
+ Subversion. */
+static svn_error_t *
+check_format (svn_fs_t *fs)
+{
+ int format = ((fs_fs_data_t *) fs->fsap_data)->format;
+
+ if (format != SVN_FS_FS__FORMAT_NUMBER)
+ {
+ return svn_error_createf
+ (SVN_ERR_FS_UNSUPPORTED_FORMAT, NULL,
+ _("Expected FS format '%d'; found format '%d'"),
+ SVN_FS_FS__FORMAT_NUMBER, format);
+ }
+
+ return SVN_NO_ERROR;
+}
+
 svn_error_t *
 svn_fs_fs__open (svn_fs_t *fs, const char *path, apr_pool_t *pool)
 {
   apr_file_t *current_file;
+ svn_error_t *err;
+ int format;
 
- /* Attempt to open the 'current' file of this repository. There
- isn't much need for specific state associated with an open fs_fs
- repository. */
-
   fs->path = apr_pstrdup (pool, path);
 
+ /* Attempt to open the 'current' file of this repository; its
+ existence indicates that this is probably an FSFS filesystem. */
   SVN_ERR (svn_io_file_open (&current_file, path_current (fs, pool),
                              APR_READ | APR_BUFFERED, APR_OS_DEFAULT, pool));
+ SVN_ERR (svn_io_file_close (current_file, pool));
 
- SVN_ERR (svn_io_file_close (current_file, pool));
+ /* Read the FS format number. */
+ err = svn_io_read_version_file (&format, path_format (fs, pool), pool);
+ if (err && APR_STATUS_IS_ENOENT (err->apr_err))
+ {
+ /* Pre-1.2 filesystems did not have a format file (you could say
+ they were format "0"), so they get upgraded on the fly. */
+ svn_error_clear (err), err = NULL;
+ format = SVN_FS_FS__FORMAT_NUMBER;
+ SVN_ERR (svn_io_write_version_file
+ (path_format (fs, pool), format, pool));
+ }
+ else if (err)
+ return err;
   
+ /* Now we've got a format number no matter what. */
+ ((fs_fs_data_t *) fs->fsap_data)->format = format;
+ SVN_ERR (check_format (fs));
+
   return SVN_NO_ERROR;
 }
 
@@ -3678,6 +3721,11 @@
   
   SVN_ERR (svn_fs_fs__dag_init_fs (fs));
 
+ /* This filesystem is ready. Stamp it with a format number. */
+ SVN_ERR (svn_io_write_version_file
+ (path_format (fs, pool), SVN_FS_FS__FORMAT_NUMBER, pool));
+ ((fs_fs_data_t *) fs->fsap_data)->format = SVN_FS_FS__FORMAT_NUMBER;
+
   return SVN_NO_ERROR;
 }
 
Index: subversion/libsvn_fs_fs/fs.h
===================================================================
--- subversion/libsvn_fs_fs/fs.h (revision 13373)
+++ subversion/libsvn_fs_fs/fs.h (working copy)
@@ -30,12 +30,24 @@
 
 /*** The filesystem structure. ***/
 
+/* The format number of this filesystem.
+ This is independent of the repository format number, and
+ independent of any other FS back ends. */
+#define SVN_FS_FS__FORMAT_NUMBER 1
+
+/* Where the format number is stored. */
+#define SVN_FS_FS__FORMAT_FILE "format"
+
 typedef struct
 {
   /* A cache of the last directory opened within the filesystem. */
   svn_fs_id_t *dir_cache_id;
   apr_hash_t *dir_cache;
   apr_pool_t *dir_cache_pool;
+
+ /* The format number of this FS. */
+ int format;
+
 } fs_fs_data_t;
 
 

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Sat Mar 12 00:29:35 2005

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.