Coverage Report

Created: 2024-02-25 07:20

/src/libewf/libewf/libewf_data_chunk.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Data chunk functions
3
 *
4
 * Copyright (C) 2006-2023, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <memory.h>
24
#include <types.h>
25
26
#include "libewf_data_chunk.h"
27
#include "libewf_definitions.h"
28
#include "libewf_io_handle.h"
29
#include "libewf_libcerror.h"
30
#include "libewf_libcthreads.h"
31
#include "libewf_types.h"
32
#include "libewf_write_io_handle.h"
33
34
/* Creates a data chunk
35
 * Make sure the value data_chunk is referencing, is set to NULL
36
 * Returns 1 if successful or -1 on error
37
 */
38
int libewf_data_chunk_initialize(
39
     libewf_data_chunk_t **data_chunk,
40
     libewf_io_handle_t *io_handle,
41
     libewf_write_io_handle_t *write_io_handle,
42
     libcerror_error_t **error )
43
0
{
44
0
  libewf_internal_data_chunk_t *internal_data_chunk = NULL;
45
0
  static char *function                             = "libewf_data_chunk_initialize";
46
47
0
  if( data_chunk == NULL )
48
0
  {
49
0
    libcerror_error_set(
50
0
     error,
51
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
52
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
53
0
     "%s: invalid data chunk.",
54
0
     function );
55
56
0
    return( -1 );
57
0
  }
58
0
  if( *data_chunk != NULL )
59
0
  {
60
0
    libcerror_error_set(
61
0
     error,
62
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
63
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
64
0
     "%s: invalid data chunk value already set.",
65
0
     function );
66
67
0
    return( -1 );
68
0
  }
69
0
  if( io_handle == NULL )
70
0
  {
71
0
    libcerror_error_set(
72
0
     error,
73
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
74
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
75
0
     "%s: invalid IO handle.",
76
0
     function );
77
78
0
    return( -1 );
79
0
  }
80
0
  internal_data_chunk = memory_allocate_structure(
81
0
                         libewf_internal_data_chunk_t );
82
83
0
  if( internal_data_chunk == NULL )
84
0
  {
85
0
    libcerror_error_set(
86
0
     error,
87
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
88
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
89
0
     "%s: unable to create data chunk.",
90
0
     function );
91
92
0
    goto on_error;
93
0
  }
94
0
  if( memory_set(
95
0
       internal_data_chunk,
96
0
       0,
97
0
       sizeof( libewf_internal_data_chunk_t ) ) == NULL )
98
0
  {
99
0
    libcerror_error_set(
100
0
     error,
101
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
102
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
103
0
     "%s: unable to clear data chunk.",
104
0
     function );
105
106
0
    memory_free(
107
0
     internal_data_chunk );
108
109
0
    return( -1 );
110
0
  }
111
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
112
0
  if( libcthreads_read_write_lock_initialize(
113
0
       &( internal_data_chunk->read_write_lock ),
114
0
       error ) != 1 )
115
0
  {
116
0
    libcerror_error_set(
117
0
     error,
118
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
119
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
120
0
     "%s: unable to initialize read/write lock.",
121
0
     function );
122
123
0
    goto on_error;
124
0
  }
125
0
#endif
126
0
  internal_data_chunk->io_handle       = io_handle;
127
0
  internal_data_chunk->write_io_handle = write_io_handle;
128
129
0
  *data_chunk = (libewf_data_chunk_t *) internal_data_chunk;
130
131
0
  return( 1 );
132
133
0
on_error:
134
0
  if( internal_data_chunk != NULL )
135
0
  {
136
0
    memory_free(
137
0
     internal_data_chunk );
138
0
  }
139
0
  return( -1 );
140
0
}
141
142
/* Frees a data chunk
143
 * Returns 1 if successful or -1 on error
144
 */
145
int libewf_data_chunk_free(
146
     libewf_data_chunk_t **data_chunk,
147
     libcerror_error_t **error )
