Whamcloud - gitweb
b=20142
authoranserper <anserper>
Fri, 24 Jul 2009 20:05:18 +0000 (20:05 +0000)
committeranserper <anserper>
Fri, 24 Jul 2009 20:05:18 +0000 (20:05 +0000)
i=Oleg Drokin
i=Johann Lombardi

remove racy i_size_reads from filter_preprw_read; those could lead to certain inconsistencies during page preparations, assertions in ost_brw_read following them

lustre/obdfilter/filter_io.c

index adcf7e3..8faafb2 100644 (file)
@@ -384,6 +384,7 @@ static int filter_preprw_read(int cmd, struct obd_export *exp, struct obdo *oa,
         int rc = 0, i, tot_bytes = 0;
         unsigned long now = jiffies;
         long timediff;
+        loff_t isize;
         ENTRY;
 
         /* We are currently not supporting multi-obj BRW_READ RPCS at all.
@@ -414,6 +415,10 @@ static int filter_preprw_read(int cmd, struct obd_export *exp, struct obdo *oa,
         }
 
         inode = dentry->d_inode;
+        /* While we are reading i_size only once, it might change after that
+         * while we are still reading, but this is perfectly fine race that
+         * we do not need to care about (bug 20142).                       */
+        isize = i_size_read(inode);
 
         obdo_to_inode(inode, oa, OBD_MD_FLATIME);
 
@@ -429,7 +434,7 @@ static int filter_preprw_read(int cmd, struct obd_export *exp, struct obdo *oa,
 
                 lnb->dentry = dentry;
 
-                if (i_size_read(inode) <= lnb->offset)
+                if (isize <= lnb->offset)
                         /* If there's no more data, abort early.  lnb->rc == 0,
                          * so it's easy to detect later. */
                         break;
@@ -440,8 +445,8 @@ static int filter_preprw_read(int cmd, struct obd_export *exp, struct obdo *oa,
 
                 lprocfs_counter_add(obd->obd_stats, LPROC_FILTER_CACHE_ACCESS, 1);
 
-                if (i_size_read(inode) < lnb->offset + lnb->len - 1)
-                        lnb->rc = i_size_read(inode) - lnb->offset;
+                if (isize < lnb->offset + lnb->len - 1)
+                        lnb->rc = isize - lnb->offset;
                 else
                         lnb->rc = lnb->len;