]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/xfs/linux-2.6/xfs_super.c
[XFS] kill vn_to_inode
[linux-2.6-omap-h63xx.git] / fs / xfs / linux-2.6 / xfs_super.c
index 7c621dfee73d907de901e9a28e9c24fcfa444ee5..71ac3a6162e9f59d1a3af06982f871151ec7623e 100644 (file)
@@ -66,6 +66,7 @@
 #include <linux/writeback.h>
 #include <linux/kthread.h>
 #include <linux/freezer.h>
+#include <linux/parser.h>
 
 static struct quotactl_ops xfs_quotactl_operations;
 static struct super_operations xfs_super_operations;
@@ -147,6 +148,23 @@ xfs_args_allocate(
 #define MNTOPT_XDSM    "xdsm"          /* DMI enabled (DMAPI / XDSM) */
 #define MNTOPT_DMI     "dmi"           /* DMI enabled (DMAPI / XDSM) */
 
+/*
+ * Table driven mount option parser.
+ *
+ * Currently only used for remount, but it will be used for mount
+ * in the future, too.
+ */
+enum {
+       Opt_barrier, Opt_nobarrier, Opt_err
+};
+
+static match_table_t tokens = {
+       {Opt_barrier, "barrier"},
+       {Opt_nobarrier, "nobarrier"},
+       {Opt_err, NULL}
+};
+
+
 STATIC unsigned long
 suffix_strtoul(char *s, char **endp, unsigned int base)
 {
@@ -595,10 +613,9 @@ xfs_set_inodeops(
 STATIC_INLINE void
 xfs_revalidate_inode(
        xfs_mount_t             *mp,
-       bhv_vnode_t             *vp,
+       struct inode            *inode,
        xfs_inode_t             *ip)
 {
-       struct inode            *inode = vn_to_inode(vp);
 
        inode->i_mode   = ip->i_d.di_mode;
        inode->i_nlink  = ip->i_d.di_nlink;
@@ -647,13 +664,12 @@ xfs_revalidate_inode(
 void
 xfs_initialize_vnode(
        struct xfs_mount        *mp,
-       bhv_vnode_t             *vp,
+       struct inode            *inode,
        struct xfs_inode        *ip)
 {
-       struct inode            *inode = vn_to_inode(vp);
 
        if (!ip->i_vnode) {
-               ip->i_vnode = vp;
+               ip->i_vnode = inode;
                inode->i_private = ip;
        }
 
@@ -665,7 +681,7 @@ xfs_initialize_vnode(
         * finish our work.
         */
        if (ip->i_d.di_mode != 0 && (inode->i_state & I_NEW)) {
-               xfs_revalidate_inode(mp, vp, ip);
+               xfs_revalidate_inode(mp, inode, ip);
                xfs_set_inodeops(inode);
 
                xfs_iflags_clear(ip, XFS_INEW);
@@ -746,14 +762,6 @@ xfs_mountfs_check_barriers(xfs_mount_t *mp)
                return;
        }
 
-       if (mp->m_ddev_targp->bt_bdev->bd_disk->queue->ordered ==
-                                       QUEUE_ORDERED_NONE) {
-               xfs_fs_cmn_err(CE_NOTE, mp,
-                 "Disabling barriers, not supported by the underlying device");
-               mp->m_flags &= ~XFS_MOUNT_BARRIER;
-               return;
-       }
-
        if (xfs_readonly_buftarg(mp->m_ddev_targp)) {
                xfs_fs_cmn_err(CE_NOTE, mp,
                  "Disabling barriers, underlying device is readonly");
@@ -782,12 +790,14 @@ xfs_close_devices(
        struct xfs_mount        *mp)
 {
        if (mp->m_logdev_targp && mp->m_logdev_targp != mp->m_ddev_targp) {
+               struct block_device *logdev = mp->m_logdev_targp->bt_bdev;
                xfs_free_buftarg(mp->m_logdev_targp);
-               xfs_blkdev_put(mp->m_logdev_targp->bt_bdev);
+               xfs_blkdev_put(logdev);
        }
        if (mp->m_rtdev_targp) {
+               struct block_device *rtdev = mp->m_rtdev_targp->bt_bdev;
                xfs_free_buftarg(mp->m_rtdev_targp);
-               xfs_blkdev_put(mp->m_rtdev_targp->bt_bdev);
+               xfs_blkdev_put(rtdev);
        }
        xfs_free_buftarg(mp->m_ddev_targp);
 }
@@ -975,21 +985,21 @@ xfs_fs_alloc_inode(
        vp = kmem_zone_alloc(xfs_vnode_zone, KM_SLEEP);
        if (unlikely(!vp))
                return NULL;
-       return vn_to_inode(vp);
+       return vp;
 }
 
 STATIC void
 xfs_fs_destroy_inode(
        struct inode            *inode)
 {
-       kmem_zone_free(xfs_vnode_zone, vn_from_inode(inode));
+       kmem_zone_free(xfs_vnode_zone, inode);
 }
 
 STATIC void
 xfs_fs_inode_init_once(
        void                    *vnode)
 {
-       inode_init_once(vn_to_inode((bhv_vnode_t *)vnode));
+       inode_init_once((struct inode *)vnode);
 }
 
 /*
@@ -1094,7 +1104,7 @@ void
 xfs_flush_inode(
        xfs_inode_t     *ip)
 {
-       struct inode    *inode = ip->i_vnode;
+       struct inode    *inode = VFS_I(ip);
 
        igrab(inode);
        xfs_syncd_queue_work(ip->i_mount, inode, xfs_flush_inode_work);
@@ -1119,7 +1129,7 @@ void
 xfs_flush_device(
        xfs_inode_t     *ip)
 {
-       struct inode    *inode = vn_to_inode(XFS_ITOV(ip));
+       struct inode    *inode = VFS_I(ip);
 
        igrab(inode);
        xfs_syncd_queue_work(ip->i_mount, inode, xfs_flush_device_work);
@@ -1188,6 +1198,15 @@ xfssyncd(
        return 0;
 }
 
+STATIC void
+xfs_free_fsname(
+       struct xfs_mount        *mp)
+{
+       kfree(mp->m_fsname);
+       kfree(mp->m_rtname);
+       kfree(mp->m_logname);
+}
+
 STATIC void
 xfs_fs_put_super(
        struct super_block      *sb)
@@ -1249,6 +1268,7 @@ xfs_fs_put_super(
        xfs_close_devices(mp);
        xfs_qmops_put(mp);
        xfs_dmops_put(mp);
+       xfs_free_fsname(mp);
        kfree(mp);
 }
 
@@ -1372,36 +1392,54 @@ xfs_fs_remount(
        char                    *options)
 {
        struct xfs_mount        *mp = XFS_M(sb);
-       struct xfs_mount_args   *args;
-       int                     error;
+       substring_t             args[MAX_OPT_ARGS];
+       char                    *p;
 
-       args = xfs_args_allocate(sb, 0);
-       if (!args)
-               return -ENOMEM;
+       while ((p = strsep(&options, ",")) != NULL) {
+               int token;
 
-       error = xfs_parseargs(mp, options, args, 1);
-       if (error)
-               goto out_free_args;
+               if (!*p)
+                       continue;
 
-       if (!(*flags & MS_RDONLY)) {                    /* rw/ro -> rw */
-               if (mp->m_flags & XFS_MOUNT_RDONLY)
-               mp->m_flags &= ~XFS_MOUNT_RDONLY;
-               if (args->flags & XFSMNT_BARRIER) {
+               token = match_token(p, tokens, args);
+               switch (token) {
+               case Opt_barrier:
                        mp->m_flags |= XFS_MOUNT_BARRIER;
-                       xfs_mountfs_check_barriers(mp);
-               } else {
+
+                       /*
+                        * Test if barriers are actually working if we can,
+                        * else delay this check until the filesystem is
+                        * marked writeable.
+                        */
+                       if (!(mp->m_flags & XFS_MOUNT_RDONLY))
+                               xfs_mountfs_check_barriers(mp);
+                       break;
+               case Opt_nobarrier:
                        mp->m_flags &= ~XFS_MOUNT_BARRIER;
+                       break;
+               default:
+                       printk(KERN_INFO
+       "XFS: mount option \"%s\" not supported for remount\n", p);
+                       return -EINVAL;
                }
-       } else if (!(mp->m_flags & XFS_MOUNT_RDONLY)) { /* rw -> ro */
+       }
+
+       /* rw/ro -> rw */
+       if ((mp->m_flags & XFS_MOUNT_RDONLY) && !(*flags & MS_RDONLY)) {
+               mp->m_flags &= ~XFS_MOUNT_RDONLY;
+               if (mp->m_flags & XFS_MOUNT_BARRIER)
+                       xfs_mountfs_check_barriers(mp);
+       }
+
+       /* rw -> ro */
+       if (!(mp->m_flags & XFS_MOUNT_RDONLY) && (*flags & MS_RDONLY)) {
                xfs_filestream_flush(mp);
                xfs_sync(mp, SYNC_DATA_QUIESCE);
                xfs_attr_quiesce(mp);
                mp->m_flags |= XFS_MOUNT_RDONLY;
        }
 
- out_free_args:
-       kfree(args);
-       return -error;
+       return 0;
 }
 
 /*
@@ -1487,6 +1525,8 @@ xfs_start_flags(
        struct xfs_mount_args   *ap,
        struct xfs_mount        *mp)
 {
+       int                     error;
+
        /* Values are in BBs */
        if ((ap->flags & XFSMNT_NOALIGN) != XFSMNT_NOALIGN) {
                /*
@@ -1519,17 +1559,27 @@ xfs_start_flags(
                        ap->logbufsize);
                return XFS_ERROR(EINVAL);
        }
+
+       error = ENOMEM;
+
        mp->m_logbsize = ap->logbufsize;
        mp->m_fsname_len = strlen(ap->fsname) + 1;
-       mp->m_fsname = kmem_alloc(mp->m_fsname_len, KM_SLEEP);
-       strcpy(mp->m_fsname, ap->fsname);
+
+       mp->m_fsname = kstrdup(ap->fsname, GFP_KERNEL);
+       if (!mp->m_fsname)
+               goto out;
+
        if (ap->rtname[0]) {
-               mp->m_rtname = kmem_alloc(strlen(ap->rtname) + 1, KM_SLEEP);
-               strcpy(mp->m_rtname, ap->rtname);
+               mp->m_rtname = kstrdup(ap->rtname, GFP_KERNEL);
+               if (!mp->m_rtname)
+                       goto out_free_fsname;
+
        }
+
        if (ap->logname[0]) {
-               mp->m_logname = kmem_alloc(strlen(ap->logname) + 1, KM_SLEEP);
-               strcpy(mp->m_logname, ap->logname);
+               mp->m_logname = kstrdup(ap->logname, GFP_KERNEL);
+               if (!mp->m_logname)
+                       goto out_free_rtname;
        }
 
        if (ap->flags & XFSMNT_WSYNC)
@@ -1602,6 +1652,14 @@ xfs_start_flags(
        if (ap->flags & XFSMNT_DMAPI)
                mp->m_flags |= XFS_MOUNT_DMAPI;
        return 0;
+
+
+ out_free_rtname:
+       kfree(mp->m_rtname);
+ out_free_fsname:
+       kfree(mp->m_fsname);
+ out:
+       return error;
 }
 
 /*
@@ -1762,10 +1820,10 @@ xfs_fs_fill_super(
         */
        error = xfs_start_flags(args, mp);
        if (error)
-               goto out_destroy_counters;
+               goto out_free_fsname;
        error = xfs_readsb(mp, flags);
        if (error)
-               goto out_destroy_counters;
+               goto out_free_fsname;
        error = xfs_finish_flags(args, mp);
        if (error)
                goto out_free_sb;
@@ -1795,7 +1853,7 @@ xfs_fs_fill_super(
        sb->s_time_gran = 1;
        set_posix_acl_flag(sb);
 
-       root = igrab(mp->m_rootip->i_vnode);
+       root = igrab(VFS_I(mp->m_rootip));
        if (!root) {
                error = ENOENT;
                goto fail_unmount;
@@ -1827,7 +1885,8 @@ xfs_fs_fill_super(
        xfs_filestream_unmount(mp);
  out_free_sb:
        xfs_freesb(mp);
- out_destroy_counters:
+ out_free_fsname:
+       xfs_free_fsname(mp);
        xfs_icsb_destroy_counters(mp);
        xfs_close_devices(mp);
  out_put_qmops:
@@ -1863,7 +1922,7 @@ xfs_fs_fill_super(
        IRELE(mp->m_rootip);
 
        xfs_unmountfs(mp);
-       goto out_destroy_counters;
+       goto out_free_fsname;
 }
 
 STATIC int