148
0
{
149
0
  libewf_internal_data_chunk_t *internal_data_chunk = NULL;
150
0
  static char *function                             = "libewf_data_chunk_free";
151
0
  int result                                        = 1;
152
153
0
  if( data_chunk == NULL )
154
0
  {
155
0
    libcerror_error_set(
156
0
     error,
157
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
158
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
159
0
     "%s: invalid data chunk.",
160
0
     function );
161
162
0
    return( -1 );
163
0
  }
164
0
  if( *data_chunk != NULL )
165
0
  {
166
0
    internal_data_chunk = (libewf_internal_data_chunk_t *) *data_chunk;
167
0
    *data_chunk         = NULL;
168
169
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
170
0
    if( libcthreads_read_write_lock_free(
171
0
         &( internal_data_chunk->read_write_lock ),
172
0
         error ) != 1 )
173
0
    {
174
0
      libcerror_error_set(
175
0
       error,
176
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
177
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
178
0
       "%s: unable to free read/write lock.",
179
0
       function );
180
181
0
      result = -1;
182
0
    }
183
0
#endif
184
0
    if( libewf_chunk_data_free(
185
0
         &( internal_data_chunk->chunk_data ),
186
0
         error ) != 1 )
187
0
    {
188
0
      libcerror_error_set(
189
0
       error,
190
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
191
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
192
0
       "%s: unable to free chunk data.",
193
0
       function );
194
195
0
      result = -1;
196
0
    }
197
    /* The io_handle and write_io_handle references are freed elsewhere
198
     */
199
0
    memory_free(
200
0
     internal_data_chunk );
201
0
  }
202
0
  return( result );
203
0
}
204
205
/* Sets the chunk data in the data chunk
206
 * Returns 1 if successful or -1 on error
207
 */
208
int libewf_internal_data_chunk_set_chunk_data(
209
     libewf_internal_data_chunk_t *internal_data_chunk,
210
     libewf_chunk_data_t *chunk_data,
211
     libcerror_error_t **error )
212
0
{
213
0
  static char *function = "libewf_internal_data_chunk_set_chunk_data";
214
0
  int result            = 1;
215
216
0
  if( internal_data_chunk == NULL )
217
0
  {
218
0
    libcerror_error_set(
219
0
     error,
220
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
221
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
222
0
     "%s: invalid data chunk.",
223
0
     function );
224
225
0
    return( -1 );
226
0
  }
227
0
  if( chunk_data == NULL )
228
0
  {
229
0
    libcerror_error_set(
230
0
     error,
231
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
232
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
233
0
     "%s: invalid chunk data.",
234
0
     function );
235
236
0
    return( -1 );
237
0
  }
238
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
239
0
  if( libcthreads_read_write_lock_grab_for_write(
240
0
       internal_data_chunk->read_write_lock,
241
0
       error ) != 1 )
242
0
  {
243
0
    libcerror_error_set(
244
0
     error,
245
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
246
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
247
0
     "%s: unable to grab read/write lock for writing.",
248
0
     function );
249
250
0
    return( -1 );
251
0
  }
252
0
#endif
253
0
  if( internal_data_chunk->chunk_data != NULL )
254
0
  {
255
0
    if( libewf_chunk_data_free(
256
0
         &( internal_data_chunk->chunk_data ),
257
0
         error ) != 1 )
258
0
    {
259
0
      libcerror_error_set(
260
0
       error,
261
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
262
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
263
0
       "%s: unable to free chunk data.",
264
0
       function );
265
266
0
      result = -1;
267
0
    }
268
0
  }
269
0
  if( result != -1 )
270
0
  {
271
0
    internal_data_chunk->chunk_data = chunk_data;
272
0
  }
273
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
274
0
  if( libcthreads_read_write_lock_release_for_write(
275
0
       internal_data_chunk->read_write_lock,
276
0
       error ) != 1 )
277
0
  {
278
0
    libcerror_error_set(
279
0
     error,
280
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
281
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
282
0
     "%s: unable to release read/write lock for writing.",
283
0
     function );
284
285
0
    return( -1 );
286
0
  }
287
0
#endif
288
0
  return( result );
289
0
}
290
291
/* Determines if the data chunk is corrupted
292
 * Returns 1 if the data chunk is corrupted, 0 if not or -1 on error
293
 */
