Author: kib
Date: Wed Aug  2 08:07:13 2017
New Revision: 321910
URL: https://svnweb.freebsd.org/changeset/base/321910

Log:
  MFC r321581:
  Mark pages after EOF as clean after pageout.

Modified:
  stable/11/sys/fs/nfsclient/nfs_clbio.c
  stable/11/sys/fs/smbfs/smbfs_io.c
  stable/11/sys/vm/vnode_pager.c
  stable/11/sys/vm/vnode_pager.h
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/fs/nfsclient/nfs_clbio.c
==============================================================================
--- stable/11/sys/fs/nfsclient/nfs_clbio.c      Wed Aug  2 08:03:40 2017        
(r321909)
+++ stable/11/sys/fs/nfsclient/nfs_clbio.c      Wed Aug  2 08:07:13 2017        
(r321910)
@@ -336,8 +336,10 @@ ncl_putpages(struct vop_putpages_args *ap)
            cred);
        crfree(cred);
 
-       if (error == 0 || !nfs_keep_dirty_on_error)
-               vnode_pager_undirty_pages(pages, rtvals, count - uio.uio_resid);
+       if (error == 0 || !nfs_keep_dirty_on_error) {
+               vnode_pager_undirty_pages(pages, rtvals, count - uio.uio_resid,
+                   np->n_size - offset, npages * PAGE_SIZE);
+       }
        return (rtvals[0]);
 }
 

Modified: stable/11/sys/fs/smbfs/smbfs_io.c
==============================================================================
--- stable/11/sys/fs/smbfs/smbfs_io.c   Wed Aug  2 08:03:40 2017        
(r321909)
+++ stable/11/sys/fs/smbfs/smbfs_io.c   Wed Aug  2 08:07:13 2017        
(r321910)
@@ -621,9 +621,11 @@ smbfs_putpages(ap)
 
        relpbuf(bp, &smbfs_pbuf_freecnt);
 
-       if (!error)
-               vnode_pager_undirty_pages(pages, rtvals, count - uio.uio_resid);
-       return rtvals[0];
+       if (error == 0) {
+               vnode_pager_undirty_pages(pages, rtvals, count - uio.uio_resid,
+                   npages * PAGE_SIZE, npages * PAGE_SIZE);
+       }
+       return (rtvals[0]);
 #endif /* SMBFS_RWGENERIC */
 }
 

Modified: stable/11/sys/vm/vnode_pager.c
==============================================================================
--- stable/11/sys/vm/vnode_pager.c      Wed Aug  2 08:03:40 2017        
(r321909)
+++ stable/11/sys/vm/vnode_pager.c      Wed Aug  2 08:07:13 2017        
(r321910)
@@ -1276,13 +1276,24 @@ vnode_pager_putpages_ioflags(int pager_flags)
        return (ioflags);
 }
 
+/*
+ * vnode_pager_undirty_pages().
+ *
+ * A helper to mark pages as clean after pageout that was possibly
+ * done with a short write.  The lpos argument specifies the page run
+ * length in bytes, and the written argument specifies how many bytes
+ * were actually written.  eof is the offset past the last valid byte
+ * in the vnode using the absolute file position of the first byte in
+ * the run as the base from which it is computed.
+ */
 void
-vnode_pager_undirty_pages(vm_page_t *ma, int *rtvals, int written)
+vnode_pager_undirty_pages(vm_page_t *ma, int *rtvals, int written, off_t eof,
+    int lpos)
 {
        vm_object_t obj;
-       int i, pos;
+       int i, pos, pos_devb;
 
-       if (written == 0)
+       if (written == 0 && eof >= lpos)
                return;
        obj = ma[0]->object;
        VM_OBJECT_WLOCK(obj);
@@ -1296,6 +1307,37 @@ vnode_pager_undirty_pages(vm_page_t *ma, int *rtvals, 
                        vm_page_clear_dirty(ma[i], 0, written & PAGE_MASK);
                }
        }
+       if (eof >= lpos) /* avoid truncation */
+               goto done;
+       for (pos = eof, i = OFF_TO_IDX(trunc_page(pos)); pos < lpos; i++) {
+               if (pos != trunc_page(pos)) {
+                       /*
+                        * The page contains the last valid byte in
+                        * the vnode, mark the rest of the page as
+                        * clean, potentially making the whole page
+                        * clean.
+                        */
+                       pos_devb = roundup2(pos & PAGE_MASK, DEV_BSIZE);
+                       vm_page_clear_dirty(ma[i], pos_devb, PAGE_SIZE -
+                           pos_devb);
+
+                       /*
+                        * If the page was cleaned, report the pageout
+                        * on it as successful.  msync() no longer
+                        * needs to write out the page, endlessly
+                        * creating write requests and dirty buffers.
+                        */
+                       if (ma[i]->dirty == 0)
+                               rtvals[i] = VM_PAGER_OK;
+
+                       pos = round_page(pos);
+               } else {
+                       /* vm_pageout_flush() clears dirty */
+                       rtvals[i] = VM_PAGER_BAD;
+                       pos += PAGE_SIZE;
+               }
+       }
+done:
        VM_OBJECT_WUNLOCK(obj);
 }
 

Modified: stable/11/sys/vm/vnode_pager.h
==============================================================================
--- stable/11/sys/vm/vnode_pager.h      Wed Aug  2 08:03:40 2017        
(r321909)
+++ stable/11/sys/vm/vnode_pager.h      Wed Aug  2 08:07:13 2017        
(r321910)
@@ -50,7 +50,8 @@ int vnode_pager_local_getpages_async(struct vop_getpag
 int vnode_pager_putpages_ioflags(int pager_flags);
 void vnode_pager_release_writecount(vm_object_t object, vm_offset_t start,
     vm_offset_t end);
-void vnode_pager_undirty_pages(vm_page_t *ma, int *rtvals, int written);
+void vnode_pager_undirty_pages(vm_page_t *ma, int *rtvals, int written,
+    off_t eof, int lpos);
 void vnode_pager_update_writecount(vm_object_t object, vm_offset_t start,
     vm_offset_t end);
 
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to