]> git.neil.brown.name Git - history.git/commitdiff
XFS: More mount cleanups
authorChristoph Hellwig <hch@sgi.com>
Mon, 14 Oct 2002 23:44:18 +0000 (01:44 +0200)
committerChristoph Hellwig <hch@sgi.com>
Mon, 14 Oct 2002 23:44:18 +0000 (01:44 +0200)
Modid: 2.5.x-xfs:slinx:128571a

fs/xfs/linux/xfs_super.c
fs/xfs/linux/xfs_super.h
fs/xfs/pagebuf/page_buf.h
fs/xfs/pagebuf/page_buf_locking.c
fs/xfs/xfs_mount.c
fs/xfs/xfs_mount.h
fs/xfs/xfs_vfsops.c

index 2dfaf44b0f7eb263f128d39d2a63c280b600f2ae..7d99bf82cd8b6e17da8883a8092770b14e05788e 100644 (file)
@@ -264,55 +264,6 @@ printk("XFS: osyncisdsync is now the default, and will soon be deprecated.\n");
        return 0;
 }
 
-/*
- * Convert one device special file to a dev_t.
- * Helper routine, used only by spectodevs below.
- */
-STATIC int
-spectodev(
-       const char              *name,
-       const char              *id,
-       dev_t                   *dev)
-{
-       struct nameidata        nd;
-       int                     error;
-
-       error = path_lookup(name, LOOKUP_FOLLOW, &nd);
-       if (error)
-               return error;
-
-       *dev = kdev_t_to_nr(nd.dentry->d_inode->i_rdev);
-       path_release(&nd);
-       return 0;
-}
-
-/*
- * Convert device special files to dev_t for data, log, realtime.
- */
-int
-spectodevs(
-       struct super_block      *sb,
-       struct xfs_mount_args   *args,
-       dev_t                   *ddevp,
-       dev_t                   *logdevp,
-       dev_t                   *rtdevp)
-{
-       int                     rval = 0;
-
-       *ddevp = sb->s_dev;
-
-       if (args->logname[0])
-               rval = spectodev(args->logname, "log", logdevp);
-       else
-               *logdevp = sb->s_dev;
-
-       if (args->rtname[0] && !rval)
-               rval = spectodev(args->rtname, "realtime", rtdevp);
-       else
-               *rtdevp = 0;
-       return rval;
-}
-
 
 STATIC kmem_cache_t * linvfs_inode_cachep;
 
index e783163a2300822daea29f7ac53b0c6cc0f3d8ff..315910498a0cdf0a5e8f528d8425d0676e4029a7 100644 (file)
        ((s)->s_fs_info = vfsp)
 
 
-struct xfs_mount_args;
-
 extern void
 linvfs_set_inode_ops(
        struct inode    *inode);
 
-extern int
-spectodevs(
-       struct super_block *sb,
-       struct xfs_mount_args *args,
-       dev_t           *ddevp,
-       dev_t           *logdevp,
-       dev_t           *rtdevp);
-
 #endif /* __XFS_SUPER_H__ */
index 18e27035cf72bf25708c3fa4a29bc6bf2b1ba9fa..6513fea00dedc8efbc52ad5911956d3d0f1c8057 100644 (file)
@@ -145,7 +145,6 @@ typedef struct pb_target {
        struct block_device     *pbr_bdev;
        struct address_space    *pbr_mapping;
        unsigned int            pbr_blocksize;
-       unsigned int            pbr_blocksize_bits;
 } pb_target_t;
 
 /*
@@ -303,18 +302,6 @@ extern int pagebuf_lock_value(             /* return count on lock         */
 extern int pagebuf_lock(               /* lock buffer                  */
                page_buf_t *);          /* buffer to lock               */
 
