X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fcmm%2Fcmm_device.c;h=01f319dc30a6edc8e5b7f8384b3e7ad63322c6c9;hb=2d9a173e64a5fbb358ac181877403b82c3f38bde;hp=38c62da65733e794c3a8c629ff5d2ee099ac2a9a;hpb=225e268c61f1ffada7c9a43f0952bd7bc8102f25;p=fs%2Flustre-release.git diff --git a/lustre/cmm/cmm_device.c b/lustre/cmm/cmm_device.c index 38c62da..01f319d 100644 --- a/lustre/cmm/cmm_device.c +++ b/lustre/cmm/cmm_device.c @@ -53,12 +53,15 @@ #include #include "cmm_internal.h" #include "mdc_internal.h" +#ifdef HAVE_QUOTA_SUPPORT +# include +#endif static struct obd_ops cmm_obd_device_ops = { .o_owner = THIS_MODULE }; -static struct lu_device_operations cmm_lu_ops; +static const struct lu_device_operations cmm_lu_ops; static inline int lu_device_is_cmm(struct lu_device *d) { @@ -127,12 +130,270 @@ static int cmm_update_capa_key(const struct lu_env *env, RETURN(rc); } -static struct md_device_operations cmm_md_ops = { +#ifdef HAVE_QUOTA_SUPPORT +static int cmm_quota_notify(const struct lu_env *env, struct md_device *m) +{ + struct cmm_device *cmm_dev = md2cmm_dev(m); + int rc; + ENTRY; + + rc = cmm_child_ops(cmm_dev)->mdo_quota.mqo_notify(env, + cmm_dev->cmm_child); + RETURN(rc); +} + +static int cmm_quota_setup(const struct lu_env *env, struct md_device *m, + void *data) +{ + struct cmm_device *cmm_dev = md2cmm_dev(m); + int rc; + ENTRY; + + rc = cmm_child_ops(cmm_dev)->mdo_quota.mqo_setup(env, + cmm_dev->cmm_child, + data); + RETURN(rc); +} + +static int cmm_quota_cleanup(const struct lu_env *env, struct md_device *m) +{ + struct cmm_device *cmm_dev = md2cmm_dev(m); + int rc; + ENTRY; + + rc = cmm_child_ops(cmm_dev)->mdo_quota.mqo_cleanup(env, + cmm_dev->cmm_child); + RETURN(rc); +} + +static int cmm_quota_recovery(const struct lu_env *env, struct md_device *m) +{ + struct cmm_device *cmm_dev = md2cmm_dev(m); + int rc; + ENTRY; + + rc = cmm_child_ops(cmm_dev)->mdo_quota.mqo_recovery(env, + cmm_dev->cmm_child); + RETURN(rc); +} + +static int cmm_quota_check(const struct lu_env *env, struct md_device *m, + struct obd_export *exp, __u32 type) +{ + struct cmm_device *cmm_dev = md2cmm_dev(m); + int rc; + ENTRY; + + /* disable quota for CMD case temporary. */ + if (cmm_dev->cmm_tgt_count) + RETURN(-EOPNOTSUPP); + + rc = cmm_child_ops(cmm_dev)->mdo_quota.mqo_check(env, + cmm_dev->cmm_child, + exp, type); + RETURN(rc); +} + +static int cmm_quota_on(const struct lu_env *env, struct md_device *m, + __u32 type) +{ + struct cmm_device *cmm_dev = md2cmm_dev(m); + int rc; + ENTRY; + + /* disable quota for CMD case temporary. */ + if (cmm_dev->cmm_tgt_count) + RETURN(-EOPNOTSUPP); + + rc = cmm_child_ops(cmm_dev)->mdo_quota.mqo_on(env, + cmm_dev->cmm_child, + type); + RETURN(rc); +} + +static int cmm_quota_off(const struct lu_env *env, struct md_device *m, + __u32 type) +{ + struct cmm_device *cmm_dev = md2cmm_dev(m); + int rc; + ENTRY; + + /* disable quota for CMD case temporary. */ + if (cmm_dev->cmm_tgt_count) + RETURN(-EOPNOTSUPP); + + rc = cmm_child_ops(cmm_dev)->mdo_quota.mqo_off(env, + cmm_dev->cmm_child, + type); + RETURN(rc); +} + +static int cmm_quota_setinfo(const struct lu_env *env, struct md_device *m, + __u32 type, __u32 id, struct obd_dqinfo *dqinfo) +{ + struct cmm_device *cmm_dev = md2cmm_dev(m); + int rc; + ENTRY; + + /* disable quota for CMD case temporary. */ + if (cmm_dev->cmm_tgt_count) + RETURN(-EOPNOTSUPP); + + rc = cmm_child_ops(cmm_dev)->mdo_quota.mqo_setinfo(env, + cmm_dev->cmm_child, + type, id, dqinfo); + RETURN(rc); +} + +static int cmm_quota_getinfo(const struct lu_env *env, + const struct md_device *m, + __u32 type, __u32 id, struct obd_dqinfo *dqinfo) +{ + struct cmm_device *cmm_dev = md2cmm_dev((struct md_device *)m); + int rc; + ENTRY; + + /* disable quota for CMD case temporary. */ + if (cmm_dev->cmm_tgt_count) + RETURN(-EOPNOTSUPP); + + rc = cmm_child_ops(cmm_dev)->mdo_quota.mqo_getinfo(env, + cmm_dev->cmm_child, + type, id, dqinfo); + RETURN(rc); +} + +static int cmm_quota_setquota(const struct lu_env *env, struct md_device *m, + __u32 type, __u32 id, struct obd_dqblk *dqblk) +{ + struct cmm_device *cmm_dev = md2cmm_dev(m); + int rc; + ENTRY; + + /* disable quota for CMD case temporary. */ + if (cmm_dev->cmm_tgt_count) + RETURN(-EOPNOTSUPP); + + rc = cmm_child_ops(cmm_dev)->mdo_quota.mqo_setquota(env, + cmm_dev->cmm_child, + type, id, dqblk); + RETURN(rc); +} + +static int cmm_quota_getquota(const struct lu_env *env, + const struct md_device *m, + __u32 type, __u32 id, struct obd_dqblk *dqblk) +{ + struct cmm_device *cmm_dev = md2cmm_dev((struct md_device *)m); + int rc; + ENTRY; + + /* disable quota for CMD case temporary. */ + if (cmm_dev->cmm_tgt_count) + RETURN(-EOPNOTSUPP); + + rc = cmm_child_ops(cmm_dev)->mdo_quota.mqo_getquota(env, + cmm_dev->cmm_child, + type, id, dqblk); + RETURN(rc); +} + +static int cmm_quota_getoinfo(const struct lu_env *env, + const struct md_device *m, + __u32 type, __u32 id, struct obd_dqinfo *dqinfo) +{ + struct cmm_device *cmm_dev = md2cmm_dev((struct md_device *)m); + int rc; + ENTRY; + + /* disable quota for CMD case temporary. */ + if (cmm_dev->cmm_tgt_count) + RETURN(-EOPNOTSUPP); + + rc = cmm_child_ops(cmm_dev)->mdo_quota.mqo_getoinfo(env, + cmm_dev->cmm_child, + type, id, dqinfo); + RETURN(rc); +} + +static int cmm_quota_getoquota(const struct lu_env *env, + const struct md_device *m, + __u32 type, __u32 id, struct obd_dqblk *dqblk) +{ + struct cmm_device *cmm_dev = md2cmm_dev((struct md_device *)m); + int rc; + ENTRY; + + /* disable quota for CMD case temporary. */ + if (cmm_dev->cmm_tgt_count) + RETURN(-EOPNOTSUPP); + + rc = cmm_child_ops(cmm_dev)->mdo_quota.mqo_getoquota(env, + cmm_dev->cmm_child, + type, id, dqblk); + RETURN(rc); +} + +static int cmm_quota_invalidate(const struct lu_env *env, struct md_device *m, + __u32 type) +{ + struct cmm_device *cmm_dev = md2cmm_dev(m); + int rc; + ENTRY; + + /* disable quota for CMD case temporary. */ + if (cmm_dev->cmm_tgt_count) + RETURN(-EOPNOTSUPP); + + rc = cmm_child_ops(cmm_dev)->mdo_quota.mqo_invalidate(env, + cmm_dev->cmm_child, + type); + RETURN(rc); +} + +static int cmm_quota_finvalidate(const struct lu_env *env, struct md_device *m, + __u32 type) +{ + struct cmm_device *cmm_dev = md2cmm_dev(m); + int rc; + ENTRY; + + /* disable quota for CMD case temporary. */ + if (cmm_dev->cmm_tgt_count) + RETURN(-EOPNOTSUPP); + + rc = cmm_child_ops(cmm_dev)->mdo_quota.mqo_finvalidate(env, + cmm_dev->cmm_child, + type); + RETURN(rc); +} +#endif + +static const struct md_device_operations cmm_md_ops = { .mdo_statfs = cmm_statfs, .mdo_root_get = cmm_root_get, .mdo_maxsize_get = cmm_maxsize_get, .mdo_init_capa_ctxt = cmm_init_capa_ctxt, .mdo_update_capa_key = cmm_update_capa_key, +#ifdef HAVE_QUOTA_SUPPORT + .mdo_quota = { + .mqo_notify = cmm_quota_notify, + .mqo_setup = cmm_quota_setup, + .mqo_cleanup = cmm_quota_cleanup, + .mqo_recovery = cmm_quota_recovery, + .mqo_check = cmm_quota_check, + .mqo_on = cmm_quota_on, + .mqo_off = cmm_quota_off, + .mqo_setinfo = cmm_quota_setinfo, + .mqo_getinfo = cmm_quota_getinfo, + .mqo_setquota = cmm_quota_setquota, + .mqo_getquota = cmm_quota_getquota, + .mqo_getoinfo = cmm_quota_getoinfo, + .mqo_getoquota = cmm_quota_getoquota, + .mqo_invalidate = cmm_quota_invalidate, + .mqo_finvalidate = cmm_quota_finvalidate + } +#endif }; extern struct lu_device_type mdc_device_type; @@ -168,8 +429,13 @@ static int cmm_add_mdc(const struct lu_env *env, struct mdc_device *mc, *tmp; struct lu_fld_target target; struct lu_device *ld; + struct lu_device *cmm_lu = cmm2lu_dev(cm); mdsno_t mdc_num; + struct lu_site *site = cmm2lu_dev(cm)->ld_site; int rc; +#ifdef HAVE_QUOTA_SUPPORT + int first; +#endif ENTRY; /* find out that there is no such mdc */ @@ -193,7 +459,7 @@ static int cmm_add_mdc(const struct lu_env *env, if (IS_ERR(ld)) RETURN(PTR_ERR(ld)); - ld->ld_site = cmm2lu_dev(cm)->ld_site; + ld->ld_site = site; rc = ldt->ldt_ops->ldto_device_init(env, ld, NULL, NULL); if (rc) { @@ -221,15 +487,33 @@ static int cmm_add_mdc(const struct lu_env *env, mc = lu2mdc_dev(ld); list_add_tail(&mc->mc_linkage, &cm->cmm_targets); cm->cmm_tgt_count++; +#ifdef HAVE_QUOTA_SUPPORT + first = cm->cmm_tgt_count; +#endif spin_unlock(&cm->cmm_tgt_guard); - lu_device_get(cmm2lu_dev(cm)); + lu_device_get(cmm_lu); + lu_ref_add(&cmm_lu->ld_reference, "mdc-child", ld); target.ft_srv = NULL; target.ft_idx = mc->mc_num; target.ft_exp = mc->mc_desc.cl_exp; fld_client_add_target(cm->cmm_fld, &target); + if (mc->mc_num == 0) { + /* this is mdt0 -> mc export, fld lookup need this export + to forward fld lookup request. */ + LASSERT(!lu_site2md(site)->ms_server_fld->lsf_control_exp); + lu_site2md(site)->ms_server_fld->lsf_control_exp = + mc->mc_desc.cl_exp; + } +#ifdef HAVE_QUOTA_SUPPORT + /* XXX: Disable quota for CMD case temporary. */ + if (first == 1) { + CWARN("Disable quota for CMD case temporary!\n"); + cmm_child_ops(cm)->mdo_quota.mqo_off(env, cm->cmm_child, UGQUOTA); + } +#endif /* Set max md size for the mdc. */ rc = cmm_post_init_mdc(env, cm); RETURN(rc); @@ -292,7 +576,7 @@ static int cmm_process_config(const struct lu_env *env, struct lu_site *ls = cmm2lu_dev(m)->ld_site; struct lu_fld_target target; - target.ft_srv = ls->ls_server_fld; + target.ft_srv = lu_site2md(ls)->ms_server_fld; target.ft_idx = m->cmm_local_num; target.ft_exp = NULL; @@ -334,10 +618,24 @@ static int cmm_recovery_complete(const struct lu_env *env, RETURN(rc); } -static struct lu_device_operations cmm_lu_ops = { +static int cmm_prepare(const struct lu_env *env, + struct lu_device *pdev, + struct lu_device *dev) +{ + struct cmm_device *cmm = lu2cmm_dev(dev); + struct lu_device *next = md2lu_dev(cmm->cmm_child); + int rc; + + ENTRY; + rc = next->ld_ops->ldo_prepare(env, dev, next); + RETURN(rc); +} + +static const struct lu_device_operations cmm_lu_ops = { .ldo_object_alloc = cmm_object_alloc, .ldo_process_config = cmm_process_config, - .ldo_recovery_complete = cmm_recovery_complete + .ldo_recovery_complete = cmm_recovery_complete, + .ldo_prepare = cmm_prepare, }; /* --- lu_device_type operations --- */ @@ -399,7 +697,7 @@ static struct lu_device *cmm_device_alloc(const struct lu_env *env, if (!m->cmm_fld) { cmm_device_free(env, l); l = ERR_PTR(-ENOMEM); - } + } } RETURN(l); } @@ -444,16 +742,16 @@ static int cmm_device_init(const struct lu_env *env, struct lu_device *d, /* Assign site's fld client ref, needed for asserts in osd. */ ls = cmm2lu_dev(m)->ld_site; - ls->ls_client_fld = m->cmm_fld; + lu_site2md(ls)->ms_client_fld = m->cmm_fld; err = cmm_procfs_init(m, name); - + RETURN(err); } static struct lu_device *cmm_device_fini(const struct lu_env *env, struct lu_device *ld) { - struct cmm_device *cm = lu2cmm_dev(ld); + struct cmm_device *cm = lu2cmm_dev(ld); struct mdc_device *mc, *tmp; struct lu_site *ls; ENTRY; @@ -462,9 +760,11 @@ static struct lu_device *cmm_device_fini(const struct lu_env *env, spin_lock(&cm->cmm_tgt_guard); list_for_each_entry_safe(mc, tmp, &cm->cmm_targets, mc_linkage) { struct lu_device *ld_m = mdc2lu_dev(mc); + struct lu_device *ld_c = cmm2lu_dev(cm); list_del_init(&mc->mc_linkage); - lu_device_put(cmm2lu_dev(cm)); + lu_ref_del(&ld_c->ld_reference, "mdc-child", ld_m); + lu_device_put(ld_c); ld_m->ld_type->ldt_ops->ldto_device_fini(env, ld_m); ld_m->ld_type->ldt_ops->ldto_device_free(env, ld_m); cm->cmm_tgt_count--; @@ -473,7 +773,7 @@ static struct lu_device *cmm_device_fini(const struct lu_env *env, fld_client_fini(cm->cmm_fld); ls = cmm2lu_dev(cm)->ld_site; - ls->ls_client_fld = NULL; + lu_site2md(ls)->ms_client_fld = NULL; cmm_procfs_fini(cm); RETURN (md2lu_dev(cm->cmm_child));