Re: [PATCH v2 13/38] cxlflash: Support adapter file descriptors for OCXL
> 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
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
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; +