From 930bcca512418852ba6aaed1fb29f510d4980a34 Mon Sep 17 00:00:00 2001 From: nikita Date: Sun, 2 Jul 2006 21:15:32 +0000 Subject: [PATCH] osd: cleanup index code --- lustre/osd/osd_handler.c | 291 ++++++++++++++++++++++++++++------------------- 1 file changed, 174 insertions(+), 117 deletions(-) diff --git a/lustre/osd/osd_handler.c b/lustre/osd/osd_handler.c index 3829919..39563a6 100644 --- a/lustre/osd/osd_handler.c +++ b/lustre/osd/osd_handler.c @@ -150,6 +150,7 @@ static int osd_index_probe (const struct lu_context *ctxt, static int osd_index_try (const struct lu_context *ctx, struct dt_object *dt, const struct dt_index_features *feat); +static void osd_index_fini (struct osd_object *o); static struct osd_object *osd_obj (const struct lu_object *o); static struct osd_device *osd_dev (const struct lu_device *d); @@ -182,6 +183,7 @@ static struct lu_context_key osd_key; static struct dt_object_operations osd_obj_ops; static struct dt_body_operations osd_body_ops; static struct dt_index_operations osd_index_ops; +static struct dt_index_operations osd_index_compat_ops; struct osd_thandle { struct thandle ot_super; @@ -269,11 +271,7 @@ static struct lu_object *osd_object_alloc(const struct lu_context *ctx, static void osd_object_init0(struct osd_object *obj) { LASSERT(obj->oo_inode != NULL); - - if (S_ISDIR(obj->oo_inode->i_mode)) - obj->oo_dt.do_index_ops = &osd_index_ops; - else - obj->oo_dt.do_body_ops = &osd_body_ops; + obj->oo_dt.do_body_ops = &osd_body_ops; } static int osd_object_init(const struct lu_context *ctxt, struct lu_object *l) @@ -302,13 +300,10 @@ static void osd_object_free(const struct lu_context *ctx, struct lu_object *l) OBD_FREE_PTR(obj); } -static void osd_object_delete(const struct lu_context *ctx, struct lu_object *l) +static void osd_index_fini(struct osd_object *o) { - struct osd_object *o = osd_obj(l); struct iam_container *bag; - LASSERT(osd_invariant(o)); - bag = &o->oo_container; if (o->oo_ipd != NULL) { LASSERT(bag->ic_descr->id_ops->id_ipd_free != NULL); @@ -317,8 +312,19 @@ static void osd_object_delete(const struct lu_context *ctx, struct lu_object *l) if (o->oo_inode != NULL) { if (o->oo_container.ic_object == o->oo_inode) iam_container_fini(&o->oo_container); - iput(o->oo_inode); - o->oo_inode = NULL; + } +} + +static void osd_object_delete(const struct lu_context *ctx, struct lu_object *l) +{ + struct osd_object *obj = osd_obj(l); + + LASSERT(osd_invariant(obj)); + + osd_index_fini(obj); + if (obj->oo_inode != NULL) { + iput(obj->oo_inode); + obj->oo_inode = NULL; } } @@ -557,7 +563,7 @@ static int osd_mkdir(struct osd_thread_info *info, struct osd_object *obj, LASSERT(dentry->d_inode != NULL); obj->oo_inode = dentry->d_inode; igrab(obj->oo_inode); - obj->oo_dt.do_index_ops = &osd_index_ops; + obj->oo_dt.do_index_ops = &osd_index_compat_ops; } dput(dentry); } else @@ -598,7 +604,6 @@ static int osd_mkreg(struct osd_thread_info *info, struct osd_object *obj, LASSERT(dentry->d_inode != NULL); obj->oo_inode = dentry->d_inode; igrab(obj->oo_inode); - obj->oo_dt.do_index_ops = &osd_index_ops; } dput(dentry); } else @@ -815,7 +820,14 @@ static int osd_index_probe(const struct lu_context *ctxt, struct osd_object *o, descr = o->oo_container.ic_descr; if (feat == &dt_directory_features) - return descr == &iam_htree_compat_param; + return osd_sb(osd_obj2dev(o))->s_root->d_inode == o->oo_inode || + descr == &iam_htree_compat_param || + (descr->id_rec_size == sizeof(struct lu_fid) && + 1 /* + * XXX check that index looks like directory. + */ + ); + else return feat->dif_keysize_min <= descr->id_key_size && @@ -833,32 +845,41 @@ static int osd_index_try(const struct lu_context *ctx, struct dt_object *dt, const struct dt_index_features *feat) { int result; - struct osd_object *obj = osd_dt_obj(dt); - struct iam_container *bag; + struct osd_object *obj = osd_dt_obj(dt); LASSERT(osd_invariant(obj)); LASSERT(lu_object_exists(ctx, &dt->do_lu)); - if (osd_has_index(obj)) - return 0; + if (osd_sb(osd_obj2dev(obj))->s_root->d_inode == obj->oo_inode) { + dt->do_index_ops = &osd_index_compat_ops; + result = 0; + } else if (!osd_has_index(obj)) { + struct iam_container *bag; - bag = &obj->oo_container; - result = iam_container_init(bag, &obj->oo_descr, obj->oo_inode); - if (result == 0) { - result = iam_container_setup(bag); + bag = &obj->oo_container; + result = iam_container_init(bag, &obj->oo_descr, obj->oo_inode); if (result == 0) { - if (osd_index_probe(ctx, obj, feat)) { + result = iam_container_setup(bag); + if (result == 0) { struct iam_path_descr *ipd; + LASSERT(obj->oo_ipd == NULL); ipd = bag->ic_descr->id_ops->id_ipd_alloc(bag); if (ipd != NULL) { obj->oo_ipd = ipd; dt->do_index_ops = &osd_index_ops; } else result = -ENOMEM; - } else - result = -EINVAL; + } } + } else + result = 0; + + if (result == 0) { + if (osd_index_probe(ctx, obj, feat)) + result = 0; + else + result = -ENOTDIR; } LASSERT(osd_invariant(obj)); return result; @@ -888,90 +909,144 @@ static int osd_index_delete(const struct lu_context *ctxt, struct dt_object *dt, RETURN(rc); } -/* - * XXX This is temporary solution: inode operations are used until iam is - * ready. - */ static int osd_index_lookup(const struct lu_context *ctxt, struct dt_object *dt, struct dt_rec *rec, const struct dt_key *key) { struct osd_object *obj = osd_dt_obj(dt); + + int rc; + + ENTRY; + LASSERT(osd_invariant(obj)); + LASSERT(lu_object_exists(ctxt, &dt->do_lu)); + LASSERT(obj->oo_container.ic_object == obj->oo_inode); + LASSERT(obj->oo_ipd != NULL); - if (!S_ISDIR(obj->oo_inode->i_mode)) { - int rc; + rc = iam_lookup(&obj->oo_container, (const struct iam_key *)key, + (struct iam_rec *)rec, obj->oo_ipd); - ENTRY; + LASSERT(osd_invariant(obj)); + RETURN(rc); +} - LASSERT(lu_object_exists(ctxt, &dt->do_lu)); - LASSERT(obj->oo_container.ic_object == obj->oo_inode); - LASSERT(obj->oo_ipd != NULL); - rc = iam_lookup(&obj->oo_container, (const struct iam_key *)key, - (struct iam_rec *)rec, obj->oo_ipd); +static int osd_index_insert(const struct lu_context *ctx, struct dt_object *dt, + const struct dt_rec *rec, const struct dt_key *key, + struct thandle *th) +{ + struct osd_object *obj = osd_dt_obj(dt); - LASSERT(osd_invariant(obj)); - RETURN(rc); - } else { - struct osd_object *obj = osd_dt_obj(dt); - struct osd_device *osd = osd_obj2dev(obj); - struct osd_thread_info *info = lu_context_key_get(ctxt, - &osd_key); - struct inode *dir; + struct osd_thandle *oh; + int rc; - int result; + ENTRY; - /* - * XXX temporary solution. - */ - struct dentry *dentry; - struct dentry *parent; + LASSERT(osd_invariant(obj)); + LASSERT(lu_object_exists(ctx, &dt->do_lu)); + LASSERT(obj->oo_container.ic_object == obj->oo_inode); + LASSERT(obj->oo_ipd != NULL); - LASSERT(osd_has_index(obj)); - LASSERT(osd->od_obj_area != NULL); + oh = container_of0(th, struct osd_thandle, ot_super); + LASSERT(oh->ot_handle != NULL); + rc = iam_insert(oh->ot_handle, &obj->oo_container, + (const struct iam_key *)key, + (struct iam_rec *)rec, obj->oo_ipd); - info->oti_str.name = (const char *)key; - info->oti_str.len = strlen((const char *)key); + LASSERT(osd_invariant(obj)); + RETURN(rc); +} - dir = obj->oo_inode; - LASSERT(dir->i_op != NULL && dir->i_op->lookup != NULL); +static struct dt_index_operations osd_index_ops = { + .dio_lookup = osd_index_lookup, + .dio_insert = osd_index_insert, + .dio_delete = osd_index_delete +}; - parent = d_alloc_root(dir); - if (parent == NULL) - return -ENOMEM; +static int osd_index_compat_delete(const struct lu_context *ctxt, + struct dt_object *dt, + const struct dt_key *key, + struct thandle *handle) +{ + struct osd_object *obj = osd_dt_obj(dt); - dentry = d_alloc(parent, &info->oti_str); - if (dentry != NULL) { - struct dentry *d; + LASSERT(S_ISDIR(obj->oo_inode->i_mode)); + ENTRY; + RETURN(-EOPNOTSUPP); +} +/* + * Compatibility index operations. + * + * XXX This is temporary solution: inode operations are used until iam is + * ready. + */ + + +static int osd_index_compat_lookup(const struct lu_context *ctxt, + struct dt_object *dt, + struct dt_rec *rec, const struct dt_key *key) +{ + struct osd_object *obj = osd_dt_obj(dt); + + struct osd_device *osd = osd_obj2dev(obj); + struct osd_thread_info *info = lu_context_key_get(ctxt, &osd_key); + struct inode *dir; + + int result; + + /* + * XXX temporary solution. + */ + struct dentry *dentry; + struct dentry *parent; + + LASSERT(osd_invariant(obj)); + LASSERT(S_ISDIR(obj->oo_inode->i_mode)); + LASSERT(osd_has_index(obj)); + LASSERT(osd->od_obj_area != NULL); + + info->oti_str.name = (const char *)key; + info->oti_str.len = strlen((const char *)key); + + dir = obj->oo_inode; + LASSERT(dir->i_op != NULL && dir->i_op->lookup != NULL); + + parent = d_alloc_root(dir); + if (parent == NULL) + return -ENOMEM; + + dentry = d_alloc(parent, &info->oti_str); + if (dentry != NULL) { + struct dentry *d; + + /* + * XXX passing NULL for nameidata should work for + * ext3/ldiskfs. + */ + d = dir->i_op->lookup(dir, dentry, NULL); + if (d == NULL) { /* - * XXX passing NULL for nameidata should work for - * ext3/ldiskfs. + * normal case, result is in @dentry. */ - d = dir->i_op->lookup(dir, dentry, NULL); - if (d == NULL) { - /* - * normal case, result is in @dentry. - */ - if (dentry->d_inode != NULL) - result = osd_build_fid(osd, dentry, - (struct lu_fid *)rec); - else - result = -ENOENT; - } else { - /* What? Disconnected alias? Ppheeeww... */ - CERROR("Aliasing where not expected\n"); - result = -EIO; - dput(d); - } - dput(dentry); - } else - result = -ENOMEM; - dput(parent); - LASSERT(osd_invariant(obj)); - return result; - } + if (dentry->d_inode != NULL) + result = osd_build_fid(osd, dentry, + (struct lu_fid *)rec); + else + result = -ENOENT; + } else { + /* What? Disconnected alias? Ppheeeww... */ + CERROR("Aliasing where not expected\n"); + result = -EIO; + dput(d); + } + dput(dentry); + } else + result = -ENOMEM; + dput(parent); + LASSERT(osd_invariant(obj)); + return result; } static int osd_add_rec(struct osd_thread_info *info, struct osd_device *dev, @@ -1020,33 +1095,13 @@ static int osd_add_rec(struct osd_thread_info *info, struct osd_device *dev, /* * XXX Temporary stuff. */ -static int osd_index_insert(const struct lu_context *ctx, struct dt_object *dt, - const struct dt_rec *rec, const struct dt_key *key, - struct thandle *th) +static int osd_index_compat_insert(const struct lu_context *ctx, + struct dt_object *dt, + const struct dt_rec *rec, + const struct dt_key *key, struct thandle *th) { struct osd_object *obj = osd_dt_obj(dt); - LASSERT(osd_invariant(obj)); - -if (!S_ISDIR(obj->oo_inode->i_mode)) { - struct osd_thandle *oh; - int rc; - - ENTRY; - - LASSERT(lu_object_exists(ctx, &dt->do_lu)); - LASSERT(obj->oo_container.ic_object == obj->oo_inode); - LASSERT(obj->oo_ipd != NULL); - - oh = container_of0(th, struct osd_thandle, ot_super); - LASSERT(oh->ot_handle != NULL); - rc = iam_insert(oh->ot_handle, &obj->oo_container, - (const struct iam_key *)key, - (struct iam_rec *)rec, obj->oo_ipd); - - LASSERT(osd_invariant(obj)); - RETURN(rc); -} else { const struct lu_fid *fid = (const struct lu_fid *)rec; const char *name = (const char *)key; @@ -1057,6 +1112,9 @@ if (!S_ISDIR(obj->oo_inode->i_mode)) { int result; + LASSERT(S_ISDIR(obj->oo_inode->i_mode)); + LASSERT(osd_invariant(obj)); + luch = lu_object_find(ctx, ludev->ld_site, fid); if (!IS_ERR(luch)) { if (lu_object_exists(ctx, luch)) { @@ -1084,12 +1142,11 @@ if (!S_ISDIR(obj->oo_inode->i_mode)) { LASSERT(osd_invariant(obj)); return result; } -} -static struct dt_index_operations osd_index_ops = { - .dio_lookup = osd_index_lookup, - .dio_insert = osd_index_insert, - .dio_delete = osd_index_delete +static struct dt_index_operations osd_index_compat_ops = { + .dio_lookup = osd_index_compat_lookup, + .dio_insert = osd_index_compat_insert, + .dio_delete = osd_index_compat_delete }; /* -- 1.8.3.1