Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 7743d87

Browse files
committed
Fix bug in FileTruncate
1 parent 72fe12d commit 7743d87

File tree

3 files changed

+84
-52
lines changed

3 files changed

+84
-52
lines changed

src/backend/storage/file/cfs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1165,7 +1165,7 @@ void cfs_gc_start_bgworkers()
11651165
elog(LOG, "Start %d background garbage collection workers for CFS", i);
11661166
}
11671167

1168-
/* Enable/disable garbage colection. */
1168+
/* Enable/disable garbage collection. */
11691169
bool cfs_control_gc(bool enabled)
11701170
{
11711171
bool was_enabled = cfs_state->gc_enabled;

src/backend/storage/file/copydir.c

Lines changed: 76 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#include "storage/copydir.h"
2626
#include "storage/fd.h"
27+
#include "storage/cfs.h"
2728
#include "access/transam.h"
2829
#include "miscadmin.h"
2930

@@ -40,6 +41,7 @@ copydir(char *fromdir, char *todir, bool recurse)
4041
struct dirent *xlde;
4142
char fromfile[MAXPGPATH];
4243
char tofile[MAXPGPATH];
44+
bool savedGCState = false;
4345

4446
if (mkdir(todir, S_IRWXU) != 0)
4547
ereport(ERROR,
@@ -52,36 +54,49 @@ copydir(char *fromdir, char *todir, bool recurse)
5254
(errcode_for_file_access(),
5355
errmsg("could not open directory \"%s\": %m", fromdir)));
5456

55-
while ((xlde = ReadDir(xldir, fromdir)) != NULL)
56-
{
57-
struct stat fst;
58-
59-
/* If we got a cancel signal during the copy of the directory, quit */
60-
CHECK_FOR_INTERRUPTS();
61-
62-
if (strcmp(xlde->d_name, ".") == 0 ||
63-
strcmp(xlde->d_name, "..") == 0)
64-
continue;
65-
66-
snprintf(fromfile, MAXPGPATH, "%s/%s", fromdir, xlde->d_name);
67-
snprintf(tofile, MAXPGPATH, "%s/%s", todir, xlde->d_name);
6857

69-
if (lstat(fromfile, &fst) < 0)
70-
ereport(ERROR,
71-
(errcode_for_file_access(),
72-
errmsg("could not stat file \"%s\": %m", fromfile)));
58+
savedGCState = cfs_control_gc(false); /* disable GC during copy */
7359

74-
if (S_ISDIR(fst.st_mode))
60+
PG_TRY();
61+
{
62+
while ((xlde = ReadDir(xldir, fromdir)) != NULL)
7563
{
76-
/* recurse to handle subdirectories */
77-
if (recurse)
78-
copydir(fromfile, tofile, true);
64+
struct stat fst;
65+
66+
/* If we got a cancel signal during the copy of the directory, quit */
67+
CHECK_FOR_INTERRUPTS();
68+
69+
if (strcmp(xlde->d_name, ".") == 0 ||
70+
strcmp(xlde->d_name, "..") == 0)
71+
continue;
72+
73+
snprintf(fromfile, MAXPGPATH, "%s/%s", fromdir, xlde->d_name);
74+
snprintf(tofile, MAXPGPATH, "%s/%s", todir, xlde->d_name);
75+
76+
if (lstat(fromfile, &fst) < 0)
77+
ereport(ERROR,
78+
(errcode_for_file_access(),
79+
errmsg("could not stat file \"%s\": %m", fromfile)));
80+
81+
if (S_ISDIR(fst.st_mode))
82+
{
83+
/* recurse to handle subdirectories */
84+
if (recurse)
85+
copydir(fromfile, tofile, true);
86+
}
87+
else if (S_ISREG(fst.st_mode))
88+
copy_file(fromfile, tofile);
7989
}
80-
else if (S_ISREG(fst.st_mode))
81-
copy_file(fromfile, tofile);
90+
FreeDir(xldir);
8291
}
83-
FreeDir(xldir);
84-
92+
PG_CATCH();
93+
{
94+
cfs_control_gc(savedGCState);
95+
PG_RE_THROW();
96+
}
97+
PG_END_TRY();
98+
cfs_control_gc(savedGCState);
99+
85100
/*
86101
* Be paranoid here and fsync all files to ensure the copy is really done.
87102
* But if fsync is disabled, we're done.
@@ -139,6 +154,7 @@ copyzipdir(char *fromdir, bool from_compressed,
139154
struct dirent *xlde;
140155
char fromfile[MAXPGPATH];
141156
char tofile[MAXPGPATH];
157+
bool savedGCState;
142158

143159
if (mkdir(todir, S_IRWXU) != 0)
144160
ereport(ERROR,
@@ -151,31 +167,43 @@ copyzipdir(char *fromdir, bool from_compressed,
151167
(errcode_for_file_access(),
152168
errmsg("could not open directory \"%s\": %m", fromdir)));
153169

154-
while ((xlde = ReadDir(xldir, fromdir)) != NULL)
155-
{
156-
struct stat fst;
157-
158-
/* If we got a cancel signal during the copy of the directory, quit */
159-
CHECK_FOR_INTERRUPTS();
160-
161-
if (strcmp(xlde->d_name, ".") == 0
162-
|| strcmp(xlde->d_name, "..") == 0
163-
|| (strlen(xlde->d_name) > 4
164-
&& strcmp(xlde->d_name + strlen(xlde->d_name) - 4, ".cfm") == 0))
165-
continue;
170+
savedGCState = cfs_control_gc(false); /* disable GC during copy */
166171

167-
snprintf(fromfile, MAXPGPATH, "%s/%s", fromdir, xlde->d_name);
168-
snprintf(tofile, MAXPGPATH, "%s/%s", todir, xlde->d_name);
169-
170-
if (lstat(fromfile, &fst) < 0)
171-
ereport(ERROR,
172-
(errcode_for_file_access(),
173-
errmsg("could not stat file \"%s\": %m", fromfile)));
174-
175-
if (S_ISREG(fst.st_mode))
176-
copy_zip_file(fromfile, from_compressed, tofile, to_compressed);
172+
PG_TRY();
173+
{
174+
while ((xlde = ReadDir(xldir, fromdir)) != NULL)
175+
{
176+
struct stat fst;
177+
178+
/* If we got a cancel signal during the copy of the directory, quit */
179+
CHECK_FOR_INTERRUPTS();
180+
181+
if (strcmp(xlde->d_name, ".") == 0
182+
|| strcmp(xlde->d_name, "..") == 0
183+
|| (strlen(xlde->d_name) > 4
184+
&& strcmp(xlde->d_name + strlen(xlde->d_name) - 4, ".cfm") == 0))
185+
continue;
186+
187+
snprintf(fromfile, MAXPGPATH, "%s/%s", fromdir, xlde->d_name);
188+
snprintf(tofile, MAXPGPATH, "%s/%s", todir, xlde->d_name);
189+
190+
if (lstat(fromfile, &fst) < 0)
191+
ereport(ERROR,
192+
(errcode_for_file_access(),
193+
errmsg("could not stat file \"%s\": %m", fromfile)));
194+
195+
if (S_ISREG(fst.st_mode))
196+
copy_zip_file(fromfile, from_compressed, tofile, to_compressed);
197+
}
198+
FreeDir(xldir);
177199
}
178-
FreeDir(xldir);
200+
PG_CATCH();
201+
{
202+
cfs_control_gc(savedGCState);
203+
PG_RE_THROW();
204+
}
205+
PG_END_TRY();
206+
cfs_control_gc(savedGCState);
179207

180208
/*
181209
* Be paranoid here and fsync all files to ensure the copy is really done.

src/backend/storage/file/fd.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2178,10 +2178,14 @@ FileTruncate(File file, off_t offset)
21782178

21792179
pg_atomic_write_u32(&map->virtSize, offset);
21802180
pg_atomic_fetch_sub_u32(&map->usedSize, released);
2181+
2182+
if (offset == 0)
2183+
{
2184+
/* We can truncate compressed file only with zero offset */
2185+
pg_atomic_write_u32(&map->physSize, 0);
2186+
returnCode = ftruncate(VfdCache[file].fd, 0);
2187+
}
21812188
cfs_unlock_file(map);
2182-
2183-
/* We can truncate compressed file only with zero offset */
2184-
returnCode = (offset == 0) ? ftruncate(VfdCache[file].fd, 0) : 0;
21852189
}
21862190
else
21872191
returnCode = ftruncate(VfdCache[file].fd, offset);

0 commit comments

Comments
 (0)