]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
added create (without open)
authorYehuda Sadeh-Weinraub <yehuda@yehuda.infit.com>
Mon, 21 Jan 2008 10:41:29 +0000 (12:41 +0200)
committerYehuda Sadeh-Weinraub <yehuda@yehuda.infit.com>
Mon, 21 Jan 2008 10:41:29 +0000 (12:41 +0200)
src/include/ceph_fs.h
src/kernel/dir.c
src/mds/Server.cc
src/mds/Server.h

index 00b8f214674b032e31cb0beee69f072e2a60d1d3..ef2e6e0167c33e526d1daef34e3a7cad7ba18291 100644 (file)
@@ -337,7 +337,8 @@ enum {
 
        CEPH_MDS_OP_OPEN = 301,
        CEPH_MDS_OP_TRUNCATE = 1303,
-       CEPH_MDS_OP_FSYNC = 303
+       CEPH_MDS_OP_FSYNC = 303,
+       CEPH_MDS_OP_CREATE = 304
 };
 
 struct ceph_mds_request_head {
index 0380509657060eed5113618fa43be9df79004bbc..6e2c41d029e59836e7e55bc079eba1e2c7b5925b 100644 (file)
@@ -518,18 +518,55 @@ static int ceph_dir_rename(struct inode *old_dir, struct dentry *old_dentry,
        return err;
 }
 
-
-/*
-
-
 static int
 ceph_dir_create(struct inode *dir, struct dentry *dentry, int mode,
                struct nameidata *nd)
 {
-}
+    struct ceph_mds_client *mdsc = &ceph_inode_to_client(dir)->mdsc;
+    ceph_ino_t pathbase;
+    char *path;
+    int pathlen;
+    struct ceph_msg *req;
+    struct ceph_mds_request_head *rhead;
+    struct ceph_mds_reply_info rinfo;
+    struct ceph_mds_session *session;
+    int err;
+       struct inode *inode;
+
+    dout(5, "create dir %p dentry %p name '%s' flags %d\n", dir, dentry, dentry->d_name.name, mode);
+    pathbase = dir->i_sb->s_root->d_inode->i_ino;
+    path = ceph_build_dentry_path(dentry, &pathlen);
+    if (IS_ERR(path)) 
+        return PTR_ERR(path);
+    req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_CREATE, pathbase, path, 0, 0); 
+    kfree(path);
+    if (IS_ERR(req)) 
+        return PTR_ERR(req);
+    rhead = req->front.iov_base;
+    rhead->args.open.flags = O_CREAT;
+    rhead->args.open.mode = mode;
+    if ((err = ceph_mdsc_do_request(mdsc, req, &rinfo, &session)) < 0)
+        return err;
+      
+    dout(10, "create got and parsed result\n");
+
+       err = le32_to_cpu(rinfo.head->result);
+       if (err == 0) {
+               err = ceph_fill_trace(dir->i_sb, &rinfo, &inode, NULL);
 
+               if (err < 0) {
+                       goto done_create;
+               }
 
-*/
+               if (inode == NULL) {
+                       err = -ENOMEM;
+                       goto done_create;
+               }
+               dout(10, "rinfo.dir_in=%p rinfo.trace_nr=%d\n", rinfo.trace_in, rinfo.trace_nr);
+       }
+done_create:
+       return err;
+}
 
 const struct inode_operations ceph_dir_iops = {
        .lookup = ceph_dir_lookup,
@@ -541,9 +578,6 @@ const struct inode_operations ceph_dir_iops = {
        .unlink = ceph_dir_unlink,
        .rmdir = ceph_dir_unlink,
        .rename = ceph_dir_rename,
-/*     .create = ceph_dir_create,
-       .getattr = ceph_vfs_getattr,
-       .setattr = ceph_vfs_setattr,
-*/
+       .create = ceph_dir_create,
 };
 
index b3c73ff709dbfe239dbcbc75ac05c94d8f2fbd75..0ef579916da3cb887025e3315d7a780aecf1b67b 100644 (file)
@@ -671,11 +671,14 @@ void Server::dispatch_client_request(MDRequest *mdr)
     // funky.
   case CEPH_MDS_OP_OPEN:
     if (req->head.args.open.flags & O_CREAT)
-      handle_client_openc(mdr);
+      handle_client_openc(mdr, true);
     else 
       handle_client_open(mdr);
     break;
 
+  case CEPH_MDS_OP_CREATE:
+    handle_client_openc(mdr, false);
+    break;
     // namespace.
     // no prior locks.
   case CEPH_MDS_OP_MKNOD:
@@ -4030,10 +4033,11 @@ class C_MDS_openc_finish : public Context {
   MDRequest *mdr;
   CDentry *dn;
   CInode *newi;
+  bool should_open;
   version_t pv;
 public:
-  C_MDS_openc_finish(MDS *m, MDRequest *r, CDentry *d, CInode *ni) :
-    mds(m), mdr(r), dn(d), newi(ni),
+  C_MDS_openc_finish(MDS *m, MDRequest *r, CDentry *d, CInode *ni, bool open) :
+    mds(m), mdr(r), dn(d), newi(ni), should_open(open),
     pv(d->get_projected_version()) {}
   void finish(int r) {
     assert(r == 0);
@@ -4047,17 +4051,22 @@ public:
     // downgrade xlock to rdlock
     //mds->locker->dentry_xlock_downgrade_to_rdlock(dn, mdr);
 
-    // set/pin ref inode for open()
-    mdr->ref = newi;
-    mdr->pin(newi);
+    if (should_open) {
+      // set/pin ref inode for open()
+      mdr->ref = newi;
+      mdr->pin(newi);
     
-    // ok, do the open.
-    mds->server->handle_client_open(mdr);
+      // ok, do the open.
+      mds->server->handle_client_open(mdr);
+    } else {
+      MClientReply *reply = new MClientReply(mdr->client_request);
+      mds->server->reply_request(mdr, reply, newi);
+    }
   }
 };
 
 
-void Server::handle_client_openc(MDRequest *mdr)
+void Server::handle_client_openc(MDRequest *mdr, bool open)
 {
   MClientRequest *req = mdr->client_request;
 
@@ -4076,7 +4085,12 @@ void Server::handle_client_openc(MDRequest *mdr)
     } 
     
     // pass to regular open handler.
-    handle_client_open(mdr);
+    if (open) {
+      handle_client_open(mdr);
+    } else {
+         MClientReply *reply = new MClientReply(req);
+         reply_request(mdr, reply, dn->get_dir()->get_inode());
+    }
     return;
   }
 
@@ -4093,7 +4107,7 @@ void Server::handle_client_openc(MDRequest *mdr)
   in->inode.version = dn->pre_dirty() - 1;
   
   // prepare finisher
-  C_MDS_openc_finish *fin = new C_MDS_openc_finish(mds, mdr, dn, in);
+  C_MDS_openc_finish *fin = new C_MDS_openc_finish(mds, mdr, dn, in, open);
   mdr->ls = mdlog->get_current_segment();
   EUpdate *le = new EUpdate(mdlog, "openc");
   le->metablob.add_client_req(req->get_reqid());
index 10e96870c4c3bb95278e8625a105e6ef249524c3..220f81d746f16ce8c3027848d1933dcd716a0bb5 100644 (file)
@@ -110,7 +110,7 @@ public:
 
   // open
   void handle_client_open(MDRequest *mdr);
-  void handle_client_openc(MDRequest *mdr);  // O_CREAT variant.
+  void handle_client_openc(MDRequest *mdr, bool open);  // O_CREAT variant.
   void handle_client_opent(MDRequest *mdr);  // O_TRUNC variant.
   void _do_open(MDRequest *mdr, CInode *ref);