* GPL HEADER END
*/
/*
- * Copyright (c) 2016, Intel Corporation.
+ * Copyright (c) 2017, Intel Corporation.
*
* lustre/mgs/mgs_barrier.c
*
#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"
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);
}
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;
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.
*
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;
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);
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:
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;
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;
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);
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;
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);
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);
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;
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);