LCOV - differential code coverage report
Current view: top level - src/backend/storage/file - fileset.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage HEAD vs 15 Lines: 93.8 % 48 45 3 45
Current Date: 2023-04-08 17:13:01 Functions: 100.0 % 8 8 8
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (240..) days: 93.8 % 48 45 3 45
Legend: Lines: hit not hit Function coverage date bins:
(240..) days: 100.0 % 8 8 8

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * fileset.c
                                  4                 :  *    Management of named temporary files.
                                  5                 :  *
                                  6                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
                                  7                 :  * Portions Copyright (c) 1994, Regents of the University of California
                                  8                 :  *
                                  9                 :  * IDENTIFICATION
                                 10                 :  *    src/backend/storage/file/fileset.c
                                 11                 :  *
                                 12                 :  * FileSets provide a temporary namespace (think directory) so that files can
                                 13                 :  * be discovered by name.
                                 14                 :  *
                                 15                 :  * FileSets can be used by backends when the temporary files need to be
                                 16                 :  * opened/closed multiple times and the underlying files need to survive across
                                 17                 :  * transactions.
                                 18                 :  *
                                 19                 :  *-------------------------------------------------------------------------
                                 20                 :  */
                                 21                 : 
                                 22                 : #include "postgres.h"
                                 23                 : 
                                 24                 : #include <limits.h>
                                 25                 : 
                                 26                 : #include "catalog/pg_tablespace.h"
                                 27                 : #include "commands/tablespace.h"
                                 28                 : #include "common/hashfn.h"
                                 29                 : #include "miscadmin.h"
                                 30                 : #include "storage/ipc.h"
                                 31                 : #include "storage/fileset.h"
                                 32                 : #include "utils/builtins.h"
                                 33                 : 
                                 34                 : static void FileSetPath(char *path, FileSet *fileset, Oid tablespace);
                                 35                 : static void FilePath(char *path, FileSet *fileset, const char *name);
                                 36                 : static Oid  ChooseTablespace(const FileSet *fileset, const char *name);
                                 37                 : 
                                 38                 : /*
                                 39                 :  * Initialize a space for temporary files. This API can be used by shared
                                 40                 :  * fileset as well as if the temporary files are used only by single backend
                                 41                 :  * but the files need to be opened and closed multiple times and also the
                                 42                 :  * underlying files need to survive across transactions.
                                 43                 :  *
                                 44                 :  * The callers are expected to explicitly remove such files by using
                                 45                 :  * FileSetDelete/FileSetDeleteAll.
                                 46                 :  *
                                 47                 :  * Files will be distributed over the tablespaces configured in
                                 48                 :  * temp_tablespaces.
                                 49                 :  *
                                 50                 :  * Under the covers the set is one or more directories which will eventually
                                 51                 :  * be deleted.
                                 52                 :  */
                                 53                 : void
  587 akapila                    54 CBC         174 : FileSetInit(FileSet *fileset)
                                 55                 : {
                                 56                 :     static uint32 counter = 0;
                                 57                 : 
                                 58             174 :     fileset->creator_pid = MyProcPid;
                                 59             174 :     fileset->number = counter;
                                 60             174 :     counter = (counter + 1) % INT_MAX;
                                 61                 : 
                                 62                 :     /* Capture the tablespace OIDs so that all backends agree on them. */
                                 63             174 :     PrepareTempTablespaces();
                                 64             174 :     fileset->ntablespaces =
                                 65             174 :         GetTempTablespaces(&fileset->tablespaces[0],
                                 66                 :                            lengthof(fileset->tablespaces));
                                 67             174 :     if (fileset->ntablespaces == 0)
                                 68                 :     {
                                 69                 :         /* If the GUC is empty, use current database's default tablespace */
                                 70             174 :         fileset->tablespaces[0] = MyDatabaseTableSpace;
                                 71             174 :         fileset->ntablespaces = 1;
                                 72                 :     }
                                 73                 :     else
                                 74                 :     {
                                 75                 :         int         i;
                                 76                 : 
                                 77                 :         /*
                                 78                 :          * An entry of InvalidOid means use the default tablespace for the
                                 79                 :          * current database.  Replace that now, to be sure that all users of
                                 80                 :          * the FileSet agree on what to do.
                                 81                 :          */
  587 akapila                    82 UBC           0 :         for (i = 0; i < fileset->ntablespaces; i++)
                                 83                 :         {
                                 84               0 :             if (fileset->tablespaces[i] == InvalidOid)
                                 85               0 :                 fileset->tablespaces[i] = MyDatabaseTableSpace;
                                 86                 :         }
                                 87                 :     }
  587 akapila                    88 CBC         174 : }
                                 89                 : 
                                 90                 : /*
                                 91                 :  * Create a new file in the given set.
                                 92                 :  */
                                 93                 : File
                                 94            1439 : FileSetCreate(FileSet *fileset, const char *name)
                                 95                 : {
                                 96                 :     char        path[MAXPGPATH];
                                 97                 :     File        file;
                                 98                 : 
                                 99            1439 :     FilePath(path, fileset, name);
                                100            1439 :     file = PathNameCreateTemporaryFile(path, false);
                                101                 : 
                                102                 :     /* If we failed, see if we need to create the directory on demand. */
                                103            1439 :     if (file <= 0)
                                104                 :     {
                                105                 :         char        tempdirpath[MAXPGPATH];
                                106                 :         char        filesetpath[MAXPGPATH];
                                107             171 :         Oid         tablespace = ChooseTablespace(fileset, name);
                                108                 : 
                                109             171 :         TempTablespacePath(tempdirpath, tablespace);
                                110             171 :         FileSetPath(filesetpath, fileset, tablespace);
                                111             171 :         PathNameCreateTemporaryDir(tempdirpath, filesetpath);
                                112             171 :         file = PathNameCreateTemporaryFile(path, true);
                                113                 :     }
                                114                 : 
                                115            1439 :     return file;
                                116                 : }
                                117                 : 
                                118                 : /*
                                119                 :  * Open a file that was created with FileSetCreate() */
                                120                 : File
                                121            4059 : FileSetOpen(FileSet *fileset, const char *name, int mode)
                                122                 : {
                                123                 :     char        path[MAXPGPATH];
                                124                 :     File        file;
                                125                 : 
                                126            4059 :     FilePath(path, fileset, name);
                                127            4059 :     file = PathNameOpenTemporaryFile(path, mode);
                                128                 : 
                                129            4059 :     return file;
                                130                 : }
                                131                 : 
                                132                 : /*
                                133                 :  * Delete a file that was created with FileSetCreate().
                                134                 :  *
                                135                 :  * Return true if the file existed, false if didn't.
                                136                 :  */
                                137                 : bool
                                138            1828 : FileSetDelete(FileSet *fileset, const char *name,
                                139                 :               bool error_on_failure)
                                140                 : {
                                141                 :     char        path[MAXPGPATH];
                                142                 : 
                                143            1828 :     FilePath(path, fileset, name);
                                144                 : 
                                145            1828 :     return PathNameDeleteTemporaryFile(path, error_on_failure);
                                146                 : }
                                147                 : 
                                148                 : /*
                                149                 :  * Delete all files in the set.
                                150                 :  */
                                151                 : void
                                152             198 : FileSetDeleteAll(FileSet *fileset)
                                153                 : {
                                154                 :     char        dirpath[MAXPGPATH];
                                155                 :     int         i;
                                156                 : 
                                157                 :     /*
                                158                 :      * Delete the directory we created in each tablespace.  Doesn't fail
                                159                 :      * because we use this in error cleanup paths, but can generate LOG
                                160                 :      * message on IO error.
                                161                 :      */
                                162             396 :     for (i = 0; i < fileset->ntablespaces; ++i)
                                163                 :     {
                                164             198 :         FileSetPath(dirpath, fileset, fileset->tablespaces[i]);
                                165             198 :         PathNameDeleteTemporaryDir(dirpath);
                                166                 :     }
                                167             198 : }
                                168                 : 
                                169                 : /*
                                170                 :  * Build the path for the directory holding the files backing a FileSet in a
                                171                 :  * given tablespace.
                                172                 :  */
                                173                 : static void
                                174            7695 : FileSetPath(char *path, FileSet *fileset, Oid tablespace)
                                175                 : {
                                176                 :     char        tempdirpath[MAXPGPATH];
                                177                 : 
                                178            7695 :     TempTablespacePath(tempdirpath, tablespace);
                                179            7695 :     snprintf(path, MAXPGPATH, "%s/%s%lu.%u.fileset",
                                180                 :              tempdirpath, PG_TEMP_FILE_PREFIX,
                                181            7695 :              (unsigned long) fileset->creator_pid, fileset->number);
                                182            7695 : }
                                183                 : 
                                184                 : /*
                                185                 :  * Sorting has to determine which tablespace a given temporary file belongs in.
                                186                 :  */
                                187                 : static Oid
                                188            7497 : ChooseTablespace(const FileSet *fileset, const char *name)
                                189                 : {
                                190            7497 :     uint32      hash = hash_any((const unsigned char *) name, strlen(name));
                                191                 : 
                                192            7497 :     return fileset->tablespaces[hash % fileset->ntablespaces];
                                193                 : }
                                194                 : 
                                195                 : /*
                                196                 :  * Compute the full path of a file in a FileSet.
                                197                 :  */
                                198                 : static void
                                199            7326 : FilePath(char *path, FileSet *fileset, const char *name)
                                200                 : {
                                201                 :     char        dirpath[MAXPGPATH];
                                202                 : 
                                203            7326 :     FileSetPath(dirpath, fileset, ChooseTablespace(fileset, name));
                                204            7326 :     snprintf(path, MAXPGPATH, "%s/%s", dirpath, name);
                                205            7326 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a