Whamcloud - gitweb
LU-14119 osd: add mount option "resetoi"
[fs/lustre-release.git] / lustre / osd-zfs / osd_oi.c
index f62a68c..38ff708 100644 (file)
@@ -211,7 +211,7 @@ static int osd_obj_create(const struct lu_env *env, struct osd_device *o,
 
        zde->zde_dnode = oid;
        zde->zde_pad = 0;
-       zde->zde_type = IFTODT(isdir ? S_IFDIR : S_IFREG);
+       zde->zde_type = S_DT(isdir ? S_IFDIR : S_IFREG);
        rc = -zap_add(o->od_os, parent, name, 8, 1, (void *)zde, tx);
 
        GOTO(commit, rc);
@@ -228,6 +228,65 @@ out:
        return rc;
 }
 
+static int osd_oi_destroy(const struct lu_env *env, struct osd_device *o,
+                         const char *name)
+{
+       struct osd_oi oi;
+       dmu_tx_t *tx;
+       dnode_t *rootdn;
+       uint64_t oid;
+       int rc;
+
+       ENTRY;
+
+       if (o->od_dt_dev.dd_rdonly)
+               RETURN(-EROFS);
+
+       rc = osd_oi_lookup(env, o, o->od_rootid, name, &oi);
+       if (rc == -ENOENT)
+               RETURN(0);
+       if (rc)
+               RETURN(rc);
+
+       oid = oi.oi_zapid;
+
+       rc = __osd_obj2dnode(o->od_os, o->od_rootid, &rootdn);
+       if (rc)
+               RETURN(rc);
+
+       tx = dmu_tx_create(o->od_os);
+       dmu_tx_mark_netfree(tx);
+       dmu_tx_hold_free(tx, oid, 0, DMU_OBJECT_END);
+       osd_tx_hold_zap(tx, oid, rootdn, FALSE, NULL);
+       rc = -dmu_tx_assign(tx, TXG_WAIT);
+       if (rc) {
+               dmu_tx_abort(tx);
+               GOTO(out, rc);
+       }
+
+       rc = -dmu_object_free(o->od_os, oid, tx);
+       if (rc) {
+               CERROR("%s: failed to free %s %llu: rc = %d\n",
+                      o->od_svname, name, oid, rc);
+               GOTO(commit, rc);
+       }
+
+       rc = osd_zap_remove(o, o->od_rootid, rootdn, name, tx);
+       if (rc) {
+               CERROR("%s: zap_remove %s failed: rc = %d\n",
+                      o->od_svname, name, rc);
+               GOTO(commit, rc);
+       }
+
+       EXIT;
+commit:
+       dmu_tx_commit(tx);
+out:
+       osd_dnode_rele(rootdn);
+
+       return rc;
+}
+
 static int
 osd_oi_find_or_create(const struct lu_env *env, struct osd_device *o,
                      uint64_t parent, const char *name, uint64_t *child)
