[Yaffs] [PATCH v2] fix read of /proc/yaffs

Top Page
Attachments:
Message as email
+ (text/plain)
Delete this message
Reply to this message
Author: Jisheng Zhang
Date:  
To: yaffs@stoneboat.aleph1.co.uk, Charles Manning
Subject: [Yaffs] [PATCH v2] fix read of /proc/yaffs
Currently, with YAFFS_NEW_PROCFS, "cat /proc/yaffs" always only show
one line:

~# cat /proc/yaffs
Multi-version YAFFS

Fix by rewriting yaffs_proc_show().

Signed-off-by: Jisheng Zhang <>
---
since v2:
- remove the buggy "break"

yaffs_vfs_multi.c | 394 +++++++++++++++++++++++++++++++++---------------------
1 file changed, 244 insertions(+), 150 deletions(-)

diff --git a/yaffs_vfs_multi.c b/yaffs_vfs_multi.c
index e4edb2c..d2a7a64 100644
--- a/yaffs_vfs_multi.c
+++ b/yaffs_vfs_multi.c
@@ -3275,149 +3275,6 @@ static DECLARE_FSTYPE(yaffs2_fs_type, "yaffs2", yaffs2_read_super,

static struct proc_dir_entry *my_proc_entry;

-static char *yaffs_dump_dev_part0(char *buf, struct yaffs_dev *dev)
-{
-    struct yaffs_param *param = &dev->param;
-    int bs[10];
-
-    yaffs_count_blocks_by_state(dev,bs);
-
-    buf += sprintf(buf, "start_block.......... %d\n", param->start_block);
-    buf += sprintf(buf, "end_block............ %d\n", param->end_block);
-    buf += sprintf(buf, "total_bytes_per_chunk %d\n",
-                param->total_bytes_per_chunk);
-    buf += sprintf(buf, "use_nand_ecc......... %d\n", param->use_nand_ecc);
-    buf += sprintf(buf, "no_tags_ecc.......... %d\n", param->no_tags_ecc);
-    buf += sprintf(buf, "is_yaffs2............ %d\n", param->is_yaffs2);
-    buf += sprintf(buf, "inband_tags.......... %d\n", param->inband_tags);
-    buf += sprintf(buf, "empty_lost_n_found... %d\n",
-                param->empty_lost_n_found);
-    buf += sprintf(buf, "disable_lazy_load.... %d\n",
-                param->disable_lazy_load);
-    buf += sprintf(buf, "disable_bad_block_mrk %d\n",
-                param->disable_bad_block_marking);
-    buf += sprintf(buf, "refresh_period....... %d\n",
-                param->refresh_period);
-    buf += sprintf(buf, "n_caches............. %d\n", param->n_caches);
-    buf += sprintf(buf, "n_reserved_blocks.... %d\n",
-                param->n_reserved_blocks);
-    buf += sprintf(buf, "always_check_erased.. %d\n",
-                param->always_check_erased);
-    buf += sprintf(buf, "\n");
-    buf += sprintf(buf, "block count by state\n");
-    buf += sprintf(buf, "0:%d 1:%d 2:%d 3:%d 4:%d\n",
-                bs[0], bs[1], bs[2], bs[3], bs[4]);
-    buf += sprintf(buf, "5:%d 6:%d 7:%d 8:%d 9:%d\n",
-                bs[5], bs[6], bs[7], bs[8], bs[9]);
-
-    return buf;
-}
-
-static char *yaffs_dump_dev_part1(char *buf, struct yaffs_dev *dev)
-{
-    buf += sprintf(buf, "max file size....... %lld\n",
-                (long long) yaffs_max_file_size(dev));
-    buf += sprintf(buf, "data_bytes_per_chunk. %d\n",
-                dev->data_bytes_per_chunk);
-    buf += sprintf(buf, "chunk_grp_bits....... %d\n", dev->chunk_grp_bits);
-    buf += sprintf(buf, "chunk_grp_size....... %d\n", dev->chunk_grp_size);
-    buf += sprintf(buf, "n_erased_blocks...... %d\n", dev->n_erased_blocks);
-    buf += sprintf(buf, "blocks_in_checkpt.... %d\n",
-                dev->blocks_in_checkpt);
-    buf += sprintf(buf, "\n");
-    buf += sprintf(buf, "n_tnodes............. %d\n", dev->n_tnodes);
-    buf += sprintf(buf, "n_obj................ %d\n", dev->n_obj);
-    buf += sprintf(buf, "n_free_chunks........ %d\n", dev->n_free_chunks);
-    buf += sprintf(buf, "\n");
-    buf += sprintf(buf, "n_page_writes........ %u\n", dev->n_page_writes);
-    buf += sprintf(buf, "n_page_reads......... %u\n", dev->n_page_reads);
-    buf += sprintf(buf, "n_erasures........... %u\n", dev->n_erasures);
-    buf += sprintf(buf, "n_gc_copies.......... %u\n", dev->n_gc_copies);
-    buf += sprintf(buf, "all_gcs.............. %u\n", dev->all_gcs);
-    buf += sprintf(buf, "passive_gc_count..... %u\n",
-                dev->passive_gc_count);
-    buf += sprintf(buf, "oldest_dirty_gc_count %u\n",
-                dev->oldest_dirty_gc_count);
-    buf += sprintf(buf, "n_gc_blocks.......... %u\n", dev->n_gc_blocks);
-    buf += sprintf(buf, "bg_gcs............... %u\n", dev->bg_gcs);
-    buf += sprintf(buf, "n_retried_writes..... %u\n",
-                dev->n_retried_writes);
-    buf += sprintf(buf, "n_retired_blocks..... %u\n",
-                dev->n_retired_blocks);
-    buf += sprintf(buf, "n_ecc_fixed.......... %u\n", dev->n_ecc_fixed);
-    buf += sprintf(buf, "n_ecc_unfixed........ %u\n", dev->n_ecc_unfixed);
-    buf += sprintf(buf, "n_tags_ecc_fixed..... %u\n",
-                dev->n_tags_ecc_fixed);
-    buf += sprintf(buf, "n_tags_ecc_unfixed... %u\n",
-                dev->n_tags_ecc_unfixed);
-    buf += sprintf(buf, "cache_hits........... %u\n", dev->cache_hits);
-    buf += sprintf(buf, "n_deleted_files...... %u\n", dev->n_deleted_files);
-    buf += sprintf(buf, "n_unlinked_files..... %u\n",
-                dev->n_unlinked_files);
-    buf += sprintf(buf, "refresh_count........ %u\n", dev->refresh_count);
-    buf += sprintf(buf, "n_bg_deletions....... %u\n", dev->n_bg_deletions);
-    buf += sprintf(buf, "tags_used............ %u\n", dev->tags_used);
-    buf += sprintf(buf, "summary_used......... %u\n", dev->summary_used);
-
-    return buf;
-}
-
-static int yaffs_proc_read(char *page,
-               char **start,
-               off_t offset, int count, int *eof, void *data)
-{
-    struct list_head *item;
-    char *buf = page;
-    int step = offset;
-    int n = 0;
-
-    /* Get proc_file_read() to step 'offset' by one on each sucessive call.
-     * We use 'offset' (*ppos) to indicate where we are in dev_list.
-     * This also assumes the user has posted a read buffer large
-     * enough to hold the complete output; but that's life in /proc.
-     */
-
-    *(int *)start = 1;
-
-    /* Print header first */
-    if (step == 0)
-        buf +=
-            sprintf(buf, "Multi-version YAFFS\n");
-    else if (step == 1)
-        buf += sprintf(buf, "\n");
-    else {
-        step -= 2;
-
-        mutex_lock(&yaffs_context_lock);
-
-        /* Locate and print the Nth entry.  Order N-squared but N is small. */
-        list_for_each(item, &yaffs_context_list) {
-            struct yaffs_linux_context *dc =
-                list_entry(item, struct yaffs_linux_context,
-                       context_list);
-            struct yaffs_dev *dev = dc->dev;
-
-            if (n < (step & ~1)) {
-                n += 2;
-                continue;
-            }
-            if ((step & 1) == 0) {
-                buf +=
-                    sprintf(buf, "\nDevice %d \"%s\"\n", n,
-                        dev->param.name);
-                buf = yaffs_dump_dev_part0(buf, dev);
-            } else {
-                buf = yaffs_dump_dev_part1(buf, dev);
-                        }
-
-            break;
-        }
-        mutex_unlock(&yaffs_context_lock);
-    }
-
-    return buf - page < count ? buf - page : count;
-}
-
 /**
  * Set the verbosity of the warnings and error messages.
  *
@@ -3665,15 +3522,112 @@ static struct file_system_to_install fs_to_install[] = {



 #ifdef YAFFS_NEW_PROCFS
+static void yaffs_dump_dev_part0(struct seq_file *m, struct yaffs_dev *dev)
+{
+    struct yaffs_param *param = &dev->param;
+    int bs[10];
+
+    yaffs_count_blocks_by_state(dev,bs);
+
+    seq_printf(m, "start_block.......... %d\n", param->start_block);
+    seq_printf(m, "end_block............ %d\n", param->end_block);
+    seq_printf(m, "total_bytes_per_chunk %d\n",
+                param->total_bytes_per_chunk);
+    seq_printf(m, "use_nand_ecc......... %d\n", param->use_nand_ecc);
+    seq_printf(m, "no_tags_ecc.......... %d\n", param->no_tags_ecc);
+    seq_printf(m, "is_yaffs2............ %d\n", param->is_yaffs2);
+    seq_printf(m, "inband_tags.......... %d\n", param->inband_tags);
+    seq_printf(m, "empty_lost_n_found... %d\n",
+                param->empty_lost_n_found);
+    seq_printf(m, "disable_lazy_load.... %d\n",
+                param->disable_lazy_load);
+    seq_printf(m, "disable_bad_block_mrk %d\n",
+                param->disable_bad_block_marking);
+    seq_printf(m, "refresh_period....... %d\n",
+                param->refresh_period);
+    seq_printf(m, "n_caches............. %d\n", param->n_caches);
+    seq_printf(m, "n_reserved_blocks.... %d\n",
+                param->n_reserved_blocks);
+    seq_printf(m, "always_check_erased.. %d\n",
+                param->always_check_erased);
+    seq_printf(m, "\n");
+    seq_printf(m, "block count by state\n");
+    seq_printf(m, "0:%d 1:%d 2:%d 3:%d 4:%d\n",
+                bs[0], bs[1], bs[2], bs[3], bs[4]);
+    seq_printf(m, "5:%d 6:%d 7:%d 8:%d 9:%d\n",
+                bs[5], bs[6], bs[7], bs[8], bs[9]);
+}
+
+static void yaffs_dump_dev_part1(struct seq_file *m, struct yaffs_dev *dev)
+{
+    seq_printf(m, "max file size....... %lld\n",
+                (long long) yaffs_max_file_size(dev));
+    seq_printf(m, "data_bytes_per_chunk. %d\n",
+                dev->data_bytes_per_chunk);
+    seq_printf(m, "chunk_grp_bits....... %d\n", dev->chunk_grp_bits);
+    seq_printf(m, "chunk_grp_size....... %d\n", dev->chunk_grp_size);
+    seq_printf(m, "n_erased_blocks...... %d\n", dev->n_erased_blocks);
+    seq_printf(m, "blocks_in_checkpt.... %d\n",
+                dev->blocks_in_checkpt);
+    seq_printf(m, "\n");
+    seq_printf(m, "n_tnodes............. %d\n", dev->n_tnodes);
+    seq_printf(m, "n_obj................ %d\n", dev->n_obj);
+    seq_printf(m, "n_free_chunks........ %d\n", dev->n_free_chunks);
+    seq_printf(m, "\n");
+    seq_printf(m, "n_page_writes........ %u\n", dev->n_page_writes);
+    seq_printf(m, "n_page_reads......... %u\n", dev->n_page_reads);
+    seq_printf(m, "n_erasures........... %u\n", dev->n_erasures);
+    seq_printf(m, "n_gc_copies.......... %u\n", dev->n_gc_copies);
+    seq_printf(m, "all_gcs.............. %u\n", dev->all_gcs);
+    seq_printf(m, "passive_gc_count..... %u\n",
+                dev->passive_gc_count);
+    seq_printf(m, "oldest_dirty_gc_count %u\n",
+                dev->oldest_dirty_gc_count);
+    seq_printf(m, "n_gc_blocks.......... %u\n", dev->n_gc_blocks);
+    seq_printf(m, "bg_gcs............... %u\n", dev->bg_gcs);
+    seq_printf(m, "n_retried_writes..... %u\n",
+                dev->n_retried_writes);
+    seq_printf(m, "n_retired_blocks..... %u\n",
+                dev->n_retired_blocks);
+    seq_printf(m, "n_ecc_fixed.......... %u\n", dev->n_ecc_fixed);
+    seq_printf(m, "n_ecc_unfixed........ %u\n", dev->n_ecc_unfixed);
+    seq_printf(m, "n_tags_ecc_fixed..... %u\n",
+                dev->n_tags_ecc_fixed);
+    seq_printf(m, "n_tags_ecc_unfixed... %u\n",
+                dev->n_tags_ecc_unfixed);
+    seq_printf(m, "cache_hits........... %u\n", dev->cache_hits);
+    seq_printf(m, "n_deleted_files...... %u\n", dev->n_deleted_files);
+    seq_printf(m, "n_unlinked_files..... %u\n",
+                dev->n_unlinked_files);
+    seq_printf(m, "refresh_count........ %u\n", dev->refresh_count);
+    seq_printf(m, "n_bg_deletions....... %u\n", dev->n_bg_deletions);
+    seq_printf(m, "tags_used............ %u\n", dev->tags_used);
+    seq_printf(m, "summary_used......... %u\n", dev->summary_used);
+}
+
 static int yaffs_proc_show(struct seq_file *m, void *v)
 {
-    /* FIXME: Unify in a better way? */
-    char buffer[512];
-    char *start;
-    int len;
+    struct list_head *item;
+    int n = 0;
+
+    seq_puts(m, "Multi-version YAFFS\n\n");
+    mutex_lock(&yaffs_context_lock);
+
+    /* Locate and print the Nth entry.  Order N-squared but N is small. */
+    list_for_each(item, &yaffs_context_list) {
+        struct yaffs_linux_context *dc =
+            list_entry(item, struct yaffs_linux_context,
+                   context_list);
+        struct yaffs_dev *dev = dc->dev;
+
+        seq_printf(m, "\nDevice %d \"%s\"\n", n,
+               dev->param.name);
+        yaffs_dump_dev_part0(m, dev);
+        yaffs_dump_dev_part1(m, dev);
+        n += 2;
+    }
+    mutex_unlock(&yaffs_context_lock);


-    len = yaffs_proc_read(buffer, &start, 0, sizeof(buffer), NULL, NULL);
-    seq_puts(m, buffer);
     return 0;
 }


