From 79053592966792a21912390b9db09b1ab1d61e2a Mon Sep 17 00:00:00 2001 From: Arshad Hussain Date: Wed, 20 Apr 2022 05:07:53 -0400 Subject: [PATCH] LU-15748 osc: fallocate interop for 2.14 clients fallocate() start and end are passed in o_size and o_blocks on the wire. Clients 2.15.0 and newer should always set the OBD_MD_FLSIZE and OBD_MD_FLBLOCKS valid flags, but some older client versions did not. We permit older clients to not set these flags, checking their version by proxy using the missing OBD_CONNECT_TRUNCLOCK to imply 2.14.0 or older. Test-Parameters: serverversion=2.14.0 testlist=sanity env=SANITY_EXCEPT="64h 103e" Fixes: 2f496148c31d ("LU-15551 Return EOPNOTSUPP instead of EPROTO") Fixes: 163870abfb7c ("LU-14382 mdt: implement fallocate in MDC/MDT") Signed-off-by: Arshad Hussain Change-Id: I1ea47854f40d54297bceb03ad32b24737efa4ae7 Reviewed-on: https://review.whamcloud.com/47098 Reviewed-by: Andreas Dilger Tested-by: jenkins Tested-by: Maloo Reviewed-by: Patrick Farrell --- lustre/include/uapi/linux/lustre/lustre_idl.h | 6 ++++-- lustre/mdt/mdt_io.c | 22 ++++++++++++++++++++-- lustre/ofd/ofd_dev.c | 23 ++++++++++++++++++----- 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/lustre/include/uapi/linux/lustre/lustre_idl.h b/lustre/include/uapi/linux/lustre/lustre_idl.h index e58dc92..0162137 100644 --- a/lustre/include/uapi/linux/lustre/lustre_idl.h +++ b/lustre/include/uapi/linux/lustre/lustre_idl.h @@ -753,8 +753,10 @@ struct ptlrpc_body_v2 { #define OBD_CONNECT_ACL 0x80ULL /*access control lists */ #define OBD_CONNECT_XATTR 0x100ULL /*client use extended attr */ #define OBD_CONNECT_LARGE_ACL 0x200ULL /* more than 32 ACL entries */ -/* was OBD_CONNECT_TRUNCLOCK 0x400ULL *locks on server for punch */ -#define OBD_CONNECT_TRANSNO 0x800ULL /*replay sends init transno */ +/* was OBD_CONNECT_TRUNCLOCK 0x400ULL *locks on server for punch */ +/* temporary reuse until 2.21.53 to indicate pre-2.15 client, see LU-15478 */ +#define OBD_CONNECT_OLD_FALLOC 0x400ULL /* missing o_valid flags */ +#define OBD_CONNECT_TRANSNO 0x800ULL /*replay sends init transno */ #define OBD_CONNECT_IBITS 0x1000ULL /* not checked in 2.11+ */ #define OBD_CONNECT_BARRIER 0x2000ULL /* write barrier. Resevered to * avoid use on client. diff --git a/lustre/mdt/mdt_io.c b/lustre/mdt/mdt_io.c index b4178382..3892589 100644 --- a/lustre/mdt/mdt_io.c +++ b/lustre/mdt/mdt_io.c @@ -950,15 +950,33 @@ int mdt_fallocate_hdl(struct tgt_session_info *tsi) RETURN(err_serious(-ENOMEM)); /* + * fallocate() start and end are passed in o_size and o_blocks + * on the wire. Clients 2.15.0 and newer should always set + * the OBD_MD_FLSIZE and OBD_MD_FLBLOCKS valid flags, but some + * older client versions did not. We permit older clients to + * not set these flags, checking their version by proxy using + * the lack of OBD_CONNECT_TRUNCLOCK to imply 2.14.0 and older. + * + * Return -EOPNOTSUPP to also work with older clients not + * supporting newer server modes. + * * fallocate start and end are passed in o_size, o_blocks * on the wire. */ if ((oa->o_valid & (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS)) != - (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS)) - RETURN(err_serious(-EPROTO)); + (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS) +#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 21, 53, 0) + && (tgt_conn_flags(tsi) & OBD_CONNECT_OLD_FALLOC) +#endif + ) + RETURN(-EOPNOTSUPP); start = oa->o_size; end = oa->o_blocks; + /* client should already limit len >= 0 */ + if (start >= end) + RETURN(-EINVAL); + mode = oa->o_falloc_mode; CDEBUG(D_INODE, diff --git a/lustre/ofd/ofd_dev.c b/lustre/ofd/ofd_dev.c index 7fcb5ac..c9bcd40 100644 --- a/lustre/ofd/ofd_dev.c +++ b/lustre/ofd/ofd_dev.c @@ -1985,17 +1985,30 @@ static int ofd_fallocate_hdl(struct tgt_session_info *tsi) RETURN(err_serious(-ENOMEM)); /* - * fallocate start and end are passed in o_size, o_blocks - * on the wire. - * Return -EOPNOTSUPP to also handle older clients not - * supporting newer server modes + * fallocate() start and end are passed in o_size and o_blocks + * on the wire. Clients 2.15.0 and newer should always set + * the OBD_MD_FLSIZE and OBD_MD_FLBLOCKS valid flags, but some + * older client versions did not. We permit older clients to + * not set these flags, checking their version by proxy using + * the lack of OBD_CONNECT_TRUNCLOCK to imply 2.14.0 and older. + * + * Return -EOPNOTSUPP to also work with older clients not + * supporting newer server modes. */ if ((oa->o_valid & (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS)) != - (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS)) + (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS) +#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 21, 53, 0) + && (tgt_conn_flags(tsi) & OBD_CONNECT_OLD_FALLOC) +#endif + ) RETURN(-EOPNOTSUPP); start = oa->o_size; end = oa->o_blocks; + /* client should already limit len >= 0 */ + if (start >= end) + RETURN(-EINVAL); + mode = oa->o_falloc_mode; /* * mode == 0 (which is standard prealloc) and PUNCH is supported -- 1.8.3.1