LCOV - code coverage report
Current view: top level - src/backend/storage/file - sharedfileset.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 93.5 % 31 29
Test Date: 2026-02-17 17:20:33 Functions: 100.0 % 4 4
Legend: Lines:     hit not hit

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

Generated by: LCOV version 2.0-1