X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fmgs%2Fmgs_barrier.c;h=225bfa98483d2849b61695ae9eb61b47afa1b54b;hb=af49e96b95909f470757890f34da760b8af3c9a8;hp=ef182730c460b923995db107f766de026e19e7f4;hpb=3afede2b8186912a08acfa8b1881356c7e11c656;p=fs%2Flustre-release.git diff --git a/lustre/mgs/mgs_barrier.c b/lustre/mgs/mgs_barrier.c index ef18273..225bfa9 100644 --- a/lustre/mgs/mgs_barrier.c +++ b/lustre/mgs/mgs_barrier.c @@ -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 +#include #include -#include +#include #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); } @@ -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,9 +354,7 @@ 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; } @@ -342,7 +368,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 +403,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 +469,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 +593,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 +637,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,9 +679,7 @@ 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; } @@ -627,8 +687,7 @@ static int mgs_barrier_rescan(const struct lu_env *env, 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 +722,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 +771,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);