linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] LVM snapshot support for reiserfs and others
@ 2001-08-09 18:35 Chris Mason
  2001-08-09 19:22 ` Andreas Dilger
  0 siblings, 1 reply; 14+ messages in thread
From: Chris Mason @ 2001-08-09 18:35 UTC (permalink / raw)
  To: linux-kernel; +Cc: torvalds, viro, mge


Hello everyone,

This patch has been floating around for a while and is heavily used;
Heinz and I coded it last October or so.  Minor change in the port to
2.4.8-pre was moving the sync_supers call in fsync_dev_lockfs to match
the changes in fsync_dev.

It adds calls to make use of the write_super_lockfs and unlockfs 
callbacks, which allows the filesystem to do a full sync and block 
new writers while LVM creates a snapshot.  This way, the snapshot is actually 
consistent on creation.

There's one reiserfs hunk in there (also very old) to fix a
bug in my initial reiserfs_write_super_lockfs call.

Patch against 2.4.8-pre6, it won't apply on top of -ac due to
Al's changes.  I'm merging a bunch of stuff into -ac again,
I'll merge this as well.

Linus, please apply

-chris

diff -Nru a/drivers/md/lvm.c b/drivers/md/lvm.c
--- a/drivers/md/lvm.c	Thu Aug  9 14:28:30 2001
+++ b/drivers/md/lvm.c	Thu Aug  9 14:28:30 2001
@@ -162,7 +162,7 @@
 #define	DEVICE_OFF(device)
 
 /* lvm_do_lv_create calls fsync_dev_lockfs()/unlockfs() */
-/* #define	LVM_VFS_ENHANCEMENT */
+#define	LVM_VFS_ENHANCEMENT
 
 #include <linux/config.h>
 #include <linux/version.h>
diff -Nru a/fs/buffer.c b/fs/buffer.c
--- a/fs/buffer.c	Thu Aug  9 14:28:30 2001
+++ b/fs/buffer.c	Thu Aug  9 14:28:30 2001
@@ -367,6 +367,33 @@
 	fsync_dev(dev);
 }
 
+int fsync_dev_lockfs(kdev_t dev)
+{
+	sync_buffers(dev, 0);
+
+	lock_kernel();
+	/* note, the FS might need to start transactions to 
+	** sync the inodes, or the quota, no locking until
+	** after these are done
+	*/
+	sync_inodes(dev);
+	DQUOT_SYNC(dev);
+	/* if inodes or quotas could be dirtied during the
+	** sync_supers_lockfs call, the FS is responsible for getting
+	** them on disk, without deadlocking against the lock
+	**
+	** we call sync_supers first so that 
+	** fsync_dev_lockfs == fsync_dev for filesystems that don't provide
+	** a lockfs call.  Yes, it could be done in sync_supers_lockfs
+	** instead, but this just makes it more explicit...
+	*/
+	sync_supers(dev) ;
+	sync_supers_lockfs(dev) ;
+	unlock_kernel();
+
+	return sync_buffers(dev, 1) ;
+}
+
 asmlinkage long sys_sync(void)
 {
 	fsync_dev(0);
diff -Nru a/fs/reiserfs/super.c b/fs/reiserfs/super.c
--- a/fs/reiserfs/super.c	Thu Aug  9 14:28:30 2001
+++ b/fs/reiserfs/super.c	Thu Aug  9 14:28:30 2001
@@ -80,7 +80,7 @@
     reiserfs_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 = dirty;
   unlock_kernel() ;
diff -Nru a/fs/super.c b/fs/super.c
--- a/fs/super.c	Thu Aug  9 14:28:30 2001
+++ b/fs/super.c	Thu Aug  9 14:28:30 2001
@@ -672,6 +672,46 @@
 	}
 }
 
+/*
+ * Note: don't check the dirty flag before waiting, we want the lock
+ * to happen every time this is called.
+ */
+void sync_supers_lockfs(kdev_t dev)
+{
+	struct super_block * sb;
+
+	for (sb = sb_entry(super_blocks.next);
+	     sb != sb_entry(&super_blocks); 
+	     sb = sb_entry(sb->s_list.next)) {
+		if (!sb->s_dev)
+			continue;
+		if (dev && sb->s_dev != dev)
+			continue;
+		lock_super(sb);
+		if (sb->s_dev && (!dev || dev == sb->s_dev))
+			if (sb->s_op && sb->s_op->write_super_lockfs)
+				sb->s_op->write_super_lockfs(sb);
+		unlock_super(sb);
+	}
+}
+
+void unlockfs(kdev_t dev)
+{
+	struct super_block * sb;
+
+	for (sb = sb_entry(super_blocks.next);
+	     sb != sb_entry(&super_blocks); 
+	     sb = sb_entry(sb->s_list.next)) {
+		if (!sb->s_dev)
+			continue;
+		if (dev && sb->s_dev != dev)
+			continue;
+		if (sb->s_dev && (!dev || dev == sb->s_dev))
+			if (sb->s_op && sb->s_op->unlockfs)
+				sb->s_op->unlockfs(sb);
+	}
+}
+
 /**
  *	get_super	-	get the superblock of a device
  *	@dev: device to get the superblock for
diff -Nru a/include/linux/fs.h b/include/linux/fs.h
--- a/include/linux/fs.h	Thu Aug  9 14:28:30 2001
+++ b/include/linux/fs.h	Thu Aug  9 14:28:30 2001
@@ -1160,6 +1160,7 @@
 extern void write_inode_now(struct inode *, int);
 extern void sync_dev(kdev_t);
 extern int fsync_dev(kdev_t);
+extern int fsync_dev_lockfs(kdev_t);
 extern int fsync_super(struct super_block *);
 extern void sync_inodes_sb(struct super_block *);
 extern int fsync_inode_buffers(struct inode *);
@@ -1168,6 +1169,8 @@
 extern void filemap_fdatasync(struct address_space *);
 extern void filemap_fdatawait(struct address_space *);
 extern void sync_supers(kdev_t);
+extern void sync_supers_lockfs(kdev_t);
+extern void unlockfs(kdev_t);
 extern int bmap(struct inode *, int);
 extern int notify_change(struct dentry *, struct iattr *);
 extern int permission(struct inode *, int);
diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c
--- a/kernel/ksyms.c	Thu Aug  9 14:28:30 2001
+++ b/kernel/ksyms.c	Thu Aug  9 14:28:30 2001
@@ -176,6 +176,8 @@
 EXPORT_SYMBOL(invalidate_inode_pages);
 EXPORT_SYMBOL(truncate_inode_pages);
 EXPORT_SYMBOL(fsync_dev);
+EXPORT_SYMBOL(fsync_dev_lockfs);
+EXPORT_SYMBOL(unlockfs);
 EXPORT_SYMBOL(permission);
 EXPORT_SYMBOL(vfs_permission);
 EXPORT_SYMBOL(inode_setattr);


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] LVM snapshot support for reiserfs and others
  2001-08-09 18:35 [PATCH] LVM snapshot support for reiserfs and others Chris Mason
@ 2001-08-09 19:22 ` Andreas Dilger
  2001-08-09 20:34   ` Chris Mason
  0 siblings, 1 reply; 14+ messages in thread
From: Andreas Dilger @ 2001-08-09 19:22 UTC (permalink / raw)
  To: Chris Mason; +Cc: linux-kernel, torvalds, viro, lvm-devel

Chris Mason writes:
> Minor change in the port to 2.4.8-pre was moving the sync_supers call
> in fsync_dev_lockfs to match the changes in fsync_dev.

Good...

> +	** we call sync_supers first so that 
> +	** fsync_dev_lockfs == fsync_dev for filesystems that don't provide
> +	** a lockfs call.  Yes, it could be done in sync_supers_lockfs
> +	** instead, but this just makes it more explicit...

I would rather make it _less_ explicit, so that sync_supers_lockfs()
actually does the sb->s_op->write_super() call for us...  Why?  Because
we are already traversing the supers list at this function, and there is
no reason to waste the CPU cycles traversing this list twice.  I think
the name "sync_supers_lockfs" is clear enough in showing that it is a
superset of "sync_supers" (try saying that 5 times fast ;-).

On a similar note, it is redundant that LVM calls fsync_dev() AND
fsync_dev_lockfs() if LVM_VFS_ENHANCEMENT is defined.  From the above
reasoning (to only walk the supers list once) it would make sense to
call only *_lockfs() if it is available.

On an "add this patch to the kernel, please" note, support for the
write_super_lockfs() VFS method is already in ext3, so it is a good
thing, with the above caveats.

Cheers, Andreas

PS - I changed the CC list to have lvm-devel@ instead of mge@sistina.com
-- 
Andreas Dilger  \ "If a man ate a pound of pasta and a pound of antipasto,
                 \  would they cancel out, leaving him still hungry?"
http://www-mddsp.enel.ucalgary.ca/People/adilger/               -- Dogbert


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] LVM snapshot support for reiserfs and others
  2001-08-09 19:22 ` Andreas Dilger
