From 9ddf386035767a96b54e21559f3ea0be126dc8cd Mon Sep 17 00:00:00 2001 From: Johann Lombardi Date: Mon, 24 Sep 2012 15:03:21 +0200 Subject: [PATCH] LU-1842 quota: remove quota code This patch removes the quota code (from quota directory, but also from mdd & obdfilter) which is going to be replaced by the new implementation. This patch also modifies the mdt to use the new space accounting scheme as already used by the ofd layer. sanity-quota.sh now also uses ofd by default and only runs the space accounting tests until quota enforcement support is landed. Signed-off-by: Johann Lombardi Change-Id: I85cbbf6058859e5d19f80aa128f45b6d41c37d92 Reviewed-on: http://review.whamcloud.com/4098 Reviewed-by: Niu Yawei Tested-by: Hudson Reviewed-by: Alex Zhuravlev Tested-by: Maloo --- libcfs/include/libcfs/libcfs.h | 4 + lustre/autoconf/lustre-core.m4 | 6 +- lustre/cmm/cmm_device.c | 275 ------ lustre/include/linux/lustre_user.h | 8 +- lustre/include/lquota.h | 8 - lustre/include/lustre_lib.h | 8 - lustre/include/lustre_quota.h | 14 - lustre/include/md_object.h | 73 -- lustre/include/obd.h | 19 - lustre/include/obd_class.h | 33 - lustre/ldlm/ldlm_lib.c | 113 --- lustre/ldlm/ldlm_lockd.c | 13 - lustre/lov/lov_obd.c | 65 -- lustre/lvfs/fsfilt_ext3.c | 31 +- lustre/lvfs/lustre_quota_fmt.c | 3 - lustre/lvfs/lustre_quota_fmt.h | 3 - lustre/lvfs/quotafmt_test.c | 4 - lustre/mdd/Makefile.in | 2 +- lustre/mdd/mdd_device.c | 41 +- lustre/mdd/mdd_dir.c | 197 +--- lustre/mdd/mdd_internal.h | 44 - lustre/mdd/mdd_lov.c | 8 +- lustre/mdd/mdd_lproc.c | 21 - lustre/mdd/mdd_object.c | 70 -- lustre/mdd/mdd_quota.c | 273 ------ lustre/mds/handler.c | 19 - lustre/mds/mds_lov.c | 11 - lustre/mdt/mdt_handler.c | 277 +++--- lustre/obdclass/lprocfs_status.c | 6 - lustre/obdfilter/filter.c | 47 - lustre/obdfilter/filter_internal.h | 3 - lustre/obdfilter/filter_io_26.c | 38 - lustre/obdfilter/lproc_obdfilter.c | 4 - lustre/ofd/lproc_ofd.c | 3 - lustre/ofd/ofd_obd.c | 36 +- lustre/osc/osc_internal.h | 4 - lustre/osc/osc_quota.c | 37 - lustre/osc/osc_request.c | 1 - lustre/osd-ldiskfs/osd_handler.c | 129 +-- lustre/osd-ldiskfs/osd_internal.h | 11 - lustre/osd-ldiskfs/osd_io.c | 12 - lustre/osd-ldiskfs/osd_oi.c | 9 - lustre/ost/ost_handler.c | 40 +- lustre/quota/Makefile.in | 5 +- lustre/quota/lproc_quota.c | 649 ------------- lustre/quota/lquota_internal.h | 6 - lustre/quota/lquota_lib.c | 14 +- lustre/quota/quota_adjust_qunit.c | 281 ------ lustre/quota/quota_check.c | 192 ---- lustre/quota/quota_context.c | 1739 ----------------------------------- lustre/quota/quota_ctl.c | 287 ------ lustre/quota/quota_interface.c | 809 ----------------- lustre/quota/quota_internal.h | 192 ---- lustre/quota/quota_master.c | 1766 ------------------------------------ lustre/tests/sanity-quota.sh | 46 +- lustre/tests/test-framework.sh | 8 +- lustre/utils/mount_utils_ldiskfs.c | 23 +- 57 files changed, 194 insertions(+), 7846 deletions(-) delete mode 100644 lustre/mdd/mdd_quota.c delete mode 100644 lustre/quota/quota_adjust_qunit.c delete mode 100644 lustre/quota/quota_check.c delete mode 100644 lustre/quota/quota_context.c delete mode 100644 lustre/quota/quota_ctl.c delete mode 100644 lustre/quota/quota_interface.c delete mode 100644 lustre/quota/quota_internal.h delete mode 100644 lustre/quota/quota_master.c diff --git a/libcfs/include/libcfs/libcfs.h b/libcfs/include/libcfs/libcfs.h index 7ce9c66..37dd2f6 100644 --- a/libcfs/include/libcfs/libcfs.h +++ b/libcfs/include/libcfs/libcfs.h @@ -63,6 +63,10 @@ #define ARRAY_SIZE(a) ((sizeof (a)) / (sizeof ((a)[0]))) #endif +#if !defined(swap) +#define swap(x,y) do { typeof(x) z = x; x = y; y = z; } while (0) +#endif + #if !defined(container_of) /* given a pointer @ptr to the field @member embedded into type (usually * struct) @type, return pointer to the embedding instance of @type. */ diff --git a/lustre/autoconf/lustre-core.m4 b/lustre/autoconf/lustre-core.m4 index f30df7f..4701029 100644 --- a/lustre/autoconf/lustre-core.m4 +++ b/lustre/autoconf/lustre-core.m4 @@ -211,9 +211,9 @@ fi # Quota support. The kernel must support CONFIG_QUOTA. # AC_DEFUN([LC_QUOTA_CONFIG], -[LB_LINUX_CONFIG_IM([QUOTA],[AC_DEFINE(HAVE_QUOTA_SUPPORT, 1, [support quota])],[ - AC_MSG_ERROR([Lustre quota requires that CONFIG_QUOTA is enabled in your kernel.]) -]) +[LB_LINUX_CONFIG_IM([QUOTA],[],[ + AC_MSG_ERROR([Lustre quota requires that CONFIG_QUOTA is enabled in your kernel.]) + ]) ]) # truncate_complete_page() was exported from RHEL5/SLES10, but not in SLES11 SP0 (2.6.27) diff --git a/lustre/cmm/cmm_device.c b/lustre/cmm/cmm_device.c index 1aabc1a..a3c9397 100644 --- a/lustre/cmm/cmm_device.c +++ b/lustre/cmm/cmm_device.c @@ -54,9 +54,6 @@ #include #include "cmm_internal.h" #include "mdc_internal.h" -#ifdef HAVE_QUOTA_SUPPORT -# include -#endif struct obd_ops cmm_obd_device_ops = { .o_owner = THIS_MODULE @@ -143,246 +140,6 @@ static int cmm_llog_ctxt_get(const struct lu_env *env, struct md_device *m, RETURN(rc); } -#ifdef HAVE_QUOTA_SUPPORT -/** - * \name Quota functions - * @{ - */ -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, - __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, - 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; - - 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 - int cmm_iocontrol(const struct lu_env *env, struct md_device *m, unsigned int cmd, int len, void *data) { @@ -403,25 +160,6 @@ static const struct md_device_operations cmm_md_ops = { .mdo_update_capa_key = cmm_update_capa_key, .mdo_llog_ctxt_get = cmm_llog_ctxt_get, .mdo_iocontrol = cmm_iocontrol, -#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; @@ -463,9 +201,6 @@ static int cmm_add_mdc(const struct lu_env *env, 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 */ @@ -517,9 +252,6 @@ static int cmm_add_mdc(const struct lu_env *env, mc = lu2mdc_dev(ld); cfs_list_add_tail(&mc->mc_linkage, &cm->cmm_targets); cm->cmm_tgt_count++; -#ifdef HAVE_QUOTA_SUPPORT - first = cm->cmm_tgt_count; -#endif cfs_spin_unlock(&cm->cmm_tgt_guard); lu_device_get(cmm_lu); @@ -537,13 +269,6 @@ static int cmm_add_mdc(const struct lu_env *env, 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); diff --git a/lustre/include/linux/lustre_user.h b/lustre/include/linux/lustre_user.h index c523e21..3446e42 100644 --- a/lustre/include/linux/lustre_user.h +++ b/lustre/include/linux/lustre_user.h @@ -41,14 +41,10 @@ #ifndef __KERNEL__ # define NEED_QUOTA_DEFS -# ifdef HAVE_QUOTA_SUPPORT -# include -# endif +# include #else # include -# ifdef HAVE_QUOTA_SUPPORT -# include -# endif +# include #endif /* diff --git a/lustre/include/lquota.h b/lustre/include/lquota.h index 3052467..e6bf161 100644 --- a/lustre/include/lquota.h +++ b/lustre/include/lquota.h @@ -147,12 +147,4 @@ static inline void qsd_op_end(const struct lu_env *env, struct lquota_trans *trans) { } - -#ifdef LPROCFS -/* dumb procfs handler which always report success, for backward compatibility - * purpose */ -int lprocfs_quota_rd_type_dumb(char *, char **, off_t, int, int *, void *); -int lprocfs_quota_wr_type_dumb(struct file *, const char *, unsigned long, - void *); -#endif /* LPROCFS */ #endif /* _LUSTRE_LQUOTA_H */ diff --git a/lustre/include/lustre_lib.h b/lustre/include/lustre_lib.h index f9b88b6..c28f5b3 100644 --- a/lustre/include/lustre_lib.h +++ b/lustre/include/lustre_lib.h @@ -93,14 +93,6 @@ int do_set_info_async(struct obd_import *imp, obd_count vallen, void *val, struct ptlrpc_request_set *set); -/* quotacheck callback, dqacq/dqrel callback handler */ -int target_handle_qc_callback(struct ptlrpc_request *req); -#ifdef HAVE_QUOTA_SUPPORT -int target_handle_dqacq_callback(struct ptlrpc_request *req); -#else -#define target_handle_dqacq_callback(req) ldlm_callback_reply(req, -ENOTSUPP) -#endif - #define OBD_RECOVERY_MAX_TIME (obd_timeout * 18) /* b13079 */ void target_send_reply(struct ptlrpc_request *req, int rc, int fail_id); diff --git a/lustre/include/lustre_quota.h b/lustre/include/lustre_quota.h index 7ea6fad..545a336 100644 --- a/lustre/include/lustre_quota.h +++ b/lustre/include/lustre_quota.h @@ -76,8 +76,6 @@ struct client_obd; #define toqb(x) (((x) + QUOTABLOCK_SIZE - 1) >> QUOTABLOCK_BITS) #endif -#ifdef HAVE_QUOTA_SUPPORT - #ifndef MAX_IQ_TIME #define MAX_IQ_TIME 604800 /* (7*24*60*60) 1 week */ #endif @@ -420,18 +418,6 @@ struct lustre_quota_ctxt { #endif /* !__KERNEL__ */ -#else - -#define LL_DQUOT_OFF(sb) do {} while(0) - -struct lustre_quota_info { -}; - -struct lustre_quota_ctxt { -}; - -#endif /* !HAVE_QUOTA_SUPPORT */ - /* If the (quota limit < qunit * slave count), the slave which can't * acquire qunit should set it's local limit as MIN_QLIMIT */ #define MIN_QLIMIT 1 diff --git a/lustre/include/md_object.h b/lustre/include/md_object.h index 7cf4c68..33c0f9a 100644 --- a/lustre/include/md_object.h +++ b/lustre/include/md_object.h @@ -378,79 +378,6 @@ struct md_device_operations { int (*mdo_iocontrol)(const struct lu_env *env, struct md_device *m, unsigned int cmd, int len, void *data); - -#ifdef HAVE_QUOTA_SUPPORT - struct md_quota_operations { - int (*mqo_notify)(const struct lu_env *env, - struct md_device *m); - - int (*mqo_setup)(const struct lu_env *env, - struct md_device *m, - void *data); - - int (*mqo_cleanup)(const struct lu_env *env, - struct md_device *m); - - int (*mqo_recovery)(const struct lu_env *env, - struct md_device *m); - - int (*mqo_check)(const struct lu_env *env, - struct md_device *m, - __u32 type); - - int (*mqo_on)(const struct lu_env *env, - struct md_device *m, - __u32 type); - - int (*mqo_off)(const struct lu_env *env, - struct md_device *m, - __u32 type); - - int (*mqo_setinfo)(const struct lu_env *env, - struct md_device *m, - __u32 type, - __u32 id, - struct obd_dqinfo *dqinfo); - - int (*mqo_getinfo)(const struct lu_env *env, - const struct md_device *m, - __u32 type, - __u32 id, - struct obd_dqinfo *dqinfo); - - int (*mqo_setquota)(const struct lu_env *env, - struct md_device *m, - __u32 type, - __u32 id, - struct obd_dqblk *dqblk); - - int (*mqo_getquota)(const struct lu_env *env, - const struct md_device *m, - __u32 type, - __u32 id, - struct obd_dqblk *dqblk); - - int (*mqo_getoinfo)(const struct lu_env *env, - const struct md_device *m, - __u32 type, - __u32 id, - struct obd_dqinfo *dqinfo); - - int (*mqo_getoquota)(const struct lu_env *env, - const struct md_device *m, - __u32 type, - __u32 id, - struct obd_dqblk *dqblk); - - int (*mqo_invalidate)(const struct lu_env *env, - struct md_device *m, - __u32 type); - - int (*mqo_finvalidate)(const struct lu_env *env, - struct md_device *m, - __u32 type); - } mdo_quota; -#endif }; enum md_upcall_event { diff --git a/lustre/include/obd.h b/lustre/include/obd.h index e7a66a4..7bc6b3f 100644 --- a/lustre/include/obd.h +++ b/lustre/include/obd.h @@ -959,8 +959,6 @@ enum obd_notify_event { OBD_NOTIFY_SYNC, /* Configuration event */ OBD_NOTIFY_CONFIG, - /* Trigger quota recovery */ - OBD_NOTIFY_QUOTA, /* Administratively deactivate/activate event */ OBD_NOTIFY_DEACTIVATE, OBD_NOTIFY_ACTIVATE @@ -1471,11 +1469,6 @@ struct obd_ops { struct obd_quotactl *); int (*o_quotactl)(struct obd_device *, struct obd_export *, struct obd_quotactl *); - int (*o_quota_adjust_qunit)(struct obd_export *exp, - struct quota_adjust_qunit *oqaq, - struct lustre_quota_ctxt *qctxt, - struct ptlrpc_request_set *rqset); - int (*o_ping)(const struct lu_env *, struct obd_export *exp); @@ -1689,18 +1682,6 @@ static inline void obd_transno_commit_cb(struct obd_device *obd, __u64 transno, obd->obd_last_committed = transno; } -static inline void init_obd_quota_ops(quota_interface_t *interface, - struct obd_ops *obd_ops) -{ - if (!interface) - return; - - LASSERT(obd_ops); - obd_ops->o_quotacheck = QUOTA_OP(interface, check); - obd_ops->o_quotactl = QUOTA_OP(interface, ctl); - obd_ops->o_quota_adjust_qunit = QUOTA_OP(interface, adjust_qunit); -} - static inline struct lustre_capa *oinfo_capa(struct obd_info *oinfo) { return oinfo->oi_capa; diff --git a/lustre/include/obd_class.h b/lustre/include/obd_class.h index 612e4c0..cee9da9 100644 --- a/lustre/include/obd_class.h +++ b/lustre/include/obd_class.h @@ -1715,39 +1715,6 @@ static inline int obd_quotactl(struct obd_export *exp, RETURN(rc); } -static inline int obd_quota_adjust_qunit(struct obd_export *exp, - struct quota_adjust_qunit *oqaq, - struct lustre_quota_ctxt *qctxt, - struct ptlrpc_request_set *set) -{ -#if defined(LPROCFS) && defined(HAVE_QUOTA_SUPPORT) - struct timeval work_start; - struct timeval work_end; - long timediff; -#endif - int rc; - ENTRY; - -#if defined(LPROCFS) && defined(HAVE_QUOTA_SUPPORT) - if (qctxt) - cfs_gettimeofday(&work_start); -#endif - EXP_CHECK_DT_OP(exp, quota_adjust_qunit); - EXP_COUNTER_INCREMENT(exp, quota_adjust_qunit); - - rc = OBP(exp->exp_obd, quota_adjust_qunit)(exp, oqaq, qctxt, set); - -#if defined(LPROCFS) && defined(HAVE_QUOTA_SUPPORT) - if (qctxt) { - cfs_gettimeofday(&work_end); - timediff = cfs_timeval_sub(&work_end, &work_start, NULL); - lprocfs_counter_add(qctxt->lqc_stats, LQUOTA_ADJUST_QUNIT, - timediff); - } -#endif - RETURN(rc); -} - static inline int obd_health_check(const struct lu_env *env, struct obd_device *obd) { diff --git a/lustre/ldlm/ldlm_lib.c b/lustre/ldlm/ldlm_lib.c index 5ed98b8..7138b19 100644 --- a/lustre/ldlm/ldlm_lib.c +++ b/lustre/ldlm/ldlm_lib.c @@ -2493,119 +2493,6 @@ void target_send_reply(struct ptlrpc_request *req, int rc, int fail_id) EXIT; } -int target_handle_qc_callback(struct ptlrpc_request *req) -{ - struct obd_quotactl *oqctl; - struct client_obd *cli = &req->rq_export->exp_obd->u.cli; - - oqctl = req_capsule_client_get(&req->rq_pill, &RMF_OBD_QUOTACTL); - if (oqctl == NULL) { - CERROR("Can't unpack obd_quotactl\n"); - RETURN(-EPROTO); - } - - cli->cl_qchk_stat = oqctl->qc_stat; - - return 0; -} - -#ifdef HAVE_QUOTA_SUPPORT -int target_handle_dqacq_callback(struct ptlrpc_request *req) -{ -#ifdef __KERNEL__ - struct obd_device *obd = req->rq_export->exp_obd; - struct obd_device *master_obd = NULL, *lov_obd = NULL; - struct obd_device_target *obt; - struct lustre_quota_ctxt *qctxt; - struct qunit_data *qdata = NULL; - int rc = 0; - ENTRY; - - if (OBD_FAIL_CHECK(OBD_FAIL_MDS_DROP_QUOTA_REQ)) - RETURN(rc); - - rc = req_capsule_server_pack(&req->rq_pill); - if (rc) { - CERROR("packing reply failed!: rc = %d\n", rc); - RETURN(rc); - } - - LASSERT(req->rq_export); - - qdata = quota_get_qdata(req, QUOTA_REQUEST, QUOTA_EXPORT); - if (IS_ERR(qdata)) { - rc = PTR_ERR(qdata); - CDEBUG(D_ERROR, "Can't unpack qunit_data(rc: %d)\n", rc); - req->rq_status = rc; - GOTO(out, rc); - } - - /* we use the observer */ - if (obd_pin_observer(obd, &lov_obd) || - obd_pin_observer(lov_obd, &master_obd)) { - CERROR("Can't find the observer, it is recovering\n"); - req->rq_status = -EAGAIN; - GOTO(out, rc); - } - - obt = &master_obd->u.obt; - qctxt = &obt->obt_qctxt; - - if (!qctxt->lqc_setup || !qctxt->lqc_valid) { - /* quota_type has not been processed yet, return EAGAIN - * until we know whether or not quotas are supposed to - * be enabled */ - CDEBUG(D_QUOTA, "quota_type not processed yet, return " - "-EAGAIN\n"); - req->rq_status = -EAGAIN; - GOTO(out, rc); - } - - cfs_down_read(&obt->obt_rwsem); - if (qctxt->lqc_lqs_hash == NULL) { - cfs_up_read(&obt->obt_rwsem); - /* quota_type has not been processed yet, return EAGAIN - * until we know whether or not quotas are supposed to - * be enabled */ - CDEBUG(D_QUOTA, "quota_ctxt is not ready yet, return " - "-EAGAIN\n"); - req->rq_status = -EAGAIN; - GOTO(out, rc); - } - - LASSERT(qctxt->lqc_handler); - rc = qctxt->lqc_handler(master_obd, qdata, - lustre_msg_get_opc(req->rq_reqmsg)); - cfs_up_read(&obt->obt_rwsem); - if (rc && rc != -EDQUOT) - CDEBUG(rc == -EBUSY ? D_QUOTA : D_ERROR, - "dqacq/dqrel failed! (rc:%d)\n", rc); - req->rq_status = rc; - - rc = quota_copy_qdata(req, qdata, QUOTA_REPLY, QUOTA_EXPORT); - if (rc < 0) { - CERROR("Can't pack qunit_data(rc: %d)\n", rc); - GOTO(out, rc); - } - - /* Block the quota req. b=14840 */ - OBD_FAIL_TIMEOUT(OBD_FAIL_MDS_BLOCK_QUOTA_REQ, obd_timeout); - EXIT; - -out: - if (master_obd) - obd_unpin_observer(lov_obd); - if (lov_obd) - obd_unpin_observer(obd); - - rc = ptlrpc_reply(req); - return rc; -#else - return 0; -#endif /* !__KERNEL__ */ -} -#endif /* HAVE_QUOTA_SUPPORT */ - ldlm_mode_t lck_compat_array[] = { [LCK_EX] LCK_COMPAT_EX, [LCK_PW] LCK_COMPAT_PW, diff --git a/lustre/ldlm/ldlm_lockd.c b/lustre/ldlm/ldlm_lockd.c index c62a1a2..a9fa177 100644 --- a/lustre/ldlm/ldlm_lockd.c +++ b/lustre/ldlm/ldlm_lockd.c @@ -1980,19 +1980,6 @@ static int ldlm_callback_handler(struct ptlrpc_request *req) RETURN(0); ldlm_callback_reply(req, rc); RETURN(0); - case OBD_QC_CALLBACK: - req_capsule_set(&req->rq_pill, &RQF_QC_CALLBACK); - if (OBD_FAIL_CHECK(OBD_FAIL_OBD_QC_CALLBACK_NET)) - RETURN(0); - rc = target_handle_qc_callback(req); - ldlm_callback_reply(req, rc); - RETURN(0); - case QUOTA_DQACQ: - case QUOTA_DQREL: - /* reply in handler */ - req_capsule_set(&req->rq_pill, &RQF_MDS_QUOTA_DQACQ); - rc = target_handle_dqacq_callback(req); - RETURN(0); case LLOG_ORIGIN_HANDLE_CREATE: req_capsule_set(&req->rq_pill, &RQF_LLOG_ORIGIN_HANDLE_CREATE); if (OBD_FAIL_CHECK(OBD_FAIL_OBD_LOGD_NET)) diff --git a/lustre/lov/lov_obd.c b/lustre/lov/lov_obd.c index 9879658c..a725351 100644 --- a/lustre/lov/lov_obd.c +++ b/lustre/lov/lov_obd.c @@ -2923,58 +2923,6 @@ out: RETURN(rc); } -int lov_quota_adjust_qunit(struct obd_export *exp, - struct quota_adjust_qunit *oqaq, - struct lustre_quota_ctxt *qctxt, - struct ptlrpc_request_set *rqset) -{ - struct obd_device *obd = class_exp2obd(exp); - struct lov_obd *lov = &obd->u.lov; - int i, err, rc = 0; - unsigned no_set = 0; - ENTRY; - - if (!QAQ_IS_ADJBLK(oqaq)) { - CERROR("bad qaq_flags %x for lov obd.\n", oqaq->qaq_flags); - RETURN(-EFAULT); - } - - if (rqset == NULL) { - rqset = ptlrpc_prep_set(); - if (!rqset) - RETURN(-ENOMEM); - no_set = 1; - } - - obd_getref(obd); - for (i = 0; i < lov->desc.ld_tgt_count; i++) { - - if (!lov->lov_tgts[i] || !lov->lov_tgts[i]->ltd_active) { - CDEBUG(D_HA, "ost %d is inactive\n", i); - continue; - } - - err = obd_quota_adjust_qunit(lov->lov_tgts[i]->ltd_exp, oqaq, - NULL, rqset); - if (err) { - if (lov->lov_tgts[i]->ltd_active && !rc) - rc = err; - continue; - } - } - - err = ptlrpc_set_wait(rqset); - if (!rc) - rc = err; - - /* Destroy the set if none was provided by the caller */ - if (no_set) - ptlrpc_set_destroy(rqset); - - obd_putref(obd); - RETURN(rc); -} - struct obd_ops lov_obd_ops = { .o_owner = THIS_MODULE, .o_setup = lov_setup, @@ -3018,12 +2966,8 @@ struct obd_ops lov_obd_ops = { .o_putref = lov_putref, .o_quotactl = lov_quotactl, .o_quotacheck = lov_quotacheck, - .o_quota_adjust_qunit = lov_quota_adjust_qunit, }; -static quota_interface_t *quota_interface; -extern quota_interface_t lov_quota_interface; - cfs_mem_cache_t *lov_oinfo_slab; extern struct lu_kmem_descr lov_caches[]; @@ -3052,16 +2996,10 @@ int __init lov_init(void) } lprocfs_lov_init_vars(&lvars); - cfs_request_module("lquota"); - quota_interface = PORTAL_SYMBOL_GET(lov_quota_interface); - init_obd_quota_ops(quota_interface, &lov_obd_ops); - rc = class_register_type(&lov_obd_ops, NULL, lvars.module_vars, LUSTRE_LOV_NAME, &lov_device_type); if (rc) { - if (quota_interface) - PORTAL_SYMBOL_PUT(lov_quota_interface); rc2 = cfs_mem_cache_destroy(lov_oinfo_slab); LASSERT(rc2 == 0); lu_kmem_fini(lov_caches); @@ -3075,9 +3013,6 @@ static void /*__exit*/ lov_exit(void) { int rc; - if (quota_interface) - PORTAL_SYMBOL_PUT(lov_quota_interface); - class_unregister_type(LUSTRE_LOV_NAME); rc = cfs_mem_cache_destroy(lov_oinfo_slab); LASSERT(rc == 0); diff --git a/lustre/lvfs/fsfilt_ext3.c b/lustre/lvfs/fsfilt_ext3.c index 1eb15b6..6f72da5 100644 --- a/lustre/lvfs/fsfilt_ext3.c +++ b/lustre/lvfs/fsfilt_ext3.c @@ -1357,13 +1357,6 @@ static int fsfilt_ext3_write_record(struct file *file, void *buf, int bufsize, static int fsfilt_ext3_setup(struct super_block *sb) { -#if defined(HAVE_QUOTA_SUPPORT) || defined(S_PDIROPS) - struct ext3_sb_info *sbi = EXT3_SB(sb); -#if 0 - sbi->dx_lock = fsfilt_ext3_dx_lock; - sbi->dx_unlock = fsfilt_ext3_dx_unlock; -#endif -#endif if (!EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) { CERROR("ext3 mounted without journal\n"); @@ -1372,26 +1365,11 @@ static int fsfilt_ext3_setup(struct super_block *sb) #ifdef S_PDIROPS CWARN("Enabling PDIROPS\n"); - set_opt(sbi->s_mount_opt, PDIROPS); + set_opt(EXT3_SB(sb)->s_mount_opt, PDIROPS); sb->s_flags |= S_PDIROPS; #endif if (!EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_DIR_INDEX)) CWARN("filesystem doesn't have dir_index feature enabled\n"); -#ifdef HAVE_QUOTA_SUPPORT - /* enable journaled quota support */ - /* kfreed in ext3_put_super() */ - sbi->s_qf_names[USRQUOTA] = kstrdup("lquota.user.reserved", GFP_KERNEL); - if (!sbi->s_qf_names[USRQUOTA]) - return -ENOMEM; - sbi->s_qf_names[GRPQUOTA] = kstrdup("lquota.group.reserved", GFP_KERNEL); - if (!sbi->s_qf_names[GRPQUOTA]) { - kfree(sbi->s_qf_names[USRQUOTA]); - sbi->s_qf_names[USRQUOTA] = NULL; - return -ENOMEM; - } - sbi->s_jquota_fmt = QFMT_LUSTRE; - set_opt(sbi->s_mount_opt, QUOTA); -#endif return 0; } @@ -1426,7 +1404,6 @@ static int fsfilt_ext3_get_op_len(int op, struct fsfilt_objinfo *fso, int logs) return 0; } -#ifdef HAVE_QUOTA_SUPPORT #define DQINFO_COPY(out, in) \ do { \ Q_COPY(out, in, dqi_bgrace); \ @@ -2003,7 +1980,6 @@ static int fsfilt_ext3_quotacheck(struct super_block *sb, /* read old quota limits from old quota file. (only for the user * has limits but hasn't file) */ -#ifdef HAVE_QUOTA_SUPPORT for (i = 0; i < MAXQUOTAS; i++) { cfs_list_t id_list; struct dquot_id *dqid, *tmp; @@ -2031,7 +2007,6 @@ static int fsfilt_ext3_quotacheck(struct super_block *sb, OBD_FREE_PTR(dqid); } } -#endif /* turn off quota cause we are to dump chk_dqblk to files */ quota_onoff(sb, Q_QUOTAOFF, oqc->qc_type, oqc->qc_id); @@ -2146,8 +2121,6 @@ static int fsfilt_ext3_get_mblk(struct super_block *sb, int *count, return 0; } -#endif - lvfs_sbdev_type fsfilt_ext3_journal_sbdev(struct super_block *sb) { return (EXT3_SB(sb)->journal_bdev); @@ -2313,14 +2286,12 @@ static struct fsfilt_operations fsfilt_ext3_ops = { .fs_get_version = fsfilt_ext3_get_version, .fs_set_version = fsfilt_ext3_set_version, #endif -#ifdef HAVE_QUOTA_SUPPORT .fs_quotactl = fsfilt_ext3_quotactl, .fs_quotacheck = fsfilt_ext3_quotacheck, .fs_quotainfo = fsfilt_ext3_quotainfo, .fs_qids = fsfilt_ext3_qids, .fs_dquot = fsfilt_ext3_dquot, .fs_get_mblk = fsfilt_ext3_get_mblk, -#endif .fs_journal_sbdev = fsfilt_ext3_journal_sbdev, .fs_fid2dentry = fsfilt_ext3_fid2dentry, }; diff --git a/lustre/lvfs/lustre_quota_fmt.c b/lustre/lvfs/lustre_quota_fmt.c index 82636c8..b1e328e 100644 --- a/lustre/lvfs/lustre_quota_fmt.c +++ b/lustre/lvfs/lustre_quota_fmt.c @@ -55,8 +55,6 @@ #include #include "lustre_quota_fmt.h" -#ifdef HAVE_QUOTA_SUPPORT - static const uint lustre_initqversions[][MAXQUOTAS] = { [LUSTRE_QUOTA_V2] = LUSTRE_INITQVERSIONS_V2 }; @@ -1124,4 +1122,3 @@ out_free: RETURN(rc); } EXPORT_SYMBOL(lustre_get_qids); -#endif diff --git a/lustre/lvfs/lustre_quota_fmt.h b/lustre/lvfs/lustre_quota_fmt.h index 0b2ba75..cca4fb9 100644 --- a/lustre/lvfs/lustre_quota_fmt.h +++ b/lustre/lvfs/lustre_quota_fmt.h @@ -39,8 +39,6 @@ #ifndef _LUSTRE_QUOTA_FMT_H #define _LUSTRE_QUOTA_FMT_H -#ifdef HAVE_QUOTA_SUPPORT - #include #include @@ -193,4 +191,3 @@ ssize_t lustre_read_quota(struct file *f, struct inode *inode, int type, #define LUSTRE_OPQFILES_NAMES_V2 { "lquota_v2.user", "lquota_v2.group" } #endif /* lustre_quota_fmt.h */ -#endif diff --git a/lustre/lvfs/quotafmt_test.c b/lustre/lvfs/quotafmt_test.c index 1f514f9..20efcca 100644 --- a/lustre/lvfs/quotafmt_test.c +++ b/lustre/lvfs/quotafmt_test.c @@ -50,8 +50,6 @@ #include "lustre_quota_fmt.h" -#ifdef HAVE_QUOTA_SUPPORT - char *test_quotafile[2] = { "usrquota_test", "grpquota_test" }; static int quotfmt_initialize(struct lustre_quota_info *lqi, @@ -498,5 +496,3 @@ MODULE_LICENSE("GPL"); module_init(quotfmt_test_init); module_exit(quotfmt_test_exit); - -#endif /* HAVE_QUOTA_SUPPORT */ diff --git a/lustre/mdd/Makefile.in b/lustre/mdd/Makefile.in index b2fa867..59e191d 100644 --- a/lustre/mdd/Makefile.in +++ b/lustre/mdd/Makefile.in @@ -1,6 +1,6 @@ MODULES := mdd mdd-objs := mdd_object.o mdd_lov.o mdd_orphans.o mdd_lproc.o mdd_dir.o -mdd-objs += mdd_device.o mdd_trans.o mdd_permission.o mdd_lock.o mdd_quota.o +mdd-objs += mdd_device.o mdd_trans.o mdd_permission.o mdd_lock.o mdd-objs += mdd_lfsck.o EXTRA_PRE_CFLAGS := -I@LINUX@/fs -I@LDISKFS_DIR@ -I@LDISKFS_DIR@/ldiskfs diff --git a/lustre/mdd/mdd_device.c b/lustre/mdd/mdd_device.c index 8e22d04..4ef9265 100644 --- a/lustre/mdd/mdd_device.c +++ b/lustre/mdd/mdd_device.c @@ -1317,25 +1317,6 @@ struct md_capainfo *md_capainfo(const struct lu_env *env) } EXPORT_SYMBOL(md_capainfo); -/* - * context key constructor/destructor: - * mdd_quota_key_init, mdd_quota_key_fini - */ -LU_KEY_INIT_FINI(mdd_quota, struct md_quota); - -struct lu_context_key mdd_quota_key = { - .lct_tags = LCT_SESSION, - .lct_init = mdd_quota_key_init, - .lct_fini = mdd_quota_key_fini -}; - -struct md_quota *md_quota(const struct lu_env *env) -{ - LASSERT(env->le_ses != NULL); - return lu_context_key_get(env->le_ses, &mdd_quota_key); -} -EXPORT_SYMBOL(md_quota); - static int mdd_changelog_user_register(struct mdd_device *mdd, int *id) { struct llog_ctxt *ctxt; @@ -1636,8 +1617,7 @@ static int mdd_iocontrol(const struct lu_env *env, struct md_device *m, } /* type constructor/destructor: mdd_type_init, mdd_type_fini */ -LU_TYPE_INIT_FINI(mdd, &mdd_thread_key, &mdd_ucred_key, &mdd_capainfo_key, - &mdd_quota_key); +LU_TYPE_INIT_FINI(mdd, &mdd_thread_key, &mdd_ucred_key, &mdd_capainfo_key); const struct md_device_operations mdd_ops = { .mdo_statfs = mdd_statfs, @@ -1647,25 +1627,6 @@ const struct md_device_operations mdd_ops = { .mdo_update_capa_key= mdd_update_capa_key, .mdo_llog_ctxt_get = mdd_llog_ctxt_get, .mdo_iocontrol = mdd_iocontrol, -#ifdef HAVE_QUOTA_SUPPORT - .mdo_quota = { - .mqo_notify = mdd_quota_notify, - .mqo_setup = mdd_quota_setup, - .mqo_cleanup = mdd_quota_cleanup, - .mqo_recovery = mdd_quota_recovery, - .mqo_check = mdd_quota_check, - .mqo_on = mdd_quota_on, - .mqo_off = mdd_quota_off, - .mqo_setinfo = mdd_quota_setinfo, - .mqo_getinfo = mdd_quota_getinfo, - .mqo_setquota = mdd_quota_setquota, - .mqo_getquota = mdd_quota_getquota, - .mqo_getoinfo = mdd_quota_getoinfo, - .mqo_getoquota = mdd_quota_getoquota, - .mqo_invalidate = mdd_quota_invalidate, - .mqo_finvalidate = mdd_quota_finvalidate - } -#endif }; static struct lu_device_type_operations mdd_device_type_ops = { diff --git a/lustre/mdd/mdd_dir.c b/lustre/mdd/mdd_dir.c index f142139..ba8d76a 100644 --- a/lustre/mdd/mdd_dir.c +++ b/lustre/mdd/mdd_dir.c @@ -835,34 +835,9 @@ static int mdd_link(const struct lu_env *env, struct md_object *tgt_obj, struct mdd_device *mdd = mdo2mdd(src_obj); struct dynlock_handle *dlh; struct thandle *handle; -#ifdef HAVE_QUOTA_SUPPORT - struct obd_device *obd = mdd->mdd_obd_dev; - struct obd_export *exp = md_quota(env)->mq_exp; - struct mds_obd *mds = &obd->u.mds; - unsigned int qids[MAXQUOTAS] = { 0, 0 }; - int quota_opc = 0, rec_pending[MAXQUOTAS] = { 0, 0 }; -#endif int rc; ENTRY; -#ifdef HAVE_QUOTA_SUPPORT - if (mds->mds_quota) { - struct lu_attr *la_tmp = &mdd_env_info(env)->mti_la; - - rc = mdd_la_get(env, mdd_tobj, la_tmp, BYPASS_CAPA); - if (!rc) { - void *data = NULL; - mdd_data_get(env, mdd_tobj, &data); - quota_opc = FSFILT_OP_LINK; - mdd_quota_wrapper(la_tmp, qids); - /* get block quota for parent */ - lquota_chkquota(mds_quota_interface_ref, obd, exp, - qids, rec_pending, 1, NULL, - LQUOTA_FLAGS_BLK, data, 1); - } - } -#endif - handle = mdd_trans_create(env, mdd); if (IS_ERR(handle)) GOTO(out_pending, rc = PTR_ERR(handle)); @@ -923,16 +898,6 @@ out_trans: stop: mdd_trans_stop(env, mdd, rc, handle); out_pending: -#ifdef HAVE_QUOTA_SUPPORT - if (quota_opc) { - lquota_pending_commit(mds_quota_interface_ref, obd, - qids, rec_pending, 1); - /* Trigger dqacq for the parent owner. If failed, - * the next call for lquota_chkquota will process it. */ - lquota_adjust(mds_quota_interface_ref, obd, 0, qids, rc, - quota_opc); - } -#endif return rc; } @@ -1062,13 +1027,6 @@ static int mdd_unlink(const struct lu_env *env, struct md_object *pobj, struct mdd_device *mdd = mdo2mdd(pobj); struct dynlock_handle *dlh; struct thandle *handle; -#ifdef HAVE_QUOTA_SUPPORT - struct obd_device *obd = mdd->mdd_obd_dev; - struct mds_obd *mds = &obd->u.mds; - unsigned int qcids[MAXQUOTAS] = { 0, 0 }; - unsigned int qpids[MAXQUOTAS] = { 0, 0 }; - int quota_opc = 0; -#endif int rc, is_dir; ENTRY; @@ -1153,23 +1111,6 @@ static int mdd_unlink(const struct lu_env *env, struct md_object *pobj, rc = mdd_la_get(env, mdd_cobj, cattr, mdd_object_capa(env, mdd_cobj)); -#ifdef HAVE_QUOTA_SUPPORT - if (mds->mds_quota && ma->ma_valid & MA_INODE && - ma->ma_attr.la_nlink == 0) { - struct lu_attr *la_tmp = &mdd_env_info(env)->mti_la; - - rc = mdd_la_get(env, mdd_pobj, la_tmp, BYPASS_CAPA); - if (!rc) { - mdd_quota_wrapper(la_tmp, qpids); - if (mdd_cobj->mod_count == 0) { - quota_opc = FSFILT_OP_UNLINK; - mdd_quota_wrapper(&ma->ma_attr, qcids); - } else { - quota_opc = FSFILT_OP_UNLINK_PARTIAL_PARENT; - } - } - } -#endif if (!is_dir) /* old files may not have link ea; ignore errors */ mdd_links_rename(env, mdd_cobj, mdo2fid(mdd_pobj), @@ -1209,13 +1150,6 @@ stop: #warning "please remove this after 2.4 (LOD/OSP)." #endif -#ifdef HAVE_QUOTA_SUPPORT - if (quota_opc) - /* Trigger dqrel on the owner of child and parent. If failed, - * the next call for lquota_chkquota will process it. */ - lquota_adjust(mds_quota_interface_ref, obd, qcids, qpids, rc, - quota_opc); -#endif return rc; } @@ -1626,17 +1560,6 @@ static int mdd_create(const struct lu_env *env, struct md_object *pobj, const char *name = lname->ln_name; int rc, created = 0, initialized = 0, inserted = 0, lmm_size = 0; int got_def_acl = 0; -#ifdef HAVE_QUOTA_SUPPORT - struct obd_device *obd = mdd->mdd_obd_dev; - struct obd_export *exp = md_quota(env)->mq_exp; - struct mds_obd *mds = &obd->u.mds; - unsigned int qcids[MAXQUOTAS] = { 0, 0 }; - unsigned int qpids[MAXQUOTAS] = { 0, 0 }; - int quota_opc = 0, block_count = 0; - int inode_pending[MAXQUOTAS] = { 0, 0 }; - int block_pending[MAXQUOTAS] = { 0, 0 }; - int parent_pending[MAXQUOTAS] = { 0, 0 }; -#endif ENTRY; /* @@ -1684,45 +1607,6 @@ static int mdd_create(const struct lu_env *env, struct md_object *pobj, if (rc) RETURN(rc); -#ifdef HAVE_QUOTA_SUPPORT - if (mds->mds_quota) { - int same = 0; - - quota_opc = FSFILT_OP_CREATE; - mdd_quota_wrapper(attr, qcids); - mdd_quota_wrapper(pattr, qpids); - /* get file quota for child */ - lquota_chkquota(mds_quota_interface_ref, obd, exp, - qcids, inode_pending, 1, NULL, 0, NULL, - 0); - switch (attr->la_mode & S_IFMT) { - case S_IFLNK: - case S_IFDIR: - block_count = 2; - break; - case S_IFREG: - block_count = 1; - break; - } - if (qcids[USRQUOTA] == qpids[USRQUOTA] && - qcids[GRPQUOTA] == qpids[GRPQUOTA]) { - block_count += 1; - same = 1; - } - /* get block quota for child and parent */ - if (block_count) - lquota_chkquota(mds_quota_interface_ref, obd, - exp, qcids, block_pending, - block_count, NULL, - LQUOTA_FLAGS_BLK, NULL, 0); - if (!same) - lquota_chkquota(mds_quota_interface_ref, obd, - exp, qpids, parent_pending, 1, - NULL, LQUOTA_FLAGS_BLK, NULL, - 0); - } -#endif - if (OBD_FAIL_CHECK(OBD_FAIL_MDS_DQACQ_NET)) GOTO(out_pending, rc = -EINPROGRESS); @@ -1899,20 +1783,6 @@ out_free: /* finish lov_create stuff, free all temporary data */ mdd_lov_create_finish(env, mdd, lmm, lmm_size, spec); out_pending: -#ifdef HAVE_QUOTA_SUPPORT - if (quota_opc) { - lquota_pending_commit(mds_quota_interface_ref, obd, qcids, - inode_pending, 0); - lquota_pending_commit(mds_quota_interface_ref, obd, qcids, - block_pending, 1); - lquota_pending_commit(mds_quota_interface_ref, obd, qpids, - parent_pending, 1); - /* Trigger dqacq on the owner of child and parent. If failed, - * the next call for lquota_chkquota will process it. */ - lquota_adjust(mds_quota_interface_ref, obd, qcids, qpids, rc, - quota_opc); - } -#endif /* The child object shouldn't be cached anymore */ if (rc) cfs_set_bit(LU_OBJECT_HEARD_BANSHEE, @@ -2139,48 +2009,11 @@ static int mdd_rename(const struct lu_env *env, int is_dir; unsigned cl_flags = 0; int rc, rc2; - -#ifdef HAVE_QUOTA_SUPPORT - struct obd_device *obd = mdd->mdd_obd_dev; - struct obd_export *exp = md_quota(env)->mq_exp; - struct mds_obd *mds = &obd->u.mds; - unsigned int qspids[MAXQUOTAS] = { 0, 0 }; - unsigned int qtcids[MAXQUOTAS] = { 0, 0 }; - unsigned int qtpids[MAXQUOTAS] = { 0, 0 }; - int quota_copc = 0, quota_popc = 0; - int rec_pending[MAXQUOTAS] = { 0, 0 }; -#endif ENTRY; if (tobj) mdd_tobj = md2mdd_obj(tobj); -#ifdef HAVE_QUOTA_SUPPORT - if (mds->mds_quota) { - struct lu_attr *la_tmp = &mdd_env_info(env)->mti_la; - - rc = mdd_la_get(env, mdd_spobj, la_tmp, BYPASS_CAPA); - if (!rc) { - mdd_quota_wrapper(la_tmp, qspids); - if (!tobj) { - rc = mdd_la_get(env, mdd_tpobj, la_tmp, - BYPASS_CAPA); - if (!rc) { - void *data = NULL; - mdd_data_get(env, mdd_tpobj, &data); - quota_popc = FSFILT_OP_LINK; - mdd_quota_wrapper(la_tmp, qtpids); - /* get block quota for target parent */ - lquota_chkquota(mds_quota_interface_ref, - obd, exp, qtpids, - rec_pending, 1, NULL, - LQUOTA_FLAGS_BLK, - data, 1); - } - } - } - } -#endif mdd_sobj = mdd_object_find(env, mdd, lf); handle = mdd_trans_create(env, mdd); @@ -2339,15 +2172,8 @@ static int mdd_rename(const struct lu_env *env, ma->ma_attr = *tg_attr; ma->ma_valid |= MA_INODE; - if (so_attr->la_nlink == 0) { + if (so_attr->la_nlink == 0) cl_flags |= CLF_RENAME_LAST; -#ifdef HAVE_QUOTA_SUPPORT - if (mds->mds_quota && mdd_tobj->mod_count == 0) { - quota_copc = FSFILT_OP_UNLINK_PARTIAL_CHILD; - mdd_quota_wrapper(&ma->ma_attr, qtcids); - } -#endif - } } la->la_valid = LA_CTIME | LA_MTIME; @@ -2435,27 +2261,6 @@ stop: if (mdd_sobj) mdd_object_put(env, mdd_sobj); out_pending: -#ifdef HAVE_QUOTA_SUPPORT - if (mds->mds_quota) { - if (quota_popc) - lquota_pending_commit(mds_quota_interface_ref, obd, - qtpids, rec_pending, 1); - - if (quota_copc) { - /* Trigger dqrel on the source owner of parent. - * If failed, the next call for lquota_chkquota will - * process it. */ - lquota_adjust(mds_quota_interface_ref, obd, 0, qspids, rc, - FSFILT_OP_UNLINK_PARTIAL_PARENT); - - /* Trigger dqrel on the target owner of child. - * If failed, the next call for lquota_chkquota - * will process it. */ - lquota_adjust(mds_quota_interface_ref, obd, qtcids, - qtpids, rc, quota_copc); - } - } -#endif return rc; } diff --git a/lustre/mdd/mdd_internal.h b/lustre/mdd/mdd_internal.h index 779c5e1..9ed853c 100644 --- a/lustre/mdd/mdd_internal.h +++ b/lustre/mdd/mdd_internal.h @@ -45,9 +45,6 @@ #include #include #include -#ifdef HAVE_QUOTA_SUPPORT -# include -#endif #include #include #include @@ -55,17 +52,6 @@ #include #include -#ifdef HAVE_QUOTA_SUPPORT -/* quota stuff */ -extern quota_interface_t *mds_quota_interface_ref; - -static inline void mdd_quota_wrapper(struct lu_attr *la, unsigned int *qids) -{ - qids[USRQUOTA] = la->la_uid; - qids[GRPQUOTA] = la->la_gid; -} -#endif - /* PDO lock is unnecessary for current MDT stack because operations * are already protected by ldlm lock */ #define MDD_DISABLE_PDO_LOCK 1 @@ -412,36 +398,6 @@ int mdd_declare_object_create_internal(const struct lu_env *env, struct lu_attr *attr, struct thandle *handle, const struct md_op_spec *spec); -/* mdd_quota.c*/ -#ifdef HAVE_QUOTA_SUPPORT -int mdd_quota_notify(const struct lu_env *env, struct md_device *m); -int mdd_quota_setup(const struct lu_env *env, struct md_device *m, - void *data); -int mdd_quota_cleanup(const struct lu_env *env, struct md_device *m); -int mdd_quota_recovery(const struct lu_env *env, struct md_device *m); -int mdd_quota_check(const struct lu_env *env, struct md_device *m, - __u32 type); -int mdd_quota_on(const struct lu_env *env, struct md_device *m, - __u32 type); -int mdd_quota_off(const struct lu_env *env, struct md_device *m, - __u32 type); -int mdd_quota_setinfo(const struct lu_env *env, struct md_device *m, - __u32 type, __u32 id, struct obd_dqinfo *dqinfo); -int mdd_quota_getinfo(const struct lu_env *env, const struct md_device *m, - __u32 type, __u32 id, struct obd_dqinfo *dqinfo); -int mdd_quota_setquota(const struct lu_env *env, struct md_device *m, - __u32 type, __u32 id, struct obd_dqblk *dqblk); -int mdd_quota_getquota(const struct lu_env *env, const struct md_device *m, - __u32 type, __u32 id, struct obd_dqblk *dqblk); -int mdd_quota_getoinfo(const struct lu_env *env, const struct md_device *m, - __u32 type, __u32 id, struct obd_dqinfo *dqinfo); -int mdd_quota_getoquota(const struct lu_env *env, const struct md_device *m, - __u32 type, __u32 id, struct obd_dqblk *dqblk); -int mdd_quota_invalidate(const struct lu_env *env, struct md_device *m, - __u32 type); -int mdd_quota_finvalidate(const struct lu_env *env, struct md_device *m, - __u32 type); -#endif /* mdd_trans.c */ int mdd_lov_destroy(const struct lu_env *env, struct mdd_device *mdd, diff --git a/lustre/mdd/mdd_lov.c b/lustre/mdd/mdd_lov.c index defe810..76b046f 100644 --- a/lustre/mdd/mdd_lov.c +++ b/lustre/mdd/mdd_lov.c @@ -76,12 +76,6 @@ static int mdd_notify(struct obd_device *host, struct obd_device *watched, rc = md_do_upcall(NULL, &mdd->mdd_md_dev, MD_LOV_CONFIG, data); break; -#ifdef HAVE_QUOTA_SUPPORT - case OBD_NOTIFY_QUOTA: - rc = md_do_upcall(NULL, &mdd->mdd_md_dev, - MD_LOV_QUOTA, data); - break; -#endif default: CDEBUG(D_INFO, "Unhandled notification %#x\n", ev); } @@ -155,7 +149,7 @@ int mdd_init_obd(const struct lu_env *env, struct mdd_device *mdd, /* * Add here for obd notify mechanism, when adding a new ost, the mds - * will notify this mdd. The mds will be used for quota also. + * will notify this mdd. */ obd->obd_upcall.onu_upcall = mdd_notify; obd->obd_upcall.onu_owner = mdd; diff --git a/lustre/mdd/mdd_lproc.c b/lustre/mdd/mdd_lproc.c index 44e3b8f..47560b8 100644 --- a/lustre/mdd/mdd_lproc.c +++ b/lustre/mdd/mdd_lproc.c @@ -249,23 +249,6 @@ static int lprocfs_rd_changelog_users(char *page, char **start, off_t off, return cucb.idx; } -#ifdef HAVE_QUOTA_SUPPORT -static int mdd_lprocfs_quota_rd_type(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct mdd_device *mdd = data; - return lprocfs_quota_rd_type(page, start, off, count, eof, - mdd->mdd_obd_dev); -} - -static int mdd_lprocfs_quota_wr_type(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - struct mdd_device *mdd = data; - return lprocfs_quota_wr_type(file, buffer, count, mdd->mdd_obd_dev); -} -#endif - static int lprocfs_rd_sync_perm(char *page, char **start, off_t off, int count, int *eof, void *data) { @@ -324,10 +307,6 @@ static struct lprocfs_vars lprocfs_mdd_obd_vars[] = { { "changelog_mask", lprocfs_rd_changelog_mask, lprocfs_wr_changelog_mask, 0 }, { "changelog_users", lprocfs_rd_changelog_users, 0, 0}, -#ifdef HAVE_QUOTA_SUPPORT - { "quota_type", mdd_lprocfs_quota_rd_type, - mdd_lprocfs_quota_wr_type, 0 }, -#endif { "sync_permission", lprocfs_rd_sync_perm, lprocfs_wr_sync_perm, 0 }, { "lfsck_speed_limit", lprocfs_rd_lfsck_speed_limit, lprocfs_wr_lfsck_speed_limit, 0 }, diff --git a/lustre/mdd/mdd_object.c b/lustre/mdd/mdd_object.c index 04aea7e..ba4b81a 100644 --- a/lustre/mdd/mdd_object.c +++ b/lustre/mdd/mdd_object.c @@ -1481,15 +1481,6 @@ int mdd_attr_set(const struct lu_env *env, struct md_object *obj, int rc, lmm_size = 0, cookie_size = 0; struct lu_attr *la_copy = &mdd_env_info(env)->mti_la_for_fix; const struct lu_attr *la = &ma->ma_attr; -#ifdef HAVE_QUOTA_SUPPORT - struct obd_device *obd = mdd->mdd_obd_dev; - struct mds_obd *mds = &obd->u.mds; - unsigned int qnids[MAXQUOTAS] = { 0, 0 }; - unsigned int qoids[MAXQUOTAS] = { 0, 0 }; - int quota_opc = 0, block_count = 0; - int inode_pending[MAXQUOTAS] = { 0, 0 }; - int block_pending[MAXQUOTAS] = { 0, 0 }; -#endif ENTRY; *la_copy = ma->ma_attr; @@ -1536,34 +1527,6 @@ int mdd_attr_set(const struct lu_env *env, struct md_object *obj, CDEBUG(D_INODE, "setting mtime "LPU64", ctime "LPU64"\n", la->la_mtime, la->la_ctime); -#ifdef HAVE_QUOTA_SUPPORT - if (mds->mds_quota && la_copy->la_valid & (LA_UID | LA_GID)) { - struct obd_export *exp = md_quota(env)->mq_exp; - struct lu_attr *la_tmp = &mdd_env_info(env)->mti_la; - - rc = mdd_la_get(env, mdd_obj, la_tmp, BYPASS_CAPA); - if (!rc) { - quota_opc = FSFILT_OP_SETATTR; - mdd_quota_wrapper(la_copy, qnids); - mdd_quota_wrapper(la_tmp, qoids); - /* get file quota for new owner */ - lquota_chkquota(mds_quota_interface_ref, obd, exp, - qnids, inode_pending, 1, NULL, 0, - NULL, 0); - block_count = (la_tmp->la_blocks + 7) >> 3; - if (block_count) { - void *data = NULL; - mdd_data_get(env, mdd_obj, &data); - /* get block quota for new owner */ - lquota_chkquota(mds_quota_interface_ref, obd, - exp, qnids, block_pending, - block_count, NULL, - LQUOTA_FLAGS_BLK, data, 1); - } - } - } -#endif - if (la_copy->la_valid & LA_FLAGS) { rc = mdd_attr_set_internal(env, mdd_obj, la_copy, handle, 1); if (rc == 0) @@ -1616,19 +1579,6 @@ stop: rc = mdd_lov_setattr_async(env, mdd_obj, lmm, lmm_size, logcookies); } -#ifdef HAVE_QUOTA_SUPPORT - if (quota_opc) { - lquota_pending_commit(mds_quota_interface_ref, obd, qnids, - inode_pending, 0); - lquota_pending_commit(mds_quota_interface_ref, obd, qnids, - block_pending, 1); - /* Trigger dqrel/dqacq for original owner and new owner. - * If failed, the next call for lquota_chkquota will - * process it. */ - lquota_adjust(mds_quota_interface_ref, obd, qnids, qoids, rc, - quota_opc); - } -#endif RETURN(rc); } @@ -1996,13 +1946,6 @@ static int mdd_close(const struct lu_env *env, struct md_object *obj, struct thandle *handle = NULL; int rc; int is_orphan = 0, reset = 1; - -#ifdef HAVE_QUOTA_SUPPORT - struct obd_device *obd = mdo2mdd(obj)->mdd_obd_dev; - struct mds_obd *mds = &obd->u.mds; - unsigned int qids[MAXQUOTAS] = { 0, 0 }; - int quota_opc = 0; -#endif ENTRY; if (ma->ma_valid & MA_FLAGS && ma->ma_attr_flags & MDS_KEEP_ORPHAN) { @@ -2071,12 +2014,6 @@ static int mdd_close(const struct lu_env *env, struct md_object *obj, /* Object maybe not in orphan list originally, it is rare case for * mdd_finish_unlink() failure. */ if (rc == 0 && (ma->ma_attr.la_nlink == 0 || is_orphan)) { -#ifdef HAVE_QUOTA_SUPPORT - if (mds->mds_quota) { - quota_opc = FSFILT_OP_UNLINK_PARTIAL_CHILD; - mdd_quota_wrapper(&ma->ma_attr, qids); - } -#endif /* MDS_CLOSE_CLEANUP means destroy OSS objects by MDS. */ if (ma->ma_valid & MA_FLAGS && ma->ma_attr_flags & MDS_CLOSE_CLEANUP) { @@ -2145,13 +2082,6 @@ out: stop: if (handle != NULL) mdd_trans_stop(env, mdd, rc, handle); -#ifdef HAVE_QUOTA_SUPPORT - if (quota_opc) - /* Trigger dqrel on the owner of child. If failed, - * the next call for lquota_chkquota will process it */ - lquota_adjust(mds_quota_interface_ref, obd, qids, 0, rc, - quota_opc); -#endif return rc; } diff --git a/lustre/mdd/mdd_quota.c b/lustre/mdd/mdd_quota.c deleted file mode 100644 index 4c65489..0000000 --- a/lustre/mdd/mdd_quota.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * GPL HEADER END - */ -/* - * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - * - * lustre/mdd/mdd_quota.c - * - * Lustre Metadata Server (mdd) routines - * - * Author: Fan Yong - */ - -#ifdef HAVE_QUOTA_SUPPORT - -#include "mdd_internal.h" - -int mdd_quota_notify(const struct lu_env *env, struct md_device *m) -{ - struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev); - struct obd_device *obd = mdd->mdd_obd_dev; - ENTRY; - - lquota_setinfo(mds_quota_interface_ref, obd, (void *)1); - RETURN(0); -} - -int mdd_quota_setup(const struct lu_env *env, struct md_device *m, - void *data) -{ - struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev); - struct obd_device *obd = mdd->mdd_obd_dev; - struct dt_device *dt = mdd->mdd_child; - int rc; - ENTRY; - - LASSERT(obd->obd_fsops != NULL); - dt->dd_ops->dt_init_quota_ctxt(env, dt, (void *)obd, data); - rc = lquota_setup(mds_quota_interface_ref, obd); - RETURN(rc); -} - -int mdd_quota_cleanup(const struct lu_env *env, struct md_device *m) -{ - struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev); - struct obd_device *obd = mdd->mdd_obd_dev; - int rc1, rc2; - ENTRY; - - rc1 = lquota_cleanup(mds_quota_interface_ref, obd); - rc2 = lquota_fs_cleanup(mds_quota_interface_ref, obd); - RETURN(rc1 ? : rc2); -} - -int mdd_quota_recovery(const struct lu_env *env, struct md_device *m) -{ - struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev); - struct obd_device *obd = mdd->mdd_obd_dev; - int rc; - ENTRY; - - rc = lquota_recovery(mds_quota_interface_ref, obd); - RETURN(rc); -} - -int mdd_quota_check(const struct lu_env *env, struct md_device *m, - __u32 type) -{ - struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev); - struct obd_device *obd = mdd->mdd_obd_dev; - struct obd_export *exp = md_quota(env)->mq_exp; - struct obd_quotactl *oqctl = &mdd_env_info(env)->mti_oqctl; - int rc; - ENTRY; - - oqctl->qc_type = type; - rc = lquota_check(mds_quota_interface_ref, obd, exp, oqctl); - RETURN(rc); -} - -int mdd_quota_on(const struct lu_env *env, struct md_device *m, - __u32 type) -{ - struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev); - struct obd_device *obd = mdd->mdd_obd_dev; - struct obd_quotactl *oqctl = &mdd_env_info(env)->mti_oqctl; - int rc; - ENTRY; - - oqctl->qc_cmd = Q_QUOTAON; - oqctl->qc_type = type; - rc = lquota_ctl(mds_quota_interface_ref, obd, oqctl); - RETURN(rc); -} - -int mdd_quota_off(const struct lu_env *env, struct md_device *m, - __u32 type) -{ - struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev); - struct obd_device *obd = mdd->mdd_obd_dev; - struct obd_quotactl *oqctl = &mdd_env_info(env)->mti_oqctl; - int rc; - ENTRY; - - oqctl->qc_cmd = Q_QUOTAOFF; - oqctl->qc_type = type; - rc = lquota_ctl(mds_quota_interface_ref, obd, oqctl); - RETURN(rc); -} - -int mdd_quota_setinfo(const struct lu_env *env, struct md_device *m, - __u32 type, __u32 id, struct obd_dqinfo *dqinfo) -{ - struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev); - struct obd_device *obd = mdd->mdd_obd_dev; - struct obd_quotactl *oqctl = &mdd_env_info(env)->mti_oqctl; - int rc; - ENTRY; - - oqctl->qc_cmd = Q_SETINFO; - oqctl->qc_type = type; - oqctl->qc_id = id; - oqctl->qc_dqinfo = *dqinfo; - rc = lquota_ctl(mds_quota_interface_ref, obd, oqctl); - RETURN(rc); -} - -int mdd_quota_getinfo(const struct lu_env *env, const struct md_device *m, - __u32 type, __u32 id, struct obd_dqinfo *dqinfo) -{ - struct mdd_device *mdd = lu2mdd_dev( - &((struct md_device *)m)->md_lu_dev); - struct obd_device *obd = mdd->mdd_obd_dev; - struct obd_quotactl *oqctl = &mdd_env_info(env)->mti_oqctl; - int rc; - ENTRY; - - oqctl->qc_cmd = Q_GETINFO; - oqctl->qc_type = type; - oqctl->qc_id = id; - rc = lquota_ctl(mds_quota_interface_ref, obd, oqctl); - *dqinfo = oqctl->qc_dqinfo; - RETURN(rc); -} - -int mdd_quota_setquota(const struct lu_env *env, struct md_device *m, - __u32 type, __u32 id, struct obd_dqblk *dqblk) -{ - struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev); - struct obd_device *obd = mdd->mdd_obd_dev; - struct obd_quotactl *oqctl = &mdd_env_info(env)->mti_oqctl; - int rc; - ENTRY; - - oqctl->qc_cmd = Q_SETQUOTA; - oqctl->qc_type = type; - oqctl->qc_id = id; - oqctl->qc_dqblk = *dqblk; - rc = lquota_ctl(mds_quota_interface_ref, obd, oqctl); - RETURN(rc); -} - -int mdd_quota_getquota(const struct lu_env *env, const struct md_device *m, - __u32 type, __u32 id, struct obd_dqblk *dqblk) -{ - struct mdd_device *mdd = lu2mdd_dev( - &((struct md_device *)m)->md_lu_dev); - struct obd_device *obd = mdd->mdd_obd_dev; - struct obd_quotactl *oqctl = &mdd_env_info(env)->mti_oqctl; - int rc; - ENTRY; - - oqctl->qc_cmd = Q_GETQUOTA; - oqctl->qc_type = type; - oqctl->qc_id = id; - rc = lquota_ctl(mds_quota_interface_ref, obd, oqctl); - *dqblk = oqctl->qc_dqblk; - RETURN(rc); -} - -int mdd_quota_getoinfo(const struct lu_env *env, const struct md_device *m, - __u32 type, __u32 id, struct obd_dqinfo *dqinfo) -{ - struct mdd_device *mdd = lu2mdd_dev( - &((struct md_device *)m)->md_lu_dev); - struct obd_device *obd = mdd->mdd_obd_dev; - struct obd_quotactl *oqctl = &mdd_env_info(env)->mti_oqctl; - int rc; - ENTRY; - - oqctl->qc_cmd = Q_GETOINFO; - oqctl->qc_type = type; - oqctl->qc_id = id; - rc = lquota_ctl(mds_quota_interface_ref, obd, oqctl); - *dqinfo = oqctl->qc_dqinfo; - RETURN(rc); -} - -int mdd_quota_getoquota(const struct lu_env *env, const struct md_device *m, - __u32 type, __u32 id, struct obd_dqblk *dqblk) -{ - struct mdd_device *mdd = lu2mdd_dev( - &((struct md_device *)m)->md_lu_dev); - struct obd_device *obd = mdd->mdd_obd_dev; - struct obd_quotactl *oqctl = &mdd_env_info(env)->mti_oqctl; - int rc; - ENTRY; - - oqctl->qc_cmd = Q_GETOQUOTA; - oqctl->qc_type = type; - oqctl->qc_id = id; - rc = lquota_ctl(mds_quota_interface_ref, obd, oqctl); - *dqblk = oqctl->qc_dqblk; - RETURN(rc); -} - -int mdd_quota_invalidate(const struct lu_env *env, struct md_device *m, - __u32 type) -{ - struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev); - struct obd_device *obd = mdd->mdd_obd_dev; - struct obd_quotactl *oqctl = &mdd_env_info(env)->mti_oqctl; - int rc; - ENTRY; - - oqctl->qc_cmd = LUSTRE_Q_INVALIDATE; - oqctl->qc_type = type; - rc = lquota_ctl(mds_quota_interface_ref, obd, oqctl); - RETURN(rc); -} - -int mdd_quota_finvalidate(const struct lu_env *env, struct md_device *m, - __u32 type) -{ - struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev); - struct obd_device *obd = mdd->mdd_obd_dev; - struct obd_quotactl *oqctl = &mdd_env_info(env)->mti_oqctl; - int rc; - ENTRY; - - oqctl->qc_cmd = LUSTRE_Q_FINVALIDATE; - oqctl->qc_type = type; - rc = lquota_ctl(mds_quota_interface_ref, obd, oqctl); - RETURN(rc); -} -#endif diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c index fac9645..75f3640 100644 --- a/lustre/mds/handler.c +++ b/lustre/mds/handler.c @@ -403,23 +403,9 @@ static struct obd_ops mds_cmd_obd_ops = { // .o_health_check = mds_cmd_health_check, }; -quota_interface_t *mds_quota_interface_ref; -extern quota_interface_t mds_quota_interface; - static int __init mds_cmd_init(void) { struct lprocfs_static_vars lvars; - int rc; - - cfs_request_module("%s", "lquota"); - mds_quota_interface_ref = PORTAL_SYMBOL_GET(mds_quota_interface); - rc = lquota_init(mds_quota_interface_ref); - if (rc) { - if (mds_quota_interface_ref) - PORTAL_SYMBOL_PUT(mds_quota_interface); - return rc; - } - init_obd_quota_ops(mds_quota_interface_ref, &mds_cmd_obd_ops); lprocfs_mds_init_vars(&lvars); class_register_type(&mds_cmd_obd_ops, NULL, lvars.module_vars, @@ -430,14 +416,9 @@ static int __init mds_cmd_init(void) static void /*__exit*/ mds_cmd_exit(void) { - lquota_exit(mds_quota_interface_ref); - if (mds_quota_interface_ref) - PORTAL_SYMBOL_PUT(mds_quota_interface); - class_unregister_type(LUSTRE_MDS_NAME); } -EXPORT_SYMBOL(mds_quota_interface_ref); MODULE_AUTHOR("Sun Microsystems, Inc. "); MODULE_DESCRIPTION("Lustre Metadata Server (MDS)"); MODULE_LICENSE("GPL"); diff --git a/lustre/mds/mds_lov.c b/lustre/mds/mds_lov.c index 4258633..880d592 100644 --- a/lustre/mds/mds_lov.c +++ b/lustre/mds/mds_lov.c @@ -885,17 +885,6 @@ static int __mds_lov_synchronize(void *data) GOTO(out, rc); } -#ifdef HAVE_QUOTA_SUPPORT - if (obd->obd_upcall.onu_owner) { - /* - * This is a hack for mds_notify->mdd_notify. When the mds obd - * in mdd is removed, This hack should be removed. - */ - LASSERT(obd->obd_upcall.onu_upcall != NULL); - rc = obd->obd_upcall.onu_upcall(obd, NULL, OBD_NOTIFY_QUOTA, - obd->obd_upcall.onu_owner,NULL); - } -#endif EXIT; out: if (rc) { diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c index f1ef253..3b590f0 100644 --- a/lustre/mdt/mdt_handler.c +++ b/lustre/mdt/mdt_handler.c @@ -65,11 +65,9 @@ #include #include #include "mdt_internal.h" -#ifdef HAVE_QUOTA_SUPPORT -# include -#endif #include #include +#include mdl_mode_t mdt_mdl_lock_modes[] = { [LCK_MINMODE] = MDL_MINMODE, @@ -1819,7 +1817,6 @@ static int mdt_reint_internal(struct mdt_thread_info *info, __u32 op) { struct req_capsule *pill = info->mti_pill; - struct md_quota *mq = md_quota(info->mti_env); struct mdt_body *repbody; int rc = 0, rc2; ENTRY; @@ -1872,7 +1869,6 @@ static int mdt_reint_internal(struct mdt_thread_info *info, rc = lustre_msg_get_status(mdt_info_req(info)->rq_repmsg); GOTO(out_ucred, rc); } - mq->mq_exp = info->mti_exp; rc = mdt_reint_rec(info, lhc); EXIT; out_ucred: @@ -2021,133 +2017,140 @@ static int mdt_sync(struct mdt_thread_info *info) RETURN(rc); } -#ifdef HAVE_QUOTA_SUPPORT -static int mdt_quotacheck_handle(struct mdt_thread_info *info) +/* + * Quotacheck handler. + * in-kernel quotacheck isn't supported any more. + */ +static int mdt_quotacheck(struct mdt_thread_info *info) { - struct obd_quotactl *oqctl; - struct req_capsule *pill = info->mti_pill; - struct obd_export *exp = info->mti_exp; - struct md_quota *mq = md_quota(info->mti_env); - struct md_device *next = info->mti_mdt->mdt_child; - int rc; - ENTRY; - - oqctl = req_capsule_client_get(pill, &RMF_OBD_QUOTACTL); - if (oqctl == NULL) - RETURN(-EPROTO); + struct obd_quotactl *oqctl; + int rc; + ENTRY; - /* remote client has no permission for quotacheck */ - if (unlikely(exp_connect_rmtclient(exp))) - RETURN(-EPERM); + oqctl = req_capsule_client_get(info->mti_pill, &RMF_OBD_QUOTACTL); + if (oqctl == NULL) + RETURN(err_serious(-EPROTO)); - rc = req_capsule_server_pack(pill); - if (rc) - RETURN(rc); + rc = req_capsule_server_pack(info->mti_pill); + if (rc) + RETURN(err_serious(rc)); - mq->mq_exp = exp; - rc = next->md_ops->mdo_quota.mqo_check(info->mti_env, next, - oqctl->qc_type); - RETURN(rc); + /* deprecated, not used any more */ + RETURN(-EOPNOTSUPP); } -static int mdt_quotactl_handle(struct mdt_thread_info *info) +/* + * Handle quota control requests to consult current usage/limit, but also + * to configure quota enforcement + */ +static int mdt_quotactl(struct mdt_thread_info *info) { - struct obd_quotactl *oqctl, *repoqc; - struct req_capsule *pill = info->mti_pill; - struct obd_export *exp = info->mti_exp; - struct md_quota *mq = md_quota(info->mti_env); - struct md_device *next = info->mti_mdt->mdt_child; - const struct md_quota_operations *mqo = &next->md_ops->mdo_quota; - int id, rc; - ENTRY; + struct obd_export *exp = info->mti_exp; + struct req_capsule *pill = info->mti_pill; + struct obd_quotactl *oqctl, *repoqc; + int id, rc; + ENTRY; - oqctl = req_capsule_client_get(pill, &RMF_OBD_QUOTACTL); - if (oqctl == NULL) - RETURN(-EPROTO); + oqctl = req_capsule_client_get(pill, &RMF_OBD_QUOTACTL); + if (oqctl == NULL) + RETURN(err_serious(-EPROTO)); - id = oqctl->qc_id; - if (exp_connect_rmtclient(exp)) { - struct ptlrpc_request *req = mdt_info_req(info); - struct mdt_export_data *med = mdt_req2med(req); - struct lustre_idmap_table *idmap = med->med_idmap; + rc = req_capsule_server_pack(pill); + if (rc) + RETURN(err_serious(rc)); - if (unlikely(oqctl->qc_cmd != Q_GETQUOTA && - oqctl->qc_cmd != Q_GETINFO)) - RETURN(-EPERM); + switch (oqctl->qc_cmd) { + case Q_QUOTACHECK: + case LUSTRE_Q_INVALIDATE: + case LUSTRE_Q_FINVALIDATE: + case Q_QUOTAON: + case Q_QUOTAOFF: + case Q_INITQUOTA: + /* deprecated, not used any more */ + RETURN(-EOPNOTSUPP); + /* master quotactl */ + case Q_GETINFO: + case Q_SETINFO: + case Q_SETQUOTA: + case Q_GETQUOTA: + /* slave quotactl */ + case Q_GETOINFO: + case Q_GETOQUOTA: + break; + default: + CERROR("Unsupported quotactl command: %d\n", oqctl->qc_cmd); + RETURN(-EFAULT); + } + /* map uid/gid for remote client */ + id = oqctl->qc_id; + if (exp_connect_rmtclient(exp)) { + struct lustre_idmap_table *idmap; + + idmap = mdt_req2med(mdt_info_req(info))->med_idmap; + + if (unlikely(oqctl->qc_cmd != Q_GETQUOTA && + oqctl->qc_cmd != Q_GETINFO)) + RETURN(-EPERM); + + if (oqctl->qc_type == USRQUOTA) + id = lustre_idmap_lookup_uid(NULL, idmap, 0, + oqctl->qc_id); + else if (oqctl->qc_type == GRPQUOTA) + id = lustre_idmap_lookup_gid(NULL, idmap, 0, + oqctl->qc_id); + else + RETURN(-EINVAL); + + if (id == CFS_IDMAP_NOTFOUND) { + CDEBUG(D_QUOTA, "no mapping for id %u\n", oqctl->qc_id); + RETURN(-EACCES); + } + } - if (oqctl->qc_type == USRQUOTA) - id = lustre_idmap_lookup_uid(NULL, idmap, 0, - oqctl->qc_id); - else if (oqctl->qc_type == GRPQUOTA) - id = lustre_idmap_lookup_gid(NULL, idmap, 0, - oqctl->qc_id); - else - RETURN(-EINVAL); + repoqc = req_capsule_server_get(pill, &RMF_OBD_QUOTACTL); + if (repoqc == NULL) + RETURN(err_serious(-EFAULT)); - if (id == CFS_IDMAP_NOTFOUND) { - CDEBUG(D_QUOTA, "no mapping for id %u\n", - oqctl->qc_id); - RETURN(-EACCES); - } - } + if (oqctl->qc_id != id) + swap(oqctl->qc_id, id); + + switch (oqctl->qc_cmd) { + + /* master quotactl */ + case Q_GETINFO: + case Q_SETINFO: + case Q_SETQUOTA: + /* XXX: not implemented yet. Will be when qmt support is + * added */ + CERROR("quotactl operation %d not implemented yet\n", + oqctl->qc_cmd); + RETURN(-EOPNOTSUPP); + case Q_GETQUOTA: + /* XXX: return no limit for now, just for testing purpose */ + memset(&oqctl->qc_dqblk, 0, sizeof(struct obd_dqblk)); + oqctl->qc_dqblk.dqb_valid = QIF_LIMITS; + rc = 0; + break; - rc = req_capsule_server_pack(pill); - if (rc) - RETURN(rc); + /* slave quotactl */ + case Q_GETOINFO: + case Q_GETOQUOTA: + rc = lquotactl_slv(info->mti_env, info->mti_mdt->mdt_bottom, + oqctl); + break; - repoqc = req_capsule_server_get(pill, &RMF_OBD_QUOTACTL); - LASSERT(repoqc != NULL); + default: + CERROR("Unsupported quotactl command: %d\n", oqctl->qc_cmd); + RETURN(-EFAULT); + } - mq->mq_exp = exp; - switch (oqctl->qc_cmd) { - case Q_QUOTAON: - rc = mqo->mqo_on(info->mti_env, next, oqctl->qc_type); - break; - case Q_QUOTAOFF: - rc = mqo->mqo_off(info->mti_env, next, oqctl->qc_type); - break; - case Q_SETINFO: - rc = mqo->mqo_setinfo(info->mti_env, next, oqctl->qc_type, id, - &oqctl->qc_dqinfo); - break; - case Q_GETINFO: - rc = mqo->mqo_getinfo(info->mti_env, next, oqctl->qc_type, id, - &oqctl->qc_dqinfo); - break; - case Q_SETQUOTA: - rc = mqo->mqo_setquota(info->mti_env, next, oqctl->qc_type, id, - &oqctl->qc_dqblk); - break; - case Q_GETQUOTA: - rc = mqo->mqo_getquota(info->mti_env, next, oqctl->qc_type, id, - &oqctl->qc_dqblk); - break; - case Q_GETOINFO: - rc = mqo->mqo_getoinfo(info->mti_env, next, oqctl->qc_type, id, - &oqctl->qc_dqinfo); - break; - case Q_GETOQUOTA: - rc = mqo->mqo_getoquota(info->mti_env, next, oqctl->qc_type, id, - &oqctl->qc_dqblk); - break; - case LUSTRE_Q_INVALIDATE: - rc = mqo->mqo_invalidate(info->mti_env, next, oqctl->qc_type); - break; - case LUSTRE_Q_FINVALIDATE: - rc = mqo->mqo_finvalidate(info->mti_env, next, oqctl->qc_type); - break; - default: - CERROR("unsupported mdt_quotactl command: %d\n", - oqctl->qc_cmd); - RETURN(-EFAULT); - } + if (oqctl->qc_id != id) + swap(oqctl->qc_id, id); - *repoqc = *oqctl; - RETURN(rc); + *repoqc = *oqctl; + RETURN(rc); } -#endif - /* * OBD PING and other handlers. @@ -4906,9 +4909,6 @@ static void mdt_fini(const struct lu_env *env, struct mdt_device *m) mdt_procfs_fini(m); -#ifdef HAVE_QUOTA_SUPPORT - next->md_ops->mdo_quota.mqo_cleanup(env, next); -#endif lut_fini(env, &m->mdt_lut); mdt_fs_cleanup(env, m); upcall_cache_cleanup(m->mdt_identity_cache); @@ -5136,16 +5136,11 @@ static int mdt_init0(const struct lu_env *env, struct mdt_device *m, mdt_adapt_sptlrpc_conf(obd, 1); next = m->mdt_child; -#ifdef HAVE_QUOTA_SUPPORT - rc = next->md_ops->mdo_quota.mqo_setup(env, next, lmi->lmi_mnt); - if (rc) - GOTO(err_llog_cleanup, rc); -#endif rc = next->md_ops->mdo_iocontrol(env, next, OBD_IOC_GET_MNTOPT, 0, &mntopts); if (rc) - GOTO(err_quota, rc); + GOTO(err_llog_cleanup, rc); if (mntopts & MNTOPT_USERXATTR) m->mdt_opts.mo_user_xattr = 1; @@ -5167,7 +5162,7 @@ static int mdt_init0(const struct lu_env *env, struct mdt_device *m, if (IS_ERR(m->mdt_identity_cache)) { rc = PTR_ERR(m->mdt_identity_cache); m->mdt_identity_cache = NULL; - GOTO(err_quota, rc); + GOTO(err_llog_cleanup, rc); } target_recovery_init(&m->mdt_lut, mdt_recovery_handle); @@ -5205,10 +5200,6 @@ err_recovery: target_recovery_fini(obd); upcall_cache_cleanup(m->mdt_identity_cache); m->mdt_identity_cache = NULL; -err_quota: -#ifdef HAVE_QUOTA_SUPPORT - next->md_ops->mdo_quota.mqo_cleanup(env, next); -#endif err_llog_cleanup: mdt_llog_ctxt_unclone(env, m, LLOG_CHANGELOG_ORIG_CTXT); mdt_obd_llog_cleanup(obd); @@ -5850,13 +5841,6 @@ static int mdt_upcall(const struct lu_env *env, struct md_device *md, /* Check that MDT is not yet configured */ LASSERT(!cfs_test_bit(MDT_FL_CFGLOG, &m->mdt_state)); break; -#ifdef HAVE_QUOTA_SUPPORT - case MD_LOV_QUOTA: - if (md->md_lu_dev.ld_obd->obd_recovering == 0 && - likely(md->md_lu_dev.ld_obd->obd_stopping == 0)) - next->md_ops->mdo_quota.mqo_recovery(env, next); - break; -#endif default: CERROR("invalid event\n"); rc = -EINVAL; @@ -5870,20 +5854,11 @@ static int mdt_obd_notify(struct obd_device *obd, enum obd_notify_event ev, void *data) { struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev); -#ifdef HAVE_QUOTA_SUPPORT - struct md_device *next = mdt->mdt_child; -#endif ENTRY; switch (ev) { case OBD_NOTIFY_CONFIG: mdt_allow_cli(mdt, (unsigned long)data); - -#ifdef HAVE_QUOTA_SUPPORT - /* quota_type has been processed, we can now handle - * incoming quota requests */ - next->md_ops->mdo_quota.mqo_notify(NULL, next); -#endif break; default: CDEBUG(D_INFO, "Unhandled notification %#x\n", ev); @@ -6131,18 +6106,10 @@ static int mdt_iocontrol(unsigned int cmd, struct obd_export *exp, int len, int mdt_postrecov(const struct lu_env *env, struct mdt_device *mdt) { struct lu_device *ld = md2lu_dev(mdt->mdt_child); -#ifdef HAVE_QUOTA_SUPPORT - struct obd_device *obd = mdt2obd_dev(mdt); - struct md_device *next = mdt->mdt_child; -#endif int rc; ENTRY; rc = ld->ld_ops->ldo_recovery_complete(env, ld); -#ifdef HAVE_QUOTA_SUPPORT - if (likely(obd->obd_stopping == 0)) - next->md_ops->mdo_quota.mqo_recovery(env, next); -#endif RETURN(rc); } @@ -6441,10 +6408,8 @@ DEF_MDT_HNDL_F(HABEO_CORPUS, DONE_WRITING, mdt_done_writing), DEF_MDT_HNDL_F(0 |HABEO_REFERO, PIN, mdt_pin), DEF_MDT_HNDL_0(0, SYNC, mdt_sync), DEF_MDT_HNDL_F(HABEO_CORPUS|HABEO_REFERO, IS_SUBDIR, mdt_is_subdir), -#ifdef HAVE_QUOTA_SUPPORT -DEF_MDT_HNDL_F(0, QUOTACHECK, mdt_quotacheck_handle), -DEF_MDT_HNDL_F(0, QUOTACTL, mdt_quotactl_handle) -#endif +DEF_MDT_HNDL_F(0, QUOTACHECK, mdt_quotacheck), +DEF_MDT_HNDL_F(0, QUOTACTL, mdt_quotactl) }; #define DEF_OBD_HNDL(flags, name, fn) \ diff --git a/lustre/obdclass/lprocfs_status.c b/lustre/obdclass/lprocfs_status.c index 0d072c4..521047c 100644 --- a/lustre/obdclass/lprocfs_status.c +++ b/lustre/obdclass/lprocfs_status.c @@ -1709,7 +1709,6 @@ void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats) LPROCFS_OBD_OP_INIT(num_private_stats, stats, get_uuid); LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotacheck); LPROCFS_OBD_OP_INIT(num_private_stats, stats, quotactl); - LPROCFS_OBD_OP_INIT(num_private_stats, stats, quota_adjust_qunit); LPROCFS_OBD_OP_INIT(num_private_stats, stats, ping); LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_new); LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_rem); @@ -2410,11 +2409,6 @@ int lprocfs_obd_rd_hash(char *page, char **start, off_t off, c += cfs_hash_debug_str(obd->obd_uuid_hash, page + c, count - c); c += cfs_hash_debug_str(obd->obd_nid_hash, page + c, count - c); c += cfs_hash_debug_str(obd->obd_nid_stats_hash, page+c, count-c); -#ifdef HAVE_QUOTA_SUPPORT - if (obd->u.obt.obt_qctxt.lqc_lqs_hash) - c += cfs_hash_debug_str(obd->u.obt.obt_qctxt.lqc_lqs_hash, - page + c, count - c); -#endif return c; } diff --git a/lustre/obdfilter/filter.c b/lustre/obdfilter/filter.c index ef7c213..82ba461 100644 --- a/lustre/obdfilter/filter.c +++ b/lustre/obdfilter/filter.c @@ -69,7 +69,6 @@ #include #include #include -#include #include #include #include @@ -2192,10 +2191,6 @@ int filter_common_setup(struct obd_device *obd, struct lustre_cfg* lcfg, /* do this after llog being initialized */ filter_adapt_sptlrpc_conf(obd, 1); - rc = lquota_setup(filter_quota_interface_ref, obd); - if (rc) - GOTO(err_post, rc); - q = bdev_get_queue(mnt->mnt_sb->s_bdev); if (queue_max_sectors(q) < queue_max_hw_sectors(q) && queue_max_sectors(q) < PTLRPC_MAX_BRW_SIZE >> 9) @@ -2705,7 +2700,6 @@ static int filter_precleanup(struct obd_device *obd, lprocfs_free_per_client_stats(obd); lprocfs_obd_cleanup(obd); lprocfs_free_obd_stats(obd); - lquota_cleanup(filter_quota_interface_ref, obd); break; } RETURN(rc); @@ -3067,8 +3061,6 @@ static int filter_destroy_export(struct obd_export *exp) exp->exp_obd->obd_name, exp->exp_client_uuid.uuid, exp, fed->fed_pending); - lquota_clearinfo(filter_quota_interface_ref, exp, exp->exp_obd); - target_destroy_export(exp); if (unlikely(obd_uuid_equals(&exp->exp_obd->obd_uuid, @@ -3167,8 +3159,6 @@ static int filter_disconnect(struct obd_export *exp) /* Flush any remaining cancel messages out to the target */ filter_sync_llogs(obd, exp); - lquota_clearinfo(filter_quota_interface_ref, exp, exp->exp_obd); - rc = server_disconnect_export(exp); /* Do not erase record for recoverable client. */ @@ -3323,7 +3313,6 @@ int filter_update_fidea(struct obd_export *exp, struct inode *inode, int filter_setattr_internal(struct obd_export *exp, struct dentry *dentry, struct obdo *oa, struct obd_trans_info *oti) { - unsigned int orig_ids[MAXQUOTAS] = {0, 0}; struct llog_cookie *fcc = NULL; struct filter_obd *filter; int rc, err, sync = 0; @@ -3403,8 +3392,6 @@ int filter_setattr_internal(struct obd_export *exp, struct dentry *dentry, iattr.ia_mode &= ~S_ISGID; } - orig_ids[USRQUOTA] = inode->i_uid; - orig_ids[GRPQUOTA] = inode->i_gid; handle = fsfilt_start_log(exp->exp_obd, inode, FSFILT_OP_SETATTR, oti, 1); if (IS_ERR(handle)) @@ -3485,16 +3472,6 @@ out_unlock: up_write(&inode->i_alloc_sem); if (fcc) OBD_FREE(fcc, sizeof(*fcc)); - - /* trigger quota release */ - if (ia_valid & (ATTR_SIZE | ATTR_UID | ATTR_GID)) { - unsigned int cur_ids[MAXQUOTAS] = {oa->o_uid, oa->o_gid}; - int rc2 = lquota_adjust(filter_quota_interface_ref, - exp->exp_obd, cur_ids, - orig_ids, rc, FSFILT_OP_SETATTR); - CDEBUG(rc2 ? D_ERROR : D_QUOTA, - "filter adjust qunit. (rc:%d)\n", rc2); - } return rc; } @@ -4235,7 +4212,6 @@ int filter_destroy(const struct lu_env *env, struct obd_export *exp, struct obd_trans_info *oti, struct obd_export *md_exp, void *capa) { - unsigned int qcids[MAXQUOTAS] = {0, 0}; struct obd_device *obd; struct filter_obd *filter; struct dentry *dchild = NULL, *dparent = NULL; @@ -4417,13 +4393,6 @@ cleanup: LBUG(); } - /* trigger quota release */ - qcids[USRQUOTA] = oa->o_uid; - qcids[GRPQUOTA] = oa->o_gid; - rc2 = lquota_adjust(filter_quota_interface_ref, obd, qcids, NULL, rc, - FSFILT_OP_UNLINK); - if (rc2) - CERROR("filter adjust qunit! (rc:%d)\n", rc2); return rc; } @@ -4659,8 +4628,6 @@ static int filter_set_mds_conn(struct obd_export *exp, void *val) /* setup llog group 1 for interop */ filter_setup_llog_group(exp, obd, FID_SEQ_LLOG); } - - lquota_setinfo(filter_quota_interface_ref, obd, exp); out: RETURN(rc); } @@ -4689,7 +4656,6 @@ static int filter_set_info_async(const struct lu_env *env, if (KEY_IS(KEY_REVIMP_UPD)) { filter_revimp_update(exp); - lquota_clearinfo(filter_quota_interface_ref, exp, exp->exp_obd); RETURN(0); } @@ -4877,9 +4843,6 @@ static struct obd_ops filter_obd_ops = { .o_notify = filter_notify, }; -quota_interface_t *filter_quota_interface_ref; -extern quota_interface_t filter_quota_interface; - static int __init obdfilter_init(void) { struct lprocfs_static_vars lvars; @@ -4891,7 +4854,6 @@ static int __init obdfilter_init(void) lprocfs_filter_init_vars(&lvars); - cfs_request_module("%s", "lquota"); OBD_ALLOC(obdfilter_created_scratchpad, OBDFILTER_CREATED_SCRATCHPAD_ENTRIES * sizeof(*obdfilter_created_scratchpad)); @@ -4904,9 +4866,6 @@ static int __init obdfilter_init(void) if (!ll_fmd_cachep) GOTO(out, rc = -ENOMEM); - filter_quota_interface_ref = PORTAL_SYMBOL_GET(filter_quota_interface); - init_obd_quota_ops(filter_quota_interface_ref, &filter_obd_ops); - rc = class_register_type(&filter_obd_ops, NULL, lvars.module_vars, LUSTRE_OST_NAME, NULL); if (rc) { @@ -4916,9 +4875,6 @@ static int __init obdfilter_init(void) LASSERTF(err == 0, "Cannot destroy ll_fmd_cachep: rc %d\n",err); ll_fmd_cachep = NULL; out: - if (filter_quota_interface_ref) - PORTAL_SYMBOL_PUT(filter_quota_interface); - OBD_FREE(obdfilter_created_scratchpad, OBDFILTER_CREATED_SCRATCHPAD_ENTRIES * sizeof(*obdfilter_created_scratchpad)); @@ -4929,9 +4885,6 @@ out: static void __exit obdfilter_exit(void) { - if (filter_quota_interface_ref) - PORTAL_SYMBOL_PUT(filter_quota_interface); - if (ll_fmd_cachep) { int rc = cfs_mem_cache_destroy(ll_fmd_cachep); LASSERTF(rc == 0, "Cannot destroy ll_fmd_cachep: rc %d\n", rc); diff --git a/lustre/obdfilter/filter_internal.h b/lustre/obdfilter/filter_internal.h index b50e985..fb51922 100644 --- a/lustre/obdfilter/filter_internal.h +++ b/lustre/obdfilter/filter_internal.h @@ -266,9 +266,6 @@ static void lprocfs_filter_init_vars(struct lprocfs_static_vars *lvars) static inline void filter_stats_counter_init(struct lprocfs_stats *stats) {} #endif -/* Quota stuff */ -extern quota_interface_t *filter_quota_interface_ref; - int filter_update_capa_key(struct obd_device *obd, struct lustre_capa_key *key); int filter_auth_capa(struct obd_export *exp, struct lu_fid *fid, obd_seq seq, struct lustre_capa *capa, __u64 opc); diff --git a/lustre/obdfilter/filter_io_26.c b/lustre/obdfilter/filter_io_26.c index 53c293c..f2becd9 100644 --- a/lustre/obdfilter/filter_io_26.c +++ b/lustre/obdfilter/filter_io_26.c @@ -49,7 +49,6 @@ #include #include -#include #include "filter_internal.h" /* 512byte block min */ @@ -484,9 +483,6 @@ int filter_direct_io(int rw, struct dentry *dchild, struct filter_iobuf *iobuf, LASSERT(iobuf->dr_npages > 0); create = 1; mutex = &obd->u.filter.fo_alloc_lock; - - lquota_enforce(filter_quota_interface_ref, obd, - iobuf->dr_ignore_quota); } if (rw == OBD_BRW_WRITE && @@ -592,8 +588,6 @@ int filter_commitrw_write(struct obd_export *exp, struct obdo *oa, struct filter_obd *fo = &obd->u.filter; void *wait_handle = NULL; int total_size = 0; - unsigned int qcids[MAXQUOTAS] = { oa->o_uid, oa->o_gid }; - int rec_pending[MAXQUOTAS] = { 0, 0 }, quota_pages = 0; int sync_journal_commit = obd->u.filter.fo_syncjournal; int retries = 0; ENTRY; @@ -624,8 +618,6 @@ int filter_commitrw_write(struct obd_export *exp, struct obdo *oa, * we don't need a grant */ if (!(flags & OBD_BRW_GRANTED) && lnb->rc == -ENOSPC) lnb->rc = 0; - } else { - quota_pages++; } if (lnb->rc) { /* ENOSPC, network RPC error, etc. */ @@ -670,22 +662,12 @@ int filter_commitrw_write(struct obd_export *exp, struct obdo *oa, } } - /* we try to get enough quota to write here, and let ldiskfs - * decide if it is out of quota or not b=14783 */ - rc = lquota_chkquota(filter_quota_interface_ref, obd, exp, qcids, - rec_pending, quota_pages, oti, LQUOTA_FLAGS_BLK, - (void *)inode, obj->ioo_bufcnt); - if (rc == -ENOTCONN) - GOTO(cleanup, rc); - if (OBD_FAIL_CHECK(OBD_FAIL_OST_DQACQ_NET)) GOTO(cleanup, rc = -EINPROGRESS); push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); cleanup_phase = 2; - fsfilt_check_slow(obd, now, "quota init"); - retry: mutex_lock(&inode->i_mutex); fsfilt_check_slow(obd, now, "i_mutex"); @@ -769,7 +751,6 @@ retry: oa->o_id, (__u32)oa->o_seq, (__u32)oa->o_seq, oa->o_size, oa->o_mtime, oa->o_atime, oa->o_ctime, oa->o_blocks); - lquota_getflag(filter_quota_interface_ref, obd, oa); fsfilt_check_slow(obd, now, "direct_io"); @@ -810,9 +791,6 @@ retry: fsfilt_check_slow(obd, now, "commitrw commit"); cleanup: - lquota_pending_commit(filter_quota_interface_ref, obd, qcids, - rec_pending, 1); - filter_grant_commit(exp, niocount, res); switch (cleanup_phase) { @@ -829,22 +807,6 @@ cleanup: break; } - /* trigger quota pre-acquire */ - err = lquota_adjust(filter_quota_interface_ref, obd, qcids, NULL, rc, - FSFILT_OP_CREATE); - CDEBUG(err ? D_ERROR : D_QUOTA, "filter adjust qunit! " - "(rc:%d, uid:%u, gid:%u)\n", - err, qcids[USRQUOTA], qcids[GRPQUOTA]); - if (qcids[USRQUOTA] != oa->o_uid || qcids[GRPQUOTA] != oa->o_gid) { - qcids[USRQUOTA] = oa->o_uid; - qcids[GRPQUOTA] = oa->o_gid; - err = lquota_adjust(filter_quota_interface_ref, obd, qcids, - NULL, rc, FSFILT_OP_CREATE); - CDEBUG(err ? D_ERROR : D_QUOTA, "filter adjust qunit! " - "(rc:%d, uid:%u, gid:%u)\n", - err, qcids[USRQUOTA], qcids[GRPQUOTA]); - } - for (i = 0, lnb = res; i < niocount; i++, lnb++) { if (lnb->page == NULL) continue; diff --git a/lustre/obdfilter/lproc_obdfilter.c b/lustre/obdfilter/lproc_obdfilter.c index 12871fe..f139c81 100644 --- a/lustre/obdfilter/lproc_obdfilter.c +++ b/lustre/obdfilter/lproc_obdfilter.c @@ -454,10 +454,6 @@ static struct lprocfs_vars lprocfs_filter_obd_vars[] = { { "readcache_max_filesize", lprocfs_filter_rd_readcache, lprocfs_filter_wr_readcache, 0 }, -#ifdef HAVE_QUOTA_SUPPORT - { "quota_type", lprocfs_quota_rd_type, - lprocfs_quota_wr_type, 0}, -#endif { "client_cache_count", lprocfs_filter_rd_fmd_max_num, lprocfs_filter_wr_fmd_max_num, 0 }, { "client_cache_seconds", lprocfs_filter_rd_fmd_max_age, diff --git a/lustre/ofd/lproc_ofd.c b/lustre/ofd/lproc_ofd.c index 64c046d..3fbfd1e 100644 --- a/lustre/ofd/lproc_ofd.c +++ b/lustre/ofd/lproc_ofd.c @@ -464,9 +464,6 @@ static struct lprocfs_vars lprocfs_ofd_obd_vars[] = { { "capa", lprocfs_ofd_rd_capa, lprocfs_ofd_wr_capa, 0 }, { "capa_count", lprocfs_ofd_rd_capa_count, 0, 0 }, - /* we still register a fake quota type file for backward compatibility*/ - { "quota_type", lprocfs_quota_rd_type_dumb, - lprocfs_quota_wr_type_dumb, 0}, { 0 } }; diff --git a/lustre/ofd/ofd_obd.c b/lustre/ofd/ofd_obd.c index a49b490..0459ad8 100644 --- a/lustre/ofd/ofd_obd.c +++ b/lustre/ofd/ofd_obd.c @@ -1426,40 +1426,7 @@ static int ofd_obd_notify(struct obd_device *obd, struct obd_device *unused, } /* - * Handle quotacheck requests. - * Although in-kernel quotacheck isn't supported any more, we still emulate it - * in order to interoperate with current MDT stack which needs proper - * quotacheck support, even for space accounting. - * - * \param obd - is the obd device associated with the ofd - * \param exp - is the client's export - * \param oqctl - is the obd_quotactl request to be processed - */ -static int ofd_quotacheck(struct obd_device *obd, struct obd_export *exp, - struct obd_quotactl *oqctl) -{ - struct ptlrpc_request *req; - struct obd_quotactl *body; - ENTRY; - - req = ptlrpc_request_alloc_pack(exp->exp_imp_reverse, &RQF_QC_CALLBACK, - LUSTRE_OBD_VERSION, OBD_QC_CALLBACK); - if (req == NULL) - RETURN(-ENOMEM); - - body = req_capsule_client_get(&req->rq_pill, &RMF_OBD_QUOTACTL); - oqctl->qc_stat = 0; - memcpy(body, oqctl, sizeof(*body)); - - ptlrpc_request_set_replen(req); - ptlrpcd_add_req(req, PDL_POLICY_ROUND, -1); - - RETURN(0); -} - -/* - * Handle quota control requests to consult current usage/limit, but also - * to configure quota enforcement + * Handle quota control requests to consult current usage/limit. * * \param obd - is the obd device associated with the ofd * \param exp - is the client's export @@ -1513,5 +1480,4 @@ struct obd_ops ofd_obd_ops = { .o_health_check = ofd_health_check, .o_notify = ofd_obd_notify, .o_quotactl = ofd_quotactl, - .o_quotacheck = ofd_quotacheck, }; diff --git a/lustre/osc/osc_internal.h b/lustre/osc/osc_internal.h index aa24a5b..0c21792 100644 --- a/lustre/osc/osc_internal.h +++ b/lustre/osc/osc_internal.h @@ -217,8 +217,4 @@ int osc_quotactl(struct obd_device *unused, struct obd_export *exp, int osc_quotacheck(struct obd_device *unused, struct obd_export *exp, struct obd_quotactl *oqctl); int osc_quota_poll_check(struct obd_export *exp, struct if_quotacheck *qchk); -int osc_quota_adjust_qunit(struct obd_export *exp, - struct quota_adjust_qunit *oqaq, - struct lustre_quota_ctxt *qctxt, - struct ptlrpc_request_set *rqset); #endif /* OSC_INTERNAL_H */ diff --git a/lustre/osc/osc_quota.c b/lustre/osc/osc_quota.c index 0cd9fae7..d165433 100644 --- a/lustre/osc/osc_quota.c +++ b/lustre/osc/osc_quota.c @@ -333,40 +333,3 @@ int osc_quota_poll_check(struct obd_export *exp, struct if_quotacheck *qchk) rc = -EINTR; RETURN(rc); } - -int osc_quota_adjust_qunit(struct obd_export *exp, - struct quota_adjust_qunit *oqaq, - struct lustre_quota_ctxt *qctxt, - struct ptlrpc_request_set *rqset) -{ - struct ptlrpc_request *req; - struct quota_adjust_qunit *oqa; - int rc = 0; - ENTRY; - - /* client don't support this kind of operation, abort it */ - if (!(exp->exp_connect_flags & OBD_CONNECT_CHANGE_QS)) { - CDEBUG(D_QUOTA, "osc: %s don't support change qunit size\n", - exp->exp_obd->obd_name); - RETURN(rc); - } - if (strcmp(exp->exp_obd->obd_type->typ_name, LUSTRE_OSC_NAME)) - RETURN(-EINVAL); - - LASSERT(rqset); - - req = ptlrpc_request_alloc_pack(class_exp2cliimp(exp), - &RQF_OST_QUOTA_ADJUST_QUNIT, - LUSTRE_OST_VERSION, - OST_QUOTA_ADJUST_QUNIT); - if (req == NULL) - RETURN(-ENOMEM); - - oqa = req_capsule_client_get(&req->rq_pill, &RMF_QUOTA_ADJUST_QUNIT); - *oqa = *oqaq; - - ptlrpc_request_set_replen(req); - - ptlrpc_set_add_req(rqset, req); - RETURN(rc); -} diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index 22c1eb9..af60e4b 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -3775,7 +3775,6 @@ struct obd_ops osc_obd_ops = { .o_process_config = osc_process_config, .o_quotactl = osc_quotactl, .o_quotacheck = osc_quotacheck, - .o_quota_adjust_qunit = osc_quota_adjust_qunit, }; extern struct lu_kmem_descr osc_caches[]; diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c index b5ab966..9a51c0c 100644 --- a/lustre/osd-ldiskfs/osd_handler.c +++ b/lustre/osd-ldiskfs/osd_handler.c @@ -104,51 +104,6 @@ static int osd_object_invariant(const struct lu_object *l) return osd_invariant(osd_obj(l)); } -#ifdef HAVE_QUOTA_SUPPORT -static inline void -osd_push_ctxt(const struct lu_env *env, struct osd_ctxt *save, bool is_md) -{ - struct md_ucred *uc; - struct cred *tc; - - if (!is_md) - /* OFD support */ - return; - - uc = md_ucred(env); - - LASSERT(uc != NULL); - - save->oc_uid = current_fsuid(); - save->oc_gid = current_fsgid(); - save->oc_cap = current_cap(); - if ((tc = prepare_creds())) { - tc->fsuid = uc->mu_fsuid; - tc->fsgid = uc->mu_fsgid; - commit_creds(tc); - } - /* XXX not suboptimal */ - cfs_curproc_cap_unpack(uc->mu_cap); -} - -static inline void -osd_pop_ctxt(struct osd_ctxt *save, bool is_md) -{ - struct cred *tc; - - if (!is_md) - /* OFD support */ - return; - - if ((tc = prepare_creds())) { - tc->fsuid = save->oc_uid; - tc->fsgid = save->oc_gid; - tc->cap_effective = save->oc_cap; - commit_creds(tc); - } -} -#endif - /* * Concurrency: doesn't matter */ @@ -1616,34 +1571,11 @@ static int osd_attr_set(const struct lu_env *env, OSD_EXEC_OP(handle, attr_set); inode = obj->oo_inode; - if (!osd_dt_dev(handle->th_dev)->od_is_md) { - /* OFD support */ - rc = osd_quota_transfer(inode, attr); - if (rc) - return rc; - } else { -#ifdef HAVE_QUOTA_SUPPORT - if ((attr->la_valid & LA_UID && attr->la_uid != inode->i_uid) || - (attr->la_valid & LA_GID && attr->la_gid != inode->i_gid)) { - struct osd_ctxt *save = &osd_oti_get(env)->oti_ctxt; - struct iattr iattr; - int rc; - - iattr.ia_valid = 0; - if (attr->la_valid & LA_UID) - iattr.ia_valid |= ATTR_UID; - if (attr->la_valid & LA_GID) - iattr.ia_valid |= ATTR_GID; - iattr.ia_uid = attr->la_uid; - iattr.ia_gid = attr->la_gid; - osd_push_ctxt(env, save, 1); - rc = ll_vfs_dq_transfer(inode, &iattr) ? -EDQUOT : 0; - osd_pop_ctxt(save, 1); - if (rc != 0) - return rc; - } -#endif - } + + rc = osd_quota_transfer(inode, attr); + if (rc) + return rc; + cfs_spin_lock(&obj->oo_guard); rc = osd_inode_setattr(env, inode, attr); cfs_spin_unlock(&obj->oo_guard); @@ -1670,9 +1602,6 @@ static int osd_mkfile(struct osd_thread_info *info, struct osd_object *obj, struct osd_thandle *oth; struct dt_object *parent = NULL; struct inode *inode; -#ifdef HAVE_QUOTA_SUPPORT - struct osd_ctxt *save = &info->oti_ctxt; -#endif LINVRNT(osd_invariant(obj)); LASSERT(obj->oo_inode == NULL); @@ -1690,16 +1619,10 @@ static int osd_mkfile(struct osd_thread_info *info, struct osd_object *obj, if (hint && hint->dah_parent) parent = hint->dah_parent; -#ifdef HAVE_QUOTA_SUPPORT - osd_push_ctxt(info->oti_env, save, osd_dt_dev(th->th_dev)->od_is_md); -#endif inode = ldiskfs_create_inode(oth->ot_handle, parent ? osd_dt_obj(parent)->oo_inode : osd_sb(osd)->s_root->d_inode, mode); -#ifdef HAVE_QUOTA_SUPPORT - osd_pop_ctxt(save, osd_dt_dev(th->th_dev)->od_is_md); -#endif if (!IS_ERR(inode)) { /* Do not update file c/mtime in ldiskfs. * NB: don't need any lock because no contention at this @@ -1902,16 +1825,9 @@ static void osd_attr_init(struct osd_thread_info *info, struct osd_object *obj, if ((valid & LA_MTIME) && (attr->la_mtime == LTIME_S(inode->i_mtime))) attr->la_valid &= ~LA_MTIME; - if (!osd_obj2dev(obj)->od_is_md) { - /* OFD support */ - result = osd_quota_transfer(inode, attr); - if (result) - return; - } else { -#ifdef HAVE_QUOTA_SUPPORT - attr->la_valid &= ~(LA_UID | LA_GID); -#endif - } + result = osd_quota_transfer(inode, attr); + if (result) + return; if (attr->la_valid != 0) { result = osd_inode_setattr(info->oti_env, inode, attr); @@ -1977,11 +1893,6 @@ static int __osd_oi_insert(const struct lu_env *env, struct osd_object *obj, LASSERT(obj->oo_inode != NULL); - if (osd->od_is_md) { - struct md_ucred *uc = md_ucred(env); - LASSERT(uc != NULL); - } - osd_id_gen(id, obj->oo_inode->i_ino, obj->oo_inode->i_generation); return osd_oi_insert(info, osd, fid, id, th); } @@ -3201,9 +3112,6 @@ static int osd_index_iam_insert(const struct lu_env *env, struct dt_object *dt, struct iam_path_descr *ipd; struct osd_thandle *oh; struct iam_container *bag = &obj->oo_dir->od_container; -#ifdef HAVE_QUOTA_SUPPORT - cfs_cap_t save = cfs_curproc_cap_pack(); -#endif struct osd_thread_info *oti = osd_oti_get(env); struct iam_rec *iam_rec; int rc; @@ -3227,12 +3135,6 @@ static int osd_index_iam_insert(const struct lu_env *env, struct dt_object *dt, oh = container_of0(th, struct osd_thandle, ot_super); LASSERT(oh->ot_handle != NULL); LASSERT(oh->ot_handle->h_transaction != NULL); -#ifdef HAVE_QUOTA_SUPPORT - if (ignore_quota) - cfs_cap_raise(CFS_CAP_SYS_RESOURCE); - else - cfs_cap_lower(CFS_CAP_SYS_RESOURCE); -#endif if (S_ISDIR(obj->oo_inode->i_mode)) { iam_rec = (struct iam_rec *)oti->oti_ldp; osd_fid_pack((struct osd_fid_pack *)iam_rec, rec, &oti->oti_fid); @@ -3249,9 +3151,6 @@ static int osd_index_iam_insert(const struct lu_env *env, struct dt_object *dt, rc = iam_insert(oh->ot_handle, bag, (const struct iam_key *)key, iam_rec, ipd); -#ifdef HAVE_QUOTA_SUPPORT - cfs_curproc_cap_unpack(save); -#endif osd_ipd_put(env, bag, ipd); LINVRNT(osd_invariant(obj)); RETURN(rc); @@ -3648,9 +3547,6 @@ static int osd_index_ea_insert(const struct lu_env *env, struct dt_object *dt, struct lu_fid *fid = (struct lu_fid *) rec; const char *name = (const char *)key; struct osd_object *child; -#ifdef HAVE_QUOTA_SUPPORT - cfs_cap_t save = cfs_curproc_cap_pack(); -#endif int rc; ENTRY; @@ -3664,16 +3560,7 @@ static int osd_index_ea_insert(const struct lu_env *env, struct dt_object *dt, child = osd_object_find(env, dt, fid); if (!IS_ERR(child)) { -#ifdef HAVE_QUOTA_SUPPORT - if (ignore_quota) - cfs_cap_raise(CFS_CAP_SYS_RESOURCE); - else - cfs_cap_lower(CFS_CAP_SYS_RESOURCE); -#endif rc = osd_ea_add_rec(env, obj, child->oo_inode, name, rec, th); -#ifdef HAVE_QUOTA_SUPPORT - cfs_curproc_cap_unpack(save); -#endif osd_object_put(env, child); } else { rc = PTR_ERR(child); diff --git a/lustre/osd-ldiskfs/osd_internal.h b/lustre/osd-ldiskfs/osd_internal.h index ab5fc62a..54d6185 100644 --- a/lustre/osd-ldiskfs/osd_internal.h +++ b/lustre/osd-ldiskfs/osd_internal.h @@ -89,14 +89,6 @@ struct inode; /** Enable thandle usage statistics */ #define OSD_THANDLE_STATS (0) -#ifdef HAVE_QUOTA_SUPPORT -struct osd_ctxt { - __u32 oc_uid; - __u32 oc_gid; - cfs_kernel_cap_t oc_cap; -}; -#endif - struct osd_directory { struct iam_container od_container; struct iam_descr od_descr; @@ -601,9 +593,6 @@ struct osd_thread_info { struct osd_iobuf oti_iobuf; struct inode oti_inode; int oti_created[PTLRPC_MAX_BRW_PAGES]; -#ifdef HAVE_QUOTA_SUPPORT - struct osd_ctxt oti_ctxt; -#endif struct lu_env oti_obj_delete_tx_env; #define OSD_FID_REC_SZ 32 char oti_ldp[OSD_FID_REC_SZ]; diff --git a/lustre/osd-ldiskfs/osd_io.c b/lustre/osd-ldiskfs/osd_io.c index d641331..ef045a5 100644 --- a/lustre/osd-ldiskfs/osd_io.c +++ b/lustre/osd-ldiskfs/osd_io.c @@ -1115,9 +1115,6 @@ static ssize_t osd_write(const struct lu_env *env, struct dt_object *dt, struct inode *inode = osd_dt_obj(dt)->oo_inode; struct osd_thandle *oh; ssize_t result; -#ifdef HAVE_QUOTA_SUPPORT - cfs_cap_t save = cfs_curproc_cap_pack(); -#endif int is_link; LASSERT(dt_object_exists(dt)); @@ -1132,12 +1129,6 @@ static ssize_t osd_write(const struct lu_env *env, struct dt_object *dt, oh = container_of(handle, struct osd_thandle, ot_super); LASSERT(oh->ot_handle->h_transaction != NULL); -#ifdef HAVE_QUOTA_SUPPORT - if (ignore_quota) - cfs_cap_raise(CFS_CAP_SYS_RESOURCE); - else - cfs_cap_lower(CFS_CAP_SYS_RESOURCE); -#endif /* Write small symlink to inode body as we need to maintain correct * on-disk symlinks for ldiskfs. * Note: the buf->lb_buf contains a NUL terminator while buf->lb_len @@ -1150,9 +1141,6 @@ static ssize_t osd_write(const struct lu_env *env, struct dt_object *dt, result = osd_ldiskfs_write_record(inode, buf->lb_buf, buf->lb_len, is_link, pos, oh->ot_handle); -#ifdef HAVE_QUOTA_SUPPORT - cfs_curproc_cap_unpack(save); -#endif if (result == 0) result = buf->lb_len; return result; diff --git a/lustre/osd-ldiskfs/osd_oi.c b/lustre/osd-ldiskfs/osd_oi.c index b4d3ee4..4319f47 100644 --- a/lustre/osd-ldiskfs/osd_oi.c +++ b/lustre/osd-ldiskfs/osd_oi.c @@ -528,9 +528,6 @@ static int osd_oi_iam_insert(struct osd_thread_info *oti, struct osd_oi *oi, struct iam_path_descr *ipd; struct osd_thandle *oh; int rc; -#ifdef HAVE_QUOTA_SUPPORT - cfs_cap_t save = cfs_curproc_cap_pack(); -#endif ENTRY; LASSERT(oi); @@ -544,9 +541,6 @@ static int osd_oi_iam_insert(struct osd_thread_info *oti, struct osd_oi *oi, oh = container_of0(th, struct osd_thandle, ot_super); LASSERT(oh->ot_handle != NULL); LASSERT(oh->ot_handle->h_transaction != NULL); -#ifdef HAVE_QUOTA_SUPPORT - cfs_cap_raise(CFS_CAP_SYS_RESOURCE); -#endif if (S_ISDIR(oi->oi_inode->i_mode)) osd_fid_pack((struct osd_fid_pack *)iam_rec, rec, &oti->oti_fid); @@ -554,9 +548,6 @@ static int osd_oi_iam_insert(struct osd_thread_info *oti, struct osd_oi *oi, iam_rec = (struct iam_rec *) rec; rc = iam_insert(oh->ot_handle, bag, (const struct iam_key *)key, iam_rec, ipd); -#ifdef HAVE_QUOTA_SUPPORT - cfs_curproc_cap_unpack(save); -#endif osd_ipd_put(oti->oti_env, bag, ipd); LINVRNT(osd_invariant(obj)); RETURN(rc); diff --git a/lustre/ost/ost_handler.c b/lustre/ost/ost_handler.c index 2318c03..37c0304 100644 --- a/lustre/ost/ost_handler.c +++ b/lustre/ost/ost_handler.c @@ -1299,7 +1299,6 @@ static int ost_get_info(struct obd_export *exp, struct ptlrpc_request *req) RETURN(rc); } -#ifdef HAVE_QUOTA_SUPPORT static int ost_handle_quotactl(struct ptlrpc_request *req) { struct obd_quotactl *oqctl, *repoqc; @@ -1336,35 +1335,11 @@ static int ost_handle_quotacheck(struct ptlrpc_request *req) if (rc) RETURN(-ENOMEM); - req->rq_status = obd_quotacheck(req->rq_export, oqctl); - RETURN(0); + /* deprecated, not used any more */ + req->rq_status = -EOPNOTSUPP; + RETURN(-EOPNOTSUPP); } -static int ost_handle_quota_adjust_qunit(struct ptlrpc_request *req) -{ - struct quota_adjust_qunit *oqaq, *repoqa; - struct lustre_quota_ctxt *qctxt; - int rc; - ENTRY; - - qctxt = &req->rq_export->exp_obd->u.obt.obt_qctxt; - oqaq = req_capsule_client_get(&req->rq_pill, &RMF_QUOTA_ADJUST_QUNIT); - if (oqaq == NULL) - GOTO(out, rc = -EPROTO); - - rc = req_capsule_server_pack(&req->rq_pill); - if (rc) - GOTO(out, rc); - - repoqa = req_capsule_server_get(&req->rq_pill, &RMF_QUOTA_ADJUST_QUNIT); - req->rq_status = obd_quota_adjust_qunit(req->rq_export, oqaq, qctxt, NULL); - *repoqa = *oqaq; - - out: - RETURN(rc); -} -#endif - static int ost_llog_handle_connect(struct obd_export *exp, struct ptlrpc_request *req) { @@ -1666,11 +1641,9 @@ int ost_msg_check_version(struct lustre_msg *msg) case OST_SYNC: case OST_SET_INFO: case OST_GET_INFO: -#ifdef HAVE_QUOTA_SUPPORT case OST_QUOTACHECK: case OST_QUOTACTL: case OST_QUOTA_ADJUST_QUNIT: -#endif rc = lustre_msg_check_version(msg, LUSTRE_OST_VERSION); if (rc) CERROR("bad opc %u version %08x, expecting %08x\n", @@ -2290,7 +2263,6 @@ int ost_handle(struct ptlrpc_request *req) req_capsule_set(&req->rq_pill, &RQF_OST_GET_INFO_GENERIC); rc = ost_get_info(req->rq_export, req); break; -#ifdef HAVE_QUOTA_SUPPORT case OST_QUOTACHECK: CDEBUG(D_INODE, "quotacheck\n"); req_capsule_set(&req->rq_pill, &RQF_OST_QUOTACHECK); @@ -2305,12 +2277,6 @@ int ost_handle(struct ptlrpc_request *req) RETURN(0); rc = ost_handle_quotactl(req); break; - case OST_QUOTA_ADJUST_QUNIT: - CDEBUG(D_INODE, "quota_adjust_qunit\n"); - req_capsule_set(&req->rq_pill, &RQF_OST_QUOTA_ADJUST_QUNIT); - rc = ost_handle_quota_adjust_qunit(req); - break; -#endif case OBD_PING: DEBUG_REQ(D_INODE, req, "ping"); req_capsule_set(&req->rq_pill, &RQF_OBD_PING); diff --git a/lustre/quota/Makefile.in b/lustre/quota/Makefile.in index 309f941..486e52d 100644 --- a/lustre/quota/Makefile.in +++ b/lustre/quota/Makefile.in @@ -1,14 +1,11 @@ MODULES := lquota -quota-objs := lquota_lib.o lquota_disk.o lproc_quota.o -quota-objs += quota_check.o quota_context.o quota_ctl.o quota_interface.o -quota-objs += quota_master.o quota_adjust_qunit.o +quota-objs := lproc_quota.o lquota_lib.o lquota_disk.o qsd-objs := qsd_lib.o lquota-objs := $(quota-objs) $(qsd-objs) EXTRA_DIST := $(lquota-objs:%.o=%.c) lquota_internal.h qsd_internal.h -EXTRA_DIST += quota_internal.h @INCLUDE_RULES@ diff --git a/lustre/quota/lproc_quota.c b/lustre/quota/lproc_quota.c index 6c8a5c8..581cf63 100644 --- a/lustre/quota/lproc_quota.c +++ b/lustre/quota/lproc_quota.c @@ -43,7 +43,6 @@ #include #include "lquota_internal.h" -#include "quota_internal.h" #ifdef LPROCFS /* structure allocated at seq_open time and release when seq_release is called. @@ -298,652 +297,4 @@ struct file_operations lprocfs_quota_seq_fops = { .llseek = seq_lseek, .release = lprocfs_quota_seq_release, }; - -int lprocfs_quota_rd_type_dumb(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - return 0; -} -EXPORT_SYMBOL(lprocfs_quota_rd_type_dumb); - -int lprocfs_quota_wr_type_dumb(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - return count; -} -EXPORT_SYMBOL(lprocfs_quota_wr_type_dumb); - -int lprocfs_quota_rd_bunit(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - struct obd_device *obd = (struct obd_device *)data; - LASSERT(obd != NULL); - - return snprintf(page, count, "%lu\n", - obd->u.obt.obt_qctxt.lqc_bunit_sz); -} -EXPORT_SYMBOL(lprocfs_quota_rd_bunit); - -int lprocfs_quota_wr_bunit(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - struct obd_device *obd = (struct obd_device *)data; - int val, rc; - LASSERT(obd != NULL); - - rc = lprocfs_write_helper(buffer, count, &val); - if (rc) - return rc; - - if (val % QUOTABLOCK_SIZE || - val <= obd->u.obt.obt_qctxt.lqc_btune_sz) - return -EINVAL; - - obd->u.obt.obt_qctxt.lqc_bunit_sz = val; - return count; -} -EXPORT_SYMBOL(lprocfs_quota_wr_bunit); - -int lprocfs_quota_rd_btune(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - struct obd_device *obd = (struct obd_device *)data; - LASSERT(obd != NULL); - - return snprintf(page, count, "%lu\n", - obd->u.obt.obt_qctxt.lqc_btune_sz); -} -EXPORT_SYMBOL(lprocfs_quota_rd_btune); - -int lprocfs_quota_wr_btune(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - struct obd_device *obd = (struct obd_device *)data; - int val, rc; - LASSERT(obd != NULL); - - rc = lprocfs_write_helper(buffer, count, &val); - if (rc) - return rc; - - if (val <= QUOTABLOCK_SIZE * MIN_QLIMIT || val % QUOTABLOCK_SIZE || - val >= obd->u.obt.obt_qctxt.lqc_bunit_sz) - return -EINVAL; - - obd->u.obt.obt_qctxt.lqc_btune_sz = val; - return count; -} -EXPORT_SYMBOL(lprocfs_quota_wr_btune); - -int lprocfs_quota_rd_iunit(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - struct obd_device *obd = (struct obd_device *)data; - LASSERT(obd != NULL); - - return snprintf(page, count, "%lu\n", - obd->u.obt.obt_qctxt.lqc_iunit_sz); -} -EXPORT_SYMBOL(lprocfs_quota_rd_iunit); - -int lprocfs_quota_wr_iunit(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - struct obd_device *obd = (struct obd_device *)data; - int val, rc; - LASSERT(obd != NULL); - - rc = lprocfs_write_helper(buffer, count, &val); - if (rc) - return rc; - - if (val <= obd->u.obt.obt_qctxt.lqc_itune_sz) - return -EINVAL; - - obd->u.obt.obt_qctxt.lqc_iunit_sz = val; - return count; -} -EXPORT_SYMBOL(lprocfs_quota_wr_iunit); - -int lprocfs_quota_rd_itune(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - struct obd_device *obd = (struct obd_device *)data; - LASSERT(obd != NULL); - - return snprintf(page, count, "%lu\n", - obd->u.obt.obt_qctxt.lqc_itune_sz); -} -EXPORT_SYMBOL(lprocfs_quota_rd_itune); - -int lprocfs_quota_wr_itune(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - struct obd_device *obd = (struct obd_device *)data; - int val, rc; - LASSERT(obd != NULL); - - rc = lprocfs_write_helper(buffer, count, &val); - if (rc) - return rc; - - if (val <= MIN_QLIMIT || - val >= obd->u.obt.obt_qctxt.lqc_iunit_sz) - return -EINVAL; - - obd->u.obt.obt_qctxt.lqc_itune_sz = val; - return count; -} -EXPORT_SYMBOL(lprocfs_quota_wr_itune); - -#define USER_QUOTA 1 -#define GROUP_QUOTA 2 - -#define MAX_STYPE_SIZE 5 - -int lprocfs_quota_rd_type(char *page, char **start, off_t off, int count, - int *eof, void *data) -{ - struct obd_device *obd = (struct obd_device *)data; - char stype[MAX_STYPE_SIZE + 1] = ""; - int oq_type; - - LASSERT(obd != NULL); - - /* Collect the needed information */ - oq_type = obd->u.obt.obt_qctxt.lqc_flags; - - /* Transform the collected data into a user-readable string */ - if (oq_type & LQC_USRQUOTA_FLAG) - strcat(stype, "u"); - if (oq_type & LQC_GRPQUOTA_FLAG) - strcat(stype, "g"); - - strcat(stype, "3"); - - return snprintf(page, count, "%s\n", stype); -} -EXPORT_SYMBOL(lprocfs_quota_rd_type); - -/* - * generic_quota_on is very lazy and tolerant about current quota settings - * @global means to turn on quotas on each OST additionally to local quotas; - * should not be called from filter_quota_ctl on MDS nodes (as it starts - * admin quotas on MDS nodes). - */ -int generic_quota_on(struct obd_device *obd, struct obd_quotactl *oqctl, int global) -{ - struct obd_device_target *obt = &obd->u.obt; - struct lvfs_run_ctxt saved; - int id, is_master, rc = 0, local; /* means we need a local quotaon */ - - cfs_down(&obt->obt_quotachecking); - push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - id = UGQUOTA2LQC(oqctl->qc_type); - local = (obt->obt_qctxt.lqc_flags & id) != id; - - oqctl->qc_cmd = Q_QUOTAON; - oqctl->qc_id = obt->obt_qfmt; - - is_master = !strcmp(obd->obd_type->typ_name, LUSTRE_MDS_NAME); - if (is_master) { - cfs_down_write(&obd->u.mds.mds_qonoff_sem); - if (local) { - /* turn on cluster wide quota */ - rc = mds_admin_quota_on(obd, oqctl); - if (rc && rc != -ENOENT) - CERROR("%s: %s admin quotaon failed. rc=%d\n", - obd->obd_name, global ? "global":"local", - rc); - } - } - - if (rc == 0) { - if (local) { - rc = fsfilt_quotactl(obd, obt->obt_sb, oqctl); - if (rc) { - if (rc != -ENOENT) - CERROR("%s: %s quotaon failed with" - " rc=%d\n", obd->obd_name, - global ? "global" : "local", rc); - } else { - obt->obt_qctxt.lqc_flags |= UGQUOTA2LQC(oqctl->qc_type); - build_lqs(obd); - } - } - - if (rc == 0 && global && is_master) - rc = obd_quotactl(obd->u.mds.mds_lov_exp, oqctl); - } - - if (is_master) - cfs_up_write(&obd->u.mds.mds_qonoff_sem); - - pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - cfs_up(&obt->obt_quotachecking); - - CDEBUG(D_QUOTA, "%s: quotaon type:master:global:local:flags:rc " - "%u:%d:%d:%d:%lu:%d\n", - obd->obd_name, oqctl->qc_type, is_master, global, local, - obt->obt_qctxt.lqc_flags, rc); - - return rc; -} - -static int auto_quota_on(struct obd_device *obd, int type) -{ - struct obd_quotactl *oqctl; - int rc; - ENTRY; - - LASSERT(type == USRQUOTA || type == GRPQUOTA || type == UGQUOTA); - - OBD_ALLOC_PTR(oqctl); - if (!oqctl) - RETURN(-ENOMEM); - - oqctl->qc_type = type; - - rc = generic_quota_on(obd, oqctl, 0); - - OBD_FREE_PTR(oqctl); - RETURN(rc); -} - -int lprocfs_quota_wr_type(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - struct obd_device *obd = (struct obd_device *)data; - int type = 0; - unsigned long i; - char stype[MAX_STYPE_SIZE + 1] = ""; - - LASSERT(obd != NULL); - - if (count > MAX_STYPE_SIZE) - return -EINVAL; - - if (cfs_copy_from_user(stype, buffer, count)) - return -EFAULT; - - for (i = 0 ; i < count ; i++) { - switch (stype[i]) { - case 'u' : - type |= USER_QUOTA; - break; - case 'g' : - type |= GROUP_QUOTA; - break; - case '1' : - case '2' : - CWARN("quota_type options 1 and 2 are obsolete, " - "they will be ignored\n"); - break; - case '3' : /* the only valid version spec, do nothing */ - default : /* just skip stray symbols like \n */ - break; - } - } - - if (type != 0) { - int rc = auto_quota_on(obd, type - 1); - - if (rc && rc != -EALREADY && rc != -ENOENT) - return rc; - } - - return count; -} -EXPORT_SYMBOL(lprocfs_quota_wr_type); - -int lprocfs_quota_rd_switch_seconds(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device *obd = (struct obd_device *)data; - LASSERT(obd != NULL); - - return snprintf(page, count, "%d\n", - obd->u.obt.obt_qctxt.lqc_switch_seconds); -} -EXPORT_SYMBOL(lprocfs_quota_rd_switch_seconds); - -int lprocfs_quota_wr_switch_seconds(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - struct obd_device *obd = (struct obd_device *)data; - int val, rc; - LASSERT(obd != NULL); - - rc = lprocfs_write_helper(buffer, count, &val); - if (rc) - return rc; - - if (val <= 10) - return -EINVAL; - - obd->u.obt.obt_qctxt.lqc_switch_seconds = val; - return count; -} -EXPORT_SYMBOL(lprocfs_quota_wr_switch_seconds); - -int lprocfs_quota_rd_sync_blk(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device *obd = (struct obd_device *)data; - LASSERT(obd != NULL); - - return snprintf(page, count, "%d\n", - obd->u.obt.obt_qctxt.lqc_sync_blk); -} -EXPORT_SYMBOL(lprocfs_quota_rd_sync_blk); - -int lprocfs_quota_wr_sync_blk(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - struct obd_device *obd = (struct obd_device *)data; - int val, rc; - LASSERT(obd != NULL); - - rc = lprocfs_write_helper(buffer, count, &val); - if (rc) - return rc; - - if (val < 0) - return -EINVAL; - - obd->u.obt.obt_qctxt.lqc_sync_blk = val; - return count; -} -EXPORT_SYMBOL(lprocfs_quota_wr_sync_blk); - -int lprocfs_quota_rd_switch_qs(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device *obd = (struct obd_device *)data; - LASSERT(obd != NULL); - - return snprintf(page, count, "changing qunit size is %s\n", - obd->u.obt.obt_qctxt.lqc_switch_qs ? - "enabled" : "disabled"); -} -EXPORT_SYMBOL(lprocfs_quota_rd_switch_qs); - -int lprocfs_quota_wr_switch_qs(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - struct obd_device *obd = (struct obd_device *)data; - int val, rc; - LASSERT(obd != NULL); - - rc = lprocfs_write_helper(buffer, count, &val); - if (rc) - return rc; - - if (val) - obd->u.obt.obt_qctxt.lqc_switch_qs = 1; - else - obd->u.obt.obt_qctxt.lqc_switch_qs = 0; - - return count; -} -EXPORT_SYMBOL(lprocfs_quota_wr_switch_qs); - -int lprocfs_quota_rd_boundary_factor(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device *obd = (struct obd_device *)data; - LASSERT(obd != NULL); - - - return snprintf(page, count, "%lu\n", - obd->u.obt.obt_qctxt.lqc_cqs_boundary_factor); -} -EXPORT_SYMBOL(lprocfs_quota_rd_boundary_factor); - -int lprocfs_quota_wr_boundary_factor(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - struct obd_device *obd = (struct obd_device *)data; - int val, rc; - LASSERT(obd != NULL); - - rc = lprocfs_write_helper(buffer, count, &val); - if (rc) - return rc; - - if (val < 2) - return -EINVAL; - - obd->u.obt.obt_qctxt.lqc_cqs_boundary_factor = val; - return count; -} -EXPORT_SYMBOL(lprocfs_quota_wr_boundary_factor); - -int lprocfs_quota_rd_least_bunit(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device *obd = (struct obd_device *)data; - LASSERT(obd != NULL); - - - return snprintf(page, count, "%lu\n", - obd->u.obt.obt_qctxt.lqc_cqs_least_bunit); -} -EXPORT_SYMBOL(lprocfs_quota_rd_least_bunit); - -int lprocfs_quota_wr_least_bunit(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - struct obd_device *obd = (struct obd_device *)data; - int val, rc; - LASSERT(obd != NULL); - - rc = lprocfs_write_helper(buffer, count, &val); - if (rc) - return rc; - - if (val < PTLRPC_MAX_BRW_SIZE || - val >= obd->u.obt.obt_qctxt.lqc_bunit_sz) - return -EINVAL; - - obd->u.obt.obt_qctxt.lqc_cqs_least_bunit = val; - return count; -} -EXPORT_SYMBOL(lprocfs_quota_wr_least_bunit); - -int lprocfs_quota_rd_least_iunit(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device *obd = (struct obd_device *)data; - LASSERT(obd != NULL); - - - return snprintf(page, count, "%lu\n", - obd->u.obt.obt_qctxt.lqc_cqs_least_iunit); -} -EXPORT_SYMBOL(lprocfs_quota_rd_least_iunit); - -int lprocfs_quota_wr_least_iunit(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - struct obd_device *obd = (struct obd_device *)data; - int val, rc; - LASSERT(obd != NULL); - - rc = lprocfs_write_helper(buffer, count, &val); - if (rc) - return rc; - - if (val < 1 || val >= obd->u.obt.obt_qctxt.lqc_iunit_sz) - return -EINVAL; - - obd->u.obt.obt_qctxt.lqc_cqs_least_iunit = val; - return count; -} -EXPORT_SYMBOL(lprocfs_quota_wr_least_iunit); - -int lprocfs_quota_rd_qs_factor(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct obd_device *obd = (struct obd_device *)data; - LASSERT(obd != NULL); - - - return snprintf(page, count, "%lu\n", - obd->u.obt.obt_qctxt.lqc_cqs_qs_factor); -} -EXPORT_SYMBOL(lprocfs_quota_rd_qs_factor); - -int lprocfs_quota_wr_qs_factor(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - struct obd_device *obd = (struct obd_device *)data; - int val, rc; - LASSERT(obd != NULL); - - rc = lprocfs_write_helper(buffer, count, &val); - if (rc) - return rc; - - if (val < 2) - return -EINVAL; - - obd->u.obt.obt_qctxt.lqc_cqs_qs_factor = val; - return count; -} -EXPORT_SYMBOL(lprocfs_quota_wr_qs_factor); - -struct lprocfs_vars lprocfs_quota_common_vars[] = { - { "quota_bunit_sz", lprocfs_quota_rd_bunit, - lprocfs_quota_wr_bunit, 0}, - { "quota_btune_sz", lprocfs_quota_rd_btune, - lprocfs_quota_wr_btune, 0}, - { "quota_iunit_sz", lprocfs_quota_rd_iunit, - lprocfs_quota_wr_iunit, 0}, - { "quota_itune_sz", lprocfs_quota_rd_itune, - lprocfs_quota_wr_itune, 0}, - { "quota_type", lprocfs_quota_rd_type, - lprocfs_quota_wr_type, 0}, - { "quota_switch_seconds", lprocfs_quota_rd_switch_seconds, - lprocfs_quota_wr_switch_seconds, 0 }, - { "quota_sync_blk", lprocfs_quota_rd_sync_blk, - lprocfs_quota_wr_sync_blk, 0}, - { NULL } -}; - -struct lprocfs_vars lprocfs_quota_master_vars[] = { - { "quota_switch_qs", lprocfs_quota_rd_switch_qs, - lprocfs_quota_wr_switch_qs, 0 }, - { "quota_boundary_factor", lprocfs_quota_rd_boundary_factor, - lprocfs_quota_wr_boundary_factor, 0 }, - { "quota_least_bunit", lprocfs_quota_rd_least_bunit, - lprocfs_quota_wr_least_bunit, 0 }, - { "quota_least_iunit", lprocfs_quota_rd_least_iunit, - lprocfs_quota_wr_least_iunit, 0 }, - { "quota_qs_factor", lprocfs_quota_rd_qs_factor, - lprocfs_quota_wr_qs_factor, 0 }, - { NULL } -}; - -int lquota_proc_setup(struct obd_device *obd, int is_master) -{ - struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt; - int rc = 0; - ENTRY; - - LASSERT(lquota_type_proc_dir && obd); - qctxt->lqc_proc_dir = lprocfs_register(obd->obd_name, - lquota_type_proc_dir, - lprocfs_quota_common_vars, obd); - if (IS_ERR(qctxt->lqc_proc_dir)) { - rc = PTR_ERR(qctxt->lqc_proc_dir); - CERROR("%s: error %d setting up lprocfs\n", - obd->obd_name, rc); - qctxt->lqc_proc_dir = NULL; - GOTO(out, rc); - } - - if (is_master) { - rc = lprocfs_add_vars(qctxt->lqc_proc_dir, - lprocfs_quota_master_vars, obd); - if (rc) { - CERROR("%s: error %d setting up lprocfs for " - "quota master\n", obd->obd_name, rc); - GOTO(out_free_proc, rc); - } - } - - qctxt->lqc_stats = lprocfs_alloc_stats(LQUOTA_LAST_STAT - - LQUOTA_FIRST_STAT, 0); - if (!qctxt->lqc_stats) - GOTO(out_free_proc, rc = -ENOMEM); - - lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_SYNC_ACQ, - LPROCFS_CNTR_AVGMINMAX, "sync_acq_req", "us"); - lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_SYNC_REL, - LPROCFS_CNTR_AVGMINMAX, "sync_rel_req", "us"); - lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_ASYNC_ACQ, - LPROCFS_CNTR_AVGMINMAX, "async_acq_req", "us"); - lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_ASYNC_REL, - LPROCFS_CNTR_AVGMINMAX, "async_rel_req", "us"); - - lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_WAIT_FOR_CHK_BLK, - LPROCFS_CNTR_AVGMINMAX, - "wait_for_blk_quota(lquota_chkquota)", "us"); - lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_WAIT_FOR_CHK_INO, - LPROCFS_CNTR_AVGMINMAX, - "wait_for_ino_quota(lquota_chkquota)", "us"); - lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_WAIT_FOR_COMMIT_BLK, - LPROCFS_CNTR_AVGMINMAX, - "wait_for_blk_quota(lquota_pending_commit)", - "us"); - lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_WAIT_FOR_COMMIT_INO, - LPROCFS_CNTR_AVGMINMAX, - "wait_for_ino_quota(lquota_pending_commit)", - "us"); - - lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_WAIT_PENDING_BLK_QUOTA, - LPROCFS_CNTR_AVGMINMAX, - "wait_for_pending_blk_quota_req" - "(qctxt_wait_pending_dqacq)", "us"); - lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_WAIT_PENDING_INO_QUOTA, - LPROCFS_CNTR_AVGMINMAX, - "wait_for_pending_ino_quota_req" - "(qctxt_wait_pending_dqacq)", "us"); - lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_NOWAIT_PENDING_BLK_QUOTA, - LPROCFS_CNTR_AVGMINMAX, - "nowait_for_pending_blk_quota_req" - "(qctxt_wait_pending_dqacq)", "us"); - lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_NOWAIT_PENDING_INO_QUOTA, - LPROCFS_CNTR_AVGMINMAX, - "nowait_for_pending_ino_quota_req" - "(qctxt_wait_pending_dqacq)", "us"); - - lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_QUOTA_CTL, - LPROCFS_CNTR_AVGMINMAX, "quota_ctl", "us"); - lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_ADJUST_QUNIT, - LPROCFS_CNTR_AVGMINMAX, "adjust_qunit", "us"); - - lprocfs_register_stats(qctxt->lqc_proc_dir, "stats", qctxt->lqc_stats); - - RETURN(rc); - -out_free_proc: - lprocfs_remove(&qctxt->lqc_proc_dir); -out: - RETURN(rc); -} - -int lquota_proc_cleanup(struct lustre_quota_ctxt *qctxt) -{ - if (!qctxt || !qctxt->lqc_proc_dir) - return -EINVAL; - - if (qctxt->lqc_stats != NULL) - lprocfs_free_stats(&qctxt->lqc_stats); - - lprocfs_remove(&qctxt->lqc_proc_dir); - return 0; -} - #endif /* LPROCFS */ diff --git a/lustre/quota/lquota_internal.h b/lustre/quota/lquota_internal.h index 3db38e0..a50132d 100644 --- a/lustre/quota/lquota_internal.h +++ b/lustre/quota/lquota_internal.h @@ -124,10 +124,4 @@ int lquota_disk_update_ver(const struct lu_env *, struct dt_device *, /* lproc_quota.c */ extern struct file_operations lprocfs_quota_seq_fops; - -/* quota_interface.c - * old quota module initialization routines, to be removed */ -int init_lustre_quota(void); -void exit_lustre_quota(void); - #endif /* _LQUOTA_INTERNAL_H */ diff --git a/lustre/quota/lquota_lib.c b/lustre/quota/lquota_lib.c index 9d51049..d7e2703 100644 --- a/lustre/quota/lquota_lib.c +++ b/lustre/quota/lquota_lib.c @@ -40,6 +40,10 @@ #include "lquota_internal.h" +static int hash_lqs_cur_bits = HASH_LQS_CUR_BITS; +CFS_MODULE_PARM(hash_lqs_cur_bits, "i", int, 0444, + "the current bits of lqs hash"); + /* register lquota key */ LU_KEY_INIT_FINI(lquota, struct lquota_thread_info); LU_CONTEXT_KEY_DEFINE(lquota, LCT_MD_THREAD | LCT_DT_THREAD | LCT_LOCAL); @@ -325,13 +329,6 @@ const struct dt_index_features *glb_idx_feature(struct lu_fid *fid) static int __init init_lquota(void) { - int rc; - - /* call old quota module init function */ - rc = init_lustre_quota(); - if (rc) - return rc; - /* new quota initialization */ lquota_key_init_generic(&lquota_thread_key, NULL); lu_context_key_register(&lquota_thread_key); @@ -348,9 +345,6 @@ static int __init init_lquota(void) static void exit_lquota(void) { - /* call old quota module exit function */ - exit_lustre_quota(); - lu_context_key_degister(&lquota_thread_key); } diff --git a/lustre/quota/quota_adjust_qunit.c b/lustre/quota/quota_adjust_qunit.c deleted file mode 100644 index 4659f21..0000000 --- a/lustre/quota/quota_adjust_qunit.c +++ /dev/null @@ -1,281 +0,0 @@ -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * GPL HEADER END - */ -/* - * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - * - * Copyright (c) 2012, Whamcloud, Inc. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - */ - -#define DEBUG_SUBSYSTEM S_LQUOTA - -#ifdef __KERNEL__ -# include -# include -# include -# include -# include -# include -# include -# include -# include -#else /* __KERNEL__ */ -# include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include "quota_internal.h" - -#ifdef __KERNEL__ -/** - * This function is charge of recording lqs_ino_rec and - * lqs_blk_rec. when a lquota slave checks a quota - * request(check_cur_qunit) and finishes a quota - * request(dqacq_completion), it will be called. - * is_chk: whether it is checking quota; otherwise, it is finishing - * is_acq: whether it is acquiring; otherwise, it is releasing - */ -void quota_compute_lqs(struct qunit_data *qdata, struct lustre_qunit_size *lqs, - int is_chk, int is_acq) -{ - long long *rec; - - LASSERT(qdata && lqs); - LASSERT_SPIN_LOCKED(&lqs->lqs_lock); - - rec = QDATA_IS_BLK(qdata) ? &lqs->lqs_blk_rec : &lqs->lqs_ino_rec; - - if (!!is_chk + !!is_acq == 1) - *rec -= qdata->qd_count; - else - *rec += qdata->qd_count; - -} - -struct lustre_qunit_size *quota_search_lqs(unsigned long long lqs_key, - struct lustre_quota_ctxt *qctxt, - int create) -{ - struct lustre_qunit_size *lqs; - struct lustre_qunit_size *lqs2; - cfs_hash_t *hs = NULL; - int rc = 0; - - cfs_spin_lock(&qctxt->lqc_lock); - if (qctxt->lqc_valid) { - LASSERT(qctxt->lqc_lqs_hash != NULL); - hs = cfs_hash_getref(qctxt->lqc_lqs_hash); - } - cfs_spin_unlock(&qctxt->lqc_lock); - - if (hs == NULL) { - rc = -EBUSY; - goto out; - } - - /* cfs_hash_lookup will +1 refcount for caller */ - lqs = cfs_hash_lookup(qctxt->lqc_lqs_hash, &lqs_key); - if (lqs != NULL) /* found */ - goto out_put; - - if (!create) - goto out_put; - - OBD_ALLOC_PTR(lqs); - if (!lqs) { - rc = -ENOMEM; - goto out_put; - } - - lqs->lqs_key = lqs_key; - - cfs_spin_lock_init(&lqs->lqs_lock); - - lqs->lqs_bwrite_pending = 0; - lqs->lqs_iwrite_pending = 0; - lqs->lqs_ino_rec = 0; - lqs->lqs_blk_rec = 0; - lqs->lqs_id = LQS_KEY_ID(lqs->lqs_key); - lqs->lqs_flags = LQS_KEY_GRP(lqs->lqs_key) ? LQUOTA_FLAGS_GRP : 0; - lqs->lqs_bunit_sz = qctxt->lqc_bunit_sz; - lqs->lqs_iunit_sz = qctxt->lqc_iunit_sz; - lqs->lqs_btune_sz = qctxt->lqc_btune_sz; - lqs->lqs_itune_sz = qctxt->lqc_itune_sz; - if (qctxt->lqc_handler) { - lqs->lqs_last_bshrink = 0; - lqs->lqs_last_ishrink = 0; - } - - lqs->lqs_ctxt = qctxt; /* must be called before lqs_initref */ - cfs_atomic_set(&lqs->lqs_refcount, 1); /* 1 for caller */ - cfs_atomic_inc(&lqs->lqs_ctxt->lqc_lqs); - - /* lqc_lqs_hash will take +1 refcount on lqs on adding */ - lqs2 = cfs_hash_findadd_unique(qctxt->lqc_lqs_hash, - &lqs->lqs_key, &lqs->lqs_hash); - if (lqs2 == lqs) /* added to hash */ - goto out_put; - - create = 0; - lqs_putref(lqs); - lqs = lqs2; - - out_put: - cfs_hash_putref(hs); - out: - if (rc != 0) { /* error */ - CERROR("get lqs error(rc: %d)\n", rc); - return ERR_PTR(rc); - } - - if (lqs != NULL) { - LQS_DEBUG(lqs, "%s\n", - (create == 1 ? "create lqs" : "search lqs")); - } - return lqs; -} - -int quota_adjust_slave_lqs(struct quota_adjust_qunit *oqaq, - struct lustre_quota_ctxt *qctxt) -{ - struct lustre_qunit_size *lqs = NULL; - unsigned long *unit, *tune; - signed long tmp = 0; - cfs_time_t time_limit = 0, *shrink; - int i, rc = 0; - ENTRY; - - LASSERT(qctxt); - lqs = quota_search_lqs(LQS_KEY(QAQ_IS_GRP(oqaq), oqaq->qaq_id), - qctxt, QAQ_IS_CREATE_LQS(oqaq) ? 1 : 0); - if (lqs == NULL || IS_ERR(lqs)){ - CERROR("fail to find a lqs for %sid %u!\n", - QAQ_IS_GRP(oqaq) ? "g" : "u", oqaq->qaq_id); - RETURN(PTR_ERR(lqs)); - } - - CDEBUG(D_QUOTA, "before: bunit: %lu, iunit: %lu.\n", - lqs->lqs_bunit_sz, lqs->lqs_iunit_sz); - cfs_spin_lock(&lqs->lqs_lock); - for (i = 0; i < 2; i++) { - if (i == 0 && !QAQ_IS_ADJBLK(oqaq)) - continue; - - if (i == 1 && !QAQ_IS_ADJINO(oqaq)) - continue; - - tmp = i ? (lqs->lqs_iunit_sz - oqaq->qaq_iunit_sz) : - (lqs->lqs_bunit_sz - oqaq->qaq_bunit_sz); - shrink = i ? &lqs->lqs_last_ishrink : - &lqs->lqs_last_bshrink; - time_limit = cfs_time_add(i ? lqs->lqs_last_ishrink : - lqs->lqs_last_bshrink, - cfs_time_seconds(qctxt->lqc_switch_seconds)); - unit = i ? &lqs->lqs_iunit_sz : &lqs->lqs_bunit_sz; - tune = i ? &lqs->lqs_itune_sz : &lqs->lqs_btune_sz; - - /* quota master shrinks */ - if (qctxt->lqc_handler && tmp > 0) - *shrink = cfs_time_current(); - - /* quota master enlarges */ - if (qctxt->lqc_handler && tmp < 0) { - /* in case of ping-pong effect, don't enlarge lqs - * in a short time */ - if (*shrink && - cfs_time_before(cfs_time_current(), time_limit)) - tmp = 0; - } - - /* when setquota, don't enlarge lqs b=18616 */ - if (QAQ_IS_CREATE_LQS(oqaq) && tmp < 0) - tmp = 0; - - if (tmp != 0) { - *unit = i ? oqaq->qaq_iunit_sz : oqaq->qaq_bunit_sz; - *tune = (*unit) / 2; - } - - - if (tmp > 0) - rc |= i ? LQS_INO_DECREASE : LQS_BLK_DECREASE; - if (tmp < 0) - rc |= i ? LQS_INO_INCREASE : LQS_BLK_INCREASE; - } - cfs_spin_unlock(&lqs->lqs_lock); - CDEBUG(D_QUOTA, "after: bunit: %lu, iunit: %lu.\n", - lqs->lqs_bunit_sz, lqs->lqs_iunit_sz); - - lqs_putref(lqs); - - RETURN(rc); -} - -int filter_quota_adjust_qunit(struct obd_export *exp, - struct quota_adjust_qunit *oqaq, - struct lustre_quota_ctxt *qctxt, - struct ptlrpc_request_set *rqset) -{ - struct obd_device *obd = exp->exp_obd; - unsigned int id[MAXQUOTAS] = { 0, 0 }; - int rc = 0; - ENTRY; - - LASSERT(oqaq); - LASSERT(QAQ_IS_ADJBLK(oqaq)); - rc = quota_adjust_slave_lqs(oqaq, qctxt); - if (rc < 0) { - CERROR("adjust mds slave's qunit size failed!(rc:%d)\n", rc); - RETURN(rc); - } - if (QAQ_IS_GRP(oqaq)) - id[GRPQUOTA] = oqaq->qaq_id; - else - id[USRQUOTA] = oqaq->qaq_id; - - if (rc > 0) { - rc = qctxt_adjust_qunit(obd, qctxt, id, 1, 0, NULL); - if (rc == -EDQUOT || rc == -EBUSY || - rc == QUOTA_REQ_RETURNED || rc == -EAGAIN) { - CDEBUG(D_QUOTA, "rc: %d.\n", rc); - rc = 0; - } - if (rc) - CERROR("slave adjust block quota failed!(rc:%d)\n", rc); - } - RETURN(rc); -} -#endif /* __KERNEL__ */ diff --git a/lustre/quota/quota_check.c b/lustre/quota/quota_check.c deleted file mode 100644 index 4b78e48c..0000000 --- a/lustre/quota/quota_check.c +++ /dev/null @@ -1,192 +0,0 @@ -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * GPL HEADER END - */ -/* - * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - * - * Copyright (c) 2011, 2012, Whamcloud, Inc. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - */ - -#define DEBUG_SUBSYSTEM S_LQUOTA - -#ifdef __KERNEL__ -# include -# include -# include -# include -# include -# include -# include -# include -# include -#else /* __KERNEL__ */ -# include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include "quota_internal.h" - -#ifdef __KERNEL__ -static int target_quotacheck_callback(struct obd_export *exp, - struct obd_quotactl *oqctl) -{ - struct ptlrpc_request *req; - struct obd_quotactl *body; - int rc; - ENTRY; - - req = ptlrpc_request_alloc_pack(exp->exp_imp_reverse, &RQF_QC_CALLBACK, - LUSTRE_OBD_VERSION, OBD_QC_CALLBACK); - if (req == NULL) - RETURN(-ENOMEM); - - body = req_capsule_client_get(&req->rq_pill, &RMF_OBD_QUOTACTL); - *body = *oqctl; - - ptlrpc_request_set_replen(req); - - rc = ptlrpc_queue_wait(req); - ptlrpc_req_finished(req); - - RETURN(rc); -} - -static int target_quotacheck_thread(void *data) -{ - struct quotacheck_thread_args *qta = data; - struct obd_export *exp; - struct obd_device *obd; - struct obd_quotactl *oqctl; - struct lvfs_run_ctxt saved; - int rc; - - cfs_daemonize_ctxt("quotacheck"); - - exp = qta->qta_exp; - obd = qta->qta_obd; - oqctl = &qta->qta_oqctl; - - push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - - rc = fsfilt_quotacheck(obd, qta->qta_sb, oqctl); - if (rc) - CERROR("%s: fsfilt_quotacheck: %d\n", obd->obd_name, rc); - - pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - - rc = target_quotacheck_callback(exp, oqctl); - class_export_put(exp); - cfs_up(qta->qta_sem); - OBD_FREE_PTR(qta); - return rc; -} - -int target_quota_check(struct obd_device *obd, struct obd_export *exp, - struct obd_quotactl *oqctl) -{ - struct obd_device_target *obt = &obd->u.obt; - struct quotacheck_thread_args *qta; - int rc = 0; - ENTRY; - - OBD_ALLOC_PTR(qta); - if (!qta) - RETURN(ENOMEM); - - cfs_down(&obt->obt_quotachecking); - - qta->qta_exp = exp; - qta->qta_obd = obd; - qta->qta_oqctl = *oqctl; - qta->qta_oqctl.qc_id = obt->obt_qfmt; /* override qfmt version */ - qta->qta_sb = obt->obt_sb; - qta->qta_sem = &obt->obt_quotachecking; - - /* quotaoff firstly */ - oqctl->qc_cmd = Q_QUOTAOFF; - if (!strcmp(obd->obd_type->typ_name, LUSTRE_MDS_NAME)) { - rc = do_mds_quota_off(obd, oqctl); - if (rc && rc != -EALREADY) { - CERROR("off quota on MDS failed: %d\n", rc); - GOTO(out, rc); - } - - /* quota master */ - rc = init_admin_quotafiles(obd, &qta->qta_oqctl); - if (rc) { - CERROR("init_admin_quotafiles failed: %d\n", rc); - GOTO(out, rc); - } - } else { - struct lvfs_run_ctxt saved; - struct lustre_quota_ctxt *qctxt = &obt->obt_qctxt; - - push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - rc = fsfilt_quotactl(obd, obt->obt_sb, oqctl); - pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - if (!rc) { - qctxt->lqc_flags &= ~UGQUOTA2LQC(oqctl->qc_type); - } else if (!quota_is_off(qctxt, oqctl)) { - CERROR("off quota on OSS failed: %d\n", rc); - GOTO(out, rc); - } - } - - /* we get ref for exp because target_quotacheck_callback() will use this - * export later b=18126 */ - class_export_get(exp); - rc = cfs_create_thread(target_quotacheck_thread, qta, - CFS_DAEMON_FLAGS); - if (rc >= 0) { - /* target_quotacheck_thread will drop the ref on exp and release - * obt_quotachecking */ - CDEBUG(D_INFO, "%s: target_quotacheck_thread: %d\n", - obd->obd_name, rc); - RETURN(0); - } else { - CERROR("%s: error starting quotacheck_thread: %d\n", - obd->obd_name, rc); - class_export_put(exp); - EXIT; - } - -out: - cfs_up(&obt->obt_quotachecking); - OBD_FREE_PTR(qta); - return rc; -} - -#endif /* __KERNEL__ */ diff --git a/lustre/quota/quota_context.c b/lustre/quota/quota_context.c deleted file mode 100644 index 9f67b0c..0000000 --- a/lustre/quota/quota_context.c +++ /dev/null @@ -1,1739 +0,0 @@ -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * GPL HEADER END - */ -/* - * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - * - * Copyright (c) 2011, 2012, Whamcloud, Inc. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - * - * lustre/quota/quota_context.c - * - * Lustre Quota Context - * - * Author: Niu YaWei - */ - -#define DEBUG_SUBSYSTEM S_LQUOTA - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include "quota_internal.h" - -static int hash_lqs_cur_bits = HASH_LQS_CUR_BITS; -CFS_MODULE_PARM(hash_lqs_cur_bits, "i", int, 0444, - "the current bits of lqs hash"); - -static cfs_hash_ops_t lqs_hash_ops; - -unsigned long default_bunit_sz = 128 * 1024 * 1024; /* 128M bytes */ -unsigned long default_btune_ratio = 50; /* 50 percentage */ -unsigned long default_iunit_sz = 5120; /* 5120 inodes */ -unsigned long default_itune_ratio = 50; /* 50 percentage */ - -cfs_mem_cache_t *qunit_cachep = NULL; -cfs_list_t qunit_hash[NR_DQHASH]; -DEFINE_SPINLOCK(qunit_hash_lock); - -/* please sync qunit_state with qunit_state_names */ -enum qunit_state { - /** - * a qunit is created - */ - QUNIT_CREATED = 0, - /** - * a qunit is added into qunit hash, that means - * a quota req will be sent or is flying - */ - QUNIT_IN_HASH = 1, - /** - * a qunit is removed from qunit hash, that - * means a quota req is handled and comes back - */ - QUNIT_RM_FROM_HASH = 2, - /** - * qunit can wake up all threads waiting for it - */ - QUNIT_FINISHED = 3, -}; - -static const char *qunit_state_names[] = { - [QUNIT_CREATED] = "CREATED", - [QUNIT_IN_HASH] = "IN_HASH", - [QUNIT_RM_FROM_HASH] = "RM_FROM_HASH", - [QUNIT_FINISHED] = "FINISHED", -}; - -struct lustre_qunit { - cfs_list_t lq_hash; /** Hash list in memory */ - cfs_atomic_t lq_refcnt; /** Use count */ - struct lustre_quota_ctxt *lq_ctxt; /** Quota context this applies to */ - struct qunit_data lq_data; /** See qunit_data */ - unsigned int lq_opc; /** QUOTA_DQACQ, QUOTA_DQREL */ - cfs_waitq_t lq_waitq; /** Threads waiting for this qunit */ - cfs_spinlock_t lq_lock; /** Protect the whole structure */ - enum qunit_state lq_state; /** Present the status of qunit */ - int lq_rc; /** The rc of lq_data */ - pid_t lq_owner; -}; - -#define QUNIT_SET_STATE(qunit, state) \ -do { \ - cfs_spin_lock(&qunit->lq_lock); \ - QDATA_DEBUG((&qunit->lq_data), "qunit(%p) lq_state(%s->%s), " \ - "lq_rc(%d), lq_owner(%d)\n", \ - qunit, qunit_state_names[qunit->lq_state], \ - qunit_state_names[state], qunit->lq_rc, \ - qunit->lq_owner); \ - qunit->lq_state = state; \ - cfs_spin_unlock(&qunit->lq_lock); \ -} while(0) - -#define QUNIT_SET_STATE_AND_RC(qunit, state, rc) \ -do { \ - cfs_spin_lock(&qunit->lq_lock); \ - qunit->lq_rc = rc; \ - QDATA_DEBUG((&qunit->lq_data), "qunit(%p) lq_state(%s->%s), " \ - "lq_rc(%d), lq_owner(%d)\n", \ - qunit, qunit_state_names[qunit->lq_state], \ - qunit_state_names[state], qunit->lq_rc, \ - qunit->lq_owner); \ - qunit->lq_state = state; \ - cfs_spin_unlock(&qunit->lq_lock); \ -} while(0) - -int should_translate_quota (struct obd_import *imp) -{ - ENTRY; - - LASSERT(imp); - if (imp->imp_connect_data.ocd_connect_flags & OBD_CONNECT_QUOTA64) - RETURN(0); - else - RETURN(1); -} - -void qunit_cache_cleanup(void) -{ - int i; - ENTRY; - - cfs_spin_lock(&qunit_hash_lock); - for (i = 0; i < NR_DQHASH; i++) - LASSERT(cfs_list_empty(qunit_hash + i)); - cfs_spin_unlock(&qunit_hash_lock); - - if (qunit_cachep) { - int rc; - rc = cfs_mem_cache_destroy(qunit_cachep); - LASSERTF(rc == 0, "couldn't destroy qunit_cache slab\n"); - qunit_cachep = NULL; - } - EXIT; -} - -int qunit_cache_init(void) -{ - int i; - ENTRY; - - LASSERT(qunit_cachep == NULL); - qunit_cachep = cfs_mem_cache_create("ll_qunit_cache", - sizeof(struct lustre_qunit), - 0, 0); - if (!qunit_cachep) - RETURN(-ENOMEM); - - cfs_spin_lock(&qunit_hash_lock); - for (i = 0; i < NR_DQHASH; i++) - CFS_INIT_LIST_HEAD(qunit_hash + i); - cfs_spin_unlock(&qunit_hash_lock); - RETURN(0); -} - -static inline int -qunit_hashfn(struct lustre_quota_ctxt *qctxt, struct qunit_data *qdata) - __attribute__((__const__)); - -static inline int -qunit_hashfn(struct lustre_quota_ctxt *qctxt, struct qunit_data *qdata) -{ - unsigned int id = qdata->qd_id; - unsigned int type = QDATA_IS_GRP(qdata); - - unsigned long tmp = ((unsigned long)qctxt >> L1_CACHE_SHIFT) ^ id; - tmp = (tmp * (MAXQUOTAS - type)) % NR_DQHASH; - return tmp; -} - -/* caller must hold qunit_hash_lock */ -static inline struct lustre_qunit *find_qunit(unsigned int hashent, - struct lustre_quota_ctxt *qctxt, - struct qunit_data *qdata) -{ - struct lustre_qunit *qunit = NULL; - struct qunit_data *tmp; - - LASSERT_SPIN_LOCKED(&qunit_hash_lock); - cfs_list_for_each_entry(qunit, qunit_hash + hashent, lq_hash) { - tmp = &qunit->lq_data; - if (qunit->lq_ctxt == qctxt && - qdata->qd_id == tmp->qd_id && - (qdata->qd_flags & LQUOTA_QUNIT_FLAGS) == - (tmp->qd_flags & LQUOTA_QUNIT_FLAGS)) - return qunit; - } - return NULL; -} - -/* check_cur_qunit - check the current usage of qunit. - * @qctxt: quota context - * @qdata: the type of quota unit to be checked - * - * return: 1 - need acquire qunit; - * 2 - need release qunit; - * 0 - need do nothing. - * < 0 - error. - */ -static int -check_cur_qunit(struct obd_device *obd, - struct lustre_quota_ctxt *qctxt, struct qunit_data *qdata) -{ - struct super_block *sb = qctxt->lqc_sb; - unsigned long qunit_sz, tune_sz; - __u64 usage, limit, limit_org, pending_write = 0; - long long record = 0; - struct obd_quotactl *qctl; - struct lustre_qunit_size *lqs = NULL; - int ret = 0; - ENTRY; - - if (!sb_has_quota_active(sb, QDATA_IS_GRP(qdata))) - RETURN(0); - - cfs_spin_lock(&qctxt->lqc_lock); - if (!qctxt->lqc_valid){ - cfs_spin_unlock(&qctxt->lqc_lock); - RETURN(0); - } - cfs_spin_unlock(&qctxt->lqc_lock); - - OBD_ALLOC_PTR(qctl); - if (qctl == NULL) - RETURN(-ENOMEM); - - /* get fs quota usage & limit */ - qctl->qc_cmd = Q_GETQUOTA; - qctl->qc_id = qdata->qd_id; - qctl->qc_type = QDATA_IS_GRP(qdata); - ret = fsfilt_quotactl(obd, sb, qctl); - if (ret) { - if (ret == -ESRCH) /* no limit */ - ret = 0; - else - CERROR("can't get fs quota usage! (rc:%d)\n", ret); - GOTO(out, ret); - } - - if (QDATA_IS_BLK(qdata)) { - usage = qctl->qc_dqblk.dqb_curspace; - limit = qctl->qc_dqblk.dqb_bhardlimit << QUOTABLOCK_BITS; - } else { - usage = qctl->qc_dqblk.dqb_curinodes; - limit = qctl->qc_dqblk.dqb_ihardlimit; - } - - /* ignore the no quota limit case; and it can avoid creating - * unnecessary lqs for uid/gid */ - if (!limit) - GOTO(out, ret = 0); - - lqs = quota_search_lqs(LQS_KEY(QDATA_IS_GRP(qdata), qdata->qd_id), - qctxt, 0); - if (IS_ERR(lqs) || lqs == NULL) { - CERROR("fail to find a lqs for %sid: %u)!\n", - QDATA_IS_GRP(qdata) ? "g" : "u", qdata->qd_id); - GOTO (out, ret = 0); - } - cfs_spin_lock(&lqs->lqs_lock); - - if (QDATA_IS_BLK(qdata)) { - qunit_sz = lqs->lqs_bunit_sz; - tune_sz = lqs->lqs_btune_sz; - pending_write = lqs->lqs_bwrite_pending; - record = lqs->lqs_blk_rec; - LASSERT(!(qunit_sz % QUOTABLOCK_SIZE)); - } else { - /* we didn't need change inode qunit size now */ - qunit_sz = lqs->lqs_iunit_sz; - tune_sz = lqs->lqs_itune_sz; - pending_write = lqs->lqs_iwrite_pending; - record = lqs->lqs_ino_rec; - } - - /* we don't count the MIN_QLIMIT */ - if ((limit == MIN_QLIMIT && !QDATA_IS_BLK(qdata)) || - (toqb(limit) == MIN_QLIMIT && QDATA_IS_BLK(qdata))) - limit = 0; - - usage += pending_write; - limit_org = limit; - /* when a releasing quota req is sent, before it returned - limit is assigned a small value. limit will overflow */ - if (record < 0) - usage -= record; - else - limit += record; - - LASSERT(qdata->qd_count == 0); - if (limit <= usage + tune_sz) { - while (qdata->qd_count + limit <= - usage + tune_sz) - qdata->qd_count += qunit_sz; - ret = 1; - } else if (limit > usage + qunit_sz + tune_sz && - limit_org > qdata->qd_count + qunit_sz) { - while (limit - qdata->qd_count > usage + qunit_sz + tune_sz && - limit_org > qdata->qd_count + qunit_sz) - qdata->qd_count += qunit_sz; - ret = 2; - /* if there are other pending writes for this uid/gid, releasing - * quota is put off until the last pending write b=16645 */ - /* if there is an ongoing quota request, a releasing request is aborted. - * That ongoing quota request will call this function again when - * it returned b=18630 */ - if (pending_write || record) { - CDEBUG(D_QUOTA, "delay quota release\n"); - ret = 0; - } - } - if (ret > 0) - quota_compute_lqs(qdata, lqs, 1, (ret == 1) ? 1 : 0); - - CDEBUG(D_QUOTA, "type: %c, limit: "LPU64", usage: "LPU64 - ", pending_write: "LPU64", record: %lld" - ", qunit_sz: %lu, tune_sz: %lu, ret: %d.\n", - QDATA_IS_BLK(qdata) ? 'b' : 'i', limit, usage, pending_write, - record, qunit_sz, tune_sz, ret); - LASSERT(ret == 0 || qdata->qd_count); - - cfs_spin_unlock(&lqs->lqs_lock); - lqs_putref(lqs); - - EXIT; - out: - OBD_FREE_PTR(qctl); - return ret; -} - -/** - * Compute the remaining quota for certain gid or uid b=11693 - */ -int compute_remquota(struct obd_device *obd, struct lustre_quota_ctxt *qctxt, - struct qunit_data *qdata, int isblk) -{ - struct super_block *sb = qctxt->lqc_sb; - __u64 usage, limit; - struct obd_quotactl *qctl; - int ret = QUOTA_RET_OK; - ENTRY; - - /* ignore root user */ - if (qdata->qd_id == 0 && QDATA_IS_GRP(qdata) == USRQUOTA) - RETURN(QUOTA_RET_NOLIMIT); - - OBD_ALLOC_PTR(qctl); - if (qctl == NULL) - RETURN(-ENOMEM); - - /* get fs quota usage & limit */ - qctl->qc_cmd = Q_GETQUOTA; - qctl->qc_id = qdata->qd_id; - qctl->qc_type = QDATA_IS_GRP(qdata); - ret = fsfilt_quotactl(obd, sb, qctl); - if (ret) { - if (ret == -ESRCH) /* no limit */ - ret = QUOTA_RET_NOLIMIT; - else - CDEBUG(D_QUOTA, "can't get fs quota usage! (rc:%d)", - ret); - GOTO(out, ret); - } - - usage = isblk ? qctl->qc_dqblk.dqb_curspace : - qctl->qc_dqblk.dqb_curinodes; - limit = isblk ? qctl->qc_dqblk.dqb_bhardlimit << QUOTABLOCK_BITS : - qctl->qc_dqblk.dqb_ihardlimit; - if (!limit){ /* no limit */ - ret = QUOTA_RET_NOLIMIT; - GOTO(out, ret); - } - - if (limit >= usage) - qdata->qd_count = limit - usage; - else - qdata->qd_count = 0; - EXIT; -out: - OBD_FREE_PTR(qctl); - return ret; -} - -static struct lustre_qunit *alloc_qunit(struct lustre_quota_ctxt *qctxt, - struct qunit_data *qdata, int opc) -{ - struct lustre_qunit *qunit = NULL; - ENTRY; - - OBD_SLAB_ALLOC_PTR_GFP(qunit, qunit_cachep, CFS_ALLOC_IO); - if (qunit == NULL) - RETURN(NULL); - - CFS_INIT_LIST_HEAD(&qunit->lq_hash); - cfs_waitq_init(&qunit->lq_waitq); - cfs_atomic_set(&qunit->lq_refcnt, 1); - qunit->lq_ctxt = qctxt; - memcpy(&qunit->lq_data, qdata, sizeof(*qdata)); - qunit->lq_opc = opc; - cfs_spin_lock_init(&qunit->lq_lock); - QUNIT_SET_STATE_AND_RC(qunit, QUNIT_CREATED, 0); - qunit->lq_owner = cfs_curproc_pid(); - RETURN(qunit); -} - -static inline void free_qunit(struct lustre_qunit *qunit) -{ - OBD_SLAB_FREE(qunit, qunit_cachep, sizeof(*qunit)); -} - -static inline void qunit_get(struct lustre_qunit *qunit) -{ - cfs_atomic_inc(&qunit->lq_refcnt); -} - -static void qunit_put(struct lustre_qunit *qunit) -{ - LASSERT(cfs_atomic_read(&qunit->lq_refcnt)); - if (cfs_atomic_dec_and_test(&qunit->lq_refcnt)) - free_qunit(qunit); -} - -/* caller must hold qunit_hash_lock and release ref of qunit after using it */ -static struct lustre_qunit *dqacq_in_flight(struct lustre_quota_ctxt *qctxt, - struct qunit_data *qdata) -{ - unsigned int hashent = qunit_hashfn(qctxt, qdata); - struct lustre_qunit *qunit; - ENTRY; - - LASSERT_SPIN_LOCKED(&qunit_hash_lock); - qunit = find_qunit(hashent, qctxt, qdata); - if (qunit) - qunit_get(qunit); - RETURN(qunit); -} - -static void -insert_qunit_nolock(struct lustre_quota_ctxt *qctxt, struct lustre_qunit *qunit) -{ - cfs_list_t *head; - - LASSERT(cfs_list_empty(&qunit->lq_hash)); - qunit_get(qunit); - head = qunit_hash + qunit_hashfn(qctxt, &qunit->lq_data); - cfs_list_add(&qunit->lq_hash, head); - QUNIT_SET_STATE(qunit, QUNIT_IN_HASH); -} - -static void compute_lqs_after_removing_qunit(struct lustre_qunit *qunit) -{ - struct lustre_qunit_size *lqs; - - lqs = quota_search_lqs(LQS_KEY(QDATA_IS_GRP(&qunit->lq_data), - qunit->lq_data.qd_id), - qunit->lq_ctxt, 0); - if (lqs && !IS_ERR(lqs)) { - cfs_spin_lock(&lqs->lqs_lock); - if (qunit->lq_opc == QUOTA_DQACQ) - quota_compute_lqs(&qunit->lq_data, lqs, 0, 1); - if (qunit->lq_opc == QUOTA_DQREL) - quota_compute_lqs(&qunit->lq_data, lqs, 0, 0); - cfs_spin_unlock(&lqs->lqs_lock); - /* this is for quota_search_lqs */ - lqs_putref(lqs); - /* this is for schedule_dqacq */ - lqs_putref(lqs); - } -} - -static void remove_qunit_nolock(struct lustre_qunit *qunit) -{ - LASSERT(!cfs_list_empty(&qunit->lq_hash)); - LASSERT_SPIN_LOCKED(&qunit_hash_lock); - - cfs_list_del_init(&qunit->lq_hash); - QUNIT_SET_STATE(qunit, QUNIT_RM_FROM_HASH); - qunit_put(qunit); -} - -void* quota_barrier(struct lustre_quota_ctxt *qctxt, - struct obd_quotactl *oqctl, int isblk) -{ - struct lustre_qunit *qunit, *find_qunit; - int cycle = 1; - - OBD_SLAB_ALLOC_PTR(qunit, qunit_cachep); - if (qunit == NULL) { - CERROR("locating %sunit failed for %sid %u\n", - isblk ? "b" : "i", oqctl->qc_type ? "g" : "u", - oqctl->qc_id); - qctxt_wait_pending_dqacq(qctxt, oqctl->qc_id, - oqctl->qc_type, isblk); - return NULL; - } - - CFS_INIT_LIST_HEAD(&qunit->lq_hash); - cfs_spin_lock_init(&qunit->lq_lock); - cfs_waitq_init(&qunit->lq_waitq); - cfs_atomic_set(&qunit->lq_refcnt, 1); - qunit->lq_ctxt = qctxt; - qunit->lq_data.qd_id = oqctl->qc_id; - qunit->lq_data.qd_flags = oqctl->qc_type; - if (isblk) - QDATA_SET_BLK(&qunit->lq_data); - QUNIT_SET_STATE_AND_RC(qunit, QUNIT_CREATED, 0); - /* it means it is only an invalid qunit for barrier */ - qunit->lq_opc = QUOTA_LAST_OPC; - - while (1) { - cfs_spin_lock(&qunit_hash_lock); - find_qunit = dqacq_in_flight(qctxt, &qunit->lq_data); - if (find_qunit) { - cfs_spin_unlock(&qunit_hash_lock); - qunit_put(find_qunit); - qctxt_wait_pending_dqacq(qctxt, oqctl->qc_id, - oqctl->qc_type, isblk); - CDEBUG(D_QUOTA, "cycle=%d\n", cycle++); - continue; - } - break; - } - insert_qunit_nolock(qctxt, qunit); - cfs_spin_unlock(&qunit_hash_lock); - return qunit; -} - -void quota_unbarrier(void *handle) -{ - struct lustre_qunit *qunit = (struct lustre_qunit *)handle; - - if (qunit == NULL) { - CERROR("handle is NULL\n"); - return; - } - - LASSERT(qunit->lq_opc == QUOTA_LAST_OPC); - cfs_spin_lock(&qunit_hash_lock); - remove_qunit_nolock(qunit); - cfs_spin_unlock(&qunit_hash_lock); - QUNIT_SET_STATE_AND_RC(qunit, QUNIT_FINISHED, QUOTA_REQ_RETURNED); - cfs_waitq_signal(&qunit->lq_waitq); - qunit_put(qunit); -} - -#define INC_QLIMIT(limit, count) (limit == MIN_QLIMIT) ? \ - (limit = count) : (limit += count) - - -static inline int is_master(struct lustre_quota_ctxt *qctxt) -{ - return qctxt->lqc_handler ? 1 : 0; -} - -static int -schedule_dqacq(struct obd_device *obd, struct lustre_quota_ctxt *qctxt, - struct qunit_data *qdata, int opc, int wait, - struct obd_trans_info *oti); - -static inline void qdata_to_oqaq(struct qunit_data *qdata, - struct quota_adjust_qunit *oqaq) -{ - LASSERT(qdata); - LASSERT(oqaq); - - oqaq->qaq_flags = qdata->qd_flags; - oqaq->qaq_id = qdata->qd_id; - if (QDATA_IS_ADJBLK(qdata)) - oqaq->qaq_bunit_sz = qdata->qd_qunit; - if (QDATA_IS_ADJINO(qdata)) - oqaq->qaq_iunit_sz = qdata->qd_qunit; -} - -static int -dqacq_completion(struct obd_device *obd, struct lustre_quota_ctxt *qctxt, - struct qunit_data *qdata, int rc, int opc) -{ - struct lustre_qunit *qunit = NULL; - struct super_block *sb = qctxt->lqc_sb; - int err = 0; - struct quota_adjust_qunit *oqaq = NULL; - int rc1 = 0; - ENTRY; - - LASSERT(qdata); - QDATA_DEBUG(qdata, "obd(%s): complete %s quota req\n", - obd->obd_name, (opc == QUOTA_DQACQ) ? "acq" : "rel"); - - /* do it only when a releasing quota req more than 5MB b=18491 */ - if (opc == QUOTA_DQREL && qdata->qd_count >= 5242880) - OBD_FAIL_TIMEOUT(OBD_FAIL_QUOTA_DELAY_REL, 5); - - /* update local operational quota file */ - if (rc == 0) { - __u64 count = QUSG(qdata->qd_count, QDATA_IS_BLK(qdata)); - struct obd_quotactl *qctl; - __u64 *hardlimit; - - OBD_ALLOC_PTR(qctl); - if (qctl == NULL) - GOTO(out, err = -ENOMEM); - - /* acq/rel qunit for specified uid/gid is serialized, - * so there is no race between get fs quota limit and - * set fs quota limit */ - qctl->qc_cmd = Q_GETQUOTA; - qctl->qc_id = qdata->qd_id; - qctl->qc_type = QDATA_IS_GRP(qdata); - err = fsfilt_quotactl(obd, sb, qctl); - if (err) { - CERROR("error get quota fs limit! (rc:%d)\n", err); - GOTO(out_mem, err); - } - - if (QDATA_IS_BLK(qdata)) { - qctl->qc_dqblk.dqb_valid = QIF_BLIMITS; - hardlimit = &qctl->qc_dqblk.dqb_bhardlimit; - } else { - qctl->qc_dqblk.dqb_valid = QIF_ILIMITS; - hardlimit = &qctl->qc_dqblk.dqb_ihardlimit; - } - - CDEBUG(D_QUOTA, "hardlimt: "LPU64"\n", *hardlimit); - - if (*hardlimit == 0) - goto out_mem; - - switch (opc) { - case QUOTA_DQACQ: - INC_QLIMIT(*hardlimit, count); - break; - case QUOTA_DQREL: - LASSERTF(count < *hardlimit, - "id(%u) flag(%u) type(%c) isblk(%c) " - "count("LPU64") qd_qunit("LPU64") " - "hardlimit("LPU64").\n", - qdata->qd_id, qdata->qd_flags, - QDATA_IS_GRP(qdata) ? 'g' : 'u', - QDATA_IS_BLK(qdata) ? 'b': 'i', - qdata->qd_count, qdata->qd_qunit, *hardlimit); - *hardlimit -= count; - break; - default: - LBUG(); - } - - /* clear quota limit */ - if (count == 0) - *hardlimit = 0; - - qctl->qc_cmd = Q_SETQUOTA; - err = fsfilt_quotactl(obd, sb, qctl); - if (err) - CERROR("error set quota fs limit! (rc:%d)\n", err); - - QDATA_DEBUG(qdata, "%s completion\n", - opc == QUOTA_DQACQ ? "DQACQ" : "DQREL"); -out_mem: - OBD_FREE_PTR(qctl); - } else if (rc == -EDQUOT) { - QDATA_DEBUG(qdata, "acquire qunit got EDQUOT.\n"); - } else if (rc == -EBUSY) { - QDATA_DEBUG(qdata, "it's is recovering, got EBUSY.\n"); - } else { - CERROR("acquire qunit got error! (rc:%d)\n", rc); - } -out: - /* remove the qunit from hash */ - cfs_spin_lock(&qunit_hash_lock); - - qunit = dqacq_in_flight(qctxt, qdata); - /* this qunit has been removed by qctxt_cleanup() */ - if (!qunit) { - cfs_spin_unlock(&qunit_hash_lock); - QDATA_DEBUG(qdata, "%s is discarded because qunit isn't found\n", - opc == QUOTA_DQACQ ? "DQACQ" : "DQREL"); - RETURN(err); - } - - LASSERT(opc == qunit->lq_opc); - /* remove this qunit from lq_hash so that new processes cannot be added - * to qunit->lq_waiters */ - remove_qunit_nolock(qunit); - cfs_spin_unlock(&qunit_hash_lock); - - compute_lqs_after_removing_qunit(qunit); - - if (rc == 0) - rc = QUOTA_REQ_RETURNED; - QUNIT_SET_STATE_AND_RC(qunit, QUNIT_FINISHED, rc); - /* wake up all waiters */ - cfs_waitq_broadcast(&qunit->lq_waitq); - - /* this is for dqacq_in_flight() */ - qunit_put(qunit); - if (rc < 0 && rc != -EDQUOT) - GOTO(out1, err); - - /* don't reschedule in such cases: - * - acq/rel failure and qunit isn't changed, - * but not for quota recovery. - * - local dqacq/dqrel. - * - local disk io failure. - */ - OBD_ALLOC_PTR(oqaq); - if (!oqaq) - GOTO(out1, err = -ENOMEM); - qdata_to_oqaq(qdata, oqaq); - /* adjust the qunit size in slaves */ - rc1 = quota_adjust_slave_lqs(oqaq, qctxt); - OBD_FREE_PTR(oqaq); - if (rc1 < 0) { - CERROR("adjust slave's qunit size failed!(rc:%d)\n", rc1); - GOTO(out1, err = rc1); - } - if (err || (rc < 0 && rc != -EBUSY && rc1 == 0) || is_master(qctxt)) - GOTO(out1, err); - - if (opc == QUOTA_DQREL && qdata->qd_count >= 5242880 && - OBD_FAIL_CHECK(OBD_FAIL_QUOTA_DELAY_REL)) - GOTO(out1, err); - - /* reschedule another dqacq/dqrel if needed */ - qdata->qd_count = 0; - qdata->qd_flags &= LQUOTA_QUNIT_FLAGS; - rc1 = check_cur_qunit(obd, qctxt, qdata); - if (rc1 > 0) { - int opc; - opc = rc1 == 1 ? QUOTA_DQACQ : QUOTA_DQREL; - rc1 = schedule_dqacq(obd, qctxt, qdata, opc, 0, NULL); - QDATA_DEBUG(qdata, "reschedudle opc(%d) rc(%d)\n", opc, rc1); - } - out1: - /* this is for alloc_qunit() */ - qunit_put(qunit); - RETURN(err); -} - -struct dqacq_async_args { - struct lustre_quota_ctxt *aa_ctxt; - struct lustre_qunit *aa_qunit; -}; - -static int dqacq_interpret(const struct lu_env *env, - struct ptlrpc_request *req, void *data, int rc) -{ - struct dqacq_async_args *aa = (struct dqacq_async_args *)data; - struct lustre_quota_ctxt *qctxt = aa->aa_ctxt; - struct obd_device_target *obt = qctxt->lqc_obt; - struct lustre_qunit *qunit = aa->aa_qunit; - struct obd_device *obd = req->rq_import->imp_obd; - struct qunit_data *qdata = NULL; - ENTRY; - - LASSERT(req); - LASSERT(req->rq_import); - - cfs_down_read(&obt->obt_rwsem); - /* if a quota req timeouts or is dropped, we should update quota - * statistics which will be handled in dqacq_completion. And in - * this situation we should get qdata from request instead of - * reply */ - qdata = quota_get_qdata(req, (rc != 0) ? QUOTA_REQUEST : QUOTA_REPLY, - QUOTA_IMPORT); - if (IS_ERR(qdata)) { - rc = PTR_ERR(qdata); - DEBUG_REQ(D_ERROR, req, - "error unpacking qunit_data(rc: %ld)\n", - PTR_ERR(qdata)); - qdata = &qunit->lq_data; - } - - QDATA_DEBUG(qdata, "qdata: interpret rc(%d).\n", rc); - QDATA_DEBUG((&qunit->lq_data), "lq_data: \n"); - - if (qdata->qd_id != qunit->lq_data.qd_id || - OBD_FAIL_CHECK(OBD_FAIL_QUOTA_RET_QDATA)) { - CERROR("the returned qd_id isn't expected!" - "(qdata: %u, lq_data: %u)\n", qdata->qd_id, - qunit->lq_data.qd_id); - qdata->qd_id = qunit->lq_data.qd_id; - rc = -EPROTO; - } - if (QDATA_IS_GRP(qdata) != QDATA_IS_GRP(&qunit->lq_data)) { - CERROR("the returned grp/usr isn't expected!" - "(qdata: %u, lq_data: %u)\n", qdata->qd_flags, - qunit->lq_data.qd_flags); - if (QDATA_IS_GRP(&qunit->lq_data)) - QDATA_SET_GRP(qdata); - else - QDATA_CLR_GRP(qdata); - rc = -EPROTO; - } - if (qdata->qd_count > qunit->lq_data.qd_count) { - CERROR("the returned qd_count isn't expected!" - "(qdata: "LPU64", lq_data: "LPU64")\n", qdata->qd_count, - qunit->lq_data.qd_count); - rc = -EPROTO; - } - - if (unlikely(rc == -ESRCH)) - CERROR("quota for %s has been enabled by master, but disabled " - "by slave.\n", QDATA_IS_GRP(qdata) ? "group" : "user"); - - rc = dqacq_completion(obd, qctxt, qdata, rc, - lustre_msg_get_opc(req->rq_reqmsg)); - - cfs_up_read(&obt->obt_rwsem); - RETURN(rc); -} - -/** - * check if quota master is online - */ -int check_qm(struct lustre_quota_ctxt *qctxt) -{ - int rc; - ENTRY; - - cfs_spin_lock(&qctxt->lqc_lock); - /* quit waiting when mds is back or qctxt is cleaned up */ - rc = qctxt->lqc_import || !qctxt->lqc_valid; - cfs_spin_unlock(&qctxt->lqc_lock); - - RETURN(rc); -} - -/* wake up all waiting threads when lqc_import is NULL */ -void dqacq_interrupt(struct lustre_quota_ctxt *qctxt) -{ - struct lustre_qunit *qunit, *tmp; - int i; - ENTRY; - - cfs_spin_lock(&qunit_hash_lock); - for (i = 0; i < NR_DQHASH; i++) { - cfs_list_for_each_entry_safe(qunit, tmp, &qunit_hash[i], - lq_hash) { - if (qunit->lq_ctxt != qctxt) - continue; - - /* Wake up all waiters. Do not change lq_state. - * The waiters will check lq_rc which is kept as 0 - * if no others change it, then the waiters will return - * -EAGAIN to caller who can perform related quota - * acq/rel if necessary. */ - cfs_waitq_broadcast(&qunit->lq_waitq); - } - } - cfs_spin_unlock(&qunit_hash_lock); - EXIT; -} - -static int got_qunit(struct lustre_qunit *qunit, int is_master) -{ - struct lustre_quota_ctxt *qctxt = qunit->lq_ctxt; - int rc = 0; - ENTRY; - - cfs_spin_lock(&qunit->lq_lock); - switch (qunit->lq_state) { - case QUNIT_IN_HASH: - case QUNIT_RM_FROM_HASH: - break; - case QUNIT_FINISHED: - rc = 1; - break; - default: - CERROR("invalid qunit state %d\n", qunit->lq_state); - } - cfs_spin_unlock(&qunit->lq_lock); - - if (!rc) { - cfs_spin_lock(&qctxt->lqc_lock); - rc = !qctxt->lqc_valid; - if (!is_master) - rc |= !qctxt->lqc_import; - cfs_spin_unlock(&qctxt->lqc_lock); - } - - RETURN(rc); -} - -static inline void -revoke_lqs_rec(struct lustre_qunit_size *lqs, struct qunit_data *qdata, int opc) -{ - /* revoke lqs_xxx_rec which is computed in check_cur_qunit - * b=18630 */ - cfs_spin_lock(&lqs->lqs_lock); - quota_compute_lqs(qdata, lqs, 0, (opc == QUOTA_DQACQ) ? 1 : 0); - cfs_spin_unlock(&lqs->lqs_lock); -} - -static int verify_cur_qunit(struct obd_device *obd, - struct lustre_quota_ctxt *qctxt, - struct qunit_data *qdata, int opc) -{ - struct obd_quotactl *qctl; - __u64 limit; - int ret = 0; - ENTRY; - - /* extra quota acquire can be tolerated. */ - if (opc == QUOTA_DQACQ) - RETURN(ret); - - OBD_ALLOC_PTR(qctl); - if (qctl == NULL) { - CERROR("Fail to allocate mem!\n"); - RETURN(-ENOMEM); - } - - qctl->qc_cmd = Q_GETQUOTA; - qctl->qc_id = qdata->qd_id; - qctl->qc_type = QDATA_IS_GRP(qdata); - ret = fsfilt_quotactl(obd, qctxt->lqc_sb, qctl); - if (ret) { - /* -ESRCH means no limit */ - CDEBUG(ret == -ESRCH ? D_QUOTA : D_ERROR, - "Can't get quota usage! rc:%d\n", ret); - GOTO(out, ret); - } - - if (QDATA_IS_BLK(qdata)) - limit = qctl->qc_dqblk.dqb_bhardlimit << QUOTABLOCK_BITS; - else - limit = qctl->qc_dqblk.dqb_ihardlimit; - - if (limit <= qdata->qd_count) { - CDEBUG(D_QUOTA, "drop extra release. id(%u), flag(%u), " - "type(%c), isblk(%c), count("LPU64"), " - "qd_qunit("LPU64"), hardlimit("LPU64").\n", - qdata->qd_id, qdata->qd_flags, - QDATA_IS_GRP(qdata) ? 'g' : 'u', - QDATA_IS_BLK(qdata) ? 'b' : 'i', - qdata->qd_count, qdata->qd_qunit, limit); - ret = -EAGAIN; - } -out: - OBD_FREE_PTR(qctl); - RETURN(ret); -} - -static int -schedule_dqacq(struct obd_device *obd, struct lustre_quota_ctxt *qctxt, - struct qunit_data *qdata, int opc, int wait, - struct obd_trans_info *oti) -{ - struct lustre_qunit *qunit, *empty; - struct l_wait_info lwi = { 0 }; - struct ptlrpc_request *req; - struct dqacq_async_args *aa; - struct obd_import *imp = NULL; - struct lustre_qunit_size *lqs = NULL; - struct timeval work_start; - struct timeval work_end; - long timediff; - int rc = 0; - ENTRY; - - LASSERT(opc == QUOTA_DQACQ || opc == QUOTA_DQREL); - cfs_gettimeofday(&work_start); - - lqs = quota_search_lqs(LQS_KEY(QDATA_IS_GRP(qdata), qdata->qd_id), - qctxt, 0); - if (lqs == NULL || IS_ERR(lqs)) { - CERROR("Can't find the lustre qunit size!\n"); - RETURN(-EPERM); - } - - if ((empty = alloc_qunit(qctxt, qdata, opc)) == NULL) { - revoke_lqs_rec(lqs, qdata, opc); - /* this is for quota_search_lqs */ - lqs_putref(lqs); - RETURN(-ENOMEM); - } - - OBD_FAIL_TIMEOUT(OBD_FAIL_QUOTA_DELAY_SD, 5); - - cfs_spin_lock(&qunit_hash_lock); - qunit = dqacq_in_flight(qctxt, qdata); - if (qunit) { - cfs_spin_unlock(&qunit_hash_lock); - qunit_put(empty); - - revoke_lqs_rec(lqs, qdata, opc); - /* this is for quota_search_lqs */ - lqs_putref(lqs); - goto wait_completion; - } - qunit = empty; - qunit_get(qunit); - insert_qunit_nolock(qctxt, qunit); - cfs_spin_unlock(&qunit_hash_lock); - - /* From here, the quota request will be sent anyway. - * When this qdata request returned or is cancelled, - * lqs_putref will be called at that time */ - lqs_getref(lqs); - /* this is for quota_search_lqs */ - lqs_putref(lqs); - - /* LU-1493 - * - * There is a race between the check_cur_qunit() and the - * dqacq_completion(): check_cur_qunit() read hardlimit - * and calculate how much quota need be acquired/released - * based on the hardlimit, however, the hardlimit can be - * changed by the dqacq_completion() at anytime. So that - * could result in extra quota acquire/release when there - * is inflight dqacq. - * - * In general, such extra dqacq dosen't bring fatal error, - * unless an extra release is going to release more than - * 'hardlimit' quota. - * - * To minimize the code changes (anyway, it'll be totally - * rewritten in the new quota design), we just do one more - * check here to avoid the extra release which could bring - * fatal error. A better solution could be calculating the - * qd_count here and removing the lqs_blk/ino_rec stuff. - */ - rc = verify_cur_qunit(obd, qctxt, qdata, opc); - if (rc) { - cfs_spin_lock(&qunit_hash_lock); - remove_qunit_nolock(qunit); - cfs_spin_unlock(&qunit_hash_lock); - - compute_lqs_after_removing_qunit(qunit); - /* this is for qunit_get() */ - qunit_put(qunit); - /* this for alloc_qunit() */ - qunit_put(qunit); - /* drop this extra release silently */ - RETURN(0); - } - - QDATA_DEBUG(qdata, "obd(%s): send %s quota req\n", - obd->obd_name, (opc == QUOTA_DQACQ) ? "acq" : "rel"); - /* master is going to dqacq/dqrel from itself */ - if (is_master(qctxt)) { - int rc2; - QDATA_DEBUG(qdata, "local %s.\n", - opc == QUOTA_DQACQ ? "DQACQ" : "DQREL"); - QDATA_SET_CHANGE_QS(qdata); - rc = qctxt->lqc_handler(obd, qdata, opc); - rc2 = dqacq_completion(obd, qctxt, qdata, rc, opc); - /* this is for qunit_get() */ - qunit_put(qunit); - - cfs_gettimeofday(&work_end); - timediff = cfs_timeval_sub(&work_end, &work_start, NULL); - if (opc == QUOTA_DQACQ) - lprocfs_counter_add(qctxt->lqc_stats, - wait ? LQUOTA_SYNC_ACQ : LQUOTA_ASYNC_ACQ, - timediff); - else - lprocfs_counter_add(qctxt->lqc_stats, - wait ? LQUOTA_SYNC_REL : LQUOTA_ASYNC_REL, - timediff); - RETURN(rc ? rc : rc2); - } - - cfs_spin_lock(&qctxt->lqc_lock); - if (!qctxt->lqc_import) { - cfs_spin_unlock(&qctxt->lqc_lock); - QDATA_DEBUG(qdata, "lqc_import is invalid.\n"); - - cfs_spin_lock(&qunit_hash_lock); - remove_qunit_nolock(qunit); - cfs_spin_unlock(&qunit_hash_lock); - - compute_lqs_after_removing_qunit(qunit); - - QUNIT_SET_STATE_AND_RC(qunit, QUNIT_FINISHED, -EAGAIN); - cfs_waitq_broadcast(&qunit->lq_waitq); - - /* this is for qunit_get() */ - qunit_put(qunit); - /* this for alloc_qunit() */ - qunit_put(qunit); - cfs_spin_lock(&qctxt->lqc_lock); - if (wait && !qctxt->lqc_import) { - cfs_spin_unlock(&qctxt->lqc_lock); - LASSERT(oti && oti->oti_thread); - /* The recovery thread doesn't have watchdog - * attached. LU-369 */ - if (oti->oti_thread->t_watchdog) - lc_watchdog_disable(oti->oti_thread->\ - t_watchdog); - CDEBUG(D_QUOTA, "sleep for quota master\n"); - l_wait_event(qctxt->lqc_wait_for_qmaster, - check_qm(qctxt), &lwi); - CDEBUG(D_QUOTA, "wake up when quota master is back\n"); - if (oti->oti_thread->t_watchdog) - lc_watchdog_touch(oti->oti_thread->t_watchdog, - ptlrpc_server_get_timeout(\ - oti->oti_thread->t_svcpt)); - } else { - cfs_spin_unlock(&qctxt->lqc_lock); - } - - RETURN(-EAGAIN); - } - imp = class_import_get(qctxt->lqc_import); - cfs_spin_unlock(&qctxt->lqc_lock); - - /* build dqacq/dqrel request */ - LASSERT(imp); - - req = ptlrpc_request_alloc_pack(imp, &RQF_MDS_QUOTA_DQACQ, - LUSTRE_MDS_VERSION, opc); - class_import_put(imp); - if (req == NULL) { - CERROR("Can't alloc request\n"); - dqacq_completion(obd, qctxt, qdata, -ENOMEM, opc); - /* this is for qunit_get() */ - qunit_put(qunit); - RETURN(-ENOMEM); - } - - ptlrpc_request_set_replen(req); - req->rq_no_resend = req->rq_no_delay = 1; - rc = quota_copy_qdata(req, qdata, QUOTA_REQUEST, QUOTA_IMPORT); - if (rc < 0) { - CERROR("Can't pack qunit_data(rc: %d)\n", rc); - ptlrpc_req_finished(req); - dqacq_completion(obd, qctxt, qdata, -EPROTO, opc); - /* this is for qunit_get() */ - qunit_put(qunit); - RETURN(rc); - } - - CLASSERT(sizeof(*aa) <= sizeof(req->rq_async_args)); - aa = ptlrpc_req_async_args(req); - aa->aa_ctxt = qctxt; - aa->aa_qunit = qunit; - - req->rq_interpret_reply = dqacq_interpret; - ptlrpcd_add_req(req, PDL_POLICY_LOCAL, -1); - - QDATA_DEBUG(qdata, "%s scheduled.\n", - opc == QUOTA_DQACQ ? "DQACQ" : "DQREL"); -wait_completion: - if (wait && qunit) { - struct qunit_data *p = &qunit->lq_data; - - QDATA_DEBUG(p, "qunit(%p) is waiting for dqacq.\n", qunit); - l_wait_event(qunit->lq_waitq, got_qunit(qunit, is_master(qctxt)), - &lwi); - /* rc = -EAGAIN, it means the quota master isn't ready yet - * rc = QUOTA_REQ_RETURNED, it means a quota req is finished; - * rc = -EDQUOT, it means out of quota - * rc = -EBUSY, it means recovery is happening - * other rc < 0, it means real errors, functions who call - * schedule_dqacq should take care of this */ - cfs_spin_lock(&qunit->lq_lock); - rc = qunit->lq_rc; - cfs_spin_unlock(&qunit->lq_lock); - CDEBUG(D_QUOTA, "qunit(%p) finishes waiting: id(%u) flag(%u) " - "rc(%d) owner(%d)\n", qunit, qunit->lq_data.qd_id, - qunit->lq_data.qd_flags, rc, qunit->lq_owner); - } - - qunit_put(qunit); - cfs_gettimeofday(&work_end); - timediff = cfs_timeval_sub(&work_end, &work_start, NULL); - if (opc == QUOTA_DQACQ) - lprocfs_counter_add(qctxt->lqc_stats, - wait ? LQUOTA_SYNC_ACQ : LQUOTA_ASYNC_ACQ, - timediff); - else - lprocfs_counter_add(qctxt->lqc_stats, - wait ? LQUOTA_SYNC_REL : LQUOTA_ASYNC_REL, - timediff); - - RETURN(rc); -} - -int -qctxt_adjust_qunit(struct obd_device *obd, struct lustre_quota_ctxt *qctxt, - const unsigned int id[], __u32 isblk, int wait, - struct obd_trans_info *oti) -{ - int rc = 0, i = USRQUOTA; - struct qunit_data qdata[MAXQUOTAS]; - ENTRY; - - /* XXX In quota_chk_acq_common(), we do something like: - * - * while (quota_check_common() & QUOTA_RET_ACQUOTA) { - * rc = qctxt_adjust_qunit(); - * } - * - * to make sure the slave acquired enough quota from master. - * - * Unfortunately, qctxt_adjust_qunit() checks QB/QI_SET to - * decide if do real DQACQ or not, but quota_check_common() - * doesn't check QB/QI_SET flags. This inconsistence could - * lead into an infinite loop. - * - * We can't fix it by simply adding QB/QI_SET checking in the - * quota_check_common(), since we must guarantee that the - * paried quota_pending_commit() has same QB/QI_SET, but the - * flags can be actually cleared at any time... - * - * A quick non-intrusive solution is to just skip the - * QB/QI_SET checking here when the @wait is non-zero. - * (If the @wait is non-zero, the caller must have already - * checked the QB/QI_SET). - */ - if (!wait && quota_is_set(obd, id, isblk ? QB_SET : QI_SET) == 0) - RETURN(0); - - for (i = 0; i < MAXQUOTAS; i++) { - qdata[i].qd_id = id[i]; - qdata[i].qd_flags = i; - if (isblk) - QDATA_SET_BLK(&qdata[i]); - qdata[i].qd_count = 0; - - rc = check_cur_qunit(obd, qctxt, &qdata[i]); - if (rc > 0) { - int opc; - /* need acquire or release */ - opc = rc == 1 ? QUOTA_DQACQ : QUOTA_DQREL; - rc = schedule_dqacq(obd, qctxt, &qdata[i], opc, - wait,oti); - if (rc < 0) - RETURN(rc); - } else if (wait == 1) { - /* when wait equates 1, that means mds_quota_acquire - * or filter_quota_acquire is calling it. */ - rc = qctxt_wait_pending_dqacq(qctxt, id[i], i, isblk); - if (rc < 0) - RETURN(rc); - } - } - - RETURN(rc); -} - -int -qctxt_wait_pending_dqacq(struct lustre_quota_ctxt *qctxt, unsigned int id, - unsigned short type, int isblk) -{ - struct lustre_qunit *qunit = NULL; - struct qunit_data qdata; - struct timeval work_start; - struct timeval work_end; - long timediff; - struct l_wait_info lwi = { 0 }; - int rc = 0; - ENTRY; - - cfs_gettimeofday(&work_start); - qdata.qd_id = id; - qdata.qd_flags = type; - if (isblk) - QDATA_SET_BLK(&qdata); - qdata.qd_count = 0; - - cfs_spin_lock(&qunit_hash_lock); - qunit = dqacq_in_flight(qctxt, &qdata); - cfs_spin_unlock(&qunit_hash_lock); - - if (qunit) { - struct qunit_data *p = &qunit->lq_data; - - QDATA_DEBUG(p, "qunit(%p) is waiting for dqacq.\n", qunit); - l_wait_event(qunit->lq_waitq, got_qunit(qunit, is_master(qctxt)), - &lwi); - CDEBUG(D_QUOTA, "qunit(%p) finishes waiting: rc(%d) " - "owner(%d)\n", qunit, qunit->lq_rc, qunit->lq_owner); - /* keep same as schedule_dqacq() b=17030 */ - cfs_spin_lock(&qunit->lq_lock); - rc = qunit->lq_rc; - cfs_spin_unlock(&qunit->lq_lock); - /* this is for dqacq_in_flight() */ - qunit_put(qunit); - cfs_gettimeofday(&work_end); - timediff = cfs_timeval_sub(&work_end, &work_start, NULL); - lprocfs_counter_add(qctxt->lqc_stats, - isblk ? LQUOTA_WAIT_PENDING_BLK_QUOTA : - LQUOTA_WAIT_PENDING_INO_QUOTA, - timediff); - } else { - cfs_gettimeofday(&work_end); - timediff = cfs_timeval_sub(&work_end, &work_start, NULL); - lprocfs_counter_add(qctxt->lqc_stats, - isblk ? LQUOTA_NOWAIT_PENDING_BLK_QUOTA : - LQUOTA_NOWAIT_PENDING_INO_QUOTA, - timediff); - } - - RETURN(rc); -} - -int -qctxt_init(struct obd_device *obd, dqacq_handler_t handler) -{ - struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt; - struct obd_device_target *obt = &obd->u.obt; - struct super_block *sb = obt->obt_sb; - int rc = 0; - ENTRY; - - LASSERT(qctxt); - - rc = ptlrpcd_addref(); - if (rc) - RETURN(rc); - - cfs_waitq_init(&qctxt->lqc_wait_for_qmaster); - cfs_waitq_init(&qctxt->lqc_lqs_waitq); - cfs_atomic_set(&qctxt->lqc_lqs, 0); - cfs_spin_lock_init(&qctxt->lqc_lock); - cfs_spin_lock(&qctxt->lqc_lock); - qctxt->lqc_handler = handler; - qctxt->lqc_sb = sb; - qctxt->lqc_obt = obt; - qctxt->lqc_import = NULL; - qctxt->lqc_recovery = 0; - qctxt->lqc_switch_qs = 1; /* Change qunit size in default setting */ - qctxt->lqc_valid = 1; - qctxt->lqc_cqs_boundary_factor = 4; - qctxt->lqc_cqs_least_bunit = PTLRPC_MAX_BRW_SIZE; - qctxt->lqc_cqs_least_iunit = 2; - qctxt->lqc_cqs_qs_factor = 2; - qctxt->lqc_flags = 0; - QUOTA_MASTER_UNREADY(qctxt); - qctxt->lqc_bunit_sz = default_bunit_sz; - qctxt->lqc_btune_sz = default_bunit_sz / 100 * default_btune_ratio; - qctxt->lqc_iunit_sz = default_iunit_sz; - qctxt->lqc_itune_sz = default_iunit_sz * default_itune_ratio / 100; - qctxt->lqc_switch_seconds = 300; /* enlarging will wait 5 minutes - * after the last shrinking */ - qctxt->lqc_sync_blk = 0; - cfs_spin_unlock(&qctxt->lqc_lock); - - qctxt->lqc_lqs_hash = cfs_hash_create("LQS_HASH", - hash_lqs_cur_bits, - HASH_LQS_MAX_BITS, - min(hash_lqs_cur_bits, - HASH_LQS_BKT_BITS), - 0, CFS_HASH_MIN_THETA, - CFS_HASH_MAX_THETA, - &lqs_hash_ops, CFS_HASH_DEFAULT); - if (!qctxt->lqc_lqs_hash) { - CERROR("initialize hash lqs for %s error!\n", obd->obd_name); - RETURN(-ENOMEM); - } - -#ifdef LPROCFS - rc = lquota_proc_setup(obd, is_master(qctxt)); - if (rc) - CERROR("initialize proc for %s error!\n", obd->obd_name); -#endif - - RETURN(rc); -} - -static int check_lqs(struct lustre_quota_ctxt *qctxt) -{ - int rc; - ENTRY; - - rc = !cfs_atomic_read(&qctxt->lqc_lqs); - - RETURN(rc); -} - -int qctxt_del_lqs(cfs_hash_t *hs, cfs_hash_bd_t *bd, - cfs_hlist_node_t *hnode, void *data) -{ - /* remove from hash and -1 refcount */ - cfs_hash_bd_del_locked(hs, bd, hnode); - return 0; -} - -void qctxt_cleanup(struct lustre_quota_ctxt *qctxt, int force) -{ - struct lustre_qunit *qunit, *tmp; - cfs_list_t tmp_list; - struct l_wait_info lwi = { 0 }; - struct obd_device_target *obt = qctxt->lqc_obt; - int i; - ENTRY; - - CFS_INIT_LIST_HEAD(&tmp_list); - - cfs_spin_lock(&qctxt->lqc_lock); - qctxt->lqc_valid = 0; - cfs_spin_unlock(&qctxt->lqc_lock); - - cfs_spin_lock(&qunit_hash_lock); - for (i = 0; i < NR_DQHASH; i++) { - cfs_list_for_each_entry_safe(qunit, tmp, &qunit_hash[i], - lq_hash) { - if (qunit->lq_ctxt != qctxt) - continue; - remove_qunit_nolock(qunit); - cfs_list_add(&qunit->lq_hash, &tmp_list); - } - } - cfs_spin_unlock(&qunit_hash_lock); - - cfs_list_for_each_entry_safe(qunit, tmp, &tmp_list, lq_hash) { - cfs_list_del_init(&qunit->lq_hash); - compute_lqs_after_removing_qunit(qunit); - - /* wake up all waiters */ - QUNIT_SET_STATE_AND_RC(qunit, QUNIT_FINISHED, 0); - cfs_waitq_broadcast(&qunit->lq_waitq); - qunit_put(qunit); - } - - /* after qctxt_cleanup, qctxt might be freed, then check_qm() is - * unpredicted. So we must wait until lqc_wait_for_qmaster is empty */ - while (cfs_waitq_active(&qctxt->lqc_wait_for_qmaster)) { - cfs_waitq_signal(&qctxt->lqc_wait_for_qmaster); - cfs_schedule_timeout_and_set_state(CFS_TASK_INTERRUPTIBLE, - cfs_time_seconds(1)); - } - - /* release refcount on lustre_qunit_size holding by lqs_hash */ - cfs_hash_for_each_safe(qctxt->lqc_lqs_hash, qctxt_del_lqs, NULL); - - l_wait_event(qctxt->lqc_lqs_waitq, check_lqs(qctxt), &lwi); - cfs_down_write(&obt->obt_rwsem); - cfs_hash_putref(qctxt->lqc_lqs_hash); - qctxt->lqc_lqs_hash = NULL; - cfs_up_write(&obt->obt_rwsem); - - ptlrpcd_decref(); - -#ifdef LPROCFS - if (lquota_proc_cleanup(qctxt)) - CERROR("cleanup proc error!\n"); -#endif - - EXIT; -} - -struct qslave_recov_thread_data { - struct obd_device *obd; - struct lustre_quota_ctxt *qctxt; - cfs_completion_t comp; -}; - -/* FIXME only recovery block quota by now */ -static int qslave_recovery_main(void *arg) -{ - struct qslave_recov_thread_data *data = arg; - struct obd_device *obd = data->obd; - struct lustre_quota_ctxt *qctxt = data->qctxt; - unsigned int type; - int rc = 0; - ENTRY; - - cfs_daemonize_ctxt("qslave_recovd"); - - /* for obdfilter */ - class_incref(obd, "qslave_recovd_filter", obd); - - cfs_complete(&data->comp); - - cfs_spin_lock(&qctxt->lqc_lock); - if (qctxt->lqc_recovery) { - cfs_spin_unlock(&qctxt->lqc_lock); - class_decref(obd, "qslave_recovd_filter", obd); - RETURN(0); - } else { - qctxt->lqc_recovery = 1; - cfs_spin_unlock(&qctxt->lqc_lock); - } - - for (type = USRQUOTA; type < MAXQUOTAS; type++) { - struct qunit_data qdata; - struct quota_info *dqopt = sb_dqopt(qctxt->lqc_sb); - cfs_list_t id_list; - struct dquot_id *dqid, *tmp; - int ret; - - mutex_lock(&dqopt->dqonoff_mutex); - if (!sb_has_quota_active(qctxt->lqc_sb, type)) { - mutex_unlock(&dqopt->dqonoff_mutex); - break; - } - - LASSERT(dqopt->files[type] != NULL); - CFS_INIT_LIST_HEAD(&id_list); - rc = fsfilt_qids(obd, NULL, dqopt->files[type], type, &id_list); - mutex_unlock(&dqopt->dqonoff_mutex); - if (rc) - CERROR("Get ids from quota file failed. (rc:%d)\n", rc); - - cfs_list_for_each_entry_safe(dqid, tmp, &id_list, di_link) { - cfs_list_del_init(&dqid->di_link); - /* skip slave recovery on itself */ - if (is_master(qctxt)) - goto free; - if (rc && rc != -EBUSY) - goto free; - - qdata.qd_id = dqid->di_id; - qdata.qd_flags = type; - QDATA_SET_BLK(&qdata); - qdata.qd_count = 0; - - ret = check_cur_qunit(obd, qctxt, &qdata); - if (ret > 0) { - int opc; - opc = ret == 1 ? QUOTA_DQACQ : QUOTA_DQREL; - rc = schedule_dqacq(obd, qctxt, &qdata, opc, - 0, NULL); - if (rc == -EDQUOT) - rc = 0; - } else { - rc = 0; - } - - if (rc && rc != -EBUSY) - CERROR("qslave recovery failed! (id:%d type:%d " - " rc:%d)\n", dqid->di_id, type, rc); -free: - OBD_FREE_PTR(dqid); - } - } - - cfs_spin_lock(&qctxt->lqc_lock); - qctxt->lqc_recovery = 0; - cfs_spin_unlock(&qctxt->lqc_lock); - class_decref(obd, "qslave_recovd_filter", obd); - RETURN(rc); -} - -void -qslave_start_recovery(struct obd_device *obd, struct lustre_quota_ctxt *qctxt) -{ - struct qslave_recov_thread_data data; - int rc; - ENTRY; - - if (!sb_any_quota_loaded(qctxt->lqc_sb)) - goto exit; - - data.obd = obd; - data.qctxt = qctxt; - cfs_init_completion(&data.comp); - - rc = cfs_create_thread(qslave_recovery_main, &data, - CFS_DAEMON_FLAGS); - if (rc < 0) { - CERROR("Cannot start quota recovery thread: rc %d\n", rc); - goto exit; - } - cfs_wait_for_completion(&data.comp); -exit: - EXIT; -} - -inline int quota_is_on(struct lustre_quota_ctxt *qctxt, - struct obd_quotactl *oqctl) -{ - return ((qctxt->lqc_flags & UGQUOTA2LQC(oqctl->qc_type)) == - UGQUOTA2LQC(oqctl->qc_type)); -} - -inline int quota_is_off(struct lustre_quota_ctxt *qctxt, - struct obd_quotactl *oqctl) -{ - return !(qctxt->lqc_flags & UGQUOTA2LQC(oqctl->qc_type)); -} - -/* - * When quotaon, build a lqs for every uid/gid who has been set limitation - * for quota. After quota_search_lqs, it will hold one ref for the lqs. - * It will be released when qctxt_cleanup() is executed b=18574 - * - * Should be called with obt->obt_quotachecking held. b=20152 - */ -void build_lqs(struct obd_device *obd) -{ - struct obd_device_target *obt = &obd->u.obt; - struct lustre_quota_ctxt *qctxt = &obt->obt_qctxt; - cfs_list_t id_list; - int i, rc; - - LASSERT_SEM_LOCKED(&obt->obt_quotachecking); - CFS_INIT_LIST_HEAD(&id_list); - for (i = 0; i < MAXQUOTAS; i++) { - struct dquot_id *dqid, *tmp; - - if (sb_dqopt(qctxt->lqc_sb)->files[i] == NULL) - continue; - - rc = fsfilt_qids(obd, NULL, sb_dqopt(qctxt->lqc_sb)->files[i], - i, &id_list); - if (rc) { - CERROR("%s: failed to get %s qids!\n", obd->obd_name, - i ? "group" : "user"); - continue; - } - - cfs_list_for_each_entry_safe(dqid, tmp, &id_list, - di_link) { - struct lustre_qunit_size *lqs; - - cfs_list_del_init(&dqid->di_link); - lqs = quota_search_lqs(LQS_KEY(i, dqid->di_id), - qctxt, 1); - if (lqs && !IS_ERR(lqs)) { - lqs->lqs_flags |= dqid->di_flag; - lqs_putref(lqs); - } else { - CERROR("%s: failed to create a lqs for %sid %u" - "\n", obd->obd_name, i ? "g" : "u", - dqid->di_id); - } - - OBD_FREE_PTR(dqid); - } - } -} - -/** - * lqs<->qctxt hash operations - */ - -/** - * string hashing using djb2 hash algorithm - */ -static unsigned -lqs_hash(cfs_hash_t *hs, const void *key, unsigned mask) -{ - unsigned long long id; - unsigned hash; - ENTRY; - - LASSERT(key); - id = *((unsigned long long *)key); - hash = (LQS_KEY_GRP(id) ? 5381 : 5387) * (unsigned)LQS_KEY_ID(id); - - RETURN(hash & mask); -} - -static void * -lqs_key(cfs_hlist_node_t *hnode) -{ - struct lustre_qunit_size *lqs; - ENTRY; - - lqs = cfs_hlist_entry(hnode, struct lustre_qunit_size, lqs_hash); - RETURN(&lqs->lqs_key); -} - -static int -lqs_keycmp(const void *key, cfs_hlist_node_t *hnode) -{ - struct lustre_qunit_size *q = - cfs_hlist_entry(hnode, struct lustre_qunit_size, lqs_hash); - - RETURN(q->lqs_key == *((unsigned long long *)key)); -} - -static void * -lqs_object(cfs_hlist_node_t *hnode) -{ - return cfs_hlist_entry(hnode, struct lustre_qunit_size, lqs_hash); -} - -static void -lqs_get(cfs_hash_t *hs, cfs_hlist_node_t *hnode) -{ - struct lustre_qunit_size *q = - cfs_hlist_entry(hnode, struct lustre_qunit_size, lqs_hash); - - lqs_getref(q); -} - -static void -lqs_put_locked(cfs_hash_t *hs, cfs_hlist_node_t *hnode) -{ - struct lustre_qunit_size *q = - cfs_hlist_entry(hnode, struct lustre_qunit_size, lqs_hash); - - lqs_putref(q); -} - -static void -lqs_exit(cfs_hash_t *hs, cfs_hlist_node_t *hnode) -{ - CERROR("It should not have any item left to be handled by this!"); -} - -static cfs_hash_ops_t lqs_hash_ops = { - .hs_hash = lqs_hash, - .hs_key = lqs_key, - .hs_keycmp = lqs_keycmp, - .hs_object = lqs_object, - .hs_get = lqs_get, - .hs_put_locked = lqs_put_locked, - .hs_exit = lqs_exit -}; diff --git a/lustre/quota/quota_ctl.c b/lustre/quota/quota_ctl.c deleted file mode 100644 index 99d30f4..0000000 --- a/lustre/quota/quota_ctl.c +++ /dev/null @@ -1,287 +0,0 @@ -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * GPL HEADER END - */ -/* - * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - * - * Copyright (c) 2011, 2012, Whamcloud, Inc. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - */ - -#define DEBUG_SUBSYSTEM S_LQUOTA - -#ifdef __KERNEL__ -# include -# include -# include -# include -# include -# include -# include -# include -# include -#else /* __KERNEL__ */ -# include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include "quota_internal.h" - -#ifdef __KERNEL__ - -int mds_quota_ctl(struct obd_device *obd, struct obd_export *unused, - struct obd_quotactl *oqctl) -{ - struct obd_device_target *obt = &obd->u.obt; - struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt; - struct timeval work_start; - struct timeval work_end; - long timediff; - int rc = 0; - ENTRY; - - cfs_gettimeofday(&work_start); - switch (oqctl->qc_cmd) { - case Q_QUOTAON: - oqctl->qc_id = obt->obt_qfmt; /* override qfmt version */ - rc = mds_quota_on(obd, oqctl); - break; - case Q_QUOTAOFF: - oqctl->qc_id = obt->obt_qfmt; /* override qfmt version */ - rc = mds_quota_off(obd, oqctl); - break; - case Q_SETINFO: - rc = mds_set_dqinfo(obd, oqctl); - break; - case Q_GETINFO: - rc = mds_get_dqinfo(obd, oqctl); - break; - case Q_SETQUOTA: - rc = mds_set_dqblk(obd, oqctl); - break; - case Q_GETQUOTA: - rc = mds_get_dqblk(obd, oqctl); - break; - case Q_GETOINFO: - case Q_GETOQUOTA: - rc = mds_get_obd_quota(obd, oqctl); - break; - case LUSTRE_Q_INVALIDATE: - rc = mds_quota_invalidate(obd, oqctl); - break; - case LUSTRE_Q_FINVALIDATE: - oqctl->qc_id = obt->obt_qfmt; /* override qfmt version */ - rc = mds_quota_finvalidate(obd, oqctl); - break; - default: - CERROR("%s: unsupported mds_quotactl command: %d\n", - obd->obd_name, oqctl->qc_cmd); - RETURN(-EFAULT); - } - - if (rc) - CDEBUG(D_INFO, "mds_quotactl admin quota command %d, id %u, " - "type %d, failed: rc = %d\n", - oqctl->qc_cmd, oqctl->qc_id, oqctl->qc_type, rc); - cfs_gettimeofday(&work_end); - timediff = cfs_timeval_sub(&work_end, &work_start, NULL); - lprocfs_counter_add(qctxt->lqc_stats, LQUOTA_QUOTA_CTL, timediff); - - RETURN(rc); -} - -int filter_quota_ctl(struct obd_device *unused, struct obd_export *exp, - struct obd_quotactl *oqctl) -{ - struct obd_device *obd = exp->exp_obd; - struct obd_device_target *obt = &obd->u.obt; - struct lvfs_run_ctxt saved; - struct lustre_quota_ctxt *qctxt = &obt->obt_qctxt; - struct lustre_qunit_size *lqs; - void *handle = NULL; - struct timeval work_start; - struct timeval work_end; - long timediff; - int rc = 0; - ENTRY; - - cfs_gettimeofday(&work_start); - switch (oqctl->qc_cmd) { - case Q_QUOTAON: - oqctl->qc_id = obt->obt_qfmt; - rc = generic_quota_on(obd, oqctl, 0); - break; - case Q_FINVALIDATE: - case Q_QUOTAOFF: - cfs_down(&obt->obt_quotachecking); - if (oqctl->qc_cmd == Q_FINVALIDATE && - (obt->obt_qctxt.lqc_flags & UGQUOTA2LQC(oqctl->qc_type))) { - CWARN("quota[%u] is on yet\n", oqctl->qc_type); - cfs_up(&obt->obt_quotachecking); - rc = -EBUSY; - break; - } - oqctl->qc_id = obt->obt_qfmt; /* override qfmt version */ - case Q_GETOINFO: - case Q_GETOQUOTA: - case Q_GETQUOTA: - /* In recovery scenario, this pending dqacq/dqrel might have - * been processed by master successfully before it's dquot - * on master enter recovery mode. We must wait for this - * dqacq/dqrel done then return the correct limits to master */ - if (oqctl->qc_stat == QUOTA_RECOVERING) - handle = quota_barrier(&obd->u.obt.obt_qctxt, oqctl, 1); - - push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - rc = fsfilt_quotactl(obd, obt->obt_sb, oqctl); - pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - - if (oqctl->qc_stat == QUOTA_RECOVERING) - quota_unbarrier(handle); - - if (oqctl->qc_cmd == Q_QUOTAOFF || - oqctl->qc_cmd == Q_FINVALIDATE) { - if (oqctl->qc_cmd == Q_QUOTAOFF) { - if (!rc) - obt->obt_qctxt.lqc_flags &= - ~UGQUOTA2LQC(oqctl->qc_type); - else if (quota_is_off(qctxt, oqctl)) - rc = -EALREADY; - CDEBUG(D_QUOTA, "%s: quotaoff type:flags:rc " - "%u:%lu:%d\n", obd->obd_name, - oqctl->qc_type, qctxt->lqc_flags, rc); - } - cfs_up(&obt->obt_quotachecking); - } - - break; - case Q_SETQUOTA: - /* currently, it is only used for nullifying the quota */ - handle = quota_barrier(&obd->u.obt.obt_qctxt, oqctl, 1); - - push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - rc = fsfilt_quotactl(obd, obd->u.obt.obt_sb, oqctl); - - if (!rc) { - oqctl->qc_cmd = Q_SYNC; - fsfilt_quotactl(obd, obd->u.obt.obt_sb, oqctl); - oqctl->qc_cmd = Q_SETQUOTA; - } - pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - quota_unbarrier(handle); - - lqs = quota_search_lqs(LQS_KEY(oqctl->qc_type, oqctl->qc_id), - qctxt, 0); - if (lqs == NULL || IS_ERR(lqs)){ - CERROR("fail to create lqs during setquota operation " - "for %sid %u\n", oqctl->qc_type ? "g" : "u", - oqctl->qc_id); - } else { - lqs->lqs_flags &= ~QB_SET; - lqs_putref(lqs); - } - - break; - case Q_INITQUOTA: - { - unsigned int id[MAXQUOTAS] = { 0, 0 }; - - /* Initialize quota limit to MIN_QLIMIT */ - LASSERT(oqctl->qc_dqblk.dqb_valid == QIF_BLIMITS); - LASSERT(oqctl->qc_dqblk.dqb_bsoftlimit == 0); - - if (!oqctl->qc_dqblk.dqb_bhardlimit) - goto adjust; - - /* There might be a pending dqacq/dqrel (which is going to - * clear stale limits on slave). we should wait for it's - * completion then initialize limits */ - handle = quota_barrier(&obd->u.obt.obt_qctxt, oqctl, 1); - LASSERT(oqctl->qc_dqblk.dqb_bhardlimit == MIN_QLIMIT); - push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - rc = fsfilt_quotactl(obd, obd->u.obt.obt_sb, oqctl); - - /* Update on-disk quota, in case of lose the changed limits - * (MIN_QLIMIT) on crash, which cannot be recovered.*/ - if (!rc) { - oqctl->qc_cmd = Q_SYNC; - fsfilt_quotactl(obd, obd->u.obt.obt_sb, oqctl); - oqctl->qc_cmd = Q_INITQUOTA; - } - pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - quota_unbarrier(handle); - - if (rc) - RETURN(rc); -adjust: - lqs = quota_search_lqs(LQS_KEY(oqctl->qc_type, oqctl->qc_id), - qctxt, 1); - if (lqs == NULL || IS_ERR(lqs)){ - CERROR("fail to create lqs during setquota operation " - "for %sid %u\n", oqctl->qc_type ? "g" : "u", - oqctl->qc_id); - break; - } else { - lqs->lqs_flags |= QB_SET; - lqs_putref(lqs); - } - - /* Trigger qunit pre-acquire */ - if (oqctl->qc_type == USRQUOTA) - id[USRQUOTA] = oqctl->qc_id; - else - id[GRPQUOTA] = oqctl->qc_id; - - rc = qctxt_adjust_qunit(obd, &obd->u.obt.obt_qctxt, - id, 1, 0, NULL); - if (rc == -EDQUOT || rc == -EBUSY) { - CDEBUG(D_QUOTA, "rc: %d.\n", rc); - rc = 0; - } - - break; - } - default: - CERROR("%s: unsupported filter_quotactl command: %d\n", - obd->obd_name, oqctl->qc_cmd); - RETURN(-EFAULT); - } - cfs_gettimeofday(&work_end); - timediff = cfs_timeval_sub(&work_end, &work_start, NULL); - lprocfs_counter_add(qctxt->lqc_stats, LQUOTA_QUOTA_CTL, timediff); - - RETURN(rc); -} -#endif /* __KERNEL__ */ diff --git a/lustre/quota/quota_interface.c b/lustre/quota/quota_interface.c deleted file mode 100644 index abb258e..0000000 --- a/lustre/quota/quota_interface.c +++ /dev/null @@ -1,809 +0,0 @@ -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * GPL HEADER END - */ -/* - * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - * - * Copyright (c) 2011, 2012, Whamcloud, Inc. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - */ - -#define DEBUG_SUBSYSTEM S_LQUOTA - -#ifdef __KERNEL__ -# include -# include -# include -# include -# include -# include -# include -# include -#else /* __KERNEL__ */ -# include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include "quota_internal.h" - -#ifdef __KERNEL__ - -static cfs_time_t last_print = 0; -static DEFINE_SPINLOCK(last_print_lock); - -static int filter_quota_setup(struct obd_device *obd) -{ - int rc = 0; - struct obd_device_target *obt = &obd->u.obt; - ENTRY; - - cfs_init_rwsem(&obt->obt_rwsem); - obt->obt_qfmt = LUSTRE_QUOTA_V2; - cfs_sema_init(&obt->obt_quotachecking, 1); - rc = qctxt_init(obd, NULL); - if (rc) - CERROR("initialize quota context failed! (rc:%d)\n", rc); - - RETURN(rc); -} - -static int filter_quota_cleanup(struct obd_device *obd) -{ - ENTRY; - qctxt_cleanup(&obd->u.obt.obt_qctxt, 0); - RETURN(0); -} - -static int filter_quota_setinfo(struct obd_device *obd, void *data) -{ - struct obd_export *exp = data; - struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt; - struct obd_import *imp = exp->exp_imp_reverse; - ENTRY; - - LASSERT(imp != NULL); - - /* setup the quota context import */ - cfs_spin_lock(&qctxt->lqc_lock); - if (qctxt->lqc_import != NULL) { - cfs_spin_unlock(&qctxt->lqc_lock); - if (qctxt->lqc_import == imp) - CDEBUG(D_WARNING, "%s: lqc_import(%p) of obd(%p) was " - "activated already.\n", obd->obd_name, imp, obd); - else - CERROR("%s: lqc_import(%p:%p) of obd(%p) was " - "activated by others.\n", obd->obd_name, - qctxt->lqc_import, imp, obd); - } else { - qctxt->lqc_import = imp; - /* make imp's connect flags equal relative exp's connect flags - * adding it to avoid the scan export list */ - imp->imp_connect_data.ocd_connect_flags |= - (exp->exp_connect_flags & - (OBD_CONNECT_QUOTA64 | OBD_CONNECT_CHANGE_QS)); - cfs_spin_unlock(&qctxt->lqc_lock); - CDEBUG(D_QUOTA, "%s: lqc_import(%p) of obd(%p) is reactivated " - "now.\n", obd->obd_name, imp, obd); - - cfs_waitq_signal(&qctxt->lqc_wait_for_qmaster); - /* start quota slave recovery thread. (release high limits) */ - qslave_start_recovery(obd, qctxt); - } - RETURN(0); -} - -static int filter_quota_clearinfo(struct obd_export *exp, struct obd_device *obd) -{ - struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt; - struct obd_import *imp = exp->exp_imp_reverse; - ENTRY; - - /* lquota may be not set up before destroying export, b=14896 */ - if (!obd->obd_set_up) - RETURN(0); - - if (unlikely(imp == NULL)) - RETURN(0); - - /* when exp->exp_imp_reverse is destroyed, the corresponding lqc_import - * should be invalid b=12374 */ - cfs_spin_lock(&qctxt->lqc_lock); - if (qctxt->lqc_import == imp) { - qctxt->lqc_import = NULL; - cfs_spin_unlock(&qctxt->lqc_lock); - CDEBUG(D_QUOTA, "%s: lqc_import(%p) of obd(%p) is invalid now.\n", - obd->obd_name, imp, obd); - ptlrpc_cleanup_imp(imp); - dqacq_interrupt(qctxt); - } else { - cfs_spin_unlock(&qctxt->lqc_lock); - } - RETURN(0); -} - -static int filter_quota_enforce(struct obd_device *obd, unsigned int ignore) -{ - ENTRY; - - if (!sb_any_quota_loaded(obd->u.obt.obt_sb)) - RETURN(0); - - if (ignore) { - CDEBUG(D_QUOTA, "blocks will be written with ignoring quota.\n"); - cfs_cap_raise(CFS_CAP_SYS_RESOURCE); - } else { - cfs_cap_lower(CFS_CAP_SYS_RESOURCE); - } - - RETURN(0); -} - -#define GET_OA_ID(flag, oa) (flag == USRQUOTA ? oa->o_uid : oa->o_gid) -static int filter_quota_getflag(struct obd_device *obd, struct obdo *oa) -{ - struct obd_device_target *obt = &obd->u.obt; - struct lustre_quota_ctxt *qctxt = &obt->obt_qctxt; - int err, cnt, rc = 0; - struct obd_quotactl *oqctl; - ENTRY; - - if (!sb_any_quota_loaded(obt->obt_sb)) - RETURN(0); - - OBD_ALLOC_PTR(oqctl); - if (!oqctl) - RETURN(-ENOMEM); - - /* set over quota flags for a uid/gid */ - oa->o_valid |= OBD_MD_FLUSRQUOTA | OBD_MD_FLGRPQUOTA; - oa->o_flags &= ~(OBD_FL_NO_USRQUOTA | OBD_FL_NO_GRPQUOTA); - - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - struct lustre_qunit_size *lqs = NULL; - - /* check if quota is enabled */ - if (!sb_has_quota_active(obt->obt_sb, cnt)) - continue; - - lqs = quota_search_lqs(LQS_KEY(cnt, GET_OA_ID(cnt, oa)), - qctxt, 0); - if (IS_ERR(lqs)) { - rc = PTR_ERR(lqs); - CDEBUG(D_QUOTA, "search lqs for %s %d failed, " - "(rc = %d)\n", - cnt == USRQUOTA ? "user" : "group", - GET_OA_ID(cnt, oa), rc); - break; - } else if (lqs == NULL) { - /* continue to check group quota if the file's owner - * doesn't have quota limit. LU-530 */ - continue; - } else { - cfs_spin_lock(&lqs->lqs_lock); - if (lqs->lqs_bunit_sz <= qctxt->lqc_sync_blk) { - oa->o_flags |= (cnt == USRQUOTA) ? - OBD_FL_NO_USRQUOTA : OBD_FL_NO_GRPQUOTA; - cfs_spin_unlock(&lqs->lqs_lock); - CDEBUG(D_QUOTA, "set sync flag: bunit(%lu), " - "sync_blk(%d)\n", lqs->lqs_bunit_sz, - qctxt->lqc_sync_blk); - /* this is for quota_search_lqs */ - lqs_putref(lqs); - continue; - } - cfs_spin_unlock(&lqs->lqs_lock); - /* this is for quota_search_lqs */ - lqs_putref(lqs); - } - - memset(oqctl, 0, sizeof(*oqctl)); - - oqctl->qc_cmd = Q_GETQUOTA; - oqctl->qc_type = cnt; - oqctl->qc_id = (cnt == USRQUOTA) ? oa->o_uid : oa->o_gid; - err = fsfilt_quotactl(obd, obt->obt_sb, oqctl); - if (err) { - if (!rc) - rc = err; - oa->o_valid &= ~((cnt == USRQUOTA) ? OBD_MD_FLUSRQUOTA : - OBD_MD_FLGRPQUOTA); - CDEBUG(D_QUOTA, "fsfilt getquota for %s %d failed, " - "(rc = %d)\n", - cnt == USRQUOTA ? "user" : "group", - cnt == USRQUOTA ? oa->o_uid : oa->o_gid, err); - continue; - } - - if (oqctl->qc_dqblk.dqb_bhardlimit && - (toqb(oqctl->qc_dqblk.dqb_curspace) >= - oqctl->qc_dqblk.dqb_bhardlimit)) { - oa->o_flags |= (cnt == USRQUOTA) ? - OBD_FL_NO_USRQUOTA : OBD_FL_NO_GRPQUOTA; - CDEBUG(D_QUOTA, "out of quota for %s %d\n", - cnt == USRQUOTA ? "user" : "group", - cnt == USRQUOTA ? oa->o_uid : oa->o_gid); - } - } - OBD_FREE_PTR(oqctl); - RETURN(rc); -} - -/** - * check whether the left quota of certain uid and gid can satisfy a block_write - * or inode_create rpc. When need to acquire quota, return QUOTA_RET_ACQUOTA - */ -static int quota_check_common(struct obd_device *obd, const unsigned int id[], - int pending[], int count, int cycle, int isblk, - struct inode *inode, int frags) -{ - struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt; - int i; - struct qunit_data qdata[MAXQUOTAS]; - int mb = 0; - int rc = 0, rc2[2] = { 0, 0 }; - ENTRY; - - cfs_spin_lock(&qctxt->lqc_lock); - if (!qctxt->lqc_valid){ - cfs_spin_unlock(&qctxt->lqc_lock); - RETURN(rc); - } - cfs_spin_unlock(&qctxt->lqc_lock); - - for (i = 0; i < MAXQUOTAS; i++) { - struct lustre_qunit_size *lqs = NULL; - - qdata[i].qd_id = id[i]; - qdata[i].qd_flags = i; - if (isblk) - QDATA_SET_BLK(&qdata[i]); - qdata[i].qd_count = 0; - - /* check if quota is enabled */ - if (!sb_has_quota_active(qctxt->lqc_sb, i)) - continue; - - /* ignore root user */ - if (qdata[i].qd_id == 0 && !QDATA_IS_GRP(&qdata[i])) - continue; - - lqs = quota_search_lqs(LQS_KEY(i, id[i]), qctxt, 0); - if (lqs == NULL || IS_ERR(lqs)) - continue; - - if (IS_ERR(lqs)) { - CERROR("can not find lqs for check_common: " - "[id %u] [%c] [isblk %d] [count %d] [rc %ld]\n", - id[i], i % 2 ? 'g': 'u', isblk, count, - PTR_ERR(lqs)); - RETURN(PTR_ERR(lqs)); - } - - rc2[i] = compute_remquota(obd, qctxt, &qdata[i], isblk); - cfs_spin_lock(&lqs->lqs_lock); - if (!cycle) { - if (isblk) { - pending[i] = count * CFS_PAGE_SIZE; - /* in order to complete this write, we need extra - * meta blocks. This function can get it through - * data needed to be written b=16542 */ - if (inode) { - mb = pending[i]; - rc = fsfilt_get_mblk(obd, qctxt->lqc_sb, - &mb, inode, - frags); - if (rc) - CERROR("%s: can't get extra " - "meta blocks\n", - obd->obd_name); - else - pending[i] += mb; - } - LASSERTF(pending[i] >= 0, "pending is not valid" - ", count=%d, mb=%d\n", count, mb); - lqs->lqs_bwrite_pending += pending[i]; - } else { - pending[i] = count; - lqs->lqs_iwrite_pending += pending[i]; - } - } - - /* if xx_rec < 0, that means quota are releasing, - * and it may return before we use quota. So if - * we find this situation, we assuming it has - * returned b=18491 */ - if (isblk && lqs->lqs_blk_rec < 0) { - if (qdata[i].qd_count < -lqs->lqs_blk_rec) - qdata[i].qd_count = 0; - else - qdata[i].qd_count += lqs->lqs_blk_rec; - } - if (!isblk && lqs->lqs_ino_rec < 0) { - if (qdata[i].qd_count < -lqs->lqs_ino_rec) - qdata[i].qd_count = 0; - else - qdata[i].qd_count += lqs->lqs_ino_rec; - } - - CDEBUG(D_QUOTA, "[id %u] [%c] [isblk %d] [count %d]" - " [lqs pending: %lu] [qd_count: "LPU64"] [metablocks: %d]" - " [pending: %d]\n", id[i], i % 2 ? 'g': 'u', isblk, count, - isblk ? lqs->lqs_bwrite_pending : lqs->lqs_iwrite_pending, - qdata[i].qd_count, mb, pending[i]); - if (rc2[i] == QUOTA_RET_OK) { - if (isblk && qdata[i].qd_count < lqs->lqs_bwrite_pending) - rc2[i] = QUOTA_RET_ACQUOTA; - if (!isblk && qdata[i].qd_count < - lqs->lqs_iwrite_pending) - rc2[i] = QUOTA_RET_ACQUOTA; - } - - cfs_spin_unlock(&lqs->lqs_lock); - - if (lqs->lqs_blk_rec < 0 && - qdata[i].qd_count < - lqs->lqs_bwrite_pending - lqs->lqs_blk_rec - mb) - OBD_FAIL_TIMEOUT(OBD_FAIL_QUOTA_DELAY_REL, 5); - - /* When cycle is zero, lqs_*_pending will be changed. We will - * get reference of the lqs here and put reference of lqs in - * quota_pending_commit b=14784 */ - if (!cycle) - lqs_getref(lqs); - - /* this is for quota_search_lqs */ - lqs_putref(lqs); - } - - if (rc2[0] == QUOTA_RET_ACQUOTA || rc2[1] == QUOTA_RET_ACQUOTA) - RETURN(QUOTA_RET_ACQUOTA); - else - RETURN(rc); -} - -int quota_is_set(struct obd_device *obd, const unsigned int id[], int flag) -{ - struct lustre_qunit_size *lqs; - int i, q_set = 0; - - if (!sb_any_quota_loaded(obd->u.obt.obt_qctxt.lqc_sb)) - RETURN(0); - - for (i = 0; i < MAXQUOTAS; i++) { - /* check if quota is enabled */ - if (!sb_has_quota_active(obd->u.obt.obt_qctxt.lqc_sb, i)) - continue; - lqs = quota_search_lqs(LQS_KEY(i, id[i]), - &obd->u.obt.obt_qctxt, 0); - if (lqs && !IS_ERR(lqs)) { - if (lqs->lqs_flags & flag) - q_set = 1; - lqs_putref(lqs); - } - } - - return q_set; -} - -static int quota_chk_acq_common(struct obd_device *obd, struct obd_export *exp, - const unsigned int id[], int pending[], - int count, quota_acquire acquire, - struct obd_trans_info *oti, int isblk, - struct inode *inode, int frags) -{ - struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt; - struct timeval work_start; - struct timeval work_end; - long timediff; - struct l_wait_info lwi = { 0 }; - int rc = 0, cycle = 0, count_err = 1; - ENTRY; - - if (!quota_is_set(obd, id, isblk ? QB_SET : QI_SET)) - RETURN(0); - - if (isblk && (exp->exp_failed || exp->exp_abort_active_req)) - /* If the client has been evicted or if it - * timed out and tried to reconnect already, - * abort the request immediately */ - RETURN(-ENOTCONN); - - CDEBUG(D_QUOTA, "check quota for %s\n", obd->obd_name); - pending[USRQUOTA] = pending[GRPQUOTA] = 0; - /* Unfortunately, if quota master is too busy to handle the - * pre-dqacq in time and quota hash on ost is used up, we - * have to wait for the completion of in flight dqacq/dqrel, - * in order to get enough quota for write b=12588 */ - cfs_gettimeofday(&work_start); - while ((rc = quota_check_common(obd, id, pending, count, cycle, isblk, - inode, frags)) & - QUOTA_RET_ACQUOTA) { - struct ptlrpc_thread *thr = oti != NULL ? - oti->oti_thread : NULL; - - cfs_spin_lock(&qctxt->lqc_lock); - if (!qctxt->lqc_import && oti != NULL) { - cfs_spin_unlock(&qctxt->lqc_lock); - - LASSERT(thr != NULL); - /* The recovery thread doesn't have watchdog - * attached. LU-369 */ - if (thr->t_watchdog != NULL) - lc_watchdog_disable(thr->t_watchdog); - CDEBUG(D_QUOTA, "sleep for quota master\n"); - l_wait_event(qctxt->lqc_wait_for_qmaster, - check_qm(qctxt), &lwi); - - CDEBUG(D_QUOTA, "wake up when quota master is back\n"); - if (thr->t_watchdog != NULL) { - lc_watchdog_touch(thr->t_watchdog, - ptlrpc_server_get_timeout(thr->t_svcpt)); - } - } else { - cfs_spin_unlock(&qctxt->lqc_lock); - } - - cycle++; - if (isblk) - OBD_FAIL_TIMEOUT(OBD_FAIL_OST_HOLD_WRITE_RPC, 90); - /* after acquire(), we should run quota_check_common again - * so that we confirm there are enough quota to finish write */ - rc = acquire(obd, id, oti, isblk); - - /* please reference to dqacq_completion for the below */ - /* a new request is finished, try again */ - if (rc == QUOTA_REQ_RETURNED) { - CDEBUG(D_QUOTA, "finish a quota req, try again\n"); - continue; - } - - /* it is out of quota already */ - if (rc == -EDQUOT) { - CDEBUG(D_QUOTA, "out of quota, return -EDQUOT\n"); - break; - } - - /* Related quota has been disabled by master, but enabled by - * slave, do not try again. */ - if (unlikely(rc == -ESRCH)) { - CERROR("mismatched quota configuration, stop try.\n"); - break; - } - - if (isblk && (exp->exp_failed || exp->exp_abort_active_req)) - /* The client has been evicted or tried to - * to reconnect already, abort the request */ - RETURN(-ENOTCONN); - - /* -EBUSY and others, wait a second and try again */ - if (rc < 0) { - cfs_waitq_t waitq; - struct l_wait_info lwi; - - if (thr != NULL && thr->t_watchdog != NULL) - lc_watchdog_touch(thr->t_watchdog, - ptlrpc_server_get_timeout(thr->t_svcpt)); - CDEBUG(D_QUOTA, "rc: %d, count_err: %d\n", rc, - count_err++); - - cfs_waitq_init(&waitq); - lwi = LWI_TIMEOUT(cfs_time_seconds(min(cycle, 10)), NULL, - NULL); - l_wait_event(waitq, 0, &lwi); - } - - if (rc < 0 || cycle % 10 == 0) { - cfs_spin_lock(&last_print_lock); - if (last_print == 0 || - cfs_time_before((last_print + cfs_time_seconds(30)), - cfs_time_current())) { - last_print = cfs_time_current(); - cfs_spin_unlock(&last_print_lock); - CWARN("still haven't managed to acquire quota " - "space from the quota master after %d " - "retries (err=%d, rc=%d)\n", - cycle, count_err - 1, rc); - } else { - cfs_spin_unlock(&last_print_lock); - } - } - - CDEBUG(D_QUOTA, "recheck quota with rc: %d, cycle: %d\n", rc, - cycle); - } - cfs_gettimeofday(&work_end); - timediff = cfs_timeval_sub(&work_end, &work_start, NULL); - lprocfs_counter_add(qctxt->lqc_stats, - isblk ? LQUOTA_WAIT_FOR_CHK_BLK : - LQUOTA_WAIT_FOR_CHK_INO, - timediff); - - if (rc > 0) - rc = 0; - RETURN(rc); -} - -/** - * when a block_write or inode_create rpc is finished, adjust the record for - * pending blocks and inodes - */ -static int quota_pending_commit(struct obd_device *obd, const unsigned int id[], - int pending[], int isblk) -{ - struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt; - struct timeval work_start; - struct timeval work_end; - long timediff; - int i; - struct qunit_data qdata[MAXQUOTAS]; - ENTRY; - - CDEBUG(D_QUOTA, "commit pending quota for %s\n", obd->obd_name); - CLASSERT(MAXQUOTAS < 4); - if (!sb_any_quota_loaded(qctxt->lqc_sb)) - RETURN(0); - - cfs_gettimeofday(&work_start); - for (i = 0; i < MAXQUOTAS; i++) { - struct lustre_qunit_size *lqs = NULL; - - LASSERT(pending[i] >= 0); - if (pending[i] == 0) - continue; - - qdata[i].qd_id = id[i]; - qdata[i].qd_flags = i; - if (isblk) - QDATA_SET_BLK(&qdata[i]); - qdata[i].qd_count = 0; - - if (qdata[i].qd_id == 0 && !QDATA_IS_GRP(&qdata[i])) - continue; - - lqs = quota_search_lqs(LQS_KEY(i, qdata[i].qd_id), qctxt, 0); - if (lqs == NULL || IS_ERR(lqs)) { - CERROR("can not find lqs for pending_commit: " - "[id %u] [%c] [pending %u] [isblk %d] (rc %ld), " - "maybe cause unexpected lqs refcount error!\n", - id[i], i ? 'g': 'u', pending[i], isblk, - lqs ? PTR_ERR(lqs) : -1); - continue; - } - - cfs_spin_lock(&lqs->lqs_lock); - if (isblk) { - LASSERTF(lqs->lqs_bwrite_pending >= pending[i], - "there are too many blocks! [id %u] [%c] " - "[bwrite_pending %lu] [pending %u]\n", - id[i], i % 2 ? 'g' : 'u', - lqs->lqs_bwrite_pending, pending[i]); - - lqs->lqs_bwrite_pending -= pending[i]; - } else { - LASSERTF(lqs->lqs_iwrite_pending >= pending[i], - "there are too many files! [id %u] [%c] " - "[iwrite_pending %lu] [pending %u]\n", - id[i], i % 2 ? 'g' : 'u', - lqs->lqs_iwrite_pending, pending[i]); - - lqs->lqs_iwrite_pending -= pending[i]; - } - CDEBUG(D_QUOTA, "%s: lqs_pending=%lu pending[%d]=%d isblk=%d\n", - obd->obd_name, - isblk ? lqs->lqs_bwrite_pending : lqs->lqs_iwrite_pending, - i, pending[i], isblk); - cfs_spin_unlock(&lqs->lqs_lock); - - /* for quota_search_lqs in pending_commit */ - lqs_putref(lqs); - /* for quota_search_lqs in quota_check */ - lqs_putref(lqs); - } - cfs_gettimeofday(&work_end); - timediff = cfs_timeval_sub(&work_end, &work_start, NULL); - lprocfs_counter_add(qctxt->lqc_stats, - isblk ? LQUOTA_WAIT_FOR_COMMIT_BLK : - LQUOTA_WAIT_FOR_COMMIT_INO, - timediff); - - RETURN(0); -} - -static int mds_quota_init(void) -{ - return lustre_dquot_init(); -} - -static int mds_quota_exit(void) -{ - lustre_dquot_exit(); - return 0; -} - -static int mds_quota_setup(struct obd_device *obd) -{ - struct obd_device_target *obt = &obd->u.obt; - struct mds_obd *mds = &obd->u.mds; - int rc; - ENTRY; - - if (unlikely(mds->mds_quota)) { - CWARN("try to reinitialize quota context!\n"); - RETURN(0); - } - - cfs_init_rwsem(&obt->obt_rwsem); - obt->obt_qfmt = LUSTRE_QUOTA_V2; - mds->mds_quota_info.qi_version = LUSTRE_QUOTA_V2; - cfs_sema_init(&obt->obt_quotachecking, 1); - /* initialize quota master and quota context */ - cfs_init_rwsem(&mds->mds_qonoff_sem); - rc = qctxt_init(obd, dqacq_handler); - if (rc) { - CERROR("%s: initialize quota context failed! (rc:%d)\n", - obd->obd_name, rc); - RETURN(rc); - } - mds->mds_quota = 1; - RETURN(rc); -} - -static int mds_quota_cleanup(struct obd_device *obd) -{ - ENTRY; - if (unlikely(!obd->u.mds.mds_quota)) - RETURN(0); - - qctxt_cleanup(&obd->u.obt.obt_qctxt, 0); - RETURN(0); -} - -static int mds_quota_setinfo(struct obd_device *obd, void *data) -{ - struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt; - ENTRY; - - if (unlikely(!obd->u.mds.mds_quota)) - RETURN(0); - - if (data != NULL) - QUOTA_MASTER_READY(qctxt); - else - QUOTA_MASTER_UNREADY(qctxt); - RETURN(0); -} - -static int mds_quota_fs_cleanup(struct obd_device *obd) -{ - struct mds_obd *mds = &obd->u.mds; - struct obd_quotactl oqctl; - ENTRY; - - if (unlikely(!mds->mds_quota)) - RETURN(0); - - mds->mds_quota = 0; - memset(&oqctl, 0, sizeof(oqctl)); - oqctl.qc_type = UGQUOTA; - - cfs_down_write(&mds->mds_qonoff_sem); - mds_admin_quota_off(obd, &oqctl); - cfs_up_write(&mds->mds_qonoff_sem); - RETURN(0); -} - -static int quota_acquire_common(struct obd_device *obd, const unsigned int id[], - struct obd_trans_info *oti, int isblk) -{ - struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt; - int rc; - ENTRY; - - rc = qctxt_adjust_qunit(obd, qctxt, id, isblk, 1, oti); - RETURN(rc); -} - -quota_interface_t mds_quota_interface = { - .quota_init = mds_quota_init, - .quota_exit = mds_quota_exit, - .quota_setup = mds_quota_setup, - .quota_cleanup = mds_quota_cleanup, - .quota_check = target_quota_check, - .quota_ctl = mds_quota_ctl, - .quota_setinfo = mds_quota_setinfo, - .quota_fs_cleanup = mds_quota_fs_cleanup, - .quota_recovery = mds_quota_recovery, - .quota_adjust = mds_quota_adjust, - .quota_chkquota = quota_chk_acq_common, - .quota_acquire = quota_acquire_common, - .quota_pending_commit = quota_pending_commit, -}; - -quota_interface_t filter_quota_interface = { - .quota_setup = filter_quota_setup, - .quota_cleanup = filter_quota_cleanup, - .quota_check = target_quota_check, - .quota_ctl = filter_quota_ctl, - .quota_setinfo = filter_quota_setinfo, - .quota_clearinfo = filter_quota_clearinfo, - .quota_enforce = filter_quota_enforce, - .quota_getflag = filter_quota_getflag, - .quota_acquire = quota_acquire_common, - .quota_adjust = filter_quota_adjust, - .quota_chkquota = quota_chk_acq_common, - .quota_adjust_qunit = filter_quota_adjust_qunit, - .quota_pending_commit = quota_pending_commit, -}; - -cfs_proc_dir_entry_t *lquota_type_proc_dir = NULL; - -int init_lustre_quota(void) -{ - int rc = 0; - - lquota_type_proc_dir = lprocfs_register(OBD_LQUOTA_DEVICENAME, - proc_lustre_root, - NULL, NULL); - if (IS_ERR(lquota_type_proc_dir)) { - CERROR("LProcFS failed in lquota-init\n"); - rc = PTR_ERR(lquota_type_proc_dir); - return rc; - } - - rc = qunit_cache_init(); - if (rc) - return rc; - - PORTAL_SYMBOL_REGISTER(filter_quota_interface); - PORTAL_SYMBOL_REGISTER(mds_quota_interface); - - return 0; -} - -void exit_lustre_quota(void) -{ - PORTAL_SYMBOL_UNREGISTER(filter_quota_interface); - PORTAL_SYMBOL_UNREGISTER(mds_quota_interface); - - qunit_cache_cleanup(); - - if (lquota_type_proc_dir) - lprocfs_remove(&lquota_type_proc_dir); -} - -EXPORT_SYMBOL(mds_quota_interface); -EXPORT_SYMBOL(filter_quota_interface); -#endif /* __KERNEL */ diff --git a/lustre/quota/quota_internal.h b/lustre/quota/quota_internal.h deleted file mode 100644 index 002300e..0000000 --- a/lustre/quota/quota_internal.h +++ /dev/null @@ -1,192 +0,0 @@ -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * GPL HEADER END - */ -/* - * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - */ - -#ifndef __QUOTA_INTERNAL_H -#define __QUOTA_INTERNAL_H - -#include - -/* QUSG covnert bytes to blocks when counting block quota */ -#define QUSG(count, isblk) (isblk ? toqb(count) : count) - -/* This flag is set in qc_stat to distinguish if the current getquota - * operation is for quota recovery */ -#define QUOTA_RECOVERING 0x01 -#define OBD_LQUOTA_DEVICENAME "lquota" - -#ifdef __KERNEL__ - -#define DQUOT_DEBUG(dquot, fmt, arg...) \ - CDEBUG(D_QUOTA, "refcnt(%u) id(%u) type(%u) off(%llu) flags(%lu) " \ - "bhardlimit("LPU64") curspace("LPU64") ihardlimit("LPU64") " \ - "curinodes("LPU64"): " fmt, cfs_atomic_read(&dquot->dq_refcnt),\ - dquot->dq_id, dquot->dq_type, dquot->dq_off, dquot->dq_flags, \ - dquot->dq_dqb.dqb_bhardlimit, dquot->dq_dqb.dqb_curspace, \ - dquot->dq_dqb.dqb_ihardlimit, dquot->dq_dqb.dqb_curinodes, \ - ## arg); \ - -#define QINFO_DEBUG(qinfo, fmt, arg...) \ - CDEBUG(D_QUOTA, "files (%p/%p) flags(%lu/%lu) blocks(%u/%u) " \ - "free_blk(/%u/%u) free_entry(%u/%u): " fmt, \ - qinfo->qi_files[0], qinfo->qi_files[1], \ - qinfo->qi_info[0].dqi_flags, qinfo->qi_info[1].dqi_flags, \ - qinfo->qi_info[0].dqi_blocks, qinfo->qi_info[1].dqi_blocks, \ - qinfo->qi_info[0].dqi_free_blk, qinfo->qi_info[1].dqi_free_blk,\ - qinfo->qi_info[0].dqi_free_entry, \ - qinfo->qi_info[1].dqi_free_entry, ## arg); - -#define QDATA_DEBUG(qd, fmt, arg...) \ - CDEBUG(D_QUOTA, "id(%u) flag(%u) type(%c) isblk(%c) count("LPU64") " \ - "qd_qunit("LPU64"): " fmt, qd->qd_id, qd->qd_flags, \ - QDATA_IS_GRP(qd) ? 'g' : 'u', QDATA_IS_BLK(qd) ? 'b': 'i', \ - qd->qd_count, \ - (QDATA_IS_ADJBLK(qd) | QDATA_IS_ADJINO(qd)) ? qd->qd_qunit : 0,\ - ## arg); - -#define QAQ_DEBUG(qaq, fmt, arg...) \ - CDEBUG(D_QUOTA, "id(%u) flag(%u) type(%c) bunit("LPU64") " \ - "iunit("LPU64"): " fmt, qaq->qaq_id, qaq->qaq_flags, \ - QAQ_IS_GRP(qaq) ? 'g': 'u', qaq->qaq_bunit_sz, \ - qaq->qaq_iunit_sz, ## arg); - -#define LQS_DEBUG(lqs, fmt, arg...) \ - CDEBUG(D_QUOTA, "lqs(%p) id(%u) flag(%lu) type(%c) bunit(%lu) " \ - "btune(%lu) iunit(%lu) itune(%lu) lqs_bwrite_pending(%lu) " \ - "lqs_iwrite_pending(%lu) ino_rec(%lld) blk_rec(%lld) " \ - "refcount(%d): " \ - fmt, lqs, lqs->lqs_id, lqs->lqs_flags, \ - LQS_IS_GRP(lqs) ? 'g' : 'u', \ - lqs->lqs_bunit_sz, lqs->lqs_btune_sz, lqs->lqs_iunit_sz, \ - lqs->lqs_itune_sz, lqs->lqs_bwrite_pending, \ - lqs->lqs_iwrite_pending, lqs->lqs_ino_rec, \ - lqs->lqs_blk_rec, cfs_atomic_read(&lqs->lqs_refcount), ## arg); - - -/* quota_context.c */ -void qunit_cache_cleanup(void); -int qunit_cache_init(void); -int qctxt_adjust_qunit(struct obd_device *obd, struct lustre_quota_ctxt *qctxt, - const unsigned int id[], __u32 isblk, int wait, - struct obd_trans_info *oti); -int qctxt_wait_pending_dqacq(struct lustre_quota_ctxt *qctxt, unsigned int id, - unsigned short type, int isblk); -int qctxt_init(struct obd_device *obd, dqacq_handler_t handler); -void qctxt_cleanup(struct lustre_quota_ctxt *qctxt, int force); -void qslave_start_recovery(struct obd_device *obd, - struct lustre_quota_ctxt *qctxt); -int compute_remquota(struct obd_device *obd, - struct lustre_quota_ctxt *qctxt, struct qunit_data *qdata, - int isblk); -int check_qm(struct lustre_quota_ctxt *qctxt); -void dqacq_interrupt(struct lustre_quota_ctxt *qctxt); -int quota_is_on(struct lustre_quota_ctxt *qctxt, struct obd_quotactl *oqctl); -int quota_is_off(struct lustre_quota_ctxt *qctxt, struct obd_quotactl *oqctl); -void* quota_barrier(struct lustre_quota_ctxt *qctxt, - struct obd_quotactl *oqctl, int isblk); -void quota_unbarrier(void *handle); -/* quota_master.c */ -int lustre_dquot_init(void); -void lustre_dquot_exit(void); -int dqacq_handler(struct obd_device *obd, struct qunit_data *qdata, int opc); -int mds_quota_adjust(struct obd_device *obd, const unsigned int qcids[], - const unsigned int qpids[], int rc, int opc); -int filter_quota_adjust(struct obd_device *obd, const unsigned int qcids[], - const unsigned int qpids[], int rc, int opc); -int init_admin_quotafiles(struct obd_device *obd, struct obd_quotactl *oqctl); -int mds_quota_get_version(struct obd_device *obd, lustre_quota_version_t *ver); -int mds_quota_invalidate(struct obd_device *obd, struct obd_quotactl *oqctl); -int mds_quota_finvalidate(struct obd_device *obd, struct obd_quotactl *oqctl); - -int mds_admin_quota_on(struct obd_device *obd, struct obd_quotactl *oqctl); -int mds_quota_on(struct obd_device *obd, struct obd_quotactl *oqctl); -int mds_quota_off(struct obd_device *obd, struct obd_quotactl *oqctl); -int do_mds_quota_off(struct obd_device *obd, struct obd_quotactl *oqctl); -int mds_admin_quota_off(struct obd_device *obd, struct obd_quotactl *oqctl); -int mds_set_dqinfo(struct obd_device *obd, struct obd_quotactl *oqctl); -int mds_get_dqinfo(struct obd_device *obd, struct obd_quotactl *oqctl); -int mds_set_dqblk(struct obd_device *obd, struct obd_quotactl *oqctl); -int mds_get_dqblk(struct obd_device *obd, struct obd_quotactl *oqctl); -int mds_quota_recovery(struct obd_device *obd); -int mds_get_obd_quota(struct obd_device *obd, struct obd_quotactl *oqctl); -int dquot_create_oqaq(struct lustre_quota_ctxt *qctxt, struct lustre_dquot - *dquot, __u32 ost_num, __u32 mdt_num, int type, - struct quota_adjust_qunit *oqaq); -int generic_quota_on(struct obd_device *, struct obd_quotactl *, int); -#endif - -/* quota_ctl.c */ -int mds_quota_ctl(struct obd_device *obd, struct obd_export *exp, - struct obd_quotactl *oqctl); -int filter_quota_ctl(struct obd_device *unused, struct obd_export *exp, - struct obd_quotactl *oqctl); - -/* quota_chk.c */ -int target_quota_check(struct obd_device *obd, struct obd_export *exp, - struct obd_quotactl *oqctl); - -int quota_adjust_slave_lqs(struct quota_adjust_qunit *oqaq, struct - lustre_quota_ctxt *qctxt); -#ifdef __KERNEL__ -int quota_is_set(struct obd_device *obd, const unsigned int id[], int flag); -struct lustre_qunit_size *quota_search_lqs(unsigned long long lqs_key, - struct lustre_quota_ctxt *qctxt, - int create); -void quota_compute_lqs(struct qunit_data *qdata, struct lustre_qunit_size *lqs, - int is_chk, int is_acq); - - -extern int quote_get_qdata(struct ptlrpc_request *req, struct qunit_data *qdata, - int is_req, int is_exp); -extern int quote_copy_qdata(struct ptlrpc_request *req, struct qunit_data *qdata, - int is_req, int is_exp); -int filter_quota_adjust_qunit(struct obd_export *exp, - struct quota_adjust_qunit *oqaq, - struct lustre_quota_ctxt *qctxt, - struct ptlrpc_request_set *rqset); -int lquota_proc_setup(struct obd_device *obd, int is_master); -int lquota_proc_cleanup(struct lustre_quota_ctxt *qctxt); -void build_lqs(struct obd_device *obd); - -extern cfs_proc_dir_entry_t *lquota_type_proc_dir; -#endif - -#define LQS_BLK_DECREASE 1 -#define LQS_BLK_INCREASE 2 -#define LQS_INO_DECREASE 4 -#define LQS_INO_INCREASE 8 - -/* the return status of quota operation */ -#define QUOTA_REQ_RETURNED 1 - -#endif diff --git a/lustre/quota/quota_master.c b/lustre/quota/quota_master.c deleted file mode 100644 index 59adaa5..0000000 --- a/lustre/quota/quota_master.c +++ /dev/null @@ -1,1766 +0,0 @@ -/* - * GPL HEADER START - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 only, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License version 2 for more details (a copy is included - * in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU General Public License - * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - * GPL HEADER END - */ -/* - * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. - * Use is subject to license terms. - * - * Copyright (c) 2011, 2012, Whamcloud, Inc. - */ -/* - * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. - * - * lustre/quota/quota_master.c - * - * Lustre Quota Master request handler - * - * Author: Niu YaWei - */ - -#define DEBUG_SUBSYSTEM S_LQUOTA - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "quota_internal.h" - -/* lock ordering: mds->mds_qonoff_sem > dquot->dq_mutex > lqs->lqs_lock */ -static cfs_list_t lustre_dquot_hash[NR_DQHASH]; -static DEFINE_RWLOCK(dquot_hash_lock); - -cfs_mem_cache_t *lustre_dquot_cachep; - -int lustre_dquot_init(void) -{ - int i; - ENTRY; - - LASSERT(lustre_dquot_cachep == NULL); - lustre_dquot_cachep = cfs_mem_cache_create("lustre_dquot_cache", - sizeof(struct lustre_dquot), - 0, 0); - if (!lustre_dquot_cachep) - return (-ENOMEM); - - for (i = 0; i < NR_DQHASH; i++) { - CFS_INIT_LIST_HEAD(lustre_dquot_hash + i); - } - RETURN(0); -} - -void lustre_dquot_exit(void) -{ - int i; - ENTRY; - /* FIXME cleanup work ?? */ - - for (i = 0; i < NR_DQHASH; i++) { - LASSERT(cfs_list_empty(lustre_dquot_hash + i)); - } - if (lustre_dquot_cachep) { - int rc; - rc = cfs_mem_cache_destroy(lustre_dquot_cachep); - LASSERTF(rc == 0,"couldn't destroy lustre_dquot_cachep slab\n"); - lustre_dquot_cachep = NULL; - } - EXIT; -} - -static inline int -dquot_hashfn(struct lustre_quota_info *info, unsigned int id, int type) - __attribute__((__const__)); - -static inline int -dquot_hashfn(struct lustre_quota_info *info, unsigned int id, int type) -{ - unsigned long tmp = ((unsigned long)info >> L1_CACHE_SHIFT) ^ id; - tmp = (tmp * (MAXQUOTAS - type)) % NR_DQHASH; - return tmp; -} - -/* caller must hold dquot_hash_lock */ -static struct lustre_dquot *find_dquot(int hashent, - struct lustre_quota_info *lqi, qid_t id, - int type) -{ - struct lustre_dquot *dquot; - ENTRY; - - cfs_list_for_each_entry(dquot, &lustre_dquot_hash[hashent], dq_hash) { - if (dquot->dq_info == lqi && - dquot->dq_id == id && dquot->dq_type == type) - RETURN(dquot); - } - RETURN(NULL); -} - -static struct lustre_dquot *alloc_dquot(struct lustre_quota_info *lqi, - qid_t id, int type) -{ - struct lustre_dquot *dquot = NULL; - ENTRY; - - OBD_SLAB_ALLOC_PTR_GFP(dquot, lustre_dquot_cachep, CFS_ALLOC_IO); - if (dquot == NULL) - RETURN(NULL); - - CFS_INIT_LIST_HEAD(&dquot->dq_hash); - cfs_mutex_init(&dquot->dq_mutex); - cfs_mutex_lock(&dquot->dq_mutex); - cfs_atomic_set(&dquot->dq_refcnt, 1); - dquot->dq_info = lqi; - dquot->dq_id = id; - dquot->dq_type = type; - - RETURN(dquot); -} - -static void free_dquot(struct lustre_dquot *dquot) -{ - OBD_SLAB_FREE(dquot, lustre_dquot_cachep, sizeof(*dquot)); -} - -static void insert_dquot_nolock(struct lustre_dquot *dquot) -{ - cfs_list_t *head = lustre_dquot_hash + - dquot_hashfn(dquot->dq_info, dquot->dq_id, dquot->dq_type); - LASSERT(cfs_list_empty(&dquot->dq_hash)); - cfs_list_add(&dquot->dq_hash, head); -} - -static void remove_dquot_nolock(struct lustre_dquot *dquot) -{ - LASSERT(!cfs_list_empty(&dquot->dq_hash)); - cfs_list_del_init(&dquot->dq_hash); -} - -static void lustre_dqput(struct lustre_dquot *dquot) -{ - ENTRY; - cfs_write_lock(&dquot_hash_lock); - LASSERT(cfs_atomic_read(&dquot->dq_refcnt)); - cfs_atomic_dec(&dquot->dq_refcnt); - if (cfs_atomic_read(&dquot->dq_refcnt) == 0) { - remove_dquot_nolock(dquot); - free_dquot(dquot); - } - cfs_write_unlock(&dquot_hash_lock); - EXIT; -} - -static struct lustre_dquot *lustre_dqget(struct obd_device *obd, - struct lustre_quota_info *lqi, - qid_t id, int type, int can_fake) -{ - unsigned int hashent = dquot_hashfn(lqi, id, type); - struct lustre_dquot *dquot, *empty; - int free_dq = 0; - ENTRY; - - if ((empty = alloc_dquot(lqi, id, type)) == NULL) - RETURN(ERR_PTR(-ENOMEM)); - - cfs_read_lock(&dquot_hash_lock); - if ((dquot = find_dquot(hashent, lqi, id, type)) != NULL) { - cfs_atomic_inc(&dquot->dq_refcnt); - cfs_read_unlock(&dquot_hash_lock); - cfs_mutex_unlock(&empty->dq_mutex); - free_dq = 1; - } else { - int rc; - - cfs_read_unlock(&dquot_hash_lock); - - dquot = empty; - rc = fsfilt_dquot(obd, dquot, QFILE_RD_DQUOT); - cfs_mutex_unlock(&dquot->dq_mutex); - if (rc) { - CERROR("can't read dquot from admin quotafile! " - "(rc:%d)\n", rc); - free_dquot(dquot); - RETURN(ERR_PTR(rc)); - } else { - cfs_write_lock(&dquot_hash_lock); - if ((dquot = find_dquot(hashent, lqi, id, type)) != NULL) { - cfs_atomic_inc(&dquot->dq_refcnt); - free_dq = 1; - } else { - dquot = empty; - insert_dquot_nolock(dquot); - } - cfs_write_unlock(&dquot_hash_lock); - } - - } - - LASSERT(dquot); - if (!can_fake && cfs_test_bit(DQ_FAKE_B, &dquot->dq_flags)) { - DQUOT_DEBUG(dquot, "It is a fake dquot: unexpected!\n"); - lustre_dqput(dquot); - dquot = ERR_PTR(-ENOENT); - } - - if (free_dq) - free_dquot(empty); - - - RETURN(dquot); -} - -static void init_oqaq(struct quota_adjust_qunit *oqaq, - struct lustre_quota_ctxt *qctxt, - qid_t id, int type) -{ - struct lustre_qunit_size *lqs = NULL; - - oqaq->qaq_id = id; - oqaq->qaq_flags = type; - lqs = quota_search_lqs(LQS_KEY(type, id), qctxt, 0); - if (lqs && !IS_ERR(lqs)) { - cfs_spin_lock(&lqs->lqs_lock); - oqaq->qaq_bunit_sz = lqs->lqs_bunit_sz; - oqaq->qaq_iunit_sz = lqs->lqs_iunit_sz; - oqaq->qaq_flags = lqs->lqs_flags; - cfs_spin_unlock(&lqs->lqs_lock); - lqs_putref(lqs); - } else { - CDEBUG(D_QUOTA, "Can't find the lustre qunit size!\n"); - oqaq->qaq_bunit_sz = qctxt->lqc_bunit_sz; - oqaq->qaq_iunit_sz = qctxt->lqc_iunit_sz; - } -} - -int dqacq_adjust_qunit_sz(struct obd_device *obd, qid_t id, int type, - __u32 is_blk) -{ - struct mds_obd *mds = &obd->u.mds; - struct lustre_quota_ctxt *qctxt = &mds->mds_obt.obt_qctxt; - __u32 ost_num = mds->mds_lov_objid_count, mdt_num = 1; - struct quota_adjust_qunit *oqaq = NULL; - unsigned int qid[MAXQUOTAS] = { 0, 0 }; - struct lustre_quota_info *info = &mds->mds_quota_info; - struct lustre_dquot *dquot = NULL; - int adjust_res = 0; - int rc = 0; - ENTRY; - - LASSERT(mds); - cfs_down_read(&mds->mds_qonoff_sem); - dquot = lustre_dqget(obd, info, id, type, 0); - if (IS_ERR(dquot)) - RETURN(PTR_ERR(dquot)); - - cfs_up_read(&mds->mds_qonoff_sem); - OBD_ALLOC_PTR(oqaq); - if (!oqaq) - GOTO(out, rc = -ENOMEM); - - cfs_mutex_lock(&dquot->dq_mutex); - init_oqaq(oqaq, qctxt, id, type); - - rc = dquot_create_oqaq(qctxt, dquot, ost_num, mdt_num, - is_blk ? LQUOTA_FLAGS_ADJBLK : - LQUOTA_FLAGS_ADJINO, oqaq); - - if (rc < 0) { - CERROR("create oqaq failed! (rc:%d)\n", rc); - GOTO(out_sem, rc); - } - QAQ_DEBUG(oqaq, "show oqaq.\n") - - if (!QAQ_IS_ADJBLK(oqaq) && !QAQ_IS_ADJINO(oqaq)) - GOTO(out_sem, rc); - - /* adjust the mds slave qunit size */ - adjust_res = quota_adjust_slave_lqs(oqaq, qctxt); - if (adjust_res <= 0) { - if (adjust_res < 0) { - rc = adjust_res; - CERROR("adjust mds slave's qunit size failed! " - "(rc:%d)\n", rc); - } else { - CDEBUG(D_QUOTA, "qunit doesn't need to be adjusted.\n"); - } - GOTO(out_sem, rc); - } - - if (type) - qid[GRPQUOTA] = dquot->dq_id; - else - qid[USRQUOTA] = dquot->dq_id; - - cfs_mutex_unlock(&dquot->dq_mutex); - - rc = qctxt_adjust_qunit(obd, qctxt, qid, is_blk, 0, NULL); - if (rc == -EDQUOT || rc == -EBUSY) { - CDEBUG(D_QUOTA, "rc: %d.\n", rc); - rc = 0; - } - if (rc) { - CERROR("%s: mds fail to adjust file quota! (rc:%d)\n", - obd->obd_name, rc); - GOTO(out, rc); - } - - /* only when block qunit is reduced, boardcast to osts */ - if ((adjust_res & LQS_BLK_DECREASE) && QAQ_IS_ADJBLK(oqaq)) - rc = obd_quota_adjust_qunit(mds->mds_lov_exp, oqaq, qctxt, NULL); - -out: - lustre_dqput(dquot); - if (oqaq) - OBD_FREE_PTR(oqaq); - - RETURN(rc); -out_sem: - cfs_mutex_unlock(&dquot->dq_mutex); - goto out; -} - -int dqacq_handler(struct obd_device *obd, struct qunit_data *qdata, int opc) -{ - struct mds_obd *mds = &obd->u.mds; - struct lustre_quota_ctxt *qctxt = &mds->mds_obt.obt_qctxt; - struct lustre_quota_info *info = &mds->mds_quota_info; - struct lustre_dquot *dquot = NULL; - __u64 *usage = NULL; - __u64 hlimit = 0, slimit = 0; - time_t *time = NULL; - unsigned int grace = 0; - struct lustre_qunit_size *lqs = NULL; - int rc = 0; - ENTRY; - - if (OBD_FAIL_CHECK(OBD_FAIL_OBD_DQACQ)) - RETURN(-EIO); - - if (!sb_has_quota_active(qctxt->lqc_sb, - QDATA_IS_GRP(qdata) ? GRPQUOTA : USRQUOTA)) - RETURN(-EIO); - - lqs = quota_search_lqs(LQS_KEY(QDATA_IS_GRP(qdata), qdata->qd_id), - qctxt, 0); - if (lqs == NULL) - rc = -ENOENT; - if (IS_ERR(lqs)) - rc = PTR_ERR(lqs); - if (rc) - RETURN(rc); - - cfs_spin_lock(&lqs->lqs_lock); - if (LQS_IS_RECOVERY(lqs)) { - cfs_spin_unlock(&lqs->lqs_lock); - LQS_DEBUG(lqs, "this lqs is under recovery\n"); - GOTO(skip, rc = -EBUSY); - } - cfs_spin_unlock(&lqs->lqs_lock); - - cfs_down_write(&mds->mds_qonoff_sem); - dquot = lustre_dqget(obd, info, qdata->qd_id, QDATA_IS_GRP(qdata), 0); - if (IS_ERR(dquot)) { - cfs_up_write(&mds->mds_qonoff_sem); - GOTO(skip, rc = PTR_ERR(dquot)); - } - - DQUOT_DEBUG(dquot, "get dquot in dqacq_handler\n"); - QINFO_DEBUG(dquot->dq_info, "get dquot in dqadq_handler\n"); - - cfs_mutex_lock(&dquot->dq_mutex); - - if (QDATA_IS_BLK(qdata)) { - grace = info->qi_info[QDATA_IS_GRP(qdata)].dqi_bgrace; - usage = &dquot->dq_dqb.dqb_curspace; - hlimit = dquot->dq_dqb.dqb_bhardlimit; - slimit = dquot->dq_dqb.dqb_bsoftlimit; - time = &dquot->dq_dqb.dqb_btime; - } else { - grace = info->qi_info[QDATA_IS_GRP(qdata)].dqi_igrace; - usage = (__u64 *) & dquot->dq_dqb.dqb_curinodes; - hlimit = dquot->dq_dqb.dqb_ihardlimit; - slimit = dquot->dq_dqb.dqb_isoftlimit; - time = &dquot->dq_dqb.dqb_itime; - } - - /* if the quota limit in admin quotafile is zero, we just inform - * slave to clear quota limit with zero qd_count */ - if (hlimit == 0 && slimit == 0) { - qdata->qd_count = 0; - GOTO(out, rc); - } - - switch (opc) { - case QUOTA_DQACQ: - if (hlimit && - QUSG(*usage + qdata->qd_count, QDATA_IS_BLK(qdata)) > hlimit) - { - if (QDATA_IS_CHANGE_QS(qdata) && - QUSG(*usage, QDATA_IS_BLK(qdata)) < hlimit) - qdata->qd_count = (hlimit - - QUSG(*usage, QDATA_IS_BLK(qdata))) - * (QDATA_IS_BLK(qdata) ? - QUOTABLOCK_SIZE : 1); - else - GOTO(out, rc = -EDQUOT); - } - - if (slimit && - QUSG(*usage + qdata->qd_count, QDATA_IS_BLK(qdata)) > slimit) { - if (*time && cfs_time_current_sec() >= *time) - GOTO(out, rc = -EDQUOT); - else if (!*time) - *time = cfs_time_current_sec() + grace; - } - - *usage += qdata->qd_count; - break; - case QUOTA_DQREL: - /* The usage in administrative file might be incorrect before - * recovery done */ - if (*usage < qdata->qd_count) - *usage = 0; - else - *usage -= qdata->qd_count; - - /* (usage <= soft limit) but not (usage < soft limit) */ - if (!slimit || QUSG(*usage, QDATA_IS_BLK(qdata)) <= slimit) - *time = 0; - break; - default: - LBUG(); - } - - rc = fsfilt_dquot(obd, dquot, QFILE_WR_DQUOT); - EXIT; -out: - cfs_mutex_unlock(&dquot->dq_mutex); - cfs_up_write(&mds->mds_qonoff_sem); - lustre_dqput(dquot); - if (rc != -EDQUOT) - dqacq_adjust_qunit_sz(obd, qdata->qd_id, QDATA_IS_GRP(qdata), - QDATA_IS_BLK(qdata)); - - cfs_spin_lock(&lqs->lqs_lock); - qdata->qd_qunit = QDATA_IS_BLK(qdata) ? lqs->lqs_bunit_sz : - lqs->lqs_iunit_sz; - cfs_spin_unlock(&lqs->lqs_lock); - - if (QDATA_IS_BLK(qdata)) - QDATA_SET_ADJBLK(qdata); - else - QDATA_SET_ADJINO(qdata); - - QDATA_DEBUG(qdata, "alloc/release qunit in dqacq_handler\n"); -skip: - lqs_putref(lqs); - - return rc; -} - -int mds_quota_adjust(struct obd_device *obd, const unsigned int qcids[], - const unsigned int qpids[], int rc, int opc) -{ - struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt; - int rc2 = 0; - ENTRY; - - if (rc && rc != -EDQUOT && rc != ENOLCK) - RETURN(0); - - switch (opc) { - case FSFILT_OP_SETATTR: - /* release file quota on original owner */ - rc2 |= qctxt_adjust_qunit(obd, qctxt, qpids, 0, 0, NULL); - /* release block quota on original owner */ - rc2 |= qctxt_adjust_qunit(obd, qctxt, qpids, 1, 0, NULL); - /* acquire file quota on current owner */ - rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids, 0, 0, NULL); - /* acquire block quota on current owner */ - rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids, 1, 0, NULL); - break; - case FSFILT_OP_UNLINK_PARTIAL_CHILD: - /* release file quota on child */ - rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids, 0, 0, NULL); - /* rlease block quota on child */ - rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids, 1, 0, NULL); - break; - case FSFILT_OP_CREATE_PARTIAL_CHILD: - /* acquire file quota on child */ - rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids, 0, 0, NULL); - /* acquire block quota on child */ - rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids, 1, 0, NULL); - break; - case FSFILT_OP_LINK: - /* acquire block quota on parent */ - rc2 |= qctxt_adjust_qunit(obd, qctxt, qpids, 1, 0, NULL); - break; - case FSFILT_OP_UNLINK: - /* release block quota on parent */ - rc2 |= qctxt_adjust_qunit(obd, qctxt, qpids, 1, 0, NULL); - /* release file quota on child */ - rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids, 0, 0, NULL); - if (qpids[0] != qcids[0] || qpids[1] != qcids[1]) - /* release block quota on child */ - rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids, 1, 0, - NULL); - break; - case FSFILT_OP_UNLINK_PARTIAL_PARENT: - /* release block quota on parent */ - rc2 |= qctxt_adjust_qunit(obd, qctxt, qpids, 1, 0, NULL); - break; - case FSFILT_OP_CREATE: - /* acquire block quota on parent */ - rc2 |= qctxt_adjust_qunit(obd, qctxt, qpids, 1, 0, NULL); - /* acquire file quota on child */ - rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids, 0, 0, NULL); - if (qpids[0] != qcids[0] || qpids[1] != qcids[1]) - /* acquire block quota on child */ - rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids, 1, 0, - NULL); - break; - default: - LBUG(); - break; - } - - if (rc2) - CDEBUG(D_QUOTA, - "mds adjust qunit %ssuccessfully! (opc:%d rc:%d)\n", - rc2 == QUOTA_REQ_RETURNED ? "" : "un", opc, rc2); - RETURN(0); -} - -int filter_quota_adjust(struct obd_device *obd, const unsigned int qcids[], - const unsigned int qpids[], int rc, int opc) -{ - struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt; - int rc2 = 0; - ENTRY; - - if (rc && rc != -EDQUOT) - RETURN(0); - - switch (opc) { - case FSFILT_OP_SETATTR: - /* acquire/release block quota on original & current owner */ - rc = qctxt_adjust_qunit(obd, qctxt, qcids, 1, 0, NULL); - rc2 = qctxt_adjust_qunit(obd, qctxt, qpids, 1, 0, NULL); - break; - case FSFILT_OP_UNLINK: - /* release block quota on this owner */ - case FSFILT_OP_CREATE: /* XXX for write operation on obdfilter */ - /* acquire block quota on this owner */ - rc = qctxt_adjust_qunit(obd, qctxt, qcids, 1, 0, NULL); - break; - default: - LBUG(); - break; - } - - if (rc || rc2) { - if (!rc) - rc = rc2; - CDEBUG(D_QUOTA, - "filter adjust qunit %ssuccessfully! (opc:%d rc%d)\n", - rc == QUOTA_REQ_RETURNED ? "" : "un", opc, rc); - } - - RETURN(0); -} - -static const char prefix[] = "OBJECTS/"; - -int mds_quota_invalidate(struct obd_device *obd, struct obd_quotactl *oqctl) -{ - struct mds_obd *mds = &obd->u.mds; - struct lustre_quota_info *qinfo = &mds->mds_quota_info; - struct obd_device_target *obt = &obd->u.obt; - int rc = 0, i, rc1 = 0; - char *quotafile[] = LUSTRE_ADMIN_QUOTAFILES_V2; - char name[64]; - struct lvfs_run_ctxt saved; - ENTRY; - - LASSERT(qinfo->qi_version == LUSTRE_QUOTA_V2); - - if (oqctl->qc_type != USRQUOTA && - oqctl->qc_type != GRPQUOTA && - oqctl->qc_type != UGQUOTA) - RETURN(-EINVAL); - - cfs_down(&obt->obt_quotachecking); - push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - cfs_down_write(&mds->mds_qonoff_sem); - - for (i = 0; i < MAXQUOTAS; i++) { - struct file *fp; - - if (!Q_TYPESET(oqctl, i)) - continue; - - /* quota file has been opened ? */ - if (qinfo->qi_files[i]) { - CWARN("quota[%d] is on yet\n", i); - rc1 = -EBUSY; - continue; - } - - LASSERT(strlen(quotafile[i]) + sizeof(prefix) <= sizeof(name)); - sprintf(name, "%s%s", prefix, quotafile[i]); - - fp = filp_open(name, O_CREAT | O_TRUNC | O_RDWR, 0644); - if (IS_ERR(fp)) { - rc = PTR_ERR(fp); - CERROR("%s: error invalidating admin quotafile %s (rc:%d)\n", - obd->obd_name, name, rc); - } - else - filp_close(fp, 0); - } - - cfs_up_write(&mds->mds_qonoff_sem); - pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - cfs_up(&obt->obt_quotachecking); - RETURN(rc ? : rc1); -} - -int mds_quota_finvalidate(struct obd_device *obd, struct obd_quotactl *oqctl) -{ - struct mds_obd *mds = &obd->u.mds; - struct obd_device_target *obt = &obd->u.obt; - int rc; - struct lvfs_run_ctxt saved; - ENTRY; - - if (oqctl->qc_type != USRQUOTA && - oqctl->qc_type != GRPQUOTA && - oqctl->qc_type != UGQUOTA) - RETURN(-EINVAL); - - cfs_down(&obt->obt_quotachecking); - if (obt->obt_qctxt.lqc_flags & UGQUOTA2LQC(oqctl->qc_type)) - GOTO(out, rc = -EBUSY); - push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - cfs_down_write(&mds->mds_qonoff_sem); - - oqctl->qc_cmd = Q_FINVALIDATE; - rc = fsfilt_quotactl(obd, obd->u.obt.obt_sb, oqctl); - if (!rc) - rc = obd_quotactl(mds->mds_lov_exp, oqctl); - - cfs_up_write(&mds->mds_qonoff_sem); - pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); -out: - cfs_up(&obt->obt_quotachecking); - RETURN(rc); -} - -int init_admin_quotafiles(struct obd_device *obd, struct obd_quotactl *oqctl) -{ - struct mds_obd *mds = &obd->u.mds; - struct lustre_quota_info *qinfo = &mds->mds_quota_info; - const char *quotafile[] = LUSTRE_ADMIN_QUOTAFILES_V2; - struct lvfs_run_ctxt saved; - char name[64]; - int i, rc = 0; - ENTRY; - - LASSERT(qinfo->qi_version == LUSTRE_QUOTA_V2); - - push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - cfs_down_write(&mds->mds_qonoff_sem); - - for (i = 0; i < MAXQUOTAS && !rc; i++) { - struct file *fp; - - if (!Q_TYPESET(oqctl, i)) - continue; - - /* quota file has been opened ? */ - if (qinfo->qi_files[i]) { - CWARN("init %s admin quotafile while quota on.\n", - i == USRQUOTA ? "user" : "group"); - continue; - } - - LASSERT(strlen(quotafile[i]) + sizeof(prefix) <= sizeof(name)); - sprintf(name, "%s%s", prefix, quotafile[i]); - - /* check if quota file exists and is correct */ - fp = filp_open(name, O_RDONLY, 0); - if (!IS_ERR(fp)) { - /* irregular file is not the right place for quota */ - if (!S_ISREG(fp->f_dentry->d_inode->i_mode)) { - CERROR("admin quota file %s is not " - "regular!", name); - filp_close(fp, 0); - rc = -EINVAL; - break; - } - qinfo->qi_files[i] = fp; - rc = fsfilt_quotainfo(obd, qinfo, i, QFILE_CHK); - qinfo->qi_files[i] = NULL; - filp_close(fp, 0); - } - else - rc = PTR_ERR(fp); - - if (!rc) - continue; - - /* -EINVAL may be returned by quotainfo for bad quota file */ - if (rc != -ENOENT && rc != -EINVAL) { - CERROR("%s: error opening old quota file %s (%d)\n", - obd->obd_name, name, rc); - break; - } - - CDEBUG(D_INFO, "%s new quota file %s\n", name, - rc == -ENOENT ? "creating" : "overwriting"); - - /* create quota file overwriting old if needed */ - fp = filp_open(name, O_CREAT | O_TRUNC | O_RDWR, 0644); - if (IS_ERR(fp)) { - rc = PTR_ERR(fp); - CERROR("%s: error creating admin quotafile %s (rc:%d)\n", - obd->obd_name, name, rc); - break; - } - - qinfo->qi_files[i] = fp; - - rc = fsfilt_quotainfo(obd, qinfo, i, QFILE_INIT_INFO); - if (rc) - CERROR("error init %s admin quotafile! (rc:%d)\n", - i == USRQUOTA ? "user" : "group", rc); - - filp_close(fp, 0); - qinfo->qi_files[i] = NULL; - } - - cfs_up_write(&mds->mds_qonoff_sem); - pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - RETURN(rc); -} - -static int close_quota_files(struct obd_quotactl *oqctl, - struct lustre_quota_info *qinfo) -{ - int i, rc = 0; - ENTRY; - - for (i = 0; i < MAXQUOTAS; i++) { - if (!Q_TYPESET(oqctl, i)) - continue; - if (qinfo->qi_files[i] == NULL) { - CDEBUG(D_QUOTA, "quota[%d] is off already\n", i); - rc = -EALREADY; - continue; - } - filp_close(qinfo->qi_files[i], 0); - qinfo->qi_files[i] = NULL; - } - RETURN(rc); -} - -int mds_admin_quota_on(struct obd_device *obd, struct obd_quotactl *oqctl) -{ - struct mds_obd *mds = &obd->u.mds; - struct lustre_quota_info *qinfo = &mds->mds_quota_info; - const char *quotafile[] = LUSTRE_ADMIN_QUOTAFILES_V2; - char name[64]; - int i, rc = 0, rc1 = 0; - ENTRY; - - LASSERT(qinfo->qi_version == LUSTRE_QUOTA_V2); - - /* open admin quota files and read quotafile info */ - for (i = 0; i < MAXQUOTAS; i++) { - struct file *fp; - - if (!Q_TYPESET(oqctl, i) || qinfo->qi_files[i] != NULL) - continue; - - LASSERT(strlen(quotafile[i]) - + sizeof(prefix) <= sizeof(name)); - sprintf(name, "%s%s", prefix, quotafile[i]); - fp = filp_open(name, O_RDWR, 0); - if (IS_ERR(fp) || !S_ISREG(fp->f_dentry->d_inode->i_mode)) { - rc = IS_ERR(fp) ? PTR_ERR(fp) : -EINVAL; - CERROR("error open/create %s! (rc:%d)\n", name, rc); - break; - } - qinfo->qi_files[i] = fp; - - rc = fsfilt_quotainfo(obd, qinfo, i, QFILE_CHK); - if (rc) { - CERROR("invalid quota file %s! (rc:%d)\n", name, rc); - break; - } - - rc = fsfilt_quotainfo(obd, qinfo, i, QFILE_RD_INFO); - if (rc) { - CERROR("error read quotainfo of %s! (rc:%d)\n", name, - rc); - break; - } - } - - if (rc && rc1 != -EALREADY) - close_quota_files(oqctl, qinfo); - - RETURN(rc ? : rc1); -} - -int mds_quota_on(struct obd_device *obd, struct obd_quotactl *oqctl) -{ - int rc; - ENTRY; - - if (oqctl->qc_type != USRQUOTA && - oqctl->qc_type != GRPQUOTA && - oqctl->qc_type != UGQUOTA) - RETURN(-EINVAL); - - rc = generic_quota_on(obd, oqctl, 1); - - RETURN(rc); -} - - -int mds_admin_quota_off(struct obd_device *obd, - struct obd_quotactl *oqctl) -{ - struct mds_obd *mds = &obd->u.mds; - struct lustre_quota_info *qinfo = &mds->mds_quota_info; - int rc; - ENTRY; - - /* close admin quota files */ - rc = close_quota_files(oqctl, qinfo); - RETURN(rc); -} - - -/* with obt->obt_quotachecking held */ -int do_mds_quota_off(struct obd_device *obd, struct obd_quotactl *oqctl) -{ - struct mds_obd *mds = &obd->u.mds; - struct obd_device_target *obt = &obd->u.obt; - struct lustre_quota_ctxt *qctxt = &obt->obt_qctxt; - struct lvfs_run_ctxt saved; - int rc = 0, rc1 = 0, rc2 = 0; - ENTRY; - - LASSERT_SEM_LOCKED(&obt->obt_quotachecking); - - if (oqctl->qc_type != USRQUOTA && - oqctl->qc_type != GRPQUOTA && - oqctl->qc_type != UGQUOTA) - RETURN(-EINVAL); - - push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - cfs_down_write(&mds->mds_qonoff_sem); - /* close admin quota files */ - rc2 = mds_admin_quota_off(obd, oqctl); - if (rc2 && rc2 != -EALREADY) { - CWARN("mds quota[%d] is failed to be off for %d\n", oqctl->qc_type, rc2); - GOTO(out, rc2); - } - - rc1 = fsfilt_quotactl(obd, obd->u.obt.obt_sb, oqctl); - if (!rc1) { - obt->obt_qctxt.lqc_flags &= ~UGQUOTA2LQC(oqctl->qc_type); - } else if (quota_is_off(qctxt, oqctl)) { - CWARN("mds local quota[%d] is off already\n", oqctl->qc_type); - rc1 = -EALREADY; - } else { - if (rc2 != -EALREADY) { - CWARN("mds local quota[%d] is failed to be off for %d\n", - oqctl->qc_type, rc1); - oqctl->qc_cmd = Q_QUOTAON; - mds_admin_quota_on(obd, oqctl); - oqctl->qc_cmd = Q_QUOTAOFF; - } - GOTO(out, rc1); - } - - rc = obd_quotactl(mds->mds_lov_exp, oqctl); - if (rc && rc != -EALREADY) { - CWARN("mds remote quota[%d] is failed to be off for %d\n", - oqctl->qc_type, rc); - oqctl->qc_cmd = Q_QUOTAON; - if (rc2 != -EALREADY) - mds_admin_quota_on(obd, oqctl); - if (rc1 != -EALREADY) { - fsfilt_quotactl(obd, obd->u.obt.obt_sb, oqctl); - qctxt->lqc_flags |= UGQUOTA2LQC(oqctl->qc_type); - } - oqctl->qc_cmd = Q_QUOTAOFF; - } - EXIT; - -out: - CDEBUG(D_QUOTA, "%s: quotaoff type:flags:rc %u:%lu:%d\n", - obd->obd_name, oqctl->qc_type, qctxt->lqc_flags, rc); - cfs_up_write(&mds->mds_qonoff_sem); - pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - return rc ? : (rc1 ? : rc2); -} - -int mds_quota_off(struct obd_device *obd, struct obd_quotactl *oqctl) -{ - struct obd_device_target *obt = &obd->u.obt; - int rc; - ENTRY; - - cfs_down(&obt->obt_quotachecking); - rc = do_mds_quota_off(obd, oqctl); - cfs_up(&obt->obt_quotachecking); - RETURN(rc); -} - -int mds_set_dqinfo(struct obd_device *obd, struct obd_quotactl *oqctl) -{ - struct mds_obd *mds = &obd->u.mds; - struct lustre_quota_info *qinfo = &mds->mds_quota_info; - struct obd_dqinfo *dqinfo = &oqctl->qc_dqinfo; - int rc; - ENTRY; - - if (oqctl->qc_type != USRQUOTA && - oqctl->qc_type != GRPQUOTA) - RETURN(-EINVAL); - - cfs_down_write(&mds->mds_qonoff_sem); - if (qinfo->qi_files[oqctl->qc_type] == NULL) { - CWARN("quota[%u] is off\n", oqctl->qc_type); - GOTO(out, rc = -ESRCH); - } - - qinfo->qi_info[oqctl->qc_type].dqi_bgrace = dqinfo->dqi_bgrace; - qinfo->qi_info[oqctl->qc_type].dqi_igrace = dqinfo->dqi_igrace; - qinfo->qi_info[oqctl->qc_type].dqi_flags = dqinfo->dqi_flags; - - rc = fsfilt_quotainfo(obd, qinfo, oqctl->qc_type, QFILE_WR_INFO); - EXIT; - -out: - cfs_up_write(&mds->mds_qonoff_sem); - return rc; -} - -int mds_get_dqinfo(struct obd_device *obd, struct obd_quotactl *oqctl) -{ - struct mds_obd *mds = &obd->u.mds; - struct lustre_quota_info *qinfo = &mds->mds_quota_info; - struct obd_dqinfo *dqinfo = &oqctl->qc_dqinfo; - int rc = 0; - ENTRY; - - if (oqctl->qc_type != USRQUOTA && - oqctl->qc_type != GRPQUOTA) - RETURN(-EINVAL); - - cfs_down_read(&mds->mds_qonoff_sem); - if (qinfo->qi_files[oqctl->qc_type] == NULL) { - CWARN("quota[%u] is off\n", oqctl->qc_type); - GOTO(out, rc = -ESRCH); - } - - dqinfo->dqi_bgrace = qinfo->qi_info[oqctl->qc_type].dqi_bgrace; - dqinfo->dqi_igrace = qinfo->qi_info[oqctl->qc_type].dqi_igrace; - dqinfo->dqi_flags = qinfo->qi_info[oqctl->qc_type].dqi_flags; - EXIT; - -out: - cfs_up_read(&mds->mds_qonoff_sem); - return rc; -} - -int dquot_create_oqaq(struct lustre_quota_ctxt *qctxt, - struct lustre_dquot *dquot, __u32 ost_num, __u32 mdt_num, - int type, struct quota_adjust_qunit *oqaq) -{ - __u64 bunit_curr_o, iunit_curr_o; - unsigned long shrink_qunit_limit = qctxt->lqc_cqs_boundary_factor; - unsigned long cqs_factor = qctxt->lqc_cqs_qs_factor; - __u64 blimit = dquot->dq_dqb.dqb_bhardlimit ? - dquot->dq_dqb.dqb_bhardlimit : dquot->dq_dqb.dqb_bsoftlimit; - __u64 ilimit = dquot->dq_dqb.dqb_ihardlimit ? - dquot->dq_dqb.dqb_ihardlimit : dquot->dq_dqb.dqb_isoftlimit; - int rc = 0; - ENTRY; - - if (!dquot || !oqaq) - RETURN(-EINVAL); - LASSERT_MUTEX_LOCKED(&dquot->dq_mutex); - LASSERT(oqaq->qaq_iunit_sz); - LASSERT(oqaq->qaq_bunit_sz); - - /* don't change qunit size */ - if (!qctxt->lqc_switch_qs) - RETURN(rc); - - bunit_curr_o = oqaq->qaq_bunit_sz; - iunit_curr_o = oqaq->qaq_iunit_sz; - - if (dquot->dq_type == GRPQUOTA) - QAQ_SET_GRP(oqaq); - - if ((type & LQUOTA_FLAGS_ADJBLK) && blimit) { - __u64 b_limitation = - oqaq->qaq_bunit_sz * (ost_num + 1) * shrink_qunit_limit; - /* enlarge block qunit size */ - while (blimit > - QUSG(dquot->dq_dqb.dqb_curspace + 2 * b_limitation, 1)) { - oqaq->qaq_bunit_sz = - QUSG(oqaq->qaq_bunit_sz * cqs_factor, 1) - << QUOTABLOCK_BITS; - if (oqaq->qaq_bunit_sz >= qctxt->lqc_bunit_sz) - break; - b_limitation = oqaq->qaq_bunit_sz * (ost_num + 1) * - shrink_qunit_limit; - } - - if (oqaq->qaq_bunit_sz > qctxt->lqc_bunit_sz) - oqaq->qaq_bunit_sz = qctxt->lqc_bunit_sz; - - /* shrink block qunit size */ - while (blimit < - QUSG(dquot->dq_dqb.dqb_curspace + b_limitation, 1)) { - do_div(oqaq->qaq_bunit_sz , cqs_factor); - oqaq->qaq_bunit_sz = QUSG(oqaq->qaq_bunit_sz, 1) << - QUOTABLOCK_BITS; - b_limitation = oqaq->qaq_bunit_sz * (ost_num + 1) * - shrink_qunit_limit; - if (oqaq->qaq_bunit_sz < qctxt->lqc_cqs_least_bunit) - break; - } - - if (oqaq->qaq_bunit_sz < qctxt->lqc_cqs_least_bunit) - oqaq->qaq_bunit_sz = qctxt->lqc_cqs_least_bunit; - - if (bunit_curr_o != oqaq->qaq_bunit_sz) - QAQ_SET_ADJBLK(oqaq); - - } - - if ((type & LQUOTA_FLAGS_ADJINO) && ilimit) { - __u64 i_limitation = - oqaq->qaq_iunit_sz * mdt_num * shrink_qunit_limit; - /* enlarge file qunit size */ - while (ilimit > dquot->dq_dqb.dqb_curinodes - + 2 * i_limitation) { - oqaq->qaq_iunit_sz = oqaq->qaq_iunit_sz * cqs_factor; - if (oqaq->qaq_iunit_sz >= qctxt->lqc_iunit_sz) - break; - i_limitation = oqaq->qaq_iunit_sz * mdt_num * - shrink_qunit_limit; - } - - if (oqaq->qaq_iunit_sz > qctxt->lqc_iunit_sz) - oqaq->qaq_iunit_sz = qctxt->lqc_iunit_sz; - - /* shrink file qunit size */ - while (ilimit < dquot->dq_dqb.dqb_curinodes - + i_limitation) { - do_div(oqaq->qaq_iunit_sz, cqs_factor); - i_limitation = oqaq->qaq_iunit_sz * mdt_num * - shrink_qunit_limit; - if (oqaq->qaq_iunit_sz < qctxt->lqc_cqs_least_iunit) - break; - } - - if (oqaq->qaq_iunit_sz < qctxt->lqc_cqs_least_iunit) - oqaq->qaq_iunit_sz = qctxt->lqc_cqs_least_iunit; - - if (iunit_curr_o != oqaq->qaq_iunit_sz) - QAQ_SET_ADJINO(oqaq); - - } - - QAQ_DEBUG(oqaq, "the oqaq computed\n"); - - RETURN(rc); -} - -static int mds_init_slave_ilimits(struct obd_device *obd, - struct obd_quotactl *oqctl, int set) -{ - /* XXX: for file limits only adjust local now */ - struct obd_device_target *obt = &obd->u.obt; - struct lustre_quota_ctxt *qctxt = &obt->obt_qctxt; - unsigned int id[MAXQUOTAS] = { 0, 0 }; - struct obd_quotactl *ioqc = NULL; - struct lustre_qunit_size *lqs; - int flag; - int rc; - ENTRY; - - /* if we are going to set zero limit, needn't init slaves */ - if (!oqctl->qc_dqblk.dqb_ihardlimit && !oqctl->qc_dqblk.dqb_isoftlimit && - !set) - RETURN(0); - - OBD_ALLOC_PTR(ioqc); - if (!ioqc) - RETURN(-ENOMEM); - - flag = oqctl->qc_dqblk.dqb_ihardlimit || - oqctl->qc_dqblk.dqb_isoftlimit || !set; - ioqc->qc_cmd = flag ? Q_INITQUOTA : Q_SETQUOTA; - ioqc->qc_id = oqctl->qc_id; - ioqc->qc_type = oqctl->qc_type; - ioqc->qc_dqblk.dqb_valid = QIF_ILIMITS; - ioqc->qc_dqblk.dqb_ihardlimit = flag ? MIN_QLIMIT : 0; - - /* build lqs for mds */ - lqs = quota_search_lqs(LQS_KEY(oqctl->qc_type, oqctl->qc_id), - qctxt, flag ? 1 : 0); - if (lqs && !IS_ERR(lqs)) { - if (flag) - lqs->lqs_flags |= QI_SET; - else - lqs->lqs_flags &= ~QI_SET; - lqs_putref(lqs); - } else { - CERROR("fail to %s lqs for inode(%s id: %u)!\n", - flag ? "create" : "search", - oqctl->qc_type ? "group" : "user", - oqctl->qc_id); - GOTO(out, rc = PTR_ERR(lqs)); - } - - /* set local limit to MIN_QLIMIT */ - rc = fsfilt_quotactl(obd, obd->u.obt.obt_sb, ioqc); - if (rc) - GOTO(out, rc); - - /* trigger local qunit pre-acquire */ - if (oqctl->qc_type == USRQUOTA) - id[USRQUOTA] = oqctl->qc_id; - else - id[GRPQUOTA] = oqctl->qc_id; - - rc = qctxt_adjust_qunit(obd, &obd->u.obt.obt_qctxt, id, 0, 0, NULL); - if (rc == -EDQUOT || rc == -EBUSY) { - CDEBUG(D_QUOTA, "rc: %d.\n", rc); - rc = 0; - } - if (rc) { - CDEBUG(D_QUOTA,"error mds adjust local file quota! (rc:%d)\n", - rc); - GOTO(out, rc); - } - /* FIXME initialize all slaves in CMD */ - EXIT; -out: - if (ioqc) - OBD_FREE_PTR(ioqc); - return rc; -} - -static int mds_init_slave_blimits(struct obd_device *obd, - struct obd_quotactl *oqctl, int set) -{ - struct obd_device_target *obt = &obd->u.obt; - struct lustre_quota_ctxt *qctxt = &obt->obt_qctxt; - struct mds_obd *mds = &obd->u.mds; - struct obd_quotactl *ioqc; - struct lustre_qunit_size *lqs; - unsigned int id[MAXQUOTAS] = { 0, 0 }; - int rc; - int flag; - ENTRY; - - /* if we are going to set zero limit, needn't init slaves */ - if (!oqctl->qc_dqblk.dqb_bhardlimit && !oqctl->qc_dqblk.dqb_bsoftlimit && - !set) - RETURN(0); - - OBD_ALLOC_PTR(ioqc); - if (!ioqc) - RETURN(-ENOMEM); - - flag = oqctl->qc_dqblk.dqb_bhardlimit || - oqctl->qc_dqblk.dqb_bsoftlimit || !set; - ioqc->qc_cmd = flag ? Q_INITQUOTA : Q_SETQUOTA; - ioqc->qc_id = oqctl->qc_id; - ioqc->qc_type = oqctl->qc_type; - ioqc->qc_dqblk.dqb_valid = QIF_BLIMITS; - ioqc->qc_dqblk.dqb_bhardlimit = flag ? MIN_QLIMIT : 0; - - /* build lqs for mds */ - lqs = quota_search_lqs(LQS_KEY(oqctl->qc_type, oqctl->qc_id), - qctxt, flag ? 1 : 0); - if (lqs && !IS_ERR(lqs)) { - if (flag) - lqs->lqs_flags |= QB_SET; - else - lqs->lqs_flags &= ~QB_SET; - lqs_putref(lqs); - } else { - CERROR("fail to %s lqs for block(%s id: %u)!\n", - flag ? "create" : "search", - oqctl->qc_type ? "group" : "user", - oqctl->qc_id); - GOTO(out, rc = PTR_ERR(lqs)); - } - - rc = fsfilt_quotactl(obd, obd->u.obt.obt_sb, ioqc); - if (rc) - GOTO(out, rc); - - /* trigger local qunit pre-acquire */ - if (oqctl->qc_type == USRQUOTA) - id[USRQUOTA] = oqctl->qc_id; - else - id[GRPQUOTA] = oqctl->qc_id; - - /* initialize all slave's limit */ - rc = obd_quotactl(mds->mds_lov_exp, ioqc); - - rc = qctxt_adjust_qunit(obd, &obd->u.obt.obt_qctxt, id, 1, 0, NULL); - if (rc == -EDQUOT || rc == -EBUSY) { - CDEBUG(D_QUOTA, "rc: %d.\n", rc); - rc = 0; - } - if (rc) { - CERROR("error mds adjust local block quota! (rc:%d)\n", rc); - GOTO(out, rc); - } - - EXIT; -out: - OBD_FREE_PTR(ioqc); - return rc; -} - -static void adjust_lqs(struct obd_device *obd, struct quota_adjust_qunit *qaq) -{ - struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt; - int rc = 0; - - QAQ_SET_CREATE_LQS(qaq); - /* adjust local lqs */ - rc = quota_adjust_slave_lqs(qaq, qctxt); - if (rc < 0) - CERROR("adjust master's qunit size failed!(rc=%d)\n", rc); - - /* adjust remote lqs */ - if (QAQ_IS_ADJBLK(qaq)) { - rc = obd_quota_adjust_qunit(obd->u.mds.mds_lov_exp, qaq, qctxt, NULL); - if (rc < 0) - CERROR("adjust slaves' qunit size failed!(rc=%d)\n", rc); - - } -} - -int mds_set_dqblk(struct obd_device *obd, struct obd_quotactl *oqctl) -{ - struct mds_obd *mds = &obd->u.mds; - struct lustre_quota_ctxt *qctxt = &mds->mds_obt.obt_qctxt; - struct obd_device *lov_obd = class_exp2obd(mds->mds_lov_exp); - struct lov_obd *lov = &lov_obd->u.lov; - struct quota_adjust_qunit *oqaq = NULL; - struct lustre_quota_info *qinfo = &mds->mds_quota_info; - __u64 ihardlimit, isoftlimit, bhardlimit, bsoftlimit; - time_t btime, itime; - struct lustre_dquot *dquot; - struct obd_dqblk *dqblk = &oqctl->qc_dqblk; - /* orig_set means if quota was set before; now_set means we are - * setting/cancelling quota */ - int orig_set, now_set; - struct lustre_qunit_size *lqs; - int rc = 0, rc2 = 0, flag = 0; - ENTRY; - - if (oqctl->qc_type != USRQUOTA && - oqctl->qc_type != GRPQUOTA) - RETURN(-EINVAL); - - OBD_ALLOC_PTR(oqaq); - if (!oqaq) - RETURN(-ENOMEM); - - cfs_down_write(&mds->mds_qonoff_sem); - init_oqaq(oqaq, qctxt, oqctl->qc_id, oqctl->qc_type); - - if (qinfo->qi_files[oqctl->qc_type] == NULL) { - CWARN("quota[%u] is off\n", oqctl->qc_type); - GOTO(out_sem, rc = -ESRCH); - } - - dquot = lustre_dqget(obd, qinfo, oqctl->qc_id, oqctl->qc_type, 1); - if (IS_ERR(dquot)) - GOTO(out_sem, rc = PTR_ERR(dquot)); - DQUOT_DEBUG(dquot, "get dquot in mds_set_blk\n"); - QINFO_DEBUG(dquot->dq_info, "get dquot in mds_set_blk\n"); - - lqs = quota_search_lqs(LQS_KEY(oqctl->qc_type, oqctl->qc_id), qctxt, 1); - if (lqs == NULL) - rc = -ENOENT; - if (IS_ERR(lqs)) - rc = PTR_ERR(lqs); - if (rc) - GOTO(out, rc); - - cfs_mutex_lock(&dquot->dq_mutex); - cfs_spin_lock(&lqs->lqs_lock); - if (LQS_IS_SETQUOTA(lqs) || LQS_IS_RECOVERY(lqs)) { - cfs_spin_unlock(&lqs->lqs_lock); - cfs_mutex_unlock(&dquot->dq_mutex); - GOTO(skip, rc = -EBUSY); - } - LQS_SET_SETQUOTA(lqs); - cfs_spin_unlock(&lqs->lqs_lock); - - ihardlimit = dquot->dq_dqb.dqb_ihardlimit; - isoftlimit = dquot->dq_dqb.dqb_isoftlimit; - bhardlimit = dquot->dq_dqb.dqb_bhardlimit; - bsoftlimit = dquot->dq_dqb.dqb_bsoftlimit; - btime = dquot->dq_dqb.dqb_btime; - itime = dquot->dq_dqb.dqb_itime; - - if (dqblk->dqb_valid & QIF_BTIME) - dquot->dq_dqb.dqb_btime = dqblk->dqb_btime; - if (dqblk->dqb_valid & QIF_ITIME) - dquot->dq_dqb.dqb_itime = dqblk->dqb_itime; - - if (dqblk->dqb_valid & QIF_BLIMITS) { - dquot->dq_dqb.dqb_bhardlimit = dqblk->dqb_bhardlimit; - dquot->dq_dqb.dqb_bsoftlimit = dqblk->dqb_bsoftlimit; - /* clear usage (limit pool) */ - if (!dquot->dq_dqb.dqb_bhardlimit && - !dquot->dq_dqb.dqb_bsoftlimit) - dquot->dq_dqb.dqb_curspace = 0; - - /* clear grace time */ - if (!dqblk->dqb_bsoftlimit || - toqb(dquot->dq_dqb.dqb_curspace) <= dqblk->dqb_bsoftlimit) - dquot->dq_dqb.dqb_btime = 0; - /* set grace only if user hasn't provided his own */ - else if (!(dqblk->dqb_valid & QIF_BTIME)) - dquot->dq_dqb.dqb_btime = cfs_time_current_sec() + - qinfo->qi_info[dquot->dq_type].dqi_bgrace; - - flag |= LQUOTA_FLAGS_ADJBLK; - } - - if (dqblk->dqb_valid & QIF_ILIMITS) { - dquot->dq_dqb.dqb_ihardlimit = dqblk->dqb_ihardlimit; - dquot->dq_dqb.dqb_isoftlimit = dqblk->dqb_isoftlimit; - /* clear usage (limit pool) */ - if (!dquot->dq_dqb.dqb_ihardlimit && - !dquot->dq_dqb.dqb_isoftlimit) - dquot->dq_dqb.dqb_curinodes = 0; - - if (!dqblk->dqb_isoftlimit || - dquot->dq_dqb.dqb_curinodes <= dqblk->dqb_isoftlimit) - dquot->dq_dqb.dqb_itime = 0; - else if (!(dqblk->dqb_valid & QIF_ITIME)) - dquot->dq_dqb.dqb_itime = cfs_time_current_sec() + - qinfo->qi_info[dquot->dq_type].dqi_igrace; - - flag |= LQUOTA_FLAGS_ADJINO; - } - QAQ_DEBUG(oqaq, "before dquot_create_oqaq\n"); - rc = dquot_create_oqaq(qctxt, dquot, lov->desc.ld_tgt_count, 1, - flag, oqaq); - QAQ_DEBUG(oqaq, "after dquot_create_oqaq\n"); - if (rc < 0) - CDEBUG(D_QUOTA, "adjust qunit size failed! (rc:%d)\n", rc); - - - rc = fsfilt_dquot(obd, dquot, QFILE_WR_DQUOT); - - cfs_mutex_unlock(&dquot->dq_mutex); - - if (rc) { - CERROR("set limit failed! (rc:%d)\n", rc); - GOTO(update_fail, rc); - } - - cfs_up_write(&mds->mds_qonoff_sem); - adjust_lqs(obd, oqaq); - - orig_set = ihardlimit || isoftlimit; - now_set = dqblk->dqb_ihardlimit || dqblk->dqb_isoftlimit; - if (dqblk->dqb_valid & QIF_ILIMITS && orig_set != now_set) { - cfs_mutex_lock(&dquot->dq_mutex); - dquot->dq_dqb.dqb_curinodes = 0; - cfs_mutex_unlock(&dquot->dq_mutex); - rc = mds_init_slave_ilimits(obd, oqctl, orig_set); - if (rc) { - CERROR("init slave ilimits failed! (rc:%d)\n", rc); - goto revoke_out; - } - } - - orig_set = bhardlimit || bsoftlimit; - now_set = dqblk->dqb_bhardlimit || dqblk->dqb_bsoftlimit; - if (dqblk->dqb_valid & QIF_BLIMITS && orig_set != now_set) { - cfs_mutex_lock(&dquot->dq_mutex); - dquot->dq_dqb.dqb_curspace = 0; - cfs_mutex_unlock(&dquot->dq_mutex); - rc = mds_init_slave_blimits(obd, oqctl, orig_set); - if (rc) { - CERROR("init slave blimits failed! (rc:%d)\n", rc); - goto revoke_out; - } - } - -revoke_out: - cfs_down_write(&mds->mds_qonoff_sem); - cfs_mutex_lock(&dquot->dq_mutex); - if (rc) { - /* cancel previous setting */ - dquot->dq_dqb.dqb_ihardlimit = ihardlimit; - dquot->dq_dqb.dqb_isoftlimit = isoftlimit; - dquot->dq_dqb.dqb_bhardlimit = bhardlimit; - dquot->dq_dqb.dqb_bsoftlimit = bsoftlimit; - dquot->dq_dqb.dqb_btime = btime; - dquot->dq_dqb.dqb_itime = itime; - } - rc2 = fsfilt_dquot(obd, dquot, QFILE_WR_DQUOT); - cfs_mutex_unlock(&dquot->dq_mutex); -update_fail: - cfs_spin_lock(&lqs->lqs_lock); - LQS_CLEAR_SETQUOTA(lqs); - cfs_spin_unlock(&lqs->lqs_lock); -skip: - lqs_putref(lqs); -out: - lustre_dqput(dquot); - EXIT; -out_sem: - cfs_up_write(&mds->mds_qonoff_sem); - - if (oqaq) - OBD_FREE_PTR(oqaq); - - return rc ? rc : rc2; -} - -static int mds_get_space(struct obd_device *obd, struct obd_quotactl *oqctl) -{ - struct obd_quotactl *soqc; - struct lvfs_run_ctxt saved; - int rc, rc1; - ENTRY; - - OBD_ALLOC_PTR(soqc); - if (!soqc) - RETURN(-ENOMEM); - - soqc->qc_cmd = Q_GETOQUOTA; - soqc->qc_id = oqctl->qc_id; - soqc->qc_type = oqctl->qc_type; - - /* get block usage from OSS */ - soqc->qc_dqblk.dqb_curspace = 0; - rc = obd_quotactl(obd->u.mds.mds_lov_exp, soqc); - if (!rc || rc == -EREMOTEIO) { - oqctl->qc_dqblk.dqb_curspace = soqc->qc_dqblk.dqb_curspace; - oqctl->qc_dqblk.dqb_valid |= QIF_SPACE; - } - - /* get block/inode usage from MDS */ - soqc->qc_dqblk.dqb_curspace = 0; - soqc->qc_dqblk.dqb_curinodes = 0; - push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - rc1 = fsfilt_quotactl(obd, obd->u.obt.obt_sb, soqc); - pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - if (!rc1) { - oqctl->qc_dqblk.dqb_curspace += soqc->qc_dqblk.dqb_curspace; - oqctl->qc_dqblk.dqb_curinodes = soqc->qc_dqblk.dqb_curinodes; - oqctl->qc_dqblk.dqb_valid |= QIF_INODES; - } - - OBD_FREE_PTR(soqc); - - RETURN(rc ? : rc1); -} - -int mds_get_dqblk(struct obd_device *obd, struct obd_quotactl *oqctl) -{ - struct mds_obd *mds = &obd->u.mds; - struct lustre_quota_info *qinfo = &mds->mds_quota_info; - struct lustre_dquot *dquot; - struct obd_dqblk *dqblk = &oqctl->qc_dqblk; - int rc; - ENTRY; - - if (oqctl->qc_type != USRQUOTA && - oqctl->qc_type != GRPQUOTA) - RETURN(-EINVAL); - - cfs_down_read(&mds->mds_qonoff_sem); - dqblk->dqb_valid = 0; - if (qinfo->qi_files[oqctl->qc_type] == NULL) { - CWARN("quota[%u] is off\n", oqctl->qc_type); - GOTO(out, rc = -ESRCH); - } - - dquot = lustre_dqget(obd, qinfo, oqctl->qc_id, oqctl->qc_type, 1); - if (IS_ERR(dquot)) - GOTO(out, rc = PTR_ERR(dquot)); - - cfs_mutex_lock(&dquot->dq_mutex); - dqblk->dqb_ihardlimit = dquot->dq_dqb.dqb_ihardlimit; - dqblk->dqb_isoftlimit = dquot->dq_dqb.dqb_isoftlimit; - dqblk->dqb_bhardlimit = dquot->dq_dqb.dqb_bhardlimit; - dqblk->dqb_bsoftlimit = dquot->dq_dqb.dqb_bsoftlimit; - dqblk->dqb_btime = dquot->dq_dqb.dqb_btime; - dqblk->dqb_itime = dquot->dq_dqb.dqb_itime; - dqblk->dqb_valid |= QIF_LIMITS | QIF_TIMES; - cfs_mutex_unlock(&dquot->dq_mutex); - - lustre_dqput(dquot); - cfs_up_read(&mds->mds_qonoff_sem); - - /* the usages in admin quota file is inaccurate */ - dqblk->dqb_curinodes = 0; - dqblk->dqb_curspace = 0; - rc = mds_get_space(obd, oqctl); - - RETURN(rc); - -out: - cfs_up_read(&mds->mds_qonoff_sem); - return rc; -} - -int mds_get_obd_quota(struct obd_device *obd, struct obd_quotactl *oqctl) -{ - struct lvfs_run_ctxt saved; - int rc; - ENTRY; - - push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - rc = fsfilt_quotactl(obd, obd->u.obt.obt_sb, oqctl); - pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - - RETURN(rc); -} - - -/* FIXME we only recovery block limit by now, need recovery inode - * limits also after CMD involved in */ -static int -dquot_recovery(struct obd_device *obd, unsigned int id, unsigned short type) -{ - struct mds_obd *mds = &obd->u.mds; - struct lustre_quota_ctxt *qctxt = &mds->mds_obt.obt_qctxt; - struct lustre_quota_info *qinfo = &mds->mds_quota_info; - struct lustre_qunit_size *lqs; - struct lustre_dquot *dquot; - struct obd_quotactl *qctl; - __u64 total_limits = 0; - int rc = 0; - ENTRY; - - OBD_ALLOC_PTR(qctl); - if (qctl == NULL) - RETURN(-ENOMEM); - - dquot = lustre_dqget(obd, qinfo, id, type, 0); - if (IS_ERR(dquot)) { - CERROR("Get dquot failed. (rc:%ld)\n", PTR_ERR(dquot)); - OBD_FREE_PTR(qctl); - RETURN(PTR_ERR(dquot)); - } - - lqs = quota_search_lqs(LQS_KEY(type, id), qctxt, 1); - if (lqs == NULL) - rc = -ENOENT; - if (IS_ERR(lqs)) - rc = PTR_ERR(lqs); - if (rc) - GOTO(skip, rc); - - cfs_mutex_lock(&dquot->dq_mutex); - - /* don't recover the dquot without limits or quota is setting or - * another recovery is already going on */ - if (!(dquot->dq_dqb.dqb_bhardlimit || dquot->dq_dqb.dqb_bsoftlimit) || - LQS_IS_SETQUOTA(lqs) || LQS_IS_RECOVERY(lqs)) { - cfs_mutex_unlock(&dquot->dq_mutex); - GOTO(skip1, rc = 0); - } - - cfs_spin_lock(&lqs->lqs_lock); - LQS_SET_RECOVERY(lqs); - cfs_spin_unlock(&lqs->lqs_lock); - cfs_mutex_unlock(&dquot->dq_mutex); - - /* release mds_qonoff_sem during obd_quotactl ops here */ - cfs_up_write(&mds->mds_qonoff_sem); - - /* get real bhardlimit from all slaves. */ - qctl->qc_cmd = Q_GETOQUOTA; - qctl->qc_type = type; - qctl->qc_id = id; - qctl->qc_stat = QUOTA_RECOVERING; - rc = obd_quotactl(mds->mds_lov_exp, qctl); - cfs_down_write(&mds->mds_qonoff_sem); - if (rc) - GOTO(out, rc); - total_limits = qctl->qc_dqblk.dqb_bhardlimit; - - /* get real bhardlimit from master */ - rc = fsfilt_quotactl(obd, obd->u.obt.obt_sb, qctl); - if (rc) - GOTO(out, rc); - total_limits += qctl->qc_dqblk.dqb_bhardlimit; - - /* amend the usage of the administrative quotafile */ - cfs_mutex_lock(&dquot->dq_mutex); - - dquot->dq_dqb.dqb_curspace = total_limits << QUOTABLOCK_BITS; - - rc = fsfilt_dquot(obd, dquot, QFILE_WR_DQUOT); - if (rc) - CERROR("write dquot failed! (rc:%d)\n", rc); - - cfs_mutex_unlock(&dquot->dq_mutex); - EXIT; -out: - cfs_spin_lock(&lqs->lqs_lock); - LQS_CLEAR_RECOVERY(lqs); - cfs_spin_unlock(&lqs->lqs_lock); -skip1: - lqs_putref(lqs); -skip: - lustre_dqput(dquot); - OBD_FREE_PTR(qctl); - return rc; -} - -struct qmaster_recov_thread_data { - struct obd_device *obd; - cfs_completion_t comp; -}; - -static int qmaster_recovery_main(void *arg) -{ - struct qmaster_recov_thread_data *data = arg; - struct obd_device *obd = data->obd; - struct mds_obd *mds = &obd->u.mds; - struct lustre_quota_info *qinfo = &mds->mds_quota_info; - int rc = 0; - unsigned short type; - ENTRY; - - cfs_daemonize_ctxt("qmaster_recovd"); - - /* for mds */ - class_incref(obd, "qmaster_recovd_mds", obd); - /* for lov */ - class_incref(mds->mds_lov_obd, "qmaster_recovd_lov", mds->mds_lov_obd); - - cfs_complete(&data->comp); - - cfs_down_write(&mds->mds_qonoff_sem); - for (type = USRQUOTA; type < MAXQUOTAS; type++) { - cfs_list_t id_list; - struct dquot_id *dqid, *tmp; - - if (qinfo->qi_files[type] == NULL) - continue; - - CFS_INIT_LIST_HEAD(&id_list); - rc = fsfilt_qids(obd, qinfo->qi_files[type], NULL, type, - &id_list); - if (rc) - CERROR("error get ids from admin quotafile.(%d)\n", rc); - - cfs_list_for_each_entry_safe(dqid, tmp, &id_list, di_link) { - cfs_list_del_init(&dqid->di_link); - if (rc) - goto free; - - rc = dquot_recovery(obd, dqid->di_id, type); - if (rc) - CERROR("%s: qmaster recovery failed for %sid %d" - " rc:%d)\n", obd->obd_name, - type ? "g" : "u", dqid->di_id, rc); -free: - OBD_FREE_PTR(dqid); - } - } - cfs_up_write(&mds->mds_qonoff_sem); - class_decref(mds->mds_lov_obd, "qmaster_recovd_lov", mds->mds_lov_obd); - class_decref(obd, "qmaster_recovd_mds", obd); - RETURN(rc); -} - -int mds_quota_recovery(struct obd_device *obd) -{ - struct mds_obd *mds = &obd->u.mds; - struct qmaster_recov_thread_data data; - int rc = 0; - ENTRY; - - if (!sb_any_quota_loaded(obd->u.obt.obt_qctxt.lqc_sb)) - RETURN(0); - - if (unlikely(!mds->mds_quota || obd->obd_stopping)) - RETURN(rc); - - cfs_mutex_lock(&obd->obd_dev_mutex); - if (mds->mds_lov_desc.ld_active_tgt_count != mds->mds_lov_objid_count) { - CWARN("Only %u/%u OSTs are active, abort quota recovery\n", - mds->mds_lov_desc.ld_active_tgt_count, - mds->mds_lov_objid_count); - cfs_mutex_unlock(&obd->obd_dev_mutex); - RETURN(rc); - } - cfs_mutex_unlock(&obd->obd_dev_mutex); - - data.obd = obd; - cfs_init_completion(&data.comp); - - rc = cfs_create_thread(qmaster_recovery_main, &data, - CFS_DAEMON_FLAGS); - if (rc < 0) - CERROR("%s: cannot start quota recovery thread: rc %d\n", - obd->obd_name, rc); - - cfs_wait_for_completion(&data.comp); - RETURN(rc); -} diff --git a/lustre/tests/sanity-quota.sh b/lustre/tests/sanity-quota.sh index 24c6882..2387913 100644 --- a/lustre/tests/sanity-quota.sh +++ b/lustre/tests/sanity-quota.sh @@ -9,10 +9,8 @@ set -e SRCDIR=`dirname $0` export PATH=$PWD/$SRCDIR:$SRCDIR:$PWD/$SRCDIR/../utils:$PATH:/sbin -if [ "$USE_OFD" = "yes" -a -z "$ONLY" ]; then - # only accounting tests are supported with OFD for the time being - ONLY="33 34 35" -fi +# only accounting tests are supported for the time being +ONLY="33 34 35" ONLY=${ONLY:-"$*"} # test_11 has been used to protect a kernel bug(bz10912), now it isn't @@ -89,21 +87,12 @@ cycle=30 build_test_filter -if [ "$USE_OFD" = "yes" ]; then - for num in `seq $OSTCOUNT`; do - if [ $(facet_fstype ost$num) = ldiskfs ]; then - # not the most efficient way to enable the quota feature - # on ost, but it still allows us to test ofd accounting - # for now - device=$(ostdevname $num) - stop ost$num - do_facet ost$num "$TUNE2FS -O quota $device" - [ ${PIPESTATUS[0]} -ne 0] && \ - error "failed to enable quota feature for ost$num" - start ost$num $device $OST_MOUNT_OPTS - fi - done -fi +# Use OFD for all quota testing +USE_OFD_OLD="$USE_OFD" +LOAD_MODULES_REMOTE_OLD="$LOAD_MODULES_REMOTE" +export USE_OFD="yes" +export LOAD_MODULES_REMOTE="true" +cleanup_and_setup_lustre # set_blk_tunables(btune_sz) set_blk_tunesz() { @@ -170,6 +159,11 @@ FAIL_ON_ERROR=false run_test_with_stat() { (($# != 2)) && error "the number of arguments is wrong" + if [ "$USE_OFD" == "yes" ]; then + run_test "$@" + return + fi + do_facet $SINGLEMDS "lctl set_param lquota.mdd_obd-${FSNAME}-MDT*.stats=0" > /dev/null for j in `seq $OSTCOUNT`; do do_facet ost$j "lctl set_param lquota.${FSNAME}-OST*.stats=0" > /dev/null @@ -307,11 +301,11 @@ quota_show_check() { quota_init() { do_nodes $(comma_list $(nodes_list)) "lctl set_param debug=+quota" - log "do the quotacheck ..." - $LFS quotacheck -ug $DIR + # log "do the quotacheck ..." + # $LFS quotacheck -ug $DIR - resetquota -u $TSTUSR - resetquota -g $TSTUSR + # resetquota -u $TSTUSR + # resetquota -g $TSTUSR } quota_init @@ -2415,13 +2409,15 @@ run_test 35 "usage is still accessible across reboot =========================== # turn off quota quota_fini() { - $LFS quotaoff $DIR + #$LFS quotaoff $DIR do_nodes $(comma_list $(nodes_list)) "lctl set_param debug=-quota" } quota_fini cd $ORIG_PWD complete $(basename $0) $SECONDS -check_and_cleanup_lustre +export USE_OFD="$USE_OFD_OLD" +export LOAD_MODULES_REMOTE="$LOAD_MODULES_REMOTE_OLD" export QUOTA_AUTO=$QUOTA_AUTO_OLD +cleanup_and_setup_lustre exit_status diff --git a/lustre/tests/test-framework.sh b/lustre/tests/test-framework.sh index 1d4c7a02..7cfe4fc 100644 --- a/lustre/tests/test-framework.sh +++ b/lustre/tests/test-framework.sh @@ -1036,10 +1036,8 @@ restore_quota_old() { setup_quota_old(){ local mntpt=$1 - if [ "$USE_OFD" = "yes" ]; then - $LFS quotacheck $mntpt || error "quotacheck failed" - return - fi + # no quota enforcement for now and accounting works out of the box + return # We need save the original quota_type params, and restore them after testing @@ -3047,7 +3045,7 @@ init_param_vars () { setup_quota $MOUNT || return 2 else echo "disable quota as required" - $LFS quotaoff -ug $MOUNT > /dev/null 2>&1 + # $LFS quotaoff -ug $MOUNT > /dev/null 2>&1 fi fi return 0 diff --git a/lustre/utils/mount_utils_ldiskfs.c b/lustre/utils/mount_utils_ldiskfs.c index c71c6a7..fb96106 100644 --- a/lustre/utils/mount_utils_ldiskfs.c +++ b/lustre/utils/mount_utils_ldiskfs.c @@ -406,8 +406,8 @@ static void append_unique(char *buf, char *prefix, char *key, char *val, } } -static void enable_default_ext4_features(struct mkfs_opts *mop, char *anchor, - size_t maxbuflen, int user_spec) +static int enable_default_ext4_features(struct mkfs_opts *mop, char *anchor, + size_t maxbuflen, int user_spec) { if (IS_OST(&mop->mo_ldd)) { append_unique(anchor, user_spec ? "," : " -O ", @@ -438,7 +438,17 @@ static void enable_default_ext4_features(struct mkfs_opts *mop, char *anchor, /* The following options are only valid for ext4-based ldiskfs. * If --backfstype=ext3 is specified, do not enable them. */ if (mop->mo_ldd.ldd_mount_type == LDD_MT_EXT3) - return; + return 0; + + /* Enable quota by default */ + if (is_e2fsprogs_feature_supp("-O quota") == 0) { + append_unique(anchor, ",", "quota", NULL, maxbuflen); + } else { + fatal(); + fprintf(stderr, "\"-O quota\" must be supported by " + "e2fsprogs, please upgrade your e2fsprogs.\n"); + return EINVAL; + } /* Allow files larger than 2TB. Also needs LU-16, but not harmful. */ if (is_e2fsprogs_feature_supp("-O huge_file") == 0) @@ -464,6 +474,7 @@ static void enable_default_ext4_features(struct mkfs_opts *mop, char *anchor, } } /* Don't add any more "-O" options here, see last comment above */ + return 0; } /** @@ -659,13 +670,15 @@ int ldiskfs_make_lustre(struct mkfs_opts *mop) start = moveopts_to_end(start); maxbuflen = sizeof(mop->mo_mkfsopts) - (start - mop->mo_mkfsopts) - strlen(start); - enable_default_ext4_features(mop, start, maxbuflen, 1); + ret = enable_default_ext4_features(mop, start, maxbuflen, 1); } else { start = mop->mo_mkfsopts + strlen(mop->mo_mkfsopts), maxbuflen = sizeof(mop->mo_mkfsopts) - strlen(mop->mo_mkfsopts); - enable_default_ext4_features(mop, start, maxbuflen, 0); + ret = enable_default_ext4_features(mop, start, maxbuflen, 0); } + if (ret) + return ret; /* end handle -O mkfs options */ /* start handle -E mkfs options */ -- 1.8.3.1