Whamcloud - gitweb
LU-1755 osc: solve a race between fsync and truncate
authorJinshan Xiong <jinshan.xiong@intel.com>
Thu, 16 Aug 2012 17:10:54 +0000 (10:10 -0700)
committerOleg Drokin <green@whamcloud.com>
Thu, 6 Sep 2012 14:36:50 +0000 (10:36 -0400)
If an OSC extent is being truncated when fsync is called, it will
have oe_fsync_wait set but no oe_urgent or oe_hp set. This causes
problem because when the extent changes OES_CACHE later, it won't
be written out immediately because urgent bit is not set.

This problem can be fixed by checking oe_fsync_wait bit and set urgent
bit correspondingly when changing osc extent's state from OES_TRUNC to
OES_CACHE at the end of truncate.

Signed-off-by: Jinshan Xiong <jinshan.xiong@intel.com>
Change-Id: I755baac066375a92730b14de1c470c66baad5320
Reviewed-on: http://review.whamcloud.com/3699
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Niu Yawei <niu@whamcloud.com>
Reviewed-by: Johann Lombardi <johann@whamcloud.com>
lustre/osc/osc_cache.c

index b67911b..23dc755 100644 (file)
@@ -2678,6 +2678,10 @@ void osc_cache_truncate_end(const struct lu_env *env, struct osc_io *oio,
                OSC_EXTENT_DUMP(D_CACHE, ext, "trunc -> cache.\n");
                osc_object_lock(obj);
                osc_extent_state_set(ext, OES_CACHE);
+               if (ext->oe_fsync_wait && !ext->oe_urgent) {
+                       ext->oe_urgent = 1;
+                       cfs_list_move_tail(&ext->oe_link, &obj->oo_urgent_exts);
+               }
                osc_update_pending(obj, OBD_BRW_WRITE, ext->oe_nr_pages);
                osc_object_unlock(obj);
                osc_extent_put(env, ext);
@@ -2808,6 +2812,11 @@ int osc_cache_writeback_range(const struct lu_env *env, struct osc_object *obj,
                         * grants. We do this for the correctness of fsync. */
                        LASSERT(hp == 0 && discard == 0);
                        ext->oe_urgent = 1;
+                       break;
+               case OES_TRUNC:
+                       /* this extent is being truncated, can't do anything
+                        * for it now. it will be set to urgent after truncate
+                        * is finished in osc_cache_truncate_end(). */
                default:
                        break;
                }