Whamcloud - gitweb
LU-13550 osd-zfs: snapshot with incompatible clients
[fs/lustre-release.git] / lustre / mgs / mgs_barrier.c
index 36e99a4..9087055 100644 (file)
@@ -20,7 +20,7 @@
  * GPL HEADER END
  */
 /*
- * Copyright (c) 2016, Intel Corporation.
+ * Copyright (c) 2017, Intel Corporation.
  *
  * lustre/mgs/mgs_barrier.c
  *
@@ -121,7 +121,7 @@ static int mgs_barrier_glimpse_lock(const struct lu_env *env,
        struct ldlm_resource *res;
        struct ldlm_glimpse_work *work;
        struct ldlm_glimpse_work *tmp;
-       struct list_head gl_list = LIST_HEAD_INIT(gl_list);
+       LIST_HEAD(gl_list);
        struct list_head *pos;
        int i;
        int rc;
@@ -129,7 +129,7 @@ static int mgs_barrier_glimpse_lock(const struct lu_env *env,
 
        LASSERT(fsdb->fsdb_mdt_count > 0);
 
-       rc = mgc_logname2resid(fsdb->fsdb_name, &res_id, CONFIG_T_BARRIER);
+       rc = mgc_logname2resid(fsdb->fsdb_name, &res_id, MGS_CFG_T_BARRIER);
        if (rc)
                RETURN(rc);
 
@@ -254,6 +254,22 @@ bool mgs_barrier_expired(struct fs_db *fsdb, time64_t timeout)
        return expired > ktime_get_real_seconds();
 }
 
+static inline bool mgs_barrier_tests_disabled(struct barrier_ctl *bc,
+                                             struct obd_export *exp,
+                                             struct fs_db *fsdb)
+{
+       __u64 flags = exp_connect_flags(exp);
+
+       if ((flags & OBD_CONNECT_MDS_MDS) && !(flags & OBD_CONNECT_BARRIER)) {
+               fsdb->fsdb_barrier_disabled = 1;
+               LCONSOLE_WARN("%s: Barrier incompatible connection %s\n",
+                             bc->bc_name,
+                             obd_uuid2str(&exp->exp_client_uuid));
+               return true;
+       }
+       return false;
+}
+
 /**
  * Create the barrier for the given instance.
  *
@@ -311,17 +327,32 @@ static int mgs_barrier_freeze(const struct lu_env *env,
        down_write(&mgs->mgs_barrier_rwsem);
        mutex_lock(&mgs->mgs_mutex);
 
-       fsdb = mgs_find_fsdb(mgs, name);
-       if (!fsdb) {
+       rc = mgs_find_or_make_fsdb_nolock(env, mgs, name, &fsdb);
+       if (rc) {
                mutex_unlock(&mgs->mgs_mutex);
                up_write(&mgs->mgs_barrier_rwsem);
-
-               RETURN(-ENODEV);
+               RETURN(rc);
        }
 
-       if (unlikely(fsdb->fsdb_mdt_count == 0))
+       if (unlikely(fsdb->fsdb_mdt_count == 0)) {
                mgs_barrier_bitmap_setup(mgs, fsdb, bc->bc_name);
 
+               /* fsdb was just created, ensure that fsdb_barrier_disabled is
+                * set correctly */
+               if (fsdb->fsdb_mdt_count > 0) {
+                       struct obd_export *exp;
+                       struct obd_device *mgs_obd = mgs->mgs_obd;
+
+                       spin_lock(&mgs_obd->obd_dev_lock);
+                       list_for_each_entry(exp, &mgs_obd->obd_exports,
+                                           exp_obd_chain) {
+                               if (mgs_barrier_tests_disabled(bc, exp, fsdb))
+                                       break;
+                       }
+                       spin_unlock(&mgs_obd->obd_dev_lock);
+               }
+       }
+
        mutex_lock(&fsdb->fsdb_mutex);
        mutex_unlock(&mgs->mgs_mutex);
 
@@ -339,6 +370,7 @@ static int mgs_barrier_freeze(const struct lu_env *env,
                        rc = -EALREADY;
                        break;
                }
+               /* fallthrough */
        case BS_INIT:
        case BS_THAWED:
        case BS_EXPIRED:
@@ -450,17 +482,32 @@ static int mgs_barrier_thaw(const struct lu_env *env,
        down_write(&mgs->mgs_barrier_rwsem);
        mutex_lock(&mgs->mgs_mutex);
 
-       fsdb = mgs_find_fsdb(mgs, name);
-       if (!fsdb) {
+       rc = mgs_find_or_make_fsdb_nolock(env, mgs, name, &fsdb);
+       if (rc) {
                mutex_unlock(&mgs->mgs_mutex);
                up_write(&mgs->mgs_barrier_rwsem);
-
-               RETURN(-ENODEV);
+               RETURN(rc);
        }
 
-       if (unlikely(fsdb->fsdb_mdt_count == 0))
+       if (unlikely(fsdb->fsdb_mdt_count == 0)) {
                mgs_barrier_bitmap_setup(mgs, fsdb, bc->bc_name);
 
+               /* fsdb was just created, ensure that fsdb_barrier_disabled is
+                * set correctly */
+               if (fsdb->fsdb_mdt_count > 0) {
+                       struct obd_export *exp;
+                       struct obd_device *mgs_obd = mgs->mgs_obd;
+
+                       spin_lock(&mgs_obd->obd_dev_lock);
+                       list_for_each_entry(exp, &mgs_obd->obd_exports,
+                                           exp_obd_chain) {
+                               if (mgs_barrier_tests_disabled(bc, exp, fsdb))
+                                       break;
+                       }
+                       spin_unlock(&mgs_obd->obd_dev_lock);
+               }
+       }
+
        mutex_lock(&fsdb->fsdb_mutex);
        mutex_unlock(&mgs->mgs_mutex);
 
@@ -599,13 +646,28 @@ static int mgs_barrier_rescan(const struct lu_env *env,
 
        snprintf(name, sizeof(mgs_env_info(env)->mgi_fsname) - 1, "%s-%s",
                 bc->bc_name, BARRIER_FILENAME);
-       b_fsdb = mgs_find_fsdb(mgs, name);
-       if (!b_fsdb) {
+       rc = mgs_find_or_make_fsdb_nolock(env, mgs, name, &b_fsdb);
+       if (rc) {
                mutex_unlock(&mgs->mgs_mutex);
                up_write(&mgs->mgs_barrier_rwsem);
                mgs_put_fsdb(mgs, c_fsdb);
+               RETURN(rc);
+       }
 
-               RETURN(-ENODEV);
+       if (unlikely(b_fsdb->fsdb_mdt_count == 0 &&
+                    c_fsdb->fsdb_mdt_count > 0)) {
+               /* fsdb was just created, ensure that fsdb_barrier_disabled is
+                * set correctly */
+               struct obd_export *exp;
+               struct obd_device *mgs_obd = mgs->mgs_obd;
+
+               spin_lock(&mgs_obd->obd_dev_lock);
+               list_for_each_entry(exp, &mgs_obd->obd_exports,
+                                   exp_obd_chain) {
+                       if (mgs_barrier_tests_disabled(bc, exp, b_fsdb))
+                               break;
+               }
+               spin_unlock(&mgs_obd->obd_dev_lock);
        }
 
        mutex_lock(&b_fsdb->fsdb_mutex);
@@ -626,6 +688,7 @@ static int mgs_barrier_rescan(const struct lu_env *env,
                        rc = -EBUSY;
                        break;
                }
+               /* fallthrough */
        case BS_INIT:
        case BS_THAWED:
        case BS_EXPIRED: