if (!res)
break;
+
+ if (io->ci_type == CIT_MISC &&
+ io->u.ci_misc.lm_next_rpc_time &&
+ ktime_get_seconds() > io->u.ci_misc.lm_next_rpc_time) {
+ osc_send_empty_rpc(osc, idx << PAGE_SHIFT);
+ io->u.ci_misc.lm_next_rpc_time = ktime_get_seconds() +
+ 5 * obd_timeout / 16;
+ }
+
if (need_resched())
cond_resched();
io->ci_obj = cl_object_top(osc2cl(osc));
io->ci_ignore_layout = 1;
+ io->u.ci_misc.lm_next_rpc_time = ktime_get_seconds() +
+ 5 * obd_timeout / 16;
result = cl_io_init(env, io, CIT_MISC, io->ci_obj);
if (result != 0)
GOTO(out, result);
int osc_process_config_base(struct obd_device *obd, struct lustre_cfg *cfg);
int osc_build_rpc(const struct lu_env *env, struct client_obd *cli,
struct list_head *ext_list, int cmd);
+void osc_send_empty_rpc(struct osc_object *osc, pgoff_t start);
unsigned long osc_lru_reserve(struct client_obd *cli, unsigned long npages);
void osc_lru_unreserve(struct client_obd *cli, unsigned long npages);
struct brw_page *pg_prev;
void *short_io_buf;
const char *obd_name = cli->cl_import->imp_obd->obd_name;
- struct inode *inode;
+ struct inode *inode = NULL;
bool directio = false;
ENTRY;
- inode = page2inode(pga[0]->pg);
- if (inode == NULL) {
- /* Try to get reference to inode from cl_page if we are
- * dealing with direct IO, as handled pages are not
- * actual page cache pages.
- */
- struct osc_async_page *oap = brw_page2oap(pga[0]);
- struct cl_page *clpage = oap2cl_page(oap);
+ if (pga[0]->pg) {
+ inode = page2inode(pga[0]->pg);
+ if (inode == NULL) {
+ /* Try to get reference to inode from cl_page if we are
+ * dealing with direct IO, as handled pages are not
+ * actual page cache pages.
+ */
+ struct osc_async_page *oap = brw_page2oap(pga[0]);
+ struct cl_page *clpage = oap2cl_page(oap);
- inode = clpage->cp_inode;
- if (inode)
- directio = true;
+ inode = clpage->cp_inode;
+ if (inode)
+ directio = true;
+ }
}
if (OBD_FAIL_CHECK(OBD_FAIL_OSC_BRW_PREP_REQ))
RETURN(-ENOMEM); /* Recoverable */
RETURN(rc);
}
+/* This is to refresh our lock in face of no RPCs. */
+void osc_send_empty_rpc(struct osc_object *osc, pgoff_t start)
+{
+ struct ptlrpc_request *req;
+ struct obdo oa;
+ struct brw_page bpg = { .off = start, .count = 1};
+ struct brw_page *pga = &bpg;
+ int rc;
+
+ memset(&oa, 0, sizeof(oa));
+ oa.o_oi = osc->oo_oinfo->loi_oi;
+ oa.o_valid = OBD_MD_FLID | OBD_MD_FLGROUP | OBD_MD_FLFLAGS;
+ /* For updated servers - don't do a read */
+ oa.o_flags = OBD_FL_NORPC;
+
+ rc = osc_brw_prep_request(OBD_BRW_READ, osc_cli(osc), &oa, 1, &pga,
+ &req, 0);
+
+ /* If we succeeded we ship it off, if not there's no point in doing
+ * anything. Also no resends.
+ * No interpret callback, no commit callback.
+ */
+ if (!rc) {
+ req->rq_no_resend = 1;
+ ptlrpcd_add_req(req);
+ }
+}
+
static int osc_set_lock_data(struct ldlm_lock *lock, void *data)
{
int set = 0;
body = tsi->tsi_ost_body;
LASSERT(body != NULL);
+ if (body->oa.o_valid & OBD_MD_FLFLAGS &&
+ body->oa.o_flags & OBD_FL_NORPC)
+ RETURN(0);
+
ioo = req_capsule_client_get(tsi->tsi_pill, &RMF_OBD_IOOBJ);
LASSERT(ioo != NULL); /* must exists after tgt_ost_body_unpack */
body = tsi->tsi_ost_body;
LASSERT(body != NULL);
+ if (body->oa.o_valid & OBD_MD_FLFLAGS &&
+ body->oa.o_flags & OBD_FL_NORPC)
+ RETURN(0);
+
+
ioo = req_capsule_client_get(&req->rq_pill, &RMF_OBD_IOOBJ);
LASSERT(ioo != NULL); /* must exists after tgt_ost_body_unpack */