Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

nfs: handle overlapping reqs in lock_and_join

This is needed for mirrored DS support, where multuple requests
cover the same range.

Signed-off-by: Weston Andros Adamson <dros@primarydata.com>

authored by

Weston Andros Adamson and committed by
Tom Haynes
309a1d65 180bb5ec

+11 -6
+11 -6
fs/nfs/write.c
··· 473 473 do { 474 474 /* 475 475 * Subrequests are always contiguous, non overlapping 476 - * and in order. If not, it's a programming error. 476 + * and in order - but may be repeated (mirrored writes). 477 477 */ 478 - WARN_ON_ONCE(subreq->wb_offset != 479 - (head->wb_offset + total_bytes)); 480 - 481 - /* keep track of how many bytes this group covers */ 482 - total_bytes += subreq->wb_bytes; 478 + if (subreq->wb_offset == (head->wb_offset + total_bytes)) { 479 + /* keep track of how many bytes this group covers */ 480 + total_bytes += subreq->wb_bytes; 481 + } else if (WARN_ON_ONCE(subreq->wb_offset < head->wb_offset || 482 + ((subreq->wb_offset + subreq->wb_bytes) > 483 + (head->wb_offset + total_bytes)))) { 484 + nfs_page_group_unlock(head); 485 + spin_unlock(&inode->i_lock); 486 + return ERR_PTR(-EIO); 487 + } 483 488 484 489 if (!nfs_lock_request(subreq)) { 485 490 /* releases page group bit lock and