From fcf2c722d3600348d01d322aba1237bcf26e09ba Mon Sep 17 00:00:00 2001 From: tianzy Date: Wed, 4 Jul 2007 07:53:53 +0000 Subject: [PATCH] Branch b1_6 Severity : normal Frequency : when qunit size is too small(less than 20M) Bugzilla : 12588 Description: write is stopped by improper -EDQUOT Details : If the master is busy and qunit size is small enough(let's say 1M), the slave can not get quota from master on time, which will lead slave to trigger a -EQUOTA to client. b=12588 i=green i=wangdi --- lustre/ChangeLog | 8 ++++++++ lustre/include/lustre_quota.h | 8 ++++++++ lustre/obdfilter/lproc_obdfilter.c | 2 ++ lustre/quota/quota_context.c | 2 ++ lustre/quota/quota_interface.c | 37 ++++++++++++++++++++++++++++++++++++- 5 files changed, 56 insertions(+), 1 deletion(-) diff --git a/lustre/ChangeLog b/lustre/ChangeLog index f8c0ec6..27e6f5e 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -15,6 +15,14 @@ tbd Cluster File Systems, Inc. * bug fixes Severity : normal +Frequency : when qunit size is too small(less than 20M) +Bugzilla : 12588 +Description: write is stopped by improper -EDQUOT +Details : If the master is busy and qunit size is small enough(let's say 1M), + the slave can not get quota from master on time, which will lead + slave to trigger a -EQUOTA to client. + +Severity : normal Frequency : rare Bugzilla : 12629 Description: Deadlock during metadata tests diff --git a/lustre/include/lustre_quota.h b/lustre/include/lustre_quota.h index cf81f60..1ead9b0 100644 --- a/lustre/include/lustre_quota.h +++ b/lustre/include/lustre_quota.h @@ -142,6 +142,9 @@ struct lustre_quota_ctxt { * more than this value + 1 iunit */ unsigned long lqc_bunit_sz; /* Unit size of block quota */ unsigned long lqc_btune_sz; /* See comment of lqc_itune_sz */ + unsigned long lqc_limit_sz; /* When remaining quota on ost is less + * than this value, ost will request + * quota from mds */ }; #else @@ -430,6 +433,11 @@ int lprocfs_rd_type(char *page, char **start, off_t off, int count, int *eof, void *data); int lprocfs_wr_type(struct file *file, const char *buffer, unsigned long count, void *data); +int lprocfs_filter_rd_limit(char *page, char **start, off_t off, int count, + int *eof, void *data); +int lprocfs_filter_wr_limit(struct file *file, const char *buffer, + unsigned long count, void *data); + #ifndef __KERNEL__ extern quota_interface_t osc_quota_interface; diff --git a/lustre/obdfilter/lproc_obdfilter.c b/lustre/obdfilter/lproc_obdfilter.c index c40ba57..46b6a79 100644 --- a/lustre/obdfilter/lproc_obdfilter.c +++ b/lustre/obdfilter/lproc_obdfilter.c @@ -203,6 +203,8 @@ static struct lprocfs_vars lprocfs_obd_vars[] = { { "quota_iunit_sz", lprocfs_rd_iunit, lprocfs_wr_iunit, 0}, { "quota_itune_sz", lprocfs_rd_itune, lprocfs_wr_itune, 0}, { "quota_type", lprocfs_rd_type, lprocfs_wr_type, 0}, + { "quota_limit_sz", lprocfs_filter_rd_limit, + lprocfs_filter_wr_limit, 0}, #endif { "client_cache_count", lprocfs_filter_rd_fmd_max_num, lprocfs_filter_wr_fmd_max_num, 0 }, diff --git a/lustre/quota/quota_context.c b/lustre/quota/quota_context.c index 73159dc..4a692eb 100644 --- a/lustre/quota/quota_context.c +++ b/lustre/quota/quota_context.c @@ -35,6 +35,7 @@ unsigned long default_bunit_sz = 100 * 1024 * 1024; /* 100M bytes */ unsigned long default_btune_ratio = 50; /* 50 percentage */ unsigned long default_iunit_sz = 5000; /* 5000 inodes */ unsigned long default_itune_ratio = 50; /* 50 percentage */ +unsigned long default_limit_sz = 20 * 1024 * 1024; cfs_mem_cache_t *qunit_cachep = NULL; struct list_head qunit_hash[NR_DQHASH]; @@ -772,6 +773,7 @@ qctxt_init(struct lustre_quota_ctxt *qctxt, struct super_block *sb, 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_limit_sz = default_limit_sz; RETURN(0); } diff --git a/lustre/quota/quota_interface.c b/lustre/quota/quota_interface.c index df60c3b..eaa4b46 100644 --- a/lustre/quota/quota_interface.c +++ b/lustre/quota/quota_interface.c @@ -281,6 +281,37 @@ int lprocfs_wr_type(struct file *file, const char *buffer, return count; } EXPORT_SYMBOL(lprocfs_wr_type); + +int lprocfs_filter_rd_limit(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_limit_sz); +} +EXPORT_SYMBOL(lprocfs_filter_rd_limit); + +int lprocfs_filter_wr_limit(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 << 20) + return -EINVAL; + + obd->u.obt.obt_qctxt.lqc_limit_sz = val; + return count; +} +EXPORT_SYMBOL(lprocfs_filter_wr_limit); + #endif /* LPROCFS */ static int filter_quota_setup(struct obd_device *obd) @@ -401,6 +432,7 @@ static int filter_quota_check(struct obd_device *obd, unsigned int uid, struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt; int i; __u32 id[MAXQUOTAS] = { uid, gid }; + __u64 limit; struct qunit_data qdata[MAXQUOTAS]; int rc; ENTRY; @@ -417,8 +449,11 @@ static int filter_quota_check(struct obd_device *obd, unsigned int uid, qctxt_wait_pending_dqacq(qctxt, id[i], i, 1); rc = compute_remquota(obd, qctxt, &qdata[i]); + limit = npage * CFS_PAGE_SIZE; + if (limit < qctxt->lqc_limit_sz ) + limit = qctxt->lqc_limit_sz; if (rc == QUOTA_RET_OK && - qdata[i].qd_count < npage * CFS_PAGE_SIZE) + qdata[i].qd_count < limit) RETURN(QUOTA_RET_ACQUOTA); } -- 1.8.3.1