pNFS: consolidate the different range intersection tests
authorTrond Myklebust <trond.myklebust@primarydata.com>
Tue, 25 Oct 2016 16:24:25 +0000 (12:24 -0400)
committerTrond Myklebust <trond.myklebust@primarydata.com>
Thu, 1 Dec 2016 22:21:41 +0000 (17:21 -0500)
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>
fs/nfs/flexfilelayout/flexfilelayoutdev.c
fs/nfs/pnfs.c
fs/nfs/pnfs.h

index f7a3f6b05369a21d7e1190625e5871c55d1aeeb2..6cf545c06cd39da92fe2fe2afad9e66dc20d2062 100644 (file)
@@ -198,22 +198,13 @@ static bool ff_layout_mirror_valid(struct pnfs_layout_segment *lseg,
        return true;
 }
 
-static u64
-end_offset(u64 start, u64 len)
-{
-       u64 end;
-
-       end = start + len;
-       return end >= start ? end : NFS4_MAX_UINT64;
-}
-
 static void extend_ds_error(struct nfs4_ff_layout_ds_err *err,
                            u64 offset, u64 length)
 {
        u64 end;
 
-       end = max_t(u64, end_offset(err->offset, err->length),
-                   end_offset(offset, length));
+       end = max_t(u64, pnfs_end_offset(err->offset, err->length),
+                   pnfs_end_offset(offset, length));
        err->offset = min_t(u64, err->offset, offset);
        err->length = end - err->offset;
 }
@@ -235,9 +226,9 @@ ff_ds_error_match(const struct nfs4_ff_layout_ds_err *e1,
        ret = memcmp(&e1->deviceid, &e2->deviceid, sizeof(e1->deviceid));
        if (ret != 0)
                return ret;
-       if (end_offset(e1->offset, e1->length) < e2->offset)
+       if (pnfs_end_offset(e1->offset, e1->length) < e2->offset)
                return -1;
-       if (e1->offset > end_offset(e2->offset, e2->length))
+       if (e1->offset > pnfs_end_offset(e2->offset, e2->length))
                return 1;
        /* If ranges overlap or are contiguous, they are the same */
        return 0;
@@ -457,16 +448,6 @@ nfs4_ff_find_or_create_ds_client(struct pnfs_layout_segment *lseg, u32 ds_idx,
        }
 }
 
-static bool is_range_intersecting(u64 offset1, u64 length1,
-                                 u64 offset2, u64 length2)
-{
-       u64 end1 = end_offset(offset1, length1);
-       u64 end2 = end_offset(offset2, length2);
-
-       return (end1 == NFS4_MAX_UINT64 || end1 > offset2) &&
-              (end2 == NFS4_MAX_UINT64 || end2 > offset1);
-}
-
 /* called with inode i_lock held */
 int ff_layout_encode_ds_ioerr(struct nfs4_flexfile_layout *flo,
                              struct xdr_stream *xdr, int *count,
@@ -476,8 +457,10 @@ int ff_layout_encode_ds_ioerr(struct nfs4_flexfile_layout *flo,
        __be32 *p;
 
        list_for_each_entry_safe(err, n, &flo->error_list, list) {
-               if (!is_range_intersecting(err->offset, err->length,
-                                          range->offset, range->length))
+               if (!pnfs_is_range_intersecting(err->offset,
+                               pnfs_end_offset(err->offset, err->length),
+                               range->offset,
+                               pnfs_end_offset(range->offset, range->length)))
                        continue;
                /* offset(8) + length(8) + stateid(NFS4_STATEID_SIZE)
                 * + array length + deviceid(NFS4_DEVICEID4_SIZE)
index e17d9ec82ca7f51dd554f9c844e3130a69b132a2..d70cc467a87b95129fc03bd7e4489d8e17bdfe66 100644 (file)
@@ -500,15 +500,6 @@ pnfs_put_lseg_locked(struct pnfs_layout_segment *lseg)
 }
 EXPORT_SYMBOL_GPL(pnfs_put_lseg_locked);
 
-static u64
-end_offset(u64 start, u64 len)
-{
-       u64 end;
-
-       end = start + len;
-       return end >= start ? end : NFS4_MAX_UINT64;
-}
-
 /*
  * is l2 fully contained in l1?
  *   start1                             end1
@@ -521,33 +512,13 @@ pnfs_lseg_range_contained(const struct pnfs_layout_range *l1,
                 const struct pnfs_layout_range *l2)
 {
        u64 start1 = l1->offset;
-       u64 end1 = end_offset(start1, l1->length);
+       u64 end1 = pnfs_end_offset(start1, l1->length);
        u64 start2 = l2->offset;
-       u64 end2 = end_offset(start2, l2->length);
+       u64 end2 = pnfs_end_offset(start2, l2->length);
 
        return (start1 <= start2) && (end1 >= end2);
 }
 
-/*
- * is l1 and l2 intersecting?
- *   start1                             end1
- *   [----------------------------------)
- *                              start2           end2
- *                              [----------------)
- */
-static bool
-pnfs_lseg_range_intersecting(const struct pnfs_layout_range *l1,
-                   const struct pnfs_layout_range *l2)
-{
-       u64 start1 = l1->offset;
-       u64 end1 = end_offset(start1, l1->length);
-       u64 start2 = l2->offset;
-       u64 end2 = end_offset(start2, l2->length);
-
-       return (end1 == NFS4_MAX_UINT64 || end1 > start2) &&
-              (end2 == NFS4_MAX_UINT64 || end2 > start1);
-}
-
 static bool pnfs_lseg_dec_and_remove_zero(struct pnfs_layout_segment *lseg,
                struct list_head *tmp_list)
 {
@@ -2069,7 +2040,7 @@ pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio,
         *
         */
        if (pgio->pg_lseg) {
-               seg_end = end_offset(pgio->pg_lseg->pls_range.offset,
+               seg_end = pnfs_end_offset(pgio->pg_lseg->pls_range.offset,
                                     pgio->pg_lseg->pls_range.length);
                req_start = req_offset(req);
                WARN_ON_ONCE(req_start >= seg_end);
index 44cad8afda0e4e3b95f64a57d16ec2036a4b0c90..337dad382b6a4404e07a4e565ebddaee0c471ebf 100644 (file)
@@ -560,6 +560,38 @@ pnfs_copy_range(struct pnfs_layout_range *dst,
        memcpy(dst, src, sizeof(*dst));
 }
 
+static inline u64
+pnfs_end_offset(u64 start, u64 len)
+{
+       if (NFS4_MAX_UINT64 - start <= len)
+               return NFS4_MAX_UINT64;
+       return start + len;
+}
+
+/*
+ * Are 2 ranges intersecting?
+ *   start1                             end1
+ *   [----------------------------------)
+ *                                start2           end2
+ *                                [----------------)
+ */
+static inline bool
+pnfs_is_range_intersecting(u64 start1, u64 end1, u64 start2, u64 end2)
+{
+       return (end1 == NFS4_MAX_UINT64 || start2 < end1) &&
+               (end2 == NFS4_MAX_UINT64 || start1 < end2);
+}
+
+static inline bool
+pnfs_lseg_range_intersecting(const struct pnfs_layout_range *l1,
+               const struct pnfs_layout_range *l2)
+{
+       u64 end1 = pnfs_end_offset(l1->offset, l1->length);
+       u64 end2 = pnfs_end_offset(l2->offset, l2->length);
+
+       return pnfs_is_range_intersecting(l1->offset, end1, l2->offset, end2);
+}
+
 extern unsigned int layoutstats_timer;
 
 #ifdef NFS_DEBUG