This is a preparation patch for FLR write support.
Test-Parameters: testlist=sanity-flr
Signed-off-by: Jinshan Xiong <jinshan.xiong@intel.com>
Change-Id: I6323c260a636d31f683c035b45536374faa10746
Reviewed-on: https://review.whamcloud.com/29090
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Lai Siyao <lai.siyao@intel.com>
Reviewed-by: Bobi Jam <bobijam@hotmail.com>
+struct md_layout_change;
+
/**
* A dt_object provides common operations to create and destroy
* objects and to manage regular and extended attributes.
/**
* A dt_object provides common operations to create and destroy
* objects and to manage regular and extended attributes.
*/
int (*do_declare_layout_change)(const struct lu_env *env,
struct dt_object *dt,
*/
int (*do_declare_layout_change)(const struct lu_env *env,
struct dt_object *dt,
- struct layout_intent *layout,
- const struct lu_buf *buf,
+ struct md_layout_change *mlc,
* \retval -ne error code
*/
int (*do_layout_change)(const struct lu_env *env, struct dt_object *dt,
* \retval -ne error code
*/
int (*do_layout_change)(const struct lu_env *env, struct dt_object *dt,
- struct layout_intent *layout,
- const struct lu_buf *buf, struct thandle *th);
+ struct md_layout_change *mlc,
+ struct thandle *th);
static inline int dt_declare_layout_change(const struct lu_env *env,
struct dt_object *o,
static inline int dt_declare_layout_change(const struct lu_env *env,
struct dt_object *o,
- struct layout_intent *layout,
- const struct lu_buf *buf,
+ struct md_layout_change *mlc,
struct thandle *th)
{
LASSERT(o);
LASSERT(o->do_ops);
LASSERT(o->do_ops->do_declare_layout_change);
struct thandle *th)
{
LASSERT(o);
LASSERT(o->do_ops);
LASSERT(o->do_ops->do_declare_layout_change);
- return o->do_ops->do_declare_layout_change(env, o, layout, buf, th);
+ return o->do_ops->do_declare_layout_change(env, o, mlc, th);
}
static inline int dt_layout_change(const struct lu_env *env,
struct dt_object *o,
}
static inline int dt_layout_change(const struct lu_env *env,
struct dt_object *o,
- struct layout_intent *layout,
- const struct lu_buf *buf,
+ struct md_layout_change *mlc,
struct thandle *th)
{
LASSERT(o);
LASSERT(o->do_ops);
LASSERT(o->do_ops->do_layout_change);
struct thandle *th)
{
LASSERT(o);
LASSERT(o->do_ops);
LASSERT(o->do_ops->do_layout_change);
- return o->do_ops->do_layout_change(env, o, layout, buf, th);
+ return o->do_ops->do_layout_change(env, o, mlc, th);
const struct dt_index_features *sp_feat;
};
const struct dt_index_features *sp_feat;
};
+enum md_layout_opc {
+ MD_LAYOUT_NOP = 0,
+ MD_LAYOUT_WRITE, /* FLR: write the file */
+};
+
+/**
+ * Parameters for layout change API.
+ */
+struct md_layout_change {
+ enum md_layout_opc mlc_opc;
+ struct layout_intent *mlc_intent;
+ struct lu_buf mlc_buf;
+};
+
union ldlm_policy_data;
/**
* Operations implemented for each md object (both directory and leaf).
union ldlm_policy_data;
/**
* Operations implemented for each md object (both directory and leaf).
*
* The caller should have held layout lock.
*
*
* The caller should have held layout lock.
*
+ * This API can be extended to support every other layout changing
+ * operations, such as component {add,del,change}, layout swap,
+ * layout merge, etc. One of the benefits by doing this is that the MDT
+ * no longer needs to understand layout.
+ *
+ * However, layout creation, removal, and fetch should still use
+ * xattr_{get,set}() because they don't interpret layout on the
+ * MDT layer.
+ *
* \param[in] env execution environment
* \param[in] obj MD object
* \param[in] layout data structure to describe the changes to
* the MD object's layout
* \param[in] env execution environment
* \param[in] obj MD object
* \param[in] layout data structure to describe the changes to
* the MD object's layout
- * \param[in] buf buffer containing the client's lovea
*
* \retval 0 success
* \retval -ne error code
*/
int (*moo_layout_change)(const struct lu_env *env,
struct md_object *obj,
*
* \retval 0 success
* \retval -ne error code
*/
int (*moo_layout_change)(const struct lu_env *env,
struct md_object *obj,
- struct layout_intent *layout,
- const struct lu_buf *buf);
+ struct md_layout_change *layout);
static inline int mo_layout_change(const struct lu_env *env,
struct md_object *m,
static inline int mo_layout_change(const struct lu_env *env,
struct md_object *m,
- struct layout_intent *layout,
- const struct lu_buf *buf)
+ struct md_layout_change *layout)
{
/* need instantiate objects which in the access range */
LASSERT(m->mo_ops->moo_layout_change);
{
/* need instantiate objects which in the access range */
LASSERT(m->mo_ops->moo_layout_change);
- return m->mo_ops->moo_layout_change(env, m, layout, buf);
+ return m->mo_ops->moo_layout_change(env, m, layout);
}
static inline int mo_swap_layouts(const struct lu_env *env,
}
static inline int mo_swap_layouts(const struct lu_env *env,
static int lod_declare_layout_change(const struct lu_env *env,
struct dt_object *dt,
static int lod_declare_layout_change(const struct lu_env *env,
struct dt_object *dt,
- struct layout_intent *layout,
- const struct lu_buf *buf,
+ struct md_layout_change *mlc,
struct thandle *th)
{
struct lod_thread_info *info = lod_env_info(env);
struct thandle *th)
{
struct lod_thread_info *info = lod_env_info(env);
struct lod_device *d = lu2lod_dev(dt->do_lu.lo_dev);
struct dt_object *next = dt_object_child(dt);
struct ost_pool *inuse = &info->lti_inuse_osts;
struct lod_device *d = lu2lod_dev(dt->do_lu.lo_dev);
struct dt_object *next = dt_object_child(dt);
struct ost_pool *inuse = &info->lti_inuse_osts;
+ struct layout_intent *layout = mlc->mlc_intent;
+ struct lu_buf *buf = &mlc->mlc_buf;
struct lod_layout_component *lod_comp;
struct lov_comp_md_v1 *comp_v1 = NULL;
bool replay = false;
struct lod_layout_component *lod_comp;
struct lov_comp_md_v1 *comp_v1 = NULL;
bool replay = false;
* Instantiate layout component objects which covers the intent write offset.
*/
static int lod_layout_change(const struct lu_env *env, struct dt_object *dt,
* Instantiate layout component objects which covers the intent write offset.
*/
static int lod_layout_change(const struct lu_env *env, struct dt_object *dt,
- struct layout_intent *layout,
- const struct lu_buf *buf, struct thandle *th)
+ struct md_layout_change *mlc, struct thandle *th)
{
struct lu_attr *attr = &lod_env_info(env)->lti_attr;
{
struct lu_attr *attr = &lod_env_info(env)->lti_attr;
static inline int
mdo_declare_layout_change(const struct lu_env *env, struct mdd_object *obj,
static inline int
mdo_declare_layout_change(const struct lu_env *env, struct mdd_object *obj,
- struct layout_intent *layout,
- const struct lu_buf *buf, struct thandle *handle)
+ struct md_layout_change *mlc, struct thandle *handle)
{
return dt_declare_layout_change(env, mdd_object_child(obj),
{
return dt_declare_layout_change(env, mdd_object_child(obj),
}
static inline int
mdo_layout_change(const struct lu_env *env, struct mdd_object *obj,
}
static inline int
mdo_layout_change(const struct lu_env *env, struct mdd_object *obj,
- struct layout_intent *layout, const struct lu_buf *buf,
- struct thandle *handle)
+ struct md_layout_change *mlc, struct thandle *handle)
- return dt_layout_change(env, mdd_object_child(obj),
- layout, buf, handle);
+ return dt_layout_change(env, mdd_object_child(obj), mlc, handle);
static int mdd_declare_layout_change(const struct lu_env *env,
struct mdd_device *mdd,
struct mdd_object *obj,
static int mdd_declare_layout_change(const struct lu_env *env,
struct mdd_device *mdd,
struct mdd_object *obj,
- struct layout_intent *layout,
- const struct lu_buf *buf,
+ struct md_layout_change *mlc,
struct thandle *handle)
{
int rc;
struct thandle *handle)
{
int rc;
- rc = mdo_declare_layout_change(env, obj, layout, buf, handle);
+ rc = mdo_declare_layout_change(env, obj, mlc, handle);
/* For PFL, this is used to instantiate necessary component objects. */
int mdd_layout_change(const struct lu_env *env, struct md_object *obj,
/* For PFL, this is used to instantiate necessary component objects. */
int mdd_layout_change(const struct lu_env *env, struct md_object *obj,
- struct layout_intent *layout, const struct lu_buf *buf)
+ struct md_layout_change *mlc)
{
struct mdd_object *mdd_obj = md2mdd_obj(obj);
struct mdd_device *mdd = mdo2mdd(obj);
{
struct mdd_object *mdd_obj = md2mdd_obj(obj);
struct mdd_device *mdd = mdo2mdd(obj);
if (IS_ERR(handle))
RETURN(PTR_ERR(handle));
if (IS_ERR(handle))
RETURN(PTR_ERR(handle));
- rc = mdd_declare_layout_change(env, mdd, mdd_obj, layout, buf, handle);
+ rc = mdd_declare_layout_change(env, mdd, mdd_obj, mlc, handle);
/**
* It's possible that another layout write intent has already
* instantiated our objects, so a -EALREADY returned, and we need to
/**
* It's possible that another layout write intent has already
* instantiated our objects, so a -EALREADY returned, and we need to
GOTO(stop, rc);
mdd_write_lock(env, mdd_obj, MOR_TGT_CHILD);
GOTO(stop, rc);
mdd_write_lock(env, mdd_obj, MOR_TGT_CHILD);
- rc = mdo_layout_change(env, mdd_obj, layout, buf, handle);
+ rc = mdo_layout_change(env, mdd_obj, mlc, handle);
mdd_write_unlock(env, mdd_obj);
if (rc)
GOTO(stop, rc);
mdd_write_unlock(env, mdd_obj);
if (rc)
GOTO(stop, rc);
*
* \param[in] info thread environment
* \param[in] obj object
*
* \param[in] info thread environment
* \param[in] obj object
- * \param[in] layout layout intent
- * \param[in] buf buffer containing client's lovea, could be empty
+ * \param[in] layout layout change descriptor
*
* \retval 0 on success
* \retval < 0 error code
*/
static int mdt_layout_change(struct mdt_thread_info *info,
struct mdt_object *obj,
*
* \retval 0 on success
* \retval < 0 error code
*/
static int mdt_layout_change(struct mdt_thread_info *info,
struct mdt_object *obj,
- struct layout_intent *layout,
- const struct lu_buf *buf)
+ struct md_layout_change *layout)
{
struct mdt_lock_handle *lh = &info->mti_lh[MDT_LH_LOCAL];
{
struct mdt_lock_handle *lh = &info->mti_lh[MDT_LH_LOCAL];
+ struct layout_intent *intent = layout->mlc_intent;
int rc;
ENTRY;
CDEBUG(D_INFO, "got layout change request from client: "
"opc:%u flags:%#x extent "DEXT"\n",
int rc;
ENTRY;
CDEBUG(D_INFO, "got layout change request from client: "
"opc:%u flags:%#x extent "DEXT"\n",
- layout->li_opc, layout->li_flags,
- PEXT(&layout->li_extent));
+ intent->li_opc, intent->li_flags, PEXT(&intent->li_extent));
- if (layout->li_extent.e_start >= layout->li_extent.e_end) {
- CERROR("Recieved an invalid layout change range "DEXT
- "for "DFID"\n",
- PEXT(&layout->li_extent), PFID(mdt_object_fid(obj)));
+ if (intent->li_extent.e_start >= intent->li_extent.e_end) {
+ CERROR(DFID ":invalid range of layout change "DEXT"\n",
+ PFID(mdt_object_fid(obj)), PEXT(&intent->li_extent));
+ if (!mdt_object_exists(obj))
+ GOTO(out, rc = -ENOENT);
+
if (!S_ISREG(lu_object_attr(&obj->mot_obj)))
GOTO(out, rc = -EINVAL);
if (!S_ISREG(lu_object_attr(&obj->mot_obj)))
GOTO(out, rc = -EINVAL);
/* take layout lock to prepare layout change */
mdt_lock_reg_init(lh, LCK_EX);
/* take layout lock to prepare layout change */
mdt_lock_reg_init(lh, LCK_EX);
- rc = mdt_object_lock(info, obj, lh,
- MDS_INODELOCK_LAYOUT | MDS_INODELOCK_XATTR);
+ rc = mdt_object_lock(info, obj, lh, MDS_INODELOCK_LAYOUT);
- rc = mo_layout_change(info->mti_env, mdt_object_child(obj), layout,
- buf);
+ rc = mo_layout_change(info->mti_env, mdt_object_child(obj), layout);
mdt_object_unlock(info, obj, lh, 1);
out:
mdt_object_unlock(info, obj, lh, 1);
out:
__u64 flags)
{
struct mdt_lock_handle *lhc = &info->mti_lh[MDT_LH_LAYOUT];
__u64 flags)
{
struct mdt_lock_handle *lhc = &info->mti_lh[MDT_LH_LAYOUT];
- struct layout_intent *layout;
+ struct md_layout_change layout = { .mlc_opc = MD_LAYOUT_NOP };
+ struct layout_intent *intent;
struct lu_fid *fid;
struct mdt_object *obj = NULL;
struct lu_fid *fid;
struct mdt_object *obj = NULL;
- bool layout_change = false;
int layout_size = 0;
int rc = 0;
ENTRY;
int layout_size = 0;
int rc = 0;
ENTRY;
- layout = req_capsule_client_get(info->mti_pill, &RMF_LAYOUT_INTENT);
- if (layout == NULL)
+ intent = req_capsule_client_get(info->mti_pill, &RMF_LAYOUT_INTENT);
+ if (intent == NULL)
- switch (layout->li_opc) {
+ switch (intent->li_opc) {
case LAYOUT_INTENT_TRUNC:
case LAYOUT_INTENT_WRITE:
case LAYOUT_INTENT_TRUNC:
case LAYOUT_INTENT_WRITE:
+ layout.mlc_opc = MD_LAYOUT_WRITE;
+ layout.mlc_intent = intent;
break;
case LAYOUT_INTENT_ACCESS:
break;
break;
case LAYOUT_INTENT_ACCESS:
break;
case LAYOUT_INTENT_RELEASE:
case LAYOUT_INTENT_RESTORE:
CERROR("%s: Unsupported layout intent opc %d\n",
case LAYOUT_INTENT_RELEASE:
case LAYOUT_INTENT_RESTORE:
CERROR("%s: Unsupported layout intent opc %d\n",
- mdt_obd_name(info->mti_mdt), layout->li_opc);
+ mdt_obd_name(info->mti_mdt), intent->li_opc);
rc = -ENOTSUPP;
break;
default:
CERROR("%s: Unknown layout intent opc %d\n",
rc = -ENOTSUPP;
break;
default:
CERROR("%s: Unknown layout intent opc %d\n",
- mdt_obd_name(info->mti_mdt), layout->li_opc);
+ mdt_obd_name(info->mti_mdt), intent->li_opc);
- if (layout_change) {
- struct lu_buf *buf = &info->mti_buf;
+ if (layout.mlc_opc != MD_LAYOUT_NOP) {
+ struct lu_buf *buf = &layout.mlc_buf;
/**
* mdt_layout_change is a reint operation, when the request
/**
* mdt_layout_change is a reint operation, when the request
* lovea, then it's a replay of the layout intent write
* RPC.
*/
* lovea, then it's a replay of the layout intent write
* RPC.
*/
- rc = mdt_layout_change(info, obj, layout, buf);
+ rc = mdt_layout_change(info, obj, &layout);
if (rc)
GOTO(out_obj, rc);
}
if (rc)
GOTO(out_obj, rc);
}