|
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))); |
|