lockfs - vfs bits
PATCH 1/3 lockfs - vfs bits
These are the generic lockfs bits. Basically it takes the XFS freezing statemachine into the VFS. It's all behind the kernel-doc documented freeze_bdev and thaw_bdev interfaces.
Based on an older patch from Chris Mason.
fs/block_dev.c +1 -0
@@ -251,6 +251,7 @@ {memset (bdev,0 ,sizeof (*bdev));sema_init (&bdev->bd_sem,1 ); +sema_init (&bdev->bd_mount_sem,1 );INIT_LIST_HEAD (&bdev->bd_inodes);INIT_LIST_HEAD (&bdev->bd_list);inode_init_once (&ei->vfs_inode);
===== fs/buffer.c 1.235 vs edited =====
fs/buffer.c +71 -0
77 lines not on this page · raw message
===== fs/super.c 1.116 vs edited =====
fs/super.c +8 -0
@@ -77,6 +77,7 @@sema_init (&s->s_dquot.dqio_sem,1 );sema_init (&s->s_dquot.dqonoff_sem,1 );init_rwsem (&s->s_dquot.dqptr_sem); +init_waitqueue_head (&s->s_wait_unfrozen); s->s_maxbytes =MAX_NON_LFS ; s->dq_op = sb_dquot_ops; s->s_qcop = sb_quotactl_ops;
@@ -621,7 +622,14 @@if (IS_ERR (bdev))return (struct super_block *)bdev; +/* +* once the super is inserted into the list by sget, s_umount +* will protect the lockfs code from trying to start a snapshot +* while we are mounting +*/ +down (&bdev->bd_mount_sem); s =sget (fs_type, test_bdev_super, set_bdev_super, bdev); +up (&bdev->bd_mount_sem);if (IS_ERR (s)) goto out;
include/linux/buffer_head.h +2 -0
@@ -164,6 +164,8 @@wait_queue_head_t *bh_waitq_head (struct buffer_head *bh);void wake_up_buffer (struct buffer_head *bh);int fsync_bdev (struct block_device *); +struct super_block *freeze_bdev (struct block_device *); +void thaw_bdev (struct block_device *,struct super_block *);int fsync_super (struct super_block *);int fsync_no_super (struct block_device *);struct buffer_head *__find_get_block (struct block_device *,sector_t ,int );
include/linux/fs.h +16 -0
@@ -345,6 +345,7 @@struct inode * bd_inode;/* will die */ int bd_openers;struct semaphore bd_sem;/* open/close mutex */ +struct semaphore bd_mount_sem;/* mount mutex */ struct list_head bd_inodes;void * bd_holder;int bd_holders;
@@ -749,6 +750,9 @@struct list_head s_instances;struct quota_info s_dquot;/* Diskquota specific options */ +int s_frozen; +wait_queue_head_t s_wait_unfrozen; +char s_id[32 ];/* Informational name */ struct kobject kobj;/* anchor for sysfs */
@@ -760,6 +764,18 @@*/ struct semaphore s_vfs_rename_sem;/* Kludge */ }; + +/* +* Snapshotting support. +*/ +enum { +SB_UNFROZEN =0 , +SB_FREEZE_WRITE =1 , +SB_FREEZE_TRANS =2 , +}; + +#define vfs_check_frozen (sb, level) \ + wait_event((sb)->s_wait_unfrozen, ((sb)->s_frozen < (level)))/* * Superblock locking.
Quoted 4 lines · Christoph Hellwig
These are the generic lockfs bits. Basically it takes the XFS freezing statemachine into the VFS. It's all behind the kernel-doc documented
freeze_bdevandthaw_bdevinterfaces.
Do we expect to see snapshotting patches for other filesystems arise as a result of this?
Quoted 8 lines · Andrew Morton
Quoted 4 lines · Christoph Hellwig
These are the generic lockfs bits. Basically it takes the XFS freezing statemachine into the VFS. It's all behind the kernel-doc documented
freeze_bdevandthaw_bdevinterfaces.Do we expect to see snapshotting patches for other filesystems arise as a result of this?
Other filesystems already implement the write_super_lockfs and unlockfs methods and should just work. An earlier version of this patch is in SuSE's tree and I think they've tested it with ext3 and reiserfs. Similarly even earlier variants are in the 2.4 vendor trees. Those filesystem don't really use the state machine to avoid starting new transactions, so to get results as reliable as XFS they need soem more work.
Quoted 8 lines · Andrew Morton
Quoted 4 lines · Christoph Hellwig
These are the generic lockfs bits. Basically it takes the XFS freezing statemachine into the VFS. It's all behind the kernel-doc documented
freeze_bdevandthaw_bdevinterfaces.Do we expect to see snapshotting patches for other filesystems arise as a result of this?
Reiserfs needs this one liner:
reiserfs_write_super_lockfs() is supposed to wait for the transaction to commit.
fs/reiserfs/super.c +1 -1
@@ -88,7 +88,7 @@ static void reiserfs_write_super_lockfsreiserfs_prepare_for_journal (s,SB_BUFFER_WITH_SB (s),1 );journal_mark_dirty (&th, s,SB_BUFFER_WITH_SB (s));reiserfs_block_writes (&th) ; -journal_end (&th, s,1 ) ; +journal_end_sync (&th, s,1 ) ; } s->s_dirt =0 ;reiserfs_write_unlock (s);