]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: put accounted_nested in fnode. clean up locker interface a bit.
authorSage Weil <sage@newdream.net>
Fri, 23 May 2008 18:31:21 +0000 (11:31 -0700)
committerSage Weil <sage@newdream.net>
Fri, 23 May 2008 18:31:21 +0000 (11:31 -0700)
src/include/types.h
src/mds/FileLock.h
src/mds/Locker.cc
src/mds/Locker.h
src/mds/MDCache.h
src/mds/Server.cc

index d3c8121f50611e62db51ee4277d88931f0638143..d4c6705e5837dd4997517648ca88dd4750fe7b7b 100644 (file)
@@ -302,11 +302,13 @@ static inline void decode(inode_t &i, bufferlist::iterator &p) {
  */
 struct fnode_t {
   version_t version;
+  utime_t mtime;
   __u64 size;            // files + dirs
   __u64 nprimary, nremote;
   __u64 nfiles;          // files
   __u64 nsubdirs;        // subdirs
   nested_info_t nested;  // nested summation
+  nested_info_t accounted_nested;  // nested summation
 
   void encode(bufferlist &bl) const {
     ::encode(version, bl);
@@ -316,6 +318,7 @@ struct fnode_t {
     ::encode(nfiles, bl);
     ::encode(nsubdirs, bl);
     ::encode(nested, bl);
+    ::encode(accounted_nested, bl);
   }
   void decode(bufferlist::iterator &bl) {
     ::decode(version, bl);
@@ -325,6 +328,7 @@ struct fnode_t {
     ::decode(nfiles, bl);
     ::decode(nsubdirs, bl);
     ::decode(nested, bl);
+    ::decode(accounted_nested, bl);
   }
 };
 WRITE_CLASS_ENCODER(fnode_t)
index ad0d7570eddc0635a26ea45f788d22af31679b42..5454f5cddc1864ab108d8e9ebffe374945950821 100644 (file)
@@ -169,8 +169,8 @@ class FileLock : public SimpleLock {
       state == LOCK_LONER || state == LOCK_GLONERM ||
       state == LOCK_GSYNCM || state == LOCK_GSYNCL;
   }
-  void get_wrlock() {
-    assert(can_wrlock());
+  void get_wrlock(bool force) {
+    assert(force || can_wrlock());
     if (num_wrlock == 0) parent->get(MDSCacheObject::PIN_LOCK);
     ++num_wrlock;
   }
index 1a426cbaad2b917067f4a8e60c46904bec619b38..c8922f02f6025a52f0774fbccd73120eda5a4bf0 100644 (file)
@@ -848,13 +848,13 @@ bool Locker::check_inode_max_size(CInode *in, bool forcewrlock)
   pi->version = in->pre_dirty();
   pi->max_size = new_max;
   EOpen *le = new EOpen(mds->mdlog);
-  predirty_nested(mut, &le->metablob, in);
+  predirty_nested(mut, &le->metablob, in, false);
   le->metablob.add_dir_context(in->get_parent_dir());
   le->metablob.add_primary_dentry(in->parent, true, 0, pi);
   le->add_ino(in->ino());
   mut->ls->open_files.push_back(&in->xlist_open_file);
   mds->mdlog->submit_entry(le, new C_Locker_FileUpdate_finish(this, in, mut, true));
-  file_wrlock_start(&in->filelock, mut, forcewrlock);  // wrlock for duration of journal
+  file_wrlock_force(&in->filelock, mut);  // wrlock for duration of journal
   return true;
 }
 
@@ -1044,8 +1044,8 @@ void Locker::handle_client_file_caps(MClientFileCaps *m)
     }
     Mutation *mut = new Mutation;
     mut->ls = mds->mdlog->get_current_segment();
-    file_wrlock_start(&in->filelock, mut);  // wrlock for duration of journal
-    predirty_nested(mut, &le->metablob, in);    
+    file_wrlock_force(&in->filelock, mut);  // wrlock for duration of journal
+    predirty_nested(mut, &le->metablob, in, false);
     le->metablob.add_dir_context(in->get_parent_dir());
     le->metablob.add_primary_dentry(in->parent, true, 0, pi);
     mds->mdlog->submit_entry(le, new C_Locker_FileUpdate_finish(this, in, mut, change_max));
@@ -1218,7 +1218,7 @@ void Locker::revoke_client_leases(SimpleLock *lock)
 
 // nested ---------------------------------------------------------------
 
-void Locker::predirty_nested(Mutation *mut, EMetaBlob *blob, CInode *in)
+void Locker::predirty_nested(Mutation *mut, EMetaBlob *blob, CInode *in, bool parent_mtime)
 {
   CDir *parent = in->get_projected_parent_dn()->get_dir();
 
@@ -1264,6 +1264,10 @@ void Locker::predirty_nested(Mutation *mut, EMetaBlob *blob, CInode *in)
 
     fnode_t *pf = parent->project_fnode();
     pf->version = parent->pre_dirty();
+    if (parent_mtime) {
+      dout(10) << "predirty_nested updating mtime on " << *parent << dendl;
+      pf->mtime = rctime = mut->now;
+    }
     pf->nested.rbytes += drbytes;
     pf->nested.rfiles += drfiles;
     pf->nested.rctime = rctime;
@@ -1272,11 +1276,8 @@ void Locker::predirty_nested(Mutation *mut, EMetaBlob *blob, CInode *in)
     curi->accounted_nested.rfiles += drfiles;
     curi->accounted_nested.rctime = rctime;
 
-    // FIXME
-    if (!pin->is_auth()) {
-      assert(0);
+    if (!pin->is_auth())
       break;
-    }
 
     // dirfrag -> diri
     mut->add_projected_inode(pin);
@@ -1285,10 +1286,17 @@ void Locker::predirty_nested(Mutation *mut, EMetaBlob *blob, CInode *in)
     version_t ppv = pin->pre_dirty();
     inode_t *pi = pin->project_inode();
     pi->version = ppv;
+    if (pf->mtime > pi->mtime)
+      pi->mtime = pf->mtime;
     pi->nested.rbytes += drbytes;
     pi->nested.rfiles += drfiles;
     pi->nested.rctime = rctime;
 
+    pf->accounted_nested.rbytes += drbytes;
+    pf->accounted_nested.rfiles += drfiles;
+    pf->accounted_nested.rctime = rctime;
+    
+    // next parent!
     cur = pin;
     curi = pi;
     parent = cur->get_projected_parent_dn()->get_dir();
@@ -1299,13 +1307,16 @@ void Locker::predirty_nested(Mutation *mut, EMetaBlob *blob, CInode *in)
   }
 
   // now, stick it in the blob
+  assert(parent->is_auth());
   blob->add_dir_context(parent);
+  blob->add_dir(parent, true);
+
   for (list<CInode*>::iterator p = lsi.begin();
        p != lsi.end();
        p++) {
     CInode *cur = *p;
     inode_t *pi = cur->get_projected_inode();
-    blob->add_primary_dentry(cur->get_parent_dn(), true, 0, pi);
+    blob->add_primary_dentry(cur->get_projected_parent_dn(), true, 0, pi);
   }
 }
 
@@ -1877,7 +1888,7 @@ bool Locker::scatter_rdlock_start(ScatterLock *lock, MDRequest *mut)
   return false;
 }
 
