Example #1
0
File: fd.c Project: hellower/gpdb
int
FileTruncate(File file, int64 offset)
{
	int			returnCode;

	Assert(FileIsValid(file));

	DO_DB(elog(LOG, "FileTruncate %d (%s)",
			   file, VfdCache[file].fileName));

	returnCode = FileAccess(file);
	if (returnCode < 0)
		return returnCode;

	/*
	 * Call ftruncate with a int64 value.
	 *
	 * WARNING:DO NOT typecast this down to a 32-bit long or
	 * append-only vacuum full adjustment of the eof will erroneously remove
	 * table data.
	 */
	returnCode = ftruncate(VfdCache[file].fd, offset);
	
	/* Assume we don't know the file position anymore */
	VfdCache[file].seekPos = FileUnknownPos;
		
	return returnCode;
}
Example #2
0
File: fd.c Project: hellower/gpdb
void
FileInvalidate(File file)
{
	Assert(FileIsValid(file));
	if (!FileIsNotOpen(file))
		LruDelete(file);
}
Example #3
0
File: fd.c Project: hellower/gpdb
int64
FileSeek(File file, int64 offset, int whence)
{
	int			returnCode;

	Assert(FileIsValid(file));

	DO_DB(elog(LOG, "FileSeek: %d (%s) " INT64_FORMAT " " INT64_FORMAT " %d",
			   file, VfdCache[file].fileName,
			   VfdCache[file].seekPos, offset, whence));

	if (FileIsNotOpen(file))
	{
		switch (whence)
		{
			case SEEK_SET:
				Assert(offset >= INT64CONST(0));
				VfdCache[file].seekPos = offset;
				break;
			case SEEK_CUR:
				VfdCache[file].seekPos += offset;
				break;
			case SEEK_END:
				returnCode = FileAccess(file);
				if (returnCode < 0)
					return returnCode;
				VfdCache[file].seekPos = pg_lseek64(VfdCache[file].fd,
											   offset, whence);
				break;
			default:
				Assert(!"invalid whence");
				break;
		}
	}
	else
	{
		switch (whence)
		{
			case SEEK_SET:
				Assert(offset >= INT64CONST(0));
				if (VfdCache[file].seekPos != offset)
					VfdCache[file].seekPos = pg_lseek64(VfdCache[file].fd,
												   offset, whence);
				break;
			case SEEK_CUR:
				if (offset != 0 || VfdCache[file].seekPos == FileUnknownPos)
					VfdCache[file].seekPos = pg_lseek64(VfdCache[file].fd,
												   offset, whence);
				break;
			case SEEK_END:
				VfdCache[file].seekPos = pg_lseek64(VfdCache[file].fd,
											   offset, whence);
				break;
			default:
				Assert(!"invalid whence");
				break;
		}
	}
	return VfdCache[file].seekPos;
}
Example #4
0
/*
 * close a file when done with it
 */
