diff mbox

[24/25] ubifs: implement ubifs_qctl_operations for quotactl

Message ID 1437467876-22106-25-git-send-email-yangds.fnst@cn.fujitsu.com (mailing list archive)
State New, archived
Headers show

Commit Message

Yang Dongsheng July 21, 2015, 8:37 a.m. UTC
To make ubifs support quota, we have to provide a qctl_operations
to quotactl. But we can not use the default operations. The problem
is quota_off function. We have to do a budget at first before
disabling quota.

Signed-off-by: Dongsheng Yang <yangds.fnst@cn.fujitsu.com>
---
 fs/ubifs/super.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)
diff mbox

Patch

diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 60deed2..00451b0 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -2278,6 +2278,62 @@  static struct ubifs_info *alloc_ubifs_info(struct ubi_volume_desc *ubi)
 	return c;
 }
 
+#ifdef CONFIG_QUOTA
+static int ubifs_quota_off(struct super_block *sb, int type)
+{
+	struct ubifs_budget_req req = {};
+	struct ubifs_info *c = sb->s_fs_info;
+	struct quota_info *dqopt = sb_dqopt(sb);
+	struct inode *inodes[MAXQUOTAS] = {};
+	struct inode *tmp = NULL;
+	struct ubifs_inode *ui = NULL;
+	int ret = 0;
+	int cnt = 0;
+
+	if (type == -1) {
+		for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+			if (!sb_has_quota_loaded(sb, cnt))
+				continue;
+			req.dirtied_ino += 1;
+			inodes[cnt] = dqopt->files[cnt];
+		}
+	} else {
+		if (sb_has_quota_loaded(sb, type)) {
+			req.dirtied_ino = 1;
+			inodes[cnt] = dqopt->files[type];
+		}
+	}
+
+	if (req.dirtied_ino) {
+		ret = ubifs_budget_space(c, &req);
+		if (ret)
+			return ret;
+	}
+
+	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
+		tmp = inodes[cnt];
+		if (!tmp)
+			break;
+		ui = ubifs_inode(tmp);
+		mutex_lock(&ui->ui_mutex);
+		ui->budgeted = 1;
+		mutex_unlock(&ui->ui_mutex);
+	}
+
+	return dquot_disable(sb, type, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
+}
+
+static const struct quotactl_ops ubifs_qctl_operations = {
+	.quota_on	= dquot_quota_on,
+	.quota_off	= ubifs_quota_off,
+	.quota_sync     = dquot_quota_sync,
+	.get_state      = dquot_get_state,
+	.set_info       = dquot_set_dqinfo,
+	.get_dqblk      = dquot_get_dqblk,
+	.set_dqblk      = dquot_set_dqblk
+};
+#endif
+
 static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct ubifs_info *c = sb->s_fs_info;