X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fosd-zfs%2Fosd_index.c;h=29b0d682fd3e930ac60e6c4c959ce56e36e6bb57;hp=29df71de928b91bdc5c462eae80b7f15cdaa38ad;hb=e84d60ea58e5d236a35eb128e73b6ca4c567373d;hpb=c330a759c70b8328a0821d6f314d61f39e1efe8c diff --git a/lustre/osd-zfs/osd_index.c b/lustre/osd-zfs/osd_index.c index 29df71d..29b0d68 100644 --- a/lustre/osd-zfs/osd_index.c +++ b/lustre/osd-zfs/osd_index.c @@ -1046,20 +1046,43 @@ static struct dt_index_operations osd_dir_ops = { /* * Primitives for index files using binary keys. - * XXX: only 64-bit keys are supported for now. */ +static int osd_prepare_key(struct osd_object *o, __u64 *dst, + const struct dt_key *src) +{ + int size; + + LASSERT(dst); + LASSERT(src); + + /* align keysize to 64bit */ + size = (o->oo_keysize + sizeof(__u64) - 1) / sizeof(__u64); + size *= sizeof(__u64); + + LASSERT(size <= MAXNAMELEN); + + if (unlikely(size > o->oo_keysize)) + memset(dst + o->oo_keysize, 0, size - o->oo_keysize); + memcpy(dst, (const char *)src, o->oo_keysize); + + return size; +} + static int osd_index_lookup(const struct lu_env *env, struct dt_object *dt, struct dt_rec *rec, const struct dt_key *key, struct lustre_capa *capa) { struct osd_object *obj = osd_dt_obj(dt); struct osd_device *osd = osd_obj2dev(obj); + __u64 *k = osd_oti_get(env)->oti_key64; int rc; ENTRY; + rc = osd_prepare_key(obj, k, key); + rc = -zap_lookup_uint64(osd->od_objset.os, obj->oo_db->db_object, - (const __u64 *)key, 1, 8, obj->oo_recsize, + k, rc, obj->oo_recusize, obj->oo_recsize, (void *)rec); RETURN(rc == 0 ? 1 : rc); } @@ -1097,6 +1120,7 @@ static int osd_index_insert(const struct lu_env *env, struct dt_object *dt, struct osd_object *obj = osd_dt_obj(dt); struct osd_device *osd = osd_obj2dev(obj); struct osd_thandle *oh; + __u64 *k = osd_oti_get(env)->oti_key64; int rc; ENTRY; @@ -1107,9 +1131,11 @@ static int osd_index_insert(const struct lu_env *env, struct dt_object *dt, oh = container_of0(th, struct osd_thandle, ot_super); + rc = osd_prepare_key(obj, k, key); + /* Insert (key,oid) into ZAP */ rc = -zap_add_uint64(osd->od_objset.os, obj->oo_db->db_object, - (const __u64 *)key, 1, 8, obj->oo_recsize, + k, rc, obj->oo_recusize, obj->oo_recsize, (void *)rec, oh->ot_tx); RETURN(rc); } @@ -1141,6 +1167,7 @@ static int osd_index_delete(const struct lu_env *env, struct dt_object *dt, struct osd_object *obj = osd_dt_obj(dt); struct osd_device *osd = osd_obj2dev(obj); struct osd_thandle *oh; + __u64 *k = osd_oti_get(env)->oti_key64; int rc; ENTRY; @@ -1148,9 +1175,11 @@ static int osd_index_delete(const struct lu_env *env, struct dt_object *dt, LASSERT(th != NULL); oh = container_of0(th, struct osd_thandle, ot_super); + rc = osd_prepare_key(obj, k, key); + /* Remove binary key from the ZAP */ rc = -zap_remove_uint64(osd->od_objset.os, obj->oo_db->db_object, - (const __u64 *)key, 1, oh->ot_tx); + k, rc, oh->ot_tx); RETURN(rc); } @@ -1165,8 +1194,11 @@ static int osd_index_it_get(const struct lu_env *env, struct dt_it *di, LASSERT(it); LASSERT(it->ozi_zc); - /* XXX: API is broken at the moment */ - LASSERT(*((const __u64 *)key) == 0); + /* + * XXX: we need a binary version of zap_cursor_move_to_key() + * to implement this API */ + if (*((const __u64 *)key) != 0) + CERROR("NOT IMPLEMETED YET (move to %Lx)\n", *((__u64 *)key)); zap_cursor_fini(it->ozi_zc); memset(it->ozi_zc, 0, sizeof(*it->ozi_zc)); @@ -1204,6 +1236,7 @@ static struct dt_key *osd_index_it_key(const struct lu_env *env, const struct dt_it *di) { struct osd_zap_it *it = (struct osd_zap_it *)di; + struct osd_object *obj = it->ozi_obj; zap_attribute_t *za = &osd_oti_get(env)->oti_za; int rc = 0; ENTRY; @@ -1214,7 +1247,7 @@ static struct dt_key *osd_index_it_key(const struct lu_env *env, RETURN(ERR_PTR(rc)); /* the binary key is stored in the name */ - it->ozi_key = *((__u64 *)za->za_name); + memcpy(&it->ozi_key, za->za_name, obj->oo_keysize); RETURN((struct dt_key *)&it->ozi_key); } @@ -1222,8 +1255,9 @@ static struct dt_key *osd_index_it_key(const struct lu_env *env, static int osd_index_it_key_size(const struct lu_env *env, const struct dt_it *di) { - /* we only support 64-bit binary keys for the time being */ - RETURN(sizeof(__u64)); + struct osd_zap_it *it = (struct osd_zap_it *)di; + struct osd_object *obj = it->ozi_obj; + RETURN(obj->oo_keysize); } static int osd_index_it_rec(const struct lu_env *env, const struct dt_it *di, @@ -1233,6 +1267,7 @@ static int osd_index_it_rec(const struct lu_env *env, const struct dt_it *di, struct osd_zap_it *it = (struct osd_zap_it *)di; struct osd_object *obj = it->ozi_obj; struct osd_device *osd = osd_obj2dev(obj); + __u64 *k = osd_oti_get(env)->oti_key64; int rc; ENTRY; @@ -1241,9 +1276,11 @@ static int osd_index_it_rec(const struct lu_env *env, const struct dt_it *di, if (rc) RETURN(rc); + rc = osd_prepare_key(obj, k, (const struct dt_key *)za->za_name); + rc = -zap_lookup_uint64(osd->od_objset.os, obj->oo_db->db_object, - (const __u64 *)za->za_name, 1, 8, - obj->oo_recsize, (void *)rec); + k, rc, obj->oo_recusize, obj->oo_recsize, + (void *)rec); RETURN(rc); } @@ -1339,10 +1376,9 @@ int osd_index_try(const struct lu_env *env, struct dt_object *dt, if ((feat->dif_flags & ~DT_IND_UPDATE) != 0) RETURN(-EINVAL); - /* Although the zap_*_uint64() primitives support large keys, we - * limit ourselves to 64-bit keys for now */ - if (feat->dif_keysize_max != sizeof(__u64) || - feat->dif_keysize_min != sizeof(__u64)) + if (feat->dif_keysize_max > ZAP_MAXNAMELEN) + RETURN(-E2BIG); + if (feat->dif_keysize_max != feat->dif_keysize_min) RETURN(-EINVAL); /* As for the record size, it should be a multiple of 8 bytes @@ -1350,11 +1386,18 @@ int osd_index_try(const struct lu_env *env, struct dt_object *dt, */ if (feat->dif_recsize_max > ZAP_MAXVALUELEN) RETURN(-E2BIG); - if (feat->dif_recsize_max != feat->dif_recsize_min || - (feat->dif_recsize_max & (sizeof(__u64) - 1))) + if (feat->dif_recsize_max != feat->dif_recsize_min) RETURN(-EINVAL); - obj->oo_recsize = feat->dif_recsize_max / sizeof(__u64); + obj->oo_keysize = feat->dif_keysize_max; + obj->oo_recsize = feat->dif_recsize_max; + obj->oo_recusize = 1; + + /* ZFS prefers to work with array of 64bits */ + if ((obj->oo_recsize & 7) == 0) { + obj->oo_recsize >>= 3; + obj->oo_recusize = 8; + } dt->do_index_ops = &osd_index_ops; }