X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fost%2Fost_handler.c;h=abb4f66b89c6f9fe0ebdb6e13e3df164d134a43f;hb=62499626b81f83f9e2ceceaa11d9b33861581cb6;hp=2b0e3a2dd4f2f456a58ed106866f562c6d68581e;hpb=f93353d31cd4e0ac3e71a30803369b1da7bcf8c2;p=fs%2Flustre-release.git diff --git a/lustre/ost/ost_handler.c b/lustre/ost/ost_handler.c index 2b0e3a2..abb4f66 100644 --- a/lustre/ost/ost_handler.c +++ b/lustre/ost/ost_handler.c @@ -86,7 +86,7 @@ void oti_to_request(struct obd_trans_info *oti, struct ptlrpc_request *req) if (!ack_lock->mode) break; /* XXX not even calling target_send_reply in some cases... */ - ptlrpc_save_lock (req, &ack_lock->lock, ack_lock->mode); + ptlrpc_save_lock (req, &ack_lock->lock, ack_lock->mode, 0); } } @@ -120,7 +120,7 @@ static int ost_destroy(struct obd_export *exp, struct ptlrpc_request *req, RETURN(rc); if (body->oa.o_valid & OBD_MD_FLCOOKIE) - oti->oti_logcookies = obdo_logcookie(&body->oa); + oti->oti_logcookies = &body->oa.o_lcookie; repbody = lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF, sizeof(*repbody)); memcpy(&repbody->oa, &body->oa, sizeof(body->oa)); @@ -200,7 +200,7 @@ static int ost_create(struct obd_export *exp, struct ptlrpc_request *req, repbody = lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF, sizeof(*repbody)); memcpy(&repbody->oa, &body->oa, sizeof(body->oa)); - oti->oti_logcookies = obdo_logcookie(&repbody->oa); + oti->oti_logcookies = &repbody->oa.o_lcookie; req->rq_status = obd_create(exp, &repbody->oa, NULL, oti); //obd_log_cancel(conn, NULL, 1, oti->oti_logcookies, 0); RETURN(0); @@ -253,7 +253,8 @@ static int ost_punch_lock_get(struct obd_export *exp, struct obdo *oa, RETURN(ldlm_cli_enqueue_local(exp->exp_obd->obd_namespace, &res_id, LDLM_EXTENT, &policy, LCK_PW, &flags, ldlm_blocking_ast, ldlm_completion_ast, - ldlm_glimpse_ast, NULL, 0, NULL, lh)); + ldlm_glimpse_ast, NULL, 0, NULL, + NULL, lh)); } /* @@ -293,7 +294,7 @@ static int ost_punch(struct obd_export *exp, struct ptlrpc_request *req, if ((oinfo.oi_oa->o_valid & (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS)) != (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS)) - RETURN(-EINVAL); + RETURN(-EPROTO); rc = lustre_pack_reply(req, 2, size, NULL); if (rc) @@ -389,101 +390,6 @@ static int ost_bulk_timeout(void *data) RETURN(1); } -static int get_per_page_niobufs(struct obd_ioobj *ioo, int nioo, - struct niobuf_remote *rnb, int nrnb, - struct niobuf_remote **pp_rnbp) -{ - /* Copy a remote niobuf, splitting it into page-sized chunks - * and setting ioo[i].ioo_bufcnt accordingly */ - struct niobuf_remote *pp_rnb; - int i; - int j; - int page; - int rnbidx = 0; - int npages = 0; - - /* - * array of sufficient size already preallocated by caller - */ - LASSERT(pp_rnbp != NULL); - LASSERT(*pp_rnbp != NULL); - - /* first count and check the number of pages required */ - for (i = 0; i < nioo; i++) - for (j = 0; j < ioo->ioo_bufcnt; j++, rnbidx++) { - obd_off offset = rnb[rnbidx].offset; - obd_off p0 = offset >> CFS_PAGE_SHIFT; - obd_off pn = (offset + rnb[rnbidx].len - 1) >> - CFS_PAGE_SHIFT; - - LASSERT(rnbidx < nrnb); - - npages += (pn + 1 - p0); - - if (rnb[rnbidx].len == 0) { - CERROR("zero len BRW: obj %d objid "LPX64 - " buf %u\n", i, ioo[i].ioo_id, j); - return -EINVAL; - } - if (j > 0 && - rnb[rnbidx].offset <= rnb[rnbidx-1].offset) { - CERROR("unordered BRW: obj %d objid "LPX64 - " buf %u offset "LPX64" <= "LPX64"\n", - i, ioo[i].ioo_id, j, rnb[rnbidx].offset, - rnb[rnbidx].offset); - return -EINVAL; - } - } - - LASSERT(rnbidx == nrnb); - - if (npages == nrnb) { /* all niobufs are for single pages */ - *pp_rnbp = rnb; - return npages; - } - - pp_rnb = *pp_rnbp; - - /* now do the actual split */ - page = rnbidx = 0; - for (i = 0; i < nioo; i++) { - int obj_pages = 0; - - for (j = 0; j < ioo[i].ioo_bufcnt; j++, rnbidx++) { - obd_off off = rnb[rnbidx].offset; - int nob = rnb[rnbidx].len; - - LASSERT(rnbidx < nrnb); - do { - obd_off poff = off & ~CFS_PAGE_MASK; - int pnob = (poff + nob > CFS_PAGE_SIZE) ? - CFS_PAGE_SIZE - poff : nob; - - LASSERT(page < npages); - pp_rnb[page].len = pnob; - pp_rnb[page].offset = off; - pp_rnb[page].flags = rnb[rnbidx].flags; - - CDEBUG(0, " obj %d id "LPX64 - "page %d(%d) "LPX64" for %d, flg %x\n", - i, ioo[i].ioo_id, obj_pages, page, - pp_rnb[page].offset, pp_rnb[page].len, - pp_rnb[page].flags); - page++; - obj_pages++; - - off += pnob; - nob -= pnob; - } while (nob > 0); - LASSERT(nob == 0); - } - ioo[i].ioo_bufcnt = obj_pages; - } - LASSERT(page == npages); - - return npages; -} - static __u32 ost_checksum_bulk(struct ptlrpc_bulk_desc *desc, int opc, cksum_type_t cksum_type) { @@ -506,62 +412,17 @@ static __u32 ost_checksum_bulk(struct ptlrpc_bulk_desc *desc, int opc, /* corrupt the data after we compute the checksum, to * simulate an OST->client data error */ if (i == 0 && opc == OST_READ && - OBD_FAIL_CHECK(OBD_FAIL_OST_CHECKSUM_SEND)) + OBD_FAIL_CHECK(OBD_FAIL_OST_CHECKSUM_SEND)) { memcpy(ptr, "bad4", min(4, len)); + /* nobody should use corrupted page again */ + ClearPageUptodate(page); + } kunmap(page); } return cksum; } -/* - * populate @nio by @nrpages pages from per-thread page pool - */ -static void ost_nio_pages_get(struct ptlrpc_request *req, - struct niobuf_local *nio, int nrpages) -{ - int i; - struct ost_thread_local_cache *tls; - - ENTRY; - - LASSERT(nrpages <= OST_THREAD_POOL_SIZE); - LASSERT(req != NULL); - LASSERT(req->rq_svc_thread != NULL); - - tls = ost_tls(req); - LASSERT(tls != NULL); - - memset(nio, 0, nrpages * sizeof *nio); - for (i = 0; i < nrpages; ++ i) { - struct page *page; - - page = tls->page[i]; - LASSERT(page != NULL); - POISON_PAGE(page, 0xf1); - nio[i].page = page; - LL_CDEBUG_PAGE(D_INFO, page, "%d\n", i); - } - EXIT; -} - -/* - * Dual for ost_nio_pages_get(). Poison pages in pool for debugging - */ -static void ost_nio_pages_put(struct ptlrpc_request *req, - struct niobuf_local *nio, int nrpages) -{ - int i; - - ENTRY; - - LASSERT(nrpages <= OST_THREAD_POOL_SIZE); - - for (i = 0; i < nrpages; ++ i) - POISON_PAGE(nio[i].page, 0xf2); - EXIT; -} - static int ost_brw_lock_get(int mode, struct obd_export *exp, struct obd_ioobj *obj, struct niobuf_remote *nb, struct lustre_handle *lh) @@ -592,7 +453,8 @@ static int ost_brw_lock_get(int mode, struct obd_export *exp, RETURN(ldlm_cli_enqueue_local(exp->exp_obd->obd_namespace, &res_id, LDLM_EXTENT, &policy, mode, &flags, ldlm_blocking_ast, ldlm_completion_ast, - ldlm_glimpse_ast, NULL, 0, NULL, lh)); + ldlm_glimpse_ast, NULL, 0, NULL, + NULL, lh)); } static void ost_brw_lock_put(int mode, @@ -654,7 +516,8 @@ static int ost_prolong_locks_iter(struct ldlm_lock *lock, void *data) } static void ost_prolong_locks(struct obd_export *exp, struct obd_ioobj *obj, - struct niobuf_remote *nb, ldlm_mode_t mode) + struct niobuf_remote *nb, struct obdo *oa, + ldlm_mode_t mode) { struct ldlm_res_id res_id; int nrbufs = obj->ioo_bufcnt; @@ -672,16 +535,30 @@ static void ost_prolong_locks(struct obd_export *exp, struct obd_ioobj *obj, CDEBUG(D_DLMTRACE,"refresh locks: "LPU64"/"LPU64" ("LPU64"->"LPU64")\n", res_id.name[0], res_id.name[1], opd.opd_policy.l_extent.start, opd.opd_policy.l_extent.end); + + if (oa->o_valid & OBD_MD_FLHANDLE) { + struct ldlm_lock *lock; + + lock = ldlm_handle2lock(&oa->o_handle); + if (lock != NULL) { + ost_prolong_locks_iter(lock, &opd); + LDLM_LOCK_PUT(lock); + EXIT; + return; + } + } + ldlm_resource_iterate(exp->exp_obd->obd_namespace, &res_id, ost_prolong_locks_iter, &opd); + + EXIT; } static int ost_brw_read(struct ptlrpc_request *req, struct obd_trans_info *oti) { - struct ptlrpc_bulk_desc *desc; + struct ptlrpc_bulk_desc *desc = NULL; struct obd_export *exp = req->rq_export; struct niobuf_remote *remote_nb; - struct niobuf_remote *pp_rnb = NULL; struct niobuf_local *local_nb; struct obd_ioobj *ioo; struct ost_body *body, *repbody; @@ -689,7 +566,7 @@ static int ost_brw_read(struct ptlrpc_request *req, struct obd_trans_info *oti) struct l_wait_info lwi; struct lustre_handle lockh = { 0 }; __u32 size[2] = { sizeof(struct ptlrpc_body), sizeof(*body) }; - int niocount, npages, nob = 0, rc, i; + int objcount, niocount, npages, nob = 0, rc, i; int no_reply = 0; ENTRY; @@ -718,6 +595,17 @@ static int ost_brw_read(struct ptlrpc_request *req, struct obd_trans_info *oti) GOTO(out, rc = -EFAULT); } + objcount = lustre_msg_buflen(req->rq_reqmsg, REQ_REC_OFF + 1) / + sizeof(*ioo); + if (objcount == 0) { + CERROR("Missing/short ioobj\n"); + GOTO(out, rc = -EFAULT); + } + if (objcount > 1) { + CERROR("too many ioobjs (%d)\n", objcount); + GOTO(out, rc = -EFAULT); + } + ioo = lustre_swab_reqbuf(req, REQ_REC_OFF + 1, sizeof(*ioo), lustre_swab_obd_ioobj); if (ioo == NULL) { @@ -756,24 +644,8 @@ static int ost_brw_read(struct ptlrpc_request *req, struct obd_trans_info *oti) * ost_thread_init(). */ local_nb = ost_tls(req)->local; - pp_rnb = ost_tls(req)->remote; - - /* FIXME all niobuf splitting should be done in obdfilter if needed */ - /* CAVEAT EMPTOR this sets ioo->ioo_bufcnt to # pages */ - npages = get_per_page_niobufs(ioo, 1, remote_nb, niocount, &pp_rnb); - if (npages < 0) - GOTO(out, rc = npages); - LASSERT(npages <= OST_THREAD_POOL_SIZE); - - ost_nio_pages_get(req, local_nb, npages); - - desc = ptlrpc_prep_bulk_exp(req, npages, - BULK_PUT_SOURCE, OST_BULK_PORTAL); - if (desc == NULL) - GOTO(out, rc = -ENOMEM); - - rc = ost_brw_lock_get(LCK_PR, exp, ioo, pp_rnb, &lockh); + rc = ost_brw_lock_get(LCK_PR, exp, ioo, remote_nb, &lockh); if (rc != 0) GOTO(out_bulk, rc); @@ -792,12 +664,18 @@ static int ost_brw_read(struct ptlrpc_request *req, struct obd_trans_info *oti) GOTO(out_lock, rc = -ETIMEDOUT); } - rc = obd_preprw(OBD_BRW_READ, exp, &body->oa, 1, - ioo, npages, pp_rnb, local_nb, oti, capa); + npages = OST_THREAD_POOL_SIZE; + rc = obd_preprw(OBD_BRW_READ, exp, &body->oa, 1, ioo, + remote_nb, &npages, local_nb, oti, capa); if (rc != 0) GOTO(out_lock, rc); - ost_prolong_locks(exp, ioo, pp_rnb, LCK_PW | LCK_PR); + desc = ptlrpc_prep_bulk_exp(req, npages, + BULK_PUT_SOURCE, OST_BULK_PORTAL); + if (desc == NULL) /* XXX: check all cleanup stuff */ + GOTO(out, rc = -ENOMEM); + + ost_prolong_locks(exp, ioo, remote_nb, &body->oa, LCK_PW | LCK_PR); nob = 0; for (i = 0; i < npages; i++) { @@ -808,17 +686,15 @@ static int ost_brw_read(struct ptlrpc_request *req, struct obd_trans_info *oti) break; } - LASSERTF(page_rc <= pp_rnb[i].len, "page_rc (%d) > " - "pp_rnb[%d].len (%d)\n", page_rc, i, pp_rnb[i].len); nob += page_rc; if (page_rc != 0) { /* some data! */ LASSERT (local_nb[i].page != NULL); ptlrpc_prep_bulk_page(desc, local_nb[i].page, - pp_rnb[i].offset & ~CFS_PAGE_MASK, + local_nb[i].offset & ~CFS_PAGE_MASK, page_rc); } - if (page_rc != pp_rnb[i].len) { /* short read */ + if (page_rc != local_nb[i].len) { /* short read */ /* All subsequent pages should be 0 */ while(++i < npages) LASSERT(local_nb[i].rc == 0); @@ -909,10 +785,8 @@ static int ost_brw_read(struct ptlrpc_request *req, struct obd_trans_info *oti) } /* Must commit after prep above in all cases */ - rc = obd_commitrw(OBD_BRW_READ, exp, &body->oa, 1, - ioo, npages, local_nb, oti, rc); - - ost_nio_pages_put(req, local_nb, npages); + rc = obd_commitrw(OBD_BRW_READ, exp, &body->oa, 1, ioo, + remote_nb, npages, local_nb, oti, rc); if (rc == 0) { repbody = lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF, @@ -921,9 +795,10 @@ static int ost_brw_read(struct ptlrpc_request *req, struct obd_trans_info *oti) } out_lock: - ost_brw_lock_put(LCK_PR, ioo, pp_rnb, &lockh); + ost_brw_lock_put(LCK_PR, ioo, remote_nb, &lockh); out_bulk: - ptlrpc_free_bulk(desc); + if (desc) + ptlrpc_free_bulk(desc); out: LASSERT(rc <= 0); if (rc == 0) { @@ -952,10 +827,9 @@ out: static int ost_brw_write(struct ptlrpc_request *req, struct obd_trans_info *oti) { - struct ptlrpc_bulk_desc *desc; + struct ptlrpc_bulk_desc *desc = NULL; struct obd_export *exp = req->rq_export; struct niobuf_remote *remote_nb; - struct niobuf_remote *pp_rnb; struct niobuf_local *local_nb; struct obd_ioobj *ioo; struct ost_body *body, *repbody; @@ -1059,24 +933,8 @@ static int ost_brw_write(struct ptlrpc_request *req, struct obd_trans_info *oti) * ost_thread_init(). */ local_nb = ost_tls(req)->local; - pp_rnb = ost_tls(req)->remote; - - /* FIXME all niobuf splitting should be done in obdfilter if needed */ - /* CAVEAT EMPTOR this sets ioo->ioo_bufcnt to # pages */ - npages = get_per_page_niobufs(ioo, objcount,remote_nb,niocount,&pp_rnb); - if (npages < 0) - GOTO(out, rc = npages); - LASSERT(npages <= OST_THREAD_POOL_SIZE); - - ost_nio_pages_get(req, local_nb, npages); - - desc = ptlrpc_prep_bulk_exp(req, npages, - BULK_GET_SINK, OST_BULK_PORTAL); - if (desc == NULL) - GOTO(out, rc = -ENOMEM); - - rc = ost_brw_lock_get(LCK_PW, exp, ioo, pp_rnb, &lockh); + rc = ost_brw_lock_get(LCK_PW, exp, ioo, remote_nb, &lockh); if (rc != 0) GOTO(out_bulk, rc); @@ -1095,7 +953,7 @@ static int ost_brw_write(struct ptlrpc_request *req, struct obd_trans_info *oti) GOTO(out_lock, rc = -ETIMEDOUT); } - ost_prolong_locks(exp, ioo, pp_rnb, LCK_PW); + ost_prolong_locks(exp, ioo, remote_nb,&body->oa, LCK_PW); /* obd_preprw clobbers oa->valid, so save what we need */ if (body->oa.o_valid & OBD_MD_FLCKSUM) { @@ -1112,17 +970,23 @@ static int ost_brw_write(struct ptlrpc_request *req, struct obd_trans_info *oti) body->oa.o_valid &= ~OBD_MD_FLGRANT; } + npages = OST_THREAD_POOL_SIZE; rc = obd_preprw(OBD_BRW_WRITE, exp, &body->oa, objcount, - ioo, npages, pp_rnb, local_nb, oti, capa); + ioo, remote_nb, &npages, local_nb, oti, capa); if (rc != 0) GOTO(out_lock, rc); + desc = ptlrpc_prep_bulk_exp(req, npages, + BULK_GET_SINK, OST_BULK_PORTAL); + if (desc == NULL) + GOTO(out, rc = -ENOMEM); + /* NB Having prepped, we must commit... */ for (i = 0; i < npages; i++) ptlrpc_prep_bulk_page(desc, local_nb[i].page, - pp_rnb[i].offset & ~CFS_PAGE_MASK, - pp_rnb[i].len); + local_nb[i].offset & ~CFS_PAGE_MASK, + local_nb[i].len); /* Check if client was evicted while we were doing i/o before touching network */ @@ -1199,8 +1063,8 @@ static int ost_brw_write(struct ptlrpc_request *req, struct obd_trans_info *oti) } /* Must commit after prep above in all cases */ - rc = obd_commitrw(OBD_BRW_WRITE, exp, &repbody->oa, - objcount, ioo, npages, local_nb, oti, rc); + rc = obd_commitrw(OBD_BRW_WRITE, exp, &repbody->oa, objcount, ioo, + remote_nb, npages, local_nb, oti, rc); if (unlikely(client_cksum != server_cksum && rc == 0)) { int new_cksum = ost_checksum_bulk(desc, OST_WRITE, cksum_type); @@ -1235,16 +1099,14 @@ static int ost_brw_write(struct ptlrpc_request *req, struct obd_trans_info *oti) body->oa.o_id, body->oa.o_valid & OBD_MD_FLGROUP ? body->oa.o_gr : (__u64)0, - pp_rnb[0].offset, - pp_rnb[npages-1].offset+pp_rnb[npages-1].len - - 1 ); + local_nb[0].offset, + local_nb[npages-1].offset + + local_nb[npages-1].len - 1 ); CERROR("client csum %x, original server csum %x, " "server csum now %x\n", client_cksum, server_cksum, new_cksum); } - ost_nio_pages_put(req, local_nb, npages); - if (rc == 0) { int nob = 0; @@ -1258,7 +1120,7 @@ static int ost_brw_write(struct ptlrpc_request *req, struct obd_trans_info *oti) LASSERT(j < npages); if (local_nb[j].rc < 0) rcs[i] = local_nb[j].rc; - len -= pp_rnb[j].len; + len -= local_nb[j].len; j++; } while (len > 0); LASSERT(len == 0); @@ -1268,9 +1130,10 @@ static int ost_brw_write(struct ptlrpc_request *req, struct obd_trans_info *oti) } out_lock: - ost_brw_lock_put(LCK_PW, ioo, pp_rnb, &lockh); + ost_brw_lock_put(LCK_PW, ioo, remote_nb, &lockh); out_bulk: - ptlrpc_free_bulk(desc); + if (desc) + ptlrpc_free_bulk(desc); out: if (rc == 0) { oti_to_request(oti, req); @@ -1770,6 +1633,8 @@ int ost_handle(struct ptlrpc_request *req) if (OBD_FAIL_CHECK(OBD_FAIL_OBD_LOG_CANCEL_NET)) RETURN(0); rc = llog_origin_handle_cancel(req); + if (OBD_FAIL_CHECK(OBD_FAIL_OBD_LOG_CANCEL_REP)) + RETURN(0); req->rq_status = rc; rc = req_capsule_server_pack(&req->rq_pill); if (rc) @@ -1832,7 +1697,6 @@ EXPORT_SYMBOL(ost_handle); */ static void ost_thread_done(struct ptlrpc_thread *thread) { - int i; struct ost_thread_local_cache *tls; /* TLS stands for Thread-Local * Storage */ @@ -1846,10 +1710,6 @@ static void ost_thread_done(struct ptlrpc_thread *thread) */ tls = thread->t_data; if (tls != NULL) { - for (i = 0; i < OST_THREAD_POOL_SIZE; ++ i) { - if (tls->page[i] != NULL) - OBD_PAGE_FREE(tls->page[i]); - } OBD_FREE_PTR(tls); thread->t_data = NULL; } @@ -1861,8 +1721,6 @@ static void ost_thread_done(struct ptlrpc_thread *thread) */ static int ost_thread_init(struct ptlrpc_thread *thread) { - int result; - int i; struct ost_thread_local_cache *tls; ENTRY; @@ -1872,23 +1730,10 @@ static int ost_thread_init(struct ptlrpc_thread *thread) LASSERTF(thread->t_id <= OSS_THREADS_MAX, "%u\n", thread->t_id); OBD_ALLOC_PTR(tls); - if (tls != NULL) { - result = 0; - thread->t_data = tls; - /* - * populate pool - */ - for (i = 0; i < OST_THREAD_POOL_SIZE; ++ i) { - OBD_PAGE_ALLOC(tls->page[i], OST_THREAD_POOL_GFP); - if (tls->page[i] == NULL) { - ost_thread_done(thread); - result = -ENOMEM; - break; - } - } - } else - result = -ENOMEM; - RETURN(result); + if (tls == NULL) + RETURN(-ENOMEM); + thread->t_data = tls; + RETURN(0); } #define OST_WATCHDOG_TIMEOUT (obd_timeout * 1000)