~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/xfs/scrub/xfarray.h

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0-or-later */
  2 /*
  3  * Copyright (C) 2021-2023 Oracle.  All Rights Reserved.
  4  * Author: Darrick J. Wong <djwong@kernel.org>
  5  */
  6 #ifndef __XFS_SCRUB_XFARRAY_H__
  7 #define __XFS_SCRUB_XFARRAY_H__
  8 
  9 /* xfile array index type, along with cursor initialization */
 10 typedef uint64_t                xfarray_idx_t;
 11 #define XFARRAY_NULLIDX         ((__force xfarray_idx_t)-1ULL)
 12 #define XFARRAY_CURSOR_INIT     ((__force xfarray_idx_t)0)
 13 
 14 /* Iterate each index of an xfile array. */
 15 #define foreach_xfarray_idx(array, idx) \
 16         for ((idx) = XFARRAY_CURSOR_INIT; \
 17              (idx) < xfarray_length(array); \
 18              (idx)++)
 19 
 20 struct xfarray {
 21         /* Underlying file that backs the array. */
 22         struct xfile    *xfile;
 23 
 24         /* Number of array elements. */
 25         xfarray_idx_t   nr;
 26 
 27         /* Maximum possible array size. */
 28         xfarray_idx_t   max_nr;
 29 
 30         /* Number of unset slots in the array below @nr. */
 31         uint64_t        unset_slots;
 32 
 33         /* Size of an array element. */
 34         size_t          obj_size;
 35 
 36         /* log2 of array element size, if possible. */
 37         int             obj_size_log;
 38 };
 39 
 40 int xfarray_create(const char *descr, unsigned long long required_capacity,
 41                 size_t obj_size, struct xfarray **arrayp);
 42 void xfarray_destroy(struct xfarray *array);
 43 int xfarray_load(struct xfarray *array, xfarray_idx_t idx, void *ptr);
 44 int xfarray_unset(struct xfarray *array, xfarray_idx_t idx);
 45 int xfarray_store(struct xfarray *array, xfarray_idx_t idx, const void *ptr);
 46 int xfarray_store_anywhere(struct xfarray *array, const void *ptr);
 47 bool xfarray_element_is_null(struct xfarray *array, const void *ptr);
 48 void xfarray_truncate(struct xfarray *array);
 49 unsigned long long xfarray_bytes(struct xfarray *array);
 50 
 51 /*
 52  * Load an array element, but zero the buffer if there's no data because we
 53  * haven't stored to that array element yet.
 54  */
 55 static inline int
 56 xfarray_load_sparse(
 57         struct xfarray  *array,
 58         uint64_t        idx,
 59         void            *rec)
 60 {
 61         int             error = xfarray_load(array, idx, rec);
 62 
 63         if (error == -ENODATA) {
 64                 memset(rec, 0, array->obj_size);
 65                 return 0;
 66         }
 67         return error;
 68 }
 69 
 70 /* Append an element to the array. */
 71 static inline int xfarray_append(struct xfarray *array, const void *ptr)
 72 {
 73         return xfarray_store(array, array->nr, ptr);
 74 }
 75 
 76 uint64_t xfarray_length(struct xfarray *array);
 77 int xfarray_load_next(struct xfarray *array, xfarray_idx_t *idx, void *rec);
 78 
 79 /*
 80  * Iterate the non-null elements in a sparse xfarray.  Callers should
 81  * initialize *idx to XFARRAY_CURSOR_INIT before the first call; on return, it
 82  * will be set to one more than the index of the record that was retrieved.
 83  * Returns 1 if a record was retrieved, 0 if there weren't any more records, or
 84  * a negative errno.
 85  */
 86 static inline int
 87 xfarray_iter(
 88         struct xfarray  *array,
 89         xfarray_idx_t   *idx,
 90         void            *rec)
 91 {
 92         int ret = xfarray_load_next(array, idx, rec);
 93 
 94         if (ret == -ENODATA)
 95                 return 0;
 96         if (ret == 0)
 97                 return 1;
 98         return ret;
 99 }
100 
101 /* Declarations for xfile array sort functionality. */
102 
103 typedef cmp_func_t xfarray_cmp_fn;
104 
105 /* Perform an in-memory heapsort for small subsets. */
106 #define XFARRAY_ISORT_SHIFT             (4)
107 #define XFARRAY_ISORT_NR                (1U << XFARRAY_ISORT_SHIFT)
108 
109 /* Evalulate this many points to find the qsort pivot. */
110 #define XFARRAY_QSORT_PIVOT_NR          (9)
111 
112 struct xfarray_sortinfo {
113         struct xfarray          *array;
114 
115         /* Comparison function for the sort. */
116         xfarray_cmp_fn          cmp_fn;
117 
118         /* Maximum height of the partition stack. */
119         uint8_t                 max_stack_depth;
120 
121         /* Current height of the partition stack. */
122         int8_t                  stack_depth;
123 
124         /* Maximum stack depth ever used. */
125         uint8_t                 max_stack_used;
126 
127         /* XFARRAY_SORT_* flags; see below. */
128         unsigned int            flags;
129 
130         /* next time we want to cond_resched() */
131         struct xchk_relax       relax;
132 
133         /* Cache a folio here for faster scanning for pivots */
134         struct folio            *folio;
135 
136         /* First array index in folio that is completely readable */
137         xfarray_idx_t           first_folio_idx;
138 
139         /* Last array index in folio that is completely readable */
140         xfarray_idx_t           last_folio_idx;
141 
142 #ifdef DEBUG
143         /* Performance statistics. */
144         uint64_t                loads;
145         uint64_t                stores;
146         uint64_t                compares;
147         uint64_t                heapsorts;
148 #endif
149         /*
150          * Extra bytes are allocated beyond the end of the structure to store
151          * quicksort information.  C does not permit multiple VLAs per struct,
152          * so we document all of this in a comment.
153          *
154          * Pretend that we have a typedef for array records:
155          *
156          * typedef char[array->obj_size]        xfarray_rec_t;
157          *
158          * First comes the quicksort partition stack:
159          *
160          * xfarray_idx_t        lo[max_stack_depth];
161          * xfarray_idx_t        hi[max_stack_depth];
162          *
163          * union {
164          *
165          * If for a given subset we decide to use an in-memory sort, we use a
166          * block of scratchpad records here to compare items:
167          *
168          *      xfarray_rec_t   scratch[ISORT_NR];
169          *
170          * Otherwise, we want to partition the records to partition the array.
171          * We store the chosen pivot record at the start of the scratchpad area
172          * and use the rest to sample some records to estimate the median.
173          * The format of the qsort_pivot array enables us to use the kernel
174          * heapsort function to place the median value in the middle.
175          *
176          *      struct {
177          *              xfarray_rec_t   pivot;
178          *              struct {
179          *                      xfarray_rec_t   rec;  (rounded up to 8 bytes)
180          *                      xfarray_idx_t   idx;
181          *              } qsort_pivot[QSORT_PIVOT_NR];
182          *      };
183          * }
184          */
185 };
186 
187 /* Sort can be interrupted by a fatal signal. */
188 #define XFARRAY_SORT_KILLABLE   (1U << 0)
189 
190 int xfarray_sort(struct xfarray *array, xfarray_cmp_fn cmp_fn,
191                 unsigned int flags);
192 
193 #endif /* __XFS_SCRUB_XFARRAY_H__ */
194 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php