# Promises — change 63809: LU-19852 lod: raidset aware stripe allocator
Branch master · PS55 · MERGED · https://review.whamcloud.com/c/fs/lustre-release/+/63809
Harvested 2026-11-05
Refer to items by id, e.g. "address item 63809-6095869a".

## Open (0)


## To check (14)

### 63809-6095869a — lustre/lod/lod_qos.c:3581 [severity: high]
*Status: not checked.*
*The thread is marked resolved, but the item is still open.*
**Summary:** Fix possible ERR_PTR dereference of 'd' in lod_comp_prep_create()
**Origin:** comment on PS53, thread resolved; promise by Ronnie Sahlberg: "Acknowledged"
**Thread:**
> [Misc Code Checks Robot (Gatekeeper helper), 2026-08-05] error: lod_comp_prep_create():'d' dereferencing possible ERR_PTR()
> [Ronnie Sahlberg, 2026-08-05] Acknowledged
> [Ronnie Sahlberg, 2026-08-05] Acknowledged
**Code context:**
```
    3576: 			GOTO(out, rc = -ENOMEM);
    3577: 
    3578: repeat:
    3579: 		lod_getref(&d->lod_ost_descs);
    3580: 		/* XXX: support for non-0 files w/o objects */
>>> 3581: 		CDEBUG(D_OTHER, "tgt_count %d stripe_count %d\n",
    3582: 		       d->lod_ost_count, stripe_len);
    3583: 
    3584: 		if (lod_comp->llc_ostlist.op_array &&
    3585: 		    lod_comp->llc_ostlist.op_count) {
    3586: 			rc = lod_alloc_ost_list(env, lo, stripe, ost_indices,
```
**Also raised in:** 63809-a786e20f (lustre/lod/lod_qos.c, PS6), 63809-703a1aaa (lustre/lod/lod_qos.c, PS7), 63809-424ba43a (lustre/lod/lod_qos.c, PS8), 63809-34cd2d02 (lustre/lod/lod_qos.c, PS9), 63809-6c3c2385 (lustre/lod/lod_qos.c, PS10), 63809-2d51aec9 (lustre/lod/lod_qos.c, PS11), 63809-d729ff40 (lustre/lod/lod_qos.c, PS12), 63809-d80848db (lustre/lod/lod_qos.c, PS13), 63809-c208ba55 (lustre/lod/lod_qos.c, PS35), 63809-78678084 (lustre/lod/lod_qos.c, PS36), 63809-5795c4b6 (lustre/lod/lod_qos.c, PS37), 63809-fd99dcdd (lustre/lod/lod_qos.c, PS38), 63809-96eeedb8 (lustre/lod/lod_qos.c, PS39)
**Gerrit:** https://review.whamcloud.com/c/fs/lustre-release/+/63809/comment/6095869a_309127a4/

### 63809-ba227e7a — include/uapi/linux/lustre/lustre_user.h:3171 [severity: high]
*Status: not checked.*
*The thread is marked resolved, but the item is still open.*
**Summary:** Handle mismatch between on-disk EC layout and new raid-set derivation for existing files
**Origin:** comment on PS52, thread resolved; promise by Ronnie Sahlberg: "That is fine. This is a new feature so no files exist yet on non-test filesystems."
**Thread:**
> [Gerrit AI review for Lustre, 2026-08-04] (defect) Lowering the threshold changes how an existing layout is interpreted, not just how a new one is built.
> 
>     ec_split_stripes(4, 2)   old -> n0=1 k0=4
>                              new -> n0=2 k0=2
> 
> A file created with `-c 4 --ec 2+1` therefore has one parity stripe on disk, while llapi_ec_resync_or_verify_comp() and lov_io.c now derive two raid sets for it from the same stored stripe counts. Is the mismatch on already-created files handled somewhere, or is EC still considered unstable enough that it doesn't matter?
> [Ronnie Sahlberg, 2026-08-04] That is fine. This is a new feature so no files exist yet on non-test filesystems.
**Code context:**
```
    3166: 
    3167: /*
    3168:  * Arbitrary limit on the minimum size we will attempt to split up into
    3169:  * smaller chunks for ec computation.
    3170:  */
>>> 3171: #define EC_MIN_SPLIT_SIZE 4
    3172: /*
    3173:  * We have data consisting of 'total' stripes. Create a mapping where
    3174:  * we split this into smaller chunks based on what the
    3175:  * suggested / requested hint is.
    3176:  * Try to keep the sizes of the different buckets as equal as possible
```
**Also raised in:** 63809-7a68f379 (include/uapi/linux/lustre/lustre_user.h, PS44)
**Gerrit:** https://review.whamcloud.com/c/fs/lustre-release/+/63809/comment/ba227e7a_3a35abba/

