X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fjffs2%2Fsuper.c;h=ffd8e84b22cc13a32323541203e5dcfdf686ccc4;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=b657c55d5f51fac0660da622ca5adf104139c984;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index b657c55d5..ffd8e84b2 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c @@ -3,11 +3,11 @@ * * Copyright (C) 2001-2003 Red Hat, Inc. * - * Created by David Woodhouse + * Created by David Woodhouse * * For licensing information, see the file 'LICENCE' in this directory. * - * $Id: super.c,v 1.90 2003/10/11 11:47:23 dwmw2 Exp $ + * $Id: super.c,v 1.110 2005/11/07 11:14:42 gleixner Exp $ * */ @@ -24,6 +24,7 @@ #include #include #include +#include "compr.h" #include "nodelist.h" static void jffs2_put_super(struct super_block *); @@ -50,11 +51,21 @@ static void jffs2_i_init_once(void * foo, kmem_cache_t * cachep, unsigned long f if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) { - init_MUTEX_LOCKED(&ei->sem); + init_MUTEX(&ei->sem); inode_init_once(&ei->vfs_inode); } } +static int jffs2_sync_fs(struct super_block *sb, int wait) +{ + struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); + + down(&c->alloc_sem); + jffs2_flush_wbuf_pad(c); + up(&c->alloc_sem); + return 0; +} + static struct super_operations jffs2_super_operations = { .alloc_inode = jffs2_alloc_inode, @@ -66,6 +77,7 @@ static struct super_operations jffs2_super_operations = .remount_fs = jffs2_remount_fs, .clear_inode = jffs2_clear_inode, .dirty_inode = jffs2_dirty_inode, + .sync_fs = jffs2_sync_fs, }; static int jffs2_sb_compare(struct super_block *sb, void *data) @@ -100,7 +112,7 @@ static int jffs2_sb_set(struct super_block *sb, void *data) } static struct super_block *jffs2_get_sb_mtd(struct file_system_type *fs_type, - int flags, const char *dev_name, + int flags, const char *dev_name, void *data, struct mtd_info *mtd) { struct super_block *sb; @@ -128,10 +140,19 @@ static struct super_block *jffs2_get_sb_mtd(struct file_system_type *fs_type, D1(printk(KERN_DEBUG "jffs2_get_sb_mtd(): New superblock for device %d (\"%s\")\n", mtd->index, mtd->name)); + /* Initialize JFFS2 superblock locks, the further initialization will be + * done later */ + init_MUTEX(&c->alloc_sem); + init_MUTEX(&c->erase_free_sem); + init_waitqueue_head(&c->erase_wait); + init_waitqueue_head(&c->inocache_wq); + spin_lock_init(&c->erase_completion_lock); + spin_lock_init(&c->inocache_lock); + sb->s_op = &jffs2_super_operations; - sb->s_flags |= MS_NOATIME; + sb->s_flags = flags | MS_NOATIME; - ret = jffs2_do_fill_super(sb, data, (flags&MS_VERBOSE)?1:0); + ret = jffs2_do_fill_super(sb, data, flags & MS_SILENT ? 1 : 0); if (ret) { /* Failure case... */ @@ -151,7 +172,7 @@ static struct super_block *jffs2_get_sb_mtd(struct file_system_type *fs_type, } static struct super_block *jffs2_get_sb_mtdnr(struct file_system_type *fs_type, - int flags, const char *dev_name, + int flags, const char *dev_name, void *data, int mtdnr) { struct mtd_info *mtd; @@ -180,7 +201,7 @@ static struct super_block *jffs2_get_sb(struct file_system_type *fs_type, /* The preferred way of mounting in future; especially when CONFIG_BLK_DEV is implemented - we specify the underlying - MTD device by number or by name, so that we don't require + MTD device by number or by name, so that we don't require block device support to be present in the kernel. */ /* FIXME: How to do the root fs this way? */ @@ -204,7 +225,7 @@ static struct super_block *jffs2_get_sb(struct file_system_type *fs_type, } else if (isdigit(dev_name[3])) { /* Mount by MTD device number name */ char *endptr; - + mtdnr = simple_strtoul(dev_name+3, &endptr, 0); if (!*endptr) { /* It was a valid number */ @@ -214,7 +235,7 @@ static struct super_block *jffs2_get_sb(struct file_system_type *fs_type, } } - /* Try the old way - the hack where we allowed users to mount + /* Try the old way - the hack where we allowed users to mount /dev/mtdblock$(n) but didn't actually _use_ the blkdev */ err = path_lookup(dev_name, LOOKUP_FOLLOW, &nd); @@ -236,7 +257,7 @@ static struct super_block *jffs2_get_sb(struct file_system_type *fs_type, } if (imajor(nd.dentry->d_inode) != MTD_BLOCK_MAJOR) { - if (!(flags & MS_VERBOSE)) /* Yes I mean this. Strangely */ + if (!(flags & MS_SILENT)) printk(KERN_NOTICE "Attempt to mount non-MTD device \"%s\" as JFFS2\n", dev_name); goto out; @@ -258,15 +279,19 @@ static void jffs2_put_super (struct super_block *sb) D2(printk(KERN_DEBUG "jffs2: jffs2_put_super()\n")); - if (!(sb->s_flags & MS_RDONLY)) - jffs2_stop_garbage_collect_thread(c); down(&c->alloc_sem); jffs2_flush_wbuf_pad(c); up(&c->alloc_sem); + + jffs2_sum_exit(c); + jffs2_free_ino_caches(c); jffs2_free_raw_node_refs(c); - kfree(c->blocks); - jffs2_nand_flash_cleanup(c); + if (jffs2_blocks_use_vmalloc(c)) + vfree(c->blocks); + else + kfree(c->blocks); + jffs2_flash_cleanup(c); kfree(c->inocache_list); if (c->mtd->sync) c->mtd->sync(c->mtd); @@ -277,6 +302,8 @@ static void jffs2_put_super (struct super_block *sb) static void jffs2_kill_sb(struct super_block *sb) { struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); + if (!(sb->s_flags & MS_RDONLY)) + jffs2_stop_garbage_collect_thread(c); generic_shutdown_super(sb); put_mtd_device(c->mtd); kfree(c); @@ -294,28 +321,32 @@ static int __init init_jffs2_fs(void) int ret; printk(KERN_INFO "JFFS2 version 2.2." -#ifdef CONFIG_FS_JFFS2_NAND +#ifdef CONFIG_JFFS2_FS_WRITEBUFFER " (NAND)" +#endif +#ifdef CONFIG_JFFS2_SUMMARY + " (SUMMARY) " #endif " (C) 2001-2003 Red Hat, Inc.\n"); jffs2_inode_cachep = kmem_cache_create("jffs2_i", sizeof(struct jffs2_inode_info), - 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT, + 0, (SLAB_RECLAIM_ACCOUNT| + SLAB_MEM_SPREAD), jffs2_i_init_once, NULL); if (!jffs2_inode_cachep) { printk(KERN_ERR "JFFS2 error: Failed to initialise inode cache\n"); return -ENOMEM; } - ret = jffs2_zlib_init(); + ret = jffs2_compressors_init(); if (ret) { - printk(KERN_ERR "JFFS2 error: Failed to initialise zlib workspaces\n"); + printk(KERN_ERR "JFFS2 error: Failed to initialise compressors\n"); goto out; } ret = jffs2_create_slab_caches(); if (ret) { printk(KERN_ERR "JFFS2 error: Failed to initialise slab caches\n"); - goto out_zlib; + goto out_compressors; } ret = register_filesystem(&jffs2_fs_type); if (ret) { @@ -326,9 +357,10 @@ static int __init init_jffs2_fs(void) out_slab: jffs2_destroy_slab_caches(); - out_zlib: - jffs2_zlib_exit(); + out_compressors: + jffs2_compressors_exit(); out: + kmem_cache_destroy(jffs2_inode_cachep); return ret; } @@ -336,7 +368,7 @@ static void __exit exit_jffs2_fs(void) { unregister_filesystem(&jffs2_fs_type); jffs2_destroy_slab_caches(); - jffs2_zlib_exit(); + jffs2_compressors_exit(); kmem_cache_destroy(jffs2_inode_cachep); } @@ -345,5 +377,5 @@ module_exit(exit_jffs2_fs); MODULE_DESCRIPTION("The Journalling Flash File System, v2"); MODULE_AUTHOR("Red Hat, Inc."); -MODULE_LICENSE("GPL"); // Actually dual-licensed, but it doesn't matter for +MODULE_LICENSE("GPL"); // Actually dual-licensed, but it doesn't matter for // the sake of this tag. It's Free Software.