@ 2001-08-09 20:34   ` Chris Mason
  2001-08-09 20:58     ` Andreas Dilger
  0 siblings, 1 reply; 14+ messages in thread
From: Chris Mason @ 2001-08-09 20:34 UTC (permalink / raw)
  To: Andreas Dilger; +Cc: linux-kernel, torvalds, viro, lvm-devel



On Thursday, August 09, 2001 01:22:56 PM -0600 Andreas Dilger <adilger@turbolinux.com> wrote:

>
> On an "add this patch to the kernel, please" note, support for the
> write_super_lockfs() VFS method is already in ext3, so it is a good
> thing, with the above caveats.
> 

Ok, recoding with these suggestions.  I'll need an ext3 tester, please
drop me a line if you are willing ;-)

-chris


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] LVM snapshot support for reiserfs and others
  2001-08-09 20:34   ` Chris Mason
@ 2001-08-09 20:58     ` Andreas Dilger
  2001-08-09 22:20       ` Chris Mason
  0 siblings, 1 reply; 14+ messages in thread
From: Andreas Dilger @ 2001-08-09 20:58 UTC (permalink / raw)
  To: Chris Mason; +Cc: Andreas Dilger, linux-kernel, torvalds, viro, lvm-devel

Chris, you write:
> Andreas Dilger <adilger@turbolinux.com> wrote:
> > On an "add this patch to the kernel, please" note, support for the
> > write_super_lockfs() VFS method is already in ext3, so it is a good
> > thing, with the above caveats.
> 
> Ok, recoding with these suggestions.  I'll need an ext3 tester, please
> drop me a line if you are willing ;-)

Consider it tested.  I already have my code changed like I suggested, but
never heard back the last time I mentioned it.  In the end I don't think
the changes can have a behaviour impact other than a small CPU savings,
and a few lines of comments removed.

Cheers, Andreas
-- 
Andreas Dilger  \ "If a man ate a pound of pasta and a pound of antipasto,
                 \  would they cancel out, leaving him still hungry?"
http://www-mddsp.enel.ucalgary.ca/People/adilger/               -- Dogbert


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] LVM snapshot support for reiserfs and others
  2001-08-09 20:58     ` Andreas Dilger
