#define DEBUG_SUBSYSTEM S_MDS
+#include <linux/kthread.h>
+
+#include <lustre_obdo.h>
+
#include "osp_internal.h"
/*
d->opd_statfs_fresh_till = cfs_time_shift(obd_timeout * 1000);
d->opd_statfs_update_in_progress = 1;
- ptlrpcd_add_req(req, PDL_POLICY_ROUND, -1);
+ ptlrpcd_add_req(req);
RETURN(0);
}
*
* If cached statfs data claim no free space, but OSP has got a request to
* destroy an object (so release some space probably), then we may need to
- * refresh cached statfs data sooner then planned. The function checks there
+ * refresh cached statfs data sooner than planned. The function checks there
* is no statfs update going and schedules immediate update if so.
* XXX: there might be a case where removed object(s) do not add free space (empty
* object). If the number of such deletions is high, then we can start to update
/* don't consider new precreation till OST is healty and
* has free space */
- return ((window - d->opd_pre_reserved < d->opd_pre_grow_count / 2) &&
+ return ((window - d->opd_pre_reserved < d->opd_pre_create_count / 2) &&
(d->opd_pre_status == 0));
}
}
spin_lock(&d->opd_pre_lock);
- if (d->opd_pre_grow_count > d->opd_pre_max_grow_count / 2)
- d->opd_pre_grow_count = d->opd_pre_max_grow_count / 2;
- grow = d->opd_pre_grow_count;
+ if (d->opd_pre_create_count > d->opd_pre_max_create_count / 2)
+ d->opd_pre_create_count = d->opd_pre_max_create_count / 2;
+ grow = d->opd_pre_create_count;
spin_unlock(&d->opd_pre_lock);
body = req_capsule_client_get(&req->rq_pill, &RMF_OST_BODY);
ptlrpc_request_set_replen(req);
+ if (OBD_FAIL_CHECK(OBD_FAIL_OSP_FAKE_PRECREATE))
+ GOTO(ready, rc = 0);
+
rc = ptlrpc_queue_wait(req);
if (rc) {
CERROR("%s: can't precreate: rc = %d\n", d->opd_obd->obd_name,
GOTO(out_req, rc = -EPROTO);
ostid_to_fid(fid, &body->oa.o_oi, d->opd_index);
+
+ready:
if (osp_fid_diff(fid, &d->opd_pre_used_fid) <= 0) {
CERROR("%s: precreate fid "DFID" < local used fid "DFID
": rc = %d\n", d->opd_obd->obd_name,
if (diff < grow) {
/* the OST has not managed to create all the
* objects we asked for */
- d->opd_pre_grow_count = max(diff, OST_MIN_PRECREATE);
- d->opd_pre_grow_slow = 1;
+ d->opd_pre_create_count = max(diff, OST_MIN_PRECREATE);
+ d->opd_pre_create_slow = 1;
} else {
/* the OST is able to keep up with the work,
- * we could consider increasing grow_count
+ * we could consider increasing create_count
* next time if needed */
- d->opd_pre_grow_slow = 0;
+ d->opd_pre_create_slow = 0;
}
body = req_capsule_client_get(&req->rq_pill, &RMF_OST_BODY);
spin_lock(&d->opd_pre_lock);
diff = osp_fid_diff(&d->opd_last_used_fid, last_fid);
if (diff > 0) {
- d->opd_pre_grow_count = OST_MIN_PRECREATE + diff;
+ d->opd_pre_create_count = OST_MIN_PRECREATE + diff;
d->opd_pre_last_created_fid = d->opd_last_used_fid;
} else {
- d->opd_pre_grow_count = OST_MIN_PRECREATE;
+ d->opd_pre_create_count = OST_MIN_PRECREATE;
d->opd_pre_last_created_fid = *last_fid;
}
/*
LASSERT(fid_oid(&d->opd_pre_last_created_fid) <=
LUSTRE_DATA_SEQ_MAX_WIDTH);
d->opd_pre_used_fid = d->opd_pre_last_created_fid;
- d->opd_pre_grow_slow = 0;
+ d->opd_pre_create_slow = 0;
spin_unlock(&d->opd_pre_lock);
CDEBUG(D_HA, "%s: Got last_id "DFID" from OST, last_created "DFID
msfs->os_bfree, used, msfs->os_bavail,
d->opd_pre_status, rc);
CDEBUG(D_INFO,
- "non-commited changes: %lu, in progress: %u\n",
+ "non-committed changes: %lu, in progress: %u\n",
d->opd_syn_changes, d->opd_syn_rpc_in_progress);
} else if (old == -ENOSPC) {
d->opd_pre_status = 0;
spin_lock(&d->opd_pre_lock);
- d->opd_pre_grow_slow = 0;
- d->opd_pre_grow_count = OST_MIN_PRECREATE;
+ d->opd_pre_create_slow = 0;
+ d->opd_pre_create_count = OST_MIN_PRECREATE;
spin_unlock(&d->opd_pre_lock);
wake_up(&d->opd_pre_waitq);
CDEBUG(D_INFO, "%s: no space: "LPU64" blocks, "LPU64
struct osp_device *d = _arg;
struct ptlrpc_thread *thread = &d->opd_pre_thread;
struct l_wait_info lwi = { 0 };
+ struct l_wait_info lwi2 = LWI_TIMEOUT(cfs_time_seconds(5),
+ back_to_sleep, NULL);
struct lu_env env;
int rc;
continue;
}
- osp_statfs_update(d);
+ if (osp_statfs_update(d)) {
+ l_wait_event(d->opd_pre_waitq,
+ !osp_precreate_running(d), &lwi2);
+ continue;
+ }
/*
* Clean up orphans or recreate missing objects.
break;
if (osp_statfs_need_update(d))
- osp_statfs_update(d);
+ if (osp_statfs_update(d))
+ break;
/* To avoid handling different seq in precreate/orphan
* cleanup, it will hold precreate until current seq is
if (d->opd_pre_status != 0 &&
d->opd_pre_status != -EAGAIN &&
d->opd_pre_status != -ENODEV &&
+ d->opd_pre_status != -ENOTCONN &&
d->opd_pre_status != -ENOSPC) {
/* DEBUG LU-3230 */
if (d->opd_pre_status != -EIO)
* increase number of precreations
*/
precreated = osp_objs_precreated(env, d);
- if (d->opd_pre_grow_count < d->opd_pre_max_grow_count &&
- d->opd_pre_grow_slow == 0 &&
- precreated <= (d->opd_pre_grow_count / 4 + 1)) {
+ if (d->opd_pre_create_count < d->opd_pre_max_create_count &&
+ d->opd_pre_create_slow == 0 &&
+ precreated <= (d->opd_pre_create_count / 4 + 1)) {
spin_lock(&d->opd_pre_lock);
- d->opd_pre_grow_slow = 1;
- d->opd_pre_grow_count *= 2;
+ d->opd_pre_create_slow = 1;
+ d->opd_pre_create_count *= 2;
spin_unlock(&d->opd_pre_lock);
}
* XXX: decide how do we do here with resend
* if we don't resend, then client may see wrong file size
* if we do resend, then MDS thread can get stuck for quite long
+ * and if we don't resend, then client will also get -EWOULDBLOCK !!
+ * (see LU-7975 and sanity/test_27F use cases)
+ * but let's decide not to resend/delay this truncate request to OST
+ * and allow Client to decide to resend, in a less agressive way from
+ * after_reply(), by returning -EINPROGRESS instead of
+ * -EAGAIN/-EWOULDBLOCK upon return from ptlrpc_queue_wait() at the
+ * end of this routine
*/
req->rq_no_resend = req->rq_no_delay = 1;
ptlrpc_request_set_replen(req);
rc = ptlrpc_queue_wait(req);
- if (rc)
- CERROR("can't punch object: %d\n", rc);
+ if (rc) {
+ /* -EWOULDBLOCK/-EAGAIN means OST is unreachable at the moment
+ * since we have decided not to resend/delay, but this could
+ * lead to wrong size to be seen at Client side and even process
+ * trying to open to exit/fail if not itself handling -EAGAIN.
+ * So it should be better to return -EINPROGRESS instead and
+ * leave the decision to resend at Client side in after_reply()
+ */
+ if (rc == -EWOULDBLOCK) {
+ rc = -EINPROGRESS;
+ CDEBUG(D_HA, "returning -EINPROGRESS instead of "
+ "-EWOULDBLOCK/-EAGAIN to allow Client to "
+ "resend\n");
+ } else {
+ CERROR("can't punch object: %d\n", rc);
+ }
+ }
out:
ptlrpc_req_finished(req);
if (oa)
d->opd_pre_last_created_fid.f_oid = 1;
d->opd_pre_reserved = 0;
d->opd_got_disconnected = 1;
- d->opd_pre_grow_slow = 0;
- d->opd_pre_grow_count = OST_MIN_PRECREATE;
- d->opd_pre_min_grow_count = OST_MIN_PRECREATE;
- d->opd_pre_max_grow_count = OST_MAX_PRECREATE;
+ d->opd_pre_create_slow = 0;
+ d->opd_pre_create_count = OST_MIN_PRECREATE;
+ d->opd_pre_min_create_count = OST_MIN_PRECREATE;
+ d->opd_pre_max_create_count = OST_MAX_PRECREATE;
spin_lock_init(&d->opd_pre_lock);
init_waitqueue_head(&d->opd_pre_waitq);