@@ -388,8 +447,7 @@ static struct osd_seq *osd_find_or_add_seq(const struct lu_env *env,
        /* Init subdir count to be 32, but each seq can have
         * different subdir count */
        osd_seq->os_subdir_count = OSD_OST_MAP_SIZE;
-       OBD_ALLOC(osd_seq->os_compat_dirs,
-                 sizeof(uint64_t) * osd_seq->os_subdir_count);
+       OBD_ALLOC_PTR_ARRAY(osd_seq->os_compat_dirs, osd_seq->os_subdir_count);
        if (osd_seq->os_compat_dirs == NULL)
                GOTO(out, rc = -ENOMEM);
 
@@ -421,8 +479,8 @@ out:
        up(&seq_list->osl_seq_init_sem);
        if (rc != 0) {
                if (osd_seq != NULL && osd_seq->os_compat_dirs != NULL)
-                       OBD_FREE(osd_seq->os_compat_dirs,
-                                sizeof(uint64_t) * osd_seq->os_subdir_count);
+                       OBD_FREE_PTR_ARRAY(osd_seq->os_compat_dirs,
+                                          osd_seq->os_subdir_count);
                if (osd_seq != NULL)
                        OBD_FREE_PTR(osd_seq);
                osd_seq = ERR_PTR(rc);
@@ -782,8 +840,8 @@ static void osd_ost_seq_fini(const struct lu_env *env, struct osd_device *osd)
        list_for_each_entry_safe(osd_seq, tmp, &osl->osl_seq_list,
                                 os_seq_list) {
                list_del(&osd_seq->os_seq_list);
-               OBD_FREE(osd_seq->os_compat_dirs,
-                        sizeof(uint64_t) * osd_seq->os_subdir_count);
+               OBD_FREE_PTR_ARRAY(osd_seq->os_compat_dirs,
+                                  osd_seq->os_subdir_count);
                OBD_FREE(osd_seq, sizeof(*osd_seq));
        }
        write_unlock(&osl->osl_seq_list_lock);
@@ -845,7 +903,7 @@ osd_oi_init_remote_parent(const struct lu_env *env, struct osd_device *o)
 /**
  * Initialize the OIs by either opening or creating them as needed.
  */
-int osd_oi_init(const struct lu_env *env, struct osd_device *o)
+int osd_oi_init(const struct lu_env *env, struct osd_device *o, bool reset)
 {
        struct lustre_scrub *scrub = &o->od_scrub;
        struct scrub_file *sf = &scrub->os_file;
@@ -872,7 +930,7 @@ int osd_oi_init(const struct lu_env *env, struct osd_device *o)
                GOTO(out, rc = count);
 
        if (count > 0) {
-               if (count == sf->sf_oi_count)
+               if (count == sf->sf_oi_count && !reset)
                        goto open;
 
                if (sf->sf_oi_count == 0) {
@@ -909,11 +967,20 @@ int osd_oi_init(const struct lu_env *env, struct osd_device *o)
        if (rc)
                GOTO(out, rc);
 
+       if (reset)
+               LCONSOLE_WARN("%s: reset Object Index mappings\n",
+                             osd_name(o));
+
        for (i = 0; i < count; i++) {
                LASSERT(sizeof(osd_oti_get(env)->oti_buf) >= 32);
 
                snprintf(key, sizeof(osd_oti_get(env)->oti_buf) - 1,
                         "%s.%d", DMU_OSD_OI_NAME_BASE, i);
+               if (reset) {
+                       rc = osd_oi_destroy(env, o, key);
+                       if (rc)
+                               GOTO(out, rc);
+               }
                rc = osd_oi_find_or_create(env, o, o->od_root, key, &sdb);
                if (rc)
                        GOTO(out, rc);
@@ -922,7 +989,7 @@ int osd_oi_init(const struct lu_env *env, struct osd_device *o)
 open:
        LASSERT((count & (count - 1)) == 0);
        o->od_oi_count = count;
-       OBD_ALLOC(o->od_oi_table, sizeof(*o->od_oi_table) * count);
+       OBD_ALLOC_PTR_ARRAY(o->od_oi_table, count);
        if (o->od_oi_table == NULL)
                GOTO(out, rc = -ENOMEM);
 
@@ -935,8 +1002,7 @@ out:
                osd_ost_seq_fini(env, o);
 
                if (o->od_oi_table) {
-                       OBD_FREE(o->od_oi_table,
-                                sizeof(struct osd_oi *) * count);
+                       OBD_FREE_PTR_ARRAY(o->od_oi_table, count);
                        o->od_oi_table = NULL;
                }
        }
@@ -952,8 +1018,7 @@ void osd_oi_fini(const struct lu_env *env, struct osd_device *o)
 
        if (o->od_oi_table != NULL) {
                (void) osd_oi_close_table(env, o);
-               OBD_FREE(o->od_oi_table,
-                        sizeof(struct osd_oi *) * o->od_oi_count);
+               OBD_FREE_PTR_ARRAY(o->od_oi_table, o->od_oi_count);
                o->od_oi_table = NULL;
                o->od_oi_count = 0;
        }
@@ -1013,14 +1078,14 @@ struct osd_idmap_cache *osd_idc_add(const struct lu_env *env,
                i = oti->oti_ins_cache_size * 2;
                if (i == 0)
                        i = OSD_INS_CACHE_SIZE;
-               OBD_ALLOC_LARGE(idc, sizeof(*idc) * i);
+               OBD_ALLOC_PTR_ARRAY_LARGE(idc, i);
                if (idc == NULL)
                        return ERR_PTR(-ENOMEM);
                if (oti->oti_ins_cache != NULL) {
                        memcpy(idc, oti->oti_ins_cache,
                               oti->oti_ins_cache_used * sizeof(*idc));
-                       OBD_FREE_LARGE(oti->oti_ins_cache,
-                                oti->oti_ins_cache_used * sizeof(*idc));
+                       OBD_FREE_PTR_ARRAY_LARGE(oti->oti_ins_cache,
+                                                oti->oti_ins_cache_used);
                }
                oti->oti_ins_cache = idc;
                oti->oti_ins_cache_size = i;