@@ -3704,9 +3658,149 @@ static int yaffs_procfs_init(void)
         return -ENOMEM;
     }
 }
-
 #else
+static char *yaffs_dump_dev_part0(char *buf, struct yaffs_dev *dev)
+{
+    struct yaffs_param *param = &dev->param;
+    int bs[10];
+
+    yaffs_count_blocks_by_state(dev,bs);
+
+    buf += sprintf(buf, "start_block.......... %d\n", param->start_block);
+    buf += sprintf(buf, "end_block............ %d\n", param->end_block);
+    buf += sprintf(buf, "total_bytes_per_chunk %d\n",
+                param->total_bytes_per_chunk);
+    buf += sprintf(buf, "use_nand_ecc......... %d\n", param->use_nand_ecc);
+    buf += sprintf(buf, "no_tags_ecc.......... %d\n", param->no_tags_ecc);
+    buf += sprintf(buf, "is_yaffs2............ %d\n", param->is_yaffs2);
+    buf += sprintf(buf, "inband_tags.......... %d\n", param->inband_tags);
+    buf += sprintf(buf, "empty_lost_n_found... %d\n",
+                param->empty_lost_n_found);
+    buf += sprintf(buf, "disable_lazy_load.... %d\n",
+                param->disable_lazy_load);
+    buf += sprintf(buf, "disable_bad_block_mrk %d\n",
+                param->disable_bad_block_marking);
+    buf += sprintf(buf, "refresh_period....... %d\n",
+                param->refresh_period);
+    buf += sprintf(buf, "n_caches............. %d\n", param->n_caches);
+    buf += sprintf(buf, "n_reserved_blocks.... %d\n",
+                param->n_reserved_blocks);
+    buf += sprintf(buf, "always_check_erased.. %d\n",
+                param->always_check_erased);
+    buf += sprintf(buf, "\n");
+    buf += sprintf(buf, "block count by state\n");
+    buf += sprintf(buf, "0:%d 1:%d 2:%d 3:%d 4:%d\n",
+                bs[0], bs[1], bs[2], bs[3], bs[4]);
+    buf += sprintf(buf, "5:%d 6:%d 7:%d 8:%d 9:%d\n",
+                bs[5], bs[6], bs[7], bs[8], bs[9]);
+
+    return buf;
+}
+
+static char *yaffs_dump_dev_part1(char *buf, struct yaffs_dev *dev)
+{
+    buf += sprintf(buf, "max file size....... %lld\n",
+                (long long) yaffs_max_file_size(dev));
+    buf += sprintf(buf, "data_bytes_per_chunk. %d\n",
+                dev->data_bytes_per_chunk);
+    buf += sprintf(buf, "chunk_grp_bits....... %d\n", dev->chunk_grp_bits);
+    buf += sprintf(buf, "chunk_grp_size....... %d\n", dev->chunk_grp_size);
+    buf += sprintf(buf, "n_erased_blocks...... %d\n", dev->n_erased_blocks);
+    buf += sprintf(buf, "blocks_in_checkpt.... %d\n",
+                dev->blocks_in_checkpt);
+    buf += sprintf(buf, "\n");
+    buf += sprintf(buf, "n_tnodes............. %d\n", dev->n_tnodes);
+    buf += sprintf(buf, "n_obj................ %d\n", dev->n_obj);
+    buf += sprintf(buf, "n_free_chunks........ %d\n", dev->n_free_chunks);
+    buf += sprintf(buf, "\n");
+    buf += sprintf(buf, "n_page_writes........ %u\n", dev->n_page_writes);
+    buf += sprintf(buf, "n_page_reads......... %u\n", dev->n_page_reads);
+    buf += sprintf(buf, "n_erasures........... %u\n", dev->n_erasures);
+    buf += sprintf(buf, "n_gc_copies.......... %u\n", dev->n_gc_copies);
+    buf += sprintf(buf, "all_gcs.............. %u\n", dev->all_gcs);
+    buf += sprintf(buf, "passive_gc_count..... %u\n",
+                dev->passive_gc_count);
+    buf += sprintf(buf, "oldest_dirty_gc_count %u\n",
+                dev->oldest_dirty_gc_count);
+    buf += sprintf(buf, "n_gc_blocks.......... %u\n", dev->n_gc_blocks);
+    buf += sprintf(buf, "bg_gcs............... %u\n", dev->bg_gcs);
+    buf += sprintf(buf, "n_retried_writes..... %u\n",
+                dev->n_retried_writes);
+    buf += sprintf(buf, "n_retired_blocks..... %u\n",
+                dev->n_retired_blocks);
+    buf += sprintf(buf, "n_ecc_fixed.......... %u\n", dev->n_ecc_fixed);
+    buf += sprintf(buf, "n_ecc_unfixed........ %u\n", dev->n_ecc_unfixed);
+    buf += sprintf(buf, "n_tags_ecc_fixed..... %u\n",
+                dev->n_tags_ecc_fixed);
+    buf += sprintf(buf, "n_tags_ecc_unfixed... %u\n",
+                dev->n_tags_ecc_unfixed);
+    buf += sprintf(buf, "cache_hits........... %u\n", dev->cache_hits);
+    buf += sprintf(buf, "n_deleted_files...... %u\n", dev->n_deleted_files);
+    buf += sprintf(buf, "n_unlinked_files..... %u\n",
+                dev->n_unlinked_files);
+    buf += sprintf(buf, "refresh_count........ %u\n", dev->refresh_count);
+    buf += sprintf(buf, "n_bg_deletions....... %u\n", dev->n_bg_deletions);
+    buf += sprintf(buf, "tags_used............ %u\n", dev->tags_used);
+    buf += sprintf(buf, "summary_used......... %u\n", dev->summary_used);
+
+    return buf;
+}
+
+static int yaffs_proc_read(char *page,
+               char **start,
+               off_t offset, int count, int *eof, void *data)
+{
+    struct list_head *item;
+    char *buf = page;
+    int step = offset;
+    int n = 0;
+
+    /* Get proc_file_read() to step 'offset' by one on each sucessive call.
+     * We use 'offset' (*ppos) to indicate where we are in dev_list.
+     * This also assumes the user has posted a read buffer large
+     * enough to hold the complete output; but that's life in /proc.
+     */
+
+    *(int *)start = 1;
+
+    /* Print header first */
+    if (step == 0)
+        buf +=
+            sprintf(buf, "Multi-version YAFFS\n");
+    else if (step == 1)
+        buf += sprintf(buf, "\n");
+    else {
+        step -= 2;
+
+        mutex_lock(&yaffs_context_lock);
+
+        /* Locate and print the Nth entry.  Order N-squared but N is small. */
+        list_for_each(item, &yaffs_context_list) {
+            struct yaffs_linux_context *dc =
+                list_entry(item, struct yaffs_linux_context,
+                       context_list);
+            struct yaffs_dev *dev = dc->dev;


+            if (n < (step & ~1)) {
+                n += 2;
+                continue;
+            }
+            if ((step & 1) == 0) {
+                buf +=
+                    sprintf(buf, "\nDevice %d \"%s\"\n", n,
+                        dev->param.name);
+                buf = yaffs_dump_dev_part0(buf, dev);
+            } else {
+                buf = yaffs_dump_dev_part1(buf, dev);
+                        }
+
+            break;
+        }
+        mutex_unlock(&yaffs_context_lock);
+    }
+
+    return buf - page < count ? buf - page : count;
+}


static int yaffs_procfs_init(void)
{
--
1.9.1