@@ -86,8 +86,11 @@ mark_file_as_archived(const char *basedir, const char *fname, bool do_sync)
86
86
/*
87
87
* Open a new WAL file in the specified directory.
88
88
*
89
- * The file will be padded to 16Mb with zeroes. The base filename (without
90
- * partial_suffix) is stored in current_walfile_name.
89
+ * Returns true if OK; on failure, returns false after printing an error msg.
90
+ * On success, 'walfile' is set to the FD for the file, and the base filename
91
+ * (without partial_suffix) is stored in 'current_walfile_name'.
92
+ *
93
+ * The file will be padded to 16Mb with zeroes.
91
94
*/
92
95
static bool
93
96
open_walfile (StreamCtl * stream , XLogRecPtr startpoint )
@@ -127,18 +130,23 @@ open_walfile(StreamCtl *stream, XLogRecPtr startpoint)
127
130
}
128
131
if (statbuf .st_size == XLogSegSize )
129
132
{
130
- /* File is open and ready to use */
131
- walfile = f ;
132
-
133
133
/*
134
134
* fsync, in case of a previous crash between padding and fsyncing the
135
135
* file.
136
136
*/
137
- if (stream -> do_sync && fsync_fname (fn , false, progname ) != 0 )
138
- return false;
139
- if (stream -> do_sync && fsync_parent_path (fn , progname ) != 0 )
140
- return false;
137
+ if (stream -> do_sync )
138
+ {
139
+ if (fsync_fname (fn , false, progname ) != 0 ||
140
+ fsync_parent_path (fn , progname ) != 0 )
141
+ {
142
+ /* error already printed */
143
+ close (f );
144
+ return false;
145
+ }
146
+ }
141
147
148
+ /* File is open and ready to use */
149
+ walfile = f ;
142
150
return true;
143
151
}
144
152
if (statbuf .st_size != 0 )
@@ -150,12 +158,20 @@ open_walfile(StreamCtl *stream, XLogRecPtr startpoint)
150
158
return false;
151
159
}
152
160
153
- /* New, empty, file. So pad it to 16Mb with zeroes */
161
+ /*
162
+ * New, empty, file. So pad it to 16Mb with zeroes. If we fail partway
163
+ * through padding, we should attempt to unlink the file on failure, so as
164
+ * not to leave behind a partially-filled file.
165
+ */
154
166
zerobuf = pg_malloc0 (XLOG_BLCKSZ );
155
167
for (bytes = 0 ; bytes < XLogSegSize ; bytes += XLOG_BLCKSZ )
156
168
{
169
+ errno = 0 ;
157
170
if (write (f , zerobuf , XLOG_BLCKSZ ) != XLOG_BLCKSZ )
158
171
{
172
+ /* if write didn't set errno, assume problem is no disk space */
173
+ if (errno == 0 )
174
+ errno = ENOSPC ;
159
175
fprintf (stderr ,
160
176
_ ("%s: could not pad transaction log file \"%s\": %s\n" ),
161
177
progname , fn , strerror (errno ));
@@ -173,10 +189,16 @@ open_walfile(StreamCtl *stream, XLogRecPtr startpoint)
173
189
* using synchronous mode, where the file is modified and fsynced
174
190
* in-place, without a directory fsync.
175
191
*/
176
- if (stream -> do_sync && fsync_fname (fn , false, progname ) != 0 )
177
- return false;
178
- if (stream -> do_sync && fsync_parent_path (fn , progname ) != 0 )
179
- return false;
192
+ if (stream -> do_sync )
193
+ {
194
+ if (fsync_fname (fn , false, progname ) != 0 ||
195
+ fsync_parent_path (fn , progname ) != 0 )
196
+ {
197
+ /* error already printed */
198
+ close (f );
199
+ return false;
200
+ }
201
+ }
180
202
181
203
if (lseek (f , SEEK_SET , 0 ) != 0 )
182
204
{
@@ -186,6 +208,8 @@ open_walfile(StreamCtl *stream, XLogRecPtr startpoint)
186
208
close (f );
187
209
return false;
188
210
}
211
+
212
+ /* File is open and ready to use */
189
213
walfile = f ;
190
214
return true;
191
215
}
@@ -209,13 +233,17 @@ close_walfile(StreamCtl *stream, XLogRecPtr pos)
209
233
fprintf (stderr ,
210
234
_ ("%s: could not determine seek position in file \"%s\": %s\n" ),
211
235
progname , current_walfile_name , strerror (errno ));
236
+ close (walfile );
237
+ walfile = -1 ;
212
238
return false;
213
239
}
214
240
215
241
if (stream -> do_sync && fsync (walfile ) != 0 )
216
242
{
217
243
fprintf (stderr , _ ("%s: could not fsync file \"%s\": %s\n" ),
218
244
progname , current_walfile_name , strerror (errno ));
245
+ close (walfile );
246
+ walfile = -1 ;
219
247
return false;
220
248
}
221
249
0 commit comments