Skip to content

Commit c15fe55

Browse files
jgross1ericvh
authored andcommitted
9p/xen: fix connection sequence
Today the connection sequence of the Xen 9pfs frontend doesn't match the documented sequence. It can work reliably only for a PV 9pfs device having been added at boot time already, as the frontend is not waiting for the backend to have set its state to "XenbusStateInitWait" before reading the backend properties from Xenstore. Fix that by following the documented sequence [1] (the documentation has a bug, so the reference is for the patch fixing that). [1]: https://lore.kernel.org/xen-devel/[email protected]/T/#u Link: https://lkml.kernel.org/r/[email protected] Fixes: 868eb12 ("xen/9pfs: introduce Xen 9pfs transport driver") Signed-off-by: Juergen Gross <[email protected]> Reviewed-by: Simon Horman <[email protected]> Signed-off-by: Dominique Martinet <[email protected]> Signed-off-by: Eric Van Hensbergen <[email protected]>
1 parent f1956f4 commit c15fe55

File tree

1 file changed

+23
-15
lines changed

1 file changed

+23
-15
lines changed

net/9p/trans_xen.c

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -373,12 +373,11 @@ static int xen_9pfs_front_alloc_dataring(struct xenbus_device *dev,
373373
return ret;
374374
}
375375

376-
static int xen_9pfs_front_probe(struct xenbus_device *dev,
377-
const struct xenbus_device_id *id)
376+
static int xen_9pfs_front_init(struct xenbus_device *dev)
378377
{
379378
int ret, i;
380379
struct xenbus_transaction xbt;
381-
struct xen_9pfs_front_priv *priv = NULL;
380+
struct xen_9pfs_front_priv *priv = dev_get_drvdata(&dev->dev);
382381
char *versions, *v;
383382
unsigned int max_rings, max_ring_order, len = 0;
384383

@@ -406,11 +405,6 @@ static int xen_9pfs_front_probe(struct xenbus_device *dev,
406405
if (p9_xen_trans.maxsize > XEN_FLEX_RING_SIZE(max_ring_order))
407406
p9_xen_trans.maxsize = XEN_FLEX_RING_SIZE(max_ring_order) / 2;
408407

409-
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
410-
if (!priv)
411-
return -ENOMEM;
412-
413-
priv->dev = dev;
414408
priv->num_rings = XEN_9PFS_NUM_RINGS;
415409
priv->rings = kcalloc(priv->num_rings, sizeof(*priv->rings),
416410
GFP_KERNEL);
@@ -469,23 +463,35 @@ static int xen_9pfs_front_probe(struct xenbus_device *dev,
469463
goto error;
470464
}
471465

472-
write_lock(&xen_9pfs_lock);
473-
list_add_tail(&priv->list, &xen_9pfs_devs);
474-
write_unlock(&xen_9pfs_lock);
475-
dev_set_drvdata(&dev->dev, priv);
476-
xenbus_switch_state(dev, XenbusStateInitialised);
477-
478466
return 0;
479467

480468
error_xenbus:
481469
xenbus_transaction_end(xbt, 1);
482470
xenbus_dev_fatal(dev, ret, "writing xenstore");
483471
error:
484-
dev_set_drvdata(&dev->dev, NULL);
485472
xen_9pfs_front_free(priv);
486473
return ret;
487474
}
488475

476+
static int xen_9pfs_front_probe(struct xenbus_device *dev,
477+
const struct xenbus_device_id *id)
478+
{
479+
struct xen_9pfs_front_priv *priv = NULL;
480+
481+
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
482+
if (!priv)
483+
return -ENOMEM;
484+
485+
priv->dev = dev;
486+
dev_set_drvdata(&dev->dev, priv);
487+
488+
write_lock(&xen_9pfs_lock);
489+
list_add_tail(&priv->list, &xen_9pfs_devs);
490+
write_unlock(&xen_9pfs_lock);
491+
492+
return 0;
493+
}
494+
489495
static int xen_9pfs_front_resume(struct xenbus_device *dev)
490496
{
491497
dev_warn(&dev->dev, "suspend/resume unsupported\n");
@@ -504,6 +510,8 @@ static void xen_9pfs_front_changed(struct xenbus_device *dev,
504510
break;
505511

506512
case XenbusStateInitWait:
513+
if (!xen_9pfs_front_init(dev))
514+
xenbus_switch_state(dev, XenbusStateInitialised);
507515
break;
508516

509517
case XenbusStateConnected:

0 commit comments

Comments
 (0)