Commit 3105b9b6 authored by Nathan Scott's avatar Nathan Scott Committed by Nathan Scott

[XFS] Revert to using a separate inode for metadata buffers once more.

SGI Modid: xfs-linux:xfs-kern:174253a
Signed-off-by: default avatarNathan Scott <nathans@sgi.com>
parent 3ce0de02
...@@ -1484,6 +1484,7 @@ xfs_free_buftarg( ...@@ -1484,6 +1484,7 @@ xfs_free_buftarg(
xfs_flush_buftarg(btp, 1); xfs_flush_buftarg(btp, 1);
if (external) if (external)
xfs_blkdev_put(btp->pbr_bdev); xfs_blkdev_put(btp->pbr_bdev);
iput(btp->pbr_mapping->host);
kmem_free(btp, sizeof(*btp)); kmem_free(btp, sizeof(*btp));
} }
...@@ -1497,7 +1498,7 @@ xfs_incore_relse( ...@@ -1497,7 +1498,7 @@ xfs_incore_relse(
truncate_inode_pages(btp->pbr_mapping, 0LL); truncate_inode_pages(btp->pbr_mapping, 0LL);
} }
void int
xfs_setsize_buftarg( xfs_setsize_buftarg(
xfs_buftarg_t *btp, xfs_buftarg_t *btp,
unsigned int blocksize, unsigned int blocksize,
...@@ -1511,7 +1512,38 @@ xfs_setsize_buftarg( ...@@ -1511,7 +1512,38 @@ xfs_setsize_buftarg(
printk(KERN_WARNING printk(KERN_WARNING
"XFS: Cannot set_blocksize to %u on device %s\n", "XFS: Cannot set_blocksize to %u on device %s\n",
sectorsize, XFS_BUFTARG_NAME(btp)); sectorsize, XFS_BUFTARG_NAME(btp));
return EINVAL;
} }
return 0;
}
STATIC int
xfs_mapping_buftarg(
xfs_buftarg_t *btp,
struct block_device *bdev)
{
struct inode *inode;
struct address_space *mapping;
struct backing_dev_info *bdi;
inode = new_inode(bdev->bd_inode->i_sb);
if (!inode) {
printk(KERN_WARNING
"XFS: Cannot allocate mapping inode for device %s\n",
XFS_BUFTARG_NAME(btp));
return ENOMEM;
}
inode->i_mode = S_IFBLK;
inode->i_bdev = bdev;
inode->i_rdev = bdev->bd_dev;
mapping = &inode->i_data;
bdi = blk_get_backing_dev_info(bdev);
if (!bdi)
bdi = &default_backing_dev_info;
mapping->backing_dev_info = bdi;
mapping_set_gfp_mask(mapping, GFP_KERNEL);
btp->pbr_mapping = mapping;
return 0;
} }
xfs_buftarg_t * xfs_buftarg_t *
...@@ -1524,10 +1556,15 @@ xfs_alloc_buftarg( ...@@ -1524,10 +1556,15 @@ xfs_alloc_buftarg(
btp->pbr_dev = bdev->bd_dev; btp->pbr_dev = bdev->bd_dev;
btp->pbr_bdev = bdev; btp->pbr_bdev = bdev;
btp->pbr_mapping = bdev->bd_inode->i_mapping; if (xfs_setsize_buftarg(btp, PAGE_CACHE_SIZE, bdev_hardsect_size(bdev)))
xfs_setsize_buftarg(btp, PAGE_CACHE_SIZE, bdev_hardsect_size(bdev)); goto error;
if (xfs_mapping_buftarg(btp, bdev))
goto error;
return btp; return btp;
error:
kmem_free(btp, sizeof(*btp));
return NULL;
} }
......
...@@ -566,7 +566,7 @@ static inline int xfs_bdwrite(void *mp, xfs_buf_t *bp) ...@@ -566,7 +566,7 @@ static inline int xfs_bdwrite(void *mp, xfs_buf_t *bp)
extern xfs_buftarg_t *xfs_alloc_buftarg(struct block_device *); extern xfs_buftarg_t *xfs_alloc_buftarg(struct block_device *);
extern void xfs_free_buftarg(xfs_buftarg_t *, int); extern void xfs_free_buftarg(xfs_buftarg_t *, int);
extern void xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int); extern int xfs_setsize_buftarg(xfs_buftarg_t *, unsigned int, unsigned int);
extern void xfs_incore_relse(xfs_buftarg_t *, int, int); extern void xfs_incore_relse(xfs_buftarg_t *, int, int);
extern int xfs_flush_buftarg(xfs_buftarg_t *, int); extern int xfs_flush_buftarg(xfs_buftarg_t *, int);
......
...@@ -430,6 +430,16 @@ xfs_mount( ...@@ -430,6 +430,16 @@ xfs_mount(
ddev = vfsp->vfs_super->s_bdev; ddev = vfsp->vfs_super->s_bdev;
logdev = rtdev = NULL; logdev = rtdev = NULL;
/*
* Setup xfs_mount function vectors from available behaviors
*/
p = vfs_bhv_lookup(vfsp, VFS_POSITION_DM);
mp->m_dm_ops = p ? *(xfs_dmops_t *) vfs_bhv_custom(p) : xfs_dmcore_stub;
p = vfs_bhv_lookup(vfsp, VFS_POSITION_QM);
mp->m_qm_ops = p ? *(xfs_qmops_t *) vfs_bhv_custom(p) : xfs_qmcore_stub;
p = vfs_bhv_lookup(vfsp, VFS_POSITION_IO);
mp->m_io_ops = p ? *(xfs_ioops_t *) vfs_bhv_custom(p) : xfs_iocore_xfs;
/* /*
* Open real time and log devices - order is important. * Open real time and log devices - order is important.
*/ */
...@@ -454,69 +464,74 @@ xfs_mount( ...@@ -454,69 +464,74 @@ xfs_mount(
} }
} }
/*
* Setup xfs_mount function vectors from available behaviors
*/
p = vfs_bhv_lookup(vfsp, VFS_POSITION_DM);
mp->m_dm_ops = p ? *(xfs_dmops_t *) vfs_bhv_custom(p) : xfs_dmcore_stub;
p = vfs_bhv_lookup(vfsp, VFS_POSITION_QM);
mp->m_qm_ops = p ? *(xfs_qmops_t *) vfs_bhv_custom(p) : xfs_qmcore_stub;
p = vfs_bhv_lookup(vfsp, VFS_POSITION_IO);
mp->m_io_ops = p ? *(xfs_ioops_t *) vfs_bhv_custom(p) : xfs_iocore_xfs;
/* /*
* Setup xfs_mount buffer target pointers * Setup xfs_mount buffer target pointers
*/ */
error = ENOMEM;
mp->m_ddev_targp = xfs_alloc_buftarg(ddev); mp->m_ddev_targp = xfs_alloc_buftarg(ddev);
if (rtdev) if (!mp->m_ddev_targp) {
xfs_blkdev_put(logdev);
xfs_blkdev_put(rtdev);
return error;
}
if (rtdev) {
mp->m_rtdev_targp = xfs_alloc_buftarg(rtdev); mp->m_rtdev_targp = xfs_alloc_buftarg(rtdev);
if (!mp->m_rtdev_targp)
goto error0;
}
mp->m_logdev_targp = (logdev && logdev != ddev) ? mp->m_logdev_targp = (logdev && logdev != ddev) ?
xfs_alloc_buftarg(logdev) : mp->m_ddev_targp; xfs_alloc_buftarg(logdev) : mp->m_ddev_targp;
if (!mp->m_logdev_targp)
goto error0;
/* /*
* Setup flags based on mount(2) options and then the superblock * Setup flags based on mount(2) options and then the superblock
*/ */
error = xfs_start_flags(vfsp, args, mp); error = xfs_start_flags(vfsp, args, mp);
if (error) if (error)
goto error; goto error1;
error = xfs_readsb(mp); error = xfs_readsb(mp);
if (error) if (error)
goto error; goto error1;
error = xfs_finish_flags(vfsp, args, mp); error = xfs_finish_flags(vfsp, args, mp);
if (error) { if (error)
xfs_freesb(mp); goto error2;
goto error;
}
/* /*
* Setup xfs_mount buffer target pointers based on superblock * Setup xfs_mount buffer target pointers based on superblock
*/ */
xfs_setsize_buftarg(mp->m_ddev_targp, mp->m_sb.sb_blocksize, error = xfs_setsize_buftarg(mp->m_ddev_targp, mp->m_sb.sb_blocksize,
mp->m_sb.sb_sectsize); mp->m_sb.sb_sectsize);
if (logdev && logdev != ddev) { if (!error && logdev && logdev != ddev) {
unsigned int log_sector_size = BBSIZE; unsigned int log_sector_size = BBSIZE;
if (XFS_SB_VERSION_HASSECTOR(&mp->m_sb)) if (XFS_SB_VERSION_HASSECTOR(&mp->m_sb))
log_sector_size = mp->m_sb.sb_logsectsize; log_sector_size = mp->m_sb.sb_logsectsize;
xfs_setsize_buftarg(mp->m_logdev_targp, mp->m_sb.sb_blocksize, error = xfs_setsize_buftarg(mp->m_logdev_targp,
mp->m_sb.sb_blocksize,
log_sector_size); log_sector_size);
} }
if (rtdev) if (!error && rtdev)
xfs_setsize_buftarg(mp->m_rtdev_targp, mp->m_sb.sb_blocksize, error = xfs_setsize_buftarg(mp->m_rtdev_targp,
mp->m_sb.sb_blocksize); mp->m_sb.sb_blocksize,
mp->m_sb.sb_sectsize);
if (error)
goto error2;
if (!(error = XFS_IOINIT(vfsp, args, flags))) error = XFS_IOINIT(vfsp, args, flags);
if (!error)
return 0; return 0;
error2:
error: if (mp->m_sb_bp)
xfs_freesb(mp);
error1:
xfs_binval(mp->m_ddev_targp); xfs_binval(mp->m_ddev_targp);
if (logdev != NULL && logdev != ddev) { if (logdev && logdev != ddev)
xfs_binval(mp->m_logdev_targp); xfs_binval(mp->m_logdev_targp);
} if (rtdev)
if (rtdev != NULL) {
xfs_binval(mp->m_rtdev_targp); xfs_binval(mp->m_rtdev_targp);
} error0:
xfs_unmountfs_close(mp, NULL); xfs_unmountfs_close(mp, credp);
return error; return error;
} }
......
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