@@ -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 }
128131 if (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 ;
142150 return true;
143151 }
144152 if (statbuf .st_size != 0 )
@@ -150,12 +158,20 @@ open_walfile(StreamCtl *stream, XLogRecPtr startpoint)
150158 return 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+ */
154166 zerobuf = pg_malloc0 (XLOG_BLCKSZ );
155167 for (bytes = 0 ; bytes < XLogSegSize ; bytes += XLOG_BLCKSZ )
156168 {
169+ errno = 0 ;
157170 if (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 ;
159175 fprintf (stderr ,
160176 _ ("%s: could not pad transaction log file \"%s\": %s\n" ),
161177 progname , 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
181203 if (lseek (f , SEEK_SET , 0 ) != 0 )
182204 {
@@ -186,6 +208,8 @@ open_walfile(StreamCtl *stream, XLogRecPtr startpoint)
186208 close (f );
187209 return false;
188210 }
211+
212+ /* File is open and ready to use */
189213 walfile = f ;
190214 return true;
191215}
@@ -209,13 +233,17 @@ close_walfile(StreamCtl *stream, XLogRecPtr pos)
209233 fprintf (stderr ,
210234 _ ("%s: could not determine seek position in file \"%s\": %s\n" ),
211235 progname , current_walfile_name , strerror (errno ));
236+ close (walfile );
237+ walfile = -1 ;
212238 return false;
213239 }
214240
215241 if (stream -> do_sync && fsync (walfile ) != 0 )
216242 {
217243 fprintf (stderr , _ ("%s: could not fsync file \"%s\": %s\n" ),
218244 progname , current_walfile_name , strerror (errno ));
245+ close (walfile );
246+ walfile = -1 ;
219247 return false;
220248 }
221249
0 commit comments