@ 2001-08-09 22:20       ` Chris Mason
  2001-08-09 22:24         ` Alexander Viro
  0 siblings, 1 reply; 14+ messages in thread
From: Chris Mason @ 2001-08-09 22:20 UTC (permalink / raw)
  To: Andreas Dilger; +Cc: linux-kernel, torvalds, viro, lvm-devel


Ok, here it is:

LVM_VFS_ENHANCEMENT #define is gone, lvm only calls fsync_dev_lockfs
when syncing for the snapshot

sync_supers_lockfs calls write_super if the super is dirty,
and write_super_lockfs (regardless of dirty state).

Works on reiserfs and ext2, should not break other filesystems
using the old patch.

updated to 2.4.8-pre7

-chris

diff -Nru a/drivers/md/lvm.c b/drivers/md/lvm.c
--- a/drivers/md/lvm.c	Thu Aug  9 18:17:52 2001
+++ b/drivers/md/lvm.c	Thu Aug  9 18:17:52 2001
@@ -161,9 +161,6 @@
 #define MAJOR_NR	LVM_BLK_MAJOR
 #define	DEVICE_OFF(device)
 
-/* lvm_do_lv_create calls fsync_dev_lockfs()/unlockfs() */
-/* #define	LVM_VFS_ENHANCEMENT */
-
 #include <linux/config.h>
 #include <linux/version.h>
 #include <linux/module.h>
@@ -2321,12 +2318,8 @@
 	if (lv_ptr->lv_access & LV_SNAPSHOT) {
 		lv_t *org = lv_ptr->lv_snapshot_org, *last;
 
-		/* sync the original logical volume */
-		fsync_dev(org->lv_dev);
-#ifdef	LVM_VFS_ENHANCEMENT
 		/* VFS function call to sync and lock the filesystem */
 		fsync_dev_lockfs(org->lv_dev);
-#endif
 
 		down(&org->lv_snapshot_sem);
 		org->lv_access |= LV_SNAPSHOT_ORG;
@@ -2346,12 +2339,10 @@
 	else
 		set_device_ro(lv_ptr->lv_dev, 1);
 
-#ifdef	LVM_VFS_ENHANCEMENT
 /* VFS function call to unlock the filesystem */
 	if (lv_ptr->lv_access & LV_SNAPSHOT) {
 		unlockfs(lv_ptr->lv_snapshot_org->lv_dev);
 	}
-#endif
 
 	lv_ptr->vg = vg_ptr;
 
diff -Nru a/fs/buffer.c b/fs/buffer.c
--- a/fs/buffer.c	Thu Aug  9 18:17:52 2001
+++ b/fs/buffer.c	Thu Aug  9 18:17:52 2001
@@ -368,6 +368,27 @@
 	fsync_dev(dev);
 }
 
+int fsync_dev_lockfs(kdev_t dev)
+{
+	sync_buffers(dev, 0);
+
+	lock_kernel();
+	/* note, the FS might need to start transactions to 
+	** sync the inodes, or the quota, no locking until
+	** after these are done
+	*/
+	sync_inodes(dev);
+	DQUOT_SYNC(dev);
+	/* if inodes or quotas could be dirtied during the
+	** sync_supers_lockfs call, the FS is responsible for getting
+	** them on disk, without deadlocking against the lock
+	*/
+	sync_supers_lockfs(dev) ;
+	unlock_kernel();
+
+	return sync_buffers(dev, 1) ;
+}
+
 asmlinkage long sys_sync(void)
 {
 	fsync_dev(0);
diff -Nru a/fs/reiserfs/super.c b/fs/reiserfs/super.c
--- a/fs/reiserfs/super.c	Thu Aug  9 18:17:52 2001
+++ b/fs/reiserfs/super.c	Thu Aug  9 18:17:52 2001
@@ -80,7 +80,7 @@
     reiserfs_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 = dirty;
   unlock_kernel() ;
diff -Nru a/fs/super.c b/fs/super.c
--- a/fs/super.c	Thu Aug  9 18:17:52 2001
+++ b/fs/super.c	Thu Aug  9 18:17:52 2001
@@ -672,6 +672,49 @@
 	}
 }
 
