From: nathan Date: Fri, 22 Aug 2008 17:40:26 +0000 (+0000) Subject: b=15899 X-Git-Tag: v1_7_80~1^70 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=1e8840d82e76c4ee1ff8925b3e25a242df78209e;p=fs%2Flustre-release.git b=15899 i=nathan i=adilger add OST pools --- diff --git a/lustre/llite/dir.c b/lustre/llite/dir.c index 9e5d517..ba54729 100644 --- a/lustre/llite/dir.c +++ b/lustre/llite/dir.c @@ -910,6 +910,7 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump, 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; @@ -919,17 +920,33 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump, * 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) @@ -938,6 +955,9 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump, } 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); @@ -1019,9 +1039,20 @@ int ll_dir_getstripe(struct inode *inode, struct lov_mds_md **lmmp, * 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; @@ -1093,21 +1124,34 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file, 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; } @@ -1224,10 +1268,18 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file, 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);