-extern void pagebuf_lock_disable(      /* disable buffer locking       */
-               struct pb_target *,     /* inode for buffers            */
-               int);                   /* do blkdev_put?               */
-
-extern struct pb_target *pagebuf_lock_enable(
-               dev_t,
-               int);                   /* do blkdev_get?               */
-
-extern void pagebuf_target_blocksize(
-               pb_target_t *,
-               unsigned int);          /* block size                   */
-
 extern void pagebuf_target_clear(struct pb_target *);
 
 extern void pagebuf_unlock(            /* unlock buffer                */
index 6be04596ec11286797630093c819f3b60f8c730f..ecabe0f3c2c25971f9b704626af35774fcaa1fe8 100644 (file)
@@ -1,6 +1,5 @@
 /*
  * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
- * Portions Copyright (c) 2002 Christoph Hellwig.  All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
 
 #include "page_buf_internal.h"
 
-#ifndef EVMS_MAJOR
-#define EVMS_MAJOR      117
-#endif
-
 /*
  *     pagebuf_cond_lock
  *
@@ -126,82 +121,6 @@ pagebuf_lock(
        return 0;
 }
 
-/*
- *     pagebuf_lock_disable
- *
- *     pagebuf_lock_disable disables buffer object locking for an inode.
- *     remove_super() does a blkdev_put for us on the data device, hence
- *     the do_blkdev_put argument.
- */
-void
-pagebuf_lock_disable(
-       pb_target_t             *target,
-       int                     do_blkdev_put)
-{
-       pagebuf_delwri_flush(target, PBDF_WAIT, NULL);
-       if (do_blkdev_put)
-               blkdev_put(target->pbr_bdev, BDEV_FS);
-       kfree(target);
-}
-
-/*
- *     pagebuf_lock_enable
- *
- *     get_sb_bdev() does a blkdev_get for us on the data device, hence
- *     the do_blkdev_get argument.
- */
-pb_target_t *
-pagebuf_lock_enable(
-       dev_t                   dev,
-       int                     do_blkdev_get)
-{
-       struct block_device     *bdev;
-       pb_target_t             *target;
-       int                     error = -ENOMEM;
-
-       target = kmalloc(sizeof(pb_target_t), GFP_KERNEL);
-       if (unlikely(!target))
-               return ERR_PTR(error);
-
-       bdev = bdget(dev);
-       if (unlikely(!bdev))
-               goto fail;
-
-       if (do_blkdev_get) {
-               error = blkdev_get(bdev, FMODE_READ|FMODE_WRITE, 0, BDEV_FS);
-               if (unlikely(error))
-                       goto fail;
-       }
-
-       target->pbr_dev = dev;
-       target->pbr_bdev = bdev;
-       target->pbr_mapping = bdev->bd_inode->i_mapping;
-
-       pagebuf_target_blocksize(target, PAGE_CACHE_SIZE);
-       
-       if ((MAJOR(dev) == MD_MAJOR) || (MAJOR(dev) == EVMS_MAJOR))
-               target->pbr_flags = PBR_ALIGNED_ONLY;
-       else if (MAJOR(dev) == LVM_BLK_MAJOR)
-               target->pbr_flags = PBR_SECTOR_ONLY;
-       else
-               target->pbr_flags = 0;
-
-       return target;
-
-fail:
-       kfree(target);
-       return ERR_PTR(error);
-}
-
-void
-pagebuf_target_blocksize(
-       pb_target_t             *target,
-       unsigned int            blocksize)
-{
-       target->pbr_blocksize = blocksize;
-       target->pbr_blocksize_bits = ffs(blocksize) - 1;
-}
-
 void
 pagebuf_target_clear(
        pb_target_t             *target)
index 13c88ba8039e92e925bf4c81aefa3d6e80730b78..4dccca3c8b34febac747055fde8aac0a554505c1 100644 (file)
  */
 
 #include <xfs.h>
+#include <linux/major.h>
+#include <linux/namei.h>
+#include <linux/pagemap.h>
+
+#ifndef EVMS_MAJOR
+#define EVMS_MAJOR     117
+#endif
 
 STATIC void    xfs_mount_reset_sbqflags(xfs_mount_t *);
 STATIC void    xfs_mount_log_sbunit(xfs_mount_t *, __int64_t);
@@ -1149,15 +1156,17 @@ xfs_unmountfs_close(xfs_mount_t *mp, struct cred *cr)
        int             have_logdev = (mp->m_logdev_targp != mp->m_ddev_targp);
 
        if (mp->m_ddev_targp) {
-               pagebuf_lock_disable(mp->m_ddev_targp, 0);
+               xfs_free_buftarg(mp->m_ddev_targp);
                mp->m_ddev_targp = NULL;
        }
        if (mp->m_rtdev_targp) {
-               pagebuf_lock_disable(mp->m_rtdev_targp, 1);
+               xfs_blkdev_put(mp->m_rtdev_targp->pbr_bdev);
+               xfs_free_buftarg(mp->m_rtdev_targp);
                mp->m_rtdev_targp = NULL;
        }
        if (mp->m_logdev_targp && have_logdev) {
-               pagebuf_lock_disable(mp->m_logdev_targp, 1);
+               xfs_blkdev_put(mp->m_logdev_targp->pbr_bdev);
+               xfs_free_buftarg(mp->m_logdev_targp);
                mp->m_logdev_targp = NULL;
        }
 }
