diff --git a/include/os/freebsd/spl/sys/list.h b/include/os/freebsd/spl/sys/list.h index 6c32402a7bd1..f15ec7a271e3 100644 --- a/include/os/freebsd/spl/sys/list.h +++ b/include/os/freebsd/spl/sys/list.h @@ -52,6 +52,7 @@ void *list_tail(list_t *); void *list_next(list_t *, void *); void *list_prev(list_t *, void *); int list_is_empty(list_t *); +int list_length(list_t *); void list_link_init(list_node_t *); void list_link_replace(list_node_t *, list_node_t *); diff --git a/include/os/linux/spl/sys/list.h b/include/os/linux/spl/sys/list.h index 80300df15abe..e0b5091e8234 100644 --- a/include/os/linux/spl/sys/list.h +++ b/include/os/linux/spl/sys/list.h @@ -50,6 +50,7 @@ typedef struct list_head list_node_t; typedef struct list { size_t list_size; size_t list_offset; + uint32_t list_length; list_node_t list_head; } list_t; @@ -62,6 +63,12 @@ list_is_empty(list_t *list) return (list_empty(&list->list_head)); } +static inline int +list_length(list_t *list) +{ + return (list->list_length); +} + static inline void list_link_init(list_node_t *node) { @@ -74,6 +81,7 @@ list_create(list_t *list, size_t size, size_t offset) { list->list_size = size; list->list_offset = offset; + list->list_length = 0; INIT_LIST_HEAD(&list->list_head); } @@ -86,12 +94,14 @@ list_destroy(list_t *list) static inline void list_insert_head(list_t *list, void *object) { + list->list_length++; list_add(list_d2l(list, object), &list->list_head); } static inline void list_insert_tail(list_t *list, void *object) { + list->list_length++; list_add_tail(list_d2l(list, object), &list->list_head); } @@ -100,8 +110,10 @@ list_insert_after(list_t *list, void *object, void *nobject) { if (object == NULL) list_insert_head(list, nobject); - else + else { + list->list_length++; list_add(list_d2l(list, nobject), list_d2l(list, object)); + } } static inline void @@ -109,19 +121,23 @@ list_insert_before(list_t *list, void *object, void *nobject) { if (object == NULL) list_insert_tail(list, nobject); - else + else { + list->list_length++; list_add_tail(list_d2l(list, nobject), list_d2l(list, object)); + } } static inline void list_remove(list_t *list, void *object) { + list->list_length--; list_del(list_d2l(list, object)); } static inline void * list_remove_head(list_t *list) { + list->list_length--; list_node_t *head = list->list_head.next; if (head == &list->list_head) return (NULL); @@ -133,6 +149,7 @@ list_remove_head(list_t *list) static inline void * list_remove_tail(list_t *list) { + list->list_length--; list_node_t *tail = list->list_head.prev; if (tail == &list->list_head) return (NULL); @@ -191,6 +208,8 @@ list_link_active(list_node_t *node) static inline void spl_list_move_tail(list_t *dst, list_t *src) { + dst->list_length += src->list_length; + src->list_length = 0; list_splice_init(&src->list_head, dst->list_head.prev); } diff --git a/lib/libspl/include/sys/list.h b/lib/libspl/include/sys/list.h index 6c32402a7bd1..f15ec7a271e3 100644 --- a/lib/libspl/include/sys/list.h +++ b/lib/libspl/include/sys/list.h @@ -52,6 +52,7 @@ void *list_tail(list_t *); void *list_next(list_t *, void *); void *list_prev(list_t *, void *); int list_is_empty(list_t *); +int list_length(list_t *); void list_link_init(list_node_t *); void list_link_replace(list_node_t *, list_node_t *); diff --git a/lib/libspl/include/sys/list_impl.h b/lib/libspl/include/sys/list_impl.h index 24c1ceb2a9fa..cc6b54168a70 100644 --- a/lib/libspl/include/sys/list_impl.h +++ b/lib/libspl/include/sys/list_impl.h @@ -41,6 +41,7 @@ struct list_node { struct list { size_t list_size; size_t list_offset; + uint32_t list_length; struct list_node list_head; }; diff --git a/lib/libspl/list.c b/lib/libspl/list.c index 24403698627c..e2c2d718dde4 100644 --- a/lib/libspl/list.c +++ b/lib/libspl/list.c @@ -67,6 +67,7 @@ list_create(list_t *list, size_t size, size_t offset) list->list_size = size; list->list_offset = offset; + list->list_length = 0; list->list_head.next = list->list_head.prev = &list->list_head; } @@ -88,6 +89,7 @@ list_insert_after(list_t *list, void *object, void *nobject) if (object == NULL) { list_insert_head(list, nobject); } else { + list->list_length++; list_node_t *lold = list_d2l(list, object); list_insert_after_node(list, lold, nobject); } @@ -99,6 +101,7 @@ list_insert_before(list_t *list, void *object, void *nobject) if (object == NULL) { list_insert_tail(list, nobject); } else { + list->list_length++; list_node_t *lold = list_d2l(list, object); list_insert_before_node(list, lold, nobject); } @@ -107,6 +110,7 @@ list_insert_before(list_t *list, void *object, void *nobject) void list_insert_head(list_t *list, void *object) { + list->list_length++; list_node_t *lold = &list->list_head; list_insert_after_node(list, lold, object); } @@ -114,6 +118,7 @@ list_insert_head(list_t *list, void *object) void list_insert_tail(list_t *list, void *object) { + list->list_length++; list_node_t *lold = &list->list_head; list_insert_before_node(list, lold, object); } @@ -121,6 +126,7 @@ list_insert_tail(list_t *list, void *object) void list_remove(list_t *list, void *object) { + list->list_length--; list_node_t *lold = list_d2l(list, object); ASSERT(!list_empty(list)); ASSERT(lold->next != NULL); @@ -130,6 +136,7 @@ list_remove(list_t *list, void *object) void * list_remove_head(list_t *list) { + list->list_length--; list_node_t *head = list->list_head.next; if (head == &list->list_head) return (NULL); @@ -140,6 +147,7 @@ list_remove_head(list_t *list) void * list_remove_tail(list_t *list) { + list->list_length--; list_node_t *tail = list->list_head.prev; if (tail == &list->list_head) return (NULL); @@ -200,6 +208,8 @@ list_move_tail(list_t *dst, list_t *src) if (list_empty(src)) return; + dst->list_length += src->list_length; + dstnode->prev->next = srcnode->next; srcnode->next->prev = dstnode->prev; dstnode->prev = srcnode->prev; @@ -207,6 +217,8 @@ list_move_tail(list_t *dst, list_t *src) /* empty src list */ srcnode->next = srcnode->prev = srcnode; + + src->list_length = 0; } void @@ -241,3 +253,9 @@ list_is_empty(list_t *list) { return (list_empty(list)); } + +int +list_length(list_t *list) +{ + return (list->list_length); +} diff --git a/module/zfs/vdev_queue.c b/module/zfs/vdev_queue.c index 08d918467d03..cf727404346d 100644 --- a/module/zfs/vdev_queue.c +++ b/module/zfs/vdev_queue.c @@ -1069,7 +1069,7 @@ vdev_queue_class_length(vdev_t *vd, zio_priority_t p) { vdev_queue_t *vq = &vd->vdev_queue; if (vdev_queue_class_fifo(p)) - return (list_is_empty(&vq->vq_class[p].vqc_list) == 0); + return (list_length(&vq->vq_class[p].vqc_list)); else return (avl_numnodes(&vq->vq_class[p].vqc_tree)); }