static inline int lov_stripe_md_cmp(struct lov_stripe_md *m1,
struct lov_stripe_md *m2)
{
+ int len = sizeof(m1->lsm_wire);
+
/*
* ->lsm_wire contains padding, but it should be zeroed out during
- * allocation.
+ * allocation. If either lsm is LOV_MAGIC_V1 do not check that
+ * the pool is the same, due to downgrade/upgrade (b=20318). This
+ * assumes that lw_pool_name is the last member in lsm_wire.
*/
- return memcmp(&m1->lsm_wire, &m2->lsm_wire, sizeof m1->lsm_wire);
+ if (m1->lsm_magic == LOV_MAGIC_V1 || m2->lsm_magic == LOV_MAGIC_V1)
+ len -= LOV_MAXPOOLNAME;
+ return memcmp(&m1->lsm_wire, &m2->lsm_wire, len);
}
void lov_stripe_lock(struct lov_stripe_md *md);
if (lli->lli_maxbytes > PAGE_CACHE_MAXBYTES)
lli->lli_maxbytes = PAGE_CACHE_MAXBYTES;
} else {
- if (lli->lli_smd->lsm_magic == lsm->lsm_magic &&
- lli->lli_smd->lsm_stripe_count ==
+ if ((lli->lli_smd->lsm_magic == lsm->lsm_magic ||
+ (lli->lli_smd->lsm_magic == LOV_MAGIC_V3 &&
+ lsm->lsm_magic == LOV_MAGIC_V1) ||
+ (lli->lli_smd->lsm_magic == LOV_MAGIC_V1 &&
+ lsm->lsm_magic == LOV_MAGIC_V3)) &&
+ lli->lli_smd->lsm_stripe_count ==
lsm->lsm_stripe_count) {
+ /* The MDS can suddenly change the magic to
+ * v1/v3 if it has been upgraded/downgraded to a
+ * version that does/doesn't support OST pools.
+ * In this case, we consider that the cached lsm
+ * is equivalent to the new one and keep it in
+ * place until the inode is evicted from the
+ * cache */
if (lov_stripe_md_cmp(lli->lli_smd, lsm)) {
CERROR("lsm mismatch for inode %ld\n",
inode->i_ino);