* precondition: dt_object_exists(dt);
*/
struct dt_it *(*init)(const struct lu_context *ctxt,
- struct dt_object *dt);
+ struct dt_object *dt, int writable);
void (*fini)(const struct lu_context *ctxt,
struct dt_it *di);
int (*get)(const struct lu_context *ctxt,
const struct dt_key *key);
void (*put)(const struct lu_context *ctxt,
struct dt_it *di);
+ int (*del)(const struct lu_context *ctxt,
+ struct dt_it *di, struct thandle *th);
int (*next)(const struct lu_context *ctxt,
struct dt_it *di);
struct dt_key *(*key)(const struct lu_context *ctxt,
struct txn_param *param, void *cookie);
int (*dtc_txn_stop)(const struct lu_context *ctx,
struct thandle *txn, void *cookie);
- int (*dtc_txn_commit)(const struct lu_context *ctx,
+ int (*dtc_txn_commit)(const struct lu_context *ctx,
struct thandle *txn, void *cookie);
void *dtc_cookie;
struct list_head dtc_linkage;
int rc;
LASSERT(ma->ma_lmm != NULL && ma->ma_lmm_size > 0);
- rc = mdd_get_md(ctxt, mdd_obj, ma->ma_lmm, &ma->ma_lmm_size, 0,
+ rc = mdd_get_md(ctxt, mdd_obj, ma->ma_lmm, &ma->ma_lmm_size, 0,
MDS_LOV_MD_NAME);
if (rc > 0) {
ma->ma_valid |= MA_LOV;
rc = __mdd_iattr_get(ctxt, mdd_obj, ma);
if (rc == 0 && ma->ma_need & MA_LOV) {
- if (S_ISREG(mdd_object_type(mdd_obj)) ||
+ if (S_ISREG(mdd_object_type(mdd_obj)) ||
S_ISDIR(mdd_object_type(mdd_obj)))
rc = __mdd_lmm_get(ctxt, mdd_obj, ma);
}
-#ifdef HAVE_SPLIT_SUPPORT
+#ifdef HAVE_SPLIT_SUPPORT
if (rc == 0 && ma->ma_need & MA_LMV) {
if (S_ISDIR(mdd_object_type(mdd_obj)))
rc = __mdd_lmv_get(ctxt, mdd_obj, ma);
}
-#endif
+#endif
CDEBUG(D_INODE, "after getattr rc = %d, ma_valid = "LPX64"\n",
rc, ma->ma_valid);
RETURN(rc);
if (lmm == NULL)
GOTO(cleanup, rc = -ENOMEM);
- rc = mdd_get_md(ctxt, mdd_obj, lmm, &lmm_size, 1,
+ rc = mdd_get_md(ctxt, mdd_obj, lmm, &lmm_size, 1,
MDS_LOV_MD_NAME);
if (rc < 0)
obj = mdd_object_child(dir);
iops = &obj->do_index_ops->dio_it;
- it = iops->init(ctx, obj);
+ it = iops->init(ctx, obj, 0);
if (it != NULL) {
result = iops->get(ctx, it, (const void *)"");
if (result > 0) {
handle = mdd_trans_start(ctxt, mdo2mdd(obj));
if (IS_ERR(handle))
GOTO(out, rc = -ENOMEM);
-
+
rc = __mdd_orphan_del(ctxt, mdd_obj, handle);
mdd_trans_stop(ctxt, mdo2mdd(obj), rc, handle);
/* Thread context for transaction commit callback.
* Currently, OSD is based on ext3/JBD. Transaction commit in ext3/JBD
- * is serialized, that is there is no more than one transaction commit
- * at a time (JBD journal_commit_transaction() is serialized).
+ * is serialized, that is there is no more than one transaction commit
+ * at a time (JBD journal_commit_transaction() is serialized).
* This means that it's enough to have _one_ lu_context.
*/
struct lu_context od_ctx_for_commit;
struct dt_it *di, const struct dt_key *key);
static void osd_it_put (const struct lu_context *ctx, struct dt_it *di);
static int osd_it_next (const struct lu_context *ctx, struct dt_it *di);
+static int osd_it_del (const struct lu_context *ctx, struct dt_it *di,
+ struct thandle *th);
static int osd_it_key_size (const struct lu_context *ctx,
const struct dt_it *di);
static void osd_conf_get (const struct lu_context *ctx,
const struct osd_inode_id *id);
static struct super_block *osd_sb (const struct osd_device *dev);
static struct dt_it *osd_it_init (const struct lu_context *ctx,
- struct dt_object *dt);
+ struct dt_object *dt, int wable);
static struct dt_key *osd_it_key (const struct lu_context *ctx,
const struct dt_it *di);
static struct dt_rec *osd_it_rec (const struct lu_context *ctx,
CERROR("transaction @0x%p commit error: %d\n", th, error);
} else {
/* This dd_ctx_for_commit is only for commit usage.
- * see "struct dt_device"
- */
+ * see "struct dt_device"
+ */
dt_txn_hook_commit(&osd_dt_dev(dev)->od_ctx_for_commit, th);
}
th = osd_trans_start(ctx, d, ¶m);
if (!IS_ERR(th))
osd_trans_stop(ctx, th);
-
+
if (sync)
osd_sync(ctx, d);
-
+
lvfs_set_rdonly(lvfs_sbdev(osd_sb(osd_dt_dev(d))));
- EXIT;
+ EXIT;
}
if (first) {
area += sizeof (struct lu_dirpage);
nob -= sizeof (struct lu_dirpage);
-
+
}
LASSERT(nob > sizeof *ent);
* iterating through directory and fill pages from @rdpg
*/
iops = &dt->do_index_ops->dio_it;
- it = iops->init(ctxt, dt);
+ it = iops->init(ctxt, dt, 0);
if (it == NULL)
return -ENOMEM;
/*
rc = osd_dir_page_build(ctxt, !i, kmap(pg),
min_t(int, nob, CFS_PAGE_SIZE),
iops, it,
- &hash_start, &hash_end,
+ &hash_start, &hash_end,
rdpg->rp_hash_end, &last);
if (rc != 0 || i == rdpg->rp_npages - 1)
last->lde_reclen = 0;
};
static struct dt_it *osd_it_init(const struct lu_context *ctx,
- struct dt_object *dt)
+ struct dt_object *dt, int writable)
{
struct osd_it *it;
struct osd_object *obj = osd_dt_obj(dt);
struct lu_object *lo = &dt->do_lu;
+ __u32 flags;
LASSERT(lu_object_exists(lo));
LASSERT(obj->oo_ipd != NULL);
+ flags = writable ? IAM_IT_MOVE|IAM_IT_WRITE : IAM_IT_MOVE;
OBD_ALLOC_PTR(it);
if (it != NULL) {
it->oi_obj = obj;
lu_object_get(lo);
- iam_it_init(&it->oi_it,
- &obj->oo_container, IAM_IT_MOVE, obj->oo_ipd);
+ iam_it_init(&it->oi_it, &obj->oo_container, flags, obj->oo_ipd);
}
return (struct dt_it *)it;
}
return iam_it_next(&it->oi_it);
}
+static int osd_it_del(const struct lu_context *ctx, struct dt_it *di,
+ struct thandle *th)
+{
+ struct osd_it *it = (struct osd_it *)di;
+ struct osd_thandle *oh;
+
+ oh = container_of0(th, struct osd_thandle, ot_super);
+ LASSERT(oh->ot_handle != NULL);
+
+ return iam_it_rec_delete(oh->ot_handle, &it->oi_it);
+}
+
static struct dt_key *osd_it_key(const struct lu_context *ctx,
const struct dt_it *di)
{
.fini = osd_it_fini,
.get = osd_it_get,
.put = osd_it_put,
+ .del = osd_it_del,
.next = osd_it_next,
.key = osd_it_key,
.key_size = osd_it_key_size,
(struct lu_fid *)rec);
else
result = -ENOENT;
+ d = dentry;
} else {
/* What? Disconnected alias? Ppheeeww... */
CERROR("Aliasing where not expected\n");
result = -EIO;
- dput(d);
}
+ dput(d);
dput(dentry);
} else
result = -ENOMEM;
iput(inode);
inode = ERR_PTR(-ESTALE);
}
-
+
return inode;
}