#include <linux/blkdev.h>
#include <linux/moduleparam.h>
#include <linux/cdev.h>
-#include <linux/idr.h>
+#include <linux/xarray.h>
#include <linux/delay.h>
#include <linux/mutex.h>
#define to_scsi_tape(obj) container_of(obj, struct scsi_tape, kref)
static DEFINE_MUTEX(st_ref_mutex);
-static DEFINE_SPINLOCK(st_index_lock);
static DEFINE_SPINLOCK(st_use_lock);
-static DEFINE_IDR(st_index_idr);
+static DEFINE_XARRAY_ALLOC(st_index);
\f
static struct scsi_tape *scsi_tape_get(int dev)
{
- struct scsi_tape *STp = NULL;
+ struct scsi_tape *STp;
mutex_lock(&st_ref_mutex);
- spin_lock(&st_index_lock);
+ xa_lock(&st_index);
- STp = idr_find(&st_index_idr, dev);
- if (!STp) goto out;
+ STp = xa_load(&st_index, dev);
+ if (!STp)
+ goto out;
kref_get(&STp->kref);
kref_put(&STp->kref, scsi_tape_release);
STp = NULL;
out:
- spin_unlock(&st_index_lock);
+ xa_unlock(&st_index);
mutex_unlock(&st_ref_mutex);
return STp;
}
tpnt->blksize_changed = 0;
mutex_init(&tpnt->lock);
- idr_preload(GFP_KERNEL);
- spin_lock(&st_index_lock);
- error = idr_alloc(&st_index_idr, tpnt, 0, ST_MAX_TAPES + 1, GFP_NOWAIT);
- spin_unlock(&st_index_lock);
- idr_preload_end();
+ error = xa_alloc(&st_index, &tpnt->index, tpnt,
+ XA_LIMIT(0, ST_MAX_TAPES), GFP_KERNEL);
if (error < 0) {
- pr_warn("st: idr allocation failed: %d\n", error);
+ pr_warn("st: ID allocation failed: %d\n", error);
goto out_put_queue;
}
- tpnt->index = error;
sprintf(disk->disk_name, "st%d", tpnt->index);
tpnt->stats = kzalloc(sizeof(struct scsi_tape_stats), GFP_KERNEL);
if (tpnt->stats == NULL) {
sdev_printk(KERN_ERR, SDp,
"st: Can't allocate statistics.\n");
- goto out_idr_remove;
+ goto out_xa_erase;
}
dev_set_drvdata(dev, tpnt);
out_remove_devs:
remove_cdevs(tpnt);
kfree(tpnt->stats);
-out_idr_remove:
- spin_lock(&st_index_lock);
- idr_remove(&st_index_idr, tpnt->index);
- spin_unlock(&st_index_lock);
+out_xa_erase:
+ xa_erase(&st_index, tpnt->index);
out_put_queue:
blk_put_queue(disk->queue);
out_put_disk:
scsi_autopm_get_device(to_scsi_device(dev));
remove_cdevs(tpnt);
+ xa_erase(&st_index, index);
mutex_lock(&st_ref_mutex);
kref_put(&tpnt->kref, scsi_tape_release);
mutex_unlock(&st_ref_mutex);
- spin_lock(&st_index_lock);
- idr_remove(&st_index_idr, index);
- spin_unlock(&st_index_lock);
return 0;
}
unregister_chrdev_region(MKDEV(SCSI_TAPE_MAJOR, 0),
ST_MAX_TAPE_ENTRIES);
class_unregister(&st_sysfs_class);
- idr_destroy(&st_index_idr);
printk(KERN_INFO "st: Unloaded.\n");
}