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 <
Jisheng.Zhang@synaptics.com>
---
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