PostgreSQL Source Code  git master
sharedfileset.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * sharedfileset.c
4  * Shared temporary file management.
5  *
6  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  * IDENTIFICATION
10  * src/backend/storage/file/sharedfileset.c
11  *
12  * SharedFileSets provide a temporary namespace (think directory) so that
13  * files can be discovered by name, and a shared ownership semantics so that
14  * shared files survive until the last user detaches.
15  *
16  *-------------------------------------------------------------------------
17  */
18 
19 #include "postgres.h"
20 
21 #include <limits.h>
22 
23 #include "storage/dsm.h"
24 #include "storage/sharedfileset.h"
25 
26 static void SharedFileSetOnDetach(dsm_segment *segment, Datum datum);
27 
28 /*
29  * Initialize a space for temporary files that can be opened by other backends.
30  * Other backends must attach to it before accessing it. Associate this
31  * SharedFileSet with 'seg'. Any contained files will be deleted when the
32  * last backend detaches.
33  *
34  * Under the covers the set is one or more directories which will eventually
35  * be deleted.
36  */
37 void
39 {
40  /* Initialize the shared fileset specific members. */
41  SpinLockInit(&fileset->mutex);
42  fileset->refcnt = 1;
43 
44  /* Initialize the fileset. */
45  FileSetInit(&fileset->fs);
46 
47  /* Register our cleanup callback. */
48  if (seg)
50 }
51 
52 /*
53  * Attach to a set of directories that was created with SharedFileSetInit.
54  */
55 void
57 {
58  bool success;
59 
60  SpinLockAcquire(&fileset->mutex);
61  if (fileset->refcnt == 0)
62  success = false;
63  else
64  {
65  ++fileset->refcnt;
66  success = true;
67  }
68  SpinLockRelease(&fileset->mutex);
69 
70  if (!success)
71  ereport(ERROR,
72  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
73  errmsg("could not attach to a SharedFileSet that is already destroyed")));
74 
75  /* Register our cleanup callback. */
77 }
78 
79 /*
80  * Delete all files in the set.
81  */
82 void
84 {
85  FileSetDeleteAll(&fileset->fs);
86 }
87 
88 /*
89  * Callback function that will be invoked when this backend detaches from a
90  * DSM segment holding a SharedFileSet that it has created or attached to. If
91  * we are the last to detach, then try to remove the directories and
92  * everything in them. We can't raise an error on failures, because this runs
93  * in error cleanup paths.
94  */
95 static void
97 {
98  bool unlink_all = false;
99  SharedFileSet *fileset = (SharedFileSet *) DatumGetPointer(datum);
100 
101  SpinLockAcquire(&fileset->mutex);
102  Assert(fileset->refcnt > 0);
103  if (--fileset->refcnt == 0)
104  unlink_all = true;
105  SpinLockRelease(&fileset->mutex);
106 
107  /*
108  * If we are the last to detach, we delete the directory in all
109  * tablespaces. Note that we are still actually attached for the rest of
110  * this function so we can safely access its data.
111  */
112  if (unlink_all)
113  FileSetDeleteAll(&fileset->fs);
114 }
#define Assert(condition)
Definition: c.h:861
void on_dsm_detach(dsm_segment *seg, on_dsm_detach_callback function, Datum arg)
Definition: dsm.c:1132
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
void FileSetInit(FileSet *fileset)
Definition: fileset.c:52
void FileSetDeleteAll(FileSet *fileset)
Definition: fileset.c:150
static bool success
Definition: initdb.c:186
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
uintptr_t Datum
Definition: postgres.h:64
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:312
static void SharedFileSetOnDetach(dsm_segment *segment, Datum datum)
Definition: sharedfileset.c:96
void SharedFileSetAttach(SharedFileSet *fileset, dsm_segment *seg)
Definition: sharedfileset.c:56
void SharedFileSetDeleteAll(SharedFileSet *fileset)
Definition: sharedfileset.c:83
void SharedFileSetInit(SharedFileSet *fileset, dsm_segment *seg)
Definition: sharedfileset.c:38
#define SpinLockInit(lock)
Definition: spin.h:57
#define SpinLockRelease(lock)
Definition: spin.h:61
#define SpinLockAcquire(lock)
Definition: spin.h:59