]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
uclient: implement CREATE operation
authorSage Weil <sage@newdream.net>
Tue, 1 Sep 2009 23:37:10 +0000 (16:37 -0700)
committerSage Weil <sage@newdream.net>
Tue, 1 Sep 2009 23:37:10 +0000 (16:37 -0700)
This avoids an additional async cap wanted update in the usual
case.  And let's us pass in default layout info!

Untested...

src/client/Client.cc
src/client/Client.h

index 1ce70ca90f3d93338fd9ac264b82296b1fd1c2de..7645111c929b5e920cd5d3fd15caf5e7f999457c 100644 (file)
@@ -3775,6 +3775,8 @@ int Client::open(const char *relpath, int flags, mode_t mode)
   tout << relpath << std::endl;
   tout << flags << std::endl;
 
+  Fh *fh = NULL;
+
   filepath path(relpath);
   Inode *in;
   int r = path_walk(path, &in);
@@ -3788,21 +3790,17 @@ int Client::open(const char *relpath, int flags, mode_t mode)
     r = path_walk(dirpath, &dir);
     if (r < 0)
       return r;
-    r = _mknod(dir, dname.c_str(), mode, 0);
-    if (r == 0) {
-      Dentry *dn = dir->dir->dentries[dname];
-      in = dn->inode;
-      assert(in);
-    }
+    r = _create(dir, dname.c_str(), flags, mode, &in, &fh);
   }
   if (r < 0)
     return r;
 
-  Fh *fh;
-  r = _open(in, flags, mode, &fh);
+  if (!fh)
+    r = _open(in, flags, mode, &fh);
   if (r >= 0) {
     // allocate a integer file descriptor
     assert(fh);
+    assert(in);
     r = get_fd();
     assert(fd_map.count(r) == 0);
     fd_map[r] = fh;
@@ -3813,6 +3811,30 @@ int Client::open(const char *relpath, int flags, mode_t mode)
   return r;
 }
 
+Fh *Client::_create_fh(Inode *in, int flags, int cmode)
+{
+  // yay
+  Fh *f = new Fh;
+  f->mode = cmode;
+  if (flags & O_APPEND)
+    f->append = true;
+  
+  // inode
+  assert(in);
+  f->inode = in;
+  f->inode->get();
+
+  dout(10) << "_create_fh " << in->ino << " mode " << cmode << dendl;
+
+  if (in->snapid != CEPH_NOSNAP) {
+    in->snap_cap_refs++;
+    dout(5) << "open success, fh is " << f << " combined IMMUTABLE SNAP caps " 
+           << ccap_string(in->caps_issued()) << dendl;
+  }
+
+  return f;
+}
+
 int Client::_open(Inode *in, int flags, mode_t mode, Fh **fhp, int uid, int gid) 
 {
   int cmode = ceph_flags_to_mode(flags);
@@ -3836,25 +3858,7 @@ int Client::_open(Inode *in, int flags, mode_t mode, Fh **fhp, int uid, int gid)
 
   // success?
   if (result >= 0) {
-    // yay
-    Fh *f = new Fh;
-    if (fhp) *fhp = f;
-    f->mode = cmode;
-    if (flags & O_APPEND)
-      f->append = true;
-
-    // inode
-    assert(in);
-    f->inode = in;
-    f->inode->get();
-
-    dout(10) << in->ino << " mode " << cmode << dendl;
-
-    if (in->snapid != CEPH_NOSNAP) {
-      in->snap_cap_refs++;
-      dout(5) << "open success, fh is " << f << " combined IMMUTABLE SNAP caps " 
-             << ccap_string(in->caps_issued()) << dendl;
-    }
+    *fhp = _create_fh(in, flags, cmode);
   } else {
     in->put_open_ref(cmode);
   }
@@ -5008,6 +5012,36 @@ int Client::ll_mknod(vinodeno_t parent, const char *name, mode_t mode, dev_t rde
   return r;
 }
 
+int Client::_create(Inode *dir, const char *name, int flags, mode_t mode, Inode **inp, Fh **fhp, int uid, int gid) 
+{ 
+  dout(3) << "_create(" << dir->ino << " " << name << ", 0" << oct << mode << dec << ")" << dendl;
+  
+  MClientRequest *req = new MClientRequest(CEPH_MDS_OP_CREATE);
+  filepath path;
+  dir->make_path(path);
+  path.push_dentry(name);
+  req->set_filepath(path); 
+  req->head.args.open.flags = flags | O_CREAT;
+  req->head.args.open.mode = mode;
+  
+  int res = make_request(req, uid, gid);
+  
+  if (res >= 0) {
+    res = _lookup(dir, name, inp);
+    if (res >= 0) {
+      int cmode = ceph_flags_to_mode(flags);
+      (*inp)->get_open_ref(cmode);
+      *fhp = _create_fh(*inp, flags, cmode);
+    }
+  }
+    
+  trim_cache();
+
+  dout(3) << "create(" << path << ", 0" << oct << mode << dec << ") = " << res << dendl;
+  return res;
+}
+
+
 int Client::_mkdir(Inode *dir, const char *name, mode_t mode, int uid, int gid)
 {
   MClientRequest *req = new MClientRequest(dir->snapid == CEPH_SNAPDIR ? CEPH_MDS_OP_MKSNAP:CEPH_MDS_OP_MKDIR);
index 9452070789e3089196dded63636cd51897f5d508..fe12fee6c0e94dcca8591f76e877cd42dbc7de74 100644 (file)
@@ -1064,6 +1064,8 @@ private:
   int _ll_put(Inode *in, int num);
   void _ll_drop_pins();
 
+  Fh *_create_fh(Inode *in, int flags, int cmode);
+
   int _read_sync(Fh *f, __u64 off, __u64 len, bufferlist *bl);
   int _read_async(Fh *f, __u64 off, __u64 len, bufferlist *bl);
 
@@ -1086,6 +1088,7 @@ private:
   int _setxattr(Inode *in, const char *name, const void *value, size_t len, int flags, int uid=-1, int gid=-1);
   int _removexattr(Inode *in, const char *nm, int uid=-1, int gid=-1);
   int _open(Inode *in, int flags, mode_t mode, Fh **fhp, int uid=-1, int gid=-1);
+  int _create(Inode *in, const char *name, int flags, mode_t mode, Inode **inp, Fh **fhp, int uid=-1, int gid=-1);
   int _release(Fh *fh);
   loff_t _lseek(Fh *fh, loff_t offset, int whence);
   int _read(Fh *fh, __s64 offset, __u64 size, bufferlist *bl);