Re: [PATCH v2 13/38] cxlflash: Support adapter file descriptors for OCXL

2018-03-23 Thread Uma Krishnan


> On Mar 22, 2018, at 12:12 PM, Frederic Barrat  
> wrote:
> 
> 
> 
> Le 26/02/2018 à 23:21, Uma Krishnan a écrit :
>> Allocate a file descriptor for an adapter context when requested. In order
>> to allocate inodes for the file descriptors, a pseudo filesystem is created
>> and used.
>> Signed-off-by: Uma Krishnan 
>> Acked-by: Matthew R. Ochs 
>> ---
> 
> 
> We've touched the subject before, and I don't have a magic solution, but it 
> feels like something could be shared here with cxl, or maybe even other 
> drivers?
> 
Yes, perhaps we could look at refactoring in a future series.

> I only took a quick read of the inode allocator.
> 
>  Fred
> 
> 
> 
> 
>>  drivers/scsi/cxlflash/ocxl_hw.c | 200 
>> 
>>  drivers/scsi/cxlflash/ocxl_hw.h |   1 +
>>  2 files changed, 201 insertions(+)
>> diff --git a/drivers/scsi/cxlflash/ocxl_hw.c 
>> b/drivers/scsi/cxlflash/ocxl_hw.c
>> index 6472210..59e9003 100644
>> --- a/drivers/scsi/cxlflash/ocxl_hw.c
>> +++ b/drivers/scsi/cxlflash/ocxl_hw.c
>> @@ -12,13 +12,144 @@
>>   * 2 of the License, or (at your option) any later version.
>>   */
>> +#include 
>>  #include 
>> +#include 
>> +#include 
>>  #include 
>>  #include "backend.h"
>>  #include "ocxl_hw.h"
>> +/*
>> + * Pseudo-filesystem to allocate inodes.
>> + */
>> +
>> +#define OCXLFLASH_FS_MAGIC  0x1697698f
>> +
>> +static int ocxlflash_fs_cnt;
>> +static struct vfsmount *ocxlflash_vfs_mount;
>> +
>> +static const struct dentry_operations ocxlflash_fs_dops = {
>> +.d_dname= simple_dname,
>> +};
>> +
>> +/*
>> + * ocxlflash_fs_mount() - mount the pseudo-filesystem
>> + * @fs_type:File system type.
>> + * @flags:  Flags for the filesystem.
>> + * @dev_name:   Device name associated with the filesystem.
>> + * @data:   Data pointer.
>> + *
>> + * Return: pointer to the directory entry structure
>> + */
>> +static struct dentry *ocxlflash_fs_mount(struct file_system_type *fs_type,
>> + int flags, const char *dev_name,
>> + void *data)
>> +{
>> +return mount_pseudo(fs_type, "ocxlflash:", NULL, &ocxlflash_fs_dops,
>> +OCXLFLASH_FS_MAGIC);
>> +}
>> +
>> +static struct file_system_type ocxlflash_fs_type = {
>> +.name   = "ocxlflash",
>> +.owner  = THIS_MODULE,
>> +.mount  = ocxlflash_fs_mount,
>> +.kill_sb= kill_anon_super,
>> +};
>> +
>> +/*
>> + * ocxlflash_release_mapping() - release the memory mapping
>> + * @ctx:Context whose mapping is to be released.
>> + */
>> +static void ocxlflash_release_mapping(struct ocxlflash_context *ctx)
>> +{
>> +if (ctx->mapping)
>> +simple_release_fs(&ocxlflash_vfs_mount, &ocxlflash_fs_cnt);
>> +ctx->mapping = NULL;
>> +}
>> +
>> +/*
>> + * ocxlflash_getfile() - allocate pseudo filesystem, inode, and the file
>> + * @dev:Generic device of the host.
>> + * @name:   Name of the pseudo filesystem.
>> + * @fops:   File operations.
>> + * @priv:   Private data.
>> + * @flags:  Flags for the file.
>> + *
>> + * Return: pointer to the file on success, ERR_PTR on failure
>> + */
>> +static struct file *ocxlflash_getfile(struct device *dev, const char *name,
>> +  const struct file_operations *fops,
>> +  void *priv, int flags)
>> +{
>> +struct qstr this;
>> +struct path path;
>> +struct file *file;
>> +struct inode *inode = NULL;
>> +int rc;
>> +
>> +if (fops->owner && !try_module_get(fops->owner)) {
>> +dev_err(dev, "%s: Owner does not exist\n", __func__);
>> +rc = -ENOENT;
>> +goto err1;
>> +}
>> +
>> +rc = simple_pin_fs(&ocxlflash_fs_type, &ocxlflash_vfs_mount,
>> +   &ocxlflash_fs_cnt);
>> +if (unlikely(rc < 0)) {
>> +dev_err(dev, "%s: Cannot mount ocxlflash pseudofs rc=%d\n",
>> +__func__, rc);
>> +goto err2;
>> +}
>> +
>> +inode = alloc_anon_inode(ocxlflash_vfs_mount->mnt_sb);
>> +if (IS_ERR(inode)) {
>> +rc = PTR_ERR(inode);
>> +dev_err(dev, "%s: alloc_anon_inode failed rc=%d\n",
>> +__func__, rc);
>> +goto err3;
>> +}
>> +
>> +this.name = name;
>> +this.len = strlen(name);
>> +this.hash = 0;
>> +path.dentry = d_alloc_pseudo(ocxlflash_vfs_mount->mnt_sb, &this);
>> +if (!path.dentry) {
>> +dev_err(dev, "%s: d_alloc_pseudo failed\n", __func__);
>> +rc = -ENOMEM;
>> +goto err4;
>> +}
>> +
>> +path.mnt = mntget(ocxlflash_vfs_mount);
>> +d_instantiate(path.dentry, inode);
>> +
>> +file = alloc_file(&path, OPEN_FMODE(flags), fops);
>> +if (IS_ERR(file)) {
>> +rc = PTR_ERR(file);
>> +dev_err(dev, "%s: alloc_file failed rc=%d\n",
>> +__func__, rc);
>> +goto 

Re: [PATCH v2 13/38] cxlflash: Support adapter file descriptors for OCXL

2018-03-22 Thread Frederic Barrat



Le 26/02/2018 à 23:21, Uma Krishnan a écrit :

Allocate a file descriptor for an adapter context when requested. In order
to allocate inodes for the file descriptors, a pseudo filesystem is created
and used.

Signed-off-by: Uma Krishnan 
Acked-by: Matthew R. Ochs 
---



We've touched the subject before, and I don't have a magic solution, but 
it feels like something could be shared here with cxl, or maybe even 
other drivers?


I only took a quick read of the inode allocator.

  Fred





  drivers/scsi/cxlflash/ocxl_hw.c | 200 
  drivers/scsi/cxlflash/ocxl_hw.h |   1 +
  2 files changed, 201 insertions(+)

diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c
index 6472210..59e9003 100644
--- a/drivers/scsi/cxlflash/ocxl_hw.c
+++ b/drivers/scsi/cxlflash/ocxl_hw.c
@@ -12,13 +12,144 @@
   * 2 of the License, or (at your option) any later version.
   */

+#include 
  #include 
+#include 
+#include 

  #include 

  #include "backend.h"
  #include "ocxl_hw.h"

+/*
+ * Pseudo-filesystem to allocate inodes.
+ */
+
+#define OCXLFLASH_FS_MAGIC  0x1697698f
+
+static int ocxlflash_fs_cnt;
+static struct vfsmount *ocxlflash_vfs_mount;
+
+static const struct dentry_operations ocxlflash_fs_dops = {
+   .d_dname= simple_dname,
+};
+
+/*
+ * ocxlflash_fs_mount() - mount the pseudo-filesystem
+ * @fs_type:   File system type.
+ * @flags: Flags for the filesystem.
+ * @dev_name:  Device name associated with the filesystem.
+ * @data:  Data pointer.
+ *
+ * Return: pointer to the directory entry structure
+ */
+static struct dentry *ocxlflash_fs_mount(struct file_system_type *fs_type,
+int flags, const char *dev_name,
+void *data)
+{
+   return mount_pseudo(fs_type, "ocxlflash:", NULL, &ocxlflash_fs_dops,
+   OCXLFLASH_FS_MAGIC);
+}
+
+static struct file_system_type ocxlflash_fs_type = {
+   .name   = "ocxlflash",
+   .owner  = THIS_MODULE,
+   .mount  = ocxlflash_fs_mount,
+   .kill_sb= kill_anon_super,
+};
+
+/*
+ * ocxlflash_release_mapping() - release the memory mapping
+ * @ctx:   Context whose mapping is to be released.
+ */
+static void ocxlflash_release_mapping(struct ocxlflash_context *ctx)
+{
+   if (ctx->mapping)
+   simple_release_fs(&ocxlflash_vfs_mount, &ocxlflash_fs_cnt);
+   ctx->mapping = NULL;
+}
+
+/*
+ * ocxlflash_getfile() - allocate pseudo filesystem, inode, and the file
+ * @dev:   Generic device of the host.
+ * @name:  Name of the pseudo filesystem.
+ * @fops:  File operations.
+ * @priv:  Private data.
+ * @flags: Flags for the file.
+ *
+ * Return: pointer to the file on success, ERR_PTR on failure
+ */
+static struct file *ocxlflash_getfile(struct device *dev, const char *name,
+ const struct file_operations *fops,
+ void *priv, int flags)
+{
+   struct qstr this;
+   struct path path;
+   struct file *file;
+   struct inode *inode = NULL;
+   int rc;
+
+   if (fops->owner && !try_module_get(fops->owner)) {
+   dev_err(dev, "%s: Owner does not exist\n", __func__);
+   rc = -ENOENT;
+   goto err1;
+   }
+
+   rc = simple_pin_fs(&ocxlflash_fs_type, &ocxlflash_vfs_mount,
+  &ocxlflash_fs_cnt);
+   if (unlikely(rc < 0)) {
+   dev_err(dev, "%s: Cannot mount ocxlflash pseudofs rc=%d\n",
+   __func__, rc);
+   goto err2;
+   }
+
+   inode = alloc_anon_inode(ocxlflash_vfs_mount->mnt_sb);
+   if (IS_ERR(inode)) {
+   rc = PTR_ERR(inode);
+   dev_err(dev, "%s: alloc_anon_inode failed rc=%d\n",
+   __func__, rc);
+   goto err3;
+   }
+
+   this.name = name;
+   this.len = strlen(name);
+   this.hash = 0;
+   path.dentry = d_alloc_pseudo(ocxlflash_vfs_mount->mnt_sb, &this);
+   if (!path.dentry) {
+   dev_err(dev, "%s: d_alloc_pseudo failed\n", __func__);
+   rc = -ENOMEM;
+   goto err4;
+   }
+
+   path.mnt = mntget(ocxlflash_vfs_mount);
+   d_instantiate(path.dentry, inode);
+
+   file = alloc_file(&path, OPEN_FMODE(flags), fops);
+   if (IS_ERR(file)) {
+   rc = PTR_ERR(file);
+   dev_err(dev, "%s: alloc_file failed rc=%d\n",
+   __func__, rc);
+   goto err5;
+   }
+
+   file->f_flags = flags & (O_ACCMODE | O_NONBLOCK);
+   file->private_data = priv;
+out:
+   return file;
+err5:
+   path_put(&path);
+err4:
+   iput(inode);
+err3:
+   simple_release_fs(&ocxlflash_vfs_mount, &ocxlflash_fs_cnt);
+err2:
+   module_put(fops->owner);
+err1:
+   file = ERR_PTR(rc);
+   goto ou

[PATCH v2 13/38] cxlflash: Support adapter file descriptors for OCXL

2018-02-26 Thread Uma Krishnan
Allocate a file descriptor for an adapter context when requested. In order
to allocate inodes for the file descriptors, a pseudo filesystem is created
and used.

Signed-off-by: Uma Krishnan 
Acked-by: Matthew R. Ochs 
---
 drivers/scsi/cxlflash/ocxl_hw.c | 200 
 drivers/scsi/cxlflash/ocxl_hw.h |   1 +
 2 files changed, 201 insertions(+)

diff --git a/drivers/scsi/cxlflash/ocxl_hw.c b/drivers/scsi/cxlflash/ocxl_hw.c
index 6472210..59e9003 100644
--- a/drivers/scsi/cxlflash/ocxl_hw.c
+++ b/drivers/scsi/cxlflash/ocxl_hw.c
@@ -12,13 +12,144 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#include 
 #include 
+#include 
+#include 
 
 #include 
 
 #include "backend.h"
 #include "ocxl_hw.h"
 
+/*
+ * Pseudo-filesystem to allocate inodes.
+ */
+
+#define OCXLFLASH_FS_MAGIC  0x1697698f
+
+static int ocxlflash_fs_cnt;
+static struct vfsmount *ocxlflash_vfs_mount;
+
+static const struct dentry_operations ocxlflash_fs_dops = {
+   .d_dname= simple_dname,
+};
+
+/*
+ * ocxlflash_fs_mount() - mount the pseudo-filesystem
+ * @fs_type:   File system type.
+ * @flags: Flags for the filesystem.
+ * @dev_name:  Device name associated with the filesystem.
+ * @data:  Data pointer.
+ *
+ * Return: pointer to the directory entry structure
+ */
+static struct dentry *ocxlflash_fs_mount(struct file_system_type *fs_type,
+int flags, const char *dev_name,
+void *data)
+{
+   return mount_pseudo(fs_type, "ocxlflash:", NULL, &ocxlflash_fs_dops,
+   OCXLFLASH_FS_MAGIC);
+}
+
+static struct file_system_type ocxlflash_fs_type = {
+   .name   = "ocxlflash",
+   .owner  = THIS_MODULE,
+   .mount  = ocxlflash_fs_mount,
+   .kill_sb= kill_anon_super,
+};
+
+/*
+ * ocxlflash_release_mapping() - release the memory mapping
+ * @ctx:   Context whose mapping is to be released.
+ */
+static void ocxlflash_release_mapping(struct ocxlflash_context *ctx)
+{
+   if (ctx->mapping)
+   simple_release_fs(&ocxlflash_vfs_mount, &ocxlflash_fs_cnt);
+   ctx->mapping = NULL;
+}
+
+/*
+ * ocxlflash_getfile() - allocate pseudo filesystem, inode, and the file
+ * @dev:   Generic device of the host.
+ * @name:  Name of the pseudo filesystem.
+ * @fops:  File operations.
+ * @priv:  Private data.
+ * @flags: Flags for the file.
+ *
+ * Return: pointer to the file on success, ERR_PTR on failure
+ */
+static struct file *ocxlflash_getfile(struct device *dev, const char *name,
+ const struct file_operations *fops,
+ void *priv, int flags)
+{
+   struct qstr this;
+   struct path path;
+   struct file *file;
+   struct inode *inode = NULL;
+   int rc;
+
+   if (fops->owner && !try_module_get(fops->owner)) {
+   dev_err(dev, "%s: Owner does not exist\n", __func__);
+   rc = -ENOENT;
+   goto err1;
+   }
+
+   rc = simple_pin_fs(&ocxlflash_fs_type, &ocxlflash_vfs_mount,
+  &ocxlflash_fs_cnt);
+   if (unlikely(rc < 0)) {
+   dev_err(dev, "%s: Cannot mount ocxlflash pseudofs rc=%d\n",
+   __func__, rc);
+   goto err2;
+   }
+
+   inode = alloc_anon_inode(ocxlflash_vfs_mount->mnt_sb);
+   if (IS_ERR(inode)) {
+   rc = PTR_ERR(inode);
+   dev_err(dev, "%s: alloc_anon_inode failed rc=%d\n",
+   __func__, rc);
+   goto err3;
+   }
+
+   this.name = name;
+   this.len = strlen(name);
+   this.hash = 0;
+   path.dentry = d_alloc_pseudo(ocxlflash_vfs_mount->mnt_sb, &this);
+   if (!path.dentry) {
+   dev_err(dev, "%s: d_alloc_pseudo failed\n", __func__);
+   rc = -ENOMEM;
+   goto err4;
+   }
+
+   path.mnt = mntget(ocxlflash_vfs_mount);
+   d_instantiate(path.dentry, inode);
+
+   file = alloc_file(&path, OPEN_FMODE(flags), fops);
+   if (IS_ERR(file)) {
+   rc = PTR_ERR(file);
+   dev_err(dev, "%s: alloc_file failed rc=%d\n",
+   __func__, rc);
+   goto err5;
+   }
+
+   file->f_flags = flags & (O_ACCMODE | O_NONBLOCK);
+   file->private_data = priv;
+out:
+   return file;
+err5:
+   path_put(&path);
+err4:
+   iput(inode);
+err3:
+   simple_release_fs(&ocxlflash_vfs_mount, &ocxlflash_fs_cnt);
+err2:
+   module_put(fops->owner);
+err1:
+   file = ERR_PTR(rc);
+   goto out;
+}
+
 /**
  * ocxlflash_set_master() - sets the context as master
  * @ctx_cookie:Adapter context to set as master.
@@ -75,6 +206,7 @@ static void *ocxlflash_dev_context_init(struct pci_dev 
*pdev, void *afu_cookie)
 
ctx->pe = rc;
ctx->master = false;
+