struct lu_device *dev,
const struct lu_fid *f,
const struct lu_object_conf *conf);
-void lu_object_purge(const struct lu_env *env, struct lu_device *dev,
- const struct lu_fid *f);
struct lu_object *lu_object_find_slice(const struct lu_env *env,
struct lu_device *dev,
const struct lu_fid *f,
extern __u32 lu_context_tags_default;
extern __u32 lu_session_tags_default;
+static inline bool lu_device_is_cl(const struct lu_device *d)
+{
+ return d->ld_type->ldt_tags & LU_DEVICE_CL;
+}
+
+static inline bool lu_object_is_cl(const struct lu_object *o)
+{
+ return lu_device_is_cl(o->lo_dev);
+}
+
/** @} lu */
#endif /* __LUSTRE_LU_OBJECT_H */
} else {
child1 = lfsck_object_find_by_dev(env, dev,
&bk->lb_lpf_fid);
- if (IS_ERR(child1))
- GOTO(put, rc = PTR_ERR(child1));
+ if (IS_ERR(child1)) {
+ child1 = NULL;
+ goto find_child2;
+ }
if (unlikely(!dt_object_exists(child1) ||
dt_object_remote(child1)) ||
}
}
+find_child2:
snprintf(name, 8, "MDT%04x", node);
rc = dt_lookup(env, parent, (struct dt_rec *)cfid,
(const struct dt_key *)name, BYPASS_CAPA);
if (IS_ERR(obj))
GOTO(out, rc = PTR_ERR(obj));
+ if (unlikely(!dt_try_as_dir(env, obj)))
+ GOTO(out, rc = -ENOTDIR);
+
rc = dt_lookup(env, obj, (struct dt_rec *)fid,
(const struct dt_key *)dotlustre, BYPASS_CAPA);
if (rc != 0)
if (rc != 0)
GOTO(out, rc);
+ if (unlikely(!dt_try_as_dir(env, obj)))
+ GOTO(out, rc = -ENOTDIR);
+
*pfid = *fid;
rc = dt_lookup(env, obj, (struct dt_rec *)fid,
(const struct dt_key *)lostfound,
o->lo_ops->loo_object_release(env, o);
}
- if (!lu_object_is_dying(top)) {
+ if (!lu_object_is_dying(top) &&
+ (lu_object_exists(orig) || lu_object_is_cl(orig))) {
LASSERT(list_empty(&top->loh_lru));
list_add_tail(&top->loh_lru, &bkt->lsb_lru);
cfs_hash_bd_unlock(site->ls_obj_hash, &bd, 1);
return ERR_PTR(-EAGAIN);
}
-static struct lu_object *htable_lookup_nowait(struct lu_site *s,
- cfs_hash_bd_t *bd,
- const struct lu_fid *f)
-{
- struct hlist_node *hnode;
- struct lu_object_header *h;
-
- /* cfs_hash_bd_peek_locked is a somehow "internal" function
- * of cfs_hash, it doesn't add refcount on object. */
- hnode = cfs_hash_bd_peek_locked(s->ls_obj_hash, bd, (void *)f);
- if (hnode == NULL) {
- lprocfs_counter_incr(s->ls_stats, LU_SS_CACHE_MISS);
- return ERR_PTR(-ENOENT);
- }
-
- h = container_of0(hnode, struct lu_object_header, loh_hash);
- if (unlikely(lu_object_is_dying(h)))
- return ERR_PTR(-ENOENT);
-
- cfs_hash_get(s->ls_obj_hash, hnode);
- lprocfs_counter_incr(s->ls_stats, LU_SS_CACHE_HIT);
- list_del_init(&h->loh_lru);
- return lu_object_top(h);
-}
-
/**
* Search cache for an object with the fid \a f. If such object is found,
* return it. Otherwise, create new object, insert it into cache and return
EXPORT_SYMBOL(lu_object_find_at);
/**
- * Try to find the object in cache without waiting for the dead object
- * to be released nor allocating object if no cached one was found.
- *
- * The found object will be set as LU_OBJECT_HEARD_BANSHEE for purging.
- */
-void lu_object_purge(const struct lu_env *env, struct lu_device *dev,
- const struct lu_fid *f)
-{
- struct lu_site *s = dev->ld_site;
- cfs_hash_t *hs = s->ls_obj_hash;
- cfs_hash_bd_t bd;
- struct lu_object *o;
-
- cfs_hash_bd_get_and_lock(hs, f, &bd, 1);
- o = htable_lookup_nowait(s, &bd, f);
- cfs_hash_bd_unlock(hs, &bd, 1);
- if (!IS_ERR(o)) {
- set_bit(LU_OBJECT_HEARD_BANSHEE, &o->lo_header->loh_flags);
- lu_object_put(env, o);
- }
-}
-EXPORT_SYMBOL(lu_object_purge);
-
-/**
* Find object with given fid, and return its slice belonging to given device.
*/
struct lu_object *lu_object_find_slice(const struct lu_env *env,
sf->sf_items_updated_prior++;
else
sf->sf_items_updated++;
-
- /* The target has been changed, need to be re-loaded. */
- lu_object_purge(info->oti_env, osd2lu_dev(dev), fid);
}
GOTO(out, rc);
again:
if (thread_is_running(thread)) {
spin_unlock(&scrub->os_lock);
- if (!scrub->os_partial_scan || flags & SS_AUTO_PARTIAL)
+ if (!(scrub->os_file.sf_flags & SF_AUTO) ||
+ (flags & (SS_AUTO_FULL | SS_AUTO_PARTIAL)))
RETURN(-EALREADY);
osd_scrub_join(dev, flags, false);