void
smgr_desc(StringInfo buf, uint8 xl_info, char *rec)
{
	uint8		info = xl_info & ~XLR_INFO_MASK;

	if (info == XLOG_SMGR_CREATE)
	{
		xl_smgr_create *xlrec = (xl_smgr_create *) rec;
		char	   *path = relpath(xlrec->rnode, MAIN_FORKNUM);

		appendStringInfo(buf, "file create: %s", path);
		pfree(path);
	}
	else if (info == XLOG_SMGR_TRUNCATE)
	{
		xl_smgr_truncate *xlrec = (xl_smgr_truncate *) rec;
		char	   *path = relpath(xlrec->rnode, MAIN_FORKNUM);

		appendStringInfo(buf, "file truncate: %s to %u blocks", path,
						 xlrec->blkno);
		pfree(path);
	}
	else
		appendStringInfo(buf, "UNKNOWN");
}
Beispiel #2
0
/* Forget any invalid pages in a whole database */
static void
forget_invalid_pages_db(Oid dbid)
{
	HASH_SEQ_STATUS status;
	xl_invalid_page *hentry;

	if (invalid_page_tab == NULL)
		return;					/* nothing to do */

	hash_seq_init(&status, invalid_page_tab);

	while ((hentry = (xl_invalid_page *) hash_seq_search(&status)) != NULL)
	{
		if (hentry->key.node.dbNode == dbid)
		{
			if (log_min_messages <= DEBUG2 || client_min_messages <= DEBUG2)
			{
				char	   *path = relpath(hentry->key.node, hentry->key.forkno);

				elog(DEBUG2, "page %u of relation %s has been dropped",
					 hentry->key.blkno, path);
				pfree(path);
			}

			if (hash_search(invalid_page_tab,
							(void *) &hentry->key,
							HASH_REMOVE, NULL) == NULL)
				elog(ERROR, "hash table corrupted");
		}
	}
}
Beispiel #3
0
/*
 * DropRelFileNodeLocalBuffers
 *		This function removes from the buffer pool all the pages of the
 *		specified relation that have block numbers >= firstDelBlock.
 *		(In particular, with firstDelBlock = 0, all pages are removed.)
 *		Dirty pages are simply dropped, without bothering to write them
 *		out first.	Therefore, this is NOT rollback-able, and so should be
 *		used only with extreme caution!
 *
 *		See DropRelFileNodeBuffers in bufmgr.c for more notes.
 */
void
DropRelFileNodeLocalBuffers(RelFileNode rnode, ForkNumber forkNum,
							BlockNumber firstDelBlock)
{
	int			i;

	for (i = 0; i < NLocBuffer; i++)
	{
		BufferDesc *bufHdr = &LocalBufferDescriptors[i];
		LocalBufferLookupEnt *hresult;

		if ((bufHdr->flags & BM_TAG_VALID) &&
			RelFileNodeEquals(bufHdr->tag.rnode, rnode) &&
			bufHdr->tag.forkNum == forkNum &&
			bufHdr->tag.blockNum >= firstDelBlock)
		{
			if (LocalRefCount[i] != 0)
				elog(ERROR, "block %u of %s is still referenced (local %u)",
					 bufHdr->tag.blockNum,
					 relpath(bufHdr->tag.rnode, bufHdr->tag.forkNum),
					 LocalRefCount[i]);
			/* Remove entry from hashtable */
			hresult = (LocalBufferLookupEnt *)
				hash_search(LocalBufHash, (void *) &bufHdr->tag,
							HASH_REMOVE, NULL);
			if (!hresult)		/* shouldn't happen */
				elog(ERROR, "local buffer hash table corrupted");
			/* Mark buffer invalid */
			CLEAR_BUFFERTAG(bufHdr->tag);
			bufHdr->flags = 0;
			bufHdr->usage_count = 0;
		}
	}
}
Beispiel #4
0
gchar *get_file_relative_path(const gchar *origin_dir, const gchar *dest_file)
{
	gchar *dest_dir, *ret;

	dest_dir = g_path_get_dirname(dest_file);
	ret = relpath(origin_dir, dest_dir);
	if (ret)
	{
		gchar *dest_basename;

		dest_basename = g_path_get_basename(dest_file);

		if (g_strcmp0(ret, "./") != 0)
		{
			setptr(ret, g_build_filename(ret, dest_basename, NULL));
		}
		else
		{
			setptr(ret, g_strdup(dest_basename));
		}

		g_free(dest_basename);
	}

	g_free(dest_dir);
	return ret;
}
Beispiel #5
0
void CommitEditor::alterFile(jstring jrelpath, jlong jrevision,
                             jobject jchecksum, jobject jcontents,
                             jobject jproperties)
{
  if (!m_valid) { throw_editor_inactive(); return; }
  SVN_JNI_ERR(m_session->m_context->checkCancel(m_session->m_context),);

  InputStream contents(jcontents);
  PropertyTable properties(jproperties, true, false);
  if (JNIUtil::isJavaExceptionThrown())
    return;

  SVN::Pool subPool(pool);
  Relpath relpath(jrelpath, subPool);
  if (JNIUtil::isExceptionThrown())
    return;
  SVN_JNI_ERR(relpath.error_occurred(),);

  svn_checksum_t checksum = build_checksum(jchecksum, subPool);
  if (JNIUtil::isJavaExceptionThrown())
    return;
  SVN_JNI_ERR(svn_editor_alter_file(
                  m_editor, relpath.c_str(), svn_revnum_t(jrevision),
                  (jcontents ? &checksum : NULL),
                  (jcontents ? contents.getStream(subPool) : NULL),
                  properties.hash(subPool)),);
}
Beispiel #6
0
/*
 * calculate size of a relation
 */
