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>hifive-unleashed-5.1
parent
ee284e35d8
commit
17822b207f
|
@ -198,22 +198,13 @@ static bool ff_layout_mirror_valid(struct pnfs_layout_segment *lseg,
|
||||||
return true;
|
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,
|
static void extend_ds_error(struct nfs4_ff_layout_ds_err *err,
|
||||||
u64 offset, u64 length)
|
u64 offset, u64 length)
|
||||||
{
|
{
|
||||||
u64 end;
|
u64 end;
|
||||||
|
|
||||||
end = max_t(u64, end_offset(err->offset, err->length),
|
end = max_t(u64, pnfs_end_offset(err->offset, err->length),
|
||||||
end_offset(offset, length));
|
pnfs_end_offset(offset, length));
|
||||||
err->offset = min_t(u64, err->offset, offset);
|
err->offset = min_t(u64, err->offset, offset);
|
||||||
err->length = end - err->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));
|
ret = memcmp(&e1->deviceid, &e2->deviceid, sizeof(e1->deviceid));
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
if (end_offset(e1->offset, e1->length) < e2->offset)
|
if (pnfs_end_offset(e1->offset, e1->length) < e2->offset)
|
||||||
return -1;
|
return -1;
|
||||||
if (e1->offset > end_offset(e2->offset, e2->length))
|
if (e1->offset > pnfs_end_offset(e2->offset, e2->length))
|
||||||
return 1;
|
return 1;
|
||||||
/* If ranges overlap or are contiguous, they are the same */
|
/* If ranges overlap or are contiguous, they are the same */
|
||||||
return 0;
|
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 */
|
/* called with inode i_lock held */
|
||||||
int ff_layout_encode_ds_ioerr(struct nfs4_flexfile_layout *flo,
|
int ff_layout_encode_ds_ioerr(struct nfs4_flexfile_layout *flo,
|
||||||
struct xdr_stream *xdr, int *count,
|
struct xdr_stream *xdr, int *count,
|
||||||
|
@ -476,8 +457,10 @@ int ff_layout_encode_ds_ioerr(struct nfs4_flexfile_layout *flo,
|
||||||
__be32 *p;
|
__be32 *p;
|
||||||
|
|
||||||
list_for_each_entry_safe(err, n, &flo->error_list, list) {
|
list_for_each_entry_safe(err, n, &flo->error_list, list) {
|
||||||
if (!is_range_intersecting(err->offset, err->length,
|
if (!pnfs_is_range_intersecting(err->offset,
|
||||||
range->offset, range->length))
|
pnfs_end_offset(err->offset, err->length),
|
||||||
|
range->offset,
|
||||||
|
pnfs_end_offset(range->offset, range->length)))
|
||||||
continue;
|
continue;
|
||||||
/* offset(8) + length(8) + stateid(NFS4_STATEID_SIZE)
|
/* offset(8) + length(8) + stateid(NFS4_STATEID_SIZE)
|
||||||
* + array length + deviceid(NFS4_DEVICEID4_SIZE)
|
* + array length + deviceid(NFS4_DEVICEID4_SIZE)
|
||||||
|
|
|
@ -500,15 +500,6 @@ pnfs_put_lseg_locked(struct pnfs_layout_segment *lseg)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(pnfs_put_lseg_locked);
|
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?
|
* is l2 fully contained in l1?
|
||||||
* start1 end1
|
* start1 end1
|
||||||
|
@ -521,33 +512,13 @@ pnfs_lseg_range_contained(const struct pnfs_layout_range *l1,
|
||||||
const struct pnfs_layout_range *l2)
|
const struct pnfs_layout_range *l2)
|
||||||
{
|
{
|
||||||
u64 start1 = l1->offset;
|
u64 start1 = l1->offset;
|
||||||
u64 end1 = end_offset(start1, l1->length);
|
u64 end1 = pnfs_end_offset(start1, l1->length);
|
||||||
u64 start2 = l2->offset;
|
u64 start2 = l2->offset;
|
||||||
u64 end2 = end_offset(start2, l2->length);
|
u64 end2 = pnfs_end_offset(start2, l2->length);
|
||||||
|
|
||||||
return (start1 <= start2) && (end1 >= end2);
|
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,
|
static bool pnfs_lseg_dec_and_remove_zero(struct pnfs_layout_segment *lseg,
|
||||||
struct list_head *tmp_list)
|
struct list_head *tmp_list)
|
||||||
{
|
{
|
||||||
|
@ -2069,7 +2040,7 @@ pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio,
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
if (pgio->pg_lseg) {
|
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);
|
pgio->pg_lseg->pls_range.length);
|
||||||
req_start = req_offset(req);
|
req_start = req_offset(req);
|
||||||
WARN_ON_ONCE(req_start >= seg_end);
|
WARN_ON_ONCE(req_start >= seg_end);
|
||||||
|
|
|
@ -560,6 +560,38 @@ pnfs_copy_range(struct pnfs_layout_range *dst,
|
||||||
memcpy(dst, src, sizeof(*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;
|
extern unsigned int layoutstats_timer;
|
||||||
|
|
||||||
#ifdef NFS_DEBUG
|
#ifdef NFS_DEBUG
|
||||||
|
|
Loading…
Reference in New Issue