]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
client: excl, unfinished
authorSage Weil <sage@newdream.net>
Tue, 25 Mar 2008 23:38:09 +0000 (16:38 -0700)
committerSage Weil <sage@newdream.net>
Tue, 25 Mar 2008 23:38:09 +0000 (16:38 -0700)
src/TODO
src/client/Client.cc
src/client/Client.h
src/include/ceph_fs.h
src/mds/Capability.h
src/mds/FileLock.h
src/mds/Locker.cc
src/start.sh

index 9ba3bab0bbad93305888368d8fca07b745e27526..efbba9e13ffacde1c997c3d51077ea24ad57640d 100644 (file)
--- a/src/TODO
+++ b/src/TODO
@@ -22,6 +22,7 @@ userspace client
 - client caps migration races
   - caps need a seq number; reap logic needs to be a bit smarter
   - also needs cope with mds failures
+- reference count lease validations on path lookup?
 
 kernel client
 - make sure link/unlink results reflected by inode/dentry cache  (let fill_trace do it?  invalidate?  do actual update?)
index 070ed25dde664930a946faeda8f8ae86ebb56e97..c7e99809703c6f95fe7f8fbce18c3b43d142653e 100644 (file)
@@ -328,12 +328,6 @@ void Client::update_inode(Inode *in, InodeStat *st, utime_t ttl)
   if (ttl > in->ttl) 
     in->ttl = ttl;
 
-  // or do we have newer size/mtime from writing?
-  if (in->file_wr_size > in->inode.size)
-    in->inode.size = in->file_wr_size;
-  if (in->file_wr_mtime > in->inode.mtime)
-    in->inode.mtime = in->file_wr_mtime;
-
   // symlink?
   if (in->inode.is_symlink()) {
     if (!in->symlink) 
@@ -1276,7 +1270,7 @@ void Client::handle_file_caps(MClientFileCaps *m)
     if (g_conf.client_oc)
       in->fc.truncate(in->inode.size, m->get_size());
 
-    in->inode.size = in->file_wr_size = m->get_size(); 
+    in->inode.size = m->get_size(); 
     delete m;
     return;
   }
@@ -1307,20 +1301,17 @@ void Client::handle_file_caps(MClientFileCaps *m)
           << " was " << cap_string(old_caps) << dendl;
   
   // update inode
-  in->inode.size = m->get_size();      // might have updated size... FIXME this is overkill!
-  in->inode.mtime = m->get_mtime();
-  in->inode.atime = m->get_atime();
-
-  // preserve our (possibly newer) file size, mtime
-  if (in->file_wr_size > in->inode.size) {
-    in->inode.size = in->file_wr_size;
-    m->set_size(in->file_wr_size);
-  }
-  if (in->file_wr_mtime > in->inode.mtime) {
-    in->inode.mtime = in->file_wr_mtime;
-    m->set_mtime(in->file_wr_mtime);
-  }
-
+  if (m->get_size() > in->inode.size)
+    in->inode.size = m->get_size();
+  if (m->get_mtime() > in->inode.mtime && (old_caps & CEPH_CAP_EXCL) == 0) 
+    in->inode.mtime = m->get_mtime();
+  if (m->get_atime() > in->inode.atime && (old_caps & CEPH_CAP_EXCL) == 0) 
+    in->inode.atime = m->get_atime();
+
+  // share our (possibly newer) file size, mtime, atime
+  m->set_size(in->inode.size);
+  m->set_mtime(in->inode.mtime);
+  m->set_atime(in->inode.atime);
 
   if (g_conf.client_oc) {
     // caching on, use FileCache.
@@ -1387,11 +1378,6 @@ void Client::implemented_caps(MClientFileCaps *m, Inode *in)
   dout(5) << "implemented_caps " << cap_string(m->get_caps()) 
           << ", acking to " << m->get_source() << dendl;
 
-  if (in->file_caps() == 0) {
-    in->file_wr_mtime = utime_t();
-    in->file_wr_size = 0;
-  }
-
   messenger->send_message(m, m->get_source_inst());
 }
 
@@ -1428,11 +1414,6 @@ void Client::release_caps(Inode *in,
     in->caps.clear();
     put_inode(in);
   }
-
-  if (in->file_caps() == 0) {
-    in->file_wr_mtime = utime_t();
-    in->file_wr_size = 0;
-  }
 }
 
 void Client::update_caps_wanted(Inode *in)
