From ca9d0978323e896a084b2f0847a7584d44286dff Mon Sep 17 00:00:00 2001 From: phlalx Date: Sun, 29 May 2016 13:52:55 +0000 Subject: [PATCH] refactoring --- extent_client.cc | 42 +++++++--------- extent_client.h | 22 ++++++--- extent_client_cache.cc | 106 ++++++++++++++++++----------------------- extent_client_cache.h | 32 +++++++++---- extent_protocol.h | 9 ++++ extent_server.cc | 63 +++++++++++------------- extent_server.h | 32 +++++++++---- extent_smain.cc | 23 +++++---- lock_client.cc | 27 +++-------- lock_client.h | 18 +++++-- lock_protocol.h | 9 +++- lock_server.cc | 24 ++++------ lock_server.h | 10 ++-- lock_server_cache.cc | 72 ++++++++++++---------------- yfs_client.cc | 103 ++++++++++++++++++--------------------- yfs_client.h | 64 ++++++++++++++----------- 16 files changed, 325 insertions(+), 331 deletions(-) diff --git a/extent_client.cc b/extent_client.cc index 1bc696d..120b16e 100644 --- a/extent_client.cc +++ b/extent_client.cc @@ -1,57 +1,49 @@ -// RPC stubs for clients to talk to extent_server - #include "extent_client.h" #include #include #include #include #include +#include -// The calls assume that the caller holds a lock on the extent - -extent_client::extent_client(std::string dst) -{ +extent_client::extent_client(const std::string &dst) { sockaddr_in dstsock; make_sockaddr(dst.c_str(), &dstsock); - cl = new rpcc(dstsock); - if (cl->bind() != 0) { - printf("extent_client: bind failed\n"); - } + cl = std::unique_ptr(new rpcc(dstsock)); + VERIFY(cl->bind() == 0); } -extent_protocol::status -extent_client::get(extent_protocol::extentid_t eid, std::string &buf) -{ +extent_protocol::status extent_client::get(extent_protocol::extentid_t eid, + std::string &buf) { + jsl_log(JSL_DBG_ME, "extent_client: get %llu\n", eid); extent_protocol::status ret = extent_protocol::OK; ret = cl->call(extent_protocol::get, eid, buf); + jsl_log(JSL_DBG_ME, "extent_client: get %llu buf = %s\n", eid, buf.c_str()); return ret; } -extent_protocol::status -extent_client::getattr(extent_protocol::extentid_t eid, - extent_protocol::attr &attr) -{ +extent_protocol::status extent_client::getattr(extent_protocol::extentid_t eid, + extent_protocol::attr &attr) { + jsl_log(JSL_DBG_ME, "extent_client: getattr %llu\n", eid); extent_protocol::status ret = extent_protocol::OK; ret = cl->call(extent_protocol::getattr, eid, attr); return ret; } -extent_protocol::status -extent_client::put(extent_protocol::extentid_t eid, std::string buf) -{ +extent_protocol::status extent_client::put(extent_protocol::extentid_t eid, + std::string buf) { + jsl_log(JSL_DBG_ME, "extent_client: put %llu %s\n", eid, buf.c_str()); extent_protocol::status ret = extent_protocol::OK; int r; ret = cl->call(extent_protocol::put, eid, buf, r); return ret; } -extent_protocol::status -extent_client::remove(extent_protocol::extentid_t eid) +extent_protocol::status extent_client::remove(extent_protocol::extentid_t eid) { + jsl_log(JSL_DBG_ME, "extent_client: remove %llu\n", eid); extent_protocol::status ret = extent_protocol::OK; int r; ret = cl->call(extent_protocol::remove, eid, r); return ret; -} - - +} \ No newline at end of file diff --git a/extent_client.h b/extent_client.h index 66712d2..8aac79a 100644 --- a/extent_client.h +++ b/extent_client.h @@ -1,25 +1,33 @@ -// extent client interface. - #ifndef extent_client_h #define extent_client_h #include #include "extent_protocol.h" #include "rpc.h" +#include +/** + * RPC stub to talk to the extent_server + * Assume that the caller always holds a lock on the extent + * Thread-safe (thanks to rpcc) + */ class extent_client { private: - rpcc *cl; + std::unique_ptr cl; public: - extent_client(std::string dst); + extent_client(const std::string &dst); extent_protocol::status get(extent_protocol::extentid_t eid, - std::string &buf); + std::string &buf); + extent_protocol::status getattr(extent_protocol::extentid_t eid, - extent_protocol::attr &a); - extent_protocol::status put(extent_protocol::extentid_t eid, std::string buf); + extent_protocol::attr &a); + + extent_protocol::status put(extent_protocol::extentid_t eid, + std::string buf); + extent_protocol::status remove(extent_protocol::extentid_t eid); }; diff --git a/extent_client_cache.cc b/extent_client_cache.cc index 2f67a0e..92dbdfe 100644 --- a/extent_client_cache.cc +++ b/extent_client_cache.cc @@ -1,5 +1,3 @@ -// RPC stubs for clxents to talk to extent_server - #include "extent_client_cache.h" #include "extent_client.h" #include @@ -10,139 +8,129 @@ #include #include -// The calls assume that the caller holds a lock on the extent - -extent_client_cache::extent_client_cache(std::string dst) -{ - ec = new extent_client(dst); +extent_client_cache::extent_client_cache(const std::string &dst) : extent_client(dst) { } -extent_protocol::status -extent_client_cache::get(extent_protocol::extentid_t eid, std::string &buf) -{ +extent_protocol::status extent_client_cache::get(extent_protocol::extentid_t eid, + std::string &buf) { extent_protocol::status res = extent_protocol::OK; bool found = true; { - ScopedLock ml(&mutex); + ScopedLock ml(&mutex_); jsl_log(JSL_DBG_ME, "extent_client_cache: get %lud %llu\n", pthread_self(), eid); - if (kv_store.find(eid) == kv_store.end()) { + if (store_.find(eid) == store_.end()) { found = false; } } - Value copy; - if (!found) { // not found locally - // TODO -> ajouter une opération sur le serveur qui renvoie tout ? - res = ec->get(eid, copy.buf); + Extent copy; + if (!found) { + // TODO(phil) ajouter une opération sur le serveur qui renvoie tout ? + res = extent_client::get(eid, copy.buf); if (res != extent_protocol::OK) { return res; } - res = ec->getattr(eid, copy.attr); + res = extent_client::getattr(eid, copy.attr); if (res != extent_protocol::OK) { return res; } } - // qu'est ce qui peut arriver quand on n'a pas le verrou ici ? + // TODO(phil) qu'est ce qui peut arriver quand on n'a pas le verrou ici ? { - ScopedLock ml(&mutex); - Value &v = kv_store[eid]; + ScopedLock ml(&mutex_); + Extent &v = store_[eid]; if (!found) { - kv_store[eid] = copy; + store_[eid] = copy; } buf = v.buf; } return res; } -extent_protocol::status -extent_client_cache::getattr(extent_protocol::extentid_t eid, - extent_protocol::attr &attr) -{ +extent_protocol::status extent_client_cache::getattr(extent_protocol::extentid_t eid, + extent_protocol::attr &attr) { + // TODO(phil) factorize this extent_protocol::status res = extent_protocol::OK; bool found = true; - { - ScopedLock ml(&mutex); - jsl_log(JSL_DBG_ME, "extent_client_cache: getattr %lud %llu\n", pthread_self(), eid); - if (kv_store.find(eid) == kv_store.end()) { - found = false; + { + ScopedLock ml(&mutex_); + jsl_log(JSL_DBG_ME, "extent_client_cache: getattr %lud %llu\n", pthread_self(), eid); + if (store_.find(eid) == store_.end()) { + found = false; + } } -} -Value copy; + Extent copy; if (!found) { // not found locally // TODO -> ajouter une opération sur le serveur qui renvoie tout ? - res = ec->get(eid, copy.buf); + res = extent_client::get(eid, copy.buf); if (res != extent_protocol::OK) { return res; } - res = ec->getattr(eid, copy.attr); + res = extent_client::getattr(eid, copy.attr); if (res != extent_protocol::OK) { return res; } } - // qu'est ce qui peut arriver quand on n'a pas le verrou ici ? { - ScopedLock ml(&mutex); - Value &v = kv_store[eid]; + ScopedLock ml(&mutex_); + Extent &v = store_[eid]; if (!found) { - kv_store[eid] = copy; + store_[eid] = copy; } attr = v.attr; } return res; } -extent_protocol::status -extent_client_cache::put(extent_protocol::extentid_t eid, std::string buf) -{ - ScopedLock ml(&mutex); +extent_protocol::status extent_client_cache::put(extent_protocol::extentid_t eid, + std::string buf) { + ScopedLock ml(&mutex_); jsl_log(JSL_DBG_ME, "extent_client_cache: put %lud %llu\n", pthread_self(), eid); - Value &v = kv_store[eid]; + Extent &v = store_[eid]; v.buf = buf; v.attr.size = buf.size(); v.dirty = true; time_t cur_time = time(NULL); - // TODO why change ctime at every access? + // TODO(phil) why change ctime at every access? v.attr.ctime = cur_time; v.attr.mtime = cur_time; return extent_protocol::OK; } -extent_protocol::status -extent_client_cache::remove(extent_protocol::extentid_t eid) -{ - ScopedLock ml(&mutex); +extent_protocol::status extent_client_cache::remove( + extent_protocol::extentid_t eid) { + ScopedLock ml(&mutex_); jsl_log(JSL_DBG_ME, "extent_client_cache remove %lud %llu\n", pthread_self(), eid); - if (kv_store.find(eid) == kv_store.end()) { + if (store_.find(eid) == store_.end()) { return extent_protocol::NOENT; } - kv_store.erase(eid); + store_.erase(eid); return extent_protocol::OK; } void extent_client_cache::flush(extent_protocol::extentid_t eid) { - ScopedLock ml(&mutex); + ScopedLock ml(&mutex_); jsl_log(JSL_DBG_ME, "extent_client_cache: flush %lud %llu %p\n", pthread_self(), eid, this); extent_protocol::status res = extent_protocol::OK; - if (kv_store.find(eid) == kv_store.end()) { + if (store_.find(eid) == store_.end()) { jsl_log(JSL_DBG_ME, "extent_client_cache: flush - remove %llu\n", eid); - res = ec->remove(eid); + res = extent_client::remove(eid); + // TODO pas toujours bon... test-lab-3-b VERIFY(res == extent_protocol::OK); return; } - Value &v = kv_store[eid]; + Extent &v = store_[eid]; if (v.dirty) { - jsl_log(JSL_DBG_ME, "extent_client_cache: flush - write back %llu\n", eid); + jsl_log(JSL_DBG_ME, "extent_client_cache: flush - write back %llu buf = %s\n ", eid, v.buf.c_str()); // writeback - res = ec->put(eid, v.buf); + res = extent_client::put(eid, v.buf); VERIFY(res == extent_protocol::OK); } jsl_log(JSL_DBG_ME, "extent_client_cache: flush - erase %llu\n", eid); - kv_store.erase(eid); + store_.erase(eid); return; } - - diff --git a/extent_client_cache.h b/extent_client_cache.h index 524a1bb..3e47e01 100644 --- a/extent_client_cache.h +++ b/extent_client_cache.h @@ -1,5 +1,3 @@ -// extent client interface. - #ifndef extent_client_cache_h #define extent_client_cache_h @@ -8,30 +6,48 @@ #include "extent_client.h" #include "rpc.h" -class extent_client_cache { +/** + * Cached client to the extent server + * Operations are mostly performed locally + * All operations are protected by a mutex + * Sequential consistency is guaranteed as long as + * the caller owns the lock on the extent + */ +class extent_client_cache : extent_client { private: - extent_client *ec; - struct Value { + struct Extent { extent_protocol::attr attr; std::string buf; bool dirty; }; - std::map kv_store; + std::map store_; - pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + pthread_mutex_t mutex_ = PTHREAD_MUTEX_INITIALIZER; public: - extent_client_cache(std::string dst); + extent_client_cache(const std::string &dst); + /** local operation, unless eid is not present */ extent_protocol::status get(extent_protocol::extentid_t eid, std::string &buf); + + /** local operation, unless eid is not present */ extent_protocol::status getattr(extent_protocol::extentid_t eid, extent_protocol::attr &a); + + /* always local */ extent_protocol::status put(extent_protocol::extentid_t eid, std::string buf); + + /* always local */ extent_protocol::status remove(extent_protocol::extentid_t eid); + + /** + * Flush writes back eid if it's dirty or has been removed + * Called by the lock client before release the lock + */ void flush(extent_protocol::extentid_t eid); }; diff --git a/extent_protocol.h b/extent_protocol.h index 2d49cd8..8a197cf 100644 --- a/extent_protocol.h +++ b/extent_protocol.h @@ -5,11 +5,20 @@ #include "rpc.h" +/** + * Common types for RPC between extent_client and extent_server + */ + class extent_protocol { public: typedef int status; + typedef unsigned long long extentid_t; + + static const extentid_t root_inum = 1L; + enum xxstatus { OK, RPCERR, NOENT, IOERR }; + enum rpc_numbers { put = 0x6001, get, diff --git a/extent_server.cc b/extent_server.cc index 330fa1b..f13eb65 100644 --- a/extent_server.cc +++ b/extent_server.cc @@ -1,5 +1,3 @@ -// the extent server implementation - #include "extent_server.h" #include #include @@ -10,69 +8,62 @@ #include extent_server::extent_server() { - // lock dans le constructeur ? - // create root directory TODO mettre cette constante 1 qq part - const int root_inum = 1; - Value &v = kv_store[root_inum]; - v.buf = ""; - v.attr.size = 0; + extent_protocol::extentid_t n = extent_protocol::root_inum; + Extent &v = store_[n]; time_t cur_time = time(NULL); - - // TODO why change ctime at every access? v.attr.ctime = cur_time; v.attr.mtime = cur_time; } -int extent_server::put(extent_protocol::extentid_t id, std::string buf, int &) -{ - ScopedLock mut(&mutex); - // LAB 2 - jsl_log(JSL_DBG_ME, "extent_server: put %llu\n", id); - Value &v = kv_store[id]; +extent_protocol::status extent_server::put(extent_protocol::extentid_t id, + std::string buf, int &) { + ScopedLock mut(&mutex_); + jsl_log(JSL_DBG_ME, "extent_server: put %llu buf = %s\n", id, buf.c_str()); + Extent &v = store_[id]; v.buf = buf; v.attr.size = buf.size(); time_t cur_time = time(NULL); - // TODO why change ctime at every access? + // TODO(phil) why change ctime at every access? v.attr.ctime = cur_time; v.attr.mtime = cur_time; return extent_protocol::OK; } -int extent_server::get(extent_protocol::extentid_t id, std::string &buf) -{ - ScopedLock mut(&mutex); - // LAB 2 +extent_protocol::status extent_server::get(extent_protocol::extentid_t id, + std::string &buf) { + ScopedLock mut(&mutex_); jsl_log(JSL_DBG_ME, "extent_server: get %llu\n", id); - if (kv_store.find(id) == kv_store.end()) { + if (store_.find(id) == store_.end()) { + jsl_log(JSL_DBG_ME, "extent_server: get %llu -> NOENT", id); return extent_protocol::NOENT; } - Value &v = kv_store[id]; + Extent &v = store_[id]; buf = v.buf; v.attr.atime = time(NULL); + jsl_log(JSL_DBG_ME, "extent_server: get %llu -> buf = %s\n", id, + v.buf.c_str()); return extent_protocol::OK; } -int extent_server::getattr(extent_protocol::extentid_t id, extent_protocol::attr &a) -{ - ScopedLock mut(&mutex); - // LAB 2 +extent_protocol::status extent_server::getattr(extent_protocol::extentid_t id, + extent_protocol::attr &a) { + ScopedLock mut(&mutex_); jsl_log(JSL_DBG_ME, "extent_server: get attr %llu\n", id); - if (kv_store.find(id) == kv_store.end()) { + if (store_.find(id) == store_.end()) { return extent_protocol::NOENT; } - a = kv_store[id].attr; + a = store_[id].attr; return extent_protocol::OK; } -int extent_server::remove(extent_protocol::extentid_t id, int &) -{ - ScopedLock mut(&mutex); - // LAB 2 +extent_protocol::status extent_server::remove(extent_protocol::extentid_t id, + int &) { + ScopedLock mut(&mutex_); jsl_log(JSL_DBG_ME, "extent_server: remove %llu\n", id); - if (kv_store.find(id) == kv_store.end()) { + if (store_.find(id) == store_.end()) { return extent_protocol::NOENT; } - kv_store.erase(id); + store_.erase(id); return extent_protocol::OK; -} +} \ No newline at end of file diff --git a/extent_server.h b/extent_server.h index d14ea59..a019b8f 100644 --- a/extent_server.h +++ b/extent_server.h @@ -1,5 +1,3 @@ -// this is the extent server - #ifndef extent_server_h #define extent_server_h @@ -7,24 +5,38 @@ #include #include "extent_protocol.h" +/** + * A simple map from extentid_t ids to extents. + * An extent is a pair (buffer, attribute) + * To be used within an RPC server + * all methods protected by a mutex + */ class extent_server { - pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +private: + pthread_mutex_t mutex_ = PTHREAD_MUTEX_INITIALIZER; - struct Value { + struct Extent { extent_protocol::attr attr; std::string buf; }; - std::map kv_store; + std::map store_; - public: +public: extent_server(); - int put(extent_protocol::extentid_t id, std::string, int &); - int get(extent_protocol::extentid_t id, std::string &); - int getattr(extent_protocol::extentid_t id, extent_protocol::attr &); - int remove(extent_protocol::extentid_t id, int &); + // last parameter is useless, needed to conform to the rpc's templates + extent_protocol::status put(extent_protocol::extentid_t id, std::string, + int &); + + extent_protocol::status get(extent_protocol::extentid_t id, std::string &); + + extent_protocol::status getattr(extent_protocol::extentid_t id, extent_protocol::attr &); + + // last parameter is useless, needed to conform to the rpc's templates + extent_protocol::status remove(extent_protocol::extentid_t id, + int &); }; #endif diff --git a/extent_smain.cc b/extent_smain.cc index de27ada..d072e72 100644 --- a/extent_smain.cc +++ b/extent_smain.cc @@ -6,11 +6,10 @@ #include "extent_server.h" #include "jsl_log.h" -// Main loop of extent server - -int -main(int argc, char *argv[]) -{ +/** + * main loop of extent server + */ +int main(int argc, char *argv[]) { jsl_set_debug(JSL_DBG_ME); int count = 0; @@ -27,13 +26,13 @@ main(int argc, char *argv[]) } rpcs server(atoi(argv[1]), count); - extent_server ls; + extent_server es; - server.reg(extent_protocol::get, &ls, &extent_server::get); - server.reg(extent_protocol::getattr, &ls, &extent_server::getattr); - server.reg(extent_protocol::put, &ls, &extent_server::put); - server.reg(extent_protocol::remove, &ls, &extent_server::remove); + server.reg(extent_protocol::get, &es, &extent_server::get); + server.reg(extent_protocol::getattr, &es, &extent_server::getattr); + server.reg(extent_protocol::put, &es, &extent_server::put); + server.reg(extent_protocol::remove, &es, &extent_server::remove); - while(1) - sleep(1000); + // TODO(phil) change this + while(1) sleep(1000); } diff --git a/lock_client.cc b/lock_client.cc index db017e5..c20a7df 100644 --- a/lock_client.cc +++ b/lock_client.cc @@ -1,45 +1,32 @@ -// RPC stubs for clients to talk to lock_server - #include "lock_client.h" #include "rpc.h" #include - #include #include #include -lock_client::lock_client(std::string dst) -{ +lock_client::lock_client(std::string dst) { sockaddr_in dstsock; make_sockaddr(dst.c_str(), &dstsock); - cl = new rpcc(dstsock); - if (cl->bind() < 0) { - printf("lock_client: call bind\n"); - } + cl = std::unique_ptr(new rpcc(dstsock)); + VERIFY(cl->bind() == 0); } -int -lock_client::stat(lock_protocol::lockid_t lid) -{ +int lock_client::stat(lock_protocol::lockid_t lid) { int r; lock_protocol::status ret = cl->call(lock_protocol::stat, cl->id(), lid, r); VERIFY(ret == lock_protocol::OK); return r; } -lock_protocol::status -lock_client::acquire(lock_protocol::lockid_t lid) -{ +lock_protocol::status lock_client::acquire(lock_protocol::lockid_t lid) { int r; lock_protocol::status ret = cl->call(lock_protocol::acquire, cl->id(), lid, r); return ret; } -lock_protocol::status -lock_client::release(lock_protocol::lockid_t lid) -{ +lock_protocol::status lock_client::release(lock_protocol::lockid_t lid) { int r; lock_protocol::status ret = cl->call(lock_protocol::release, cl->id(), lid, r); return ret; -} - +} \ No newline at end of file diff --git a/lock_client.h b/lock_client.h index aeee6a8..5cfa051 100644 --- a/lock_client.h +++ b/lock_client.h @@ -1,5 +1,3 @@ -// lock client interface. - #ifndef lock_client_h #define lock_client_h @@ -7,18 +5,28 @@ #include "lock_protocol.h" #include "rpc.h" #include +#include -// Client interface to the lock server +/** + * RPC stub to talk to lock_server + * Thread safe (thanks to rpcc) + */ class lock_client { protected: - rpcc *cl; + + std::unique_ptr cl; + public: + lock_client(std::string d); + virtual ~lock_client() {}; + virtual lock_protocol::status acquire(lock_protocol::lockid_t); + virtual lock_protocol::status release(lock_protocol::lockid_t); + virtual lock_protocol::status stat(lock_protocol::lockid_t); }; - #endif diff --git a/lock_protocol.h b/lock_protocol.h index a327c11..6268b39 100644 --- a/lock_protocol.h +++ b/lock_protocol.h @@ -1,10 +1,12 @@ -// lock protocol - #ifndef lock_protocol_h #define lock_protocol_h #include "rpc.h" +/** + * Common types for RPCs between lock_client (or lock_client_cache) + * and lock_server + */ class lock_protocol { public: enum xxstatus { OK, RETRY, RPCERR, NOENT, IOERR }; @@ -18,6 +20,9 @@ class lock_protocol { }; }; +/** + * Common types for RPCs between lock_server and lock_client_cache + */ class rlock_protocol { public: enum xxstatus { OK, RPCERR }; diff --git a/lock_server.cc b/lock_server.cc index ec1b93c..f7e9eb2 100644 --- a/lock_server.cc +++ b/lock_server.cc @@ -1,28 +1,21 @@ -// the lock server implementation - #include "lock_server.h" #include #include #include #include -lock_server::lock_server(): - nacquire (0) -{ -} +lock_server::lock_server(): nacquire (0) { } -lock_protocol::status -lock_server::stat(int clt, lock_protocol::lockid_t lid, int &r) -{ +lock_protocol::status lock_server::stat(int clt, lock_protocol::lockid_t lid, + int &r) { lock_protocol::status ret = lock_protocol::OK; printf("stat request from clt %d\n", clt); r = nacquire; return ret; } -lock_protocol::status -lock_server::acquire(int clt, lock_protocol::lockid_t lid, int &r) -{ +lock_protocol::status lock_server::acquire(int clt, lock_protocol::lockid_t lid, + int &r) { pthread_mutex_lock(&mutex); lock_protocol::status ret = lock_protocol::OK; printf("acquire request from clt %d\n", clt); @@ -42,15 +35,14 @@ lock_server::acquire(int clt, lock_protocol::lockid_t lid, int &r) return ret; } -lock_protocol::status -lock_server::release(int clt, lock_protocol::lockid_t lid, int &r) -{ +lock_protocol::status lock_server::release(int clt, lock_protocol::lockid_t lid, + int &r) { pthread_mutex_lock(&mutex); lock_protocol::status ret = lock_protocol::OK; printf("release request from clt %d\n", clt); if (locks.find(lid) == locks.end()) { - assert(false); + VERIFY(false); } else { lock_info &li = locks[lid]; assert(li.is_locked); diff --git a/lock_server.h b/lock_server.h index d04fd53..3a3d309 100644 --- a/lock_server.h +++ b/lock_server.h @@ -1,6 +1,3 @@ -// this is the lock server -// the lock client has a similar interface - #ifndef lock_server_h #define lock_server_h @@ -12,6 +9,11 @@ #include #include +/** + * A simple lock server (Lab 1) + * https://pdos.csail.mit.edu/archive/6.824-2012/labs/lab-1.html + * To be used within an RPC server + */ class lock_server { protected: @@ -33,7 +35,7 @@ class lock_server { pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - public: +public: lock_server(); ~lock_server() {}; lock_protocol::status stat(int clt, lock_protocol::lockid_t lid, int &); diff --git a/lock_server_cache.cc b/lock_server_cache.cc index a3fa8a8..fbff228 100644 --- a/lock_server_cache.cc +++ b/lock_server_cache.cc @@ -1,5 +1,3 @@ -// the caching lock server implementation - #include "lock_server_cache.h" #include #include @@ -11,28 +9,24 @@ #include "jsl_log.h" #include "rpc.h" -lock_server_cache::lock_server_cache() -{ -} +lock_server_cache::lock_server_cache() { } -int lock_server_cache::acquire(lock_protocol::lockid_t lid, std::string id, int &) -{ +int lock_server_cache::acquire(lock_protocol::lockid_t lid, std::string id, + int &) { jsl_log(JSL_DBG_ME, "%llu acquire from %s\n", lid, id.c_str()); bool revok = false; std::string client_to_be_revoked = ""; { ScopedLock ml(&mutex); - lock_info &li = locks[lid]; - if (!li.is_locked) { - // easy case, lock is not held + // easy case, lock is not held li.is_locked = true; li.id = id; jsl_log(JSL_DBG_ME, "%llu lock granted immediately to %s\n", lid, id.c_str()); return lock_protocol :: OK; } - // a client shouldn't ask twice for the lock + // a client shouldn't ask twice for the lock VERIFY(li.waiting.find(id) == li.waiting.end()); // If this is the first time a client ask for this lock when it's held @@ -49,7 +43,7 @@ int lock_server_cache::acquire(lock_protocol::lockid_t lid, std::string id, int // TODO: we don't consider the case where a client terminates if (revok) { jsl_log(JSL_DBG_ME, "%llu couldn't grant lock to %s, revoke current owner %s\n", - lid, id.c_str(), client_to_be_revoked.c_str()); + lid, id.c_str(), client_to_be_revoked.c_str()); revoke(client_to_be_revoked, lid); } else { jsl_log(JSL_DBG_ME, "%llu revoked already sent to current owner %s\n", lid, @@ -59,35 +53,31 @@ int lock_server_cache::acquire(lock_protocol::lockid_t lid, std::string id, int } void lock_server_cache :: revoke(const std::string &client_to_be_revoked, - const lock_protocol::lockid_t &lid) - { - jsl_log(JSL_DBG_ME, "%llu client.revoke() %s\n", lid, client_to_be_revoked.c_str()); - sockaddr_in dstsock; - make_sockaddr(client_to_be_revoked.c_str(), &dstsock); - rpcc cl(dstsock); - VERIFY (cl.bind() >= 0); - int r; - VERIFY(cl.call(rlock_protocol::revoke, lid, r) == rlock_protocol::OK); - jsl_log(JSL_DBG_ME, "%llu client.revoke() - OK %s\n", lid, client_to_be_revoked.c_str()); - return; + const lock_protocol::lockid_t &lid) { + jsl_log(JSL_DBG_ME, "%llu client.revoke() %s\n", lid, client_to_be_revoked.c_str()); + sockaddr_in dstsock; + make_sockaddr(client_to_be_revoked.c_str(), &dstsock); + rpcc cl(dstsock); + VERIFY (cl.bind() >= 0); + int r; + VERIFY(cl.call(rlock_protocol::revoke, lid, r) == rlock_protocol::OK); + jsl_log(JSL_DBG_ME, "%llu client.revoke() - OK %s\n", lid, client_to_be_revoked.c_str()); + return; } void lock_server_cache :: retry(const std::string &client_to_be_retried, - const lock_protocol::lockid_t &lid) - { - jsl_log(JSL_DBG_ME, "%llu client.retry() %s\n", lid, client_to_be_retried.c_str()); - sockaddr_in dstsock; - make_sockaddr(client_to_be_retried.c_str(), &dstsock); - rpcc cl(dstsock); - VERIFY (cl.bind() >= 0); - int r; - VERIFY(cl.call(rlock_protocol::retry, lid, r) == rlock_protocol::OK); - jsl_log(JSL_DBG_ME, "%llu client.retry() - OK %s\n", lid, client_to_be_retried.c_str()); + const lock_protocol::lockid_t &lid) { + jsl_log(JSL_DBG_ME, "%llu client.retry() %s\n", lid, client_to_be_retried.c_str()); + sockaddr_in dstsock; + make_sockaddr(client_to_be_retried.c_str(), &dstsock); + rpcc cl(dstsock); + VERIFY (cl.bind() >= 0); + int r; + VERIFY(cl.call(rlock_protocol::retry, lid, r) == rlock_protocol::OK); + jsl_log(JSL_DBG_ME, "%llu client.retry() - OK %s\n", lid, client_to_be_retried.c_str()); } -int -lock_server_cache::release(lock_protocol::lockid_t lid, std::string id, int &r) -{ +int lock_server_cache::release(lock_protocol::lockid_t lid, std::string id, int &r) { bool need_retry = false; bool need_revoke = false; std::string new_owner; @@ -120,10 +110,8 @@ lock_server_cache::release(lock_protocol::lockid_t lid, std::string id, int &r) return lock_protocol::OK; } -lock_protocol::status -lock_server_cache::stat(lock_protocol::lockid_t lid, int &r) -{ - r = nacquire; - return lock_protocol::OK; +lock_protocol::status lock_server_cache::stat(lock_protocol::lockid_t lid, + int &r) { + r = nacquire; + return lock_protocol::OK; } - diff --git a/yfs_client.cc b/yfs_client.cc index a3f775d..495d64a 100644 --- a/yfs_client.cc +++ b/yfs_client.cc @@ -1,4 +1,3 @@ -// yfs client. implements FS operations using extent and lock server #include "yfs_client.h" #include "extent_client_cache.h" #include "lock_client_cache.h" @@ -34,10 +33,10 @@ yfs_client::yfs_client(std::string extent_dst, std::string lock_dst) { lock_release_user *lru = new my_lock_release_user(ec); lc = new lock_client_cache(lock_dst, lru); srand (time(NULL)); // TODO déjà fait dans fuse ?? - } -yfs_client::status yfs_client::create(inum parent, const char *name, inum &file_inum) { +yfs_client::status yfs_client::create(inum parent, const char *name, + inum &file_inum) { jsl_log(JSL_DBG_ME, "yfs_client_create %s\n", name); extent_protocol::status st1, st2; @@ -71,7 +70,8 @@ yfs_client::status yfs_client::create(inum parent, const char *name, inum &file_ return OK; } -yfs_client::status yfs_client::mkdir(inum parent, const char *name, inum &dir_inum) { +yfs_client::status yfs_client::mkdir(inum parent, const char *name, + inum &dir_inum) { jsl_log(JSL_DBG_ME, "yfs_client_mkdir %s\n", name); std::vector content; extent_protocol::status st1, st2; @@ -101,16 +101,16 @@ yfs_client::status yfs_client::mkdir(inum parent, const char *name, inum &dir_in // TODO utiliser lookup plutot que de refaire la recherche dans le dir à chaque fois yfs_client::status yfs_client::unlink(inum parent, const char *name) { - jsl_log(JSL_DBG_ME, "yfs_client_unlink %s\n", name); - std::vector content; - extent_protocol::status st1; - st1 = read_dir(parent, content); - if (st1 != extent_protocol::OK) { + jsl_log(JSL_DBG_ME, "yfs_client_unlink %s\n", name); + std::vector content; + extent_protocol::status st1; + st1 = read_dir(parent, content); + if (st1 != extent_protocol::OK) { return IOERR; - } + } - auto it = std::find_if(content.begin(), content.end(), [name] (dirent &s) { return s.name == name; } ); - if (it == content.end()) { + auto it = std::find_if(content.begin(), content.end(), [name] (dirent &s) { return s.name == name; } ); + if (it == content.end()) { jsl_log(JSL_DBG_ME, "yfs_client_unlink file doesn't exists\n"); return NOENT; } @@ -118,17 +118,18 @@ yfs_client::status yfs_client::unlink(inum parent, const char *name) { st1 = ec->remove(it->inum); if (st1 != extent_protocol::OK) { return IOERR; - } - content.erase(it); - std::string new_dir = serialize_dir(content); - st1 = ec->put(parent, new_dir); - if (st1 != extent_protocol::OK) { - return IOERR; - } - return OK; + } + content.erase(it); + std::string new_dir = serialize_dir(content); + st1 = ec->put(parent, new_dir); + if (st1 != extent_protocol::OK) { + return IOERR; + } + return OK; } -yfs_client::status yfs_client::lookup(inum parent, const char *name, inum &file_inum) { +yfs_client::status yfs_client::lookup(inum parent, const char *name, + inum &file_inum) { jsl_log(JSL_DBG_ME, "yfs_client_lookup %s\n", name); std::vector content; extent_protocol::status st1; @@ -148,18 +149,20 @@ yfs_client::status yfs_client::lookup(inum parent, const char *name, inum &file_ } yfs_client::status yfs_client::read_dir(inum parent, std::vector &v) { - jsl_log(JSL_DBG_ME, "yfs_client_read_dir %016llx\n", parent); - VERIFY(isdir(parent)); - std::string buf; - extent_protocol::status st = ec->get(parent, buf); - if (st != extent_protocol::OK) { - return IOERR; - } - deserialize_dir(buf, v); - return OK; + jsl_log(JSL_DBG_ME, "yfs_client_read_dir %016llx\n", parent); + VERIFY(isdir(parent)); + std::string buf; + extent_protocol::status st = ec->get(parent, buf); + if (st != extent_protocol::OK) { + return IOERR; + } + jsl_log(JSL_DBG_ME, "yfs_client_read_dir %016llx buf = %s \n", parent, buf.c_str()); + deserialize_dir(buf, v); + return OK; } -yfs_client::status yfs_client::read(inum num, size_t size, off_t off, std::string &buf) { +yfs_client::status yfs_client::read(inum num, size_t size, off_t off, + std::string &buf) { jsl_log(JSL_DBG_ME, "yfs_client_read %016llx size %lu off %lu\n", num, size, off); std::string extent; extent_protocol::status st = ec->get(num, extent); @@ -176,7 +179,8 @@ yfs_client::status yfs_client::read(inum num, size_t size, off_t off, std::strin return OK; } -yfs_client::status yfs_client::write(inum num, size_t size, off_t off, const char *buf) { +yfs_client::status yfs_client::write(inum num, size_t size, off_t off, + const char *buf) { jsl_log(JSL_DBG_ME, "yfs_client_write %016llx\n", num); std::string extent; if (size == 0) { @@ -270,18 +274,11 @@ yfs_client::getdir(inum inum, dirinfo &din) ///// Local methods, don't access the server, stateless - -bool -yfs_client::isfile(inum inum) -{ - if(inum & 0x80000000) - return true; - return false; +bool yfs_client::isfile(inum inum) { + return (inum & 0x80000000); } -bool -yfs_client::isdir(inum inum) -{ +bool yfs_client::isdir(inum inum) { return ! isfile(inum); } @@ -300,36 +297,30 @@ std::string yfs_client::serialize_dir(std::vector dir) { return res; } -void yfs_client::deserialize_dir(std::string s, std::vector &r){ - std::stringstream ss(s); - std::string item1, item2; - while (std::getline(ss, item1, '/')) { +void yfs_client::deserialize_dir(std::string s, std::vector &r) { + std::stringstream ss(s); + std::string item1, item2; + while (std::getline(ss, item1, '/')) { VERIFY(std::getline(ss, item2, '/')); r.push_back(dirent(item1, n2i(item2))); } } -yfs_client::inum -yfs_client::fresh_inum(bool is_dir) -{ +yfs_client::inum yfs_client::fresh_inum(bool is_dir) { unsigned long int r = rand(); if (!is_dir) { r |= 0x80000000; } return (inum) r; } -yfs_client::inum -yfs_client::n2i(std::string n) -{ +yfs_client::inum yfs_client::n2i(std::string n) { std::istringstream ist(n); unsigned long long finum; ist >> finum; return finum; } -std::string -yfs_client::filename(inum inum) -{ +std::string yfs_client::filename(inum inum) { std::ostringstream ost; ost << inum; return ost.str(); -} \ No newline at end of file +} diff --git a/yfs_client.h b/yfs_client.h index a2a7f42..89b429f 100644 --- a/yfs_client.h +++ b/yfs_client.h @@ -8,11 +8,16 @@ #include "lock_client_cache.h" #include "jsl_log.h" +/** + * This class provides the interface from the fuse module to yfs. + * It encapsulates the lock client cache client and the extent cache client + * We assume that RPC always succeed, all extent server must be locked through + * the lock server. + * When lock is revoked, cached extent are written back before releasing the + * lock + */ class yfs_client { - extent_client_cache *ec; - lock_client *lc = NULL; - public: typedef unsigned long long inum; @@ -38,46 +43,24 @@ class yfs_client { dirent(std::string name, yfs_client::inum inum) : name(name), inum(inum) {} }; + yfs_client(std::string, std::string); + void acquireLock(inum i); void releaseLock(inum i); -private: - - class my_lock_release_user : public lock_release_user { - private: - extent_client_cache *ec; - public: - my_lock_release_user(extent_client_cache *ec) : ec(ec) {}; - virtual void dorelease(lock_protocol::lockid_t id) { - jsl_log(JSL_DBG_ME, "yfs_client do release %llu\n", id); - ec->flush(id); - jsl_log(JSL_DBG_ME, "yfs_client do release done\n"); - } - }; - - static std::string filename(inum); - static inum n2i(std::string); - static std::string serialize_dir(std::vector); - static void deserialize_dir(std::string, std::vector &); - static inum fresh_inum(bool is_dir); - -public: - - yfs_client(std::string, std::string); - bool isfile(inum); + bool isdir(inum); status getfile(inum, fileinfo &); + status getdir(inum, dirinfo &); // TODO supprimer les VERIFY qui feront planter le programme et utiliser // les codes de retour dédiés (cf. get attr dans fuse.cc) - // TODO mettre ces méthodes dans FUSE.cc ? // precondition: parent is a dir - // -1 if name already exists status create(inum parent, const char *name, inum &file_inum); // precondition: parent is a dir @@ -97,6 +80,29 @@ class yfs_client { status unlink(inum parent, const char *name); status resize(inum num, size_t size); + +private: + + extent_client_cache *ec; + lock_client *lc = NULL; + + class my_lock_release_user : public lock_release_user { + private: + extent_client_cache *ec; + public: + my_lock_release_user(extent_client_cache *ec) : ec(ec) {}; + virtual void dorelease(lock_protocol::lockid_t id) { + jsl_log(JSL_DBG_ME, "yfs_client do release %llu\n", id); + ec->flush(id); + jsl_log(JSL_DBG_ME, "yfs_client do release done\n"); + } + }; + + static std::string filename(inum); + static inum n2i(std::string); + static std::string serialize_dir(std::vector); + static void deserialize_dir(std::string, std::vector &); + static inum fresh_inum(bool is_dir); }; #endif