diff options
author | Sage Weil <sage@inktank.com> | 2013-01-19 10:11:18 -0800 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-02-04 22:05:28 -0800 |
commit | d386622c3961a3b57eea42fdb82611cd2e904f4d (patch) | |
tree | 81881d3baf2aaa460ff33ca2c60a3d875504e958 | |
parent | 6af5da7ae2c4ef95c16c6460770b6244d1aa1a6e (diff) | |
download | ceph-d386622c3961a3b57eea42fdb82611cd2e904f4d.tar.gz |
mds: allow dir layout/policy to be removed via removexattr on ceph.dir.layout
This lets a user remove a policy that was previously set on a dir.
Signed-off-by: Sage Weil <sage@inktank.com>
(cherry picked from commit db31a1f9f27416e4d531fda716e32d42a275e84f)
-rw-r--r-- | src/mds/Server.cc | 65 | ||||
-rw-r--r-- | src/mds/Server.h | 4 |
2 files changed, 64 insertions, 5 deletions
diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 0f74349f90e..c17fc8d0050 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -3508,6 +3508,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; @@ -3607,25 +3652,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; diff --git a/src/mds/Server.h b/src/mds/Server.h index d4732bd5da5..d5ee05253a9 100644 --- a/src/mds/Server.h +++ b/src/mds/Server.h @@ -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); |