void
FileClose(File file)
{
    Vfd		   *vfdP;
    struct stat filestats;

    Assert(FileIsValid(file));

    DO_DB(elog(LOG, "FileClose: %d (%s)",
               file, VfdCache[file].fileName));

    vfdP = &VfdCache[file];

    if (!FileIsNotOpen(file))
    {
        /* remove the file from the lru ring */
        Delete(file);

        /* close the file */
        if (close(vfdP->fd))
            elog(ERROR, "could not close file \"%s\": %m", vfdP->fileName);

        --nfile;
        vfdP->fd = VFD_CLOSED;
    }

    /*
     * Delete the file if it was temporary
     */
    if (vfdP->fdstate & FD_TEMPORARY)
    {
        /* reset flag so that die() interrupt won't cause problems */
        vfdP->fdstate &= ~FD_TEMPORARY;
        if (log_temp_files >= 0)
        {
            if (stat(vfdP->fileName, &filestats) == 0)
            {
                if (filestats.st_size >= log_temp_files)
                    ereport(LOG,
                            (errmsg("temporary file: path \"%s\", size %lu",
                                    vfdP->fileName,
                                    (unsigned long) filestats.st_size)));
            }
            else
                elog(LOG, "could not stat file \"%s\": %m", vfdP->fileName);
        }
        if (unlink(vfdP->fileName))
            elog(LOG, "could not unlink file \"%s\": %m", vfdP->fileName);
    }

    /* Unregister it from the resource owner */
    if (vfdP->resowner)
        ResourceOwnerForgetFile(vfdP->resowner, file);

    /*
     * Return the Vfd slot to the free list
     */
    FreeVfd(file);
}
Example #5
0
File: fd.c Project: hellower/gpdb
int64
FileTell(File file)
{
	Assert(FileIsValid(file));
	DO_DB(elog(LOG, "FileTell %d (%s)",
			   file, VfdCache[file].fileName));
	return VfdCache[file].seekPos;
}
Example #6
0
File: fd.c Project: hellower/gpdb
int
FileRead(File file, char *buffer, int amount)
{
	int			returnCode;

	Assert(FileIsValid(file));

	DO_DB(elog(LOG, "FileRead: %d (%s) " INT64_FORMAT " %d %p",
			   file, VfdCache[file].fileName,
			   VfdCache[file].seekPos, amount, buffer));

	if (Debug_filerep_print)
		(elog(LOG, "FileRead: %d (%s) " INT64_FORMAT " %d %p",
			  file, VfdCache[file].fileName,
			  VfdCache[file].seekPos, amount, buffer));

	returnCode = FileAccess(file);
	if (returnCode < 0)
		return returnCode;

retry:
	returnCode = read(VfdCache[file].fd, buffer, amount);

	if (returnCode >= 0)
		VfdCache[file].seekPos += returnCode;
	else
	{
		/*
		 * Windows may run out of kernel buffers and return "Insufficient
		 * system resources" error.  Wait a bit and retry to solve it.
		 *
		 * It is rumored that EINTR is also possible on some Unix filesystems,
		 * in which case immediate retry is indicated.
		 */
#ifdef WIN32
		DWORD		error = GetLastError();

		switch (error)
		{
			case ERROR_NO_SYSTEM_RESOURCES:
				pg_usleep(1000L);
				errno = EINTR;
				break;
			default:
				_dosmaperr(error);
				break;
		}
#endif
		/* OK to retry if interrupted */
		if (errno == EINTR)
			goto retry;

		/* Trouble, so assume we don't know the file position anymore */
		VfdCache[file].seekPos = FileUnknownPos;
	}

	return returnCode;
}
Example #7
0
int
FileWrite(File file, char *buffer, int amount)
{
    int			returnCode;

    Assert(FileIsValid(file));

    DO_DB(elog(LOG, "FileWrite: %d (%s) %ld %d %p",
               file, VfdCache[file].fileName,
               VfdCache[file].seekPos, amount, buffer));

    returnCode = FileAccess(file);
    if (returnCode < 0)
        return returnCode;

retry:
    errno = 0;
    returnCode = write(VfdCache[file].fd, buffer, amount);

    /* if write didn't set errno, assume problem is no disk space */
    if (returnCode != amount && errno == 0)
        errno = ENOSPC;

    if (returnCode >= 0)
        VfdCache[file].seekPos += returnCode;
    else
    {
        /*
         * See comments in FileRead()
         */
#ifdef WIN32
        DWORD		error = GetLastError();

        switch (error)
        {
        case ERROR_NO_SYSTEM_RESOURCES:
            pg_usleep(1000L);
            errno = EINTR;
            break;
        default:
            _dosmaperr(error);
            break;
        }
#endif
        /* OK to retry if interrupted */
        if (errno == EINTR)
            goto retry;

        /* Trouble, so assume we don't know the file position anymore */
        VfdCache[file].seekPos = FileUnknownPos;
    }

    return returnCode;
}
Example #8
0
File: fd.c Project: hellower/gpdb
/*
 * close a file and forcibly delete the underlying Unix file
 */
void
FileUnlink(File file)
{
	Assert(FileIsValid(file));

	DO_DB(elog(LOG, "FileUnlink: %d (%s)",
	     file, VfdCache[file].fileName));

	/* force FileClose to delete it */
	VfdCache[file].fdstate |= FD_TEMPORARY;

	FileClose(file);
}
Example #9
0
int
FileSync(File file)
{
    int			returnCode;

    Assert(FileIsValid(file));

    DO_DB(elog(LOG, "FileSync: %d (%s)",
               file, VfdCache[file].fileName));

    returnCode = FileAccess(file);
    if (returnCode < 0)
        return returnCode;

    return pg_fsync(VfdCache[file].fd);
}
Example #10
0
File: fd.c Project: hellower/gpdb
int64
FileNonVirtualCurSeek(File file)
{
	int			returnCode;

	Assert(FileIsValid(file));

	DO_DB(elog(LOG, "FileNonVirtualCurSeek: %d (%s) virtual position" INT64_FORMAT,
			   file, VfdCache[file].fileName,
			   VfdCache[file].seekPos));

	returnCode = FileAccess(file);
	if (returnCode < 0)
		return returnCode;

	return pg_lseek64(VfdCache[file].fd, 0, SEEK_CUR);
}
Example #11
0
File: fd.c Project: hellower/gpdb
int
FileSync(File file)
{
	int			returnCode;
	FileRepGpmonRecord_s gpmonRecord;
	FileRepGpmonStatType_e whichStat;

	if (fileRepRole == FileRepPrimaryRole)
	{
			whichStat = FileRepGpmonStatType_PrimaryFsyncSyscall;
			FileRepGpmonStat_OpenRecord(whichStat, &gpmonRecord);
	} else 
	{
			whichStat = FileRepGpmonStatType_MirrorFsyncSyscall;
			FileRepGpmonStat_OpenRecord(whichStat, &gpmonRecord);
	}
	Assert(FileIsValid(file));

	DO_DB(elog(LOG, "FileSync: %d (%s)",
			   file, VfdCache[file].fileName));

	returnCode = FileAccess(file);
	if (returnCode < 0)
		return returnCode;

#ifdef FAULT_INJECTOR
	FaultInjector_InjectFaultIfSet(
								   FileRepFlush,
								   DDLNotSpecified,
								   "",	//databaseName
								   ""); // tableName
#endif								
	
	returnCode =  pg_fsync(VfdCache[file].fd);
	
	if (returnCode >= 0)
	{
			//only include stats if successful
			if ((fileRepRole == FileRepPrimaryRole) || 
				(fileRepRole == FileRepMirrorRole))
			{
					FileRepGpmonStat_CloseRecord(whichStat, &gpmonRecord);
			}
	}
	return returnCode;
}
Example #12
0
int
FileTruncate(File file, long offset)
{
    int			returnCode;

    Assert(FileIsValid(file));

    DO_DB(elog(LOG, "FileTruncate %d (%s)",
               file, VfdCache[file].fileName));

    returnCode = FileAccess(file);
    if (returnCode < 0)
        return returnCode;

    returnCode = ftruncate(VfdCache[file].fd, (size_t) offset);
    return returnCode;
}
Example #13
0
File: fd.c Project: hellower/gpdb
/*
 * close a file when done with it
 */
