forked from mirrors/linux
		
	xen/xenbus: Add 'will_handle' callback support in xenbus_watch_path()
Some code does not directly make 'xenbus_watch' object and call 'register_xenbus_watch()' but use 'xenbus_watch_path()' instead. This commit adds support of 'will_handle' callback in the 'xenbus_watch_path()' and it's wrapper, 'xenbus_watch_pathfmt()'. This is part of XSA-349 Cc: stable@vger.kernel.org Signed-off-by: SeongJae Park <sjpark@amazon.de> Reported-by: Michael Kurth <mku@amazon.de> Reported-by: Pawel Wieczorkiewicz <wipawel@amazon.de> Reviewed-by: Juergen Gross <jgross@suse.com> Signed-off-by: Juergen Gross <jgross@suse.com>
This commit is contained in:
		
							parent
							
								
									fed1755b11
								
							
						
					
					
						commit
						2e85d32b1c
					
				
					 6 changed files with 17 additions and 7 deletions
				
			
		|  | @ -675,7 +675,8 @@ static int xen_blkbk_probe(struct xenbus_device *dev, | ||||||
| 	/* setup back pointer */ | 	/* setup back pointer */ | ||||||
| 	be->blkif->be = be; | 	be->blkif->be = be; | ||||||
| 
 | 
 | ||||||
| 	err = xenbus_watch_pathfmt(dev, &be->backend_watch, backend_changed, | 	err = xenbus_watch_pathfmt(dev, &be->backend_watch, NULL, | ||||||
|  | 				   backend_changed, | ||||||
| 				   "%s/%s", dev->nodename, "physical-device"); | 				   "%s/%s", dev->nodename, "physical-device"); | ||||||
| 	if (err) | 	if (err) | ||||||
| 		goto fail; | 		goto fail; | ||||||
|  |  | ||||||
|  | @ -824,7 +824,7 @@ static void connect(struct backend_info *be) | ||||||
| 	xenvif_carrier_on(be->vif); | 	xenvif_carrier_on(be->vif); | ||||||
| 
 | 
 | ||||||
| 	unregister_hotplug_status_watch(be); | 	unregister_hotplug_status_watch(be); | ||||||
| 	err = xenbus_watch_pathfmt(dev, &be->hotplug_status_watch, | 	err = xenbus_watch_pathfmt(dev, &be->hotplug_status_watch, NULL, | ||||||
| 				   hotplug_status_changed, | 				   hotplug_status_changed, | ||||||
| 				   "%s/%s", dev->nodename, "hotplug-status"); | 				   "%s/%s", dev->nodename, "hotplug-status"); | ||||||
| 	if (!err) | 	if (!err) | ||||||
|  |  | ||||||
|  | @ -689,7 +689,7 @@ static int xen_pcibk_xenbus_probe(struct xenbus_device *dev, | ||||||
| 
 | 
 | ||||||
| 	/* watch the backend node for backend configuration information */ | 	/* watch the backend node for backend configuration information */ | ||||||
| 	err = xenbus_watch_path(dev, dev->nodename, &pdev->be_watch, | 	err = xenbus_watch_path(dev, dev->nodename, &pdev->be_watch, | ||||||
| 				xen_pcibk_be_watch); | 				NULL, xen_pcibk_be_watch); | ||||||
| 	if (err) | 	if (err) | ||||||
| 		goto out; | 		goto out; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -127,19 +127,22 @@ EXPORT_SYMBOL_GPL(xenbus_strstate); | ||||||
|  */ |  */ | ||||||
| int xenbus_watch_path(struct xenbus_device *dev, const char *path, | int xenbus_watch_path(struct xenbus_device *dev, const char *path, | ||||||
| 		      struct xenbus_watch *watch, | 		      struct xenbus_watch *watch, | ||||||
|  | 		      bool (*will_handle)(struct xenbus_watch *, | ||||||
|  | 					  const char *, const char *), | ||||||
| 		      void (*callback)(struct xenbus_watch *, | 		      void (*callback)(struct xenbus_watch *, | ||||||
| 				       const char *, const char *)) | 				       const char *, const char *)) | ||||||
| { | { | ||||||
| 	int err; | 	int err; | ||||||
| 
 | 
 | ||||||
| 	watch->node = path; | 	watch->node = path; | ||||||
| 	watch->will_handle = NULL; | 	watch->will_handle = will_handle; | ||||||
| 	watch->callback = callback; | 	watch->callback = callback; | ||||||
| 
 | 
 | ||||||
| 	err = register_xenbus_watch(watch); | 	err = register_xenbus_watch(watch); | ||||||
| 
 | 
 | ||||||
| 	if (err) { | 	if (err) { | ||||||
| 		watch->node = NULL; | 		watch->node = NULL; | ||||||
|  | 		watch->will_handle = NULL; | ||||||
| 		watch->callback = NULL; | 		watch->callback = NULL; | ||||||
| 		xenbus_dev_fatal(dev, err, "adding watch on %s", path); | 		xenbus_dev_fatal(dev, err, "adding watch on %s", path); | ||||||
| 	} | 	} | ||||||
|  | @ -166,6 +169,8 @@ EXPORT_SYMBOL_GPL(xenbus_watch_path); | ||||||
|  */ |  */ | ||||||
| int xenbus_watch_pathfmt(struct xenbus_device *dev, | int xenbus_watch_pathfmt(struct xenbus_device *dev, | ||||||
| 			 struct xenbus_watch *watch, | 			 struct xenbus_watch *watch, | ||||||
|  | 			 bool (*will_handle)(struct xenbus_watch *, | ||||||
|  | 					const char *, const char *), | ||||||
| 			 void (*callback)(struct xenbus_watch *, | 			 void (*callback)(struct xenbus_watch *, | ||||||
| 					  const char *, const char *), | 					  const char *, const char *), | ||||||
| 			 const char *pathfmt, ...) | 			 const char *pathfmt, ...) | ||||||
|  | @ -182,7 +187,7 @@ int xenbus_watch_pathfmt(struct xenbus_device *dev, | ||||||
| 		xenbus_dev_fatal(dev, -ENOMEM, "allocating path for watch"); | 		xenbus_dev_fatal(dev, -ENOMEM, "allocating path for watch"); | ||||||
| 		return -ENOMEM; | 		return -ENOMEM; | ||||||
| 	} | 	} | ||||||
| 	err = xenbus_watch_path(dev, path, watch, callback); | 	err = xenbus_watch_path(dev, path, watch, will_handle, callback); | ||||||
| 
 | 
 | ||||||
| 	if (err) | 	if (err) | ||||||
| 		kfree(path); | 		kfree(path); | ||||||
|  |  | ||||||
|  | @ -136,7 +136,7 @@ static int watch_otherend(struct xenbus_device *dev) | ||||||
| 		container_of(dev->dev.bus, struct xen_bus_type, bus); | 		container_of(dev->dev.bus, struct xen_bus_type, bus); | ||||||
| 
 | 
 | ||||||
| 	return xenbus_watch_pathfmt(dev, &dev->otherend_watch, | 	return xenbus_watch_pathfmt(dev, &dev->otherend_watch, | ||||||
| 				    bus->otherend_changed, | 				    NULL, bus->otherend_changed, | ||||||
| 				    "%s/%s", dev->otherend, "state"); | 				    "%s/%s", dev->otherend, "state"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -204,10 +204,14 @@ void xenbus_probe(struct work_struct *); | ||||||
| 
 | 
 | ||||||
| int xenbus_watch_path(struct xenbus_device *dev, const char *path, | int xenbus_watch_path(struct xenbus_device *dev, const char *path, | ||||||
| 		      struct xenbus_watch *watch, | 		      struct xenbus_watch *watch, | ||||||
|  | 		      bool (*will_handle)(struct xenbus_watch *, | ||||||
|  | 					  const char *, const char *), | ||||||
| 		      void (*callback)(struct xenbus_watch *, | 		      void (*callback)(struct xenbus_watch *, | ||||||
| 				       const char *, const char *)); | 				       const char *, const char *)); | ||||||
| __printf(4, 5) | __printf(5, 6) | ||||||
| int xenbus_watch_pathfmt(struct xenbus_device *dev, struct xenbus_watch *watch, | int xenbus_watch_pathfmt(struct xenbus_device *dev, struct xenbus_watch *watch, | ||||||
|  | 			 bool (*will_handle)(struct xenbus_watch *, | ||||||
|  | 					     const char *, const char *), | ||||||
| 			 void (*callback)(struct xenbus_watch *, | 			 void (*callback)(struct xenbus_watch *, | ||||||
| 					  const char *, const char *), | 					  const char *, const char *), | ||||||
| 			 const char *pathfmt, ...); | 			 const char *pathfmt, ...); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 SeongJae Park
						SeongJae Park