Whamcloud - gitweb
LU-2378 lma: move HSM & SOM attributes to dedicated xattrs
authorJohann Lombardi <johann.lombardi@intel.com>
Fri, 23 Nov 2012 14:23:29 +0000 (15:23 +0100)
committerOleg Drokin <green@whamcloud.com>
Mon, 17 Dec 2012 03:13:15 +0000 (22:13 -0500)
Reduce LMA to its minimum and move HSM & SOM attributes to dedicated
on-disk extented attributes. This is more consistent with the MDS
layering (HSM, LMA & SOM are managed in different layers) and avoids
locking + read/modify/write in many cases.

As far as interoperability is concerned, the old code works just fine
if it reads a smaller LMA size and the new code retries with a
larger buffer on ERANGE error.

Signed-off-by: Johann Lombardi <johann.lombardi@intel.com>
Change-Id: Id4ee465ea69820229f7214d800821864330a8aec
Reviewed-on: http://review.whamcloud.com/4746
Reviewed-by: Aurelien Degremont <aurelien.degremont@cea.fr>
Tested-by: Hudson
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Alex Zhuravlev <bzzz@whamcloud.com>
Tested-by: Maloo <whamcloud.maloo@gmail.com>
13 files changed:
lustre/include/lustre/lustre_idl.h
lustre/include/md_object.h
lustre/mdt/Makefile.in
lustre/mdt/mdt_handler.c
lustre/mdt/mdt_hsm.c [new file with mode: 0644]
lustre/mdt/mdt_open.c
lustre/obdclass/Makefile.in
lustre/obdclass/md_attrs.c [new file with mode: 0644]
lustre/osd-ldiskfs/osd_handler.c
lustre/osd-ldiskfs/osd_internal.h
lustre/ptlrpc/wiretest.c
lustre/utils/wirecheck.c
lustre/utils/wiretest.c

index 2340e58..c658f8c 100644 (file)
@@ -265,6 +265,8 @@ static inline int range_compare_loc(const struct lu_seq_range *r1,
 
 /**
  * Flags for lustre_mdt_attrs::lma_compat and lustre_mdt_attrs::lma_incompat.
+ * Deprecated since HSM and SOM attributes are now stored in separate on-disk
+ * xattr.
  */
 enum lma_compat {
         LMAC_HSM = 0x00000001,
@@ -275,9 +277,10 @@ enum lma_compat {
  * Masks for all features that should be supported by a Lustre version to
  * access a specific file.
  * This information is stored in lustre_mdt_attrs::lma_incompat.
- *
- * NOTE: No incompat feature should be added before bug #17670 is landed.
  */
+enum lma_incompat {
+       LMAI_RELEASED = 0x0000001, /* file is released */
+};
 #define LMA_INCOMPAT_SUPP 0x0
 
 /**
@@ -300,59 +303,56 @@ struct lustre_mdt_attrs {
         struct lu_fid  lma_self_fid;
         /** mdt/ost type, others */
         __u64   lma_flags;
-        /* IO Epoch SOM attributes belongs to */
-        __u64   lma_ioepoch;
-        /** total file size in objects */
-        __u64   lma_som_size;
-        /** total fs blocks in objects */
-        __u64   lma_som_blocks;
-        /** mds mount id the size is valid for */
-        __u64   lma_som_mountid;
 };
 
 /**
- * Fill \a lma with its first content.
- * Only fid is stored.
+ * Prior to 2.4, the LMA structure also included SOM attributes which has since
+ * been moved to a dedicated xattr
  */
-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_ioepoch     = 0;
-        lma->lma_som_size    = 0;
-        lma->lma_som_blocks  = 0;
-        lma->lma_som_mountid = 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_mountid) +
-                 sizeof(lma->lma_som_mountid)));
+#define LMA_OLD_SIZE (sizeof(struct lustre_mdt_attrs) + 4 * sizeof(__u64))
+
+extern void lustre_lma_swab(struct lustre_mdt_attrs *lma);
+extern void lustre_lma_init(struct lustre_mdt_attrs *lma,
+                           const struct lu_fid *fid);
+/**
+ * SOM on-disk attributes stored in a separate xattr.
+ */
+struct som_attrs {
+       /** Bitfield for supported data in this structure. For future use. */
+       __u32   som_compat;
+
+       /** Incompat feature list. The supported feature mask is availabe in
+        * SOM_INCOMPAT_SUPP */
+       __u32   som_incompat;
+
+       /** IO Epoch SOM attributes belongs to */
+       __u64   som_ioepoch;
+       /** total file size in objects */
+       __u64   som_size;
+       /** total fs blocks in objects */
+       __u64   som_blocks;
+       /** mds mount id the size is valid for */
+       __u64   som_mountid;
 };
+extern void lustre_som_swab(struct som_attrs *attrs);
 
-extern void lustre_swab_lu_fid(struct lu_fid *fid);
+#define SOM_INCOMPAT_SUPP 0x0
 
 /**
- * Swab, if needed, lustre_mdt_attr struct to on-disk format.
- * Otherwise, do not touch it.
+ * HSM on-disk attributes stored in a separate xattr.
  */
-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_ioepoch);
-                __swab64s(&lma->lma_som_size);
-                __swab64s(&lma->lma_som_blocks);
-                __swab64s(&lma->lma_som_mountid);
-        }
+struct hsm_attrs {
+       /** Bitfield for supported data in this structure. For future use. */
+       __u32   hsm_compat;
+
+       /** HSM flags, see hsm_flags enum below */
+       __u32   hsm_flags;
+       /** backend archive id associated with the file */
+       __u64   hsm_arch_id;
+       /** version associated with the last archiving, if any */
+       __u64   hsm_arch_ver;
 };
