layout intent for truncate IO needs stale components for non
primary mirror overlapping [trunc_size, eof), while needs to
instantiate components overlapping [0, trunc_size).
Test-Parameters: testlist=sanity-flr
Signed-off-by: Bobi Jam <bobijam.xu@intel.com>
Change-Id: Ibf31e3e1fd68d1a643f2ed3ac5b9e3c778563895
Signed-off-by: Jinshan Xiong <jinshan.xiong@intel.com>
Reviewed-on: https://review.whamcloud.com/29099
Reviewed-by: Jian Yu <jian.yu@intel.com>
Reviewed-by: Lai Siyao <lai.siyao@intel.com>
Tested-by: Jenkins
Reviewed-by: Dmitry Eremin <dmitry.eremin@intel.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
char gp_name[0]; /**< zero-terminated link name */
} __attribute__((packed));
char gp_name[0]; /**< zero-terminated link name */
} __attribute__((packed));
+enum layout_intent_opc {
LAYOUT_INTENT_ACCESS = 0, /** generic access */
LAYOUT_INTENT_READ = 1, /** not used */
LAYOUT_INTENT_WRITE = 2, /** write file, for comp layout */
LAYOUT_INTENT_ACCESS = 0, /** generic access */
LAYOUT_INTENT_READ = 1, /** not used */
LAYOUT_INTENT_WRITE = 2, /** write file, for comp layout */
struct cl_layout cl = {
.cl_is_composite = false,
};
struct cl_layout cl = {
.cl_is_composite = false,
};
+ struct lu_extent ext = {
+ .e_start = 0,
+ .e_end = OBD_OBJECT_EOF,
+ };
env = cl_env_get(&refcheck);
if (IS_ERR(env))
env = cl_env_get(&refcheck);
if (IS_ERR(env))
rc = cl_object_layout_get(env, obj, &cl);
if (!rc && cl.cl_is_composite)
rc = cl_object_layout_get(env, obj, &cl);
if (!rc && cl.cl_is_composite)
- rc = ll_layout_write_intent(inode, 0, OBD_OBJECT_EOF);
+ rc = ll_layout_write_intent(inode, LAYOUT_INTENT_WRITE,
+ &ext);
cl_env_put(env, &refcheck);
if (rc)
cl_env_put(env, &refcheck);
if (rc)
* Issue layout intent RPC indicating where in a file an IO is about to write.
*
* \param[in] inode file inode.
* Issue layout intent RPC indicating where in a file an IO is about to write.
*
* \param[in] inode file inode.
- * \param[in] start start offset of fille in bytes where an IO is about to
- * write.
- * \param[in] end exclusive end offset in bytes of the write range.
+ * \param[in] ext write range with start offset of fille in bytes where
+ * an IO is about to write, and exclusive end offset in
+ * bytes.
*
* \retval 0 on success
* \retval < 0 error code
*/
*
* \retval 0 on success
* \retval < 0 error code
*/
-int ll_layout_write_intent(struct inode *inode, __u64 start, __u64 end)
+int ll_layout_write_intent(struct inode *inode, enum layout_intent_opc opc,
+ struct lu_extent *ext)
{
struct layout_intent intent = {
{
struct layout_intent intent = {
- .li_opc = LAYOUT_INTENT_WRITE,
- .li_extent.e_start = start,
- .li_extent.e_end = end,
+ .li_opc = opc,
+ .li_extent.e_start = ext->e_start,
+ .li_extent.e_end = ext->e_end,
io->u.ci_setattr.sa_valid = attr->ia_valid;
io->u.ci_setattr.sa_parent_fid = lu_object_fid(&obj->co_lu);
io->u.ci_setattr.sa_valid = attr->ia_valid;
io->u.ci_setattr.sa_parent_fid = lu_object_fid(&obj->co_lu);
if (attr->ia_valid & ATTR_FILE)
ll_io_set_mirror(io, attr->ia_file);
if (attr->ia_valid & ATTR_FILE)
ll_io_set_mirror(io, attr->ia_file);
if (cl_io_init(env, io, CIT_SETATTR, io->ci_obj) == 0) {
struct vvp_io *vio = vvp_env_io(env);
if (cl_io_init(env, io, CIT_SETATTR, io->ci_obj) == 0) {
struct vvp_io *vio = vvp_env_io(env);
int ll_layout_conf(struct inode *inode, const struct cl_object_conf *conf);
int ll_layout_refresh(struct inode *inode, __u32 *gen);
int ll_layout_restore(struct inode *inode, loff_t start, __u64 length);
int ll_layout_conf(struct inode *inode, const struct cl_object_conf *conf);
int ll_layout_refresh(struct inode *inode, __u32 *gen);
int ll_layout_restore(struct inode *inode, loff_t start, __u64 length);
-int ll_layout_write_intent(struct inode *inode, __u64 start, __u64 end);
+int ll_layout_write_intent(struct inode *inode, enum layout_intent_opc opc,
+ struct lu_extent *ext);
int ll_xattr_init(void);
void ll_xattr_fini(void);
int ll_xattr_init(void);
void ll_xattr_fini(void);
* RPC.
*/
if (io->ci_need_write_intent) {
* RPC.
*/
if (io->ci_need_write_intent) {
+ enum layout_intent_opc opc = LAYOUT_INTENT_WRITE;
+
io->ci_need_write_intent = 0;
LASSERT(io->ci_type == CIT_WRITE ||
io->ci_need_write_intent = 0;
LASSERT(io->ci_type == CIT_WRITE ||
PFID(lu_object_fid(&obj->co_lu)), io->ci_type,
PEXT(&io->ci_write_intent));
PFID(lu_object_fid(&obj->co_lu)), io->ci_type,
PEXT(&io->ci_write_intent));
- rc = ll_layout_write_intent(inode, io->ci_write_intent.e_start,
- io->ci_write_intent.e_end);
+ if (cl_io_is_trunc(io))
+ opc = LAYOUT_INTENT_TRUNC;
+
+ rc = ll_layout_write_intent(inode, opc, &io->ci_write_intent);
io->ci_result = rc;
if (!rc)
io->ci_need_restart = 1;
io->ci_result = rc;
if (!rc)
io->ci_need_restart = 1;
+ if (layout->li_opc == LAYOUT_INTENT_TRUNC) {
+ /**
+ * trunc transfers [size, eof) in the intent extent, while
+ * we'd instantiated components covers [0, size).
+ */
+ layout->li_extent.e_end = layout->li_extent.e_start;
+ layout->li_extent.e_start = 0;
+ }
+
/* Make sure defined layout covers the requested write range. */
lod_comp = &lo->ldo_comp_entries[lo->ldo_comp_cnt - 1];
if (lo->ldo_comp_cnt > 1 &&
/* Make sure defined layout covers the requested write range. */
lod_comp = &lo->ldo_comp_entries[lo->ldo_comp_cnt - 1];
if (lo->ldo_comp_cnt > 1 &&
lod_stale_components(lo, picked, &extent);
/* instantiate components for the picked mirror, start from 0 */
lod_stale_components(lo, picked, &extent);
/* instantiate components for the picked mirror, start from 0 */
- extent = (struct lu_extent) { 0, layout->li_extent.e_end };
+ if (layout->li_opc == LAYOUT_INTENT_TRUNC) {
+ /**
+ * trunc transfers [size, eof) in the intent extent, we'd
+ * stale components overlapping [size, eof), while we'd
+ * instantiated components covers [0, size).
+ */
+ extent.e_end = extent.e_start;
+ }
+ extent.e_start = 0;
+
lod_foreach_mirror_comp(lod_comp, lo, picked) {
if (!lu_extent_is_overlapped(&extent,
&lod_comp->llc_extent))
lod_foreach_mirror_comp(lod_comp, lo, picked) {
if (!lu_extent_is_overlapped(&extent,
&lod_comp->llc_extent))
/* 2. find out the components need instantiating.
* instantiate [0, mlc->mlc_intent->e_end) */
/* 2. find out the components need instantiating.
* instantiate [0, mlc->mlc_intent->e_end) */
+ if (mlc->mlc_intent->li_opc == LAYOUT_INTENT_TRUNC) {
+ /**
+ * trunc transfers [size, eof) in the intent extent,
+ * we'd stale components overlapping [size, eof),
+ * while we'd instantiated components covers [0, size).
+ */
+ extent.e_end = extent.e_start;
+ }
lod_foreach_mirror_comp(lod_comp, lo, primary) {
if (!lu_extent_is_overlapped(&extent,
&lod_comp->llc_extent))
lod_foreach_mirror_comp(lod_comp, lo, primary) {
if (!lu_extent_is_overlapped(&extent,
&lod_comp->llc_extent))
(cl_io_is_trunc(io) && io->u.ci_setattr.sa_attr.lvb_size > 0)))
GOTO(out, result = 0);
(cl_io_is_trunc(io) && io->u.ci_setattr.sa_attr.lvb_size > 0)))
GOTO(out, result = 0);
- ext.e_start = lio->lis_pos;
- ext.e_end = lio->lis_endpos;
+ io->ci_write_intent.e_start = lio->lis_pos;
+ io->ci_write_intent.e_end = lio->lis_endpos;
+ ext = io->ci_write_intent;
/* for truncate, it only needs to instantiate the components
* before the truncated size. */
if (cl_io_is_trunc(io)) {
/* for truncate, it only needs to instantiate the components
* before the truncated size. */
if (cl_io_is_trunc(io)) {
lov_foreach_io_layout(index, lio, &ext) {
if (!lsm_entry_inited(obj->lo_lsm, index)) {
io->ci_need_write_intent = 1;
lov_foreach_io_layout(index, lio, &ext) {
if (!lsm_entry_inited(obj->lo_lsm, index)) {
io->ci_need_write_intent = 1;
- io->ci_write_intent = ext;
$TRUNCATE $comp_file $((1024*1024*1+1))
f2=$($LFS getstripe -I2 $comp_file | grep "l_fid")
$TRUNCATE $comp_file $((1024*1024*1+1))
f2=$($LFS getstripe -I2 $comp_file | grep "l_fid")
- [[ -z $f2 ]] && error "2: 2nd component uninstantiated"
+ [[ -z $f2 ]] && error "3: 2nd component uninstantiated"
f3=$($LFS getstripe -I3 $comp_file | grep "l_fid")
[[ -z $f3 ]] && error "3: 3rd component uninstantiated"
f4=$($LFS getstripe -I4 $comp_file | grep "l_fid")
f3=$($LFS getstripe -I3 $comp_file | grep "l_fid")
[[ -z $f3 ]] && error "3: 3rd component uninstantiated"
f4=$($LFS getstripe -I4 $comp_file | grep "l_fid")