/* ------------------------ */ cnid_t cnid_cdb_rebuild_add(struct _cnid_db *cdb, const struct stat *st, const cnid_t did, char *name, const size_t len, cnid_t hint) { CNID_private *db; DBT key, data; int rc; if (!cdb || !(db = cdb->_private) || !st || !name || hint == CNID_INVALID || hint < CNID_START) { errno = CNID_ERR_PARAM; return CNID_INVALID; } #if 0 /* FIXME: Bjoern does a lookup. Should we not overwrite unconditionally? */ /* Do a lookup. */ id = cnid_cdb_lookup(cdb, st, did, name, len); /* ... Return id if it is valid, or if Rootinfo is read-only. */ if (id || (db->flags & CNIDFLAG_DB_RO)) { #ifdef DEBUG LOG(log_debug9, logtype_default, "cnid_add: Looked up did %u, name %s as %u", ntohl(did), name, ntohl(id)); #endif return id; } #endif /* Initialize our DBT data structures. */ memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); if ((data.data = make_cnid_data(cdb->flags, st, did, name, len)) == NULL) { LOG(log_error, logtype_default, "cnid_add: Path name is too long"); errno = CNID_ERR_PATH; return CNID_INVALID; } data.size = CNID_HEADER_LEN + len + 1; memcpy(data.data, &hint, sizeof(hint)); key.data = &hint; key.size = sizeof(hint); /* Now we need to add the CNID data to the databases. */ if ((rc = db->db_cnid->put(db->db_cnid, tid, &key, &data, 0))) { LOG(log_error, logtype_default , "cnid_add: Failed to add CNID for %s to database using hint %u: %s", name, ntohl(hint), db_strerror(rc)); errno = CNID_ERR_DB; goto cleanup; } if (set_max_cnid(db, hint) == CNID_INVALID) { errno = CNID_ERR_DB; goto cleanup; } #ifdef DEBUG LOG(log_debug9, logtype_default, "cnid_add: Returned CNID for did %u, name %s as %u", ntohl(did), name, ntohl(hint)); #endif return hint; cleanup: return CNID_INVALID; }
/* ------------------------ */ cnid_t cnid_cdb_add(struct _cnid_db *cdb, const struct stat *st, cnid_t did, const char *name, size_t len, cnid_t hint) { CNID_private *db; DBT key, data; cnid_t id; int rc; if (!cdb || !(db = cdb->_private) || !st || !name) { errno = CNID_ERR_PARAM; return CNID_INVALID; } /* Do a lookup. */ id = cnid_cdb_lookup(cdb, st, did, name, len); /* ... Return id if it is valid, or if Rootinfo is read-only. */ if (id || (db->flags & CNIDFLAG_DB_RO)) { #ifdef DEBUG LOG(log_debug9, logtype_default, "cnid_add: Looked up did %u, name %s as %u", ntohl(did), name, ntohl(id)); #endif return id; } /* Initialize our DBT data structures. */ memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); if ((data.data = make_cnid_data(cdb->flags, st, did, name, len)) == NULL) { LOG(log_error, logtype_default, "cnid_add: Path name is too long"); errno = CNID_ERR_PATH; return CNID_INVALID; } data.size = CNID_HEADER_LEN + len + 1; if ((hint = get_cnid(db)) == 0) { errno = CNID_ERR_DB; return CNID_INVALID; } memcpy(data.data, &hint, sizeof(hint)); key.data = &hint; key.size = sizeof(hint); /* Now we need to add the CNID data to the databases. */ if ((rc = db->db_cnid->put(db->db_cnid, tid, &key, &data, DB_NOOVERWRITE))) { if (rc == EINVAL) { /* if we have a duplicate * on cnid it's a fatal error. * on dev:inode * - leftover should have been delete before. * - a second process already updated the db * - it's a new file eg our file is already deleted and replaced * on did:name leftover */ if (cnid_cdb_update(cdb, hint, st, did, name, len)) { errno = CNID_ERR_DB; return CNID_INVALID; } } else { LOG(log_error, logtype_default , "cnid_add: Failed to add CNID for %s to database using hint %u: %s", name, ntohl(hint), db_strerror(rc)); errno = CNID_ERR_DB; return CNID_INVALID; } } #ifdef DEBUG LOG(log_debug9, logtype_default, "cnid_add: Returned CNID for did %u, name %s as %u", ntohl(did), name, ntohl(hint)); #endif return hint; }