struct osd_object *obj,
struct osd_directory *dir)
{
+ struct iam_container *bag = &dir->od_container;
int result;
- struct iam_container *bag;
- bag = &dir->od_container;
result = iam_container_init(bag, &dir->od_descr, obj->oo_inode);
- if (result == 0) {
- result = iam_container_setup(bag);
- if (result == 0)
- obj->oo_dt.do_index_ops = &osd_index_iam_ops;
- else
- iam_container_fini(bag);
+ if (result != 0)
+ return result;
+
+ result = iam_container_setup(bag);
+ if (result != 0)
+ goto out;
+
+ if (osd_obj2dev(obj)->od_iop_mode) {
+ u32 ptr = bag->ic_descr->id_ops->id_root_ptr(bag);
+
+ bag->ic_root_bh = ldiskfs_bread(NULL, obj->oo_inode,
+ ptr, 0, &result);
}
+
+ out:
+ if (result == 0)
+ obj->oo_dt.do_index_ops = &osd_index_iam_ops;
+ else
+ iam_container_fini(bag);
+
return result;
}
*/
void iam_container_fini(struct iam_container *c)
{
+ brelse(c->ic_root_bh);
+ c->ic_root_bh = NULL;
}
EXPORT_SYMBOL(iam_container_fini);
{
int result = 0;
+ /* NB: it can be called by iam_lfix_guess() which is still at
+ * very early stage, c->ic_root_bh and c->ic_descr->id_ops
+ * haven't been intialized yet.
+ * Also, we don't have this for IAM dir.
+ */
+ if (c->ic_root_bh != NULL &&
+ c->ic_descr->id_ops->id_root_ptr(c) == ptr) {
+ get_bh(c->ic_root_bh);
+ *bh = c->ic_root_bh;
+ return 0;
+ }
+
*bh = ldiskfs_bread(h, c->ic_object, (int)ptr, 0, &result);
if (*bh == NULL)
result = -EIO;
* Underlying flat file. IO against this object is issued to
* read/write nodes.
*/
- struct inode *ic_object;
+ struct inode *ic_object;
+ /*
+ * BH of root block
+ */
+ struct buffer_head *ic_root_bh;
/*
* container flavor.
*/
- struct iam_descr *ic_descr;
+ struct iam_descr *ic_descr;
/*
* read-write lock protecting index consistency.
*/
- cfs_rw_semaphore_t ic_sem;
+ cfs_rw_semaphore_t ic_sem;
};
/*