1
0
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:
sageweil 2007-01-31 22:51:08 +00:00
parent b100a1ff64
commit 31d854b727
2 changed files with 66 additions and 24 deletions
trunk/ceph/ebofs

View File

@ -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)

View File

@ -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);