xfs
[Top] [All Lists]

[PATCH 2/6] xfs: add DAX block zeroing support

To: xfs@xxxxxxxxxxx
Subject: [PATCH 2/6] xfs: add DAX block zeroing support
From: Dave Chinner <david@xxxxxxxxxxxxx>
Date: Wed, 4 Mar 2015 10:30:23 +1100
Cc: linux-fsdevel@xxxxxxxxxxxxxxx, jack@xxxxxxx, willy@xxxxxxxxxxxxxxx
Delivered-to: xfs@xxxxxxxxxxx
In-reply-to: <1425425427-16283-1-git-send-email-david@xxxxxxxxxxxxx>
References: <1425425427-16283-1-git-send-email-david@xxxxxxxxxxxxx>
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 dc5f609..bc0008f 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);
+               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);
-- 
2.0.0

<Prev in Thread] Current Thread [Next in Thread>