+/*
+ * Note: don't check the dirty flag before waiting, we want the lock
+ * to happen every time this is called.
+ */
+void sync_supers_lockfs(kdev_t dev)
+{
+	struct super_block * sb;
+
+	for (sb = sb_entry(super_blocks.next);
+	     sb != sb_entry(&super_blocks); 
+	     sb = sb_entry(sb->s_list.next)) {
+		if (!sb->s_dev)
+			continue;
+		if (dev && sb->s_dev != dev)
+			continue;
+		lock_super(sb);
+		if (sb->s_dev && (!dev || dev == sb->s_dev)) {
+			if (sb->s_dirt && sb->s_op && sb->s_op->write_super)
+				sb->s_op->write_super(sb);
+			if (sb->s_op && sb->s_op->write_super_lockfs)
+				sb->s_op->write_super_lockfs(sb);
+		}
+		unlock_super(sb);
+	}
+}
+
+void unlockfs(kdev_t dev)
+{
+	struct super_block * sb;
+
+	for (sb = sb_entry(super_blocks.next);
+	     sb != sb_entry(&super_blocks); 
+	     sb = sb_entry(sb->s_list.next)) {
+		if (!sb->s_dev)
+			continue;
+		if (dev && sb->s_dev != dev)
+			continue;
+		if (sb->s_dev && (!dev || dev == sb->s_dev))
+			if (sb->s_op && sb->s_op->unlockfs)
+				sb->s_op->unlockfs(sb);
+	}
+}
+
 /**
  *	get_super	-	get the superblock of a device
  *	@dev: device to get the superblock for
diff -Nru a/include/linux/fs.h b/include/linux/fs.h
--- a/include/linux/fs.h	Thu Aug  9 18:17:52 2001
+++ b/include/linux/fs.h	Thu Aug  9 18:17:52 2001
@@ -1160,6 +1160,7 @@
 extern void write_inode_now(struct inode *, int);
 extern void sync_dev(kdev_t);
 extern int fsync_dev(kdev_t);
+extern int fsync_dev_lockfs(kdev_t);
 extern int fsync_super(struct super_block *);
 extern void sync_inodes_sb(struct super_block *);
 extern int fsync_inode_buffers(struct inode *);
@@ -1168,6 +1169,8 @@
 extern void filemap_fdatasync(struct address_space *);
 extern void filemap_fdatawait(struct address_space *);
 extern void sync_supers(kdev_t);
+extern void sync_supers_lockfs(kdev_t);
+extern void unlockfs(kdev_t);
 extern int bmap(struct inode *, int);
 extern int notify_change(struct dentry *, struct iattr *);
 extern int permission(struct inode *, int);
diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c
--- a/kernel/ksyms.c	Thu Aug  9 18:17:52 2001
+++ b/kernel/ksyms.c	Thu Aug  9 18:17:52 2001
@@ -176,6 +176,8 @@
 EXPORT_SYMBOL(invalidate_inode_pages);
 EXPORT_SYMBOL(truncate_inode_pages);
 EXPORT_SYMBOL(fsync_dev);
+EXPORT_SYMBOL(fsync_dev_lockfs);
+EXPORT_SYMBOL(unlockfs);
 EXPORT_SYMBOL(permission);
 EXPORT_SYMBOL(vfs_permission);
 EXPORT_SYMBOL(inode_setattr);




^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] LVM snapshot support for reiserfs and others
  2001-08-09 22:20       ` Chris Mason
@ 2001-08-09 22:24         ` Alexander Viro
  2001-08-09 22:42           ` Chris Mason
  0 siblings, 1 reply; 14+ messages in thread
From: Alexander Viro @ 2001-08-09 22:24 UTC (permalink / raw)
  To: Chris Mason; +Cc: Andreas Dilger, linux-kernel, torvalds, lvm-devel



On Thu, 9 Aug 2001, Chris Mason wrote:

> 
> Ok, here it is:
> 
> LVM_VFS_ENHANCEMENT #define is gone, lvm only calls fsync_dev_lockfs
> when syncing for the snapshot
> 
> sync_supers_lockfs calls write_super if the super is dirty,
> and write_super_lockfs (regardless of dirty state).
> 
> Works on reiserfs and ext2, should not break other filesystems
> using the old patch.
> 
> updated to 2.4.8-pre7

Chris, how about doing that after fs/super.c stuff (things that went into
-ac)?


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] LVM snapshot support for reiserfs and others
  2001-08-09 22:24         ` Alexander Viro
@ 2001-08-09 22:42           ` Chris Mason
  2001-08-09 23:26             ` Alexander Viro
  0 siblings, 1 reply; 14+ messages in thread
From: Chris Mason @ 2001-08-09 22:42 UTC (permalink / raw)
  To: Alexander Viro; +Cc: Andreas Dilger, linux-kernel, torvalds, lvm-devel



On Thursday, August 09, 2001 06:24:46 PM -0400 Alexander Viro <viro@math.psu.edu> wrote:

> Chris, how about doing that after fs/super.c stuff (things that went into
> -ac)?
> 

well, it depends on how soon the fs/super.c stuff goes in ;-)
I'd prefer to provide you with an updated patch for -ac, and get
this into the kernel sooner than later.  It's your call though, including
if you just want to hold off until I've got the -ac patch done.

-chris


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] LVM snapshot support for reiserfs and others
  2001-08-09 22:42           ` Chris Mason
@ 2001-08-09 23:26             ` Alexander Viro
  2001-08-09 23:50               ` Alexander Viro
  2001-08-10 19:49               ` Chris Mason
  0 siblings, 2 replies; 14+ messages in thread
From: Alexander Viro @ 2001-08-09 23:26 UTC (permalink / raw)
  To: Chris Mason; +Cc: Andreas Dilger, linux-kernel, torvalds, lvm-devel



On Thu, 9 Aug 2001, Chris Mason wrote:

> 
> 
> On Thursday, August 09, 2001 06:24:46 PM -0400 Alexander Viro <viro@math.psu.edu> wrote:
> 
> > Chris, how about doing that after fs/super.c stuff (things that went into
> > -ac)?
> > 
> 
> well, it depends on how soon the fs/super.c stuff goes in ;-)

That, in turn, depends on Linus. Since this stuff got public testing
in -ac (since 2.4.7-ac3) and since Linus had said that he doesn't mind
patches landing in his mailbox after each prerelease... ;-)

I'll resubmit that stuff - let's see when it gets applied...

> I'd prefer to provide you with an updated patch for -ac, and get
> this into the kernel sooner than later.  It's your call though, including
> if you just want to hold off until I've got the -ac patch done.

I think that doing variant against -ac first (or just fs/super.c stuff
that went into -ac) makes a lot of sense, since it will simplify testing.
We need this stuff in the tree and it's 2.4 matter - we need to close
the oopsen. I'd rather get tricky (and already debugged) stuff first
and then deal with relatively simple patch atop of it.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] LVM snapshot support for reiserfs and others
  2001-08-09 23:26             ` Alexander Viro
@ 2001-08-09 23:50               ` Alexander Viro
  2001-08-10 19:49               ` Chris Mason
  1 sibling, 0 replies; 14+ messages in thread
From: Alexander Viro @ 2001-08-09 23:50 UTC (permalink / raw)
  To: Chris Mason; +Cc: Andreas Dilger, linux-kernel, torvalds, lvm-devel



On Thu, 9 Aug 2001, Alexander Viro wrote:

> That, in turn, depends on Linus. Since this stuff got public testing
> in -ac (since 2.4.7-ac3) and since Linus had said that he doesn't mind

Sorry - -ac4, actually.


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] LVM snapshot support for reiserfs and others
  2001-08-09 23:26             ` Alexander Viro
  2001-08-09 23:50               ` Alexander Viro
@ 2001-08-10 19:49               ` Chris Mason
  2001-08-10 20:04                 ` Andrew Morton
                                   ` (2 more replies)
  1 sibling, 3 replies; 14+ messages in thread
From: Chris Mason @ 2001-08-10 19:49 UTC (permalink / raw)
  To: Alexander Viro; +Cc: Andreas Dilger, linux-kernel, torvalds, lvm-devel

 
Hi guys,

Here's a new patch against 2.4.8-pre8, updated to Al's new super
handling.  The differences between the original are small, 
but they are big enough that I want extra testing from the
LVM guys (and ext3/XFS).  Linus is just cc'd as an FYI.

Changes:

fsync_dev_lockfs(0) will just call fsync_dev instead of
trying to lock every FS on the system.  LVM always sends
a real device, so it doesn't change any of the current
users.  If someone wants to experiment with locking all
of them, let me know (I'm guessing you'll end up deadlocked
somewhere).

unlockfs() grabs mount_sem so that we don't race
against someone mounting the FS.  It can't lock the super
because somebody might be waiting for the FS to unlock
with the super lock already held.  

-chris

--- linux/include/linux/fs.h	Thu Aug  9 12:43:59 2001
+++ linux/include/linux/fs.h	Fri Aug 10 14:24:17 2001
@@ -1161,6 +1161,7 @@
 extern void write_inode_now(struct inode *, int);
 extern void sync_dev(kdev_t);
 extern int fsync_dev(kdev_t);
+extern int fsync_dev_lockfs(kdev_t);
 extern int fsync_super(struct super_block *);
 extern int fsync_no_super(kdev_t);
 extern void sync_inodes_sb(struct super_block *);
@@ -1170,6 +1171,8 @@
 extern void filemap_fdatasync(struct address_space *);
 extern void filemap_fdatawait(struct address_space *);
 extern void sync_supers(kdev_t);
+extern void sync_supers_lockfs(kdev_t);
+extern void unlockfs(kdev_t);
 extern int bmap(struct inode *, int);
 extern int notify_change(struct dentry *, struct iattr *);
 extern int permission(struct inode *, int);
--- linux/kernel/ksyms.c	Thu Aug  9 12:41:36 2001
+++ linux/kernel/ksyms.c	Fri Aug 10 14:03:49 2001
@@ -177,6 +177,8 @@
 EXPORT_SYMBOL(invalidate_inode_pages);
 EXPORT_SYMBOL(truncate_inode_pages);
 EXPORT_SYMBOL(fsync_dev);
+EXPORT_SYMBOL(fsync_dev_lockfs);
+EXPORT_SYMBOL(unlockfs);
 EXPORT_SYMBOL(permission);
 EXPORT_SYMBOL(vfs_permission);
 EXPORT_SYMBOL(inode_setattr);
--- linux/drivers/md/lvm.c	Wed Jul 11 12:35:37 2001
+++ linux/drivers/md/lvm.c	Fri Aug 10 14:03:49 2001
@@ -161,9 +161,6 @@
 #define MAJOR_NR	LVM_BLK_MAJOR
 #define	DEVICE_OFF(device)
 
-/* lvm_do_lv_create calls fsync_dev_lockfs()/unlockfs() */
-/* #define	LVM_VFS_ENHANCEMENT */
-
 #include <linux/config.h>
 #include <linux/version.h>
 #include <linux/module.h>
