From 8f49de0fb1ab6cd33c07fc382722ce37b42d74c8 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 9 Nov 2012 18:34:22 -0800 Subject: [PATCH] osdc/ObjectCacher: only call flush callback if we transitions to clean If we race with e.g. truncate and are in bh_write_commit but the oset is already clean, we should not call the flush callback (again). This is reproduced by: - kludging slow osd replies into the code (e.g., 2 second delay) - mount ceph-fuse with --client-oc-max-dirty-age 1 - dd if=/dev/zero of=mnt/foo count=1 sleep 1 truncate --size 0 mnt/foo -> crash Signed-off-by: Sage Weil --- src/osdc/ObjectCacher.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/osdc/ObjectCacher.cc b/src/osdc/ObjectCacher.cc index 610a0061dcd92..a700959613d24 100644 --- a/src/osdc/ObjectCacher.cc +++ b/src/osdc/ObjectCacher.cc @@ -720,6 +720,7 @@ void ObjectCacher::bh_write_commit(int64_t poolid, sobject_t oid, loff_t start, ldout(cct, 7) << "bh_write_commit no object cache" << dendl; } else { Object *ob = objects[poolid][oid]; + int was_dirty_or_tx = ob->oset->dirty_or_tx; // apply to bh's! for (map::iterator p = ob->data.lower_bound(start); @@ -780,6 +781,7 @@ void ObjectCacher::bh_write_commit(int64_t poolid, sobject_t oid, loff_t start, // is the entire object set now clean? if (flush_set_callback && + was_dirty_or_tx > 0 && oset->dirty_or_tx == 0) { // nothing dirty/tx flush_set_callback(flush_set_callback_arg, oset); } -- 2.39.5