From ce7bd320a3a8c975e607d739e5e7456414e4a0e8 Mon Sep 17 00:00:00 2001 From: anwleung Date: Sun, 11 Mar 2007 19:49:46 +0000 Subject: [PATCH] Client cap caching totally redone git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@1205 29311d96-e01e-0410-9327-a35deaab8ce9 --- .../aleung/security1/ceph/client/Client.cc | 20 ++++-- .../aleung/security1/ceph/client/Client.h | 15 ++-- .../security1/ceph/client/ClientCapCache.h | 71 +++++++++++++++++++ 3 files changed, 96 insertions(+), 10 deletions(-) create mode 100644 branches/aleung/security1/ceph/client/ClientCapCache.h diff --git a/branches/aleung/security1/ceph/client/Client.cc b/branches/aleung/security1/ceph/client/Client.cc index 2546e43b2dc7d..df245125519f9 100644 --- a/branches/aleung/security1/ceph/client/Client.cc +++ b/branches/aleung/security1/ceph/client/Client.cc @@ -49,6 +49,7 @@ using namespace std; #include "osdc/Filer.h" #include "osdc/Objecter.h" #include "osdc/ObjectCacher.h" +#include "ClientCapCache.h" #include "common/Cond.h" #include "common/Mutex.h" @@ -127,6 +128,7 @@ Client::Client(Messenger *m, MonMap *mm) objecter = new Objecter(messenger, monmap, osdmap); objectcacher = new ObjectCacher(objecter, client_lock); filer = new Filer(objecter); + capcache = new ClientCapCache(client_lock); } @@ -137,6 +139,7 @@ Client::~Client() if (objectcacher) { delete objectcacher; objectcacher = 0; } if (objecter) { delete objecter; objecter = 0; } if (osdmap) { delete osdmap; osdmap = 0; } + if (capcache) { delete capcache; capcache = 0; } tear_down_cache(); } @@ -2563,11 +2566,12 @@ int Client::open(const char *relpath, int flags, __int64_t uid, __int64_t gid) dout(3) << "Received a " << ext_cap.mode() << " capability for uid: " << ext_cap.get_uid() << " for inode: " << ext_cap.get_ino() << endl; - // FIXME the client should not actually verif the cap - //assert(ext_cap.verif_extcap(monmap->get_key())); - // cache it f->inode->set_ext_cap(uid, &ext_cap); + capcache->cache_cap(f->inode->ino(), uid, ext_cap); + // presumably i want to renew it later + //caps_in_use[uid].insert(ext_cap.get_id()); + capcache->open_cap(uid, ext_cap.get_id()); assert(reply->get_file_caps_seq() >= f->inode->caps[mds].seq); if (reply->get_file_caps_seq() > f->inode->caps[mds].seq) { @@ -2686,6 +2690,10 @@ int Client::close(fh_t fh, __int64_t uid, __int64_t gid) if (before != after && after) update_caps_wanted(in); + // stop using capability + //caps_in_use[uid].erase(in->get_ext_cap(uid)->get_id()); + capcache->close_cap(uid, capcache->get_cache_cap(in->ino(), uid)->get_id()); + // hose fh fh_map.erase(fh); delete f; @@ -2776,7 +2784,8 @@ int Client::read(fh_t fh, char *buf, off_t size, off_t offset, // grab security cap for file (mode should always be correct) // add that assertion - ExtCap *read_ext_cap = in->get_ext_cap(uid); + //ExtCap *read_ext_cap = in->get_ext_cap(uid); + ExtCap *read_ext_cap = capcache->get_cache_cap(in->ino(), uid); assert(read_ext_cap); // do we have read file cap? @@ -2924,7 +2933,8 @@ int Client::write(fh_t fh, const char *buf, off_t size, off_t offset, 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); + //ExtCap *write_ext_cap = in->get_ext_cap(uid); + ExtCap *write_ext_cap = capcache->get_cache_cap(in->ino(), uid); assert(write_ext_cap); // do we have write file cap? diff --git a/branches/aleung/security1/ceph/client/Client.h b/branches/aleung/security1/ceph/client/Client.h index 9f3744e51dab1..b99cba3510a7a 100644 --- a/branches/aleung/security1/ceph/client/Client.h +++ b/branches/aleung/security1/ceph/client/Client.h @@ -49,6 +49,7 @@ using namespace CryptoLib; #include "crypto/Ticket.h" #include "crypto/CapGroup.h" #include "crypto/MerkleTree.h" +//#include "ClientCapCache.h" // stl #include @@ -68,6 +69,7 @@ class Filer; class Objecter; class ObjectCacher; class Ticket; +class ClientCapCache; extern class LogType client_logtype; extern class Logger *client_logger; @@ -363,6 +365,9 @@ protected: Filer *filer; ObjectCacher *objectcacher; Objecter *objecter; // (non-blocking) osd interface + + // capability cache + ClientCapCache *capcache; // cache hash_map inode_map; @@ -515,12 +520,12 @@ protected: map user_priv_key; map groups; - map > update_waiter_osd; + //map > update_waiter_osd; + map > update_waiter_osd; //map > update_waiter_cond; - - - // user map - //map user_identity; + map > caps_in_use; + // renew caps that are in use (leaves a re-use grace period) + // expunge caps that are not open, are expired and have no extension Ticket *get_user_ticket(uid_t uid, gid_t gid); void put_user_ticket(Ticket *tk); diff --git a/branches/aleung/security1/ceph/client/ClientCapCache.h b/branches/aleung/security1/ceph/client/ClientCapCache.h new file mode 100644 index 0000000000000..62ed82223d1f9 --- /dev/null +++ b/branches/aleung/security1/ceph/client/ClientCapCache.h @@ -0,0 +1,71 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2006 Sage Weil + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ +#ifndef __CLIENTCAPCACHE_H +#define __CLIENTCAPCACHE_H + +#include "common/Cond.h" +#include "common/Thread.h" + +class ClientCapCache { + public: + void cache_cap(inodeno_t ino, uid_t user, ExtCap& cap) { + inode_user_cap_cache[ino][user] = cap; + } + void clear_cap(inodeno_t ino, uid_t user) { + inode_user_cap_cache[ino].erase(user); + } + void open_cap(uid_t user, cap_id_t cid) { + caps_in_use[user].insert(cid); + } + void close_cap(uid_t user, cap_id_t cid) { + caps_in_use[user].erase(cid); + } + ExtCap *get_cache_cap(inodeno_t ino, uid_t user) { + if (inode_user_cap_cache[ino].count(user) == 0) + return 0; + return &(inode_user_cap_cache[ino][user]); + } + + ClientCapCache (Mutex& l) : lock(l), cleaner_stop(false), + cleaner_thread(this) { cleaner_thread.create(); } + ~ClientCapCache () { + cleaner_stop = true; + cleaner_cond.Signal(); + cleaner_thread.join(); + } + + private: + Mutex& lock; + map > inode_user_cap_cache; + map > caps_in_use; + + bool cleaner_stop; + Cond cleaner_cond; + void cleaner_entry() { + cout << "Cleaner start" << endl; + lock.Lock(); + lock.Unlock(); + cout << "Cleaner finish" << endl; + } + class CleanerThread : public Thread { + ClientCapCache *cc; + public: + CleanerThread(ClientCapCache *c) : cc(c) {} + void *entry() { + cc->cleaner_entry(); + return 0; + } + } cleaner_thread; +}; + +#endif -- 2.39.5