From: Eric Mei Date: Tue, 2 Mar 2010 01:57:23 +0000 (-0800) Subject: b=20731 add handling of statfs ioctl in mdc. X-Git-Tag: 1.10.0.38~18 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=de488c3a079dced9e1501131506b223dd70c4c84 b=20731 add handling of statfs ioctl in mdc. when cluster is upgraded from 1.8, client don't have LMV up and running, so statfs ioctl will have to handled by mdc directly. r=adilger r=pravin --- diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 4d117c5..431d484 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -2059,6 +2059,12 @@ int ll_obd_statfs(struct inode *inode, void *arg) !data->ioc_pbuf1 || !data->ioc_pbuf2) GOTO(out_statfs, rc = -EINVAL); + if (data->ioc_inllen1 != sizeof(__u32) || + data->ioc_inllen2 != sizeof(__u32) || + data->ioc_plen1 != sizeof(struct obd_statfs) || + data->ioc_plen2 != sizeof(struct obd_uuid)) + GOTO(out_statfs, rc = -EINVAL); + memcpy(&type, data->ioc_inlbuf1, sizeof(__u32)); if (type == LL_STATFS_MDC) exp = sbi->ll_md_exp; diff --git a/lustre/lmv/lmv_obd.c b/lustre/lmv/lmv_obd.c index 58c50c3..8f38fd9 100644 --- a/lustre/lmv/lmv_obd.c +++ b/lustre/lmv/lmv_obd.c @@ -738,8 +738,6 @@ static int lmv_iocontrol(unsigned int cmd, struct obd_export *exp, __u32 index; memcpy(&index, data->ioc_inlbuf2, sizeof(__u32)); - LASSERT(data->ioc_plen1 == sizeof(struct obd_statfs)); - if ((index >= count)) RETURN(-ENODEV); diff --git a/lustre/lov/lov_obd.c b/lustre/lov/lov_obd.c index a73ff2f..0d096fd 100644 --- a/lustre/lov/lov_obd.c +++ b/lustre/lov/lov_obd.c @@ -1948,8 +1948,6 @@ static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len, __u32 index; memcpy(&index, data->ioc_inlbuf2, sizeof(__u32)); - LASSERT(data->ioc_plen1 == sizeof(struct obd_statfs)); - if ((index >= count)) RETURN(-ENODEV); diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c index a02b180..74afc27 100644 --- a/lustre/mdc/mdc_request.c +++ b/lustre/mdc/mdc_request.c @@ -1066,6 +1066,60 @@ int mdc_readpage(struct obd_export *exp, const struct lu_fid *fid, RETURN(0); } +static int mdc_statfs(struct obd_device *obd, struct obd_statfs *osfs, + __u64 max_age, __u32 flags) +{ + struct ptlrpc_request *req; + struct obd_statfs *msfs; + struct obd_import *imp = NULL; + int rc; + ENTRY; + + /* + * Since the request might also come from lprocfs, so we need + * sync this with client_disconnect_export Bug15684 + */ + cfs_down_read(&obd->u.cli.cl_sem); + if (obd->u.cli.cl_import) + imp = class_import_get(obd->u.cli.cl_import); + cfs_up_read(&obd->u.cli.cl_sem); + if (!imp) + RETURN(-ENODEV); + + req = ptlrpc_request_alloc_pack(imp, &RQF_MDS_STATFS, + LUSTRE_MDS_VERSION, MDS_STATFS); + if (req == NULL) + GOTO(output, rc = -ENOMEM); + + ptlrpc_request_set_replen(req); + + if (flags & OBD_STATFS_NODELAY) { + /* procfs requests not want stay in wait for avoid deadlock */ + req->rq_no_resend = 1; + req->rq_no_delay = 1; + } + + rc = ptlrpc_queue_wait(req); + if (rc) { + /* check connection error first */ + if (imp->imp_connect_error) + rc = imp->imp_connect_error; + GOTO(out, rc); + } + + msfs = req_capsule_server_get(&req->rq_pill, &RMF_OBD_STATFS); + if (msfs == NULL) + GOTO(out, rc = -EPROTO); + + *osfs = *msfs; + EXIT; +out: + ptlrpc_req_finished(req); +output: + class_import_put(imp); + return rc; +} + static int mdc_ioc_fid2path(struct obd_export *exp, struct getinfo_fid2path *gf) { __u32 keylen, vallen; @@ -1169,6 +1223,32 @@ static int mdc_iocontrol(unsigned int cmd, struct obd_export *exp, int len, case OBD_IOC_PING_TARGET: rc = ptlrpc_obd_ping(obd); GOTO(out, rc); + /* + * Normally IOC_OBD_STATFS iocontrol is handled by LMV instead of MDC. + * But when the cluster is upgraded from 1.8, there'd be no LMV layer + * thus we might be called here. Eventually this code should be removed. + * bz20731. + */ + case IOC_OBD_STATFS: { + struct obd_statfs stat_buf = {0}; + + if (*((__u32 *) data->ioc_inlbuf2) != 0) + GOTO(out, rc = -ENODEV); + + rc = mdc_statfs(obd, &stat_buf, + cfs_time_current_64() - CFS_HZ, 0); + if (rc != 0) + GOTO(out, rc); + + if (cfs_copy_to_user(data->ioc_pbuf1, &stat_buf, + data->ioc_plen1)) + GOTO(out, rc = -EFAULT); + if (cfs_copy_to_user(data->ioc_pbuf2, obd2cli_tgt(obd), + data->ioc_plen2)) + GOTO(out, rc = -EFAULT); + + GOTO(out, rc = 0); + } default: CERROR("mdc_ioctl(): unrecognised ioctl %#x\n", cmd); GOTO(out, rc = -ENOTTY); @@ -1402,59 +1482,6 @@ int mdc_get_info(struct obd_export *exp, __u32 keylen, void *key, RETURN(rc); } -static int mdc_statfs(struct obd_device *obd, struct obd_statfs *osfs, - __u64 max_age, __u32 flags) -{ - struct ptlrpc_request *req; - struct obd_statfs *msfs; - struct obd_import *imp = NULL; - int rc; - ENTRY; - - - /*Since the request might also come from lprocfs, so we need - *sync this with client_disconnect_export Bug15684*/ - cfs_down_read(&obd->u.cli.cl_sem); - if (obd->u.cli.cl_import) - imp = class_import_get(obd->u.cli.cl_import); - cfs_up_read(&obd->u.cli.cl_sem); - if (!imp) - RETURN(-ENODEV); - - req = ptlrpc_request_alloc_pack(imp, &RQF_MDS_STATFS, - LUSTRE_MDS_VERSION, MDS_STATFS); - if (req == NULL) - GOTO(output, rc = -ENOMEM); - - ptlrpc_request_set_replen(req); - - if (flags & OBD_STATFS_NODELAY) { - /* procfs requests not want stay in wait for avoid deadlock */ - req->rq_no_resend = 1; - req->rq_no_delay = 1; - } - - rc = ptlrpc_queue_wait(req); - if (rc) { - /* check connection error first */ - if (imp->imp_connect_error) - rc = imp->imp_connect_error; - GOTO(out, rc); - } - - msfs = req_capsule_server_get(&req->rq_pill, &RMF_OBD_STATFS); - if (msfs == NULL) - GOTO(out, rc = -EPROTO); - - *osfs = *msfs; - EXIT; -out: - ptlrpc_req_finished(req); -output: - class_import_put(imp); - return rc; -} - static int mdc_pin(struct obd_export *exp, const struct lu_fid *fid, struct obd_capa *oc, struct obd_client_handle *handle, int flags)