|
@@ -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);
|