Re: [PATCH] rbd: mark rbd disk to ro if we found feature unsupported enabled after mapping

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Dec 24, 2018 at 2:24 AM Dongsheng Yang
<dongsheng.yang@xxxxxxxxxxxx> wrote:
>
>
>
> On 12/22/2018 10:35 AM, Gregory Farnum wrote:
> > On Fri, Dec 21, 2018 at 1:56 AM Ilya Dryomov <idryomov@xxxxxxxxx> wrote:
> >> On Tue, Dec 18, 2018 at 10:33 AM Dongsheng Yang
> >> <dongsheng.yang@xxxxxxxxxxxx> wrote:
> >>> If there is unsupported feature enabled after rbd map, we will noticed it in
> >>> refreshing, then we need to set the disk readonly. In addition, we need to
> >>> set disk to rw if these unsupportted features disabled later.
> >> Do we really need to revert back to RW?  If the block device suddenly
> >> goes RO, most applications including filesystems will fail irreversibly
> >> anyway.
> >>
> >>> Signed-off-by: Dongsheng Yang <dongsheng.yang@xxxxxxxxxxxx>
> >>> ---
> >>>   drivers/block/rbd.c | 48 ++++++++++++++++++++++++------------------------
> >>>   1 file changed, 24 insertions(+), 24 deletions(-)
> >>>
> >>> diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
> >>> index 8e5140b..e911830 100644
> >>> --- a/drivers/block/rbd.c
> >>> +++ b/drivers/block/rbd.c
> >>> @@ -3695,6 +3695,9 @@ static void rbd_queue_workfn(struct work_struct *work)
> >>>                  snapc = rbd_dev->header.snapc;
> >>>                  ceph_get_snap_context(snapc);
> >>>          }
> >>> +       must_be_locked =
> >>> +           (rbd_dev->header.features & RBD_FEATURE_EXCLUSIVE_LOCK) &&
> >>> +           (op_type != OBJ_OP_READ || rbd_dev->opts->lock_on_read);
> >>>          up_read(&rbd_dev->header_rwsem);
> >>>
> >>>          if (offset + length > mapping_size) {
> >>> @@ -3704,9 +3707,6 @@ static void rbd_queue_workfn(struct work_struct *work)
> >>>                  goto err_rq;
> >>>          }
> >>>
> >>> -       must_be_locked =
> >>> -           (rbd_dev->header.features & RBD_FEATURE_EXCLUSIVE_LOCK) &&
> >>> -           (op_type != OBJ_OP_READ || rbd_dev->opts->lock_on_read);
> >>>          if (must_be_locked) {
> >>>                  down_read(&rbd_dev->lock_rwsem);
> >>>                  result = rbd_wait_state_locked(rbd_dev,
> >>> @@ -4567,13 +4567,6 @@ static int _rbd_dev_v2_snap_features(struct rbd_device *rbd_dev, u64 snap_id,
> >>>          if (ret < sizeof (features_buf))
> >>>                  return -ERANGE;
> >>>
> >>> -       unsup = le64_to_cpu(features_buf.incompat) & ~RBD_FEATURES_SUPPORTED;
> >>> -       if (unsup) {
> >>> -               rbd_warn(rbd_dev, "image uses unsupported features: 0x%llx",
> >>> -                        unsup);
> >>> -               return -ENXIO;
> >>> -       }
> >>> -
> >>>          *snap_features = le64_to_cpu(features_buf.features);
> >>>
> >>>          dout("  snap_id 0x%016llx features = 0x%016llx incompat = 0x%016llx\n",
> >>> @@ -4581,13 +4574,14 @@ static int _rbd_dev_v2_snap_features(struct rbd_device *rbd_dev, u64 snap_id,
> >>>                  (unsigned long long)*snap_features,
> >>>                  (unsigned long long)le64_to_cpu(features_buf.incompat));
> >>>
> >>> -       return 0;
> >>> -}
> >>> +       unsup = le64_to_cpu(features_buf.incompat) & ~RBD_FEATURES_SUPPORTED;
> >>> +       if (unsup) {
> >>> +               rbd_warn(rbd_dev, "image uses unsupported features: 0x%llx",
> >>> +                        unsup);
> >>> +               return -ENXIO;
> >>> +       }
> >>>
> >>> -static int rbd_dev_v2_features(struct rbd_device *rbd_dev)
> >>> -{
> >>> -       return _rbd_dev_v2_snap_features(rbd_dev, CEPH_NOSNAP,
> >>> -                                               &rbd_dev->header.features);
> >>> +       return 0;
> >>>   }
> >>>
> >>>   struct parent_image_info {
> >>> @@ -5184,12 +5178,26 @@ static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev,
> >>>   static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev)
> >>>   {
> >>>          bool first_time = rbd_dev->header.object_prefix == NULL;
> >>> +       u64 features = 0;
> >>>          int ret;
> >>>
> >>>          ret = rbd_dev_v2_image_size(rbd_dev);
> >>>          if (ret)
> >>>                  return ret;
> >>>
> >>> +       ret = _rbd_dev_v2_snap_features(rbd_dev, CEPH_NOSNAP,
> >>> +                                       &features);
> >>> +       if (ret) {
> >>> +               if (-ENXIO == ret && !first_time)
> >>> +                       set_disk_ro(rbd_dev->disk, true);
> >>> +               else
> >>> +                       return ret;
> >>> +       } else {
> >>> +               if (!first_time && !rbd_dev->opts->read_only)
> >>> +                       set_disk_ro(rbd_dev->disk, false);
> >>> +       }
> >>> +       rbd_dev->mapping.features = rbd_dev->header.features = features;
> >>> +
> >>>          if (first_time) {
> >>>                  ret = rbd_dev_v2_header_onetime(rbd_dev);
> >>>                  if (ret)
> >>> @@ -5560,14 +5568,6 @@ static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev)
> >>>          if (ret)
> >>>                  goto out_err;
> >>>
> >>> -       /*
> >>> -        * Get the and check features for the image.  Currently the
> >>> -        * features are assumed to never change.
> >>> -        */
> >>> -       ret = rbd_dev_v2_features(rbd_dev);
> >>> -       if (ret)
> >>> -               goto out_err;
> >>> -
> >>>          /* If the image supports fancy striping, get its parameters */
> >>>
> >>>          if (rbd_dev->header.features & RBD_FEATURE_STRIPINGV2) {
> >> I think we should take this further.  We don't support _any_ changes
> >> while the image is mapped, i.e. not just enabling something unsupported
> >> but also disabling something supported.  Let's change all places where
> >> we check for features to use rbd_dev->mapping.features and simply add
> >> a new rbd_dev->header.features != rbd_dev->mapping.features check to
> >> rbd_dev_refresh().
> > Is that a statement of how things work now, or a rule you'd like to
> > enforce? I thought it was possible to do things like enable the object
> > map while images are in use, and it seems like we'd want to continue
> > supporting that.
>
> I agree with Greg here. In my use case, we have an operation
> to add a rbd image into DR (disaster recovery, actually enable journaling
> and start rbd-mirroring for it). So we need to change the feature of
> an image online.

It's not just a matter of a less strict check -- allowing manipulating
image features while the image is mapped will require some thought and
possibly a lot of additional code and tests.  The current assumption in
the kernel code is that all features are immutable.

Thanks,

                Ilya



[Index of Archives]     [CEPH Users]     [Ceph Large]     [Information on CEPH]     [Linux BTRFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux