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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy