From bef33e1bc021bed5f0822bcd8c39a502805ff2ec Mon Sep 17 00:00:00 2001 From: anwleung Date: Sat, 17 Mar 2007 19:24:12 +0000 Subject: [PATCH] fixed a deadlock problem, may come back to bite me git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@1259 29311d96-e01e-0410-9327-a35deaab8ce9 --- .../aleung/security1/ceph/crypto/ExtCap.h | 1 + branches/aleung/security1/ceph/mds/CInode.cc | 31 ++++++++++---- branches/aleung/security1/ceph/mds/CInode.h | 2 + branches/aleung/security1/ceph/mds/Server.cc | 40 ++++++++++++++----- 4 files changed, 56 insertions(+), 18 deletions(-) diff --git a/branches/aleung/security1/ceph/crypto/ExtCap.h b/branches/aleung/security1/ceph/crypto/ExtCap.h index c379c90762545..d4efd93f4d710 100644 --- a/branches/aleung/security1/ceph/crypto/ExtCap.h +++ b/branches/aleung/security1/ceph/crypto/ExtCap.h @@ -28,6 +28,7 @@ using namespace CryptoLib; #define NO_GROUP 0 #define UNIX_GROUP 1 +#define BATCH 2 struct cap_id_t { int cid; diff --git a/branches/aleung/security1/ceph/mds/CInode.cc b/branches/aleung/security1/ceph/mds/CInode.cc index a1e462b0a6adf..a0d048729bc46 100644 --- a/branches/aleung/security1/ceph/mds/CInode.cc +++ b/branches/aleung/security1/ceph/mds/CInode.cc @@ -96,10 +96,13 @@ CInode::CInode(MDCache *c, bool auth) { group_cap_set = false; world_cap_set = false; + thread_init = false; batching = false; buffer_stop = false; buffer_thread = BufferThread(this); + cout << "Starting buffer_thread.create()" << endl; buffer_thread.create(); + cout << "Buffer_thread created!" << endl; auth_pins = 0; nested_auth_pins = 0; @@ -120,20 +123,30 @@ CInode::~CInode() { } void CInode::buffer_entry() { - cout << "buffer start" << endl; + cout << "buffer thread start------> for " << inode.ino << endl; buffer_lock.Lock(); + + // init myself and signal anyone waiting for me to init + thread_init = true; + buffer_cond.Signal(); + while(!buffer_stop) { + // ifwe're not buffering, then, // were gonna get signaled when we start buffering - cout << "Buffer waiting" << endl; - buffer_cond.Wait(buffer_lock); - cout << "Buffer signaled" << endl; + // plus i need to release the lock for anyone + // waiting for me to init + cout << "Buffer thread waiting on cond" << endl; + if (!batching) + buffer_cond.Wait(buffer_lock); + cout << "Buffer thread signaled" << endl; // the sleep releases the lock and allows the dispatch // to insert requests into the buffer // sleep first, then serve cap - cout << "buffer sleeping to buffer" << endl; + cout << "buffer thread sleeping to buffer" << endl; buffer_cond.WaitInterval(buffer_lock, utime_t(5,0)); + cout << "buffer thread awoke from interval sleep" << endl; /* // now i've slept, make cap for users @@ -166,10 +179,14 @@ void CInode::buffer_entry() cout << "ABOUT TO PASS OFF THE REQUEST" << endl; //open_fun_ptr(*ri, this); server->handle_client_open(*ri, this); - } + } + + //turn batching off + batching = false; } + cout << "Buffer thread about to unlock" << endl; buffer_lock.Unlock(); - cout << "buffer finish" << endl; + cout << "<------buffer finish" << endl; } diff --git a/branches/aleung/security1/ceph/mds/CInode.h b/branches/aleung/security1/ceph/mds/CInode.h index bfa5f86135bd4..baf3728faf248 100644 --- a/branches/aleung/security1/ceph/mds/CInode.h +++ b/branches/aleung/security1/ceph/mds/CInode.h @@ -178,12 +178,14 @@ class CInode : public MDSCacheObject { // batching information bool batching; + utime_t two_req_ago; utime_t one_req_ago; set buffered_reqs; bool batch_id_set; cap_id_t batch_id; + bool thread_init; Mutex buffer_lock; Cond buffer_cond; bool buffer_stop; diff --git a/branches/aleung/security1/ceph/mds/Server.cc b/branches/aleung/security1/ceph/mds/Server.cc index acc2453f7ea94..1ab1e8d563883 100644 --- a/branches/aleung/security1/ceph/mds/Server.cc +++ b/branches/aleung/security1/ceph/mds/Server.cc @@ -1296,10 +1296,12 @@ int Server::prepare_mknod(MClientRequest *req, CInode *diri, // create inode + cout << "creating inode....should i maybe be creating the thread here?" << endl; *pin = mdcache->create_inode(); (*pin)->inode.uid = req->get_caller_uid(); (*pin)->inode.gid = req->get_caller_gid(); (*pin)->inode.ctime = (*pin)->inode.mtime = (*pin)->inode.atime = g_clock.gettime(); // now + cout << "Done setting up inode" << endl; // note: inode.version will get set by finisher's mark_dirty. // create dentry @@ -2435,6 +2437,9 @@ void Server::handle_client_openc(MClientRequest *req, CInode *diri) assert(dn); if (r == 1) { + cout << "openc for " << req->get_filepath() << " from uid:" << + req->get_caller_uid() << " on client:" << req->get_client() << + " with client inst " << req->get_client_inst() << endl; // created. // it's a file. in->inode.mode = 0644; // FIXME req should have a umask @@ -2465,43 +2470,56 @@ void Server::handle_client_openc(MClientRequest *req, CInode *diri) << " against " << utime_t(1, 0) << endl; //if (open_req_time - in->two_req_ago < utime_t(1, 0)) { if (open_req_time > utime_t()) { - cout << "Buffering the request" << endl; + cout << "Buffering the request for uid:" << + req->get_caller_uid() << " on client:" << + req->get_client() << " for file:" << + in->ino() << " with client inst:" << req->get_client_inst() << endl; in->two_req_ago = in->one_req_ago; in->one_req_ago = open_req_time; + cout << "HCO: Grabbing lock" << endl; + in->buffer_lock.Lock(); + cout << "HCO: Grabbed lock" << endl; + + // wait for thread if it hasn't init'd + if (! in->thread_init) + in->buffer_cond.Wait(in->buffer_lock); + // if buffer waiting thread is off, turn it on if (!in->batching) { + cout << "HCO: Batching is now turned on" << endl; // grab lock and insert - in->buffer_lock.Lock(); in->buffered_reqs.insert(req); + cout << "HCO: Inserted request" << endl; // prepare capid for future capability in->batch_id.cid = mds->cap_id_count; in->batch_id.mds_id = mds->get_nodeid(); mds->cap_id_count++; // turn on batching flags + cout << "HCO: Turning batching on" << endl; in->batching = true; in->batch_id_set = true; - in->buffer_stop = false; + //in->buffer_stop = false; - // set function pointer to open handler - //in->open_fun_ptr = (void (*)(MClientRequest*, CInode*))&handle_client_open; + // set server exit point in->server = this; - + //singal the thread cout << "Going to singal" << endl; in->buffer_cond.Signal(); cout << "Done signaling" << endl; - // release the lock - in->buffer_lock.Unlock(); } else { - // grab lock and insert - in->buffer_lock.Lock(); + cout << "HCO: Inserting into buffer" << endl; in->buffered_reqs.insert(req); - in->buffer_lock.Unlock(); } + + // release the lock + cout << "HCO: releasing lock" << endl; + in->buffer_lock.Unlock(); + cout << "HCO: released lock" << endl; return; } else { -- 2.39.5