Fix XFS to work with the new VFS-lock patch. --- diff/fs/xfs/linux/xfs_ioctl.c 2004-04-06 15:53:42.984093632 +0100 +++ source/fs/xfs/linux/xfs_ioctl.c 2004-04-06 15:54:28.804127928 +0100 @@ -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: { --- diff/fs/xfs/linux/xfs_lrw.c 2004-03-11 10:20:28.000000000 +0000 +++ source/fs/xfs/linux/xfs_lrw.c 2004-04-06 15:54:28.805127776 +0100 @@ -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; } --- diff/fs/xfs/linux/xfs_super.c 2004-04-06 15:53:42.985093480 +0100 +++ source/fs/xfs/linux/xfs_super.c 2004-04-06 15:54:28.805127776 +0100 @@ -612,28 +612,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 * @@ -873,7 +852,6 @@ STATIC struct super_operations linvfs_so .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, --- diff/fs/xfs/linux/xfs_vfs.c 2004-04-06 15:53:42.986093328 +0100 +++ source/fs/xfs/linux/xfs_vfs.c 2004-04-06 15:54:28.806127624 +0100 @@ -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 ) { --- diff/fs/xfs/linux/xfs_vfs.h 2004-04-06 15:53:42.987093176 +0100 +++ source/fs/xfs/linux/xfs_vfs.h 2004-04-06 15:54:28.806127624 +0100 @@ -114,6 +114,7 @@ typedef int (*vfs_quotactl_t)(bhv_desc_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 */ @@ -130,6 +131,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; /* @@ -149,6 +151,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. @@ -166,6 +169,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); @@ -180,6 +184,7 @@ extern int vfs_dmapiops(bhv_desc_t *, ca 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; --- diff/fs/xfs/xfs_fsops.c 2004-03-11 10:20:28.000000000 +0000 +++ source/fs/xfs/xfs_fsops.c 2004-04-06 15:54:28.807127472 +0100 @@ -582,63 +582,25 @@ xfs_fs_log_dummy(xfs_mount_t *mp) } 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; --- diff/fs/xfs/xfs_fsops.h 2004-03-11 10:20:28.000000000 +0000 +++ source/fs/xfs/xfs_fsops.h 2004-04-06 15:54:28.807127472 +0100 @@ -60,14 +60,6 @@ xfs_reserve_blocks( 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, __uint32_t inflags); --- diff/fs/xfs/xfs_log.c 2004-04-05 12:57:08.000000000 +0100 +++ source/fs/xfs/xfs_log.c 2004-04-06 15:54:28.809127168 +0100 @@ -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; --- diff/fs/xfs/xfs_mount.c 2004-04-05 12:57:08.000000000 +0100 +++ source/fs/xfs/xfs_mount.c 2004-04-06 15:54:28.810127016 +0100 @@ -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); -} --- diff/fs/xfs/xfs_mount.h 2004-03-11 10:20:28.000000000 +0000 +++ source/fs/xfs/xfs_mount.h 2004-04-06 15:54:28.810127016 +0100 @@ -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_mou 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; --- diff/fs/xfs/xfs_trans.c 2004-04-05 12:57:08.000000000 +0100 +++ source/fs/xfs/xfs_trans.c 2004-04-06 15:54:28.811126864 +0100 @@ -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)); } --- diff/fs/xfs/xfs_vfsops.c 2004-04-05 12:57:08.000000000 +0100 +++ source/fs/xfs/xfs_vfsops.c 2004-04-06 15:54:28.812126712 +0100 @@ -1549,6 +1549,11 @@ xfs_syncsub( } } + if (XFS_MTOVFS(mp)->vfs_super->s_frozen == SB_FREEZE_TRANS) { + while (atomic_read(&mp->m_active_trans) > 0) + delay(100); + } + return XFS_ERROR(last_error); } @@ -1858,6 +1863,17 @@ xfs_showargs( return 0; } +STATIC void +xfs_freeze( + bhv_desc_t *bdp) +{ + xfs_mount_t *mp = XFS_BHVTOM(bdp); + + /* 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 +1890,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, };