@@ -1725,3 +1734,71 @@ xfs_check_frozen(
        if (level == XFS_FREEZE_TRANS)
                atomic_inc(&mp->m_active_trans);
 }
+
+int
+xfs_blkdev_get(
+       const char              *name,
+       struct block_device     **bdevp)
+{
+       struct nameidata        nd;
+       int                     error = 0;
+
+       error = path_lookup(name, LOOKUP_FOLLOW, &nd);
+       if (error) {
+               printk("XFS: Invalid device [%s], error=%d\n",
+                               name, error);
+               return error;
+       }
+
+       /* I think we actually want bd_acquire here..  --hch */
+       *bdevp = bdget(kdev_t_to_nr(nd.dentry->d_inode->i_rdev));
+       if (*bdevp) {
+               error = blkdev_get(*bdevp, FMODE_READ|FMODE_WRITE, 0, BDEV_FS);
+       } else {
+               error = -ENOMEM;
+       }
+
+       path_release(&nd);
+       return -error;
+}
+
+void
+xfs_blkdev_put(
+       struct block_device     *bdev)
+{
+       blkdev_put(bdev, BDEV_FS);
+}
+
+void
+xfs_free_buftarg(
+       xfs_buftarg_t           *btp)
+{
+       pagebuf_delwri_flush(btp, PBDF_WAIT, NULL);
+       kfree(btp);
+}
+
+xfs_buftarg_t *
+xfs_alloc_buftarg(
+       struct block_device     *bdev)
+{
+       xfs_buftarg_t           *btp;
+
+       btp = kmem_zalloc(sizeof(*btp), KM_SLEEP);
+
+       btp->pbr_dev =  bdev->bd_dev;
+       btp->pbr_bdev = bdev;
+       btp->pbr_mapping = bdev->bd_inode->i_mapping;
+       btp->pbr_blocksize = PAGE_CACHE_SIZE;
+
+       switch (MAJOR(btp->pbr_dev)) {
+       case MD_MAJOR:
+       case EVMS_MAJOR:
+               btp->pbr_flags = PBR_ALIGNED_ONLY;
+               break;
+       case LVM_BLK_MAJOR:
+               btp->pbr_flags = PBR_SECTOR_ONLY;
+               break;
+       }
+
+       return btp;
+}
index 51c86fea20c47777702245296ace886edf108d65..a5b4ec193617aba48346ce95aad99dcd0205b192 100644 (file)
@@ -436,6 +436,11 @@ int                xfs_syncsub(xfs_mount_t *, int, int, int *);
 void           xfs_initialize_perag(xfs_mount_t *, int);
 void           xfs_xlatesb(void *, struct xfs_sb *, int, xfs_arch_t, __int64_t);
 
+int            xfs_blkdev_get(const char *, struct block_device **);
+void           xfs_blkdev_put(struct block_device *);
+struct xfs_buftarg *xfs_alloc_buftarg(struct block_device *);
+void           xfs_free_buftarg(struct xfs_buftarg *);
+
 /*
  * Flags for freeze operations.
  */
