summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/osd/osd_uld.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/osd/osd_uld.c')
-rw-r--r--drivers/scsi/osd/osd_uld.c66
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);