]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: Implement op CEPH_MDS_OP_SETDIRLAYOUT.
authorGreg Farnum <gregf@hq.newdream.net>
Fri, 24 Sep 2010 00:13:05 +0000 (17:13 -0700)
committerGreg Farnum <gregf@hq.newdream.net>
Mon, 4 Oct 2010 17:42:36 +0000 (10:42 -0700)
Implement handler functions, add to inode projection machinery, etc.

src/include/ceph_fs.h
src/mds/CInode.cc
src/mds/CInode.h
src/mds/Server.cc
src/mds/Server.h

index ba122f3794f51d653f1578fe214c77ff96bda9fc..83953f77dde7378201a0adb316f19f16f6f60ca3 100644 (file)
@@ -305,6 +305,7 @@ enum {
        CEPH_MDS_OP_SETATTR    = 0x01108,
        CEPH_MDS_OP_SETFILELOCK= 0x01109,
        CEPH_MDS_OP_GETFILELOCK= 0x00110,
+       CEPH_MDS_OP_SETDIRLAYOUT=0x0110a,
 
        CEPH_MDS_OP_MKNOD      = 0x01201,
        CEPH_MDS_OP_LINK       = 0x01202,
index bb5c9d18b92710bd8705f6a4da180b543028b5ad..bdc5aebbd227c42f6b8b043770fc08f39153bba8 100644 (file)
@@ -227,6 +227,7 @@ inode_t *CInode::project_inode(map<string,bufferptr> *px)
     projected_nodes.push_back(new projected_inode_t(new inode_t(inode)));
     if (px)
       *px = xattrs;
+    projected_nodes.back()->dir_layout = default_layout;
   } else {
     projected_nodes.push_back(new projected_inode_t(
         new inode_t(*projected_nodes.back()->inode)));
@@ -252,6 +253,11 @@ void CInode::pop_and_dirty_projected_inode(LogSegment *ls)
     delete px;
   }
 
+  if (projected_nodes.front()->dir_layout != default_layout) {
+    delete default_layout;
+    default_layout = projected_nodes.front()->dir_layout;
+  }
+
   if (projected_nodes.front()->snapnode)
     pop_projected_snaprealm(projected_nodes.front()->snapnode);
 
index f775b967af927df1dde3c8ee34e363c1009a537d..30774e2bbe7ccf7856c3b4e44db581a3bb278273 100644 (file)
@@ -232,6 +232,7 @@ public:
     inode_t *inode;
     map<string,bufferptr> *xattrs;
     sr_t *snapnode;
+    default_file_layout *dir_layout;
 
     projected_inode_t() : inode(NULL), xattrs(NULL), snapnode(NULL) {}
     projected_inode_t(inode_t *in, sr_t *sn) : inode(in), xattrs(NULL), snapnode(sn) {}
@@ -243,6 +244,26 @@ public:
   inode_t *project_inode(map<string,bufferptr> *px=0);
   void pop_and_dirty_projected_inode(LogSegment *ls);
 
+  projected_inode_t *get_projected_node() {
+    if (projected_nodes.empty())
+      return NULL;
+    else
+      return projected_nodes.back();
+  }
+
+  ceph_file_layout *get_projected_dir_layout() {
+    if (!inode.is_dir()) return NULL;
+    if (projected_nodes.empty()) {
+      if (default_layout)
+        return &default_layout->layout;
+      else
+        return NULL;
+    }
+    else if (projected_nodes.back()->dir_layout)
+      return &projected_nodes.back()->dir_layout->layout;
+    else return NULL;
+  }
+
   version_t get_projected_version() {
     if (projected_nodes.empty())
       return inode.version;
index 279d9f01247eaeaa201f0290ada275a0f7c7d61a..41c2cf30fd18e24ede6ca4576a39438376d7063f 100644 (file)
@@ -1147,6 +1147,9 @@ void Server::dispatch_client_request(MDRequest *mdr)
   case CEPH_MDS_OP_SETLAYOUT:
     handle_client_setlayout(mdr);
     break;
+  case CEPH_MDS_OP_SETDIRLAYOUT:
+    handle_client_setdirlayout(mdr);
+    break;
   case CEPH_MDS_OP_SETXATTR:
     handle_client_setxattr(mdr);
     break;
@@ -2959,6 +2962,69 @@ void Server::handle_client_setlayout(MDRequest *mdr)
   journal_and_reply(mdr, cur, 0, le, new C_MDS_inode_update_finish(mds, mdr, cur));
 }
 
