diff options
author | Nathan Scott <nathans@sgi.com> | 2004-08-20 05:44:39 +1000 |
---|---|---|
committer | Nathan Scott <nathans@lips.borg.umn.edu> | 2004-08-20 05:44:39 +1000 |
commit | 3105b9b65ba717b29fb7e96b0efb831f9991b40f (patch) | |
tree | 473676a3bdbaedfb97670f009f49859e55c6f7f3 /fs | |
parent | 3ce0de02ea9b964dae68a5ad417f4f7e799bb6a2 (diff) | |
download | history-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.c | 45 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_buf.h | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_vfsops.c | 81 |
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; } |