Whamcloud - gitweb
b=11742 FSX checksum false positves due to mmap IO
authorDmitry Zogin <dmitry.zoguine@oracle.com>
Fri, 16 Jul 2010 13:31:52 +0000 (17:31 +0400)
committerMikhail Pershin <tappro@sun.com>
Tue, 20 Jul 2010 07:05:05 +0000 (11:05 +0400)
 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

lustre/include/lustre/lustre_idl.h
lustre/lclient/lcommon_cl.c
lustre/osc/osc_request.c
lustre/ost/ost_handler.c

index 567ebb8..2eaa676 100644 (file)
@@ -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,
 
index 886ee10..6159d3f 100644 (file)
@@ -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 = {
index 12edc7e..6a21fc2 100644 (file)
@@ -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) {
index 1d32e38..2d00451 100644 (file)
@@ -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;