Whamcloud - gitweb
b=19669
authornathan <nathan>
Thu, 5 Nov 2009 23:33:58 +0000 (23:33 +0000)
committernathan <nathan>
Thu, 5 Nov 2009 23:33:58 +0000 (23:33 +0000)
i=adilger
i=vitaly
- get and set LMA in mdd layer
- change LMA endianness and handle swabbing

lustre/include/lustre/lustre_idl.h
lustre/include/lustre/lustre_user.h
lustre/include/md_object.h
lustre/mdd/mdd_object.c
lustre/osd/osd_handler.c
lustre/utils/liblustreapi.c

index 7f76ca0..5344ad3 100644 (file)
@@ -294,6 +294,45 @@ struct lustre_mdt_attrs {
 };
 
 /**
+ * Fill \a lma with its first content.
+ * Only fid is stored.
+ */
+static inline void lustre_lma_init(struct lustre_mdt_attrs *lma,
+                                   const struct lu_fid *fid)
+{
+        lma->lma_compat      = 0;
+        lma->lma_incompat    = 0;
+        memcpy(&lma->lma_self_fid, fid, sizeof(*fid));
+        lma->lma_flags       = 0;
+        lma->lma_som_sectors = 0;
+
+        /* If a field is added in struct lustre_mdt_attrs, zero it explicitly
+         * and change the test below. */
+        LASSERT(sizeof(*lma) ==
+                (offsetof(struct lustre_mdt_attrs, lma_som_sectors) +
+                 sizeof(lma->lma_som_sectors)));
+};
+
+extern void lustre_swab_lu_fid(struct lu_fid *fid);
+
+/**
+ * Swab, if needed, lustre_mdt_attr struct to on-disk format.
+ * Otherwise, do not touch it.
+ */
+static inline void lustre_lma_swab(struct lustre_mdt_attrs *lma)
+{
+        /* Use LUSTRE_MSG_MAGIC to detect local endianess. */
+        if (LUSTRE_MSG_MAGIC != cpu_to_le32(LUSTRE_MSG_MAGIC)) {
+                __swab32s(&lma->lma_compat);
+                __swab32s(&lma->lma_incompat);
+                lustre_swab_lu_fid(&lma->lma_self_fid);
+                __swab64s(&lma->lma_flags);
+                __swab64s(&lma->lma_som_sectors);
+        }
+};
+
+
+/**
  * fid constants
  */
 enum {
index 0777e2a..4f3695b 100644 (file)
@@ -522,6 +522,11 @@ enum changelog_message_type {
 
 
 /********* HSM **********/
+
+
+#define HSM_FLAGS_MASK  0
+
+
 enum hsm_message_type {
         HMT_ACTION_LIST = 100, /* message is a hsm_action_list */
 };
index bfa7de4..0e3dd26 100644 (file)
@@ -123,7 +123,10 @@ enum ma_valid {
         MA_FLAGS     = (1 << 3),
         MA_LMV       = (1 << 4),
         MA_ACL_DEF   = (1 << 5),
-        MA_LOV_DEF   = (1 << 6)
+        MA_LOV_DEF   = (1 << 6),
+/* (Layout lock will used #7 here) */
+        MA_HSM       = (1 << 8),
+        MA_SOM       = (1 << 9)
 };
 
 typedef enum {
@@ -144,6 +147,11 @@ typedef enum {
         MDT_PDO_LOCK = (1 << 1)
 } mdl_type_t;
 
+struct md_hsm {
+        __u32  mh_flags;
+};
+#define ma_hsm_flags ma_hsm.mh_flags
+
 struct md_attr {
         __u64                   ma_valid;
         __u64                   ma_need;
@@ -158,6 +166,8 @@ struct md_attr {
         struct llog_cookie     *ma_cookie;
         int                     ma_cookie_size;
         struct lustre_capa     *ma_capa;
+        struct md_hsm           ma_hsm;
+/* XXX:  struct md_som_data   *ma_som; */
 };
 
 /** Additional parameters for create */
index 55b9f7b..ddb26db 100644 (file)
@@ -685,6 +685,55 @@ static int __mdd_lmv_get(const struct lu_env *env,
         RETURN(rc);
 }
 
+static int __mdd_lma_get(const struct lu_env *env, struct mdd_object *mdd_obj,
+                         struct md_attr *ma)
+{
+        struct mdd_thread_info *info = mdd_env_info(env);
+        struct lustre_mdt_attrs *lma =
+                                 (struct lustre_mdt_attrs *)info->mti_xattr_buf;
+        int lma_size;
+        int rc;
+        ENTRY;
+
+        /* If all needed data are already valid, nothing to do */
+        if ((ma->ma_valid & (MA_HSM | MA_SOM)) ==
+            (ma->ma_need & (MA_HSM | MA_SOM)))
+                RETURN(0);
+
+        /* Read LMA from disk EA */
+        lma_size = sizeof(info->mti_xattr_buf);
+        rc = mdd_get_md(env, mdd_obj, lma, &lma_size, XATTR_NAME_LMA);
+        if (rc <= 0)
+                RETURN(rc);
+
+        /* Useless to check LMA incompatibility because this is already done in
+         * osd_ea_fid_get(), and this will fail long before this code is
+         * called.
+         * So, if we are here, LMA is compatible.
+         */
+
+        lustre_lma_swab(lma);
+
+        /* Swab and copy LMA */
+        if (ma->ma_need & MA_HSM) {
+                if (lma->lma_compat & LMAC_HSM)
+                        ma->ma_hsm_flags = lma->lma_flags & HSM_FLAGS_MASK;
+                else
+                        ma->ma_hsm_flags = 0;
+                ma->ma_valid |= MA_HSM;
+        }
+        if (ma->ma_need & MA_SOM) {
+
+                /* XXX: Here, copy and swab SoM data, and then remove this
+                 * assert. */
+                LASSERT(!(ma->ma_need & MA_SOM));
+
+                ma->ma_valid |= MA_SOM;
+        }
+
+        RETURN(0);
+}
+
 static int mdd_attr_get_internal(const struct lu_env *env,
                                  struct mdd_object *mdd_obj,
                                  struct md_attr *ma)
@@ -704,6 +753,10 @@ static int mdd_attr_get_internal(const struct lu_env *env,
                 if (S_ISDIR(mdd_object_type(mdd_obj)))
                         rc = __mdd_lmv_get(env, mdd_obj, ma);
         }
+        if (rc == 0 && ma->ma_need & (MA_HSM | MA_SOM)) {
+                if (S_ISREG(mdd_object_type(mdd_obj)))
+                        rc = __mdd_lma_get(env, mdd_obj, ma);
+        }
 #ifdef CONFIG_FS_POSIX_ACL
         if (rc == 0 && ma->ma_need & MA_ACL_DEF) {
                 if (S_ISDIR(mdd_object_type(mdd_obj)))
@@ -719,7 +772,8 @@ int mdd_attr_get_internal_locked(const struct lu_env *env,
                                  struct mdd_object *mdd_obj, struct md_attr *ma)
 {
         int rc;
-        int needlock = ma->ma_need & (MA_LOV | MA_LMV | MA_ACL_DEF);
+        int needlock = ma->ma_need &
+                       (MA_LOV | MA_LMV | MA_ACL_DEF | MA_HSM | MA_SOM);
 
         if (needlock)
                 mdd_read_lock(env, mdd_obj, MOR_TGT_CHILD);
@@ -1216,6 +1270,76 @@ static int mdd_changelog_data_store(const struct lu_env     *env,
         return 0;
 }
 
+/**
+ * Should be called with write lock held.
+ *
+ * \see mdd_lma_set_locked().
+ */
+static int __mdd_lma_set(const struct lu_env *env, struct mdd_object *mdd_obj,
+                       const struct md_attr *ma, struct thandle *handle)
+{
+        struct mdd_thread_info *info = mdd_env_info(env);
+        struct lu_buf *buf;
+        struct lustre_mdt_attrs *lma =
+                                (struct lustre_mdt_attrs *) info->mti_xattr_buf;
+        int lmasize = sizeof(struct lustre_mdt_attrs);
+        int rc = 0;
+
+        ENTRY;
+
+        memset(lma, 0, lmasize);
+
+        /* Either HSM or SOM part is not valid, we need to read it before */
+        if ((!ma->ma_valid) & (MA_HSM | MA_SOM)) {
+                rc = mdd_get_md(env, mdd_obj, lma, &lmasize, XATTR_NAME_LMA);
+                if (rc)
+                        RETURN(rc);
+
+                lustre_lma_swab(lma);
+        }
+
+        /* Copy HSM data */
+        if (ma->ma_valid & MA_HSM) {
+                lma->lma_flags  |= ma->ma_hsm_flags & HSM_FLAGS_MASK;
+                lma->lma_compat |= LMAC_HSM;
+        }
+        /* XXX: Copy SOM data */
+        if (ma->ma_valid & MA_SOM) {
+                /*
+                lma->lma_compat |= LMAC_SOM;
+                */
+                LASSERT(!(ma->ma_valid & MA_SOM));
+        }
+
+        /* Copy FID */
+        memcpy(&lma->lma_self_fid, mdo2fid(mdd_obj), sizeof(lma->lma_self_fid));
+
+        lustre_lma_swab(lma);
+        buf = mdd_buf_get(env, lma, lmasize);
+        rc = __mdd_xattr_set(env, mdd_obj, buf, XATTR_NAME_LMA, 0, handle);
+
+        RETURN(rc);
+}
+
+/**
+ * Save LMA extended attributes with data from \a ma.
+ *
+ * HSM and Size-On-MDS data will be extracted from \ma if they are valid, if
+ * not, LMA EA will be first read from disk, modified and write back.
+ *
+ */
+static int mdd_lma_set_locked(const struct lu_env *env,
+                              struct mdd_object *mdd_obj,
+                              const struct md_attr *ma, struct thandle *handle)
+{
+        int rc;
+
+        mdd_write_lock(env, mdd_obj, MOR_TGT_CHILD);
+        rc = __mdd_lma_set(env, mdd_obj, ma, handle);
+        mdd_write_unlock(env, mdd_obj);
+        return rc;
+}
+
 /* set attr and LOV EA at once, return updated attr */
 static int mdd_attr_set(const struct lu_env *env, struct md_object *obj,
                         const struct md_attr *ma)
@@ -1331,6 +1455,14 @@ static int mdd_attr_set(const struct lu_env *env, struct md_object *obj,
                 }
 
         }
+        if (rc == 0 && ma->ma_valid & (MA_HSM | MA_SOM)) {
+                umode_t mode;
+
+                mode = mdd_object_type(mdd_obj);
+                if (S_ISREG(mode))
+                        rc = mdd_lma_set_locked(env, mdd_obj, ma, handle);
+
+        }
 cleanup:
         if ((rc == 0) && (ma->ma_attr.la_valid & (LA_MTIME | LA_CTIME)))
                 rc = mdd_changelog_data_store(env, mdd, CL_SETATTR, mdd_obj,
index 40901dd..cb3c654 100644 (file)
@@ -1710,8 +1710,8 @@ static int osd_ea_fid_set(const struct lu_env *env, struct dt_object *dt,
         struct osd_thread_info  *info      = osd_oti_get(env);
         struct lustre_mdt_attrs *mdt_attrs = &info->oti_mdt_attrs;
 
-        fid_cpu_to_be(&mdt_attrs->lma_self_fid, fid);
-
+        lustre_lma_init(mdt_attrs, fid);
+        lustre_lma_swab(mdt_attrs);
         return __osd_xattr_set(env, dt,
                                osd_buf_get(env, mdt_attrs, sizeof *mdt_attrs),
                                XATTR_NAME_LMA, LU_XATTR_CREATE);
@@ -1794,15 +1794,16 @@ static int osd_ea_fid_get(const struct lu_env *env, struct osd_object *obj,
 
         /* Check LMA compatibility */
         if (rc > 0 &&
-            (mdt_attrs->lma_incompat & ~cpu_to_be32(LMA_INCOMPAT_SUPP))) {
+            (mdt_attrs->lma_incompat & ~cpu_to_le32(LMA_INCOMPAT_SUPP))) {
                 CWARN("Inode %lx: Unsupported incompat LMA feature(s) %#x\n",
-                      inode->i_ino, be32_to_cpu(mdt_attrs->lma_incompat) &
+                      inode->i_ino, le32_to_cpu(mdt_attrs->lma_incompat) &
                       ~LMA_INCOMPAT_SUPP);
                 return -ENOSYS;
         }
 
         if (rc > 0) {
-                fid_be_to_cpu(fid, &mdt_attrs->lma_self_fid);
+                lustre_lma_swab(mdt_attrs);
+                memcpy(fid, &mdt_attrs->lma_self_fid, sizeof(*mdt_attrs));
                 rc = 0;
         } else if (rc == -ENODATA) {
                 osd_igif_get(env, inode, fid);
index 33a9f46..d0c3144 100644 (file)
@@ -2873,7 +2873,7 @@ static int path2fid_from_lma(const char *path, lustre_fid *fid)
         if (rc < 0)
                 return -errno;
         lma = (struct lustre_mdt_attrs *)buf;
-        fid_be_to_cpu(fid, &lma->lma_self_fid);
+        fid_le_to_cpu(fid, &lma->lma_self_fid);
         return 0;
 }