Commit f2ef8e82 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Nathan Scott

[XFS] close external blockdevice after final flush

SGI Modid: xfs-linux:xfs-kern:170489a
parent b606f6bf
......@@ -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
......
......@@ -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__ */
......@@ -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>
......
......@@ -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(
......
......@@ -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__ */
......@@ -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
......
......@@ -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 */
......
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