void
FileClose(File file)
{
	Vfd		   *vfdP;

	Assert(FileIsValid(file));

	DO_DB(elog(LOG, "FileClose: %d (%s)",
			   file, VfdCache[file].fileName));

	vfdP = &VfdCache[file];

	if (!FileIsNotOpen(file))
	{
		/* remove the file from the lru ring */
		Delete(file);

		/* close the file */
		if (gp_retry_close(vfdP->fd))
			elog(ERROR, "could not close file \"%s\": %m",
				 vfdP->fileName);

		--nfile;
		vfdP->fd = VFD_CLOSED;
	}

	/*
	 * Delete the file if it was temporary
	 */
	if (vfdP->fdstate & FD_TEMPORARY)
	{
		/* reset flag so that die() interrupt won't cause problems */
		vfdP->fdstate &= ~FD_TEMPORARY;
		if (unlink(vfdP->fileName))
			elog(DEBUG1, "failed to unlink \"%s\": %m",
				 vfdP->fileName);
	}

	/*
	 * Return the Vfd slot to the free list
	 */
	FreeVfd(file);
}
Example #14
0
File: fd.c Project: hellower/gpdb
int
FileWrite(File file, char *buffer, int amount)
{
	int			returnCode;
	FileRepGpmonRecord_s gpmonRecord;
	FileRepGpmonStatType_e whichStat =0;

	if (fileRepRole == FileRepPrimaryRole)
	{
			whichStat = FileRepGpmonStatType_PrimaryWriteSyscall;
			FileRepGpmonStat_OpenRecord(whichStat, &gpmonRecord);
			gpmonRecord.size = amount;

	} else if (fileRepRole == FileRepMirrorRole)
	{
			whichStat = FileRepGpmonStatType_MirrorWriteSyscall;
			FileRepGpmonStat_OpenRecord(whichStat, &gpmonRecord);
			gpmonRecord.size = amount;

	}

	Assert(FileIsValid(file));

	DO_DB(elog(LOG, "FileWrite: %d (%s) " INT64_FORMAT " %d %p",
			   file, VfdCache[file].fileName,
			   VfdCache[file].seekPos, amount, buffer));

	/* Added temporary for troubleshooting */
	if (Debug_filerep_print)
		elog(LOG, "FileWrite: %d (%s) " INT64_FORMAT " %d %p",
		 file, VfdCache[file].fileName,
		 VfdCache[file].seekPos, amount, buffer);
	else
		FileRep_InsertLogEntry(
							   "FileWrite",
							   FileRep_GetFlatFileIdentifier(VfdCache[file].fileName, ""),
							   FileRepRelationTypeFlatFile,
							   FileRepOperationWrite,
							   FILEREP_UNDEFINED,
							   FILEREP_UNDEFINED,
							   FileRepAckStateNotInitialized,
							   VfdCache[file].seekPos,
							   amount);

	returnCode = FileAccess(file);
	if (returnCode < 0)
		return returnCode;

#ifdef FAULT_INJECTOR	
	if (! strcmp(VfdCache[file].fileName, "global/pg_control"))
	{
		if (FaultInjector_InjectFaultIfSet(
										   PgControl, 
										   DDLNotSpecified,
										   "" /* databaseName */,
										   "" /* tableName */) == FaultInjectorTypeDataCorruption)
		{
			MemSet(buffer, 0, amount);
		}
	}
	
	if (strstr(VfdCache[file].fileName, "pg_xlog/"))
	{
		if (FaultInjector_InjectFaultIfSet(
										   PgXlog, 
										   DDLNotSpecified,
										   "" /* databaseName */,
										   "" /* tableName */) == FaultInjectorTypeDataCorruption)
		{
			MemSet(buffer, 0, amount);
		}
	}
#endif

retry:
	errno = 0;
	returnCode = write(VfdCache[file].fd, buffer, amount);

	/* if write didn't set errno, assume problem is no disk space */
	if (returnCode != amount && errno == 0)
		errno = ENOSPC;

	if (returnCode >= 0)
		VfdCache[file].seekPos += returnCode;
	else
	{
		/*
		 * See comments in FileRead()
		 */
#ifdef WIN32
		DWORD		error = GetLastError();

		switch (error)
		{
			case ERROR_NO_SYSTEM_RESOURCES:
				pg_usleep(1000L);
				errno = EINTR;
				break;
			default:
				_dosmaperr(error);
				break;
		}
#endif
		/* OK to retry if interrupted */
		if (errno == EINTR)
			goto retry;

		/* Trouble, so assume we don't know the file position anymore */
		VfdCache[file].seekPos = FileUnknownPos;
	}

	if (returnCode >= 0)
	{
		//only include stat if successful
		if ((fileRepRole == FileRepPrimaryRole) ||
			(fileRepRole == FileRepMirrorRole))
		{
			FileRepGpmonStat_CloseRecord(whichStat, &gpmonRecord);
		}
	}
	return returnCode;
}
Example #15
0
long
FileSeek(File file, long offset, int whence)
{
    int			returnCode;

    Assert(FileIsValid(file));

    DO_DB(elog(LOG, "FileSeek: %d (%s) %ld %ld %d",
               file, VfdCache[file].fileName,
               VfdCache[file].seekPos, offset, whence));

    if (FileIsNotOpen(file))
    {
        switch (whence)
        {
        case SEEK_SET:
            if (offset < 0)
                elog(ERROR, "invalid seek offset: %ld", offset);
            VfdCache[file].seekPos = offset;
            break;
        case SEEK_CUR:
            VfdCache[file].seekPos += offset;
            break;
        case SEEK_END:
            returnCode = FileAccess(file);
            if (returnCode < 0)
                return returnCode;
            VfdCache[file].seekPos = lseek(VfdCache[file].fd,
                                           offset, whence);
            break;
        default:
            elog(ERROR, "invalid whence: %d", whence);
            break;
        }
    }
    else
    {
        switch (whence)
        {
        case SEEK_SET:
            if (offset < 0)
                elog(ERROR, "invalid seek offset: %ld", offset);
            if (VfdCache[file].seekPos != offset)
                VfdCache[file].seekPos = lseek(VfdCache[file].fd,
                                               offset, whence);
            break;
        case SEEK_CUR:
            if (offset != 0 || VfdCache[file].seekPos == FileUnknownPos)
                VfdCache[file].seekPos = lseek(VfdCache[file].fd,
                                               offset, whence);
            break;
        case SEEK_END:
            VfdCache[file].seekPos = lseek(VfdCache[file].fd,
                                           offset, whence);
            break;
        default:
            elog(ERROR, "invalid whence: %d", whence);
            break;
        }
    }
    return VfdCache[file].seekPos;
}