#include <asm/div64.h>
#include <libcfs/libcfs.h>
-#include <obd_class.h>
#include <lustre/lustre_idl.h>
+#include <lustre_swab.h>
+#include <obd_class.h>
+
#include "lod_internal.h"
/*
LASSERT(ost);
rc = dt_statfs(env, ost->ltd_ost, sfs);
-
- if (rc == -ENOSPC)
- RETURN(rc);
-
if (rc && rc != -ENOTCONN)
CERROR("%s: statfs: rc = %d\n", lod2obd(d)->obd_name, rc);
spin_lock(&d->lod_desc_lock);
if (ost->ltd_active) {
ost->ltd_active = 0;
+ if (rc == -ENOTCONN)
+ ost->ltd_connecting = 1;
+
LASSERT(d->lod_desc.ld_active_tgt_count > 0);
d->lod_desc.ld_active_tgt_count--;
d->lod_qos.lq_dirty = 1;
spin_lock(&d->lod_desc_lock);
if (ost->ltd_active == 0) {
ost->ltd_active = 1;
+ ost->ltd_connecting = 0;
d->lod_desc.ld_active_tgt_count++;
d->lod_qos.lq_dirty = 1;
d->lod_qos.lq_rr.lqr_dirty = 1;
#define LOV_CREATE_RESEED_MIN 2000
/**
+ * Check if an OST is full.
+ *
+ * Check whether an OST should be considered full based
+ * on the given statfs data.
+ *
+ * \param[in] msfs statfs data
+ *
+ * \retval false not full
+ * \retval true full
+ */
+static int inline lod_qos_dev_is_full(struct obd_statfs *msfs)
+{
+ __u64 used;
+ int bs = msfs->os_bsize;
+
+ LASSERT(((bs - 1) & bs) == 0);
+
+ /* the minimum of 0.1% used blocks and 1GB bytes. */
+ used = min_t(__u64, (msfs->os_blocks - msfs->os_bfree) >> 10,
+ 1 << (31 - ffs(bs)));
+ return (msfs->os_bavail < used);
+}
+
+/**
* Initialize temporary OST-in-use array.
*
* Allocate or extend the array used to mark targets already assigned to a new
}
/*
+ * skip full devices
+ */
+ if (lod_qos_dev_is_full(sfs)) {
+ QOS_DEBUG("#%d is full\n", ost_idx);
+ goto out_return;
+ }
+
+ /*
* We expect number of precreated objects in f_ffree at
* the first iteration, skip OSPs with no objects ready
*/
int rc;
__u32 ost_start_idx_temp;
int speed = 0;
+ int ost_connecting = 0;
__u32 stripe_idx = 0;
__u32 stripe_cnt = lo->ldo_stripenr;
__u32 stripe_cnt_min = min_stripe_count(stripe_cnt, flags);
rc = lod_check_and_reserve_ost(env, m, sfs, ost_idx, speed,
&stripe_idx, stripe, th);
spin_lock(&lqr->lqr_alloc);
+
+ if (rc != 0 && OST_TGT(m, ost_idx)->ltd_connecting)
+ ost_connecting = 1;
}
if ((speed < 2) && (stripe_idx < stripe_cnt_min)) {
/* Try again, allowing slower OSCs */
speed++;
lqr->lqr_start_idx = ost_start_idx_temp;
+
+ ost_connecting = 0;
goto repeat_find;
}
rc = 0;
} else {
/* nobody provided us with a single object */
- rc = -ENOSPC;
+ if (ost_connecting)
+ rc = -EINPROGRESS;
+ else
+ rc = -ENOSPC;
}
out:
continue;
}
+ /*
+ * skip full devices
+ */
+ if (lod_qos_dev_is_full(sfs))
+ continue;
+
/* Fail Check before osc_precreate() is called
so we can only 'fail' single OSC. */
if (OBD_FAIL_CHECK(OBD_FAIL_MDS_OSC_PRECREATE) &&