+extern void lustre_hsm_swab(struct hsm_attrs *attrs);
 
 /* This is the maximum number of MDTs allowed in CMD testing until such
  * a time that FID-on-OST is implemented.  This is due to the limitations
@@ -1451,6 +1451,8 @@ struct lov_mds_md_v1 {            /* LOV EA mds/wire data (little-endian) */
 #define XATTR_NAME_LINK         "trusted.link"
 #define XATTR_NAME_FID          "trusted.fid"
 #define XATTR_NAME_VERSION      "trusted.version"
+#define XATTR_NAME_SOM         "trusted.som"
+#define XATTR_NAME_HSM         "trusted.hsm"
 
 
 struct lov_mds_md_v3 {            /* LOV EA mds/wire data (little-endian) */
index f704dc9..ce8f875 100644 (file)
@@ -135,17 +135,21 @@ typedef enum {
 } mdl_type_t;
 
 struct md_hsm {
-        __u32  mh_flags;
-        __u32  mh_archive_number;
+       __u32   mh_compat;
+       __u32   mh_flags;
+       __u64   mh_arch_id;
+       __u64   mh_arch_ver;
 };
 
 #define IOEPOCH_INVAL 0
 
 struct md_som_data {
-        __u64 msd_ioepoch;
-        __u64 msd_size;
-        __u64 msd_blocks;
-        __u64 msd_mountid;
+       __u32   msd_compat;
+       __u32   msd_incompat;
+       __u64   msd_ioepoch;
+       __u64   msd_size;
+       __u64   msd_blocks;
+       __u64   msd_mountid;
 };
 
 struct md_attr {
@@ -861,5 +865,8 @@ int llo_local_objects_setup(const struct lu_env *env,
                              struct md_device * md,
                              struct dt_device * dt);
 
+int lustre_buf2som(void *buf, int rc, struct md_som_data *msd);
+int lustre_buf2hsm(void *buf, int rc, struct md_hsm *mh);
+void lustre_hsm2buf(void *buf, struct md_hsm *mh);
 /** @} md */
 #endif /* _LINUX_MD_OBJECT_H */
index a1be690..8573464 100644 (file)
@@ -1,6 +1,6 @@
 MODULES := mdt
 mdt-objs := mdt_handler.o mdt_lib.o mdt_reint.o mdt_xattr.o mdt_recovery.o
 mdt-objs += mdt_open.o mdt_idmap.o mdt_identity.o mdt_capa.o mdt_lproc.o mdt_fs.o
-mdt-objs += mdt_lvb.o
+mdt-objs += mdt_lvb.o mdt_hsm.o
 
 @INCLUDE_RULES@
index 144fc0b..da410c2 100644 (file)
@@ -712,40 +712,30 @@ int mdt_attr_get_complex(struct mdt_thread_info *info,
                        GOTO(out, rc = rc2);
        }
 
+       if (need & MA_SOM && S_ISREG(mode)) {
+               buf->lb_buf = info->mti_xattr_buf;
+               buf->lb_len = sizeof(info->mti_xattr_buf);
+               CLASSERT(sizeof(struct som_attrs) <=
+                        sizeof(info->mti_xattr_buf));
+               rc2 = mo_xattr_get(info->mti_env, next, buf, XATTR_NAME_SOM);
+               rc2 = lustre_buf2som(info->mti_xattr_buf, rc2, ma->ma_som);
+               if (rc2 == 0)
+                       ma->ma_valid |= MA_SOM;
+               else if (rc2 < 0 && rc2 != -ENODATA)
+                       GOTO(out, rc = rc2);
+       }
 
-       if (rc == 0 && S_ISREG(mode) && (need & (MA_HSM | MA_SOM))) {
-               struct lustre_mdt_attrs *lma;
-
-               lma = (struct lustre_mdt_attrs *)info->mti_xattr_buf;
-               CLASSERT(sizeof(*lma) <= sizeof(info->mti_xattr_buf));
-
-               buf->lb_buf = lma;
+       if (need & MA_HSM && S_ISREG(mode)) {
+               buf->lb_buf = info->mti_xattr_buf;
                buf->lb_len = sizeof(info->mti_xattr_buf);
-               rc = mo_xattr_get(env, next, buf, XATTR_NAME_LMA);
-               if (rc > 0) {
-                       lustre_lma_swab(lma);
-                       /* Swab and copy LMA */
-                       if (need & MA_HSM) {
-                               if (lma->lma_compat & LMAC_HSM)
-                                       ma->ma_hsm.mh_flags =
-                                               lma->lma_flags & HSM_FLAGS_MASK;
-                               else
-                                       ma->ma_hsm.mh_flags = 0;
-                               ma->ma_valid |= MA_HSM;
-                       }
-                       /* Copy SOM */
-                       if (need & MA_SOM && lma->lma_compat & LMAC_SOM) {
-                               LASSERT(ma->ma_som != NULL);
-                               ma->ma_som->msd_ioepoch = lma->lma_ioepoch;
-                               ma->ma_som->msd_size    = lma->lma_som_size;
-                               ma->ma_som->msd_blocks  = lma->lma_som_blocks;
-                               ma->ma_som->msd_mountid = lma->lma_som_mountid;
-                               ma->ma_valid |= MA_SOM;
-                       }
-                       rc = 0;
-               } else if (rc == -ENODATA) {
-                       rc = 0;
-               }
+               CLASSERT(sizeof(struct hsm_attrs) <=
+                        sizeof(info->mti_xattr_buf));
+               rc2 = mo_xattr_get(info->mti_env, next, buf, XATTR_NAME_HSM);
+               rc2 = lustre_buf2hsm(info->mti_xattr_buf, rc2, &ma->ma_hsm);
+               if (rc2 == 0)
+                       ma->ma_valid |= MA_HSM;
+               else if (rc2 < 0 && rc2 != -ENODATA)
+                       GOTO(out, rc = rc2);
        }
 
 #ifdef CONFIG_FS_POSIX_ACL
diff --git a/lustre/mdt/mdt_hsm.c b/lustre/mdt/mdt_hsm.c
new file mode 100644 (file)
index 0000000..84c741e
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2012 Intel Corporation
+ * Use is subject to license terms.
+ */
+
+#define DEBUG_SUBSYSTEM S_MDS
+
+#include "mdt_internal.h"
+
+/**
+ * Update on-disk HSM attributes.
+ */
+int mdt_hsm_attr_set(struct mdt_thread_info *info, struct mdt_object *obj,
+                    struct md_hsm *mh)
+{
+       struct md_object        *next = mdt_object_child(obj);
+       struct lu_buf           *buf = &info->mti_buf;
+       struct hsm_attrs        *attrs;
+       int                      rc;
+       ENTRY;
+
+       attrs = (struct hsm_attrs *)info->mti_xattr_buf;
+       CLASSERT(sizeof(info->mti_xattr_buf) >= sizeof(*attrs));
+
+       /* pack HSM attributes */
+       lustre_hsm2buf(info->mti_xattr_buf, mh);
+
+       /* update SOM attributes */
+       buf->lb_buf = attrs;
+       buf->lb_len = sizeof(*attrs);
+       rc = mo_xattr_set(info->mti_env, next, buf, XATTR_NAME_HSM, 0);
+
+       RETURN(rc);
+}
index d414f89..f3f4347 100644 (file)
@@ -217,18 +217,13 @@ int mdt_ioepoch_open(struct mdt_thread_info *info, struct mdt_object *o,
 /**
  * Update SOM on-disk attributes.
  * If enabling, write update inodes and lustre-ea with the proper IOEpoch,
- * mountid and attributes. If disabling, zero IOEpoch id in lustre-ea.
+ * mountid and attributes. If disabling, clean SOM xattr.
  * Call under ->mot_ioepoch_mutex.
  */
 static int mdt_som_attr_set(struct mdt_thread_info *info,
-                            struct mdt_object *obj, __u64 ioepoch, int enable)
+                           struct mdt_object *obj, __u64 ioepoch, bool enable)
 {
-       struct lustre_mdt_attrs *lma;
-       struct md_attr          *ma = &info->mti_attr;
-       struct lu_buf           *buf = &info->mti_buf;
        struct md_object        *next = mdt_object_child(obj);
-       struct mdt_device       *mdt = info->mti_mdt;
-       struct lu_attr          *la = &ma->ma_attr;
        int                      rc;
         ENTRY;
 
@@ -236,35 +231,35 @@ static int mdt_som_attr_set(struct mdt_thread_info *info,
                " on "DFID".\n", enable ? "update" : "disabling",
                ioepoch, PFID(mdt_object_fid(obj)));
 
-       lma = (struct lustre_mdt_attrs *) info->mti_xattr_buf;
-       CLASSERT(sizeof(info->mti_xattr_buf) >= sizeof(*lma));
-
-       buf->lb_buf = lma;
-       buf->lb_len = sizeof(info->mti_xattr_buf);
-       rc = mo_xattr_get(info->mti_env, next, buf, XATTR_NAME_LMA);
-       if (rc > 0) {
-               lustre_lma_swab(lma);
-       } else if (rc == -ENODATA) {
-               memset(lma, 0, sizeof(*lma));
+       if (enable) {
+               struct lu_buf           *buf = &info->mti_buf;
+               struct som_attrs        *attrs;
+               struct md_attr          *ma = &info->mti_attr;
+               struct lu_attr          *la = &ma->ma_attr;
+               struct obd_device       *obd = info->mti_mdt->mdt_lut.lut_obd;
+
+               attrs = (struct som_attrs *)info->mti_xattr_buf;
+               CLASSERT(sizeof(info->mti_xattr_buf) >= sizeof(*attrs));
+
+               /* pack SOM attributes */
+               memset(attrs, 0, sizeof(*attrs));
+               attrs->som_ioepoch = ioepoch;
+               attrs->som_mountid = obd->u.obt.obt_mount_count;
+               if ((la->la_valid & LA_SIZE) != 0)
+                       attrs->som_size = la->la_size;
+               if ((la->la_valid & LA_BLOCKS) != 0)
+                       attrs->som_blocks = la->la_blocks;
+               lustre_som_swab(attrs);
+
+               /* update SOM attributes */
+               buf->lb_buf = attrs;
+               buf->lb_len = sizeof(*attrs);
+               rc = mo_xattr_set(info->mti_env, next, buf, XATTR_NAME_SOM, 0);
        } else {
-               RETURN(rc);
+               /* delete SOM attributes */
+               rc = mo_xattr_del(info->mti_env, next, XATTR_NAME_SOM);
        }
 
-       /* Copy FID */
-       memcpy(&lma->lma_self_fid, mdt_object_fid(obj), sizeof(lma->lma_self_fid));
-
-       /* Copy SOM data */
-       lma->lma_ioepoch     = ioepoch;
-       lma->lma_som_size    = la->la_valid & LA_SIZE ? la->la_size : 0;
-       lma->lma_som_blocks  = la->la_valid & LA_BLOCKS ?  la->la_blocks : 0;
-       lma->lma_som_mountid = mdt->mdt_lut.lut_obd->u.obt.obt_mount_count;
-       if (enable)
-               lma->lma_compat |= LMAC_SOM;
-       else
-               lma->lma_compat &= ~LMAC_SOM;
-
-       rc = mo_xattr_set(info->mti_env, next, buf, XATTR_NAME_LMA, 0);
-
         RETURN(rc);
 }
 
index 3af5216..b090861 100644 (file)
@@ -16,7 +16,7 @@ obdclass-all-objs += statfs_pack.o obdo.o obd_config.o obd_mount.o mea.o
 obdclass-all-objs += lu_object.o dt_object.o capa.o lu_time.o
 obdclass-all-objs += cl_object.o cl_page.o cl_lock.o cl_io.o lu_ref.o
 obdclass-all-objs += acl.o idmap.o
-obdclass-all-objs += md_local_object.o
+obdclass-all-objs += md_local_object.o md_attrs.o
 
 obdclass-objs := $(obdclass-linux-objs) $(obdclass-all-objs)
 
diff --git a/lustre/obdclass/md_attrs.c b/lustre/obdclass/md_attrs.c
new file mode 100644 (file)
index 0000000..3bcea4d
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2012 Intel Corporation
+ * Use is subject to license terms.
+ *
+ * Author: Johann Lombardi <johann.lombardi@intel.com>
+ */
+
+#include <lustre/lustre_idl.h>
+#include <obd.h>
+#include <md_object.h>
+
+/**
+ * Initialize new \a lma. Only fid is stored.
+ *
+ * \param lma - is the new LMA structure to be initialized
+ * \param fid - is the FID of the object this LMA belongs to
+ */
+void lustre_lma_init(struct lustre_mdt_attrs *lma, const struct lu_fid *fid)
+{
+       lma->lma_compat   = 0;
+       lma->lma_incompat = 0;
+       lma->lma_self_fid = *fid;
+       lma->lma_flags    = 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_flags) +
+                sizeof(lma->lma_flags)));
+};
+EXPORT_SYMBOL(lustre_lma_init);
+
+/**
+ * Swab, if needed, LMA structure which is stored on-disk in little-endian order.
+ *
+ * \param lma - is a pointer to the LMA structure to be swabbed.
+ */
+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);
+       }
+};
+EXPORT_SYMBOL(lustre_lma_swab);
+
+/**
+ * Swab, if needed, SOM structure which is stored on-disk in little-endian
+ * order.
+ *
+ * \param attrs - is a pointer to the SOM structure to be swabbed.
+ */
+void lustre_som_swab(struct som_attrs *attrs)
+{
+       /* Use LUSTRE_MSG_MAGIC to detect local endianess. */
+       if (LUSTRE_MSG_MAGIC != cpu_to_le32(LUSTRE_MSG_MAGIC)) {
+               __swab32s(&attrs->som_compat);
+               __swab32s(&attrs->som_incompat);
+               __swab64s(&attrs->som_ioepoch);
+               __swab64s(&attrs->som_size);
+               __swab64s(&attrs->som_blocks);
+               __swab64s(&attrs->som_mountid);
+       }
+};
+EXPORT_SYMBOL(lustre_som_swab);
+
+/*
+ * Swab and extract SOM attributes from on-disk xattr.
+ *
+ * \param buf - is a buffer containing the on-disk SOM extended attribute.
+ * \param rc  - is the SOM xattr stored in \a buf
+ * \param msd - is the md_som_data structure where to extract SOM attributes.
+ */
+int lustre_buf2som(void *buf, int rc, struct md_som_data *msd)
+{
+       struct som_attrs *attrs = (struct som_attrs *)buf;
+       ENTRY;
+
+       if (rc == 0 ||  rc == -ENODATA)
+               /* no SOM attributes */
+               RETURN(-ENODATA);
+
+       if (rc < 0)
+               /* error hit while fetching xattr */
+               RETURN(rc);
+
+       /* check SOM compatibility */
+       if (attrs->som_incompat & ~cpu_to_le32(SOM_INCOMPAT_SUPP))
+               RETURN(-ENODATA);
+
+       /* unpack SOM attributes */
+       lustre_som_swab(attrs);
+
+       /* fill in-memory msd structure */
+       msd->msd_compat   = attrs->som_compat;
+       msd->msd_incompat = attrs->som_incompat;
+       msd->msd_ioepoch  = attrs->som_ioepoch;
+       msd->msd_size     = attrs->som_size;
+       msd->msd_blocks   = attrs->som_blocks;
+       msd->msd_mountid  = attrs->som_mountid;
+
+       RETURN(0);
+}
+EXPORT_SYMBOL(lustre_buf2som);
+
+/**
+ * Swab, if needed, HSM structure which is stored on-disk in little-endian
+ * order.
+ *
+ * \param attrs - is a pointer to the HSM structure to be swabbed.
+ */
+void lustre_hsm_swab(struct hsm_attrs *attrs)
+{
+       /* Use LUSTRE_MSG_MAGIC to detect local endianess. */
+       if (LUSTRE_MSG_MAGIC != cpu_to_le32(LUSTRE_MSG_MAGIC)) {
+               __swab32s(&attrs->hsm_compat);
+               __swab32s(&attrs->hsm_flags);
+               __swab64s(&attrs->hsm_arch_id);
+               __swab64s(&attrs->hsm_arch_ver);
+       }
+};
+EXPORT_SYMBOL(lustre_hsm_swab);
+
+/*
+ * Swab and extract HSM attributes from on-disk xattr.
+ *
+ * \param buf - is a buffer containing the on-disk HSM extended attribute.
+ * \param rc  - is the HSM xattr stored in \a buf
+ * \param mh  - is the md_hsm structure where to extract HSM attributes.
+ */
+int lustre_buf2hsm(void *buf, int rc, struct md_hsm *mh)
+{
+       struct hsm_attrs *attrs = (struct hsm_attrs *)buf;
+       ENTRY;
+
+       if (rc == 0 ||  rc == -ENODATA)
+               /* no HSM attributes */
+               RETURN(-ENODATA);
+
+       if (rc < 0)
+               /* error hit while fetching xattr */
+               RETURN(rc);
+
+       /* unpack HSM attributes */
+       lustre_hsm_swab(attrs);
+
+       /* fill md_hsm structure */
+       mh->mh_compat   = attrs->hsm_compat;
+       mh->mh_flags    = attrs->hsm_flags;
+       mh->mh_arch_id  = attrs->hsm_arch_id;
+       mh->mh_arch_ver = attrs->hsm_arch_ver;
+
+       RETURN(0);
+}
+EXPORT_SYMBOL(lustre_buf2hsm);
+
+/*
+ * Pack HSM attributes.
+ *
+ * \param buf - is the output buffer where to pack the on-disk HSM xattr.
+ * \param mh  - is the md_hsm structure to pack.
+ */
+void lustre_hsm2buf(void *buf, struct md_hsm *mh)
+{
+       struct hsm_attrs *attrs = (struct hsm_attrs *)buf;
+       ENTRY;
+
+       /* copy HSM attributes */
+       attrs->hsm_compat   = mh->mh_compat;
+       attrs->hsm_flags    = mh->mh_flags;
+       attrs->hsm_arch_id  = mh->mh_arch_id;
+       attrs->hsm_arch_ver = mh->mh_arch_ver;
+
+       /* pack xattr */
+       lustre_hsm_swab(attrs);
+}
+EXPORT_SYMBOL(lustre_hsm2buf);
index dc8c919..59d093f 100644 (file)
@@ -161,14 +161,22 @@ static struct lu_object *osd_object_alloc(const struct lu_env *env,
         }
 }
 