### 63809-c72d531c — (change-level) [severity: high]
*Status: not checked.*
*The thread is marked resolved, but the item is still open.*
**Summary:** Relax overly stringent stripe-count requirement and add -c -1 EC test coverage for production readiness
**Origin:** comment on PS14, thread resolved
**Thread:**
> [Andreas Dilger, 2026-03-26] For this to become production-ready it needs to become less stringent on the stripe count requirement, or I think it could result in EC-enabled filesystems being less available than without EC in some cases.
> 
> I also don't see *any* test cases in sanity-ec.sh where `-c -1` is used to allocate a widely-striped file/component.  The stripe count is always explicitly calculated to leave enough margin for parity stripes, but that isn't how layouts are specified in production.
**Gerrit:** https://review.whamcloud.com/c/fs/lustre-release/+/63809/comment/c72d531c_478c2042/

### 63809-1131eb7d — lustre/lod/lod_qos.c:2201 [severity: med]
*Status: not checked.*
**Summary:** Track this issue via filed ticket LU-20526
**Origin:** comment on PS54; promise by Ronnie Sahlberg: "LU-20526 tracks this"
**Thread:**
> [kg.xu, 2026-08-07] (minor) It would be helpful to include the ticket here, if one exists for this part.
> [Andreas Dilger, 2026-08-10] +1, please file a ticket to track this if it doesn't already exist.
> [Ronnie Sahlberg, 2026-08-10] LU-20526 tracks this
**Code context:**
```
    2196: 			CDEBUG(D_OTHER,
    2197: 			       "stripe_count=%d nfound=%d cur_weight=%llu rand=%llu total_weight=%llu\n",
    2198: 			       stripe_count, nfound, cur_weight, rand,
    2199: 			       total_weight);
    2200: 
>>> 2201: 			/* TODO: this check is wrong and can cause the qos
    2202: 			 * allocator to fail.the problem is that we do not
    2203: 			 * compute total_weight and cur_weight the same way
    2204: 			 * when OSTs are offline.
    2205: 			 * Very annoying since if OSTs are offline this will
    2206: 			 * fail, and fallback to rr quite often, making
```
**Also raised in:** 63809-d5fac409 (lustre/lod/lod_qos.c, PS44)
**Gerrit:** https://review.whamcloud.com/c/fs/lustre-release/+/63809/comment/1131eb7d_db1fa96f/

### 63809-1dca7dfd — lustre/tests/sanity-ec.sh:3189 [severity: med]
*Status: not checked.*
**Summary:** Add tests for cross-raidset parity reuse and forced RR allocation path
**Origin:** comment on PS54; promise by Ronnie Sahlberg: "But they are minor tweaks so lets leave them until after this lands, or if there is a code refresh, and I can bake them into the next set of patches"
**Thread:**
> [kg.xu, 2026-08-07] (suggestion) test_27d–27f cover same-raidset uniqueness for -C, but the -c path is different: parity may reuse data OSTs from other raidsets via lod_ec_add_parities(). Worth a case that creates a multi-raidset layout with -c (e.g. -c 8 --ec 4+2 on enough OSTs) and checks that no OST is shared between data and parity within the same raidset, while allowing cross-raidset reuse.
> 
> (suggestion) Most of these paths are hit through QoS first; RR is only the -EAGAIN fallback. Consider one create with lod.*.qos_threshold_rr=100 (restored via stack_trap) so allocation is forced through lod_ost_alloc_rr(), reusing an existing check such as 27c or a -C same-raidset uniqueness check. That would catch RR-only completion / overstriping-flag issues that QoS may not show.
> 
> -- from my AI reviewer
> [Ronnie Sahlberg, 2026-08-10] Good suggestions. But they are minor tweaks so lets leave them until after this lands, or if there is a code refresh, and I can bake them into the next set of patches (which will likely be the failure domain stuff   which is in limbo and needs to be rebased on this once it lands.)
**Code context:**
```
    3184: 	fi
    3185: 
    3186: 	return 0
    3187: }
    3188: 
>>> 3189: test_27d() {
    3190: 	(( OSTCOUNT >= 6 )) || skip "needs >= 6 OSTs"
    3191: 	enable_ec
    3192: 
    3193: 	local tf=$DIR/$tfile
    3194: 
```
**Gerrit:** https://review.whamcloud.com/c/fs/lustre-release/+/63809/comment/1dca7dfd_bc00f602/

