]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: Use RBD image flags for invalid object maps
authorJason Dillaman <dillaman@redhat.com>
Mon, 10 Nov 2014 15:08:26 +0000 (10:08 -0500)
committerJason Dillaman <dillaman@redhat.com>
Thu, 29 Jan 2015 02:12:52 +0000 (21:12 -0500)
If the RBD object map state is corrupted, flag the object map
as invalid so that it won't be used for IO operations.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
src/include/rbd/librbd.h
src/librbd/ImageCtx.cc
src/librbd/ImageCtx.h
src/librbd/internal.cc

index 8d7f23ff2c95e3bd1d457e7268a10a6e3e232a85..b94faff149ffd9114d9fa8c6a8380f8ce11d20b3 100644 (file)
@@ -47,6 +47,8 @@ extern "C" {
   #define CEPH_RBD_API
 #endif
 
+#define RBD_FLAG_OBJECT_MAP_INVALID   (1<<0)
+
 typedef void *rbd_snap_t;
 typedef void *rbd_image_t;
 
index d17e6fd357e0b5d65093619aff7869c01db059cc..9f1150828cc35f3e7d8855c383b17d20196a6b43 100644 (file)
@@ -55,7 +55,7 @@ namespace librbd {
       order(0), size(0), features(0),
       format_string(NULL),
       id(image_id), parent(NULL),
-      stripe_unit(0), stripe_count(0),
+      stripe_unit(0), stripe_count(0), flags(0),
       object_cacher(NULL), writeback_handler(NULL), object_set(NULL),
       readahead(),
       total_bytes_read(0), copyup_finisher(NULL),
@@ -687,8 +687,9 @@ namespace librbd {
 
   bool ImageCtx::object_may_exist(uint64_t object_no) const
   {
-    // Fall back to default logic if object map is disabled
-    if ((features & RBD_FEATURE_OBJECT_MAP) == 0 /* || invalid map */) {
+    // Fall back to default logic if object map is disabled or invalid
+    if ((features & RBD_FEATURE_OBJECT_MAP) == 0 ||
+        ((flags & RBD_FLAG_OBJECT_MAP_INVALID) != 0)) {
       return true;
     }
 
@@ -710,7 +711,7 @@ namespace librbd {
     if (r < 0) {
       lderr(cct) << "error refreshing object map: " << cpp_strerror(r)
                 << dendl;
-      // TODO: flag object map as invalid
+      invalidate_object_map();
       object_map.clear();
       return r;
     }
@@ -723,7 +724,7 @@ namespace librbd {
       // resize op might have been interrupted
       lderr(cct) << "incorrect object map size: " << object_map.size()
                 << " != " << num_objs << dendl;
-      // TODO: flag object map as invalid
+      invalidate_object_map();
       return -EINVAL;
     }
     return 0;
@@ -745,7 +746,7 @@ namespace librbd {
       lderr(cct) << "error resizing object map: size=" << num_objs << ", "
                  << "state=" << default_object_state << ", "
                  << "error=" << cpp_strerror(r) << dendl;
-      // TODO: flag object map as invalid
+      invalidate_object_map();
       return 0;
     }
 
@@ -773,7 +774,8 @@ namespace librbd {
 
     RWLock::WLocker l(object_map_lock);
     assert(start_object_no <= end_object_no);
-    assert(/* flagged as invalid || */ end_object_no <= object_map.size());
+    assert(end_object_no <= object_map.size() ||
+          (flags & RBD_FLAG_OBJECT_MAP_INVALID) != 0);
     if (end_object_no > object_map.size()) {
       ldout(cct, 20) << "skipping update of invalid object map" << dendl;
       return 0;
@@ -803,7 +805,7 @@ namespace librbd {
     int r = data_ctx.operate(object_map_name(id), &op);
     if (r < 0) {
       lderr(cct) << "object map update failed: " << cpp_strerror(r) << dendl;
-      // TODO: remove RBD_FEATURE_EXCLUSIVE_LOCK feature on image
+      invalidate_object_map();
     } else {
       for (uint64_t object_no = start_object_no; object_no < end_object_no;
            ++object_no) {
@@ -814,4 +816,15 @@ namespace librbd {
     }
     return r;
   }
+
+  void ImageCtx::invalidate_object_map()
+  {
+    flags |= RBD_FLAG_OBJECT_MAP_INVALID;
+    int r = cls_client::set_flags(&md_ctx, header_oid, flags,
+                                  RBD_FLAG_OBJECT_MAP_INVALID);
+    if (r < 0) {
+      lderr(cct) << "Failed to invalidate object map: " << cpp_strerror(r)
+                 << dendl;
+    }
+  }
 }
index 1c148d5e90cca7d59a9f901ac4470606dc470eb0..6c0977ee964332cef0a907c0ed5b4bfcb666b860 100644 (file)
@@ -96,6 +96,7 @@ namespace librbd {
     parent_info parent_md;
     ImageCtx *parent;
     uint64_t stripe_unit, stripe_count;
+    uint64_t flags;
 
     ceph_file_layout layout;
 
@@ -189,6 +190,7 @@ namespace librbd {
     int update_object_map(uint64_t start_object_no, uint64_t end_object_no,
                          uint8_t new_state,
                          const boost::optional<uint8_t> &current_state);
+    void invalidate_object_map();
   };
 }
 
index 9feaa18f520f26707082fcb29da2cf3bd6188ec4..db13d68e0fc426df3fa2b9a0ab2de4c5dbd398c1 100644 (file)
@@ -2217,6 +2217,26 @@ reprotect_and_return_err:
              return -ENOSYS;
            }
 
+            r = cls_client::get_flags(&ictx->md_ctx, ictx->header_oid,
+                                      ictx->snap_id, &ictx->flags);
+            if (r == -EOPNOTSUPP || r == -EIO) {
+              // Older OSD doesn't support RBD flags, need to assume the worst
+              ldout(ictx->cct, 10) << "OSD does not support RBD flags" << dendl;
+            } else if (r == -ENOENT) {
+              ldout(ictx->cct, 10) << "Image at invalid snapshot" << dendl;
+            } else if (r < 0 && r != -ENOENT) {
+              lderr(cct) << "Error reading flags: " << cpp_strerror(r) << dendl;
+              return r;
+            }
+            if (r < 0) {
+              ictx->flags = 0;
+              if ((ictx->features & RBD_FEATURE_OBJECT_MAP) != 0) {
+                ldout(ictx->cct, 10) << "disabling object map optimizations"
+                                     << dendl;
+                ictx->flags |= RBD_FLAG_OBJECT_MAP_INVALID;
+              }
+            }
+
            r = cls_client::snapshot_list(&(ictx->md_ctx), ictx->header_oid,
                                          new_snapc.snaps, &snap_names,
                                          &snap_sizes, &snap_features,