294
int libewf_data_chunk_is_corrupted(
295
     libewf_data_chunk_t *data_chunk,
296
     libcerror_error_t **error )
297
0
{
298
0
  libewf_internal_data_chunk_t *internal_data_chunk = NULL;
299
0
  static char *function                             = "libewf_data_chunk_is_corrupted";
300
0
  int result                                        = 0;
301
302
0
  if( data_chunk == NULL )
303
0
  {
304
0
    libcerror_error_set(
305
0
     error,
306
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
307
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
308
0
     "%s: invalid data chunk.",
309
0
     function );
310
311
0
    return( -1 );
312
0
  }
313
0
  internal_data_chunk = (libewf_internal_data_chunk_t *) data_chunk;
314
315
0
  if( internal_data_chunk->chunk_data == NULL )
316
0
  {
317
0
    libcerror_error_set(
318
0
     error,
319
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
320
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
321
0
     "%s: invalid data chunk - missing chunk data.",
322
0
     function );
323
324
0
    return( -1 );
325
0
  }
326
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
327
0
  if( libcthreads_read_write_lock_grab_for_read(
328
0
       internal_data_chunk->read_write_lock,
329
0
       error ) != 1 )
330
0
  {
331
0
    libcerror_error_set(
332
0
     error,
333
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
334
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
335
0
     "%s: unable to grab read/write lock for reading.",
336
0
     function );
337
338
0
    return( -1 );
339
0
  }
340
0
#endif
341
0
  if( ( internal_data_chunk->chunk_data->range_flags & LIBEWF_RANGE_FLAG_IS_CORRUPTED ) != 0 )
342
0
  {
343
0
    result = 1;
344
0
  }
345
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
346
0
  if( libcthreads_read_write_lock_release_for_read(
347
0
       internal_data_chunk->read_write_lock,
348
0
       error ) != 1 )
349
0
  {
350
0
    libcerror_error_set(
351
0
     error,
352
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
353
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
354
0
     "%s: unable to release read/write lock for reading.",
355
0
     function );
356
357
0
    return( -1 );
358
0
  }
359
0
#endif
360
0
  return( result );
361
0
}
362
363
/* Reads a buffer from the data chunk
364
 * It applies decompression if necessary and validates the chunk checksum
365
 * This function should be used after libewf_handle_read_data_chunk
366
 * Returns the number of bytes read, 0 when no longer data can be read or -1 on error
367
 */
368
ssize_t libewf_data_chunk_read_buffer(
369
         libewf_data_chunk_t *data_chunk,
370
         void *buffer,
371
         size_t buffer_size,
372
         libcerror_error_t **error )
373
0
{
374
0
  libewf_internal_data_chunk_t *internal_data_chunk = NULL;
375
0
  static char *function                             = "libewf_data_chunk_read_buffer";
376
0
  ssize_t read_count                                = 0;
377
378
0
  if( data_chunk == NULL )
379
0
  {
380
0
    libcerror_error_set(
381
0
     error,
382
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
383
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
384
0
     "%s: invalid data chunk.",
385
0
     function );
386
387
0
    return( -1 );
388
0
  }
389
0
  internal_data_chunk = (libewf_internal_data_chunk_t *) data_chunk;
390
391
0
  if( internal_data_chunk->chunk_data == NULL )
392
0
  {
393
0
    libcerror_error_set(
394
0
     error,
395
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
396
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
397
0
     "%s: invalid data chunk - missing chunk data.",
398
0
     function );
399
400
0
    return( -1 );
401
0
  }
402
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
403
0
  if( libcthreads_read_write_lock_grab_for_write(
404
0
       internal_data_chunk->read_write_lock,
405
0
       error ) != 1 )
406
0
  {
407
0
    libcerror_error_set(
408
0
     error,
409
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
410
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
411
0
     "%s: unable to grab read/write lock for writing.",
412
0
     function );
413
414
0
    return( -1 );
415
0
  }
416
0
#endif
417
0
  if( ( internal_data_chunk->chunk_data->range_flags & LIBEWF_RANGE_FLAG_IS_PACKED ) != 0 )
418
0
  {
419
/* TODO optimize to unpack directly to buffer */
420
0
    if( libewf_chunk_data_unpack(
421
0
         internal_data_chunk->chunk_data,
422
0
         internal_data_chunk->io_handle,
423
0
         error ) != 1 )
424
0
    {
425
0
      libcerror_error_set(
426
0
       error,
427
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
428
0
       LIBCERROR_RUNTIME_ERROR_GENERIC,
429
0
       "%s: unable to unpack chunk: %" PRIu64 " data.",
430
0
       function,
431
0
       internal_data_chunk->chunk_data->chunk_index );
432
433
0
      read_count = -1;
434
0
    }
435
0
  }
436
0
  if( read_count != -1 )
437
0
  {
438
0
    read_count = libewf_chunk_data_read_buffer(
439
0
                  internal_data_chunk->chunk_data,
440
0
                  buffer,
441
0
                  buffer_size,
442
0
                  error );
443
444
0
    if( read_count < 0 )
445
0
    {
446
0
      libcerror_error_set(
447
0
       error,
448
0
       LIBCERROR_ERROR_DOMAIN_IO,
449
0
       LIBCERROR_IO_ERROR_READ_FAILED,
450
0
       "%s: unable to read chunk: %" PRIu64 " data.",
451
0
       function,
452
0
       internal_data_chunk->chunk_data->chunk_index );
453
454
0
      read_count = -1;
455
0
    }
456
0
  }
457
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
458
0
  if( libcthreads_read_write_lock_release_for_write(
459
0
       internal_data_chunk->read_write_lock,
460
0
       error ) != 1 )
461
0
  {
462
0
    libcerror_error_set(
463
0
     error,
464
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
465
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
466
0
     "%s: unable to release read/write lock for writing.",
467
0
     function );
468
469
0
    return( -1 );
470
0
  }
471
0
#endif
472
0
  return( read_count );
473
0
}
474
475
/* Writes a buffer to the data chunk
476
 * It applies compression if necessary and calculated the chunk checksum
477
 * This function should be used before libewf_handle_write_data_chunk
478
 * Returns the number of bytes written, 0 when no longer data can be written or -1 on error
479
 */
480
ssize_t libewf_data_chunk_write_buffer(
481
         libewf_data_chunk_t *data_chunk,
482
         const void *buffer,
483
         size_t buffer_size,
484
         libcerror_error_t **error )
