From c3d7d81274525f116b20976e2d25a7e8c2ce1b78 Mon Sep 17 00:00:00 2001 From: sage Date: Wed, 1 Jun 2005 15:53:07 +0000 Subject: [PATCH] *** empty log message *** git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@251 29311d96-e01e-0410-9327-a35deaab8ce9 --- ceph/mds/AnchorTable.cc | 17 +++++ ceph/mds/AnchorTable.h | 1 + ceph/mds/CInode.cc | 9 +++ ceph/mds/MDCache.cc | 107 +++++++++++++++++++++++++++++--- ceph/mds/MDCache.h | 2 + ceph/messages/MAnchorRequest.h | 1 + ceph/messages/MInodeUnlinkAck.h | 30 +++++++++ 7 files changed, 160 insertions(+), 7 deletions(-) create mode 100644 ceph/messages/MInodeUnlinkAck.h diff --git a/ceph/mds/AnchorTable.cc b/ceph/mds/AnchorTable.cc index 2d596942080f2..ff3cf498f8b79 100644 --- a/ceph/mds/AnchorTable.cc +++ b/ceph/mds/AnchorTable.cc @@ -176,6 +176,11 @@ void AnchorTable::handle_anchor_request(class MAnchorRequest *m) lookup( m->get_ino(), reply->get_trace() ); break; + case ANCHOR_OP_UPDATE: + destroy( m->get_ino() ); + create( m->get_ino(), m->get_trace() ); + break; + case ANCHOR_OP_CREATE: create( m->get_ino(), m->get_trace() ); break; @@ -212,6 +217,7 @@ void AnchorTable::handle_anchor_reply(class MAnchorReply *m) } break; + case ANCHOR_OP_UPDATE: case ANCHOR_OP_CREATE: case ANCHOR_OP_DESTROY: { @@ -274,6 +280,17 @@ void AnchorTable::create(inodeno_t ino, vector& trace, Context *onfinis mds->messenger->send_message(req, MSG_ADDR_MDS(0), MDS_PORT_ANCHORMGR, MDS_PORT_ANCHORMGR); } +void AnchorTable::update(inodeno_t ino, vector& trace, Context *onfinish) +{ + // send message + MAnchorRequest *req = new MAnchorRequest(ANCHOR_OP_UPDATE, ino); + req->set_trace(trace); + + pending_op[ino] = onfinish; + + mds->messenger->send_message(req, MSG_ADDR_MDS(0), MDS_PORT_ANCHORMGR, MDS_PORT_ANCHORMGR); +} + void AnchorTable::destroy(inodeno_t ino, Context *onfinish) { // me? diff --git a/ceph/mds/AnchorTable.h b/ceph/mds/AnchorTable.h index 11803bd45a06b..6d025b4bd70b1 100644 --- a/ceph/mds/AnchorTable.h +++ b/ceph/mds/AnchorTable.h @@ -94,6 +94,7 @@ class AnchorTable { // user interface void lookup(inodeno_t ino, vector& trace, Context *onfinish); void create(inodeno_t ino, vector& trace, Context *onfinish); + void update(inodeno_t ino, vector& trace, Context *onfinish); void destroy(inodeno_t ino, Context *onfinish); diff --git a/ceph/mds/CInode.cc b/ceph/mds/CInode.cc index 18fd24507820c..f64d71480a262 100644 --- a/ceph/mds/CInode.cc +++ b/ceph/mds/CInode.cc @@ -166,6 +166,15 @@ void CInode::make_anchor_trace(vector& trace) parent->dir->inode->ino(), parent->name) ); } + else if (state_test(CINODE_STATE_DANGLING)) { + dout(7) << "make_anchor_trace dangling " << ino() << " on mds " << dangling_auth << endl; + string ref_dn; + trace.push_back( new Anchor(ino(), + MDS_INO_INODEFILE_OFFSET+dangling_auth, + ref_dn) ); + } + else + assert(is_root()); } diff --git a/ceph/mds/MDCache.cc b/ceph/mds/MDCache.cc index f205b71964fae..f0f7ab7f3a1b3 100644 --- a/ceph/mds/MDCache.cc +++ b/ceph/mds/MDCache.cc @@ -44,6 +44,7 @@ #include "messages/MInodeLink.h" #include "messages/MInodeLinkAck.h" #include "messages/MInodeUnlink.h" +#include "messages/MInodeUnlinkAck.h" #include "messages/MLock.h" #include "messages/MDentryUnlink.h" @@ -2226,6 +2227,23 @@ void MDCache::handle_dir_update(MDirUpdate *m) +class C_MDC_DentryUnlink : public Context { +public: + MDCache *mdc; + CDentry *dn; + CDir *dir; + Context *c; + C_MDC_DentryUnlink(MDCache *mdc, CDentry *dn, CDir *dir, Context *c) { + this->mdc = mdc; + this->dn = dn; + this->dir = dir; + this->c = c; + } + void finish(int r) { + assert(r == 0); + mdc->dentry_unlink_finish(dn, dir, c); + } +}; // NAMESPACE FUN @@ -2289,11 +2307,20 @@ void MDCache::dentry_unlink(CDentry *dn, Context *c) // dangling but still linked. assert(dn->inode->is_anchored()); + // unlink locally + CInode *in = dn->inode; + dn->dir->unlink_inode( dn ); + dn->mark_dirty(); + // mark it dirty! - dn->inode->mark_dirty(); + in->mark_dirty(); // update anchor to point to inode file+mds - assert(0); + vector atrace; + in->make_anchor_trace(atrace); + assert(atrace.size() == 1); // it's dangling + mds->anchormgr->update(in->ino(), atrace, + new C_MDC_DentryUnlink(this, dn, dir, c)); } } else if (dn->is_remote()) { @@ -2310,27 +2337,33 @@ void MDCache::dentry_unlink(CDentry *dn, Context *c) mds->messenger->send_message(new MInodeUnlink(dn->inode->ino(), mds->get_nodeid()), MSG_ADDR_MDS(auth), MDS_PORT_CACHE, MDS_PORT_CACHE); + // unlink locally + CInode *in = dn->inode; + dn->dir->unlink_inode( dn ); + dn->mark_dirty(); + // add waiter - dn->inode->add_waiter(CINODE_WAIT_UNLINK, c); + in->add_waiter(CINODE_WAIT_UNLINK, c); return; } } else assert(0); // unlink on null dentry?? + // unlink locally + dn->dir->unlink_inode( dn ); + dn->mark_dirty(); + // finish! dentry_unlink_finish(dn, dir, c); } + void MDCache::dentry_unlink_finish(CDentry *dn, CDir *dir, Context *c) { dout(7) << "dentry_unlink_finish on " << *dn << endl; string dname = dn->name; - // unlink locally - dn->dir->unlink_inode( dn ); - dn->mark_dirty(); - // unpin dir / unxlock dentry_xlock_finish(dn, true); // quiet, no need to bother replicas since they're already unlinking @@ -2387,6 +2420,66 @@ void MDCache::handle_dentry_unlink(MDentryUnlink *m) } +void MDCache::handle_inode_unlink(MInodeUnlink *m) +{ + CInode *in = get_inode(m->get_ino()); + assert(in); + + // proxy? + if (in->is_proxy()) { + dout(7) << "handle_inode_unlink proxy on " << *in << endl; + mds->messenger->send_message(m, + MSG_ADDR_MDS(in->authority()), MDS_PORT_CACHE, MDS_PORT_CACHE); + return; + } + assert(in->is_auth()); + + // do it. + dout(7) << "handle_inode_unlink nlink=" << in->inode.nlink << " on " << *in << endl; + assert(in->inode.nlink > 0); + in->inode.nlink--; + + if (in->state_test(CINODE_STATE_DANGLING)) { + // already dangling. + // last link? + if (in->inode.nlink == 0) { + dout(7) << "last link, marking clean and removing anchor" << endl; + + in->mark_clean(); // mark it clean. + + // remove anchor (async) + mds->anchormgr->destroy(in->ino(), NULL); + } + else { + in->mark_dirty(); + } + } else { + // has primary link still. + assert(in->inode.nlink >= 1); + in->mark_dirty(); + + if (in->inode.nlink == 1) { + dout(7) << "nlink=1, removing anchor" << endl; + + // remove anchor (async) + mds->anchormgr->destroy(in->ino(), NULL); + } + } + + // ack + mds->messenger->send_message(new MInodeUnlinkAck(m->get_ino()), + MSG_ADDR_MDS(m->get_from()), MDS_PORT_CACHE, MDS_PORT_CACHE); +} + +void MDCache::handle_inode_unlink_ack(MInodeUnlinkAck *m) +{ + CInode *in = get_inode(m->get_ino()); + assert(in); + + dout(7) << "handle_inode_unlink_ack on " << *in << endl; + in->finish_waiting(CINODE_WAIT_UNLINK, 0); +} + // renaming! diff --git a/ceph/mds/MDCache.h b/ceph/mds/MDCache.h index 23eb234b50a5a..b2d433a9ac6d7 100644 --- a/ceph/mds/MDCache.h +++ b/ceph/mds/MDCache.h @@ -226,6 +226,8 @@ class MDCache { void dentry_unlink(CDentry *in, Context *c); void dentry_unlink_finish(CDentry *in, CDir *dir, Context *c); void handle_dentry_unlink(MDentryUnlink *m); + void handle_inode_unlink(class MInodeUnlink *m); + void handle_inode_unlink_ack(class MInodeUnlinkAck *m); // initiator void file_rename(CDentry *srcdn, CDentry *destdn, Context *c); diff --git a/ceph/messages/MAnchorRequest.h b/ceph/messages/MAnchorRequest.h index 25138db896f00..4780f3231d109 100644 --- a/ceph/messages/MAnchorRequest.h +++ b/ceph/messages/MAnchorRequest.h @@ -9,6 +9,7 @@ #define ANCHOR_OP_CREATE 1 #define ANCHOR_OP_DESTROY 2 #define ANCHOR_OP_LOOKUP 3 +#define ANCHOR_OP_UPDATE 4 class MAnchorRequest : public Message { int op; diff --git a/ceph/messages/MInodeUnlinkAck.h b/ceph/messages/MInodeUnlinkAck.h new file mode 100644 index 0000000000000..f8bedd6958c2b --- /dev/null +++ b/ceph/messages/MInodeUnlinkAck.h @@ -0,0 +1,30 @@ +#ifndef __MINODEUNLINKACK_H +#define __MINODEUNLINKACK_H + +typedef struct { + inodeno_t ino; +} MInodeUnlinkAck_st; + +class MInodeUnlinkAck : public Message { + MInodeUnlinkAck_st st; + + public: + inodeno_t get_ino() { return st.ino; } + + MInodeUnlinkAck() {} + MInodeUnlinkAck(inodeno_t ino) : + Message(MSG_MDS_INODEUNLINKACK) { + st.ino = ino; + } + virtual char *get_type_name() { return "InUlA";} + + virtual void decode_payload(crope& s, int& off) { + s.copy(off, sizeof(st), (char*)&st); + off += sizeof(st); + } + virtual void encode_payload(crope& s) { + s.append((char*)&st,sizeof(st)); + } +}; + +#endif -- 2.39.5