### 63809-e9b7763c — lustre/lod/lod_qos.c:409 [severity: med]
*Status: not checked.*
*The thread is marked resolved, but the item is still open.*
**Summary:** Check available OST count in RR case before returning error
**Origin:** comment on PS44, thread resolved; promise by Ronnie Sahlberg: "Acknowledged"
**Thread:**
> [Andreas Dilger, 2026-07-24] If it isn't clear if the number of available OSTs is enough in the RR case, then this should be checked rather than just returning an error for the allocation.
> [Ronnie Sahlberg, 2026-07-29] Acknowledged
**Code context:**
```
     404:  * IF we are computing the minimum stripe count for the data component
     405:  * and we are using the qos allocator we can include the cstripe count
     406:  * in the minimum and allow it to fail early if there are not enough
     407:  * OSTs available for both the data component and the ec component.
     408:  * For the RR allocator we do not have the initial loop to count the
>>>  409:  * total number of available OSTs so we can not do this optimization.
     410:  *
     411:  * Return: an acceptable stripe count depending on flag LOD_USES_DEFAULT_STRIPE:
     412:  *	   all stripes or 3/4 of stripes.  The code is written this way to avoid
     413:  *	   returning 0 for stripe_count < 4, like "stripe_count * 3 / 4" would
     414:  */
```
**Gerrit:** https://review.whamcloud.com/c/fs/lustre-release/+/63809/comment/e9b7763c_a2c6ed07/

### 63809-b509b3cf — lustre/lod/lod_qos.c:430 [severity: med]
*Status: not checked.*
*The thread is marked resolved, but the item is still open.*
**Summary:** Clarify/fix minimum stripe count logic for overstriped vs widely-striped files
**Origin:** comment on PS33, thread resolved; promise by Andreas Dilger: "Yeah, it isn't clear to me why the bear would be specific to overstriped files vs. widely-striped regular files"
**Thread:**
> [Andreas Dilger, 2026-05-22] This seems like it would calculate a large minimum stripe count, essentially covering all of the data and EC stripes for the whole file instead of allowing overlapping data and parity stripes.  So if the requested data stripe count (before splitting into RAID sets) uses all of the OSTs then the EC stripes would push it over the top and cause the file allocation to fail.
> 
> Is there a reason not to have the same `esc_n0 + esc_n1 == 1 ? cstripe_count : 0` check as above?
> [Ronnie Sahlberg, 2026-06-02] The idea was that if we are not using overstriping then we would use a unique OST for each stripe in the whole stripe set but if overstriping is allowed then we only require unique OSTs within each raid set. Thus leading to sometimes requiring very many OSTs.
> 
> 
> Maybe that is not all that useful  so I have changed it now to only require unique OSTs within raidsets regardless of overstriping setting.
> From patchset 36.
> [Andreas Dilger, 2026-06-03] Yeah, it isn't clear to me why the bear would be specific to overstriped files vs. widely-striped regular files
**Code context:**
```
     425: 			return stripe_count + maybe_cstripe;
     426: 
     427: 		if (lod_comp->llc_pattern & LOV_PATTERN_OVERSTRIPING)
     428: 			return sc->esc_k0 + maybe_cstripe;
     429: 		else
>>>  430: 			return sc->esc_k0 * sc->esc_n0 +
     431: 			  sc->esc_k1 * sc->esc_n1;
     432: 	}
     433: 
     434: 	return (flags & LOD_USES_DEFAULT_STRIPE ?
     435: 		stripe_count - (stripe_count / 4) : stripe_count);
```
**Gerrit:** https://review.whamcloud.com/c/fs/lustre-release/+/63809/comment/b509b3cf_90b8d79f/

