]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: add new CDentry tags support
authorXiubo Li <xiubli@redhat.com>
Wed, 23 Sep 2020 02:54:34 +0000 (10:54 +0800)
committerPatrick Donnelly <pdonnell@redhat.com>
Sat, 16 Jan 2021 01:30:39 +0000 (17:30 -0800)
This will add new tag 'i' for inode and new tag 'l' for remote link
for the CDentry. And at the same time will add one proper dentry
version, which will be helpful to add new features/members in future
for the CDentry.

Fixes: https://tracker.ceph.com/issues/47162
Signed-off-by: Xiubo Li <xiubli@redhat.com>
PendingReleaseNotes
src/mds/CDir.cc
src/mds/CDir.h
src/mds/Migrator.cc
src/tools/cephfs/DataScan.cc
src/tools/cephfs/JournalTool.cc
src/tools/cephfs/MetaTool.cc

index e9f3581222a4ca97473a8b094a565762619a1a28..c981c82942a690974006b7a758e71ae154d0718e 100644 (file)
@@ -3,6 +3,10 @@
 * New bluestore_rocksdb_options_annex config parameter. Complements
   bluestore_rocksdb_options and allows setting rocksdb options without repeating
   the existing defaults.
+* The cephfs addes two new CDentry tags, 'I' --> 'i' and 'L' --> 'l', and
+  on-RADOS metadata is no longer backwards compatible after upgraded to Pacific
+  or a later release.
+
 * $pid expansion in config paths like `admin_socket` will now properly expand
   to the daemon pid for commands like `ceph-mds` or `ceph-osd`. Previously only
   `ceph-fuse`/`rbd-nbd` expanded `$pid` with the actual daemon pid.
