]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
client: obey and request max_size for client_oc=0 mode
authorSage Weil <sage@newdream.net>
Thu, 15 May 2008 01:14:45 +0000 (18:14 -0700)
committerSage Weil <sage@newdream.net>
Thu, 15 May 2008 01:14:45 +0000 (18:14 -0700)
src/TODO
src/client/Client.cc
src/client/Client.h
src/messages/MClientFileCaps.h

index bca91d076378505757ddcbc8873f3ab6699711c1..e2fb86425ae4547a1bc0963905d8230986c7011f 100644 (file)
--- a/src/TODO
+++ b/src/TODO
@@ -77,9 +77,6 @@ mds
   - mds lock last_change stamp?
 
 - fix file_data_version
-- on recovery, validate file sizes when max_size > size
-
-- coalesce lease revocations on dir inode + dentry, where possible
 
 - fix reconnect/rejoin open file weirdness
 - get rid of C*Discover objects for replicate_to .. encode to bufferlists directly?
@@ -87,7 +84,7 @@ mds
   - dentry versions vs dirfrags...
 - failure during reconnect vs clientmap.  
 
-- inode.rmtime (recursive mtime)?
+- inode.rctime (recursive mtime)?
 - make inode.size reflect directory size (number of entries)?
 
 - osd needs a set_floor_and_read op for safe failover/STOGITH-like semantics.
index c06a6cddaa7ed2803b69b5799b2ca3bc197f3c8d..a7723312d7e805d97c88d3f430618eb3e55b584f 100644 (file)
@@ -1446,6 +1446,15 @@ void Client::handle_file_caps(MClientFileCaps *m)
     in->inode.time_warp_seq = m->get_time_warp_seq();
   }
 
+  if (m->get_max_size() != in->inode.max_size) {
+    dout(10) << "max_size " << in->inode.max_size << " -> " << m->get_max_size() << dendl;
+    in->inode.max_size = m->get_max_size();
+    if (in->inode.max_size > in->wanted_max_size) {
+      in->wanted_max_size = 0;
+      in->requested_max_size = 0;
+    }
+  }
+
   // share our (possibly newer) file size, mtime, atime
   m->set_size(in->inode.size);
   m->set_mtime(in->inode.mtime);
@@ -1559,6 +1568,7 @@ void Client::update_caps_wanted(Inode *in)
   int wanted = in->file_caps_wanted();
   dout(5) << "updating caps wanted on ino " << in->inode.ino 
           << " to " << cap_string(wanted)
+         << " max_size " << in->wanted_max_size
           << dendl;
   
   // FIXME: pick a single mds and let the others off the hook..
@@ -1570,6 +1580,8 @@ void Client::update_caps_wanted(Inode *in)
                                              it->second.seq,
                                              it->second.caps,
                                              wanted);
+    m->set_max_size(in->wanted_max_size);
+    in->requested_max_size = in->wanted_max_size;
     messenger->send_message(m, mdsmap->get_inst(it->first));
     if (wanted == 0)
       mds_sessions[it->first].num_caps--;
@@ -3176,8 +3188,21 @@ int Client::_write(Fh *f, __s64 offset, __u64 size, const char *buf)
     dout(7) << "synchronous write" << dendl;
 
     // do we have write file cap?
-    while (!lazy && (in->file_caps() & CEPH_CAP_WR) == 0) {
-      dout(7) << " don't have write cap, waiting" << dendl;
+    __u64 endoff = offset + size;
+
+    if ((endoff >= in->inode.max_size ||
+        endoff > (in->inode.size << 1)) &&
+       endoff > in->wanted_max_size) {
+      dout(10) << "wanted_max_size " << in->wanted_max_size << " -> " << endoff << dendl;
+      in->wanted_max_size = endoff;
+      update_caps_wanted(in);
+    }
+
+    while (!lazy &&
+          ((in->file_caps() & CEPH_CAP_WR) == 0 ||
+           endoff > in->inode.max_size)) {
+      dout(7) << " don't have write cap for endoff " << endoff
+             << " (max " << in->inode.max_size << "), waiting" << dendl;
       Cond cond;
       in->waitfor_write.push_back(&cond);
       cond.Wait(client_lock);
index 401ff4400545fbe776f70c490fa99303e2ca6662..0a9f28f634618a2f40d2f6cee1a370bba41f7db9 100644 (file)
@@ -149,6 +149,7 @@ class Inode {
   map<int,InodeCap> stale_caps;      // mds -> cap .. stale
 
   int       num_open_rd, num_open_wr, num_open_lazy;  // num readers, writers
+  __u64     wanted_max_size, requested_max_size;
 
   int       ref;      // ref count. 1 for each dentry, fh that links to me.
   int       ll_ref;   // separate ref count for ll client
@@ -207,6 +208,7 @@ class Inode {
     lease_mask(0), lease_mds(-1),
     dir_auth(-1), dir_hashed(false), dir_replicated(false), 
     num_open_rd(0), num_open_wr(0), num_open_lazy(0),
+    wanted_max_size(0), requested_max_size(0),
     ref(0), ll_ref(0), 
     dir(0), dn(0), symlink(0),
     fc(_oc, ino, layout),
index 7795632def5b150c5a96316e1f7b15f8a99fd63e..0d5cde6ada428bb78e33d7727a88a33cefbff1bf 100644 (file)
@@ -56,6 +56,8 @@ class MClientFileCaps : public Message {
   void set_caps(int c) { h.caps = c; }
   void set_wanted(int w) { h.wanted = w; }
 
+  void set_max_size(__u64 ms) { h.max_size = ms; }
+
   void set_migrate_mds(int m) { h.migrate_mds = m; }
   void set_migrate_seq(int m) { h.migrate_seq = m; }
   void set_op(int o) { h.op = o; }