@@ -2321,12 +2318,8 @@
 	if (lv_ptr->lv_access & LV_SNAPSHOT) {
 		lv_t *org = lv_ptr->lv_snapshot_org, *last;
 
-		/* sync the original logical volume */
-		fsync_dev(org->lv_dev);
-#ifdef	LVM_VFS_ENHANCEMENT
 		/* VFS function call to sync and lock the filesystem */
 		fsync_dev_lockfs(org->lv_dev);
-#endif
 
 		down(&org->lv_snapshot_sem);
 		org->lv_access |= LV_SNAPSHOT_ORG;
@@ -2346,12 +2339,10 @@
 	else
 		set_device_ro(lv_ptr->lv_dev, 1);
 
-#ifdef	LVM_VFS_ENHANCEMENT
 /* VFS function call to unlock the filesystem */
 	if (lv_ptr->lv_access & LV_SNAPSHOT) {
 		unlockfs(lv_ptr->lv_snapshot_org->lv_dev);
 	}
-#endif
 
 	lv_ptr->vg = vg_ptr;
 
--- linux/fs/buffer.c	Thu Aug  9 12:41:36 2001
+++ linux/fs/buffer.c	Fri Aug 10 14:16:52 2001
@@ -374,6 +374,34 @@
 	fsync_dev(dev);
 }
 
