Exemple #1
0
/** put the basic write operation into the buffer (bb) to be journaled */
static void prepBasicWrite_inlock(AlignedBuilder& bb,
                                  const WriteIntent* i,
                                  RelativePath& lastDbPath) {
    size_t ofs = 1;
    DurableMappedFile* mmf = findMMF_inlock(i->start(), /*out*/ ofs);

    if (MONGO_unlikely(!mmf->willNeedRemap())) {
        // tag this mmf as needed a remap of its private view later.
        // usually it will already be dirty/already set, so we do the if above first
        // to avoid possibility of cpu cache line contention
        mmf->setWillNeedRemap();
    }

    // since we have already looked up the mmf, we go ahead and remember the write view location
    // so we don't have to find the DurableMappedFile again later in WRITETODATAFILES()
    //
    // this was for WRITETODATAFILES_Impl2 so commented out now
    //
    /*
    dassert( i->w_ptr == 0 );
    i->w_ptr = ((char*)mmf->view_write()) + ofs;
    */

    JEntry e;
    e.len = min(i->length(), (unsigned)(mmf->length() - ofs));  // don't write past end of file
    verify(ofs <= 0x80000000);
    e.ofs = (unsigned)ofs;
    e.setFileNo(mmf->fileSuffixNo());

    if (mmf->relativePath() == local) {
        e.setLocalDbContextBit();
    } else if (mmf->relativePath() != lastDbPath) {
        lastDbPath = mmf->relativePath();
        JDbContext c;
        bb.appendStruct(c);
        bb.appendStr(lastDbPath.toString());
    }

    bb.appendStruct(e);
    bb.appendBuf(i->start(), e.len);

    if (MONGO_unlikely(e.len != (unsigned)i->length())) {
        log() << "journal info splitting prepBasicWrite at boundary" << endl;

        // This only happens if we write to the last byte in a file and
        // the fist byte in another file that is mapped adjacently. I
        // think most OSs leave at least a one page gap between
        // mappings, but better to be safe.

        WriteIntent next((char*)i->start() + e.len, i->length() - e.len);
        prepBasicWrite_inlock(bb, &next, lastDbPath);
    }
}
 Status AuthorizationSession::checkAuthForQuery(const NamespaceString& ns,
                                                const BSONObj& query) {
     if (MONGO_unlikely(ns.isCommand())) {
         return Status(ErrorCodes::InternalError, mongoutils::str::stream() <<
                       "Checking query auth on command namespace " << ns.ns());
     }
     if (!isAuthorizedForActionsOnNamespace(ns, ActionType::find)) {
         return Status(ErrorCodes::Unauthorized,
                       mongoutils::str::stream() << "not authorized for query on " << ns.ns());
     }
     return Status::OK();
 }
