@@ -380,10 +380,30 @@ hdfs_calculate_checksum(hdfs_handle_t *hdfs_handle, hdfsFS fs, const char *type)
380380 return rc ;
381381}
382382
383+ /*
384+ * Returns 1 if the requested checksum type is supported; 0 otherwise.
385+ */
386+ static int
387+ hdfs_checksum_type_supported (hdfs_handle_t * hdfs_handle , const char * requested_cksm ) {
388+ return (
389+ (!strcasecmp ("MD5" , requested_cksm ) && (hdfs_handle -> cksm_types & HDFS_CKSM_TYPE_MD5 )) ||
390+ (!strcasecmp ("CKSUM" , requested_cksm ) && (hdfs_handle -> cksm_types & HDFS_CKSM_TYPE_CKSUM )) ||
391+ (!strcasecmp ("CRC32" , requested_cksm ) && (hdfs_handle -> cksm_types & HDFS_CKSM_TYPE_CRC32 )) ||
392+ (!strcasecmp ("ADLER32" , requested_cksm ) && (hdfs_handle -> cksm_types & HDFS_CKSM_TYPE_ADLER32 )) ||
393+ (!strcasecmp ("CVMFS" , requested_cksm ) && (hdfs_handle -> cksm_types & HDFS_CKSM_TYPE_CVMFS ))
394+ );
395+ }
396+
383397/*
384398 * Retrieve checksums.
385399 */
386- globus_result_t hdfs_get_checksum (hdfs_handle_t * hdfs_handle , const char * pathname , const char * requested_cksm , char * * cksm_value ) {
400+ static globus_result_t hdfs_get_checksum_internal (hdfs_handle_t * hdfs_handle , const char * pathname , const char * requested_cksm , char * * cksm_value , int recurse );
401+
402+ globus_result_t hdfs_get_checksum (hdfs_handle_t * hdfs_handle , const char * pathname , const char * requested_cksm , char * * cksm_value ) {
403+ return hdfs_get_checksum_internal (hdfs_handle , pathname , requested_cksm , cksm_value , 1 );
404+ }
405+
406+ globus_result_t hdfs_get_checksum_internal (hdfs_handle_t * hdfs_handle , const char * pathname , const char * requested_cksm , char * * cksm_value , int recurse ) {
387407
388408 globus_result_t rc = GLOBUS_SUCCESS ;
389409
@@ -462,9 +482,17 @@ globus_result_t hdfs_get_checksum(hdfs_handle_t *hdfs_handle, const char * pathn
462482 }
463483 ptr += 1 ;
464484 if (* ptr == '\0' ) {
465- char * err_str = globus_common_create_string ("Requested checksum type %s not found." , requested_cksm );
466- GenericError (hdfs_handle , err_str , rc );
467- globus_free (err_str );
485+ if (recurse && hdfs_checksum_type_supported (hdfs_handle , requested_cksm )) {
486+ // Try clearing the current checksum file and re-opening.
487+ hdfsCloseFile (fs , fh );
488+ hdfsDelete (fs , filename , 0 );
489+ fh = hdfsOpenFile (fs , filename , O_RDONLY , 0 , 0 , 0 );
490+ rc = hdfs_get_checksum_internal (hdfs_handle , pathname , requested_cksm , cksm_value , 0 );
491+ } else {
492+ char * err_str = globus_common_create_string ("Requested checksum type %s not found." , requested_cksm );
493+ GenericError (hdfs_handle , err_str , rc );
494+ globus_free (err_str );
495+ }
468496 break ;
469497 }
470498 }
@@ -473,8 +501,8 @@ globus_result_t hdfs_get_checksum(hdfs_handle_t *hdfs_handle, const char * pathn
473501 GenericError (hdfs_handle , "Failed to retrieve checksum" , rc );
474502 }
475503
476- // return -1 on err
477- if (hdfsCloseFile (fs , fh ) < 0 ) {
504+ // return -1 on err; we check for fh being null here as it may have been re-opened if we regenerate the checksum file above.
505+ if (fh && ( hdfsCloseFile (fs , fh ) < 0 ) ) {
478506 SystemError (hdfs_handle , "Failed to close checksum file" , rc );
479507 }
480508
0 commit comments