static int64
calculate_relation_size(RelFileNode *rfn)
{
	int64		totalsize = 0;
	char	   *relationpath;
	char		pathname[MAXPGPATH];
	unsigned int segcount = 0;

	relationpath = relpath(*rfn);

	for (segcount = 0;; segcount++)
	{
		struct stat fst;

		if (segcount == 0)
			snprintf(pathname, MAXPGPATH, "%s",
					 relationpath);
		else
			snprintf(pathname, MAXPGPATH, "%s.%u",
					 relationpath, segcount);

		if (stat(pathname, &fst) < 0)
		{
			if (errno == ENOENT)
				break;
			else
				ereport(ERROR,
						(errcode_for_file_access(),
						 errmsg("could not stat file \"%s\": %m", pathname)));
		}
		totalsize += fst.st_size;
	}

	return totalsize;
}
Beispiel #7
0
void SaveFiles(FILE *out, PROJECTITEM *proj, PROJECTITEM *children, int indent)
{
    while (children)
    {
        int i;
        for (i=0; i < indent; i++)
            fprintf(out, "\t");
        if (children->type == PJ_FOLDER)
        {
            fprintf(out, "<FOLDER TITLE=\"%s\">\n", children->displayName);
            SaveFiles(out, proj, children->children, indent + 1);
            for (i=0; i < indent; i++)
                fprintf(out, "\t");
            fprintf(out, "</FOLDER>\n");
        }
        else
        {
            fprintf(out, "<FILE NAME=\"%s\" TITLE=\"%s\" CLEAN=\"%d\"",relpath(children->realName, proj->realName), children->displayName, children->clean);
            if (HasProperties(children))
            {
                fprintf(out, ">\n");
                SaveProfiles(out, children, indent+1);
                for (i=0; i < indent; i++)
                    fprintf(out, "\t");
                fprintf(out, "</FILE>\n");
            }
            else
            {
                fprintf(out, "/>\n" );
            }
        }
        children = children->next;
    }
}
Beispiel #8
0
void CommitEditor::addDirectory(jstring jrelpath,
                                jobject jchildren, jobject jproperties,
                                jlong jreplaces_revision)
{
  if (!m_valid) { throw_editor_inactive(); return; }
  SVN_JNI_ERR(m_session->m_context->checkCancel(m_session->m_context),);

  Iterator children(jchildren);
  if (JNIUtil::isJavaExceptionThrown())
    return;
  PropertyTable properties(jproperties, true, true);
  if (JNIUtil::isJavaExceptionThrown())
    return;

  SVN::Pool subPool(pool);
  Relpath relpath(jrelpath, subPool);
  if (JNIUtil::isExceptionThrown())
    return;
  SVN_JNI_ERR(relpath.error_occurred(),);

  SVN_JNI_ERR(svn_editor_add_directory(m_editor, relpath.c_str(),
                                       build_children(children, subPool),
                                       properties.hash(subPool),
                                       svn_revnum_t(jreplaces_revision)),);
}
Beispiel #9
0
/* Forget any invalid pages >= minblkno, because they've been dropped */
static void
forget_invalid_pages(RelFileNode node, ForkNumber forkno, BlockNumber minblkno)
{
	HASH_SEQ_STATUS status;
	xl_invalid_page *hentry;

	if (invalid_page_tab == NULL)
		return;					/* nothing to do */

	hash_seq_init(&status, invalid_page_tab);

	while ((hentry = (xl_invalid_page *) hash_seq_search(&status)) != NULL)
	{
		if (RelFileNodeEquals(hentry->key.node, node) &&
			hentry->key.forkno == forkno &&
			hentry->key.blkno >= minblkno)
		{
			if (log_min_messages <= DEBUG2 || client_min_messages <= DEBUG2)
			{
				char	   *path = relpath(hentry->key.node, forkno);

				elog(DEBUG2, "page %u of relation %s has been dropped",
					 hentry->key.blkno, path);
				pfree(path);
			}

			if (hash_search(invalid_page_tab,
							(void *) &hentry->key,
							HASH_REMOVE, NULL) == NULL)
				elog(ERROR, "hash table corrupted");
		}
	}
}
/*
 *  Create HdfsFileInfo structure before calling GetHdfsFileBlockLocations 
 */