+void Server::handle_client_setdirlayout(MDRequest *mdr)
+{
+  MClientRequest *req = mdr->client_request;
+  set<SimpleLock*> rdlocks, wrlocks, xlocks;
+  CInode *cur = rdlock_path_pin_ref(mdr, 0, rdlocks, true);
+  if (!cur) return;
+
+  if (mdr->snapid != CEPH_NOSNAP) {
+    reply_request(mdr, -EROFS);
+    return;
+  }
+
+  if (!cur->is_dir()) {
+    reply_request(mdr, -ENOTDIR);
+    return;
+  }
+
+  xlocks.insert(&cur->policylock);
+  if (!mds->locker->acquire_locks(mdr, rdlocks, wrlocks, xlocks))
+    return;
+
+  // validate layout
+  default_file_layout *layout = new default_file_layout;
+  if (cur->get_projected_dir_layout())
+    layout->layout = *cur->get_projected_dir_layout();
+  else
+    layout->layout = g_default_file_layout;
+
+  if (req->head.args.setlayout.layout.fl_object_size > 0)
+    layout->layout.fl_object_size = req->head.args.setlayout.layout.fl_object_size;
+  if (req->head.args.setlayout.layout.fl_stripe_unit > 0)
+    layout->layout.fl_stripe_unit = req->head.args.setlayout.layout.fl_stripe_unit;
+  if (req->head.args.setlayout.layout.fl_stripe_count > 0)
+    layout->layout.fl_stripe_count=req->head.args.setlayout.layout.fl_stripe_count;
+  if (req->head.args.setlayout.layout.fl_cas_hash > 0)
+    layout->layout.fl_cas_hash = req->head.args.setlayout.layout.fl_cas_hash;
+  if (req->head.args.setlayout.layout.fl_object_stripe_unit > 0)
+    layout->layout.fl_object_stripe_unit = req->head.args.setlayout.layout.fl_object_stripe_unit;
+  if (req->head.args.setlayout.layout.fl_pg_preferred > 0)
+    layout->layout.fl_pg_preferred = req->head.args.setlayout.layout.fl_pg_preferred;
+  if (req->head.args.setlayout.layout.fl_pg_pool > 0)
+    layout->layout.fl_pg_pool = req->head.args.setlayout.layout.fl_pg_pool;
+  if (!ceph_file_layout_is_valid(&layout->layout)) {
+    dout(10) << "bad layout" << dendl;
+    reply_request(mdr, -EINVAL);
+    return;
+  }
+
+  cur->project_inode();
+  cur->get_projected_node()->dir_layout = layout;
+  cur->get_projected_inode()->version = cur->pre_dirty();
+
+  // log + wait
+  mdr->ls = mdlog->get_current_segment();
+  EUpdate *le = new EUpdate(mdlog, "setlayout");
+  mdlog->start_entry(le);
+  le->metablob.add_client_req(req->get_reqid(), req->get_oldest_client_tid());
+  mdcache->predirty_journal_parents(mdr, &le->metablob, cur, 0, PREDIRTY_PRIMARY, false);
+  mdcache->journal_dirty_inode(mdr, &le->metablob, cur);
+
+  journal_and_reply(mdr, cur, 0, le, new C_MDS_inode_update_finish(mds, mdr, cur));
+}
+
 
 
 
index 444339de7dd1ecd83150d93e435da6108dba6135..61dbbd860c5f771dd8a7c40bb4fe2e9691ada41b 100644 (file)
@@ -141,6 +141,7 @@ public:
 
   void handle_client_setattr(MDRequest *mdr);
   void handle_client_setlayout(MDRequest *mdr);
+  void handle_client_setdirlayout(MDRequest *mdr);
   void handle_client_setxattr(MDRequest *mdr);
   void handle_client_removexattr(MDRequest *mdr);