mm: bdi init hooks
Peter Zijlstra [Wed, 17 Oct 2007 06:25:46 +0000 (23:25 -0700)]
provide BDI constructor/destructor hooks

[akpm@linux-foundation.org: compile fix]
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

19 files changed:
block/ll_rw_blk.c
drivers/block/rd.c
drivers/char/mem.c
fs/char_dev.c
fs/configfs/configfs_internal.h
fs/configfs/inode.c
fs/configfs/mount.c
fs/fuse/inode.c
fs/hugetlbfs/inode.c
fs/nfs/client.c
fs/ocfs2/dlm/dlmfs.c
fs/ramfs/inode.c
fs/sysfs/inode.c
fs/sysfs/mount.c
fs/sysfs/sysfs.h
include/linux/backing-dev.h
mm/readahead.c
mm/shmem.c
mm/swap.c

index 9eabac9..524404b 100644 (file)
@@ -1786,6 +1786,7 @@ static void blk_release_queue(struct kobject *kobj)
 
        blk_trace_shutdown(q);
 
+       bdi_destroy(&q->backing_dev_info);
        kmem_cache_free(requestq_cachep, q);
 }
 
@@ -1839,21 +1840,27 @@ static struct kobj_type queue_ktype;
 struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
 {
        struct request_queue *q;
+       int err;
 
        q = kmem_cache_alloc_node(requestq_cachep,
                                gfp_mask | __GFP_ZERO, node_id);
        if (!q)
                return NULL;
 
+       q->backing_dev_info.unplug_io_fn = blk_backing_dev_unplug;
+       q->backing_dev_info.unplug_io_data = q;
+       err = bdi_init(&q->backing_dev_info);
+       if (err) {
+               kmem_cache_free(requestq_cachep, q);
+               return NULL;
+       }
+
        init_timer(&q->unplug_timer);
 
        kobject_set_name(&q->kobj, "%s", "queue");
        q->kobj.ktype = &queue_ktype;
        kobject_init(&q->kobj);
 
-       q->backing_dev_info.unplug_io_fn = blk_backing_dev_unplug;
-       q->backing_dev_info.unplug_io_data = q;
-
        mutex_init(&q->sysfs_lock);
 
        return q;
index 701ea77..80e1585 100644 (file)
@@ -411,6 +411,9 @@ static void __exit rd_cleanup(void)
                blk_cleanup_queue(rd_queue[i]);
        }
        unregister_blkdev(RAMDISK_MAJOR, "ramdisk");
+
+       bdi_destroy(&rd_file_backing_dev_info);
+       bdi_destroy(&rd_backing_dev_info);
 }
 
 /*
@@ -419,7 +422,19 @@ static void __exit rd_cleanup(void)
 static int __init rd_init(void)
 {
        int i;
-       int err = -ENOMEM;
+       int err;
+
+       err = bdi_init(&rd_backing_dev_info);
+       if (err)
+               goto out2;
+
+       err = bdi_init(&rd_file_backing_dev_info);
+       if (err) {
+               bdi_destroy(&rd_backing_dev_info);
+               goto out2;
+       }
+
+       err = -ENOMEM;
 
        if (rd_blocksize > PAGE_SIZE || rd_blocksize < 512 ||
                        (rd_blocksize & (rd_blocksize-1))) {
@@ -473,6 +488,9 @@ out:
                put_disk(rd_disks[i]);
                blk_cleanup_queue(rd_queue[i]);
        }
+       bdi_destroy(&rd_backing_dev_info);
+       bdi_destroy(&rd_file_backing_dev_info);
+out2:
        return err;
 }
 
index 64551ab..0e937f6 100644 (file)
@@ -893,6 +893,11 @@ static struct class *mem_class;
 static int __init chr_dev_init(void)
 {
        int i;
+       int err;
+
+       err = bdi_init(&zero_bdi);
+       if (err)
+               return err;
 
        if (register_chrdev(MEM_MAJOR,"mem",&memory_fops))
                printk("unable to get major %d for memory devs\n", MEM_MAJOR);
index bbbf07b..c3bfa76 100644 (file)
@@ -545,6 +545,7 @@ static struct kobject *base_probe(dev_t dev, int *part, void *data)
 void __init chrdev_init(void)
 {
        cdev_map = kobj_map_init(base_probe, &chrdevs_lock);
+       bdi_init(&directly_mappable_cdev_bdi);
 }
 
 
index 3b0185f..cca9860 100644 (file)
@@ -56,6 +56,8 @@ extern int configfs_is_root(struct config_item *item);
 
 extern struct inode * configfs_new_inode(mode_t mode, struct configfs_dirent *);
 extern int configfs_create(struct dentry *, int mode, int (*init)(struct inode *));
+extern int configfs_inode_init(void);
+extern void configfs_inode_exit(void);
 
 extern int configfs_create_file(struct config_item *, const struct configfs_attribute *);
 extern int configfs_make_dirent(struct configfs_dirent *,
index dbd257d..4c1ebff 100644 (file)
@@ -256,4 +256,12 @@ void configfs_hash_and_remove(struct dentry * dir, const char * name)
        mutex_unlock(&dir->d_inode->i_mutex);
 }
 
+int __init configfs_inode_init(void)
+{
+       return bdi_init(&configfs_backing_dev_info);
+}
 
+void __exit configfs_inode_exit(void)
+{
+       bdi_destroy(&configfs_backing_dev_info);
+}
index 871b0cb..3bf0278 100644 (file)
@@ -154,8 +154,16 @@ static int __init configfs_init(void)
                subsystem_unregister(&config_subsys);
                kmem_cache_destroy(configfs_dir_cachep);
                configfs_dir_cachep = NULL;
+               goto out;
        }
 
+       err = configfs_inode_init();
+       if (err) {
+               unregister_filesystem(&configfs_fs_type);
+               subsystem_unregister(&config_subsys);
+               kmem_cache_destroy(configfs_dir_cachep);
+               configfs_dir_cachep = NULL;
+       }
 out:
        return err;
 }
@@ -166,6 +174,7 @@ static void __exit configfs_exit(void)
        subsystem_unregister(&config_subsys);
        kmem_cache_destroy(configfs_dir_cachep);
        configfs_dir_cachep = NULL;
+       configfs_inode_exit();
 }
 
 MODULE_AUTHOR("Oracle");
index 5448f62..ca30b6a 100644 (file)
@@ -401,6 +401,7 @@ static int fuse_show_options(struct seq_file *m, struct vfsmount *mnt)
 static struct fuse_conn *new_conn(void)
 {
        struct fuse_conn *fc;
+       int err;
 
        fc = kzalloc(sizeof(*fc), GFP_KERNEL);
        if (fc) {
@@ -416,10 +417,17 @@ static struct fuse_conn *new_conn(void)
                atomic_set(&fc->num_waiting, 0);
                fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE;
                fc->bdi.unplug_io_fn = default_unplug_io_fn;
+               err = bdi_init(&fc->bdi);
+               if (err) {
+                       kfree(fc);
+                       fc = NULL;
+                       goto out;
+               }
                fc->reqctr = 0;
                fc->blocked = 1;
                get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key));
        }
+out:
        return fc;
 }
 
@@ -429,6 +437,7 @@ void fuse_conn_put(struct fuse_conn *fc)
                if (fc->destroy_req)
                        fuse_request_free(fc->destroy_req);
                mutex_destroy(&fc->inst_mutex);
+               bdi_destroy(&fc->bdi);
                kfree(fc);
        }
 }
index 04598e1..0d9a205 100644 (file)
@@ -974,11 +974,15 @@ static int __init init_hugetlbfs_fs(void)
        int error;
        struct vfsmount *vfsmount;
 
+       error = bdi_init(&hugetlbfs_backing_dev_info);
+       if (error)
+               return error;
+
        hugetlbfs_inode_cachep = kmem_cache_create("hugetlbfs_inode_cache",
                                        sizeof(struct hugetlbfs_inode_info),
                                        0, 0, init_once);
        if (hugetlbfs_inode_cachep == NULL)
-               return -ENOMEM;
+               goto out2;
 
        error = register_filesystem(&hugetlbfs_fs_type);
        if (error)
@@ -996,6 +1000,8 @@ static int __init init_hugetlbfs_fs(void)
  out:
        if (error)
                kmem_cache_destroy(hugetlbfs_inode_cachep);
+ out2:
+       bdi_destroy(&hugetlbfs_backing_dev_info);
        return error;
 }
 
@@ -1003,6 +1009,7 @@ static void __exit exit_hugetlbfs_fs(void)
 {
        kmem_cache_destroy(hugetlbfs_inode_cachep);
        unregister_filesystem(&hugetlbfs_fs_type);
+       bdi_destroy(&hugetlbfs_backing_dev_info);
 }
 
 module_init(init_hugetlbfs_fs)
index a532ee1..70587f3 100644 (file)
@@ -627,6 +627,7 @@ static void nfs_server_set_fsinfo(struct nfs_server *server, struct nfs_fsinfo *
        if (server->rsize > NFS_MAX_FILE_IO_SIZE)
                server->rsize = NFS_MAX_FILE_IO_SIZE;
        server->rpages = (server->rsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+
        server->backing_dev_info.ra_pages = server->rpages * NFS_MAX_READAHEAD;
 
        if (server->wsize > max_rpc_payload)
@@ -677,6 +678,10 @@ static int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, str
                goto out_error;
 
        nfs_server_set_fsinfo(server, &fsinfo);
+       error = bdi_init(&server->backing_dev_info);
+       if (error)
+               goto out_error;
+
 
        /* Get some general file system info */
        if (server->namelen == 0) {
@@ -756,6 +761,7 @@ void nfs_free_server(struct nfs_server *server)
        nfs_put_client(server->nfs_client);
 
        nfs_free_iostats(server->io_stats);
+       bdi_destroy(&server->backing_dev_info);
        kfree(server);
        nfs_release_automount_timer();
        dprintk("<-- nfs_free_server()\n");
index 7418dc8..1150412 100644 (file)
@@ -588,13 +588,17 @@ static int __init init_dlmfs_fs(void)
 
        dlmfs_print_version();
 
+       status = bdi_init(&dlmfs_backing_dev_info);
+       if (status)
+               return status;
+
        dlmfs_inode_cache = kmem_cache_create("dlmfs_inode_cache",
                                sizeof(struct dlmfs_inode_private),
                                0, (SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|
                                        SLAB_MEM_SPREAD),
                                dlmfs_init_once);
        if (!dlmfs_inode_cache)
-               return -ENOMEM;
+               goto bail;
        cleanup_inode = 1;
 
        user_dlm_worker = create_singlethread_workqueue("user_dlm");
@@ -611,6 +615,7 @@ bail:
                        kmem_cache_destroy(dlmfs_inode_cache);
                if (cleanup_worker)
                        destroy_workqueue(user_dlm_worker);
+               bdi_destroy(&dlmfs_backing_dev_info);
        } else
                printk("OCFS2 User DLM kernel interface loaded\n");
        return status;