HdfsFileInfo *
CreateHdfsFileInfo(RelFileNode rnode, int segno)
{
    char *basepath = NULL;
    int relfile_len = 0;
    
    HdfsFileInfo *file_info = (HdfsFileInfo *)palloc(sizeof(HdfsFileInfo));
    if (NULL == file_info)
    {
        return NULL;
    }

    file_info->tablespace_oid = rnode.spcNode;
    file_info->database_oid = rnode.dbNode;
    file_info->relation_oid = rnode.relNode;
    file_info->segno = segno;

    basepath = relpath(rnode);
    relfile_len = strlen(basepath) + 9;
    file_info->filepath = (char *)palloc0(relfile_len);
    FormatAOSegmentFileName(basepath, file_info->segno, -1, 0, &file_info->segno, file_info->filepath);
    pfree(basepath);

    return file_info;
}
Beispiel #11
0
/* Log a reference to an invalid page */
static void
log_invalid_page(RelFileNode node, ForkNumber forkno, BlockNumber blkno,
				 bool present)
{
	xl_invalid_page_key key;
	xl_invalid_page *hentry;
	bool		found;

	/*
	 * Log references to invalid pages at DEBUG1 level.  This allows some
	 * tracing of the cause (note the elog context mechanism will tell us
	 * something about the XLOG record that generated the reference).
	 */
	if (log_min_messages <= DEBUG1 || client_min_messages <= DEBUG1)
	{
		char	   *path = relpath(node, forkno);

		if (present)
			elog(DEBUG1, "page %u of relation %s is uninitialized",
				 blkno, path);
		else
			elog(DEBUG1, "page %u of relation %s does not exist",
				 blkno, path);
		pfree(path);
	}

	if (invalid_page_tab == NULL)
	{
		/* create hash table when first needed */
		HASHCTL		ctl;

		memset(&ctl, 0, sizeof(ctl));
		ctl.keysize = sizeof(xl_invalid_page_key);
		ctl.entrysize = sizeof(xl_invalid_page);
		ctl.hash = tag_hash;

		invalid_page_tab = hash_create("XLOG invalid-page table",
									   100,
									   &ctl,
									   HASH_ELEM | HASH_FUNCTION);
	}

	/* we currently assume xl_invalid_page_key contains no padding */
	key.node = node;
	key.forkno = forkno;
	key.blkno = blkno;
	hentry = (xl_invalid_page *)
		hash_search(invalid_page_tab, (void *) &key, HASH_ENTER, &found);

	if (!found)
	{
		/* hash_search already filled in the key */
		hentry->present = present;
	}
	else
	{
		/* repeat reference ... leave "present" as it was */
	}
}
Beispiel #12
0
/*
 *	mdunlink() -- Unlink a relation.
 *
 * Note that we're passed a RelFileNode --- by the time this is called,
 * there won't be an SMgrRelation hashtable entry anymore.
 *
 * If isRedo is true, it's okay for the relation to be already gone.
 */
bool
mdunlink(RelFileNode rnode, bool isRedo)
{
	bool		status = true;
	int			save_errno = 0;
	char	   *path;

	/*
	 * We have to clean out any pending fsync requests for the doomed relation,
	 * else the next mdsync() will fail.
	 */
	ForgetRelationFsyncRequests(rnode);

	path = relpath(rnode);

	/* Delete the first segment, or only segment if not doing segmenting */
	if (unlink(path) < 0)
	{
		if (!isRedo || errno != ENOENT)
		{
			status = false;
			save_errno = errno;
		}
	}

#ifndef LET_OS_MANAGE_FILESIZE
	/* Delete the additional segments, if any */
	if (status)
	{
		char	   *segpath = (char *) palloc(strlen(path) + 12);
		BlockNumber segno;

		/*
		 * Note that because we loop until getting ENOENT, we will
		 * correctly remove all inactive segments as well as active ones.
		 */
		for (segno = 1;; segno++)
		{
			sprintf(segpath, "%s.%u", path, segno);
			if (unlink(segpath) < 0)
			{
				/* ENOENT is expected after the last segment... */
				if (errno != ENOENT)
				{
					status = false;
					save_errno = errno;
				}
				break;
			}
		}
		pfree(segpath);
	}
#endif

	pfree(path);

	errno = save_errno;
	return status;
}
Beispiel #13
0
/**
 * @brief Open the next data file and returns its descriptor.
 * @param rnode  [in] RelFileNode of target relation.
 * @param blknum [in] Block number to seek.
 * @return File descriptor of the last data file.
 */
