The root object may be accessed via local storage stack and release
the reference by lu_object_put_nocache(), then the root object will
be marked as LU_OBJECT_HEARD_BANSHEE. On the other hand, the LFSCK
still holds reference on the root object. Under such case, if some
others want to access the root object, they have to wait the LFSCK
to release the root object and re-generate the root object in RAM.
But if the LFSCK does not release the reference on the root object
until the device umount, then all the others will hung there.
Test-Parameters: testlist=sanity-lfsck
Signed-off-by: Fan Yong <fan.yong@intel.com>
Change-Id: I068c442ae808bb2f018e93e0a584a35dcf4c2f9c
Reviewed-on: http://review.whamcloud.com/7643
Tested-by: Hudson
Reviewed-by: Niu Yawei <yawei.niu@intel.com>
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
int lfsck_bookmark_setup(const struct lu_env *env,
struct lfsck_instance *lfsck)
{
int lfsck_bookmark_setup(const struct lu_env *env,
struct lfsck_instance *lfsck)
{
+ struct dt_object *root;
struct dt_object *obj;
int rc;
ENTRY;
struct dt_object *obj;
int rc;
ENTRY;
- obj = local_file_find_or_create(env, lfsck->li_los,
- lfsck->li_local_root,
+ root = dt_locate(env, lfsck->li_bottom, &lfsck->li_local_root_fid);
+ if (IS_ERR(root))
+ RETURN(PTR_ERR(root));
+
+ dt_try_as_dir(env, root);
+ obj = local_file_find_or_create(env, lfsck->li_los, root,
lfsck_bookmark_name,
S_IFREG | S_IRUGO | S_IWUSR);
lfsck_bookmark_name,
S_IFREG | S_IRUGO | S_IWUSR);
+ lu_object_put(env, &root->do_lu);
if (IS_ERR(obj))
RETURN(PTR_ERR(obj));
if (IS_ERR(obj))
RETURN(PTR_ERR(obj));
struct dt_device *li_bottom;
struct ldlm_namespace *li_namespace;
struct local_oid_storage *li_los;
struct dt_device *li_bottom;
struct ldlm_namespace *li_namespace;
struct local_oid_storage *li_los;
- struct dt_object *li_local_root; /* backend root "/" */
+ struct lu_fid li_local_root_fid; /* backend root "/" */
struct lu_fid li_global_root_fid; /* /ROOT */
struct dt_object *li_bookmark_obj;
struct lfsck_bookmark li_bookmark_ram;
struct lu_fid li_global_root_fid; /* /ROOT */
struct dt_object *li_bookmark_obj;
struct lfsck_bookmark li_bookmark_ram;
- if (lfsck->li_local_root != NULL) {
- lu_object_put_nocache(env, &lfsck->li_local_root->do_lu);
- lfsck->li_local_root = NULL;
- }
-
- if (unlikely(lu_fid_eq(fid,
- lfsck_dto2fid(lfsck->li_local_root))))
+ if (unlikely(lu_fid_eq(fid, &lfsck->li_local_root_fid)))
return 0;
obj = lfsck_object_find(env, lfsck, fid);
return 0;
obj = lfsck_object_find(env, lfsck, fid);
struct dt_device *next, bool master)
{
struct lfsck_instance *lfsck;
struct dt_device *next, bool master)
{
struct lfsck_instance *lfsck;
- struct dt_object *root;
+ struct dt_object *root = NULL;
struct dt_object *obj;
struct lu_fid *fid = &lfsck_env_info(env)->lti_fid;
int rc;
struct dt_object *obj;
struct lu_fid *fid = &lfsck_env_info(env)->lti_fid;
int rc;
if (IS_ERR(root))
GOTO(out, rc = PTR_ERR(root));
if (IS_ERR(root))
GOTO(out, rc = PTR_ERR(root));
- lfsck->li_local_root = root;
+ lfsck->li_local_root_fid = *fid;
dt_try_as_dir(env, root);
if (master) {
lfsck->li_master = 1;
dt_try_as_dir(env, root);
if (master) {
lfsck->li_master = 1;
add:
rc = lfsck_instance_add(lfsck);
out:
add:
rc = lfsck_instance_add(lfsck);
out:
+ if (root != NULL && !IS_ERR(root))
+ lu_object_put(env, &root->do_lu);
if (rc != 0)
lfsck_instance_cleanup(env, lfsck);
return rc;
if (rc != 0)
lfsck_instance_cleanup(env, lfsck);
return rc;
struct lfsck_instance *lfsck = com->lc_lfsck;
struct lfsck_namespace *ns =
(struct lfsck_namespace *)com->lc_file_ram;
struct lfsck_instance *lfsck = com->lc_lfsck;
struct lfsck_namespace *ns =
(struct lfsck_namespace *)com->lc_file_ram;
+ struct dt_object *root;
struct dt_object *dto;
int rc;
ENTRY;
struct dt_object *dto;
int rc;
ENTRY;
+ root = dt_locate(env, lfsck->li_bottom, &lfsck->li_local_root_fid);
+ if (IS_ERR(root))
+ RETURN(PTR_ERR(root));
+
+ dt_try_as_dir(env, root);
+
down_write(&com->lc_sem);
if (init) {
memset(ns, 0, sizeof(*ns));
down_write(&com->lc_sem);
if (init) {
memset(ns, 0, sizeof(*ns));
ns->ln_magic = LFSCK_NAMESPACE_MAGIC;
ns->ln_status = LS_INIT;
ns->ln_magic = LFSCK_NAMESPACE_MAGIC;
ns->ln_status = LS_INIT;
- rc = local_object_unlink(env, lfsck->li_bottom, lfsck->li_local_root,
+ rc = local_object_unlink(env, lfsck->li_bottom, root,
lfsck_namespace_name);
if (rc != 0)
GOTO(out, rc);
lfsck_object_put(env, com->lc_obj);
com->lc_obj = NULL;
lfsck_namespace_name);
if (rc != 0)
GOTO(out, rc);
lfsck_object_put(env, com->lc_obj);
com->lc_obj = NULL;
- dto = local_index_find_or_create(env, lfsck->li_los, lfsck->li_local_root,
+ dto = local_index_find_or_create(env, lfsck->li_los, root,
lfsck_namespace_name,
S_IFREG | S_IRUGO | S_IWUSR,
&dt_lfsck_features);
lfsck_namespace_name,
S_IFREG | S_IRUGO | S_IWUSR,
&dt_lfsck_features);
out:
up_write(&com->lc_sem);
out:
up_write(&com->lc_sem);
+ lu_object_put(env, &root->do_lu);
{
struct lfsck_component *com;
struct lfsck_namespace *ns;
{
struct lfsck_component *com;
struct lfsck_namespace *ns;
+ struct dt_object *root = NULL;
struct dt_object *obj;
int rc;
ENTRY;
struct dt_object *obj;
int rc;
ENTRY;
if (com->lc_file_disk == NULL)
GOTO(out, rc = -ENOMEM);
if (com->lc_file_disk == NULL)
GOTO(out, rc = -ENOMEM);
- obj = local_index_find_or_create(env, lfsck->li_los,
- lfsck->li_local_root,
+ root = dt_locate(env, lfsck->li_bottom, &lfsck->li_local_root_fid);
+ if (IS_ERR(root))
+ GOTO(out, rc = PTR_ERR(root));
+
+ dt_try_as_dir(env, root);
+ obj = local_index_find_or_create(env, lfsck->li_los, root,
lfsck_namespace_name,
S_IFREG | S_IRUGO | S_IWUSR,
&dt_lfsck_features);
lfsck_namespace_name,
S_IFREG | S_IRUGO | S_IWUSR,
&dt_lfsck_features);
+ if (root != NULL && !IS_ERR(root))
+ lu_object_put(env, &root->do_lu);
if (rc != 0)
lfsck_component_cleanup(env, com);
return rc;
if (rc != 0)
lfsck_component_cleanup(env, com);
return rc;