+int fsync_dev_lockfs(kdev_t dev)
+{
+	/* you are not allowed to try locking all the filesystems
+	** on the system, your chances of getting through without
+	** total deadlock are slim to none.
+	*/
+	if (!dev)
+		return fsync_dev(dev) ;
+
+	sync_buffers(dev, 0);
+
+	lock_kernel();
+	/* note, the FS might need to start transactions to 
+	** sync the inodes, or the quota, no locking until
+	** after these are done
+	*/
+	sync_inodes(dev);
+	DQUOT_SYNC(dev);
+	/* if inodes or quotas could be dirtied during the
+	** sync_supers_lockfs call, the FS is responsible for getting
+	** them on disk, without deadlocking against the lock
+	*/
+	sync_supers_lockfs(dev) ;
+	unlock_kernel();
+
+	return sync_buffers(dev, 1) ;
+}
+
 asmlinkage long sys_sync(void)
 {
 	fsync_dev(0);
--- linux/fs/super.c	Thu Aug  9 12:41:36 2001
+++ linux/fs/super.c	Fri Aug 10 15:34:32 2001
@@ -681,6 +681,18 @@
 			sb->s_op->write_super(sb);
 	unlock_super(sb);
 }
+
+static inline void write_super_lockfs(struct super_block *sb)
+{
+	lock_super(sb);
+	if (sb->s_root) {
+		if (sb->s_dirt && sb->s_op && sb->s_op->write_super)
+			sb->s_op->write_super(sb);
+		if (sb->s_op && sb->s_op->write_super_lockfs)
+			sb->s_op->write_super_lockfs(sb);
+	}
+	unlock_super(sb);
+}
  
 /*
  * Note: check the dirty flag before waiting, so we don't
@@ -714,6 +726,48 @@
 		} else
 			sb = sb_entry(sb->s_list.next);
 	spin_unlock(&sb_lock);
+}
+
+/*
+ * Note: don't check the dirty flag before waiting, we want the lock
+ * to happen every time this is called.  dev must be non-zero
+ */
+void sync_supers_lockfs(kdev_t dev)
+{
+	struct super_block * sb;
+
+	if (dev) {
+		sb = get_super(dev);
+		if (sb) {
+			write_super_lockfs(sb);
+			drop_super(sb);
+		}
+	}
+}
+
+void unlockfs(kdev_t dev)
+{
+	struct super_block * sb;
+
+	if (dev) {
+		/* we cannot lock the super here because someone
+		** might be waiting on the unlock with the
+		** super already locked
+		**
+		** so, we grab the mount semaphore instead, we have
+		** to make sure nobody is mounting during our
+		** unlock operation.  The FS won't unmount because it
+		** was locked.
+		*/
+		down(&mount_sem);
+		sb = get_super(dev);
+		if (sb) {
+			if (sb->s_op && sb->s_op->unlockfs)
+				sb->s_op->unlockfs(sb) ;
+			drop_super(sb);
+		}
+		up(&mount_sem);
+	}
 }
 
 /**
--- linux/fs/reiserfs/super.c	Fri Jun 29 11:38:17 2001
+++ linux/fs/reiserfs/super.c	Fri Aug 10 15:17:08 2001
@@ -80,7 +80,7 @@
     reiserfs_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 = dirty;
   unlock_kernel() ;








^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] LVM snapshot support for reiserfs and others
  2001-08-10 19:49               ` Chris Mason
@ 2001-08-10 20:04                 ` Andrew Morton
  2001-08-14 20:25                 ` Andreas Dilger
  2001-08-22  4:06                 ` Chris Mason
  2 siblings, 0 replies; 14+ messages in thread
From: Andrew Morton @ 2001-08-10 20:04 UTC (permalink / raw)
  To: Chris Mason
  Cc: Alexander Viro, Andreas Dilger, linux-kernel, torvalds,
	lvm-devel, ext3-users

Chris Mason wrote:
> 
> 
> Hi guys,
> 
> Here's a new patch against 2.4.8-pre8, updated to Al's new super
> handling.  The differences between the original are small,
> but they are big enough that I want extra testing from the
> LVM guys (and ext3/XFS).

ext3 will probably lock up on unmount with 2.4.8-pre8.  The fix is
to replace fsync_dev with fsync_no_super in fs/ext3/super.c and
fs/jbd/recovery.c.  I'll be generating a new patchset this weekend.

-

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] LVM snapshot support for reiserfs and others
  2001-08-10 19:49               ` Chris Mason
  2001-08-10 20:04                 ` Andrew Morton
@ 2001-08-14 20:25                 ` Andreas Dilger
  2001-08-22  4:06                 ` Chris Mason
  2 siblings, 0 replies; 14+ messages in thread
From: Andreas Dilger @ 2001-08-14 20:25 UTC (permalink / raw)
  To: Chris Mason
  Cc: Alexander Viro, Andreas Dilger, linux-kernel, torvalds, lvm-devel

Chris writes:
> +static inline void write_super_lockfs(struct super_block *sb)
> +{
> +	lock_super(sb);
> +	if (sb->s_root) {
> +		if (sb->s_dirt && sb->s_op && sb->s_op->write_super)
> +			sb->s_op->write_super(sb);
> +		if (sb->s_op && sb->s_op->write_super_lockfs)
> +			sb->s_op->write_super_lockfs(sb);
> +	}
> +	unlock_super(sb);
> +}

Minor nit, could it be:
	if (sb->s_root && sb->s_op) {
		if (sb->s_dirt && sb->s_op->write_super)
			sb->s_op->write_super(sb);
		if (sb->s_op->write_super_lockfs)
			sb->s_op->write_super_lockfs(sb);
	}

I'm just going to do some testing...

Cheers, Andreas
-- 
Andreas Dilger  \ "If a man ate a pound of pasta and a pound of antipasto,
                 \  would they cancel out, leaving him still hungry?"
http://www-mddsp.enel.ucalgary.ca/People/adilger/               -- Dogbert


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] LVM snapshot support for reiserfs and others
  2001-08-10 19:49               ` Chris Mason
  2001-08-10 20:04                 ` Andrew Morton
  2001-08-14 20:25                 ` Andreas Dilger
@ 2001-08-22  4:06                 ` Chris Mason
  2 siblings, 0 replies; 14+ messages in thread
From: Chris Mason @ 2001-08-22  4:06 UTC (permalink / raw)
  To: alan, Alexander Viro; +Cc: Andreas Dilger, linux-kernel, lvm-devel


Ok, here's a version against 2.4.8-ac8, tested against ext2 and
reiserfs.  Andreas reported ext3 success with the last patch,
and none of the LVM guys have complained yet ;-)

BTW [sistina folks], it might be a good idea to update lvm-1.0.x 
the 2.4.4 VFS-lock patches no longer apply cleanly.

Alan, please include:

-chris

# allow LVM to lock the filesystem during snapshot creation, so the
# FS can flush pending changes and put things into a consistent state.
#
# includes small fix to current reiserfs support, forcing a transaction
# commit during the lock.
#
#
diff -Nru a/drivers/md/lvm.c b/drivers/md/lvm.c
--- a/drivers/md/lvm.c	Tue Aug 21 23:55:59 2001
+++ b/drivers/md/lvm.c	Tue Aug 21 23:55:59 2001
@@ -182,9 +182,6 @@
 #define DEVICE_OFF(device)
 #define LOCAL_END_REQUEST
 
-/* lvm_do_lv_create calls fsync_dev_lockfs()/unlockfs() */
-/* #define	LVM_VFS_ENHANCEMENT */
-
 #include <linux/config.h>
 #include <linux/version.h>
 
