[PATCH linux-2.6.1-rc1-mm1] dio_isize.patch

From: Daniel McNeil
Date: Wed Dec 31 2003 - 17:49:00 EST


This patch samples i_size before dropping the i_sem.
The i_size could change by a racing write and we could
return uninitialized data.

re-diffed against 2.6.1-rc1-mm1.

Daniel
--- 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;
/*