dout(10) << "cur file size is " << in->inode.size << " wr size " << in->file_wr_size << endl;
+ ExtCap *write_ext_cap = in->get_ext_cap(uid);
+ assert(write_ext_cap);
+
// do we have write file cap?
while (!lazy && (in->file_caps() & CAP_FILE_WR) == 0) {
dout(7) << " don't have write cap, waiting" << endl;
assert(objectcacher);
// write (this may block!)
- in->fc.write(offset, size, blist, client_lock);
+ in->fc.write(offset, size, blist, client_lock, write_ext_cap);
} else {
// legacy, inconsistent synchronous write.
dout(20) << " sync write start " << onfinish << endl;
filer->write(in->inode, offset, size, blist, 0,
- onfinish, onsafe
+ onfinish, onsafe, write_ext_cap
//, 1+((int)g_clock.now()) / 10 //f->pos // hack hack test osd revision snapshots
);
return r;
}
-void FileCache::write(off_t offset, size_t size, bufferlist& blist, Mutex& client_lock)
+void FileCache::write(off_t offset, size_t size, bufferlist& blist, Mutex& client_lock, ExtCap *write_ext_cap)
{
// inc writing counter
num_writing++;
oc->wait_for_write(size, client_lock);
// async, caching, non-blocking.
- oc->file_write(inode, offset, size, blist);
+ oc->file_write(inode, offset, size, blist, write_ext_cap);
} else {
// atomic, synchronous, blocking.
- oc->file_atomic_sync_write(inode, offset, size, blist, client_lock);
+ oc->file_atomic_sync_write(inode, offset, size, blist, client_lock, write_ext_cap);
}
// dec writing counter
#include "common/Cond.h"
#include "mds/Capability.h"
+#include "crypto/CryptoLib.h"
+using namespace CryptoLib;
#include "crypto/ExtCap.h"
class ObjectCacher;
int read(off_t offset, size_t size, bufferlist& blist, Mutex& client_lock,
ExtCap *read_ext_cap=0); // may block.
- void write(off_t offset, size_t size, bufferlist& blist, Mutex& client_lock); // may block.
+ void write(off_t offset, size_t size, bufferlist& blist, Mutex& client_lock,
+ ExtCap *write_ext_cap=0); // may block.
};
#ifndef __EXTCAP_H
#define __EXTCAP_H
+#include "include/types.h"
#include "include/buffer.h"
#include "mds/Capability.h"
#include "crypto/CryptoLib.h"
using namespace CryptoLib;
+#include "common/Clock.h"
+
class ExtCap {
private:
struct cap_data_t {
#include <iomanip>
using namespace std;
+#include "crypto/ExtCap.h"
+
typedef __uint32_t objectrev_t;
//<< " in " << *pg
<< endl;
+ // verify the capability
+ ExtCap *op_capability = op->get_capability();
+ if (op_capability) {
+ cout << "OSD recieved a capability" << endl;
+ if (op_capability->verif_extcap(monmap->get_key()))
+ cout << "OSD successfully verified capability" << endl;
+ else
+ cout << "OSD failed to verify capability" << endl;
+ }
+
long r = 0;
bufferlist bl;
// check for capability
ExtCap *op_capability = op->get_capability();
- if (op_capability) {
- cout << "OSD recieved a capability" << endl;
+ if (op_capability && op->get_op() == OSD_OP_WRITE) {
+ cout << "OSD recieved a write with a capability" << endl;
if (op_capability->verif_extcap(monmap->get_key()))
cout << "OSD successfully verified capability" << endl;
else
cout << "OSD failed to verify capability" << endl;
}
+ else if (op->get_op() == OSD_OP_WRITE) {
+ cout << "Received write with no capability" << endl;
+ }
+ else
+ cout << "Received " << opname << " with no capability" << endl;
// locked by someone else?
// for _any_ op type -- eg only the locker can unlock!
bufferlist& bl,
int flags,
Context *onack,
- Context *oncommit,
+ Context *oncommit, ExtCap* write_cap=0,
objectrev_t rev=0) {
- Objecter::OSDWrite *wr = new Objecter::OSDWrite(bl);
+ Objecter::OSDWrite *wr;
+ if (!write_cap) // we should always pass a cap
+ wr = new Objecter::OSDWrite(bl);
+ else
+ wr = new Objecter::OSDWrite(bl, write_cap);
file_to_extents(inode, offset, len, wr->extents, rev);
return objecter->modifyx(wr, onack, oncommit) > 0 ? 0:-1;
}
left -= glen;
continue; // more?
}
- }
+s }
}
// set versoin
}
-void ObjectCacher::bh_write(BufferHead *bh)
+void ObjectCacher::bh_write(BufferHead *bh, ExtCap *write_cap)
{
dout(7) << "bh_write " << *bh << endl;
// go
tid_t tid = objecter->write(bh->ob->get_oid(), bh->start(), bh->length(), bh->bl,
- onack, oncommit);
+ onack, oncommit, write_cap);
// set bh last_write_tid
onack->tid = tid;
{
utime_t now = g_clock.now();
+ // grab all objects in the extent
for (list<ObjectExtent>::iterator ex_it = wr->extents.begin();
ex_it != wr->extents.end();
ex_it++) {
// map it all into a single bufferhead.
BufferHead *bh = o->map_write(wr);
-
+ // set security cap in bh
+ bh->bh_cap = wr->modify_cap;
+
// adjust buffer pointers (ie "copy" data into my cache)
// this is over a single ObjectExtent, so we know that
// - there is one contiguous bh
map<off_t,BufferHead*>::iterator p = o->data.find(bh->start());
if (p != o->data.begin()) {
p--;
- if (p->second->is_dirty()) {
+ if (p->second->is_dirty() && p->second->bh_cap == bh->bh_cap) {
o->merge_left(p->second,bh);
bh = p->second;
}
p = o->data.find(bh->start());
p++;
if (p != o->data.end() &&
- p->second->is_dirty())
+ p->second->is_dirty() &&
+ p->second->bh_cap == bh->bh_cap)
o->merge_left(p->second,bh);
}
continue;
}
if (!bh->is_dirty()) continue;
-
- bh_write(bh);
+ // get capability for write back
+ ExtCap *write_cap = ob->ocap;
+ bh_write(bh, write_cap);
clean = false;
}
return clean;
#include "Objecter.h"
#include "Filer.h"
+//#include "crypto/CryptoLib.h"
+//using namespace CryptoLib;
+//#include "crypto/ExtCap.h"
+
class Objecter;
class Objecter::OSDRead;
class Objecter::OSDWrite;
bufferlist bl;
tid_t last_write_tid; // version of bh (if non-zero)
utime_t last_write;
+
+ // security cap
+ ExtCap *bh_cap;
map< off_t, list<Context*> > waitfor_read;
ObjectCacher *oc;
object_t oid; // this _always_ is oid.rev=0
inodeno_t ino;
- objectrev_t rev; // last rev we're written
+ objectrev_t rev; // last rev we're written
public:
map<off_t, BufferHead*> data;
// io
void bh_read(BufferHead *bh, ExtCap* read_ext_cap=0);
- void bh_write(BufferHead *bh);
+ void bh_write(BufferHead *bh, ExtCap *write_cap=0);
void trim(off_t max=-1);
void flush(off_t amount=0);
int file_write(inode_t& inode,
off_t offset, size_t len,
- bufferlist& bl,
+ bufferlist& bl, ExtCap *write_ext_cap,
objectrev_t rev=0) {
- Objecter::OSDWrite *wr = new Objecter::OSDWrite(bl);
+ Objecter::OSDWrite *wr;
+ if (!write_ext_cap)
+ wr = new Objecter::OSDWrite(bl);
+ else
+ wr = new Objecter::OSDWrite(bl, write_ext_cap);
filer.file_to_extents(inode, offset, len, wr->extents);
return writex(wr, inode.ino);
}
int file_atomic_sync_write(inode_t& inode,
off_t offset, size_t len,
bufferlist& bl,
- Mutex &lock,
+ Mutex &lock, ExtCap *write_ext_cap=0,
objectrev_t rev=0) {
Objecter::OSDWrite *wr = new Objecter::OSDWrite(bl);
filer.file_to_extents(inode, offset, len, wr->extents);
tid_t Objecter::write(object_t oid, off_t off, size_t len, bufferlist &bl,
Context *onack, Context *oncommit,
- objectrev_t rev)
+ ExtCap *write_ext_cap, objectrev_t rev)
{
- OSDWrite *wr = new OSDWrite(bl);
+ OSDWrite *wr;
+ if (write_ext_cap)
+ wr = new OSDWrite(bl, write_ext_cap);
+ else
+ wr = new OSDWrite(bl);
wr->extents.push_back(ObjectExtent(oid, off, len));
wr->extents.front().pgid = osdmap->object_to_pg( oid, g_OSD_FileLayout );
wr->extents.front().buffer_extents[0] = len;
m->set_length(ex.length);
m->set_offset(ex.start);
m->set_rev(ex.rev);
+ // only cap for a write, fix later
+ if (wr->modify_cap && wr->op == OSD_OP_WRITE)
+ m->set_capability(wr->modify_cap);
if (wr->tid_version.count(tid))
m->set_version(wr->tid_version[tid]); // we're replaying this op!
map<tid_t, ObjectExtent> waitfor_ack;
map<tid_t, eversion_t> tid_version;
map<tid_t, ObjectExtent> waitfor_commit;
+ ExtCap *modify_cap;
OSDModify(int o) : op(o), onack(0), oncommit(0) {}
+ OSDModify(int o, ExtCap* cap) : op(o), onack(0), oncommit(0), modify_cap(cap) {}
};
// write (includes the bufferlist)
public:
bufferlist bl;
OSDWrite(bufferlist &b) : OSDModify(OSD_OP_WRITE), bl(b) {}
+ OSDWrite(bufferlist &b, ExtCap *write_cap) : OSDModify(OSD_OP_WRITE, write_cap), bl(b) {}
};
// even lazier
tid_t read(object_t oid, off_t off, size_t len, bufferlist *bl,
- Context *onfinish, ExtCap* read_ext_cap=0,
+ Context *onfinish, ExtCap *read_ext_cap=0,
objectrev_t rev=0);
tid_t write(object_t oid, off_t off, size_t len, bufferlist &bl,
- Context *onack, Context *oncommit,
+ Context *onack, Context *oncommit, ExtCap *write_ext_cap=0,
objectrev_t rev=0);
tid_t zero(object_t oid, off_t off, size_t len,
Context *onack, Context *oncommit,