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(
xfs_flush_buftarg(btp, 1);
if (external)
xfs_blkdev_put(btp->pbr_bdev);
iput(btp->pbr_mapping->host);
kmem_free(btp, sizeof(*btp));
}
......@@ -1497,7 +1498,7 @@ xfs_incore_relse(
truncate_inode_pages(btp->pbr_mapping, 0LL);
}
void
int
xfs_setsize_buftarg(
xfs_buftarg_t *btp,
unsigned int blocksize,
......@@ -1511,7 +1512,38 @@ xfs_setsize_buftarg(
printk(KERN_WARNING
"XFS: Cannot set_blocksize to %u on device %s\n",
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 *
......@@ -1524,10 +1556,15 @@ xfs_alloc_buftarg(
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));
if (xfs_setsize_buftarg(btp, PAGE_CACHE_SIZE, bdev_hardsect_size(bdev)))
goto error;
if (xfs_mapping_buftarg(btp, bdev))
goto error;
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)
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 int 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);
......
......@@ -430,6 +430,16 @@ xfs_mount(
ddev = vfsp->vfs_super->s_bdev;
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.
*/
......@@ -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
*/
error = ENOMEM;
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);
if (!mp->m_rtdev_targp)
goto error0;
}
mp->m_logdev_targp = (logdev && logdev != ddev) ?
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
*/
error = xfs_start_flags(vfsp, args, mp);
if (error)
goto error;
goto error1;
error = xfs_readsb(mp);
if (error)
goto error;
goto error1;
error = xfs_finish_flags(vfsp, args, mp);
if (error) {
xfs_freesb(mp);
goto error;
}
if (error)
goto error2;
/*
* Setup xfs_mount buffer target pointers based on superblock
*/
xfs_setsize_buftarg(mp->m_ddev_targp, mp->m_sb.sb_blocksize,
mp->m_sb.sb_sectsize);
if (logdev && logdev != ddev) {
error = xfs_setsize_buftarg(mp->m_ddev_targp, mp->m_sb.sb_blocksize,
mp->m_sb.sb_sectsize);
if (!error && logdev && logdev != ddev) {
unsigned int log_sector_size = BBSIZE;
if (XFS_SB_VERSION_HASSECTOR(&mp->m_sb))
log_sector_size = mp->m_sb.sb_logsectsize;
xfs_setsize_buftarg(mp->m_logdev_targp, mp->m_sb.sb_blocksize,
log_sector_size);
error = xfs_setsize_buftarg(mp->m_logdev_targp,
mp->m_sb.sb_blocksize,
log_sector_size);
}
if (rtdev)
xfs_setsize_buftarg(mp->m_rtdev_targp, mp->m_sb.sb_blocksize,
mp->m_sb.sb_blocksize);
if (!error && rtdev)
error = xfs_setsize_buftarg(mp->m_rtdev_targp,
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;
error:
error2:
if (mp->m_sb_bp)
xfs_freesb(mp);
error1:
xfs_binval(mp->m_ddev_targp);
if (logdev != NULL && logdev != ddev) {
if (logdev && logdev != ddev)
xfs_binval(mp->m_logdev_targp);
}
if (rtdev != NULL) {
if (rtdev)
xfs_binval(mp->m_rtdev_targp);
}
xfs_unmountfs_close(mp, NULL);
error0:
xfs_unmountfs_close(mp, credp);
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