Whamcloud - gitweb
b=15899
authornathan <nathan>
Fri, 22 Aug 2008 17:40:26 +0000 (17:40 +0000)
committernathan <nathan>
Fri, 22 Aug 2008 17:40:26 +0000 (17:40 +0000)
i=nathan
i=adilger
add OST pools

lustre/llite/dir.c

index 9e5d517..ba54729 100644 (file)
@@ -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);