summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@sgi.com>2004-04-29 10:45:34 +1000
committerNathan Scott <nathans@sgi.com>2004-04-29 10:45:34 +1000
commitf2ef8e82a31c5af3ec7f698fdc08d57da7cc70ac (patch)
tree9714189642907c99ddda97b1286ef92b28dc2e76 /fs
parentb606f6bf62cb9cec6328f9d9e6d24efc05b79f84 (diff)
[XFS] close external blockdevice after final flush
SGI Modid: xfs-linux:xfs-kern:170489a
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/linux/xfs_buf.c74
-rw-r--r--fs/xfs/linux/xfs_buf.h37
-rw-r--r--fs/xfs/linux/xfs_linux.h1
-rw-r--r--fs/xfs/linux/xfs_super.c70
-rw-r--r--fs/xfs/linux/xfs_super.h8
-rw-r--r--fs/xfs/xfs_mount.c21
-rw-r--r--fs/xfs/xfs_vfsops.c9
7 files changed, 99 insertions, 121 deletions
diff --git a/fs/xfs/linux/xfs_buf.c b/fs/xfs/linux/xfs_buf.c
index ce514381e53b..69050a0de927 100644
--- a/fs/xfs/linux/xfs_buf.c
+++ b/fs/xfs/linux/xfs_buf.c
@@ -47,7 +47,6 @@
#include <linux/pagemap.h>
#include <linux/init.h>
#include <linux/vmalloc.h>
-#include <linux/blkdev.h>
#include <linux/bio.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
@@ -1472,6 +1471,64 @@ pagebuf_iomove(
}
}
+/*
+ * Handling of buftargs.
+ */
+
+void
+xfs_free_buftarg(
+ xfs_buftarg_t *btp,
+ int external)
+{
+ xfs_flush_buftarg(btp, 1);
+ if (external)
+ xfs_blkdev_put(btp->pbr_bdev);
+ kmem_free(btp, sizeof(*btp));
+}
+
+void
+xfs_incore_relse(
+ xfs_buftarg_t *btp,
+ int delwri_only,
+ int wait)
+{
+ invalidate_bdev(btp->pbr_bdev, 1);
+ truncate_inode_pages(btp->pbr_mapping, 0LL);
+}
+
+void
+xfs_setsize_buftarg(
+ xfs_buftarg_t *btp,
+ unsigned int blocksize,
+ unsigned int sectorsize)
+{
+ btp->pbr_bsize = blocksize;
+ btp->pbr_sshift = ffs(sectorsize) - 1;
+ btp->pbr_smask = sectorsize - 1;
+
+ if (set_blocksize(btp->pbr_bdev, sectorsize)) {
+ printk(KERN_WARNING
+ "XFS: Cannot set_blocksize to %u on device %s\n",
+ sectorsize, XFS_BUFTARG_NAME(btp));
+ }
+}
+
+xfs_buftarg_t *
+xfs_alloc_buftarg(
+ struct block_device *bdev)
+{
+ xfs_buftarg_t *btp;
+
+ btp = kmem_zalloc(sizeof(*btp), KM_SLEEP);
+
+ btp->pbr_dev = bdev->bd_dev;
+ btp->pbr_bdev = bdev;
+ btp->pbr_mapping = bdev->bd_inode->i_mapping;
+ xfs_setsize_buftarg(btp, PAGE_CACHE_SIZE, bdev_hardsect_size(bdev));
+
+ return btp;
+}
+
/*
* Pagebuf delayed write buffer handling
@@ -1598,11 +1655,15 @@ pagebuf_daemon(
complete_and_exit(&pagebuf_daemon_done, 0);
}
-void
-pagebuf_delwri_flush(
+/*
+ * Go through all incore buffers, and release buffers if they belong to
+ * the given device. This is used in filesystem error handling to
+ * preserve the consistency of its metadata.
+ */
+int
+xfs_flush_buftarg(
xfs_buftarg_t *target,
- int wait,
- int *pinptr)
+ int wait)
{
struct list_head tmp;
xfs_buf_t *pb, *n;
@@ -1658,8 +1719,7 @@ pagebuf_delwri_flush(
if (wait)
blk_run_address_space(target->pbr_mapping);
- if (pinptr)
- *pinptr = pincount;
+ return pincount;
}
STATIC int
diff --git a/fs/xfs/linux/xfs_buf.h b/fs/xfs/linux/xfs_buf.h
index 16becc722551..f97e6c0cd597 100644
--- a/fs/xfs/linux/xfs_buf.h
+++ b/fs/xfs/linux/xfs_buf.h
@@ -296,7 +296,6 @@ extern int pagebuf_ispin( /* check if buffer is pinned */
/* Delayed Write Buffer Routines */
-extern void pagebuf_delwri_flush(xfs_buftarg_t *, int, int *);
extern void pagebuf_delwri_dequeue(xfs_buf_t *);
/* Buffer Daemon Setup Routines */
@@ -565,21 +564,6 @@ static inline int xfs_bdwrite(void *mp, xfs_buf_t *bp)
#define xfs_iowait(pb) pagebuf_iowait(pb)
-
-/*
- * Go through all incore buffers, and release buffers
- * if they belong to the given device. This is used in
- * filesystem error handling to preserve the consistency
- * of its metadata.
- */
-
-#define xfs_binval(buftarg) xfs_flush_buftarg(buftarg)
-
-#define XFS_bflush(buftarg) xfs_flush_buftarg(buftarg)
-
-#define xfs_incore_relse(buftarg,delwri_only,wait) \
- xfs_relse_buftarg(buftarg)
-
#define xfs_baread(target, rablkno, ralen) \
pagebuf_readahead((target), (rablkno), (ralen), PBF_DONT_BLOCK)
@@ -587,5 +571,24 @@ static inline int xfs_bdwrite(void *mp, xfs_buf_t *bp)
#define xfs_buf_get_noaddr(len, target) pagebuf_get_no_daddr((len), (target))
#define xfs_buf_free(bp) pagebuf_free(bp)
-#endif /* __XFS_BUF_H__ */
+/*
+ * Handling of buftargs.
+ */
+
+extern xfs_buftarg_t *xfs_alloc_buftarg(struct block_device *);
+extern void xfs_free_buftarg(xfs_buftarg_t *, int);
+extern void xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int);
+extern void xfs_incore_relse(xfs_buftarg_t *, int, int);
+extern int xfs_flush_buftarg(xfs_buftarg_t *, int);
+
+#define xfs_getsize_buftarg(buftarg) \
+ block_size((buftarg)->pbr_bdev)
+#define xfs_readonly_buftarg(buftarg) \
+ bdev_read_only((buftarg)->pbr_bdev)
+#define xfs_binval(buftarg) \
+ xfs_flush_buftarg(buftarg, 1)
+#define XFS_bflush(buftarg) \
+ xfs_flush_buftarg(buftarg, 1)
+
+#endif /* __XFS_BUF_H__ */
diff --git a/fs/xfs/linux/xfs_linux.h b/fs/xfs/linux/xfs_linux.h
index bfd0604ea7a6..70481f85f047 100644
--- a/fs/xfs/linux/xfs_linux.h
+++ b/fs/xfs/linux/xfs_linux.h
@@ -72,6 +72,7 @@
#include <linux/mm.h>
#include <linux/kernel.h>
+#include <linux/blkdev.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/file.h>
diff --git a/fs/xfs/linux/xfs_super.c b/fs/xfs/linux/xfs_super.c
index 7bca10400c51..5878bf65b318 100644
--- a/fs/xfs/linux/xfs_super.c
+++ b/fs/xfs/linux/xfs_super.c
@@ -67,7 +67,6 @@
#include "xfs_utils.h"
#include "xfs_version.h"
-#include <linux/blkdev.h>
#include <linux/namei.h>
#include <linux/init.h>
#include <linux/mount.h>
@@ -282,75 +281,6 @@ xfs_blkdev_put(
close_bdev_excl(bdev);
}
-void
-xfs_flush_buftarg(
- xfs_buftarg_t *btp)
-{
- pagebuf_delwri_flush(btp, 1, NULL);
-}
-
-void
-xfs_free_buftarg(
- xfs_buftarg_t *btp)
-{
- xfs_flush_buftarg(btp);
- kmem_free(btp, sizeof(*btp));
-}
-
-int
-xfs_readonly_buftarg(
- xfs_buftarg_t *btp)
-{
- return bdev_read_only(btp->pbr_bdev);
-}
-
-void
-xfs_relse_buftarg(
- xfs_buftarg_t *btp)
-{
- invalidate_bdev(btp->pbr_bdev, 1);
- truncate_inode_pages(btp->pbr_mapping, 0LL);
-}
-
-unsigned int
-xfs_getsize_buftarg(
- xfs_buftarg_t *btp)
-{
- return block_size(btp->pbr_bdev);
-}
-
-void
-xfs_setsize_buftarg(
- xfs_buftarg_t *btp,
- unsigned int blocksize,
- unsigned int sectorsize)
-{
- btp->pbr_bsize = blocksize;
- btp->pbr_sshift = ffs(sectorsize) - 1;
- btp->pbr_smask = sectorsize - 1;
-
- if (set_blocksize(btp->pbr_bdev, sectorsize)) {
- printk(KERN_WARNING
- "XFS: Cannot set_blocksize to %u on device %s\n",
- sectorsize, XFS_BUFTARG_NAME(btp));
- }
-}
-
-xfs_buftarg_t *
-xfs_alloc_buftarg(
- struct block_device *bdev)
-{
- xfs_buftarg_t *btp;
-
- btp = kmem_zalloc(sizeof(*btp), KM_SLEEP);
-
- btp->pbr_dev = bdev->bd_dev;
- btp->pbr_bdev = bdev;
- btp->pbr_mapping = bdev->bd_inode->i_mapping;
- xfs_setsize_buftarg(btp, PAGE_CACHE_SIZE, bdev_hardsect_size(bdev));
-
- return btp;
-}
STATIC struct inode *
linvfs_alloc_inode(
diff --git a/fs/xfs/linux/xfs_super.h b/fs/xfs/linux/xfs_super.h
index 15b238889b68..55762691909d 100644
--- a/fs/xfs/linux/xfs_super.h
+++ b/fs/xfs/linux/xfs_super.h
@@ -126,12 +126,4 @@ extern int xfs_blkdev_get(struct xfs_mount *, const char *,
struct block_device **);
extern void xfs_blkdev_put(struct block_device *);
-extern struct xfs_buftarg *xfs_alloc_buftarg(struct block_device *);
-extern void xfs_relse_buftarg(struct xfs_buftarg *);
-extern void xfs_free_buftarg(struct xfs_buftarg *);
-extern void xfs_flush_buftarg(struct xfs_buftarg *);
-extern int xfs_readonly_buftarg(struct xfs_buftarg *);
-extern void xfs_setsize_buftarg(struct xfs_buftarg *, unsigned int, unsigned int);
-extern unsigned int xfs_getsize_buftarg(struct xfs_buftarg *);
-
#endif /* __XFS_SUPER_H__ */
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 56d104d21e63..927936e6d023 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -1126,22 +1126,11 @@ xfs_unmountfs(xfs_mount_t *mp, struct cred *cr)
void
xfs_unmountfs_close(xfs_mount_t *mp, struct cred *cr)
{
- int have_logdev = (mp->m_logdev_targp != mp->m_ddev_targp);
-
- if (mp->m_ddev_targp) {
- xfs_free_buftarg(mp->m_ddev_targp);
- mp->m_ddev_targp = NULL;
- }
- if (mp->m_rtdev_targp) {
- xfs_blkdev_put(mp->m_rtdev_targp->pbr_bdev);
- xfs_free_buftarg(mp->m_rtdev_targp);
- mp->m_rtdev_targp = NULL;
- }
- if (mp->m_logdev_targp && have_logdev) {
- xfs_blkdev_put(mp->m_logdev_targp->pbr_bdev);
- xfs_free_buftarg(mp->m_logdev_targp);
- mp->m_logdev_targp = NULL;
- }
+ if (mp->m_logdev_targp != mp->m_ddev_targp)
+ xfs_free_buftarg(mp->m_logdev_targp, 1);
+ if (mp->m_rtdev_targp)
+ xfs_free_buftarg(mp->m_rtdev_targp, 1);
+ xfs_free_buftarg(mp->m_ddev_targp, 0);
}
int
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index 5ebaa2fd92f2..aa16d90e2521 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -625,7 +625,7 @@ xfs_mntupdate(
if (*flags & MS_RDONLY) {
xfs_refcache_purge_mp(mp);
- pagebuf_delwri_flush(mp->m_ddev_targp, 0, NULL);
+ xfs_flush_buftarg(mp->m_ddev_targp, 0);
xfs_finish_reclaim_all(mp, 0);
/* This loop must run at least twice.
@@ -637,8 +637,11 @@ xfs_mntupdate(
*/
do {
VFS_SYNC(vfsp, REMOUNT_READONLY_FLAGS, NULL, error);
- pagebuf_delwri_flush(mp->m_ddev_targp, 1, &pincount);
- if(0 == pincount) { delay(50); count++; }
+ pincount = xfs_flush_buftarg(mp->m_ddev_targp, 1);
+ if (!pincount) {
+ delay(50);
+ count++;
+ }
} while (count < 2);
/* Ok now write out an unmount record */