X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Ftarget%2Ftgt_handler.c;h=d630d85c73b3e574a26ad9cb2ebb95de5b829297;hb=b0ab95d6133e783acacc6329c025d17fb282775e;hp=872d7cc24708ce79fa4bc362dac73a40f87c47e3;hpb=4bca07f115e6beada1462599cf362c3b84767576;p=fs%2Flustre-release.git diff --git a/lustre/target/tgt_handler.c b/lustre/target/tgt_handler.c index 872d7cc..d630d85 100644 --- a/lustre/target/tgt_handler.c +++ b/lustre/target/tgt_handler.c @@ -42,9 +42,9 @@ #include #include #include -#include #include #include +#include #include "tgt_internal.h" @@ -343,10 +343,13 @@ static int tgt_request_preprocess(struct tgt_session_info *tsi, dlm_req = req_capsule_client_get(pill, &RMF_DLM_REQ); if (dlm_req != NULL) { + union ldlm_wire_policy_data *policy = + &dlm_req->lock_desc.l_policy_data; + if (unlikely(dlm_req->lock_desc.l_resource.lr_type == LDLM_IBITS && - dlm_req->lock_desc.l_policy_data.\ - l_inodebits.bits == 0)) { + (policy->l_inodebits.bits | + policy->l_inodebits.try_bits) == 0)) { /* * Lock without inodebits makes no sense and * will oops later in ldlm. If client miss to @@ -426,6 +429,10 @@ static int tgt_handle_request0(struct tgt_session_info *tsi, RCL_SERVER)) req_capsule_set_size(tsi->tsi_pill, &RMF_LOGCOOKIES, RCL_SERVER, 0); + if (req_capsule_has_field(tsi->tsi_pill, &RMF_ACL, RCL_SERVER)) + req_capsule_set_size(tsi->tsi_pill, + &RMF_ACL, RCL_SERVER, + LUSTRE_POSIX_ACL_MAX_SIZE_OLD); rc = req_capsule_server_pack(tsi->tsi_pill); } @@ -893,7 +900,7 @@ int tgt_connect_check_sptlrpc(struct ptlrpc_request *req, struct obd_export *exp return rc; } -int tgt_adapt_sptlrpc_conf(struct lu_target *tgt, int initial) +int tgt_adapt_sptlrpc_conf(struct lu_target *tgt) { struct sptlrpc_rule_set tmp_rset; int rc; @@ -904,7 +911,7 @@ int tgt_adapt_sptlrpc_conf(struct lu_target *tgt, int initial) } sptlrpc_rule_set_init(&tmp_rset); - rc = sptlrpc_conf_target_get_rules(tgt->lut_obd, &tmp_rset, initial); + rc = sptlrpc_conf_target_get_rules(tgt->lut_obd, &tmp_rset); if (rc) { CERROR("%s: failed get sptlrpc rules: rc = %d\n", tgt_name(tgt), rc); @@ -1249,7 +1256,7 @@ static int tgt_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc, } err_put: if (obj != NULL) - lu_object_put(&env, &obj->do_lu); + dt_object_put(&env, obj); err_env: lu_env_fini(&env); } @@ -1433,15 +1440,27 @@ TGT_SEC_HDL_VAR(0, SEC_CTX_FINI, tgt_sec_ctx_handle), }; EXPORT_SYMBOL(tgt_sec_ctx_handlers); +int (*tgt_lfsck_in_notify_local)(const struct lu_env *env, + struct dt_device *key, + struct lfsck_req_local *lrl, + struct thandle *th) = NULL; + +void tgt_register_lfsck_in_notify_local(int (*notify)(const struct lu_env *, + struct dt_device *, + struct lfsck_req_local *, + struct thandle *)) +{ + tgt_lfsck_in_notify_local = notify; +} +EXPORT_SYMBOL(tgt_register_lfsck_in_notify_local); + int (*tgt_lfsck_in_notify)(const struct lu_env *env, struct dt_device *key, - struct lfsck_request *lr, - struct thandle *th) = NULL; + struct lfsck_request *lr) = NULL; void tgt_register_lfsck_in_notify(int (*notify)(const struct lu_env *, struct dt_device *, - struct lfsck_request *, - struct thandle *)) + struct lfsck_request *)) { tgt_lfsck_in_notify = notify; } @@ -1476,7 +1495,7 @@ static int tgt_handle_lfsck_notify(struct tgt_session_info *tsi) if (lr == NULL) RETURN(-EPROTO); - rc = tgt_lfsck_in_notify(env, key, lr, NULL); + rc = tgt_lfsck_in_notify(env, key, lr); RETURN(rc); } @@ -1676,6 +1695,12 @@ static __u32 tgt_checksum_bulk(struct lu_target *tgt, memcpy(ptr2, ptr, len); memcpy(ptr2, "bad3", min(4, len)); kunmap(np); + + /* LU-8376 to preserve original index for + * display in dump_all_bulk_pages() */ + np->index = BD_GET_KIOV(desc, + i).kiov_page->index; + BD_GET_KIOV(desc, i).kiov_page = np; } else { CERROR("%s: can't alloc page for corruption\n", @@ -1705,6 +1730,12 @@ static __u32 tgt_checksum_bulk(struct lu_target *tgt, memcpy(ptr2, ptr, len); memcpy(ptr2, "bad4", min(4, len)); kunmap(np); + + /* LU-8376 to preserve original index for + * display in dump_all_bulk_pages() */ + np->index = BD_GET_KIOV(desc, + i).kiov_page->index; + BD_GET_KIOV(desc, i).kiov_page = np; } else { CERROR("%s: can't alloc page for corruption\n", @@ -1719,6 +1750,122 @@ static __u32 tgt_checksum_bulk(struct lu_target *tgt, return cksum; } +char dbgcksum_file_name[PATH_MAX]; + +static void dump_all_bulk_pages(struct obdo *oa, int count, + lnet_kiov_t *iov, __u32 server_cksum, + __u32 client_cksum) +{ + struct file *filp; + int rc, i; + unsigned int len; + char *buf; + mm_segment_t oldfs; + + /* will only keep dump of pages on first error for the same range in + * file/fid, not during the resends/retries. */ + snprintf(dbgcksum_file_name, sizeof(dbgcksum_file_name), + "%s-checksum_dump-ost-"DFID":[%llu-%llu]-%x-%x", + (strncmp(libcfs_debug_file_path_arr, "NONE", 4) != 0 ? + libcfs_debug_file_path_arr : + LIBCFS_DEBUG_FILE_PATH_DEFAULT), + oa->o_valid & OBD_MD_FLFID ? oa->o_parent_seq : (__u64)0, + oa->o_valid & OBD_MD_FLFID ? oa->o_parent_oid : 0, + oa->o_valid & OBD_MD_FLFID ? oa->o_parent_ver : 0, + (__u64)iov[0].kiov_page->index << PAGE_SHIFT, + ((__u64)iov[count - 1].kiov_page->index << PAGE_SHIFT) + + iov[count - 1].kiov_len - 1, client_cksum, server_cksum); + filp = filp_open(dbgcksum_file_name, + O_CREAT | O_EXCL | O_WRONLY | O_LARGEFILE, 0600); + if (IS_ERR(filp)) { + rc = PTR_ERR(filp); + if (rc == -EEXIST) + CDEBUG(D_INFO, "%s: can't open to dump pages with " + "checksum error: rc = %d\n", dbgcksum_file_name, + rc); + else + CERROR("%s: can't open to dump pages with checksum " + "error: rc = %d\n", dbgcksum_file_name, rc); + return; + } + + oldfs = get_fs(); + set_fs(KERNEL_DS); + for (i = 0; i < count; i++) { + len = iov[i].kiov_len; + buf = kmap(iov[i].kiov_page); + while (len != 0) { + rc = vfs_write(filp, (__force const char __user *)buf, + len, &filp->f_pos); + if (rc < 0) { + CERROR("%s: wanted to write %u but got %d " + "error\n", dbgcksum_file_name, len, rc); + break; + } + len -= rc; + buf += rc; + CDEBUG(D_INFO, "%s: wrote %d bytes\n", + dbgcksum_file_name, rc); + } + kunmap(iov[i].kiov_page); + } + set_fs(oldfs); + + rc = ll_vfs_fsync_range(filp, 0, LLONG_MAX, 1); + if (rc) + CERROR("%s: sync returns %d\n", dbgcksum_file_name, rc); + filp_close(filp, NULL); + return; +} + +static int check_read_checksum(struct ptlrpc_bulk_desc *desc, struct obdo *oa, + const lnet_process_id_t *peer, + __u32 client_cksum, __u32 server_cksum, + cksum_type_t server_cksum_type) +{ + char *msg; + cksum_type_t cksum_type; + + /* unlikely to happen and only if resend does not occur due to cksum + * control failure on Client */ + if (unlikely(server_cksum == client_cksum)) { + CDEBUG(D_PAGE, "checksum %x confirmed upon retry\n", + client_cksum); + return 0; + } + + if (desc->bd_export->exp_obd->obd_checksum_dump) + dump_all_bulk_pages(oa, desc->bd_iov_count, + &BD_GET_KIOV(desc, 0), server_cksum, + client_cksum); + + cksum_type = cksum_type_unpack(oa->o_valid & OBD_MD_FLFLAGS ? + oa->o_flags : 0); + + if (cksum_type != server_cksum_type) + msg = "the server may have not used the checksum type specified" + " in the original request - likely a protocol problem"; + else + msg = "should have changed on the client or in transit"; + + LCONSOLE_ERROR_MSG(0x132, "%s: BAD READ CHECKSUM: %s: from %s inode " + DFID " object "DOSTID" extent [%llu-%llu], client returned csum" + " %x (type %x), server csum %x (type %x)\n", + desc->bd_export->exp_obd->obd_name, + msg, libcfs_nid2str(peer->nid), + oa->o_valid & OBD_MD_FLFID ? oa->o_parent_seq : 0ULL, + oa->o_valid & OBD_MD_FLFID ? oa->o_parent_oid : 0, + oa->o_valid & OBD_MD_FLFID ? oa->o_parent_ver : 0, + POSTID(&oa->o_oi), + (__u64)BD_GET_KIOV(desc, 0).kiov_page->index << PAGE_SHIFT, + ((__u64)BD_GET_KIOV(desc, + desc->bd_iov_count - 1).kiov_page->index + << PAGE_SHIFT) + + BD_GET_KIOV(desc, desc->bd_iov_count - 1).kiov_len - 1, + client_cksum, cksum_type, server_cksum, server_cksum_type); + return 1; +} + int tgt_brw_read(struct tgt_session_info *tsi) { struct ptlrpc_request *req = tgt_ses_req(tsi); @@ -1787,13 +1934,12 @@ int tgt_brw_read(struct tgt_session_info *tsi) * If getting the lock took more time than * client was willing to wait, drop it. b=11330 */ - if (cfs_time_current_sec() > req->rq_deadline || + if (ktime_get_real_seconds() > req->rq_deadline || OBD_FAIL_CHECK(OBD_FAIL_OST_DROP_REQ)) { no_reply = 1; - CERROR("Dropping timed-out read from %s because locking" - "object "DOSTID" took %ld seconds (limit was %ld).\n", + CERROR("Dropping timed-out read from %s because locking object " DOSTID " took %lld seconds (limit was %lld).\n", libcfs_id2str(req->rq_peer), POSTID(&ioo->ioo_oid), - cfs_time_current_sec() - req->rq_arrival_time.tv_sec, + ktime_get_real_seconds() - req->rq_arrival_time.tv_sec, req->rq_deadline - req->rq_arrival_time.tv_sec); GOTO(out_lock, rc = -ETIMEDOUT); } @@ -1848,12 +1994,22 @@ int tgt_brw_read(struct tgt_session_info *tsi) cksum_type_t cksum_type = cksum_type_unpack(body->oa.o_valid & OBD_MD_FLFLAGS ? body->oa.o_flags : 0); + repbody->oa.o_flags = cksum_type_pack(cksum_type); repbody->oa.o_valid = OBD_MD_FLCKSUM | OBD_MD_FLFLAGS; repbody->oa.o_cksum = tgt_checksum_bulk(tsi->tsi_tgt, desc, OST_READ, cksum_type); CDEBUG(D_PAGE, "checksum at read origin: %x\n", repbody->oa.o_cksum); + + /* if a resend it could be for a cksum error, so check Server + * cksum with returned Client cksum (this should even cover + * zero-cksum case) */ + if ((body->oa.o_valid & OBD_MD_FLFLAGS) && + (body->oa.o_flags & OBD_FL_RECOV_RESEND)) + check_read_checksum(desc, &body->oa, &req->rq_peer, + body->oa.o_cksum, + repbody->oa.o_cksum, cksum_type); } else { repbody->oa.o_valid = 0; } @@ -1930,13 +2086,18 @@ static void tgt_warn_on_cksum(struct ptlrpc_request *req, router = libcfs_nid2str(desc->bd_sender); } + if (exp->exp_obd->obd_checksum_dump) + dump_all_bulk_pages(&body->oa, desc->bd_iov_count, + &BD_GET_KIOV(desc, 0), server_cksum, + client_cksum); + if (mmap) { CDEBUG_LIMIT(D_INFO, "client csum %x, server csum %x\n", client_cksum, server_cksum); return; } - LCONSOLE_ERROR_MSG(0x168, "BAD WRITE CHECKSUM: %s from %s%s%s inode " + LCONSOLE_ERROR_MSG(0x168, "%s: BAD WRITE CHECKSUM: from %s%s%s inode " DFID" object "DOSTID" extent [%llu-%llu" "]: client csum %x, server csum %x\n", exp->exp_obd->obd_name, libcfs_id2str(req->rq_peer), @@ -1971,6 +2132,7 @@ int tgt_brw_write(struct tgt_session_info *tsi) cksum_type_t cksum_type = OBD_CKSUM_CRC32; bool no_reply = false, mmap; struct tgt_thread_big_cache *tbc = req->rq_svc_thread->t_data; + bool wait_sync = false; ENTRY; @@ -2024,7 +2186,7 @@ int tgt_brw_write(struct tgt_session_info *tsi) RETURN(err_serious(-EPROTO)); if ((remote_nb[0].rnb_flags & OBD_BRW_MEMALLOC) && - (exp->exp_connection->c_peer.nid == exp->exp_connection->c_self)) + ptlrpc_connection_is_local(exp->exp_connection)) memory_pressure_set(); req_capsule_set_size(&req->rq_pill, &RMF_RCS, RCL_SERVER, @@ -2047,14 +2209,13 @@ int tgt_brw_write(struct tgt_session_info *tsi) * If getting the lock took more time than * client was willing to wait, drop it. b=11330 */ - if (cfs_time_current_sec() > req->rq_deadline || + if (ktime_get_real_seconds() > req->rq_deadline || OBD_FAIL_CHECK(OBD_FAIL_OST_DROP_REQ)) { no_reply = true; - CERROR("%s: Dropping timed-out write from %s because locking " - "object "DOSTID" took %ld seconds (limit was %ld).\n", + CERROR("%s: Dropping timed-out write from %s because locking object " DOSTID " took %lld seconds (limit was %lld).\n", tgt_name(tsi->tsi_tgt), libcfs_id2str(req->rq_peer), POSTID(&ioo->ioo_oid), - cfs_time_current_sec() - req->rq_arrival_time.tv_sec, + ktime_get_real_seconds() - req->rq_arrival_time.tv_sec, req->rq_deadline - req->rq_arrival_time.tv_sec); GOTO(out_lock, rc = -ETIMEDOUT); } @@ -2138,6 +2299,12 @@ skip_transfer: * has timed out the request already */ no_reply = true; + for (i = 0; i < niocount; i++) { + if (!(local_nb[i].lnb_flags & OBD_BRW_ASYNC)) { + wait_sync = true; + break; + } + } /* * Disable sending mtime back to the client. If the client locked the * whole object, then it has already updated the mtime on its side, @@ -2171,15 +2338,16 @@ out_lock: if (desc) ptlrpc_free_bulk(desc); out: - if (no_reply) { + if (unlikely(no_reply || (exp->exp_obd->obd_no_transno && wait_sync))) { req->rq_no_reply = 1; /* reply out callback would free */ ptlrpc_req_drop_rs(req); - LCONSOLE_WARN("%s: Bulk IO write error with %s (at %s), " - "client will retry: rc %d\n", - exp->exp_obd->obd_name, - obd_uuid2str(&exp->exp_client_uuid), - obd_export_nid2str(exp), rc); + if (!exp->exp_obd->obd_no_transno) + LCONSOLE_WARN("%s: Bulk IO write error with %s (at %s)," + " client will retry: rc = %d\n", + exp->exp_obd->obd_name, + obd_uuid2str(&exp->exp_client_uuid), + obd_export_nid2str(exp), rc); } memory_pressure_clr(); RETURN(rc);