Whamcloud - gitweb
LU-9367 llite: restore ll_file_getstripe in ll_lov_setstripe 15/26915/13
authorBobi Jam <bobijam.xu@intel.com>
Tue, 2 May 2017 12:30:27 +0000 (20:30 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Mon, 12 Jun 2017 22:35:10 +0000 (22:35 +0000)
Commit fafe6b4d4a6fa63cedff3bd44e6578009578b3d7 has get rid of
the call to ll_file_getstripe in ll_lov_setstripe.

Add a @size parameter for series of xxx_getstripe interfaces,
indicating the max buffer size that user provides to hold the
stripe information. It is mainly for the ll_lov_setstripe, which
will call ll_file_getstripe to fetch basic stripe inforation.

Add LL_IOC_LOV_SETSTRIPE_NEW/LL_IOC_LOV_GETSTRIPE_NEW ioctl interface
which defines the interface correctly, which could be used in later
Lustre versions.

Signed-off-by: Bobi Jam <bobijam.xu@intel.com>
Change-Id: Ic2f541fa3c74133eb40d230c8a836434043d7691
Reviewed-on: https://review.whamcloud.com/26915
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Tested-by: Jenkins
Reviewed-by: Jinshan Xiong <jinshan.xiong@intel.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
lustre/include/cl_object.h
lustre/include/lustre/lustre_user.h
lustre/llite/dir.c
lustre/llite/file.c
lustre/lov/lov_cl_internal.h
lustre/lov/lov_object.c
lustre/lov/lov_pack.c
lustre/obdclass/cl_object.c

index ca9b520..78d0926 100644 (file)
@@ -393,7 +393,7 @@ struct cl_object_operations {
         * Object getstripe method.
         */
        int (*coo_getstripe)(const struct lu_env *env, struct cl_object *obj,
-                            struct lov_user_md __user *lum);
+                            struct lov_user_md __user *lum, size_t size);
        /**
         * Get FIEMAP mapping from the object.
         */
@@ -2051,7 +2051,7 @@ int  cl_conf_set          (const struct lu_env *env, struct cl_object *obj,
 int  cl_object_prune      (const struct lu_env *env, struct cl_object *obj);
 void cl_object_kill       (const struct lu_env *env, struct cl_object *obj);
 int cl_object_getstripe(const struct lu_env *env, struct cl_object *obj,
-                       struct lov_user_md __user *lum);
+                       struct lov_user_md __user *lum, size_t size);
 int cl_object_fiemap(const struct lu_env *env, struct cl_object *obj,
                     struct ll_fiemap_info_key *fmkey, struct fiemap *fiemap,
                     size_t *buflen);
index 5db4dc1..1303143 100644 (file)
@@ -314,7 +314,9 @@ struct ll_futimes_3 {
 #define LL_IOC_SETFLAGS                 _IOW ('f', 152, long)
 #define LL_IOC_CLRFLAGS                 _IOW ('f', 153, long)
 #define LL_IOC_LOV_SETSTRIPE            _IOW ('f', 154, long)
+#define LL_IOC_LOV_SETSTRIPE_NEW       _IOWR('f', 154, struct lov_user_md)
 #define LL_IOC_LOV_GETSTRIPE            _IOW ('f', 155, long)
+#define LL_IOC_LOV_GETSTRIPE_NEW       _IOR('f', 155, struct lov_user_md)
 #define LL_IOC_LOV_SETEA                _IOW ('f', 156, long)
 /*     LL_IOC_RECREATE_OBJ             157 obsolete */
 /*     LL_IOC_RECREATE_FID             157 obsolete */
index b7508cd..45dd02e 100644 (file)
@@ -1283,6 +1283,7 @@ lmv_out_free:
 
                RETURN(rc);
        }
+       case LL_IOC_LOV_SETSTRIPE_NEW:
        case LL_IOC_LOV_SETSTRIPE: {
                struct lov_user_md_v3 lumv3;
                struct lov_user_md_v1 *lumv1 = (struct lov_user_md_v1 *)&lumv3;
@@ -1434,11 +1435,12 @@ out_rmdir:
                RETURN(-EPERM);
        case IOC_OBD_STATFS:
                RETURN(ll_obd_statfs(inode, (void __user *)arg));
-        case LL_IOC_LOV_GETSTRIPE:
-        case LL_IOC_MDC_GETINFO:
-        case IOC_MDC_GETFILEINFO:
-        case IOC_MDC_GETFILESTRIPE: {
-                struct ptlrpc_request *request = NULL;
+       case LL_IOC_LOV_GETSTRIPE:
+       case LL_IOC_LOV_GETSTRIPE_NEW:
+       case LL_IOC_MDC_GETINFO:
+       case IOC_MDC_GETFILEINFO:
+       case IOC_MDC_GETFILESTRIPE: {
+               struct ptlrpc_request *request = NULL;
                struct lov_user_md __user *lump;
                 struct lov_mds_md *lmm = NULL;
                 struct mdt_body *body;
@@ -1474,8 +1476,9 @@ out_rmdir:
                                 GOTO(out_req, rc);
                 }
 
-                if (cmd == IOC_MDC_GETFILESTRIPE ||
-                    cmd == LL_IOC_LOV_GETSTRIPE) {
+               if (cmd == IOC_MDC_GETFILESTRIPE ||
+                   cmd == LL_IOC_LOV_GETSTRIPE ||
+                   cmd == LL_IOC_LOV_GETSTRIPE_NEW) {
                        lump = (struct lov_user_md __user *)arg;
                 } else {
                        struct lov_user_mds_data __user *lmdp;
index 09bc0bf..d6591f5 100644 (file)
@@ -1763,7 +1763,7 @@ out:
 }
 
 static int ll_lov_setea(struct inode *inode, struct file *file,
-                            unsigned long arg)
+                       void __user *arg)
 {
        __u64                    flags = MDS_OPEN_HAS_OBJS | FMODE_WRITE;
        struct lov_user_md      *lump;
@@ -1779,7 +1779,7 @@ static int ll_lov_setea(struct inode *inode, struct file *file,
        if (lump == NULL)
                 RETURN(-ENOMEM);
 
-       if (copy_from_user(lump, (struct lov_user_md __user *)arg, lum_size))
+       if (copy_from_user(lump, arg, lum_size))
                GOTO(out_lump, rc = -EFAULT);
 
        rc = ll_lov_setstripe_ea_info(inode, file_dentry(file), flags, lump,
@@ -1791,8 +1791,7 @@ out_lump:
        RETURN(rc);
 }
 
-static int ll_file_getstripe(struct inode *inode,
-                            struct lov_user_md __user *lum)
+static int ll_file_getstripe(struct inode *inode, void __user *lum, size_t size)
 {
        struct lu_env   *env;
        __u16           refcheck;
@@ -1803,13 +1802,13 @@ static int ll_file_getstripe(struct inode *inode,
        if (IS_ERR(env))
                RETURN(PTR_ERR(env));
 
-       rc = cl_object_getstripe(env, ll_i2info(inode)->lli_clob, lum);
+       rc = cl_object_getstripe(env, ll_i2info(inode)->lli_clob, lum, size);
        cl_env_put(env, &refcheck);
        RETURN(rc);
 }
 
 static int ll_lov_setstripe(struct inode *inode, struct file *file,
-                           unsigned long arg)
+                           void __user *arg)
 {
        struct lov_user_md __user *lum = (struct lov_user_md __user *)arg;
        struct lov_user_md        *klum;
@@ -1824,7 +1823,22 @@ static int ll_lov_setstripe(struct inode *inode, struct file *file,
        lum_size = rc;
        rc = ll_lov_setstripe_ea_info(inode, file_dentry(file), flags, klum,
                                      lum_size);
+       if (!rc) {
+               __u32 gen;
+
+               rc = put_user(0, &lum->lmm_stripe_count);
+               if (rc)
+                       GOTO(out, rc);
+
+               rc = ll_layout_refresh(inode, &gen);
+               if (rc)
+                       GOTO(out, rc);
+
+               rc = ll_file_getstripe(inode, arg, lum_size);
+       }
        cl_lov_delay_create_clear(&file->f_flags);
+
+out:
        OBD_FREE(klum, lum_size);
        RETURN(rc);
 }
@@ -2582,16 +2596,17 @@ ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
                         fd->fd_flags &= ~flags;
                 }
                 RETURN(0);
-        case LL_IOC_LOV_SETSTRIPE:
-                RETURN(ll_lov_setstripe(inode, file, arg));
-        case LL_IOC_LOV_SETEA:
-                RETURN(ll_lov_setea(inode, file, arg));
+       case LL_IOC_LOV_SETSTRIPE:
+       case LL_IOC_LOV_SETSTRIPE_NEW:
+               RETURN(ll_lov_setstripe(inode, file, (void __user *)arg));
+       case LL_IOC_LOV_SETEA:
+               RETURN(ll_lov_setea(inode, file, (void __user *)arg));
        case LL_IOC_LOV_SWAP_LAYOUTS: {
                struct file *file2;
                struct lustre_swap_layouts lsl;
 
                if (copy_from_user(&lsl, (char __user *)arg,
-                                      sizeof(struct lustre_swap_layouts)))
+                                  sizeof(struct lustre_swap_layouts)))
                        RETURN(-EFAULT);
 
                if ((file->f_flags & O_ACCMODE) == O_RDONLY)
@@ -2632,8 +2647,8 @@ out:
                RETURN(rc);
        }
        case LL_IOC_LOV_GETSTRIPE:
-               RETURN(ll_file_getstripe(inode,
-                                        (struct lov_user_md __user *)arg));
+       case LL_IOC_LOV_GETSTRIPE_NEW:
+               RETURN(ll_file_getstripe(inode, (void __user *)arg, 0));
         case FSFILT_IOC_GETFLAGS:
         case FSFILT_IOC_SETFLAGS:
                 RETURN(ll_iocontrol(inode, file, cmd, arg));
index e16a6aa..ca40cc8 100644 (file)
@@ -653,7 +653,8 @@ static inline struct lov_stripe_md_entry *lov_lse(struct lov_object *lov, int i)
 
 /* lov_pack.c */
 int lov_getstripe(const struct lu_env *env, struct lov_object *obj,
-                 struct lov_stripe_md *lsm, struct lov_user_md __user *lump);
+                 struct lov_stripe_md *lsm, struct lov_user_md __user *lump,
+                 size_t size);
 
 /** @} lov */
 
index 614ca03..e26769c 100644 (file)
@@ -1602,7 +1602,7 @@ out_lsm:
 }
 
 static int lov_object_getstripe(const struct lu_env *env, struct cl_object *obj,
-                               struct lov_user_md __user *lum)
+                               struct lov_user_md __user *lum, size_t size)
 {
        struct lov_object       *lov = cl2lov(obj);
        struct lov_stripe_md    *lsm;
@@ -1613,7 +1613,7 @@ static int lov_object_getstripe(const struct lu_env *env, struct cl_object *obj,
        if (lsm == NULL)
                RETURN(-ENODATA);
 
-       rc = lov_getstripe(env, cl2lov(obj), lsm, lum);
+       rc = lov_getstripe(env, cl2lov(obj), lsm, lum, size);
        lov_lsm_put(lsm);
        RETURN(rc);
 }
index baff061..bdcf146 100644 (file)
@@ -341,12 +341,16 @@ struct lov_stripe_md *lov_unpackmd(struct lov_obd *lov, void *buf,
  * @lump is a pointer to an in-core struct with lmm_ost_count indicating
  * the maximum number of OST indices which will fit in the user buffer.
  * lmm_magic must be LOV_USER_MAGIC.
+ *
+ * If @size > 0, User specified limited buffer size, usually the buffer is from
+ * ll_lov_setstripe(), and the buffer can only hold basic layout template info.
  */
 int lov_getstripe(const struct lu_env *env, struct lov_object *obj,
-                 struct lov_stripe_md *lsm, struct lov_user_md __user *lump)
+                 struct lov_stripe_md *lsm, struct lov_user_md __user *lump,
+                 size_t size)
 {
        /* we use lov_user_md_v3 because it is larger than lov_user_md_v1 */
-       struct lov_mds_md *lmmk;
+       struct lov_mds_md *lmmk, *lmm;
        struct lov_user_md_v1 lum;
        size_t  lmmk_size;
        ssize_t lmm_size, lum_size = 0;
@@ -431,12 +435,22 @@ int lov_getstripe(const struct lu_env *env, struct lov_object *obj,
                        comp_md = (struct lov_mds_md *)((char *)comp_v1 +
                                        comp_v1->lcm_entries[i].lcme_offset);
                }
-               if (copy_to_user(lump, comp_md, lum_size))
-                       GOTO(out_free, rc = -EFAULT);
+
+               lmm = comp_md;
+               lmm_size = lum_size;
        } else {
-               if (copy_to_user(lump, lmmk, lmmk_size))
-                       GOTO(out_free, rc = -EFAULT);
+               lmm = lmmk;
+               lmm_size = lmmk_size;
        }
+       /**
+        * User specified limited buffer size, usually the buffer is
+        * from ll_lov_setstripe(), and the buffer can only hold basic
+        * layout template info.
+        */
+       if (size == 0 || size > lmm_size)
+               size = lmm_size;
+       if (copy_to_user(lump, lmm, size))
+               GOTO(out_free, rc = -EFAULT);
 
 out_free:
        OBD_FREE_LARGE(lmmk, lmmk_size);
index 7c7c41f..ddf97fc 100644 (file)
@@ -339,7 +339,7 @@ EXPORT_SYMBOL(cl_object_prune);
  * Get stripe information of this object.
  */
 int cl_object_getstripe(const struct lu_env *env, struct cl_object *obj,
-                       struct lov_user_md __user *uarg)
+                       struct lov_user_md __user *uarg, size_t size)
 {
        struct lu_object_header *top;
        int                     result = 0;
@@ -348,7 +348,8 @@ int cl_object_getstripe(const struct lu_env *env, struct cl_object *obj,
        top = obj->co_lu.lo_header;
        list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) {
                if (obj->co_ops->coo_getstripe != NULL) {
-                       result = obj->co_ops->coo_getstripe(env, obj, uarg);
+                       result = obj->co_ops->coo_getstripe(env, obj, uarg,
+                                                           size);
                        if (result != 0)
                                break;
                }