@@ -1933,12 +1930,8 @@
 	if (lv_ptr->lv_access & LV_SNAPSHOT) {
 		lv_t *org = lv_ptr->lv_snapshot_org, *last;
 
-		/* sync the original logical volume */
-		fsync_dev(org->lv_dev);
-#ifdef	LVM_VFS_ENHANCEMENT
 		/* VFS function call to sync and lock the filesystem */
 		fsync_dev_lockfs(org->lv_dev);
-#endif
 
 		down(&org->lv_snapshot_sem);
 		org->lv_access |= LV_SNAPSHOT_ORG;
@@ -1962,12 +1955,10 @@
 	else
 		set_device_ro(lv_ptr->lv_dev, 1);
 
-#ifdef	LVM_VFS_ENHANCEMENT
 /* VFS function call to unlock the filesystem */
 	if (lv_ptr->lv_access & LV_SNAPSHOT) {
 		unlockfs(lv_ptr->lv_snapshot_org->lv_dev);
 	}
-#endif
 
 	lv_ptr->vg = vg_ptr;
 
diff -Nru a/fs/buffer.c b/fs/buffer.c
--- a/fs/buffer.c	Tue Aug 21 23:55:59 2001
+++ b/fs/buffer.c	Tue Aug 21 23:55:59 2001
@@ -350,6 +350,34 @@
 	fsync_dev(dev);
 }
 
+int fsync_dev_lockfs(kdev_t dev)
+{
+	/* you are not allowed to try locking all the filesystems
+	** on the system, your chances of getting through without
+	** total deadlock are slim to none.
+	*/
+	if (!dev)
+		return fsync_dev(dev) ;
+
+	sync_buffers(dev, 0);
+
+	lock_kernel();
+	/* note, the FS might need to start transactions to 
+	** sync the inodes, or the quota, no locking until
+	** after these are done
+	*/
+	sync_inodes(dev);
+	DQUOT_SYNC(dev);
+	/* if inodes or quotas could be dirtied during the
+	** sync_supers_lockfs call, the FS is responsible for getting
+	** them on disk, without deadlocking against the lock
+	*/
+	sync_supers_lockfs(dev) ;
+	unlock_kernel();
+
+	return sync_buffers(dev, 1) ;
+}
+
 asmlinkage long sys_sync(void)
 {
 	fsync_dev(0);
diff -Nru a/fs/reiserfs/super.c b/fs/reiserfs/super.c
--- a/fs/reiserfs/super.c	Tue Aug 21 23:55:59 2001
+++ b/fs/reiserfs/super.c	Tue Aug 21 23:55:59 2001
@@ -66,7 +66,7 @@
     reiserfs_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 = dirty;
   unlock_kernel() ;
diff -Nru a/fs/super.c b/fs/super.c
--- a/fs/super.c	Tue Aug 21 23:55:59 2001
+++ b/fs/super.c	Tue Aug 21 23:55:59 2001
@@ -637,6 +637,18 @@
 			sb->s_op->write_super(sb);
 	unlock_super(sb);
 }
