Details : fix a race between class_handle_unhash() and class_handle2object()
introduced in lustre 1.6.5 by bug 13622.
+Severity : minor
+Frequency : rare
+Bugzilla : 15899
+Description: Pools downgrade compatibility
+Details : Files striped across pools in future (1.8) releases will be
+ properly understood if the server is downgraded to this version.
+
-------------------------------------------------------------------------------
#define LOV_MAGIC_V1 0x0BD10BD0
#define LOV_MAGIC LOV_MAGIC_V1
#define LOV_MAGIC_JOIN 0x0BD20BD0
+#define LOV_MAGIC_V3 0x0BD30BD0
#define LOV_PATTERN_RAID0 0x001 /* stripes are used round-robin */
#define LOV_PATTERN_RAID1 0x002 /* stripes are mirrors of each other */
#define LOV_OBJECT_GROUP_DEFAULT ~0ULL
#define LOV_OBJECT_GROUP_CLEAR 0ULL
+#define MAXPOOLNAME 16
+#define POOLNAMEF "%.16s"
+
#define lov_ost_data lov_ost_data_v1
struct lov_ost_data_v1 { /* per-stripe data structure (little-endian)*/
__u64 l_object_id; /* OST object ID */
struct lov_ost_data_v1 lmm_objects[0]; /* per-stripe data */
};
+struct lov_mds_md_v3 { /* LOV EA mds/wire data (little-endian) */
+ __u32 lmm_magic; /* magic number = LOV_MAGIC_V3 */
+ __u32 lmm_pattern; /* LOV_PATTERN_RAID0, LOV_PATTERN_RAID1 */
+ __u64 lmm_object_id; /* LOV object ID */
+ __u64 lmm_object_gr; /* LOV object group */
+ __u32 lmm_stripe_size; /* size of stripe in bytes */
+ __u32 lmm_stripe_count; /* num stripes in use for this object */
+ char lmm_pool_name[MAXPOOLNAME]; /* must be 32bit aligned */
+ struct lov_ost_data_v1 lmm_objects[0]; /* per-stripe data */
+};
+
+
#define OBD_MD_FLID (0x00000001ULL) /* object ID */
#define OBD_MD_FLATIME (0x00000002ULL) /* access time */
#define OBD_MD_FLMTIME (0x00000004ULL) /* data modification time */
if (i == mds->mds_lov_objid_lastpage)
size = (mds->mds_lov_objid_lastidx + 1) * sizeof(obd_id);
- CDEBUG(D_INFO,"write %lld - %ld\n", off, size);
+ CDEBUG(D_INFO, "write %lld - %u\n", off, size);
rc = fsfilt_write_record(obd, mds->mds_lov_objid_filp, data,
size, &off, 0);
if (rc < 0)
int rc, err;
ENTRY;
+ if (le32_to_cpu(lmm->lmm_magic) == LOV_MAGIC_V3) {
+ /* LOV_MAGIC_V3 ea, we have to convert it to V1
+ * we convert the lmm from v3 to v1
+ * and return the new size (which is smaller)
+ * the caller support this way to return the new size
+ */
+ int new_lmm_size;
+
+ lmm->lmm_magic = cpu_to_le32(LOV_MAGIC_V1);
+ /* lmm_stripe_count for non reg files is not used or -1 */
+ if (!S_ISREG(inode->i_mode)) {
+ new_lmm_size = lov_mds_md_size(0);
+ } else {
+ int count = le32_to_cpu(
+ ((struct lov_mds_md_v3 *)lmm)->lmm_stripe_count);
+ new_lmm_size = lov_mds_md_size(count);
+ memmove(lmm->lmm_objects,
+ ((struct lov_mds_md_v3 *)lmm)->lmm_objects,
+ count * sizeof(struct lov_ost_data_v1));
+ }
+ /* even if new size is smaller than old one,
+ * this should not generate memory leak */
+ RETURN(new_lmm_size);
+ }
+
if (le32_to_cpu(lmm->lmm_magic) == LOV_MAGIC ||
le32_to_cpu(lmm->lmm_magic == LOV_MAGIC_JOIN))
RETURN(0);