From 69b34f1a015ee0ffabf4c6477f9d681608aa5af6 Mon Sep 17 00:00:00 2001 From: wang di Date: Wed, 18 Dec 2013 00:01:45 -0800 Subject: [PATCH] LU-4222 mdt: extra checking for getattr RPC. Check whether getattr RPC can hold layout MD(RMF_MDT_MD), in case the client sends some invalid RPC, which can cause panic on MDT. Client will retrieve cl_max_md_size/cl_default_md_size from MDS during mount process, so it will initialize cl_max_md_size/cl_default_md_size before sending getattr to MDS. Signed-off-by: wang di Change-Id: I43bbe54c37360242bb7a3cd2aa8d90c2b9e0baf1 Reviewed-on: http://review.whamcloud.com/8599 Reviewed-by: Fan Yong Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger --- lustre/llite/llite_lib.c | 3 ++- lustre/mdc/mdc_request.c | 15 +++++++-------- lustre/mdt/mdt_handler.c | 39 +++++++++++++++++++++++++-------------- 3 files changed, 34 insertions(+), 23 deletions(-) diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index eef54b1..1aec027 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -492,7 +492,8 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, /* make root inode * XXX: move this to after cbd setup? */ - valid = OBD_MD_FLGETATTR | OBD_MD_FLBLOCKS | OBD_MD_FLMDSCAPA; + valid = OBD_MD_FLGETATTR | OBD_MD_FLBLOCKS | OBD_MD_FLMDSCAPA | + OBD_MD_FLMODEASIZE; if (sbi->ll_flags & LL_SBI_RMT_CLIENT) valid |= OBD_MD_FLRMTPERM; else if (sbi->ll_flags & LL_SBI_ACL) diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c index 68c5f27..4288f0e 100644 --- a/lustre/mdc/mdc_request.c +++ b/lustre/mdc/mdc_request.c @@ -190,14 +190,13 @@ static int mdc_getattr_common(struct obd_export *exp, CDEBUG(D_NET, "mode: %o\n", body->mode); - if (body->eadatasize != 0) { - mdc_update_max_ea_from_body(exp, body); - - eadata = req_capsule_server_sized_get(pill, &RMF_MDT_MD, - body->eadatasize); - if (eadata == NULL) - RETURN(-EPROTO); - } + mdc_update_max_ea_from_body(exp, body); + if (body->eadatasize != 0) { + eadata = req_capsule_server_sized_get(pill, &RMF_MDT_MD, + body->eadatasize); + if (eadata == NULL) + RETURN(-EPROTO); + } if (body->valid & OBD_MD_FLRMTPERM) { struct mdt_remote_perm *perm; diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c index bd23719..2e7b16d 100644 --- a/lustre/mdt/mdt_handler.c +++ b/lustre/mdt/mdt_handler.c @@ -735,23 +735,34 @@ static int mdt_getattr_internal(struct mdt_thread_info *info, } buffer->lb_len = reqbody->eadatasize; - if (buffer->lb_len > 0) + if (buffer->lb_len > 0) { buffer->lb_buf = req_capsule_server_get(pill, &RMF_MDT_MD); - else + if (buffer->lb_buf == NULL) + GOTO(out, rc = -EPROTO); + } else { buffer->lb_buf = NULL; + ma_need &= ~(MA_LOV | MA_LMV); + CDEBUG(D_INFO, "%s: RPC from %s: does not need LOVEA.\n", + mdt_obd_name(info->mti_mdt), + req->rq_export->exp_client_uuid.uuid); + } - /* If it is dir object and client require MEA, then we got MEA */ - if (S_ISDIR(lu_object_attr(&next->mo_lu)) && - reqbody->valid & OBD_MD_MEA) { - /* Assumption: MDT_MD size is enough for lmv size. */ - ma->ma_lmv = buffer->lb_buf; - ma->ma_lmv_size = buffer->lb_len; - ma->ma_need = MA_LMV | MA_INODE; - } else { - ma->ma_lmm = buffer->lb_buf; - ma->ma_lmm_size = buffer->lb_len; - ma->ma_need = MA_LOV | MA_INODE | MA_HSM; - } + /* If it is dir object and client require MEA, then we got MEA */ + if (S_ISDIR(lu_object_attr(&next->mo_lu)) && + reqbody->valid & OBD_MD_MEA) { + /* Assumption: MDT_MD size is enough for lmv size. */ + ma->ma_lmv = buffer->lb_buf; + ma->ma_lmv_size = buffer->lb_len; + ma->ma_need = MA_INODE; + if (ma->ma_lmm_size > 0) + ma->ma_need |= MA_LMV; + } else { + ma->ma_lmm = buffer->lb_buf; + ma->ma_lmm_size = buffer->lb_len; + ma->ma_need = MA_INODE | MA_HSM; + if (ma->ma_lmm_size > 0) + ma->ma_need |= MA_LOV; + } if (S_ISDIR(lu_object_attr(&next->mo_lu)) && reqbody->valid & OBD_MD_FLDIREA && -- 1.8.3.1