static inline __u64 exp_connect_flags2(struct obd_export *exp)
{
- return *exp_connect_flags2_ptr(exp);
+ if (exp_connect_flags(exp) & OBD_CONNECT_FLAGS2)
+ return *exp_connect_flags2_ptr(exp);
+ return 0;
}
static inline int exp_max_brw_size(struct obd_export *exp)
return !!(exp_connect_flags2(exp) & OBD_CONNECT2_LOCKAHEAD);
}
+static inline int exp_connect_flr(struct obd_export *exp)
+{
+ return !!(exp_connect_flags2(exp) & OBD_CONNECT2_FLR);
+}
+
extern struct obd_export *class_conn2export(struct lustre_handle *conn);
extern struct obd_device *class_conn2obd(struct lustre_handle *conn);
/* ocd_connect_flags2 flags */
#define OBD_CONNECT2_FILE_SECCTX 0x1ULL /* set file security context at create */
#define OBD_CONNECT2_LOCKAHEAD 0x2ULL /* ladvise lockahead v2 */
+#define OBD_CONNECT2_FLR 0x20ULL /* FLR support */
/* XXX README XXX:
* Please DO NOT add flag values here before first ensuring that this same
OBD_CONNECT_GRANT_PARAM | \
OBD_CONNECT_SHORTIO | OBD_CONNECT_FLAGS2)
-#define MDT_CONNECT_SUPPORTED2 OBD_CONNECT2_FILE_SECCTX
+#define MDT_CONNECT_SUPPORTED2 (OBD_CONNECT2_FILE_SECCTX | OBD_CONNECT2_FLR)
#define OST_CONNECT_SUPPORTED (OBD_CONNECT_SRVLOCK | OBD_CONNECT_GRANT | \
OBD_CONNECT_REQPORTAL | OBD_CONNECT_VERSION | \
OBD_CONNECT_GRANT_PARAM |
OBD_CONNECT_SHORTIO | OBD_CONNECT_FLAGS2;
- data->ocd_connect_flags2 = 0;
+ data->ocd_connect_flags2 = OBD_CONNECT2_FLR;
#ifdef HAVE_LRU_RESIZE_SUPPORT
if (sbi->ll_flags & LL_SBI_LRU_RESIZE)
return LMM_NO_DOM;
}
+static inline bool mdt_lmm_is_flr(struct lov_mds_md *lmm)
+{
+ struct lov_comp_md_v1 *lcm = (typeof(lcm))lmm;
+
+ return le32_to_cpu(lmm->lmm_magic) == LOV_MAGIC_COMP_V1 &&
+ le16_to_cpu(lcm->lcm_mirror_count) > 0;
+}
+
__u64 mdt_get_disposition(struct ldlm_reply *rep, __u64 op_flag);
void mdt_set_disposition(struct mdt_thread_info *info,
struct ldlm_reply *rep, __u64 op_flag);
islnk = S_ISLNK(la->la_mode);
mdt_pack_attr2body(info, repbody, la, mdt_object_fid(o));
+ /* compatibility check for 2.10 clients when it tries to open mirrored
+ * files. 2.10 clients don't verify overlapping components so they
+ * would read and write mirrored files just as if they were normal
+ * PFL files, which will cause the problem that sycned mirrors actually
+ * contain different data.
+ * Older clients are not a concern here because they don't even
+ * understand PFL layout. */
+ if (isreg && !exp_connect_flr(exp) && ma->ma_valid & MA_LOV &&
+ mdt_lmm_is_flr(ma->ma_lmm)) {
+ /* LU-10286: for simplicity clients who don't understand
+ * mirrored layout(with connect flag OBD_CONNECT2_FLR) won't
+ * be able to open mirrored files */
+ RETURN(-EOPNOTSUPP);
+ }
+
/* LU-2275, simulate broken behaviour (esp. prevalent in
* pre-2.4 servers where a very strange reply is sent on error
* that looks like it was actually almost successful and a
if (mdt_object_remote(mo))
GOTO(out_put, rc = -EREMOTE);
- if ((ma->ma_attr.la_valid & LA_SIZE) ||
- (rr->rr_flags & MRF_OPEN_TRUNC)) {
+ if (ma->ma_attr.la_valid & LA_SIZE || rr->rr_flags & MRF_OPEN_TRUNC) {
/* Check write access for the O_TRUNC case */
if (mdt_write_read(mo) < 0)
GOTO(out_put, rc = -ETXTBSY);
+
+ /* LU-10286: compatibility check for FLR.
+ * Please check the comment in mdt_finish_open() for details */
+ if (!exp_connect_flr(info->mti_exp)) {
+ rc = mdt_big_xattr_get(info, mo, XATTR_NAME_LOV);
+ if (rc < 0 && rc != -ENODATA)
+ GOTO(out_put, rc);
+
+ if (rc > 0 && mdt_lmm_is_flr(info->mti_big_lmm))
+ GOTO(out_put, rc = -EOPNOTSUPP);
+ }
}
if ((ma->ma_valid & MA_INODE) && ma->ma_attr.la_valid) {