-void Locker::scatter_rdlock_finish(ScatterLock *lock, MDRequest *mut)
+void Locker::scatter_rdlock_finish(ScatterLock *lock, Mutation *mut)
 {
   dout(7) << "scatter_rdlock_finish  on " << *lock
          << " on " << *lock->get_parent() << dendl;  
@@ -2592,7 +2603,7 @@ bool Locker::local_wrlock_start(LocalLock *lock, MDRequest *mut)
   }
 }
 
-void Locker::local_wrlock_finish(LocalLock *lock, MDRequest *mut)
+void Locker::local_wrlock_finish(LocalLock *lock, Mutation *mut)
 {
   dout(7) << "local_wrlock_finish  on " << *lock
          << " on " << *lock->get_parent() << dendl;  
@@ -2617,7 +2628,7 @@ bool Locker::local_xlock_start(LocalLock *lock, MDRequest *mut)
   return true;
 }
 
-void Locker::local_xlock_finish(LocalLock *lock, MDRequest *mut)
+void Locker::local_xlock_finish(LocalLock *lock, Mutation *mut)
 {
   dout(7) << "local_xlock_finish  on " << *lock
          << " on " << *lock->get_parent() << dendl;  
@@ -2704,7 +2715,7 @@ bool Locker::file_rdlock_start(FileLock *lock, MDRequest *mut)
 
 
 
-void Locker::file_rdlock_finish(FileLock *lock, MDRequest *mut)
+void Locker::file_rdlock_finish(FileLock *lock, Mutation *mut)
 {
   dout(7) << "rdlock_finish on " << *lock << " on " << *lock->get_parent() << dendl;
 
@@ -2721,12 +2732,11 @@ void Locker::file_rdlock_finish(FileLock *lock, MDRequest *mut)
   }
 }
 
