Whamcloud - gitweb
LU-14286 osd-ldiskfs: fallocate() should zero new blocks
[fs/lustre-release.git] / lustre / mgs / mgs_barrier.c
index ef18273..b624f89 100644 (file)
@@ -20,7 +20,7 @@
  * GPL HEADER END
  */
 /*
- * Copyright (c) 2016, Intel Corporation.
+ * Copyright (c) 2017, Intel Corporation.
  *
  * lustre/mgs/mgs_barrier.c
  *
@@ -30,9 +30,9 @@
 #define DEBUG_SUBSYSTEM S_MGS
 #define D_MGS D_CONFIG
 
-#include <lustre_ioctl.h>
+#include <uapi/linux/lustre/lustre_ioctl.h>
 #include <lustre_swab.h>
-#include <lustre/lustre_barrier_user.h>
+#include <uapi/linux/lustre/lustre_barrier_user.h>
 
 #include "mgs_internal.h"
 
@@ -62,9 +62,11 @@ static int mgs_barrier_gl_interpret_reply(const struct lu_env *env,
        ENTRY;
 
        if (rc) {
-               if (rc == -ENODEV)
+               if (rc == -ENODEV) {
                        /* The lock is useless, cancel it. */
                        ldlm_lock_cancel(ca->ca_lock);
+                       rc = 0;
+               }
 
                GOTO(out, rc);
        }
@@ -119,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;
@@ -245,6 +247,13 @@ static bool mgs_barrier_done(struct fs_db *fsdb)
        return true;
 }
 
+bool mgs_barrier_expired(struct fs_db *fsdb, time64_t timeout)
+{
+       time64_t expired = fsdb->fsdb_barrier_latest_create_time + timeout;
+
+       return expired > ktime_get_real_seconds();
+}
+
 /**
  * Create the barrier for the given instance.
  *
@@ -291,7 +300,7 @@ static int mgs_barrier_freeze(const struct lu_env *env,
        char *name = mgs_env_info(env)->mgi_fsname;
        struct fs_db *fsdb;
        int rc = 0;
-       int left;
+       time64_t left;
        bool phase1 = true;
        bool dirty = false;
        ENTRY;
@@ -302,17 +311,36 @@ 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) {
+                               __u64 flags = exp_connect_flags(exp);
+                               if (!!(flags & OBD_CONNECT_MDS_MDS) &&
+                                   !(flags & OBD_CONNECT_BARRIER)) {
+                                       fsdb->fsdb_barrier_disabled = 1;
+                                       break;
+                               }
+                       }
+                       spin_unlock(&mgs_obd->obd_dev_lock);
+               }
+       }
+
        mutex_lock(&fsdb->fsdb_mutex);
        mutex_unlock(&mgs->mgs_mutex);
 
@@ -326,12 +354,11 @@ static int mgs_barrier_freeze(const struct lu_env *env,
                rc = -EINPROGRESS;
                break;
        case BS_FROZEN:
-               if (cfs_time_before(cfs_time_current_sec(),
-                                   fsdb->fsdb_barrier_latest_create_time +
-                                   fsdb->fsdb_barrier_timeout)) {
+               if (mgs_barrier_expired(fsdb, fsdb->fsdb_barrier_timeout)) {
                        rc = -EALREADY;
                        break;
                }
+               /* fallthrough */
        case BS_INIT:
        case BS_THAWED:
        case BS_EXPIRED:
@@ -342,7 +369,7 @@ static int mgs_barrier_freeze(const struct lu_env *env,
                        rc = -ENODEV;
                } else {
                        fsdb->fsdb_barrier_latest_create_time =
-                                                       cfs_time_current_sec();
+                               ktime_get_real_seconds();
                        fsdb->fsdb_barrier_status = BS_FREEZING_P1;
                        if (bc->bc_timeout != 0)
                                fsdb->fsdb_barrier_timeout = bc->bc_timeout;
@@ -377,7 +404,7 @@ again:
 
        dirty = true;
        left = fsdb->fsdb_barrier_latest_create_time +
-               fsdb->fsdb_barrier_timeout - cfs_time_current_sec();
+              fsdb->fsdb_barrier_timeout - ktime_get_real_seconds();
        if (left <= 0) {
                fsdb->fsdb_barrier_status = BS_EXPIRED;
 
@@ -443,17 +470,36 @@ 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) {
+                               __u64 flags = exp_connect_flags(exp);
+                               if (!!(flags & OBD_CONNECT_MDS_MDS) &&
+                                   !(flags & OBD_CONNECT_BARRIER)) {
+                                       fsdb->fsdb_barrier_disabled = 1;
+                                       break;
+                               }
+                       }
+                       spin_unlock(&mgs_obd->obd_dev_lock);
+               }
+       }
+
        mutex_lock(&fsdb->fsdb_mutex);
        mutex_unlock(&mgs->mgs_mutex);
 
