AMPI #952: update ROMIO to MPICH2-1.4.1p1
[charm.git] / src / libs / ck-libs / ampi / romio / adio / common / ad_prealloc.c
blobcd18dbb2838cae6cde115e62071056b816b4441a
1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
2 /*
4 * Copyright (C) 2004 University of Chicago.
5 * See COPYRIGHT notice in top-level directory.
6 */
8 #include "adio.h"
9 #include "adio_extern.h"
11 /* this used to be implemented in every file system as an fcntl, but the code
12 * is identical for all file systems without a real "preallocate" system call.
13 * This naive approach will get the job done, but not in a terribly efficient
14 * manner.
16 void ADIOI_GEN_Prealloc(ADIO_File fd, ADIO_Offset diskspace, int *error_code)
18 ADIO_Offset curr_fsize, alloc_size, size, len, done;
19 ADIO_Status status;
20 int i, ntimes;
21 char *buf;
22 ADIO_Fcntl_t *fcntl_struct;
23 static char myname[] = "ADIOI_GEN_PREALLOC";
25 /* will be called by one process only */
26 /* On file systems with no preallocation function, we have to
27 explicitly write
28 to allocate space. Since there could be holes in the file,
29 we need to read up to the current file size, write it back,
30 and then write beyond that depending on how much
31 preallocation is needed.
32 read/write in sizes of no more than ADIOI_PREALLOC_BUFSZ */
34 /*curr_fsize = fd->fp_ind; */
35 fcntl_struct = (ADIO_Fcntl_t *) ADIOI_Malloc(sizeof(ADIO_Fcntl_t));
36 ADIO_Fcntl(fd, ADIO_FCNTL_GET_FSIZE, fcntl_struct, error_code);
38 curr_fsize = fcntl_struct->fsize; /* don't rely on fd->fp_ind: might be
39 working on a pre-existing file */
40 alloc_size = diskspace;
42 size = ADIOI_MIN(curr_fsize, alloc_size);
44 ntimes = (size + ADIOI_PREALLOC_BUFSZ - 1)/ADIOI_PREALLOC_BUFSZ;
45 buf = (char *) ADIOI_Malloc(ADIOI_PREALLOC_BUFSZ);
46 done = 0;
48 for (i=0; i<ntimes; i++) {
49 len = ADIOI_MIN(size-done, ADIOI_PREALLOC_BUFSZ);
50 ADIO_ReadContig(fd, buf,
51 len, /* len is ADIO_Offset but is <= ADIOI_PREALLOC_BUFSZ (16M),
52 so it fits in an int parameter */
53 MPI_BYTE, ADIO_EXPLICIT_OFFSET, done,
54 &status, error_code);
55 if (*error_code != MPI_SUCCESS) {
56 *error_code = MPIO_Err_create_code(MPI_SUCCESS,
57 MPIR_ERR_RECOVERABLE,
58 myname, __LINE__,
59 MPI_ERR_IO,
60 "**iopreallocrdwr",
61 0);
62 return;
64 ADIO_WriteContig(fd, buf,
65 len, /* len is ADIO_Offset but is <= ADIOI_PREALLOC_BUFSZ (16M),
66 so it fits in an int parameter */
67 MPI_BYTE, ADIO_EXPLICIT_OFFSET,
68 done, &status, error_code);
69 if (*error_code != MPI_SUCCESS) return;
70 done += len;
73 if (alloc_size > curr_fsize) {
74 memset(buf, 0, ADIOI_PREALLOC_BUFSZ);
75 size = alloc_size - curr_fsize;
76 ntimes = (size + ADIOI_PREALLOC_BUFSZ - 1)/ADIOI_PREALLOC_BUFSZ;
77 for (i=0; i<ntimes; i++) {
78 len = ADIOI_MIN(alloc_size-done, ADIOI_PREALLOC_BUFSZ);
79 ADIO_WriteContig(fd, buf,
80 len, /* len is ADIO_Offset but is <= ADIOI_PREALLOC_BUFSZ (16M),
81 so it fits in an int parameter */
82 MPI_BYTE, ADIO_EXPLICIT_OFFSET,
83 done, &status, error_code);
84 if (*error_code != MPI_SUCCESS) return;
85 done += len;
88 ADIOI_Free(fcntl_struct);
89 ADIOI_Free(buf);
90 *error_code = MPI_SUCCESS;