diff options
Diffstat (limited to 'drivers/scsi/osd')
-rw-r--r-- | drivers/scsi/osd/osd_uld.c | 66 |
1 files changed, 30 insertions, 36 deletions
diff --git a/drivers/scsi/osd/osd_uld.c b/drivers/scsi/osd/osd_uld.c index 22b59e13ba8..0bdef339090 100644 --- a/drivers/scsi/osd/osd_uld.c +++ b/drivers/scsi/osd/osd_uld.c @@ -49,6 +49,7 @@ #include <linux/device.h> #include <linux/idr.h> #include <linux/major.h> +#include <linux/file.h> #include <scsi/scsi.h> #include <scsi/scsi_driver.h> @@ -175,10 +176,9 @@ static const struct file_operations osd_fops = { struct osd_dev *osduld_path_lookup(const char *name) { - struct path path; - struct inode *inode; - struct cdev *cdev; - struct osd_uld_device *uninitialized_var(oud); + struct osd_uld_device *oud; + struct osd_dev *od; + struct file *file; int error; if (!name || !*name) { @@ -186,52 +186,46 @@ struct osd_dev *osduld_path_lookup(const char *name) return ERR_PTR(-EINVAL); } - error = kern_path(name, LOOKUP_FOLLOW, &path); - if (error) { - OSD_ERR("path_lookup of %s failed=>%d\n", name, error); - return ERR_PTR(error); - } + od = kzalloc(sizeof(*od), GFP_KERNEL); + if (!od) + return ERR_PTR(-ENOMEM); - inode = path.dentry->d_inode; - error = -EINVAL; /* Not the right device e.g osd_uld_device */ - if (!S_ISCHR(inode->i_mode)) { - OSD_DEBUG("!S_ISCHR()\n"); - goto out; + file = filp_open(name, O_RDWR, 0); + if (IS_ERR(file)) { + error = PTR_ERR(file); + goto free_od; } - cdev = inode->i_cdev; - if (!cdev) { - OSD_ERR("Before mounting an OSD Based filesystem\n"); - OSD_ERR(" user-mode must open+close the %s device\n", name); - OSD_ERR(" Example: bash: echo < %s\n", name); - goto out; + if (file->f_op != &osd_fops){ + error = -EINVAL; + goto close_file; } - /* The Magic wand. Is it our char-dev */ - /* TODO: Support sg devices */ - if (cdev->owner != THIS_MODULE) { - OSD_ERR("Error mounting %s - is not an OSD device\n", name); - goto out; - } + oud = file->private_data; - oud = container_of(cdev, struct osd_uld_device, cdev); + *od = oud->od; + od->file = file; - __uld_get(oud); - error = 0; + return od; -out: - path_put(&path); - return error ? ERR_PTR(error) : &oud->od; +close_file: + fput(file); +free_od: + kfree(od); + return ERR_PTR(error); } EXPORT_SYMBOL(osduld_path_lookup); void osduld_put_device(struct osd_dev *od) { - if (od) { - struct osd_uld_device *oud = container_of(od, - struct osd_uld_device, od); - __uld_put(oud); + if (od && !IS_ERR(od)) { + struct osd_uld_device *oud = od->file->private_data; + + BUG_ON(od->scsi_device != oud->od.scsi_device); + + fput(od->file); + kfree(od); } } EXPORT_SYMBOL(osduld_put_device); |