struct lustre_sb_info *lsi = s2lsi(inode->i_sb);
struct obd_device *mgc = lsi->lsi_mgc;
char *fsname = NULL, *param = NULL;
+ int lum_size;
struct iattr attr = { 0 };
int rc = 0;
* local endian. But the MDS would like it in little
* endian, so we swab it before we send it.
*/
- if (lump->lmm_magic != LOV_USER_MAGIC)
+ switch (lump->lmm_magic) {
+ case LOV_USER_MAGIC_V1: {
+ if (lump->lmm_magic != cpu_to_le32(LOV_USER_MAGIC_V1))
+ lustre_swab_lov_user_md_v1(lump);
+ lum_size = sizeof(struct lov_user_md_v1);
+ break;
+ }
+ case LOV_USER_MAGIC_V3: {
+ if (lump->lmm_magic != cpu_to_le32(LOV_USER_MAGIC_V3))
+ lustre_swab_lov_user_md_v3((struct lov_user_md_v3 *)lump);
+ lum_size = sizeof(struct lov_user_md_v3);
+ break;
+ }
+ default: {
+ CDEBUG(D_IOCTL, "bad userland LOV MAGIC:"
+ " %#08x != %#08x nor %#08x\n",
+ lump->lmm_magic, LOV_USER_MAGIC_V1,
+ LOV_USER_MAGIC_V3);
RETURN(-EINVAL);
-
- if (lump->lmm_magic != cpu_to_le32(LOV_USER_MAGIC))
- lustre_swab_lov_user_md(lump);
+ }
+ }
ll_prepare_mdc_op_data(&data, inode, NULL, NULL, 0, 0, NULL);
/* swabbing is done in lov_setstripe() on server side */
rc = mdc_setattr(sbi->ll_mdc_exp, &data,
- &attr, lump, sizeof(*lump), NULL, 0, &req);
+ &attr, lump, lum_size, NULL, 0, &req);
if (rc) {
ptlrpc_req_finished(req);
if (rc != -EPERM && rc != -EACCES)
}
ptlrpc_req_finished(req);
+ /* In the following we use the fact that LOV_USER_MAGIC_V1 and
+ LOV_USER_MAGIC_V3 have the same initial fields so we do not
+ need the make the distiction between the 2 versions */
if (set_default && mgc->u.cli.cl_mgc_mgsexp) {
OBD_ALLOC(param, MGS_PARAM_MAXLEN);
* little endian. We convert it to host endian before
* passing it to userspace.
*/
- if ((LOV_MAGIC != cpu_to_le32(LOV_MAGIC)) &&
- (cpu_to_le32(LOV_MAGIC) == lmm->lmm_magic))
- lustre_swab_lov_user_md((struct lov_user_md *)lmm);
+ if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC)) {
+ if (cpu_to_le32(LOV_MAGIC_V1) == lmm->lmm_magic) {
+ lustre_swab_lov_user_md_v1((struct lov_user_md_v1 *)lmm);
+ lustre_swab_lov_user_md_objects(
+ ((struct lov_user_md_v1 *)lmm)->lmm_objects,
+ ((struct lov_user_md_v1 *)lmm)->lmm_stripe_count);
+ } else if (cpu_to_le32(LOV_MAGIC_V3) == lmm->lmm_magic) {
+ lustre_swab_lov_user_md_v3((struct lov_user_md_v3 *)lmm);
+ lustre_swab_lov_user_md_objects(
+ ((struct lov_user_md_v3 *)lmm)->lmm_objects,
+ ((struct lov_user_md_v3 *)lmm)->lmm_stripe_count);
+ }
+ }
+
out:
*lmmp = lmm;
*lmm_size = lmmsize;
return rc;
}
case LL_IOC_LOV_SETSTRIPE: {
- struct lov_user_md lum, *lump = (struct lov_user_md *)arg;
+ struct lov_user_md_v3 lumv3;
+ struct lov_user_md_v1 *lumv1 = (struct lov_user_md_v1 *)&lumv3;
+ struct lov_user_md_v1 *lumv1p = (struct lov_user_md_v1 *)arg;
+ struct lov_user_md_v3 *lumv3p = (struct lov_user_md_v3 *)arg;
+
int rc = 0;
int set_default = 0;
- LASSERT(sizeof(lum) == sizeof(*lump));
- LASSERT(sizeof(lum.lmm_objects[0]) ==
- sizeof(lump->lmm_objects[0]));
- rc = copy_from_user(&lum, lump, sizeof(lum));
+ LASSERT(sizeof(lumv3) == sizeof(*lumv3p));
+ LASSERT(sizeof(lumv3.lmm_objects[0]) ==
+ sizeof(lumv3p->lmm_objects[0]));
+
+ /* first try with v1 which is smaller than v3 */
+ rc = copy_from_user(lumv1, lumv1p, sizeof(*lumv1));
if (rc)
return(-EFAULT);
+ if (lumv1->lmm_magic == LOV_USER_MAGIC_V3) {
+ rc = copy_from_user(&lumv3, lumv3p, sizeof(lumv3));
+ if (rc)
+ RETURN(-EFAULT);
+ }
+
if (inode->i_sb->s_root == file->f_dentry)
set_default = 1;
- rc = ll_dir_setstripe(inode, &lum, set_default);
+ /* in v1 and v3 cases lumv1 points to data */
+ rc = ll_dir_setstripe(inode, lumv1, set_default);
return rc;
}
if (lmm->lmm_magic != LOV_USER_MAGIC)
GOTO(free_lmm, rc = -EINVAL);
- if (LOV_USER_MAGIC != cpu_to_le32(LOV_USER_MAGIC) &&
- cpu_to_le32(LOV_USER_MAGIC) == cpu_to_le32(lmm->lmm_magic)) {
- lustre_swab_lov_user_md_objects((struct lov_user_md *)lmm);
- lustre_swab_lov_user_md((struct lov_user_md *)lmm);
+ if (LOV_USER_MAGIC != cpu_to_le32(LOV_USER_MAGIC)) {
+ if (cpu_to_le32(LOV_USER_MAGIC_V1) == cpu_to_le32(lmm->lmm_magic)) {
+ lustre_swab_lov_user_md_v1((struct lov_user_md_v1 *)lmm);
+ lustre_swab_lov_user_md_objects(
+ ((struct lov_user_md_v1 *)lmm)->lmm_objects,
+ ((struct lov_user_md_v1 *)lmm)->lmm_stripe_count);
+ } else if (cpu_to_le32(LOV_USER_MAGIC_V3) == cpu_to_le32(lmm->lmm_magic)) {
+ lustre_swab_lov_user_md_v3((struct lov_user_md_v3 *)lmm);
+ lustre_swab_lov_user_md_objects(
+ ((struct lov_user_md_v3 *)lmm)->lmm_objects,
+ ((struct lov_user_md_v3 *)lmm)->lmm_stripe_count);
+ }
}
rc = obd_unpackmd(sbi->ll_osc_exp, &lsm, lmm, lmmsize);