From 21e39775a0f4f8d7819a49c37b59379a1181f52a Mon Sep 17 00:00:00 2001 From: Jinshan Xiong Date: Sun, 21 Jan 2018 01:58:01 +0000 Subject: [PATCH 1/1] LU-10286 mdt: deny 2.10 clients to open mirrored files 2.10 clients would manipulate mirrored layout as PFL layout, which would damage mirrored files. This patch only allows mirrored files to be opened by clients who understand mirror layout. It also fixes the problem that it should check OBD_CONNECT_FLAGS2 first before checking OBD_CONNECT2_XXX flags. Test-Parameters: envdefinitions=SLOW=yes clientjob=lustre-b2_10 clientbuildno=68 testlist=runtests,sanity Signed-off-by: Jinshan Xiong Change-Id: I3431211ad30a1edd07f0f583d573328d6308779d Reviewed-on: https://review.whamcloud.com/30957 Tested-by: Jenkins Tested-by: Maloo Tested-by: Jian Yu Reviewed-by: Jian Yu Reviewed-by: Andreas Dilger --- lustre/include/lustre_export.h | 9 ++++++++- lustre/include/uapi/linux/lustre/lustre_idl.h | 3 ++- lustre/llite/llite_lib.c | 2 +- lustre/mdt/mdt_internal.h | 8 ++++++++ lustre/mdt/mdt_open.c | 15 +++++++++++++++ lustre/mdt/mdt_reint.c | 14 ++++++++++++-- 6 files changed, 46 insertions(+), 5 deletions(-) diff --git a/lustre/include/lustre_export.h b/lustre/include/lustre_export.h index fb531f9..a1271ff9 100644 --- a/lustre/include/lustre_export.h +++ b/lustre/include/lustre_export.h @@ -324,7 +324,9 @@ static inline __u64 *exp_connect_flags2_ptr(struct obd_export *exp) 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) @@ -439,6 +441,11 @@ static inline int exp_connect_lockahead(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); diff --git a/lustre/include/uapi/linux/lustre/lustre_idl.h b/lustre/include/uapi/linux/lustre/lustre_idl.h index 27734b4..5bfe219 100644 --- a/lustre/include/uapi/linux/lustre/lustre_idl.h +++ b/lustre/include/uapi/linux/lustre/lustre_idl.h @@ -810,6 +810,7 @@ struct ptlrpc_body_v2 { /* 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 @@ -860,7 +861,7 @@ struct ptlrpc_body_v2 { 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 | \ diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index ed9f4ad..8cc2f03 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -223,7 +223,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, 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) diff --git a/lustre/mdt/mdt_internal.h b/lustre/mdt/mdt_internal.h index 3c2f60e..414cc81 100644 --- a/lustre/mdt/mdt_internal.h +++ b/lustre/mdt/mdt_internal.h @@ -666,6 +666,14 @@ static inline int mdt_lmm_dom_entry(struct lov_mds_md *lmm) 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); diff --git a/lustre/mdt/mdt_open.c b/lustre/mdt/mdt_open.c index f477d99..32b9aea 100644 --- a/lustre/mdt/mdt_open.c +++ b/lustre/mdt/mdt_open.c @@ -522,6 +522,21 @@ static int mdt_finish_open(struct mdt_thread_info *info, 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 diff --git a/lustre/mdt/mdt_reint.c b/lustre/mdt/mdt_reint.c index 11ea9c9..a865f75 100644 --- a/lustre/mdt/mdt_reint.c +++ b/lustre/mdt/mdt_reint.c @@ -731,11 +731,21 @@ static int mdt_reint_setattr(struct mdt_thread_info *info, 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) { -- 1.8.3.1