]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: allow dir layout/policy to be removed via removexattr on ceph.dir.layout
authorSage Weil <sage@inktank.com>
Sat, 19 Jan 2013 18:11:18 +0000 (10:11 -0800)
committerSage Weil <sage@inktank.com>
Wed, 30 Jan 2013 00:25:05 +0000 (16:25 -0800)
This lets a user remove a policy that was previously set on a dir.

Signed-off-by: Sage Weil <sage@inktank.com>
src/mds/Server.cc
src/mds/Server.h

index bbda20f1522cd13efd8e1d1fc60e1384bfdc8c19..900f1f5290dec5ad719c016bb0e6e7c4c6198997 100644 (file)
@@ -3627,6 +3627,51 @@ void Server::handle_set_vxattr(MDRequest *mdr, CInode *cur,
   reply_request(mdr, -EINVAL);
 }
 
+void Server::handle_remove_vxattr(MDRequest *mdr, CInode *cur,
+                                 set<SimpleLock*> rdlocks,
+                                 set<SimpleLock*> wrlocks,
+                                 set<SimpleLock*> xlocks)
+{
+  MClientRequest *req = mdr->client_request;
+  string name(req->get_path2());
+  if (name == "ceph.dir.layout") {
+    if (!cur->is_dir()) {
+      reply_request(mdr, -ENODATA);
+      return;
+    }
+    if (cur->is_root()) {
+      dout(10) << "can't remove layout policy on the root directory" << dendl;
+      reply_request(mdr, -EINVAL);
+      return;
+    }
+
+    if (!cur->get_projected_dir_layout()) {
+      reply_request(mdr, -ENODATA);
+      return;
+    }
+
+    xlocks.insert(&cur->policylock);
+    if (!mds->locker->acquire_locks(mdr, rdlocks, wrlocks, xlocks))
+      return;
+
+    cur->project_inode();
+    cur->get_projected_node()->dir_layout = NULL;
+    cur->get_projected_inode()->version = cur->pre_dirty();
+
+    // log + wait
+    mdr->ls = mdlog->get_current_segment();
+    EUpdate *le = new EUpdate(mdlog, "remove dir layout vxattr");
+    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));
+    return;
+  }
+
+  reply_request(mdr, -ENODATA);
+}
 
 class C_MDS_inode_xattr_update_finish : public Context {
   MDS *mds;
@@ -3726,25 +3771,35 @@ void Server::handle_client_setxattr(MDRequest *mdr)
 void Server::handle_client_removexattr(MDRequest *mdr)
 {
   MClientRequest *req = mdr->client_request;
+  string name(req->get_path2());
   set<SimpleLock*> rdlocks, wrlocks, xlocks;
-  CInode *cur = rdlock_path_pin_ref(mdr, 0, rdlocks, true);
-  if (!cur) return;
+  ceph_file_layout *dir_layout = NULL;
+  CInode *cur;
+  if (name == "ceph.dir.layout")
+    cur = rdlock_path_pin_ref(mdr, 0, rdlocks, true, false, &dir_layout);
+  else
+    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_base()) {
+  if (cur->is_base()) {
     reply_request(mdr, -EINVAL);   // for now
     return;
   }
 
+  if (name.find("ceph.") == 0) {
+    handle_remove_vxattr(mdr, cur, rdlocks, wrlocks, xlocks);
+    return;
+  }
+
   xlocks.insert(&cur->xattrlock);
   if (!mds->locker->acquire_locks(mdr, rdlocks, wrlocks, xlocks))
     return;
 
-  string name(req->get_path2());
-
   map<string, bufferptr> *pxattrs = cur->get_projected_xattrs();
   if (pxattrs->count(name) == 0) {
     dout(10) << "removexattr '" << name << "' and ENODATA on " << *cur << dendl;
index 83dd318347d4dcb5a23c301a971073e549ef0ad2..79977fc8dd54cf1115b07ce93e854160af97108f 100644 (file)
@@ -159,6 +159,10 @@ public:
                         set<SimpleLock*> rdlocks,
                         set<SimpleLock*> wrlocks,
                         set<SimpleLock*> xlocks);
+  void handle_remove_vxattr(MDRequest *mdr, CInode *cur,
+                           set<SimpleLock*> rdlocks,
+                           set<SimpleLock*> wrlocks,
+                           set<SimpleLock*> xlocks);
   void handle_client_setxattr(MDRequest *mdr);
   void handle_client_removexattr(MDRequest *mdr);