static int
open_data_file(RelFileNode rnode, bool istemp, BlockNumber blknum)
{
	int			fd = -1;
	int			ret;
	BlockNumber segno;
	char	   *fname = NULL;

#if PG_VERSION_NUM >= 90100
	RelFileNodeBackend	bknode;
	bknode.node = rnode;
	bknode.backend = istemp ? MyBackendId : InvalidBackendId;
	fname = relpath(bknode, MAIN_FORKNUM);
#else
	fname = relpath(rnode, MAIN_FORKNUM);
#endif
	segno = blknum / RELSEG_SIZE;
	if (segno > 0)
	{
		/*
		 * The length `+ 12' is taken from _mdfd_openmesg() in backend/storage/smgr/md.c.
		 */
		char	   *tmp = palloc(strlen(fname) + 12);

		sprintf(tmp, "%s.%u", fname, segno);
		pfree(fname);
		fname = tmp;
	}
	fd = BasicOpenFile(fname, O_CREAT | O_WRONLY | PG_BINARY, S_IRUSR | S_IWUSR);
	if (fd == -1)
		ereport(ERROR, (errcode_for_file_access(),
						errmsg("could not open data file: %m")));
	ret = lseek(fd, BLCKSZ * (blknum % RELSEG_SIZE), SEEK_SET);
	if (ret == -1)
	{
		close(fd);
		ereport(ERROR, (errcode_for_file_access(),
						errmsg
						("could not seek the end of the data file: %m")));
	}

	pfree(fname);

	return fd;
}
Beispiel #14
0
/*
 * Can the given OID be used as pg_class.relfilenode?
 *
 * As a side-effect, advances OID counter to the given OID and remembers
 * that the OID has been used as a relfilenode, so that the same value
 * doesn't get chosen again.
 */
bool
CheckNewRelFileNodeIsOk(Oid newOid, Oid reltablespace, bool relisshared)
{
	RelFileNode rnode;
	char	   *rpath;
	int			fd;
	bool		collides;
	SnapshotData SnapshotDirty;

	/*
	 * Advance our current OID counter with the given value, to keep
	 * the counter roughly in sync across all nodes. This ensures
	 * that a GetNewRelFileNode() call after this will not choose the
	 * same OID, and won't have to loop excessively to retry. That
	 * still leaves a race condition, if GetNewRelFileNode() is called
	 * just before CheckNewRelFileNodeIsOk() - UseOidForRelFileNode()
	 * is called to plug that.
	 *
	 * FIXME: handle OID wraparound gracefully.
	 */
	while(GetNewObjectId() < newOid);

	if (!UseOidForRelFileNode(newOid))
		return false;

	InitDirtySnapshot(SnapshotDirty);

	/* This should match RelationInitPhysicalAddr */
	rnode.spcNode = reltablespace ? reltablespace : MyDatabaseTableSpace;
	rnode.dbNode = relisshared ? InvalidOid : MyDatabaseId;

	rnode.relNode = newOid;

	/* Check for existing file of same name */
	rpath = relpath(rnode);
	fd = BasicOpenFile(rpath, O_RDONLY | PG_BINARY, 0);

	if (fd >= 0)
	{
		/* definite collision */
		gp_retry_close(fd);
		collides = true;
	}
	else
		collides = false;

	pfree(rpath);

	elog(DEBUG1, "Called CheckNewRelFileNodeIsOk in %s mode for %u / %u / %u. "
		 "collides = %s",
		 (Gp_role == GP_ROLE_EXECUTE ? "execute" :
		  Gp_role == GP_ROLE_UTILITY ? "utility" :
		  "dispatch"), newOid, reltablespace, relisshared,
		 collides ? "true" : "false");

	return !collides;
}
Beispiel #15
0
void tpafile::add_from_local_dir(const pal::string_t& dir)
{
	trace::verbose(_X("adding files from %s to TPA"), dir.c_str());
	const pal::char_t * const tpa_extensions[] = {
		_X(".ni.dll"),      // Probe for .ni.dll first so that it's preferred if ni and il coexist in the same dir
		_X(".dll"),
		_X(".ni.exe"),
		_X(".exe"),
	};

	std::set<pal::string_t> added_assemblies;

	// Get directory entries
	auto files = pal::readdir(dir);
	for (auto ext : tpa_extensions)
	{
		auto len = pal::strlen(ext);
		for (auto file : files)
		{
			// Can't be a match if it's the same length as the extension :)
			if (file.length() > len)
			{
				// Extract the same amount of text from the end of file name
				auto file_ext = file.substr(file.length() - len, len);

				// Check if this file name matches
				if (pal::strcasecmp(ext, file_ext.c_str()) == 0)
				{
					// Get the assembly name by stripping the extension
					// and add it to the set so we can de-dupe
					auto asm_name = file.substr(0, file.length() - len);

					// TODO(anurse): Also check if already in TPA file
					if (added_assemblies.find(asm_name) == added_assemblies.end())
					{
						added_assemblies.insert(asm_name);

						tpaentry_t entry;
						entry.asset_type = pal::string_t(_X("runtime"));
						entry.library_name = pal::string_t(asm_name);
						entry.library_version = pal::string_t(_X(""));

						pal::string_t relpath(dir);
						relpath.push_back(DIR_SEPARATOR);
						relpath.append(file);
						entry.relative_path = relpath;
						entry.asset_name = asm_name;

						trace::verbose(_X("adding %s to TPA list from %s"), asm_name.c_str(), relpath.c_str());
						m_entries.push_back(entry);
					}
				}
			}
		}
	}
}
Beispiel #16
0
		InputOutputStreamPtr VFS::openIO(const Path & path) const
		{
			auto lock = _mountpoints.lock();
			std::string mnt = matchMountPoint(path);
			if (mnt == "")
				throw std::runtime_error("Failed to find mountpoint");
			Path relpath(path.getString().substr(mnt.size() - 1));
			VFSProviderPtr provider = lock->at(mnt);
			return provider->openIO(relpath);
		}
