]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: fix cow_old_inode to properly save xattrs
authorSage Weil <sage@newdream.net>
Tue, 24 Aug 2010 18:57:19 +0000 (11:57 -0700)
committerSage Weil <sage@newdream.net>
Tue, 24 Aug 2010 19:15:05 +0000 (12:15 -0700)
src/mds/CInode.cc
src/mds/CInode.h
src/mds/Locker.cc
src/mds/MDCache.cc

index 029797f63a736d85e2335ac1629e4f0a3212ab7c..8e01aec0a6442f7fb4003a1e7c28074216d12255 100644 (file)
@@ -1561,15 +1561,20 @@ snapid_t CInode::get_oldest_snap()
   return MIN(t, first);
 }
 
-old_inode_t& CInode::cow_old_inode(snapid_t follows, inode_t *pi)
+old_inode_t& CInode::cow_old_inode(snapid_t follows, bool cow_head)
 {
   assert(follows >= first);
 
+  inode_t *pi = cow_head ? get_projected_inode() : get_previous_projected_inode();
+  map<string,bufferptr> *px = cow_head ? get_projected_xattrs() : get_previous_projected_xattrs();
+
   old_inode_t &old = old_inodes[follows];
   old.first = first;
   old.inode = *pi;
-  old.xattrs = *get_previous_projected_xattrs();
+  old.xattrs = *px;
   
+  dout(10) << " " << px->size() << " xattrs cowed, " << *px << dendl;
+
   old.inode.trim_client_ranges(follows);
 
   if (!(old.inode.rstat == old.inode.accounted_rstat))
@@ -1577,7 +1582,8 @@ old_inode_t& CInode::cow_old_inode(snapid_t follows, inode_t *pi)
   
   first = follows+1;
 
-  dout(10) << "cow_old_inode to [" << old.first << "," << follows << "] on "
+  dout(10) << "cow_old_inode " << (cow_head ? "head" : "previous_head" )
+          << " to [" << old.first << "," << follows << "] on "
           << *this << dendl;
 
   return old;
@@ -1587,7 +1593,7 @@ void CInode::pre_cow_old_inode()
 {
   snapid_t follows = find_snaprealm()->get_newest_seq();
   if (first <= follows)
-    cow_old_inode(follows, get_projected_inode());
+    cow_old_inode(follows, true);
 }
 
 void CInode::purge_stale_snap_data(const set<snapid_t>& snaps)
@@ -1798,12 +1804,13 @@ int CInode::encode_inodestat(bufferlist& bl, Session *session,
   // xattr
   i = pxattr ? pi:oi;
   bool had_latest_xattrs = cap && (cap->issued() & CEPH_CAP_XATTR_SHARED) &&
-    cap->client_xattr_version == i->xattr_version;
+    cap->client_xattr_version == i->xattr_version &&
+    snapid == CEPH_NOSNAP;
 
   // xattr
   bufferlist xbl;
   e.xattr_version = i->xattr_version;
-  if (!had_latest_xattrs && cap) {
+  if (!had_latest_xattrs) {
     if (!pxattrs)
       pxattrs = pxattr ? get_projected_xattrs() : &xattrs;
     ::encode(*pxattrs, xbl);
@@ -1893,16 +1900,18 @@ int CInode::encode_inodestat(bufferlist& bl, Session *session,
   }
   e.cap.flags = is_auth() ? CEPH_CAP_FLAG_AUTH:0;
   dout(10) << "encode_inodestat caps " << ccap_string(e.cap.caps)
-          << " seq " << e.cap.seq
-          << " mseq " << e.cap.mseq << dendl;
+          << " seq " << e.cap.seq << " mseq " << e.cap.mseq
+          << " xattrv " << e.xattr_version << " len " << xbl.length()
+          << dendl;
 
   // include those xattrs?
-  if (xbl.length()) {
-    if (cap && (cap->pending() & CEPH_CAP_XATTR_SHARED)) {
+  if (xbl.length() && cap) {
+    if (cap->pending() & CEPH_CAP_XATTR_SHARED) {
       dout(10) << "including xattrs version " << i->xattr_version << dendl;
       cap->client_xattr_version = i->xattr_version;
     } else {
-      xbl.clear(); // no xattrs
+      dout(10) << "dropping xattrs version " << i->xattr_version << dendl;
+      xbl.clear(); // no xattrs .. XXX what's this about?!?
     }
   }
 
index 3758a03114452d4191b5563603af0138f7624bbd..a7e22796dce2f38d1cf23c764b91bda14a1eecab 100644 (file)
@@ -279,7 +279,7 @@ private:
   void pop_projected_snaprealm(sr_t *next_snaprealm);
 
 public:
-  old_inode_t& cow_old_inode(snapid_t follows, inode_t *pi);
+  old_inode_t& cow_old_inode(snapid_t follows, bool cow_head);
   old_inode_t *pick_old_inode(snapid_t last);
   void pre_cow_old_inode();
   void purge_stale_snap_data(const set<snapid_t>& snaps);
index cf8f38b409912e8d16eb290239e6551ca052ae6a..856cbd7c0c1ffaef6f11dd534768c047ad68e2fa 100644 (file)
@@ -2057,29 +2057,37 @@ void Locker::_do_snap_update(CInode *in, int dirty, snapid_t follows, client_t c
 
   // normal metadata updates that we can apply to the head as well.
 
-  // xattrs update?
+  // update xattrs?
+  bool xattrs = false;
   map<string,bufferptr> *px = 0;
   if ((dirty & CEPH_CAP_XATTR_EXCL) && 
       m->xattrbl.length() &&
       m->head.xattr_version > in->get_projected_inode()->xattr_version)
-    px = new map<string,bufferptr>;
-
-  inode_t *pi = in->project_inode(px);
-  pi->version = in->pre_dirty();
+    xattrs = true;
 
+  old_inode_t *oi = 0;
   if (in->is_multiversion()) {
-    old_inode_t *oi = in->pick_old_inode(snap);
+    oi = in->pick_old_inode(snap);
     if (oi) {
       dout(10) << " writing into old inode" << dendl;
-      pi = &oi->inode;
+      if (xattrs)
+       px = &oi->xattrs;
     }
-  }      
+  }
+  if (xattrs && !px)
+    px = new map<string,bufferptr>;
+
+  inode_t *pi = in->project_inode(px);
+  pi->version = in->pre_dirty();
+  if (oi)
+    pi = &oi->inode;
 
   _update_cap_fields(in, dirty, m, pi);
 
   // xattr
   if (px) {
-    dout(7) << " xattrs v" << pi->xattr_version << " -> " << m->head.xattr_version << dendl;
+    dout(7) << " xattrs v" << pi->xattr_version << " -> " << m->head.xattr_version
+           << " len " << m->xattrbl.length() << dendl;
     pi->xattr_version = m->head.xattr_version;
     bufferlist::iterator p = m->xattrbl.begin();
     ::decode(*px, p);
index ee5f7ceacc92ffbe9631a31ea2c0ec17bb39098b..d4ee46e04816664ac111db14e5b397597b7c861a 100644 (file)
@@ -1344,7 +1344,7 @@ void MDCache::journal_cow_dentry(Mutation *mut, EMetaBlob *metablob, CDentry *dn
       return;
     }
 
-    in->cow_old_inode(follows, in->get_previous_projected_inode());
+    in->cow_old_inode(follows, false);
 
   } else {
     if (follows == CEPH_NOSNAP)
@@ -1537,8 +1537,6 @@ void MDCache::project_rstat_frag_to_inode(nest_info_t& rstat, nest_info_t& accou
 
   accounted_rstat = rstat;
 
-  inode_t *pi_to_cow = cow_head ? pin->get_projected_inode() : pin->get_previous_projected_inode();
-
   while (last >= ofirst) {
     inode_t *pi;
     snapid_t first;
@@ -1546,13 +1544,13 @@ void MDCache::project_rstat_frag_to_inode(nest_info_t& rstat, nest_info_t& accou
       pi = pin->get_projected_inode();
       first = MAX(ofirst, pin->first);
       if (first > pin->first) {
-       old_inode_t& old = pin->cow_old_inode(first-1, pi_to_cow);
+       old_inode_t& old = pin->cow_old_inode(first-1, cow_head);
        dout(20) << "   cloned old_inode rstat is " << old.inode.rstat << dendl;
       }
     } else {
       if (last >= pin->first) {
        first = pin->first;
-       pin->cow_old_inode(last, pi_to_cow);
+       pin->cow_old_inode(last, cow_head);
       } else {
        // our life is easier here because old_inodes is not sparse
        // (although it may not begin at snapid 1)