Author: philip
Date: Wed Dec 11 15:00:37 2013
New Revision: 1550164

URL: http://svn.apache.org/r1550164
Log:
FSX implementation of FSFS r1549907.

Make sure that the temporary transaction properties associated with
commit flags do not disappear when svn_fs_commit_txn is interrupted.
As a side effect this also reduces by one the number of times the
proto-revprop file is written in a typical commit.

* subversion/libsvn_fs_fs/structure: Describe new file.

* subversion/libsvn_fs_fs/fs.h
  (PATH_TXN_PROPS_FINAL): New.

* subversion/libsvn_fs_fs/transaction.c
  (svn_fs_x__change_txn_props): Rename to ...
  (change_txn_props): ... this, add boolean parameter.
  (svn_fs_x__change_txn_props): New wrapper.
  (write_final_revprop): New.
  (commit_body): Call write_final_revprop.

* subversion/libsvn_fs_fs/util.h
  (svn_fs_x__path_txn_props_final): New.

* subversion/libsvn_fs_fs/util.c
  (svn_fs_x__path_txn_props_final): New.
  (set_txn_proplist): Add boolean final flag.

Modified:
    subversion/trunk/subversion/libsvn_fs_x/fs.h
    subversion/trunk/subversion/libsvn_fs_x/structure
    subversion/trunk/subversion/libsvn_fs_x/transaction.c
    subversion/trunk/subversion/libsvn_fs_x/util.c
    subversion/trunk/subversion/libsvn_fs_x/util.h

Modified: subversion/trunk/subversion/libsvn_fs_x/fs.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/fs.h?rev=1550164&r1=1550163&r2=1550164&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/fs.h (original)
+++ subversion/trunk/subversion/libsvn_fs_x/fs.h Wed Dec 11 15:00:37 2013
@@ -81,6 +81,8 @@ extern "C" {
 /* Names of special files and file extensions for transactions */
 #define PATH_CHANGES       "changes"       /* Records changes made so far */
 #define PATH_TXN_PROPS     "props"         /* Transaction properties */
+#define PATH_TXN_PROPS_FINAL "props-final" /* Final transaction properties
+                                              before moving to revprops */
 #define PATH_NEXT_IDS      "next-ids"      /* Next temporary ID assignments */
 #define PATH_PREFIX_NODE   "node."         /* Prefix for node filename */
 #define PATH_EXT_TXN       ".txn"          /* Extension of txn dir */

Modified: subversion/trunk/subversion/libsvn_fs_x/structure
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/structure?rev=1550164&r1=1550163&r2=1550164&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/structure (original)
+++ subversion/trunk/subversion/libsvn_fs_x/structure Wed Dec 11 15:00:37 2013
@@ -226,6 +226,7 @@ Transaction layout
 A transaction directory has the following layout:
 
   props                      Transaction props
+  props-final                Final transaction props (optional)
   next-ids                   Next temporary node-ID and copy-ID
   changes                    Changed-path information so far
   node.<nid>.<cid>           New node-rev data for node
@@ -241,9 +242,10 @@ they are received from the client.  To e
 writing to the file at a given time, the "rev-lock" file is locked for
 the duration of each write.
 
-The two kinds of props files are all in hash dump format.  The "props"
+The three kinds of props files are all in hash dump format.  The "props"
 file will always be present.  The "node.<nid>.<cid>.props" file will
-only be present if the node-rev properties have been changed.
+only be present if the node-rev properties have been changed.  The
+"props-final" only exists while converting the transaction into a revision.
 
 The <sha1> files' content is that of text rep references:
 "<rev> <offset> <length> <size> <digest>"

Modified: subversion/trunk/subversion/libsvn_fs_x/transaction.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/transaction.c?rev=1550164&r1=1550163&r2=1550164&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/transaction.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/transaction.c Wed Dec 11 15:00:37 
2013
@@ -1141,10 +1141,11 @@ svn_fs_x__change_txn_prop(svn_fs_txn_t *
   return svn_fs_x__change_txn_props(txn, props, pool);
 }
 
-svn_error_t *
-svn_fs_x__change_txn_props(svn_fs_txn_t *txn,
-                           const apr_array_header_t *props,
-                           apr_pool_t *pool)
+static svn_error_t *
+change_txn_props(svn_fs_txn_t *txn,
+                 const apr_array_header_t *props,
+                 svn_boolean_t final,
+                 apr_pool_t *pool)
 {
   fs_txn_data_t *ftd = txn->fsap_data;
   const char *txn_prop_filename;
@@ -1184,8 +1185,20 @@ svn_fs_x__change_txn_props(svn_fs_txn_t 
                       svn_io_file_del_none,
                       pool));
   return svn_io_file_rename(txn_prop_filename,
-                      svn_fs_x__path_txn_props(txn->fs, &ftd->txn_id, pool),
-                      pool);
+                (final 
+                 ? svn_fs_x__path_txn_props_final(txn->fs, &ftd->txn_id, pool)
+                 : svn_fs_x__path_txn_props(txn->fs, &ftd->txn_id, pool)),
+                pool);
+}
+
+svn_error_t *
+svn_fs_x__change_txn_props(svn_fs_txn_t *txn,
+                           const apr_array_header_t *props,
+                           apr_pool_t *pool)
+{
+  SVN_ERR(change_txn_props(txn, props, FALSE, pool));
+
+  return SVN_NO_ERROR;
 }
 
 svn_error_t *
