Commit 970b0648 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.dk/linux-2.6-block

* 'for-linus' of git://git.kernel.dk/linux-2.6-block:
  coda: move backing-dev.h kernel include inside __KERNEL__
  mtd: ensure that bdi entries are properly initialized and registered
  Move mtd_bdi_*mappable to mtdcore.c
  btrfs: convert to using bdi_setup_and_register()
  Catch filesystems lacking s_bdi
  drbd: Terminate a connection early if sending the protocol fails
  drbd: fix memory leak
  Fix JFFS2 sync silent failure
  smbfs: add bdi backing to mount session
  ncpfs: add bdi backing to mount session
  exofs: add bdi backing to mount session
  ecryptfs: add bdi backing to mount session
  coda: add bdi backing to mount session
  cifs: add bdi backing to mount session
  afs: add bdi backing to mount session.
  9p: add bdi backing to mount session
  bdi: add helper function for doing init and register of a bdi for a file system
  block: ensure jiffies wrap is handled correctly in blk_rq_timed_out_timer
parents 696e65c3 33f60e96
...@@ -109,6 +109,7 @@ void blk_rq_timed_out_timer(unsigned long data) ...@@ -109,6 +109,7 @@ void blk_rq_timed_out_timer(unsigned long data)
struct request_queue *q = (struct request_queue *) data; struct request_queue *q = (struct request_queue *) data;
unsigned long flags, next = 0; unsigned long flags, next = 0;
struct request *rq, *tmp; struct request *rq, *tmp;
int next_set = 0;
spin_lock_irqsave(q->queue_lock, flags); spin_lock_irqsave(q->queue_lock, flags);
...@@ -122,16 +123,13 @@ void blk_rq_timed_out_timer(unsigned long data) ...@@ -122,16 +123,13 @@ void blk_rq_timed_out_timer(unsigned long data)
if (blk_mark_rq_complete(rq)) if (blk_mark_rq_complete(rq))
continue; continue;
blk_rq_timed_out(rq); blk_rq_timed_out(rq);
} else if (!next || time_after(next, rq->deadline)) } else if (!next_set || time_after(next, rq->deadline)) {
next = rq->deadline; next = rq->deadline;
next_set = 1;
}
} }
/* if (next_set)
* next can never be 0 here with the list non-empty, since we always
* bump ->deadline to 1 so we can detect if the timer was ever added
* or not. See comment in blk_add_timer()
*/
if (next)
mod_timer(&q->timeout, round_jiffies_up(next)); mod_timer(&q->timeout, round_jiffies_up(next));
spin_unlock_irqrestore(q->queue_lock, flags); spin_unlock_irqrestore(q->queue_lock, flags);
......
...@@ -1695,6 +1695,7 @@ int drbd_send_protocol(struct drbd_conf *mdev) ...@@ -1695,6 +1695,7 @@ int drbd_send_protocol(struct drbd_conf *mdev)
cf |= CF_DRY_RUN; cf |= CF_DRY_RUN;
else { else {
dev_err(DEV, "--dry-run is not supported by peer"); dev_err(DEV, "--dry-run is not supported by peer");
kfree(p);
return 0; return 0;
} }
} }
......
...@@ -899,7 +899,8 @@ static int drbd_connect(struct drbd_conf *mdev) ...@@ -899,7 +899,8 @@ static int drbd_connect(struct drbd_conf *mdev)
drbd_thread_start(&mdev->asender); drbd_thread_start(&mdev->asender);
drbd_send_protocol(mdev); if (!drbd_send_protocol(mdev))
return -1;
drbd_send_sync_param(mdev, &mdev->sync_conf); drbd_send_sync_param(mdev, &mdev->sync_conf);
drbd_send_sizes(mdev, 0); drbd_send_sizes(mdev, 0);
drbd_send_uuids(mdev); drbd_send_uuids(mdev);
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# Core functionality. # Core functionality.
obj-$(CONFIG_MTD) += mtd.o obj-$(CONFIG_MTD) += mtd.o
mtd-y := mtdcore.o mtdsuper.o mtdbdi.o mtd-y := mtdcore.o mtdsuper.o
mtd-$(CONFIG_MTD_PARTITIONS) += mtdpart.o mtd-$(CONFIG_MTD_PARTITIONS) += mtdpart.o
obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o
......
/* Internal MTD definitions
*
* Copyright © 2006 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
/*
* mtdbdi.c
*/
extern struct backing_dev_info mtd_bdi_unmappable;
extern struct backing_dev_info mtd_bdi_ro_mappable;
extern struct backing_dev_info mtd_bdi_rw_mappable;
/* MTD backing device capabilities
*
* Copyright © 2006 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <linux/backing-dev.h>
#include <linux/mtd/mtd.h>
#include "internal.h"
/*
* backing device capabilities for non-mappable devices (such as NAND flash)
* - permits private mappings, copies are taken of the data
*/
struct backing_dev_info mtd_bdi_unmappable = {
.capabilities = BDI_CAP_MAP_COPY,
};
/*
* backing device capabilities for R/O mappable devices (such as ROM)
* - permits private mappings, copies are taken of the data
* - permits non-writable shared mappings
*/
struct backing_dev_info mtd_bdi_ro_mappable = {
.capabilities = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT |
BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP),
};
/*
* backing device capabilities for writable mappable devices (such as RAM)
* - permits private mappings, copies are taken of the data
* - permits non-writable shared mappings
*/
struct backing_dev_info mtd_bdi_rw_mappable = {
.capabilities = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT |
BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP |
BDI_CAP_WRITE_MAP),
};
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
* Core registration and callback routines for MTD * Core registration and callback routines for MTD
* drivers and users. * drivers and users.
* *
* bdi bits are:
* Copyright © 2006 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*/ */
#include <linux/module.h> #include <linux/module.h>
...@@ -16,11 +19,39 @@ ...@@ -16,11 +19,39 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/mtd/compatmac.h> #include <linux/mtd/compatmac.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/backing-dev.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include "internal.h"
#include "mtdcore.h" #include "mtdcore.h"
/*
* backing device capabilities for non-mappable devices (such as NAND flash)
* - permits private mappings, copies are taken of the data
*/
struct backing_dev_info mtd_bdi_unmappable = {
.capabilities = BDI_CAP_MAP_COPY,
};
/*
* backing device capabilities for R/O mappable devices (such as ROM)
* - permits private mappings, copies are taken of the data
* - permits non-writable shared mappings
*/
struct backing_dev_info mtd_bdi_ro_mappable = {
.capabilities = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT |
BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP),
};
/*
* backing device capabilities for writable mappable devices (such as RAM)
* - permits private mappings, copies are taken of the data
* - permits non-writable shared mappings
*/
struct backing_dev_info mtd_bdi_rw_mappable = {
.capabilities = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT |
BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP |
BDI_CAP_WRITE_MAP),
};
static int mtd_cls_suspend(struct device *dev, pm_message_t state); static int mtd_cls_suspend(struct device *dev, pm_message_t state);
static int mtd_cls_resume(struct device *dev); static int mtd_cls_resume(struct device *dev);
...@@ -628,20 +659,55 @@ static int mtd_read_proc (char *page, char **start, off_t off, int count, ...@@ -628,20 +659,55 @@ static int mtd_read_proc (char *page, char **start, off_t off, int count,
/*====================================================================*/ /*====================================================================*/
/* Init code */ /* Init code */
static int __init mtd_bdi_init(struct backing_dev_info *bdi, const char *name)
{
int ret;
ret = bdi_init(bdi);
if (!ret)
ret = bdi_register(bdi, NULL, name);
if (ret)
bdi_destroy(bdi);
return ret;
}
static int __init init_mtd(void) static int __init init_mtd(void)
{ {
int ret; int ret;
ret = class_register(&mtd_class); ret = class_register(&mtd_class);
if (ret)
goto err_reg;
ret = mtd_bdi_init(&mtd_bdi_unmappable, "mtd-unmap");
if (ret)
goto err_bdi1;
ret = mtd_bdi_init(&mtd_bdi_ro_mappable, "mtd-romap");
if (ret)
goto err_bdi2;
ret = mtd_bdi_init(&mtd_bdi_rw_mappable, "mtd-rwmap");
if (ret)
goto err_bdi3;
if (ret) {
pr_err("Error registering mtd class: %d\n", ret);
return ret;
}
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
if ((proc_mtd = create_proc_entry( "mtd", 0, NULL ))) if ((proc_mtd = create_proc_entry( "mtd", 0, NULL )))
proc_mtd->read_proc = mtd_read_proc; proc_mtd->read_proc = mtd_read_proc;
#endif /* CONFIG_PROC_FS */ #endif /* CONFIG_PROC_FS */
return 0; return 0;
err_bdi3:
bdi_destroy(&mtd_bdi_ro_mappable);
err_bdi2:
bdi_destroy(&mtd_bdi_unmappable);
err_bdi1:
class_unregister(&mtd_class);
err_reg:
pr_err("Error registering mtd class or bdi: %d\n", ret);
return ret;
} }
static void __exit cleanup_mtd(void) static void __exit cleanup_mtd(void)
...@@ -651,6 +717,9 @@ static void __exit cleanup_mtd(void) ...@@ -651,6 +717,9 @@ static void __exit cleanup_mtd(void)
remove_proc_entry( "mtd", NULL); remove_proc_entry( "mtd", NULL);
#endif /* CONFIG_PROC_FS */ #endif /* CONFIG_PROC_FS */
class_unregister(&mtd_class); class_unregister(&mtd_class);
bdi_destroy(&mtd_bdi_unmappable);
bdi_destroy(&mtd_bdi_ro_mappable);
bdi_destroy(&mtd_bdi_rw_mappable);
} }
module_init(init_mtd); module_init(init_mtd);
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/mtd/super.h> #include <linux/mtd/super.h>
#include <linux/namei.h> #include <linux/namei.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/slab.h>
/* /*
* compare superblocks to see if they're equivalent * 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,6 +45,7 @@ static int get_sb_mtd_set(struct super_block *sb, void *_mtd)
sb->s_mtd = mtd; sb->s_mtd = mtd;
sb->s_dev = MKDEV(MTD_BLOCK_MAJOR, mtd->index); sb->s_dev = MKDEV(MTD_BLOCK_MAJOR, mtd->index);
sb->s_bdi = mtd->backing_dev_info;
return 0; return 0;
} }
......
...@@ -238,6 +238,13 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, ...@@ -238,6 +238,13 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
} }
rc = bdi_setup_and_register(&v9ses->bdi, "9p", BDI_CAP_MAP_COPY);
if (rc) {
__putname(v9ses->aname);
__putname(v9ses->uname);
return ERR_PTR(rc);
}
spin_lock(&v9fs_sessionlist_lock); spin_lock(&v9fs_sessionlist_lock);
list_add(&v9ses->slist, &v9fs_sessionlist); list_add(&v9ses->slist, &v9fs_sessionlist);
spin_unlock(&v9fs_sessionlist_lock); spin_unlock(&v9fs_sessionlist_lock);
...@@ -301,6 +308,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses, ...@@ -301,6 +308,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
return fid; return fid;
error: error:
bdi_destroy(&v9ses->bdi);
return ERR_PTR(retval); return ERR_PTR(retval);
} }
...@@ -326,6 +334,8 @@ void v9fs_session_close(struct v9fs_session_info *v9ses) ...@@ -326,6 +334,8 @@ void v9fs_session_close(struct v9fs_session_info *v9ses)
__putname(v9ses->uname); __putname(v9ses->uname);
__putname(v9ses->aname); __putname(v9ses->aname);
bdi_destroy(&v9ses->bdi);
spin_lock(&v9fs_sessionlist_lock); spin_lock(&v9fs_sessionlist_lock);
list_del(&v9ses->slist); list_del(&v9ses->slist);
spin_unlock(&v9fs_sessionlist_lock); spin_unlock(&v9fs_sessionlist_lock);
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
* Boston, MA 02111-1301 USA * Boston, MA 02111-1301 USA
* *
*/ */
#include <linux/backing-dev.h>
/** /**
* enum p9_session_flags - option flags for each 9P session * enum p9_session_flags - option flags for each 9P session
...@@ -102,6 +103,7 @@ struct v9fs_session_info { ...@@ -102,6 +103,7 @@ struct v9fs_session_info {
u32 uid; /* if ACCESS_SINGLE, the uid that has access */ u32 uid; /* if ACCESS_SINGLE, the uid that has access */
struct p9_client *clnt; /* 9p client */ struct p9_client *clnt; /* 9p client */
struct list_head slist; /* list of sessions registered with v9fs */ struct list_head slist; /* list of sessions registered with v9fs */
struct backing_dev_info bdi;
}; };
struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *, struct p9_fid *v9fs_session_init(struct v9fs_session_info *, const char *,
......
...@@ -77,6 +77,7 @@ v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses, ...@@ -77,6 +77,7 @@ v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses,
sb->s_blocksize = 1 << sb->s_blocksize_bits; sb->s_blocksize = 1 << sb->s_blocksize_bits;
sb->s_magic = V9FS_MAGIC; sb->s_magic = V9FS_MAGIC;
sb->s_op = &v9fs_super_ops; sb->s_op = &v9fs_super_ops;
sb->s_bdi = &v9ses->bdi;
sb->s_flags = flags | MS_ACTIVE | MS_SYNCHRONOUS | MS_DIRSYNC | sb->s_flags = flags | MS_ACTIVE | MS_SYNCHRONOUS | MS_DIRSYNC |
MS_NOATIME; MS_NOATIME;
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/fscache.h> #include <linux/fscache.h>
#include <linux/backing-dev.h>
#include "afs.h" #include "afs.h"
#include "afs_vl.h" #include "afs_vl.h"
...@@ -313,6 +314,7 @@ struct afs_volume { ...@@ -313,6 +314,7 @@ struct afs_volume {
unsigned short rjservers; /* number of servers discarded due to -ENOMEDIUM */ unsigned short rjservers; /* number of servers discarded due to -ENOMEDIUM */
struct afs_server *servers[8]; /* servers on which volume resides (ordered) */ struct afs_server *servers[8]; /* servers on which volume resides (ordered) */
struct rw_semaphore server_sem; /* lock for accessing current server */ struct rw_semaphore server_sem; /* lock for accessing current server */
struct backing_dev_info bdi;
}; };
/* /*
......
...@@ -311,6 +311,7 @@ static int afs_fill_super(struct super_block *sb, void *data) ...@@ -311,6 +311,7 @@ static int afs_fill_super(struct super_block *sb, void *data)
sb->s_magic = AFS_FS_MAGIC; sb->s_magic = AFS_FS_MAGIC;
sb->s_op = &afs_super_ops; sb->s_op = &afs_super_ops;
sb->s_fs_info = as; sb->s_fs_info = as;
sb->s_bdi = &as->volume->bdi;
/* allocate the root inode and dentry */ /* allocate the root inode and dentry */
fid.vid = as->volume->vid; fid.vid = as->volume->vid;
......
...@@ -106,6 +106,10 @@ struct afs_volume *afs_volume_lookup(struct afs_mount_params *params) ...@@ -106,6 +106,10 @@ struct afs_volume *afs_volume_lookup(struct afs_mount_params *params)
volume->cell = params->cell; volume->cell = params->cell;
volume->vid = vlocation->vldb.vid[params->type]; volume->vid = vlocation->vldb.vid[params->type];
ret = bdi_setup_and_register(&volume->bdi, "afs", BDI_CAP_MAP_COPY);
if (ret)
goto error_bdi;
init_rwsem(&volume->server_sem); init_rwsem(&volume->server_sem);
/* look up all the applicable server records */ /* look up all the applicable server records */
...@@ -151,6 +155,8 @@ struct afs_volume *afs_volume_lookup(struct afs_mount_params *params) ...@@ -151,6 +155,8 @@ struct afs_volume *afs_volume_lookup(struct afs_mount_params *params)
return ERR_PTR(ret); return ERR_PTR(ret);
error_discard: error_discard:
bdi_destroy(&volume->bdi);
error_bdi:
up_write(&params->cell->vl_sem); up_write(&params->cell->vl_sem);
for (loop = volume->nservers - 1; loop >= 0; loop--) for (loop = volume->nservers - 1; loop >= 0; loop--)
...@@ -200,6 +206,7 @@ void afs_put_volume(struct afs_volume *volume) ...@@ -200,6 +206,7 @@ void afs_put_volume(struct afs_volume *volume)
for (loop = volume->nservers - 1; loop >= 0; loop--) for (loop = volume->nservers - 1; loop >= 0; loop--)
afs_put_server(volume->servers[loop]); afs_put_server(volume->servers[loop]);
bdi_destroy(&volume->bdi);
kfree(volume); kfree(volume);
_leave(" [destroyed]"); _leave(" [destroyed]");
......
...@@ -44,8 +44,6 @@ static struct extent_io_ops btree_extent_io_ops; ...@@ -44,8 +44,6 @@ static struct extent_io_ops btree_extent_io_ops;
static void end_workqueue_fn(struct btrfs_work *work); static void end_workqueue_fn(struct btrfs_work *work);
static void free_fs_root(struct btrfs_root *root); static void free_fs_root(struct btrfs_root *root);
static atomic_t btrfs_bdi_num = ATOMIC_INIT(0);
/* /*
* end_io_wq structs are used to do processing in task context when an IO is * end_io_wq structs are used to do processing in task context when an IO is
* complete. This is used during reads to verify checksums, and it is used * 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,19 +1373,11 @@ static int setup_bdi(struct btrfs_fs_info *info, struct backing_dev_info *bdi)
{ {
int err; int err;
bdi->name = "btrfs";
bdi->capabilities = BDI_CAP_MAP_COPY; bdi->capabilities = BDI_CAP_MAP_COPY;
err = bdi_init(bdi); err = bdi_setup_and_register(bdi, "btrfs", BDI_CAP_MAP_COPY);
if (err) if (err)
return err; return err;
err = bdi_register(bdi, NULL, "btrfs-%d",
atomic_inc_return(&btrfs_bdi_num));
if (err) {
bdi_destroy(bdi);
return err;
}
bdi->ra_pages = default_backing_dev_info.ra_pages; bdi->ra_pages = default_backing_dev_info.ra_pages;
bdi->unplug_io_fn = btrfs_unplug_io_fn; bdi->unplug_io_fn = btrfs_unplug_io_fn;
bdi->unplug_io_data = info; bdi->unplug_io_data = info;
......
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
#ifndef _CIFS_FS_SB_H #ifndef _CIFS_FS_SB_H
#define _CIFS_FS_SB_H #define _CIFS_FS_SB_H
#include <linux/backing-dev.h>
#define CIFS_MOUNT_NO_PERM 1 /* do not do client vfs_perm check */ #define CIFS_MOUNT_NO_PERM 1 /* do not do client vfs_perm check */
#define CIFS_MOUNT_SET_UID 2 /* set current's euid in create etc. */ #define CIFS_MOUNT_SET_UID 2 /* set current's euid in create etc. */
#define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */ #define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */
...@@ -50,5 +52,6 @@ struct cifs_sb_info { ...@@ -50,5 +52,6 @@ struct cifs_sb_info {
#ifdef CONFIG_CIFS_DFS_UPCALL #ifdef CONFIG_CIFS_DFS_UPCALL
char *mountdata; /* mount options received at mount time */ char *mountdata; /* mount options received at mount time */
#endif #endif
struct backing_dev_info bdi;
}; };
#endif /* _CIFS_FS_SB_H */ #endif /* _CIFS_FS_SB_H */
...@@ -103,6 +103,12 @@ cifs_read_super(struct super_block *sb, void *data, ...@@ -103,6 +103,12 @@ cifs_read_super(struct super_block *sb, void *data,
if (cifs_sb == NULL) if (cifs_sb == NULL)
return -ENOMEM; return -ENOMEM;
rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY);
if (rc) {
kfree(cifs_sb);
return rc;
}
#ifdef CONFIG_CIFS_DFS_UPCALL #ifdef CONFIG_CIFS_DFS_UPCALL
/* copy mount params to sb for use in submounts */ /* copy mount params to sb for use in submounts */
/* BB: should we move this after the mount so we /* BB: should we move this after the mount so we
...@@ -115,6 +121,7 @@ cifs_read_super(struct super_block *sb, void *data, ...@@ -115,6 +121,7 @@ cifs_read_super(struct super_block *sb, void *data,
int len = strlen(data); int len = strlen(data);
cifs_sb->mountdata = kzalloc(len + 1, GFP_KERNEL); cifs_sb->mountdata = kzalloc(len + 1, GFP_KERNEL);
if (cifs_sb->mountdata == NULL) { if (cifs_sb->mountdata == NULL) {
bdi_destroy(&cifs_sb->bdi);
kfree(sb->s_fs_info); kfree(sb->s_fs_info);
sb->s_fs_info = NULL; sb->s_fs_info = NULL;
return -ENOMEM; return -ENOMEM;
...@@ -135,6 +142,7 @@ cifs_read_super(struct super_block *sb, void *data, ...@@ -135,6 +142,7 @@ cifs_read_super(struct super_block *sb, void *data,
sb->s_magic = CIFS_MAGIC_NUMBER; sb->s_magic = CIFS_MAGIC_NUMBER;
sb->s_op = &cifs_super_ops; sb->s_op = &cifs_super_ops;
sb->s_bdi = &cifs_sb->bdi;
/* if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512) /* if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512)
sb->s_blocksize = sb->s_blocksize =
cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */ cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */
...@@ -183,6 +191,7 @@ cifs_read_super(struct super_block *sb, void *data, ...@@ -183,6 +191,7 @@ cifs_read_super(struct super_block *sb, void *data,
} }
#endif #endif
unload_nls(cifs_sb->local_nls); unload_nls(cifs_sb->local_nls);
bdi_destroy(&cifs_sb->bdi);
kfree(cifs_sb); kfree(cifs_sb);
} }
return rc; return rc;
...@@ -214,6 +223,7 @@ cifs_put_super(struct super_block *sb) ...@@ -214,6 +223,7 @@ cifs_put_super(struct super_block *sb)
#endif #endif
unload_nls(cifs_sb->local_nls); unload_nls(cifs_sb->local_nls);
bdi_destroy(&cifs_sb->bdi);
kfree(cifs_sb); kfree(cifs_sb);
unlock_kernel(); unlock_kernel();
......
...@@ -167,6 +167,10 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent) ...@@ -167,6 +167,10 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
return -EBUSY; return -EBUSY;
} }
error = bdi_setup_and_register(&vc->bdi, "coda", BDI_CAP_MAP_COPY);
if (error)
goto bdi_err;
vc->vc_sb = sb; vc->vc_sb = sb;
sb->s_fs_info = vc; sb->s_fs_info = vc;
...@@ -175,6 +179,7 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent) ...@@ -175,6 +179,7 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
sb->s_blocksize_bits = 12; sb->s_blocksize_bits = 12;
sb->s_magic = CODA_SUPER_MAGIC; sb->s_magic = CODA_SUPER_MAGIC;
sb->s_op = &coda_super_operations; sb->s_op = &coda_super_operations;
sb->s_bdi = &vc->bdi;
/* get root fid from Venus: this needs the root inode */ /* get root fid from Venus: this needs the root inode */
error = venus_rootfid(sb, &fid); error = venus_rootfid(sb, &fid);
...@@ -200,6 +205,8 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent) ...@@ -200,6 +205,8 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
return 0; return 0;
error: error:
bdi_destroy(&vc->bdi);
bdi_err:
if (root) if (root)
iput(root); iput(root);
if (vc) if (vc)
...@@ -210,6 +217,7 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent) ...@@ -210,6 +217,7 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
static void coda_put_super(struct super_block *sb) static void coda_put_super(struct super_block *sb)
{ {
bdi_destroy(&coda_vcp(sb)->bdi);
coda_vcp(sb)->vc_sb = NULL; coda_vcp(sb)->vc_sb = NULL;
sb->s_fs_info = NULL; sb->s_fs_info = NULL;
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <linux/hash.h> #include <linux/hash.h>
#include <linux/nsproxy.h> #include <linux/nsproxy.h>
#include <linux/backing-dev.h>
/* Version verification for shared data structures w/ userspace */ /* Version verification for shared data structures w/ userspace */
#define ECRYPTFS_VERSION_MAJOR 0x00 #define ECRYPTFS_VERSION_MAJOR 0x00
...@@ -393,6 +394,7 @@ struct ecryptfs_mount_crypt_stat { ...@@ -393,6 +394,7 @@ struct ecryptfs_mount_crypt_stat {
struct ecryptfs_sb_info { struct ecryptfs_sb_info {
struct super_block *wsi_sb; struct super_block *wsi_sb;
struct ecryptfs_mount_crypt_stat mount_crypt_stat; struct ecryptfs_mount_crypt_stat mount_crypt_stat;
struct backing_dev_info bdi;
}; };
/* file private data. */ /* file private data. */
......
...@@ -497,17 +497,25 @@ struct kmem_cache *ecryptfs_sb_info_cache; ...@@ -497,17 +497,25 @@ struct kmem_cache *ecryptfs_sb_info_cache;
static int static int
ecryptfs_fill_super(struct super_block *sb, void *raw_data, int silent) ecryptfs_fill_super(struct super_block *sb, void *raw_data, int silent)
{ {
struct ecryptfs_sb_info *esi;
int rc = 0; int rc = 0;
/* Released in ecryptfs_put_super() */ /* Released in ecryptfs_put_super() */
ecryptfs_set_superblock_private(sb, ecryptfs_set_superblock_private(sb,
kmem_cache_zalloc(ecryptfs_sb_info_cache, kmem_cache_zalloc(ecryptfs_sb_info_cache,
GFP_KERNEL)); GFP_KERNEL));
if (!ecryptfs_superblock_to_private(sb)) { esi = ecryptfs_superblock_to_private(sb);
if (!esi) {
ecryptfs_printk(KERN_WARNING, "Out of memory\n"); ecryptfs_printk(KERN_WARNING, "Out of memory\n");
rc = -ENOMEM; rc = -ENOMEM;
goto out; goto out;
} }
rc = bdi_setup_and_register(&esi->bdi, "ecryptfs", BDI_CAP_MAP_COPY);
if (rc)
goto out;
sb->s_bdi = &esi->bdi;
sb->s_op = &ecryptfs_sops; sb->s_op = &ecryptfs_sops;
/* Released through deactivate_super(sb) from get_sb_nodev */ /* Released through deactivate_super(sb) from get_sb_nodev */
sb->s_root = d_alloc(NULL, &(const struct qstr) { sb->s_root = d_alloc(NULL, &(const struct qstr) {
......
...@@ -122,6 +122,7 @@ static void ecryptfs_put_super(struct super_block *sb) ...@@ -122,6 +122,7 @@ static void ecryptfs_put_super(struct super_block *sb)
lock_kernel(); lock_kernel();
ecryptfs_destroy_mount_crypt_stat(&sb_info->mount_crypt_stat); ecryptfs_destroy_mount_crypt_stat(&sb_info->mount_crypt_stat);
bdi_destroy(&sb_info->bdi);
kmem_cache_free(ecryptfs_sb_info_cache, sb_info); kmem_cache_free(ecryptfs_sb_info_cache, sb_info);
ecryptfs_set_superblock_private(sb, NULL); ecryptfs_set_superblock_private(sb, NULL);
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/time.h> #include <linux/time.h>
#include <linux/backing-dev.h>
#include "common.h" #include "common.h"
/* FIXME: Remove once pnfs hits mainline /* FIXME: Remove once pnfs hits mainline
...@@ -92,6 +93,7 @@ struct exofs_sb_info { ...@@ -92,6 +93,7 @@ struct exofs_sb_info {
struct exofs_layout layout; /* Default files layout, struct exofs_layout layout; /* Default files layout,
* contains the variable osd_dev * contains the variable osd_dev
* array. Keep last */ * array. Keep last */
struct backing_dev_info bdi;
struct osd_dev *_min_one_dev[1]; /* Place holder for one dev */ struct osd_dev *_min_one_dev[1]; /* Place holder for one dev */
}; };
......
...@@ -302,6 +302,7 @@ static void exofs_put_super(struct super_block *sb) ...@@ -302,6 +302,7 @@ static void exofs_put_super(struct super_block *sb)
_exofs_print_device("Unmounting", NULL, sbi->layout.s_ods[0], _exofs_print_device("Unmounting", NULL, sbi->layout.s_ods[0],
sbi->layout.s_pid); sbi->layout.s_pid);
bdi_destroy(&sbi->bdi);
exofs_free_sbi(sbi); exofs_free_sbi(sbi);
sb->s_fs_info = NULL; sb->s_fs_info = NULL;
} }
...@@ -546,6 +547,10 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -546,6 +547,10 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
if (!sbi) if (!sbi)
return -ENOMEM; return -ENOMEM;
ret = bdi_setup_and_register(&sbi->bdi, "exofs", BDI_CAP_MAP_COPY);
if (ret)
goto free_bdi;
/* use mount options to fill superblock */ /* use mount options to fill superblock */
od = osduld_path_lookup(opts->dev_name); od = osduld_path_lookup(opts->dev_name);
if (IS_ERR(od)) { if (IS_ERR(od)) {
...@@ -612,6 +617,7 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -612,6 +617,7 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
} }
/* set up operation vectors */ /* set up operation vectors */
sb->s_bdi = &sbi->bdi;
sb->s_fs_info = sbi; sb->s_fs_info = sbi;
sb->s_op = &exofs_sops; sb->s_op = &exofs_sops;
sb->s_export_op = &exofs_export_ops; 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,6 +649,8 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent)
return 0; return 0;
free_sbi: free_sbi:
bdi_destroy(&sbi->bdi);
free_bdi:
EXOFS_ERR("Unable to mount exofs on %s pid=0x%llx err=%d\n", EXOFS_ERR("Unable to mount exofs on %s pid=0x%llx err=%d\n",
opts->dev_name, sbi->layout.s_pid, ret); opts->dev_name, sbi->layout.s_pid, ret);
exofs_free_sbi(sbi); exofs_free_sbi(sbi);
......
...@@ -526,10 +526,15 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) ...@@ -526,10 +526,15 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
sb->s_blocksize_bits = 10; sb->s_blocksize_bits = 10;
sb->s_magic = NCP_SUPER_MAGIC; sb->s_magic = NCP_SUPER_MAGIC;
sb->s_op = &ncp_sops; sb->s_op = &ncp_sops;
sb->s_bdi = &server->bdi;
server = NCP_SBP(sb); server = NCP_SBP(sb);
memset(server, 0, sizeof(*server)); memset(server, 0, sizeof(*server));
error = bdi_setup_and_register(&server->bdi, "ncpfs", BDI_CAP_MAP_COPY);
if (error)
goto out_bdi;
server->ncp_filp = ncp_filp; server->ncp_filp = ncp_filp;
server->ncp_sock = sock; server->ncp_sock = sock;
...@@ -719,6 +724,8 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) ...@@ -719,6 +724,8 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
if (server->info_filp) if (server->info_filp)
fput(server->info_filp); fput(server->info_filp);
out_fput: out_fput:
bdi_destroy(&server->bdi);
out_bdi:
/* 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>: /* 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>:
* *
* The previously used put_filp(ncp_filp); was bogous, since * The previously used put_filp(ncp_filp); was bogous, since
...@@ -756,6 +763,7 @@ static void ncp_put_super(struct super_block *sb) ...@@ -756,6 +763,7 @@ static void ncp_put_super(struct super_block *sb)
kill_pid(server->m.wdog_pid, SIGTERM, 1); kill_pid(server->m.wdog_pid, SIGTERM, 1);
put_pid(server->m.wdog_pid); put_pid(server->m.wdog_pid);
bdi_destroy(&server->bdi);
kfree(server->priv.data); kfree(server->priv.data);
kfree(server->auth.object_name); kfree(server->auth.object_name);
vfree(server->rxbuf); vfree(server->rxbuf);
......
...@@ -479,6 +479,7 @@ smb_put_super(struct super_block *sb) ...@@ -479,6 +479,7 @@ smb_put_super(struct super_block *sb)
if (server->conn_pid) if (server->conn_pid)
kill_pid(server->conn_pid, SIGTERM, 1); kill_pid(server->conn_pid, SIGTERM, 1);
bdi_destroy(&server->bdi);
kfree(server->ops); kfree(server->ops);
smb_unload_nls(server); smb_unload_nls(server);
sb->s_fs_info = NULL; sb->s_fs_info = NULL;
...@@ -526,6 +527,11 @@ static int smb_fill_super(struct super_block *sb, void *raw_data, int silent) ...@@ -526,6 +527,11 @@ static int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
goto out_no_server; goto out_no_server;
sb->s_fs_info = server; sb->s_fs_info = server;
if (bdi_setup_and_register(&server->bdi, "smbfs", BDI_CAP_MAP_COPY))
goto out_bdi;
sb->s_bdi = &server->bdi;
server->super_block = sb; server->super_block = sb;
server->mnt = NULL; server->mnt = NULL;
server->sock_file = NULL; server->sock_file = NULL;
...@@ -624,6 +630,8 @@ static int smb_fill_super(struct super_block *sb, void *raw_data, int silent) ...@@ -624,6 +630,8 @@ static int smb_fill_super(struct super_block *sb, void *raw_data, int silent)
out_bad_option: out_bad_option:
kfree(mem); kfree(mem);
out_no_mem: out_no_mem:
bdi_destroy(&server->bdi);
out_bdi:
if (!server->mnt) if (!server->mnt)
printk(KERN_ERR "smb_fill_super: allocation failure\n"); printk(KERN_ERR "smb_fill_super: allocation failure\n");
sb->s_fs_info = NULL; sb->s_fs_info = NULL;
......
...@@ -693,6 +693,7 @@ int set_anon_super(struct super_block *s, void *data) ...@@ -693,6 +693,7 @@ int set_anon_super(struct super_block *s, void *data)
return -EMFILE; return -EMFILE;
} }
s->s_dev = MKDEV(0, dev & MINORMASK); s->s_dev = MKDEV(0, dev & MINORMASK);
s->s_bdi = &noop_backing_dev_info;
return 0; return 0;
} }
...@@ -954,6 +955,7 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void ...@@ -954,6 +955,7 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
if (error < 0) if (error < 0)
goto out_free_secdata; goto out_free_secdata;
BUG_ON(!mnt->mnt_sb); BUG_ON(!mnt->mnt_sb);
WARN_ON(!mnt->mnt_sb->s_bdi);
error = security_sb_kern_mount(mnt->mnt_sb, flags, secdata); error = security_sb_kern_mount(mnt->mnt_sb, flags, secdata);
if (error) if (error)
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/quotaops.h> #include <linux/quotaops.h>
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#include <linux/backing-dev.h>
#include "internal.h" #include "internal.h"
#define VALID_FLAGS (SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE| \ #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,7 +33,7 @@ static int __sync_filesystem(struct super_block *sb, int wait)
* This should be safe, as we require bdi backing to actually * This should be safe, as we require bdi backing to actually
* write out data in the first place * write out data in the first place
*/ */
if (!sb->s_bdi) if (!sb->s_bdi || sb->s_bdi == &noop_backing_dev_info)
return 0; return 0;
if (sb->s_qcop && sb->s_qcop->quota_sync) if (sb->s_qcop && sb->s_qcop->quota_sync)
......
...@@ -101,6 +101,7 @@ int bdi_register(struct backing_dev_info *bdi, struct device *parent, ...@@ -101,6 +101,7 @@ int bdi_register(struct backing_dev_info *bdi, struct device *parent,
const char *fmt, ...); const char *fmt, ...);
int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev); int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev);
void bdi_unregister(struct backing_dev_info *bdi); void bdi_unregister(struct backing_dev_info *bdi);
int bdi_setup_and_register(struct backing_dev_info *, char *, unsigned int);
void bdi_start_writeback(struct backing_dev_info *bdi, struct super_block *sb, void bdi_start_writeback(struct backing_dev_info *bdi, struct super_block *sb,
long nr_pages); long nr_pages);
int bdi_writeback_task(struct bdi_writeback *wb); 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,6 +247,7 @@ int bdi_set_max_ratio(struct backing_dev_info *bdi, unsigned int max_ratio);
#endif #endif
extern struct backing_dev_info default_backing_dev_info; extern struct backing_dev_info default_backing_dev_info;
extern struct backing_dev_info noop_backing_dev_info;
void default_unplug_io_fn(struct backing_dev_info *bdi, struct page *page); void default_unplug_io_fn(struct backing_dev_info *bdi, struct page *page);
int writeback_in_progress(struct backing_dev_info *bdi); int writeback_in_progress(struct backing_dev_info *bdi);
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
#define MAX_CODADEVS 5 /* how many do we allow */ #define MAX_CODADEVS 5 /* how many do we allow */
#ifdef __KERNEL__ #ifdef __KERNEL__
#include <linux/backing-dev.h>
struct kstatfs; struct kstatfs;
/* communication pending/processing queues */ /* communication pending/processing queues */
...@@ -17,6 +19,7 @@ struct venus_comm { ...@@ -17,6 +19,7 @@ struct venus_comm {
struct list_head vc_processing; struct list_head vc_processing;
int vc_inuse; int vc_inuse;
struct super_block *vc_sb; struct super_block *vc_sb;
struct backing_dev_info bdi;
}; };
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/ncp_mount.h> #include <linux/ncp_mount.h>
#include <linux/net.h> #include <linux/net.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/backing-dev.h>
#ifdef __KERNEL__ #ifdef __KERNEL__
...@@ -127,6 +128,7 @@ struct ncp_server { ...@@ -127,6 +128,7 @@ struct ncp_server {
size_t len; size_t len;
__u8 data[128]; __u8 data[128];
} unexpected_packet; } unexpected_packet;
struct backing_dev_info bdi;
}; };
extern void ncp_tcp_rcv_proc(struct work_struct *work); extern void ncp_tcp_rcv_proc(struct work_struct *work);
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#define _SMB_FS_SB #define _SMB_FS_SB
#include <linux/types.h> #include <linux/types.h>
#include <linux/backing-dev.h>
#include <linux/smb.h> #include <linux/smb.h>
/* /*
...@@ -74,6 +75,8 @@ struct smb_sb_info { ...@@ -74,6 +75,8 @@ struct smb_sb_info {
struct smb_ops *ops; struct smb_ops *ops;
struct super_block *super_block; struct super_block *super_block;
struct backing_dev_info bdi;
}; };
static inline int static inline int
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
#include <linux/writeback.h> #include <linux/writeback.h>
#include <linux/device.h> #include <linux/device.h>
static atomic_long_t bdi_seq = ATOMIC_LONG_INIT(0);
void default_unplug_io_fn(struct backing_dev_info *bdi, struct page *page) void default_unplug_io_fn(struct backing_dev_info *bdi, struct page *page)
{ {
} }
...@@ -25,6 +27,11 @@ struct backing_dev_info default_backing_dev_info = { ...@@ -25,6 +27,11 @@ struct backing_dev_info default_backing_dev_info = {
}; };
EXPORT_SYMBOL_GPL(default_backing_dev_info); EXPORT_SYMBOL_GPL(default_backing_dev_info);
struct backing_dev_info noop_backing_dev_info = {
.name = "noop",
};
EXPORT_SYMBOL_GPL(noop_backing_dev_info);
static struct class *bdi_class; static struct class *bdi_class;
/* /*
...@@ -715,6 +722,33 @@ void bdi_destroy(struct backing_dev_info *bdi) ...@@ -715,6 +722,33 @@ void bdi_destroy(struct backing_dev_info *bdi)
} }
EXPORT_SYMBOL(bdi_destroy); EXPORT_SYMBOL(bdi_destroy);
/*
* For use from filesystems to quickly init and register a bdi associated
* with dirty writeback
*/
int bdi_setup_and_register(struct backing_dev_info *bdi, char *name,
unsigned int cap)
{
char tmp[32];
int err;
bdi->name = name;
bdi->capabilities = cap;
err = bdi_init(bdi);
if (err)
return err;
sprintf(tmp, "%.28s%s", name, "-%d");
err = bdi_register(bdi, NULL, tmp, atomic_long_inc_return(&bdi_seq));
if (err) {
bdi_destroy(bdi);
return err;
}
return 0;
}
EXPORT_SYMBOL(bdi_setup_and_register);
static wait_queue_head_t congestion_wqh[2] = { static wait_queue_head_t congestion_wqh[2] = {
__WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[0]), __WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[0]),
__WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[1]) __WAIT_QUEUE_HEAD_INITIALIZER(congestion_wqh[1])
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment