xfs
[Top] [All Lists]

[PATCH 101/119] xfs: promote buffered writes to CoW when cowextsz is set

To: david@xxxxxxxxxxxxx, darrick.wong@xxxxxxxxxx
Subject: [PATCH 101/119] xfs: promote buffered writes to CoW when cowextsz is set
From: "Darrick J. Wong" <darrick.wong@xxxxxxxxxx>
Date: Thu, 16 Jun 2016 18:28:43 -0700
Cc: linux-fsdevel@xxxxxxxxxxxxxxx, vishal.l.verma@xxxxxxxxx, xfs@xxxxxxxxxxx
Delivered-to: xfs@xxxxxxxxxxx
In-reply-to: <146612627129.12839.3827886950949809165.stgit@xxxxxxxxxxxxxxxx>
References: <146612627129.12839.3827886950949809165.stgit@xxxxxxxxxxxxxxxx>
User-agent: StGit/0.17.1-dirty
When we're doing non-cow writes to a part of a file that already has a
CoW reservation by virtue of cowextsz being set, promote the write to
copy-on-write so that the entire extent can get written out as a single
block, thereby reducing post-CoW fragmentation.

Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx>
---
 fs/xfs/xfs_aops.c |   39 ++++++++++++++++++---------------------
 1 file changed, 18 insertions(+), 21 deletions(-)


diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index 812bae5..31205fa 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -668,10 +668,12 @@ xfs_check_page_type(
        bh = head = page_buffers(page);
        do {
                if (buffer_unwritten(bh)) {
-                       if (type == XFS_IO_UNWRITTEN)
+                       if (type == XFS_IO_UNWRITTEN ||
+                           type == XFS_IO_COW)
                                return true;
                } else if (buffer_delay(bh)) {
-                       if (type == XFS_IO_DELALLOC)
+                       if (type == XFS_IO_DELALLOC ||
+                           type == XFS_IO_COW)
                                return true;
                } else if (buffer_dirty(bh) && buffer_mapped(bh)) {
                        if (type == XFS_IO_OVERWRITE ||
@@ -836,25 +838,13 @@ xfs_writepage_map(
                        continue;
                }
 
-               if (buffer_unwritten(bh)) {
-                       if (wpc->io_type != XFS_IO_UNWRITTEN) {
-                               wpc->io_type = XFS_IO_UNWRITTEN;
-                               wpc->imap_valid = false;
-                       }
-               } else if (buffer_delay(bh)) {
-                       if (wpc->io_type != XFS_IO_DELALLOC) {
-                               wpc->io_type = XFS_IO_DELALLOC;
-                               wpc->imap_valid = false;
-                       }
-               } else if (buffer_uptodate(bh)) {
-                       new_type = xfs_is_cow_io(XFS_I(inode), offset) ?
-                                       XFS_IO_COW : XFS_IO_OVERWRITE;
-
-                       if (wpc->io_type != new_type) {
-                               wpc->io_type = new_type;
-                               wpc->imap_valid = false;
-                       }
-               } else {
+               if (buffer_unwritten(bh))
+                       new_type = XFS_IO_UNWRITTEN;
+               else if (buffer_delay(bh))
+                       new_type = XFS_IO_DELALLOC;
+               else if (buffer_uptodate(bh))
+                       new_type = XFS_IO_OVERWRITE;
+               else {
                        if (PageUptodate(page))
                                ASSERT(buffer_mapped(bh));
                        /*
@@ -867,6 +857,13 @@ xfs_writepage_map(
                        continue;
                }
 
+               if (xfs_is_cow_io(XFS_I(inode), offset))
+                       new_type = XFS_IO_COW;
+               if (wpc->io_type != new_type) {
+                       wpc->io_type = new_type;
+                       wpc->imap_valid = false;
+               }
+
                if (wpc->imap_valid)
                        wpc->imap_valid = xfs_imap_valid(inode, &wpc->imap,
                                                         offset);

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