index cce4a74d5dfe407663f2345b6a0d5c5ed94bfe49..297cfe03e845474114bbb216823d1faa81ee153c 100644 (file)
@@ -392,144 +392,114 @@ xfs_finish_flags(
 }
 
 /*
- * xfs_cmountfs
+ * xfs_mount
+ *
+ * The file system configurations are:
+ *     (1) device (partition) with data and internal log
+ *     (2) logical volume with data and log subvolumes.
+ *     (3) logical volume with data, log, and realtime subvolumes.
  *
- * This function is the common mount file system function for XFS.
+ * The Linux VFS took care of finding and opening the data volume for
+ * us.  We have to handle the other two (if present) here.
  */
 STATIC int
-xfs_cmountfs(
+xfs_mount(
        vfs_t                   *vfsp,
-       dev_t                   ddev,
-       dev_t                   logdev,
-       dev_t                   rtdev,
-       struct xfs_mount_args   *ap,
-       struct cred             *cr)
+       struct xfs_mount_args   *args,
+       cred_t                  *credp)
 {
        xfs_mount_t             *mp;
+       struct block_device     *ddev, *logdev, *rtdev;
        int                     ronly = (vfsp->vfs_flag & VFS_RDONLY);
        int                     error = 0;
 
-       /*
-        * Allocate VFS private data (xfs mount structure).
-        */
-       mp = xfs_mount_init();
-
-       vfs_insertbhv(vfsp, &mp->m_bhv, &xfs_vfsops, mp);
+       ddev = vfsp->vfs_super->s_bdev;
+       logdev = rtdev = NULL;
 
        /*
-        * Open data, real time, and log devices now - order is important.
+        * Open real time and log devices - order is important.
         */
-       mp->m_ddev_targp = pagebuf_lock_enable(ddev, 0);
-       if (IS_ERR(mp->m_ddev_targp)) {
-               error = PTR_ERR(mp->m_ddev_targp);
-               goto error2;
+       if (args->logname[0]) {
+               error = xfs_blkdev_get(args->logname, &logdev);
+               if (error)
+                       return error;
        }
-
-       if (rtdev != 0) {
-               mp->m_rtdev_targp = pagebuf_lock_enable(rtdev, 1);
-               if (IS_ERR(mp->m_rtdev_targp)) {
-                       error = PTR_ERR(mp->m_rtdev_targp);
-                       pagebuf_lock_disable(mp->m_ddev_targp, 0);
-                       goto error2;
+       if (args->rtname[0]) {
+               error = xfs_blkdev_get(args->rtname, &rtdev);
+               if (error) {
+                       xfs_blkdev_put(logdev);
+                       return error;
                }
 
                if (rtdev == ddev || rtdev == logdev) {
                        cmn_err(CE_WARN,
        "XFS: Cannot mount filesystem with identical rtdev and ddev/logdev.");
-                       error = EINVAL;
-                       pagebuf_lock_disable(mp->m_ddev_targp, 0);
-                       goto error2;
+                       xfs_blkdev_put(logdev);
+                       xfs_blkdev_put(rtdev);
+                       return EINVAL;
                }
-               
-               /* Set the realtime device's block size */
-               set_blocksize(mp->m_rtdev_targp->pbr_bdev, 512);
        }
 
-       if (logdev != ddev) {
-               mp->m_logdev_targp = pagebuf_lock_enable(logdev, 1);
-               if (IS_ERR(mp->m_logdev_targp)) {
-                       error = PTR_ERR(mp->m_logdev_targp);
-                       pagebuf_lock_disable(mp->m_ddev_targp, 1);
-                       if (mp->m_rtdev_targp)
-                               pagebuf_lock_disable(mp->m_rtdev_targp, 1);
-                       goto error2;
-               }
+       /*
+        * Allocate VFS private data (xfs mount structure).
+        */
+       mp = xfs_mount_init();
 
-               /* Set the log device's block size */
-               set_blocksize(mp->m_logdev_targp->pbr_bdev, 512);
+       vfs_insertbhv(vfsp, &mp->m_bhv, &xfs_vfsops, mp);
+
+       mp->m_ddev_targp = xfs_alloc_buftarg(ddev);
+       if (rtdev != NULL) {
+               mp->m_rtdev_targp = xfs_alloc_buftarg(rtdev);
+               set_blocksize(rtdev, 512);
+       }
+       if (logdev != NULL && logdev != ddev) {
+               mp->m_logdev_targp = xfs_alloc_buftarg(logdev);
+               set_blocksize(logdev, 512);
        } else {
                mp->m_logdev_targp = mp->m_ddev_targp;
        }
        
-       if ((error = xfs_start_flags(ap, mp, ronly)))
-               goto error3;
+       error = xfs_start_flags(args, mp, ronly);
+       if (error)
+               goto error;
 
-       if ((error = xfs_readsb(mp)))
-               goto error3;
+       error = xfs_readsb(mp);
+       if (error)
+               goto error;
 
-       if ((error = xfs_finish_flags(ap, mp, ronly))) {
+       error = xfs_finish_flags(args, mp, ronly);
+       if (error) {
                xfs_freesb(mp);
-               goto error3;
+               goto error;
        }
 
-       pagebuf_target_blocksize(mp->m_ddev_targp, mp->m_sb.sb_blocksize);
-       if (logdev != 0 && logdev != ddev)
-               pagebuf_target_blocksize(mp->m_logdev_targp,
-                                       mp->m_sb.sb_blocksize);
-       if (rtdev != 0)
-               pagebuf_target_blocksize(mp->m_rtdev_targp,
-                                       mp->m_sb.sb_blocksize);
+       mp->m_ddev_targp->pbr_blocksize = mp->m_sb.sb_blocksize;
+       if (logdev != 0 && logdev != ddev) {
+               mp->m_logdev_targp->pbr_blocksize = mp->m_sb.sb_blocksize;
+       }
+       if (rtdev != 0) {
+               mp->m_rtdev_targp->pbr_blocksize = mp->m_sb.sb_blocksize;
+       }
 
        mp->m_cxfstype = XFS_CXFS_NOT;
-       error = xfs_mountfs(vfsp, mp, ddev, 0);
+       error = xfs_mountfs(vfsp, mp, ddev->bd_dev, 0);
        if (error)
-               goto error3;
+               goto error;
        return 0;
 
- error3:
-       /* It's impossible to get here before buftargs are filled */
+ error:
        xfs_binval(mp->m_ddev_targp);
-       pagebuf_lock_disable(mp->m_ddev_targp, 0);
-       if (logdev && logdev != ddev) {
+       if (logdev != NULL && logdev != ddev) {
                xfs_binval(mp->m_logdev_targp);
-               pagebuf_lock_disable(mp->m_logdev_targp, 1);
        }
-       if (rtdev != 0) {
+       if (rtdev != NULL) {
                xfs_binval(mp->m_rtdev_targp);
-               pagebuf_lock_disable(mp->m_rtdev_targp, 1);
-       }
- error2:
-       if (error) {
-               xfs_mount_free(mp, 1);
        }
+       xfs_unmountfs_close(mp, NULL);
+       xfs_mount_free(mp, 1);
        return error;
 }
 
-/*
- * xfs_mount
- *
- * The file system configurations are:
- *     (1) device (partition) with data and internal log
- *     (2) logical volume with data and log subvolumes.
- *     (3) logical volume with data, log, and realtime subvolumes.
- */
-STATIC int
-xfs_mount(
-       vfs_t                   *vfsp,
-       struct xfs_mount_args   *args,
-       cred_t                  *credp)
-{
-       dev_t           ddev;
-       dev_t           logdev;
-       dev_t           rtdev;
-       int             error;
-
-       error = spectodevs(vfsp->vfs_super, args, &ddev, &logdev, &rtdev);
-       if (!error)
-               error = xfs_cmountfs(vfsp, ddev, logdev, rtdev, args, credp);
-       return (error);
-}
-
 /*
  * xfs_ibusy searches for a busy inode in the mounted file system.
  *