* 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.
*/
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);
#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 */
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;
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;
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;
}
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;
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,
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;
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;
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);
}
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)
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));
/* 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 */
}
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;
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);
}
* @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;
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);
* 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;
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;
}