485
0
{
486
0
  libewf_internal_data_chunk_t *internal_data_chunk = NULL;
487
0
  static char *function                             = "libewf_data_chunk_write_buffer";
488
0
  ssize_t write_count                               = 0;
489
490
0
  if( data_chunk == NULL )
491
0
  {
492
0
    libcerror_error_set(
493
0
     error,
494
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
495
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
496
0
     "%s: invalid data chunk.",
497
0
     function );
498
499
0
    return( -1 );
500
0
  }
501
0
  internal_data_chunk = (libewf_internal_data_chunk_t *) data_chunk;
502
503
0
  if( internal_data_chunk->io_handle == NULL )
504
0
  {
505
0
    libcerror_error_set(
506
0
     error,
507
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
508
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
509
0
     "%s: invalid data chunk - missing IO handle.",
510
0
     function );
511
512
0
    return( -1 );
513
0
  }
514
0
  if( internal_data_chunk->write_io_handle == NULL )
515
0
  {
516
0
    libcerror_error_set(
517
0
     error,
518
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
519
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
520
0
     "%s: invalid data chunk - missing write IO handle.",
521
0
     function );
522
523
0
    return( -1 );
524
0
  }
525
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
526
0
  if( libcthreads_read_write_lock_grab_for_write(
527
0
       internal_data_chunk->read_write_lock,
528
0
       error ) != 1 )
529
0
  {
530
0
    libcerror_error_set(
531
0
     error,
532
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
533
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
534
0
     "%s: unable to grab read/write lock for writing.",
535
0
     function );
536
537
0
    return( -1 );
538
0
  }
539
0
#endif
540
0
  if( internal_data_chunk->chunk_data != NULL )
541
0
  {
542
0
    if( libewf_chunk_data_free(
543
0
         &( internal_data_chunk->chunk_data ),
544
0
         error ) != 1 )
545
0
    {
546
0
      libcerror_error_set(
547
0
       error,
548
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
549
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
550
0
       "%s: unable to free chunk data.",
551
0
       function );
552
553
0
      goto on_error;
554
0
    }
555
0
  }
556
0
  if( libewf_chunk_data_initialize(
557
0
       &( internal_data_chunk->chunk_data ),
558
0
       internal_data_chunk->io_handle->chunk_size,
559
0
       0,
560
0
       error ) != 1 )
561
0
  {
562
0
    libcerror_error_set(
563
0
     error,
564
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
565
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
566
0
     "%s: unable to create chunk data.",
567
0
     function );
568
569
0
    goto on_error;
570
0
  }
571
0
  write_count = libewf_chunk_data_write_buffer(
572
0
                 internal_data_chunk->chunk_data,
573
0
                 buffer,
574
0
                 buffer_size,
575
0
                 error );
576
577
0
  if( write_count < 0 )
578
0
  {
579
0
    libcerror_error_set(
580
0
     error,
581
0
     LIBCERROR_ERROR_DOMAIN_IO,
582
0
     LIBCERROR_IO_ERROR_WRITE_FAILED,
583
0
     "%s: unable to write buffer to chunk data.",
584
0
     function );
585
586
0
    goto on_error;
587
0
  }
588
0
  internal_data_chunk->data_size = buffer_size;
589
590
0
  if( libewf_chunk_data_pack(
591
0
       internal_data_chunk->chunk_data,
592
0
       internal_data_chunk->io_handle,
593
0
       internal_data_chunk->write_io_handle->compressed_zero_byte_empty_block,
594
0
       internal_data_chunk->write_io_handle->compressed_zero_byte_empty_block_size,
595
0
       internal_data_chunk->write_io_handle->pack_flags,
596
0
       error ) != 1 )
597
0
  {
598
0
    libcerror_error_set(
599
0
     error,
600
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
601
0
     LIBCERROR_RUNTIME_ERROR_GENERIC,
602
0
     "%s: unable to pack chunk data.",
603
0
     function );
604
605
0
    goto on_error;
606
0
  }
607
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
608
0
  if( libcthreads_read_write_lock_release_for_write(
609
0
       internal_data_chunk->read_write_lock,
610
0
       error ) != 1 )
611
0
  {
612
0
    libcerror_error_set(
613
0
     error,
614
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
615
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
616
0
     "%s: unable to release read/write lock for writing.",
617
0
     function );
618
619
0
    return( -1 );
620
0
  }
621
0
#endif
622
0
  return( write_count );
623
624
0
on_error:
625
0
#if defined( HAVE_LIBEWF_MULTI_THREAD_SUPPORT )
626
0
  libcthreads_read_write_lock_release_for_write(
627
0
   internal_data_chunk->read_write_lock,
628
0
   NULL );
629
0
#endif
630
0
  return( -1 );
631
0
}
632