Whamcloud - gitweb
git://git.whamcloud.com
/
fs
/
lustre-release.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
LU-15097 quota: stop pool_recalc before killing pool
[fs/lustre-release.git]
/
lustre
/
quota
/
qmt_pool.c
diff --git
a/lustre/quota/qmt_pool.c
b/lustre/quota/qmt_pool.c
index
37bb488
..
c4398a5
100644
(file)
--- a/
lustre/quota/qmt_pool.c
+++ b/
lustre/quota/qmt_pool.c
@@
-79,6
+79,8
@@
static int qpi_state_seq_show(struct seq_file *m, void *data)
int type;
LASSERT(pool != NULL);
int type;
LASSERT(pool != NULL);
+ if (unlikely(!test_bit(QPI_FLAG_STATE_INITED, &pool->qpi_flags)))
+ return -ENOENT;
seq_printf(m, "pool:\n"
" id: %u\n"
seq_printf(m, "pool:\n"
" id: %u\n"
@@
-106,6
+108,8
@@
static int qpi_soft_least_qunit_seq_show(struct seq_file *m, void *data)
{
struct qmt_pool_info *pool = m->private;
LASSERT(pool != NULL);
{
struct qmt_pool_info *pool = m->private;
LASSERT(pool != NULL);
+ if (unlikely(!test_bit(QPI_FLAG_STATE_INITED, &pool->qpi_flags)))
+ return -ENOENT;
seq_printf(m, "%lu\n", pool->qpi_soft_least_qunit);
return 0;
seq_printf(m, "%lu\n", pool->qpi_soft_least_qunit);
return 0;
@@
-121,6
+125,8
@@
qpi_soft_least_qunit_seq_write(struct file *file, const char __user *buffer,
int rc;
LASSERT(pool != NULL);
int rc;
LASSERT(pool != NULL);
+ if (unlikely(!test_bit(QPI_FLAG_STATE_INITED, &pool->qpi_flags)))
+ return -ENOENT;
/* Not tuneable for inode limit */
if (pool->qpi_rtype != LQUOTA_RES_DT)
/* Not tuneable for inode limit */
if (pool->qpi_rtype != LQUOTA_RES_DT)
@@
-177,6
+183,7
@@
static int qmt_pool_alloc(const struct lu_env *env, struct qmt_device *qmt,
init_rwsem(&pool->qpi_recalc_sem);
pool->qpi_rtype = pool_type;
init_rwsem(&pool->qpi_recalc_sem);
pool->qpi_rtype = pool_type;
+ pool->qpi_flags = 0;
/* initialize refcount to 1, hash table will then grab an additional
* reference */
/* initialize refcount to 1, hash table will then grab an additional
* reference */
@@
-459,6
+466,8
@@
void qmt_pool_fini(const struct lu_env *env, struct qmt_device *qmt)
/* parse list of pool and destroy each element */
list_for_each_entry_safe(pool, tmp, &qmt->qmt_pool_list, qpi_linkage) {
/* parse list of pool and destroy each element */
list_for_each_entry_safe(pool, tmp, &qmt->qmt_pool_list, qpi_linkage) {
+ /* stop all recalc threads - it may hold qpi reference */
+ qmt_stop_pool_recalc(pool);
/* release extra reference taken in qmt_pool_alloc */
qpi_putref(env, pool);
}
/* release extra reference taken in qmt_pool_alloc */
qpi_putref(env, pool);
}
@@
-670,6
+679,7
@@
int qmt_pool_prepare(const struct lu_env *env, struct qmt_device *qmt,
qmt->qmt_svname, PFID(&qti->qti_fid), rc);
#endif
}
qmt->qmt_svname, PFID(&qti->qti_fid), rc);
#endif
}
+ set_bit(QPI_FLAG_STATE_INITED, &pool->qpi_flags);
if (name)
break;
}
if (name)
break;
}
@@
-1155,6
+1165,13
@@
static int qmt_pool_recalc(void *args)
pool = args;
pool = args;
+ rc = lu_env_init(&env, LCT_MD_THREAD);
+ if (rc) {
+ CERROR("%s: cannot init env: rc = %d\n",
+ pool->qpi_qmt->qmt_svname, rc);
+ GOTO(out, rc);
+ }
+
obd = qmt_get_mgc(pool->qpi_qmt);
if (IS_ERR(obd))
GOTO(out, rc = PTR_ERR(obd));
obd = qmt_get_mgc(pool->qpi_qmt);
if (IS_ERR(obd))
GOTO(out, rc = PTR_ERR(obd));
@@
-1164,6
+1181,7
@@
static int qmt_pool_recalc(void *args)
while (obd->obd_process_conf)
schedule_timeout_uninterruptible(cfs_time_seconds(1));
while (obd->obd_process_conf)
schedule_timeout_uninterruptible(cfs_time_seconds(1));
+ OBD_FAIL_TIMEOUT(OBD_FAIL_QUOTA_RECALC, cfs_fail_val);
sem = qmt_sarr_rwsem(pool);
LASSERT(sem);
down_read(sem);
sem = qmt_sarr_rwsem(pool);
LASSERT(sem);
down_read(sem);
@@
-1183,15
+1201,9
@@
static int qmt_pool_recalc(void *args)
* solution looks more complex, so leave it as it is. */
down_write(&pool->qpi_recalc_sem);
* solution looks more complex, so leave it as it is. */
down_write(&pool->qpi_recalc_sem);
- rc = lu_env_init(&env, LCT_MD_THREAD);
- if (rc) {
- CERROR("%s: cannot init env: rc = %d\n", obd->obd_name, rc);
- GOTO(out, rc);
- }
-
glbl_pool = qmt_pool_lookup_glb(&env, pool->qpi_qmt, pool->qpi_rtype);
if (IS_ERR(glbl_pool))
glbl_pool = qmt_pool_lookup_glb(&env, pool->qpi_qmt, pool->qpi_rtype);
if (IS_ERR(glbl_pool))
- GOTO(out
_env
, rc = PTR_ERR(glbl_pool));
+ GOTO(out, rc = PTR_ERR(glbl_pool));
slaves_cnt = qmt_sarr_count(pool);
CDEBUG(D_QUOTA, "Starting pool recalculation for %d slaves in %s\n",
slaves_cnt = qmt_sarr_count(pool);
CDEBUG(D_QUOTA, "Starting pool recalculation for %d slaves in %s\n",
@@
-1237,8
+1249,6
@@
static int qmt_pool_recalc(void *args)
GOTO(out_stop, rc);
out_stop:
qpi_putref(&env, glbl_pool);
GOTO(out_stop, rc);
out_stop:
qpi_putref(&env, glbl_pool);
-out_env:
- lu_env_fini(&env);
out:
if (xchg(&pool->qpi_recalc_task, NULL) == NULL)
/*
out:
if (xchg(&pool->qpi_recalc_task, NULL) == NULL)
/*
@@
-1251,12
+1261,20
@@
out:
clear_bit(QPI_FLAG_RECALC_OFFSET, &pool->qpi_flags);
/* Pool can't be changed, since sem has been down.
clear_bit(QPI_FLAG_RECALC_OFFSET, &pool->qpi_flags);
/* Pool can't be changed, since sem has been down.
- * Thus until up_read, no one can restart recalc thread. */
+ * Thus until up_read, no one can restart recalc thread.
+ */
if (sem) {
up_read(sem);
up_write(&pool->qpi_recalc_sem);
}
if (sem) {
up_read(sem);
up_write(&pool->qpi_recalc_sem);
}
- qpi_putref(&env, pool);
+
+ /* qpi_getref has been called in qmt_start_pool_recalc,
+ * however we can't call qpi_putref if lu_env_init failed.
+ */
+ if (env.le_ctx.lc_state == LCS_ENTERED) {
+ qpi_putref(&env, pool);
+ lu_env_fini(&env);
+ }
return rc;
}
return rc;
}
@@
-1349,6
+1367,9
@@
static int qmt_pool_add_rem(struct obd_device *obd, char *poolname,
int rc, idx;
ENTRY;
int rc, idx;
ENTRY;
+ if (qmt->qmt_stopping)
+ RETURN(0);
+
if (strnlen(poolname, LOV_MAXPOOLNAME + 1) > LOV_MAXPOOLNAME)
RETURN(-ENAMETOOLONG);
if (strnlen(poolname, LOV_MAXPOOLNAME + 1) > LOV_MAXPOOLNAME)
RETURN(-ENAMETOOLONG);