### 63809-msg-87393e02b527f100b65cefcb8e20ae56c7c46ecd — (change-level) [severity: med]
*Status: not checked.*
**Summary:** Renumber new tests to avoid collision with tests already added by LU-12668 series
**Origin:** comment on PS29
**Thread:**
> [Patrick Farrell, 2026-05-05] The new tests test_26a, test_26b, test_27a, test_30a, test_30b, test_30c in this change collide with same-numbered tests already introduced earlier in the series by 62417 (LU-12668 ec: basic ec tests). Could you renumber these in this patch into a non-overlapping range (28a, 29a, 31a are taken by 62417, so 28b/c, 29b, 31b/c/d would work)?
**Gerrit:** https://review.whamcloud.com/c/fs/lustre-release/+/63809

### 63809-0753db71 — (change-level) [severity: med]
*Status: not checked.*
*The thread is marked resolved, but the item is still open.*
**Summary:** Add exception list or self-skip in sanity.sh test_27D for insufficient OSTs
**Origin:** comment on PS6, thread resolved
**Thread:**
> [Andreas Dilger, 2026-02-18] This needs to add an exception list in `sanity.sh::test_27D()` when there are fewer OSTs than required by the tests...  or have the test cases skip themselves if there aren't enough OSTs.
**Gerrit:** https://review.whamcloud.com/c/fs/lustre-release/+/63809/comment/0753db71_c1b7c5cf/

### 63809-b0ba6344 — lustre/lod/lod_qos.c:944 [severity: low]
*Status: not checked.*
**Summary:** Clarify/verify whether while loop is needed given nfound may be smaller than stripe_count
**Origin:** comment on PS54
**Thread:**
> [kg.xu, 2026-08-07] (question) if `nfound` is the target value, do we really need the above while loop?
> It could produce a smaller `stripe_count` compared with `nfound` though. But still, seems `nfound` is good enough.
**Code context:**
```
     939: 			sc->esc_n1 = 0;
     940: 		}
     941: 		stripe_count--;
     942: 	}
     943: 
>>>  944: 	if (stripe_count > nfound) {
     945: 		/* Resplit from scratch around the OST count we actually have */
     946: 		stripe_count = nfound;
     947: 		ec_split_stripes(stripe_count, suggested, sc);
     948: 	}
     949: 
```
**Gerrit:** https://review.whamcloud.com/c/fs/lustre-release/+/63809/comment/b0ba6344_28064c35/

