Merge branch 'master' of ssh://www.aleph1.co.uk/home/aleph1/git/yaffs2
[yaffs2.git] / yaffs_fs.c
index 3deef5d7e47065d44e0a855a06ac66f101de7deb..69b739b2b6a60c5c780acde58ae495bc5e5d97f7 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 const char *yaffs_fs_c_version =
-    "$Id: yaffs_fs.c,v 1.99 2010-03-15 06:07:44 charles Exp $";
+    "$Id: yaffs_fs.c,v 1.102 2010-03-15 23:10:33 charles Exp $";
 extern const char *yaffs_guts_c_version;
 
 #include <linux/version.h>
@@ -138,16 +138,19 @@ static uint32_t YCALCBLOCKS(uint64_t partition_size, uint32_t block_size)
 unsigned int yaffs_traceMask = YAFFS_TRACE_BAD_BLOCKS | YAFFS_TRACE_ALWAYS;
 unsigned int yaffs_wr_attempts = YAFFS_WR_ATTEMPTS;
 unsigned int yaffs_auto_checkpoint = 1;
+unsigned int yaffs_gc_control = 1;
 
 /* Module Parameters */
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
 module_param(yaffs_traceMask, uint, 0644);
 module_param(yaffs_wr_attempts, uint, 0644);
 module_param(yaffs_auto_checkpoint, uint, 0644);
+module_param(yaffs_gc_control, uint, 0644);
 #else
 MODULE_PARM(yaffs_traceMask, "i");
 MODULE_PARM(yaffs_wr_attempts, "i");
 MODULE_PARM(yaffs_auto_checkpoint, "i");
+MODULE_PARM(yaffs_gc_control, "i");
 #endif
 
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25))
@@ -392,6 +395,11 @@ static const struct super_operations yaffs_super_ops = {
        .sync_fs = yaffs_sync_fs,
        .write_super = yaffs_write_super,
 };
+
+static unsigned yaffs_gc_control_callback(yaffs_Device *dev)
+{
+       return yaffs_gc_control;
+}
                                                                                                                        
 static void yaffs_GrossLock(yaffs_Device *dev)
 {
@@ -2462,6 +2470,7 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion,
        yaffs_DeviceToContext(dev)->putSuperFunc = yaffs_MTDPutSuper;
 
        param->markSuperBlockDirty = yaffs_MarkSuperBlockDirty;
+       param->gcControl = yaffs_gc_control_callback;
 
        yaffs_DeviceToContext(dev)->superBlock= sb;
        
@@ -2632,6 +2641,7 @@ static DECLARE_FSTYPE(yaffs2_fs_type, "yaffs2", yaffs2_read_super,
 #endif                         /* CONFIG_YAFFS_YAFFS2 */
 
 static struct proc_dir_entry *my_proc_entry;
+static struct proc_dir_entry *debug_proc_entry;
 
 static char *yaffs_dump_dev_part0(char *buf, yaffs_Device * dev)
 {
@@ -2742,6 +2752,40 @@ static int yaffs_proc_read(char *page,
        return buf - page < count ? buf - page : count;
 }
 
+static int yaffs_debug_proc_read(char *page,
+                               char **start,
+                               off_t offset, int count, int *eof, void *data)
+{
+       struct ylist_head *item;
+       char *buf = page;
+       int n = 0;
+
+       down(&yaffs_context_lock);
+
+       /* Locate and print the Nth entry.  Order N-squared but N is small. */
+       ylist_for_each(item, &yaffs_context_list) {
+               struct yaffs_LinuxContext *dc = ylist_entry(item, struct yaffs_LinuxContext, contextList);
+               yaffs_Device *dev = dc->dev;
+
+               int erasedChunks;
+               int nObjects;
+               int nTnodes;
+
+               erasedChunks = dev->nErasedBlocks * dev->param.nChunksPerBlock;
+               nObjects = dev->nObjectsCreated -dev->nFreeObjects;
+               nTnodes = dev->nTnodesCreated - dev->nFreeTnodes;
+               
+               
+               buf += sprintf(buf,"%d, %d, %d, %d, %d\n", 
+                               n, dev->nFreeChunks, erasedChunks,
+                               nObjects, nTnodes);
+       }
+       up(&yaffs_context_lock);
+
+
+       return buf - page < count ? buf - page : count;
+}
+
 /**
  * Set the verbosity of the warnings and error messages.
  *
@@ -2906,7 +2950,7 @@ static int __init init_yaffs_fs(void)
 
        init_MUTEX(&yaffs_context_lock);
 
-       /* Install the proc_fs entry */
+       /* Install the proc_fs entries */
        my_proc_entry = create_proc_entry("yaffs",
                                               S_IRUGO | S_IFREG,
                                               YPROC_ROOT);
@@ -2918,6 +2962,17 @@ static int __init init_yaffs_fs(void)
        } else
                return -ENOMEM;
 
+       debug_proc_entry = create_proc_entry("yaffs_debug",
+                                              S_IRUGO | S_IFREG,
+                                              YPROC_ROOT);
+
+       if (debug_proc_entry) {
+               debug_proc_entry->write_proc = NULL;
+               debug_proc_entry->read_proc = yaffs_debug_proc_read;
+               debug_proc_entry->data = NULL;
+       } else
+               return -ENOMEM;
+
        /* Now add the file system entries */
 
        fsinst = fs_to_install;