@@ -3014,6 +3027,68 @@ verify_moves(svn_fs_t *fs,
   return SVN_NO_ERROR;
 }
 
+/* Return in *PATH the path to a file containing the properties that
+   make up the final revision properties file.  This involves setting
+   svn:date and removing any temporary properties associated with the
+   commit flags. */
+static svn_error_t *
+write_final_revprop(const char **path,
+                    svn_boolean_t set_timestamp,
+                    svn_fs_txn_t *txn,
+                    const svn_fs_x__id_part_t *txn_id,
+                    apr_pool_t *pool)
+{
+  apr_hash_t *txnprops;
+  apr_array_header_t *final_mods = NULL;
+  svn_string_t date;
+  svn_prop_t prop;
+
+  SVN_ERR(svn_fs_x__txn_proplist(&txnprops, txn, pool));
+
+  /* Remove any temporary txn props representing 'flags'. */
+  prop.value = NULL;
+  if (svn_hash_gets(txnprops, SVN_FS__PROP_TXN_CHECK_OOD))
+    {
+      if (!final_mods)
+        final_mods = apr_array_make(pool, 3, sizeof(svn_prop_t));
+      prop.name = SVN_FS__PROP_TXN_CHECK_OOD;
+      APR_ARRAY_PUSH(final_mods, svn_prop_t) = prop;
+    }
+
+  if (svn_hash_gets(txnprops, SVN_FS__PROP_TXN_CHECK_LOCKS))
+    {
+      if (!final_mods)
+        final_mods = apr_array_make(pool, 3, sizeof(svn_prop_t));
+      prop.name = SVN_FS__PROP_TXN_CHECK_LOCKS;
+      APR_ARRAY_PUSH(final_mods, svn_prop_t) = prop;
+    }
+
+  /* Update commit time to ensure that svn:date revprops remain ordered if
+     requested. */
+  if (set_timestamp)
+    {
+      if (!final_mods)
+        final_mods = apr_array_make(pool, 3, sizeof(svn_prop_t));
+      date.data = svn_time_to_cstring(apr_time_now(), pool);
+      date.len = strlen(date.data);
+      prop.name = SVN_PROP_REVISION_DATE;
+      prop.value = &date;
+      APR_ARRAY_PUSH(final_mods, svn_prop_t) = prop;
+    }
+
+  if (final_mods)
+    {
+      SVN_ERR(change_txn_props(txn, final_mods, TRUE, pool));
+      *path = svn_fs_x__path_txn_props_final(txn->fs, txn_id, pool);
+    }
+  else
+    {
+      *path = svn_fs_x__path_txn_props(txn->fs, txn_id, pool);
+    }
+
+  return SVN_NO_ERROR;
+}
+
 /* Baton used for commit_body below. */
 struct commit_baton {
   svn_revnum_t *new_rev_p;
@@ -3097,26 +3172,6 @@ commit_body(void *baton, apr_pool_t *poo
      race with another caller writing to the prototype revision file
      before we commit it. */
 
-  /* Remove any temporary txn props representing 'flags'. */
-  SVN_ERR(svn_fs_x__txn_proplist(&txnprops, cb->txn, pool));
-  txnprop_list = apr_array_make(pool, 3, sizeof(svn_prop_t));
-  prop.value = NULL;
-
-  if (svn_hash_gets(txnprops, SVN_FS__PROP_TXN_CHECK_OOD))
-    {
-      prop.name = SVN_FS__PROP_TXN_CHECK_OOD;
-      APR_ARRAY_PUSH(txnprop_list, svn_prop_t) = prop;
-    }
-
-  if (svn_hash_gets(txnprops, SVN_FS__PROP_TXN_CHECK_LOCKS))
-    {
-      prop.name = SVN_FS__PROP_TXN_CHECK_LOCKS;
-      APR_ARRAY_PUSH(txnprop_list, svn_prop_t) = prop;
-    }
-
-  if (! apr_is_empty_array(txnprop_list))
-    SVN_ERR(svn_fs_x__change_txn_props(cb->txn, txnprop_list, pool));
-
   /* Create the shard for the rev and revprop file, if we're sharding and
      this is the first revision of a new shard.  We don't care if this
      fails because the shard already existed for some reason. */
@@ -3177,22 +3232,10 @@ commit_body(void *baton, apr_pool_t *poo
      remove the transaction directory later. */
   SVN_ERR(unlock_proto_rev(cb->fs, txn_id, proto_file_lockcookie, pool));
 
-  /* Update commit time to ensure that svn:date revprops remain ordered if
-     requested. */
-  if (cb->set_timestamp)
-    {
-      svn_string_t date;
-
-      date.data = svn_time_to_cstring(apr_time_now(), pool);
-      date.len = strlen(date.data);
-
-      SVN_ERR(svn_fs_x__change_txn_prop(cb->txn, SVN_PROP_REVISION_DATE,
-                                        &date, pool));
-    }
-
   /* Move the revprops file into place. */
   SVN_ERR_ASSERT(! svn_fs_x__is_packed_revprop(cb->fs, new_rev));
-  revprop_filename = svn_fs_x__path_txn_props(cb->fs, txn_id, pool);
+  SVN_ERR(write_final_revprop(&revprop_filename, cb->set_timestamp,
+                              cb->txn, txn_id, pool));
   final_revprop = svn_fs_x__path_revprops(cb->fs, new_rev, pool);
   SVN_ERR(svn_fs_x__move_into_place(revprop_filename, final_revprop,
                                     old_rev_filename, pool));

Modified: subversion/trunk/subversion/libsvn_fs_x/util.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/util.c?rev=1550164&r1=1550163&r2=1550164&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/util.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/util.c Wed Dec 11 15:00:37 2013
@@ -286,6 +286,15 @@ svn_fs_x__path_txn_props(svn_fs_t *fs,
                          PATH_TXN_PROPS, pool);
 }
 
+const char *
+svn_fs_x__path_txn_props_final(svn_fs_t *fs,
+                               const svn_fs_x__id_part_t *txn_id,
+                               apr_pool_t *pool)
+{
+  return svn_dirent_join(svn_fs_x__path_txn_dir(fs, txn_id, pool),
+                         PATH_TXN_PROPS_FINAL, pool);
+}
+
 const char*
 svn_fs_x__path_l2p_proto_index(svn_fs_t *fs,
                                const svn_fs_x__id_part_t *txn_id,

Modified: subversion/trunk/subversion/libsvn_fs_x/util.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/util.h?rev=1550164&r1=1550163&r2=1550164&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/util.h (original)
+++ subversion/trunk/subversion/libsvn_fs_x/util.h Wed Dec 11 15:00:37 2013
@@ -187,6 +187,11 @@ svn_fs_x__path_txn_props(svn_fs_t *fs,
                          apr_pool_t *pool);
 
 const char *
+svn_fs_x__path_txn_props_final(svn_fs_t *fs,
+                               const svn_fs_x__id_part_t *txn_id,
+                               apr_pool_t *pool);
+
+const char *
 svn_fs_x__path_txn_next_ids(svn_fs_t *fs,
                             const svn_fs_x__id_part_t *txn_id,
                             apr_pool_t *pool);


Reply via email to