### 63809-6ec36747 — lustre/lod/lod_qos.c:1221 [severity: low]
*Status: not checked.*
**Summary:** Move parameter to previous line if code is refreshed later
**Origin:** comment on PS54; promise by kg.xu: "could move this parameter up to the previous line (if there's code refresh)."
**Thread:**
> [kg.xu, 2026-08-07] (typo) could move this parameter up to the previous line (if there's code refresh).
**Code context:**
```
    1216: 		if (!(lod_comp->llc_flags & LCME_FL_PARITY) &&
    1217: 		    (ec_raidset_count(sc) > 1) &&
    1218: 		    stripe_idx >= stripe_count_min) {
    1219: 			if (want_overstriping) {
    1220: 				stripe_idx = lod_ec_add_data(env, lo,
>>> 1221: 							     th,
    1222: 							     stripe_idx,
    1223: 							     lod_comp,
    1224: 							     stripe,
    1225: 							     ost_indices);
    1226: 			} else {
```
**Gerrit:** https://review.whamcloud.com/c/fs/lustre-release/+/63809/comment/6ec36747_bb513c42/

### 63809-bb386b2f — lustre/lod/lod_qos.c:1181 [severity: low]
*Status: not checked.*
*The thread is marked resolved, but the item is still open.*
**Summary:** Fix incorrect comment describing raidset conversion behaviour
**Origin:** comment on PS53, thread resolved; promise by Ronnie Sahlberg: "Acknowledged"
**Thread:**
> [Gerrit AI review for Lustre, 2026-08-05] (minor) This describes converting esc_k0 raidsets into esc_k1, but lod_ec_shrink_data_geometry() calls ec_split_stripes(nfound, dstripe, sc), which recomputes the split from scratch and generally changes the number of raid sets rather than their width - `-c 24 --ec 6+2` shrunk to 18 becomes 3x6, not 4x5/4/4/... The same wording is repeated on the QoS side around line 2312.
> [Ronnie Sahlberg, 2026-08-05] Acknowledged
> [Ronnie Sahlberg, 2026-08-05] Acknowledged
**Code context:**
```
    1176: 							 stripe, ost_indices);
    1177: 		/*
    1178: 		 * EC-protected data component is short of unique OSTs.
    1179: 		 * With overstriping (-C) reuse OSTs from earlier raid
    1180: 		 * sets. Without it (-c), shrink the EC geometry by
>>> 1181: 		 * converting esc_k0 raidsets into esc_k1 until the
    1182: 		 * allocated OST count is enough — prefer a smaller
    1183: 		 * layout over failing create when OSTs are offline.
    1184: 		 */
    1185: 		if (!(lod_comp->llc_flags & LCME_FL_PARITY) &&
    1186: 		    (ec_raidset_count(sc) > 1) &&
```
**Gerrit:** https://review.whamcloud.com/c/fs/lustre-release/+/63809/comment/bb386b2f_75a061ee/

### 63809-d08da1ec — lustre/lod/lod_qos.c:668 [severity: low]
*Status: not checked.*
*The thread is marked resolved, but the item is still open.*
**Summary:** Fix misleading error message about parity vs EC-protected data component
**Origin:** comment on PS44, thread resolved; promise by Ronnie Sahlberg: "Acknowledged"
**Thread:**
> [Zhenyu Xu, 2026-07-17] I don't get this, the message implies that this is a parity component trying to be allocated on OST[ost_idx], but an ec protected data component also has non-zero lod_comp->llc_cstripe_count.
> [Ronnie Sahlberg, 2026-07-27] Acknowledged
**Code context:**
```
     663: 	if (ost->ltd_statfs.os_state & OS_STATFS_DEGRADED && speed < 2) {
     664: 		CDEBUG(D_OTHER, "#%d: degraded\n", ost_idx);
     665: 		RETURN(rc);
     666: 	}
     667: 
>>>  668: 	if (lod_comp->llc_cstripe_count &&
     669: 	    (lag->lag_ost_avail <= 0 ||
     670: 	     lod_should_avoid_ost(lo, lag, ost_idx))) {
     671: 		CDEBUG(D_OTHER,
     672: 		       "Skip conflicting OST%d because we want unique OSTs for EC\n",
     673: 		       ost_idx);
```
**Gerrit:** https://review.whamcloud.com/c/fs/lustre-release/+/63809/comment/d08da1ec_8a77dab4/

### 63809-e880dc04 — lustre/lod/lod_qos.c:1826 [severity: low]
*Status: not checked.*
*The thread is marked resolved, but the item is still open.*
**Summary:** Remove dead code later in the patch series
**Origin:** comment on PS43, thread resolved; promise by Marc Vef: "Looks like it, and won't be used by the end of the series."
**Thread:**
> [kg.xu, 2026-07-15] dead code?
> [Marc Vef, 2026-07-15] Looks like it, and won't be used by the end of the series.
**Code context:**
```
    1821:  * i: data stripe index
    1822:  *
    1823:  * This function covnerts a data stripe index into which raid set
    1824:  * it belongs to.
    1825:  */
>>> 1826: static inline int sc_idx_to_raidset(struct ec_split_comp *sc, int i)
    1827: {
    1828: 	int total = (sc->esc_n0 * sc->esc_k0) + (sc->esc_n1 * sc->esc_k1);
    1829: 
    1830: 	if (!total)
    1831: 		return 0;
```
**Gerrit:** https://review.whamcloud.com/c/fs/lustre-release/+/63809/comment/e880dc04_2ca10d54/

