#include <linux/lustre_iam.h>
#include "osd_internal.h"
+#include "osd_igif.h"
struct osd_object {
struct dt_object oo_dt;
const struct lu_fid *fid);
static int osd_inode_getattr (const struct lu_context *ctx,
struct inode *inode, struct lu_attr *attr);
-static int osd_inode_get_fid (struct osd_device *d, const struct inode *inode,
- struct lu_fid *fid);
static int osd_param_is_sane (const struct osd_device *dev,
const struct txn_param *param);
static int osd_index_lookup (const struct lu_context *ctxt,
#define osd_invariant(obj) (1)
#endif
-/*
- * DT methods.
- */
-static struct dt_object *dt_obj(struct lu_object *o)
-{
- return container_of0(o, struct dt_object, do_lu);
-}
-
static int osd_root_get(const struct lu_context *ctx,
struct dt_device *dev, struct lu_fid *f)
{
- struct osd_device *d = osd_dt_dev(dev);
-
- return osd_inode_get_fid(d, osd_sb(d)->s_root->d_inode, f);
-}
-
-struct dt_object *dt_object_find(struct lu_context *ctxt,
- struct dt_device *d,
- const struct lu_fid *f)
-{
- struct lu_object *o;
+ struct inode *inode;
- o = lu_object_find(ctxt, d->dd_lu_dev.ld_site, f);
- if (IS_ERR(o))
- return (struct dt_object *)o;
- else {
- o = lu_object_locate(o->lo_header, &osd_device_type);
- LASSERT(lu_device_is_osd(o->lo_dev));
- return dt_obj(o);
- }
+ inode = osd_sb(osd_dt_dev(dev))->s_root->d_inode;
+ lu_igif_build(f, inode->i_ino, inode->i_generation);
+ return 0;
}
-EXPORT_SYMBOL(dt_object_find);
/*
* OSD object methods.
LASSERT(dentry->d_inode != NULL);
obj->oo_inode = dentry->d_inode;
igrab(obj->oo_inode);
- obj->oo_dt.do_index_ops = &osd_index_compat_ops;
+ obj->oo_dt.do_index_ops = &osd_index_ops;
}
dput(dentry);
} else
return result;
}
-/*
- * Destroy existing object.
- *
- * precondition: lu_object_exists(ctxt, &dt->do_lu);
- * postcondition: ergo(result == 0,
- * !lu_object_exists(ctxt, &dt->do_lu));
- */
-int osd_object_destroy(const struct lu_context *ctxt,
- struct dt_object *dt, struct thandle *th)
-{
- /*
- * Stub for now, just drop inode.
- */
- LASSERT(lu_object_exists(ctxt, &dt->do_lu));
- CWARN("Stub!\n");
- osd_object_delete(ctxt, &dt->do_lu);
- LASSERT(!lu_object_exists(ctxt, &dt->do_lu));
- return 0;
-}
-
static void osd_inode_inc_link(const struct lu_context *ctxt,
struct inode *inode, struct thandle *th)
{
.do_attr_get = osd_attr_get,
.do_attr_set = osd_attr_set,
.do_object_create = osd_object_create,
- .do_object_destroy = osd_object_destroy,
.do_object_index_try = osd_index_try,
.do_object_ref_add = osd_object_ref_add,
.do_object_ref_del = osd_object_ref_del,
* Index operations.
*/
-#if OI_IN_MEMORY
-
-/*
- * XXX fid for "real" root.
- */
-static const struct lu_fid uber_fid = {
- .f_seq = LUSTRE_ROOT_FID_SEQ,
- .f_oid = LUSTRE_ROOT_FID_OID,
- .f_ver = 0
-};
-
-extern void osd_oi_init0(struct osd_oi *oi, const struct lu_fid *fid,
- __u64 root_ino, __u32 root_gen);
-extern int osd_oi_find_fid(struct osd_oi *oi,
- __u64 ino, __u32 gen, struct lu_fid *fid);
-#endif
-
-static int osd_build_fid(struct osd_device *osd,
- struct dentry *dentry, struct lu_fid *fid)
-{
- struct inode *inode = dentry->d_inode;
- int result;
-
- /*
- * Build fid from inode.
- */
- result = osd_oi_find_fid(&osd->od_oi,
- inode->i_ino, inode->i_generation, fid);
- if (result == -ENOENT) {
- /* XXX hard-coded */
- fid->f_seq = LUSTRE_ROOT_FID_SEQ + 1;
- fid->f_oid = inode->i_ino;
- fid->f_ver = inode->i_generation;
- osd_oi_init0(&osd->od_oi, fid,
- inode->i_ino, inode->i_generation);
- result = 0;
- }
- return result;
-}
-
static int osd_index_probe(const struct lu_context *ctxt, struct osd_object *o,
const struct dt_index_features *feat)
{
/*
* Compatibility index operations.
- *
- * XXX This is temporary solution: inode operations are used until iam is
- * ready.
*/
+static int osd_build_fid(struct osd_device *osd,
+ struct dentry *dentry, struct lu_fid *fid)
+{
+ struct inode *inode = dentry->d_inode;
+
+ lu_igif_build(fid, inode->i_ino, inode->i_generation);
+ return 0;
+}
+
static int osd_index_compat_lookup(const struct lu_context *ctxt,
struct dt_object *dt,
struct dt_rec *rec, const struct dt_key *key)
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);
struct osd_thread_info *info;
OBD_ALLOC_PTR(info);
- if (info == NULL)
+ if (info != NULL)
+ info->oti_ctx = ctx;
+ else
info = ERR_PTR(-ENOMEM);
return info;
}
{
struct lustre_mount_info *lmi;
const char *dev = lustre_cfg_string(cfg, 0);
- struct inode *inode;
+ struct osd_thread_info *info = lu_context_key_get(ctx, &osd_key);
int result;
ENTRY;
LASSERT(lmi != NULL);
/* save lustre_mount_info in dt_device */
o->od_mount = lmi;
- result = osd_oi_init(&o->od_oi, osd_sb(o)->s_root,
- osd2lu_dev(o)->ld_site);
+
+ result = osd_oi_init(info, &o->od_oi, &o->od_dt_dev);
if (result == 0) {
struct dentry *d;
- inode = osd_sb(o)->s_root->d_inode;
- /*
- * XXX temporary kludge: this should be done by mkfs.
- */
- osd_oi_init0(&o->od_oi, &uber_fid,
- inode->i_ino, inode->i_generation);
-
d = simple_mkdir(osd_sb(o)->s_root, "*OBJ-TEMP*", 0777, 1);
if (!IS_ERR(d)) {
o->od_obj_area = d;
-
/*
- * XXX temporary fix for mdd/fld: create root
- * directory if not yet there, and insert it into fld.
+ * XXX temporary resolution: OBJ_IDS should also be
+ * done in mkfs
*/
- d = simple_mkdir(osd_sb(o)->s_root, "ROOT", 0777, 1);
+ d = simple_mknod(osd_sb(o)->s_root,
+ "lov_objid", 0777, 1);
if (!IS_ERR(d))
dput(d);
else
result = PTR_ERR(d);
} else
result = PTR_ERR(d);
- /*
- * XXX temporary resolution: OBJ_IDS should also be done in mkfs
- */
- d = simple_mknod(osd_sb(o)->s_root, "lov_objid", 0777, 1);
- if (!IS_ERR(d))
- dput(d);
- else
- result = PTR_ERR(d);
}
if (result != 0)
osd_device_fini(ctx, osd2lu_dev(o));
static struct lu_device *osd_device_fini(const struct lu_context *ctx,
struct lu_device *d)
{
- struct osd_device *o = osd_dev(d);
+ struct osd_device *o = osd_dev(d);
+ struct osd_thread_info *info = lu_context_key_get(ctx, &osd_key);
ENTRY;
if (o->od_obj_area != NULL) {
dput(o->od_obj_area);
o->od_obj_area = NULL;
}
- osd_oi_fini(&o->od_oi);
+ osd_oi_fini(info, &o->od_oi);
if (o->od_mount)
server_put_mount(o->od_mount->lmi_name, o->od_mount->lmi_mnt);
* fid<->inode<->object functions.
*/
-static int osd_inode_get_fid(struct osd_device *d, const struct inode *inode,
- struct lu_fid *fid)
-{
- int result;
-
- /*
- * XXX: Should return fid stored together with inode in memory.
- */
- if (OI_IN_MEMORY) {
- result = osd_oi_find_fid(&d->od_oi, inode->i_ino,
- inode->i_generation, fid);
- } else {
- fid->f_seq = inode->i_ino;
- fid->f_oid = inode->i_generation;
- result = 0;
- }
- return result;
-}
-
struct dentry *osd_open(struct dentry *parent, const char *name, mode_t mode)
{
struct dentry *dentry;
return dentry;
}
+int osd_lookup_id(struct dt_device *dev, const char *name, mode_t mode,
+ struct osd_inode_id *id)
+{
+ struct dentry *dent;
+ struct osd_device *osd = osd_dt_dev(dev);
+ int result;
+
+ dent = osd_open(osd_sb(osd)->s_root, name, mode);
+ if (!IS_ERR(dent)) {
+ struct inode *inode;
+
+ inode = dent->d_inode;
+ LASSERT(inode != NULL);
+ id->oii_ino = inode->i_ino;
+ id->oii_gen = inode->i_generation;
+ result = 0;
+ } else
+ result = PTR_ERR(dent);
+ return result;
+}
+
static struct inode *osd_iget(struct osd_thread_info *info,
struct osd_device *dev,
const struct osd_inode_id *id)
struct lu_device *ldev = obj->oo_dt.do_lu.lo_dev;
struct osd_device *dev;
struct osd_inode_id id;
+ struct osd_oi *oi;
struct inode *inode;
int result;
info = lu_context_key_get(ctx, &osd_key);
dev = osd_dev(ldev);
+ oi = &dev->od_oi;
+
if (OBD_FAIL_CHECK(OBD_FAIL_OST_ENOENT))
RETURN(-ENOENT);
- osd_oi_read_lock(&dev->od_oi);
- result = osd_oi_lookup(info, &dev->od_oi, fid, &id);
+ osd_oi_read_lock(oi);
+ result = osd_oi_lookup(info, oi, fid, &id);
if (result == 0) {
inode = osd_iget(info, dev, &id);
if (!IS_ERR(inode)) {
result = PTR_ERR(inode);
} else if (result == -ENOENT)
result = 0;
- osd_oi_read_unlock(&dev->od_oi);
+ osd_oi_read_unlock(oi);
LASSERT(osd_invariant(obj));
RETURN(result);
}
static int lu_device_is_osd(const struct lu_device *d)
{
- /*
- * XXX for now. Tags in lu_device_type->ldt_something are needed.
- */
return ergo(d != NULL && d->ld_ops != NULL, d->ld_ops == &osd_lu_ops);
}
#include "osd_oi.h"
/* osd_lookup(), struct osd_thread_info */
#include "osd_internal.h"
+/* lu_fid_is_igif() */
+#include "osd_igif.h"
+#include "dt_object.h"
+
+static const struct dt_key *oi_fid_key(struct osd_thread_info *info,
+ const struct lu_fid *fid);
+static const char oi_dirname[] = "oi";
+
+static const struct dt_index_features oi_index_features = {
+ .dif_flags = DT_IND_UPDATE,
+ .dif_keysize_min = sizeof(struct lu_fid),
+ .dif_keysize_max = sizeof(struct lu_fid),
+ .dif_recsize_min = sizeof(__u64) + sizeof(__u32),
+ .dif_recsize_max = sizeof(__u64) + sizeof(__u32)
+};
-static struct lu_fid *oi_fid_key(struct osd_thread_info *info,
- const struct lu_fid *fid);
-static const char osd_oi_dirname[] = "oi";
-
-int osd_oi_init(struct osd_oi *oi, struct dentry *root, struct lu_site *site)
+int osd_oi_init(struct osd_thread_info *info,
+ struct osd_oi *oi, struct dt_device *dev)
{
int result;
-
- oi->oi_dir = osd_open(root, osd_oi_dirname, S_IFREG);
- if (IS_ERR(oi->oi_dir)) {
- result = PTR_ERR(oi->oi_dir);
- oi->oi_dir = NULL;
+ struct dt_object *obj;
+ const struct lu_context *ctx;
+
+ ctx = info->oti_ctx;
+ /*
+ * Initialize ->oi_lock first, because of possible oi re-entrance in
+ * dt_store_open().
+ */
+ init_rwsem(&oi->oi_lock);
+
+ obj = dt_store_open(ctx, dev, oi_dirname, &info->oti_fid);
+ if (!IS_ERR(obj)) {
+ result = obj->do_ops->do_object_index_try(ctx, obj,
+ &oi_index_features);
+ if (result == 0) {
+ LASSERT(obj->do_index_ops != NULL);
+ oi->oi_dir = obj;
+ } else
+ CERROR("Wrong index \"%s\": %d\n",
+ oi_dirname, result);
} else {
- result = 0;
- init_rwsem(&oi->oi_lock);
- oi->oi_site = site;
+ result = PTR_ERR(obj);
+ CERROR("Cannot open \"%s\": %d\n", oi_dirname, result);
}
return result;
}
-void osd_oi_fini(struct osd_oi *oi)
+void osd_oi_fini(struct osd_thread_info *info, struct osd_oi *oi)
{
if (oi->oi_dir != NULL) {
- dput(oi->oi_dir);
+ lu_object_put(info->oti_ctx, &oi->oi_dir->do_lu);
oi->oi_dir = NULL;
}
}
up_write(&oi->oi_lock);
}
-static struct lu_fid *oi_fid_key(struct osd_thread_info *info,
- const struct lu_fid *fid)
+static const struct dt_key *oi_fid_key(struct osd_thread_info *info,
+ const struct lu_fid *fid)
{
- fid_to_le(&info->oti_fid, fid);
- return &info->oti_fid;
+ fid_to_be(&info->oti_fid, fid);
+ return (const struct dt_key *)&info->oti_fid;
}
-/****************************************************************************
- * XXX prototype.
- ****************************************************************************/
-
-#if OI_IN_MEMORY
-struct oi_entry {
- struct lu_fid oe_key;
- struct osd_inode_id oe_rec;
- struct list_head oe_linkage;
+enum {
+ OI_TXN_INSERT_CREDITS = 20,
+ OI_TXN_DELETE_CREDITS = 20
};
-static CFS_LIST_HEAD(oi_head);
-
-static struct oi_entry *oi_lookup(const struct lu_fid *fid)
-{
- struct oi_entry *entry;
-
- list_for_each_entry(entry, &oi_head, oe_linkage) {
- if (lu_fid_eq(fid, &entry->oe_key))
- return entry;
- }
- return NULL;
-}
-
/*
* Locking: requires at least read lock on oi.
*/
int osd_oi_lookup(struct osd_thread_info *info, struct osd_oi *oi,
const struct lu_fid *fid, struct osd_inode_id *id)
{
- struct oi_entry *entry;
int result;
- LASSERT(fid_is_local(oi->oi_site, fid));
- entry = oi_lookup(fid);
- if (entry != NULL) {
- *id = entry->oe_rec;
+ if (lu_fid_is_igif(fid)) {
+ lu_igif_to_id(fid, id);
result = 0;
- } else
- result = -ENOENT;
+ } else {
+ result = oi->oi_dir->do_index_ops->dio_lookup
+ (info->oti_ctx, oi->oi_dir,
+ (struct dt_rec *)id, oi_fid_key(info, fid));
+ id->oii_ino = be64_to_cpu(id->oii_ino);
+ id->oii_gen = be32_to_cpu(id->oii_gen);
+ }
return result;
}
* Locking: requires write lock on oi.
*/
int osd_oi_insert(struct osd_thread_info *info, struct osd_oi *oi,
- const struct lu_fid *fid, const struct osd_inode_id *id,
+ const struct lu_fid *fid, const struct osd_inode_id *id0,
struct thandle *th)
{
- struct oi_entry *entry;
- int result;
+ struct dt_object *idx;
+ struct dt_device *dev;
+ struct osd_inode_id *id;
- LASSERT(fid_is_local(oi->oi_site, fid));
- entry = oi_lookup(fid);
- if (entry == NULL) {
- OBD_ALLOC_PTR(entry);
- if (entry != NULL) {
- entry->oe_key = *fid;
- entry->oe_rec = *id;
- list_add(&entry->oe_linkage, &oi_head);
- result = 0;
- } else
- result = -ENOMEM;
- } else
- result = -EEXIST;
- return result;
+ LASSERT(oi->oi_boot == NULL);
+
+ idx = oi->oi_dir;
+ dev = lu2dt_dev(idx->do_lu.lo_dev);
+ id = &info->oti_id;
+ id->oii_ino = cpu_to_be64(id0->oii_ino);
+ id->oii_gen = cpu_to_be32(id0->oii_gen);
+ return idx->do_index_ops->dio_insert(info->oti_ctx, idx,
+ (const struct dt_rec *)id,
+ oi_fid_key(info, fid), th);
}
/*
struct osd_oi *oi, const struct lu_fid *fid,
struct thandle *th)
{
- struct oi_entry *entry;
- int result;
-
- LASSERT(fid_is_local(oi->oi_site, fid));
- entry = oi_lookup(fid);
- if (entry != NULL) {
- list_del(&entry->oe_linkage);
- OBD_FREE_PTR(entry);
- result = 0;
- } else
- result = -ENOENT;
- return result;
-}
-
-void osd_oi_init0(struct osd_oi *oi, const struct lu_fid *fid,
- __u64 root_ino, __u32 root_gen)
-{
- int result;
- const struct osd_inode_id root_id = {
- .oii_ino = root_ino,
- .oii_gen = root_gen
- };
-
- result = osd_oi_insert(NULL, oi, fid, &root_id, NULL);
- LASSERT(result == 0);
-}
-
-int osd_oi_find_fid(struct osd_oi *oi, __u64 ino, __u32 gen, struct lu_fid *fid)
-{
- struct oi_entry *entry;
- int result;
-
- result = -ENOENT;
- osd_oi_read_lock(oi);
- list_for_each_entry(entry, &oi_head, oe_linkage) {
- if (entry->oe_rec.oii_ino == ino &&
- entry->oe_rec.oii_gen == gen) {
- *fid = entry->oe_key;
- result = 0;
- LASSERT(fid_is_local(oi->oi_site, fid));
- break;
- }
- }
- osd_oi_read_unlock(oi);
- return result;
-}
-
-/* OI_IN_MEMORY */
-#else
-
-/*
- * Locking: requires at least read lock on oi.
- */
-int osd_oi_lookup(struct osd_thread_info *info, struct osd_oi *oi,
- const struct lu_fid *fid, struct osd_inode_id *id)
-{
- id->oii_ino = fid_seq(fid);
- id->oii_gen = fid_oid(fid);
- return 0;
-}
+ struct dt_object *idx;
+ struct dt_device *dev;
-/*
- * Locking: requires write lock on oi.
- */
-int osd_oi_insert(struct osd_thread_info *info, struct osd_oi *oi,
- const struct lu_fid *fid, const struct osd_inode_id *id,
- struct thandle *th)
-{
- LASSERT(id->oii_ino == fid_seq(fid));
- LASSERT(id->oii_gen == fid_oid(fid));
- return 0;
-}
+ LASSERT(oi->oi_boot == NULL);
-/*
- * Locking: requires write lock on oi.
- */
-int osd_oi_delete(struct osd_thread_info *info,
- struct osd_oi *oi, const struct lu_fid *fid,
- struct thandle *th)
-{
- return 0;
+ idx = oi->oi_dir;
+ dev = lu2dt_dev(idx->do_lu.lo_dev);
+ return idx->do_index_ops->dio_delete(info->oti_ctx, idx,
+ oi_fid_key(info, fid), th);
}
-/* OI_IN_MEMORY */
-#endif