Beispiel #17
0
		void VFS::remove(const Path & path) const
		{
			auto lock = _mountpoints.lock();
			std::string mnt = matchMountPoint(path);
			if (mnt == "")
				throw std::runtime_error("Failed to find mountpoint");
			Path relpath(path.getString().substr(mnt.size() - 1));
			VFSProviderPtr provider = lock->at(mnt);
			provider->remove(relpath);
		}
Beispiel #18
0
/*
 * GetNewRelFileNode
 *		Generate a new relfilenode number that is unique within the given
 *		tablespace.
 *
 * Note: we don't support using this in bootstrap mode.  All relations
 * created by bootstrap have preassigned OIDs, so there's no need.
 */
Oid
GetNewRelFileNode(Oid reltablespace, bool relisshared)
{
	RelFileNode rnode;
	char	   *rpath;
	int			fd;
	bool		collides = true;

	/* This should match RelationInitPhysicalAddr */
	rnode.spcNode = reltablespace ? reltablespace : MyDatabaseTableSpace;
	rnode.dbNode = relisshared ? InvalidOid : MyDatabaseId;

	do
	{
		CHECK_FOR_INTERRUPTS();

		/* Generate the Relfilenode */
		rnode.relNode = GetNewSegRelfilenode();

		if (!IsOidAcceptable(rnode.relNode))
			continue;

		/* Check for existing file of same name */
		rpath = relpath(rnode);
		fd = BasicOpenFile(rpath, O_RDONLY | PG_BINARY, 0);

		if (fd >= 0)
		{
			/* definite collision */
			gp_retry_close(fd);
			collides = true;
		}
		else
		{
			/*
			 * Here we have a little bit of a dilemma: if errno is something
			 * other than ENOENT, should we declare a collision and loop? In
			 * particular one might think this advisable for, say, EPERM.
			 * However there really shouldn't be any unreadable files in a
			 * tablespace directory, and if the EPERM is actually complaining
			 * that we can't read the directory itself, we'd be in an infinite
			 * loop.  In practice it seems best to go ahead regardless of the
			 * errno.  If there is a colliding file we will get an smgr
			 * failure when we attempt to create the new relation file.
			 */
			collides = false;
		}

		pfree(rpath);
	} while (collides);

	elog(DEBUG1, "Calling GetNewRelFileNode returns new relfilenode = %d", rnode.relNode);

	return rnode.relNode;
}
Beispiel #19
0
/*
 *	mdopen() -- Open the specified relation.  ereport's on failure.
 *		(Optionally, can return NULL instead of ereport for ENOENT.)
 *
 * Note we only open the first segment, when there are multiple segments.
 */
