]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: adjust client_ranges on setattr size
authorSage Weil <sage@newdream.net>
Mon, 20 Jul 2009 17:51:38 +0000 (10:51 -0700)
committerSage Weil <sage@newdream.net>
Mon, 20 Jul 2009 18:03:51 +0000 (11:03 -0700)
src/mds/CInode.cc
src/mds/Locker.cc
src/mds/Locker.h
src/mds/MDCache.cc
src/mds/Server.cc

index 5e062055a66344603105c768b894f96f8b0cbcd6..36a50e10218c474d292da68c4baf17aa464b4c57 100644 (file)
@@ -137,11 +137,10 @@ ostream& operator<<(ostream& out, CInode& in)
   out << " " << in.versionlock;
 
   // hack: spit out crap on which clients have caps
-  if (!in.get_client_caps().empty()) {
-
-    if (in.inode.client_ranges.size())
-      out << " cr=" << in.inode.client_ranges;
+  if (in.inode.client_ranges.size())
+    out << " cr=" << in.inode.client_ranges;
 
+  if (!in.get_client_caps().empty()) {
     out << " caps={";
     for (map<int,Capability*>::iterator it = in.get_client_caps().begin();
          it != in.get_client_caps().end();
index 14153b391618f39e2d6604279a84c9fcac2f2442..8bf2c344884ab7a2a8ee92f7593ac452f413e64e 100644 (file)
@@ -1411,17 +1411,9 @@ public:
 };
 
 
-bool Locker::check_inode_max_size(CInode *in, bool force_wrlock,
-                                 bool update_size, __u64 new_size, utime_t new_mtime)
+void Locker::calc_new_client_ranges(CInode *in, __u64 size, map<int,byte_range_t>& new_ranges)
 {
-  assert(in->is_auth());
-
   inode_t *latest = in->get_projected_inode();
-  map<int,byte_range_t> new_ranges;
-  __u64 size = latest->size;
-  if (update_size)
-    size = new_size;
-  bool new_max = false;
 
   // increase ranges as appropriate.
   // shrink to 0 if no WR|BUFFER caps issued.
@@ -1437,6 +1429,23 @@ bool Locker::check_inode_max_size(CInode *in, bool force_wrlock,
        new_ranges[p->first].last = ROUND_UP_TO((size+1)<<1, latest->get_layout_size_increment());
     }
   }
+
+}
+
+bool Locker::check_inode_max_size(CInode *in, bool force_wrlock,
+                                 bool update_size, __u64 new_size, utime_t new_mtime)
+{
+  assert(in->is_auth());
+
+  inode_t *latest = in->get_projected_inode();
+  map<int,byte_range_t> new_ranges;
+  __u64 size = latest->size;
+  if (update_size)
+    size = new_size;
+  bool new_max = false;
+
+  calc_new_client_ranges(in, size, new_ranges);
+
   if (latest->client_ranges != new_ranges)
     new_max = true;
 
index 3b9d475e23d0a4aa553232f9dadd9b4b01ba159b..5ffe4f8b92d4c7537acba276f7297dfc9534f406 100644 (file)
@@ -223,11 +223,12 @@ protected:
   void file_update_finish(CInode *in, Mutation *mut, bool share, int client, Capability *cap,
                          MClientCaps *ack);
 public:
+  void calc_new_client_ranges(CInode *in, __u64 size, map<int,byte_range_t>& new_ranges);
   bool check_inode_max_size(CInode *in, bool force_wrlock=false, bool update_size=false, __u64 newsize=0,
                            utime_t mtime=utime_t());
-private:
   void share_inode_max_size(CInode *in);
 
+private:
   friend class C_MDL_CheckMaxSize;
   friend class C_MDL_RequestInodeFileCaps;
   friend class C_Locker_FileUpdate_finish;
index b928a0addbbabaccfcf541b13d4068c45f5d912b..3e1c51bd2364af914b6e7d3c374b4b1f31edb503 100644 (file)
@@ -4329,6 +4329,7 @@ void MDCache::identify_files_to_recover()
         p++) {
       Capability *cap = in->get_client_cap(p->first);
       if (!cap) {
+       dout(10) << " client" << p->first << " has range " << p->second << " but no cap on " << *in << dendl;
        recover = true;
        break;
       }
index 5e0de28f2c8919ae7f5ac601511e686311251d90..2e24c472726c97849db0f4da2b181334d6f813dc 100644 (file)
@@ -2285,10 +2285,10 @@ class C_MDS_inode_update_finish : public Context {
   MDS *mds;
   MDRequest *mdr;
   CInode *in;
-  bool smaller;
+  bool smaller, changed_ranges;
 public:
-  C_MDS_inode_update_finish(MDS *m, MDRequest *r, CInode *i, bool sm=false) :
-    mds(m), mdr(r), in(i), smaller(sm) { }
+  C_MDS_inode_update_finish(MDS *m, MDRequest *r, CInode *i, bool sm=false, bool cr=false) :
+    mds(m), mdr(r), in(i), smaller(sm), changed_ranges(cr) { }
   void finish(int r) {
     assert(r == 0);
 
@@ -2305,6 +2305,9 @@ public:
     mds->balancer->hit_inode(mdr->now, in, META_POP_IWR);   
 
     mds->server->reply_request(mdr, 0);
+
+    if (changed_ranges)
+      mds->locker->share_inode_max_size(in);
   }
 };
 
@@ -2348,6 +2351,8 @@ void Server::handle_client_setattr(MDRequest *mdr)
     return;
   }
 
+  bool changed_ranges = false;
+
   // project update
   mdr->ls = mdlog->get_current_segment();
   EUpdate *le = new EUpdate(mdlog, "setattr");
@@ -2378,6 +2383,15 @@ void Server::handle_client_setattr(MDRequest *mdr)
       pi->size = req->head.args.setattr.size;
     }
     pi->rstat.rbytes = pi->size;
+
+    // adjust client's max_size?
+    map<int,byte_range_t> new_ranges;
+    mds->locker->calc_new_client_ranges(cur, pi->size, new_ranges);
+    if (pi->client_ranges != new_ranges) {
+      dout(10) << " client_ranges " << pi->client_ranges << " -> " << new_ranges << dendl;
+      pi->client_ranges = new_ranges;
+      changed_ranges = true;
+    }
   }
 
   pi->version = cur->pre_dirty();
@@ -2388,7 +2402,7 @@ void Server::handle_client_setattr(MDRequest *mdr)
   mdcache->predirty_journal_parents(mdr, &le->metablob, cur, 0, PREDIRTY_PRIMARY, false);
   mdcache->journal_dirty_inode(mdr, &le->metablob, cur);
   
-  journal_and_reply(mdr, cur, 0, le, new C_MDS_inode_update_finish(mds, mdr, cur, smaller));
+  journal_and_reply(mdr, cur, 0, le, new C_MDS_inode_update_finish(mds, mdr, cur, smaller, changed_ranges));
 
   // flush immediately if there are readers/writers waiting
   if (cur->get_caps_wanted() & (CEPH_CAP_FILE_RD|CEPH_CAP_FILE_WR))