Whamcloud - gitweb
LU-9771 flr: extend DATA_VERSION API to read layout version 92/29092/14
authorJinshan Xiong <jinshan.xiong@intel.com>
Fri, 15 Sep 2017 20:49:02 +0000 (20:49 +0000)
committerJinshan Xiong <jinshan.xiong@intel.com>
Mon, 20 Nov 2017 21:50:06 +0000 (21:50 +0000)
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>
lustre/include/cl_object.h
lustre/include/lustre/lustreapi.h
lustre/include/uapi/linux/lustre/lustre_user.h
lustre/llite/file.c
lustre/lov/lov_io.c
lustre/ofd/ofd_dev.c
lustre/osc/osc_io.c
lustre/tests/multiop.c
lustre/utils/liblustreapi.c

index 61338cd..4ab1dc0 100644 (file)
@@ -1819,6 +1819,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 {
index 1ae9361..cc50d5d 100644 (file)
@@ -344,6 +344,7 @@ int llapi_get_version_string(char *version, unsigned int version_size);
 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,
index c538657..a9e53af 100644 (file)
@@ -1242,11 +1242,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 */
+};
+
+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)))
index 8b516bb..96115bd 100644 (file)
@@ -2105,18 +2105,8 @@ gf_free:
        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;
@@ -2126,11 +2116,12 @@ int ll_data_version(struct inode *inode, __u64 *data_version, int flags)
 
        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))
@@ -2139,7 +2130,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) == 0)
@@ -2147,7 +2139,8 @@ restart:
        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);
 
@@ -2160,6 +2153,29 @@ restart:
 }
 
 /*
+ * 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)
@@ -2887,7 +2903,7 @@ out:
                        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)))
index 9440d4f..317fb3f 100644 (file)
@@ -868,14 +868,18 @@ lov_io_data_version_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;
 
        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;
index 8b498c0..19f8381 100644 (file)
@@ -1332,6 +1332,16 @@ static int ofd_getattr_hdl(struct tgt_session_info *tsi)
                        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);
index 5ccff72..bcfbe8b 100644 (file)
@@ -715,11 +715,16 @@ static void osc_io_data_version_end(const struct lu_env *env,
 
        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;
index 7d284f9..f959746 100644 (file)
@@ -219,7 +219,6 @@ int main(int argc, char **argv)
        lustre_fid               fid;
        struct timespec          ts;
        struct lov_user_md_v3    lum;
-       __u64                    dv;
 
         if (argc < 3) {
                 fprintf(stderr, usage, argv[0]);
@@ -643,7 +642,9 @@ int main(int argc, char **argv)
                        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"
@@ -652,6 +653,19 @@ int main(int argc, char **argv)
                        }
                        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;
index ccf9e8c..1fdc411 100644 (file)
@@ -4750,18 +4750,39 @@ int llapi_get_connect_flags(const char *mnt, __u64 *flags)
  */
 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;
 }
 
 /*