|
11 | 11 | *as a service.
|
12 | 12 | *
|
13 | 13 | * IDENTIFICATION
|
14 |
| - * $PostgreSQL: pgsql/src/port/copydir.c,v 1.33 2010/02/26 02:01:38 momjian Exp $ |
| 14 | + * $PostgreSQL: pgsql/src/port/copydir.c,v 1.34 2010/02/28 21:05:30 stark Exp $ |
15 | 15 | *
|
16 | 16 | *-------------------------------------------------------------------------
|
17 | 17 | */
|
|
37 | 37 |
|
38 | 38 |
|
39 | 39 | staticvoidcopy_file(char*fromfile,char*tofile);
|
40 |
| -staticvoidfsync_fname(char*fname); |
| 40 | +staticvoidfsync_fname(char*fname,boolisdir); |
41 | 41 |
|
42 | 42 |
|
43 | 43 | /*
|
@@ -121,22 +121,17 @@ copydir(char *fromdir, char *todir, bool recurse)
|
121 | 121 | errmsg("could not stat file \"%s\": %m",tofile)));
|
122 | 122 |
|
123 | 123 | if (S_ISREG(fst.st_mode))
|
124 |
| -fsync_fname(tofile); |
| 124 | +fsync_fname(tofile, false); |
125 | 125 | }
|
126 | 126 | FreeDir(xldir);
|
127 | 127 |
|
128 |
| -#ifdefNOTYET |
129 |
| - |
130 | 128 | /*
|
131 | 129 | * It's important to fsync the destination directory itself as individual
|
132 | 130 | * file fsyncs don't guarantee that the directory entry for the file is
|
133 | 131 | * synced. Recent versions of ext4 have made the window much wider but
|
134 | 132 | * it's been true for ext3 and other filesystems in the past.
|
135 |
| - * |
136 |
| - * However we can't do this just yet, it has portability issues. |
137 | 133 | */
|
138 |
| -fsync_fname(todir); |
139 |
| -#endif |
| 134 | +fsync_fname(todir, true); |
140 | 135 | }
|
141 | 136 |
|
142 | 137 | /*
|
@@ -216,20 +211,48 @@ copy_file(char *fromfile, char *tofile)
|
216 | 211 |
|
217 | 212 | /*
|
218 | 213 | * fsync a file
|
| 214 | + * |
| 215 | + * Try to fsync directories but ignore errors that indicate the OS |
| 216 | + * just doesn't allow/require fsyncing directories. |
219 | 217 | */
|
220 | 218 | staticvoid
|
221 |
| -fsync_fname(char*fname) |
| 219 | +fsync_fname(char*fname,boolisdir) |
222 | 220 | {
|
223 |
| -intfd=BasicOpenFile(fname, |
224 |
| -O_RDWR |PG_BINARY, |
225 |
| -S_IRUSR |S_IWUSR); |
| 221 | +intfd; |
| 222 | +intreturncode; |
226 | 223 |
|
227 |
| -if (fd<0) |
| 224 | +/* Some OSs require directories to be opened read-only whereas |
| 225 | + * other systems don't allow us to fsync files opened read-only so |
| 226 | + * we need both cases here |
| 227 | + */ |
| 228 | +if (!isdir) |
| 229 | +fd=BasicOpenFile(fname, |
| 230 | +O_RDWR |PG_BINARY, |
| 231 | +S_IRUSR |S_IWUSR); |
| 232 | +else |
| 233 | +fd=BasicOpenFile(fname, |
| 234 | +O_RDONLY |PG_BINARY, |
| 235 | +S_IRUSR |S_IWUSR); |
| 236 | + |
| 237 | +/* Some OSs don't allow us to open directories at all */ |
| 238 | +if (fd<0&&isdir&&errno==EISDIR) |
| 239 | +return; |
| 240 | + |
| 241 | +elseif (fd<0) |
228 | 242 | ereport(ERROR,
|
229 | 243 | (errcode_for_file_access(),
|
230 | 244 | errmsg("could not open file \"%s\": %m",fname)));
|
231 | 245 |
|
232 |
| -if (pg_fsync(fd)!=0) |
| 246 | +returncode=pg_fsync(fd); |
| 247 | + |
| 248 | +/* Some OSs don't allow us to fsync directories at all */ |
| 249 | +if (returncode!=0&&isdir&&errno==EBADF) |
| 250 | +{ |
| 251 | +close(fd); |
| 252 | +return; |
| 253 | +} |
| 254 | + |
| 255 | +if (returncode!=0) |
233 | 256 | ereport(ERROR,
|
234 | 257 | (errcode_for_file_access(),
|
235 | 258 | errmsg("could not fsync file \"%s\": %m",fname)));
|
|