--- linux-2.6.1-rc1-mm1/fs/direct-io.c 2003-12-31 10:52:45.940193469 -0800 +++ linux-2.6.1-rc1-mm1.dio_isize/fs/direct-io.c 2003-12-31 13:56:06.836825169 -0800 @@ -882,6 +882,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; @@ -982,7 +983,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); @@ -1026,7 +1032,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; /*