diff options
author | mav <mav@FreeBSD.org> | 2008-03-11 21:58:48 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2008-03-11 21:58:48 +0000 |
commit | dd8463bf8829b5952ae30689231e7d4060d170f6 (patch) | |
tree | 8a8b6cd557e9a8f70a8992596adaaf8fa83292a5 /sys/netgraph | |
parent | 384b4a0305cc04c8c51a266299a985170a7901cf (diff) | |
download | FreeBSD-src-dd8463bf8829b5952ae30689231e7d4060d170f6.zip FreeBSD-src-dd8463bf8829b5952ae30689231e7d4060d170f6.tar.gz |
Improve apply callback error reporting:
Before this patch callback returned result of the last finished call chain.
Now it returns last nonzero result from all call chain results in this request.
As soon as this improvement gives reliable error reporting, it is now possible
to remove dirty workaround in ng_socket, made to return ENOBUFS error statuses
of request-response operations. That workaround was responsible for returning
ENOBUFS errors to completely unrelated requests working at the same time
on socket.
Diffstat (limited to 'sys/netgraph')
-rw-r--r-- | sys/netgraph/netgraph.h | 3 | ||||
-rw-r--r-- | sys/netgraph/ng_base.c | 33 | ||||
-rw-r--r-- | sys/netgraph/ng_socket.c | 2 |
3 files changed, 28 insertions, 10 deletions
diff --git a/sys/netgraph/netgraph.h b/sys/netgraph/netgraph.h index 69559ce..e0b53d1 100644 --- a/sys/netgraph/netgraph.h +++ b/sys/netgraph/netgraph.h @@ -608,6 +608,7 @@ struct ng_apply_info { ng_apply_t *apply; void *context; int refs; + int error; }; struct ng_item { u_long el_flags; @@ -634,7 +635,7 @@ struct ng_item { * and its context. */ struct ng_apply_info *apply; - void *PAD1; + uintptr_t depth; #ifdef NETGRAPH_DEBUG /*----------------------------------------------*/ char *lastfile; int lastline; diff --git a/sys/netgraph/ng_base.c b/sys/netgraph/ng_base.c index 10eca62..cde7fdb 100644 --- a/sys/netgraph/ng_base.c +++ b/sys/netgraph/ng_base.c @@ -2250,9 +2250,13 @@ ng_flush_input_queue(struct ng_queue * ngq) NG_QUEUE_UNLOCK(ngq); /* If the item is supplying a callback, call it with an error */ - if (item->apply != NULL && - refcount_release(&item->apply->refs)) { - (*item->apply->apply)(item->apply->context, ENOENT); + if (item->apply != NULL) { + if (item->depth == 1) + item->apply->error = ENOENT; + if (refcount_release(&item->apply->refs)) { + (*item->apply->apply)(item->apply->context, + item->apply->error); + } } NG_FREE_ITEM(item); NG_QUEUE_LOCK(ngq); @@ -2367,6 +2371,7 @@ ng_snd_item(item_p item, int flags) #ifdef NETGRAPH_DEBUG _ngi_check(item, __FILE__, __LINE__); #endif + item->depth = 1; NG_QUEUE_LOCK(ngq); ng_queue_rw(ngq, item, rw); NG_QUEUE_UNLOCK(ngq); @@ -2394,6 +2399,7 @@ ng_snd_item(item_p item, int flags) NGI_GET_NODE(item, node); /* zaps stored node */ + item->depth++; error = ng_apply_item(node, item, rw); /* drops r/w lock when done */ /* @@ -2413,8 +2419,14 @@ ng_snd_item(item_p item, int flags) done: /* If was not sent, apply callback here. */ - if (item->apply != NULL && refcount_release(&item->apply->refs)) - (*item->apply->apply)(item->apply->context, error); + if (item->apply != NULL) { + if (item->depth == 0 && error != 0) + item->apply->error = error; + if (refcount_release(&item->apply->refs)) { + (*item->apply->apply)(item->apply->context, + item->apply->error); + } + } NG_FREE_ITEM(item); return (error); @@ -2430,10 +2442,10 @@ static int ng_apply_item(node_p node, item_p item, int rw) { hook_p hook; - int error = 0; ng_rcvdata_t *rcvdata; ng_rcvmsg_t *rcvmsg; struct ng_apply_info *apply; + int error = 0, depth; /* Node and item are never optional. */ KASSERT(node != NULL, ("ng_apply_item: node is NULL")); @@ -2445,6 +2457,7 @@ ng_apply_item(node_p node, item_p item, int rw) #endif apply = item->apply; + depth = item->depth; switch (item->el_flags & NGQF_TYPE) { case NGQF_DATA: @@ -2552,8 +2565,12 @@ ng_apply_item(node_p node, item_p item, int rw) ng_leave_write(&node->nd_input_queue); /* Apply callback. */ - if (apply != NULL && refcount_release(&apply->refs)) - (*apply->apply)(apply->context, error); + if (apply != NULL) { + if (depth == 1 && error != 0) + apply->error = error; + if (refcount_release(&apply->refs)) + (*apply->apply)(apply->context, apply->error); + } return (error); } diff --git a/sys/netgraph/ng_socket.c b/sys/netgraph/ng_socket.c index b444794..410c2d9 100644 --- a/sys/netgraph/ng_socket.c +++ b/sys/netgraph/ng_socket.c @@ -919,7 +919,7 @@ ngs_rcvmsg(node_p node, item_p item, hook_p lasthook) if (sbappendaddr(&so->so_rcv, (struct sockaddr *)&addr, m, NULL) == 0) { TRAP_ERROR; m_freem(m); - error = so->so_error = ENOBUFS; + return (ENOBUFS); } sorwakeup(so); |