nfs: handle overlapping reqs in lock_and_join
authorWeston Andros Adamson <dros@primarydata.com>
Fri, 5 Sep 2014 20:34:29 +0000 (16:34 -0400)
committerTom Haynes <loghyr@primarydata.com>
Tue, 3 Feb 2015 19:06:44 +0000 (11:06 -0800)
This is needed for mirrored DS support, where multuple requests
cover the same range.

Signed-off-by: Weston Andros Adamson <dros@primarydata.com>
fs/nfs/write.c

index 8800bd3b235d090b9c73f43573ef965593813691..e9974574b19ac2d18ecacd5c34e55d27e018eae0 100644 (file)
@@ -473,13 +473,18 @@ try_again:
        do {
                /*
                 * Subrequests are always contiguous, non overlapping
-                * and in order. If not, it's a programming error.
+                * and in order - but may be repeated (mirrored writes).
                 */
-               WARN_ON_ONCE(subreq->wb_offset !=
-                    (head->wb_offset + total_bytes));
-
-               /* keep track of how many bytes this group covers */
-               total_bytes += subreq->wb_bytes;
+               if (subreq->wb_offset == (head->wb_offset + total_bytes)) {
+                       /* keep track of how many bytes this group covers */
+                       total_bytes += subreq->wb_bytes;
+               } else if (WARN_ON_ONCE(subreq->wb_offset < head->wb_offset ||
+                           ((subreq->wb_offset + subreq->wb_bytes) >
+                            (head->wb_offset + total_bytes)))) {
+                       nfs_page_group_unlock(head);
+                       spin_unlock(&inode->i_lock);
+                       return ERR_PTR(-EIO);
+               }
 
                if (!nfs_lock_request(subreq)) {
                        /* releases page group bit lock and