@@ -777,12 +777,14 @@ static int xen_register_credit_watch(str
return -ENOMEM;
snprintf(node, maxlen, "%s/rate", dev->nodename);
vif->credit_watch.node = node;
+ vif->credit_watch.will_handle = NULL;
vif->credit_watch.callback = xen_net_rate_changed;
err = register_xenbus_watch(&vif->credit_watch);
if (err) {
pr_err("Failed to set watcher %s\n", vif->credit_watch.node);
kfree(node);
vif->credit_watch.node = NULL;
+ vif->credit_watch.will_handle = NULL;
vif->credit_watch.callback = NULL;
}
return err;
@@ -829,6 +831,7 @@ static int xen_register_mcast_ctrl_watch
snprintf(node, maxlen, "%s/request-multicast-control",
dev->otherend);
vif->mcast_ctrl_watch.node = node;
+ vif->mcast_ctrl_watch.will_handle = NULL;
vif->mcast_ctrl_watch.callback = xen_mcast_ctrl_changed;
err = register_xenbus_watch(&vif->mcast_ctrl_watch);
if (err) {
@@ -836,6 +839,7 @@ static int xen_register_mcast_ctrl_watch
vif->mcast_ctrl_watch.node);
kfree(node);
vif->mcast_ctrl_watch.node = NULL;
+ vif->mcast_ctrl_watch.will_handle = NULL;
vif->mcast_ctrl_watch.callback = NULL;
}
return err;
@@ -120,6 +120,7 @@ int xenbus_watch_path(struct xenbus_devi
int err;
watch->node = path;
+ watch->will_handle = NULL;
watch->callback = callback;
err = register_xenbus_watch(watch);
@@ -700,7 +700,10 @@ int xs_watch_msg(struct xs_watch_event *
spin_lock(&watches_lock);
event->handle = find_watch(event->token);
- if (event->handle != NULL) {
+ if (event->handle != NULL &&
+ (!event->handle->will_handle ||
+ event->handle->will_handle(event->handle,
+ event->path, event->token))) {
spin_lock(&watch_events_lock);
list_add_tail(&event->list, &watch_events);
wake_up(&watch_events_waitq);
@@ -59,6 +59,13 @@ struct xenbus_watch
/* Path being watched. */
const char *node;
+ /*
+ * Called just before enqueing new event while a spinlock is held.
+ * The event will be discarded if this callback returns false.
+ */
+ bool (*will_handle)(struct xenbus_watch *,
+ const char *path, const char *token);
+
/* Callback (executed in a process context with no locks held). */
void (*callback)(struct xenbus_watch *,
const char *path, const char *token);