Age Owner Branch data TLA Line data Source code
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
2326 andres@anarazel.de 38 :CBC 165 : SharedFileSetInit(SharedFileSet *fileset, dsm_segment *seg)
39 : : {
40 : : /* Initialize the shared fileset specific members. */
41 : 165 : SpinLockInit(&fileset->mutex);
42 : 165 : fileset->refcnt = 1;
43 : :
44 : : /* Initialize the fileset. */
958 akapila@postgresql.o 45 : 165 : FileSetInit(&fileset->fs);
46 : :
47 : : /* Register our cleanup callback. */
1327 48 [ + - ]: 165 : if (seg)
49 : 165 : on_dsm_detach(seg, SharedFileSetOnDetach, PointerGetDatum(fileset));
2326 andres@anarazel.de 50 : 165 : }
51 : :
52 : : /*
53 : : * Attach to a set of directories that was created with SharedFileSetInit.
54 : : */
55 : : void
56 : 259 : SharedFileSetAttach(SharedFileSet *fileset, dsm_segment *seg)
57 : : {
58 : : bool success;
59 : :
60 [ - + ]: 259 : SpinLockAcquire(&fileset->mutex);
61 [ - + ]: 259 : if (fileset->refcnt == 0)
2326 andres@anarazel.de 62 :UBC 0 : success = false;
63 : : else
64 : : {
2326 andres@anarazel.de 65 :CBC 259 : ++fileset->refcnt;
66 : 259 : success = true;
67 : : }
68 : 259 : SpinLockRelease(&fileset->mutex);
69 : :
70 [ - + ]: 259 : if (!success)
2326 andres@anarazel.de 71 [ # # ]:UBC 0 : 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. */
2326 andres@anarazel.de 76 :CBC 259 : on_dsm_detach(seg, SharedFileSetOnDetach, PointerGetDatum(fileset));
77 : 259 : }
78 : :
79 : : /*
80 : : * Delete all files in the set.
81 : : */
82 : : void
83 : 24 : SharedFileSetDeleteAll(SharedFileSet *fileset)
84 : : {
958 akapila@postgresql.o 85 : 24 : FileSetDeleteAll(&fileset->fs);
2326 andres@anarazel.de 86 : 24 : }
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
96 : 424 : SharedFileSetOnDetach(dsm_segment *segment, Datum datum)
97 : : {
98 : 424 : bool unlink_all = false;
99 : 424 : SharedFileSet *fileset = (SharedFileSet *) DatumGetPointer(datum);
100 : :
101 [ - + ]: 424 : SpinLockAcquire(&fileset->mutex);
102 [ - + ]: 424 : Assert(fileset->refcnt > 0);
103 [ + + ]: 424 : if (--fileset->refcnt == 0)
104 : 165 : unlink_all = true;
105 : 424 : 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 [ + + ]: 424 : if (unlink_all)
958 akapila@postgresql.o 113 : 165 : FileSetDeleteAll(&fileset->fs);
2326 andres@anarazel.de 114 : 424 : }
|