aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/inode.c
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2015-06-03 19:18:18 -0400
committerDave Chinner <david@fromorbit.com>2015-06-03 19:18:18 -0400
commite842f2903908934187af7232fb5b21da527d1757 (patch)
tree5fe6e2da05d58519d0f9360cf5116662a766906a /fs/ext4/inode.c
parentec56b1f1fdc69599963574ce94cc5693d535dd64 (diff)
dax: don't abuse get_block mapping for endio callbacks
dax_fault() currently relies on the get_block callback to attach an io completion callback to the mapping buffer head so that it can run unwritten extent conversion after zeroing allocated blocks. Instead of this hack, pass the conversion callback directly into dax_fault() similar to the get_block callback. When the filesystem allocates unwritten extents, it will set the buffer_unwritten() flag, and hence the dax_fault code can call the completion function in the contexts where it is necessary without overloading the mapping buffer head. Note: The changes to ext4 to use this interface are suspect at best. In fact, the way ext4 did this end_io assignment in the first place looks suspect because it only set a completion callback when there wasn't already some other write() call taking place on the same inode. The ext4 end_io code looks rather intricate and fragile with all it's reference counting and passing to different contexts for modification via inode private pointers that aren't protected by locks... Signed-off-by: Dave Chinner <dchinner@redhat.com> Acked-by: Jan Kara <jack@suse.cz> Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r--fs/ext4/inode.c21
1 files changed, 7 insertions, 14 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 55b187c3bac1..7c38ed3494cb 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -656,18 +656,6 @@ has_zeroout:
656 return retval; 656 return retval;
657} 657}
658 658
659static void ext4_end_io_unwritten(struct buffer_head *bh, int uptodate)
660{
661 struct inode *inode = bh->b_assoc_map->host;
662 /* XXX: breaks on 32-bit > 16GB. Is that even supported? */
663 loff_t offset = (loff_t)(uintptr_t)bh->b_private << inode->i_blkbits;
664 int err;
665 if (!uptodate)
666 return;
667 WARN_ON(!buffer_unwritten(bh));
668 err = ext4_convert_unwritten_extents(NULL, inode, offset, bh->b_size);
669}
670
671/* Maximum number of blocks we map for direct IO at once. */ 659/* Maximum number of blocks we map for direct IO at once. */
672#define DIO_MAX_BLOCKS 4096 660#define DIO_MAX_BLOCKS 4096
673 661
@@ -705,10 +693,15 @@ static int _ext4_get_block(struct inode *inode, sector_t iblock,
705 693
706 map_bh(bh, inode->i_sb, map.m_pblk); 694 map_bh(bh, inode->i_sb, map.m_pblk);
707 bh->b_state = (bh->b_state & ~EXT4_MAP_FLAGS) | map.m_flags; 695 bh->b_state = (bh->b_state & ~EXT4_MAP_FLAGS) | map.m_flags;
708 if (IS_DAX(inode) && buffer_unwritten(bh) && !io_end) { 696 if (IS_DAX(inode) && buffer_unwritten(bh)) {
697 /*
698 * dgc: I suspect unwritten conversion on ext4+DAX is
699 * fundamentally broken here when there are concurrent
700 * read/write in progress on this inode.
701 */
702 WARN_ON_ONCE(io_end);
709 bh->b_assoc_map = inode->i_mapping; 703 bh->b_assoc_map = inode->i_mapping;
710 bh->b_private = (void *)(unsigned long)iblock; 704 bh->b_private = (void *)(unsigned long)iblock;
711 bh->b_end_io = ext4_end_io_unwritten;
712 } 705 }
713 if (io_end && io_end->flag & EXT4_IO_END_UNWRITTEN) 706 if (io_end && io_end->flag & EXT4_IO_END_UNWRITTEN)
714 set_buffer_defer_completion(bh); 707 set_buffer_defer_completion(bh);