extern void lustre_swab_ost_last_id(obd_id *id);
extern void lustre_swab_fiemap(struct ll_user_fiemap *fiemap);
-extern void lustre_swab_lov_user_md_v1(struct lov_user_md_v1 *lum);
-extern void lustre_swab_lov_user_md_v3(struct lov_user_md_v3 *lum);
-extern void lustre_swab_lov_user_md_objects(struct lov_user_ost_data *lod,
- int stripe_count);
+extern int lustre_swab_lov_user_md(struct lov_user_md_v1 *lum);
+extern int lustre_swab_lov_user_md_objects(struct lov_user_md *lod);
extern void lustre_swab_lov_user_md_join(struct lov_user_md_join *lumj);
extern void lustre_swab_lov_mds_md(struct lov_mds_md *lmm);
#define LOV_USER_MAGIC_JOIN 0x0BD20BD0
#define LOV_USER_MAGIC_V3 0x0BD30BD0
+#define LOV_USER_MAGIC_V1_SWABBED 0xD00BD10B
+#define LOV_USER_MAGIC_V3_SWABBED 0xD00BD30B
+
#define LOV_PATTERN_RAID0 0x001
#define LOV_PATTERN_RAID1 0x002
#define LOV_PATTERN_FIRST 0x100
struct ptlrpc_request *request = NULL;
struct mdc_op_data op_data;
struct iattr attr = { 0 };
- struct lov_user_md lum, *lump = (struct lov_user_md *)arg;
- int rc = 0;
+ struct lov_user_md_v3 lum;
+ struct lov_user_md *lump = (struct lov_user_md *)arg;
+ int rc = 0, lum_size = 0;
llu_prepare_mdc_op_data(&op_data, ino, NULL, NULL, 0, 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));
+ rc = copy_from_user(&lum, lump, sizeof(*lump));
if (rc)
return(-EFAULT);
-
- switch (lum.lmm_magic) {
- case LOV_USER_MAGIC_V1: {
- if (lum.lmm_magic != cpu_to_le32(LOV_USER_MAGIC_V1))
- lustre_swab_lov_user_md_v1(&lum);
- break;
- }
- case LOV_USER_MAGIC_V3: {
- if (lum.lmm_magic != cpu_to_le32(LOV_USER_MAGIC_V3))
- lustre_swab_lov_user_md_v3((struct lov_user_md_v3 *)&lum);
- break;
- }
- default: {
- CDEBUG(D_IOCTL, "bad userland LOV MAGIC:"
- " %#08x != %#08x nor %#08x\n",
- lum.lmm_magic, LOV_USER_MAGIC_V1,
- LOV_USER_MAGIC_V3);
- RETURN(-EINVAL);
+ lum_size = sizeof(struct lov_user_md_v1);
+ if (lum.lmm_magic == LOV_USER_MAGIC_V3) {
+ rc = copy_from_user(&lum, lump, sizeof(lum));
+ if (rc)
+ return(-EFAULT);
+ lum_size = sizeof(struct lov_user_md_v3);
}
+
+ if ((lum.lmm_magic != cpu_to_le32(LOV_USER_MAGIC_V1)) &&
+ (lum.lmm_magic != cpu_to_le32(LOV_USER_MAGIC_V3))) {
+ rc = lustre_swab_lov_user_md((struct lov_user_md_v1 *)&lum);
+ if (rc)
+ RETURN(rc);
}
/* swabbing is done in lov_setstripe() on server side */
rc = mdc_setattr(sbi->ll_mdc_exp, &op_data,
- &attr, &lum, sizeof(lum), NULL, 0, &request);
+ &attr, &lum, lum_size, NULL, 0, &request);
if (rc) {
ptlrpc_req_finished(request);
if (rc != -EPERM && rc != -EACCES)
struct lustre_sb_info *lsi = s2lsi(inode->i_sb);
struct obd_device *mgc = lsi->lsi_mgc;
char *fsname = NULL, *param = NULL;
- int lum_size;
+ int lum_size = sizeof(struct lov_user_md_v1);
struct iattr attr = { 0 };
int rc = 0;
+ if (lump->lmm_magic == LOV_USER_MAGIC_V3)
+ lum_size = sizeof(struct lov_user_md_v3);
/*
* This is coming from userspace, so should be in
* local endian. But the MDS would like it in little
* endian, so we swab it before we send it.
*/
- 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_V1)) &&
+ (lump->lmm_magic != cpu_to_le32(LOV_USER_MAGIC_V3))) {
+ rc = lustre_swab_lov_user_md(lump);
+ if (rc)
+ return rc;
}
ll_prepare_mdc_op_data(&data, inode, NULL, NULL, 0, 0, NULL);
* passing it to userspace.
*/
/* We don't swab objects for directories */
- switch (le32_to_cpu(lmm->lmm_magic)) {
- case LOV_MAGIC_V1:
- if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC))
- lustre_swab_lov_user_md_v1((struct lov_user_md_v1 *)lmm);
- break;
- case LOV_MAGIC_V3:
- if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC))
- lustre_swab_lov_user_md_v3((struct lov_user_md_v3 *)lmm);
- break;
- default:
- CERROR("unknown magic: %lX\n", (unsigned long)lmm->lmm_magic);
- rc = -EPROTO;
+ if (((le32_to_cpu(lmm->lmm_magic) == LOV_MAGIC_V1) ||
+ (le32_to_cpu(lmm->lmm_magic) == LOV_MAGIC_V3)) &&
+ (LOV_MAGIC != cpu_to_le32(LOV_MAGIC))) {
+ rc = lustre_swab_lov_user_md((struct lov_user_md*)lmm);
+ if (rc)
+ GOTO(out, rc);
}
out:
if (rc)
GOTO(free_lmm, rc = -EFAULT);
- switch (lmm->lmm_magic) {
- case LOV_USER_MAGIC_V1:
- if (LOV_USER_MAGIC == cpu_to_le32(LOV_USER_MAGIC))
- break;
- /* swab objects first so that stripes num will be sane */
- lustre_swab_lov_user_md_objects(
- ((struct lov_user_md_v1 *)lmm)->lmm_objects,
- ((struct lov_user_md_v1 *)lmm)->lmm_stripe_count);
- lustre_swab_lov_user_md_v1((struct lov_user_md_v1 *)lmm);
- break;
- case LOV_USER_MAGIC_V3:
- if (LOV_USER_MAGIC == cpu_to_le32(LOV_USER_MAGIC))
- break;
- /* swab objects first so that stripes num will be sane */
- lustre_swab_lov_user_md_objects(
- ((struct lov_user_md_v3 *)lmm)->lmm_objects,
- ((struct lov_user_md_v3 *)lmm)->lmm_stripe_count);
- lustre_swab_lov_user_md_v3((struct lov_user_md_v3 *)lmm);
- break;
- default:
- GOTO(free_lmm, rc = -EINVAL);
+ if (LOV_USER_MAGIC != cpu_to_le32(LOV_USER_MAGIC)) {
+ rc = lustre_swab_lov_user_md(
+ (struct lov_user_md_v1 *)lmm);
+ if (rc)
+ GOTO(free_lmm, rc);
+ rc = lustre_swab_lov_user_md_objects(
+ (struct lov_user_md*)lmm);
+ if (rc)
+ GOTO(free_lmm, rc);
}
rc = obd_unpackmd(sbi->ll_osc_exp, &lsm, lmm, lmmsize);
if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC)) {
/* if function called for directory - we should
* avoid swab not existent lsm objects */
- if (lmm->lmm_magic == cpu_to_le32(LOV_MAGIC_V1)) {
- lustre_swab_lov_user_md_v1((struct lov_user_md_v1 *)lmm);
+ if ((lmm->lmm_magic == cpu_to_le32(LOV_MAGIC_V1)) ||
+ (lmm->lmm_magic == cpu_to_le32(LOV_MAGIC_V3))) {
+ lustre_swab_lov_user_md((struct lov_user_md*)lmm);
if (S_ISREG(body->mode))
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 (lmm->lmm_magic == cpu_to_le32(LOV_MAGIC_V3)) {
- lustre_swab_lov_user_md_v3((struct lov_user_md_v3 *)lmm);
- if (S_ISREG(body->mode))
- lustre_swab_lov_user_md_objects(
- ((struct lov_user_md_v3 *)lmm)->lmm_objects,
- ((struct lov_user_md_v3 *)lmm)->lmm_stripe_count);
+ (struct lov_user_md*)lmm);
} else if (lmm->lmm_magic == cpu_to_le32(LOV_MAGIC_JOIN)) {
lustre_swab_lov_user_md_join((struct lov_user_md_join *)lmm);
}
struct lov_obd *lov = &obd->u.lov;
struct lov_user_md_v3 lumv3;
struct lov_user_md_v1 *lumv1 = (struct lov_user_md_v1 *)&lumv3;
- int lmm_magic;
int stripe_count;
int rc;
ENTRY;
rc = copy_from_user(&lumv3, lump, sizeof(struct lov_user_md_v1));
if (rc)
RETURN(-EFAULT);
-
- lmm_magic = lumv1->lmm_magic;
-
- if (lmm_magic == __swab32(LOV_USER_MAGIC_V1)) {
- lustre_swab_lov_user_md_v1(lumv1);
- lmm_magic = LOV_USER_MAGIC_V1;
- } else if (lmm_magic == LOV_USER_MAGIC_V3) {
+ if (lumv1->lmm_magic == LOV_USER_MAGIC_V3) {
rc = copy_from_user(&lumv3, lump, sizeof(lumv3));
if (rc)
RETURN(-EFAULT);
- } else if (lmm_magic == __swab32(LOV_USER_MAGIC_V3)) {
- rc = copy_from_user(&lumv3, lump, sizeof(lumv3));
+ }
+
+ if ((lumv1->lmm_magic == LOV_USER_MAGIC_V1_SWABBED) ||
+ (lumv1->lmm_magic == LOV_USER_MAGIC_V3_SWABBED)) {
+ rc = lustre_swab_lov_user_md(lumv1);
if (rc)
- RETURN(-EFAULT);
- lustre_swab_lov_user_md_v3(&lumv3);
- lmm_magic = LOV_USER_MAGIC_V3;
- } else if (lmm_magic != LOV_USER_MAGIC_V1) {
- CDEBUG(D_IOCTL,
- "bad userland LOV MAGIC: %#08x != %#08x nor %#08x\n",
- lmm_magic, LOV_USER_MAGIC_V1, LOV_USER_MAGIC_V3);
- RETURN(-EINVAL);
+ RETURN(rc);
}
/* in the rest of the tests, as *lumv1 and lumv3 have the same
stripe_count = lov_get_stripecnt(lov, lumv1->lmm_stripe_count);
- if (lmm_magic == LOV_USER_MAGIC_V3) {
+ if (lumv1->lmm_magic == LOV_USER_MAGIC_V3) {
struct pool_desc *pool;
pool = lov_find_pool(lov, lumv3.lmm_pool_name);
}
}
- rc = lov_alloc_memmd(lsmp, stripe_count, lumv1->lmm_pattern, lmm_magic);
+ rc = lov_alloc_memmd(lsmp, stripe_count, lumv1->lmm_pattern,
+ lumv1->lmm_magic);
if (rc < 0)
RETURN(rc);
(*lsmp)->lsm_oinfo[0]->loi_ost_idx = lumv1->lmm_stripe_offset;
(*lsmp)->lsm_stripe_size = lumv1->lmm_stripe_size;
- if (lmm_magic == LOV_USER_MAGIC_V3)
+ if (lumv1->lmm_magic == LOV_USER_MAGIC_V3)
strncpy((*lsmp)->lsm_pool_name, lumv3.lmm_pool_name,
LOV_MAXPOOLNAME);
if ((cpu_to_le32(LOV_MAGIC) != LOV_MAGIC) &&
((lmmk->lmm_magic == cpu_to_le32(LOV_MAGIC_V1)) ||
(lmmk->lmm_magic == cpu_to_le32(LOV_MAGIC_V3)))) {
+ lustre_swab_lov_user_md_objects((struct lov_user_md*)lmmk);
lustre_swab_lov_mds_md(lmmk);
- lustre_swab_lov_user_md_objects(
- (struct lov_user_ost_data*)lmmk->lmm_objects,
- lmmk->lmm_stripe_count);
}
if (lum.lmm_magic == LOV_USER_MAGIC) {
/* User request for v1, we need skip lmm_pool_name */
if (lmmk->lmm_magic == LOV_MAGIC_V3) {
- memmove((char*)(&lmmk->lmm_stripe_count) +
- sizeof(lmmk->lmm_stripe_count),
+ memmove(((struct lov_mds_md_v1*)lmmk)->lmm_objects,
((struct lov_mds_md_v3*)lmmk)->lmm_objects,
lmmk->lmm_stripe_count *
sizeof(struct lov_ost_data_v1));
/* we only need the header part from user space to get lmm_magic and
* lmm_stripe_count, (the header part is common to v1 and v3) */
lum_size = sizeof(struct lov_user_md_v1);
+ memset(&lum, 0x00, sizeof(lum));
if (copy_from_user(&lum, lump, lum_size))
RETURN(-EFAULT);
lumk = &lum;
}
- lumk->lmm_object_id = lsm->lsm_object_id;
+ lumk->lmm_magic = lum.lmm_magic;
lumk->lmm_stripe_count = 1;
+ lumk->lmm_object_id = lsm->lsm_object_id;
+
+ if ((lsm->lsm_magic == LOV_USER_MAGIC_V1_SWABBED) ||
+ (lsm->lsm_magic == LOV_USER_MAGIC_V3_SWABBED)) {
+ /* lsm not in host order, so count also need be in same order */
+ __swab32s(&lumk->lmm_magic);
+ __swab16s(&lumk->lmm_stripe_count);
+ lustre_swab_lov_user_md((struct lov_user_md_v1*)lumk);
+ if (lum.lmm_stripe_count > 0)
+ lustre_swab_lov_user_md_objects(
+ (struct lov_user_md_v1*)lumk);
+ }
if (copy_to_user(lump, lumk, lum_size))
rc = -EFAULT;
EXIT;
}
-void lustre_swab_lov_user_md_v1(struct lov_user_md_v1 *lum)
+static void lustre_swab_lov_user_md_v1(struct lov_user_md_v1 *lum)
{
ENTRY;
CDEBUG(D_IOCTL, "swabbing lov_user_md v1\n");
EXIT;
}
-void lustre_swab_lov_user_md_v3(struct lov_user_md_v3 *lum)
+static void lustre_swab_lov_user_md_v3(struct lov_user_md_v3 *lum)
{
ENTRY;
CDEBUG(D_IOCTL, "swabbing lov_user_md v3\n");
EXIT;
}
+int lustre_swab_lov_user_md(struct lov_user_md_v1 *lum)
+{
+ ENTRY;
+ switch (lum->lmm_magic) {
+ case LOV_USER_MAGIC_V1:
+ case LOV_USER_MAGIC_V1_SWABBED:
+ lustre_swab_lov_user_md_v1(lum);
+ break;
+ case LOV_USER_MAGIC_V3:
+ case LOV_USER_MAGIC_V3_SWABBED:
+ lustre_swab_lov_user_md_v3((struct lov_user_md_v3 *)lum);
+ break;
+ default:
+ CDEBUG(D_IOCTL, "bad userland LOV MAGIC:"
+ " %#08x != %#08x nor %#08x\n",
+ lum->lmm_magic, LOV_USER_MAGIC_V1,
+ LOV_USER_MAGIC_V3);
+ RETURN(-EINVAL);
+ }
+ RETURN(0);
+}
+
void lustre_swab_lov_mds_md(struct lov_mds_md *lmm)
{
ENTRY;
EXIT;
}
-void lustre_swab_lov_user_md_objects(struct lov_user_ost_data *lod,
- int stripe_count)
+int lustre_swab_lov_user_md_objects(struct lov_user_md *lum)
{
- int i;
+ int i, stripe_count = lum->lmm_stripe_count;
+ struct lov_user_ost_data *lod;
ENTRY;
+ switch (lum->lmm_magic) {
+ case LOV_USER_MAGIC_V1_SWABBED:
+ __swab32s(&stripe_count);
+ case LOV_USER_MAGIC_V1:
+ lod = lum->lmm_objects;
+ break;
+ case LOV_USER_MAGIC_V3_SWABBED:
+ __swab32s(&stripe_count);
+ case LOV_USER_MAGIC_V3:
+ lod = ((struct lov_user_md_v3 *)lum)->lmm_objects;
+ break;
+ default:
+ CDEBUG(D_IOCTL, "bad userland LOV MAGIC:"
+ " %#08x != %#08x nor %#08x\n",
+ lum->lmm_magic, LOV_USER_MAGIC_V1,
+ LOV_USER_MAGIC_V3);
+ RETURN(-EINVAL);
+ }
for (i = 0; i < stripe_count; i++) {
__swab64s(&(lod[i].l_object_id));
__swab64s(&(lod[i].l_object_gr));
__swab32s(&(lod[i].l_ost_gen));
__swab32s(&(lod[i].l_ost_idx));
}
- EXIT;
+ RETURN(0);
}
void lustre_swab_ldlm_res_id (struct ldlm_res_id *id)
EXPORT_SYMBOL(lustre_swab_mds_rec_unlink);
EXPORT_SYMBOL(lustre_swab_mds_rec_rename);
EXPORT_SYMBOL(lustre_swab_lov_desc);
-EXPORT_SYMBOL(lustre_swab_lov_user_md_v1);
-EXPORT_SYMBOL(lustre_swab_lov_user_md_v3);
+EXPORT_SYMBOL(lustre_swab_lov_user_md);
EXPORT_SYMBOL(lustre_swab_lov_user_md_objects);
EXPORT_SYMBOL(lustre_swab_lov_user_md_join);
EXPORT_SYMBOL(lustre_swab_lov_mds_md);