aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/block/dasd_devmap.c
diff options
context:
space:
mode:
authorHorst Hummel <horst.hummel@de.ibm.com>2006-08-10 09:45:16 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2006-08-10 09:45:16 -0400
commitd0710c7c9eea2145a0614f39dbe9dc8cb4ae14da (patch)
tree6d89207033a0a4a9e0c02b507a7f4745d40d4a9d /drivers/s390/block/dasd_devmap.c
parentebc4599990898ecaaace7ed40dfad6d8d9f2a24a (diff)
[S390] dasd calls kzalloc while holding a spinlock.
The dasd function dasd_set_uid calls kzalloc while holding the dasd_devmap_lock. Rearrange the code to do the memory allocation outside the lock. Signed-off-by: Horst Hummel <horst.hummel@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/block/dasd_devmap.c')
-rw-r--r--drivers/s390/block/dasd_devmap.c65
1 files changed, 28 insertions, 37 deletions
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index 7f6fdac74706..6fcb28d55a9d 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -89,7 +89,7 @@ static char *dasd[256];
89module_param_array(dasd, charp, NULL, 0); 89module_param_array(dasd, charp, NULL, 0);
90 90
91/* 91/*
92 * Single spinlock to protect devmap structures and lists. 92 * Single spinlock to protect devmap and servermap structures and lists.
93 */ 93 */
94static DEFINE_SPINLOCK(dasd_devmap_lock); 94static DEFINE_SPINLOCK(dasd_devmap_lock);
95 95
@@ -859,39 +859,6 @@ static struct attribute_group dasd_attr_group = {
859}; 859};
860 860
861/* 861/*
862 * Check if the related storage server is already contained in the
863 * dasd_serverlist. If server is not contained, create new entry.
864 * Return 0 if server was already in serverlist,
865 * 1 if the server was added successfully
866 * <0 in case of error.
867 */
868static int
869dasd_add_server(struct dasd_uid *uid)
870{
871 struct dasd_servermap *new, *tmp;
872
873 /* check if server is already contained */
874 list_for_each_entry(tmp, &dasd_serverlist, list)
875 // normale cmp?
876 if (strncmp(tmp->sid.vendor, uid->vendor,
877 sizeof(tmp->sid.vendor)) == 0
878 && strncmp(tmp->sid.serial, uid->serial,
879 sizeof(tmp->sid.serial)) == 0)
880 return 0;
881
882 new = (struct dasd_servermap *)
883 kzalloc(sizeof(struct dasd_servermap), GFP_KERNEL);
884 if (!new)
885 return -ENOMEM;
886
887 strncpy(new->sid.vendor, uid->vendor, sizeof(new->sid.vendor));
888 strncpy(new->sid.serial, uid->serial, sizeof(new->sid.serial));
889 list_add(&new->list, &dasd_serverlist);
890 return 1;
891}
892
893
894/*
895 * Return copy of the device unique identifier. 862 * Return copy of the device unique identifier.
896 */ 863 */
897int 864int
@@ -910,6 +877,8 @@ dasd_get_uid(struct ccw_device *cdev, struct dasd_uid *uid)
910 877
911/* 878/*
912 * Register the given device unique identifier into devmap struct. 879 * Register the given device unique identifier into devmap struct.
880 * In addition check if the related storage server is already contained in the
881 * dasd_serverlist. If server is not contained, create new entry.
913 * Return 0 if server was already in serverlist, 882 * Return 0 if server was already in serverlist,
914 * 1 if the server was added successful 883 * 1 if the server was added successful
915 * <0 in case of error. 884 * <0 in case of error.
@@ -918,16 +887,38 @@ int
918dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid) 887dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid)
919{ 888{
920 struct dasd_devmap *devmap; 889 struct dasd_devmap *devmap;
921 int rc; 890 struct dasd_servermap *srv, *tmp;
922 891
923 devmap = dasd_find_busid(cdev->dev.bus_id); 892 devmap = dasd_find_busid(cdev->dev.bus_id);
924 if (IS_ERR(devmap)) 893 if (IS_ERR(devmap))
925 return PTR_ERR(devmap); 894 return PTR_ERR(devmap);
895
896 /* generate entry for servermap */
897 srv = (struct dasd_servermap *)
898 kzalloc(sizeof(struct dasd_servermap), GFP_KERNEL);
899 if (!srv)
900 return -ENOMEM;
901 strncpy(srv->sid.vendor, uid->vendor, sizeof(srv->sid.vendor) - 1);
902 strncpy(srv->sid.serial, uid->serial, sizeof(srv->sid.serial) - 1);
903
904 /* server is already contained ? */
926 spin_lock(&dasd_devmap_lock); 905 spin_lock(&dasd_devmap_lock);
927 devmap->uid = *uid; 906 devmap->uid = *uid;
928 rc = dasd_add_server(uid); 907 list_for_each_entry(tmp, &dasd_serverlist, list) {
908 if (!memcmp(&srv->sid, &tmp->sid,
909 sizeof(struct dasd_servermap))) {
910 kfree(srv);
911 srv = NULL;
912 break;
913 }
914 }
915
916 /* add servermap to serverlist */
917 if (srv)
918 list_add(&srv->list, &dasd_serverlist);
929 spin_unlock(&dasd_devmap_lock); 919 spin_unlock(&dasd_devmap_lock);
930 return rc; 920
921 return (srv ? 1 : 0);
931} 922}
932EXPORT_SYMBOL_GPL(dasd_set_uid); 923EXPORT_SYMBOL_GPL(dasd_set_uid);
933 924