Commit 98c05147 authored by Josh Kunz's avatar Josh Kunz

Actually call grant callback + callback docs

Currently I'm assuming that we want the grant callbacks to actually see
the granted cnode. Therefore, we need to roll-back if the grant callback
aborts the grant operation.

The additional comments about the libcap callbacks just explain their
semantics in greater detail.
parent 909fc18e
......@@ -821,6 +821,15 @@ fail3:
return ret;
}
static void __cap_try_grant_cnode_copy(struct cnode *src, struct cnode *dst,
bool do_list) {
dst->type = src->type;
dst->object = src->object;
dst->cspace = src->cspace;
dst->cdt_root = src->cdt_root;
if (do_list) { dst->siblings = src->siblings; }
}
static int __cap_try_grant(struct cnode *src, struct cnode *dst) {
int ret;
if (!__cap_cnode_is_used(src)) {
......@@ -844,16 +853,30 @@ static int __cap_try_grant(struct cnode *src, struct cnode *dst) {
/*
* Add dest cnode to source's children in cdt
*/
list_add(&dst->siblings, &dst->children);
__cap_cnode_release_cdt_root(src);
list_add(&dst->siblings, &src->children);
dst->type = src->type;
dst->object = src->object;
dst->cspace = src->cspace;
dst->cdt_root = src->cdt_root;
/* save dst contents in case we need to roll-back */
struct cnode _tmp;
__cap_try_grant_cnode_copy(dst, &_tmp, true);
__cap_try_grant_cnode_copy(src, dst, false);
/* Invoke the grant callback for this cnode type. No additional locking
* of the ts is needed because all ts updated are additive. */
ret = src->cspace->ts->types[src->type].grant(src, dst);
if (ret < 0) { /* rollback */
/* remove the dst node from the siblings list */
list_del(&dst->siblings);
/* Fixup everything else from our temporary copy.
* XXX: Can't use a memcpy 'cause we need to keep the same
* cnode lock. I'm not sure if copying held locks is OK. */
__cap_try_grant_cnode_copy(&_tmp, dst, true);
} else {
ret = 1;
}
ret = 1;
__cap_cnode_release_cdt_root(src);
fail:
return ret;
......
......@@ -74,13 +74,26 @@ struct cnode;
struct cap_type_ops {
char *name;
/* Invoked when a cnode is deleted. The cptr, cspace, and object associated
* with this cnode can obtained using the cnode accessor functions. */
* with this cnode can obtained using the cnode accessor functions.
* The operation can be aborted by returning a negative exit status which
* will be returned from the cap_X call.
* XXX: Be careful not to overlap exit codes. */
int (*delete)(struct cnode *cnode);
/* Invoked when a cnode is involed in a grant operation. */
/* Invoked when a cnode is involed in a grant operation. 'src' corresponds
* to the 'src' cptr, and 'dst' corresponds to the 'dst' cptr. See the
* delete callback for interface. */
int (*grant)(struct cnode *src, struct cnode *dst);
/* Invoked when a cnode is the source in a cap_derive operation. */
/* This callback is invoked for the 'src' cnode when that cnode is involved
* in a 'derive' operation. The 'src' corresponds to the 'src' cptr, and
* the 'dst' corresponds to the 'dst' cptr. See delete callback for
* interface. */
int (*derive_src)(struct cnode *src, struct cnode *dst);
/* Invoked when a cnode is the destination in a cap_derive operation. */
/* This callback is invoked for the 'dst' cnode (because its type may be
* different from the 'src' cnode and therefore it may have a different
* handler) when it is the 'dst' cptr of a 'derive' operation. Note: even
* though this callback is invoked on the dst node, the 'src' and 'dst' cnodes
* are still semantically related to the 'src' and 'dst' cnodes passed
* in the 'cap_derive' call. See the delete callback for interface. */
int (*derive_dst)(struct cnode *src, struct cnode *dst);
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment