diff options
32 files changed, 219 insertions, 90 deletions
diff --git a/block/blk-timeout.c b/block/blk-timeout.c index 1ba7e0aca878..4f0c06c7a338 100644 --- a/block/blk-timeout.c +++ b/block/blk-timeout.c | |||
@@ -109,6 +109,7 @@ void blk_rq_timed_out_timer(unsigned long data) | |||
109 | struct request_queue *q = (struct request_queue *) data; | 109 | struct request_queue *q = (struct request_queue *) data; |
110 | unsigned long flags, next = 0; | 110 | unsigned long flags, next = 0; |
111 | struct request *rq, *tmp; | 111 | struct request *rq, *tmp; |
112 | int next_set = 0; | ||
112 | 113 | ||
113 | spin_lock_irqsave(q->queue_lock, flags); | 114 | spin_lock_irqsave(q->queue_lock, flags); |
114 | 115 | ||
@@ -122,16 +123,13 @@ void blk_rq_timed_out_timer(unsigned long data) | |||
122 | if (blk_mark_rq_complete(rq)) | 123 | if (blk_mark_rq_complete(rq)) |
123 | continue; | 124 | continue; |
124 | blk_rq_timed_out(rq); | 125 | blk_rq_timed_out(rq); |
125 | } else if (!next || time_after(next, rq->deadline)) | 126 | } else if (!next_set || time_after(next, rq->deadline)) { |
126 | next = rq->deadline; | 127 | next = rq->deadline; |
128 | next_set = 1; | ||
129 | } | ||
127 | } | 130 | } |
128 | 131 | ||
129 | /* | 132 | if (next_set) |
130 | * next can never be 0 here with the list non-empty, since we always | ||
131 | * bump ->deadline to 1 so we can detect if the timer was ever added | ||
132 | * or not. See comment in blk_add_timer() | ||
133 | */ | ||
134 | if (next) | ||
135 | mod_timer(&q->timeout, round_jiffies_up(next)); | 133 | mod_timer(&q->timeout, round_jiffies_up(next)); |
136 | 134 | ||
137 | spin_unlock_irqrestore(q->queue_lock, flags); | 135 | spin_unlock_irqrestore(q->queue_lock, flags); |
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 67e0fc542249..93d1f9b469d4 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c | |||
@@ -1695,6 +1695,7 @@ int drbd_send_protocol(struct drbd_conf *mdev) | |||
1695 | cf |= CF_DRY_RUN; | 1695 | cf |= CF_DRY_RUN; |
1696 | else { | 1696 | else { |
1697 | dev_err(DEV, "--dry-run is not supported by peer"); | 1697 | dev_err(DEV, "--dry-run is not supported by peer"); |
1698 | kfree(p); | ||
1698 | return 0; | 1699 | return 0; |
1699 | } | 1700 | } |
1700 | } | 1701 | } |
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index ed9f1de24a71..3f096e7959b4 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c | |||
@@ -899,7 +899,8 @@ retry: | |||
899 | 899 | ||
900 | drbd_thread_start(&mdev->asender); | 900 | drbd_thread_start(&mdev->asender); |
901 | 901 | ||
902 | drbd_send_protocol(mdev); | 902 | if (!drbd_send_protocol(mdev)) |
903 | return -1; | ||
903 | drbd_send_sync_param(mdev, &mdev->sync_conf); | 904 | drbd_send_sync_param(mdev, &mdev->sync_conf); |
904 | drbd_send_sizes(mdev, 0); | 905 | drbd_send_sizes(mdev, 0); |
905 | drbd_send_uuids(mdev); | 906 | drbd_send_uuids(mdev); |
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile index 82d1e4de475b..4521b1ecce45 100644 --- a/drivers/mtd/Makefile +++ b/drivers/mtd/Makefile | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | # Core functionality. | 5 | # Core functionality. |
6 | obj-$(CONFIG_MTD) += mtd.o | 6 | obj-$(CONFIG_MTD) += mtd.o |
7 | mtd-y := mtdcore.o mtdsuper.o mtdbdi.o | 7 | mtd-y := mtdcore.o mtdsuper.o |
8 | mtd-$(CONFIG_MTD_PARTITIONS) += mtdpart.o | 8 | mtd-$(CONFIG_MTD_PARTITIONS) += mtdpart.o |
9 | 9 | ||
10 | obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o | 10 | obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o |
diff --git a/drivers/mtd/internal.h b/drivers/mtd/internal.h index c658fe7216b5..e69de29bb2d1 100644 --- a/drivers/mtd/internal.h +++ b/drivers/mtd/internal.h | |||
@@ -1,17 +0,0 @@ | |||
1 | /* Internal MTD definitions | ||
2 | * | ||
3 | * Copyright © 2006 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | * mtdbdi.c | ||
14 | */ | ||
15 | extern struct backing_dev_info mtd_bdi_unmappable; | ||
16 | extern struct backing_dev_info mtd_bdi_ro_mappable; | ||
17 | extern struct backing_dev_info mtd_bdi_rw_mappable; | ||
diff --git a/drivers/mtd/mtdbdi.c b/drivers/mtd/mtdbdi.c index 5ca5aed0b225..e69de29bb2d1 100644 --- a/drivers/mtd/mtdbdi.c +++ b/drivers/mtd/mtdbdi.c | |||
@@ -1,43 +0,0 @@ | |||
1 | /* MTD backing device capabilities | ||
2 | * | ||
3 | * Copyright © 2006 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/backing-dev.h> | ||
13 | #include <linux/mtd/mtd.h> | ||
14 | #include "internal.h" | ||
15 | |||
16 | /* | ||
17 | * backing device capabilities for non-mappable devices (such as NAND flash) | ||
18 | * - permits private mappings, copies are taken of the data | ||
19 | */ | ||
20 | struct backing_dev_info mtd_bdi_unmappable = { | ||
21 | .capabilities = BDI_CAP_MAP_COPY, | ||
22 | }; | ||
23 | |||
24 | /* | ||
25 | * backing device capabilities for R/O mappable devices (such as ROM) | ||
26 | * - permits private mappings, copies are taken of the data | ||
27 | * - permits non-writable shared mappings | ||
28 | */ | ||
29 | struct backing_dev_info mtd_bdi_ro_mappable = { | ||
30 | .capabilities = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT | | ||
31 | BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP), | ||
32 | }; | ||
33 | |||
34 | /* | ||
35 | * backing device capabilities for writable mappable devices (such as RAM) | ||
36 | * - permits private mappings, copies are taken of the data | ||
37 | * - permits non-writable shared mappings | ||
38 | */ | ||
39 | struct backing_dev_info mtd_bdi_rw_mappable = { | ||
40 | .capabilities = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT | | ||
41 | BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP | | ||
42 | BDI_CAP_WRITE_MAP), | ||
43 | }; | ||
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 5b38b17d2229..b177e750efc3 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c | |||
@@ -2,6 +2,9 @@ | |||
2 | * Core registration and callback routines for MTD | 2 | * Core registration and callback routines for MTD |
3 | * drivers and users. | 3 | * drivers and users. |
4 | * | 4 | * |
5 | * bdi bits are: | ||
6 | * Copyright © 2006 Red Hat, Inc. All Rights Reserved. | ||
7 | * Written by David Howells (dhowells@redhat.com) | ||
5 | */ | 8 | */ |
6 | 9 | ||
7 | #include <linux/module.h> | 10 | #include <linux/module.h> |
@@ -16,11 +19,39 @@ | |||
16 | #include <linux/init.h> | 19 | #include <linux/init.h> |
17 | #include <linux/mtd/compatmac.h> | 20 | #include <linux/mtd/compatmac.h> |
18 | #include <linux/proc_fs.h> | 21 | #include <linux/proc_fs.h> |
22 | #include <linux/backing-dev.h> | ||
19 | 23 | ||
20 | #include <linux/mtd/mtd.h> | 24 | #include <linux/mtd/mtd.h> |
21 | #include "internal.h" | ||
22 | 25 | ||
23 | #include "mtdcore.h" | 26 | #include "mtdcore.h" |
27 | /* | ||
28 | * backing device capabilities for non-mappable devices (such as NAND flash) | ||
29 | * - permits private mappings, copies are taken of the data | ||
30 | */ | ||
31 | struct backing_dev_info mtd_bdi_unmappable = { | ||
32 | .capabilities = BDI_CAP_MAP_COPY, | ||
33 | }; | ||
34 | |||
35 | /* | ||
36 | * backing device capabilities for R/O mappable devices (such as ROM) | ||
37 | * - permits private mappings, copies are taken of the data | ||
38 | * - permits non-writable shared mappings | ||
39 | */ | ||
40 | struct backing_dev_info mtd_bdi_ro_mappable = { | ||
41 | .capabilities = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT | | ||
42 | BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP), | ||
43 | }; | ||
44 | |||
45 | /* | ||
46 | * backing device capabilities for writable mappable devices (such as RAM) | ||
47 | * - permits private mappings, copies are taken of the data | ||
48 | * - permits non-writable shared mappings | ||
49 | */ | ||
50 | struct backing_dev_info mtd_bdi_rw_mappable = { | ||
51 | .capabilities = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT | | ||
52 | BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP | | ||
53 | BDI_CAP_WRITE_MAP), | ||
54 | }; | ||
24 | 55 | ||
25 | static int mtd_cls_suspend(struct device *dev, pm_message_t state); | 56 | static int mtd_cls_suspend(struct device *dev, pm_message_t state); |
26 | static int mtd_cls_resume(struct device *dev); | 57 | static int mtd_cls_resume(struct device *dev); |
@@ -628,20 +659,55 @@ done: | |||
628 | /*====================================================================*/ | 659 | /*====================================================================*/ |
629 | /* Init code */ | 660 | /* Init code */ |
630 | 661 | ||
662 | static int __init mtd_bdi_init(struct backing_dev_info *bdi, const char *name) | ||
663 | { | ||
664 | int ret; | ||
665 | |||
666 | ret = bdi_init(bdi); | ||
667 | if (!ret) | ||
668 | ret = bdi_register(bdi, NULL, name); | ||
669 | |||
670 | if (ret) | ||
671 | bdi_destroy(bdi); | ||
672 | |||
673 | return ret; | ||
674 | } | ||
675 | |||
631 | static int __init init_mtd(void) | 676 | static int __init init_mtd(void) |
632 | { | 677 | { |
633 | int ret; | 678 | int ret; |
679 | |||
634 | ret = class_register(&mtd_class); | 680 | ret = class_register(&mtd_class); |
681 | if (ret) | ||
682 | goto err_reg; | ||
683 | |||
684 | ret = mtd_bdi_init(&mtd_bdi_unmappable, "mtd-unmap"); | ||
685 | if (ret) | ||
686 | goto err_bdi1; | ||
687 | |||
688 | ret = mtd_bdi_init(&mtd_bdi_ro_mappable, "mtd-romap"); | ||
689 | if (ret) | ||
690 | goto err_bdi2; | ||
691 | |||
692 | ret = mtd_bdi_init(&mtd_bdi_rw_mappable, "mtd-rwmap"); | ||
693 | if (ret) | ||
694 | goto err_bdi3; | ||
635 | 695 | ||
636 | if (ret) { | ||
637 | pr_err("Error registering mtd class: %d\n", ret); | ||
638 | return ret; | ||
639 | } | ||
640 | #ifdef CONFIG_PROC_FS | 696 | #ifdef CONFIG_PROC_FS |
641 | if ((proc_mtd = create_proc_entry( "mtd", 0, NULL ))) | 697 | if ((proc_mtd = create_proc_entry( "mtd", 0, NULL ))) |
642 | proc_mtd->read_proc = mtd_read_proc; | 698 | proc_mtd->read_proc = mtd_read_proc; |
643 | #endif /* CONFIG_PROC_FS */ | 699 | #endif /* CONFIG_PROC_FS */ |
644 | return 0; | 700 | return 0; |
701 | |||
702 | err_bdi3: | ||
703 | bdi_destroy(&mtd_bdi_ro_mappable); | ||
704 | err_bdi2: | ||
705 | bdi_destroy(&mtd_bdi_unmappable); | ||
706 | err_bdi1: | ||
707 | class_unregister(&mtd_class); | ||
708 | err_reg: | ||
709 | pr_err("Error registering mtd class or bdi: %d\n", ret); | ||
710 | return ret; | ||
645 | } | 711 | } |
646 | 712 | ||
647 | static void __exit cleanup_mtd(void) | 713 | static void __exit cleanup_mtd(void) |
@@ -651,6 +717,9 @@ static void __exit cleanup_mtd(void) | |||
651 | remove_proc_entry( "mtd", NULL); | 717 | remove_proc_entry( "mtd", NULL); |
652 | #endif /* CONFIG_PROC_FS */ | 718 | #endif /* CONFIG_PROC_FS */ |
653 | class_unregister(&mtd_class); | 719 | class_unregister(&mtd_class); |
720 | bdi_destroy(&mtd_bdi_unmappable); | ||
721 | bdi_destroy(&mtd_bdi_ro_mappable); | ||
722 | bdi_destroy(&mtd_bdi_rw_mappable); | ||
654 | } | 723 | } |
655 | 724 | ||
656 | module_init(init_mtd); | 725 | module_init(init_mtd); |
diff --git a/drivers/mtd/mtdsuper.c b/drivers/mtd/mtdsuper.c index af8b42e0a55b..7c003191fca4 100644 --- a/drivers/mtd/mtdsuper.c +++ b/drivers/mtd/mtdsuper.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/mtd/super.h> | 13 | #include <linux/mtd/super.h> |
14 | #include <linux/namei.h> | 14 | #include <linux/namei.h> |
15 | #include <linux/ctype.h> | 15 | #include <linux/ctype.h> |
16 | #include <linux/slab.h> | ||
16 | 17 | ||
17 | /* | 18 | /* |
18 | * compare superblocks to see if they're equivalent | 19 | * compare superblocks to see if they're equivalent |
@@ -44,6 +45,7 @@ static int get_sb_mtd_set(struct super_block *sb, void *_mtd) | |||
44 | 45 | ||
45 | sb->s_mtd = mtd; | 46 | sb->s_mtd = mtd; |
46 | sb->s_dev = MKDEV(MTD_BLOCK_MAJOR, mtd->index); | 47 | sb->s_dev = MKDEV(MTD_BLOCK_MAJOR, mtd->index); |
48 | sb->s_bdi = mtd->backing_dev_info; | ||
47 | return 0; | 49 | return 0; |
48 | } | 50 | } |
49 | 51 | ||
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c index 5c5bc8480070..f8b86e92cd66 100644 --- a/fs/9p/v9fs.c +++ b/fs/9p/v9fs.c | |||
@@ -238,6 +238,13 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, | |||
238 | return ERR_PTR(-ENOMEM); | 238 | return ERR_PTR(-ENOMEM); |
239 | } | 239 | } |
240 | 240 | ||
241 | rc = bdi_setup_and_register(&v9ses->bdi, "9p", BDI_CAP_MAP_COPY); | ||
242 | if (rc) { | ||
243 | __putname(v9ses->aname); | ||
244 | __putname(v9ses->uname); | ||
245 | return ERR_PTR(rc); | ||
246 | } | ||
247 | |||
241 | spin_lock(&v9fs_sessionlist_lock); | 248 | spin_lock(&v9fs_sessionlist_lock); |
242 | list_add(&v9ses->slist, &v9fs_sessionlist); | 249 | list_add(&v9ses->slist, &v9fs_sessionlist); |
243 | spin_unlock(&v9fs_sessionlist_lock); | 250 | spin_unlock(&v9fs_sessionlist_lock); |
@@ -301,6 +308,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, | |||
301 | return fid; | 308 | return fid; |
302 | 309 | ||
303 | error: | 310 | error: |
311 | bdi_destroy(&v9ses->bdi); | ||
304 | return ERR_PTR(retval); | 312 | return ERR_PTR(retval); |
305 | } | 313 | } |
306 | 314 | ||
@@ -326,6 +334,8 @@ void v9fs_session_close(struct v9fs_session_info *v9ses) | |||
326 | __putname(v9ses->uname); | 334 | __putname(v9ses->uname); |
327 | __putname(v9ses->aname); | 335 | __putname(v9ses->aname); |
328 | 336 | ||
337 | bdi_destroy(&v9ses->bdi); | ||
338 | |||
329 | spin_lock(&v9fs_sessionlist_lock); | 339 | spin_lock(&v9fs_sessionlist_lock); |
330 | list_del(&v9ses->slist); | 340 | list_del(&v9ses->slist); |
331 | spin_unlock(&v9fs_sessionlist_lock); | 341 | spin_unlock(&v9fs_sessionlist_lock); |
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h index a0a8d3dd1361..bec4d0bcb458 100644 --- a/fs/9p/v9fs.h +++ b/fs/9p/v9fs.h | |||
@@ -20,6 +20,7 @@ | |||
20 | * Boston, MA 02111-1301 USA | 20 | * Boston, MA 02111-1301 USA |
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | #include <linux/backing-dev.h> | ||
23 | 24 | ||
24 | /** | 25 | /** |
25 | * enum p9_session_flags - option flags for each 9P session | 26 | * enum p9_session_flags - option flags for each 9P session |
@@ -102,6 +103,7 @@ struct v9fs_session_info { | |||
102 | u32 uid; /* if ACCESS_SINGLE, the uid that has access */ | 103 | u32 uid; /* if ACCESS_SINGLE, the uid that has access */ |
103 | struct p9_client *clnt; /* 9p client */ | 104 | struct p9_client *clnt; /* 9p client */ |
104 | struct list_head slist; /* list of sessions registered with v9fs */ | 105 | struct list_head slist; /* list of sessions registered with v9fs */ |
106 | struct backing_dev_info bdi; | ||
105 | }; | 107 | }; |
106 | 108 | ||
107 | struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *, | 109 | struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *, |
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index 491108bd6e0d..806da5d3b3a0 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c | |||
@@ -77,6 +77,7 @@ v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses, | |||
77 | sb->s_blocksize = 1 << sb->s_blocksize_bits; | 77 | sb->s_blocksize = 1 << sb->s_blocksize_bits; |
78 | sb->s_magic = V9FS_MAGIC; | 78 | sb->s_magic = V9FS_MAGIC; |
79 | sb->s_op = &v9fs_super_ops; | 79 | sb->s_op = &v9fs_super_ops; |
80 | sb->s_bdi = &v9ses->bdi; | ||
80 | 81 | ||
81 | sb->s_flags = flags | MS_ACTIVE | MS_SYNCHRONOUS | MS_DIRSYNC | | 82 | sb->s_flags = flags | MS_ACTIVE | MS_SYNCHRONOUS | MS_DIRSYNC | |
82 | MS_NOATIME; | 83 | MS_NOATIME; |
diff --git a/fs/afs/internal.h b/fs/afs/internal.h index c54dad4e6063..a10f2582844f 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/workqueue.h> | 19 | #include <linux/workqueue.h> |
20 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
21 | #include <linux/fscache.h> | 21 | #include <linux/fscache.h> |
22 | #include <linux/backing-dev.h> | ||
22 | 23 | ||
23 | #include "afs.h" | 24 | #include "afs.h" |
24 | #include "afs_vl.h" | 25 | #include "afs_vl.h" |
@@ -313,6 +314,7 @@ struct afs_volume { | |||
313 | unsigned short rjservers; /* number of servers discarded due to -ENOMEDIUM */ | 314 | unsigned short rjservers; /* number of servers discarded due to -ENOMEDIUM */ |
314 | struct afs_server *servers[8]; /* servers on which volume resides (ordered) */ | 315 | struct afs_server *servers[8]; /* servers on which volume resides (ordered) */ |
315 | struct rw_semaphore server_sem; /* lock for accessing current server */ | 316 | struct rw_semaphore server_sem; /* lock for accessing current server */ |
317 | struct backing_dev_info bdi; | ||
316 | }; | 318 | }; |
317 | 319 | ||
318 | /* | 320 | /* |
diff --git a/fs/afs/super.c b/fs/afs/super.c index 14f6431598ad..e932e5a3a0c1 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c | |||
@@ -311,6 +311,7 @@ static int afs_fill_super(struct super_block *sb, void *data) | |||
311 | sb->s_magic = AFS_FS_MAGIC; | 311 | sb->s_magic = AFS_FS_MAGIC; |
312 | sb->s_op = &afs_super_ops; | 312 | sb->s_op = &afs_super_ops; |
313 | sb->s_fs_info = as; | 313 | sb->s_fs_info = as; |
314 | sb->s_bdi = &as->volume->bdi; | ||
314 | 315 | ||
315 | /* allocate the root inode and dentry */ | 316 | /* allocate the root inode and dentry */ |
316 | fid.vid = as->volume->vid; | 317 | fid.vid = as->volume->vid; |
diff --git a/fs/afs/volume.c b/fs/afs/volume.c index a353e69e2391..401eeb21869f 100644 --- a/fs/afs/volume.c +++ b/fs/afs/volume.c | |||
@@ -106,6 +106,10 @@ struct afs_volume *afs_volume_lookup(struct afs_mount_params *params) | |||
106 | volume->cell = params->cell; | 106 | volume->cell = params->cell; |
107 | volume->vid = vlocation->vldb.vid[params->type]; | 107 | volume->vid = vlocation->vldb.vid[params->type]; |
108 | 108 | ||
109 | ret = bdi_setup_and_register(&volume->bdi, "afs", BDI_CAP_MAP_COPY); | ||
110 | if (ret) | ||
111 | goto error_bdi; | ||
112 | |||
109 | init_rwsem(&volume->server_sem); | 113 | init_rwsem(&volume->server_sem); |
110 | 114 | ||
111 | /* look up all the applicable server records */ | 115 | /* look up all the applicable server records */ |
@@ -151,6 +155,8 @@ error: | |||
151 | return ERR_PTR(ret); | 155 | return ERR_PTR(ret); |
152 | 156 | ||
153 | error_discard: | 157 | error_discard: |
158 | bdi_destroy(&volume->bdi); | ||
159 | error_bdi: | ||
154 | up_write(¶ms->cell->vl_sem); | 160 | up_write(¶ms->cell->vl_sem); |
155 | 161 | ||
156 | for (loop = volume->nservers - 1; loop >= 0; loop--) | 162 | for (loop = volume->nservers - 1; loop >= 0; loop--) |
@@ -200,6 +206,7 @@ void afs_put_volume(struct afs_volume *volume) | |||
200 | for (loop = volume->nservers - 1; loop >= 0; loop--) | 206 | for (loop = volume->nservers - 1; loop >= 0; loop--) |
201 | afs_put_server(volume->servers[loop]); | 207 | afs_put_server(volume->servers[loop]); |
202 | 208 | ||
209 | bdi_destroy(&volume->bdi); | ||
203 | kfree(volume); | 210 | kfree(volume); |
204 | 211 | ||
205 | _leave(" [destroyed]"); | 212 | _leave(" [destroyed]"); |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index e7b8f2c89ccb..feca04197d02 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -44,8 +44,6 @@ static struct extent_io_ops btree_extent_io_ops; | |||
44 | static void end_workqueue_fn(struct btrfs_work *work); | 44 | static void end_workqueue_fn(struct btrfs_work *work); |
45 | static void free_fs_root(struct btrfs_root *root); | 45 | static void free_fs_root(struct btrfs_root *root); |
46 | 46 | ||
47 | static atomic_t btrfs_bdi_num = ATOMIC_INIT(0); | ||
48 | |||
49 | /* | 47 | /* |
50 | * end_io_wq structs are used to do processing in task context when an IO is | 48 | * end_io_wq structs are used to do processing in task context when an IO is |
51 | * complete. This is used during reads to verify checksums, and it is used | 49 | * complete. This is used during reads to verify checksums, and it is used |
@@ -1375,19 +1373,11 @@ static int setup_bdi(struct btrfs_fs_info *info, struct backing_dev_info *bdi) | |||
1375 | { | 1373 | { |
1376 | int err; | 1374 | int err; |
1377 | 1375 | ||
1378 | bdi->name = "btrfs"; | ||
1379 | bdi->capabilities = BDI_CAP_MAP_COPY; | 1376 | bdi->capabilities = BDI_CAP_MAP_COPY; |
1380 | err = bdi_init(bdi); | 1377 | err = bdi_setup_and_register(bdi, "btrfs", BDI_CAP_MAP_COPY); |
1381 | if (err) | 1378 | if (err) |
1382 | return err; | 1379 | return err; |
1383 | 1380 | ||
1384 | err = bdi_register(bdi, NULL, "btrfs-%d", | ||
1385 | atomic_inc_return(&btrfs_bdi_num)); | ||
1386 | if (err) { | ||
1387 | bdi_destroy(bdi); | ||
1388 | return err; | ||
1389 | } | ||
1390 | |||
1391 | bdi->ra_pages = default_backing_dev_info.ra_pages; | 1381 | bdi->ra_pages = default_backing_dev_info.ra_pages; |
1392 | bdi->unplug_io_fn = btrfs_unplug_io_fn; | 1382 | bdi->unplug_io_fn = btrfs_unplug_io_fn; |
1393 | bdi->unplug_io_data = info; | 1383 | bdi->unplug_io_data = info; |
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index 4797787c6a44..246a167cb913 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h | |||
@@ -18,6 +18,8 @@ | |||
18 | #ifndef _CIFS_FS_SB_H | 18 | #ifndef _CIFS_FS_SB_H |
19 | #define _CIFS_FS_SB_H | 19 | #define _CIFS_FS_SB_H |
20 | 20 | ||
21 | #include <linux/backing-dev.h> | ||
22 | |||
21 | #define CIFS_MOUNT_NO_PERM 1 /* do not do client vfs_perm check */ | 23 | #define CIFS_MOUNT_NO_PERM 1 /* do not do client vfs_perm check */ |
22 | #define CIFS_MOUNT_SET_UID 2 /* set current's euid in create etc. */ | 24 | #define CIFS_MOUNT_SET_UID 2 /* set current's euid in create etc. */ |
23 | #define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */ | 25 | #define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */ |
@@ -50,5 +52,6 @@ struct cifs_sb_info { | |||
50 | #ifdef CONFIG_CIFS_DFS_UPCALL | 52 | #ifdef CONFIG_CIFS_DFS_UPCALL |
51 | char *mountdata; /* mount options received at mount time */ | 53 | char *mountdata; /* mount options received at mount time */ |
52 | #endif | 54 | #endif |
55 | struct backing_dev_info bdi; | ||
53 | }; | 56 | }; |
54 | #endif /* _CIFS_FS_SB_H */ | 57 | #endif /* _CIFS_FS_SB_H */ |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index ded66be6597c..ad235d604a0b 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -103,6 +103,12 @@ cifs_read_super(struct super_block *sb, void *data, | |||
103 | if (cifs_sb == NULL) | 103 | if (cifs_sb == NULL) |
104 | return -ENOMEM; | 104 | return -ENOMEM; |
105 | 105 | ||
106 | rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY); | ||
107 | if (rc) { | ||
108 | kfree(cifs_sb); | ||
109 | return rc; | ||
110 | } | ||
111 | |||
106 | #ifdef CONFIG_CIFS_DFS_UPCALL | 112 | #ifdef CONFIG_CIFS_DFS_UPCALL |
107 | /* copy mount params to sb for use in submounts */ | 113 | /* copy mount params to sb for use in submounts */ |
108 | /* BB: should we move this after the mount so we | 114 | /* BB: should we move this after the mount so we |
@@ -115,6 +121,7 @@ cifs_read_super(struct super_block *sb, void *data, | |||
115 | int len = strlen(data); | 121 | int len = strlen(data); |
116 | cifs_sb->mountdata = kzalloc(len + 1, GFP_KERNEL); | 122 | cifs_sb->mountdata = kzalloc(len + 1, GFP_KERNEL); |
117 | if (cifs_sb->mountdata == NULL) { | 123 | if (cifs_sb->mountdata == NULL) { |
124 | bdi_destroy(&cifs_sb->bdi); | ||
118 | kfree(sb->s_fs_info); | 125 | kfree(sb->s_fs_info); |
119 | sb->s_fs_info = NULL; | 126 | sb->s_fs_info = NULL; |
120 | return -ENOMEM; | 127 | return -ENOMEM; |
@@ -135,6 +142,7 @@ cifs_read_super(struct super_block *sb, void *data, | |||
135 | 142 | ||
136 | sb->s_magic = CIFS_MAGIC_NUMBER; | 143 | sb->s_magic = CIFS_MAGIC_NUMBER; |
137 | sb->s_op = &cifs_super_ops; | 144 | sb->s_op = &cifs_super_ops; |
145 | sb->s_bdi = &cifs_sb->bdi; | ||
138 | /* if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512) | 146 | /* if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512) |
139 | sb->s_blocksize = | 147 | sb->s_blocksize = |
140 | cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */ | 148 | cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */ |
@@ -183,6 +191,7 @@ out_mount_failed: | |||
183 | } | 191 | } |
184 | #endif | 192 | #endif |
185 | unload_nls(cifs_sb->local_nls); | 193 | unload_nls(cifs_sb->local_nls); |
194 | bdi_destroy(&cifs_sb->bdi); | ||
186 | kfree(cifs_sb); | 195 | kfree(cifs_sb); |
187 | } | 196 | } |
188 | return rc; | 197 | return rc; |
@@ -214,6 +223,7 @@ cifs_put_super(struct super_block *sb) | |||
214 | #endif | 223 | #endif |
215 | 224 | ||
216 | unload_nls(cifs_sb->local_nls); | 225 | unload_nls(cifs_sb->local_nls); |
226 | bdi_destroy(&cifs_sb->bdi); | ||
217 | kfree(cifs_sb); | 227 | kfree(cifs_sb); |
218 | 228 | ||
219 | unlock_kernel(); | 229 | unlock_kernel(); |
diff --git a/fs/coda/inode.c b/fs/coda/inode.c index a1695dcadd99..d97f9935a028 100644 --- a/fs/coda/inode.c +++ b/fs/coda/inode.c | |||
@@ -167,6 +167,10 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent) | |||
167 | return -EBUSY; | 167 | return -EBUSY; |
168 | } | 168 | } |
169 | 169 | ||
170 | error = bdi_setup_and_register(&vc->bdi, "coda", BDI_CAP_MAP_COPY); | ||
171 | if (error) | ||
172 | goto bdi_err; | ||
173 | |||
170 | vc->vc_sb = sb; | 174 | vc->vc_sb = sb; |
171 | 175 | ||
172 | sb->s_fs_info = vc; | 176 | sb->s_fs_info = vc; |
@@ -175,6 +179,7 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent) | |||
175 | sb->s_blocksize_bits = 12; | 179 | sb->s_blocksize_bits = 12; |
176 | sb->s_magic = CODA_SUPER_MAGIC; | 180 | sb->s_magic = CODA_SUPER_MAGIC; |
177 | sb->s_op = &coda_super_operations; | 181 | sb->s_op = &coda_super_operations; |
182 | sb->s_bdi = &vc->bdi; | ||
178 | 183 | ||
179 | /* get root fid from Venus: this needs the root inode */ | 184 | /* get root fid from Venus: this needs the root inode */ |
180 | error = venus_rootfid(sb, &fid); | 185 | error = venus_rootfid(sb, &fid); |
@@ -200,6 +205,8 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent) | |||
200 | return 0; | 205 | return 0; |
201 | 206 | ||
202 | error: | 207 | error: |
208 | bdi_destroy(&vc->bdi); | ||
209 | bdi_err: | ||
203 | if (root) | 210 | if (root) |
204 | iput(root); | 211 | iput(root); |
205 | if (vc) | 212 | if (vc) |
@@ -210,6 +217,7 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent) | |||
210 | 217 | ||
211 | static void coda_put_super(struct super_block *sb) | 218 | static void coda_put_super(struct super_block *sb) |
212 | { | 219 | { |
220 | bdi_destroy(&coda_vcp(sb)->bdi); | ||
213 | coda_vcp(sb)->vc_sb = NULL; | 221 | coda_vcp(sb)->vc_sb = NULL; |
214 | sb->s_fs_info = NULL; | 222 | sb->s_fs_info = NULL; |
215 | 223 | ||
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index bc7115403f38..bfc2e0f78f00 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/scatterlist.h> | 35 | #include <linux/scatterlist.h> |
36 | #include <linux/hash.h> | 36 | #include <linux/hash.h> |
37 | #include <linux/nsproxy.h> | 37 | #include <linux/nsproxy.h> |
38 | #include <linux/backing-dev.h> | ||
38 | 39 | ||
39 | /* Version verification for shared data structures w/ userspace */ | 40 | /* Version verification for shared data structures w/ userspace */ |
40 | #define ECRYPTFS_VERSION_MAJOR 0x00 | 41 | #define ECRYPTFS_VERSION_MAJOR 0x00 |
@@ -393,6 +394,7 @@ struct ecryptfs_mount_crypt_stat { | |||
393 | struct ecryptfs_sb_info { | 394 | struct ecryptfs_sb_info { |
394 | struct super_block *wsi_sb; | 395 | struct super_block *wsi_sb; |
395 | struct ecryptfs_mount_crypt_stat mount_crypt_stat; | 396 | struct ecryptfs_mount_crypt_stat mount_crypt_stat; |
397 | struct backing_dev_info bdi; | ||
396 | }; | 398 | }; |
397 | 399 | ||
398 | /* file private data. */ | 400 | /* file private data. */ |
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index af1a8f01ebac..760983d0f25e 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -497,17 +497,25 @@ struct kmem_cache *ecryptfs_sb_info_cache; | |||
497 | static int | 497 | static int |
498 | ecryptfs_fill_super(struct super_block *sb, void *raw_data, int silent) | 498 | ecryptfs_fill_super(struct super_block *sb, void *raw_data, int silent) |
499 | { | 499 | { |
500 | struct ecryptfs_sb_info *esi; | ||
500 | int rc = 0; | 501 | int rc = 0; |
501 | 502 | ||
502 | /* Released in ecryptfs_put_super() */ | 503 | /* Released in ecryptfs_put_super() */ |
503 | ecryptfs_set_superblock_private(sb, | 504 | ecryptfs_set_superblock_private(sb, |
504 | kmem_cache_zalloc(ecryptfs_sb_info_cache, | 505 | kmem_cache_zalloc(ecryptfs_sb_info_cache, |
505 | GFP_KERNEL)); | 506 | GFP_KERNEL)); |
506 | if (!ecryptfs_superblock_to_private(sb)) { | 507 | esi = ecryptfs_superblock_to_private(sb); |
508 | if (!esi) { | ||
507 | ecryptfs_printk(KERN_WARNING, "Out of memory\n"); | 509 | ecryptfs_printk(KERN_WARNING, "Out of memory\n"); |
508 | rc = -ENOMEM; | 510 | rc = -ENOMEM; |
509 | goto out; | 511 | goto out; |
510 | } | 512 | } |
513 | |||
514 | rc = bdi_setup_and_register(&esi->bdi, "ecryptfs", BDI_CAP_MAP_COPY); | ||
515 | if (rc) | ||
516 | goto out; | ||
517 | |||
518 | sb->s_bdi = &esi->bdi; | ||
511 | sb->s_op = &ecryptfs_sops; | 519 | sb->s_op = &ecryptfs_sops; |
512 | /* Released through deactivate_super(sb) from get_sb_nodev */ | 520 | /* Released through deactivate_super(sb) from get_sb_nodev */ |
513 | sb->s_root = d_alloc(NULL, &(const struct qstr) { | 521 | sb->s_root = d_alloc(NULL, &(const struct qstr) { |
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c index 278743c7716a..0c0ae491d231 100644 --- a/fs/ecryptfs/super.c +++ b/fs/ecryptfs/super.c | |||
@@ -122,6 +122,7 @@ static void ecryptfs_put_super(struct super_block *sb) | |||
122 | lock_kernel(); | 122 | lock_kernel(); |
123 | 123 | ||
124 | ecryptfs_destroy_mount_crypt_stat(&sb_info->mount_crypt_stat); | 124 | ecryptfs_destroy_mount_crypt_stat(&sb_info->mount_crypt_stat); |
125 | bdi_destroy(&sb_info->bdi); | ||
125 | kmem_cache_free(ecryptfs_sb_info_cache, sb_info); | 126 | kmem_cache_free(ecryptfs_sb_info_cache, sb_info); |
126 | ecryptfs_set_superblock_private(sb, NULL); | 127 | ecryptfs_set_superblock_private(sb, NULL); |
127 | 128 | ||
diff --git a/fs/exofs/exofs.h b/fs/exofs/exofs.h index 8442e353309f..54373278a353 100644 --- a/fs/exofs/exofs.h +++ b/fs/exofs/exofs.h | |||
@@ -35,6 +35,7 @@ | |||
35 | 35 | ||
36 | #include <linux/fs.h> | 36 | #include <linux/fs.h> |
37 | #include <linux/time.h> | 37 | #include <linux/time.h> |
38 | #include <linux/backing-dev.h> | ||
38 | #include "common.h" | 39 | #include "common.h" |
39 | 40 | ||
40 | /* FIXME: Remove once pnfs hits mainline | 41 | /* FIXME: Remove once pnfs hits mainline |
@@ -92,6 +93,7 @@ struct exofs_sb_info { | |||
92 | struct exofs_layout layout; /* Default files layout, | 93 | struct exofs_layout layout; /* Default files layout, |
93 | * contains the variable osd_dev | 94 | * contains the variable osd_dev |
94 | * array. Keep last */ | 95 | * array. Keep last */ |
96 | struct backing_dev_info bdi; | ||
95 | struct osd_dev *_min_one_dev[1]; /* Place holder for one dev */ | 97 | struct osd_dev *_min_one_dev[1]; /* Place holder for one dev */ |
96 | }; | 98 | }; |
97 | 99 | ||
diff --git a/fs/exofs/super.c b/fs/exofs/super.c index 18e57ea1e5b4..03149b9a5178 100644 --- a/fs/exofs/super.c +++ b/fs/exofs/super.c | |||
@@ -302,6 +302,7 @@ static void exofs_put_super(struct super_block *sb) | |||
302 | _exofs_print_device("Unmounting", NULL, sbi->layout.s_ods[0], | 302 | _exofs_print_device("Unmounting", NULL, sbi->layout.s_ods[0], |
303 | sbi->layout.s_pid); | 303 | sbi->layout.s_pid); |
304 | 304 | ||
305 | bdi_destroy(&sbi->bdi); | ||
305 | exofs_free_sbi(sbi); | 306 | exofs_free_sbi(sbi); |
306 | sb->s_fs_info = NULL; | 307 | sb->s_fs_info = NULL; |
307 | } | 308 | } |
@@ -546,6 +547,10 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent) | |||
546 | if (!sbi) | 547 | if (!sbi) |
547 | return -ENOMEM; | 548 | return -ENOMEM; |
548 | 549 | ||
550 | ret = bdi_setup_and_register(&sbi->bdi, "exofs", BDI_CAP_MAP_COPY); | ||
551 | if (ret) | ||
552 | goto free_bdi; | ||
553 | |||
549 | /* use mount options to fill superblock */ | 554 | /* use mount options to fill superblock */ |
550 | od = osduld_path_lookup(opts->dev_name); | 555 | od = osduld_path_lookup(opts->dev_name); |
551 | if (IS_ERR(od)) { | 556 | if (IS_ERR(od)) { |
@@ -612,6 +617,7 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent) | |||
612 | } | 617 | } |
613 | 618 | ||
614 | /* set up operation vectors */ | 619 | /* set up operation vectors */ |
620 | sb->s_bdi = &sbi->bdi; | ||
615 | sb->s_fs_info = sbi; | 621 | sb->s_fs_info = sbi; |
616 | sb->s_op = &exofs_sops; | 622 | sb->s_op = &exofs_sops; |
617 | sb->s_export_op = &exofs_export_ops; | 623 | sb->s_export_op = &exofs_export_ops; |
@@ -643,6 +649,8 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent) | |||
643 | return 0; | 649 | return 0; |
644 | 650 | ||
645 | free_sbi: | 651 | free_sbi: |
652 | bdi_destroy(&sbi->bdi); | ||
653 | free_bdi: | ||
646 | EXOFS_ERR("Unable to mount exofs on %s pid=0x%llx err=%d\n", | 654 | EXOFS_ERR("Unable to mount exofs on %s pid=0x%llx err=%d\n", |
647 | opts->dev_name, sbi->layout.s_pid, ret); | 655 | opts->dev_name, sbi->layout.s_pid, ret); |
648 | exofs_free_sbi(sbi); | 656 | exofs_free_sbi(sbi); |
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index cf98da1be23e..fa3385154023 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c | |||
@@ -526,10 +526,15 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) | |||
526 | sb->s_blocksize_bits = 10; | 526 | sb->s_blocksize_bits = 10; |
527 | sb->s_magic = NCP_SUPER_MAGIC; | 527 | sb->s_magic = NCP_SUPER_MAGIC; |
528 | sb->s_op = &ncp_sops; | 528 | sb->s_op = &ncp_sops; |
529 | sb->s_bdi = &server->bdi; | ||
529 | 530 | ||
530 | server = NCP_SBP(sb); | 531 | server = NCP_SBP(sb); |
531 | memset(server, 0, sizeof(*server)); | 532 | memset(server, 0, sizeof(*server)); |
532 | 533 | ||
534 | error = bdi_setup_and_register(&server->bdi, "ncpfs", BDI_CAP_MAP_COPY); | ||
535 | if (error) | ||
536 | goto out_bdi; | ||
537 | |||
533 | server->ncp_filp = ncp_filp; | 538 | server->ncp_filp = ncp_filp; |
534 | server->ncp_sock = sock; | 539 | server->ncp_sock = sock; |
535 | 540 | ||
@@ -719,6 +724,8 @@ out_fput2: | |||
719 | if (server->info_filp) | 724 | if (server->info_filp) |
720 | fput(server->info_filp); | 725 | fput(server->info_filp); |
721 | out_fput: | 726 | out_fput: |
727 | bdi_destroy(&server->bdi); | ||
728 | out_bdi: | ||
722 | /* 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>: | 729 | /* 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>: |
723 | * | 730 | * |
724 | * The previously used put_filp(ncp_filp); was bogous, since | 731 | * The previously used put_filp(ncp_filp); was bogous, since |
@@ -756,6 +763,7 @@ static void ncp_put_super(struct super_block *sb) | |||
756 | kill_pid(server->m.wdog_pid, SIGTERM, 1); | 763 | kill_pid(server->m.wdog_pid, SIGTERM, 1); |
757 | put_pid(server->m.wdog_pid); | 764 | put_pid(server->m.wdog_pid); |
758 | 765 | ||
766 | bdi_destroy(&server->bdi); | ||
759 | kfree(server->priv.data); | 767 | kfree(server->priv.data); |
760 | kfree(server->auth.object_name); | 768 | kfree(server->auth.object_name); |
761 | vfree(server->rxbuf); | 769 | vfree(server->rxbuf); |
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c index 1c4c8f089970..dfa1d67f8fca 100644 --- a/fs/smbfs/inode.c +++ b/fs/smbfs/inode.c | |||
@@ -479,6 +479,7 @@ smb_put_super(struct super_block *sb) | |||
479 | if (server->conn_pid) | 479 | if (server->conn_pid) |
480 | kill_pid(server->conn_pid, SIGTERM, 1); | 480 | kill_pid(server->conn_pid, SIGTERM, 1); |
481 | 481 | ||
482 | bdi_destroy(&server->bdi); | ||
482 | kfree(server->ops); | 483 | kfree(server->ops); |
483 | smb_unload_nls(server); | 484 | smb_unload_nls(server); |
484 | sb->s_fs_info = NULL; | 485 | sb->s_fs_info = NULL; |
@@ -525,6 +526,11 @@ static int smb_fill_super(struct super_block *sb, void *raw_data, int silent) | |||
525 | if (!server) | 526 | if (!server) |
526 | goto out_no_server; | 527 | goto out_no_server; |
527 | sb->s_fs_info = server; | 528 | sb->s_fs_info = server; |
529 | |||
530 | if (bdi_setup_and_register(&server->bdi, "smbfs", BDI_CAP_MAP_COPY)) | ||
531 | goto out_bdi; | ||
532 | |||
533 | sb->s_bdi = &server->bdi; | ||
528 | 534 | ||
529 | server->super_block = sb; | 535 | server->super_block = sb; |
530 | server->mnt = NULL; | 536 | server->mnt = NULL; |
@@ -624,6 +630,8 @@ out_no_smbiod: | |||
624 | out_bad_option: | 630 | out_bad_option: |
625 | kfree(mem); | 631 | kfree(mem); |
626 | out_no_mem: | 632 | out_no_mem: |
633 | bdi_destroy(&server->bdi); | ||
634 | out_bdi: | ||
627 | if (!server->mnt) | 635 | if (!server->mnt) |
628 | printk(KERN_ERR "smb_fill_super: allocation failure\n"); | 636 | printk(KERN_ERR "smb_fill_super: allocation failure\n"); |
629 | sb->s_fs_info = NULL; | 637 | sb->s_fs_info = NULL; |
diff --git a/fs/super.c b/fs/super.c index f35ac6022109..dc72491a19f9 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -693,6 +693,7 @@ int set_anon_super(struct super_block *s, void *data) | |||
693 | return -EMFILE; | 693 | return -EMFILE; |
694 | } | 694 | } |
695 | s->s_dev = MKDEV(0, dev & MINORMASK); | 695 | s->s_dev = MKDEV(0, dev & MINORMASK); |
696 | s->s_bdi = &noop_backing_dev_info; | ||
696 | return 0; | 697 | return 0; |
697 | } | 698 | } |
698 | 699 | ||
@@ -954,10 +955,11 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void | |||
954 | if (error < 0) | 955 | if (error < 0) |
955 | goto out_free_secdata; | 956 | goto out_free_secdata; |
956 | BUG_ON(!mnt->mnt_sb); | 957 | BUG_ON(!mnt->mnt_sb); |
958 | WARN_ON(!mnt->mnt_sb->s_bdi); | ||
957 | 959 | ||
958 | error = security_sb_kern_mount(mnt->mnt_sb, flags, secdata); | 960 | error = security_sb_kern_mount(mnt->mnt_sb, flags, secdata); |
959 | if (error) | 961 | if (error) |
960 | goto out_sb; | 962 | goto out_sb; |
961 | 963 | ||
962 | /* | 964 | /* |
963 | * filesystems should never set s_maxbytes larger than MAX_LFS_FILESIZE | 965 | * filesystems should never set s_maxbytes larger than MAX_LFS_FILESIZE |
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/pagemap.h> | 14 | #include <linux/pagemap.h> |
15 | #include <linux/quotaops.h> | 15 | #include <linux/quotaops.h> |
16 | #include <linux/buffer_head.h> | 16 | #include <linux/buffer_head.h> |
17 | #include <linux/backing-dev.h> | ||
17 | #include "internal.h" | 18 | #include "internal.h" |
18 | 19 | ||
19 | #define VALID_FLAGS (SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE| \ | 20 | #define VALID_FLAGS (SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE| \ |
@@ -32,7 +33,7 @@ static int __sync_filesystem(struct super_block *sb, int wait) | |||
32 | * This should be safe, as we require bdi backing to actually | 33 | * This should be safe, as we require bdi backing to actually |
33 | * write out data in the first place | 34 | * write out data in the first place |
34 | */ | 35 | */ |
35 | if (!sb->s_bdi) | 36 | if (!sb->s_bdi || sb->s_bdi == &noop_backing_dev_info) |
36 | return 0; | 37 | return 0; |
37 | 38 | ||
38 | if (sb->s_qcop && sb->s_qcop->quota_sync) | 39 | if (sb->s_qcop && sb->s_qcop->quota_sync) |
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h index fcbc26af00e4..bd0e3c6f323f 100644 --- a/include/linux/backing-dev.h +++ b/include/linux/backing-dev.h | |||
@@ -101,6 +101,7 @@ int bdi_register(struct backing_dev_info *bdi, struct device *parent, | |||
101 | const char *fmt, ...); | 101 | const char *fmt, ...); |
102 | int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev); | 102 | int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev); |
103 | void bdi_unregister(struct backing_dev_info *bdi); | 103 | void bdi_unregister(struct backing_dev_info *bdi); |
104 | int bdi_setup_and_register(struct backing_dev_info *, char *, unsigned int); | ||
104 | void bdi_start_writeback(struct backing_dev_info *bdi, struct super_block *sb, | 105 | void bdi_start_writeback(struct backing_dev_info *bdi, struct super_block *sb, |
105 | long nr_pages); | 106 | long nr_pages); |
106 | int bdi_writeback_task(struct bdi_writeback *wb); | 107 | int bdi_writeback_task(struct bdi_writeback *wb); |
@@ -246,6 +247,7 @@ int bdi_set_max_ratio(struct backing_dev_info *bdi, unsigned int max_ratio); | |||
246 | #endif | 247 | #endif |
247 | 248 | ||
248 | extern struct backing_dev_info default_backing_dev_info; | 249 | extern struct backing_dev_info default_backing_dev_info; |
250 | extern struct backing_dev_info noop_backing_dev_info; | ||
249 | void default_unplug_io_fn(struct backing_dev_info *bdi, struct page *page); | 251 | void default_unplug_io_fn(struct backing_dev_info *bdi, struct page *page); |
250 | 252 | ||
251 | int writeback_in_progress(struct backing_dev_info *bdi); | 253 | int writeback_in_progress(struct backing_dev_info *bdi); |
diff --git a/include/linux/coda_psdev.h b/include/linux/coda_psdev.h index 5b5d4731f956..8859e2ede9fe 100644 --- a/include/linux/coda_psdev.h +++ b/include/linux/coda_psdev.h | |||
@@ -7,6 +7,8 @@ | |||
7 | #define MAX_CODADEVS 5 /* how many do we allow */ | 7 | #define MAX_CODADEVS 5 /* how many do we allow */ |
8 | 8 | ||
9 | #ifdef __KERNEL__ | 9 | #ifdef __KERNEL__ |
10 | #include <linux/backing-dev.h> | ||
11 | |||
10 | struct kstatfs; | 12 | struct kstatfs; |
11 | 13 | ||
12 | /* communication pending/processing queues */ | 14 | /* communication pending/processing queues */ |
@@ -17,6 +19,7 @@ struct venus_comm { | |||
17 | struct list_head vc_processing; | 19 | struct list_head vc_processing; |
18 | int vc_inuse; | 20 | int vc_inuse; |
19 | struct super_block *vc_sb; | 21 | struct super_block *vc_sb; |
22 | struct backing_dev_info bdi; | ||
20 | }; | 23 | }; |
21 | 24 | ||
22 | 25 | ||
diff --git a/include/linux/ncp_fs_sb.h b/include/linux/ncp_fs_sb.h index 6330fc76b00f..5ec9ca671687 100644 --- a/include/linux/ncp_fs_sb.h +++ b/include/linux/ncp_fs_sb.h | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/ncp_mount.h> | 12 | #include <linux/ncp_mount.h> |
13 | #include <linux/net.h> | 13 | #include <linux/net.h> |
14 | #include <linux/mutex.h> | 14 | #include <linux/mutex.h> |
15 | #include <linux/backing-dev.h> | ||
15 | 16 | ||
16 | #ifdef __KERNEL__ | 17 | #ifdef __KERNEL__ |
17 | 18 | ||
@@ -127,6 +128,7 @@ struct ncp_server { | |||
127 | size_t len; | 128 | size_t len; |
128 | __u8 data[128]; | 129 | __u8 data[128]; |
129 | } unexpected_packet; | 130 | } unexpected_packet; |
131 | struct backing_dev_info bdi; | ||
130 | }; | 132 | }; |
131 | 133 | ||
132 | extern void ncp_tcp_rcv_proc(struct work_struct *work); | 134 | extern void ncp_tcp_rcv_proc(struct work_struct *work); |
diff --git a/include/linux/smb_fs_sb.h b/include/linux/smb_fs_sb.h index 8a060a7040d8..bb947dd1fba9 100644 --- a/include/linux/smb_fs_sb.h +++ b/include/linux/smb_fs_sb.h | |||
@@ -10,6 +10,7 @@ | |||
10 | #define _SMB_FS_SB | 10 | #define _SMB_FS_SB |
11 | 11 | ||
12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
13 | #include <linux/backing-dev.h> | ||
13 | #include <linux/smb.h> | 14 | #include <linux/smb.h> |
14 | 15 | ||
15 | /* | 16 | /* |
@@ -74,6 +75,8 @@ struct smb_sb_info { | |||
74 | struct smb_ops *ops; | 75 | struct smb_ops *ops; |
75 | 76 | ||
76 | struct super_block *super_block; | 77 | struct super_block *super_block; |
78 | |||
79 | struct backing_dev_info bdi; | ||
77 | }; | 80 | }; |
78 | 81 | ||
79 | static inline int | 82 | static inline int |
diff --git a/mm/backing-dev.c b/mm/backing-dev.c index f13e067e1467..707d0dc6da0f 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c | |||
@@ -11,6 +11,8 @@ | |||
11 | #include <linux/writeback.h> | 11 | #include <linux/writeback.h> |
12 | #include <linux/device.h> | 12 | #include <linux/device.h> |
13 | 13 | ||
14 | static atomic_long_t bdi_seq = ATOMIC_LONG_INIT(0); | ||
15 | |||
14 | void default_unplug_io_fn(struct backing_dev_info *bdi, struct page *page) | 16 | void default_unplug_io_fn(struct backing_dev_info *bdi, struct page *page) |
15 | { | 17 | { |
16 | } | 18 | } |
@@ -25,6 +27,11 @@ struct backing_dev_info default_backing_dev_info = { | |||
25 | }; | 27 | }; |
26 | EXPORT_SYMBOL_GPL(default_backing_dev_info); | 28 | EXPORT_SYMBOL_GPL(default_backing_dev_info); |
27 | 29 | ||
30 | struct backing_dev_info noop_backing_dev_info = { | ||
31 | .name = "noop", | ||
32 | }; | ||
33 | EXPORT_SYMBOL_GPL(noop_backing_dev_info); | ||
34 | |||
28 | static struct class *bdi_class; | 35 | static struct class *bdi_class; |
29 | 36 | ||
30 | /* | 37 | /* |
@@ -715,6 +722,33 @@ void bdi_destroy(struct backing_dev_info *bdi) | |||
715 | } | 722 | } |
716 | EXPORT_SYMBOL(bdi_destroy); | 723 | EXPORT_SYMBOL(bdi_destroy); |
717 | 724 | ||
725 | /* | ||
726 | * For use from filesystems to quickly init and register a bdi associated | ||
727 | * with dirty writeback | ||
728 | */ | ||
729 | int bdi_setup_and_register(struct backing_dev_info *bdi, char *name, | ||
730 | unsigned int cap) | ||
731 | { | ||
732 | char tmp[32]; | ||
733 | int err; | ||
734 | |||
735 | bdi->name = name; | ||
736 | bdi->capabilities = cap; | ||
737 | err = bdi_init(bdi); | ||
738 | if (err) | ||
739 | return err; | ||
740 | |||
741 | sprintf(tmp, "%.28s%s", name, "-%d"); | ||
742 | err = bdi_register(bdi, NULL, tmp, atomic_long_inc_return(&bdi_seq)); | ||
743 | if (err) { | ||
744 | bdi_destroy(bdi); | ||
745 | return err; | ||
746 | } | ||
747 | |||
748 | return 0; | ||
749 | } | ||
750 | EXPORT_SYMBOL(bdi_setup_and_register); | ||
751 | |||
718 | static wait_queue_head_t congestion_wqh[2] = { | 752 | static wait_queue_head_t congestion_wqh[2] = { |
719 | __WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[0]), | 753 | __WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[0]), |
720 | __WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[1]) | 754 | __WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[1]) |