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-2026, 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
3237 andres@anarazel.de 38 :CBC 276 : SharedFileSetInit(SharedFileSet *fileset, dsm_segment *seg)
39 : : {
40 : : /* Initialize the shared fileset specific members. */
20 nathan@postgresql.or 41 :GNC 276 : pg_atomic_init_u32(&fileset->refcnt, 1);
42 : :
43 : : /* Initialize the fileset. */
1869 akapila@postgresql.o 44 :CBC 276 : FileSetInit(&fileset->fs);
45 : :
46 : : /* Register our cleanup callback. */
2238 47 [ + - ]: 276 : if (seg)
48 : 276 : on_dsm_detach(seg, SharedFileSetOnDetach, PointerGetDatum(fileset));
3237 andres@anarazel.de 49 : 276 : }
50 : :
51 : : /*
52 : : * Attach to a set of directories that was created with SharedFileSetInit.
53 : : */
54 : : void
55 : 426 : SharedFileSetAttach(SharedFileSet *fileset, dsm_segment *seg)
56 : : {
57 : : uint32 refcnt;
58 : :
20 nathan@postgresql.or 59 :GNC 426 : refcnt = pg_atomic_read_u32(&fileset->refcnt);
60 : : while (true)
61 : : {
62 [ - + ]: 426 : if (refcnt == 0)
20 nathan@postgresql.or 63 [ # # ]:UNC 0 : ereport(ERROR,
64 : : (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
65 : : errmsg("could not attach to a SharedFileSet that is already destroyed")));
66 : :
20 nathan@postgresql.or 67 [ + - ]:GNC 426 : if (pg_atomic_compare_exchange_u32(&fileset->refcnt, &refcnt,
68 : : refcnt + 1))
69 : 426 : break;
70 : : }
71 : :
72 : : /* Register our cleanup callback. */
3237 andres@anarazel.de 73 :CBC 426 : on_dsm_detach(seg, SharedFileSetOnDetach, PointerGetDatum(fileset));
74 : 426 : }
75 : :
76 : : /*
77 : : * Delete all files in the set.
78 : : */
79 : : void
80 : 32 : SharedFileSetDeleteAll(SharedFileSet *fileset)
81 : : {
1869 akapila@postgresql.o 82 : 32 : FileSetDeleteAll(&fileset->fs);
3237 andres@anarazel.de 83 : 32 : }
84 : :
85 : : /*
86 : : * Callback function that will be invoked when this backend detaches from a
87 : : * DSM segment holding a SharedFileSet that it has created or attached to. If
88 : : * we are the last to detach, then try to remove the directories and
89 : : * everything in them. We can't raise an error on failures, because this runs
90 : : * in error cleanup paths.
91 : : */
92 : : static void
93 : 702 : SharedFileSetOnDetach(dsm_segment *segment, Datum datum)
94 : : {
95 : 702 : bool unlink_all = false;
96 : 702 : SharedFileSet *fileset = (SharedFileSet *) DatumGetPointer(datum);
97 : :
20 nathan@postgresql.or 98 [ - + ]:GNC 702 : Assert(pg_atomic_read_u32(&fileset->refcnt) > 0);
99 [ + + ]: 702 : if (pg_atomic_sub_fetch_u32(&fileset->refcnt, 1) == 0)
3237 andres@anarazel.de 100 :CBC 276 : unlink_all = true;
101 : :
102 : : /*
103 : : * If we are the last to detach, we delete the directory in all
104 : : * tablespaces. Note that we are still actually attached for the rest of
105 : : * this function so we can safely access its data.
106 : : */
107 [ + + ]: 702 : if (unlink_all)
1869 akapila@postgresql.o 108 : 276 : FileSetDeleteAll(&fileset->fs);
3237 andres@anarazel.de 109 : 702 : }
|