diff options
-rw-r--r-- | drivers/scsi/osd/osd_uld.c | 66 | ||||
-rw-r--r-- | include/scsi/osd_initiator.h | 1 |
2 files changed, 31 insertions, 36 deletions
diff --git a/drivers/scsi/osd/osd_uld.c b/drivers/scsi/osd/osd_uld.c index 22b59e13ba83..0bdef3390902 100644 --- a/drivers/scsi/osd/osd_uld.c +++ b/drivers/scsi/osd/osd_uld.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #include <linux/device.h> | 49 | #include <linux/device.h> |
50 | #include <linux/idr.h> | 50 | #include <linux/idr.h> |
51 | #include <linux/major.h> | 51 | #include <linux/major.h> |
52 | #include <linux/file.h> | ||
52 | 53 | ||
53 | #include <scsi/scsi.h> | 54 | #include <scsi/scsi.h> |
54 | #include <scsi/scsi_driver.h> | 55 | #include <scsi/scsi_driver.h> |
@@ -175,10 +176,9 @@ static const struct file_operations osd_fops = { | |||
175 | 176 | ||
176 | struct osd_dev *osduld_path_lookup(const char *name) | 177 | struct osd_dev *osduld_path_lookup(const char *name) |
177 | { | 178 | { |
178 | struct path path; | 179 | struct osd_uld_device *oud; |
179 | struct inode *inode; | 180 | struct osd_dev *od; |
180 | struct cdev *cdev; | 181 | struct file *file; |
181 | struct osd_uld_device *uninitialized_var(oud); | ||
182 | int error; | 182 | int error; |
183 | 183 | ||
184 | if (!name || !*name) { | 184 | if (!name || !*name) { |
@@ -186,52 +186,46 @@ struct osd_dev *osduld_path_lookup(const char *name) | |||
186 | return ERR_PTR(-EINVAL); | 186 | return ERR_PTR(-EINVAL); |
187 | } | 187 | } |
188 | 188 | ||
189 | error = kern_path(name, LOOKUP_FOLLOW, &path); | 189 | od = kzalloc(sizeof(*od), GFP_KERNEL); |
190 | if (error) { | 190 | if (!od) |
191 | OSD_ERR("path_lookup of %s failed=>%d\n", name, error); | 191 | return ERR_PTR(-ENOMEM); |
192 | return ERR_PTR(error); | ||
193 | } | ||
194 | 192 | ||
195 | inode = path.dentry->d_inode; | 193 | file = filp_open(name, O_RDWR, 0); |
196 | error = -EINVAL; /* Not the right device e.g osd_uld_device */ | 194 | if (IS_ERR(file)) { |
197 | if (!S_ISCHR(inode->i_mode)) { | 195 | error = PTR_ERR(file); |
198 | OSD_DEBUG("!S_ISCHR()\n"); | 196 | goto free_od; |
199 | goto out; | ||
200 | } | 197 | } |
201 | 198 | ||
202 | cdev = inode->i_cdev; | 199 | if (file->f_op != &osd_fops){ |
203 | if (!cdev) { | 200 | error = -EINVAL; |
204 | OSD_ERR("Before mounting an OSD Based filesystem\n"); | 201 | goto close_file; |
205 | OSD_ERR(" user-mode must open+close the %s device\n", name); | ||
206 | OSD_ERR(" Example: bash: echo < %s\n", name); | ||
207 | goto out; | ||
208 | } | 202 | } |
209 | 203 | ||
210 | /* The Magic wand. Is it our char-dev */ | 204 | oud = file->private_data; |
211 | /* TODO: Support sg devices */ | ||
212 | if (cdev->owner != THIS_MODULE) { | ||
213 | OSD_ERR("Error mounting %s - is not an OSD device\n", name); | ||
214 | goto out; | ||
215 | } | ||
216 | 205 | ||
217 | oud = container_of(cdev, struct osd_uld_device, cdev); | 206 | *od = oud->od; |
207 | od->file = file; | ||
218 | 208 | ||
219 | __uld_get(oud); | 209 | return od; |
220 | error = 0; | ||
221 | 210 | ||
222 | out: | 211 | close_file: |
223 | path_put(&path); | 212 | fput(file); |
224 | return error ? ERR_PTR(error) : &oud->od; | 213 | free_od: |
214 | kfree(od); | ||
215 | return ERR_PTR(error); | ||
225 | } | 216 | } |
226 | EXPORT_SYMBOL(osduld_path_lookup); | 217 | EXPORT_SYMBOL(osduld_path_lookup); |
227 | 218 | ||
228 | void osduld_put_device(struct osd_dev *od) | 219 | void osduld_put_device(struct osd_dev *od) |
229 | { | 220 | { |
230 | if (od) { | ||
231 | struct osd_uld_device *oud = container_of(od, | ||
232 | struct osd_uld_device, od); | ||
233 | 221 | ||
234 | __uld_put(oud); | 222 | if (od && !IS_ERR(od)) { |
223 | struct osd_uld_device *oud = od->file->private_data; | ||
224 | |||
225 | BUG_ON(od->scsi_device != oud->od.scsi_device); | ||
226 | |||
227 | fput(od->file); | ||
228 | kfree(od); | ||
235 | } | 229 | } |
236 | } | 230 | } |
237 | EXPORT_SYMBOL(osduld_put_device); | 231 | EXPORT_SYMBOL(osduld_put_device); |
diff --git a/include/scsi/osd_initiator.h b/include/scsi/osd_initiator.h index b44dc53bd881..02bd9f716357 100644 --- a/include/scsi/osd_initiator.h +++ b/include/scsi/osd_initiator.h | |||
@@ -48,6 +48,7 @@ enum osd_std_version { | |||
48 | */ | 48 | */ |
49 | struct osd_dev { | 49 | struct osd_dev { |
50 | struct scsi_device *scsi_device; | 50 | struct scsi_device *scsi_device; |
51 | struct file *file; | ||
51 | unsigned def_timeout; | 52 | unsigned def_timeout; |
52 | 53 | ||
53 | #ifdef OSD_VER1_SUPPORT | 54 | #ifdef OSD_VER1_SUPPORT |