-static int osd_get_lma(struct inode *inode, struct dentry *dentry,
-                      struct lustre_mdt_attrs *lma)
+static int osd_get_lma(struct osd_thread_info *info, struct inode *inode,
+                      struct dentry *dentry, struct lustre_mdt_attrs *lma)
 {
        int rc;
 
        dentry->d_inode = inode;
        rc = inode->i_op->getxattr(dentry, XATTR_NAME_LMA, (void *)lma,
                                   sizeof(*lma));
+       if (rc == -ERANGE) {
+               /* try with old lma size */
+               rc = inode->i_op->getxattr(dentry, XATTR_NAME_LMA,
+                                          info->oti_mdt_attrs_old,
+                                          LMA_OLD_SIZE);
+               if (rc > 0)
+                       memcpy(lma, info->oti_mdt_attrs_old, sizeof(*lma));
+       }
        if (rc > 0) {
                /* Check LMA compatibility */
                if (lma->lma_incompat & ~cpu_to_le32(LMA_INCOMPAT_SUPP)) {
@@ -246,7 +254,7 @@ struct inode *osd_iget_fid(struct osd_thread_info *info, struct osd_device *dev,
        if (IS_ERR(inode))
                return inode;
 
-       rc = osd_get_lma(inode, &info->oti_obj_dentry, lma);
+       rc = osd_get_lma(info, inode, &info->oti_obj_dentry, lma);
        if (rc == 0) {
                *fid = lma->lma_self_fid;
        } else if (rc == -ENODATA) {
@@ -270,7 +278,7 @@ osd_iget_verify(struct osd_thread_info *info, struct osd_device *dev,
        if (IS_ERR(inode))
                return inode;
 
-       rc = osd_get_lma(inode, &info->oti_obj_dentry, lma);
+       rc = osd_get_lma(info, inode, &info->oti_obj_dentry, lma);
        if (rc == -ENODATA)
                return inode;
 
index 527fa5c..e67bd62 100644 (file)
@@ -603,7 +603,11 @@ struct osd_thread_info {
         /** used in osd_fid_set() to put xattr */
         struct lu_buf          oti_buf;
         /** used in osd_ea_fid_set() to set fid into common ea */
-        struct lustre_mdt_attrs oti_mdt_attrs;
+       union {
+               struct lustre_mdt_attrs oti_mdt_attrs;
+               /* old LMA for compatibility */
+               char                    oti_mdt_attrs_old[LMA_OLD_SIZE];
+       };
         /** 0-copy IO */
         struct osd_iobuf       oti_iobuf;
         struct inode           oti_inode;
index fdfaea6..09e627c 100644 (file)
@@ -395,8 +395,8 @@ void lustre_assert_wire_constants(void)
                  (long long)LU_SEQ_RANGE_OST);
 
         /* Checks for struct lustre_mdt_attrs */
-        LASSERTF((int)sizeof(struct lustre_mdt_attrs) == 64, "found %lld\n",
-                 (long long)(int)sizeof(struct lustre_mdt_attrs));
+       LASSERTF((int)sizeof(struct lustre_mdt_attrs) == 32, "found %lld\n",
+                (long long)(int)sizeof(struct lustre_mdt_attrs));
         LASSERTF((int)offsetof(struct lustre_mdt_attrs, lma_compat) == 0, "found %lld\n",
                  (long long)(int)offsetof(struct lustre_mdt_attrs, lma_compat));
         LASSERTF((int)sizeof(((struct lustre_mdt_attrs *)0)->lma_compat) == 4, "found %lld\n",
@@ -413,29 +413,63 @@ void lustre_assert_wire_constants(void)
                  (long long)(int)offsetof(struct lustre_mdt_attrs, lma_flags));
         LASSERTF((int)sizeof(((struct lustre_mdt_attrs *)0)->lma_flags) == 8, "found %lld\n",
                  (long long)(int)sizeof(((struct lustre_mdt_attrs *)0)->lma_flags));
-        LASSERTF((int)offsetof(struct lustre_mdt_attrs, lma_ioepoch) == 32, "found %lld\n",
-                 (long long)(int)offsetof(struct lustre_mdt_attrs, lma_ioepoch));
-        LASSERTF((int)sizeof(((struct lustre_mdt_attrs *)0)->lma_ioepoch) == 8, "found %lld\n",
-                 (long long)(int)sizeof(((struct lustre_mdt_attrs *)0)->lma_ioepoch));
-        LASSERTF((int)offsetof(struct lustre_mdt_attrs, lma_som_size) == 40, "found %lld\n",
-                 (long long)(int)offsetof(struct lustre_mdt_attrs, lma_som_size));
-        LASSERTF((int)sizeof(((struct lustre_mdt_attrs *)0)->lma_som_size) == 8, "found %lld\n",
-                 (long long)(int)sizeof(((struct lustre_mdt_attrs *)0)->lma_som_size));
-        LASSERTF((int)offsetof(struct lustre_mdt_attrs, lma_som_blocks) == 48, "found %lld\n",
-                 (long long)(int)offsetof(struct lustre_mdt_attrs, lma_som_blocks));
-        LASSERTF((int)sizeof(((struct lustre_mdt_attrs *)0)->lma_som_blocks) == 8, "found %lld\n",
-                 (long long)(int)sizeof(((struct lustre_mdt_attrs *)0)->lma_som_blocks));
-        LASSERTF((int)offsetof(struct lustre_mdt_attrs, lma_som_mountid) == 56, "found %lld\n",
-                 (long long)(int)offsetof(struct lustre_mdt_attrs, lma_som_mountid));
-        LASSERTF((int)sizeof(((struct lustre_mdt_attrs *)0)->lma_som_mountid) == 8, "found %lld\n",
-                 (long long)(int)sizeof(((struct lustre_mdt_attrs *)0)->lma_som_mountid));
         LASSERTF(LMA_INCOMPAT_SUPP == 0x0, "found %lld\n",
                  (long long)LMA_INCOMPAT_SUPP);
+       LASSERTF(LMAI_RELEASED == 0x00000001UL, "found 0x%.8xUL\n",
+                (unsigned)LMAI_RELEASED);
         LASSERTF(LMAC_HSM == 0x00000001UL, "found 0x%.8xUL\n",
                  (unsigned)LMAC_HSM);
         LASSERTF(LMAC_SOM == 0x00000002UL, "found 0x%.8xUL\n",
                  (unsigned)LMAC_SOM);
 
+       /* Checks for struct som_attrs */
+       LASSERTF((int)sizeof(struct som_attrs) == 40, "found %lld\n",
+                (long long)(int)sizeof(struct som_attrs));
+       LASSERTF((int)offsetof(struct som_attrs, som_compat) == 0, "found %lld\n",
+                (long long)(int)offsetof(struct som_attrs, som_compat));
+       LASSERTF((int)sizeof(((struct som_attrs *)0)->som_compat) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct som_attrs *)0)->som_compat));
+       LASSERTF((int)offsetof(struct som_attrs, som_incompat) == 4, "found %lld\n",
+                (long long)(int)offsetof(struct som_attrs, som_incompat));
+       LASSERTF((int)sizeof(((struct som_attrs *)0)->som_incompat) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct som_attrs *)0)->som_incompat));
+       LASSERTF((int)offsetof(struct som_attrs, som_ioepoch) == 8, "found %lld\n",
+                (long long)(int)offsetof(struct som_attrs, som_ioepoch));
+       LASSERTF((int)sizeof(((struct som_attrs *)0)->som_ioepoch) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct som_attrs *)0)->som_ioepoch));
+       LASSERTF((int)offsetof(struct som_attrs, som_size) == 16, "found %lld\n",
+                (long long)(int)offsetof(struct som_attrs, som_size));
+       LASSERTF((int)sizeof(((struct som_attrs *)0)->som_size) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct som_attrs *)0)->som_size));
+       LASSERTF((int)offsetof(struct som_attrs, som_blocks) == 24, "found %lld\n",
+                (long long)(int)offsetof(struct som_attrs, som_blocks));
+       LASSERTF((int)sizeof(((struct som_attrs *)0)->som_blocks) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct som_attrs *)0)->som_blocks));
+       LASSERTF((int)offsetof(struct som_attrs, som_mountid) == 32, "found %lld\n",
+                (long long)(int)offsetof(struct som_attrs, som_mountid));
+       LASSERTF((int)sizeof(((struct som_attrs *)0)->som_mountid) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct som_attrs *)0)->som_mountid));
+
+       /* Checks for struct hsm_attrs */
+       LASSERTF((int)sizeof(struct hsm_attrs) == 24, "found %lld\n",
+                (long long)(int)sizeof(struct hsm_attrs));
+       LASSERTF((int)offsetof(struct hsm_attrs, hsm_compat) == 0, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_attrs, hsm_compat));
+       LASSERTF((int)sizeof(((struct hsm_attrs *)0)->hsm_compat) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_attrs *)0)->hsm_compat));
+       LASSERTF((int)offsetof(struct hsm_attrs, hsm_flags) == 4, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_attrs, hsm_flags));
+       LASSERTF((int)sizeof(((struct hsm_attrs *)0)->hsm_flags) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_attrs *)0)->hsm_flags));
+       LASSERTF((int)offsetof(struct hsm_attrs, hsm_arch_id) == 8, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_attrs, hsm_arch_id));
+       LASSERTF((int)sizeof(((struct hsm_attrs *)0)->hsm_arch_id) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_attrs *)0)->hsm_arch_id));
+       LASSERTF((int)offsetof(struct hsm_attrs, hsm_arch_ver) == 16, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_attrs, hsm_arch_ver));
+       LASSERTF((int)sizeof(((struct hsm_attrs *)0)->hsm_arch_ver) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_attrs *)0)->hsm_arch_ver));
+
         /* Checks for struct ost_id */
         LASSERTF((int)sizeof(struct ost_id) == 16, "found %lld\n",
                  (long long)(int)sizeof(struct ost_id));
