Whamcloud - gitweb
LU-12296 llite: improve ll_dom_lock_cancel
[fs/lustre-release.git] / lustre / lov / lov_object.c
index 1b337a2..cc041c0 100644 (file)
@@ -76,6 +76,8 @@ struct lov_layout_operations {
                             struct cl_object *obj, struct cl_io *io);
         int  (*llo_getattr)(const struct lu_env *env, struct cl_object *obj,
                             struct cl_attr *attr);
+       int  (*llo_flush)(const struct lu_env *env, struct cl_object *obj,
+                         struct ldlm_lock *lock);
 };
 
 static int lov_layout_wait(const struct lu_env *env, struct lov_object *lov);
@@ -213,9 +215,8 @@ static int lov_init_raid0(const struct lu_env *env, struct lov_device *dev,
 
        spin_lock_init(&r0->lo_sub_lock);
        r0->lo_nr = lse->lsme_stripe_count;
-       LASSERT(r0->lo_nr <= lov_targets_nr(dev));
 
-       OBD_ALLOC_LARGE(r0->lo_sub, r0->lo_nr * sizeof r0->lo_sub[0]);
+       OBD_ALLOC_LARGE(r0->lo_sub, r0->lo_nr * sizeof(r0->lo_sub[0]));
        if (r0->lo_sub == NULL)
                GOTO(out, result = -ENOMEM);
 
@@ -282,14 +283,14 @@ static void lov_subobject_kill(const struct lu_env *env, struct lov_object *lov,
 {
        struct cl_object        *sub;
        struct lu_site          *site;
-       struct lu_site_bkt_data *bkt;
-       wait_queue_t          *waiter;
+       wait_queue_head_t *wq;
+       wait_queue_entry_t *waiter;
 
         LASSERT(r0->lo_sub[idx] == los);
 
-        sub  = lovsub2cl(los);
-        site = sub->co_lu.lo_dev->ld_site;
-        bkt  = lu_site_bkt_from_fid(site, &sub->co_lu.lo_header->loh_fid);
+       sub = lovsub2cl(los);
+       site = sub->co_lu.lo_dev->ld_site;
+       wq = lu_site_wq_from_fid(site, &sub->co_lu.lo_header->loh_fid);
 
         cl_object_kill(env, sub);
         /* release a reference to the sub-object and ... */
@@ -301,7 +302,7 @@ static void lov_subobject_kill(const struct lu_env *env, struct lov_object *lov,
        if (r0->lo_sub[idx] == los) {
                waiter = &lov_env_info(env)->lti_waiter;
                init_waitqueue_entry(waiter, current);
-               add_wait_queue(&bkt->lsb_marche_funebre, waiter);
+               add_wait_queue(wq, waiter);
                set_current_state(TASK_UNINTERRUPTIBLE);
                while (1) {
                        /* this wait-queue is signaled at the end of
@@ -317,7 +318,7 @@ static void lov_subobject_kill(const struct lu_env *env, struct lov_object *lov,
                                break;
                        }
                }
-               remove_wait_queue(&bkt->lsb_marche_funebre, waiter);
+               remove_wait_queue(wq, waiter);
        }
        LASSERT(r0->lo_sub[idx] == NULL);
 }
@@ -812,10 +813,25 @@ static int lov_init_released(const struct lu_env *env,
        return 0;
 }
 
+static int lov_init_foreign(const struct lu_env *env,
+                           struct lov_device *dev, struct lov_object *lov,
+                           struct lov_stripe_md *lsm,
+                           const struct cl_object_conf *conf,
+                           union lov_layout_state *state)
+{
+       LASSERT(lsm != NULL);
+       LASSERT(lov->lo_type == LLT_FOREIGN);
+       LASSERT(lov->lo_lsm == NULL);
+
+       lov->lo_lsm = lsm_addref(lsm);
+       return 0;
+}
+
 static int lov_delete_empty(const struct lu_env *env, struct lov_object *lov,
                            union lov_layout_state *state)
 {
-       LASSERT(lov->lo_type == LLT_EMPTY || lov->lo_type == LLT_RELEASED);
+       LASSERT(lov->lo_type == LLT_EMPTY || lov->lo_type == LLT_RELEASED ||
+               lov->lo_type == LLT_FOREIGN);
 
        lov_layout_wait(env, lov);
        return 0;
@@ -937,6 +953,23 @@ static int lov_print_released(const struct lu_env *env, void *cookie,
        return 0;
 }
 
+static int lov_print_foreign(const struct lu_env *env, void *cookie,
+                               lu_printer_t p, const struct lu_object *o)
+{
+       struct lov_object       *lov = lu2lov(o);
+       struct lov_stripe_md    *lsm = lov->lo_lsm;
+
+       (*p)(env, cookie,
+               "foreign: %s, lsm{%p 0x%08X %d %u}:\n",
+               lov->lo_layout_invalid ? "invalid" : "valid", lsm,
+               lsm->lsm_magic, atomic_read(&lsm->lsm_refc),
+               lsm->lsm_layout_gen);
+       (*p)(env, cookie,
+               "raw_ea_content '%.*s'\n",
+               (int)lsm->lsm_foreign_size, (char *)lsm_foreign(lsm));
+       return 0;
+}
+
 /**
  * Implements cl_object_operations::coo_attr_get() method for an object
  * without stripes (LLT_EMPTY layout type).
@@ -1004,6 +1037,22 @@ static int lov_attr_get_composite(const struct lu_env *env,
        RETURN(0);
 }
 
+static int lov_flush_composite(const struct lu_env *env,
+                              struct cl_object *obj,
+                              struct ldlm_lock *lock)
+{
+       struct lov_object *lov = cl2lov(obj);
+       struct lovsub_object *lovsub;
+
+       ENTRY;
+
+       if (!lsme_is_dom(lov->lo_lsm->lsm_entries[0]))
+               RETURN(-EINVAL);
+
+       lovsub = lov->u.composite.lo_entries[0].lle_dom.lo_dom;
+       RETURN(cl_object_flush(env, lovsub2cl(lovsub), lock));
+}
+
 const static struct lov_layout_operations lov_dispatch[] = {
        [LLT_EMPTY] = {
                .llo_init      = lov_init_empty,
@@ -1034,6 +1083,17 @@ const static struct lov_layout_operations lov_dispatch[] = {
                .llo_lock_init = lov_lock_init_composite,
                .llo_io_init   = lov_io_init_composite,
                .llo_getattr   = lov_attr_get_composite,
+               .llo_flush     = lov_flush_composite,
+       },
+       [LLT_FOREIGN] = {
+               .llo_init      = lov_init_foreign,
+               .llo_delete    = lov_delete_empty,
+               .llo_fini      = lov_fini_released,
+               .llo_print     = lov_print_foreign,
+               .llo_page_init = lov_page_init_foreign,
+               .llo_lock_init = lov_lock_init_empty,
+               .llo_io_init   = lov_io_init_empty,
+               .llo_getattr   = lov_attr_get_empty,
        },
 };
 
@@ -1066,6 +1126,9 @@ static enum lov_layout_type lov_type(struct lov_stripe_md *lsm)
            lsm->lsm_magic == LOV_MAGIC_COMP_V1)
                return LLT_COMP;
 
+       if (lsm->lsm_magic == LOV_MAGIC_FOREIGN)
+               return LLT_FOREIGN;
+
        return LLT_EMPTY;
 }
 
@@ -1647,7 +1710,7 @@ int fiemap_for_stripe(const struct lu_env *env, struct cl_object *obj,
        if (lun_start == lun_end)
                return 0;
 
-       req_fm_len = obd_object_end - lun_start;
+       req_fm_len = obd_object_end - lun_start + 1;
        fs->fs_fm->fm_length = 0;
        len_mapped_single_call = 0;
 
@@ -1690,7 +1753,7 @@ int fiemap_for_stripe(const struct lu_env *env, struct cl_object *obj,
                        fs->fs_fm->fm_mapped_extents = 1;
 
                        fm_ext[0].fe_logical = lun_start;
-                       fm_ext[0].fe_length = obd_object_end - lun_start;
+                       fm_ext[0].fe_length = obd_object_end - lun_start + 1;
                        fm_ext[0].fe_flags |= FIEMAP_EXTENT_UNKNOWN;
 
                        goto inactive_tgt;
@@ -2000,6 +2063,7 @@ static int lov_object_layout_get(const struct lu_env *env,
        cl->cl_size = lov_comp_md_size(lsm);
        cl->cl_layout_gen = lsm->lsm_layout_gen;
        cl->cl_dom_comp_size = 0;
+       cl->cl_is_released = lsm->lsm_is_released;
        if (lsm_is_composite(lsm->lsm_magic)) {
                struct lov_stripe_md_entry *lsme = lsm->lsm_entries[0];
 
@@ -2033,6 +2097,12 @@ static loff_t lov_object_maxbytes(struct cl_object *obj)
        return maxbytes;
 }
 
+static int lov_object_flush(const struct lu_env *env, struct cl_object *obj,
+                           struct ldlm_lock *lock)
+{
+       return LOV_2DISPATCH_NOLOCK(cl2lov(obj), llo_flush, env, obj, lock);
+}
+
 static const struct cl_object_operations lov_ops = {
        .coo_page_init    = lov_page_init,
        .coo_lock_init    = lov_lock_init,
@@ -2044,6 +2114,7 @@ static const struct cl_object_operations lov_ops = {
        .coo_layout_get   = lov_object_layout_get,
        .coo_maxbytes     = lov_object_maxbytes,
        .coo_fiemap       = lov_object_fiemap,
+       .coo_object_flush = lov_object_flush
 };
 
 static const struct lu_object_operations lov_lu_obj_ops = {
@@ -2137,6 +2208,8 @@ int lov_read_and_clear_async_rc(struct cl_object *clob)
                }
                case LLT_RELEASED:
                case LLT_EMPTY:
+                       /* fall through */
+               case LLT_FOREIGN:
                        break;
                default:
                        LBUG();