* 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
* 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
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;
{ "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 },
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];
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);
}
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)
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;
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);
}