[S390] ccwgroup: add locking around drvdata access

Several processes may concurrently try to create a group device
from the same ccw_device(s). Add locking arround the drvdata
access to prevent race conditions.

Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

authored by Sebastian Ott and committed by Martin Schwidefsky c560d105 a65a3e82

+7
+7
drivers/s390/cio/ccwgroup.c
··· 123 124 for (i = 0; i < gdev->count; i++) { 125 if (gdev->cdev[i]) { 126 if (dev_get_drvdata(&gdev->cdev[i]->dev) == gdev) 127 dev_set_drvdata(&gdev->cdev[i]->dev, NULL); 128 put_device(&gdev->cdev[i]->dev); 129 } 130 } ··· 264 goto error; 265 } 266 /* Don't allow a device to belong to more than one group. */ 267 if (dev_get_drvdata(&gdev->cdev[i]->dev)) { 268 rc = -EINVAL; 269 goto error; 270 } 271 dev_set_drvdata(&gdev->cdev[i]->dev, gdev); 272 } 273 /* Check for sufficient number of bus ids. */ 274 if (i < num_devices && !curr_buf) { ··· 308 error: 309 for (i = 0; i < num_devices; i++) 310 if (gdev->cdev[i]) { 311 if (dev_get_drvdata(&gdev->cdev[i]->dev) == gdev) 312 dev_set_drvdata(&gdev->cdev[i]->dev, NULL); 313 put_device(&gdev->cdev[i]->dev); 314 gdev->cdev[i] = NULL; 315 }
··· 123 124 for (i = 0; i < gdev->count; i++) { 125 if (gdev->cdev[i]) { 126 + spin_lock_irq(gdev->cdev[i]->ccwlock); 127 if (dev_get_drvdata(&gdev->cdev[i]->dev) == gdev) 128 dev_set_drvdata(&gdev->cdev[i]->dev, NULL); 129 + spin_unlock_irq(gdev->cdev[i]->ccwlock); 130 put_device(&gdev->cdev[i]->dev); 131 } 132 } ··· 262 goto error; 263 } 264 /* Don't allow a device to belong to more than one group. */ 265 + spin_lock_irq(gdev->cdev[i]->ccwlock); 266 if (dev_get_drvdata(&gdev->cdev[i]->dev)) { 267 + spin_unlock_irq(gdev->cdev[i]->ccwlock); 268 rc = -EINVAL; 269 goto error; 270 } 271 dev_set_drvdata(&gdev->cdev[i]->dev, gdev); 272 + spin_unlock_irq(gdev->cdev[i]->ccwlock); 273 } 274 /* Check for sufficient number of bus ids. */ 275 if (i < num_devices && !curr_buf) { ··· 303 error: 304 for (i = 0; i < num_devices; i++) 305 if (gdev->cdev[i]) { 306 + spin_lock_irq(gdev->cdev[i]->ccwlock); 307 if (dev_get_drvdata(&gdev->cdev[i]->dev) == gdev) 308 dev_set_drvdata(&gdev->cdev[i]->dev, NULL); 309 + spin_unlock_irq(gdev->cdev[i]->ccwlock); 310 put_device(&gdev->cdev[i]->dev); 311 gdev->cdev[i] = NULL; 312 }