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-2021, 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 "catalog/pg_tablespace.h"
24 #include "commands/tablespace.h"
25 #include "common/hashfn.h"
26 #include "miscadmin.h"
27 #include "storage/dsm.h"
28 #include "storage/ipc.h"
29 #include "storage/sharedfileset.h"
30 #include "utils/builtins.h"
31 
32 static void SharedFileSetOnDetach(dsm_segment *segment, Datum datum);
33 
34 /*
35  * Initialize a space for temporary files that can be opened by other backends.
36  * Other backends must attach to it before accessing it. Associate this
37  * SharedFileSet with 'seg'. Any contained files will be deleted when the
38  * last backend detaches.
39  *
40  * Under the covers the set is one or more directories which will eventually
41  * be deleted.
42  */
43 void
45 {
46  /* Initialize the shared fileset specific members. */
47  SpinLockInit(&fileset->mutex);
48  fileset->refcnt = 1;
49 
50  /* Initialize the fileset. */
51  FileSetInit(&fileset->fs);
52 
53  /* Register our cleanup callback. */
54  if (seg)
56 }
57 
58 /*
59  * Attach to a set of directories that was created with SharedFileSetInit.
60  */
61 void
63 {
64  bool success;
65 
66  SpinLockAcquire(&fileset->mutex);
67  if (fileset->refcnt == 0)
68  success = false;
69  else
70  {
71  ++fileset->refcnt;
72  success = true;
73  }
74  SpinLockRelease(&fileset->mutex);
75 
76  if (!success)
77  ereport(ERROR,
78  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
79  errmsg("could not attach to a SharedFileSet that is already destroyed")));
80 
81  /* Register our cleanup callback. */
83 }
84 
85 /*
86  * Delete all files in the set.
87  */
88 void
90 {
91  FileSetDeleteAll(&fileset->fs);
92 }
93 
94 /*
95  * Callback function that will be invoked when this backend detaches from a
96  * DSM segment holding a SharedFileSet that it has created or attached to. If
97  * we are the last to detach, then try to remove the directories and
98  * everything in them. We can't raise an error on failures, because this runs
99  * in error cleanup paths.
100  */
101 static void
103 {
104  bool unlink_all = false;
105  SharedFileSet *fileset = (SharedFileSet *) DatumGetPointer(datum);
106 
107  SpinLockAcquire(&fileset->mutex);
108  Assert(fileset->refcnt > 0);
109  if (--fileset->refcnt == 0)
110  unlink_all = true;
111  SpinLockRelease(&fileset->mutex);
112 
113  /*
114  * If we are the last to detach, we delete the directory in all
115  * tablespaces. Note that we are still actually attached for the rest of
116  * this function so we can safely access its data.
117  */
118  if (unlink_all)
119  FileSetDeleteAll(&fileset->fs);
120 }
void SharedFileSetInit(SharedFileSet *fileset, dsm_segment *seg)
Definition: sharedfileset.c:44
#define PointerGetDatum(X)
Definition: postgres.h:600
#define SpinLockInit(lock)
Definition: spin.h:60
int errcode(int sqlerrcode)
Definition: elog.c:698
void FileSetInit(FileSet *fileset)
Definition: fileset.c:54
void on_dsm_detach(dsm_segment *seg, on_dsm_detach_callback function, Datum arg)
Definition: dsm.c:1096
#define SpinLockAcquire(lock)
Definition: spin.h:62
#define ERROR
Definition: elog.h:46
#define SpinLockRelease(lock)
Definition: spin.h:64
uintptr_t Datum
Definition: postgres.h:411
#define ereport(elevel,...)
Definition: elog.h:157
void SharedFileSetDeleteAll(SharedFileSet *fileset)
Definition: sharedfileset.c:89
#define Assert(condition)
Definition: c.h:804
#define DatumGetPointer(X)
Definition: postgres.h:593
int errmsg(const char *fmt,...)
Definition: elog.c:909
void SharedFileSetAttach(SharedFileSet *fileset, dsm_segment *seg)
Definition: sharedfileset.c:62
void FileSetDeleteAll(FileSet *fileset)
Definition: fileset.c:152
static bool success
Definition: initdb.c:165
static void SharedFileSetOnDetach(dsm_segment *segment, Datum datum)