static MdfdVec *
mdopen(SMgrRelation reln, bool allowNotFound)
{
	MdfdVec    *mdfd;
	char	   *path;
	File		fd;

	/* No work if already open */
	if (reln->md_fd)
		return reln->md_fd;

	path = relpath(reln->smgr_rnode);

	fd = FileNameOpenFile(path, O_RDWR | PG_BINARY, 0600);

	if (fd < 0)
	{
		/*
		 * During bootstrap, there are cases where a system relation will
		 * be accessed (by internal backend processes) before the
		 * bootstrap script nominally creates it.  Therefore, accept
		 * mdopen() as a substitute for mdcreate() in bootstrap mode only.
		 * (See mdcreate)
		 */
		if (IsBootstrapProcessingMode())
			fd = FileNameOpenFile(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY, 0600);
		if (fd < 0)
		{
			pfree(path);
			if (allowNotFound && errno == ENOENT)
				return NULL;
			ereport(ERROR,
					(errcode_for_file_access(),
					 errmsg("could not open relation %u/%u/%u: %m",
							reln->smgr_rnode.spcNode,
							reln->smgr_rnode.dbNode,
							reln->smgr_rnode.relNode)));
		}
	}

	pfree(path);

	reln->md_fd = mdfd = _fdvec_alloc();

	mdfd->mdfd_vfd = fd;
	mdfd->mdfd_segno = 0;
#ifndef LET_OS_MANAGE_FILESIZE
	mdfd->mdfd_chain = NULL;
	Assert(_mdnblocks(fd, BLCKSZ) <= ((BlockNumber) RELSEG_SIZE));
#endif

	return mdfd;
}
Beispiel #20
0
void CommitEditor::remove(jstring jrelpath, jlong jrevision)
{
  if (!m_valid) { throw_editor_inactive(); return; }
  SVN_JNI_ERR(m_session->m_context->checkCancel(m_session->m_context),);

  SVN::Pool subPool(pool);
  Relpath relpath(jrelpath, subPool);
  if (JNIUtil::isExceptionThrown())
    return;
  SVN_JNI_ERR(relpath.error_occurred(),);

  SVN_JNI_ERR(svn_editor_delete(m_editor, relpath.c_str(),
                                svn_revnum_t(jrevision)),);
}
Beispiel #21
0
/*
 *	mdopen() -- Open the specified relation.
 *
 * Note we only open the first segment, when there are multiple segments.
 *
 * If first segment is not present, either ereport or return NULL according
 * to "behavior".  We treat EXTENSION_CREATE the same as EXTENSION_FAIL;
 * EXTENSION_CREATE means it's OK to extend an existing relation, not to
 * invent one out of whole cloth.
 */
static MdfdVec *
mdopen(SMgrRelation reln, ForkNumber forknum, ExtensionBehavior behavior)
{
	MdfdVec    *mdfd;
	char	   *path;
	File		fd;

	/* No work if already open */
	if (reln->md_fd[forknum])
		return reln->md_fd[forknum];

	path = relpath(reln->smgr_rnode, forknum);

	fd = PathNameOpenFile(path, O_RDWR | PG_BINARY, 0600);

	if (fd < 0)
	{
		/*
		 * During bootstrap, there are cases where a system relation will be
		 * accessed (by internal backend processes) before the bootstrap
		 * script nominally creates it.  Therefore, accept mdopen() as a
		 * substitute for mdcreate() in bootstrap mode only. (See mdcreate)
		 */
		if (IsBootstrapProcessingMode())
			fd = PathNameOpenFile(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY, 0600);
		if (fd < 0)
		{
			if (behavior == EXTENSION_RETURN_NULL &&
				FILE_POSSIBLY_DELETED(errno))
			{
				pfree(path);
				return NULL;
			}
			ereport(ERROR,
					(errcode_for_file_access(),
					 errmsg("could not open file \"%s\": %m", path)));
		}
	}

	pfree(path);

	reln->md_fd[forknum] = mdfd = _fdvec_alloc();

	mdfd->mdfd_vfd = fd;
	mdfd->mdfd_segno = 0;
	mdfd->mdfd_chain = NULL;
	Assert(_mdnblocks(reln, forknum, mdfd) <= ((BlockNumber) RELSEG_SIZE));

	return mdfd;
}
Beispiel #22
0
/*
 * calculate size of a relation
 *
 * Iterator over all files belong to the relation and do stat.
 * The obviously better way is to use glob.  For whatever reason,
 * glob is extremely slow if there are lots of relations in the
 * database.  So we handle all cases, instead. 
 */
static int64
calculate_relation_size(Relation rel, ForkNumber forknum)
{
	int64		totalsize = 0;
	char	   *relationpath;
	char		pathname[MAXPGPATH];
	unsigned int segcount = 0;

	relationpath = relpath(rel->rd_node, forknum);

if (RelationIsHeap(rel))
{
	/* Ordinary relation, including heap and index.
	 * They take form of relationpath, or relationpath.%d
	 * There will be no holes, therefore, we can stop we
	 * we reach the first non-exist file.
	 */
	for (segcount = 0;; segcount++)
	{
		struct stat fst;

		CHECK_FOR_INTERRUPTS();

		if (segcount == 0)
			snprintf(pathname, MAXPGPATH, "%s",
					 relationpath);
		else
			snprintf(pathname, MAXPGPATH, "%s.%u",
					 relationpath, segcount);

		if (stat(pathname, &fst) < 0)
		{
			if (errno == ENOENT)
				break;
			else
				ereport(ERROR,
						(errcode_for_file_access(),
						 errmsg("could not stat file %s: %m", pathname)));
		}
		totalsize += fst.st_size;
	}
}
else if (RelationIsAoRows(rel))
	totalsize = GetAOTotalBytes(rel, SnapshotNow);
else if (RelationIsAoCols(rel))
	totalsize = GetAOCSTotalBytes(rel, SnapshotNow, true);

    /* RELSTORAGE_VIRTUAL has no space usage */
    return totalsize;
}
Beispiel #23
0
/*
 *	mdcreate() -- Create a new relation on magnetic disk.
 *
 * If isRedo is true, it's okay for the relation to exist already.
 */