index c745497..b038e2c 100644 (file)
@@ -207,18 +207,40 @@ check_lustre_mdt_attrs(void)
         CHECK_MEMBER(lustre_mdt_attrs, lma_incompat);
         CHECK_MEMBER(lustre_mdt_attrs, lma_self_fid);
         CHECK_MEMBER(lustre_mdt_attrs, lma_flags);
-        CHECK_MEMBER(lustre_mdt_attrs, lma_ioepoch);
-        CHECK_MEMBER(lustre_mdt_attrs, lma_som_size);
-        CHECK_MEMBER(lustre_mdt_attrs, lma_som_blocks);
-        CHECK_MEMBER(lustre_mdt_attrs, lma_som_mountid);
 
         CHECK_DEFINE(LMA_INCOMPAT_SUPP);
 
+       CHECK_VALUE_X(LMAI_RELEASED);
+
         CHECK_VALUE_X(LMAC_HSM);
         CHECK_VALUE_X(LMAC_SOM);
 }
 
 static void
+check_som_attrs(void)
+{
+       BLANK_LINE();
+       CHECK_STRUCT(som_attrs);
+       CHECK_MEMBER(som_attrs, som_compat);
+       CHECK_MEMBER(som_attrs, som_incompat);
+       CHECK_MEMBER(som_attrs, som_ioepoch);
+       CHECK_MEMBER(som_attrs, som_size);
+       CHECK_MEMBER(som_attrs, som_blocks);
+       CHECK_MEMBER(som_attrs, som_mountid);
+}
+
+static void
+check_hsm_attrs(void)
+{
+       BLANK_LINE();
+       CHECK_STRUCT(hsm_attrs);
+       CHECK_MEMBER(hsm_attrs, hsm_compat);
+       CHECK_MEMBER(hsm_attrs, hsm_flags);
+       CHECK_MEMBER(hsm_attrs, hsm_arch_id);
+       CHECK_MEMBER(hsm_attrs, hsm_arch_ver);
+}
+
+static void
 check_ost_id(void)
 {
         BLANK_LINE();
@@ -2123,6 +2145,8 @@ main(int argc, char **argv)
         CHECK_STRUCT(obd_uuid);
         check_lu_seq_range();
         check_lustre_mdt_attrs();
+       check_som_attrs();
+       check_hsm_attrs();
         check_ost_id();
         check_lu_dirent();
         check_luda_type();
index e1df03b..6ca6c20 100644 (file)
@@ -403,8 +403,8 @@ void lustre_assert_wire_constants(void)
                  (long long)LU_SEQ_RANGE_OST);
 
         /* Checks for struct lustre_mdt_attrs */
