2 * JFFS -- Journaling Flash File System, Linux implementation.
4 * Copyright (C) 2000 Axis Communications AB.
6 * Created by Simon Kagstrom <simonk@axis.com>.
8 * $Id: jffs_proc.c,v 1.5 2001/06/02 14:34:55 dwmw2 Exp $
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.
16 * This file defines JFFS partition entries in the proc file system.
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.
24 #include <linux/errno.h>
26 #include <linux/jffs.h>
27 #include <linux/slab.h>
28 #include <linux/proc_fs.h>
29 #include <linux/time.h>
30 #include <linux/types.h>
32 #include "jffs_proc.h"
35 * Structure for a JFFS partition in the system
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
;
46 * Structure for top-level entry in '/proc/fs' directory
48 struct proc_dir_entry
*jffs_proc_root
;
51 * Linked list of 'jffs_partition_dirs' to help us track
52 * the mounted JFFS partitions in the system
54 static struct jffs_partition_dir
*jffs_part_dirs
;
57 * Read functions for entries
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
);
66 * Register a JFFS partition directory (called upon mount)
68 int jffs_register_jffs_proc_dir(int mtd
, struct jffs_control
*c
)
70 struct jffs_partition_dir
*part_dir
;
71 struct proc_dir_entry
*part_info
= NULL
;
72 struct proc_dir_entry
*part_layout
= NULL
;
73 struct proc_dir_entry
*part_root
= NULL
;
76 sprintf(name
, "%d", mtd
);
77 /* Allocate structure for local JFFS partition table */
78 part_dir
= (struct jffs_partition_dir
*)
79 kmalloc(sizeof (struct jffs_partition_dir
), GFP_KERNEL
);
83 /* Create entry for this partition */
84 part_root
= proc_mkdir(name
, jffs_proc_root
);
88 /* Create entry for 'info' file */
89 part_info
= create_proc_entry ("info", 0, part_root
);
92 part_info
->read_proc
= jffs_proc_info_read
;
93 part_info
->data
= (void *) c
;
95 /* Create entry for 'layout' file */
96 part_layout
= create_proc_entry ("layout", 0, part_root
);
99 part_layout
->read_proc
= jffs_proc_layout_read
;
100 part_layout
->data
= (void *) c
;
102 /* Fill in structure for table and insert in the list */
104 part_dir
->part_root
= part_root
;
105 part_dir
->part_info
= part_info
;
106 part_dir
->part_layout
= part_layout
;
107 part_dir
->next
= jffs_part_dirs
;
108 jffs_part_dirs
= part_dir
;
114 remove_proc_entry("info", part_root
);
116 remove_proc_entry(name
, jffs_proc_root
);
125 * Unregister a JFFS partition directory (called at umount)
127 int jffs_unregister_jffs_proc_dir(struct jffs_control
*c
)
129 struct jffs_partition_dir
*part_dir
= jffs_part_dirs
;
130 struct jffs_partition_dir
*prev_part_dir
= NULL
;
133 if (part_dir
->c
== c
) {
134 /* Remove entries for partition */
135 remove_proc_entry (part_dir
->part_info
->name
,
136 part_dir
->part_root
);
137 remove_proc_entry (part_dir
->part_layout
->name
,
138 part_dir
->part_root
);
139 remove_proc_entry (part_dir
->part_root
->name
,
142 /* Remove entry from list */
144 prev_part_dir
->next
= part_dir
->next
;
146 jffs_part_dirs
= part_dir
->next
;
149 * Check to see if this is the last one
150 * and remove the entry from '/proc/fs'
153 if (jffs_part_dirs
== part_dir
->next
)
154 remove_proc_entry ("jffs", proc_root_fs
);
156 /* Free memory for entry */
163 /* Move to next entry */
164 prev_part_dir
= part_dir
;
165 part_dir
= part_dir
->next
;
174 * Read a JFFS partition's `info' file
176 static int jffs_proc_info_read (char *page
, char **start
, off_t off
,
177 int count
, int *eof
, void *data
)
179 struct jffs_control
*c
= (struct jffs_control
*) data
;
182 /* Get information on the parition */
183 len
+= sprintf (page
,
184 "partition size: %08lX (%u)\n"
185 "sector size: %08lX (%u)\n"
186 "used size: %08lX (%u)\n"
187 "dirty size: %08lX (%u)\n"
188 "free size: %08lX (%u)\n\n",
189 (unsigned long) c
->fmc
->flash_size
, c
->fmc
->flash_size
,
190 (unsigned long) c
->fmc
->sector_size
, c
->fmc
->sector_size
,
191 (unsigned long) c
->fmc
->used_size
, c
->fmc
->used_size
,
192 (unsigned long) c
->fmc
->dirty_size
, c
->fmc
->dirty_size
,
193 (unsigned long) (c
->fmc
->flash_size
-
194 (c
->fmc
->used_size
+ c
->fmc
->dirty_size
)),
195 c
->fmc
->flash_size
- (c
->fmc
->used_size
+ c
->fmc
->dirty_size
));
206 * Read a JFFS partition's `layout' file
208 static int jffs_proc_layout_read (char *page
, char **start
, off_t off
,
209 int count
, int *eof
, void *data
)
211 struct jffs_control
*c
= (struct jffs_control
*) data
;
212 struct jffs_fm
*fm
= NULL
;
213 struct jffs_fm
*last_fm
= NULL
;
216 /* Get the first item in the list */
219 /* Print free space */
220 if (fm
&& fm
->offset
) {
221 len
+= sprintf (page
, "00000000 %08lX free\n",
222 (unsigned long) fm
->offset
);
225 /* Loop through all of the flash control structures */
226 while (fm
&& (len
< (off
+ count
))) {
228 len
+= sprintf (page
+ len
,
229 "%08lX %08lX ino=%08lX, ver=%08lX\n",
230 (unsigned long) fm
->offset
,
231 (unsigned long) fm
->size
,
232 (unsigned long) fm
->nodes
->node
->ino
,
233 (unsigned long) fm
->nodes
->node
->version
);
236 len
+= sprintf (page
+ len
,
237 "%08lX %08lX dirty\n",
238 (unsigned long) fm
->offset
,
239 (unsigned long) fm
->size
);
245 /* Print free space */
246 if ((len
< (off
+ count
)) && last_fm
247 && (last_fm
->offset
< c
->fmc
->flash_size
)) {
248 len
+= sprintf (page
+ len
,
249 "%08lX %08lX free\n",
250 (unsigned long) last_fm
->offset
+
252 (unsigned long) (c
->fmc
->flash_size
-
253 (last_fm
->offset
+ last_fm
->size
)));