]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: fix xattr projection
authorSage Weil <sage@newdream.net>
Wed, 31 Dec 2008 17:15:34 +0000 (09:15 -0800)
committerSage Weil <sage@newdream.net>
Wed, 31 Dec 2008 17:15:34 +0000 (09:15 -0800)
We do not want the new xattr to appear in the inode until the journal
entry commits.

src/TODO
src/mds/Server.cc

index 771d72053541731d2965889bc04a4f3cae02438a..63ae1c6e1d7a30864ff4a7c500c738fa47d7e96b 100644 (file)
--- a/src/TODO
+++ b/src/TODO
@@ -105,7 +105,6 @@ userspace client
 
 mds
 - xlock vs wrlock.. need more lock states?
-- xattrs need to be properly projected.  should we just expand inode_t?  or make some smarter thing?
 - dftlock is missing from rejoin phase
 - file size recovery gives (wrong) 4MB-increment results?
 - hard link backpointers
index 010a1900472f48e0fc2f555dd704c36cf764515c..f27e89270b04d451fadd467f08820b720f020526 100644 (file)
@@ -1979,6 +1979,31 @@ void Server::handle_client_setlayout(MDRequest *mdr)
 
 // XATTRS
 
+class C_MDS_inode_xattr_update_finish : public Context {
+  MDS *mds;
+  MDRequest *mdr;
+  CInode *in;
+public:
+  map<string, bufferptr> xattrs;
+
+  C_MDS_inode_xattr_update_finish(MDS *m, MDRequest *r, CInode *i) :
+    mds(m), mdr(r), in(i) { }
+  void finish(int r) {
+    assert(r == 0);
+
+    // apply
+    in->pop_and_dirty_projected_inode(mdr->ls);
+    
+    in->xattrs.swap(xattrs);
+
+    mdr->apply();
+
+    mds->balancer->hit_inode(mdr->now, in, META_POP_IWR);   
+
+    mds->server->reply_request(mdr, 0);
+  }
+};
+
 void Server::handle_client_setxattr(MDRequest *mdr)
 {
   MClientRequest *req = mdr->client_request;
@@ -2029,15 +2054,21 @@ void Server::handle_client_setxattr(MDRequest *mdr)
   mdcache->predirty_journal_parents(mdr, &le->metablob, cur, 0, PREDIRTY_PRIMARY, false);
 
   mdcache->journal_cow_inode(mdr, &le->metablob, cur);
+
+  C_MDS_inode_xattr_update_finish *fin = new C_MDS_inode_xattr_update_finish(mds, mdr, cur);
+  fin->xattrs = cur->xattrs;
+
   cur->xattrs.erase(name);
   cur->xattrs[name] = buffer::create(len);
   if (len)
     req->get_data().copy(0, len, cur->xattrs[name].c_str());
   le->metablob.add_primary_dentry(cur->get_projected_parent_dn(), true, cur, pi);
-  
+
   early_reply(mdr, cur, 0);
 
-  mdlog->submit_entry(le, new C_MDS_inode_update_finish(mds, mdr, cur));
+  fin->xattrs.swap(cur->xattrs);
+
+  mdlog->submit_entry(le, fin);
 }
 
 void Server::handle_client_removexattr(MDRequest *mdr)
@@ -2082,12 +2113,18 @@ void Server::handle_client_removexattr(MDRequest *mdr)
   mdcache->predirty_journal_parents(mdr, &le->metablob, cur, 0, PREDIRTY_PRIMARY, false);
 
   mdcache->journal_cow_inode(mdr, &le->metablob, cur);
+
+  C_MDS_inode_xattr_update_finish *fin = new C_MDS_inode_xattr_update_finish(mds, mdr, cur);
+  fin->xattrs = cur->xattrs;
+
   cur->xattrs.erase(name);
   le->metablob.add_primary_dentry(cur->get_projected_parent_dn(), true, cur, pi);
 
   early_reply(mdr, cur, 0);
 
-  mdlog->submit_entry(le, new C_MDS_inode_update_finish(mds, mdr, cur));
+  fin->xattrs.swap(cur->xattrs);
+
+  mdlog->submit_entry(le, fin);
 }