-        LASSERTF((int)sizeof(struct lustre_mdt_attrs) == 64, "found %lld\n",
-                 (long long)(int)sizeof(struct lustre_mdt_attrs));
+       LASSERTF((int)sizeof(struct lustre_mdt_attrs) == 32, "found %lld\n",
+                (long long)(int)sizeof(struct lustre_mdt_attrs));
         LASSERTF((int)offsetof(struct lustre_mdt_attrs, lma_compat) == 0, "found %lld\n",
                  (long long)(int)offsetof(struct lustre_mdt_attrs, lma_compat));
         LASSERTF((int)sizeof(((struct lustre_mdt_attrs *)0)->lma_compat) == 4, "found %lld\n",
@@ -421,29 +421,63 @@ void lustre_assert_wire_constants(void)
                  (long long)(int)offsetof(struct lustre_mdt_attrs, lma_flags));
         LASSERTF((int)sizeof(((struct lustre_mdt_attrs *)0)->lma_flags) == 8, "found %lld\n",
                  (long long)(int)sizeof(((struct lustre_mdt_attrs *)0)->lma_flags));
-        LASSERTF((int)offsetof(struct lustre_mdt_attrs, lma_ioepoch) == 32, "found %lld\n",
-                 (long long)(int)offsetof(struct lustre_mdt_attrs, lma_ioepoch));
-        LASSERTF((int)sizeof(((struct lustre_mdt_attrs *)0)->lma_ioepoch) == 8, "found %lld\n",
-                 (long long)(int)sizeof(((struct lustre_mdt_attrs *)0)->lma_ioepoch));
-        LASSERTF((int)offsetof(struct lustre_mdt_attrs, lma_som_size) == 40, "found %lld\n",
-                 (long long)(int)offsetof(struct lustre_mdt_attrs, lma_som_size));
-        LASSERTF((int)sizeof(((struct lustre_mdt_attrs *)0)->lma_som_size) == 8, "found %lld\n",
-                 (long long)(int)sizeof(((struct lustre_mdt_attrs *)0)->lma_som_size));
-        LASSERTF((int)offsetof(struct lustre_mdt_attrs, lma_som_blocks) == 48, "found %lld\n",
-                 (long long)(int)offsetof(struct lustre_mdt_attrs, lma_som_blocks));
-        LASSERTF((int)sizeof(((struct lustre_mdt_attrs *)0)->lma_som_blocks) == 8, "found %lld\n",
-                 (long long)(int)sizeof(((struct lustre_mdt_attrs *)0)->lma_som_blocks));
-        LASSERTF((int)offsetof(struct lustre_mdt_attrs, lma_som_mountid) == 56, "found %lld\n",
-                 (long long)(int)offsetof(struct lustre_mdt_attrs, lma_som_mountid));
-        LASSERTF((int)sizeof(((struct lustre_mdt_attrs *)0)->lma_som_mountid) == 8, "found %lld\n",
-                 (long long)(int)sizeof(((struct lustre_mdt_attrs *)0)->lma_som_mountid));
         LASSERTF(LMA_INCOMPAT_SUPP == 0x0, "found %lld\n",
                  (long long)LMA_INCOMPAT_SUPP);
