The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/jffs/jffs_proc.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * JFFS -- Journaling Flash File System, Linux implementation.
    3  *
    4  * Copyright (C) 2000  Axis Communications AB.
    5  *
    6  * Created by Simon Kagstrom <simonk@axis.com>.
    7  *
    8  * $Id: jffs_proc.c,v 1.5 2001/06/02 14:34:55 dwmw2 Exp $
    9  *
   10  * This is free software; you can redistribute it and/or modify it
   11  * under the terms of the GNU General Public License as published by
   12  * the Free Software Foundation; either version 2 of the License, or
   13  * (at your option) any later version.
   14  *
   15  *  Overview:
   16  *   This file defines JFFS partition entries in the proc file system.
   17  *
   18  *  TODO:
   19  *   Create some more proc files for different kinds of info, i.e. statistics
   20  *   about written and read bytes, number of calls to different routines,
   21  *   reports about failures.
   22  */
   23 
   24 #include <linux/errno.h>
   25 #include <linux/fs.h>
   26 #include <linux/jffs.h>
   27 #include <linux/slab.h>
   28 #include <linux/proc_fs.h>
   29 #include <linux/sched.h>
   30 #include <linux/types.h>
   31 #include "jffs_fm.h"
   32 #include "jffs_proc.h"
   33 
   34 /*
   35  * Structure for a JFFS partition in the system
   36  */
   37 struct jffs_partition_dir {
   38         struct jffs_control *c;
   39         struct proc_dir_entry *part_root;
   40         struct proc_dir_entry *part_info;
   41         struct proc_dir_entry *part_layout;
   42         struct jffs_partition_dir *next;
   43 };
   44 
   45 /*
   46  * Structure for top-level entry in '/proc/fs' directory
   47  */
   48 struct proc_dir_entry *jffs_proc_root;
   49 
   50 /*
   51  * Linked list of 'jffs_partition_dirs' to help us track
   52  * the mounted JFFS partitions in the system
   53  */
   54 static struct jffs_partition_dir *jffs_part_dirs = 0;
   55 
   56 /*
   57  * Read functions for entries
   58  */
   59 static int jffs_proc_info_read(char *page, char **start, off_t off,
   60                 int count, int *eof, void *data);
   61 static int jffs_proc_layout_read (char *page, char **start, off_t off,
   62                 int count, int *eof, void *data);
   63 
   64 
   65 /*
   66  * Register a JFFS partition directory (called upon mount)
   67  */
   68 int jffs_register_jffs_proc_dir(kdev_t dev, struct jffs_control *c)
   69 {
   70         struct jffs_partition_dir *part_dir;
   71         struct proc_dir_entry *part_info = 0;
   72         struct proc_dir_entry *part_layout = 0;
   73         struct proc_dir_entry *part_root = 0;
   74 
   75         /* Allocate structure for local JFFS partition table */
   76         if (!(part_dir = (struct jffs_partition_dir *)
   77                 kmalloc (sizeof (struct jffs_partition_dir), GFP_KERNEL))) {
   78                 return -ENOMEM;
   79         }
   80 
   81         /* Create entry for this partition */
   82         if ((part_root = create_proc_entry (kdevname(dev),
   83                 S_IFDIR | S_IRUGO | S_IXUGO, jffs_proc_root))) {
   84                 part_root->read_proc = jffs_proc_info_read;
   85                 part_root->data = (void *) c;
   86         }
   87         else {
   88                 kfree (part_dir);
   89                 return -ENOMEM;
   90         }
   91 
   92         /* Create entry for 'info' file */
   93         if ((part_info = create_proc_entry ("info", 0, part_root))) {
   94                 part_info->read_proc = jffs_proc_info_read;
   95                 part_info->data = (void *) c;
   96         }
   97         else {
   98                 remove_proc_entry (part_root->name, jffs_proc_root);
   99                 kfree (part_dir);
  100                 return -ENOMEM;
  101         }
  102 
  103         /* Create entry for 'layout' file */
  104         if ((part_layout = create_proc_entry ("layout", 0, part_root))) {
  105                 part_layout->read_proc = jffs_proc_layout_read;
  106                 part_layout->data = (void *) c;
  107         }
  108         else {
  109                 remove_proc_entry (part_info->name, part_root);
  110                 remove_proc_entry (part_root->name, jffs_proc_root);
  111                 kfree (part_dir);
  112                 return -ENOMEM;
  113         }
  114 
  115         /* Fill in structure for table and insert in the list */
  116         part_dir->c = c;
  117         part_dir->part_root = part_root;
  118         part_dir->part_info = part_info;
  119         part_dir->part_layout = part_layout;
  120         part_dir->next = jffs_part_dirs;
  121         jffs_part_dirs = part_dir;
  122 
  123         /* Return happy */
  124         return 0;
  125 }
  126 
  127 
  128 /*
  129  * Unregister a JFFS partition directory (called at umount)
  130  */
  131 int jffs_unregister_jffs_proc_dir(struct jffs_control *c)
  132 {
  133         struct jffs_partition_dir *part_dir = jffs_part_dirs;
  134         struct jffs_partition_dir *prev_part_dir = 0;
  135 
  136         while (part_dir) {
  137                 if (part_dir->c == c) {
  138                         /* Remove entries for partition */
  139                         remove_proc_entry (part_dir->part_info->name,
  140                                 part_dir->part_root);
  141                         remove_proc_entry (part_dir->part_layout->name,
  142                                 part_dir->part_root);
  143                         remove_proc_entry (part_dir->part_root->name,
  144                                 jffs_proc_root);
  145 
  146                         /* Remove entry from list */
  147                         if (prev_part_dir)
  148                                 prev_part_dir->next = part_dir->next;
  149                         else
  150                                 jffs_part_dirs = part_dir->next;
  151 
  152                         /*
  153                          * Check to see if this is the last one
  154                          * and remove the entry from '/proc/fs'
  155                          * if it is.
  156                          */
  157                         if (jffs_part_dirs == part_dir->next)
  158 #if LINUX_VERSION_CODE < 0x020300
  159                                 remove_proc_entry ("jffs", &proc_root_fs);
  160 #else
  161                                 remove_proc_entry ("jffs", proc_root_fs);
  162 #endif
  163 
  164                         /* Free memory for entry */
  165                         kfree(part_dir);
  166 
  167                         /* Return happy */
  168                         return 0;
  169                 }
  170 
  171                 /* Move to next entry */
  172                 prev_part_dir = part_dir;
  173                 part_dir = part_dir->next;
  174         }
  175 
  176         /* Return unhappy */
  177         return -1;
  178 }
  179 
  180 
  181 /*
  182  * Read a JFFS partition's `info' file
  183  */
  184 static int jffs_proc_info_read (char *page, char **start, off_t off,
  185                 int count, int *eof, void *data)
  186 {
  187         struct jffs_control *c = (struct jffs_control *) data;
  188         int len = 0;
  189 
  190         /* Get information on the parition */
  191         len += sprintf (page,
  192                 "partition size:     %08lX (%u)\n"
  193                 "sector size:        %08lX (%u)\n"
  194                 "used size:          %08lX (%u)\n"
  195                 "dirty size:         %08lX (%u)\n"
  196                 "free size:          %08lX (%u)\n\n",
  197                 (unsigned long) c->fmc->flash_size, c->fmc->flash_size,
  198                 (unsigned long) c->fmc->sector_size, c->fmc->sector_size,
  199                 (unsigned long) c->fmc->used_size, c->fmc->used_size,
  200                 (unsigned long) c->fmc->dirty_size, c->fmc->dirty_size,
  201                 (unsigned long) (c->fmc->flash_size -
  202                         (c->fmc->used_size + c->fmc->dirty_size)),
  203                 c->fmc->flash_size - (c->fmc->used_size + c->fmc->dirty_size));
  204 
  205         /* We're done */
  206         *eof = 1;
  207 
  208         /* Return length */
  209         return len;
  210 }
  211 
  212 
  213 /*
  214  * Read a JFFS partition's `layout' file
  215  */
  216 static int jffs_proc_layout_read (char *page, char **start, off_t off,
  217                 int count, int *eof, void *data)
  218 {
  219         struct jffs_control *c = (struct jffs_control *) data;
  220         struct jffs_fm *fm = 0;
  221         struct jffs_fm *last_fm = 0;
  222         int len = 0;
  223 
  224         /* Get the first item in the list */
  225         fm = c->fmc->head;
  226 
  227         /* Print free space */
  228         if (fm && fm->offset) {
  229                 len += sprintf (page, "00000000 %08lX free\n",
  230                         (unsigned long) fm->offset);
  231         }
  232 
  233         /* Loop through all of the flash control structures */
  234         while (fm && (len < (off + count))) {
  235                 if (fm->nodes) {
  236                         len += sprintf (page + len,
  237                                 "%08lX %08lX ino=%08lX, ver=%08lX\n",
  238                                 (unsigned long) fm->offset,
  239                                 (unsigned long) fm->size,
  240                                 (unsigned long) fm->nodes->node->ino,
  241                                 (unsigned long) fm->nodes->node->version);
  242                 }
  243                 else {
  244                         len += sprintf (page + len,
  245                                 "%08lX %08lX dirty\n",
  246                                 (unsigned long) fm->offset,
  247                                 (unsigned long) fm->size);
  248                 }
  249                 last_fm = fm;
  250                 fm = fm->next;
  251         }
  252 
  253         /* Print free space */
  254         if ((len < (off + count)) && last_fm
  255             && (last_fm->offset < c->fmc->flash_size)) {
  256                 len += sprintf (page + len,
  257                                "%08lX %08lX free\n",
  258                                (unsigned long) last_fm->offset + 
  259                                 last_fm->size,
  260                                (unsigned long) (c->fmc->flash_size -
  261                                                     (last_fm->offset + last_fm->size)));
  262         }
  263 
  264         /* We're done */
  265         *eof = 1;
  266 
  267         /* Return length */
  268         return len;
  269 }

Cache object: e73383bfdf23c791de50c32e6531bf85


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.