* then a modify/write/read cycle when writing to a page in the
  * page cache.
  *
+ * Some pNFS layout drivers can only read/write at a certain block
+ * granularity like all block devices and therefore we must perform
+ * read/modify/write whenever a page hasn't read yet and the data
+ * to be written there is not aligned to a block boundary and/or
+ * smaller than the block size.
+ *
  * The modify/write/read cycle may occur if a page is read before
  * being completely filled by the writer.  In this situation, the
  * page must be completely written to stable storage on the server
  * and that the new data won't completely replace the old data in
  * that range of the file.
  */
-static int nfs_want_read_modify_write(struct file *file, struct page *page,
-                       loff_t pos, unsigned len)
+static bool nfs_full_page_write(struct page *page, loff_t pos, unsigned int len)
 {
        unsigned int pglen = nfs_page_length(page);
        unsigned int offset = pos & (PAGE_SIZE - 1);
        unsigned int end = offset + len;
 
-       if (pnfs_ld_read_whole_page(file->f_mapping->host)) {
-               if (!PageUptodate(page) && !PagePrivate(page))
-                       return 1;
-               return 0;
-       }
+       return !pglen || (end >= pglen && !offset);
+}
 
-       if ((file->f_mode & FMODE_READ) &&      /* open for read? */
-           !PageUptodate(page) &&              /* Uptodate? */
-           !PagePrivate(page) &&               /* i/o request already? */
-           pglen &&                            /* valid bytes of file? */
-           (end < pglen || offset))            /* replace all valid bytes? */
-               return 1;
-       return 0;
+static bool nfs_want_read_modify_write(struct file *file, struct page *page,
+                       loff_t pos, unsigned int len)
+{
+       /*
+        * Up-to-date pages, those with ongoing or full-page write
+        * don't need read/modify/write
+        */
+       if (PageUptodate(page) || PagePrivate(page) ||
+           nfs_full_page_write(page, pos, len))
+               return false;
+
+       if (pnfs_ld_read_whole_page(file->f_mapping->host))
+               return true;
+       /* Open for reading too? */
+       if (file->f_mode & FMODE_READ)
+               return true;
+       return false;
 }
 
 /*