@@ -624,6 +629,8 @@ static void __exit exit_dlmfs_fs(void)
        destroy_workqueue(user_dlm_worker);
 
        kmem_cache_destroy(dlmfs_inode_cache);
+
+       bdi_destroy(&dlmfs_backing_dev_info);
 }
 
 MODULE_AUTHOR("Oracle");
index ef2b46d..8428d5b 100644 (file)
@@ -223,7 +223,17 @@ module_exit(exit_ramfs_fs)
 
 int __init init_rootfs(void)
 {
-       return register_filesystem(&rootfs_fs_type);
+       int err;
+
+       err = bdi_init(&ramfs_backing_dev_info);
+       if (err)
+               return err;
+
+       err = register_filesystem(&rootfs_fs_type);
+       if (err)
+               bdi_destroy(&ramfs_backing_dev_info);
+
+       return err;
 }
 
 MODULE_LICENSE("GPL");
index c4ef945..d9262f7 100644 (file)
@@ -37,6 +37,11 @@ static const struct inode_operations sysfs_inode_operations ={
        .setattr        = sysfs_setattr,
 };
 
+int __init sysfs_inode_init(void)
+{
+       return bdi_init(&sysfs_backing_dev_info);
+}
+
 int sysfs_setattr(struct dentry * dentry, struct iattr * iattr)
 {
        struct inode * inode = dentry->d_inode;
index c76c540..7416826 100644 (file)
@@ -92,6 +92,10 @@ int __init sysfs_init(void)
        if (!sysfs_dir_cachep)
                goto out;
 
+       err = sysfs_inode_init();
+       if (err)
+               goto out_err;
+
        err = register_filesystem(&sysfs_fs_type);
        if (!err) {
                sysfs_mount = kern_mount(&sysfs_fs_type);
index f0326f2..f841798 100644 (file)
@@ -146,6 +146,7 @@ static inline void sysfs_put(struct sysfs_dirent *sd)
 struct inode *sysfs_get_inode(struct sysfs_dirent *sd);
 int sysfs_setattr(struct dentry *dentry, struct iattr *iattr);
 int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name);
+int sysfs_inode_init(void);
 
 /*
  * file.c
index 210933c..8f56634 100644 (file)
@@ -34,6 +34,14 @@ struct backing_dev_info {
        void *unplug_io_data;
 };
 
+static inline int bdi_init(struct backing_dev_info *bdi)
+{
+       return 0;
+}
+
+static inline void bdi_destroy(struct backing_dev_info *bdi)
+{
+}
 
 /*
  * Flags in backing_dev_info::capability
index 2297888..c9c50ca 100644 (file)
@@ -233,6 +233,12 @@ unsigned long max_sane_readahead(unsigned long nr)
                + node_page_state(numa_node_id(), NR_FREE_PAGES)) / 2);
 }
 
+static int __init readahead_init(void)
+{
+       return bdi_init(&default_backing_dev_info);
+}
+subsys_initcall(readahead_init);
+
 /*
  * Submit IO for the read-ahead request in file_ra_state.
  */
index 8a82342..2f039f3 100644 (file)
@@ -2464,6 +2464,10 @@ static int __init init_tmpfs(void)
 {
        int error;
 
+       error = bdi_init(&shmem_backing_dev_info);
+       if (error)
+               goto out4;
+
        error = init_inodecache();
        if (error)
                goto out3;
@@ -2488,6 +2492,8 @@ out1:
 out2:
        destroy_inodecache();
 out3:
+       bdi_destroy(&shmem_backing_dev_info);
+out4:
        shm_mnt = ERR_PTR(error);
        return error;
 }
index d034b21..a65eff8 100644 (file)
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -28,6 +28,7 @@
 #include <linux/percpu.h>
 #include <linux/cpu.h>
 #include <linux/notifier.h>
+#include <linux/backing-dev.h>
 
 /* How many pages do we try to swap or page in/out together? */
 int page_cluster;
@@ -547,6 +548,10 @@ void __init swap_setup(void)
 {
        unsigned long megs = num_physpages >> (20 - PAGE_SHIFT);
 
+#ifdef CONFIG_SWAP
+       bdi_init(swapper_space.backing_dev_info);
+#endif
+
        /* Use a smaller cluster for small-memory machines */
        if (megs < 16)
                page_cluster = 2;