aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorNathan Scott <nathans@sgi.com>2004-08-20 05:44:39 +1000
committerNathan Scott <nathans@lips.borg.umn.edu>2004-08-20 05:44:39 +1000
commit3105b9b65ba717b29fb7e96b0efb831f9991b40f (patch)
tree473676a3bdbaedfb97670f009f49859e55c6f7f3 /fs
parent3ce0de02ea9b964dae68a5ad417f4f7e799bb6a2 (diff)
downloadhistory-3105b9b65ba717b29fb7e96b0efb831f9991b40f.tar.gz
[XFS] Revert to using a separate inode for metadata buffers once more.
SGI Modid: xfs-linux:xfs-kern:174253a Signed-off-by: Nathan Scott <nathans@sgi.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.c45
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.h2
-rw-r--r--fs/xfs/xfs_vfsops.c81
3 files changed, 90 insertions, 38 deletions
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index ed8abf22dac92b..6b2a67f4f11690 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -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;
}
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h
index 7bebfd65a7fca0..242ba07d6168b9 100644
--- a/fs/xfs/linux-2.6/xfs_buf.h
+++ b/fs/xfs/linux-2.6/xfs_buf.h
@@ -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);
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index 114c53a766a20e..3b4addb11db9eb 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -431,6 +431,16 @@ xfs_mount(
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.
*/
if (args->logname[0]) {
@@ -455,68 +465,73 @@ 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;
}