1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2 /*
3 *
4 * Copyright (C) 2007 UChicago/Argonne LLC
5 * See COPYRIGHT notice in top-level directory.
6 */
7
8 #include "adio.h"
9
10
11 /* this "collective" open is useful for frankly broken file systems such
12 * as NFS where a create from one client might not be immediately
13 * visible on another */
14
15 void ADIOI_FAILSAFE_OpenColl(ADIO_File fd, int rank,
16 int access_mode, int *error_code)
17 {
18 MPI_Comm tmp_comm;
19 int orig_amode_excl, orig_amode_wronly;
20
21 orig_amode_excl = access_mode;
22 if ((access_mode & ADIO_CREATE) && (access_mode & ADIO_EXCL)) {
23 /* the open should fail if the file exists. Only *1* process
24 * should check this. Otherwise, if all processes try to check
25 * and the file does not exist, one process will create the file
26 * and others who reach later will return error. */
27 if(rank == fd->hints->ranklist[0]) {
28 fd->access_mode = access_mode;
29
30 /* if the lower-level file system tries to communicate, COMM_SELF
31 * will ensure it doesn't get stuck waiting for non-existant
32 * participants */
33 tmp_comm = fd->comm;
34 fd->comm = MPI_COMM_SELF;
35 (*(fd->fns->ADIOI_xxx_Open))(fd, error_code);
36 MPI_Bcast(error_code, 1, MPI_INT, \
37 fd->hints->ranklist[0], tmp_comm);
38 /* if no error, close the file and reopen normally below */
39 if (*error_code == MPI_SUCCESS)
40 (*(fd->fns->ADIOI_xxx_Close))(fd, error_code);
41 /* and put it all back the way we found it for subsequent code */
42 fd->comm = tmp_comm;
43 }
44 else MPI_Bcast(error_code, 1, MPI_INT,
45 fd->hints->ranklist[0], fd->comm);
46 if (*error_code != MPI_SUCCESS) {
47 return;
48 }
49 else {
50 /* turn off EXCL for real open */
51 access_mode = access_mode ^ ADIO_EXCL;
52 }
53 }
54 /* if we are doing deferred open, non-aggregators should return now */
55 if (fd->hints->deferred_open && !(fd->is_agg)) {
56 /* we might have turned off EXCL for the aggregators.
57 * restore access_mode that non-aggregators get the right
58 * value from get_amode */
59 fd->access_mode = orig_amode_excl;
60 *error_code = MPI_SUCCESS;
61 return;
62 }
63
64 /* For writing with data sieving, a read-modify-write is needed. If
65 the file is opened for write_only, the read will fail. Therefore,
66 if write_only, open the file as read_write, but record it as write_only
67 in fd, so that get_amode returns the right answer. */
68
69 orig_amode_wronly = access_mode;
70 if (access_mode & ADIO_WRONLY) {
71 access_mode = access_mode ^ ADIO_WRONLY;
72 access_mode = access_mode | ADIO_RDWR;
73 }
74 fd->access_mode = access_mode;
75
76 (*(fd->fns->ADIOI_xxx_Open))(fd, error_code);
77
78 /* if error, may be it was due to the change in amode above.
79 therefore, reopen with access mode provided by the user.*/
80 fd->access_mode = orig_amode_wronly;
81 if (*error_code != MPI_SUCCESS)
82 (*(fd->fns->ADIOI_xxx_Open))(fd, error_code);
83
84 if(*error_code != MPI_SUCCESS) return;
85 /* if we turned off EXCL earlier, then we should turn it back on */
86 if (fd->access_mode != orig_amode_excl) fd->access_mode = orig_amode_excl;
87
88 /* for deferred open: this process has opened the file (because if we are
89 * not an aggregaor and we are doing deferred open, we returned earlier)*/
90 fd->is_open = 1;
91 }
92
93
94
95 /*
96 * vim: ts=8 sts=4 sw=4 noexpandtab
97 */