index a6194fcd23f43166887cc7bcf34d390e31abc572..610796f76747f279f6d6184493aafc515e17f64d 100644 (file)
@@ -1762,12 +1762,20 @@ CDentry *CDir::_load_dentry(
   else
     dn = lookup(dname, last);
 
-  if (type == 'L') {
+  if (type == 'L' || type == 'l') {
     // hard link
     inodeno_t ino;
     unsigned char d_type;
-    decode(ino, q);
-    decode(d_type, q);
+
+    if (type == 'l') {
+      DECODE_START(1, q);
+      decode(ino, q);
+      decode(d_type, q);
+      DECODE_FINISH(q);
+    } else {
+      decode(ino, q);
+      decode(d_type, q);
+    }
 
     if (stale) {
       if (!dn) {
@@ -1803,12 +1811,17 @@ CDentry *CDir::_load_dentry(
       }
     }
   }
-  else if (type == 'I') {
+  else if (type == 'I' || type == 'i') {
+    InodeStore inode_data;
     // inode
-
     // Load inode data before looking up or constructing CInode
-    InodeStore inode_data;
-    inode_data.decode_bare(q);
+    if (type == 'i') {
+      DECODE_START(1, q);
+      inode_data.decode(q);
+      DECODE_FINISH(q);
+    } else {
+      inode_data.decode_bare(q);
+    }
 
     if (stale) {
       if (!dn) {
@@ -2190,6 +2203,42 @@ private:
   mempool::mds_co::compact_set<mempool::mds_co::string> stale_items;
 };
 
+// This is doing the same thing with the InodeStoreBase::encode()
+void CDir::_encode_primary_inode_base(dentry_commit_item &item, bufferlist &dfts,
+                                      bufferlist &bl)
+{
+  ENCODE_START(6, 4, bl);
+  encode(*item.inode, bl, item.features);
+
+  if (!item.symlink.empty())
+    encode(item.symlink, bl);
+
+  // dirfragtree
+  dfts.splice(0, item.dft_len, &bl);
+
+  if (item.xattrs)
+    encode(*item.xattrs, bl);
+  else
+    encode((__u32)0, bl);
+
+  if (item.snaprealm) {
+    bufferlist snapr_bl;
+    encode(item.srnode, snapr_bl);
+    encode(snapr_bl, bl);
+  } else {
+    encode(bufferlist(), bl);
+  }
+
+  if (item.old_inodes)
+    encode(*item.old_inodes, bl, item.features);
+  else
+    encode((__u32)0, bl);
+
+  encode(item.oldest_snap, bl);
+  encode(item.damage_flags, bl);
+  ENCODE_FINISH(bl);
+}
+
 // This is not locked by mds_lock
 void CDir::_omap_commit_ops(int r, int op_prio, int64_t metapool, version_t version, bool _new,
                            vector<dentry_commit_item> &to_set, bufferlist &dfts,
@@ -2276,40 +2325,19 @@ void CDir::_omap_commit_ops(int r, int op_prio, int64_t metapool, version_t vers
   for (auto &item : to_set) {
     encode(item.first, bl);
     if (item.is_remote) {
-      bl.append('L');         // remote link
+      // marker, name, ino
+      bl.append('l');         // remote link
+      ENCODE_START(1, 1, bl);
       encode(item.ino, bl);
       encode(item.d_type, bl);
+      ENCODE_FINISH(bl);
     } else {
-      bl.append('I');         // inode
-
-      encode(*item.inode, bl, item.features);
-
-      if (!item.symlink.empty())
-        encode(item.symlink, bl);
-
-      // dirfragtree
-      dfts.splice(0, item.dft_len, &bl);
-
-      if (item.xattrs)
-        encode(*item.xattrs, bl);
-      else
-        encode((__u32)0, bl);
-
-      if (item.snaprealm) {
-        bufferlist snapr_bl;
-        encode(item.srnode, snapr_bl);
-        encode(snapr_bl, bl);
-      } else {
-        encode(bufferlist(), bl);
-      }
-
-      if (item.old_inodes)
-        encode(*item.old_inodes, bl, item.features);
-      else
-        encode((__u32)0, bl);
+      // marker, name, inode, [symlink string]
+      bl.append('i');         // inode
 
-      encode(item.oldest_snap, bl);
-      encode(item.damage_flags, bl);
+      ENCODE_START(1, 1, bl);
+      _encode_primary_inode_base(item, dfts, bl);
+      ENCODE_FINISH(bl);
     }
     off += item.dft_len;
 
@@ -2439,7 +2467,6 @@ void CDir::_parse_dentry(CDentry *dn, dentry_commit_item &item,
     ceph_assert(in);
 
     dout(14) << " dn '" << dn->get_name() << "' inode " << *in << dendl;
-    // marker, name, inode, [symlink string]
 
     if (in->is_multiversion()) {
       if (!in->snaprealm) {
index 25c5f0e3d0992c057ef53cb57b2330d02bd25df3..030d9c949cbddee0e62efdbfa0cf0c2411c094b0 100644 (file)
@@ -675,6 +675,8 @@ protected:
                        vector<dentry_commit_item> &to_set, bufferlist &dfts,
                        vector<string> &to_remove,
                        mempool::mds_co::compact_set<mempool::mds_co::string> &_stale);
+  void _encode_primary_inode_base(dentry_commit_item &item, bufferlist &dfts,
+                                  bufferlist &bl);
   void _omap_commit(int op_prio);
   void _parse_dentry(CDentry *dn, dentry_commit_item &item,
                      const set<snapid_t> *snaps, bufferlist &bl);
index c6ee67b24dc72e938033b3938d96a54fca1a9a29..f2c2d33fecc16d885a32e61a7482936a971c2ce9 100644 (file)
@@ -1792,20 +1792,24 @@ void Migrator::encode_export_dir(bufferlist& exportbl,
     
     if (dn->get_linkage()->is_remote()) {
       // remote link
-      exportbl.append("L", 1);  // remote link
+      exportbl.append("l", 1);  // remote link
       
       inodeno_t ino = dn->get_linkage()->get_remote_ino();
       unsigned char d_type = dn->get_linkage()->get_remote_d_type();
+      ENCODE_START(1, 1, exportbl);
       encode(ino, exportbl);
       encode(d_type, exportbl);
+      ENCODE_FINISH(exportbl);
       continue;
     }
 
     // primary link
     // -- inode
-    exportbl.append("I", 1);    // inode dentry
-    
+    exportbl.append("i", 1);    // inode dentry
+
+    ENCODE_START(1, 1, exportbl);
     encode_export_inode(in, exportbl, exported_client_map, exported_client_metadata_map);  // encode, and (update state for) export
+    ENCODE_FINISH(exportbl);
 
     // directory?
     auto&& dfs = in->get_dirfrags();
@@ -3443,23 +3447,37 @@ void Migrator::decode_import_dir(bufferlist::const_iterator& blp,
       
       // fall thru
     }
-    else if (icode == 'L') {
+    else if (icode == 'L' || icode == 'l') {
       // remote link
       inodeno_t ino;
       unsigned char d_type;
-      decode(ino, blp);
-      decode(d_type, blp);
+      if (icode == 'l') {
+        DECODE_START(1, blp);
+        decode(ino, blp);
+        decode(d_type, blp);
+        DECODE_FINISH(blp);
+      } else {
+        decode(ino, blp);
+        decode(d_type, blp);
+      }
       if (dn->get_linkage()->is_remote()) {
        ceph_assert(dn->get_linkage()->get_remote_ino() == ino);
       } else {
        dir->link_remote_inode(dn, ino, d_type);
       }
     }
-    else if (icode == 'I') {
+    else if (icode == 'I' || icode == 'i') {
       // inode
       ceph_assert(le);
-      decode_import_inode(dn, blp, oldauth, ls,
-                         peer_exports, updated_scatterlocks);
+      if (icode == 'i') {
+        DECODE_START(1, blp);
+        decode_import_inode(dn, blp, oldauth, ls,
+                            peer_exports, updated_scatterlocks);
+        DECODE_FINISH(blp);
+      } else {
+        decode_import_inode(dn, blp, oldauth, ls,
+                            peer_exports, updated_scatterlocks);
+      }
     }
     
     // add dentry to journal entry
index d279f283c2dd248af3ea8034538e6fb71db265f2..d19a6ece02af7e40b703e697adfd304f135a81fa 100644 (file)
@@ -989,9 +989,16 @@ int DataScan::scan_links()
          }
          char dentry_type;
          decode(dentry_type, q);
-         if (dentry_type == 'I') {
+         if (dentry_type == 'I' || dentry_type == 'i') {
            InodeStore inode;
-           inode.decode_bare(q);
+            if (dentry_type == 'i') {
+             DECODE_START(1, q);
+             inode.decode(q);
+             DECODE_FINISH(q);
+           } else {
+             inode.decode_bare(q);
+           }
+
            inodeno_t ino = inode.inode->ino;
 
            if (step == SCAN_INOS) {
@@ -1048,11 +1055,18 @@ int DataScan::scan_links()
              if (dnfirst == CEPH_NOSNAP)
                injected_inos[ino] = link_info_t(dir_ino, frag_id, dname, inode.inode);
            }
-         } else if (dentry_type == 'L') {
+         } else if (dentry_type == 'L' || dentry_type == 'l') {
            inodeno_t ino;
            unsigned char d_type;
-           decode(ino, q);
-           decode(d_type, q);
+            if (dentry_type == 'l') {
+             DECODE_START(1, q);
+             decode(ino, q);
+             decode(d_type, q);
+             DECODE_FINISH(q);
+           } else {
+             decode(ino, q);
+             decode(d_type, q);
+           }
 
            if (step == SCAN_INOS) {
              remote_links[ino]++;
@@ -1472,8 +1486,14 @@ int MetadataTool::read_dentry(inodeno_t parent_ino, frag_t frag,
     decode(first, q);
     char dentry_type;
     decode(dentry_type, q);
-    if (dentry_type == 'I') {
-      inode->decode_bare(q);
+    if (dentry_type == 'I' || dentry_type == 'i') {
+      if (dentry_type == 'i') {
+        DECODE_START(1, q);
+        inode->decode(q);
+        DECODE_FINISH(q);
+      } else {
+        inode->decode_bare(q);
+      }
     } else {
       dout(20) << "dentry type '" << dentry_type << "': cannot"
                   "read an inode out of that" << dendl;
index b20a6b29608c6028ab5dd588147473794b538d85..f4598a44029509e8dcf0773d17d7bac0f86a6cfa 100644 (file)
@@ -824,7 +824,7 @@ int JournalTool::recover_dentries(
         char dentry_type;
         decode(dentry_type, q);
 
-        if (dentry_type == 'L') {
+        if (dentry_type == 'L' || dentry_type == 'l') {
           // leave write_dentry false, we have no version to
           // compare with in a hardlink, so it's not safe to
           // squash over it with what's in this fullbit
@@ -833,10 +833,16 @@ int JournalTool::recover_dentries(
                << "' with lump fnode version " << lump.fnode->version
                << "vs existing fnode version " << old_fnode_version << dendl;
           write_dentry = old_fnode_version < lump.fnode->version;
-        } else if (dentry_type == 'I') {
+        } else if (dentry_type == 'I' || dentry_type == 'i') {
           // Read out inode version to compare with backing store
           InodeStore inode;
-          inode.decode_bare(q);
+          if (dentry_type == 'i') {
+            DECODE_START(1, q);
+            inode.decode(q);
+            DECODE_FINISH(q);
+         } else {
+            inode.decode_bare(q);
+         }
           dout(4) << "decoded embedded inode version "
             << inode.inode->version << " vs fullbit version "
             << fb.inode->version << dendl;
@@ -890,13 +896,13 @@ int JournalTool::recover_dentries(
         char dentry_type;
         decode(dentry_type, q);
 
-        if (dentry_type == 'L') {
+        if (dentry_type == 'L' || dentry_type == 'l') {
           dout(10) << "Existing hardlink inode in slot to be (maybe) written "
                << "by a remote inode from the journal dn '" << rb.dn.c_str()
                << "' with lump fnode version " << lump.fnode->version
                << "vs existing fnode version " << old_fnode_version << dendl;
           write_dentry = old_fnode_version < lump.fnode->version;
-        } else if (dentry_type == 'I') {
+        } else if (dentry_type == 'I' || dentry_type == 'i') {
           dout(10) << "Existing full inode in slot to be (maybe) written "
                << "by a remote inode from the journal dn '" << rb.dn.c_str()
                << "' with lump fnode version " << lump.fnode->version
@@ -946,13 +952,13 @@ int JournalTool::recover_dentries(
        decode(dentry_type, q);
 
        bool remove_dentry = false;
-       if (dentry_type == 'L') {
+       if (dentry_type == 'L' || dentry_type == 'l') {
          dout(10) << "Existing hardlink inode in slot to be (maybe) removed "
            << "by null journal dn '" << nb.dn.c_str()
            << "' with lump fnode version " << lump.fnode->version
            << "vs existing fnode version " << old_fnode_version << dendl;
          remove_dentry = old_fnode_version < lump.fnode->version;
-       } else if (dentry_type == 'I') {
+       } else if (dentry_type == 'I' || dentry_type == 'i') {
          dout(10) << "Existing full inode in slot to be (maybe) removed "
            << "by null journal dn '" << nb.dn.c_str()
            << "' with lump fnode version " << lump.fnode->version
index b9c79d489d0ecddfe628c80c5b9c845a99d9a5d9..1d7d855da4bb8c8ff2ab36d5b5fe53ae943847ae 100644 (file)
@@ -921,12 +921,20 @@ int MetaTool::show_child(std::string_view key,
   //    dn = lookup_exact_snap(dname, last);
   //else
   //    dn = lookup(dname, last);
-  if (type == 'L') {
+  if (type == 'L' || type == 'l') {
     // hard link
     inodeno_t ino;
     unsigned char d_type;
-    ::decode(ino, q);
-    ::decode(d_type, q);
+    if (type == 'l') {
+      DECODE_START(1, q);
+      ::decode(ino, q);
+      ::decode(d_type, q);
+      DECODE_FINISH(q);
+    } else {
+      ::decode(ino, q);
+      ::decode(d_type, q);
+    }
+
     if (sp_ino > 0) {
       if (sp_ino == ino) {
         std::cout << "find hard link : " << ino << "," << d_type << std::endl;
@@ -935,11 +943,17 @@ int MetaTool::show_child(std::string_view key,
     }
 
     std::cout << "hard link : " << ino << "," << d_type << std::endl;
-  } else if (type == 'I') {
+  } else if (type == 'I' || type == 'i') {
     // inode
     // load inode data before lookuping up or constructing CInode
     InodeStore& inode_data = *(new InodeStore);
-    inode_data.decode_bare(q);
+    if (type == 'i') {
+      DECODE_START(1, q);
+      inode_data.decode(q);
+      DECODE_FINISH(q);
+    } else {
+      inode_data.decode_bare(q);
+    }
 
     std::stringstream ds;
     std::string format = "json";