+       LASSERTF(LMAI_RELEASED == 0x00000001UL, "found 0x%.8xUL\n",
+                (unsigned)LMAI_RELEASED);
         LASSERTF(LMAC_HSM == 0x00000001UL, "found 0x%.8xUL\n",
                  (unsigned)LMAC_HSM);
         LASSERTF(LMAC_SOM == 0x00000002UL, "found 0x%.8xUL\n",
                  (unsigned)LMAC_SOM);
 
+       /* Checks for struct som_attrs */
+       LASSERTF((int)sizeof(struct som_attrs) == 40, "found %lld\n",
+                (long long)(int)sizeof(struct som_attrs));
+       LASSERTF((int)offsetof(struct som_attrs, som_compat) == 0, "found %lld\n",
+                (long long)(int)offsetof(struct som_attrs, som_compat));
+       LASSERTF((int)sizeof(((struct som_attrs *)0)->som_compat) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct som_attrs *)0)->som_compat));
+       LASSERTF((int)offsetof(struct som_attrs, som_incompat) == 4, "found %lld\n",
+                (long long)(int)offsetof(struct som_attrs, som_incompat));
+       LASSERTF((int)sizeof(((struct som_attrs *)0)->som_incompat) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct som_attrs *)0)->som_incompat));
+       LASSERTF((int)offsetof(struct som_attrs, som_ioepoch) == 8, "found %lld\n",
+                (long long)(int)offsetof(struct som_attrs, som_ioepoch));
+       LASSERTF((int)sizeof(((struct som_attrs *)0)->som_ioepoch) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct som_attrs *)0)->som_ioepoch));
+       LASSERTF((int)offsetof(struct som_attrs, som_size) == 16, "found %lld\n",
+                (long long)(int)offsetof(struct som_attrs, som_size));
+       LASSERTF((int)sizeof(((struct som_attrs *)0)->som_size) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct som_attrs *)0)->som_size));
+       LASSERTF((int)offsetof(struct som_attrs, som_blocks) == 24, "found %lld\n",
+                (long long)(int)offsetof(struct som_attrs, som_blocks));
+       LASSERTF((int)sizeof(((struct som_attrs *)0)->som_blocks) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct som_attrs *)0)->som_blocks));
+       LASSERTF((int)offsetof(struct som_attrs, som_mountid) == 32, "found %lld\n",
+                (long long)(int)offsetof(struct som_attrs, som_mountid));
+       LASSERTF((int)sizeof(((struct som_attrs *)0)->som_mountid) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct som_attrs *)0)->som_mountid));
+
+       /* Checks for struct hsm_attrs */
+       LASSERTF((int)sizeof(struct hsm_attrs) == 24, "found %lld\n",
+                (long long)(int)sizeof(struct hsm_attrs));
+       LASSERTF((int)offsetof(struct hsm_attrs, hsm_compat) == 0, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_attrs, hsm_compat));
+       LASSERTF((int)sizeof(((struct hsm_attrs *)0)->hsm_compat) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_attrs *)0)->hsm_compat));
+       LASSERTF((int)offsetof(struct hsm_attrs, hsm_flags) == 4, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_attrs, hsm_flags));
+       LASSERTF((int)sizeof(((struct hsm_attrs *)0)->hsm_flags) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_attrs *)0)->hsm_flags));
+       LASSERTF((int)offsetof(struct hsm_attrs, hsm_arch_id) == 8, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_attrs, hsm_arch_id));
+       LASSERTF((int)sizeof(((struct hsm_attrs *)0)->hsm_arch_id) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_attrs *)0)->hsm_arch_id));
+       LASSERTF((int)offsetof(struct hsm_attrs, hsm_arch_ver) == 16, "found %lld\n",
+                (long long)(int)offsetof(struct hsm_attrs, hsm_arch_ver));
+       LASSERTF((int)sizeof(((struct hsm_attrs *)0)->hsm_arch_ver) == 8, "found %lld\n",
+                (long long)(int)sizeof(((struct hsm_attrs *)0)->hsm_arch_ver));
+
         /* Checks for struct ost_id */
         LASSERTF((int)sizeof(struct ost_id) == 16, "found %lld\n",
                  (long long)(int)sizeof(struct ost_id));