diff mbox

[MTD] Fix JFFS2 sync silent failure

Message ID 20100422062631.GC27309@logfs.org
State New, archived
Headers show

Commit Message

Jörn Engel April 22, 2010, 6:26 a.m. UTC
Linus,

I think this is bad enough that you should be involved.  32a88aa1 broke
a number of filesystems in a way that sync() would return 0 without
doing any work.  Even politicians are better at keeping the promises.

This is caused by the two-liner in __sync_filesystem:
	if (!sb->s_bdi)
		return 0;
s_bdi is set implicitly for all filesystems using set_bdev_super(), so
most block device based filesystems are safe.  There are, however, a
number of odd-balls around:

On Thu, 22 April 2010 07:54:48 +0200, Jörn Engel wrote:
> 
> 9p	no s_bdi
> afs	no s_bdi
> ceph	creates its own s_bdi
> cifs	no s_bdi
> coda	no s_bdi
> ecryptfs no s_bdi
> exofs	no s_bdi
> fuse	creates its own s_bdi?
> gfs2	creates its own s_bdi?
> jffs2	patch exists
> logfs	fixed now
> ncpfs	no s_bdi
> nfs	creates its own s_bdi
> ocfs2	no s_bdi
> smbfs	no s_bdi
> ubifs	creates its own s_bdi

Obviously this list should get checked and all affected filesystems get
repaired.  Additionally we should add an assertion and BUG() or refuse
to mount or something.  My original patch to that extend was this:

  		goto out_sb;

The real problem is finding a condition that has neither false positives
nor false negatives.  The "(mnt->mnt_sb->s_bdev || mnt->mnt_sb->s_mtd)"
part takes care of false positives like tmpfs, but it would catch none
of the network filesystems.  Should we instead annotate tmpfs and friends
with something like sb->s_dont_need_bdi?  It is the only way I can think
of not to miss something.

Jörn

Comments

Linus Torvalds April 22, 2010, 2:25 p.m. UTC | #1
On Thu, 22 Apr 2010, Jörn Engel wrote:
>
> I think this is bad enough that you should be involved.  32a88aa1 broke
> a number of filesystems in a way that sync() would return 0 without
> doing any work.  Even politicians are better at keeping the promises.
> 
> This is caused by the two-liner in __sync_filesystem:
> 	if (!sb->s_bdi)
> 		return 0;
> s_bdi is set implicitly for all filesystems using set_bdev_super(), so
> most block device based filesystems are safe.  There are, however, a
> number of odd-balls around:

Umm. Why not just remove the two-liner? It was incorrect. The comment says 
"this should be safe", and if it wasn't, then the commit that caused this 
all was total crap to begin with.

Why even discuss any other measures?

		Linus
Linus Torvalds April 22, 2010, 2:33 p.m. UTC | #2
On Thu, 22 Apr 2010, Linus Torvalds wrote:
>
> Umm. Why not just remove the two-liner? It was incorrect. The comment says 
> "this should be safe", and if it wasn't, then the commit that caused this 
> all was total crap to begin with.

Grr. Ok, so we do need it. Because Jens made it not work without it, and 
didn't fix up the filesystems, just added a random comment saying "we 
shouldn't need to".

Double-grr. I hate misleading comments. It makes the patch and the code 
look like people knew what they were doing.

Jens - please help fix this up.

		Linus
Jens Axboe April 22, 2010, 4:27 p.m. UTC | #3
On Thu, Apr 22 2010, Linus Torvalds wrote:
> 
> 
> On Thu, 22 Apr 2010, Linus Torvalds wrote:
> >
> > Umm. Why not just remove the two-liner? It was incorrect. The comment says 
> > "this should be safe", and if it wasn't, then the commit that caused this 
> > all was total crap to begin with.
> 
> Grr. Ok, so we do need it. Because Jens made it not work without it, and 
> didn't fix up the filesystems, just added a random comment saying "we 
> shouldn't need to".
> 
> Double-grr. I hate misleading comments. It makes the patch and the code 
> look like people knew what they were doing.

Yeah sorry, that part was apparently not well thought through. It did go
through review and testing, but at least the latter was not good enough.

> Jens - please help fix this up.

Of course, I already posted a series of patches to fix this up. I want
to test them a bit, and I'll send them in tomorrow.
diff mbox

Patch

diff --git a/fs/super.c b/fs/super.c
index f35ac60..e8af253 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -954,6 +954,8 @@  vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void
 	if (error < 0)
 		goto out_free_secdata;
 	BUG_ON(!mnt->mnt_sb);
+	BUG_ON(!mnt->mnt_sb->s_bdi &&
+			(mnt->mnt_sb->s_bdev || mnt->mnt_sb->s_mtd));
 
  	error = security_sb_kern_mount(mnt->mnt_sb, flags, secdata);
  	if (error)