]> git.neil.brown.name Git - history.git/commitdiff
[XFS] Revert to using a separate inode for metadata buffers once more.
authorNathan Scott <nathans@sgi.com>
Thu, 19 Aug 2004 19:44:39 +0000 (05:44 +1000)
committerNathan Scott <nathans@lips.borg.umn.edu>
Thu, 19 Aug 2004 19:44:39 +0000 (05:44 +1000)
SGI Modid: xfs-linux:xfs-kern:174253a
Signed-off-by: Nathan Scott <nathans@sgi.com>
fs/xfs/linux-2.6/xfs_buf.c
fs/xfs/linux-2.6/xfs_buf.h
fs/xfs/xfs_vfsops.c

index ed8abf22dac92be5b8a5b548af569fe8cb95539b..6b2a67f4f1169048034b62be7d1f9c43802eb0ee 100644 (file)
@@ -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;
 }
 
 
index 7bebfd65a7fca08eb659349ad825c920ab0918ef..242ba07d6168b9b40d17702cad5876452f413f29 100644 (file)
@@ -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);
 
index 114c53a766a20edca678b73befd3d47b2933644c..3b4addb11db9eb2c8c2231ff8e13021c7de35205 100644 (file)
@@ -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;
 }