@@ -86,6 +86,7 @@
void lustre_swab_lov_comp_md_v1(struct lov_comp_md_v1 *lum);
void lustre_swab_lov_user_md_objects(struct lov_user_ost_data *lod,
int stripe_count);
+void lustre_swab_lov_user_md(struct lov_user_md *lum);
void lustre_swab_lov_mds_md(struct lov_mds_md *lmm);
void lustre_swab_lustre_capa(struct lustre_capa *c);
void lustre_swab_lustre_capa_key(struct lustre_capa_key *k);
@@ -525,60 +525,46 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump,
int lum_size;
if (lump) {
- /*
- * 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);
+ case LOV_USER_MAGIC_V1:
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);
+ case LOV_USER_MAGIC_V3:
lum_size = sizeof(struct lov_user_md_v3);
break;
- }
- case LOV_USER_MAGIC_COMP_V1: {
- if (lump->lmm_magic !=
- cpu_to_le32(LOV_USER_MAGIC_COMP_V1))
- lustre_swab_lov_comp_md_v1((struct lov_comp_md_v1 *)lump);
- lum_size = le32_to_cpu(((struct lov_comp_md_v1 *)lump)->lcm_size);
+ case LOV_USER_MAGIC_COMP_V1:
+ lum_size = ((struct lov_comp_md_v1 *)lump)->lcm_size;
break;
- }
- case LMV_USER_MAGIC: {
+ case LMV_USER_MAGIC:
if (lump->lmm_magic != cpu_to_le32(LMV_USER_MAGIC))
lustre_swab_lmv_user_md((struct lmv_user_md *)lump);
lum_size = sizeof(struct lmv_user_md);
break;
- }
case LOV_USER_MAGIC_SPECIFIC: {
struct lov_user_md_v3 *v3 =
- (struct lov_user_md_v3 *)lump;
+ (struct lov_user_md_v3 *)lump;
if (v3->lmm_stripe_count > LOV_MAX_STRIPE_COUNT)
return -EINVAL;
- if (lump->lmm_magic !=
- cpu_to_le32(LOV_USER_MAGIC_SPECIFIC)) {
- lustre_swab_lov_user_md_v3(v3);
- lustre_swab_lov_user_md_objects(v3->lmm_objects,
- v3->lmm_stripe_count);
- }
lum_size = lov_user_md_size(v3->lmm_stripe_count,
LOV_USER_MAGIC_SPECIFIC);
break;
}
- default: {
+ 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;
}
- }
+
+ /*
+ * 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.
+ */
+ if ((__swab32(lump->lmm_magic) & le32_to_cpu(LOV_MAGIC_MASK)) ==
+ le32_to_cpu(LOV_MAGIC_MAGIC))
+ lustre_swab_lov_user_md(lump);
} else {
lum_size = sizeof(struct lov_user_md_v1);
}
@@ -706,16 +692,11 @@ int ll_dir_getstripe(struct inode *inode, void **plmm, int *plmm_size,
/* We don't swab objects for directories */
switch (le32_to_cpu(lmm->lmm_magic)) {
case LOV_MAGIC_V1:
- if (cpu_to_le32(LOV_MAGIC) != LOV_MAGIC)
- lustre_swab_lov_user_md_v1((struct lov_user_md_v1 *)lmm);
- break;
case LOV_MAGIC_V3:
- if (cpu_to_le32(LOV_MAGIC) != LOV_MAGIC)
- lustre_swab_lov_user_md_v3((struct lov_user_md_v3 *)lmm);
- break;
case LOV_MAGIC_COMP_V1:
+ case LOV_USER_MAGIC_SPECIFIC:
if (cpu_to_le32(LOV_MAGIC) != LOV_MAGIC)
- lustre_swab_lov_comp_md_v1((struct lov_comp_md_v1 *)lmm);
+ lustre_swab_lov_user_md((struct lov_user_md *)lmm);
break;
case LMV_MAGIC_V1:
if (cpu_to_le32(LMV_MAGIC) != LMV_MAGIC)
@@ -725,16 +706,6 @@ int ll_dir_getstripe(struct inode *inode, void **plmm, int *plmm_size,
if (cpu_to_le32(LMV_USER_MAGIC) != LMV_USER_MAGIC)
lustre_swab_lmv_user_md((struct lmv_user_md *)lmm);
break;
- case LOV_USER_MAGIC_SPECIFIC: {
- struct lov_user_md_v3 *v3 = (struct lov_user_md_v3 *)lmm;
-
- if (cpu_to_le32(LOV_MAGIC) != LOV_MAGIC) {
- lustre_swab_lov_user_md_v3(v3);
- lustre_swab_lov_user_md_objects(v3->lmm_objects,
- v3->lmm_stripe_count);
- }
- }
- break;
case LMV_MAGIC_FOREIGN: {
struct lmv_foreign_md *lfm = (struct lmv_foreign_md *)lmm;
@@ -1852,6 +1852,12 @@ int ll_lov_setstripe_ea_info(struct inode *inode, struct dentry *dentry,
};
int rc = 0;
+ if ((__swab32(lum->lmm_magic) & le32_to_cpu(LOV_MAGIC_MASK)) ==
+ le32_to_cpu(LOV_MAGIC_MAGIC)) {
+ /* this code will only exist for big-endian systems */
+ lustre_swab_lov_user_md(lum);
+ }
+
ll_inode_size_lock(inode);
rc = ll_intent_file_open(dentry, lum, lum_size, &oit);
if (rc < 0)
@@ -1920,8 +1926,9 @@ int ll_lov_getstripe_ea_info(struct inode *inode, const char *filename,
* little endian. We convert it to host endian before
* passing it to userspace.
*/
- if (cpu_to_le32(LOV_MAGIC) != LOV_MAGIC) {
- int stripe_count;
+ if ((lmm->lmm_magic & __swab32(LOV_MAGIC_MAGIC)) ==
+ __swab32(LOV_MAGIC_MAGIC)) {
+ int stripe_count = 0;
if (lmm->lmm_magic == cpu_to_le32(LOV_MAGIC_V1) ||
lmm->lmm_magic == cpu_to_le32(LOV_MAGIC_V3)) {
@@ -1931,31 +1938,20 @@ int ll_lov_getstripe_ea_info(struct inode *inode, const char *filename,
stripe_count = 0;
}
+ lustre_swab_lov_user_md((struct lov_user_md *)lmm);
+
/* 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 (S_ISREG(body->mbo_mode))
- lustre_swab_lov_user_md_objects(((struct lov_user_md_v1 *)lmm)->lmm_objects,
- 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->mbo_mode))
- lustre_swab_lov_user_md_objects(((struct lov_user_md_v3 *)lmm)->lmm_objects,
- stripe_count);
- } else if (lmm->lmm_magic == cpu_to_le32(LOV_MAGIC_COMP_V1)) {
- lustre_swab_lov_comp_md_v1((struct lov_comp_md_v1 *)lmm);
- } else if (lmm->lmm_magic ==
- cpu_to_le32(LOV_MAGIC_FOREIGN)) {
- struct lov_foreign_md *lfm;
-
- lfm = (struct lov_foreign_md *)lmm;
- __swab32s(&lfm->lfm_magic);
- __swab32s(&lfm->lfm_length);
- __swab32s(&lfm->lfm_type);
- __swab32s(&lfm->lfm_flags);
- }
+ if (lmm->lmm_magic == LOV_MAGIC_V1 && S_ISREG(body->mbo_mode))
+ lustre_swab_lov_user_md_objects(
+ ((struct lov_user_md_v1 *)lmm)->lmm_objects,
+ stripe_count);
+ else if (lmm->lmm_magic == LOV_MAGIC_V3 &&
+ S_ISREG(body->mbo_mode))
+ lustre_swab_lov_user_md_objects(
+ ((struct lov_user_md_v3 *)lmm)->lmm_objects,
+ stripe_count);
}
out:
@@ -2040,7 +2036,7 @@ static int ll_lov_setstripe(struct inode *inode, struct file *file,
cl_lov_delay_create_clear(&file->f_flags);
out:
- kfree(klum);
+ kvfree(klum);
return rc;
}
@@ -2757,14 +2757,14 @@ ssize_t ll_copy_user_md(const struct lov_user_md __user *md,
if (lum_size < 0)
goto no_kbuf;
- *kbuf = kzalloc(lum_size, GFP_NOFS);
+ *kbuf = kvzalloc(lum_size, GFP_NOFS);
if (!*kbuf) {
lum_size = -ENOMEM;
goto no_kbuf;
}
if (copy_from_user(*kbuf, md, lum_size) != 0) {
- kfree(*kbuf);
+ kvfree(*kbuf);
*kbuf = NULL;
lum_size = -EFAULT;
}
@@ -40,6 +40,7 @@
#include <obd_support.h>
#include <lustre_dlm.h>
+#include <lustre_swab.h>
#include "llite_internal.h"
@@ -316,6 +317,11 @@ static int ll_xattr_set(const struct xattr_handler *handler,
return 0;
}
+ if (strncmp(name, "lov.", 4) == 0 &&
+ (__swab32(((struct lov_user_md *)value)->lmm_magic) &
+ le32_to_cpu(LOV_MAGIC_MASK)) == le32_to_cpu(LOV_MAGIC_MAGIC))
+ lustre_swab_lov_user_md((struct lov_user_md *)value);
+
return ll_xattr_set_common(handler, dentry, inode, name, value, size,
flags);
}
@@ -485,10 +491,25 @@ static ssize_t ll_getxattr_lov(struct inode *inode, void *buf, size_t buf_size)
* file is restored. See LU-2809.
*/
magic = ((struct lov_mds_md *)buf)->lmm_magic;
- if (magic == LOV_MAGIC_COMP_V1 || magic == LOV_MAGIC_FOREIGN)
+ if ((magic & __swab32(LOV_MAGIC_MAGIC)) ==
+ __swab32(LOV_MAGIC_MAGIC))
+ magic = __swab32(magic);
+
+ switch (magic) {
+ case LOV_MAGIC_V1:
+ case LOV_MAGIC_V3:
+ case LOV_MAGIC_SPECIFIC:
+ ((struct lov_mds_md *)buf)->lmm_layout_gen = 0;
+ break;
+ case LOV_MAGIC_COMP_V1:
+ case LOV_MAGIC_FOREIGN:
+ goto out_env;
+ default:
+ CERROR("Invalid LOV magic %08x\n", magic);
+ rc = -EINVAL;
goto out_env;
+ }
- ((struct lov_mds_md *)buf)->lmm_layout_gen = 0;
out_env:
cl_env_put(env, &refcheck);
@@ -2004,6 +2004,8 @@ void lustre_swab_lmv_user_md(struct lmv_user_md *lum)
if (lum->lum_magic == LMV_MAGIC_FOREIGN) {
__swab32s(&lum->lum_magic);
__swab32s(&((struct lmv_foreign_md *)lum)->lfm_length);
+ __swab32s(&((struct lmv_foreign_md *)lum)->lfm_type);
+ __swab32s(&((struct lmv_foreign_md *)lum)->lfm_flags);
return;
}
@@ -2132,18 +2134,6 @@ void lustre_swab_lov_comp_md_v1(struct lov_comp_md_v1 *lum)
}
EXPORT_SYMBOL(lustre_swab_lov_comp_md_v1);
-void lustre_swab_lov_mds_md(struct lov_mds_md *lmm)
-{
- CDEBUG(D_IOCTL, "swabbing lov_mds_md\n");
- __swab32s(&lmm->lmm_magic);
- __swab32s(&lmm->lmm_pattern);
- lustre_swab_lmm_oi(&lmm->lmm_oi);
- __swab32s(&lmm->lmm_stripe_size);
- __swab16s(&lmm->lmm_stripe_count);
- __swab16s(&lmm->lmm_layout_gen);
-}
-EXPORT_SYMBOL(lustre_swab_lov_mds_md);
-
void lustre_swab_lov_user_md_objects(struct lov_user_ost_data *lod,
int stripe_count)
{
@@ -2157,9 +2147,67 @@ void lustre_swab_lov_user_md_objects(struct lov_user_ost_data *lod,
}
EXPORT_SYMBOL(lustre_swab_lov_user_md_objects);
+void lustre_swab_lov_user_md(struct lov_user_md *lum)
+{
+ CDEBUG(D_IOCTL, "swabbing lov_user_md\n");
+ switch (lum->lmm_magic) {
+ case __swab32(LOV_MAGIC_V1):
+ case LOV_USER_MAGIC_V1:
+ lustre_swab_lov_user_md_v1((struct lov_user_md_v1 *)lum);
+ break;
+ case __swab32(LOV_MAGIC_V3):
+ case LOV_USER_MAGIC_V3:
+ lustre_swab_lov_user_md_v3((struct lov_user_md_v3 *)lum);
+ break;
+ case __swab32(LOV_USER_MAGIC_SPECIFIC):
+ case LOV_USER_MAGIC_SPECIFIC:
+ {
+ struct lov_user_md_v3 *v3 = (struct lov_user_md_v3 *)lum;
+ u16 stripe_count = v3->lmm_stripe_count;
+
+ if (lum->lmm_magic != LOV_USER_MAGIC_SPECIFIC)
+ __swab16s(&stripe_count);
+
+ lustre_swab_lov_user_md_v3(v3);
+ lustre_swab_lov_user_md_objects(v3->lmm_objects, stripe_count);
+ break;
+ }
+ case __swab32(LOV_MAGIC_COMP_V1):
+ case LOV_USER_MAGIC_COMP_V1:
+ lustre_swab_lov_comp_md_v1((struct lov_comp_md_v1 *)lum);
+ break;
+ case __swab32(LOV_MAGIC_FOREIGN):
+ case LOV_USER_MAGIC_FOREIGN:
+ {
+ struct lov_foreign_md *lfm = (struct lov_foreign_md *)lum;
+
+ __swab32s(&lfm->lfm_magic);
+ __swab32s(&lfm->lfm_length);
+ __swab32s(&lfm->lfm_type);
+ __swab32s(&lfm->lfm_flags);
+ break;
+ }
+ default:
+ CDEBUG(D_IOCTL, "Invalid LOV magic %08x\n", lum->lmm_magic);
+ }
+}
+EXPORT_SYMBOL(lustre_swab_lov_user_md);
+
+void lustre_swab_lov_mds_md(struct lov_mds_md *lmm)
+{
+ CDEBUG(D_IOCTL, "swabbing lov_mds_md\n");
+ __swab32s(&lmm->lmm_magic);
+ __swab32s(&lmm->lmm_pattern);
+ lustre_swab_lmm_oi(&lmm->lmm_oi);
+ __swab32s(&lmm->lmm_stripe_size);
+ __swab16s(&lmm->lmm_stripe_count);
+ __swab16s(&lmm->lmm_layout_gen);
+}
+EXPORT_SYMBOL(lustre_swab_lov_mds_md);
+
static void lustre_swab_ldlm_res_id(struct ldlm_res_id *id)
{
- int i;
+ int i;
for (i = 0; i < RES_NAME_SIZE; i++)
__swab64s(&id->name[i]);