linux/fs/ext3
Chris Mason 4f003fd32b ext3: Add locking to ext3_do_update_inode
I've been struggling with this off and on while I've been testing the
data=guarded work.  The symptom is corrupted orphan lists and inodes
with the wrong i_size stored on disk.  I was convinced the
data=guarded code was just missing a call to ext3_mark_inode_dirty, but
tracing showed the i_disksize I was sending to ext3_mark_inode_dirty
wasn't actually making it to the drive.

ext3_mark_inode_dirty can be called without locks held (atime updates
and a few others), so the data=guarded code uses locks while updating
the in-memory inode, and then calls ext3_mark_inode_dirty
without any locks held.

But, ext3_mark_inode_dirty has no internal locking to make sure that
only one CPU is updating the buffer head at a time.  Generally this
works out ok because everyone that changes the inode then calls
ext3_mark_inode_dirty themselves.  Even though it races, eventually
someone updates the buffer heads and things move on.

But there is still a risk of the wrong values getting in, and the
data=guarded code seems to hit the race very often.

Since everyone that changes the inode also logs it, it should be
possible to fix this with some memory barriers.  I'll leave that as an
exercise to the reader and lock the buffer head instead.

It it probably a good idea to have a different patch series for lockless
bit flipping on the ext3 i_state field.  ext3_do_update_inode &= clears
EXT3_STATE_NEW without any locks held.

Signed-off-by: Chris Mason <chris.mason@oracle.com>
Signed-off-by: Jan Kara <jack@suse.cz>
2009-09-16 17:44:11 +02:00
..
acl.c ext[234]: move over to 'check_acl' permission model 2009-09-08 11:09:04 -07:00
acl.h ext[234]: move over to 'check_acl' permission model 2009-09-08 11:09:04 -07:00
balloc.c ext3: remove ->write_super and stop maintaining ->s_dirt 2009-06-11 21:36:05 -04:00
bitmap.c fs: mark nibblemap const 2007-10-17 08:42:47 -07:00
dir.c ext3: Get rid of extenddisksize parameter of ext3_get_blocks_handle() 2009-07-15 21:30:46 +02:00
ext3_jbd.c ext3: replace remaining __FUNCTION__ occurrences 2008-04-28 08:58:45 -07:00
file.c ext3: Remove syncing logic from ext3_file_write 2009-09-14 17:08:16 +02:00
fsync.c ext3: fdatasync should skip metadata writeout when overwriting 2008-04-28 08:58:43 -07:00
hash.c ext3: Add support for non-native signed/unsigned htree hash algorithms 2008-10-28 13:21:55 -04:00
ialloc.c ext3: remove ->write_super and stop maintaining ->s_dirt 2009-06-11 21:36:05 -04:00
inode.c ext3: Add locking to ext3_do_update_inode 2009-09-16 17:44:11 +02:00
ioctl.c ext3: remove the BKL in ext3/ioctl.c 2009-04-02 19:04:52 -07:00
Kconfig ext3: Update Kconfig description of EXT3_DEFAULTS_TO_ORDERED 2009-08-24 16:48:32 +02:00
Makefile [PATCH] ext3: uninline large functions 2006-12-07 08:39:35 -08:00
namei.c ext[234]: move over to 'check_acl' permission model 2009-09-08 11:09:04 -07:00
namei.h [PATCH] ext3: sparse fixes 2005-10-30 17:37:25 -08:00
resize.c block: rename CONFIG_LBD to CONFIG_LBDAF 2009-06-19 08:08:50 +02:00
super.c ext3: Improve error message that changing journaling mode on remount is not possible 2009-08-24 16:48:45 +02:00
symlink.c [PATCH] mark struct inode_operations const 1 2007-02-12 09:48:46 -08:00
xattr_security.c ext3: remove double definitions of xattr macros 2008-07-25 10:53:32 -07:00
xattr_trusted.c ext3: remove double definitions of xattr macros 2008-07-25 10:53:32 -07:00
xattr_user.c ext3: remove double definitions of xattr macros 2008-07-25 10:53:32 -07:00
xattr.c ext3: remove ->write_super and stop maintaining ->s_dirt 2009-06-11 21:36:05 -04:00
xattr.h make ext3_xattr_list() static 2008-04-28 08:58:44 -07:00