mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-27 08:14:35 +08:00
scsi: ch: synchronize ch_probe() and ch_open()
The 'ch' device node is created before the configuration is being read in, which leads to a race window when ch_open() is called before that. To avoid any races we should be taking the device mutex during ch_readconfig() and ch_init_elem(), and also during ch_open(). That ensures ch_probe is finished before ch_open() completes. Link: https://lore.kernel.org/r/20200213153207.123357-3-hare@suse.de Reviewed-by: Bart Van Assche <bvanassche@acm.org> Signed-off-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
66167283c2
commit
1c7ce4bcfb
@ -606,7 +606,10 @@ ch_open(struct inode *inode, struct file *file)
|
|||||||
mutex_unlock(&ch_mutex);
|
mutex_unlock(&ch_mutex);
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
}
|
}
|
||||||
|
/* Synchronize with ch_probe() */
|
||||||
|
mutex_lock(&ch->lock);
|
||||||
file->private_data = ch;
|
file->private_data = ch;
|
||||||
|
mutex_unlock(&ch->lock);
|
||||||
mutex_unlock(&ch_mutex);
|
mutex_unlock(&ch_mutex);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -949,6 +952,9 @@ static int ch_probe(struct device *dev)
|
|||||||
goto remove_idr;
|
goto remove_idr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_init(&ch->lock);
|
||||||
|
kref_init(&ch->ref);
|
||||||
|
ch->device = sd;
|
||||||
class_dev = device_create(ch_sysfs_class, dev,
|
class_dev = device_create(ch_sysfs_class, dev,
|
||||||
MKDEV(SCSI_CHANGER_MAJOR, ch->minor), ch,
|
MKDEV(SCSI_CHANGER_MAJOR, ch->minor), ch,
|
||||||
"s%s", ch->name);
|
"s%s", ch->name);
|
||||||
@ -959,15 +965,16 @@ static int ch_probe(struct device *dev)
|
|||||||
goto put_device;
|
goto put_device;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_init(&ch->lock);
|
mutex_lock(&ch->lock);
|
||||||
kref_init(&ch->ref);
|
|
||||||
ch->device = sd;
|
|
||||||
ret = ch_readconfig(ch);
|
ret = ch_readconfig(ch);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
mutex_unlock(&ch->lock);
|
||||||
goto destroy_dev;
|
goto destroy_dev;
|
||||||
|
}
|
||||||
if (init)
|
if (init)
|
||||||
ch_init_elem(ch);
|
ch_init_elem(ch);
|
||||||
|
|
||||||
|
mutex_unlock(&ch->lock);
|
||||||
dev_set_drvdata(dev, ch);
|
dev_set_drvdata(dev, ch);
|
||||||
sdev_printk(KERN_INFO, sd, "Attached scsi changer %s\n", ch->name);
|
sdev_printk(KERN_INFO, sd, "Attached scsi changer %s\n", ch->name);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user