On Mon, Oct 29, 2012 at 03:26:36PM +0530, Prabhu Gnana Sundar wrote: > Thanks much Stefan, > > Now, I have changed the code in libsvn_fs/fs-loader.c to handle the > error. Passed the keep_going to the verify_fs so that it can be > handled in both libsvn_fs_fs and libsvn_fs_base. I have attached the > updated patch with this mail. Please share your reviews.
More review below (mostly stylistic nits). > Index: subversion/libsvn_repos/dump.c > =================================================================== > --- subversion/libsvn_repos/dump.c (revision 1402414) > +++ subversion/libsvn_repos/dump.c (working copy) > @@ -1360,9 +1360,10 @@ > } > > svn_error_t * > -svn_repos_verify_fs2(svn_repos_t *repos, > +svn_repos_verify_fs3(svn_repos_t *repos, > svn_revnum_t start_rev, > svn_revnum_t end_rev, > + svn_boolean_t keep_going, > svn_repos_notify_func_t notify_func, > void *notify_baton, > svn_cancel_func_t cancel_func, > @@ -1398,7 +1399,7 @@ > > /* Verify global/auxiliary data and backend-specific data first. */ > SVN_ERR(svn_fs_verify(svn_fs_path(fs, pool), cancel_func, cancel_baton, > - start_rev, end_rev, pool)); > + start_rev, end_rev, keep_going, pool)); > > /* Create a notify object that we can reuse within the loop. */ > if (notify_func) > @@ -1413,11 +1414,12 @@ > void *cancel_edit_baton; > svn_fs_root_t *to_root; > apr_hash_t *props; > + svn_error_t *err; > > svn_pool_clear(iterpool); > > /* Get cancellable dump editor, but with our close_directory handler. > */ > - SVN_ERR(get_dump_editor(&dump_editor, &dump_edit_baton, > + err = get_dump_editor(&dump_editor, &dump_edit_baton, > fs, rev, "", > svn_stream_empty(iterpool), > NULL, NULL, Please also change indentation of function parameters on additional lines to align at the opening bracket like this: err = get_dump_editor(&dump_editor, &dump_edit_baton, fs, rev, "", svn_stream_empty(iterpool), NULL, NULL, With your patch it would look like this, which is wrong indentation for our code base: err = get_dump_editor(&dump_editor, &dump_edit_baton, fs, rev, "", svn_stream_empty(iterpool), NULL, NULL, > @@ -1425,7 +1427,19 @@ > notify_func, notify_baton, > start_rev, > FALSE, TRUE, /* use_deltas, verify */ > - iterpool)); > + iterpool); > + > + if (err && keep_going) > + { > + svn_repos_notify_t *notify2 = > svn_repos_notify_create(svn_repos_notify_failure, iterpool); Why call the variable 'notify2', not just 'notify'? Also, the above line doesn't wrap at column 78. I'd suggest using 'notify' as variable name and indenting like this: svn_repos_notify_t *notify; notify = svn_repos_notify_create(svn_repos_notify_failure, iterpool); > + notify2->err = err; > + notify_func(notify_baton, notify2, iterpool); > + svn_error_clear(err); > + continue; > + } > + else > + SVN_ERR(err); > + > SVN_ERR(svn_delta_get_cancellation_editor(cancel_func, cancel_baton, > dump_editor, dump_edit_baton, > &cancel_editor, > @@ -1433,9 +1447,21 @@ > iterpool)); > > SVN_ERR(svn_fs_revision_root(&to_root, fs, rev, iterpool)); > - SVN_ERR(svn_repos_replay2(to_root, "", SVN_INVALID_REVNUM, FALSE, > + err = svn_repos_replay2(to_root, "", SVN_INVALID_REVNUM, FALSE, > cancel_editor, cancel_edit_baton, Again, please adjust indentation of function parameters. > - NULL, NULL, iterpool)); > + NULL, NULL, iterpool); > + > + if (err && keep_going) > + { > + svn_repos_notify_t *notify2 = > svn_repos_notify_create(svn_repos_notify_failure, iterpool); Same as above suggestion for 'notify' + indentation. > + notify2->err = err; > + notify_func(notify_baton, notify2, iterpool); > + svn_error_clear(err); > + continue; > + } > + else > + SVN_ERR(err); > + > /* While our editor close_edit implementation is a no-op, we still > do this for completeness. */ > SVN_ERR(cancel_editor->close_edit(cancel_edit_baton, iterpool)); > Index: subversion/libsvn_repos/deprecated.c > =================================================================== > --- subversion/libsvn_repos/deprecated.c (revision 1402414) > +++ subversion/libsvn_repos/deprecated.c (working copy) > @@ -728,6 +728,27 @@ > } > > svn_error_t * > +svn_repos_verify_fs2(svn_repos_t *repos, > + svn_revnum_t start_rev, > + svn_revnum_t end_rev, > + svn_repos_notify_func_t notify_func, > + void *notify_baton, > + svn_cancel_func_t cancel_func, > + void *cancel_baton, > + apr_pool_t *pool) > +{ > + return svn_error_trace(svn_repos_verify_fs3(repos, > + start_rev, > + end_rev, > + FALSE, > + notify_func, > + notify_baton, > + cancel_func, > + cancel_baton, > + pool)); > +} > + > +svn_error_t * > svn_repos_verify_fs(svn_repos_t *repos, > svn_stream_t *feedback_stream, > svn_revnum_t start_rev, > Index: subversion/libsvn_fs_fs/fs_fs.c > =================================================================== > --- subversion/libsvn_fs_fs/fs_fs.c (revision 1402414) > +++ subversion/libsvn_fs_fs/fs_fs.c (working copy) > @@ -10117,6 +10117,7 @@ > void *cancel_baton, > svn_revnum_t start, > svn_revnum_t end, > + svn_boolean_t keep_going, > apr_pool_t *pool) > { > fs_fs_data_t *ffd = fs->fsap_data; > @@ -10151,6 +10152,7 @@ > commit-time checks in validate_root_noderev(). */ > { > svn_revnum_t i; > + svn_error_t *err; We usually add a blank line between variable declarations and code. So you should add a blank here. > for (i = start; i <= end; i++) > { > svn_fs_root_t *root; > @@ -10162,7 +10164,15 @@ > When this code is called in the library, we want to ensure we > use the on-disk data --- rather than some data that was read > in the possibly-distance past and cached since. */ > - SVN_ERR(svn_fs_fs__revision_root(&root, fs, i, iterpool)); > + err = svn_fs_fs__revision_root(&root, fs, i, iterpool); > + if (err && keep_going) > + { > + svn_error_clear(err); No notification about this error? Instead of pushing the repos-layer notifier down into the FS-layer, I'd suggest catching this error thrown from svn_fs_fs__verify() in the repos-layer caller and notifying there if --keep-going was used. And then this function won't even need a keep_going parameter and all the FS-layer bits can be left unchanged, making your patch a bit smaller. > + return SVN_NO_ERROR; > + } > + else > + SVN_ERR(err); > + > SVN_ERR(svn_fs_fs__verify_root(root, iterpool)); > } > } > Index: subversion/libsvn_fs_fs/fs_fs.h > =================================================================== > --- subversion/libsvn_fs_fs/fs_fs.h (revision 1402414) > +++ subversion/libsvn_fs_fs/fs_fs.h (working copy) > @@ -38,12 +38,14 @@ > svn_error_t *svn_fs_fs__upgrade(svn_fs_t *fs, > apr_pool_t *pool); > > -/* Verify the fsfs filesystem FS. Use POOL for temporary allocations. */ > +/* Verify the fsfs filesystem FS. Use POOL for temporary allocations. > + * If KEEP_GOING is TRUE, do not stop upon failure. */ > svn_error_t *svn_fs_fs__verify(svn_fs_t *fs, > svn_cancel_func_t cancel_func, > void *cancel_baton, > svn_revnum_t start, > svn_revnum_t end, > + svn_boolean_t keep_going, > apr_pool_t *pool); > > /* Copy the fsfs filesystem SRC_FS at SRC_PATH into a new copy DST_FS at > Index: subversion/libsvn_fs_fs/fs.c > =================================================================== > --- subversion/libsvn_fs_fs/fs.c (revision 1402414) > +++ subversion/libsvn_fs_fs/fs.c (working copy) > @@ -287,6 +287,7 @@ > void *cancel_baton, > svn_revnum_t start, > svn_revnum_t end, > + svn_boolean_t keep_going, > apr_pool_t *pool, > apr_pool_t *common_pool) > { > @@ -295,7 +296,8 @@ > SVN_ERR(svn_fs_fs__open(fs, path, pool)); > SVN_ERR(svn_fs_fs__initialize_caches(fs, pool)); > SVN_ERR(fs_serialized_init(fs, common_pool, pool)); > - return svn_fs_fs__verify(fs, cancel_func, cancel_baton, start, end, pool); > + return svn_fs_fs__verify(fs, cancel_func, cancel_baton, start, end, > + keep_going, pool); > } > > static svn_error_t * > Index: subversion/libsvn_fs/fs-loader.c > =================================================================== > --- subversion/libsvn_fs/fs-loader.c (revision 1402414) > +++ subversion/libsvn_fs/fs-loader.c (working copy) > @@ -487,6 +487,7 @@ > void *cancel_baton, > svn_revnum_t start, > svn_revnum_t end, > + svn_boolean_t keep_going, > apr_pool_t *pool) > { > fs_library_vtable_t *vtable; > @@ -497,7 +498,7 @@ > > SVN_MUTEX__WITH_LOCK(common_pool_lock, > vtable->verify_fs(fs, path, cancel_func, cancel_baton, > - start, end, pool, common_pool)); > + start, end, keep_going, pool, > common_pool)); > return SVN_NO_ERROR; > } > > Index: subversion/libsvn_fs/fs-loader.h > =================================================================== > --- subversion/libsvn_fs/fs-loader.h (revision 1402414) > +++ subversion/libsvn_fs/fs-loader.h (working copy) > @@ -92,6 +92,7 @@ > svn_cancel_func_t cancel_func, void > *cancel_baton, > svn_revnum_t start, > svn_revnum_t end, > + svn_boolean_t keep_going, > apr_pool_t *pool, > apr_pool_t *common_pool); > svn_error_t *(*delete_fs)(const char *path, apr_pool_t *pool); > Index: subversion/svnadmin/main.c > =================================================================== > --- subversion/svnadmin/main.c (revision 1402414) > +++ subversion/svnadmin/main.c (working copy) > @@ -176,6 +176,7 @@ > { > svnadmin__version = SVN_OPT_FIRST_LONGOPT_ID, > svnadmin__incremental, > + svnadmin__keep_going, > svnadmin__deltas, > svnadmin__ignore_uuid, > svnadmin__force_uuid, > @@ -288,6 +289,9 @@ > N_("use format compatible with Subversion versions\n" > " earlier than 1.8")}, > > + {"keep-going", svnadmin__keep_going, 0, > + N_("continue verifying even if there is a corruption")}, > + > {"memory-cache-size", 'M', 1, > N_("size of the extra in-memory cache in MB used to\n" > " minimize redundant operations. > Default: 16.\n" > @@ -475,7 +479,7 @@ > {"verify", subcommand_verify, {0}, N_ > ("usage: svnadmin verify REPOS_PATH\n\n" > "Verifies the data stored in the repository.\n"), > - {'r', 'q', 'M'} }, > + {'r', 'q', svnadmin__keep_going, 'M'} }, > > { NULL, NULL, {0}, NULL, {0} } > }; > @@ -505,6 +509,7 @@ > svn_boolean_t clean_logs; /* --clean-logs */ > svn_boolean_t bypass_hooks; /* --bypass-hooks */ > svn_boolean_t wait; /* --wait */ > + svn_boolean_t keep_going; /* --keep-going */ > svn_boolean_t bypass_prop_validation; /* > --bypass-prop-validation */ > enum svn_repos_load_uuid uuid_action; /* --ignore-uuid, > --force-uuid */ > @@ -738,6 +743,10 @@ > notify->warning_str)); > return; > > + case svn_repos_notify_failure: > + svn_handle_error2(notify->err, stderr, FALSE /* non-fatal */, > "svnadmin: "); Another overlong line. I'd suggest: svn_handle_error2(notify->err, stderr, FALSE /* non-fatal */, "svnadmin: "); > + return; > + > case svn_repos_notify_dump_rev_end: > svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool, > _("* Dumped revision %ld.\n"), > @@ -1527,7 +1536,8 @@ > if (! opt_state->quiet) > progress_stream = recode_stream_create(stderr, pool); > > - return svn_repos_verify_fs2(repos, lower, upper, > + return svn_repos_verify_fs3(repos, lower, upper, > + opt_state->keep_going, > !opt_state->quiet > ? repos_notify_handler : NULL, > progress_stream, check_cancel, NULL, pool); > @@ -1992,6 +2002,9 @@ > case svnadmin__pre_1_8_compatible: > opt_state.pre_1_8_compatible = TRUE; > break; > + case svnadmin__keep_going: > + opt_state.keep_going = TRUE; > + break; > case svnadmin__fs_type: > SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_state.fs_type, opt_arg, > pool)); > break; > Index: subversion/libsvn_fs_base/fs.c > =================================================================== > --- subversion/libsvn_fs_base/fs.c (revision 1402414) > +++ subversion/libsvn_fs_base/fs.c (working copy) > @@ -896,6 +896,7 @@ > void *cancel_baton, > svn_revnum_t start, > svn_revnum_t end, > + svn_boolean_t keep_going, > apr_pool_t *pool, > apr_pool_t *common_pool) > { > Index: subversion/include/svn_fs.h > =================================================================== > --- subversion/include/svn_fs.h (revision 1402414) > +++ subversion/include/svn_fs.h (working copy) > @@ -280,6 +280,7 @@ > void *cancel_baton, > svn_revnum_t start, > svn_revnum_t end, > + svn_boolean_t keep_going, > apr_pool_t *scratch_pool); > > /** > Index: subversion/include/svn_repos.h > =================================================================== > --- subversion/include/svn_repos.h (revision 1402414) > +++ subversion/include/svn_repos.h (working copy) > @@ -193,6 +193,9 @@ > /** A warning message is waiting. */ > svn_repos_notify_warning = 0, > > + /** A revision is found with corruption/errors. */ > + svn_repos_notify_failure, > + This enum has already been released in 1.7! We must add new values at the end to preserve binary compatibility. So please put svn_repos_notify_failure after svn_repos_notify_load_skipped_rev. And please add "@since New in 1.8" to the docstring, like this: /** A revision is found with corruption/errors. @since New in 1.8. */ > /** A revision has finished being dumped. */ > svn_repos_notify_dump_rev_end, > > @@ -318,9 +321,13 @@ > /** For #svn_repos_notify_load_node_start, the path of the node. */ > const char *path; > > + /** The error chain. */ Please expand this comment to explain the intended use of this field. I'd suggest: /** For #svn_repos_notify_failure, this error chain indicates what * went wrong during verification. */ > + svn_error_t *err; > + > /* NOTE: Add new fields at the end to preserve binary compatibility. > Also, if you add fields here, you have to update > svn_repos_notify_create(). */ > + Why add a blank line here? > } svn_repos_notify_t; > > /** Callback for providing notification from the repository. > @@ -2517,8 +2524,29 @@ > * cancel_baton as argument to see if the caller wishes to cancel the > * verification. > * > + * If @a keep_going is @c TRUE, the verify process prints the error message > + * to the stderr and continues. > + * > + * @since New in 1.8. > + */ > +svn_error_t * > +svn_repos_verify_fs3(svn_repos_t *repos, > + svn_revnum_t start_rev, > + svn_revnum_t end_rev, > + svn_boolean_t keep_going, > + svn_repos_notify_func_t notify_func, > + void *notify_baton, > + svn_cancel_func_t cancel, > + void *cancel_baton, > + apr_pool_t *scratch_pool); > + > +/** > + * Similar to svn_repos_verify_fs3(), but without force. It's now called 'keep_going', not 'force'. I'd suggest to say: * Like svn_repos_verify_fs3(), but with @a keep_going set to @c FALSE. > + * > * @since New in 1.7. > + * @deprecated Provided for backward compatibility with the 1.7 API. > */ > +SVN_DEPRECATED > svn_error_t * > svn_repos_verify_fs2(svn_repos_t *repos, > svn_revnum_t start_rev, > Implement svnadmin verify --keep-going, which would continue the verification > even if there is some corruption, after printing the errors to stderr. > > * subversion/svnadmin/main.c > (svnadmin__cmdline_options_t): Missing change description? Or has svnadmin__cmdline_options_t not changed? > (svnadmin_opt_state) : add keep-going option. The indentation style of the log message differs from the style we usually use. I'd suggest formatting log entries like this: * subversion/svnadmin/main.c (svnadmin_opt_state): add keep-going option. (subcommand_verify): uses the new svn_repos_verify_fs3 function. (repos_notify_handler): svn_repos_notify_failure handles failure and prints warning to stderr. I'd also suggest using proper capitalisation. * subversion/svnadmin/main.c (svnadmin_opt_state): Add keep-going option. What follows are stylistic suggestions. Log messages all differ based on personal style and preferences. There are no strict guidelines and what follows is just my personal opinion. > (subcommand_verify) : uses the new svn_repos_verify_fs3 function. The above doesn't describe the change itself but the result of the change. Also, third-person simple present verbs like "X uses Y" makes it sounds as if you're stating a fact, something that is always true and independent of your change, rather than describing a change you are making. Compare to this: (subcommand_verify): Switch to the new svn_repos_verify_fs3 function instead of svn_repos_verify_fs2, and pass the keep-going option. I've added a minor detail by mentioning the keep-going option. When describing changes I often try to describe each chunk of the diff in a way that allows the reader of the log message to imagine what the chunk might look like. This might seem overly detailed and it's not a strict requirement of the project. But I found that this helps me with writing log messages that I can make sense of myself when I read them again half a year later :) > (repos_notify_handler) : svn_repos_notify_failure handles failure and > prints warning to stderr. When expressing code changes in English, I prefer to phrase data structures (in this case, svn_repos_notify_failure) as grammatical objects and executing code acting on the data (in this case, repos_notify_handler) as the grammatical subject acting on the object. Your wording suggests that svn_repos_notify_failure (the data), and not repos_notify_handler (the executing code), prints the warning to stderr. Compare to phrasing it like this: (repos_notify_handler): Handle svn_repos_notify_failure notification by printing warnings to stderr. That's all for now. I haven't tried to compile and run the patch yet. You might also want to add a regression test for your change, by the way, to make sure the --keep-going option doesn't break when we make further changes in the future. But that can be done as a separate patch. Thanks! > > * subversion/include/svn_repos.h > (svn_repos_notify_action_t): add svn_repos_notify_failure to notify failure. > (svn_repos_verify_fs3) : newly added to handle "keep-going" option. > > * subversion/include/svn_fs.h > (svn_fs_verify) : handles keep-going. If keep-going is TRUE, svn_fs_verify > would return no error. > > * subversion/libsvn_fs_fs/fs_fs.h > (svn_fs_fs__verify) : added the keep_going parameter. > > * subversion/libsvn_fs_fs/fs_fs.c > (svn_fs_fs__verify) : handles keep_going. If keep_going is TRUE, > SVN_NO_ERROR > is returned upon failure too. > > * subversion/libsvn_fs/fs-loader.h > (fs_library_vtable_t) : added keep_going parameter. > > * subversion/libsvn_fs/fs-loader.c > (svn_fs_verify) : handles keep_going, which is also passed on to > vtable->verify_fs. > > * subversion/libsvn_fs_base/fs.c > (base_verify) : handles keep_going parameter. > > * subversion/libsvn_fs_fs/fs.c > (fs_verify) : send keep_going to svn_fs_fs__verify function. > > * subversion/libsvn_repos/dump.c > (svn_repos_verify_fs3): now handles "keep-going". > If "keep-going" is TRUE, then the error message is > written to the stderr and verify process continues. > > * subversion/libsvn_repos/deprecated.c > (svn_repos_verify_fs2) : deprecated. > Now calls svn_repos_verify_fs3 with keep-going as > FALSE. > > > Patch by: Prabhu Gnana Sundar <prabhugs{_AT_}collab.net>