summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
01d23cc)
layout locks are not replayed and instead cancelled as unused, what
requires to take lov_conf_lock. the semaphore may be already taken by
cl_lock_flush() which prepares a new IO which is not be able to be
sent to MDS as it is in the recovery.
HPE-bug-id: LUS-9232
Signed-off-by: Vitaly Fertman <c17818@cray.com>
Change-Id: I1a1a91a81c19ad4deca9ff581107512642f0b666
Reviewed-by: Alexey Lyashkov <c17817@cray.com>
Reviewed-by: Andriy Skulysh <c17819@cray.com>
Tested-by: Jenkins Build User <nssreleng@cray.com>
Reviewed-on: https://review.whamcloud.com/40867
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Alexey Lyashkov <alexey.lyashkov@hpe.com>
Reviewed-by: Andriy Skulysh <askulysh@gmail.com>
Reviewed-by: Mike Pershin <mpershin@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
#define OBD_FAIL_LDLM_PROLONG_PAUSE 0x32b
#define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
#define OBD_FAIL_LDLM_LOCK_REPLAY 0x32d
#define OBD_FAIL_LDLM_PROLONG_PAUSE 0x32b
#define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
#define OBD_FAIL_LDLM_LOCK_REPLAY 0x32d
+#define OBD_FAIL_LDLM_REPLAY_PAUSE 0x32e
/* LOCKLESS IO */
#define OBD_FAIL_LDLM_SET_CONTENTION 0x385
/* LOCKLESS IO */
#define OBD_FAIL_LDLM_SET_CONTENTION 0x385
"Dropping as many unused locks as possible before replay for namespace %s (%d)\n",
ldlm_ns_name(ns), ns->ns_nr_unused);
"Dropping as many unused locks as possible before replay for namespace %s (%d)\n",
ldlm_ns_name(ns), ns->ns_nr_unused);
+ OBD_FAIL_TIMEOUT(OBD_FAIL_LDLM_REPLAY_PAUSE, cfs_fail_val);
+
/*
* We don't need to care whether or not LRU resize is enabled
* because the LDLM_LRU_FLAG_NO_WAIT policy doesn't use the
/*
* We don't need to care whether or not LRU resize is enabled
* because the LDLM_LRU_FLAG_NO_WAIT policy doesn't use the
if (IS_ERR(env))
RETURN(PTR_ERR(env));
if (IS_ERR(env))
RETURN(PTR_ERR(env));
+ OBD_FAIL_TIMEOUT(OBD_FAIL_LDLM_REPLAY_PAUSE, cfs_fail_val);
+
/* reach MDC layer to flush data under the DoM ldlm lock */
rc = cl_object_flush(env, lli->lli_clob, lock);
if (rc == -ENODATA) {
/* reach MDC layer to flush data under the DoM ldlm lock */
rc = cl_object_flush(env, lli->lli_clob, lock);
if (rc == -ENODATA) {
unsigned short lre_end; /* end index of this mirror */
};
unsigned short lre_end; /* end index of this mirror */
};
+enum lov_object_flags {
+ /* Layout is invalid, set when layout lock is lost */
+ LO_LAYOUT_INVALID = 0x1,
+};
+
/**
* lov-specific file state.
*
/**
* lov-specific file state.
*
*/
enum lov_layout_type lo_type;
/**
*/
enum lov_layout_type lo_type;
/**
- * True if layout is invalid. This bit is cleared when layout lock
- * is lost.
- bool lo_layout_invalid;
+ unsigned long lo_obj_flags;
/**
* How many IOs are on going on this object. Layout can be changed
* only if there is no active IO.
/**
* How many IOs are on going on this object. Layout can be changed
* only if there is no active IO.
old_obj = lu_object_locate(&parent->coh_lu, &lov_device_type);
LASSERT(old_obj != NULL);
old_lov = cl2lov(lu2cl(old_obj));
old_obj = lu_object_locate(&parent->coh_lu, &lov_device_type);
LASSERT(old_obj != NULL);
old_lov = cl2lov(lu2cl(old_obj));
- if (old_lov->lo_layout_invalid) {
+ if (test_bit(LO_LAYOUT_INVALID, &old_lov->lo_obj_flags)) {
/* the object's layout has already changed but isn't
* refreshed */
lu_object_unhash(env, &subobj->co_lu);
/* the object's layout has already changed but isn't
* refreshed */
lu_object_unhash(env, &subobj->co_lu);
LASSERT(lsm->lsm_entry_count > 0);
LASSERT(lov->lo_lsm == NULL);
lov->lo_lsm = lsm_addref(lsm);
LASSERT(lsm->lsm_entry_count > 0);
LASSERT(lov->lo_lsm == NULL);
lov->lo_lsm = lsm_addref(lsm);
- lov->lo_layout_invalid = true;
+ set_bit(LO_LAYOUT_INVALID, &lov->lo_obj_flags);
static int lov_print_empty(const struct lu_env *env, void *cookie,
lu_printer_t p, const struct lu_object *o)
{
static int lov_print_empty(const struct lu_env *env, void *cookie,
lu_printer_t p, const struct lu_object *o)
{
- (*p)(env, cookie, "empty %d\n", lu2lov(o)->lo_layout_invalid);
+ (*p)(env, cookie, "empty %d\n",
+ test_bit(LO_LAYOUT_INVALID, &lu2lov(o)->lo_obj_flags));
(*p)(env, cookie, "entries: %d, %s, lsm{%p 0x%08X %d %u}:\n",
lsm->lsm_entry_count,
(*p)(env, cookie, "entries: %d, %s, lsm{%p 0x%08X %d %u}:\n",
lsm->lsm_entry_count,
- lov->lo_layout_invalid ? "invalid" : "valid", lsm,
- lsm->lsm_magic, atomic_read(&lsm->lsm_refc),
+ test_bit(LO_LAYOUT_INVALID, &lov->lo_obj_flags) ? "invalid" :
+ "valid", lsm, lsm->lsm_magic, atomic_read(&lsm->lsm_refc),
lsm->lsm_layout_gen);
for (i = 0; i < lsm->lsm_entry_count; i++) {
lsm->lsm_layout_gen);
for (i = 0; i < lsm->lsm_entry_count; i++) {
(*p)(env, cookie,
"released: %s, lsm{%p 0x%08X %d %u}:\n",
(*p)(env, cookie,
"released: %s, lsm{%p 0x%08X %d %u}:\n",
- lov->lo_layout_invalid ? "invalid" : "valid", lsm,
- lsm->lsm_magic, atomic_read(&lsm->lsm_refc),
+ test_bit(LO_LAYOUT_INVALID, &lov->lo_obj_flags) ? "invalid" :
+ "valid", lsm, lsm->lsm_magic, atomic_read(&lsm->lsm_refc),
lsm->lsm_layout_gen);
return 0;
}
lsm->lsm_layout_gen);
return 0;
}
(*p)(env, cookie,
"foreign: %s, lsm{%p 0x%08X %d %u}:\n",
(*p)(env, cookie,
"foreign: %s, lsm{%p 0x%08X %d %u}:\n",
- lov->lo_layout_invalid ? "invalid" : "valid", lsm,
+ test_bit(LO_LAYOUT_INVALID, &lov->lo_obj_flags) ?
+ "invalid" : "valid", lsm,
lsm->lsm_magic, atomic_read(&lsm->lsm_refc),
lsm->lsm_layout_gen);
(*p)(env, cookie,
lsm->lsm_magic, atomic_read(&lsm->lsm_refc),
lsm->lsm_layout_gen);
(*p)(env, cookie,
dump_lsm(D_INODE, lsm);
}
dump_lsm(D_INODE, lsm);
}
if (conf->coc_opc == OBJECT_CONF_INVALIDATE) {
if (conf->coc_opc == OBJECT_CONF_INVALIDATE) {
- lov->lo_layout_invalid = true;
- GOTO(out, result = 0);
+ set_bit(LO_LAYOUT_INVALID, &lov->lo_obj_flags);
+ GOTO(out_lsm, result = 0);
if (conf->coc_opc == OBJECT_CONF_WAIT) {
if (conf->coc_opc == OBJECT_CONF_WAIT) {
- if (lov->lo_layout_invalid &&
+ if (test_bit(LO_LAYOUT_INVALID, &lov->lo_obj_flags) &&
atomic_read(&lov->lo_active_ios) > 0) {
lov_conf_unlock(lov);
result = lov_layout_wait(env, lov);
atomic_read(&lov->lo_active_ios) > 0) {
lov_conf_unlock(lov);
result = lov_layout_wait(env, lov);
(lov->lo_lsm->lsm_entries[0]->lsme_pattern ==
lsm->lsm_entries[0]->lsme_pattern))) {
/* same version of layout */
(lov->lo_lsm->lsm_entries[0]->lsme_pattern ==
lsm->lsm_entries[0]->lsme_pattern))) {
/* same version of layout */
- lov->lo_layout_invalid = false;
+ clear_bit(LO_LAYOUT_INVALID, &lov->lo_obj_flags);
GOTO(out, result = 0);
}
/* will change layout - check if there still exists active IO. */
if (atomic_read(&lov->lo_active_ios) > 0) {
GOTO(out, result = 0);
}
/* will change layout - check if there still exists active IO. */
if (atomic_read(&lov->lo_active_ios) > 0) {
- lov->lo_layout_invalid = true;
+ set_bit(LO_LAYOUT_INVALID, &lov->lo_obj_flags);
GOTO(out, result = -EBUSY);
}
result = lov_layout_change(env, lov, lsm, conf);
GOTO(out, result = -EBUSY);
}
result = lov_layout_change(env, lov, lsm, conf);
- lov->lo_layout_invalid = result != 0;
+ if (result)
+ set_bit(LO_LAYOUT_INVALID, &lov->lo_obj_flags);
+ else
+ clear_bit(LO_LAYOUT_INVALID, &lov->lo_obj_flags);
EXIT;
out:
lov_conf_unlock(lov);
EXIT;
out:
lov_conf_unlock(lov);
- CDEBUG(D_INODE, DFID" lo_layout_invalid=%d\n",
- PFID(lu_object_fid(lov2lu(lov))), lov->lo_layout_invalid);
+ CDEBUG(D_INODE, DFID" lo_layout_invalid=%u\n",
+ PFID(lu_object_fid(lov2lu(lov))),
+ test_bit(LO_LAYOUT_INVALID, &lov->lo_obj_flags));
lsm = lsm_addref(lov->lo_lsm);
CDEBUG(D_INODE, "lsm %p addref %d/%d by %p.\n",
lsm, atomic_read(&lsm->lsm_refc),
lsm = lsm_addref(lov->lo_lsm);
CDEBUG(D_INODE, "lsm %p addref %d/%d by %p.\n",
lsm, atomic_read(&lsm->lsm_refc),
- lov->lo_layout_invalid, current);
+ test_bit(LO_LAYOUT_INVALID, &lov->lo_obj_flags),
+ current);
}
lov_conf_thaw(lov);
return lsm;
}
lov_conf_thaw(lov);
return lsm;
}
run_test 29 "replay vs update with the same xid"
}
run_test 29 "replay vs update with the same xid"
+test_30() {
+ $LFS setstripe -E 1m -L mdt -E -1 $DIR/$tfile
+ #first write to have no problems with grants
+ dd if=/dev/zero of=$DIR/$tfile bs=4k count=10 ||
+ error "dd on client failed"
+ dd if=/dev/zero of=$DIR/$tfile bs=4k count=10 seek=10 ||
+ error "dd on client failed"
+
+ #define OBD_FAIL_LDLM_REPLAY_PAUSE 0x32e
+ lctl set_param fail_loc=0x32e fail_val=4
+ dd of=/dev/null if=$DIR2/$tfile &
+ local pid=$!
+ sleep 1
+
+ fail $SINGLEMDS
+
+ wait $pid || error "dd on client failed"
+}
+run_test 30 "layout lock replay is not blocked on IO"
+
complete $SECONDS
SLEEP=$((SECONDS - $NOW))
[ $SLEEP -lt $TIMEOUT ] && sleep $SLEEP
complete $SECONDS
SLEEP=$((SECONDS - $NOW))
[ $SLEEP -lt $TIMEOUT ] && sleep $SLEEP