@@ -548,13 +594,11 @@ static int mgs_barrier_stat(const struct lu_env *env,
                if (bc->bc_status == BS_FREEZING_P1 ||
                    bc->bc_status == BS_FREEZING_P2 ||
                    bc->bc_status == BS_FROZEN) {
-                       if (cfs_time_before(cfs_time_current_sec(),
-                                       fsdb->fsdb_barrier_latest_create_time +
-                                       fsdb->fsdb_barrier_timeout))
+                       if (mgs_barrier_expired(fsdb, fsdb->fsdb_barrier_timeout))
                                bc->bc_timeout =
                                        fsdb->fsdb_barrier_latest_create_time +
                                        fsdb->fsdb_barrier_timeout -
-                                       cfs_time_current_sec();
+                                       ktime_get_real_seconds();
                        else
                                bc->bc_status = fsdb->fsdb_barrier_status =
                                        BS_EXPIRED;
@@ -594,13 +638,32 @@ 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) {
+                       __u64 flags = exp_connect_flags(exp);
+                       if (!!(flags & OBD_CONNECT_MDS_MDS) &&
+                           !(flags & OBD_CONNECT_BARRIER)) {
+                               b_fsdb->fsdb_barrier_disabled = 1;
+                               break;
+                       }
+               }
+               spin_unlock(&mgs_obd->obd_dev_lock);
        }
 
        mutex_lock(&b_fsdb->fsdb_mutex);
@@ -617,18 +680,16 @@ static int mgs_barrier_rescan(const struct lu_env *env,
                rc = -EBUSY;
                break;
        case BS_FROZEN:
-               if (cfs_time_before(cfs_time_current_sec(),
-                                   b_fsdb->fsdb_barrier_latest_create_time +
-                                   b_fsdb->fsdb_barrier_timeout)) {
+               if (mgs_barrier_expired(b_fsdb, b_fsdb->fsdb_barrier_timeout)) {
                        rc = -EBUSY;
                        break;
                }
+               /* fallthrough */
        case BS_INIT:
        case BS_THAWED:
        case BS_EXPIRED:
        case BS_FAILED:
-               b_fsdb->fsdb_barrier_latest_create_time =
-                                                       cfs_time_current_sec();
+               b_fsdb->fsdb_barrier_latest_create_time = ktime_get_real_seconds();
                b_fsdb->fsdb_barrier_status = BS_RESCAN;
                memcpy(b_fsdb->fsdb_mdt_index_map, c_fsdb->fsdb_mdt_index_map,
                       INDEX_MAP_SIZE);
@@ -663,9 +724,7 @@ again:
                b_fsdb->fsdb_barrier_status = rc;
                rc = -EREMOTE;
        } else if (rc == -ETIMEDOUT &&
-                  cfs_time_before(cfs_time_current_sec(),
-                                  b_fsdb->fsdb_barrier_latest_create_time +
-                                  bc->bc_timeout)) {
+                  mgs_barrier_expired(b_fsdb, bc->bc_timeout)) {
                memset(b_fsdb->fsdb_barrier_map, 0, INDEX_MAP_SIZE);
 
                goto again;
@@ -714,9 +773,14 @@ int mgs_iocontrol_barrier(const struct lu_env *env,
        if (unlikely(bc->bc_version != BARRIER_VERSION_V1))
                RETURN(-EOPNOTSUPP);
 
-       if (unlikely(strnlen(bc->bc_name, sizeof(bc->bc_name)) > 8))
+       if (unlikely(bc->bc_name[0] == '\0' ||
+                    strnlen(bc->bc_name, sizeof(bc->bc_name)) > 8))
                RETURN(-EINVAL);
 
+       /* NOT allow barrier operations during recovery. */
+       if (unlikely(mgs->mgs_obd->obd_recovering))
+               RETURN(-EBUSY);
+
        switch (bc->bc_cmd) {
        case BC_FREEZE:
                rc = mgs_barrier_freeze(env, mgs, bc);