On Tue, Mar 24, 2015 at 09:51:02PM +1100, Dave Chinner wrote: > From: Dave Chinner <dchinner@xxxxxxxxxx> > > Add initial support for DAX block zeroing operations to XFS. DAX > cannot use buffered IO through the page cache for zeroing, nor do we > need to issue IO for uncached block zeroing. In both cases, we can > simply call out to the dax block zeroing function. > > Signed-off-by: Dave Chinner <dchinner@xxxxxxxxxx> > --- > fs/xfs/xfs_bmap_util.c | 23 +++++++++++++++++++---- > fs/xfs/xfs_file.c | 28 +++++++++++++++++----------- > 2 files changed, 36 insertions(+), 15 deletions(-) > > diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c > index 1bd5393..d1fe432 100644 > --- a/fs/xfs/xfs_bmap_util.c > +++ b/fs/xfs/xfs_bmap_util.c > @@ -1133,14 +1133,29 @@ xfs_zero_remaining_bytes( > break; > ASSERT(imap.br_blockcount >= 1); > ASSERT(imap.br_startoff == offset_fsb); > + ASSERT(imap.br_startblock != DELAYSTARTBLOCK); > + > + if (imap.br_startblock == HOLESTARTBLOCK || > + imap.br_state == XFS_EXT_UNWRITTEN) { > + /* skip the entire extent */ > + lastoffset = XFS_FSB_TO_B(mp, imap.br_startoff + > + imap.br_blockcount) - 1; > + continue; > + } > + > lastoffset = XFS_FSB_TO_B(mp, imap.br_startoff + 1) - 1; > if (lastoffset > endoff) > lastoffset = endoff; > - if (imap.br_startblock == HOLESTARTBLOCK) > - continue; > - ASSERT(imap.br_startblock != DELAYSTARTBLOCK); > - if (imap.br_state == XFS_EXT_UNWRITTEN) > + > + /* DAX can just zero the backing device directly */ > + if (IS_DAX(VFS_I(ip))) { > + error = dax_zero_page_range(VFS_I(ip), offset, > + lastoffset - offset + 1, > + xfs_get_blocks_dax); > + if (error) > + return error; > continue; > + } > > error = xfs_buf_read_uncached(XFS_IS_REALTIME_INODE(ip) ? > mp->m_rtdev_targp : mp->m_ddev_targp, > diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c > index a4c882e..94713c2 100644 > --- a/fs/xfs/xfs_file.c > +++ b/fs/xfs/xfs_file.c > @@ -97,7 +97,8 @@ xfs_iozero( > { > struct page *page; > struct address_space *mapping; > - int status; > + int status = 0; > + > > mapping = VFS_I(ip)->i_mapping; > do { > @@ -109,20 +110,25 @@ xfs_iozero( > if (bytes > count) > bytes = count; > > - status = pagecache_write_begin(NULL, mapping, pos, bytes, > - AOP_FLAG_UNINTERRUPTIBLE, > - &page, &fsdata); > - if (status) > - break; > + if (IS_DAX(VFS_I(ip))) > + dax_zero_page_range(VFS_I(ip), pos, bytes, > + xfs_get_blocks_dax); xfs_get_blocks_dax() isn't defined yet. We should also probably error check here, yes? A nit... If we have to update this patch, it would be nice to update the comment above the function to adjust expectations with regard to the suggestion that this always allocates blocks. If I follow the dax codepath correctly, dax_zero_page_range() is a noop over holes or unwritten blocks (not that it seems to matter for current callers). > + else { > + status = pagecache_write_begin(NULL, mapping, pos, bytes, > + AOP_FLAG_UNINTERRUPTIBLE, > + &page, &fsdata); > + if (status) > + break; > > - zero_user(page, offset, bytes); > + zero_user(page, offset, bytes); > > - status = pagecache_write_end(NULL, mapping, pos, bytes, bytes, > - page, fsdata); > - WARN_ON(status <= 0); /* can't return less than zero! */ > + status = pagecache_write_end(NULL, mapping, pos, bytes, > + bytes, page, fsdata); > + WARN_ON(status <= 0); /* can't return less than zero! */ > + status = 0; > + } > pos += bytes; > count -= bytes; > - status = 0; > } while (count); > > return (-status); FWIW, that looks like a potential positive return code path (write_begin)... Brian > -- > 2.0.0 > > _______________________________________________ > xfs mailing list > xfs@xxxxxxxxxxx > http://oss.sgi.com/mailman/listinfo/xfs _______________________________________________ xfs mailing list xfs@xxxxxxxxxxx http://oss.sgi.com/mailman/listinfo/xfs