Header And Logo

PostgreSQL
| The world's most advanced open source database.

Defines | Functions

file.c File Reference

#include "postgres_fe.h"
#include "pg_upgrade.h"
#include <fcntl.h>
Include dependency graph for file.c:

Go to the source code of this file.

Defines

#define COPY_BUF_SIZE   (50 * BLCKSZ)

Functions

static int copy_file (const char *fromfile, const char *tofile, bool force)
const char * copyAndUpdateFile (pageCnvCtx *pageConverter, const char *src, const char *dst, bool force)
const char * linkAndUpdateFile (pageCnvCtx *pageConverter, const char *src, const char *dst)
void check_hard_link (void)
FILE * fopen_priv (const char *path, const char *mode)

Define Documentation

#define COPY_BUF_SIZE   (50 * BLCKSZ)

Referenced by copy_file().


Function Documentation

void check_hard_link ( void   ) 

Definition at line 197 of file file.c.

References getErrorText(), new_cluster, old_cluster, PG_FATAL, pg_link_file, pg_log(), ClusterInfo::pgdata, snprintf(), and unlink().

Referenced by check_new_cluster().

{
    char        existing_file[MAXPGPATH];
    char        new_link_file[MAXPGPATH];

    snprintf(existing_file, sizeof(existing_file), "%s/PG_VERSION", old_cluster.pgdata);
    snprintf(new_link_file, sizeof(new_link_file), "%s/PG_VERSION.linktest", new_cluster.pgdata);
    unlink(new_link_file);      /* might fail */

    if (pg_link_file(existing_file, new_link_file) == -1)
    {
        pg_log(PG_FATAL,
               "Could not create hard link between old and new data directories: %s\n"
               "In link mode the old and new data directories must be on the same file system volume.\n",
               getErrorText(errno));
    }
    unlink(new_link_file);
}

static int copy_file ( const char *  fromfile,
const char *  tofile,
bool  force 
) [static]

Definition at line 128 of file file.c.

References close, COPY_BUF_SIZE, NULL, pg_free(), pg_malloc(), read, and write.

Referenced by copydir(), and ResetUnloggedRelationsInDbspaceDir().

{

#define COPY_BUF_SIZE (50 * BLCKSZ)

    int         src_fd;
    int         dest_fd;
    char       *buffer;
    int         ret = 0;
    int         save_errno = 0;

    if ((srcfile == NULL) || (dstfile == NULL))
        return -1;

    if ((src_fd = open(srcfile, O_RDONLY, 0)) < 0)
        return -1;

    if ((dest_fd = open(dstfile, O_RDWR | O_CREAT | (force ? 0 : O_EXCL), S_IRUSR | S_IWUSR)) < 0)
    {
        if (src_fd != 0)
            close(src_fd);

        return -1;
    }

    buffer = (char *) pg_malloc(COPY_BUF_SIZE);

    /* perform data copying i.e read src source, write to destination */
    while (true)
    {
        ssize_t     nbytes = read(src_fd, buffer, COPY_BUF_SIZE);

        if (nbytes < 0)
        {
            save_errno = errno;
            ret = -1;
            break;
        }

        if (nbytes == 0)
            break;

        errno = 0;

        if (write(dest_fd, buffer, nbytes) != nbytes)
        {
            save_errno = errno;
            ret = -1;
            break;
        }
    }

    pg_free(buffer);

    if (src_fd != 0)
        close(src_fd);

    if (dest_fd != 0)
        close(dest_fd);

    if (save_errno != 0)
        errno = save_errno;

    return ret;
}

const char* copyAndUpdateFile ( pageCnvCtx pageConverter,
const char *  src,
const char *  dst,
bool  force 
)

Definition at line 32 of file file.c.

References buf, close, getErrorText(), NULL, pg_copy_file, read, and write.

Referenced by transfer_relfile().

{
    if (pageConverter == NULL)
    {
        if (pg_copy_file(src, dst, force) == -1)
            return getErrorText(errno);
        else
            return NULL;
    }
    else
    {
        /*
         * We have a pageConverter object - that implies that the
         * PageLayoutVersion differs between the two clusters so we have to
         * perform a page-by-page conversion.
         *
         * If the pageConverter can convert the entire file at once, invoke
         * that plugin function, otherwise, read each page in the relation
         * file and call the convertPage plugin function.
         */

#ifdef PAGE_CONVERSION
        if (pageConverter->convertFile)
            return pageConverter->convertFile(pageConverter->pluginData,
                                              dst, src);
        else
#endif
        {
            int         src_fd;
            int         dstfd;
            char        buf[BLCKSZ];
            ssize_t     bytesRead;
            const char *msg = NULL;

            if ((src_fd = open(src, O_RDONLY, 0)) < 0)
                return "could not open source file";

            if ((dstfd = open(dst, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR)) < 0)
            {
                close(src_fd);
                return "could not create destination file";
            }

            while ((bytesRead = read(src_fd, buf, BLCKSZ)) == BLCKSZ)
            {
#ifdef PAGE_CONVERSION
                if ((msg = pageConverter->convertPage(pageConverter->pluginData, buf, buf)) != NULL)
                    break;
#endif
                if (write(dstfd, buf, BLCKSZ) != BLCKSZ)
                {
                    msg = "could not write new page to destination";
                    break;
                }
            }

            close(src_fd);
            close(dstfd);

            if (msg)
                return msg;
            else if (bytesRead != 0)
                return "found partial page in source file";
            else
                return NULL;
        }
    }
}

FILE* fopen_priv ( const char *  path,
const char *  mode 
)
const char* linkAndUpdateFile ( pageCnvCtx pageConverter,
const char *  src,
const char *  dst 
)

Definition at line 113 of file file.c.

References getErrorText(), NULL, and pg_link_file.

Referenced by transfer_relfile().

{
    if (pageConverter != NULL)
        return "Cannot in-place update this cluster, page-by-page conversion is required";

    if (pg_link_file(src, dst) == -1)
        return getErrorText(errno);
    else
        return NULL;
}