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 [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to