Whamcloud - gitweb
LU-14119 osd: add mount option "resetoi"
[fs/lustre-release.git] / lustre / osd-zfs / osd_oi.c
index b499263..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);
@@ -538,7 +596,7 @@ osd_get_name_n_idx_compat(const struct lu_env *env, struct osd_device *osd,
        if (zdn != NULL)
                *zdn = NULL;
 
-       if (fid_is_on_ost(env, osd, fid) == 1 || fid_seq(fid) == FID_SEQ_ECHO) {
+       if (fid_is_echo(fid) || fid_is_on_ost(env, osd, fid)) {
                zapid = osd_get_idx_for_ost_obj_compat(env, osd, fid,
                                                       buf, bufsize);
        } else if (unlikely(fid_seq(fid) == FID_SEQ_LOCAL_FILE)) {
@@ -572,8 +630,8 @@ uint64_t osd_get_name_n_idx(const struct lu_env *env, struct osd_device *osd,
        if (zdn != NULL)
                *zdn = NULL;
 
-       if (fid_is_on_ost(env, osd, fid) == 1 || fid_seq(fid) == FID_SEQ_ECHO ||
-           fid_is_last_id(fid)) {
+       if (fid_is_echo(fid) || fid_is_last_id(fid) ||
+           fid_is_on_ost(env, osd, fid)) {
                zapid = osd_get_idx_for_ost_obj(env, osd, fid, buf, bufsize);
        } else if (unlikely(fid_seq(fid) == FID_SEQ_LOCAL_FILE)) {
                /* special objects with fixed known fids get their name */
@@ -782,13 +840,11 @@ 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);
-
-       return;
 }
 
 /**
@@ -847,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;
@@ -874,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) {
@@ -911,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);
@@ -924,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(struct osd_oi *) * count);
+       OBD_ALLOC_PTR_ARRAY(o->od_oi_table, count);
        if (o->od_oi_table == NULL)
                GOTO(out, rc = -ENOMEM);
 
@@ -937,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;
                }
        }
@@ -954,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,17 +1076,16 @@ struct osd_idmap_cache *osd_idc_add(const struct lu_env *env,
 
        if (unlikely(oti->oti_ins_cache_used >= oti->oti_ins_cache_size)) {
                i = oti->oti_ins_cache_size * 2;
-               LASSERT(i < 1000);
                if (i == 0)
                        i = OSD_INS_CACHE_SIZE;
-               OBD_ALLOC(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(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;
@@ -1059,10 +1121,16 @@ struct osd_idmap_cache *osd_idc_find_or_init(const struct lu_env *env,
        if (idc != NULL)
                return idc;
 
+       CDEBUG(D_INODE, "%s: FID "DFID" not in the id map cache\n",
+              osd->od_svname, PFID(fid));
+
        /* new mapping is needed */
        idc = osd_idc_add(env, osd, fid);
-       if (IS_ERR(idc))
+       if (IS_ERR(idc)) {
+               CERROR("%s: FID "DFID" add id map cache failed: %ld\n",
+                      osd->od_svname, PFID(fid), PTR_ERR(idc));
                return idc;
+       }
 
        /* initialize it */
        rc = osd_remote_fid(env, osd, fid);
@@ -1107,10 +1175,16 @@ int osd_idc_find_and_init(const struct lu_env *env, struct osd_device *osd,
                return 0;
        }
 
+       CDEBUG(D_INODE, "%s: FID "DFID" not in the id map cache\n",
+              osd->od_svname, PFID(fid));
+
        /* new mapping is needed */
        idc = osd_idc_add(env, osd, fid);
-       if (IS_ERR(idc))
+       if (IS_ERR(idc)) {
+               CERROR("%s: FID "DFID" add id map cache failed: %ld\n",
+                      osd->od_svname, PFID(fid), PTR_ERR(idc));
                return PTR_ERR(idc);
+       }
 
        if (obj->oo_dn)
                idc->oic_dnode = obj->oo_dn->dn_object;