summaryrefslogtreecommitdiffstats
path: root/sys/netgraph
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2008-03-11 21:58:48 +0000
committermav <mav@FreeBSD.org>2008-03-11 21:58:48 +0000
commitdd8463bf8829b5952ae30689231e7d4060d170f6 (patch)
tree8a8b6cd557e9a8f70a8992596adaaf8fa83292a5 /sys/netgraph
parent384b4a0305cc04c8c51a266299a985170a7901cf (diff)
downloadFreeBSD-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.h3
-rw-r--r--sys/netgraph/ng_base.c33
-rw-r--r--sys/netgraph/ng_socket.c2
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);
OpenPOWER on IntegriCloud