The previous patch allows us to relax the buffer.c requirement that the page lock be held in order to avoid writepage zeroing out new data beyond isize. [actually as I said I think it still has a bug due to writepage requiring i_size_read] --- fs/buffer.c | 28 ++++++++-------------------- mm/shmem.c | 6 +++--- 2 files changed, 11 insertions(+), 23 deletions(-) Index: linux-2.6/fs/buffer.c =================================================================== --- linux-2.6.orig/fs/buffer.c +++ linux-2.6/fs/buffer.c @@ -2049,33 +2049,20 @@ int generic_write_end(struct file *file, struct page *page, void *fsdata) { struct inode *inode = mapping->host; - int i_size_changed = 0; copied = block_write_end(file, mapping, pos, len, copied, page, fsdata); + unlock_page(page); + page_cache_release(page); + /* * No need to use i_size_read() here, the i_size * cannot change under us because we hold i_mutex. - * - * But it's important to update i_size while still holding page lock: - * page writeout could otherwise come in and zero beyond i_size. */ if (pos+copied > inode->i_size) { i_size_write(inode, pos+copied); - i_size_changed = 1; - } - - unlock_page(page); - page_cache_release(page); - - /* - * Don't mark the inode dirty under page lock. First, it unnecessarily - * makes the holding time of page lock longer. Second, it forces lock - * ordering of page lock and transaction start for journaling - * filesystems. - */ - if (i_size_changed) mark_inode_dirty(inode); + } return copied; } @@ -2624,14 +2611,15 @@ int nobh_write_end(struct file *file, st SetPageUptodate(page); set_page_dirty(page); + + unlock_page(page); + page_cache_release(page); + if (pos+copied > inode->i_size) { i_size_write(inode, pos+copied); mark_inode_dirty(inode); } - unlock_page(page); - page_cache_release(page); - while (head) { bh = head; head = head->b_this_page; Index: linux-2.6/mm/shmem.c =================================================================== --- linux-2.6.orig/mm/shmem.c +++ linux-2.6/mm/shmem.c @@ -1631,13 +1631,13 @@ shmem_write_end(struct file *file, struc { struct inode *inode = mapping->host; - if (pos + copied > inode->i_size) - i_size_write(inode, pos + copied); - unlock_page(page); set_page_dirty(page); page_cache_release(page); + if (pos + copied > inode->i_size) + i_size_write(inode, pos + copied); + return copied; } -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html