From 359f2588fef2be1fc2a1b6485fde690a2fe8a3f8 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 4 Sep 2009 15:09:59 -0700 Subject: [PATCH] objectcacher: add is_cached method Helps us see what we have cached... --- src/osdc/ObjectCacher.cc | 85 ++++++++++++++++++++++++++++++++++++++++ src/osdc/ObjectCacher.h | 17 ++++++++ 2 files changed, 102 insertions(+) diff --git a/src/osdc/ObjectCacher.cc b/src/osdc/ObjectCacher.cc index 96ecf002ed8e9..6418a9b810a41 100644 --- a/src/osdc/ObjectCacher.cc +++ b/src/osdc/ObjectCacher.cc @@ -126,6 +126,40 @@ void ObjectCacher::Object::try_merge_bh(BufferHead *bh) merge_left(bh, p->second); } +/* + * count bytes we have cached in given range + */ +bool ObjectCacher::Object::is_cached(loff_t cur, loff_t left) +{ + map::iterator p = data.lower_bound(cur); + + if (p != data.begin() && + (p == data.end() || p->first > cur)) { + p--; // might overlap! + if (p->first + p->second->length() <= cur) + p++; // doesn't overlap. + } + + while (left > 0) { + if (p == data.end()) + return false; + + if (p->first <= cur) { + // have part of it + loff_t lenfromcur = MIN(p->second->end() - cur, left); + cur += lenfromcur; + left -= lenfromcur; + p++; + continue; + } else if (p->first > cur) { + // gap + return false; + } else + assert(0); + } + + return true; +} /* * map a range of bytes into buffer_heads. @@ -748,6 +782,25 @@ void ObjectCacher::trim(loff_t max) /* public */ +bool ObjectCacher::is_cached(inodeno_t ino, vector& extents, snapid_t snapid) +{ + for (vector::iterator ex_it = extents.begin(); + ex_it != extents.end(); + ex_it++) { + dout(10) << "is_cached " << *ex_it << dendl; + + // get Object cache + sobject_t soid(ex_it->oid, snapid); + Object *o = get_object_maybe(soid, ino, ex_it->layout); + if (!o) + return false; + if (!o->is_cached(ex_it->offset, ex_it->length)) + return false; + } + return true; +} + + /* * returns # bytes read (if in cache). onfinish is untouched (caller must delete it) * returns 0 if doing async read @@ -1569,6 +1622,38 @@ loff_t ObjectCacher::release_set(inodeno_t ino) return unclean; } + +__u64 ObjectCacher::release_all() +{ + dout(10) << "release_all" << dendl; + __u64 unclean = 0; + + hash_map::iterator p = objects.begin(); + while (p != objects.end()) { + hash_map::iterator n = p; + n++; + + Object *ob = p->second; + + loff_t o_unclean = release(ob); + unclean += o_unclean; + + if (o_unclean) + dout(10) << "release_all " << *ob + << " has " << o_unclean << " bytes left" + << dendl; + } + + if (unclean) { + dout(10) << "release_all unclean " << unclean << " bytes left" << dendl; + } + + return unclean; +} + + + + void ObjectCacher::truncate_set(inodeno_t ino, vector& exls) { if (objects_by_ino.count(ino) == 0) { diff --git a/src/osdc/ObjectCacher.h b/src/osdc/ObjectCacher.h index 1b6ac910bec74..19422c3e33f77 100644 --- a/src/osdc/ObjectCacher.h +++ b/src/osdc/ObjectCacher.h @@ -224,6 +224,7 @@ class ObjectCacher { void merge_left(BufferHead *left, BufferHead *right); void try_merge_bh(BufferHead *bh); + bool is_cached(loff_t off, loff_t len); int map_read(OSDRead *rd, map& hits, map& missing, @@ -269,6 +270,13 @@ class ObjectCacher { // objects + Object *get_object_maybe(sobject_t oid, inodeno_t ino, ceph_object_layout &l) { + // have it? + if (objects.count(oid)) + return objects[oid]; + return NULL; + } + Object *get_object(sobject_t oid, inodeno_t ino, ceph_object_layout &l) { // have it? if (objects.count(oid)) @@ -514,6 +522,7 @@ class ObjectCacher { // non-blocking. async. int readx(OSDRead *rd, inodeno_t ino, Context *onfinish); int writex(OSDWrite *wr, inodeno_t ino); + bool is_cached(inodeno_t ino, vector& extents, snapid_t snapid); // write blocking bool wait_for_write(size_t len, Mutex& lock); @@ -534,6 +543,7 @@ class ObjectCacher { void purge_set(inodeno_t ino); loff_t release_set(inodeno_t ino); // returns # of bytes not released (ie non-clean) + __u64 release_all(); void truncate_set(inodeno_t ino, vector& ex); @@ -544,6 +554,13 @@ class ObjectCacher { // file functions /*** async+caching (non-blocking) file interface ***/ + int file_is_cached(inodeno_t ino, ceph_file_layout *layout, snapid_t snapid, + loff_t offset, size_t len) { + vector extents; + filer.file_to_extents(ino, layout, offset, len, extents); + return is_cached(ino, extents, snapid); + } + int file_read(inodeno_t ino, ceph_file_layout *layout, snapid_t snapid, loff_t offset, size_t len, bufferlist *bl, -- 2.39.5