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

pNFS: consolidate the different range intersection tests

Both pnfs.c and the flexfiles code have their own versions of the
range intersection testing, and the "end_offset" helper.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>

+43 -57
+8 -25
fs/nfs/flexfilelayout/flexfilelayoutdev.c
··· 198 198 return true; 199 199 } 200 200 201 - static u64 202 - end_offset(u64 start, u64 len) 203 - { 204 - u64 end; 205 - 206 - end = start + len; 207 - return end >= start ? end : NFS4_MAX_UINT64; 208 - } 209 - 210 201 static void extend_ds_error(struct nfs4_ff_layout_ds_err *err, 211 202 u64 offset, u64 length) 212 203 { 213 204 u64 end; 214 205 215 - end = max_t(u64, end_offset(err->offset, err->length), 216 - end_offset(offset, length)); 206 + end = max_t(u64, pnfs_end_offset(err->offset, err->length), 207 + pnfs_end_offset(offset, length)); 217 208 err->offset = min_t(u64, err->offset, offset); 218 209 err->length = end - err->offset; 219 210 } ··· 226 235 ret = memcmp(&e1->deviceid, &e2->deviceid, sizeof(e1->deviceid)); 227 236 if (ret != 0) 228 237 return ret; 229 - if (end_offset(e1->offset, e1->length) < e2->offset) 238 + if (pnfs_end_offset(e1->offset, e1->length) < e2->offset) 230 239 return -1; 231 - if (e1->offset > end_offset(e2->offset, e2->length)) 240 + if (e1->offset > pnfs_end_offset(e2->offset, e2->length)) 232 241 return 1; 233 242 /* If ranges overlap or are contiguous, they are the same */ 234 243 return 0; ··· 448 457 } 449 458 } 450 459 451 - static bool is_range_intersecting(u64 offset1, u64 length1, 452 - u64 offset2, u64 length2) 453 - { 454 - u64 end1 = end_offset(offset1, length1); 455 - u64 end2 = end_offset(offset2, length2); 456 - 457 - return (end1 == NFS4_MAX_UINT64 || end1 > offset2) && 458 - (end2 == NFS4_MAX_UINT64 || end2 > offset1); 459 - } 460 - 461 460 /* called with inode i_lock held */ 462 461 int ff_layout_encode_ds_ioerr(struct nfs4_flexfile_layout *flo, 463 462 struct xdr_stream *xdr, int *count, ··· 457 476 __be32 *p; 458 477 459 478 list_for_each_entry_safe(err, n, &flo->error_list, list) { 460 - if (!is_range_intersecting(err->offset, err->length, 461 - range->offset, range->length)) 479 + if (!pnfs_is_range_intersecting(err->offset, 480 + pnfs_end_offset(err->offset, err->length), 481 + range->offset, 482 + pnfs_end_offset(range->offset, range->length))) 462 483 continue; 463 484 /* offset(8) + length(8) + stateid(NFS4_STATEID_SIZE) 464 485 * + array length + deviceid(NFS4_DEVICEID4_SIZE)
+3 -32
fs/nfs/pnfs.c
··· 500 500 } 501 501 EXPORT_SYMBOL_GPL(pnfs_put_lseg_locked); 502 502 503 - static u64 504 - end_offset(u64 start, u64 len) 505 - { 506 - u64 end; 507 - 508 - end = start + len; 509 - return end >= start ? end : NFS4_MAX_UINT64; 510 - } 511 - 512 503 /* 513 504 * is l2 fully contained in l1? 514 505 * start1 end1 ··· 512 521 const struct pnfs_layout_range *l2) 513 522 { 514 523 u64 start1 = l1->offset; 515 - u64 end1 = end_offset(start1, l1->length); 524 + u64 end1 = pnfs_end_offset(start1, l1->length); 516 525 u64 start2 = l2->offset; 517 - u64 end2 = end_offset(start2, l2->length); 526 + u64 end2 = pnfs_end_offset(start2, l2->length); 518 527 519 528 return (start1 <= start2) && (end1 >= end2); 520 - } 521 - 522 - /* 523 - * is l1 and l2 intersecting? 524 - * start1 end1 525 - * [----------------------------------) 526 - * start2 end2 527 - * [----------------) 528 - */ 529 - static bool 530 - pnfs_lseg_range_intersecting(const struct pnfs_layout_range *l1, 531 - const struct pnfs_layout_range *l2) 532 - { 533 - u64 start1 = l1->offset; 534 - u64 end1 = end_offset(start1, l1->length); 535 - u64 start2 = l2->offset; 536 - u64 end2 = end_offset(start2, l2->length); 537 - 538 - return (end1 == NFS4_MAX_UINT64 || end1 > start2) && 539 - (end2 == NFS4_MAX_UINT64 || end2 > start1); 540 529 } 541 530 542 531 static bool pnfs_lseg_dec_and_remove_zero(struct pnfs_layout_segment *lseg, ··· 2040 2069 * 2041 2070 */ 2042 2071 if (pgio->pg_lseg) { 2043 - seg_end = end_offset(pgio->pg_lseg->pls_range.offset, 2072 + seg_end = pnfs_end_offset(pgio->pg_lseg->pls_range.offset, 2044 2073 pgio->pg_lseg->pls_range.length); 2045 2074 req_start = req_offset(req); 2046 2075 WARN_ON_ONCE(req_start >= seg_end);
+32
fs/nfs/pnfs.h
··· 560 560 memcpy(dst, src, sizeof(*dst)); 561 561 } 562 562 563 + static inline u64 564 + pnfs_end_offset(u64 start, u64 len) 565 + { 566 + if (NFS4_MAX_UINT64 - start <= len) 567 + return NFS4_MAX_UINT64; 568 + return start + len; 569 + } 570 + 571 + /* 572 + * Are 2 ranges intersecting? 573 + * start1 end1 574 + * [----------------------------------) 575 + * start2 end2 576 + * [----------------) 577 + */ 578 + static inline bool 579 + pnfs_is_range_intersecting(u64 start1, u64 end1, u64 start2, u64 end2) 580 + { 581 + return (end1 == NFS4_MAX_UINT64 || start2 < end1) && 582 + (end2 == NFS4_MAX_UINT64 || start1 < end2); 583 + } 584 + 585 + static inline bool 586 + pnfs_lseg_range_intersecting(const struct pnfs_layout_range *l1, 587 + const struct pnfs_layout_range *l2) 588 + { 589 + u64 end1 = pnfs_end_offset(l1->offset, l1->length); 590 + u64 end2 = pnfs_end_offset(l2->offset, l2->length); 591 + 592 + return pnfs_is_range_intersecting(l1->offset, end1, l2->offset, end2); 593 + } 594 + 563 595 extern unsigned int layoutstats_timer; 564 596 565 597 #ifdef NFS_DEBUG