@@ -1798,6 +1798,7 @@ struct cl_io {
} ci_setattr;
struct cl_data_version_io {
u64 dv_data_version;
+ u32 dv_layout_version;
int dv_flags;
} ci_data_version;
struct cl_fault_io {
@@ -1851,18 +1851,8 @@ int ll_fid2path(struct inode *inode, void __user *arg)
return rc;
}
-/*
- * Read the data_version for inode.
- *
- * This value is computed using stripe object version on OST.
- * Version is computed using server side locking.
- *
- * @flags: if do sync on the OST side;
- * 0: no sync
- * LL_DV_RD_FLUSH: flush dirty pages, LCK_PR on OSTs
- * LL_DV_WR_FLUSH: drop all caching pages, LCK_PW on OSTs
- */
-int ll_data_version(struct inode *inode, u64 *data_version, int flags)
+static int
+ll_ioc_data_version(struct inode *inode, struct ioc_data_version *ioc)
{
struct cl_object *obj = ll_i2info(inode)->lli_clob;
struct lu_env *env;
@@ -1870,11 +1860,12 @@ int ll_data_version(struct inode *inode, u64 *data_version, int flags)
u16 refcheck;
int result;
+ ioc->idv_version = 0;
+ ioc->idv_layout_version = UINT_MAX;
+
/* If no file object initialized, we consider its version is 0. */
- if (!obj) {
- *data_version = 0;
+ if (!obj)
return 0;
- }
env = cl_env_get(&refcheck);
if (IS_ERR(env))
@@ -1883,7 +1874,8 @@ int ll_data_version(struct inode *inode, u64 *data_version, int flags)
io = vvp_env_thread_io(env);
io->ci_obj = obj;
io->u.ci_data_version.dv_data_version = 0;
- io->u.ci_data_version.dv_flags = flags;
+ io->u.ci_data_version.dv_layout_version = UINT_MAX;
+ io->u.ci_data_version.dv_flags = ioc->idv_flags;
restart:
if (!cl_io_init(env, io, CIT_DATA_VERSION, io->ci_obj))
@@ -1891,7 +1883,8 @@ int ll_data_version(struct inode *inode, u64 *data_version, int flags)
else
result = io->ci_result;
- *data_version = io->u.ci_data_version.dv_data_version;
+ ioc->idv_version = io->u.ci_data_version.dv_data_version;
+ ioc->idv_layout_version = io->u.ci_data_version.dv_layout_version;
cl_io_fini(env, io);
@@ -1904,6 +1897,29 @@ int ll_data_version(struct inode *inode, u64 *data_version, int flags)
}
/*
+ * Read the data_version for inode.
+ *
+ * This value is computed using stripe object version on OST.
+ * Version is computed using server side locking.
+ *
+ * @param flags if do sync on the OST side;
+ * 0: no sync
+ * LL_DV_RD_FLUSH: flush dirty pages, LCK_PR on OSTs
+ * LL_DV_WR_FLUSH: drop all caching pages, LCK_PW on OSTs
+ */
+int ll_data_version(struct inode *inode, u64 *data_version, int flags)
+{
+ struct ioc_data_version ioc = { .idv_flags = flags };
+ int rc;
+
+ rc = ll_ioc_data_version(inode, &ioc);
+ if (!rc)
+ *data_version = ioc.idv_version;
+
+ return rc;
+}
+
+/*
* Trigger a HSM release request for the provided inode.
*/
int ll_hsm_release(struct inode *inode)
@@ -2677,7 +2693,7 @@ int ll_ioctl_fssetxattr(struct inode *inode, unsigned int cmd,
return -EFAULT;
idv.idv_flags &= LL_DV_RD_FLUSH | LL_DV_WR_FLUSH;
- rc = ll_data_version(inode, &idv.idv_version, idv.idv_flags);
+ rc = ll_ioc_data_version(inode, &idv);
if (rc == 0 && copy_to_user((char __user *)arg, &idv,
sizeof(idv)))
return -EFAULT;
@@ -844,13 +844,17 @@ static void lov_io_end(const struct lu_env *env, const struct cl_io_slice *ios)
{
struct lov_io *lio = cl2lov_io(env, ios);
struct cl_io *parent = lio->lis_cl.cis_io;
+ struct cl_data_version_io *pdv = &parent->u.ci_data_version;
struct lov_io_sub *sub;
list_for_each_entry(sub, &lio->lis_active, sub_linkage) {
+ struct cl_data_version_io *sdv = &sub->sub_io.u.ci_data_version;
+
lov_io_end_wrapper(sub->sub_env, &sub->sub_io);
- parent->u.ci_data_version.dv_data_version +=
- sub->sub_io.u.ci_data_version.dv_data_version;
+ pdv->dv_data_version += sdv->dv_data_version;
+ if (pdv->dv_layout_version > sdv->dv_layout_version)
+ pdv->dv_layout_version = sdv->dv_layout_version;
if (!parent->ci_result)
parent->ci_result = sub->sub_io.ci_result;
@@ -714,11 +714,16 @@ static void osc_io_data_version_end(const struct lu_env *env,
if (cbargs->opc_rc) {
slice->cis_io->ci_result = cbargs->opc_rc;
- } else if (!(oio->oi_oa.o_valid & OBD_MD_FLDATAVERSION)) {
- slice->cis_io->ci_result = -EOPNOTSUPP;
} else {
- dv->dv_data_version = oio->oi_oa.o_data_version;
slice->cis_io->ci_result = 0;
+ if (!(oio->oi_oa.o_valid &
+ (OBD_MD_LAYOUT_VERSION | OBD_MD_FLDATAVERSION)))
+ slice->cis_io->ci_result = -ENOTSUPP;
+
+ if (oio->oi_oa.o_valid & OBD_MD_LAYOUT_VERSION)
+ dv->dv_layout_version = oio->oi_oa.o_layout_version;
+ if (oio->oi_oa.o_valid & OBD_MD_FLDATAVERSION)
+ dv->dv_data_version = oio->oi_oa.o_data_version;
}
}
@@ -1132,12 +1132,15 @@ enum changelog_message_type {
/********* Misc **********/
struct ioc_data_version {
- __u64 idv_version;
- __u64 idv_flags; /* See LL_DV_xxx */
+ __u64 idv_version;
+ __u32 idv_layout_version; /* FLR: layout version for OST objects */
+ __u32 idv_flags; /* enum ioc_data_version_flags */
};
-#define LL_DV_RD_FLUSH (1 << 0) /* Flush dirty pages from clients */
-#define LL_DV_WR_FLUSH (1 << 1) /* Flush all caching pages from clients */
+enum ioc_data_version_flags {
+ LL_DV_RD_FLUSH = (1 << 0), /* Flush dirty pages from clients */
+ LL_DV_WR_FLUSH = (1 << 1), /* Flush all caching pages from clients */
+};
#ifndef offsetof
# define offsetof(typ, memb) ((unsigned long)((char *)&(((typ *)0)->memb)))