From 364ec95f3688ac5cc3195f7f46d0d860844796f9 Mon Sep 17 00:00:00 2001 From: Bobi Jam Date: Tue, 2 May 2017 20:30:27 +0800 Subject: [PATCH] LU-9367 llite: restore ll_file_getstripe in ll_lov_setstripe 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 Change-Id: Ic2f541fa3c74133eb40d230c8a836434043d7691 Reviewed-on: https://review.whamcloud.com/26915 Reviewed-by: Andreas Dilger Tested-by: Jenkins Reviewed-by: Jinshan Xiong Tested-by: Maloo --- lustre/include/cl_object.h | 4 ++-- lustre/include/lustre/lustre_user.h | 2 ++ lustre/llite/dir.c | 17 ++++++++------- lustre/llite/file.c | 41 +++++++++++++++++++++++++------------ lustre/lov/lov_cl_internal.h | 3 ++- lustre/lov/lov_object.c | 4 ++-- lustre/lov/lov_pack.c | 26 +++++++++++++++++------ lustre/obdclass/cl_object.c | 5 +++-- 8 files changed, 69 insertions(+), 33 deletions(-) diff --git a/lustre/include/cl_object.h b/lustre/include/cl_object.h index ca9b520..78d0926 100644 --- a/lustre/include/cl_object.h +++ b/lustre/include/cl_object.h @@ -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); diff --git a/lustre/include/lustre/lustre_user.h b/lustre/include/lustre/lustre_user.h index 5db4dc1..1303143 100644 --- a/lustre/include/lustre/lustre_user.h +++ b/lustre/include/lustre/lustre_user.h @@ -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 */ diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index b7508cd..45dd02e 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -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; diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 09bc0bf..d6591f5 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -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)); diff --git a/lustre/lov/lov_cl_internal.h b/lustre/lov/lov_cl_internal.h index e16a6aa..ca40cc8 100644 --- a/lustre/lov/lov_cl_internal.h +++ b/lustre/lov/lov_cl_internal.h @@ -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 */ diff --git a/lustre/lov/lov_object.c b/lustre/lov/lov_object.c index 614ca03..e26769c 100644 --- a/lustre/lov/lov_object.c +++ b/lustre/lov/lov_object.c @@ -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); } diff --git a/lustre/lov/lov_pack.c b/lustre/lov/lov_pack.c index baff061..bdcf146 100644 --- a/lustre/lov/lov_pack.c +++ b/lustre/lov/lov_pack.c @@ -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); diff --git a/lustre/obdclass/cl_object.c b/lustre/obdclass/cl_object.c index 7c7c41f..ddf97fc 100644 --- a/lustre/obdclass/cl_object.c +++ b/lustre/obdclass/cl_object.c @@ -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; } -- 1.8.3.1