bool
mdcreate(SMgrRelation reln, bool isRedo)
{
	char	   *path;
	File		fd;

	if (isRedo && reln->md_fd != NULL)
		return true;			/* created and opened already... */

	Assert(reln->md_fd == NULL);

	path = relpath(reln->smgr_rnode);

	fd = FileNameOpenFile(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY, 0600);

	if (fd < 0)
	{
		int			save_errno = errno;

		/*
		 * During bootstrap, there are cases where a system relation will
		 * be accessed (by internal backend processes) before the
		 * bootstrap script nominally creates it.  Therefore, allow the
		 * file to exist already, even if isRedo is not set.  (See also
		 * mdopen)
		 */
		if (isRedo || IsBootstrapProcessingMode())
			fd = FileNameOpenFile(path, O_RDWR | PG_BINARY, 0600);
		if (fd < 0)
		{
			pfree(path);
			/* be sure to return the error reported by create, not open */
			errno = save_errno;
			return false;
		}
		errno = 0;
	}

	pfree(path);

	reln->md_fd = _fdvec_alloc();

	reln->md_fd->mdfd_vfd = fd;
	reln->md_fd->mdfd_segno = 0;
#ifndef LET_OS_MANAGE_FILESIZE
	reln->md_fd->mdfd_chain = NULL;
#endif

	return true;
}
Beispiel #24
0
/*
 *	mdunlink() -- Unlink a relation.
 *
 * Note that we're passed a RelFileNode --- by the time this is called,
 * there won't be an SMgrRelation hashtable entry anymore.
 *
 * If isRedo is true, it's okay for the relation to be already gone.
 */
bool
mdunlink(RelFileNode rnode, bool isRedo)
{
	bool		status = true;
	int			save_errno = 0;
	char	   *path;

	path = relpath(rnode);

	/* Delete the first segment, or only segment if not doing segmenting */
	if (unlink(path) < 0)
	{
		if (!isRedo || errno != ENOENT)
		{
			status = false;
			save_errno = errno;
		}
	}

#ifndef LET_OS_MANAGE_FILESIZE
	/* Get the additional segments, if any */
	if (status)
	{
		char	   *segpath = (char *) palloc(strlen(path) + 12);
		BlockNumber segno;

		for (segno = 1;; segno++)
		{
			sprintf(segpath, "%s.%u", path, segno);
			if (unlink(segpath) < 0)
			{
				/* ENOENT is expected after the last segment... */
				if (errno != ENOENT)
				{
					status = false;
					save_errno = errno;
				}
				break;
			}
		}
		pfree(segpath);
	}
#endif

	pfree(path);

	errno = save_errno;
	return status;
}
Beispiel #25
0
LString makeAbsolutePath(const LString &aRel, const LString &aBase)
{
  MB_DPRINTLN("makeAbsPath rel=%s, base=%s", aRel.c_str(), aBase.c_str());

  fs::path relpath(aRel.c_str());
  fs::path basepath(aBase.c_str());
  if (relpath.is_complete())
    return aRel; // aRel is already in abs form

  // convert to the absolute representation

  fs::path::const_iterator iter1 = relpath.begin();
  fs::path::const_iterator iter1_end = relpath.end();

  int nup = 0;
  for (; iter1!=iter1_end; ++iter1) {
    if (*iter1=="..")
      ++nup;
    else
      break;
  }

  if (nup==0) {
    // There's no up-dir ('..') string --> just concat to make abs path.
#if (BOOST_FILESYSTEM_VERSION==2)
    relpath = fs::complete(relpath, basepath);
    return relpath.file_string();
#else
    relpath = fs::absolute(relpath, basepath);
    return relpath.string();
#endif
  }

  for (; nup>0; --nup) {
    MB_ASSERT(basepath.has_parent_path());
    basepath = basepath.parent_path();
  }
  
  for (; iter1!=iter1_end; ++iter1) {
    basepath /= *iter1;
  }

#if (BOOST_FILESYSTEM_VERSION==2)
  return basepath.file_string();
#else
  return basepath.string();
#endif
}
Beispiel #26
0
void CommitEditor::addAbsent(jstring jrelpath, jobject jkind,
                             jlong jreplaces_revision)
{
  if (!m_valid) { throw_editor_inactive(); return; }
  SVN_JNI_ERR(m_session->m_context->checkCancel(m_session->m_context),);

  SVN::Pool subPool(pool);
  Relpath relpath(jrelpath, subPool);
  if (JNIUtil::isExceptionThrown())
    return;
  SVN_JNI_ERR(relpath.error_occurred(),);

  SVN_JNI_ERR(svn_editor_add_absent(m_editor, relpath.c_str(),
                                    EnumMapper::toNodeKind(jkind),
                                    svn_revnum_t(jreplaces_revision)),);
}
Beispiel #27
0
		std::vector<Path> VFS::getFiles(const Path & path) const
		{
			auto lock = _mountpoints.lock();
			std::string mnt = matchMountPoint(path);
			if (mnt == "")
				throw std::runtime_error("Failed to find mountpoint");
			Path relpath(path.getString().substr(mnt.size() - 1));
			VFSProviderPtr provider = lock->at(mnt);
			auto files = provider->getFiles(relpath);
			std::vector<Path> res;
			for (const auto& e : files)
			{
				res.push_back(Path(mnt + e.getString().substr(1)));
			}
			return res;
		}
