|
@@ -173,6 +173,69 @@ static const struct file_operations osd_fops = {
|
|
|
.unlocked_ioctl = osd_uld_ioctl,
|
|
|
};
|
|
|
|
|
|
+struct osd_dev *osduld_path_lookup(const char *path)
|
|
|
+{
|
|
|
+ struct nameidata nd;
|
|
|
+ struct inode *inode;
|
|
|
+ struct cdev *cdev;
|
|
|
+ struct osd_uld_device *uninitialized_var(oud);
|
|
|
+ int error;
|
|
|
+
|
|
|
+ if (!path || !*path) {
|
|
|
+ OSD_ERR("Mount with !path || !*path\n");
|
|
|
+ return ERR_PTR(-EINVAL);
|
|
|
+ }
|
|
|
+
|
|
|
+ error = path_lookup(path, LOOKUP_FOLLOW, &nd);
|
|
|
+ if (error) {
|
|
|
+ OSD_ERR("path_lookup of %s faild=>%d\n", path, error);
|
|
|
+ return ERR_PTR(error);
|
|
|
+ }
|
|
|
+
|
|
|
+ inode = nd.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;
|
|
|
+ }
|
|
|
+
|
|
|
+ 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", path);
|
|
|
+ OSD_ERR(" Example: bash: echo < %s\n", path);
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 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", path);
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ oud = container_of(cdev, struct osd_uld_device, cdev);
|
|
|
+
|
|
|
+ __uld_get(oud);
|
|
|
+ error = 0;
|
|
|
+
|
|
|
+out:
|
|
|
+ path_put(&nd.path);
|
|
|
+ return error ? ERR_PTR(error) : &oud->od;
|
|
|
+}
|
|
|
+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);
|
|
|
+ }
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(osduld_put_device);
|
|
|
+
|
|
|
/*
|
|
|
* Scsi Device operations
|
|
|
*/
|