+
+static inline void write_super_lockfs(struct super_block *sb)
+{
+	lock_super(sb);
+	if (sb->s_root && sb->s_op) {
+		if (sb->s_dirt && sb->s_op->write_super)
+			sb->s_op->write_super(sb);
+		if (sb->s_op->write_super_lockfs)
+			sb->s_op->write_super_lockfs(sb);
+	}
+	unlock_super(sb);
+}
  
 /*
  * Note: check the dirty flag before waiting, so we don't
@@ -670,6 +682,48 @@
 		} else
 			sb = sb_entry(sb->s_list.next);
 	spin_unlock(&sb_lock);
+}
+
+/*
+ * Note: don't check the dirty flag before waiting, we want the lock
+ * to happen every time this is called.  dev must be non-zero
+ */
+void sync_supers_lockfs(kdev_t dev)
+{
+	struct super_block * sb;
+
+	if (dev) {
+		sb = get_super(dev);
+		if (sb) {
+			write_super_lockfs(sb);
+			drop_super(sb);
+		}
+	}
+}
+
+void unlockfs(kdev_t dev)
+{
+	struct super_block * sb;
+
+	if (dev) {
+		/* we cannot lock the super here because someone
+		** might be waiting on the unlock with the
+		** super already locked
+		**
+		** so, we grab the mount semaphore instead, we have
+		** to make sure nobody is mounting during our
+		** unlock operation.  The FS won't unmount because it
+		** was locked.
+		*/
+		down(&mount_sem);
+		sb = get_super(dev);
+		if (sb) {
+			if (sb->s_op && sb->s_op->unlockfs)
+				sb->s_op->unlockfs(sb) ;
+			drop_super(sb);
+		}
+		up(&mount_sem);
+	}
 }
 
 /**
diff -Nru a/include/linux/fs.h b/include/linux/fs.h
--- a/include/linux/fs.h	Tue Aug 21 23:55:59 2001
+++ b/include/linux/fs.h	Tue Aug 21 23:55:59 2001
@@ -1223,6 +1223,7 @@
 extern void write_inode_now(struct inode *, int);
 extern void sync_dev(kdev_t);
 extern int fsync_dev(kdev_t);
+extern int fsync_dev_lockfs(kdev_t);
 extern int fsync_super(struct super_block *);
 extern int fsync_no_super(kdev_t);
 extern void sync_inodes_sb(struct super_block *);
@@ -1232,6 +1233,8 @@
 extern void filemap_fdatasync(struct address_space *);
 extern void filemap_fdatawait(struct address_space *);
 extern void sync_supers(kdev_t);
+extern void sync_supers_lockfs(kdev_t);
+extern void unlockfs(kdev_t);
 extern int bmap(struct inode *, int);
 extern int notify_change(struct dentry *, struct iattr *);
 extern int permission(struct inode *, int);
diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c
--- a/kernel/ksyms.c	Tue Aug 21 23:55:59 2001
+++ b/kernel/ksyms.c	Tue Aug 21 23:55:59 2001
@@ -178,6 +178,8 @@
 EXPORT_SYMBOL(invalidate_inode_pages);
 EXPORT_SYMBOL(truncate_inode_pages);
 EXPORT_SYMBOL(fsync_dev);
+EXPORT_SYMBOL(fsync_dev_lockfs);
+EXPORT_SYMBOL(unlockfs);
 EXPORT_SYMBOL(fsync_no_super);
 EXPORT_SYMBOL(permission);
 EXPORT_SYMBOL(vfs_permission);


^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH] LVM snapshot support for reiserfs and others
       [not found] <no.id>
@ 2001-08-10 22:01 ` Alan Cox
  0 siblings, 0 replies; 14+ messages in thread
From: Alan Cox @ 2001-08-10 22:01 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Chris Mason, Alexander Viro, Andreas Dilger, linux-kernel,
	torvalds, lvm-devel, ext3-users

> ext3 will probably lock up on unmount with 2.4.8-pre8.  The fix is
> to replace fsync_dev with fsync_no_super in fs/ext3/super.c and
> fs/jbd/recovery.c.  I'll be generating a new patchset this weekend.

Actually if you dont fix recovery.c it will hang the machine when you mount
an fs that needs recovering. With the old patches at least umount of ext3
seems fine as is.

Alan

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2001-08-22  4:07 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-08-09 18:35 [PATCH] LVM snapshot support for reiserfs and others Chris Mason
2001-08-09 19:22 ` Andreas Dilger
2001-08-09 20:34   ` Chris Mason
2001-08-09 20:58     ` Andreas Dilger
2001-08-09 22:20       ` Chris Mason
2001-08-09 22:24         ` Alexander Viro
2001-08-09 22:42           ` Chris Mason
2001-08-09 23:26             ` Alexander Viro
2001-08-09 23:50               ` Alexander Viro
2001-08-10 19:49               ` Chris Mason
2001-08-10 20:04                 ` Andrew Morton
2001-08-14 20:25                 ` Andreas Dilger
2001-08-22  4:06                 ` Chris Mason
     [not found] <no.id>
2001-08-10 22:01 ` Alan Cox

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).