@@ -86,8 +86,11 @@ mark_file_as_archived(const char *basedir, const char *fname, bool do_sync)
8686/*
8787 * Open a new WAL file in the specified directory.
8888 *
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.
9194 */
9295static bool
9396open_walfile (StreamCtl * stream ,XLogRecPtr startpoint )
@@ -127,18 +130,23 @@ open_walfile(StreamCtl *stream, XLogRecPtr startpoint)
127130}
128131if (statbuf .st_size == XLogSegSize )
129132{
130- /* File is open and ready to use */
131- walfile = f ;
132-
133133/*
134134 * fsync, in case of a previous crash between padding and fsyncing the
135135 * file.
136136 */
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+ }
141147
148+ /* File is open and ready to use */
149+ walfile = f ;
142150return true;
143151}
144152if (statbuf .st_size != 0 )
@@ -150,12 +158,20 @@ open_walfile(StreamCtl *stream, XLogRecPtr startpoint)
150158return false;
151159}
152160
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+ */
154166zerobuf = pg_malloc0 (XLOG_BLCKSZ );
155167for (bytes = 0 ;bytes < XLogSegSize ;bytes += XLOG_BLCKSZ )
156168{
169+ errno = 0 ;
157170if (write (f ,zerobuf ,XLOG_BLCKSZ )!= XLOG_BLCKSZ )
158171{
172+ /* if write didn't set errno, assume problem is no disk space */
173+ if (errno == 0 )
174+ errno = ENOSPC ;
159175fprintf (stderr ,
160176_ ("%s: could not pad transaction log file \"%s\": %s\n" ),
161177progname ,fn ,strerror (errno ));
@@ -173,10 +189,16 @@ open_walfile(StreamCtl *stream, XLogRecPtr startpoint)
173189 * using synchronous mode, where the file is modified and fsynced
174190 * in-place, without a directory fsync.
175191 */
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+ }
180202
181203if (lseek (f ,SEEK_SET ,0 )!= 0 )
182204{
@@ -186,6 +208,8 @@ open_walfile(StreamCtl *stream, XLogRecPtr startpoint)
186208close (f );
187209return false;
188210}
211+
212+ /* File is open and ready to use */
189213walfile = f ;
190214return true;
191215}
@@ -209,13 +233,17 @@ close_walfile(StreamCtl *stream, XLogRecPtr pos)
209233fprintf (stderr ,
210234_ ("%s: could not determine seek position in file \"%s\": %s\n" ),
211235progname ,current_walfile_name ,strerror (errno ));
236+ close (walfile );
237+ walfile = -1 ;
212238return false;
213239}
214240
215241if (stream -> do_sync && fsync (walfile )!= 0 )
216242{
217243fprintf (stderr ,_ ("%s: could not fsync file \"%s\": %s\n" ),
218244progname ,current_walfile_name ,strerror (errno ));
245+ close (walfile );
246+ walfile = -1 ;
219247return false;
220248}
221249