@@ -1777,7 +1758,6 @@ int Client::unlink(const char *relpath)
 
 int Client::_unlink(const char *path)
 {
-
   MClientRequest *req = new MClientRequest(CEPH_MDS_OP_UNLINK, messenger->get_myinst());
   req->set_path(path);
  
@@ -2230,6 +2210,18 @@ int Client::utime(const char *relpath, struct utimbuf *buf)
 int Client::_utimes(const char *path, utime_t mtime, utime_t atime)
 {
   dout(3) << "_utimes(" << path << ", " << mtime << ", " << atime << ")" << dendl;
+
+  filepath fpath(path);
+  Dentry *dn = lookup(fpath);
+  int want = CEPH_CAP_WR|CEPH_CAP_WRBUFFER|CEPH_CAP_EXCL;
+  if (dn && dn->inode &&
+      (dn->inode->file_caps() & want) == want) {
+    dout(5) << " have WR and EXCL caps, just updating our m/atime" << dendl;
+    dn->inode->inode.mtime = mtime;
+    dn->inode->inode.atime = atime;
+    return 0;
+  }
+
   MClientRequest *req = new MClientRequest(CEPH_MDS_OP_UTIME, messenger->get_myinst());
   req->set_path(path); 
   mtime.encode_timeval(&req->head.args.utime.mtime);
@@ -3074,7 +3066,7 @@ int Client::_write(Fh *f, off_t offset, off_t size, const char *buf)
 
   bool lazy = f->mode == FILE_MODE_LAZY;
 
-  dout(10) << "cur file size is " << in->inode.size << "    wr size " << in->file_wr_size << dendl;
+  dout(10) << "cur file size is " << in->inode.size << dendl;
 
   // time it.
   utime_t start = g_clock.real_now();
@@ -3155,14 +3147,14 @@ int Client::_write(Fh *f, off_t offset, off_t size, const char *buf)
   
   // extend file?
   if (totalwritten + offset > in->inode.size) {
-    in->inode.size = in->file_wr_size = totalwritten + offset;
+    in->inode.size = totalwritten + offset;
     dout(7) << "wrote to " << totalwritten+offset << ", extending file size" << dendl;
   } else {
     dout(7) << "wrote to " << totalwritten+offset << ", leaving file size at " << in->inode.size << dendl;
   }
 
   // mtime
-  in->file_wr_mtime = in->inode.mtime = g_clock.real_now();
+  in->inode.mtime = g_clock.real_now();
 
   // ok!
   return totalwritten;  
index b614de1ac4279e6b08d23a2090b72126563f3120..4cb56da732d441f26526e7c419c9fb30b2085c17 100644 (file)
@@ -141,8 +141,6 @@ class Inode {
   map<int,InodeCap> caps;            // mds -> InodeCap
   map<int,InodeCap> stale_caps;      // mds -> cap .. stale
 
-  utime_t   file_wr_mtime;   // [writers] time of last write
-  off_t     file_wr_size;    // [writers] largest offset we've written to
   int       num_open_rd, num_open_wr, num_open_lazy;  // num readers, writers
 
   int       ref;      // ref count. 1 for each dentry, fh that links to me.
@@ -199,7 +197,6 @@ class Inode {
     inode(_inode),
     mask(0),
     dir_auth(-1), dir_hashed(false), dir_replicated(false), 
-    file_wr_mtime(0, 0), file_wr_size(0), 
     num_open_rd(0), num_open_wr(0), num_open_lazy(0),
     ref(0), ll_ref(0), 
     dir(0), dn(0), symlink(0),
@@ -229,7 +226,7 @@ class Inode {
   }
 
   int file_caps_wanted() {
-    int w = 0;
+    int w = CEPH_CAP_EXCL;  // always ask
     if (num_open_rd) w |= CEPH_CAP_RD|CEPH_CAP_RDCACHE;
     if (num_open_wr) w |= CEPH_CAP_WR|CEPH_CAP_WRBUFFER;
     if (num_open_lazy) w |= CEPH_CAP_LAZYIO;
index 5d03d6fd90f1d9aba1e39f983860243343fa7488..8d267cb0932ebabcac9564e9ee02c3a9cf7fb756 100644 (file)
@@ -478,6 +478,7 @@ struct ceph_mds_reply_dirfrag {
 #define CEPH_CAP_WRBUFFER 16  /* client can buffer writes */
 #define CEPH_CAP_WREXTEND 32  /* client can extend eof */
 #define CEPH_CAP_LAZYIO   64  /* client can perform lazy io */
+#define CEPH_CAP_EXCL    128  /* exclusive/loner access */
 
 enum {
        CEPH_CAP_OP_GRANT,   /* mds->client grant */
index ac165ec781e203a3fb5ccbc3f99159168ec2fb5c..2b7d6a5381bc617849e8ad730f929fca9aa1dc6f 100644 (file)
@@ -39,6 +39,7 @@ inline string cap_string(int cap)
   if (cap & CEPH_CAP_WRBUFFER) s += " wrbuffer";
   if (cap & CEPH_CAP_WRBUFFER) s += " wrextend";
   if (cap & CEPH_CAP_LAZYIO) s += " lazyio";
+  if (cap & CEPH_CAP_EXCL) s += " excl";
   s += " ]";
   return s;
 }
index cb0151cdf450b68b56909bcc363bc1ab0605e7b2..ef7941088c305cc000df88eacc27ae3fb9f3a736 100644 (file)
@@ -208,7 +208,7 @@ class FileLock : public SimpleLock {
         return 0;
 
       case LOCK_LONER:  // single client writer, of course.
-        return CEPH_CAP_RDCACHE | CEPH_CAP_RD | CEPH_CAP_WR | CEPH_CAP_WREXTEND | CEPH_CAP_WRBUFFER | CEPH_CAP_LAZYIO;
+        return CEPH_CAP_RDCACHE | CEPH_CAP_RD | CEPH_CAP_WR | CEPH_CAP_WREXTEND | CEPH_CAP_WRBUFFER | CEPH_CAP_LAZYIO | CEPH_CAP_EXCL;
       case LOCK_GLONERR:
         return CEPH_CAP_RD | CEPH_CAP_LAZYIO;
       case LOCK_GLONERM:
index 98704f48cec300815f5b15ff022b307ba56b6e18..3542b0e2188211391ea1adfc638d489f4d53ed66 100644 (file)
@@ -884,15 +884,19 @@ void Locker::handle_client_file_caps(MClientFileCaps *m)
 
   // atime|mtime|size?
   bool had_or_has_wr = (had|has) & CEPH_CAP_WR;
-  bool dirty = false;
-  //if (atime > latest->atime) 
-  //dirty = true;
+  bool excl = (had|has) & CEPH_CAP_EXCL;
+  bool dirty_atime = false;
+  bool dirty_mtime = false;
+  bool dirty_size = false;
   if (had_or_has_wr) {
-    if (mtime > latest->mtime) 
-      dirty = true;
+    if (mtime > latest->mtime || (excl && mtime != latest->mtime)
+      dirty_mtime = true;
     if (size > latest->size) 
-      dirty = true;
+      dirty_size = true;
   }
+  if (excl && atime != latest->atime)
+    dirty_atime = true;
+  bool dirty = dirty_atime || dirty_mtime || dirty_size;
   
   // increase max_size?
   bool increase_max = false;
@@ -918,19 +922,19 @@ void Locker::handle_client_file_caps(MClientFileCaps *m)
       dout(7) << " increasing max_size " << pi->max_size << " to " << new_max << dendl;
       pi->max_size = new_max;
     }    
-    if (mtime > latest->mtime) {
-      dout(7) << "  taking mtime " << mtime << " > " 
-             << in->inode.mtime << " for " << *in << dendl;
+    if (dirty_mtime) {
+      dout(7) << "  mtime " << pi->mtime << " -> " <<  mtime
+             << " for " << *in << dendl;
       pi->mtime = mtime;
     }
-    if (size > latest->size) {
-      dout(7) << "  taking size " << size << " > " 
-             << in->inode.size << " for " << *in << dendl;
+    if (dirty_size) {
+      dout(7) << "  size " << pi->size << " -> " << size
+             << " for " << *in << dendl;
       pi->size = size;
     }
-    if (atime > latest->atime) {
-      dout(7) << "  taking atime " << atime << " > " 
-             << in->inode.atime << " for " << *in << dendl;
+    if (dirty_atime) {
+      dout(7) << "  atime " << pi->atime << " -> " << atime
+             << " for " << *in << dendl;
       pi->atime = atime;
     }
     le->metablob.add_dir_context(in->get_parent_dir());
index d83f28d1f20e70503ba8e266865d386955423ebe..451ff2f5a9c6bc41357e45d202b424a467f3baf3 100755 (executable)
@@ -43,7 +43,7 @@ do
 done
 
 # mds
-$CEPH_BIN/cmds $ARGS --debug_mds 10
+$CEPH_BIN/cmds $ARGS --debug_mds 20
 
 echo "started.  stop.sh to stop.  see out/* (e.g. 'tail -f out/????') for debug output."