generic_osync_inode() broken?

From: Marcelo Tosatti (marcelo@conectiva.com.br)
Date: Thu Apr 12 2001 - 12:37:20 EST


Hi,

generic_osync_inode() (called by generic_file_write()) is not checking if
the inode being synced has the I_LOCK bit set before checking the I_DIRTY
bit.

AFAICS, the following problem can happen:

sync()
...
sync_one()
reset I_DIRTY, set I_LOCK
filemap_fdatasync() <-- #window
write_inode() <-- #window
filemap_fdatawait() <-- #window
unset I_LOCK

There is no guarantee that the inode is fully synced until sync_one()
cleans the inode I_LOCK bit.

If generic_osync_inode() checks the I_DIRTY bit (and sees it clean) during
"#window", an "O_SYNC write()" call may return to userspace without having
all the data actually synced.

If I'm not missing something here this patch should the problem.

Comments?

--- fs/inode.c~ Thu Mar 22 16:04:13 2001
+++ fs/inode.c Thu Apr 12 15:18:22 2001
@@ -347,6 +347,11 @@
 #endif
 
         spin_lock(&inode_lock);
+ while (inode->i_state & I_LOCK) {
+ spin_unlock(&inode_lock);
+ __wait_on_inode(inode);
+ spin_lock(&inode_lock);
+ }
         if (!(inode->i_state & I_DIRTY))
                 goto out;
         if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sun Apr 15 2001 - 21:00:19 EST