--- linux-2.6.3-rc2-mm1.orig/fs/direct-io.c 2004-02-12 11:35:41.613567579 -0800 +++ linux-2.6.3-rc2-mm1/fs/direct-io.c 2004-02-12 11:35:52.135706887 -0800 @@ -909,6 +909,7 @@ direct_io_worker(int rw, struct kiocb *i int ret = 0; int ret2; size_t bytes; + loff_t i_size; dio->bio = NULL; dio->inode = inode; @@ -1017,7 +1018,12 @@ direct_io_worker(int rw, struct kiocb *i * All block lookups have been performed. For READ requests * we can let i_sem go now that its achieved its purpose * of protecting us from looking up uninitialized blocks. + * + * We also need sample i_size before we release i_sem to prevent + * a racing write from changing i_size causing us to return + * uninitialized data. */ + i_size = i_size_read(inode); if ((rw == READ) && dio->needs_locking) up(&dio->inode->i_sem); @@ -1064,7 +1070,6 @@ direct_io_worker(int rw, struct kiocb *i if (ret == 0) ret = dio->page_errors; if (ret == 0 && dio->result) { - loff_t i_size = i_size_read(inode); ret = dio->result; /*