- old_ops = &lov_dispatch[obj->lo_type];
- new_ops = &lov_dispatch[llt];
-
- result = new_ops->llo_init(env, lu2lov_dev(obj->lo_cl.co_lu.lo_dev),
- obj, conf, state);
- if (result == 0) {
- struct cl_object_header *hdr = cl_object_header(&obj->lo_cl);
- void *cookie;
- struct lu_env *nested;
- int refcheck;
-
- cookie = cl_env_reenter();
- nested = cl_env_get(&refcheck);
- if (!IS_ERR(nested))
- cl_object_prune(nested, &obj->lo_cl);
- else
- result = PTR_ERR(nested);
- cl_env_put(nested, &refcheck);
- cl_env_reexit(cookie);
-
- old_ops->llo_fini(env, obj, &obj->u);
- LASSERT(list_empty(&hdr->coh_locks));
- LASSERT(hdr->coh_tree.rnode == NULL);
- LASSERT(hdr->coh_pages == 0);
-
- new_ops->llo_install(env, obj, state);
- obj->lo_type = llt;
- } else
- new_ops->llo_fini(env, obj, state);
- RETURN(result);
+static int lov_layout_wait(const struct lu_env *env, struct lov_object *lov)
+{
+ struct l_wait_info lwi = { 0 };
+ ENTRY;
+
+ while (cfs_atomic_read(&lov->lo_active_ios) > 0) {
+ CDEBUG(D_INODE, "file:"DFID" wait for active IO, now: %d.\n",
+ PFID(lu_object_fid(lov2lu(lov))),
+ cfs_atomic_read(&lov->lo_active_ios));
+
+ l_wait_event(lov->lo_waitq,
+ cfs_atomic_read(&lov->lo_active_ios) == 0, &lwi);
+ }
+ RETURN(0);
+}
+
+static int lov_layout_change(const struct lu_env *unused,
+ struct lov_object *lov,
+ const struct cl_object_conf *conf)
+{
+ int result;
+ enum lov_layout_type llt = LLT_EMPTY;
+ union lov_layout_state *state = &lov->u;
+ const struct lov_layout_operations *old_ops;
+ const struct lov_layout_operations *new_ops;
+
+ struct cl_object_header *hdr = cl_object_header(&lov->lo_cl);
+ void *cookie;
+ struct lu_env *env;
+ int refcheck;
+ ENTRY;
+
+ LASSERT(0 <= lov->lo_type && lov->lo_type < ARRAY_SIZE(lov_dispatch));
+
+ if (conf->u.coc_md != NULL && conf->u.coc_md->lsm != NULL)
+ llt = LLT_RAID0; /* only raid0 is supported. */
+ LASSERT(0 <= llt && llt < ARRAY_SIZE(lov_dispatch));
+
+ cookie = cl_env_reenter();
+ env = cl_env_get(&refcheck);
+ if (IS_ERR(env)) {
+ cl_env_reexit(cookie);
+ RETURN(PTR_ERR(env));
+ }
+
+ old_ops = &lov_dispatch[lov->lo_type];
+ new_ops = &lov_dispatch[llt];
+
+ result = old_ops->llo_delete(env, lov, &lov->u);
+ if (result == 0) {
+ old_ops->llo_fini(env, lov, &lov->u);
+
+ LASSERT(cfs_atomic_read(&lov->lo_active_ios) == 0);
+ LASSERT(hdr->coh_tree.rnode == NULL);
+ LASSERT(hdr->coh_pages == 0);
+
+ lov->lo_type = LLT_EMPTY;
+ result = new_ops->llo_init(env,
+ lu2lov_dev(lov->lo_cl.co_lu.lo_dev),
+ lov, conf, state);
+ if (result == 0) {
+ new_ops->llo_install(env, lov, state);
+ lov->lo_type = llt;
+ } else {
+ new_ops->llo_delete(env, lov, state);
+ new_ops->llo_fini(env, lov, state);
+ /* this file becomes an EMPTY file. */
+ }
+ }
+
+ cl_env_put(env, &refcheck);
+ cl_env_reexit(cookie);
+ RETURN(result);