The API is extended to fetch layout version from ost objects.
Test-Parameters: testlist=sanity-flr
Signed-off-by: Jinshan Xiong <jinshan.xiong@intel.com>
Change-Id: Iba852633992f0c52af8837cfed70922c1ed9ae00
Reviewed-on: https://review.whamcloud.com/29092
Reviewed-by: Bobi Jam <bobijam@hotmail.com>
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Dmitry Eremin <dmitry.eremin@intel.com>
} 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 {
int llapi_get_version(char *buffer, int buffer_size, char **version)
__attribute__((deprecated));
int llapi_get_data_version(int fd, __u64 *data_version, __u64 flags);
+extern int llapi_get_ost_layout_version(int fd, __u32 *layout_version);
int llapi_hsm_state_get_fd(int fd, struct hsm_user_state *hus);
int llapi_hsm_state_get(const char *path, struct hsm_user_state *hus);
int llapi_hsm_state_set_fd(int fd, __u64 setmask, __u64 clearmask,
/********* 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 */
+};
+
+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 */
};
-#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 */
#ifndef offsetof
#define offsetof(typ, memb) ((unsigned long)((char *)&(((typ *)0)->memb)))
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.
- *
- * @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)
+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;
ENTRY;
+ ioc->idv_version = 0;
+ ioc->idv_layout_version = UINT_MAX;
+
/* If no file object initialized, we consider its version is 0. */
- if (obj == NULL) {
- *data_version = 0;
+ if (obj == NULL)
RETURN(0);
- }
env = cl_env_get(&refcheck);
if (IS_ERR(env))
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) == 0)
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);
}
/*
+ * 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)
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)))
{
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;
ENTRY;
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(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 == 0)
parent->ci_result = sub->sub_io.ci_result;
repbody->oa.o_valid |= OBD_MD_FLDATAVERSION;
repbody->oa.o_data_version = curr_version;
}
+
+ if (fo->ofo_ff.ff_layout_version > 0) {
+ repbody->oa.o_valid |= OBD_MD_LAYOUT_VERSION;
+ repbody->oa.o_layout_version =
+ fo->ofo_ff.ff_layout_version + fo->ofo_ff.ff_range;
+
+ CDEBUG(D_INODE, DFID": get layout version: %u\n",
+ PFID(&tsi->tsi_fid),
+ repbody->oa.o_layout_version);
+ }
}
ofd_object_put(tsi->tsi_env, fo);
if (cbargs->opc_rc != 0) {
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;
}
EXIT;
lustre_fid fid;
struct timespec ts;
struct lov_user_md_v3 lum;
- __u64 dv;
if (argc < 3) {
fprintf(stderr, usage, argv[0]);
for (i = 0; i < mmap_len && mmap_ptr; i += 4096)
mmap_ptr[i] += junk++;
break;
- case 'x':
+ case 'x': {
+ __u64 dv;
+
rc = llapi_get_data_version(fd, &dv, 0);
if (rc) {
fprintf(stderr, "cannot get file data version"
}
printf("dataversion is %ju\n", (uintmax_t)dv);
break;
+ }
+ case 'X': {
+ __u32 layout_version;
+
+ rc = llapi_get_ost_layout_version(fd, &layout_version);
+ if (rc) {
+ fprintf(stderr, "cannot get ost layout version"
+ " %d\n", rc);
+ exit(-rc);
+ }
+ printf("ostlayoutversion: %u\n", layout_version);
+ break;
+ }
case 'y':
if (fsync(fd) == -1) {
save_errno = errno;
*/
int llapi_get_data_version(int fd, __u64 *data_version, __u64 flags)
{
- int rc;
- struct ioc_data_version idv;
+ int rc;
+ struct ioc_data_version idv;
- idv.idv_flags = flags;
+ idv.idv_flags = (__u32)flags;
- rc = ioctl(fd, LL_IOC_DATA_VERSION, &idv);
- if (rc)
- rc = -errno;
- else
- *data_version = idv.idv_version;
+ rc = ioctl(fd, LL_IOC_DATA_VERSION, &idv);
+ if (rc)
+ rc = -errno;
+ else
+ *data_version = idv.idv_version;
- return rc;
+ return rc;
+}
+
+/*
+ * Fetch layout version from OST objects. Layout version on OST objects are
+ * only set when the file is a mirrored file AND after the file has been
+ * written at least once.
+ *
+ * It actually fetches the least layout version from the objects.
+ */
+int llapi_get_ost_layout_version(int fd, __u32 *layout_version)
+{
+ int rc;
+ struct ioc_data_version idv = { 0 };
+
+ rc = ioctl(fd, LL_IOC_DATA_VERSION, &idv);
+ if (rc)
+ rc = -errno;
+ else
+ *layout_version = idv.idv_layout_version;
+
+ return rc;
}
/*