From: Christoph Hellwig 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. --- 25-akpm/fs/xfs/linux/xfs_ioctl.c | 5 +- 25-akpm/fs/xfs/linux/xfs_lrw.c | 2 - 25-akpm/fs/xfs/linux/xfs_super.c | 24 -------------- 25-akpm/fs/xfs/linux/xfs_vfs.c | 12 +++++++ 25-akpm/fs/xfs/linux/xfs_vfs.h | 5 ++ 25-akpm/fs/xfs/xfs_fsops.c | 66 ++++++++------------------------------- 25-akpm/fs/xfs/xfs_fsops.h | 8 ---- 25-akpm/fs/xfs/xfs_log.c | 2 - 25-akpm/fs/xfs/xfs_mount.c | 61 ------------------------------------ 25-akpm/fs/xfs/xfs_mount.h | 14 -------- 25-akpm/fs/xfs/xfs_trans.c | 4 +- 25-akpm/fs/xfs/xfs_vfsops.c | 15 ++++++++ 12 files changed, 54 insertions(+), 164 deletions(-) diff -puN fs/xfs/linux/xfs_ioctl.c~lockfs-xfs-bits fs/xfs/linux/xfs_ioctl.c --- 25/fs/xfs/linux/xfs_ioctl.c~lockfs-xfs-bits 2004-04-17 16:30:24.131961544 -0700 +++ 25-akpm/fs/xfs/linux/xfs_ioctl.c 2004-04-17 16:30:24.159957288 -0700 @@ -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 -puN fs/xfs/linux/xfs_lrw.c~lockfs-xfs-bits fs/xfs/linux/xfs_lrw.c --- 25/fs/xfs/linux/xfs_lrw.c~lockfs-xfs-bits 2004-04-17 16:30:24.133961240 -0700 +++ 25-akpm/fs/xfs/linux/xfs_lrw.c 2004-04-17 16:30:24.160957136 -0700 @@ -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 -puN fs/xfs/linux/xfs_super.c~lockfs-xfs-bits fs/xfs/linux/xfs_super.c --- 25/fs/xfs/linux/xfs_super.c~lockfs-xfs-bits 2004-04-17 16:30:24.134961088 -0700 +++ 25-akpm/fs/xfs/linux/xfs_super.c 2004-04-17 16:30:24.161956984 -0700 @@ -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 -puN fs/xfs/linux/xfs_vfs.c~lockfs-xfs-bits fs/xfs/linux/xfs_vfs.c --- 25/fs/xfs/linux/xfs_vfs.c~lockfs-xfs-bits 2004-04-17 16:30:24.135960936 -0700 +++ 25-akpm/fs/xfs/linux/xfs_vfs.c 2004-04-17 16:30:24.161956984 -0700 @@ -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 -puN fs/xfs/linux/xfs_vfs.h~lockfs-xfs-bits fs/xfs/linux/xfs_vfs.h --- 25/fs/xfs/linux/xfs_vfs.h~lockfs-xfs-bits 2004-04-17 16:30:24.137960632 -0700 +++ 25-akpm/fs/xfs/linux/xfs_vfs.h 2004-04-17 16:30:24.162956832 -0700 @@ -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 -puN fs/xfs/xfs_fsops.c~lockfs-xfs-bits fs/xfs/xfs_fsops.c --- 25/fs/xfs/xfs_fsops.c~lockfs-xfs-bits 2004-04-17 16:30:24.138960480 -0700 +++ 25-akpm/fs/xfs/xfs_fsops.c 2004-04-17 16:30:24.151958504 -0700 @@ -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 -puN fs/xfs/xfs_fsops.h~lockfs-xfs-bits fs/xfs/xfs_fsops.h --- 25/fs/xfs/xfs_fsops.h~lockfs-xfs-bits 2004-04-17 16:30:24.140960176 -0700 +++ 25-akpm/fs/xfs/xfs_fsops.h 2004-04-17 16:30:24.151958504 -0700 @@ -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 -puN fs/xfs/xfs_log.c~lockfs-xfs-bits fs/xfs/xfs_log.c --- 25/fs/xfs/xfs_log.c~lockfs-xfs-bits 2004-04-17 16:30:24.142959872 -0700 +++ 25-akpm/fs/xfs/xfs_log.c 2004-04-17 16:30:24.154958048 -0700 @@ -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 -puN fs/xfs/xfs_mount.c~lockfs-xfs-bits fs/xfs/xfs_mount.c --- 25/fs/xfs/xfs_mount.c~lockfs-xfs-bits 2004-04-17 16:30:24.143959720 -0700 +++ 25-akpm/fs/xfs/xfs_mount.c 2004-04-17 16:30:24.155957896 -0700 @@ -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 -puN fs/xfs/xfs_mount.h~lockfs-xfs-bits fs/xfs/xfs_mount.h --- 25/fs/xfs/xfs_mount.h~lockfs-xfs-bits 2004-04-17 16:30:24.145959416 -0700 +++ 25-akpm/fs/xfs/xfs_mount.h 2004-04-17 16:30:24.156957744 -0700 @@ -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 -puN fs/xfs/xfs_trans.c~lockfs-xfs-bits fs/xfs/xfs_trans.c --- 25/fs/xfs/xfs_trans.c~lockfs-xfs-bits 2004-04-17 16:30:24.146959264 -0700 +++ 25-akpm/fs/xfs/xfs_trans.c 2004-04-17 16:30:24.157957592 -0700 @@ -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 -puN fs/xfs/xfs_vfsops.c~lockfs-xfs-bits fs/xfs/xfs_vfsops.c --- 25/fs/xfs/xfs_vfsops.c~lockfs-xfs-bits 2004-04-17 16:30:24.147959112 -0700 +++ 25-akpm/fs/xfs/xfs_vfsops.c 2004-04-17 16:30:24.158957440 -0700 @@ -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, }; _