Beispiel #28
0
/*
 * calculate size of a relation
 *
 * Iterator over all files belong to the relation and do stat.
 * The obviously better way is to use glob.  For whatever reason,
 * glob is extremely slow if there are lots of relations in the
 * database.  So we handle all cases, instead. 
 */
int64
calculate_relation_size(Relation rel)
{
	int64		totalsize = 0;
	char	   *relationpath;
	char		pathname[MAXPGPATH];

    struct stat fst;
    int i;

	relationpath = relpath(rel->rd_node);

    if(RelationIsHeap(rel))
    {
        /* Ordinary relation, including heap and index.
         * They take form of relationpath, or relationpath.%d
         * There will be no holes, therefore, we can stop we
         * we reach the first non-exist file.
         */
        for(i=0; ; ++i)
        {
            if (i==0)
                snprintf(pathname, MAXPGPATH, "%s", relationpath); 
            else
                snprintf(pathname, MAXPGPATH, "%s.%d", relationpath, i);

            if (stat(pathname, &fst) >= 0)
                totalsize += fst.st_size;
            else
            {
                if (errno == ENOENT)
                    break;
                else
                    ereport(ERROR, (errcode_for_file_access(), 
                                    errmsg("could not stat file %s: %m", pathname)
                                ));
            }
        }
    }
	else if (RelationIsAoRows(rel))
		totalsize = GetAOTotalBytes(rel, SnapshotNow);
	else if (RelationIsParquet(rel))
		totalsize = GetParquetTotalBytes(rel, SnapshotNow);
           
    /* RELSTORAGE_VIRTUAL has no space usage */
    return totalsize;
}
Beispiel #29
0
/*
 *	mdcreate() -- Create a new relation on magnetic disk.
 *
 * If isRedo is true, it's okay for the relation to exist already.
 */
void
mdcreate(SMgrRelation reln, ForkNumber forkNum, bool isRedo)
{
	char	   *path;
	File		fd;

	if (isRedo && reln->md_fd[forkNum] != NULL)
		return;					/* created and opened already... */

	Assert(reln->md_fd[forkNum] == NULL);

	path = relpath(reln->smgr_rnode, forkNum);

	fd = PathNameOpenFile(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY, 0600);

	if (fd < 0)
	{
		int			save_errno = errno;

		/*
		 * During bootstrap, there are cases where a system relation will be
		 * accessed (by internal backend processes) before the bootstrap
		 * script nominally creates it.  Therefore, allow the file to exist
		 * already, even if isRedo is not set.	(See also mdopen)
		 */
		if (isRedo || IsBootstrapProcessingMode())
			fd = PathNameOpenFile(path, O_RDWR | PG_BINARY, 0600);
		if (fd < 0)
		{
			/* be sure to report the error reported by create, not open */
			errno = save_errno;
			ereport(ERROR,
					(errcode_for_file_access(),
					 errmsg("could not create file \"%s\": %m", path)));
		}
	}

	pfree(path);

	reln->md_fd[forkNum] = _fdvec_alloc();

	reln->md_fd[forkNum]->mdfd_vfd = fd;
	reln->md_fd[forkNum]->mdfd_segno = 0;
	reln->md_fd[forkNum]->mdfd_chain = NULL;
}
Beispiel #30
0
Datei: aomd.c Projekt: 50wu/gpdb
int
AOSegmentFilePathNameLen(Relation rel)
{
	char		*basepath;
	int 		len;
		
	/* Get base path for this relation file */
	basepath = relpath(rel->rd_node);

	/*
	 * The basepath will be the RelFileNode number.  Optional part is dot "." plus 
	 * 6 digit segment file number.
	 */
	len = strlen(basepath) + 8;	// Generous.
	
	pfree(basepath);

	return len;
}