>From 96f051597cfd91fe51a30fc3dbdeed290b98d7fe Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Wed, 24 Sep 2014 14:02:38 -0400 Subject: [PATCH 5/7] ext4: Add a callback to convert unwritten extents A different bug was masking the problem that unwritten extents need to be converted to written extents once we've faulted them into existence. Following the XFS example, add a b_end_io callback. We "borrow" a few additional fields in the buffer_head, but there aren't any big enough for a sector_t. Fortunately, we only use this callback for DAX, and ext4 already requires a 4k block size for using DAX, which puts the limit at 16TB. The page cache already limits file sizes to 16TB on 32-bit systems, so we don't need to grow any fields. --- fs/ext4/inode.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 5edd903..eaa293a 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -676,6 +676,18 @@ has_zeroout: return retval; } +static void ext4_end_io_unwritten(struct buffer_head *bh, int uptodate) +{ + struct inode *inode = bh->b_assoc_map->host; + /* XXX: breaks on 32-bit > 16GB. Is that even supported? */ + loff_t offset = (loff_t)(uintptr_t)bh->b_private << inode->i_blkbits; + int err; + if (!uptodate) + return; + WARN_ON(!buffer_unwritten(bh)); + err = ext4_convert_unwritten_extents(NULL, inode, offset, bh->b_size); +} + /* Maximum number of blocks we map for direct IO at once. */ #define DIO_MAX_BLOCKS 4096 @@ -713,6 +725,11 @@ static int _ext4_get_block(struct inode *inode, sector_t iblock, map_bh(bh, inode->i_sb, map.m_pblk); bh->b_state = (bh->b_state & ~EXT4_MAP_FLAGS) | map.m_flags; + if (IS_DAX(inode) && buffer_unwritten(bh) && !io_end) { + bh->b_assoc_map = inode->i_mapping; + bh->b_private = (void *)(unsigned long)iblock; + bh->b_end_io = ext4_end_io_unwritten; + } if (io_end && io_end->flag & EXT4_IO_END_UNWRITTEN) set_buffer_defer_completion(bh); bh->b_size = inode->i_sb->s_blocksize * map.m_len; -- 2.1.0