subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From i...@apache.org
Subject svn commit: r1683378 - in /subversion/trunk/subversion/libsvn_fs_fs: pack.c revprops.c
Date Wed, 03 Jun 2015 15:48:36 GMT
Author: ivan
Date: Wed Jun  3 15:48:35 2015
New Revision: 1683378

URL: http://svn.apache.org/r1683378
Log:
Prevent a possible FSFS repository corruption with power or network disk
failures during 'svnadmin pack'.

* subversion/libsvn_fs_fs/pack.c
  (close_pack_context): Call svn_io_file_flush_to_disk() for pack file.
  (pack_phys_addressed): Use svn_io_file_open() to open pack and manifest 
   file and call svn_io_file_flush_to_disk() before closing them.

* subversion/libsvn_fs_fs/revprops.c
  (svn_fs_fs__copy_revprops): Use apr_file_t to write pack file and flush
   changes to disk before close.
  (svn_fs_fs__pack_revprops_shard): Use svn_io_file_open() to packed revision
   properties manifest file and call svn_io_file_flush_to_disk()
   before closing it.

Modified:
    subversion/trunk/subversion/libsvn_fs_fs/pack.c
    subversion/trunk/subversion/libsvn_fs_fs/revprops.c

Modified: subversion/trunk/subversion/libsvn_fs_fs/pack.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/pack.c?rev=1683378&r1=1683377&r2=1683378&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/pack.c (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/pack.c Wed Jun  3 15:48:35 2015
@@ -384,6 +384,8 @@ close_pack_context(pack_context_t *conte
   SVN_ERR(svn_io_remove_file2(proto_l2p_index_path, FALSE, pool));
   SVN_ERR(svn_io_remove_file2(proto_p2l_index_path, FALSE, pool));
 
+  /* Ensure that packed file is written to disk.*/
+  SVN_ERR(svn_io_file_flush_to_disk(context->pack_file, pool));
   SVN_ERR(svn_io_file_close(context->pack_file, pool));
 
   return SVN_NO_ERROR;
@@ -1654,7 +1656,9 @@ pack_phys_addressed(const char *pack_fil
                     apr_pool_t *pool)
 {
   const char *pack_file_path, *manifest_file_path;
-  svn_stream_t *pack_stream, *manifest_stream;
+  apr_file_t *pack_file;
+  apr_file_t *manifest_file;
+  svn_stream_t *manifest_stream;
   svn_revnum_t end_rev, rev;
   apr_off_t next_offset;
   apr_pool_t *iterpool;
@@ -1663,13 +1667,18 @@ pack_phys_addressed(const char *pack_fil
   pack_file_path = svn_dirent_join(pack_file_dir, PATH_PACKED, pool);
   manifest_file_path = svn_dirent_join(pack_file_dir, PATH_MANIFEST, pool);
 
-  /* Create the new directory and pack file. */
-  SVN_ERR(svn_stream_open_writable(&pack_stream, pack_file_path, pool,
-                                    pool));
+  /* Create the new directory and pack file.
+   * Use unbuffered apr_file_t since we're going to write using 16kb
+   * chunks. */
+  SVN_ERR(svn_io_file_open(&pack_file, pack_file_path,
+                           APR_WRITE | APR_CREATE | APR_EXCL,
+                           APR_OS_DEFAULT, pool));
 
   /* Create the manifest file. */
-  SVN_ERR(svn_stream_open_writable(&manifest_stream, manifest_file_path,
-                                   pool, pool));
+  SVN_ERR(svn_io_file_open(&manifest_file, manifest_file_path,
+                           APR_WRITE | APR_BUFFERED | APR_CREATE | APR_EXCL,
+                           APR_OS_DEFAULT, pool));
+  manifest_stream = svn_stream_from_aprfile2(manifest_file, TRUE, pool);
 
   end_rev = start_rev + max_files_per_dir - 1;
   next_offset = 0;
@@ -1696,16 +1705,24 @@ pack_phys_addressed(const char *pack_fil
 
       /* Copy all the bits from the rev file to the end of the pack file. */
       SVN_ERR(svn_stream_open_readonly(&rev_stream, path, iterpool, iterpool));
-      SVN_ERR(svn_stream_copy3(rev_stream, svn_stream_disown(pack_stream,
-                                                             iterpool),
+      SVN_ERR(svn_stream_copy3(rev_stream,
+                               svn_stream_from_aprfile2(pack_file, TRUE, pool),
                                cancel_func, cancel_baton, iterpool));
     }
 
-  /* disallow write access to the manifest file */
+  /* Close stream over APR file. */
   SVN_ERR(svn_stream_close(manifest_stream));
+
+  /* Ensure that pack file is written to disk. */
+  SVN_ERR(svn_io_file_flush_to_disk(manifest_file, pool));
+  SVN_ERR(svn_io_file_close(manifest_file, pool));
+
+  /* disallow write access to the manifest file */
   SVN_ERR(svn_io_set_file_read_only(manifest_file_path, FALSE, iterpool));
 
-  SVN_ERR(svn_stream_close(pack_stream));
+  /* Ensure that pack file is written to disk. */
+  SVN_ERR(svn_io_file_flush_to_disk(pack_file, pool));
+  SVN_ERR(svn_io_file_close(pack_file, pool));
 
   svn_pool_destroy(iterpool);
 

Modified: subversion/trunk/subversion/libsvn_fs_fs/revprops.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/revprops.c?rev=1683378&r1=1683377&r2=1683378&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/revprops.c (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/revprops.c Wed Jun  3 15:48:35 2015
@@ -1168,7 +1168,6 @@ svn_fs_fs__copy_revprops(const char *pac
   apr_file_t *pack_file;
   svn_revnum_t rev;
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
-  svn_stream_t *stream;
 
   /* create empty data buffer and a write stream on top of it */
   svn_stringbuf_t *uncompressed
@@ -1192,6 +1191,7 @@ svn_fs_fs__copy_revprops(const char *pac
   for (rev = start_rev; rev <= end_rev; rev++)
     {
       const char *path;
+      svn_stream_t *stream;
 
       svn_pool_clear(iterpool);
 
@@ -1213,9 +1213,10 @@ svn_fs_fs__copy_revprops(const char *pac
   SVN_ERR(svn__compress(uncompressed, compressed, compression_level));
 
   /* write the pack file content to disk */
-  stream = svn_stream_from_aprfile2(pack_file, FALSE, scratch_pool);
-  SVN_ERR(svn_stream_write(stream, compressed->data, &compressed->len));
-  SVN_ERR(svn_stream_close(stream));
+  SVN_ERR(svn_io_file_write_full(pack_file, compressed->data, compressed->len,
+                                 NULL, scratch_pool));
+  SVN_ERR(svn_io_file_flush_to_disk(pack_file, scratch_pool));
+  SVN_ERR(svn_io_file_close(pack_file, scratch_pool));
 
   svn_pool_destroy(iterpool);
 
@@ -1234,6 +1235,7 @@ svn_fs_fs__pack_revprops_shard(const cha
                                apr_pool_t *scratch_pool)
 {
   const char *manifest_file_path, *pack_filename = NULL;
+  apr_file_t *manifest_file;
   svn_stream_t *manifest_stream;
   svn_revnum_t start_rev, end_rev, rev;
   apr_off_t total_size;
@@ -1250,8 +1252,12 @@ svn_fs_fs__pack_revprops_shard(const cha
 
   /* Create the new directory and manifest file stream. */
   SVN_ERR(svn_io_dir_make(pack_file_dir, APR_OS_DEFAULT, scratch_pool));
-  SVN_ERR(svn_stream_open_writable(&manifest_stream, manifest_file_path,
-                                   scratch_pool, scratch_pool));
+
+  SVN_ERR(svn_io_file_open(&manifest_file, manifest_file_path,
+                           APR_WRITE | APR_BUFFERED | APR_CREATE | APR_EXCL,
+                           APR_OS_DEFAULT, scratch_pool));
+  manifest_stream = svn_stream_from_aprfile2(manifest_file, TRUE,
+                                             scratch_pool);
 
   /* revisions to handle. Special case: revision 0 */
   start_rev = (svn_revnum_t) (shard * max_files_per_dir);
@@ -1318,8 +1324,10 @@ svn_fs_fs__pack_revprops_shard(const cha
                                      compression_level, cancel_func,
                                      cancel_baton, iterpool));
 
-  /* flush the manifest file and update permissions */
+  /* flush the manifest file to disk and update permissions */
   SVN_ERR(svn_stream_close(manifest_stream));
+  SVN_ERR(svn_io_file_flush_to_disk(manifest_file, iterpool));
+  SVN_ERR(svn_io_file_close(manifest_file, iterpool));
   SVN_ERR(svn_io_copy_perms(shard_path, pack_file_dir, iterpool));
 
   svn_pool_destroy(iterpool);



Mime
View raw message