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"); }
/* 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"); } } }
/* * 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; } } }
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; }
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)),); }
/* * 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; }
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; } }
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)),); }
/* 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; }
/* 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 */ } }
/* * 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; }
/** * @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; }
/* * 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; }
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); } } } } } }
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); }
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); }
/* * 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; }
/* * 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; }
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)),); }
/* * 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; }
/* * 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; }
/* * 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; }
/* * 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; }
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 }
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)),); }
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; }
/* * 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; }
/* * 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; }
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; }