void subs_DeleteServer ( sub_sServer *sp ) { pwr_tStatus sts; sub_sBuffer *bp; gdb_sObject *op; gdb_AssumeLocked; bp = pool_Address(NULL, gdbroot->pool, sp->br); /* Disconnect from buffer. If the number of servers connected to the buffer reaches zero, the buffer gets disposed when it times out the next time. */ pool_Qremove(NULL, gdbroot->pool, &sp->bufsubs_ll); bp->bufsubs_lc -= 1; bp->totsize -= sp->aref.Size; /* Now give the subsrv entry back to the pool. */ pool_Qremove(NULL, gdbroot->pool, &sp->subs_ll); gdbroot->db->subs_lc--; pool_Qremove(NULL, gdbroot->pool, &sp->nodsubs_ll); /* Remove from server table. */ hash_Remove(&sts, gdbroot->subs_ht, sp); /* Decrement subcounter for referenced object */ op = vol_OidToObject(&sts, sp->aref.Objid, gdb_mLo_owned, vol_mTrans_alias, cvol_eHint_none); if (op != NULL) { op->u.n.subcount--; } pool_Free(NULL, gdbroot->pool, sp); }
pwr_tBoolean dvol_DeleteObject ( pwr_tStatus *sts, pwr_tObjid oid ) { static cvol_sNotify dm; /* Cannot be on the stack for VAXELN */ gdb_sObject *op; gdb_sObject *p_op; gdb_sVolume *vp; gdb_AssumeLocked; if (oid.oix == pwr_cNObjectIx) pwr_Return(FALSE, sts, GDH__VOLDELETE); op = vol_OidToObject(sts, oid, gdb_mLo_dynamic, vol_mTrans_none, cvol_eHint_none); if (op == NULL) return FALSE; if (op->g.flags.b.isParent && cdh_ObjidIsNotNull(op->g.soid)) pwr_Return(FALSE, sts, GDH__CHILDREN); p_op = pool_Address(NULL, gdbroot->pool, op->l.por); vp = pool_Address(NULL, gdbroot->pool, op->l.vr); cvols_InitNotify(op, &dm, net_eMsg_deleteObject); unadoptObject(sts, op, p_op, &dm); vol_UnlinkObject(sts, vp, op, vol_mLink_delete); cvols_Notify(&dm); pwr_Return(TRUE, sts, GDH__SUCCESS); }
static gdb_sNode * testClient ( pwr_tStatus *sts, sub_sClient *cp ) { pwr_tStatus lsts = GDH__SUCCESS; pwr_tSubid sid = cp->sid; cdh_sParseName parseName; cdh_sParseName *pn; gdb_sObject *op = NULL; sub_sClient *rcp; gdb_sVolume *vp; gdb_sNode *np = NULL; mvol_sAttribute attribute; mvol_sAttribute *ap; pwr_sAttrRef *arp; pwr_sAttrRef *rarp; gdb_sCclass *ccp; gdb_sCclass *ccpLocked; pool_tRef ccr; pwr_tUInt32 ridx; pwr_tBoolean equal; pwr_tBoolean fetched; gdb_AssumeLocked; do { if (cp->sub_by_name) { /* Lookup by name. */ pn = cdh_ParseName(&lsts, &parseName, pwr_cNObjid, cp->name, 0); if (pn == NULL) break; do { ap = vol_NameToAttribute(&lsts, &attribute, pn, gdb_mLo_global, vol_mTrans_all); if (ap == NULL) break; rcp = hash_Search(sts, gdbroot->subc_ht, &sid); if (rcp != cp) break; /* Subscription client no longer exists! */ arp = mvol_AttributeToAref(&lsts, ap, &cp->aref); if (arp == NULL) break; op = ap->op; /* */ vp = pool_Address(NULL, gdbroot->pool, op->l.vr); np = hash_Search(&lsts, gdbroot->nid_ht, &vp->g.nid); if (np == NULL) { op = NULL; break; } ccp = NULL; equal = 1; /* Get cached class if needed */ if (!op->u.c.flags.b.classChecked || !op->u.c.flags.b.classEqual) { ccp = cmvolc_GetCachedClass(&lsts, np, vp, ap, &equal, &fetched, NULL); if (EVEN(lsts)) { np = NULL; op = NULL; break; } if (fetched) { rcp = hash_Search(sts, gdbroot->subc_ht, &sid); if (rcp != cp) break; /* Subscription client no longer exists! */ } if (equal) { if (cp->cclass != pool_cNRef) { ccp = pool_Address(NULL, gdbroot->pool, cp->cclass); if (ccp == NULL) errh_Bugcheck(GDH__WEIRD, "cached class address"); cmvolc_UnlockClass(NULL, ccp); cp->cclass = pool_cNRef; } ccp = NULL; } else { ccr = pool_ItemReference(NULL, gdbroot->pool, ccp); if (ccr == pool_cNRef) errh_Bugcheck(GDH__WEIRD, "cache class address to reference"); if (ccr != cp->cclass) { if (cp->cclass != pool_cNRef) { gdb_sCclass *cc2p = pool_Address(NULL, gdbroot->pool, cp->cclass); cmvolc_UnlockClass(NULL, cc2p); } cmvolc_LockClass(NULL, ccp); cp->cclass = ccr; } } /* If gdb has been unlocked, refresh pointers */ /** @todo Check if we can do it more efficient, eg. vol_ArefToAttribute */ if (fetched) { np = NULL; op = NULL; continue; } } break; } while (1); } else { /* Lookup by attribute reference. */ do { op = vol_OidToObject(&lsts, cp->aref.Objid, gdb_mLo_global, vol_mTrans_all, cvol_eHint_none); if (op == NULL) { lsts = GDH__NOSUCHOBJ; break; } rcp = hash_Search(sts, gdbroot->subc_ht, &sid); if (rcp != cp) break; /* Subscription client no longer exists! */ if (op->g.flags.b.isAliasServer) cp->aref.Objid = op->g.oid; /* This is a not to ugly fix, but it should be removed, LW. It's done to make Leif-Göran Hansson happier. I.e. it makes the linksup program work. */ cp->aref.Objid = op->g.oid; vp = pool_Address(NULL, gdbroot->pool, op->l.vr); np = hash_Search(&lsts, gdbroot->nid_ht, &vp->g.nid); if (np == NULL) { op = NULL; break; } ccp = NULL; equal = 1; /* Get cached class if needed */ if (!op->u.c.flags.b.classChecked || !op->u.c.flags.b.classEqual) { ap = vol_ArefToAttribute(&lsts, &attribute, &cp->aref, gdb_mLo_global, vol_mTrans_all); if (ap == NULL) break; ccp = cmvolc_GetCachedClass(&lsts, np, vp, ap, &equal, &fetched, NULL); if (EVEN(lsts)) { np = NULL; op = NULL; break; } if (fetched) { rcp = hash_Search(sts, gdbroot->subc_ht, &sid); if (rcp != cp) break; /* Subscription client no longer exists! */ } if (equal) { if (cp->cclass != pool_cNRef) { ccp = pool_Address(NULL, gdbroot->pool, cp->cclass); if (ccp == NULL) errh_Bugcheck(GDH__WEIRD, "cached class address"); cmvolc_UnlockClass(NULL, ccp); cp->cclass = pool_cNRef; } ccp = NULL; } else { ccr = pool_ItemReference(NULL, gdbroot->pool, ccp); if (ccr == pool_cNRef) errh_Bugcheck(GDH__WEIRD, "cache class address to reference"); if (ccr != cp->cclass) { if (cp->cclass != pool_cNRef) { gdb_sCclass *cc2p = pool_Address(NULL, gdbroot->pool, cp->cclass); cmvolc_UnlockClass(NULL, cc2p); } cmvolc_LockClass(NULL, ccp); cp->cclass = ccr; } } /* If gdb has been unlocked, refresh pointers */ /** @todo Check if we can do it more efficient, eg. vol_ArefToAttribute */ if (fetched) { np = NULL; op = NULL; continue; } } break; } while (1); } } while (0); /* There is a risk that the client has disappeared after these calls (can result in a cache lookup). Verify that it still exists... */ rcp = hash_Search(sts, gdbroot->subc_ht, &sid); if (rcp == cp) { /* OK, it exists! */ cp->sts = lsts; if (op != NULL) { if (gdbroot->db->log.b.sub) errh_Info("Test client %s", op->g.f.name.orig); vp = pool_Address(NULL, gdbroot->pool, op->l.vr); np = pool_Address(NULL, gdbroot->pool, vp->l.nr); if (!equal) { ccpLocked = ccp; rarp = ndc_NarefToRaref(sts, ap, arp, ccp, &ridx, &cp->raref, &equal, NULL, ccpLocked, vp, np ); if (rarp == NULL || equal) { if (ccp->flags.b.cacheLock) cmvolc_UnlockClass(NULL, ccp); cp->cclass = pool_cNRef; if (rarp == NULL) np = gdbroot->no_node; } else { if (!ccp->flags.b.rnConv) { ndc_sRemoteToNative *tbl; gdb_sClass *c = hash_Search(sts, gdbroot->cid_ht, &ccp->key.cid); if (c == NULL) errh_Bugcheck(GDH__WEIRD, "can't get class"); tbl = pool_Alloc(sts, gdbroot->pool, sizeof(*tbl) * c->acount); ndc_UpdateRemoteToNativeTable(sts, tbl, c->acount, c, ccp, np->nid); if (ODD(*sts)) { ccp->rnConv = pool_Reference(NULL, gdbroot->pool, tbl); ccp->flags.b.rnConv = 1; } else { pool_Free(NULL, gdbroot->pool, tbl); cmvolc_UnlockClass(NULL, ccp); cp->cclass = pool_cNRef; np = gdbroot->no_node; } } } } /* not equal class versions */ } else { np = gdbroot->no_node; } } return np; }
gdb_sObject * dvol_CreateObject ( pwr_tStatus *sts, cdh_sParseName *pn, pwr_tClassId cid, pwr_tUInt32 size, pwr_tObjid oid /* Requested objid, */ ) { static cvol_sNotify cm; /* Cannot be on the stack for VAXELN */ pwr_tObjid poid; /* Objid of parent (or pwr_cNObjid) */ pwr_tInt32 size2; /* Size of the new object */ gdb_sClass *cp; gdb_sObject *tmp_op; gdb_sObject *op; gdb_sObject *pop; gdb_sVolume *vp; pwr_sClassDef *cdef; gdb_AssumeLocked; if (pn->flags.b.idString) pwr_Return(NULL, sts, GDH__NOSUCHOBJ); /* Verify class. */ cp = hash_Search(sts, gdbroot->cid_ht, &cid); if (cp == NULL) return NULL; size2 = MAX(size, cp->size); /* Check parent. */ pop = vol_NameToParentObject(sts, pn, gdb_mLo_dynamic, vol_mTrans_all); if (pop == NULL) { if (pn->nObject > 1) pwr_Return(NULL, sts , GDH__BADPARENT); poid = pwr_cNObjid; if (cdh_ObjidIsNull(oid)) poid.vid = gdbroot->db->vid; else poid.vid = oid.vid; pop = vol_OidToObject(sts, poid, gdb_mLo_dynamic, vol_mTrans_all, cvol_eHint_none); if (pop == NULL) return NULL; } else { poid = pop->g.oid; if (cdh_ObjidIsNotNull(oid) && oid.vid != pop->g.oid.vid) pwr_Return(NULL, sts, GDH__BADPARENT); } vp = pool_Address(sts, gdbroot->pool, pop->l.vr); if (vp == NULL) pwr_Return(NULL, sts, GDH__BADPARENT); if (!vp->l.flags.b.dynamic) pwr_Return(NULL, sts, GDH__STATICVOL); /* Make sure that the name is unique. */ pn->object[pn->nObject-1].poid = poid; if (hash_Search(sts, gdbroot->family_ht, &pn->object[pn->nObject-1]) != NULL) pwr_Return(NULL, sts, GDH__DUPLNAME); if (cdh_ObjidIsNull(oid)) oid = vol_Oid(sts, vp, cid); if (hash_Search(sts, gdbroot->oid_ht, &oid) != NULL) return NULL; tmp_op = op = gdb_AddObject(sts, pn->object[pn->nObject-1].name.orig, oid, cid, size2, poid, net_mGo__, pwr_cNObjid); if (op == NULL) return NULL; do { /* We have alloced an object header. Free it if something happens. */ op = vol_LinkObject(sts, vp, op, vol_mLink_create); if (op == NULL) break; cvols_InitNotify(op, &cm, net_eMsg_createObject); op = adoptObject(sts, op, pop, &cm); if (op == NULL) break; cdef = pool_Address(NULL, gdbroot->rtdb, cp->cbr); if ( cdef->Flags.b.RtReadOnly) op->u.n.lflags.b.readOnly = 1; cvols_Notify(&cm); return op; } while (0); vol_UnlinkObject(sts, vp, op, vol_mLink_delete); return NULL; }