mirror of
https://github.com/ceph/ceph
synced 2025-03-31 07:53:23 +00:00
ebofs sync() tweaks (untested!); first pass at is_cached interface (with half-assed implementation)
git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@1063 29311d96-e01e-0410-9327-a35deaab8ce9
This commit is contained in:
parent
b100a1ff64
commit
31d854b727
@ -16,13 +16,7 @@
|
||||
#include "Ebofs.h"
|
||||
|
||||
#include <errno.h>
|
||||
#ifdef DARWIN
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/statvfs.h>
|
||||
#else
|
||||
#include <sys/vfs.h>
|
||||
#endif // DARWIN
|
||||
|
||||
// *******************
|
||||
|
||||
@ -1218,8 +1212,10 @@ void Ebofs::kick_idle()
|
||||
void Ebofs::sync(Context *onsafe)
|
||||
{
|
||||
ebofs_lock.Lock();
|
||||
if (onsafe)
|
||||
if (onsafe) {
|
||||
dirty = true;
|
||||
commit_waiters[super_epoch].push_back(onsafe);
|
||||
}
|
||||
ebofs_lock.Unlock();
|
||||
}
|
||||
|
||||
@ -1229,22 +1225,14 @@ void Ebofs::sync()
|
||||
if (!dirty) {
|
||||
dout(7) << "sync in " << super_epoch << ", not dirty" << endl;
|
||||
} else {
|
||||
dout(7) << "sync in " << super_epoch << endl;
|
||||
|
||||
if (!commit_thread_started) {
|
||||
dout(10) << "sync waiting for commit thread to start" << endl;
|
||||
epoch_t start = super_epoch;
|
||||
dout(7) << "sync start in " << start << endl;
|
||||
while (super_epoch == start) {
|
||||
dout(7) << "sync kicking commit in " << super_epoch << endl;
|
||||
dirty = true;
|
||||
commit_cond.Signal();
|
||||
sync_cond.Wait(ebofs_lock);
|
||||
}
|
||||
|
||||
if (mid_commit) {
|
||||
dout(10) << "sync waiting for commit in progress" << endl;
|
||||
sync_cond.Wait(ebofs_lock);
|
||||
}
|
||||
|
||||
commit_cond.Signal(); // trigger a commit
|
||||
|
||||
sync_cond.Wait(ebofs_lock); // wait
|
||||
|
||||
dout(10) << "sync finish in " << super_epoch << endl;
|
||||
}
|
||||
ebofs_lock.Unlock();
|
||||
@ -1290,9 +1278,7 @@ int Ebofs::statfs(struct statfs *buf)
|
||||
buf->f_files = nodepool.num_total(); /* total file nodes in file system */
|
||||
buf->f_ffree = nodepool.num_free(); /* free file nodes in fs */
|
||||
//buf->f_fsid = 0; /* file system id */
|
||||
#ifndef DARWIN
|
||||
buf->f_namelen = 8; /* maximum length of filenames */
|
||||
#endif // DARWIN
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1830,6 +1816,60 @@ bool Ebofs::attempt_read(Onode *on, off_t off, size_t len, bufferlist& bl,
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* is_cached -- query whether a object extent is in our cache
|
||||
* return value of -1 if onode isn't loaded. otherwise, the number
|
||||
* of extents that need to be read (i.e. # of seeks)
|
||||
*/
|
||||
int Ebofs::is_cached(object_t oid, off_t off, size_t len)
|
||||
{
|
||||
ebofs_lock.Lock();
|
||||
int r = _is_cached(oid, off, len);
|
||||
ebofs_lock.Unlock();
|
||||
return r;
|
||||
}
|
||||
|
||||
int Ebofs::_is_cached(object_t oid, off_t off, size_t len)
|
||||
{
|
||||
Onode *on = 0;
|
||||
if (onode_map.count(oid) == 0) {
|
||||
dout(7) << "_is_cached " << oid << " " << off << "~" << len << " ... onode " << endl;
|
||||
return -1; // object dne?
|
||||
}
|
||||
|
||||
if (!on->have_oc()) {
|
||||
// nothing is cached. return # of extents in file.
|
||||
return on->extent_map.size();
|
||||
}
|
||||
|
||||
// map
|
||||
block_t bstart = off / EBOFS_BLOCK_SIZE;
|
||||
block_t blast = (len+off-1) / EBOFS_BLOCK_SIZE;
|
||||
block_t blen = blast-bstart+1;
|
||||
|
||||
map<block_t, BufferHead*> hits;
|
||||
map<block_t, BufferHead*> missing; // read these
|
||||
map<block_t, BufferHead*> rx; // wait for these
|
||||
map<block_t, BufferHead*> partials; // ??
|
||||
on->get_oc(&bc)->map_read(bstart, blen, hits, missing, rx, partials);
|
||||
return missing.size() + rx.size() + partials.size();
|
||||
|
||||
// FIXME: actually, we should calculate if these extents are contiguous.
|
||||
// and not using map_read, probably...
|
||||
/* hrmpf
|
||||
block_t dpos = 0;
|
||||
block_t opos = bstart;
|
||||
while (opos < blen) {
|
||||
if (hits.begin()->first == opos) {
|
||||
} else {
|
||||
block_t d;
|
||||
if (missing.begin()->first == opos) d = missing.begin()->second.
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
int Ebofs::read(object_t oid,
|
||||
off_t off, size_t len,
|
||||
bufferlist& bl)
|
||||
|
@ -242,7 +242,8 @@ class Ebofs : public ObjectStore {
|
||||
bool exists(object_t);
|
||||
int stat(object_t, struct stat*);
|
||||
int read(object_t, off_t off, size_t len, bufferlist& bl);
|
||||
//int write(object_t oid, off_t off, size_t len, bufferlist& bl, bool fsync=true);
|
||||
int is_cached(object_t oid, off_t off, size_t len);
|
||||
|
||||
int write(object_t oid, off_t off, size_t len, bufferlist& bl, Context *onsafe);
|
||||
int truncate(object_t oid, off_t size, Context *onsafe=0);
|
||||
int truncate_front(object_t oid, off_t size, Context *onsafe=0);
|
||||
@ -298,6 +299,7 @@ class Ebofs : public ObjectStore {
|
||||
private:
|
||||
// private interface -- use if caller already holds lock
|
||||
int _read(object_t oid, off_t off, size_t len, bufferlist& bl);
|
||||
int _is_cached(object_t oid, off_t off, size_t len);
|
||||
int _stat(object_t oid, struct stat *st);
|
||||
int _getattr(object_t oid, const char *name, void *value, size_t size);
|
||||
int _getattrs(object_t oid, map<string,bufferptr> &aset);
|
||||
|
Loading…
Reference in New Issue
Block a user