]> git.hungrycats.org Git - linux/commitdiff
[PATCH] Fix race in ext3_getblk
authorAndrew Morton <akpm@osdl.org>
Fri, 1 Aug 2003 03:04:17 +0000 (20:04 -0700)
committerLinus Torvalds <torvalds@home.osdl.org>
Fri, 1 Aug 2003 03:04:17 +0000 (20:04 -0700)
From: Alex Tomas <bzzz@tmi.comex.ru>

ext3_getblk() memsets a newly allocated buffer, but forgets to check
whether a different thread brought it uptodate while we waited for the
buffer lock.

It's OK normally because we're serialised by the page lock.  But lustre
apparently is doing something different with getblk and hits this race.

Plus I suspect it's racy with competing O_DIRECT writes.

fs/ext3/inode.c

index 9ca808e53f1a2626e1ff3d62289dfc96d189b2e2..05e0e3e1e65e37d0b790d988086f36c814644902 100644 (file)
@@ -938,15 +938,15 @@ struct buffer_head *ext3_getblk(handle_t *handle, struct inode * inode,
                        lock_buffer(bh);
                        BUFFER_TRACE(bh, "call get_create_access");
                        fatal = ext3_journal_get_create_access(handle, bh);
-                       if (!fatal) {
-                               memset(bh->b_data, 0,
-                                      inode->i_sb->s_blocksize);
+                       if (!fatal && !buffer_uptodate(bh)) {
+                               memset(bh->b_data, 0, inode->i_sb->s_blocksize);
                                set_buffer_uptodate(bh);
                        }
                        unlock_buffer(bh);
                        BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
                        err = ext3_journal_dirty_metadata(handle, bh);
-                       if (!fatal) fatal = err;
+                       if (!fatal)
+                               fatal = err;
                } else {
                        BUFFER_TRACE(bh, "not a new buffer");
                }