]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] lockfs - xfs bits
authorAndrew Morton <akpm@osdl.org>
Wed, 21 Apr 2004 00:43:05 +0000 (17:43 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Wed, 21 Apr 2004 00:43:05 +0000 (17:43 -0700)
From: Christoph Hellwig <hch@lst.de>

Remove all the code now in the VFS, make XFS's freeze ioctls use the new
infastructure and reorganize some code.

This code needs some work so the source files shared with 2.4 aren't
exposed to the new VFS interfaces directly.  You'll get an update once this
has been discussed with the other XFS developers and is implemented.  Note
that the current patch works fine and I wouldn't complain if it gets into
Linus' tree as-is.

12 files changed:
fs/xfs/linux/xfs_ioctl.c
fs/xfs/linux/xfs_lrw.c
fs/xfs/linux/xfs_super.c
fs/xfs/linux/xfs_vfs.c
fs/xfs/linux/xfs_vfs.h
fs/xfs/xfs_fsops.c
fs/xfs/xfs_fsops.h
fs/xfs/xfs_log.c
fs/xfs/xfs_mount.c
fs/xfs/xfs_mount.h
fs/xfs/xfs_trans.c
fs/xfs/xfs_vfsops.c

index fb317760a25e3aad7859da4b013133655d69931c..c5059bbe56949153c7b54558e47d2a1bb35ec65b 100644 (file)
@@ -825,13 +825,14 @@ xfs_ioctl(
        case XFS_IOC_FREEZE:
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
-               xfs_fs_freeze(mp);
+
+               freeze_bdev(inode->i_sb->s_bdev);
                return 0;
 
        case XFS_IOC_THAW:
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
-               xfs_fs_thaw(mp);
+               thaw_bdev(inode->i_sb->s_bdev, inode->i_sb);
                return 0;
 
        case XFS_IOC_GOINGDOWN: {
index 2077d85362087dab77dc185dd9abcae49f959b58..93bb959fef484986473a3d405b49d1bdf8995aa7 100644 (file)
@@ -682,8 +682,6 @@ xfs_write(
        io = &xip->i_iocore;
        mp = io->io_mount;
 
-       xfs_check_frozen(mp, bdp, XFS_FREEZE_WRITE);
-
        if (XFS_FORCED_SHUTDOWN(mp)) {
                return -EIO;
        }
index 478e7caca9021d4a6daac2a7237995ec7030bc24..5b7f46bc34b9d82f68c2a965efe052835a3243e1 100644 (file)
@@ -589,28 +589,7 @@ STATIC void
 linvfs_freeze_fs(
        struct super_block      *sb)
 {
-       vfs_t                   *vfsp = LINVFS_GET_VFS(sb);
-       vnode_t                 *vp;
-       int                     error;
-
-       if (sb->s_flags & MS_RDONLY)
-               return;
-       VFS_ROOT(vfsp, &vp, error);
-       VOP_IOCTL(vp, LINVFS_GET_IP(vp), NULL, 0, XFS_IOC_FREEZE, 0, error);
-       VN_RELE(vp);
-}
-
-STATIC void
-linvfs_unfreeze_fs(
-       struct super_block      *sb)
-{
-       vfs_t                   *vfsp = LINVFS_GET_VFS(sb);
-       vnode_t                 *vp;
-       int                     error;
-
-       VFS_ROOT(vfsp, &vp, error);
-       VOP_IOCTL(vp, LINVFS_GET_IP(vp), NULL, 0, XFS_IOC_THAW, 0, error);
-       VN_RELE(vp);
+       VFS_FREEZE(LINVFS_GET_VFS(sb));
 }
 
 STATIC struct dentry *
@@ -850,7 +829,6 @@ STATIC struct super_operations linvfs_sops = {
        .write_super            = linvfs_write_super,
        .sync_fs                = linvfs_sync_super,
        .write_super_lockfs     = linvfs_freeze_fs,
-       .unlockfs               = linvfs_unfreeze_fs,
        .statfs                 = linvfs_statfs,
        .remount_fs             = linvfs_remount,
        .show_options           = linvfs_show_options,
index 63adf1d5988ebde45b32e8a264633ed5dd129aa6..2b75cccdfd6087e31c843d5672d1c1b8db89f234 100644 (file)
@@ -230,6 +230,18 @@ vfs_force_shutdown(
        ((*bhvtovfsops(next)->vfs_force_shutdown)(next, fl, file, line));
 }
 
+void
+vfs_freeze(
+       struct bhv_desc         *bdp)
+{
+       struct bhv_desc         *next = bdp;
+
+       ASSERT(next);
+       while (! (bhvtovfsops(next))->vfs_freeze)
+               next = BHV_NEXT(next);
+       ((*bhvtovfsops(next)->vfs_freeze)(next));
+}
+
 vfs_t *
 vfs_allocate( void )
 {
index f94ce05153c3f2395e4e0466c7c2a53773402f9a..dc1cd1973dda29217825155f4e4a72919d4976b7 100644 (file)
@@ -112,6 +112,7 @@ typedef int (*vfs_quotactl_t)(bhv_desc_t *, int, int, caddr_t);
 typedef void   (*vfs_init_vnode_t)(bhv_desc_t *,
                                struct vnode *, bhv_desc_t *, int);
 typedef void   (*vfs_force_shutdown_t)(bhv_desc_t *, int, char *, int);
+typedef void   (*vfs_freeze_t)(bhv_desc_t *);
 
 typedef struct vfsops {
        bhv_position_t          vf_position;    /* behavior chain position */
@@ -128,6 +129,7 @@ typedef struct vfsops {
        vfs_quotactl_t          vfs_quotactl;   /* disk quota */
        vfs_init_vnode_t        vfs_init_vnode; /* initialize a new vnode */
        vfs_force_shutdown_t    vfs_force_shutdown;     /* crash and burn */
+       vfs_freeze_t            vfs_freeze;     /* freeze fs for snapshot */
 } vfsops_t;
 
 /*
@@ -147,6 +149,7 @@ typedef struct vfsops {
 #define VFS_QUOTACTL(v, c,id,p, rv)    ((rv) = vfs_quotactl(VHEAD(v), c,id,p))
 #define VFS_INIT_VNODE(v, vp,b,ul)     ( vfs_init_vnode(VHEAD(v), vp,b,ul) )
 #define VFS_FORCE_SHUTDOWN(v, fl,f,l)  ( vfs_force_shutdown(VHEAD(v), fl,f,l) )
+#define VFS_FREEZE(v)                  ( vfs_freeze(VHEAD(v)) )
 
 /*
  * PVFS's.  Operates on behavior descriptor pointers.
@@ -164,6 +167,7 @@ typedef struct vfsops {
 #define PVFS_QUOTACTL(b, c,id,p, rv)   ((rv) = vfs_quotactl(b, c,id,p))
 #define PVFS_INIT_VNODE(b, vp,b2,ul)   ( vfs_init_vnode(b, vp,b2,ul) )
 #define PVFS_FORCE_SHUTDOWN(b, fl,f,l) ( vfs_force_shutdown(b, fl,f,l) )
+#define PVFS_FREEZE(b)                 ( vfs_freeze(b) )
 
 extern int vfs_mount(bhv_desc_t *, struct xfs_mount_args *, struct cred *);
 extern int vfs_parseargs(bhv_desc_t *, char *, struct xfs_mount_args *, int);
@@ -178,6 +182,7 @@ extern int vfs_dmapiops(bhv_desc_t *, caddr_t);
 extern int vfs_quotactl(bhv_desc_t *, int, int, caddr_t);
 extern void vfs_init_vnode(bhv_desc_t *, struct vnode *, bhv_desc_t *, int);
 extern void vfs_force_shutdown(bhv_desc_t *, int, char *, int);
+extern void vfs_freeze(bhv_desc_t *);
 
 typedef struct bhv_vfsops {
        struct vfsops           bhv_common;
index d6a6d056c34e0bb62e68a8526a79118ef5bf133c..37b28e59e8c138ccd3ca33cb2971c6d323b4fa38 100644 (file)
@@ -581,64 +581,26 @@ xfs_fs_log_dummy(xfs_mount_t *mp)
        xfs_iunlock(ip, XFS_ILOCK_EXCL);
 }
 
-int
-xfs_fs_freeze(
-       xfs_mount_t     *mp)
-{
-       vfs_t           *vfsp;
-       /*REFERENCED*/
-       int             error;
-
-       vfsp = XFS_MTOVFS(mp);
-
-       /* Stop new writers */
-       xfs_start_freeze(mp, XFS_FREEZE_WRITE);
-
-       /* Flush the refcache */
-       xfs_refcache_purge_mp(mp);
-
-       /* Flush delalloc and delwri data */
-       VFS_SYNC(vfsp, SYNC_DELWRI|SYNC_WAIT, NULL, error);
-
-       /* Pause transaction subsystem */
-       xfs_start_freeze(mp, XFS_FREEZE_TRANS);
-
-       /* Flush any remaining inodes into buffers */
-       VFS_SYNC(vfsp, SYNC_ATTR|SYNC_WAIT, NULL, error);
-
-       /* Push all buffers out to disk */
-       xfs_binval(mp->m_ddev_targp);
-       if (mp->m_rtdev_targp) {
-               xfs_binval(mp->m_rtdev_targp);
-       }
-
-       /* Push the superblock and write an unmount record */
-       xfs_log_unmount_write(mp);
-       xfs_unmountfs_writesb(mp);
-
-       return 0;
-}
-
-int
-xfs_fs_thaw(
-       xfs_mount_t     *mp)
-{
-       xfs_finish_freeze(mp);
-       return 0;
-}
-
 int
 xfs_fs_goingdown(
        xfs_mount_t     *mp,
        __uint32_t      inflags)
 {
-       switch (inflags)
-       {
-       case XFS_FSOP_GOING_FLAGS_DEFAULT:
-               xfs_fs_freeze(mp);
-               xfs_force_shutdown(mp, XFS_FORCE_UMOUNT);
-               xfs_fs_thaw(mp);
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
+       switch (inflags) {
+       case XFS_FSOP_GOING_FLAGS_DEFAULT: {
+               struct vfs *vfsp = XFS_MTOVFS(mp);
+               struct super_block *sb = freeze_bdev(vfsp->vfs_super->s_bdev);
+
+               if (sb) {
+                       xfs_force_shutdown(mp, XFS_FORCE_UMOUNT);
+                       thaw_bdev(sb->s_bdev, sb);
+               }
+
                break;
+       }
        case XFS_FSOP_GOING_FLAGS_LOGFLUSH:
                xfs_force_shutdown(mp, XFS_FORCE_UMOUNT);
                break;
index 70b0f125767bc12575a91e68534b9c096b0f8690..b61486173a610e8810cb756fa9526125beab562f 100644 (file)
@@ -59,14 +59,6 @@ xfs_reserve_blocks(
        __uint64_t              *inval,
        xfs_fsop_resblks_t      *outval);
 
-int
-xfs_fs_freeze(
-       xfs_mount_t             *mp);
-
-int
-xfs_fs_thaw(
-       xfs_mount_t             *mp);
-
 int
 xfs_fs_goingdown(
        xfs_mount_t             *mp,
index 9ff45c11d3c8d6bf2fa7bdb6965173ed73af2b50..8505f1d35429093780c502b8135da07ada748e6a 100644 (file)
@@ -820,7 +820,7 @@ xfs_log_need_covered(xfs_mount_t *mp)
        xlog_t          *log = mp->m_log;
        vfs_t           *vfsp = XFS_MTOVFS(mp);
 
-       if (mp->m_frozen || XFS_FORCED_SHUTDOWN(mp) ||
+       if (vfsp->vfs_super->s_frozen || XFS_FORCED_SHUTDOWN(mp) ||
            (vfsp->vfs_flag & VFS_RDONLY))
                return 0;
 
index e9039e8842b0ab016a8d94d3bf669fa02de7e08b..56d104d21e63bfcc736e3c6ea5b96b003a64d3fd 100644 (file)
@@ -140,9 +140,6 @@ xfs_mount_init(void)
         */
        xfs_trans_ail_init(mp);
 
-       /* Init freeze sync structures */
-       spinlock_init(&mp->m_freeze_lock, "xfs_freeze");
-       init_sv(&mp->m_wait_unfreeze, SV_DEFAULT, "xfs_freeze", 0);
        atomic_set(&mp->m_active_trans, 0);
 
        return mp;
@@ -192,8 +189,6 @@ xfs_mount_free(
                VFS_REMOVEBHV(vfsp, &mp->m_bhv);
        }
 
-       spinlock_destroy(&mp->m_freeze_lock);
-       sv_destroy(&mp->m_wait_unfreeze);
        kmem_free(mp, sizeof(xfs_mount_t));
 }
 
@@ -1586,59 +1581,3 @@ xfs_mount_log_sbunit(
        xfs_mod_sb(tp, fields);
        xfs_trans_commit(tp, 0, NULL);
 }
-
-/* Functions to lock access out of the filesystem for forced
- * shutdown or snapshot.
- */
-
-void
-xfs_start_freeze(
-       xfs_mount_t     *mp,
-       int             level)
-{
-       unsigned long   s = mutex_spinlock(&mp->m_freeze_lock);
-
-       mp->m_frozen = level;
-       mutex_spinunlock(&mp->m_freeze_lock, s);
-
-       if (level == XFS_FREEZE_TRANS) {
-               while (atomic_read(&mp->m_active_trans) > 0)
-                       delay(100);
-       }
-}
-
-void
-xfs_finish_freeze(
-       xfs_mount_t     *mp)
-{
-       unsigned long   s = mutex_spinlock(&mp->m_freeze_lock);
-
-       if (mp->m_frozen) {
-               mp->m_frozen = 0;
-               sv_broadcast(&mp->m_wait_unfreeze);
-       }
-
-       mutex_spinunlock(&mp->m_freeze_lock, s);
-}
-
-void
-xfs_check_frozen(
-       xfs_mount_t     *mp,
-       bhv_desc_t      *bdp,
-       int             level)
-{
-       unsigned long   s;
-
-       if (mp->m_frozen) {
-               s = mutex_spinlock(&mp->m_freeze_lock);
-
-               if (mp->m_frozen < level) {
-                       mutex_spinunlock(&mp->m_freeze_lock, s);
-               } else {
-                       sv_wait(&mp->m_wait_unfreeze, 0, &mp->m_freeze_lock, s);
-               }
-       }
-
-       if (level == XFS_FREEZE_TRANS)
-               atomic_inc(&mp->m_active_trans);
-}
index ea86fbaffd407a945dc8babb39af8ad9336abc51..e338e32d346df2239ce1b2f691a20a1e4d0761a3 100644 (file)
@@ -379,10 +379,6 @@ typedef struct xfs_mount {
        struct xfs_dmops        m_dm_ops;       /* vector of DMI ops */
        struct xfs_qmops        m_qm_ops;       /* vector of XQM ops */
        struct xfs_ioops        m_io_ops;       /* vector of I/O ops */
-       lock_t                  m_freeze_lock;  /* Lock for m_frozen */
-       uint                    m_frozen;       /* FS frozen for shutdown or
-                                                * snapshot */
-       sv_t                    m_wait_unfreeze;/* waiting to unfreeze */
        atomic_t                m_active_trans; /* number trans frozen */
 } xfs_mount_t;
 
@@ -558,16 +554,6 @@ extern void        xfs_initialize_perag(xfs_mount_t *, int);
 extern void    xfs_xlatesb(void *, struct xfs_sb *, int, xfs_arch_t,
                        __int64_t);
 
-/*
- * Flags for freeze operations.
- */
-#define XFS_FREEZE_WRITE       1
-#define XFS_FREEZE_TRANS       2
-
-extern void    xfs_start_freeze(xfs_mount_t *, int);
-extern void    xfs_finish_freeze(xfs_mount_t *);
-extern void    xfs_check_frozen(xfs_mount_t *, bhv_desc_t *, int);
-
 extern struct vfsops xfs_vfsops;
 extern struct vnodeops xfs_vnodeops;
 
index af07bd91b81e1f2624b7b851d774f41e5a02940f..aebea7a293d65b662dc1a3c4cfff3792abf44a5d 100644 (file)
@@ -131,7 +131,9 @@ xfs_trans_alloc(
        xfs_mount_t     *mp,
        uint            type)
 {
-       xfs_check_frozen(mp, NULL, XFS_FREEZE_TRANS);
+       vfs_check_frozen(XFS_MTOVFS(mp)->vfs_super, SB_FREEZE_TRANS);
+       atomic_inc(&mp->m_active_trans);
+
        return (_xfs_trans_alloc(mp, type));
 
 }
index e0bbdbef441a617100f535d179ea5d43a91310e7..3d6822de23eb53a100d172686904b27c4759ddc0 100644 (file)
@@ -1858,6 +1858,20 @@ xfs_showargs(
        return 0;
 }
 
+STATIC void
+xfs_freeze(
+       bhv_desc_t      *bdp)
+{
+       xfs_mount_t     *mp = XFS_BHVTOM(bdp);
+
+       while (atomic_read(&mp->m_active_trans) > 0)
+               delay(100);
+
+       /* Push the superblock and write an unmount record */
+       xfs_log_unmount_write(mp);
+       xfs_unmountfs_writesb(mp);
+}
+
 
 vfsops_t xfs_vfsops = {
        BHV_IDENTITY_INIT(VFS_BHV_XFS,VFS_POSITION_XFS),
@@ -1874,4 +1888,5 @@ vfsops_t xfs_vfsops = {
        .vfs_quotactl           = (vfs_quotactl_t)fs_nosys,
        .vfs_init_vnode         = xfs_initialize_vnode,
        .vfs_force_shutdown     = xfs_do_force_shutdown,
+       .vfs_freeze             = xfs_freeze,
 };