static struct dt_object *lod_qos_declare_object_on(const struct lu_env *env,
struct lod_device *d,
__u32 ost_idx,
+ bool can_block,
struct thandle *th)
{
+ struct dt_allocation_hint *ah = &lod_env_info(env)->lti_ah;
struct lod_tgt_desc *ost;
struct lu_object *o, *n;
struct lu_device *nd;
dt = container_of(n, struct dt_object, do_lu);
- rc = lod_sub_declare_create(env, dt, NULL, NULL, NULL, th);
+ ah->dah_can_block = can_block;
+ rc = lod_sub_declare_create(env, dt, NULL, ah, NULL, th);
if (rc < 0) {
CDEBUG(D_OTHER, "can't declare creation on #%u: %d\n",
ost_idx, rc);
RETURN(rc);
}
- o = lod_qos_declare_object_on(env, lod, ost_idx, th);
+ o = lod_qos_declare_object_on(env, lod, ost_idx, true, th);
if (IS_ERR(o)) {
CDEBUG(D_OTHER, "can't declare new object on #%u: %d\n",
ost_idx, (int) PTR_ERR(o));
if (rc < 0) /* this OSP doesn't feel well */
break;
- o = lod_qos_declare_object_on(env, m, ost_idx, th);
+ o = lod_qos_declare_object_on(env, m, ost_idx, true, th);
if (IS_ERR(o)) {
rc = PTR_ERR(o);
CDEBUG(D_OTHER,
if (i && !tgt->ltd_statfs.os_fprecreated && !speed)
continue;
- o = lod_qos_declare_object_on(env, m, ost_idx, th);
+ o = lod_qos_declare_object_on(env, m, ost_idx, true, th);
if (IS_ERR(o)) {
CDEBUG(D_OTHER, "can't declare new object on #%u: %d\n",
ost_idx, (int) PTR_ERR(o));
__u32 nfound, good_osts, stripe_count, stripe_count_min;
bool overstriped = false;
int stripes_per_ost = 1;
+ bool slow = false;
int rc = 0;
ENTRY;
*/
for (i = 0; i < osts->op_count; i++) {
__u32 idx = osts->op_array[i];
+ struct lod_tgt_desc *ost = OST_TGT(lod, idx);
if (lod_should_avoid_ost(lo, lag, idx))
continue;
continue;
}
- o = lod_qos_declare_object_on(env, lod, idx, th);
+ o = lod_qos_declare_object_on(env, lod, idx, slow, th);
if (IS_ERR(o)) {
QOS_DEBUG("can't declare object on #%u: %d\n",
idx, (int) PTR_ERR(o));
break;
}
+ if (rc && !slow && nfound < stripe_count) {
+ /* couldn't allocate using precreated objects
+ * so try to wait for new precreations */
+ slow = true;
+ rc = 0;
+ }
+
if (rc) {
/* no OST found on this iteration, give up */
break;
* \retval -EAGAIN try later, slow precreation in progress
* \retval -EIO when no access to OST
*/
-int osp_precreate_reserve(const struct lu_env *env, struct osp_device *d)
+int osp_precreate_reserve(const struct lu_env *env, struct osp_device *d,
+ bool can_block)
{
time64_t expire = ktime_get_seconds() + obd_timeout;
int precreated, rc, synced = 0;
break;
}
+ if (!can_block) {
+ LASSERT(d->opd_pre);
+ rc = -ENOBUFS;
+ break;
+ }
+
if (wait_event_idle_timeout(
d->opd_pre_user_waitq,
osp_precreate_ready_condition(env, d),
}
run_test 27o "create file with all full OSTs (should error)"
+function create_and_checktime() {
+ local fname=$1
+ local loops=$2
+ local i
+
+ for ((i=0; i < $loops; i++)); do
+ local start=$SECONDS
+ multiop $fname-$i Oc
+ ((SECONDS-start < TIMEOUT)) ||
+ error "creation took " $((SECONDS-$start)) && return 1
+ done
+}
+
+test_27oo() {
+ local mdts=$(comma_list $(mdts_nodes))
+
+ [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
+ skip "Need MDS version at least 2.13.57"
+
+ local f0=$DIR/${tfile}-0
+ local f1=$DIR/${tfile}-1
+
+ wait_delete_completed
+
+ # refill precreated objects
+ $LFS setstripe -i0 -c1 $f0
+
+ saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
+ # force QoS allocation policy
+ do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
+ stack_trap "do_nodes $mdts $LCTL set_param \
+ lov.*.qos_threshold_rr=$saved" EXIT
+ sleep_maxage
+
+ # one OST is unavailable, but still have few objects preallocated
+ stop ost1
+ stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
+ rm -rf $f1 $DIR/$tdir*" EXIT
+
+ for ((i=0; i < 7; i++)); do
+ mkdir $DIR/$tdir$i || error "can't create dir"
+ $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
+ error "can't set striping"
+ done
+ for ((i=0; i < 7; i++)); do
+ create_and_checktime $DIR/$tdir$i/$tfile 100 &
+ done
+ wait
+}
+run_test 27oo "don't let few threads to reserve too many objects"
+
test_27p() {
[[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
[ $PARALLEL == "yes" ] && skip "skip parallel run"