+static int osd_mk_index(struct osd_thread_info *info, struct osd_object *obj,
+ struct lu_attr *attr,
+ struct dt_allocation_hint *hint,
+ struct dt_object_format *dof,
+ struct thandle *th)
+{
+ int result;
+ struct osd_thandle *oth;
+ const struct dt_index_features *feat = dof->u.dof_idx.di_feat;
+
+ __u32 mode = (attr->la_mode & (S_IFMT | S_IRWXUGO | S_ISVTX));
+
+ LASSERT(S_ISREG(attr->la_mode));
+
+ oth = container_of(th, struct osd_thandle, ot_super);
+ LASSERT(oth->ot_handle->h_transaction != NULL);
+
+ result = osd_mkfile(info, obj, mode, hint, th);
+ if (result == 0) {
+ LASSERT(obj->oo_inode != NULL);
+ if (feat->dif_flags & DT_IND_VARKEY)
+ result = iam_lvar_create(obj->oo_inode,
+ feat->dif_keysize_max,
+ feat->dif_ptrsize,
+ feat->dif_recsize_max,
+ oth->ot_handle);
+ else
+ result = iam_lfix_create(obj->oo_inode,
+ feat->dif_keysize_max,
+ feat->dif_ptrsize,
+ feat->dif_recsize_max,
+ oth->ot_handle);
+
+ }
+ return result;
+}
+
+static int osd_mkreg(struct osd_thread_info *info, struct osd_object *obj,
+ struct lu_attr *attr,
+ struct dt_allocation_hint *hint,
+ struct dt_object_format *dof,
+ struct thandle *th)
+{
+ LASSERT(S_ISREG(attr->la_mode));
+ return osd_mkfile(info, obj, (attr->la_mode &
+ (S_IFMT | S_IRWXUGO | S_ISVTX)), hint, th);
+}
+
+static int osd_mksym(struct osd_thread_info *info, struct osd_object *obj,
+ struct lu_attr *attr,
+ struct dt_allocation_hint *hint,
+ struct dt_object_format *dof,
+ struct thandle *th)
+{
+ LASSERT(S_ISLNK(attr->la_mode));
+ return osd_mkfile(info, obj, (attr->la_mode &
+ (S_IFMT | S_IRWXUGO | S_ISVTX)), hint, th);
+}
+
+static int osd_mknod(struct osd_thread_info *info, struct osd_object *obj,
+ struct lu_attr *attr,
+ struct dt_allocation_hint *hint,
+ struct dt_object_format *dof,
+ struct thandle *th)
+{
+ umode_t mode = attr->la_mode & (S_IFMT | S_IRWXUGO | S_ISVTX);
+ int result;
+
+ LINVRNT(osd_invariant(obj));
+ LASSERT(obj->oo_inode == NULL);
+ LASSERT(S_ISCHR(mode) || S_ISBLK(mode) ||
+ S_ISFIFO(mode) || S_ISSOCK(mode));
+
+ result = osd_mkfile(info, obj, mode, hint, th);
+ if (result == 0) {
+ LASSERT(obj->oo_inode != NULL);
+ init_special_inode(obj->oo_inode, mode, attr->la_rdev);
+ }
+ LINVRNT(osd_invariant(obj));
+ return result;
+}
+
+typedef int (*osd_obj_type_f)(struct osd_thread_info *, struct osd_object *,
+ struct lu_attr *,
+ struct dt_allocation_hint *hint,
+ struct dt_object_format *dof,
+ struct thandle *);
+
+static osd_obj_type_f osd_create_type_f(enum dt_format_type type)
+{
+ osd_obj_type_f result;
+
+ switch (type) {
+ case DFT_DIR:
+ result = osd_mkdir;
+ break;
+ case DFT_REGULAR:
+ result = osd_mkreg;
+ break;
+ case DFT_SYM:
+ result = osd_mksym;
+ break;
+ case DFT_NODE:
+ result = osd_mknod;
+ break;
+ case DFT_INDEX:
+ result = osd_mk_index;
+ break;
+
+ default:
+ LBUG();
+ break;
+ }
+ return result;
+}
+
+
+static void osd_ah_init(const struct lu_env *env, struct dt_allocation_hint *ah,
+ struct dt_object *parent, umode_t child_mode)
+{
+ LASSERT(ah);
+
+ memset(ah, 0, sizeof(*ah));
+ ah->dah_parent = parent;
+ ah->dah_mode = child_mode;
+}
+
+/**
+ * Helper function for osd_object_create()
+ *
+ * \retval 0, on success
+ */
+static int __osd_object_create(struct osd_thread_info *info,
+ struct osd_object *obj, struct lu_attr *attr,
+ struct dt_allocation_hint *hint,
+ struct dt_object_format *dof,
+ struct thandle *th)
+{
+
+ int result;
+
+ result = osd_create_pre(info, obj, attr, th);
+ if (result == 0) {
+ result = osd_create_type_f(dof->dof_type)(info, obj,
+ attr, hint, dof, th);
+ if (result == 0)
+ result = osd_create_post(info, obj, attr, th);
+ }
+ return result;
+}
+
+/**
+ * Helper function for osd_object_create()
+ *
+ * \retval 0, on success
+ */
+static int __osd_oi_insert(const struct lu_env *env, struct osd_object *obj,
+ const struct lu_fid *fid, struct thandle *th)
+{
+ struct osd_thread_info *info = osd_oti_get(env);
+ struct osd_inode_id *id = &info->oti_id;
+ struct osd_device *osd = osd_obj2dev(obj);
+ struct md_ucred *uc = md_ucred(env);
+
+ LASSERT(obj->oo_inode != NULL);
+ LASSERT(uc != NULL);
+
+ id->oii_ino = obj->oo_inode->i_ino;
+ id->oii_gen = obj->oo_inode->i_generation;
+
+ return osd_oi_insert(info, &osd->od_oi, fid, id, th,
+ uc->mu_cap & CFS_CAP_SYS_RESOURCE_MASK);
+}
+
+static int osd_object_create(const struct lu_env *env, struct dt_object *dt,
+ struct lu_attr *attr,
+ struct dt_allocation_hint *hint,
+ struct dt_object_format *dof,
+ struct thandle *th)
+{
+ const struct lu_fid *fid = lu_object_fid(&dt->do_lu);
+ struct osd_object *obj = osd_dt_obj(dt);
+ struct osd_thread_info *info = osd_oti_get(env);
+ int result;
+
+ ENTRY;
+
+ LINVRNT(osd_invariant(obj));
+ LASSERT(!dt_object_exists(dt));
+ LASSERT(osd_write_locked(env, obj));
+ LASSERT(th != NULL);
+
+ result = __osd_object_create(info, obj, attr, hint, dof, th);
+ if (result == 0)
+ result = __osd_oi_insert(env, obj, fid, th);
+
+ LASSERT(ergo(result == 0, dt_object_exists(dt)));
+ LASSERT(osd_invariant(obj));
+ RETURN(result);
+}
+
+/**
+ * Helper function for osd_xattr_set()
+ */
+static int __osd_xattr_set(const struct lu_env *env, struct dt_object *dt,
+ const struct lu_buf *buf, const char *name, int fl)
+{
+ struct osd_object *obj = osd_dt_obj(dt);
+ struct inode *inode = obj->oo_inode;
+ struct osd_thread_info *info = osd_oti_get(env);
+ struct dentry *dentry = &info->oti_child_dentry;
+ struct timespec *t = &info->oti_time;
+ int fs_flags = 0;
+ int rc;
+
+ LASSERT(dt_object_exists(dt));
+ LASSERT(inode->i_op != NULL && inode->i_op->setxattr != NULL);
+ LASSERT(osd_write_locked(env, obj));
+
+ if (fl & LU_XATTR_REPLACE)
+ fs_flags |= XATTR_REPLACE;
+
+ if (fl & LU_XATTR_CREATE)
+ fs_flags |= XATTR_CREATE;
+
+ dentry->d_inode = inode;
+ *t = inode->i_ctime;
+ rc = inode->i_op->setxattr(dentry, name, buf->lb_buf,
+ buf->lb_len, fs_flags);
+ /* ctime should not be updated with server-side time. */
+ spin_lock(&obj->oo_guard);
+ inode->i_ctime = *t;
+ spin_unlock(&obj->oo_guard);
+ mark_inode_dirty(inode);
+ return rc;
+}
+
+/**
+ * Put the fid into lustre_mdt_attrs, and then place the structure
+ * inode's ea. This fid should not be altered during the life time
+ * of the inode.
+ *
+ * \retval +ve, on success
+ * \retval -ve, on error
+ *
+ * FIXME: It is good to have/use ldiskfs_xattr_set_handle() here
+ */
+static int osd_ea_fid_set(const struct lu_env *env, struct dt_object *dt,
+ const struct lu_fid *fid)
+{
+ struct osd_thread_info *info = osd_oti_get(env);
+ struct lustre_mdt_attrs *mdt_attrs = &info->oti_mdt_attrs;
+
+ fid_cpu_to_be(&mdt_attrs->lma_self_fid, fid);
+
+ return __osd_xattr_set(env, dt,
+ osd_buf_get(env, mdt_attrs, sizeof *mdt_attrs),
+ XATTR_NAME_LMA, LU_XATTR_CREATE);
+
+}
+
+/**
+ * Helper function to form igif
+ */
+static inline void osd_igif_get(const struct lu_env *env, struct inode *inode,
+ struct lu_fid *fid)