static int cml_create(const struct lu_context *ctx, struct md_object *mo_p,
const char *child_name, struct md_object *mo_c,
- const char *target_name, struct md_attr *ma)
+ const char *target_name, const void *eadata,
+ int eadatalen, struct md_attr *ma)
{
int rc;
ENTRY;
rc = mdo_create(ctx, md_object_next(mo_p), child_name,
- md_object_next(mo_c), target_name, ma);
+ md_object_next(mo_c), target_name, eadata, eadatalen,
+ ma);
+ RETURN(rc);
+}
+
+static int cml_create_data_object(const struct lu_context *ctx,
+ struct md_object *p, struct md_object *o,
+ const void *eadata, int eadatalen,
+ struct md_attr *ma)
+{
+ int rc;
+ ENTRY;
+ rc = mdo_create_data_object(ctx, md_object_next(p), md_object_next(o),
+ eadata, eadatalen, ma);
RETURN(rc);
}
.mdo_name_insert = cml_name_insert,
.mdo_rename = cml_rename,
.mdo_rename_tgt = cml_rename_tgt,
+ .mdo_create_data_object = cml_create_data_object,
};
/* -------------------------------------------------------------------
*/
static int cmr_create(const struct lu_context *ctx, struct md_object *mo_p,
const char *child_name, struct md_object *mo_c,
- const char *target_name, struct md_attr *ma)
+ const char *target_name, const char *eadata,
+ int eadatasize, struct md_attr *ma)
{
int rc;
/* target_name is valid iff this is a symlink operation. */
int (*mdo_create)(const struct lu_context *, struct md_object *,
const char *child_name, struct md_object *,
- const char *target_name, struct md_attr *);
+ const char *target_name, const void *eadata,
+ int eadatalen, struct md_attr *);
+ /* This method is used for creating data object for this meta object*/
+ int (*mdo_create_data_object)(const struct lu_context *cx,
+ struct md_object *p, struct md_object *o,
+ const void *eadata, int eadatalen,
+ struct md_attr *ma);
int (*mdo_rename)(const struct lu_context *ctxt,
struct md_object *spobj, struct md_object *tpobj,
const struct lu_fid *lf, const char *sname,
static inline int mdo_create(const struct lu_context *cx, struct md_object *p,
const char *child_name, struct md_object *c,
- const char *target_name, struct md_attr *at)
+ const char *target_name, const void *eadata,
+ int eadatalen, struct md_attr *at)
{
LASSERT(c->mo_dir_ops->mdo_create);
- return c->mo_dir_ops->mdo_create(cx, p, child_name, c, target_name, at);
+ return c->mo_dir_ops->mdo_create(cx, p, child_name, c, target_name,
+ eadata, eadatalen, at);
+}
+static inline int mdo_create_data_object(const struct lu_context *cx,
+ struct md_object *p, struct md_object *c,
+ const void *eadata, int eadatalen,
+ struct md_attr *ma)
+{
+ LASSERT(c->mo_dir_ops->mdo_create_data_object);
+ return c->mo_dir_ops->mdo_create_data_object(cx, p, c, eadata,
+ eadatalen, ma);
}
static inline int mdo_rename(const struct lu_context *cx,
rc = next->do_ops->do_attr_get(ctxt, next, &ma->ma_attr);
if (rc == 0) {
ma->ma_valid |= MA_INODE;
- if (S_ISREG(ma->ma_attr.la_mode) &&
- ma->ma_lmm != 0 && ma->ma_lmm_size > 0) {
- rc = mdd_get_md(ctxt, obj, ma->ma_lmm, &ma->ma_lmm_size, 0);
- if (rc >= 0) {
+ if ((S_ISREG(ma->ma_attr.la_mode)
+ || S_ISDIR(ma->ma_attr.la_mode))
+ && ma->ma_lmm != 0 && ma->ma_lmm_size > 0) {
+ rc = mdd_get_md(ctxt, obj, ma->ma_lmm,&ma->ma_lmm_size);
+ if (rc > 0) {
ma->ma_valid |= MA_LOV;
rc = 0;
}
return rc;
}
+static int mdd_create_data_object(const struct lu_context *ctxt,
+ struct md_object *pobj, struct md_object *cobj,
+ const void *eadata, int eadatasize,
+ struct md_attr *ma)
+{
+ struct mdd_device *mdd = mdo2mdd(pobj);
+ struct mdd_object *mdo = md2mdd_obj(pobj);
+ struct mdd_object *son = md2mdd_obj(cobj);
+ struct lu_attr *attr = &ma->ma_attr;
+ struct lov_mds_md *lmm = NULL;
+ int lmm_size = 0;
+ int rc;
+ ENTRY;
+
+ rc = mdd_lov_create(ctxt, mdd, mdo, son, &lmm, &lmm_size, eadata,
+ eadatasize, attr);
+ if (rc)
+ RETURN(rc);
+
+ rc = mdd_lov_set_md(ctxt, pobj, cobj, lmm, lmm_size, attr->la_mode);
+ if (rc)
+ RETURN(rc);
+
+ rc = mdd_attr_get(ctxt, cobj, ma);
+
+ RETURN(rc);
+}
/*
* Create object and insert it into namespace.
*/
static int mdd_create(const struct lu_context *ctxt, struct md_object *pobj,
const char *name, struct md_object *child,
- const char *target_name, struct md_attr* ma)
+ const char *target_name, const void *eadata,
+ int eadatasize, struct md_attr* ma)
{
struct mdd_device *mdd = mdo2mdd(pobj);
struct mdd_object *mdo = md2mdd_obj(pobj);
* first */
if (S_ISREG(attr->la_mode)) {
- rc = mdd_lov_create(ctxt, mdd, son, &lmm, &lmm_size);
+ rc = mdd_lov_create(ctxt, mdd, mdo, son, &lmm, &lmm_size,
+ eadata, eadatasize, attr);
if (rc)
RETURN(rc);
}
inserted = 1;
rc = mdd_lov_set_md(ctxt, pobj, child, lmm, lmm_size, attr->la_mode);
- if (rc)
+ if (rc) {
+ CERROR("error on stripe info copy %d \n", rc);
GOTO(cleanup, rc);
-
+ }
if (S_ISLNK(attr->la_mode)) {
struct dt_object *dt = mdd_object_child(son);
loff_t pos = 0;
else
rc = -EFAULT;
}
-
- if (rc == 0)
- rc = mdd_attr_get(ctxt, child, ma);
- else
- CERROR("error on stripe info copy %d \n", rc);
+ rc = mdd_attr_get(ctxt, child, ma);
cleanup:
if (rc && created) {
int rc2 = 0;
.mdo_name_insert = mdd_mkname,
.mdo_name_remove = mdd_name_remove,
.mdo_rename_tgt = mdd_rename_tgt,
+ .mdo_create_data_object = mdd_create_data_object,
};
struct md_object *child, struct lov_mds_md *lmm,
int lmm_size, int mode);
int mdd_lov_create(const struct lu_context *ctxt, struct mdd_device *mdd,
- struct mdd_object *child, struct lov_mds_md **lmm,
- int *lmm_size);
+ struct mdd_object *parent, struct mdd_object *child,
+ struct lov_mds_md **lmm, int *lmm_size, const void *eadata,
+ int eadatasize, struct lu_attr *la);
int mdd_get_md(const struct lu_context *ctxt, struct md_object *obj,
- void *md, int *md_size, int lock);
+ void *md, int *md_size);
int mdd_unlink_log(const struct lu_context *ctxt, struct mdd_device *mdd,
struct mdd_object *mdd_cobj, struct md_attr *ma);
struct mdd_thread_info *mdd_ctx_info(const struct lu_context *ctx);
}
int mdd_get_md(const struct lu_context *ctxt, struct md_object *obj,
- void *md, int *md_size, int lock)
+ void *md, int *md_size)
{
struct dt_object *next;
int rc = 0;
}else if (S_ISDIR(mode)) {
struct lov_mds_md *lmm = &mdd_ctx_info(ctxt)->mti_lmm;
int size = sizeof(lmm);
- rc = mdd_get_md(ctxt, pobj, &lmm, &size, 1);
+ rc = mdd_get_md(ctxt, pobj, &lmm, &size);
if (rc > 0) {
rc = mdd_xattr_set(ctxt, child, lmm, size,
/*
rc);
}
}
-
+
RETURN(rc);
}
}
int mdd_lov_create(const struct lu_context *ctxt, struct mdd_device *mdd,
- struct mdd_object *child, struct lov_mds_md **lmm,
- int *lmm_size)
+ struct mdd_object *parent, struct mdd_object *child,
+ struct lov_mds_md **lmm, int *lmm_size, const void *eadata,
+ int eadatasize, struct lu_attr *la)
{
struct obd_device *obd = mdd2_obd(mdd);
struct obd_export *lov_exp = obd->u.mds.mds_osc_exp;
int rc = 0;
ENTRY;
+ if (la->la_flags & MDS_OPEN_DELAY_CREATE ||
+ !(la->la_flags & FMODE_WRITE))
+ RETURN(0);
+
oa = obdo_alloc();
oa->o_uid = 0; /* must have 0 uid / gid on OST */
OBD_MD_FLMODE | OBD_MD_FLUID | OBD_MD_FLGID;
oa->o_size = 0;
- rc = obd_create(lov_exp, oa, &lsm, NULL);
- if (rc)
- GOTO(out_oa, rc);
+ if (!(la->la_flags & MDS_OPEN_HAS_OBJS)) {
+ if (la->la_flags & MDS_OPEN_HAS_EA) {
+ LASSERT(eadata != NULL);
+ rc = obd_iocontrol(OBD_IOC_LOV_SETSTRIPE, lov_exp,
+ 0, &lsm, (void*)eadata);
+ if (rc)
+ GOTO(out_oa, rc);
+ } else {
+ LASSERT(*lmm == NULL);
+ rc = mdd_get_md(ctxt, &parent->mod_obj, *lmm,
+ lmm_size);
+ if (rc > 0)
+ rc = obd_iocontrol(OBD_IOC_LOV_SETSTRIPE,
+ lov_exp, 0, &lsm, *lmm);
+ }
+ rc = obd_create(lov_exp, oa, &lsm, NULL);
+ if (rc) {
+ if (rc > 0) {
+ CERROR("obd_create returned invalid "
+ "rc %d\n", rc);
+ rc = -EIO;
+ }
+ GOTO(out_oa, rc);
+ }
+ } else {
+ LASSERT(eadata != NULL);
+ rc = obd_iocontrol(OBD_IOC_LOV_SETEA, lov_exp, 0, &lsm,
+ (void*)eadata);
+ if (rc) {
+ GOTO(out_oa, rc);
+ }
+ lsm->lsm_object_id = oa->o_id;
+ }
rc = obd_packmd(lov_exp, lmm, lsm);
if (rc < 0) {
} else
result = -EFAULT;
+ if (req_capsule_field_present(pill, &RMF_EADATA)) {
+ rr->rr_eadata = req_capsule_client_get(pill, &RMF_EADATA);
+ rr->rr_eadatalen = req_capsule_get_size(pill,
+ &RMF_EADATA,
+ RCL_CLIENT);
+ }
+
RETURN(result);
}
OBD_FREE_PTR(mfd);
}
+static int mdt_create_data_obj(struct mdt_thread_info *info,
+ struct mdt_object *p, struct mdt_object *o)
+{
+ struct md_attr *ma = &info->mti_attr;
+ struct mdt_reint_record *mrr = &info->mti_rr;
+
+ return mdo_create_data_object(info->mti_ctxt, mdt_object_child(p),
+ mdt_object_child(o), mrr->rr_eadata,
+ mrr->rr_eadatalen, ma);
+}
+
static int mdt_mfd_open(struct mdt_thread_info *info,
+ struct mdt_object *p,
struct mdt_object *o,
int flags, int created)
{
/* If client supports this, do not return open handle
* for special nodes */
RETURN(0);
-
+ if ((S_ISREG(la->la_mode) || S_ISDIR(la->la_mode))
+ && !created && !(ma->ma_valid & MA_LOV)) {
+ /*No EA, check whether it is will set regEA and dirEA
+ *since in above attr get, these size might be zero,
+ *so reset it, to retrieve the MD after create obj*/
+ ma->ma_lmm_size = req_capsule_get_size(&info->mti_pill,
+ &RMF_MDT_MD,
+ RCL_SERVER);
+ LASSERT(p != NULL);
+ rc = mdt_create_data_obj(info, p, o);
+ if (rc)
+ RETURN(rc);
+ }
/* FIXME:maybe this can be done earlier? */
if (S_ISDIR(la->la_mode)) {
if (flags & (MDS_OPEN_CREAT | FMODE_WRITE)) {
la->la_flags & MDS_OPEN_CREAT)
rc = -EEXIST;
else
- rc = mdt_mfd_open(info, o, flags, 0);
+ rc = mdt_mfd_open(info, NULL, o, flags, 0);
} else {
rc = -ENOENT;
if (la->la_flags & MDS_OPEN_CREAT) {
mdt_object_child(o),
&info->mti_attr);
if (rc == 0)
- rc = mdt_mfd_open(info, o, flags, 1);
+ rc = mdt_mfd_open(info, NULL, o, flags, 1);
}
}
mdt_object_put(info->mti_ctxt, o);
/* new object will be created. see the following */
} else {
intent_set_disposition(ldlm_rep, DISP_LOOKUP_POS);
- if (la->la_flags & MDS_OPEN_EXCL &&
- la->la_flags & MDS_OPEN_CREAT)
+ if ((la->la_flags & MDS_OPEN_EXCL &&
+ la->la_flags & MDS_OPEN_CREAT))
GOTO(out_parent, result = -EEXIST);
}
mdt_object_child(parent),
rr->rr_name,
mdt_object_child(child),
- rr->rr_tgt,
- &info->mti_attr);
+ rr->rr_tgt, rr->rr_eadata,
+ rr->rr_eadatalen, &info->mti_attr);
intent_set_disposition(ldlm_rep, DISP_OPEN_CREATE);
if (result != 0)
GOTO(out_child, result);
}
/* Open it now. */
- result = mdt_mfd_open(info, child, la->la_flags, created);
+ result = mdt_mfd_open(info, parent, child, la->la_flags, created);
intent_set_disposition(ldlm_rep, DISP_OPEN_OPEN);
GOTO(finish_open, result);
struct md_object *next = mdt_object_child(parent);
rc = mdo_create(info->mti_ctxt, next, rr->rr_name,
- mdt_object_child(child), rr->rr_tgt, ma);
+ mdt_object_child(child), rr->rr_tgt, NULL, 0,
+ ma);
if (rc == 0) {
/* return fid & attr to client. */
if (ma->ma_valid & MA_INODE)
attr->la_blocks = inode->i_blocks;
attr->la_uid = inode->i_uid;
attr->la_gid = inode->i_gid;
- attr->la_flags = inode->i_flags;
+// attr->la_flags = inode->i_flags;
attr->la_nlink = inode->i_nlink;
return 0;
}
&RMF_LDLM_INTENT,
&RMF_REC_CREATE, /* coincides with mds_reint_open_client[] */
&RMF_NAME,
- &RMF_SYMTGT
+ &RMF_EADATA
};
static const struct req_msg_field *ldlm_intent_unlink_client[] = {