staging: lustre: llite: use more private data in dump_pgcache
authorNeilBrown <neilb@suse.com>
Mon, 7 May 2018 00:54:48 +0000 (10:54 +1000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 8 May 2018 11:09:20 +0000 (13:09 +0200)
The dump_page_cache debugfs file allocates and frees an 'env' in each
call to vvp_pgcache_start,next,show.  This is likely to be fast, but
does introduce the need to check for errors.

It is reasonable to allocate a single 'env' when the file is opened,
and use that throughout.

So create 'seq_private' structure which stores the sbi, env, and
refcheck, and attach this to the seqfile.

Then use it throughout instead of allocating 'env' repeatedly.

Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/lustre/lustre/llite/vvp_dev.c

index 987c03b..183ea3d 100644 (file)
@@ -390,6 +390,12 @@ struct vvp_pgcache_id {
        struct lu_object_header *vpi_obj;
 };
 
+struct seq_private {
+       struct ll_sb_info       *sbi;
+       struct lu_env           *env;
+       u16                     refcheck;
+};
+
 static void vvp_pgcache_id_unpack(loff_t pos, struct vvp_pgcache_id *id)
 {
        BUILD_BUG_ON(sizeof(pos) != sizeof(__u64));
@@ -531,95 +537,72 @@ static void vvp_pgcache_page_show(const struct lu_env *env,
 
 static int vvp_pgcache_show(struct seq_file *f, void *v)
 {
+       struct seq_private      *priv = f->private;
        loff_t             pos;
-       struct ll_sb_info       *sbi;
        struct cl_object        *clob;
-       struct lu_env      *env;
        struct vvp_pgcache_id    id;
-       u16 refcheck;
-       int                   result;
 
-       env = cl_env_get(&refcheck);
-       if (!IS_ERR(env)) {
-               pos = *(loff_t *)v;
-               vvp_pgcache_id_unpack(pos, &id);
-               sbi = f->private;
-               clob = vvp_pgcache_obj(env, &sbi->ll_cl->cd_lu_dev, &id);
-               if (clob) {
-                       struct inode *inode = vvp_object_inode(clob);
-                       struct cl_page *page = NULL;
-                       struct page *vmpage;
-
-                       result = find_get_pages_contig(inode->i_mapping,
-                                                      id.vpi_index, 1,
-                                                      &vmpage);
-                       if (result > 0) {
-                               lock_page(vmpage);
-                               page = cl_vmpage_page(vmpage, clob);
-                               unlock_page(vmpage);
-                               put_page(vmpage);
-                       }
+       pos = *(loff_t *)v;
+       vvp_pgcache_id_unpack(pos, &id);
+       clob = vvp_pgcache_obj(priv->env, &priv->sbi->ll_cl->cd_lu_dev, &id);
+       if (clob) {
+               struct inode *inode = vvp_object_inode(clob);
+               struct cl_page *page = NULL;
+               struct page *vmpage;
+               int result;
+
+               result = find_get_pages_contig(inode->i_mapping,
+                                              id.vpi_index, 1,
+                                              &vmpage);
+               if (result > 0) {
+                       lock_page(vmpage);
+                       page = cl_vmpage_page(vmpage, clob);
+                       unlock_page(vmpage);
+                       put_page(vmpage);
+               }
 
-                       seq_printf(f, "%8x@" DFID ": ", id.vpi_index,
-                                  PFID(lu_object_fid(&clob->co_lu)));
-                       if (page) {
-                               vvp_pgcache_page_show(env, f, page);
-                               cl_page_put(env, page);
-                       } else {
-                               seq_puts(f, "missing\n");
-                       }
-                       lu_object_ref_del(&clob->co_lu, "dump", current);
-                       cl_object_put(env, clob);
+               seq_printf(f, "%8x@" DFID ": ", id.vpi_index,
+                          PFID(lu_object_fid(&clob->co_lu)));
+               if (page) {
+                       vvp_pgcache_page_show(priv->env, f, page);
+                       cl_page_put(priv->env, page);
                } else {
-                       seq_printf(f, "%llx missing\n", pos);
+                       seq_puts(f, "missing\n");
                }
-               cl_env_put(env, &refcheck);
-               result = 0;
+               lu_object_ref_del(&clob->co_lu, "dump", current);
+               cl_object_put(priv->env, clob);
        } else {
-               result = PTR_ERR(env);
+               seq_printf(f, "%llx missing\n", pos);
        }
-       return result;
+       return 0;
 }
 
 static void *vvp_pgcache_start(struct seq_file *f, loff_t *pos)
 {
-       struct ll_sb_info *sbi;
-       struct lu_env     *env;
-       u16 refcheck;
-
-       sbi = f->private;
+       struct seq_private      *priv = f->private;
 
-       env = cl_env_get(&refcheck);
-       if (!IS_ERR(env)) {
-               sbi = f->private;
-               if (sbi->ll_site->ls_obj_hash->hs_cur_bits >
-                   64 - PGC_OBJ_SHIFT) {
-                       pos = ERR_PTR(-EFBIG);
-               } else {
-                       *pos = vvp_pgcache_find(env, &sbi->ll_cl->cd_lu_dev,
-                                               *pos);
-                       if (*pos == ~0ULL)
-                               pos = NULL;
-               }
-               cl_env_put(env, &refcheck);
+       if (priv->sbi->ll_site->ls_obj_hash->hs_cur_bits >
+           64 - PGC_OBJ_SHIFT) {
+               pos = ERR_PTR(-EFBIG);
+       } else {
+               *pos = vvp_pgcache_find(priv->env, &priv->sbi->ll_cl->cd_lu_dev,
+                                       *pos);
+               if (*pos == ~0ULL)
+                       pos = NULL;
        }
+
        return pos;
 }
 
 static void *vvp_pgcache_next(struct seq_file *f, void *v, loff_t *pos)
 {
-       struct ll_sb_info *sbi;
-       struct lu_env     *env;
-       u16 refcheck;
+       struct seq_private *priv = f->private;
+
+       *pos = vvp_pgcache_find(priv->env, &priv->sbi->ll_cl->cd_lu_dev,
+                               *pos + 1);
+       if (*pos == ~0ULL)
+               pos = NULL;
 
-       env = cl_env_get(&refcheck);
-       if (!IS_ERR(env)) {
-               sbi = f->private;
-               *pos = vvp_pgcache_find(env, &sbi->ll_cl->cd_lu_dev, *pos + 1);
-               if (*pos == ~0ULL)
-                       pos = NULL;
-               cl_env_put(env, &refcheck);
-       }
        return pos;
 }
 
@@ -637,23 +620,36 @@ static const struct seq_operations vvp_pgcache_ops = {
 
 static int vvp_dump_pgcache_seq_open(struct inode *inode, struct file *filp)
 {
-       struct seq_file *seq;
-       int rc;
+       struct seq_private *priv;
 
-       rc = seq_open(filp, &vvp_pgcache_ops);
-       if (rc)
-               return rc;
+       priv = __seq_open_private(filp, &vvp_pgcache_ops, sizeof(*priv));
+       if (!priv)
+               return -ENOMEM;
 
-       seq = filp->private_data;
-       seq->private = inode->i_private;
+       priv->sbi = inode->i_private;
+       priv->env = cl_env_get(&priv->refcheck);
+       if (IS_ERR(priv->env)) {
+               int err = PTR_ERR(priv->env);
 
+               seq_release_private(inode, filp);
+               return err;
+       }
        return 0;
 }
 
+static int vvp_dump_pgcache_seq_release(struct inode *inode, struct file *file)
+{
+       struct seq_file *seq = file->private_data;
+       struct seq_private *priv = seq->private;
+
+       cl_env_put(priv->env, &priv->refcheck);
+       return seq_release_private(inode, file);
+}
+
 const struct file_operations vvp_dump_pgcache_file_ops = {
        .owner   = THIS_MODULE,
        .open    = vvp_dump_pgcache_seq_open,
        .read    = seq_read,
        .llseek  = seq_lseek,
-       .release = seq_release,
+       .release = vvp_dump_pgcache_seq_release,
 };