bool OperationContext::hasDeadlineExpired() const {
    if (!hasDeadline()) {
        return false;
    }
    if (MONGO_FAIL_POINT(maxTimeNeverTimeOut)) {
        return false;
    }
    if (MONGO_FAIL_POINT(maxTimeAlwaysTimeOut)) {
        return true;
    }

    // TODO: Remove once all OperationContexts are properly connected to Clients and ServiceContexts
    // in tests.
    if (MONGO_unlikely(!getClient() || !getServiceContext())) {
        return false;
    }

    const auto now = getServiceContext()->getFastClockSource()->now();
    return now >= getDeadline();
}
Exemple #4
0
std::shared_ptr<ViewDefinition> ViewCatalog::_lookup_inlock(OperationContext* txn, StringData ns) {
    // We expect the catalog to be valid, so short-circuit other checks for best performance.
    if (MONGO_unlikely(!_valid.load())) {
        // If the catalog is invalid, we want to avoid references to virtualized or other invalid
        // collection names to trigger a reload. This makes the system more robust in presence of
        // invalid view definitions.
        if (!NamespaceString::validCollectionName(ns))
            return nullptr;
        Status status = _reloadIfNeeded_inlock(txn);
        // In case of errors we've already logged a message. Only uassert if there actually is
        // a user connection, as otherwise we'd crash the server. The catalog will remain invalid,
        // and any views after the first invalid one are ignored.
        if (txn->getClient()->isFromUserConnection())
            uassertStatusOK(status);
    }

    ViewMap::const_iterator it = _viewMap.find(ns);
    if (it != _viewMap.end()) {
        return it->second;
    }
    return nullptr;
}
Exemple #5
0
OplogEntry::OplogEntry(BSONObj rawInput) : raw(std::move(rawInput)) {
    if (MONGO_unlikely(!raw.isOwned())) {
        raw = raw.copy();
    }

    for (auto elem : raw) {
        const auto name = elem.fieldNameStringData();
        if (name == "ns") {
            ns = elem.valuestrsafe();
        } else if (name == "op") {
            opType = elem.valuestrsafe();
        } else if (name == "o2") {
            o2 = elem;
        } else if (name == "ts") {
            ts = elem;
        } else if (name == "v") {
            version = elem;
        } else if (name == "o") {
            o = elem;
        }
    }
}
int BSONElement::computeSize() const {
    enum SizeStyle : uint8_t {
        kFixed,         // Total size is a fixed amount + key length.
        kIntPlusFixed,  // Like Fixed, but also add in the int32 immediately following the key.
        kRegEx,         // Handled specially.
    };
    struct SizeInfo {
        uint8_t style : 2;
        uint8_t bytes : 6;  // Includes type byte. Excludes field name and variable lengths.
    };
    MONGO_STATIC_ASSERT(sizeof(SizeInfo) == 1);

    // This table should take 20 bytes. Align to next power of 2 to avoid splitting across cache
    // lines unnecessarily.
    static constexpr SizeInfo kSizeInfoTable alignas(32)[] = {
        {SizeStyle::kFixed, 1},          // EOO
        {SizeStyle::kFixed, 9},          // NumberDouble
        {SizeStyle::kIntPlusFixed, 5},   // String
        {SizeStyle::kIntPlusFixed, 1},   // Object
        {SizeStyle::kIntPlusFixed, 1},   // Array
        {SizeStyle::kIntPlusFixed, 6},   // BinData
        {SizeStyle::kFixed, 1},          // Undefined
        {SizeStyle::kFixed, 13},         // OID
        {SizeStyle::kFixed, 2},          // Bool
        {SizeStyle::kFixed, 9},          // Date
        {SizeStyle::kFixed, 1},          // Null
        {SizeStyle::kRegEx},             // Regex
        {SizeStyle::kIntPlusFixed, 17},  // DBRef
        {SizeStyle::kIntPlusFixed, 5},   // Code
        {SizeStyle::kIntPlusFixed, 5},   // Symbol
        {SizeStyle::kIntPlusFixed, 1},   // CodeWScope
        {SizeStyle::kFixed, 5},          // Int
        {SizeStyle::kFixed, 9},          // Timestamp
        {SizeStyle::kFixed, 9},          // Long
        {SizeStyle::kFixed, 17},         // Decimal
    };
    MONGO_STATIC_ASSERT((sizeof(kSizeInfoTable) / sizeof(kSizeInfoTable[0])) == JSTypeMax + 1);

    // This is the start of the runtime code for this function. Everything above happens at compile
    // time. This function attempts to push complex handling of unlikely events out-of-line to
    // ensure that the common cases never need to spill any registers (at least on x64 with
    // gcc-5.4), which reduces the function call overhead.
    int8_t type = *data;
    if (MONGO_unlikely(type < 0 || type > JSTypeMax)) {
        if (MONGO_unlikely(type != MinKey && type != MaxKey)) {
            msgAssertedBadType(type);
        }

        // MinKey and MaxKey should be treated the same as Null
        type = jstNULL;
    }

    const auto sizeInfo = kSizeInfoTable[type];
    if (sizeInfo.style == SizeStyle::kFixed)
        return sizeInfo.bytes + fieldNameSize();
    if (MONGO_likely(sizeInfo.style == SizeStyle::kIntPlusFixed))
        return sizeInfo.bytes + fieldNameSize() + valuestrsize();

    return [this, type]() NOINLINE_DECL {
        // Regex is two c-strings back-to-back.
        invariant(type == BSONType::RegEx);
        const char* p = value();
        size_t len1 = strlen(p);
        p = p + len1 + 1;
        size_t len2 = strlen(p);
        return (len1 + 1 + len2 + 1) + fieldNameSize() + 1;
    }();
}