From: Dmitry Zogin Date: Fri, 16 Jul 2010 13:31:52 +0000 (+0400) Subject: b=11742 FSX checksum false positves due to mmap IO X-Git-Tag: 2.0.0.51~25 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=f8995c83720e999b13f057739f8217822a3951fa b=11742 FSX checksum false positves due to mmap IO Use OBD_FL_MMAP flag for IOs on a memory mapped file. Do not print checksum errors, if the flag is set on a request. i=adilger i=alexey.lyashkov i=johann --- diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h index 567ebb8..2eaa676 100644 --- a/lustre/include/lustre/lustre_idl.h +++ b/lustre/include/lustre/lustre_idl.h @@ -1182,6 +1182,7 @@ enum obdo_flags { OBD_FL_CKSUM_RSVD2 = 0x00008000, /* for future cksum types */ OBD_FL_CKSUM_RSVD3 = 0x00010000, /* for future cksum types */ OBD_FL_SHRINK_GRANT = 0x00020000, /* object shrink the grant */ + OBD_FL_MMAP = 0x00040000, /* object is mmapped on the client */ OBD_FL_CKSUM_ALL = OBD_FL_CKSUM_CRC32 | OBD_FL_CKSUM_ADLER, diff --git a/lustre/lclient/lcommon_cl.c b/lustre/lclient/lcommon_cl.c index 886ee10..6159d3f 100644 --- a/lustre/lclient/lcommon_cl.c +++ b/lustre/lclient/lcommon_cl.c @@ -1001,6 +1001,17 @@ void ccc_req_attr_set(const struct lu_env *env, } obdo_from_inode(oa, inode, &cl_i2info(inode)->lli_fid, valid_flags & flags); +#ifdef __KERNEL__ + /* Bug11742 - set the OBD_FL_MMAP flag for memory mapped files */ + if (cfs_atomic_read(&(cl_inode2ccc(inode)->cob_mmap_cnt)) != 0) { + if (!(oa->o_valid & OBD_MD_FLFLAGS)) { + oa->o_valid |= OBD_MD_FLFLAGS; + oa->o_flags = OBD_FL_MMAP; + } else { + oa->o_flags |= OBD_FL_MMAP; + } + } +#endif } const struct cl_req_operations ccc_req_ops = { diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index 12edc7e..6a21fc2 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -1427,6 +1427,10 @@ static int check_write_checksum(struct obdo *oa, const lnet_process_id_t *peer, return 0; } + /* If this is mmaped file - it can be changed at any time */ + if (oa->o_valid & OBD_MD_FLFLAGS && oa->o_flags & OBD_FL_MMAP) + return 1; + if (oa->o_valid & OBD_MD_FLFLAGS) cksum_type = cksum_type_unpack(oa->o_flags); else @@ -2167,9 +2171,20 @@ static int brw_interpret(const struct lu_env *env, rc = osc_brw_fini_request(req, rc); CDEBUG(D_INODE, "request %p aa %p rc %d\n", req, aa, rc); if (osc_recoverable_error(rc)) { - rc = osc_brw_redo_request(req, aa); - if (rc == 0) - RETURN(0); + /* Only retry once for mmaped files since the mmaped page + * might be modified at anytime. We have to retry at least + * once in case there WAS really a corruption of the page + * on the network, that was not caused by mmap() modifying + * the page. Bug11742 */ + if ((rc == -EAGAIN) && (aa->aa_resends > 0) && + aa->aa_oa->o_valid & OBD_MD_FLFLAGS && + aa->aa_oa->o_flags & OBD_FL_MMAP) { + rc = 0; + } else { + rc = osc_brw_redo_request(req, aa); + if (rc == 0) + RETURN(0); + } } if (aa->aa_ocapa) { diff --git a/lustre/ost/ost_handler.c b/lustre/ost/ost_handler.c index 1d32e38..2d00451 100644 --- a/lustre/ost/ost_handler.c +++ b/lustre/ost/ost_handler.c @@ -1005,7 +1005,7 @@ static int ost_brw_write(struct ptlrpc_request *req, struct obd_trans_info *oti) int rc, i, j; obd_count client_cksum = 0, server_cksum = 0; cksum_type_t cksum_type = OBD_CKSUM_CRC32; - int no_reply = 0; + int no_reply = 0, mmap = 0; __u32 o_uid = 0, o_gid = 0; struct ost_thread_local_cache *tls; ENTRY; @@ -1115,6 +1115,8 @@ static int ost_brw_write(struct ptlrpc_request *req, struct obd_trans_info *oti) if (body->oa.o_valid & OBD_MD_FLFLAGS) cksum_type = cksum_type_unpack(body->oa.o_flags); } + if (body->oa.o_valid & OBD_MD_FLFLAGS && body->oa.o_flags & OBD_FL_MMAP) + mmap = 1; /* Because we already sync grant info with client when reconnect, * grant info will be cleared for resent req, then fed_grant and @@ -1216,8 +1218,9 @@ static int ost_brw_write(struct ptlrpc_request *req, struct obd_trans_info *oti) repbody->oa.o_cksum = server_cksum; cksum_counter++; if (unlikely(client_cksum != server_cksum)) { - CERROR("client csum %x, server csum %x\n", - client_cksum, server_cksum); + CDEBUG_LIMIT(mmap ? D_INFO : D_ERROR, + "client csum %x, server csum %x\n", + client_cksum, server_cksum); cksum_counter = 0; } else if ((cksum_counter & (-cksum_counter)) == cksum_counter){ CDEBUG(D_INFO, "Checksum %u from %s OK: %x\n", @@ -1247,7 +1250,7 @@ static int ost_brw_write(struct ptlrpc_request *req, struct obd_trans_info *oti) */ repbody->oa.o_valid &= ~(OBD_MD_FLMTIME | OBD_MD_FLATIME); - if (unlikely(client_cksum != server_cksum && rc == 0)) { + if (unlikely(client_cksum != server_cksum && rc == 0 && !mmap)) { int new_cksum = ost_checksum_bulk(desc, OST_WRITE, cksum_type); char *msg; char *via;