-bool Locker::file_wrlock_start(FileLock *lock, MDRequest *mut, bool force)
+bool Locker::file_wrlock_force(FileLock *lock, Mutation *mut)
 {
-  dout(7) << "file_wrlock_start  on " << *lock
+  dout(7) << "file_wrlock_force  on " << *lock
          << " on " << *lock->get_parent() << dendl;  
-  assert(force || lock->can_wrlock());
-  lock->get_wrlock();
+  lock->get_wrlock(true);
   mut->wrlocks.insert(lock);
   mut->locks.insert(lock);
   return true;
@@ -2800,7 +2810,7 @@ bool Locker::file_xlock_start(FileLock *lock, MDRequest *mut)
 }
 
 
-void Locker::file_xlock_finish(FileLock *lock, MDRequest *mut)
+void Locker::file_xlock_finish(FileLock *lock, Mutation *mut)
 {
   dout(7) << "file_xlock_finish on " << *lock << " on " << *lock->get_parent() << dendl;
 
index 666e030127cbafaad694cd9c77f0dcb628d5933a..666e9ed7badcfac2b3c3a986847765db5cd75693 100644 (file)
@@ -156,7 +156,7 @@ protected:
   void scatter_writebehind_finish(ScatterLock *lock, LogSegment *ls);
 
 public:
-  void predirty_nested(Mutation *mut, EMetaBlob *blob, CInode *in);
+  void predirty_nested(Mutation *mut, EMetaBlob *blob, CInode *in, bool parent_mtime);
 
   // local
 protected:
@@ -180,8 +180,8 @@ protected:
   bool file_rdlock_try(FileLock *lock, Context *con);
   bool file_rdlock_start(FileLock *lock, MDRequest *mut);
   void file_rdlock_finish(FileLock *lock, Mutation *mut);
-  bool file_wrlock_start(FileLock *lock, MDRequest *mut, bool force=false);
-  void file_wrlock_finish(FileLock *lock);
+  bool file_wrlock_force(FileLock *lock, Mutation *mut);
+  void file_wrlock_finish(FileLock *lock, Mutation *mut);
   bool file_xlock_start(FileLock *lock, MDRequest *mut);
   void file_xlock_finish(FileLock *lock, Mutation *mut);
 
index a7a3b692c589a1787eeef41039c3825383848e52..b797e1b1715f3ca9baed9a36b57e5078273c07f5 100644 (file)
@@ -75,6 +75,7 @@ struct PVList {
 };
 
 struct Mutation {
+  metareqid_t reqid;
   LogSegment *ls;  // the log segment i'm committing to
   utime_t now;
 
@@ -104,8 +105,11 @@ struct Mutation {
   list<CDir*> projected_fnodes;
 
   Mutation() : ls(0),
-              done_locking(false), committing(false), aborted(false)
-  {}
+              done_locking(false), committing(false), aborted(false) {}
+  Mutation(metareqid_t ri) : reqid(ri),
+                            ls(0),
+                            done_locking(false), committing(false), aborted(false) {}
+  virtual ~Mutation() {}
 
   // pin items in cache
   void pin(MDSCacheObject *o) {
@@ -168,6 +172,11 @@ struct Mutation {
     }
   }
 
+  void apply() {
+    pop_and_dirty_projected_inodes();
+    pop_and_dirty_projected_fnodes();
+  }
+
   virtual void print(ostream &out) {
     out << "mutation(" << this << ")";
   }
@@ -186,7 +195,6 @@ inline ostream& operator<<(ostream& out, Mutation &mut)
  * the request is finished or forwarded.  see request_*().
  */
 struct MDRequest : public Mutation {
-  metareqid_t reqid;
   Session *session;
 
   // -- i am a client (master) request
@@ -238,11 +246,13 @@ struct MDRequest : public Mutation {
     slave_request(0), slave_to_mds(-1), 
     _more(0) {}
   MDRequest(metareqid_t ri, MClientRequest *req) : 
-    reqid(ri), session(0), client_request(req), ref(0), 
+    Mutation(ri),
+    session(0), client_request(req), ref(0), 
     slave_request(0), slave_to_mds(-1), 
     _more(0) {}
   MDRequest(metareqid_t ri, int by) : 
-    reqid(ri), session(0), client_request(0), ref(0),
+    Mutation(ri),
+    session(0), client_request(0), ref(0),
     slave_request(0), slave_to_mds(by), 
     _more(0) {}
   ~MDRequest() {
index f00b7665dd1b75bd7a2ddb419ac4ad7c71c30979..81aea634efc1d63c6d627ff28ed2678903e55a57 100644 (file)
@@ -1992,12 +1992,9 @@ class C_MDS_mknod_finish : public Context {
   MDRequest *mdr;
   CDentry *dn;
   CInode *newi;
-  version_t dirpv;
-  version_t newdirpv;
 public:
-  C_MDS_mknod_finish(MDS *m, MDRequest *r, CDentry *d, CInode *ni, version_t dirpv_, version_t newdirpv_=0) :
-    mds(m), mdr(r), dn(d), newi(ni),
-    dirpv(dirpv_), newdirpv(newdirpv_) {}
+  C_MDS_mknod_finish(MDS *m, MDRequest *r, CDentry *d, CInode *ni) :
+    mds(m), mdr(r), dn(d), newi(ni) {}
   void finish(int r) {
     assert(r == 0);
 
@@ -2008,16 +2005,13 @@ public:
     newi->mark_dirty(newi->inode.version + 1, mdr->ls);
 
     // mkdir?
-    if (newdirpv) { 
+    if (newi->inode.is_dir()) { 
       CDir *dir = newi->get_dirfrag(frag_t());
       assert(dir);
-      dir->mark_dirty(newdirpv, mdr->ls);
+      dir->mark_dirty(1, mdr->ls);
     }
 
-    // dir inode's mtime
-    mds->server->dirty_dn_diri(mdr, dn, dirpv);
-    mdr->pop_and_dirty_projected_inodes();
-    mdr->pop_and_dirty_projected_fnodes();
+    mdr->apply();
 
     // hit pop
     mds->balancer->hit_inode(mdr->now, newi, META_POP_IWR);
@@ -2056,13 +2050,14 @@ void Server::handle_client_mknod(MDRequest *mdr)
   EUpdate *le = new EUpdate(mdlog, "mknod");
   le->metablob.add_client_req(req->get_reqid());
   le->metablob.add_allocated_ino(newi->ino(), mds->idalloc->get_version());
-  mds->locker->predirty_nested(mdr, &le->metablob, newi);
-  version_t dirpv = predirty_dn_diri(mdr, dn, &le->metablob);  // dir mtime too
-  le->metablob.add_dir_context(dn->dir);
+
+  mds->locker->predirty_nested(mdr, &le->metablob, newi, true);
+  //version_t dirpv = predirty_dn_diri(mdr, dn, &le->metablob);  // dir mtime too
+
   le->metablob.add_primary_dentry(dn, true, newi, &newi->inode);
   
   // log + wait
-  mdlog->submit_entry(le, new C_MDS_mknod_finish(mds, mdr, dn, newi, dirpv));
+  mdlog->submit_entry(le, new C_MDS_mknod_finish(mds, mdr, dn, newi));
 }
 
 
@@ -2092,7 +2087,7 @@ void Server::handle_client_mkdir(MDRequest *mdr)
   // ...and that new dir is empty.
   CDir *newdir = newi->get_or_open_dirfrag(mds->mdcache, frag_t());
   newdir->mark_complete();
-  version_t newdirpv = newdir->pre_dirty();
+  newdir->pre_dirty();
 
   //if (mds->logger) mds->logger->inc("mkdir");
 
@@ -2101,14 +2096,12 @@ void Server::handle_client_mkdir(MDRequest *mdr)
   EUpdate *le = new EUpdate(mdlog, "mkdir");
   le->metablob.add_client_req(req->get_reqid());
   le->metablob.add_allocated_ino(newi->ino(), mds->idalloc->get_version());
-  version_t dirpv = predirty_dn_diri(mdr, dn, &le->metablob);  // dir mtime too
-  le->metablob.add_dir_context(dn->dir);
-  mds->locker->predirty_nested(mdr, &le->metablob, newi);
+  mds->locker->predirty_nested(mdr, &le->metablob, newi, true);
   le->metablob.add_primary_dentry(dn, true, newi, &newi->inode);
   le->metablob.add_dir(newdir, true, true); // dirty AND complete
   
   // log + wait
-  mdlog->submit_entry(le, new C_MDS_mknod_finish(mds, mdr, dn, newi, dirpv, newdirpv));
+  mdlog->submit_entry(le, new C_MDS_mknod_finish(mds, mdr, dn, newi));
 
   /* old export heuristic.  pbly need to reimplement this at some point.    
   if (
@@ -2154,13 +2147,11 @@ void Server::handle_client_symlink(MDRequest *mdr)
   EUpdate *le = new EUpdate(mdlog, "symlink");
   le->metablob.add_client_req(req->get_reqid());
   le->metablob.add_allocated_ino(newi->ino(), mds->idalloc->get_version());
-  version_t dirpv = predirty_dn_diri(mdr, dn, &le->metablob);  // dir mtime too
-  le->metablob.add_dir_context(dn->dir);
-  mds->locker->predirty_nested(mdr, &le->metablob, newi);
+  mds->locker->predirty_nested(mdr, &le->metablob, newi, true);
   le->metablob.add_primary_dentry(dn, true, newi, &newi->inode);
 
   // log + wait
-  mdlog->submit_entry(le, new C_MDS_mknod_finish(mds, mdr, dn, newi, dirpv));
+  mdlog->submit_entry(le, new C_MDS_mknod_finish(mds, mdr, dn, newi));
 }