]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
fixed caps race with client, play_trace can do metadata only
authorsageweil <sageweil@29311d96-e01e-0410-9327-a35deaab8ce9>
Sat, 11 Aug 2007 22:14:34 +0000 (22:14 +0000)
committersageweil <sageweil@29311d96-e01e-0410-9327-a35deaab8ce9>
Sat, 11 Aug 2007 22:14:34 +0000 (22:14 +0000)
git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@1623 29311d96-e01e-0410-9327-a35deaab8ce9

branches/sage/mds/client/Client.cc
branches/sage/mds/client/Client.h
branches/sage/mds/client/SyntheticClient.cc
branches/sage/mds/client/SyntheticClient.h

index 35c9063ba85c0d8510e811e207fe818c3bed1e1c..483051ff588b72247cdd440b4286fba455e6e9dc 100644 (file)
@@ -58,7 +58,7 @@ using namespace std;
 
 #include "config.h"
 #undef dout
-#define  dout(l)    if (l<=g_conf.debug || l <= g_conf.debug_client) cout << g_clock.now() << " client" << whoami << "." << pthread_self() << " "
+#define  dout(l)    if (l<=g_conf.debug || l <= g_conf.debug_client) cout << g_clock.now() << " client" << whoami /*<< "." << pthread_self() */ << " "
 
 #define  tout       if (g_conf.client_trace) traceout
 
@@ -2459,6 +2459,14 @@ int Client::_open(const char *path, int flags, mode_t mode, Fh **fhp)
   // FIXME where does FUSE maintain user information
   req->set_caller_uid(getuid());
   req->set_caller_gid(getgid());
+
+  // do i have the inode?
+  Dentry *dn = lookup(req->get_filepath());
+  Inode *in = 0;
+  if (dn) {
+    in = dn->inode;
+    in->add_open(cmode);  // make note of pending open, since it effects _wanted_ caps.
+  }
   
   MClientReply *reply = make_request(req);
   assert(reply);
@@ -2478,50 +2486,51 @@ int Client::_open(const char *path, int flags, mode_t mode, Fh **fhp)
     assert(f->inode);
     f->inode->get();
 
-    if (cmode & FILE_MODE_R) f->inode->num_open_rd++;
-    if (cmode & FILE_MODE_W) f->inode->num_open_wr++;
-    if (cmode & FILE_MODE_LAZY) f->inode->num_open_lazy++;
+    if (!in) {
+      in = f->inode;
+      in->add_open(f->mode);
+    }
 
     // caps included?
     int mds = reply->get_source().num();
 
-    if (f->inode->caps.empty()) {// first caps?
-      dout(7) << " first caps on " << f->inode->inode.ino << endl;
-      f->inode->get();
+    if (in->caps.empty()) {// first caps?
+      dout(7) << " first caps on " << in->inode.ino << endl;
+      in->get();
     }
 
     int new_caps = reply->get_file_caps();
 
-    assert(reply->get_file_caps_seq() >= f->inode->caps[mds].seq);
-    if (reply->get_file_caps_seq() > f->inode->caps[mds].seq) {   
-      int old_caps = f->inode->caps[mds].caps;
+    assert(reply->get_file_caps_seq() >= in->caps[mds].seq);
+    if (reply->get_file_caps_seq() > in->caps[mds].seq) {   
+      int old_caps = in->caps[mds].caps;
 
       dout(7) << "open got caps " << cap_string(new_caps)
              << " (had " << cap_string(old_caps) << ")"
-              << " for " << f->inode->ino() 
+              << " for " << in->ino() 
               << " seq " << reply->get_file_caps_seq() 
               << " from mds" << mds 
              << endl;
 
-      f->inode->caps[mds].caps = new_caps;
-      f->inode->caps[mds].seq = reply->get_file_caps_seq();
+      in->caps[mds].caps = new_caps;
+      in->caps[mds].seq = reply->get_file_caps_seq();
 
       // we shouldn't ever lose caps at this point.
       // actually, we might...?
-      assert((old_caps & ~f->inode->caps[mds].caps) == 0);
+      assert((old_caps & ~in->caps[mds].caps) == 0);
 
       if (g_conf.client_oc)
-        f->inode->fc.set_caps(new_caps);
+        in->fc.set_caps(new_caps);
 
     } else {
       dout(7) << "open got SAME caps " << cap_string(new_caps) 
-              << " for " << f->inode->ino() 
+              << " for " << in->ino() 
               << " seq " << reply->get_file_caps_seq() 
               << " from mds" << mds 
              << endl;
     }
     
-    dout(5) << "open success, fh is " << f << " combined caps " << cap_string(f->inode->file_caps()) << endl;
+    dout(5) << "open success, fh is " << f << " combined caps " << cap_string(in->file_caps()) << endl;
   }
 
   delete reply;
@@ -2583,10 +2592,7 @@ int Client::_release(Fh *f)
 
   // update inode rd/wr counts
   int before = in->file_caps_wanted();
-  if (f->mode & FILE_MODE_R)     
-    in->num_open_rd--;
-  if (f->mode & FILE_MODE_W)
-    in->num_open_wr--;
+  in->sub_open(f->mode);
   int after = in->file_caps_wanted();
 
   // does this change what caps we want?
@@ -3183,19 +3189,24 @@ int Client::ll_lookup(inodeno_t parent, const char *name, struct stat *attr)
   tout << parent.val << endl;
   tout << name << endl;
 
+  string dname = name;
+  Inode *diri = 0;
+  int r = 0;
+
   if (inode_map.count(parent) == 0) {
     tout << 0 << endl;
     dout(1) << "ll_lookup " << parent << " " << name << " -> ENOENT (parent DNE... WTF)" << endl;
-    return -ENOENT;
+    r = -ENOENT;
+    goto out;
   }
-  Inode *diri = inode_map[parent];
+  diri = inode_map[parent];
   if (!diri->inode.is_dir()) {
     tout << 0 << endl;
     dout(1) << "ll_lookup " << parent << " " << name << " -> ENOTDIR (parent not a dir... WTF)" << endl;
-    return -ENOTDIR;
+    r = -ENOTDIR;
+    goto out;
   }
 
-  string dname = name;
 
   // refresh the dir?
   //  FIXME: this is the hackish way.
@@ -3229,13 +3240,15 @@ int Client::ll_lookup(inodeno_t parent, const char *name, struct stat *attr)
     dout(3) << "ll_lookup " << parent << " " << name << " -> " << in->inode.ino
            << " (" << in << ")" << endl;
     assert(inode_map[in->inode.ino] == in);
-    tout << in->inode.ino << endl;
-    return 0;
   } else {
-    dout(3) << "ll_lookup " << parent << " " << name << " -> ENOENT" << endl;
-    tout << 0 << endl;
-    return -ENOENT;
+    r = -ENOENT;
   }
+
+ out:
+  dout(3) << "ll_lookup " << parent << " " << name
+         << " -> " << r << " (" << hex << attr->st_ino << dec << ")" << endl;
+  tout << attr->st_ino << endl;
+  return r;
 }
 
 void Client::_ll_get(Inode *in)
index 4c20169556875fe0558771d90f9fb0300e94881f..5f62b5c9292ac040b4d994f7c7de0441a520fa7c 100644 (file)
@@ -232,6 +232,17 @@ class Inode {
     return w;
   }
 
+  void add_open(int cmode) {
+    if (cmode & FILE_MODE_R) num_open_rd++;
+    if (cmode & FILE_MODE_W) num_open_wr++;
+    if (cmode & FILE_MODE_LAZY) num_open_lazy++;
+  }
+  void sub_open(int cmode) {
+    if (cmode & FILE_MODE_R) num_open_rd--;
+    if (cmode & FILE_MODE_W) num_open_wr--;
+    if (cmode & FILE_MODE_LAZY) num_open_lazy--;
+  }
+
   int authority(MDSMap *mdsmap) {
     //cout << "authority on " << inode.ino << " .. dir_auth is " << dir_auth<< endl;
     // parent?
index badea61b17878c077a1e987435db073a297ebdc9..52dba42418c14a6b9753fdb18d190e73bce75792 100644 (file)
@@ -555,7 +555,7 @@ int SyntheticClient::run()
             utime_t start = g_clock.now();
             
             if (time_to_stop()) break;
-            play_trace(t, prefix);
+            play_trace(t, prefix, false);
             if (time_to_stop()) break;
             clean_dir(prefix);
             
@@ -693,7 +693,7 @@ void SyntheticClient::up()
 }
 
 
-int SyntheticClient::play_trace(Trace& t, string& prefix)
+int SyntheticClient::play_trace(Trace& t, string& prefix, bool metadata_only)
 {
   dout(4) << "play trace" << endl;
   t.start();
@@ -815,18 +815,22 @@ int SyntheticClient::play_trace(Trace& t, string& prefix)
       int64_t size = t.get_int();
       int64_t off = t.get_int();
       int64_t fd = open_files[f];
-      char *b = new char[size];
-      client->read(fd, b, size, off);
-      delete[] b;
+      if (!metadata_only) {
+       char *b = new char[size];
+       client->read(fd, b, size, off);
+       delete[] b;
+      }
     } else if (strcmp(op, "write") == 0) {
       int64_t f = t.get_int();
       int64_t fd = open_files[f];
       int64_t size = t.get_int();
       int64_t off = t.get_int();
-      char *b = new char[size];
-      memset(b, 1, size);            // let's write 1's!
-      client->write(fd, b, size, off);
-      delete[] b;
+      if (!metadata_only) {
+       char *b = new char[size];
+       memset(b, 1, size);            // let's write 1's!
+       client->write(fd, b, size, off);
+       delete[] b;
+      }
     } else if (strcmp(op, "truncate") == 0) {
       const char *a = t.get_string(buf, p);
       int64_t l = t.get_int();
@@ -963,18 +967,22 @@ int SyntheticClient::play_trace(Trace& t, string& prefix)
       int64_t off = t.get_int();
       int64_t size = t.get_int();
       Fh *fh = ll_files[f];
-      bufferlist bl;
-      client->ll_read(fh, off, size, &bl);
+      if (!metadata_only) {
+       bufferlist bl;
+       client->ll_read(fh, off, size, &bl);
+      }
     } else if (strcmp(op, "ll_write") == 0) {
       int64_t f = t.get_int();
       int64_t off = t.get_int();
       int64_t size = t.get_int();
       Fh *fh = ll_files[f];
-      bufferlist bl;
-      bufferptr bp(size);
-      bl.push_back(bp);
-      bp.zero();
-      client->ll_write(fh, off, size, bl.c_str());
+      if (!metadata_only) {
+       bufferlist bl;
+       bufferptr bp(size);
+       bl.push_back(bp);
+       bp.zero();
+       client->ll_write(fh, off, size, bl.c_str());
+      }
     } else if (strcmp(op, "ll_release") == 0) {
       int64_t f = t.get_int();
       Fh *fh = ll_files[f];
index 0f572bd4a85883c17856583572bae6d94244e420..b8367315edbb23ee6e35872665ef5a318a9777e1 100644 (file)
@@ -226,7 +226,7 @@ class SyntheticClient {
 
   int clean_dir(string& basedir);
 
-  int play_trace(Trace& t, string& prefix);
+  int play_trace(Trace& t, string& prefix, bool metadata_only=false);
 
   void make_dir_mess(const char *basedir, int n);
   void foo();